Lines Matching full:sensor

3  * Omnivision OV2680 CMOS Image Sensor driver
7 * Based on OV5640 Sensor Driver
206 /* Sensor control register tweaks */
273 static void ov2680_power_up(struct ov2680_dev *sensor) in ov2680_power_up() argument
275 if (!sensor->pwdn_gpio) in ov2680_power_up()
278 gpiod_set_value(sensor->pwdn_gpio, 0); in ov2680_power_up()
282 static void ov2680_power_down(struct ov2680_dev *sensor) in ov2680_power_down() argument
284 if (!sensor->pwdn_gpio) in ov2680_power_down()
287 gpiod_set_value(sensor->pwdn_gpio, 1); in ov2680_power_down()
291 static void ov2680_set_bayer_order(struct ov2680_dev *sensor, in ov2680_set_bayer_order() argument
296 if (sensor->ctrls.vflip && sensor->ctrls.vflip->val) in ov2680_set_bayer_order()
299 if (sensor->ctrls.hflip && sensor->ctrls.hflip->val) in ov2680_set_bayer_order()
306 __ov2680_get_pad_format(struct ov2680_dev *sensor, in __ov2680_get_pad_format() argument
312 return v4l2_subdev_get_try_format(&sensor->sd, state, pad); in __ov2680_get_pad_format()
314 return &sensor->mode.fmt; in __ov2680_get_pad_format()
318 __ov2680_get_pad_crop(struct ov2680_dev *sensor, in __ov2680_get_pad_crop() argument
324 return v4l2_subdev_get_try_crop(&sensor->sd, state, pad); in __ov2680_get_pad_crop()
326 return &sensor->mode.crop; in __ov2680_get_pad_crop()
329 static void ov2680_fill_format(struct ov2680_dev *sensor, in ov2680_fill_format() argument
338 ov2680_set_bayer_order(sensor, fmt); in ov2680_fill_format()
341 static void ov2680_calc_mode(struct ov2680_dev *sensor) in ov2680_calc_mode() argument
343 int width = sensor->mode.fmt.width; in ov2680_calc_mode()
344 int height = sensor->mode.fmt.height; in ov2680_calc_mode()
348 if (width <= (sensor->mode.crop.width / 2) && in ov2680_calc_mode()
349 height <= (sensor->mode.crop.height / 2)) { in ov2680_calc_mode()
350 sensor->mode.binning = true; in ov2680_calc_mode()
354 sensor->mode.binning = false; in ov2680_calc_mode()
357 sensor->mode.h_start = (sensor->mode.crop.left + in ov2680_calc_mode()
358 (sensor->mode.crop.width - width) / 2) & ~1; in ov2680_calc_mode()
359 sensor->mode.v_start = (sensor->mode.crop.top + in ov2680_calc_mode()
360 (sensor->mode.crop.height - height) / 2) & ~1; in ov2680_calc_mode()
361 sensor->mode.h_end = in ov2680_calc_mode()
362 min(sensor->mode.h_start + width + OV2680_END_MARGIN - 1, in ov2680_calc_mode()
364 sensor->mode.v_end = in ov2680_calc_mode()
365 min(sensor->mode.v_start + height + OV2680_END_MARGIN - 1, in ov2680_calc_mode()
367 sensor->mode.h_output_size = orig_width; in ov2680_calc_mode()
368 sensor->mode.v_output_size = orig_height; in ov2680_calc_mode()
369 sensor->mode.hts = OV2680_PIXELS_PER_LINE; in ov2680_calc_mode()
370 sensor->mode.vts = OV2680_LINES_PER_FRAME; in ov2680_calc_mode()
373 static int ov2680_set_mode(struct ov2680_dev *sensor) in ov2680_set_mode() argument
378 if (sensor->mode.binning) { in ov2680_set_mode()
390 cci_write(sensor->regmap, OV2680_REG_SENSOR_CTRL_0A, in ov2680_set_mode()
392 cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_START, in ov2680_set_mode()
393 sensor->mode.h_start, &ret); in ov2680_set_mode()
394 cci_write(sensor->regmap, OV2680_REG_VERTICAL_START, in ov2680_set_mode()
395 sensor->mode.v_start, &ret); in ov2680_set_mode()
396 cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_END, in ov2680_set_mode()
397 sensor->mode.h_end, &ret); in ov2680_set_mode()
398 cci_write(sensor->regmap, OV2680_REG_VERTICAL_END, in ov2680_set_mode()
399 sensor->mode.v_end, &ret); in ov2680_set_mode()
400 cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_OUTPUT_SIZE, in ov2680_set_mode()
401 sensor->mode.h_output_size, &ret); in ov2680_set_mode()
402 cci_write(sensor->regmap, OV2680_REG_VERTICAL_OUTPUT_SIZE, in ov2680_set_mode()
403 sensor->mode.v_output_size, &ret); in ov2680_set_mode()
404 cci_write(sensor->regmap, OV2680_REG_TIMING_HTS, in ov2680_set_mode()
405 sensor->mode.hts, &ret); in ov2680_set_mode()
406 cci_write(sensor->regmap, OV2680_REG_TIMING_VTS, in ov2680_set_mode()
407 sensor->mode.vts, &ret); in ov2680_set_mode()
408 cci_write(sensor->regmap, OV2680_REG_ISP_X_WIN, 0, &ret); in ov2680_set_mode()
409 cci_write(sensor->regmap, OV2680_REG_ISP_Y_WIN, 0, &ret); in ov2680_set_mode()
410 cci_write(sensor->regmap, OV2680_REG_X_INC, inc, &ret); in ov2680_set_mode()
411 cci_write(sensor->regmap, OV2680_REG_Y_INC, inc, &ret); in ov2680_set_mode()
412 cci_write(sensor->regmap, OV2680_REG_X_WIN, in ov2680_set_mode()
413 sensor->mode.h_output_size, &ret); in ov2680_set_mode()
414 cci_write(sensor->regmap, OV2680_REG_Y_WIN, in ov2680_set_mode()
415 sensor->mode.v_output_size, &ret); in ov2680_set_mode()
416 cci_write(sensor->regmap, OV2680_REG_FORMAT1, fmt1, &ret); in ov2680_set_mode()
417 cci_write(sensor->regmap, OV2680_REG_FORMAT2, fmt2, &ret); in ov2680_set_mode()
422 static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) in ov2680_set_vflip() argument
426 if (sensor->is_streaming) in ov2680_set_vflip()
429 ret = cci_update_bits(sensor->regmap, OV2680_REG_FORMAT1, in ov2680_set_vflip()
434 ov2680_set_bayer_order(sensor, &sensor->mode.fmt); in ov2680_set_vflip()
438 static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) in ov2680_set_hflip() argument
442 if (sensor->is_streaming) in ov2680_set_hflip()
445 ret = cci_update_bits(sensor->regmap, OV2680_REG_FORMAT2, in ov2680_set_hflip()
450 ov2680_set_bayer_order(sensor, &sensor->mode.fmt); in ov2680_set_hflip()
454 static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) in ov2680_test_pattern_set() argument
459 return cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, in ov2680_test_pattern_set()
462 cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, in ov2680_test_pattern_set()
464 cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, in ov2680_test_pattern_set()
470 static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain) in ov2680_gain_set() argument
472 return cci_write(sensor->regmap, OV2680_REG_GAIN_PK, gain, NULL); in ov2680_gain_set()
475 static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) in ov2680_exposure_set() argument
477 return cci_write(sensor->regmap, OV2680_REG_EXPOSURE_PK, exp << 4, in ov2680_exposure_set()
481 static int ov2680_stream_enable(struct ov2680_dev *sensor) in ov2680_stream_enable() argument
485 ret = cci_write(sensor->regmap, OV2680_REG_PLL_MULTIPLIER, in ov2680_stream_enable()
486 sensor->pll_mult, NULL); in ov2680_stream_enable()
490 ret = regmap_multi_reg_write(sensor->regmap, in ov2680_stream_enable()
496 ret = ov2680_set_mode(sensor); in ov2680_stream_enable()
501 ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); in ov2680_stream_enable()
505 return cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 1, NULL); in ov2680_stream_enable()
508 static int ov2680_stream_disable(struct ov2680_dev *sensor) in ov2680_stream_disable() argument
510 return cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 0, NULL); in ov2680_stream_disable()
513 static int ov2680_power_off(struct ov2680_dev *sensor) in ov2680_power_off() argument
515 clk_disable_unprepare(sensor->xvclk); in ov2680_power_off()
516 ov2680_power_down(sensor); in ov2680_power_off()
517 regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies); in ov2680_power_off()
521 static int ov2680_power_on(struct ov2680_dev *sensor) in ov2680_power_on() argument
525 ret = regulator_bulk_enable(OV2680_NUM_SUPPLIES, sensor->supplies); in ov2680_power_on()
527 dev_err(sensor->dev, "failed to enable regulators: %d\n", ret); in ov2680_power_on()
531 if (!sensor->pwdn_gpio) { in ov2680_power_on()
532 ret = cci_write(sensor->regmap, OV2680_REG_SOFT_RESET, 0x01, in ov2680_power_on()
535 dev_err(sensor->dev, "sensor soft reset failed\n"); in ov2680_power_on()
540 ov2680_power_down(sensor); in ov2680_power_on()
541 ov2680_power_up(sensor); in ov2680_power_on()
544 ret = clk_prepare_enable(sensor->xvclk); in ov2680_power_on()
551 regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies); in ov2680_power_on()
558 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_s_g_frame_interval() local
560 mutex_lock(&sensor->lock); in ov2680_s_g_frame_interval()
561 fi->interval = sensor->mode.frame_interval; in ov2680_s_g_frame_interval()
562 mutex_unlock(&sensor->lock); in ov2680_s_g_frame_interval()
569 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_s_stream() local
572 mutex_lock(&sensor->lock); in ov2680_s_stream()
574 if (sensor->is_streaming == !!enable) in ov2680_s_stream()
578 ret = pm_runtime_resume_and_get(sensor->sd.dev); in ov2680_s_stream()
582 ret = ov2680_stream_enable(sensor); in ov2680_s_stream()
584 pm_runtime_put(sensor->sd.dev); in ov2680_s_stream()
588 ret = ov2680_stream_disable(sensor); in ov2680_s_stream()
589 pm_runtime_put(sensor->sd.dev); in ov2680_s_stream()
592 sensor->is_streaming = !!enable; in ov2680_s_stream()
595 mutex_unlock(&sensor->lock); in ov2680_s_stream()
604 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_enum_mbus_code() local
609 code->code = sensor->mode.fmt.code; in ov2680_enum_mbus_code()
618 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_get_fmt() local
621 fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, in ov2680_get_fmt()
624 mutex_lock(&sensor->lock); in ov2680_get_fmt()
626 mutex_unlock(&sensor->lock); in ov2680_get_fmt()
635 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_set_fmt() local
641 crop = __ov2680_get_pad_crop(sensor, sd_state, format->pad, in ov2680_set_fmt()
650 ov2680_fill_format(sensor, &format->format, width, height); in ov2680_set_fmt()
658 mutex_lock(&sensor->lock); in ov2680_set_fmt()
660 if (sensor->is_streaming) { in ov2680_set_fmt()
665 sensor->mode.fmt = format->format; in ov2680_set_fmt()
666 ov2680_calc_mode(sensor); in ov2680_set_fmt()
669 mutex_unlock(&sensor->lock); in ov2680_set_fmt()
678 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_get_selection() local
682 mutex_lock(&sensor->lock); in ov2680_get_selection()
683 sel->r = *__ov2680_get_pad_crop(sensor, state, sel->pad, in ov2680_get_selection()
685 mutex_unlock(&sensor->lock); in ov2680_get_selection()
708 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_set_selection() local
717 * Clamp the boundaries of the crop rectangle to the size of the sensor in ov2680_set_selection()
736 crop = __ov2680_get_pad_crop(sensor, state, sel->pad, sel->which); in ov2680_set_selection()
738 mutex_lock(&sensor->lock); in ov2680_set_selection()
744 format = __ov2680_get_pad_format(sensor, state, sel->pad, in ov2680_set_selection()
751 mutex_unlock(&sensor->lock); in ov2680_set_selection()
761 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_init_cfg() local
765 ov2680_fill_format(sensor, &sd_state->pads[0].try_fmt, in ov2680_init_cfg()
774 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_enum_frame_size() local
780 crop = __ov2680_get_pad_crop(sensor, sd_state, fse->pad, fse->which); in ov2680_enum_frame_size()
820 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_enum_frame_interval() local
826 fie->interval = sensor->mode.frame_interval; in ov2680_enum_frame_interval()
834 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_s_ctrl() local
838 if (!pm_runtime_get_if_in_use(sensor->sd.dev)) { in ov2680_s_ctrl()
839 ov2680_set_bayer_order(sensor, &sensor->mode.fmt); in ov2680_s_ctrl()
845 ret = ov2680_gain_set(sensor, ctrl->val); in ov2680_s_ctrl()
848 ret = ov2680_exposure_set(sensor, ctrl->val); in ov2680_s_ctrl()
851 ret = ov2680_set_vflip(sensor, ctrl->val); in ov2680_s_ctrl()
854 ret = ov2680_set_hflip(sensor, ctrl->val); in ov2680_s_ctrl()
857 ret = ov2680_test_pattern_set(sensor, ctrl->val); in ov2680_s_ctrl()
864 pm_runtime_put(sensor->sd.dev); in ov2680_s_ctrl()
894 static int ov2680_mode_init(struct ov2680_dev *sensor) in ov2680_mode_init() argument
897 sensor->mode.crop = ov2680_default_crop; in ov2680_mode_init()
898 ov2680_fill_format(sensor, &sensor->mode.fmt, in ov2680_mode_init()
900 ov2680_calc_mode(sensor); in ov2680_mode_init()
902 sensor->mode.frame_interval.denominator = OV2680_FRAME_RATE; in ov2680_mode_init()
903 sensor->mode.frame_interval.numerator = 1; in ov2680_mode_init()
908 static int ov2680_v4l2_register(struct ov2680_dev *sensor) in ov2680_v4l2_register() argument
910 struct i2c_client *client = to_i2c_client(sensor->dev); in ov2680_v4l2_register()
912 struct ov2680_ctrls *ctrls = &sensor->ctrls; in ov2680_v4l2_register()
917 v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_subdev_ops); in ov2680_v4l2_register()
919 sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in ov2680_v4l2_register()
920 sensor->pad.flags = MEDIA_PAD_FL_SOURCE; in ov2680_v4l2_register()
921 sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov2680_v4l2_register()
923 ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad); in ov2680_v4l2_register()
929 hdl->lock = &sensor->lock; in ov2680_v4l2_register()
946 0, 0, sensor->link_freq); in ov2680_v4l2_register()
948 0, sensor->pixel_rate, in ov2680_v4l2_register()
949 1, sensor->pixel_rate); in ov2680_v4l2_register()
960 sensor->sd.ctrl_handler = hdl; in ov2680_v4l2_register()
962 ret = v4l2_async_register_subdev(&sensor->sd); in ov2680_v4l2_register()
969 media_entity_cleanup(&sensor->sd.entity); in ov2680_v4l2_register()
975 static int ov2680_get_regulators(struct ov2680_dev *sensor) in ov2680_get_regulators() argument
980 sensor->supplies[i].supply = ov2680_supply_name[i]; in ov2680_get_regulators()
982 return devm_regulator_bulk_get(sensor->dev, in ov2680_get_regulators()
983 OV2680_NUM_SUPPLIES, sensor->supplies); in ov2680_get_regulators()
986 static int ov2680_check_id(struct ov2680_dev *sensor) in ov2680_check_id() argument
991 cci_read(sensor->regmap, OV2680_REG_CHIP_ID, &chip_id, &ret); in ov2680_check_id()
992 cci_read(sensor->regmap, OV2680_REG_SC_CMMN_SUB_ID, &rev, &ret); in ov2680_check_id()
994 dev_err(sensor->dev, "failed to read chip id\n"); in ov2680_check_id()
999 dev_err(sensor->dev, "chip id: 0x%04llx does not match expected 0x%04x\n", in ov2680_check_id()
1004 dev_info(sensor->dev, "sensor_revision id = 0x%llx, rev= %lld\n", in ov2680_check_id()
1010 static int ov2680_parse_dt(struct ov2680_dev *sensor) in ov2680_parse_dt() argument
1015 struct device *dev = sensor->dev; in ov2680_parse_dt()
1036 * The pin we want is named XSHUTDN in the datasheet. Linux sensor in ov2680_parse_dt()
1051 sensor->pwdn_gpio = gpio; in ov2680_parse_dt()
1053 sensor->xvclk = devm_clk_get_optional(dev, "xvclk"); in ov2680_parse_dt()
1054 if (IS_ERR(sensor->xvclk)) { in ov2680_parse_dt()
1055 ret = dev_err_probe(dev, PTR_ERR(sensor->xvclk), in ov2680_parse_dt()
1071 if (ret && !sensor->xvclk) { in ov2680_parse_dt()
1076 if (!ret && sensor->xvclk) { in ov2680_parse_dt()
1077 ret = clk_set_rate(sensor->xvclk, rate); in ov2680_parse_dt()
1084 sensor->xvclk_freq = rate ?: clk_get_rate(sensor->xvclk); in ov2680_parse_dt()
1087 if (sensor->xvclk_freq == ov2680_xvclk_freqs[i]) in ov2680_parse_dt()
1094 sensor->xvclk_freq); in ov2680_parse_dt()
1098 sensor->pll_mult = ov2680_pll_multipliers[i]; in ov2680_parse_dt()
1100 sensor->link_freq[0] = sensor->xvclk_freq / OV2680_PLL_PREDIV0 / in ov2680_parse_dt()
1101 OV2680_PLL_PREDIV * sensor->pll_mult; in ov2680_parse_dt()
1104 sensor->pixel_rate = sensor->link_freq[0] * 2; in ov2680_parse_dt()
1105 do_div(sensor->pixel_rate, 10); in ov2680_parse_dt()
1113 if (bus_cfg.link_frequencies[i] == sensor->link_freq[0]) in ov2680_parse_dt()
1119 sensor->link_freq[0]); in ov2680_parse_dt()
1133 struct ov2680_dev *sensor; in ov2680_probe() local
1136 sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); in ov2680_probe()
1137 if (!sensor) in ov2680_probe()
1140 sensor->dev = &client->dev; in ov2680_probe()
1142 sensor->regmap = devm_cci_regmap_init_i2c(client, 16); in ov2680_probe()
1143 if (IS_ERR(sensor->regmap)) in ov2680_probe()
1144 return PTR_ERR(sensor->regmap); in ov2680_probe()
1146 ret = ov2680_parse_dt(sensor); in ov2680_probe()
1150 ret = ov2680_mode_init(sensor); in ov2680_probe()
1154 ret = ov2680_get_regulators(sensor); in ov2680_probe()
1160 mutex_init(&sensor->lock); in ov2680_probe()
1166 ret = ov2680_power_on(sensor); in ov2680_probe()
1170 ret = ov2680_check_id(sensor); in ov2680_probe()
1178 ret = ov2680_v4l2_register(sensor); in ov2680_probe()
1192 ov2680_power_off(sensor); in ov2680_probe()
1195 mutex_destroy(&sensor->lock); in ov2680_probe()
1203 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_remove() local
1205 v4l2_async_unregister_subdev(&sensor->sd); in ov2680_remove()
1206 mutex_destroy(&sensor->lock); in ov2680_remove()
1207 media_entity_cleanup(&sensor->sd.entity); in ov2680_remove()
1208 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ov2680_remove()
1216 ov2680_power_off(sensor); in ov2680_remove()
1223 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_suspend() local
1225 if (sensor->is_streaming) in ov2680_suspend()
1226 ov2680_stream_disable(sensor); in ov2680_suspend()
1228 return ov2680_power_off(sensor); in ov2680_suspend()
1234 struct ov2680_dev *sensor = to_ov2680_dev(sd); in ov2680_resume() local
1237 ret = ov2680_power_on(sensor); in ov2680_resume()
1241 if (sensor->is_streaming) { in ov2680_resume()
1242 ret = ov2680_stream_enable(sensor); in ov2680_resume()
1250 ov2680_stream_disable(sensor); in ov2680_resume()
1251 sensor->is_streaming = false; in ov2680_resume()
1284 MODULE_DESCRIPTION("OV2680 CMOS Image Sensor driver");