Lines Matching +full:clip +full:- +full:y +full:- +full:low

1 // SPDX-License-Identifier: GPL-2.0
4 * - Przemysłowy Instytut Automatyki i Pomiarów PIAP
12 #include <media/v4l2-ctrls.h>
13 #include <media/v4l2-fwnode.h>
14 #include <media/v4l2-subdev.h>
145 return &container_of(ctrl->handler, struct ar0521_dev, in ctrl_to_sd()
146 ctrls.handler)->sd; in ctrl_to_sd()
156 return div_u64(v + d - 1, d); in div64_round_up()
161 switch (sensor->fmt.code) { in ar0521_code_to_bpp()
166 return -EINVAL; in ar0521_code_to_bpp()
173 struct i2c_client *client = sensor->i2c_client; in ar0521_write_regs()
177 msg.addr = client->addr; in ar0521_write_regs()
178 msg.flags = client->flags; in ar0521_write_regs()
182 ret = i2c_transfer(client->adapter, &msg, 1); in ar0521_write_regs()
185 v4l2_err(&sensor->sd, "%s: I2C write error\n", __func__); in ar0521_write_regs()
202 u16 x = clamp((AR0521_WIDTH_MAX - sensor->fmt.width) / 2, in ar0521_set_geometry()
204 u16 y = clamp(((AR0521_HEIGHT_MAX - sensor->fmt.height) / 2) & ~1, in ar0521_set_geometry() local
207 /* All dimensions are unsigned 12-bit integers */ in ar0521_set_geometry()
210 be(sensor->fmt.height + sensor->ctrls.vblank->val), in ar0521_set_geometry()
211 be(sensor->fmt.width + sensor->ctrls.hblank->val), in ar0521_set_geometry()
213 be(y), in ar0521_set_geometry()
214 be(x + sensor->fmt.width - 1), in ar0521_set_geometry()
215 be(y + sensor->fmt.height - 1), in ar0521_set_geometry()
216 be(sensor->fmt.width), in ar0521_set_geometry()
217 be(sensor->fmt.height) in ar0521_set_geometry()
225 int green = sensor->ctrls.gain->val; in ar0521_set_gains()
226 int red = max(green + sensor->ctrls.red_balance->val, 0); in ar0521_set_gains()
227 int blue = max(green + sensor->ctrls.blue_balance->val, 0); in ar0521_set_gains()
229 unsigned int analog = min(gain, 64u); /* range is 0 - 127 */ in ar0521_set_gains()
232 red = min(red - analog + 64, 511u); in ar0521_set_gains()
233 green = min(green - analog + 64, 511u); in ar0521_set_gains()
234 blue = min(blue - analog + 64, 511u); in ar0521_set_gains()
252 sensor->extclk_freq); in calc_pll()
258 if (sensor->extclk_freq * (u64)new_mult < (u64)AR0521_PLL_MIN * in calc_pll()
261 if (sensor->extclk_freq * (u64)new_mult > (u64)AR0521_PLL_MAX * in calc_pll()
264 new_pll = div64_round_up(sensor->extclk_freq * (u64)new_mult, in calc_pll()
273 pll = div64_round(sensor->extclk_freq * (u64)mult, pre); in calc_pll()
292 * - mclk -> / pre_div1 * pre_mul1 = VCO1 = COUNTER_CLOCK in ar0521_calc_pll()
295 * - mclk -> / pre_div * pre_mul = VCO in ar0521_calc_pll()
297 * VCO -> / vt_pix = PIXEL_CLOCK in ar0521_calc_pll()
298 * VCO -> / vt_pix / 2 = WORD_CLOCK in ar0521_calc_pll()
299 * VCO -> / op_sys = SERIAL_CLOCK in ar0521_calc_pll()
302 * - vt_pix = bpp / 2 in ar0521_calc_pll()
303 * - WORD_CLOCK = PIXEL_CLOCK / 2 in ar0521_calc_pll()
304 * - SERIAL_CLOCK = MIPI data rate (Mbps / lane) = WORD_CLOCK * bpp in ar0521_calc_pll()
324 * WORD_CLOCK = (35MHz - 120 MHz) in ar0521_calc_pll()
325 * PIXEL_CLOCK = (84MHz - 207MHz) in ar0521_calc_pll()
326 * VCO = (320MHz - 1280MHz) in ar0521_calc_pll()
332 pixel_clock = AR0521_PIXEL_CLOCK_RATE * 2 / sensor->lane_count; in ar0521_calc_pll()
334 sensor->pll.vt_pix = bpp / 2; in ar0521_calc_pll()
335 vco = pixel_clock * sensor->pll.vt_pix; in ar0521_calc_pll()
339 sensor->pll.pre = sensor->pll.pre2 = pre; in ar0521_calc_pll()
340 sensor->pll.mult = sensor->pll.mult2 = mult; in ar0521_calc_pll()
347 /* 0x300 */ be(sensor->pll.vt_pix), /* vt_pix_clk_div = bpp / 2 */ in ar0521_pll_config()
349 /* 0x304 */ be((sensor->pll.pre2 << 8) | sensor->pll.pre), in ar0521_pll_config()
350 /* 0x306 */ be((sensor->pll.mult2 << 8) | sensor->pll.mult), in ar0521_pll_config()
351 /* 0x308 */ be(sensor->pll.vt_pix * 2), /* op_pix_clk_div = 2 * vt_pix_clk_div */ in ar0521_pll_config()
364 ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); in ar0521_set_stream()
382 ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); in ar0521_set_stream()
386 /* Exit LP-11 mode on clock and data lanes */ in ar0521_set_stream()
402 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_set_stream()
420 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_set_stream()
427 fmt->width = clamp(ALIGN(fmt->width, 4), AR0521_WIDTH_MIN, in ar0521_adj_fmt()
429 fmt->height = clamp(ALIGN(fmt->height, 4), AR0521_HEIGHT_MIN, in ar0521_adj_fmt()
431 fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; in ar0521_adj_fmt()
432 fmt->field = V4L2_FIELD_NONE; in ar0521_adj_fmt()
433 fmt->colorspace = V4L2_COLORSPACE_SRGB; in ar0521_adj_fmt()
434 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in ar0521_adj_fmt()
435 fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; in ar0521_adj_fmt()
436 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in ar0521_adj_fmt()
446 mutex_lock(&sensor->lock); in ar0521_get_fmt()
448 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in ar0521_get_fmt()
451 fmt = &sensor->fmt; in ar0521_get_fmt()
453 format->format = *fmt; in ar0521_get_fmt()
455 mutex_unlock(&sensor->lock); in ar0521_get_fmt()
467 ar0521_adj_fmt(&format->format); in ar0521_set_fmt()
469 mutex_lock(&sensor->lock); in ar0521_set_fmt()
471 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { in ar0521_set_fmt()
475 *fmt = format->format; in ar0521_set_fmt()
477 mutex_unlock(&sensor->lock); in ar0521_set_fmt()
482 sensor->fmt = format->format; in ar0521_set_fmt()
489 max_hblank = AR0521_TOTAL_WIDTH_MAX - sensor->fmt.width; in ar0521_set_fmt()
490 ret = __v4l2_ctrl_modify_range(sensor->ctrls.hblank, in ar0521_set_fmt()
491 sensor->ctrls.hblank->minimum, in ar0521_set_fmt()
492 max_hblank, sensor->ctrls.hblank->step, in ar0521_set_fmt()
493 sensor->ctrls.hblank->minimum); in ar0521_set_fmt()
497 ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.hblank, in ar0521_set_fmt()
498 sensor->ctrls.hblank->minimum); in ar0521_set_fmt()
502 max_vblank = AR0521_TOTAL_HEIGHT_MAX - sensor->fmt.height; in ar0521_set_fmt()
503 ret = __v4l2_ctrl_modify_range(sensor->ctrls.vblank, in ar0521_set_fmt()
504 sensor->ctrls.vblank->minimum, in ar0521_set_fmt()
505 max_vblank, sensor->ctrls.vblank->step, in ar0521_set_fmt()
506 sensor->ctrls.vblank->minimum); in ar0521_set_fmt()
510 ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, in ar0521_set_fmt()
511 sensor->ctrls.vblank->minimum); in ar0521_set_fmt()
515 exposure_max = sensor->fmt.height + AR0521_HEIGHT_BLANKING_MIN - 4; in ar0521_set_fmt()
516 ret = __v4l2_ctrl_modify_range(sensor->ctrls.exposure, in ar0521_set_fmt()
517 sensor->ctrls.exposure->minimum, in ar0521_set_fmt()
519 sensor->ctrls.exposure->step, in ar0521_set_fmt()
520 sensor->ctrls.exposure->default_value); in ar0521_set_fmt()
522 mutex_unlock(&sensor->lock); in ar0521_set_fmt()
536 switch (ctrl->id) { in ar0521_s_ctrl()
538 exp_max = sensor->fmt.height + ctrl->val - 4; in ar0521_s_ctrl()
539 __v4l2_ctrl_modify_range(sensor->ctrls.exposure, in ar0521_s_ctrl()
540 sensor->ctrls.exposure->minimum, in ar0521_s_ctrl()
541 exp_max, sensor->ctrls.exposure->step, in ar0521_s_ctrl()
542 sensor->ctrls.exposure->default_value); in ar0521_s_ctrl()
547 if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev)) in ar0521_s_ctrl()
550 switch (ctrl->id) { in ar0521_s_ctrl()
557 ctrl->val); in ar0521_s_ctrl()
567 ctrl->val); in ar0521_s_ctrl()
571 ctrl->val); in ar0521_s_ctrl()
574 dev_err(&sensor->i2c_client->dev, in ar0521_s_ctrl()
575 "Unsupported control %x\n", ctrl->id); in ar0521_s_ctrl()
576 ret = -EINVAL; in ar0521_s_ctrl()
580 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_s_ctrl()
598 struct ar0521_ctrls *ctrls = &sensor->ctrls; in ar0521_init_controls()
599 struct v4l2_ctrl_handler *hdl = &ctrls->handler; in ar0521_init_controls()
607 hdl->lock = &sensor->lock; in ar0521_init_controls()
615 ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 511, 1, 0); in ar0521_init_controls()
616 ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE, in ar0521_init_controls()
617 -512, 511, 1, 0); in ar0521_init_controls()
618 ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE, in ar0521_init_controls()
619 -512, 511, 1, 0); in ar0521_init_controls()
620 v4l2_ctrl_cluster(3, &ctrls->gain); in ar0521_init_controls()
623 max_hblank = AR0521_TOTAL_WIDTH_MAX - AR0521_WIDTH_MAX; in ar0521_init_controls()
624 ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, in ar0521_init_controls()
629 max_vblank = AR0521_TOTAL_HEIGHT_MAX - AR0521_HEIGHT_MAX; in ar0521_init_controls()
630 ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK, in ar0521_init_controls()
634 v4l2_ctrl_cluster(2, &ctrls->hblank); in ar0521_init_controls()
636 /* Read-only */ in ar0521_init_controls()
637 ctrls->pixrate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE, in ar0521_init_controls()
642 /* Manual exposure time: max exposure time = visible + blank - 4 */ in ar0521_init_controls()
643 exposure_max = AR0521_HEIGHT_MAX + AR0521_HEIGHT_BLANKING_MIN - 4; in ar0521_init_controls()
644 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, in ar0521_init_controls()
648 ARRAY_SIZE(ar0521_link_frequencies) - 1, in ar0521_init_controls()
651 link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ar0521_init_controls()
653 ctrls->test_pattern = v4l2_ctrl_new_std_menu_items(hdl, ops, in ar0521_init_controls()
655 ARRAY_SIZE(test_pattern_menu) - 1, in ar0521_init_controls()
658 if (hdl->error) { in ar0521_init_controls()
659 ret = hdl->error; in ar0521_init_controls()
663 sensor->sd.ctrl_handler = hdl; in ar0521_init_controls()
678 REGS(be(0x0112), be(0x0808)), /* 8-bit/8-bit mode */
695 be(0x0FFF), /* 30DA: CC: column correction clip level 2 is 0 */
696 be(0x0FFF), /* 30DC: CC: column correction clip level 3 is 0 */
708 be(0x008B), /* 31B0: frame_preamble - FIXME check WRT lanes# */
709 be(0x0050)), /* 31B2: line_preamble - FIXME check WRT lanes# */
794 /* 3ECE: Ramp buffer settings and Booster enable (bits 0-5) */
815 /* 3F0A: Define noise_floor0(low address) and noise_floor1 */
844 if (sensor->reset_gpio) in __ar0521_power_off()
846 gpiod_set_value_cansleep(sensor->reset_gpio, 1); in __ar0521_power_off()
848 for (i = ARRAY_SIZE(ar0521_supply_names) - 1; i >= 0; i--) { in __ar0521_power_off()
849 if (sensor->supplies[i]) in __ar0521_power_off()
850 regulator_disable(sensor->supplies[i]); in __ar0521_power_off()
859 clk_disable_unprepare(sensor->extclk); in ar0521_power_off()
873 if (sensor->supplies[cnt]) { in ar0521_power_on()
874 ret = regulator_enable(sensor->supplies[cnt]); in ar0521_power_on()
881 ret = clk_prepare_enable(sensor->extclk); in ar0521_power_on()
883 v4l2_err(&sensor->sd, "error enabling sensor clock\n"); in ar0521_power_on()
888 if (sensor->reset_gpio) in ar0521_power_on()
890 gpiod_set_value_cansleep(sensor->reset_gpio, 0); in ar0521_power_on()
902 sensor->lane_count); in ar0521_power_on()
906 /* set MIPI test mode - disabled for now */ in ar0521_power_on()
908 ((0x40 << sensor->lane_count) - 0x40) | in ar0521_power_on()
914 4 / sensor->lane_count); in ar0521_power_on()
920 clk_disable_unprepare(sensor->extclk); in ar0521_power_on()
931 if (code->index) in ar0521_enum_mbus_code()
932 return -EINVAL; in ar0521_enum_mbus_code()
934 code->code = sensor->fmt.code; in ar0521_enum_mbus_code()
942 if (fse->index) in ar0521_enum_frame_size()
943 return -EINVAL; in ar0521_enum_frame_size()
945 if (fse->code != MEDIA_BUS_FMT_SGRBG8_1X8) in ar0521_enum_frame_size()
946 return -EINVAL; in ar0521_enum_frame_size()
948 fse->min_width = AR0521_WIDTH_MIN; in ar0521_enum_frame_size()
949 fse->max_width = AR0521_WIDTH_MAX; in ar0521_enum_frame_size()
950 fse->min_height = AR0521_HEIGHT_MIN; in ar0521_enum_frame_size()
951 fse->max_height = AR0521_HEIGHT_MAX; in ar0521_enum_frame_size()
962 return -EACCES; in ar0521_pre_streamon()
964 ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); in ar0521_pre_streamon()
968 /* Set LP-11 on clock and data lanes */ in ar0521_pre_streamon()
974 /* Start streaming LP-11 */ in ar0521_pre_streamon()
983 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_pre_streamon()
991 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_post_streamoff()
1000 mutex_lock(&sensor->lock); in ar0521_s_stream()
1002 mutex_unlock(&sensor->lock); in ar0521_s_stream()
1035 struct device *dev = &client->dev; in ar0521_probe()
1043 return -ENOMEM; in ar0521_probe()
1045 sensor->i2c_client = client; in ar0521_probe()
1046 sensor->fmt.width = AR0521_WIDTH_MAX; in ar0521_probe()
1047 sensor->fmt.height = AR0521_HEIGHT_MAX; in ar0521_probe()
1053 return -EINVAL; in ar0521_probe()
1065 return -EINVAL; in ar0521_probe()
1068 sensor->lane_count = ep.bus.mipi_csi2.num_data_lanes; in ar0521_probe()
1069 switch (sensor->lane_count) { in ar0521_probe()
1076 return -EINVAL; in ar0521_probe()
1080 sensor->extclk = devm_clk_get(dev, "extclk"); in ar0521_probe()
1081 if (IS_ERR(sensor->extclk)) { in ar0521_probe()
1083 return PTR_ERR(sensor->extclk); in ar0521_probe()
1086 sensor->extclk_freq = clk_get_rate(sensor->extclk); in ar0521_probe()
1088 if (sensor->extclk_freq < AR0521_EXTCLK_MIN || in ar0521_probe()
1089 sensor->extclk_freq > AR0521_EXTCLK_MAX) { in ar0521_probe()
1091 sensor->extclk_freq); in ar0521_probe()
1092 return -EINVAL; in ar0521_probe()
1095 /* Request optional reset pin (usually active low) and assert it */ in ar0521_probe()
1096 sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset", in ar0521_probe()
1099 v4l2_i2c_subdev_init(&sensor->sd, client, &ar0521_subdev_ops); in ar0521_probe()
1101 sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in ar0521_probe()
1102 sensor->pad.flags = MEDIA_PAD_FL_SOURCE; in ar0521_probe()
1103 sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in ar0521_probe()
1104 ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad); in ar0521_probe()
1117 sensor->supplies[cnt] = supply; in ar0521_probe()
1120 mutex_init(&sensor->lock); in ar0521_probe()
1126 ar0521_adj_fmt(&sensor->fmt); in ar0521_probe()
1128 ret = v4l2_async_register_subdev(&sensor->sd); in ar0521_probe()
1133 ret = ar0521_power_on(&client->dev); in ar0521_probe()
1136 pm_runtime_set_active(&client->dev); in ar0521_probe()
1137 pm_runtime_enable(&client->dev); in ar0521_probe()
1138 pm_runtime_idle(&client->dev); in ar0521_probe()
1142 v4l2_async_unregister_subdev(&sensor->sd); in ar0521_probe()
1143 media_entity_cleanup(&sensor->sd.entity); in ar0521_probe()
1145 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ar0521_probe()
1147 media_entity_cleanup(&sensor->sd.entity); in ar0521_probe()
1148 mutex_destroy(&sensor->lock); in ar0521_probe()
1157 v4l2_async_unregister_subdev(&sensor->sd); in ar0521_remove()
1158 media_entity_cleanup(&sensor->sd.entity); in ar0521_remove()
1159 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ar0521_remove()
1160 pm_runtime_disable(&client->dev); in ar0521_remove()
1161 if (!pm_runtime_status_suspended(&client->dev)) in ar0521_remove()
1162 ar0521_power_off(&client->dev); in ar0521_remove()
1163 pm_runtime_set_suspended(&client->dev); in ar0521_remove()
1164 mutex_destroy(&sensor->lock); in ar0521_remove()