Lines Matching +full:bias +full:- +full:bus +full:- +full:hold
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>
126 return &container_of(ctrl->handler, struct ar0521_dev, in ctrl_to_sd()
127 ctrls.handler)->sd; in ctrl_to_sd()
137 return div_u64(v + d - 1, d); in div64_round_up()
144 struct i2c_client *client = sensor->i2c_client; in ar0521_write_regs()
148 msg.addr = client->addr; in ar0521_write_regs()
149 msg.flags = client->flags; in ar0521_write_regs()
153 ret = i2c_transfer(client->adapter, &msg, 1); in ar0521_write_regs()
156 v4l2_err(&sensor->sd, "%s: I2C write error\n", __func__); in ar0521_write_regs()
172 /* All dimensions are unsigned 12-bit integers */ in ar0521_set_geometry()
173 u16 x = (AR0521_WIDTH_MAX - sensor->fmt.width) / 2; in ar0521_set_geometry()
174 u16 y = ((AR0521_HEIGHT_MAX - sensor->fmt.height) / 2) & ~1; in ar0521_set_geometry()
177 be(sensor->total_height), in ar0521_set_geometry()
178 be(sensor->total_width), in ar0521_set_geometry()
181 be(x + sensor->fmt.width - 1), in ar0521_set_geometry()
182 be(y + sensor->fmt.height - 1), in ar0521_set_geometry()
183 be(sensor->fmt.width), in ar0521_set_geometry()
184 be(sensor->fmt.height) in ar0521_set_geometry()
192 int green = sensor->ctrls.gain->val; in ar0521_set_gains()
193 int red = max(green + sensor->ctrls.red_balance->val, 0); in ar0521_set_gains()
194 int blue = max(green + sensor->ctrls.blue_balance->val, 0); in ar0521_set_gains()
196 unsigned int analog = min(gain, 64u); /* range is 0 - 127 */ in ar0521_set_gains()
199 red = min(red - analog + 64, 511u); in ar0521_set_gains()
200 green = min(green - analog + 64, 511u); in ar0521_set_gains()
201 blue = min(blue - analog + 64, 511u); in ar0521_set_gains()
220 sensor->extclk_freq); in calc_pll()
226 if (sensor->extclk_freq * (u64)new_mult < AR0521_PLL_MIN * in calc_pll()
229 if (sensor->extclk_freq * (u64)new_mult > AR0521_PLL_MAX * in calc_pll()
232 new_pll = div64_round_up(sensor->extclk_freq * (u64)new_mult, in calc_pll()
241 pll = div64_round(sensor->extclk_freq * (u64)mult, pre); in calc_pll()
250 unsigned int speed_mod = 4 / sensor->lane_count; /* 1 with 4 DDR lanes */ in ar0521_calc_mode()
251 u16 total_width = max(sensor->fmt.width + AR0521_WIDTH_BLANKING_MIN, in ar0521_calc_mode()
253 u16 total_height = sensor->fmt.height + AR0521_HEIGHT_BLANKING_MIN; in ar0521_calc_mode()
258 /* PLL1 drives pixel clock - dual rate */ in ar0521_calc_mode()
259 pix_clk = calc_pll(sensor, 1, pix_clk * (DIV / 2), &sensor->pll_pre, in ar0521_calc_mode()
260 &sensor->pll_mult); in ar0521_calc_mode()
262 calc_pll(sensor, 2, pix_clk * (DIV / 2) * speed_mod, &sensor->pll_pre2, in ar0521_calc_mode()
263 &sensor->pll_mult2); in ar0521_calc_mode()
265 sensor->total_width = total_width; in ar0521_calc_mode()
266 sensor->total_height = total_height; in ar0521_calc_mode()
275 /* 0x304 */ be((sensor->pll_pre2 << 8) | sensor->pll_pre), in ar0521_write_mode()
276 /* 0x306 */ be((sensor->pll_mult2 << 8) | sensor->pll_mult), in ar0521_write_mode()
297 sensor->ctrls.exposure->val); in ar0521_write_mode()
308 sensor->ctrls.test_pattern->val); in ar0521_write_mode()
317 ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); in ar0521_set_stream()
330 /* Exit LP-11 mode on clock and data lanes */ in ar0521_set_stream()
346 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_set_stream()
364 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_set_stream()
371 fmt->width = clamp(ALIGN(fmt->width, 4), AR0521_WIDTH_MIN, in ar0521_adj_fmt()
373 fmt->height = clamp(ALIGN(fmt->height, 4), AR0521_HEIGHT_MIN, in ar0521_adj_fmt()
375 fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; in ar0521_adj_fmt()
376 fmt->field = V4L2_FIELD_NONE; in ar0521_adj_fmt()
377 fmt->colorspace = V4L2_COLORSPACE_SRGB; in ar0521_adj_fmt()
378 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in ar0521_adj_fmt()
379 fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; in ar0521_adj_fmt()
380 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in ar0521_adj_fmt()
390 mutex_lock(&sensor->lock); in ar0521_get_fmt()
392 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in ar0521_get_fmt()
393 fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, 0 in ar0521_get_fmt()
396 fmt = &sensor->fmt; in ar0521_get_fmt()
398 format->format = *fmt; in ar0521_get_fmt()
400 mutex_unlock(&sensor->lock); in ar0521_get_fmt()
410 ar0521_adj_fmt(&format->format); in ar0521_set_fmt()
412 mutex_lock(&sensor->lock); in ar0521_set_fmt()
414 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { in ar0521_set_fmt()
418 *fmt = format->format; in ar0521_set_fmt()
420 sensor->fmt = format->format; in ar0521_set_fmt()
424 mutex_unlock(&sensor->lock); in ar0521_set_fmt()
436 switch (ctrl->id) { in ar0521_s_ctrl()
439 sensor->total_width = sensor->fmt.width + in ar0521_s_ctrl()
440 sensor->ctrls.hblank->val; in ar0521_s_ctrl()
441 sensor->total_height = sensor->fmt.width + in ar0521_s_ctrl()
442 sensor->ctrls.vblank->val; in ar0521_s_ctrl()
445 ret = -EINVAL; in ar0521_s_ctrl()
450 if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev)) in ar0521_s_ctrl()
453 switch (ctrl->id) { in ar0521_s_ctrl()
466 ctrl->val); in ar0521_s_ctrl()
470 ctrl->val); in ar0521_s_ctrl()
474 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_s_ctrl()
492 struct ar0521_ctrls *ctrls = &sensor->ctrls; in ar0521_init_controls()
493 struct v4l2_ctrl_handler *hdl = &ctrls->handler; in ar0521_init_controls()
499 hdl->lock = &sensor->lock; in ar0521_init_controls()
502 ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 511, 1, 0); in ar0521_init_controls()
503 ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE, in ar0521_init_controls()
504 -512, 511, 1, 0); in ar0521_init_controls()
505 ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE, in ar0521_init_controls()
506 -512, 511, 1, 0); in ar0521_init_controls()
507 v4l2_ctrl_cluster(3, &ctrls->gain); in ar0521_init_controls()
509 ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, in ar0521_init_controls()
512 ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK, in ar0521_init_controls()
515 v4l2_ctrl_cluster(2, &ctrls->hblank); in ar0521_init_controls()
517 /* Read-only */ in ar0521_init_controls()
518 ctrls->pixrate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE, in ar0521_init_controls()
524 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, in ar0521_init_controls()
527 ctrls->test_pattern = v4l2_ctrl_new_std_menu_items(hdl, ops, in ar0521_init_controls()
529 ARRAY_SIZE(test_pattern_menu) - 1, in ar0521_init_controls()
532 if (hdl->error) { in ar0521_init_controls()
533 ret = hdl->error; in ar0521_init_controls()
537 sensor->sd.ctrl_handler = hdl; in ar0521_init_controls()
552 REGS(be(0x0112), be(0x0808)), /* 8-bit/8-bit mode */
582 be(0x008B), /* 31B0: frame_preamble - FIXME check WRT lanes# */
583 be(0x0050)), /* 31B2: line_preamble - FIXME check WRT lanes# */
590 REGS(be(0x341A), be(0x4735)), /* Samp&Hold pulse in ADC */
591 REGS(be(0x3420), be(0x4735)), /* Samp&Hold pulse in ADC */
657 be(0x0086)), /* 3EBC: Bias currents for FSC/ECL */
668 /* 3ECE: Ramp buffer settings and Booster enable (bits 0-5) */
673 be(0x4081), /* 3ED6: Txlatch fr cfpn rows/vln bias */
718 clk_disable_unprepare(sensor->extclk); in ar0521_power_off()
720 if (sensor->reset_gpio) in ar0521_power_off()
721 gpiod_set_value(sensor->reset_gpio, 1); /* assert RESET signal */ in ar0521_power_off()
723 for (i = ARRAY_SIZE(ar0521_supply_names) - 1; i >= 0; i--) { in ar0521_power_off()
724 if (sensor->supplies[i]) in ar0521_power_off()
725 regulator_disable(sensor->supplies[i]); in ar0521_power_off()
738 if (sensor->supplies[cnt]) { in ar0521_power_on()
739 ret = regulator_enable(sensor->supplies[cnt]); in ar0521_power_on()
746 ret = clk_prepare_enable(sensor->extclk); in ar0521_power_on()
748 v4l2_err(&sensor->sd, "error enabling sensor clock\n"); in ar0521_power_on()
753 if (sensor->reset_gpio) in ar0521_power_on()
755 gpiod_set_value(sensor->reset_gpio, 0); in ar0521_power_on()
767 sensor->lane_count); in ar0521_power_on()
771 /* set MIPI test mode - disabled for now */ in ar0521_power_on()
773 ((0x40 << sensor->lane_count) - 0x40) | in ar0521_power_on()
779 4 / sensor->lane_count); in ar0521_power_on()
795 if (code->index) in ar0521_enum_mbus_code()
796 return -EINVAL; in ar0521_enum_mbus_code()
798 code->code = sensor->fmt.code; in ar0521_enum_mbus_code()
808 return -EACCES; in ar0521_pre_streamon()
810 ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); in ar0521_pre_streamon()
814 /* Set LP-11 on clock and data lanes */ in ar0521_pre_streamon()
820 /* Start streaming LP-11 */ in ar0521_pre_streamon()
829 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_pre_streamon()
837 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_post_streamoff()
846 mutex_lock(&sensor->lock); in ar0521_s_stream()
850 sensor->streaming = enable; in ar0521_s_stream()
852 mutex_unlock(&sensor->lock); in ar0521_s_stream()
883 if (sensor->streaming) in ar0521_suspend()
894 if (sensor->streaming) in ar0521_resume()
905 struct device *dev = &client->dev; in ar0521_probe()
913 return -ENOMEM; in ar0521_probe()
915 sensor->i2c_client = client; in ar0521_probe()
916 sensor->fmt.width = AR0521_WIDTH_MAX; in ar0521_probe()
917 sensor->fmt.height = AR0521_HEIGHT_MAX; in ar0521_probe()
923 return -EINVAL; in ar0521_probe()
934 dev_err(dev, "invalid bus type, must be MIPI CSI2\n"); in ar0521_probe()
935 return -EINVAL; in ar0521_probe()
938 sensor->lane_count = ep.bus.mipi_csi2.num_data_lanes; in ar0521_probe()
939 switch (sensor->lane_count) { in ar0521_probe()
946 return -EINVAL; in ar0521_probe()
950 sensor->extclk = devm_clk_get(dev, "extclk"); in ar0521_probe()
951 if (IS_ERR(sensor->extclk)) { in ar0521_probe()
953 return PTR_ERR(sensor->extclk); in ar0521_probe()
956 sensor->extclk_freq = clk_get_rate(sensor->extclk); in ar0521_probe()
958 if (sensor->extclk_freq < AR0521_EXTCLK_MIN || in ar0521_probe()
959 sensor->extclk_freq > AR0521_EXTCLK_MAX) { in ar0521_probe()
961 sensor->extclk_freq); in ar0521_probe()
962 return -EINVAL; in ar0521_probe()
966 sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset", in ar0521_probe()
969 v4l2_i2c_subdev_init(&sensor->sd, client, &ar0521_subdev_ops); in ar0521_probe()
971 sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in ar0521_probe()
972 sensor->pad.flags = MEDIA_PAD_FL_SOURCE; in ar0521_probe()
973 sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in ar0521_probe()
974 ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad); in ar0521_probe()
987 sensor->supplies[cnt] = supply; in ar0521_probe()
990 mutex_init(&sensor->lock); in ar0521_probe()
996 ar0521_adj_fmt(&sensor->fmt); in ar0521_probe()
998 ret = v4l2_async_register_subdev(&sensor->sd); in ar0521_probe()
1003 ret = ar0521_power_on(&client->dev); in ar0521_probe()
1006 pm_runtime_set_active(&client->dev); in ar0521_probe()
1007 pm_runtime_enable(&client->dev); in ar0521_probe()
1008 pm_runtime_idle(&client->dev); in ar0521_probe()
1012 v4l2_async_unregister_subdev(&sensor->sd); in ar0521_probe()
1013 media_entity_cleanup(&sensor->sd.entity); in ar0521_probe()
1015 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ar0521_probe()
1017 media_entity_cleanup(&sensor->sd.entity); in ar0521_probe()
1018 mutex_destroy(&sensor->lock); in ar0521_probe()
1027 v4l2_async_unregister_subdev(&sensor->sd); in ar0521_remove()
1028 media_entity_cleanup(&sensor->sd.entity); in ar0521_remove()
1029 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ar0521_remove()
1030 pm_runtime_disable(&client->dev); in ar0521_remove()
1031 if (!pm_runtime_status_suspended(&client->dev)) in ar0521_remove()
1032 ar0521_power_off(&client->dev); in ar0521_remove()
1033 pm_runtime_set_suspended(&client->dev); in ar0521_remove()
1034 mutex_destroy(&sensor->lock); in ar0521_remove()