Lines Matching +full:rate +full:- +full:lp +full:- +full:ms

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>
24 /* Effective pixel sample rate on the pixel array. */
147 return &container_of(ctrl->handler, struct ar0521_dev, in ctrl_to_sd()
148 ctrls.handler)->sd; in ctrl_to_sd()
158 return div_u64(v + d - 1, d); in div64_round_up()
163 switch (sensor->fmt.code) { in ar0521_code_to_bpp()
168 return -EINVAL; in ar0521_code_to_bpp()
175 struct i2c_client *client = sensor->i2c_client; in ar0521_write_regs()
179 msg.addr = client->addr; in ar0521_write_regs()
180 msg.flags = client->flags; in ar0521_write_regs()
184 ret = i2c_transfer(client->adapter, &msg, 1); in ar0521_write_regs()
187 v4l2_err(&sensor->sd, "%s: I2C write error\n", __func__); in ar0521_write_regs()
204 u16 x = clamp((AR0521_WIDTH_MAX - sensor->fmt.width) / 2, in ar0521_set_geometry()
206 u16 y = clamp(((AR0521_HEIGHT_MAX - sensor->fmt.height) / 2) & ~1, in ar0521_set_geometry()
209 /* All dimensions are unsigned 12-bit integers */ in ar0521_set_geometry()
212 be(sensor->fmt.height + sensor->ctrls.vblank->val), in ar0521_set_geometry()
213 be(sensor->fmt.width + sensor->ctrls.hblank->val), in ar0521_set_geometry()
216 be(x + sensor->fmt.width - 1), in ar0521_set_geometry()
217 be(y + sensor->fmt.height - 1), in ar0521_set_geometry()
218 be(sensor->fmt.width), in ar0521_set_geometry()
219 be(sensor->fmt.height) in ar0521_set_geometry()
227 int green = sensor->ctrls.gain->val; in ar0521_set_gains()
228 int red = max(green + sensor->ctrls.red_balance->val, 0); in ar0521_set_gains()
229 int blue = max(green + sensor->ctrls.blue_balance->val, 0); in ar0521_set_gains()
231 unsigned int analog = min(gain, 64u); /* range is 0 - 127 */ in ar0521_set_gains()
234 red = min(red - analog + 64, 511u); in ar0521_set_gains()
235 green = min(green - analog + 64, 511u); in ar0521_set_gains()
236 blue = min(blue - analog + 64, 511u); in ar0521_set_gains()
254 sensor->extclk_freq); in calc_pll()
260 if (sensor->extclk_freq * (u64)new_mult < (u64)AR0521_PLL_MIN * in calc_pll()
263 if (sensor->extclk_freq * (u64)new_mult > (u64)AR0521_PLL_MAX * in calc_pll()
266 new_pll = div64_round_up(sensor->extclk_freq * (u64)new_mult, in calc_pll()
275 pll = div64_round(sensor->extclk_freq * (u64)mult, pre); in calc_pll()
294 * - mclk -> / pre_div1 * pre_mul1 = VCO1 = COUNTER_CLOCK in ar0521_calc_pll()
297 * - mclk -> / pre_div * pre_mul = VCO in ar0521_calc_pll()
299 * VCO -> / vt_pix = PIXEL_CLOCK in ar0521_calc_pll()
300 * VCO -> / vt_pix / 2 = WORD_CLOCK in ar0521_calc_pll()
301 * VCO -> / op_sys = SERIAL_CLOCK in ar0521_calc_pll()
304 * - vt_pix = bpp / 2 in ar0521_calc_pll()
305 * - WORD_CLOCK = PIXEL_CLOCK / 2 in ar0521_calc_pll()
306 * - SERIAL_CLOCK = MIPI data rate (Mbps / lane) = WORD_CLOCK * bpp in ar0521_calc_pll()
326 * WORD_CLOCK = (35MHz - 120 MHz) in ar0521_calc_pll()
327 * PIXEL_CLOCK = (84MHz - 207MHz) in ar0521_calc_pll()
328 * VCO = (320MHz - 1280MHz) in ar0521_calc_pll()
334 pixel_clock = AR0521_PIXEL_CLOCK_RATE * 2 / sensor->lane_count; in ar0521_calc_pll()
336 sensor->pll.vt_pix = bpp / 2; in ar0521_calc_pll()
337 vco = pixel_clock * sensor->pll.vt_pix; in ar0521_calc_pll()
341 sensor->pll.pre = sensor->pll.pre2 = pre; in ar0521_calc_pll()
342 sensor->pll.mult = sensor->pll.mult2 = mult; in ar0521_calc_pll()
349 /* 0x300 */ be(sensor->pll.vt_pix), /* vt_pix_clk_div = bpp / 2 */ in ar0521_pll_config()
351 /* 0x304 */ be((sensor->pll.pre2 << 8) | sensor->pll.pre), in ar0521_pll_config()
352 /* 0x306 */ be((sensor->pll.mult2 << 8) | sensor->pll.mult), in ar0521_pll_config()
353 /* 0x308 */ be(sensor->pll.vt_pix * 2), /* op_pix_clk_div = 2 * vt_pix_clk_div */ in ar0521_pll_config()
366 ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); in ar0521_set_stream()
384 ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); in ar0521_set_stream()
388 /* Exit LP-11 mode on clock and data lanes */ in ar0521_set_stream()
404 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_set_stream()
422 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_set_stream()
429 fmt->width = clamp(ALIGN(fmt->width, 4), AR0521_WIDTH_MIN, in ar0521_adj_fmt()
431 fmt->height = clamp(ALIGN(fmt->height, 4), AR0521_HEIGHT_MIN, in ar0521_adj_fmt()
433 fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; in ar0521_adj_fmt()
434 fmt->field = V4L2_FIELD_NONE; in ar0521_adj_fmt()
435 fmt->colorspace = V4L2_COLORSPACE_SRGB; in ar0521_adj_fmt()
436 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in ar0521_adj_fmt()
437 fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; in ar0521_adj_fmt()
438 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in ar0521_adj_fmt()
448 mutex_lock(&sensor->lock); in ar0521_get_fmt()
450 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in ar0521_get_fmt()
451 fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, 0 in ar0521_get_fmt()
454 fmt = &sensor->fmt; in ar0521_get_fmt()
456 format->format = *fmt; in ar0521_get_fmt()
458 mutex_unlock(&sensor->lock); in ar0521_get_fmt()
470 ar0521_adj_fmt(&format->format); in ar0521_set_fmt()
472 mutex_lock(&sensor->lock); in ar0521_set_fmt()
474 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { in ar0521_set_fmt()
478 *fmt = format->format; in ar0521_set_fmt()
480 mutex_unlock(&sensor->lock); in ar0521_set_fmt()
485 sensor->fmt = format->format; in ar0521_set_fmt()
492 max_hblank = AR0521_TOTAL_WIDTH_MAX - sensor->fmt.width; in ar0521_set_fmt()
493 ret = __v4l2_ctrl_modify_range(sensor->ctrls.hblank, in ar0521_set_fmt()
494 sensor->ctrls.hblank->minimum, in ar0521_set_fmt()
495 max_hblank, sensor->ctrls.hblank->step, in ar0521_set_fmt()
496 sensor->ctrls.hblank->minimum); in ar0521_set_fmt()
500 ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.hblank, in ar0521_set_fmt()
501 sensor->ctrls.hblank->minimum); in ar0521_set_fmt()
505 max_vblank = AR0521_TOTAL_HEIGHT_MAX - sensor->fmt.height; in ar0521_set_fmt()
506 ret = __v4l2_ctrl_modify_range(sensor->ctrls.vblank, in ar0521_set_fmt()
507 sensor->ctrls.vblank->minimum, in ar0521_set_fmt()
508 max_vblank, sensor->ctrls.vblank->step, in ar0521_set_fmt()
509 sensor->ctrls.vblank->minimum); in ar0521_set_fmt()
513 ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, in ar0521_set_fmt()
514 sensor->ctrls.vblank->minimum); in ar0521_set_fmt()
518 exposure_max = sensor->fmt.height + AR0521_HEIGHT_BLANKING_MIN - 4; in ar0521_set_fmt()
519 ret = __v4l2_ctrl_modify_range(sensor->ctrls.exposure, in ar0521_set_fmt()
520 sensor->ctrls.exposure->minimum, in ar0521_set_fmt()
522 sensor->ctrls.exposure->step, in ar0521_set_fmt()
523 sensor->ctrls.exposure->default_value); in ar0521_set_fmt()
525 mutex_unlock(&sensor->lock); in ar0521_set_fmt()
539 switch (ctrl->id) { in ar0521_s_ctrl()
541 exp_max = sensor->fmt.height + ctrl->val - 4; in ar0521_s_ctrl()
542 __v4l2_ctrl_modify_range(sensor->ctrls.exposure, in ar0521_s_ctrl()
543 sensor->ctrls.exposure->minimum, in ar0521_s_ctrl()
544 exp_max, sensor->ctrls.exposure->step, in ar0521_s_ctrl()
545 sensor->ctrls.exposure->default_value); in ar0521_s_ctrl()
550 if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev)) in ar0521_s_ctrl()
553 switch (ctrl->id) { in ar0521_s_ctrl()
560 ctrl->val); in ar0521_s_ctrl()
570 ctrl->val); in ar0521_s_ctrl()
574 ctrl->val); in ar0521_s_ctrl()
577 dev_err(&sensor->i2c_client->dev, in ar0521_s_ctrl()
578 "Unsupported control %x\n", ctrl->id); in ar0521_s_ctrl()
579 ret = -EINVAL; in ar0521_s_ctrl()
583 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_s_ctrl()
601 struct ar0521_ctrls *ctrls = &sensor->ctrls; in ar0521_init_controls()
602 struct v4l2_ctrl_handler *hdl = &ctrls->handler; in ar0521_init_controls()
610 hdl->lock = &sensor->lock; in ar0521_init_controls()
618 ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 511, 1, 0); in ar0521_init_controls()
619 ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE, in ar0521_init_controls()
620 -512, 511, 1, 0); in ar0521_init_controls()
621 ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE, in ar0521_init_controls()
622 -512, 511, 1, 0); in ar0521_init_controls()
623 v4l2_ctrl_cluster(3, &ctrls->gain); in ar0521_init_controls()
626 max_hblank = AR0521_TOTAL_WIDTH_MAX - AR0521_WIDTH_MAX; in ar0521_init_controls()
627 ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, in ar0521_init_controls()
632 max_vblank = AR0521_TOTAL_HEIGHT_MAX - AR0521_HEIGHT_MAX; in ar0521_init_controls()
633 ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK, in ar0521_init_controls()
637 v4l2_ctrl_cluster(2, &ctrls->hblank); in ar0521_init_controls()
639 /* Read-only */ in ar0521_init_controls()
640 ctrls->pixrate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE, in ar0521_init_controls()
645 /* Manual exposure time: max exposure time = visible + blank - 4 */ in ar0521_init_controls()
646 exposure_max = AR0521_HEIGHT_MAX + AR0521_HEIGHT_BLANKING_MIN - 4; in ar0521_init_controls()
647 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, in ar0521_init_controls()
651 ARRAY_SIZE(ar0521_link_frequencies) - 1, in ar0521_init_controls()
654 link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ar0521_init_controls()
656 ctrls->test_pattern = v4l2_ctrl_new_std_menu_items(hdl, ops, in ar0521_init_controls()
658 ARRAY_SIZE(test_pattern_menu) - 1, in ar0521_init_controls()
661 if (hdl->error) { in ar0521_init_controls()
662 ret = hdl->error; in ar0521_init_controls()
666 sensor->sd.ctrl_handler = hdl; in ar0521_init_controls()
681 REGS(be(0x0112), be(0x0808)), /* 8-bit/8-bit mode */
711 be(0x008B), /* 31B0: frame_preamble - FIXME check WRT lanes# */
712 be(0x0050)), /* 31B2: line_preamble - FIXME check WRT lanes# */
797 /* 3ECE: Ramp buffer settings and Booster enable (bits 0-5) */
847 clk_disable_unprepare(sensor->extclk); in ar0521_power_off()
849 if (sensor->reset_gpio) in ar0521_power_off()
851 gpiod_set_value_cansleep(sensor->reset_gpio, 1); in ar0521_power_off()
853 for (i = ARRAY_SIZE(ar0521_supply_names) - 1; i >= 0; i--) { in ar0521_power_off()
854 if (sensor->supplies[i]) in ar0521_power_off()
855 regulator_disable(sensor->supplies[i]); in ar0521_power_off()
868 if (sensor->supplies[cnt]) { in ar0521_power_on()
869 ret = regulator_enable(sensor->supplies[cnt]); in ar0521_power_on()
873 usleep_range(1000, 1500); /* min 1 ms */ in ar0521_power_on()
876 ret = clk_prepare_enable(sensor->extclk); in ar0521_power_on()
878 v4l2_err(&sensor->sd, "error enabling sensor clock\n"); in ar0521_power_on()
881 usleep_range(1000, 1500); /* min 1 ms */ in ar0521_power_on()
883 if (sensor->reset_gpio) in ar0521_power_on()
885 gpiod_set_value_cansleep(sensor->reset_gpio, 0); in ar0521_power_on()
897 sensor->lane_count); in ar0521_power_on()
901 /* set MIPI test mode - disabled for now */ in ar0521_power_on()
903 ((0x40 << sensor->lane_count) - 0x40) | in ar0521_power_on()
909 4 / sensor->lane_count); in ar0521_power_on()
925 if (code->index) in ar0521_enum_mbus_code()
926 return -EINVAL; in ar0521_enum_mbus_code()
928 code->code = sensor->fmt.code; in ar0521_enum_mbus_code()
936 if (fse->index) in ar0521_enum_frame_size()
937 return -EINVAL; in ar0521_enum_frame_size()
939 if (fse->code != MEDIA_BUS_FMT_SGRBG8_1X8) in ar0521_enum_frame_size()
940 return -EINVAL; in ar0521_enum_frame_size()
942 fse->min_width = AR0521_WIDTH_MIN; in ar0521_enum_frame_size()
943 fse->max_width = AR0521_WIDTH_MAX; in ar0521_enum_frame_size()
944 fse->min_height = AR0521_HEIGHT_MIN; in ar0521_enum_frame_size()
945 fse->max_height = AR0521_HEIGHT_MAX; in ar0521_enum_frame_size()
956 return -EACCES; in ar0521_pre_streamon()
958 ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); in ar0521_pre_streamon()
962 /* Set LP-11 on clock and data lanes */ in ar0521_pre_streamon()
968 /* Start streaming LP-11 */ in ar0521_pre_streamon()
977 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_pre_streamon()
985 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_post_streamoff()
994 mutex_lock(&sensor->lock); in ar0521_s_stream()
998 sensor->streaming = enable; in ar0521_s_stream()
1000 mutex_unlock(&sensor->lock); in ar0521_s_stream()
1032 if (sensor->streaming) in ar0521_suspend()
1043 if (sensor->streaming) in ar0521_resume()
1054 struct device *dev = &client->dev; in ar0521_probe()
1062 return -ENOMEM; in ar0521_probe()
1064 sensor->i2c_client = client; in ar0521_probe()
1065 sensor->fmt.width = AR0521_WIDTH_MAX; in ar0521_probe()
1066 sensor->fmt.height = AR0521_HEIGHT_MAX; in ar0521_probe()
1072 return -EINVAL; in ar0521_probe()
1084 return -EINVAL; in ar0521_probe()
1087 sensor->lane_count = ep.bus.mipi_csi2.num_data_lanes; in ar0521_probe()
1088 switch (sensor->lane_count) { in ar0521_probe()
1095 return -EINVAL; in ar0521_probe()
1099 sensor->extclk = devm_clk_get(dev, "extclk"); in ar0521_probe()
1100 if (IS_ERR(sensor->extclk)) { in ar0521_probe()
1102 return PTR_ERR(sensor->extclk); in ar0521_probe()
1105 sensor->extclk_freq = clk_get_rate(sensor->extclk); in ar0521_probe()
1107 if (sensor->extclk_freq < AR0521_EXTCLK_MIN || in ar0521_probe()
1108 sensor->extclk_freq > AR0521_EXTCLK_MAX) { in ar0521_probe()
1110 sensor->extclk_freq); in ar0521_probe()
1111 return -EINVAL; in ar0521_probe()
1115 sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset", in ar0521_probe()
1118 v4l2_i2c_subdev_init(&sensor->sd, client, &ar0521_subdev_ops); in ar0521_probe()
1120 sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in ar0521_probe()
1121 sensor->pad.flags = MEDIA_PAD_FL_SOURCE; in ar0521_probe()
1122 sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in ar0521_probe()
1123 ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad); in ar0521_probe()
1136 sensor->supplies[cnt] = supply; in ar0521_probe()
1139 mutex_init(&sensor->lock); in ar0521_probe()
1145 ar0521_adj_fmt(&sensor->fmt); in ar0521_probe()
1147 ret = v4l2_async_register_subdev(&sensor->sd); in ar0521_probe()
1152 ret = ar0521_power_on(&client->dev); in ar0521_probe()
1155 pm_runtime_set_active(&client->dev); in ar0521_probe()
1156 pm_runtime_enable(&client->dev); in ar0521_probe()
1157 pm_runtime_idle(&client->dev); in ar0521_probe()
1161 v4l2_async_unregister_subdev(&sensor->sd); in ar0521_probe()
1162 media_entity_cleanup(&sensor->sd.entity); in ar0521_probe()
1164 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ar0521_probe()
1166 media_entity_cleanup(&sensor->sd.entity); in ar0521_probe()
1167 mutex_destroy(&sensor->lock); in ar0521_probe()
1176 v4l2_async_unregister_subdev(&sensor->sd); in ar0521_remove()
1177 media_entity_cleanup(&sensor->sd.entity); in ar0521_remove()
1178 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ar0521_remove()
1179 pm_runtime_disable(&client->dev); in ar0521_remove()
1180 if (!pm_runtime_status_suspended(&client->dev)) in ar0521_remove()
1181 ar0521_power_off(&client->dev); in ar0521_remove()
1182 pm_runtime_set_suspended(&client->dev); in ar0521_remove()
1183 mutex_destroy(&sensor->lock); in ar0521_remove()