Lines Matching full:sensor
159 static int ar0521_code_to_bpp(struct ar0521_dev *sensor) in ar0521_code_to_bpp() argument
161 switch (sensor->fmt.code) { in ar0521_code_to_bpp()
170 static int ar0521_write_regs(struct ar0521_dev *sensor, const __be16 *data, in ar0521_write_regs() argument
173 struct i2c_client *client = sensor->i2c_client; in ar0521_write_regs()
185 v4l2_err(&sensor->sd, "%s: I2C write error\n", __func__); in ar0521_write_regs()
192 static int ar0521_write_reg(struct ar0521_dev *sensor, u16 reg, u16 val) in ar0521_write_reg() argument
196 return ar0521_write_regs(sensor, buf, 2); in ar0521_write_reg()
199 static int ar0521_set_geometry(struct ar0521_dev *sensor) in ar0521_set_geometry() argument
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()
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()
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()
220 return ar0521_write_regs(sensor, regs, ARRAY_SIZE(regs)); in ar0521_set_geometry()
223 static int ar0521_set_gains(struct ar0521_dev *sensor) in ar0521_set_gains() argument
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()
241 return ar0521_write_regs(sensor, regs, ARRAY_SIZE(regs)); in ar0521_set_gains()
244 static u32 calc_pll(struct ar0521_dev *sensor, u32 freq, u16 *pre_ptr, u16 *mult_ptr) in calc_pll() argument
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()
279 static void ar0521_calc_pll(struct ar0521_dev *sensor) in ar0521_calc_pll() argument
332 pixel_clock = AR0521_PIXEL_CLOCK_RATE * 2 / sensor->lane_count; in ar0521_calc_pll()
333 bpp = ar0521_code_to_bpp(sensor); 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()
337 calc_pll(sensor, vco, &pre, &mult); 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()
343 static int ar0521_pll_config(struct ar0521_dev *sensor) in ar0521_pll_config() argument
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()
355 ar0521_calc_pll(sensor); in ar0521_pll_config()
356 return ar0521_write_regs(sensor, pll_regs, ARRAY_SIZE(pll_regs)); in ar0521_pll_config()
359 static int ar0521_set_stream(struct ar0521_dev *sensor, bool on) in ar0521_set_stream() argument
364 ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); in ar0521_set_stream()
369 ret = ar0521_write_reg(sensor, AR0521_REG_RESET, in ar0521_set_stream()
374 ret = ar0521_set_geometry(sensor); in ar0521_set_stream()
378 ret = ar0521_pll_config(sensor); in ar0521_set_stream()
382 ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); in ar0521_set_stream()
387 ret = ar0521_write_reg(sensor, AR0521_REG_HISPI_CONTROL_STATUS, in ar0521_set_stream()
393 ret = ar0521_write_reg(sensor, AR0521_REG_RESET, in ar0521_set_stream()
402 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_set_stream()
407 * Reset gain, the sensor may produce all white pixels without in ar0521_set_stream()
410 ret = ar0521_write_reg(sensor, AR0521_REG_GLOBAL_GAIN, 0x2000); in ar0521_set_stream()
415 ret = ar0521_write_reg(sensor, AR0521_REG_RESET, in ar0521_set_stream()
420 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_set_stream()
443 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_get_fmt() local
446 mutex_lock(&sensor->lock); in ar0521_get_fmt()
451 fmt = &sensor->fmt; in ar0521_get_fmt()
455 mutex_unlock(&sensor->lock); in ar0521_get_fmt()
463 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_set_fmt() local
469 mutex_lock(&sensor->lock); in ar0521_set_fmt()
477 mutex_unlock(&sensor->lock); in ar0521_set_fmt()
482 sensor->fmt = format->format; in ar0521_set_fmt()
483 ar0521_calc_pll(sensor); 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()
530 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_s_ctrl() local
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()
546 /* access the sensor only if it's powered up */ in ar0521_s_ctrl()
547 if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev)) in ar0521_s_ctrl()
553 ret = ar0521_set_geometry(sensor); in ar0521_s_ctrl()
556 ret = ar0521_write_reg(sensor, AR0521_REG_ANA_GAIN_CODE_GLOBAL, in ar0521_s_ctrl()
562 ret = ar0521_set_gains(sensor); in ar0521_s_ctrl()
565 ret = ar0521_write_reg(sensor, in ar0521_s_ctrl()
570 ret = ar0521_write_reg(sensor, AR0521_REG_TEST_PATTERN_MODE, in ar0521_s_ctrl()
574 dev_err(&sensor->i2c_client->dev, in ar0521_s_ctrl()
580 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_s_ctrl()
595 static int ar0521_init_controls(struct ar0521_dev *sensor) in ar0521_init_controls() argument
598 struct ar0521_ctrls *ctrls = &sensor->ctrls; in ar0521_init_controls()
607 hdl->lock = &sensor->lock; in ar0521_init_controls()
663 sensor->sd.ctrl_handler = hdl; in ar0521_init_controls()
841 struct ar0521_dev *sensor = to_ar0521_dev(sd); in __ar0521_power_off() local
844 if (sensor->reset_gpio) in __ar0521_power_off()
846 gpiod_set_value_cansleep(sensor->reset_gpio, 1); in __ar0521_power_off()
849 if (sensor->supplies[i]) in __ar0521_power_off()
850 regulator_disable(sensor->supplies[i]); in __ar0521_power_off()
857 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_power_off() local
859 clk_disable_unprepare(sensor->extclk); in ar0521_power_off()
868 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_power_on() local
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()
894 ret = ar0521_write_regs(sensor, initial_regs[cnt].data, in ar0521_power_on()
900 ret = ar0521_write_reg(sensor, AR0521_REG_SERIAL_FORMAT, in ar0521_power_on()
902 sensor->lane_count); in ar0521_power_on()
907 ret = ar0521_write_reg(sensor, AR0521_REG_HISPI_TEST_MODE, in ar0521_power_on()
908 ((0x40 << sensor->lane_count) - 0x40) | in ar0521_power_on()
913 ret = ar0521_write_reg(sensor, AR0521_REG_ROW_SPEED, 0x110 | in ar0521_power_on()
914 4 / sensor->lane_count); in ar0521_power_on()
920 clk_disable_unprepare(sensor->extclk); in ar0521_power_on()
929 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_enum_mbus_code() local
934 code->code = sensor->fmt.code; in ar0521_enum_mbus_code()
958 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_pre_streamon() local
964 ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); in ar0521_pre_streamon()
969 ret = ar0521_write_reg(sensor, AR0521_REG_HISPI_CONTROL_STATUS, in ar0521_pre_streamon()
975 ret = ar0521_write_reg(sensor, AR0521_REG_RESET, in ar0521_pre_streamon()
983 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_pre_streamon()
989 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_post_streamoff() local
991 pm_runtime_put(&sensor->i2c_client->dev); in ar0521_post_streamoff()
997 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_s_stream() local
1000 mutex_lock(&sensor->lock); in ar0521_s_stream()
1001 ret = ar0521_set_stream(sensor, enable); in ar0521_s_stream()
1002 mutex_unlock(&sensor->lock); in ar0521_s_stream()
1037 struct ar0521_dev *sensor; in ar0521_probe() local
1041 sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); in ar0521_probe()
1042 if (!sensor) 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()
1068 sensor->lane_count = ep.bus.mipi_csi2.num_data_lanes; in ar0521_probe()
1069 switch (sensor->lane_count) { 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()
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()
1122 ret = ar0521_init_controls(sensor); in ar0521_probe()
1126 ar0521_adj_fmt(&sensor->fmt); in ar0521_probe()
1128 ret = v4l2_async_register_subdev(&sensor->sd); 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()
1155 struct ar0521_dev *sensor = to_ar0521_dev(sd); in ar0521_remove() local
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()
1164 mutex_destroy(&sensor->lock); in ar0521_remove()