Lines Matching +full:bias +full:- +full:ctrl +full:- +full:value
1 // SPDX-License-Identifier: GPL-2.0-only
25 #include <media/media-entity.h>
26 #include <media/v4l2-async.h>
27 #include <media/v4l2-ctrls.h>
28 #include <media/v4l2-device.h>
29 #include <media/v4l2-event.h>
30 #include <media/v4l2-image-sizes.h>
31 #include <media/v4l2-subdev.h>
32 #include <media/v4l2-mediabus.h>
37 MODULE_PARM_DESC(debug, "Debug level (0-2)");
45 #define REG_BLUE 0x01 /* AWB - Blue channel gain */
46 #define REG_RED 0x02 /* AWB - Red channel gain */
47 #define REG_VREF 0x03 /* [7:6] - AGC[9:8], [5:3]/[2:0] */
48 #define VREF_GAIN_MASK 0xc0 /* - VREF end/start low 3 bits */
67 #define REG_AECH 0x10 /* Exposure value, AEC[9:2] */
115 #define REG_BBIAS 0x27 /* B channel output bias */
116 #define REG_GBBIAS 0x28 /* Gb channel output bias */
120 #define REG_RBIAS 0x2c /* R channel output bias */
123 #define REG_YAVE 0x2f /* Y/G channel average value */
133 #define TSLB_YUYV_MASK 0x0c /* UYVY or VYUY - see com13 */
144 #define COM13_UVSWAP 0x01 /* V before U - w/TSLB */
160 #define REG_MTX(__n) (0x4f + (__n) - 1)
163 #define REG_LCC(__n) (0x62 + (__n) - 1)
166 #define REG_MANU 0x67 /* Manual U value */
167 #define REG_MANV 0x68 /* Manual V value */
169 #define REG_MBD 0x6a /* Manual banding filter value */
191 #define REG_AECHM 0xa1 /* Exposure value - bits AEC[15:10] */
192 #define REG_BD50ST 0xa2 /* Banding filter value for 50Hz */
193 #define REG_BD60ST 0xa3 /* Banding filter value for 60Hz */
283 u8 value; member
391 /* REG_TSLB value, only bits [3:2] may be set. */
415 static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) in ctrl_to_sd() argument
417 return &container_of(ctrl->handler, struct ov965x, ctrls.handler)->sd; in ctrl_to_sd()
430 ret = regmap_read(ov965x->regmap, addr, &buf); in ov965x_read()
434 *val = -1; in ov965x_read()
436 v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02x. (%d)\n", in ov965x_read()
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()
460 ret = ov965x_write(ov965x, regs[i].addr, regs[i].value); in ov965x_write_array()
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()
538 mutex_lock(&ov965x->lock); in ov965x_s_power()
539 if (ov965x->power == !on) { 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()
562 struct v4l2_ctrl *ctrl = ov965x->ctrls.exposure; in ov965x_update_exposure_ctrl() local
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()
587 max = (max - 100) / 100; in ov965x_update_exposure_ctrl()
588 def = min + (max - min) / 2; in ov965x_update_exposure_ctrl()
590 if (v4l2_ctrl_modify_range(ctrl, min, max, 1, def)) 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
602 if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED) in ov965x_set_banding_filter()
608 if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED) in ov965x_set_banding_filter()
610 if (WARN_ON(!ov965x->fiv)) in ov965x_set_banding_filter()
611 return -EINVAL; in ov965x_set_banding_filter()
613 if (value == V4L2_CID_POWER_LINE_FREQUENCY_50HZ) 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()
637 ov965x->ctrls.blue_balance->val); in ov965x_set_white_balance()
641 ov965x->ctrls.red_balance->val); in ov965x_set_white_balance()
653 { 0x1c, 0x12, 0x50 }, /* -3 */ in ov965x_set_brightness()
654 { 0x3d, 0x30, 0x71 }, /* -2 */ in ov965x_set_brightness()
655 { 0x50, 0x44, 0x92 }, /* -1 */ in ov965x_set_brightness()
665 return -EINVAL; in ov965x_set_brightness()
675 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in ov965x_set_gain()
680 * gain value in REG_VREF, REG_GAIN is not overwritten. in ov965x_set_gain()
682 if (ctrls->auto_gain->is_new) { in ov965x_set_gain()
686 if (ctrls->auto_gain->val) in ov965x_set_gain()
695 if (ctrls->gain->is_new && !auto_gain) { in ov965x_set_gain()
696 unsigned int gain = ctrls->gain->val; in ov965x_set_gain()
700 * Convert gain control value to the sensor's gain in ov965x_set_gain()
703 for (m = 6; m >= 0; m--) in ov965x_set_gain()
707 /* Sanity check: don't adjust the gain with a negative value */ in ov965x_set_gain()
709 return -EINVAL; in ov965x_set_gain()
711 rgain = (gain - ((1 << m) * 16)) / (1 << m); in ov965x_set_gain()
712 rgain |= (((1 << m) - 1) << 4); in ov965x_set_gain()
725 /* Return updated control's value to userspace */ in ov965x_set_gain()
726 ctrls->gain->val = (1 << m) * (16 + (rgain & 0xf)); in ov965x_set_gain()
732 static int ov965x_set_sharpness(struct ov965x *ov965x, unsigned int value) in ov965x_set_sharpness() argument
743 com14 = value ? com14 | COM14_EDGE_EN : com14 & ~COM14_EDGE_EN; in ov965x_set_sharpness()
744 value--; in ov965x_set_sharpness()
745 if (value > 0x0f) { in ov965x_set_sharpness()
747 value >>= 1; in ov965x_set_sharpness()
756 edge |= ((u8)value & 0x0f); in ov965x_set_sharpness()
763 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in ov965x_set_exposure()
768 if (ctrls->auto_exp->is_new) { in ov965x_set_exposure()
781 if (!auto_exposure && ctrls->exposure->is_new) { in ov965x_set_exposure()
782 unsigned int exposure = (ctrls->exposure->val * 100) in ov965x_set_exposure()
783 / ov965x->exp_row_interval; in ov965x_set_exposure()
785 * Manual exposure value in ov965x_set_exposure()
786 * [b15:b0] - AECHM (b15:b10), AECH (b9:b2), COM1 (b1:b0) in ov965x_set_exposure()
795 /* Update the value to minimize rounding errors */ 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()
810 if (ov965x->ctrls.hflip->val) in ov965x_set_flip()
813 if (ov965x->ctrls.vflip->val) in ov965x_set_flip()
826 { 0x1d, 0x1f, 0x02, 0x09, 0x13, 0x1c }, /* -2 */ in ov965x_set_saturation()
827 { 0x2e, 0x31, 0x02, 0x0e, 0x1e, 0x2d }, /* -1 */ in ov965x_set_saturation()
837 return -EINVAL; in ov965x_set_saturation()
845 static int ov965x_set_test_pattern(struct ov965x *ov965x, int value) in ov965x_set_test_pattern() argument
853 reg = value ? reg | COM23_TEST_MODE : reg & ~COM23_TEST_MODE; 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()
866 switch (ctrl->id) { in __g_volatile_ctrl()
868 if (!ctrl->val) in __g_volatile_ctrl()
878 ov965x->ctrls.gain->val = m * (16 + (gain & 0xf)); in __g_volatile_ctrl()
882 if (ctrl->val == V4L2_EXPOSURE_MANUAL) 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()
903 static int ov965x_g_volatile_ctrl(struct v4l2_ctrl *ctrl) in ov965x_g_volatile_ctrl() argument
905 struct v4l2_subdev *sd = ctrl_to_sd(ctrl); in ov965x_g_volatile_ctrl()
909 v4l2_dbg(1, debug, sd, "g_ctrl: %s\n", ctrl->name); in ov965x_g_volatile_ctrl()
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()
917 static int ov965x_s_ctrl(struct v4l2_ctrl *ctrl) in ov965x_s_ctrl() argument
919 struct v4l2_subdev *sd = ctrl_to_sd(ctrl); in ov965x_s_ctrl()
921 int ret = -EINVAL; in ov965x_s_ctrl()
923 v4l2_dbg(1, debug, sd, "s_ctrl: %s, value: %d. power: %d\n", in ov965x_s_ctrl()
924 ctrl->name, ctrl->val, ov965x->power); in ov965x_s_ctrl()
926 mutex_lock(&ov965x->lock); in ov965x_s_ctrl()
929 * value to the hardware, until it is ready to accept commands. in ov965x_s_ctrl()
931 if (ov965x->power == 0) { in ov965x_s_ctrl()
932 mutex_unlock(&ov965x->lock); in ov965x_s_ctrl()
936 switch (ctrl->id) { 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()
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()
991 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in ov965x_initialize_controls()
992 struct v4l2_ctrl_handler *hdl = &ctrls->handler; in ov965x_initialize_controls()
1000 ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops, in ov965x_initialize_controls()
1003 ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE, in ov965x_initialize_controls()
1005 ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE, in ov965x_initialize_controls()
1008 ctrls->auto_exp = in ov965x_initialize_controls()
1014 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, in ov965x_initialize_controls()
1018 ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, in ov965x_initialize_controls()
1020 ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, in ov965x_initialize_controls()
1023 ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, in ov965x_initialize_controls()
1024 -2, 2, 1, 0); in ov965x_initialize_controls()
1025 ctrls->brightness = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, in ov965x_initialize_controls()
1026 -3, 3, 1, 0); in ov965x_initialize_controls()
1027 ctrls->sharpness = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, in ov965x_initialize_controls()
1030 ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0); in ov965x_initialize_controls()
1031 ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0); in ov965x_initialize_controls()
1033 ctrls->light_freq = in ov965x_initialize_controls()
1040 ARRAY_SIZE(test_pattern_menu) - 1, 0, 0, in ov965x_initialize_controls()
1042 if (hdl->error) { in ov965x_initialize_controls()
1043 ret = hdl->error; in ov965x_initialize_controls()
1048 ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; in ov965x_initialize_controls()
1049 ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; in ov965x_initialize_controls()
1051 v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false); in ov965x_initialize_controls()
1052 v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true); in ov965x_initialize_controls()
1053 v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true); in ov965x_initialize_controls()
1054 v4l2_ctrl_cluster(2, &ctrls->hflip); in ov965x_initialize_controls()
1056 ov965x->sd.ctrl_handler = hdl; in ov965x_initialize_controls()
1065 mf->width = ov965x_framesizes[0].width; in ov965x_get_default_format()
1066 mf->height = ov965x_framesizes[0].height; in ov965x_get_default_format()
1067 mf->colorspace = ov965x_formats[0].colorspace; in ov965x_get_default_format()
1068 mf->code = ov965x_formats[0].code; in ov965x_get_default_format()
1069 mf->field = V4L2_FIELD_NONE; in ov965x_get_default_format()
1076 if (code->index >= ARRAY_SIZE(ov965x_formats)) in ov965x_enum_mbus_code()
1077 return -EINVAL; in ov965x_enum_mbus_code()
1079 code->code = ov965x_formats[code->index].code; in ov965x_enum_mbus_code()
1089 if (fse->index >= ARRAY_SIZE(ov965x_framesizes)) in ov965x_enum_frame_sizes()
1090 return -EINVAL; in ov965x_enum_frame_sizes()
1092 while (--i) in ov965x_enum_frame_sizes()
1093 if (fse->code == ov965x_formats[i].code) in ov965x_enum_frame_sizes()
1096 fse->code = ov965x_formats[i].code; in ov965x_enum_frame_sizes()
1098 fse->min_width = ov965x_framesizes[fse->index].width; in ov965x_enum_frame_sizes()
1099 fse->max_width = fse->min_width; in ov965x_enum_frame_sizes()
1100 fse->max_height = ov965x_framesizes[fse->index].height; in ov965x_enum_frame_sizes()
1101 fse->min_height = fse->max_height; in ov965x_enum_frame_sizes()
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()
1121 struct v4l2_mbus_framefmt *mbus_fmt = &ov965x->format; in __ov965x_set_frame_interval()
1126 if (fi->interval.denominator == 0) in __ov965x_set_frame_interval()
1127 return -EINVAL; in __ov965x_set_frame_interval()
1129 req_int = (u64)fi->interval.numerator * 10000; in __ov965x_set_frame_interval()
1130 do_div(req_int, fi->interval.denominator); in __ov965x_set_frame_interval()
1135 if (mbus_fmt->width != iv->size.width || in __ov965x_set_frame_interval()
1136 mbus_fmt->height != iv->size.height) in __ov965x_set_frame_interval()
1138 err = abs((u64)(iv->interval.numerator * 10000) / in __ov965x_set_frame_interval()
1139 iv->interval.denominator - req_int); 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()
1148 fiv->interval.numerator * 1000000 / fiv->interval.denominator); in __ov965x_set_frame_interval()
1160 fi->interval.numerator, fi->interval.denominator); in ov965x_s_frame_interval()
1162 mutex_lock(&ov965x->lock); 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()
1176 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in ov965x_get_fmt()
1178 fmt->format = *mf; in ov965x_get_fmt()
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()
1197 while (i--) { in __ov965x_try_frame_size()
1198 int err = abs(fsize->width - mf->width) in __ov965x_try_frame_size()
1199 + abs(fsize->height - mf->height); in __ov965x_try_frame_size()
1208 mf->width = match->width; in __ov965x_try_frame_size()
1209 mf->height = match->height; in __ov965x_try_frame_size()
1219 struct v4l2_mbus_framefmt *mf = &fmt->format; in ov965x_set_fmt()
1226 while (--index) in ov965x_set_fmt()
1227 if (ov965x_formats[index].code == mf->code) in ov965x_set_fmt()
1230 mf->colorspace = V4L2_COLORSPACE_JPEG; in ov965x_set_fmt()
1231 mf->code = ov965x_formats[index].code; in ov965x_set_fmt()
1232 mf->field = V4L2_FIELD_NONE; in ov965x_set_fmt()
1234 mutex_lock(&ov965x->lock); in ov965x_set_fmt()
1236 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in ov965x_set_fmt()
1238 mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); in ov965x_set_fmt()
1239 *mf = fmt->format; in ov965x_set_fmt()
1242 if (ov965x->streaming) { in ov965x_set_fmt()
1243 ret = -EBUSY; in ov965x_set_fmt()
1245 ov965x->frame_size = size; in ov965x_set_fmt()
1246 ov965x->format = fmt->format; in ov965x_set_fmt()
1247 ov965x->tslb_reg = ov965x_formats[index].tslb_reg; in ov965x_set_fmt()
1248 ov965x->apply_frame_fmt = 1; in ov965x_set_fmt()
1252 if (!ret && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { in ov965x_set_fmt()
1259 mutex_unlock(&ov965x->lock); in ov965x_set_fmt()
1273 ov965x->frame_size->regs[i]); in ov965x_set_frame_size()
1279 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in __ov965x_set_params()
1283 if (ov965x->apply_frame_fmt) { in __ov965x_set_params()
1284 reg = DEF_CLKRC + ov965x->fiv->clkrc_div; in __ov965x_set_params()
1295 reg |= ov965x->tslb_reg; in __ov965x_set_params()
1317 * Banding filter (REG_MBD value) needs to match selected in __ov965x_set_params()
1320 return ov965x_set_banding_filter(ov965x, ctrls->light_freq->val); in __ov965x_set_params()
1326 struct ov965x_ctrls *ctrls = &ov965x->ctrls; in ov965x_s_stream()
1331 mutex_lock(&ov965x->lock); in ov965x_s_stream()
1332 if (ov965x->streaming == !on) { in ov965x_s_stream()
1336 if (!ret && ctrls->update) { in ov965x_s_stream()
1341 mutex_unlock(&ov965x->lock); in ov965x_s_stream()
1342 ret = v4l2_ctrl_handler_setup(&ctrls->handler); in ov965x_s_stream()
1344 mutex_lock(&ov965x->lock); in ov965x_s_stream()
1346 ctrls->update = 0; in ov965x_s_stream()
1353 ov965x->streaming += on ? 1 : -1; in ov965x_s_stream()
1355 WARN_ON(ov965x->streaming < 0); in ov965x_s_stream()
1356 mutex_unlock(&ov965x->lock); in ov965x_s_stream()
1367 v4l2_subdev_get_try_format(sd, fh->pad, 0); in ov965x_open()
1412 struct device *dev = regmap_get_device(ov965x->regmap); in ov965x_configure_gpios_pdata()
1414 gpios[GPIO_PWDN] = pdata->gpio_pwdn; in ov965x_configure_gpios_pdata()
1415 gpios[GPIO_RST] = pdata->gpio_reset; in ov965x_configure_gpios_pdata()
1417 for (i = 0; i < ARRAY_SIZE(ov965x->gpios); i++) { in ov965x_configure_gpios_pdata()
1426 v4l2_dbg(1, debug, &ov965x->sd, "set gpio %d to 1\n", gpio); in ov965x_configure_gpios_pdata()
1430 ov965x->gpios[i] = gpio_to_desc(gpio); in ov965x_configure_gpios_pdata()
1438 struct device *dev = regmap_get_device(ov965x->regmap); in ov965x_configure_gpios()
1440 ov965x->gpios[GPIO_PWDN] = devm_gpiod_get_optional(dev, "powerdown", in ov965x_configure_gpios()
1442 if (IS_ERR(ov965x->gpios[GPIO_PWDN])) { in ov965x_configure_gpios()
1444 return PTR_ERR(ov965x->gpios[GPIO_PWDN]); in ov965x_configure_gpios()
1447 ov965x->gpios[GPIO_RST] = devm_gpiod_get_optional(dev, "reset", in ov965x_configure_gpios()
1449 if (IS_ERR(ov965x->gpios[GPIO_RST])) { in ov965x_configure_gpios()
1451 return PTR_ERR(ov965x->gpios[GPIO_RST]); in ov965x_configure_gpios()
1463 mutex_lock(&ov965x->lock); in ov965x_detect_sensor()
1478 ov965x->id = OV965X_ID(pid, ver); in ov965x_detect_sensor()
1479 if (ov965x->id == OV9650_ID || ov965x->id == OV9652_ID) { in ov965x_detect_sensor()
1480 v4l2_info(sd, "Found OV%04X sensor\n", ov965x->id); in ov965x_detect_sensor()
1483 ov965x->id, ret); in ov965x_detect_sensor()
1484 ret = -ENODEV; in ov965x_detect_sensor()
1488 mutex_unlock(&ov965x->lock); in ov965x_detect_sensor()
1495 const struct ov9650_platform_data *pdata = client->dev.platform_data; in ov965x_probe()
1505 ov965x = devm_kzalloc(&client->dev, sizeof(*ov965x), GFP_KERNEL); in ov965x_probe()
1507 return -ENOMEM; in ov965x_probe()
1509 ov965x->regmap = devm_regmap_init_sccb(client, &ov965x_regmap_config); in ov965x_probe()
1510 if (IS_ERR(ov965x->regmap)) { in ov965x_probe()
1511 dev_err(&client->dev, "Failed to allocate register map\n"); in ov965x_probe()
1512 return PTR_ERR(ov965x->regmap); in ov965x_probe()
1516 if (pdata->mclk_frequency == 0) { in ov965x_probe()
1517 dev_err(&client->dev, "MCLK frequency not specified\n"); in ov965x_probe()
1518 return -EINVAL; in ov965x_probe()
1520 ov965x->mclk_frequency = pdata->mclk_frequency; in ov965x_probe()
1525 } else if (dev_fwnode(&client->dev)) { in ov965x_probe()
1526 ov965x->clk = devm_clk_get(&client->dev, NULL); in ov965x_probe()
1527 if (IS_ERR(ov965x->clk)) in ov965x_probe()
1528 return PTR_ERR(ov965x->clk); in ov965x_probe()
1529 ov965x->mclk_frequency = clk_get_rate(ov965x->clk); in ov965x_probe()
1535 dev_err(&client->dev, in ov965x_probe()
1538 return -EINVAL; in ov965x_probe()
1541 mutex_init(&ov965x->lock); in ov965x_probe()
1543 sd = &ov965x->sd; in ov965x_probe()
1545 strscpy(sd->name, DRIVER_NAME, sizeof(sd->name)); in ov965x_probe()
1547 sd->internal_ops = &ov965x_sd_internal_ops; in ov965x_probe()
1548 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in ov965x_probe()
1551 ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; in ov965x_probe()
1552 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov965x_probe()
1553 ret = media_entity_pads_init(&sd->entity, 1, &ov965x->pad); in ov965x_probe()
1561 ov965x_get_default_format(&ov965x->format); in ov965x_probe()
1562 ov965x->frame_size = &ov965x_framesizes[0]; in ov965x_probe()
1563 ov965x->fiv = &ov965x_intervals[0]; in ov965x_probe()
1578 v4l2_ctrl_handler_free(sd->ctrl_handler); in ov965x_probe()
1580 media_entity_cleanup(&sd->entity); in ov965x_probe()
1582 mutex_destroy(&ov965x->lock); in ov965x_probe()
1592 v4l2_ctrl_handler_free(sd->ctrl_handler); in ov965x_remove()
1593 media_entity_cleanup(&sd->entity); in ov965x_remove()
1594 mutex_destroy(&ov965x->lock); in ov965x_remove()