Lines Matching refs:ov965x
248 struct ov965x { struct
417 return &container_of(ctrl->handler, struct ov965x, ctrls.handler)->sd; in ctrl_to_sd()
420 static inline struct ov965x *to_ov965x(struct v4l2_subdev *sd) in to_ov965x()
422 return container_of(sd, struct ov965x, sd); in to_ov965x()
425 static int ov965x_read(struct ov965x *ov965x, u8 addr, u8 *val) in ov965x_read() argument
430 ret = regmap_read(ov965x->regmap, addr, &buf); in ov965x_read()
436 v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02x. (%d)\n", in ov965x_read()
442 static int ov965x_write(struct ov965x *ov965x, u8 addr, u8 val) in ov965x_write() argument
446 ret = regmap_write(ov965x->regmap, addr, val); in ov965x_write()
448 v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02X (%d)\n", in ov965x_write()
454 static int ov965x_write_array(struct ov965x *ov965x, in ov965x_write_array() argument
460 ret = ov965x_write(ov965x, regs[i].addr, regs[i].value); in ov965x_write_array()
465 static int ov965x_set_default_gamma_curve(struct ov965x *ov965x) in ov965x_set_default_gamma_curve() argument
478 int ret = ov965x_write(ov965x, addr, gamma_curve[i]); in ov965x_set_default_gamma_curve()
488 static int ov965x_set_color_matrix(struct ov965x *ov965x) in ov965x_set_color_matrix() argument
498 int ret = ov965x_write(ov965x, addr, mtx[i]); in ov965x_set_color_matrix()
508 static int __ov965x_set_power(struct ov965x *ov965x, int on) in __ov965x_set_power() argument
511 int ret = clk_prepare_enable(ov965x->clk); in __ov965x_set_power()
516 gpiod_set_value_cansleep(ov965x->gpios[GPIO_PWDN], 0); in __ov965x_set_power()
517 gpiod_set_value_cansleep(ov965x->gpios[GPIO_RST], 0); in __ov965x_set_power()
520 gpiod_set_value_cansleep(ov965x->gpios[GPIO_RST], 1); in __ov965x_set_power()
521 gpiod_set_value_cansleep(ov965x->gpios[GPIO_PWDN], 1); in __ov965x_set_power()
523 clk_disable_unprepare(ov965x->clk); in __ov965x_set_power()
526 ov965x->streaming = 0; in __ov965x_set_power()
533 struct ov965x *ov965x = to_ov965x(sd); in ov965x_s_power() local
538 mutex_lock(&ov965x->lock); in ov965x_s_power()
539 if (ov965x->power == !on) { in ov965x_s_power()
540 ret = __ov965x_set_power(ov965x, on); in ov965x_s_power()
542 ret = ov965x_write_array(ov965x, in ov965x_s_power()
544 ov965x->apply_frame_fmt = 1; in ov965x_s_power()
545 ov965x->ctrls.update = 1; in ov965x_s_power()
549 ov965x->power += on ? 1 : -1; in ov965x_s_power()
551 WARN_ON(ov965x->power < 0); in ov965x_s_power()
552 mutex_unlock(&ov965x->lock); in ov965x_s_power()
560 static void ov965x_update_exposure_ctrl(struct ov965x *ov965x) in ov965x_update_exposure_ctrl() argument
562 struct v4l2_ctrl *ctrl = ov965x->ctrls.exposure; in ov965x_update_exposure_ctrl()
567 mutex_lock(&ov965x->lock); in ov965x_update_exposure_ctrl()
568 if (WARN_ON(!ctrl || !ov965x->frame_size)) { in ov965x_update_exposure_ctrl()
569 mutex_unlock(&ov965x->lock); in ov965x_update_exposure_ctrl()
572 clkrc = DEF_CLKRC + ov965x->fiv->clkrc_div; in ov965x_update_exposure_ctrl()
574 fint = ov965x->mclk_frequency * ((clkrc >> 7) + 1) / in ov965x_update_exposure_ctrl()
578 max = ov965x->frame_size->max_exp_lines * trow; in ov965x_update_exposure_ctrl()
579 ov965x->exp_row_interval = trow; in ov965x_update_exposure_ctrl()
580 mutex_unlock(&ov965x->lock); in ov965x_update_exposure_ctrl()
582 v4l2_dbg(1, debug, &ov965x->sd, "clkrc: %#x, fi: %lu, tr: %lu, %d\n", in ov965x_update_exposure_ctrl()
591 v4l2_err(&ov965x->sd, "Exposure ctrl range update failed\n"); in ov965x_update_exposure_ctrl()
594 static int ov965x_set_banding_filter(struct ov965x *ov965x, int value) in ov965x_set_banding_filter() argument
600 ret = ov965x_read(ov965x, REG_COM8, ®); in ov965x_set_banding_filter()
606 ret = ov965x_write(ov965x, REG_COM8, reg); in ov965x_set_banding_filter()
610 if (WARN_ON(!ov965x->fiv)) in ov965x_set_banding_filter()
617 mbd = (1000UL * ov965x->fiv->interval.denominator * in ov965x_set_banding_filter()
618 ov965x->frame_size->max_exp_lines) / in ov965x_set_banding_filter()
619 ov965x->fiv->interval.numerator; in ov965x_set_banding_filter()
622 return ov965x_write(ov965x, REG_MBD, mbd); in ov965x_set_banding_filter()
625 static int ov965x_set_white_balance(struct ov965x *ov965x, int awb) in ov965x_set_white_balance() argument
630 ret = ov965x_read(ov965x, REG_COM8, ®); in ov965x_set_white_balance()
633 ret = ov965x_write(ov965x, REG_COM8, reg); in ov965x_set_white_balance()
636 ret = ov965x_write(ov965x, REG_BLUE, in ov965x_set_white_balance()
637 ov965x->ctrls.blue_balance->val); in ov965x_set_white_balance()
640 ret = ov965x_write(ov965x, REG_RED, in ov965x_set_white_balance()
641 ov965x->ctrls.red_balance->val); in ov965x_set_white_balance()
649 static int ov965x_set_brightness(struct ov965x *ov965x, int val) in ov965x_set_brightness() argument
668 ret = ov965x_write(ov965x, regs[0][i], in ov965x_set_brightness()
673 static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain) in ov965x_set_gain() argument
675 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in ov965x_set_gain()
683 ret = ov965x_read(ov965x, REG_COM8, ®); in ov965x_set_gain()
690 ret = ov965x_write(ov965x, REG_COM8, reg); in ov965x_set_gain()
714 ret = ov965x_write(ov965x, REG_GAIN, rgain & 0xff); in ov965x_set_gain()
717 ret = ov965x_read(ov965x, REG_VREF, ®); in ov965x_set_gain()
722 ret = ov965x_write(ov965x, REG_VREF, reg); in ov965x_set_gain()
732 static int ov965x_set_sharpness(struct ov965x *ov965x, unsigned int value) in ov965x_set_sharpness() argument
737 ret = ov965x_read(ov965x, REG_COM14, &com14); in ov965x_set_sharpness()
740 ret = ov965x_read(ov965x, REG_EDGE, &edge); in ov965x_set_sharpness()
751 ret = ov965x_write(ov965x, REG_COM14, com14); in ov965x_set_sharpness()
758 return ov965x_write(ov965x, REG_EDGE, edge); in ov965x_set_sharpness()
761 static int ov965x_set_exposure(struct ov965x *ov965x, int exp) in ov965x_set_exposure() argument
763 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in ov965x_set_exposure()
769 ret = ov965x_read(ov965x, REG_COM8, ®); in ov965x_set_exposure()
776 ret = ov965x_write(ov965x, REG_COM8, reg); in ov965x_set_exposure()
783 / ov965x->exp_row_interval; in ov965x_set_exposure()
788 ret = ov965x_write(ov965x, REG_COM1, exposure & 0x3); in ov965x_set_exposure()
790 ret = ov965x_write(ov965x, REG_AECH, in ov965x_set_exposure()
793 ret = ov965x_write(ov965x, REG_AECHM, in ov965x_set_exposure()
796 ctrls->exposure->val = ((exposure * ov965x->exp_row_interval) in ov965x_set_exposure()
802 v4l2_ctrl_activate(ov965x->ctrls.brightness, !exp); in ov965x_set_exposure()
806 static int ov965x_set_flip(struct ov965x *ov965x) in ov965x_set_flip() argument
810 if (ov965x->ctrls.hflip->val) in ov965x_set_flip()
813 if (ov965x->ctrls.vflip->val) in ov965x_set_flip()
816 return ov965x_write(ov965x, REG_MVFP, mvfp); in ov965x_set_flip()
822 static int ov965x_set_saturation(struct ov965x *ov965x, int val) in ov965x_set_saturation() argument
840 ret = ov965x_write(ov965x, addr + i, regs[val][i]); in ov965x_set_saturation()
845 static int ov965x_set_test_pattern(struct ov965x *ov965x, int value) in ov965x_set_test_pattern() argument
850 ret = ov965x_read(ov965x, REG_COM23, ®); in ov965x_set_test_pattern()
854 return ov965x_write(ov965x, REG_COM23, reg); in ov965x_set_test_pattern()
857 static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl) in __g_volatile_ctrl() argument
863 if (!ov965x->power) in __g_volatile_ctrl()
870 ret = ov965x_read(ov965x, REG_GAIN, ®0); in __g_volatile_ctrl()
873 ret = ov965x_read(ov965x, REG_VREF, ®1); in __g_volatile_ctrl()
878 ov965x->ctrls.gain->val = m * (16 + (gain & 0xf)); in __g_volatile_ctrl()
884 ret = ov965x_read(ov965x, REG_COM1, ®0); in __g_volatile_ctrl()
887 ret = ov965x_read(ov965x, REG_AECH, ®1); in __g_volatile_ctrl()
890 ret = ov965x_read(ov965x, REG_AECHM, ®2); in __g_volatile_ctrl()
895 ov965x->ctrls.exposure->val = ((exposure * in __g_volatile_ctrl()
896 ov965x->exp_row_interval) + 50) / 100; in __g_volatile_ctrl()
906 struct ov965x *ov965x = to_ov965x(sd); in ov965x_g_volatile_ctrl() local
911 mutex_lock(&ov965x->lock); in ov965x_g_volatile_ctrl()
912 ret = __g_volatile_ctrl(ov965x, ctrl); in ov965x_g_volatile_ctrl()
913 mutex_unlock(&ov965x->lock); in ov965x_g_volatile_ctrl()
920 struct ov965x *ov965x = to_ov965x(sd); in ov965x_s_ctrl() local
924 ctrl->name, ctrl->val, ov965x->power); in ov965x_s_ctrl()
926 mutex_lock(&ov965x->lock); in ov965x_s_ctrl()
931 if (ov965x->power == 0) { in ov965x_s_ctrl()
932 mutex_unlock(&ov965x->lock); in ov965x_s_ctrl()
938 ret = ov965x_set_white_balance(ov965x, ctrl->val); in ov965x_s_ctrl()
942 ret = ov965x_set_brightness(ov965x, ctrl->val); in ov965x_s_ctrl()
946 ret = ov965x_set_exposure(ov965x, ctrl->val); in ov965x_s_ctrl()
950 ret = ov965x_set_gain(ov965x, ctrl->val); in ov965x_s_ctrl()
954 ret = ov965x_set_flip(ov965x); in ov965x_s_ctrl()
958 ret = ov965x_set_banding_filter(ov965x, ctrl->val); in ov965x_s_ctrl()
962 ret = ov965x_set_saturation(ov965x, ctrl->val); in ov965x_s_ctrl()
966 ret = ov965x_set_sharpness(ov965x, ctrl->val); in ov965x_s_ctrl()
970 ret = ov965x_set_test_pattern(ov965x, ctrl->val); in ov965x_s_ctrl()
974 mutex_unlock(&ov965x->lock); in ov965x_s_ctrl()
988 static int ov965x_initialize_controls(struct ov965x *ov965x) in ov965x_initialize_controls() argument
991 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in ov965x_initialize_controls()
1056 ov965x->sd.ctrl_handler = hdl; in ov965x_initialize_controls()
1109 struct ov965x *ov965x = to_ov965x(sd); in ov965x_g_frame_interval() local
1111 mutex_lock(&ov965x->lock); in ov965x_g_frame_interval()
1112 fi->interval = ov965x->fiv->interval; in ov965x_g_frame_interval()
1113 mutex_unlock(&ov965x->lock); in ov965x_g_frame_interval()
1118 static int __ov965x_set_frame_interval(struct ov965x *ov965x, in __ov965x_set_frame_interval() argument
1121 struct v4l2_mbus_framefmt *mbus_fmt = &ov965x->format; in __ov965x_set_frame_interval()
1145 ov965x->fiv = fiv; in __ov965x_set_frame_interval()
1147 v4l2_dbg(1, debug, &ov965x->sd, "Changed frame interval to %u us\n", in __ov965x_set_frame_interval()
1156 struct ov965x *ov965x = to_ov965x(sd); in ov965x_s_frame_interval() local
1162 mutex_lock(&ov965x->lock); in ov965x_s_frame_interval()
1163 ret = __ov965x_set_frame_interval(ov965x, fi); in ov965x_s_frame_interval()
1164 ov965x->apply_frame_fmt = 1; in ov965x_s_frame_interval()
1165 mutex_unlock(&ov965x->lock); in ov965x_s_frame_interval()
1173 struct ov965x *ov965x = to_ov965x(sd); in ov965x_get_fmt() local
1182 mutex_lock(&ov965x->lock); in ov965x_get_fmt()
1183 fmt->format = ov965x->format; in ov965x_get_fmt()
1184 mutex_unlock(&ov965x->lock); in ov965x_get_fmt()
1220 struct ov965x *ov965x = to_ov965x(sd); in ov965x_set_fmt() local
1234 mutex_lock(&ov965x->lock); in ov965x_set_fmt()
1243 if (ov965x->streaming) { in ov965x_set_fmt()
1246 ov965x->frame_size = size; in ov965x_set_fmt()
1247 ov965x->format = fmt->format; in ov965x_set_fmt()
1248 ov965x->tslb_reg = ov965x_formats[index].tslb_reg; in ov965x_set_fmt()
1249 ov965x->apply_frame_fmt = 1; in ov965x_set_fmt()
1258 __ov965x_set_frame_interval(ov965x, &fiv); in ov965x_set_fmt()
1260 mutex_unlock(&ov965x->lock); in ov965x_set_fmt()
1263 ov965x_update_exposure_ctrl(ov965x); in ov965x_set_fmt()
1268 static int ov965x_set_frame_size(struct ov965x *ov965x) in ov965x_set_frame_size() argument
1273 ret = ov965x_write(ov965x, frame_size_reg_addr[i], in ov965x_set_frame_size()
1274 ov965x->frame_size->regs[i]); in ov965x_set_frame_size()
1278 static int __ov965x_set_params(struct ov965x *ov965x) in __ov965x_set_params() argument
1280 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in __ov965x_set_params()
1284 if (ov965x->apply_frame_fmt) { in __ov965x_set_params()
1285 reg = DEF_CLKRC + ov965x->fiv->clkrc_div; in __ov965x_set_params()
1286 ret = ov965x_write(ov965x, REG_CLKRC, reg); in __ov965x_set_params()
1289 ret = ov965x_set_frame_size(ov965x); in __ov965x_set_params()
1292 ret = ov965x_read(ov965x, REG_TSLB, ®); in __ov965x_set_params()
1296 reg |= ov965x->tslb_reg; in __ov965x_set_params()
1297 ret = ov965x_write(ov965x, REG_TSLB, reg); in __ov965x_set_params()
1301 ret = ov965x_set_default_gamma_curve(ov965x); in __ov965x_set_params()
1304 ret = ov965x_set_color_matrix(ov965x); in __ov965x_set_params()
1311 ret = ov965x_read(ov965x, REG_COM11, ®); in __ov965x_set_params()
1314 ret = ov965x_write(ov965x, REG_COM11, reg); in __ov965x_set_params()
1321 return ov965x_set_banding_filter(ov965x, ctrls->light_freq->val); in __ov965x_set_params()
1326 struct ov965x *ov965x = to_ov965x(sd); in ov965x_s_stream() local
1327 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in ov965x_s_stream()
1332 mutex_lock(&ov965x->lock); in ov965x_s_stream()
1333 if (ov965x->streaming == !on) { in ov965x_s_stream()
1335 ret = __ov965x_set_params(ov965x); in ov965x_s_stream()
1342 mutex_unlock(&ov965x->lock); in ov965x_s_stream()
1345 mutex_lock(&ov965x->lock); in ov965x_s_stream()
1350 ret = ov965x_write(ov965x, REG_COM2, in ov965x_s_stream()
1354 ov965x->streaming += on ? 1 : -1; in ov965x_s_stream()
1356 WARN_ON(ov965x->streaming < 0); in ov965x_s_stream()
1357 mutex_unlock(&ov965x->lock); in ov965x_s_stream()
1408 static int ov965x_configure_gpios_pdata(struct ov965x *ov965x, in ov965x_configure_gpios_pdata() argument
1413 struct device *dev = regmap_get_device(ov965x->regmap); in ov965x_configure_gpios_pdata()
1418 for (i = 0; i < ARRAY_SIZE(ov965x->gpios); i++) { in ov965x_configure_gpios_pdata()
1427 v4l2_dbg(1, debug, &ov965x->sd, "set gpio %d to 1\n", gpio); in ov965x_configure_gpios_pdata()
1431 ov965x->gpios[i] = gpio_to_desc(gpio); in ov965x_configure_gpios_pdata()
1437 static int ov965x_configure_gpios(struct ov965x *ov965x) in ov965x_configure_gpios() argument
1439 struct device *dev = regmap_get_device(ov965x->regmap); in ov965x_configure_gpios()
1441 ov965x->gpios[GPIO_PWDN] = devm_gpiod_get_optional(dev, "powerdown", in ov965x_configure_gpios()
1443 if (IS_ERR(ov965x->gpios[GPIO_PWDN])) { in ov965x_configure_gpios()
1445 return PTR_ERR(ov965x->gpios[GPIO_PWDN]); in ov965x_configure_gpios()
1448 ov965x->gpios[GPIO_RST] = devm_gpiod_get_optional(dev, "reset", in ov965x_configure_gpios()
1450 if (IS_ERR(ov965x->gpios[GPIO_RST])) { in ov965x_configure_gpios()
1452 return PTR_ERR(ov965x->gpios[GPIO_RST]); in ov965x_configure_gpios()
1460 struct ov965x *ov965x = to_ov965x(sd); in ov965x_detect_sensor() local
1464 mutex_lock(&ov965x->lock); in ov965x_detect_sensor()
1465 ret = __ov965x_set_power(ov965x, 1); in ov965x_detect_sensor()
1472 ret = ov965x_read(ov965x, REG_PID, &pid); in ov965x_detect_sensor()
1474 ret = ov965x_read(ov965x, REG_VER, &ver); in ov965x_detect_sensor()
1476 __ov965x_set_power(ov965x, 0); in ov965x_detect_sensor()
1479 ov965x->id = OV965X_ID(pid, ver); in ov965x_detect_sensor()
1480 if (ov965x->id == OV9650_ID || ov965x->id == OV9652_ID) { in ov965x_detect_sensor()
1481 v4l2_info(sd, "Found OV%04X sensor\n", ov965x->id); in ov965x_detect_sensor()
1484 ov965x->id); in ov965x_detect_sensor()
1489 mutex_unlock(&ov965x->lock); in ov965x_detect_sensor()
1498 struct ov965x *ov965x; in ov965x_probe() local
1506 ov965x = devm_kzalloc(&client->dev, sizeof(*ov965x), GFP_KERNEL); in ov965x_probe()
1507 if (!ov965x) in ov965x_probe()
1510 ov965x->regmap = devm_regmap_init_sccb(client, &ov965x_regmap_config); in ov965x_probe()
1511 if (IS_ERR(ov965x->regmap)) { in ov965x_probe()
1513 return PTR_ERR(ov965x->regmap); in ov965x_probe()
1521 ov965x->mclk_frequency = pdata->mclk_frequency; in ov965x_probe()
1523 ret = ov965x_configure_gpios_pdata(ov965x, pdata); in ov965x_probe()
1527 ov965x->clk = devm_clk_get(&client->dev, NULL); in ov965x_probe()
1528 if (IS_ERR(ov965x->clk)) in ov965x_probe()
1529 return PTR_ERR(ov965x->clk); in ov965x_probe()
1530 ov965x->mclk_frequency = clk_get_rate(ov965x->clk); in ov965x_probe()
1532 ret = ov965x_configure_gpios(ov965x); in ov965x_probe()
1542 mutex_init(&ov965x->lock); in ov965x_probe()
1544 sd = &ov965x->sd; in ov965x_probe()
1552 ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; in ov965x_probe()
1554 ret = media_entity_pads_init(&sd->entity, 1, &ov965x->pad); in ov965x_probe()
1558 ret = ov965x_initialize_controls(ov965x); in ov965x_probe()
1562 ov965x_get_default_format(&ov965x->format); in ov965x_probe()
1563 ov965x->frame_size = &ov965x_framesizes[0]; in ov965x_probe()
1564 ov965x->fiv = &ov965x_intervals[0]; in ov965x_probe()
1571 ov965x_update_exposure_ctrl(ov965x); in ov965x_probe()
1583 mutex_destroy(&ov965x->lock); in ov965x_probe()
1590 struct ov965x *ov965x = to_ov965x(sd); in ov965x_remove() local
1595 mutex_destroy(&ov965x->lock); in ov965x_remove()