0001
0002
0003
0004 #include <linux/clk.h>
0005 #include <linux/delay.h>
0006 #include <linux/gpio/consumer.h>
0007 #include <linux/i2c.h>
0008 #include <linux/module.h>
0009 #include <linux/pm_runtime.h>
0010 #include <linux/regmap.h>
0011 #include <media/v4l2-ctrls.h>
0012 #include <media/v4l2-event.h>
0013 #include <media/v4l2-image-sizes.h>
0014 #include <media/v4l2-subdev.h>
0015
0016 #define REG_OUTSIZE_LSB 0x34
0017
0018
0019 #define REG_GAIN 0x00
0020 #define REG_BGAIN 0x01
0021 #define REG_RGAIN 0x02
0022 #define REG_GGAIN 0x03
0023 #define REG_REG04 0x04
0024 #define REG_BAVG 0x05
0025 #define REG_GAVG 0x06
0026 #define REG_RAVG 0x07
0027
0028 #define REG_REG0C 0x0C
0029 #define REG0C_IMG_FLIP 0x80
0030 #define REG0C_IMG_MIRROR 0x40
0031
0032 #define REG_REG0E 0x0E
0033 #define REG_HAEC 0x0F
0034 #define REG_AEC 0x10
0035
0036 #define REG_CLK 0x11
0037 #define REG_REG55 0x55
0038
0039 #define REG_REG12 0x12
0040
0041 #define REG_REG13 0x13
0042 #define REG13_AEC_EN 0x01
0043 #define REG13_AGC_EN 0x04
0044
0045 #define REG_REG14 0x14
0046 #define REG_CTRL15 0x15
0047 #define REG15_GAIN_MSB 0x03
0048
0049 #define REG_REG16 0x16
0050
0051 #define REG_MIDH 0x1C
0052 #define REG_MIDL 0x1D
0053 #define REG_PIDH 0x0A
0054 #define REG_PIDL 0x0B
0055
0056 #define REG_84 0x84
0057 #define REG_REG38 0x38
0058
0059 #define REG_AHSTART 0x17
0060 #define REG_AHSIZE 0x18
0061 #define REG_AVSTART 0x19
0062 #define REG_AVSIZE 0x1A
0063 #define REG_PSHFT 0x1b
0064
0065 #define REG_HOUTSIZE 0x31
0066 #define REG_VOUTSIZE 0x32
0067 #define REG_HVSIZEOFF 0x33
0068 #define REG_REG34 0x34
0069
0070 #define REG_ISP_CTRL00 0x80
0071 #define ISPCTRL00_AWB_EN 0x10
0072 #define ISPCTRL00_AWB_GAIN_EN 0x04
0073
0074 #define REG_YGAIN 0xE2
0075
0076 #define REG_YBRIGHT 0xE3
0077 #define REG_SGNSET 0xE4
0078 #define SGNSET_YBRIGHT_MASK 0x08
0079
0080 #define REG_USAT 0xDD
0081 #define REG_VSAT 0xDE
0082
0083
0084 struct ov7740 {
0085 struct v4l2_subdev subdev;
0086 #if defined(CONFIG_MEDIA_CONTROLLER)
0087 struct media_pad pad;
0088 #endif
0089 struct v4l2_mbus_framefmt format;
0090 const struct ov7740_pixfmt *fmt;
0091 const struct ov7740_framesize *frmsize;
0092 struct regmap *regmap;
0093 struct clk *xvclk;
0094 struct v4l2_ctrl_handler ctrl_handler;
0095 struct {
0096
0097 struct v4l2_ctrl *auto_gain;
0098 struct v4l2_ctrl *gain;
0099 };
0100 struct {
0101 struct v4l2_ctrl *auto_wb;
0102 struct v4l2_ctrl *blue_balance;
0103 struct v4l2_ctrl *red_balance;
0104 };
0105 struct {
0106 struct v4l2_ctrl *hflip;
0107 struct v4l2_ctrl *vflip;
0108 };
0109 struct {
0110
0111 struct v4l2_ctrl *auto_exposure;
0112 struct v4l2_ctrl *exposure;
0113 };
0114 struct {
0115
0116 struct v4l2_ctrl *saturation;
0117 struct v4l2_ctrl *hue;
0118 };
0119 struct v4l2_ctrl *brightness;
0120 struct v4l2_ctrl *contrast;
0121
0122 struct mutex mutex;
0123 bool streaming;
0124
0125 struct gpio_desc *resetb_gpio;
0126 struct gpio_desc *pwdn_gpio;
0127 };
0128
0129 struct ov7740_pixfmt {
0130 u32 mbus_code;
0131 enum v4l2_colorspace colorspace;
0132 const struct reg_sequence *regs;
0133 u32 reg_num;
0134 };
0135
0136 struct ov7740_framesize {
0137 u16 width;
0138 u16 height;
0139 const struct reg_sequence *regs;
0140 u32 reg_num;
0141 };
0142
0143 static const struct reg_sequence ov7740_vga[] = {
0144 {0x55, 0x40},
0145 {0x11, 0x02},
0146
0147 {0xd5, 0x10},
0148 {0x0c, 0x12},
0149 {0x0d, 0x34},
0150 {0x17, 0x25},
0151 {0x18, 0xa0},
0152 {0x19, 0x03},
0153 {0x1a, 0xf0},
0154 {0x1b, 0x89},
0155 {0x22, 0x03},
0156 {0x29, 0x18},
0157 {0x2b, 0xf8},
0158 {0x2c, 0x01},
0159 {REG_HOUTSIZE, 0xa0},
0160 {REG_VOUTSIZE, 0xf0},
0161 {0x33, 0xc4},
0162 {REG_OUTSIZE_LSB, 0x0},
0163 {0x35, 0x05},
0164 {0x04, 0x60},
0165 {0x27, 0x80},
0166 {0x3d, 0x0f},
0167 {0x3e, 0x80},
0168 {0x3f, 0x40},
0169 {0x40, 0x7f},
0170 {0x41, 0x6a},
0171 {0x42, 0x29},
0172 {0x44, 0x22},
0173 {0x45, 0x41},
0174 {0x47, 0x02},
0175 {0x49, 0x64},
0176 {0x4a, 0xa1},
0177 {0x4b, 0x40},
0178 {0x4c, 0x1a},
0179 {0x4d, 0x50},
0180 {0x4e, 0x13},
0181 {0x64, 0x00},
0182 {0x67, 0x88},
0183 {0x68, 0x1a},
0184
0185 {0x14, 0x28},
0186 {0x24, 0x3c},
0187 {0x25, 0x30},
0188 {0x26, 0x72},
0189 {0x50, 0x97},
0190 {0x51, 0x1f},
0191 {0x52, 0x00},
0192 {0x53, 0x00},
0193 {0x20, 0x00},
0194 {0x21, 0xcf},
0195 {0x50, 0x4b},
0196 {0x38, 0x14},
0197 {0xe9, 0x00},
0198 {0x56, 0x55},
0199 {0x57, 0xff},
0200 {0x58, 0xff},
0201 {0x59, 0xff},
0202 {0x5f, 0x04},
0203 {0xec, 0x00},
0204 {0x13, 0xff},
0205
0206 {0x81, 0x3f},
0207 {0x82, 0x32},
0208 {0x38, 0x11},
0209 {0x84, 0x70},
0210 {0x85, 0x00},
0211 {0x86, 0x03},
0212 {0x87, 0x01},
0213 {0x88, 0x05},
0214 {0x89, 0x30},
0215 {0x8d, 0x30},
0216 {0x8f, 0x85},
0217 {0x93, 0x30},
0218 {0x95, 0x85},
0219 {0x99, 0x30},
0220 {0x9b, 0x85},
0221
0222 {0x9c, 0x08},
0223 {0x9d, 0x12},
0224 {0x9e, 0x23},
0225 {0x9f, 0x45},
0226 {0xa0, 0x55},
0227 {0xa1, 0x64},
0228 {0xa2, 0x72},
0229 {0xa3, 0x7f},
0230 {0xa4, 0x8b},
0231 {0xa5, 0x95},
0232 {0xa6, 0xa7},
0233 {0xa7, 0xb5},
0234 {0xa8, 0xcb},
0235 {0xa9, 0xdd},
0236 {0xaa, 0xec},
0237 {0xab, 0x1a},
0238
0239 {0xce, 0x78},
0240 {0xcf, 0x6e},
0241 {0xd0, 0x0a},
0242 {0xd1, 0x0c},
0243 {0xd2, 0x84},
0244 {0xd3, 0x90},
0245 {0xd4, 0x1e},
0246
0247 {0x5a, 0x24},
0248 {0x5b, 0x1f},
0249 {0x5c, 0x88},
0250 {0x5d, 0x60},
0251
0252 {0xac, 0x6e},
0253 {0xbe, 0xff},
0254 {0xbf, 0x00},
0255
0256 {0x0f, 0x1d},
0257 {0x0f, 0x1f},
0258 };
0259
0260 static const struct ov7740_framesize ov7740_framesizes[] = {
0261 {
0262 .width = VGA_WIDTH,
0263 .height = VGA_HEIGHT,
0264 .regs = ov7740_vga,
0265 .reg_num = ARRAY_SIZE(ov7740_vga),
0266 },
0267 };
0268
0269 #ifdef CONFIG_VIDEO_ADV_DEBUG
0270 static int ov7740_get_register(struct v4l2_subdev *sd,
0271 struct v4l2_dbg_register *reg)
0272 {
0273 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
0274 struct regmap *regmap = ov7740->regmap;
0275 unsigned int val = 0;
0276 int ret;
0277
0278 ret = regmap_read(regmap, reg->reg & 0xff, &val);
0279 reg->val = val;
0280 reg->size = 1;
0281
0282 return ret;
0283 }
0284
0285 static int ov7740_set_register(struct v4l2_subdev *sd,
0286 const struct v4l2_dbg_register *reg)
0287 {
0288 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
0289 struct regmap *regmap = ov7740->regmap;
0290
0291 regmap_write(regmap, reg->reg & 0xff, reg->val & 0xff);
0292
0293 return 0;
0294 }
0295 #endif
0296
0297 static int ov7740_set_power(struct ov7740 *ov7740, int on)
0298 {
0299 int ret;
0300
0301 if (on) {
0302 ret = clk_prepare_enable(ov7740->xvclk);
0303 if (ret)
0304 return ret;
0305
0306 if (ov7740->pwdn_gpio)
0307 gpiod_direction_output(ov7740->pwdn_gpio, 0);
0308
0309 if (ov7740->resetb_gpio) {
0310 gpiod_set_value(ov7740->resetb_gpio, 1);
0311 usleep_range(500, 1000);
0312 gpiod_set_value(ov7740->resetb_gpio, 0);
0313 usleep_range(3000, 5000);
0314 }
0315 } else {
0316 clk_disable_unprepare(ov7740->xvclk);
0317
0318 if (ov7740->pwdn_gpio)
0319 gpiod_direction_output(ov7740->pwdn_gpio, 0);
0320 }
0321
0322 return 0;
0323 }
0324
0325 static const struct v4l2_subdev_core_ops ov7740_subdev_core_ops = {
0326 .log_status = v4l2_ctrl_subdev_log_status,
0327 #ifdef CONFIG_VIDEO_ADV_DEBUG
0328 .g_register = ov7740_get_register,
0329 .s_register = ov7740_set_register,
0330 #endif
0331 .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
0332 .unsubscribe_event = v4l2_event_subdev_unsubscribe,
0333 };
0334
0335 static int ov7740_set_white_balance(struct ov7740 *ov7740, int awb)
0336 {
0337 struct regmap *regmap = ov7740->regmap;
0338 unsigned int value;
0339 int ret;
0340
0341 ret = regmap_read(regmap, REG_ISP_CTRL00, &value);
0342 if (!ret) {
0343 if (awb)
0344 value |= (ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
0345 else
0346 value &= ~(ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
0347 ret = regmap_write(regmap, REG_ISP_CTRL00, value);
0348 if (ret)
0349 return ret;
0350 }
0351
0352 if (!awb) {
0353 ret = regmap_write(regmap, REG_BGAIN,
0354 ov7740->blue_balance->val);
0355 if (ret)
0356 return ret;
0357
0358 ret = regmap_write(regmap, REG_RGAIN, ov7740->red_balance->val);
0359 if (ret)
0360 return ret;
0361 }
0362
0363 return 0;
0364 }
0365
0366 static int ov7740_set_saturation(struct regmap *regmap, int value)
0367 {
0368 int ret;
0369
0370 ret = regmap_write(regmap, REG_USAT, (unsigned char)value);
0371 if (ret)
0372 return ret;
0373
0374 return regmap_write(regmap, REG_VSAT, (unsigned char)value);
0375 }
0376
0377 static int ov7740_set_gain(struct regmap *regmap, int value)
0378 {
0379 int ret;
0380
0381 ret = regmap_write(regmap, REG_GAIN, value & 0xff);
0382 if (ret)
0383 return ret;
0384
0385 ret = regmap_update_bits(regmap, REG_CTRL15,
0386 REG15_GAIN_MSB, (value >> 8) & 0x3);
0387 if (!ret)
0388 ret = regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
0389
0390 return ret;
0391 }
0392
0393 static int ov7740_set_autogain(struct regmap *regmap, int value)
0394 {
0395 unsigned int reg;
0396 int ret;
0397
0398 ret = regmap_read(regmap, REG_REG13, ®);
0399 if (ret)
0400 return ret;
0401 if (value)
0402 reg |= REG13_AGC_EN;
0403 else
0404 reg &= ~REG13_AGC_EN;
0405 return regmap_write(regmap, REG_REG13, reg);
0406 }
0407
0408 static int ov7740_set_brightness(struct regmap *regmap, int value)
0409 {
0410
0411 regmap_update_bits(regmap, REG_REG13, REG13_AEC_EN, 0);
0412 regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
0413
0414 if (value >= 0) {
0415 regmap_write(regmap, REG_YBRIGHT, (unsigned char)value);
0416 regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 0);
0417 } else{
0418 regmap_write(regmap, REG_YBRIGHT, (unsigned char)(-value));
0419 regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 1);
0420 }
0421
0422 return 0;
0423 }
0424
0425 static int ov7740_set_contrast(struct regmap *regmap, int value)
0426 {
0427 return regmap_write(regmap, REG_YGAIN, (unsigned char)value);
0428 }
0429
0430 static int ov7740_get_gain(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
0431 {
0432 struct regmap *regmap = ov7740->regmap;
0433 unsigned int value0, value1;
0434 int ret;
0435
0436 if (!ctrl->val)
0437 return 0;
0438
0439 ret = regmap_read(regmap, REG_GAIN, &value0);
0440 if (ret)
0441 return ret;
0442 ret = regmap_read(regmap, REG_CTRL15, &value1);
0443 if (ret)
0444 return ret;
0445
0446 ov7740->gain->val = (value1 << 8) | (value0 & 0xff);
0447
0448 return 0;
0449 }
0450
0451 static int ov7740_get_exp(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
0452 {
0453 struct regmap *regmap = ov7740->regmap;
0454 unsigned int value0, value1;
0455 int ret;
0456
0457 if (ctrl->val == V4L2_EXPOSURE_MANUAL)
0458 return 0;
0459
0460 ret = regmap_read(regmap, REG_AEC, &value0);
0461 if (ret)
0462 return ret;
0463 ret = regmap_read(regmap, REG_HAEC, &value1);
0464 if (ret)
0465 return ret;
0466
0467 ov7740->exposure->val = (value1 << 8) | (value0 & 0xff);
0468
0469 return 0;
0470 }
0471
0472 static int ov7740_set_exp(struct regmap *regmap, int value)
0473 {
0474 int ret;
0475
0476
0477 ret = regmap_update_bits(regmap, REG_REG13,
0478 REG13_AEC_EN | REG13_AGC_EN, 0);
0479 if (ret)
0480 return ret;
0481
0482 ret = regmap_write(regmap, REG_AEC, (unsigned char)value);
0483 if (ret)
0484 return ret;
0485
0486 return regmap_write(regmap, REG_HAEC, (unsigned char)(value >> 8));
0487 }
0488
0489 static int ov7740_set_autoexp(struct regmap *regmap,
0490 enum v4l2_exposure_auto_type value)
0491 {
0492 unsigned int reg;
0493 int ret;
0494
0495 ret = regmap_read(regmap, REG_REG13, ®);
0496 if (!ret) {
0497 if (value == V4L2_EXPOSURE_AUTO)
0498 reg |= (REG13_AEC_EN | REG13_AGC_EN);
0499 else
0500 reg &= ~(REG13_AEC_EN | REG13_AGC_EN);
0501 ret = regmap_write(regmap, REG_REG13, reg);
0502 }
0503
0504 return ret;
0505 }
0506
0507
0508 static int ov7740_get_volatile_ctrl(struct v4l2_ctrl *ctrl)
0509 {
0510 struct ov7740 *ov7740 = container_of(ctrl->handler,
0511 struct ov7740, ctrl_handler);
0512 int ret;
0513
0514 switch (ctrl->id) {
0515 case V4L2_CID_AUTOGAIN:
0516 ret = ov7740_get_gain(ov7740, ctrl);
0517 break;
0518 case V4L2_CID_EXPOSURE_AUTO:
0519 ret = ov7740_get_exp(ov7740, ctrl);
0520 break;
0521 default:
0522 ret = -EINVAL;
0523 break;
0524 }
0525 return ret;
0526 }
0527
0528 static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
0529 {
0530 struct ov7740 *ov7740 = container_of(ctrl->handler,
0531 struct ov7740, ctrl_handler);
0532 struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
0533 struct regmap *regmap = ov7740->regmap;
0534 int ret;
0535 u8 val;
0536
0537 if (!pm_runtime_get_if_in_use(&client->dev))
0538 return 0;
0539
0540 switch (ctrl->id) {
0541 case V4L2_CID_AUTO_WHITE_BALANCE:
0542 ret = ov7740_set_white_balance(ov7740, ctrl->val);
0543 break;
0544 case V4L2_CID_SATURATION:
0545 ret = ov7740_set_saturation(regmap, ctrl->val);
0546 break;
0547 case V4L2_CID_BRIGHTNESS:
0548 ret = ov7740_set_brightness(regmap, ctrl->val);
0549 break;
0550 case V4L2_CID_CONTRAST:
0551 ret = ov7740_set_contrast(regmap, ctrl->val);
0552 break;
0553 case V4L2_CID_VFLIP:
0554 val = ctrl->val ? REG0C_IMG_FLIP : 0x00;
0555 ret = regmap_update_bits(regmap, REG_REG0C,
0556 REG0C_IMG_FLIP, val);
0557 break;
0558 case V4L2_CID_HFLIP:
0559 val = ctrl->val ? REG0C_IMG_MIRROR : 0x00;
0560 ret = regmap_update_bits(regmap, REG_REG0C,
0561 REG0C_IMG_MIRROR, val);
0562 break;
0563 case V4L2_CID_AUTOGAIN:
0564 if (!ctrl->val)
0565 ret = ov7740_set_gain(regmap, ov7740->gain->val);
0566 else
0567 ret = ov7740_set_autogain(regmap, ctrl->val);
0568 break;
0569
0570 case V4L2_CID_EXPOSURE_AUTO:
0571 if (ctrl->val == V4L2_EXPOSURE_MANUAL)
0572 ret = ov7740_set_exp(regmap, ov7740->exposure->val);
0573 else
0574 ret = ov7740_set_autoexp(regmap, ctrl->val);
0575 break;
0576 default:
0577 ret = -EINVAL;
0578 break;
0579 }
0580
0581 pm_runtime_put(&client->dev);
0582
0583 return ret;
0584 }
0585
0586 static const struct v4l2_ctrl_ops ov7740_ctrl_ops = {
0587 .g_volatile_ctrl = ov7740_get_volatile_ctrl,
0588 .s_ctrl = ov7740_set_ctrl,
0589 };
0590
0591 static int ov7740_start_streaming(struct ov7740 *ov7740)
0592 {
0593 int ret;
0594
0595 if (ov7740->fmt) {
0596 ret = regmap_multi_reg_write(ov7740->regmap,
0597 ov7740->fmt->regs,
0598 ov7740->fmt->reg_num);
0599 if (ret)
0600 return ret;
0601 }
0602
0603 if (ov7740->frmsize) {
0604 ret = regmap_multi_reg_write(ov7740->regmap,
0605 ov7740->frmsize->regs,
0606 ov7740->frmsize->reg_num);
0607 if (ret)
0608 return ret;
0609 }
0610
0611 return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);
0612 }
0613
0614 static int ov7740_set_stream(struct v4l2_subdev *sd, int enable)
0615 {
0616 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
0617 struct i2c_client *client = v4l2_get_subdevdata(sd);
0618 int ret = 0;
0619
0620 mutex_lock(&ov7740->mutex);
0621 if (ov7740->streaming == enable) {
0622 mutex_unlock(&ov7740->mutex);
0623 return 0;
0624 }
0625
0626 if (enable) {
0627 ret = pm_runtime_resume_and_get(&client->dev);
0628 if (ret < 0)
0629 goto err_unlock;
0630
0631 ret = ov7740_start_streaming(ov7740);
0632 if (ret)
0633 goto err_rpm_put;
0634 } else {
0635 pm_runtime_put(&client->dev);
0636 }
0637
0638 ov7740->streaming = enable;
0639
0640 mutex_unlock(&ov7740->mutex);
0641 return ret;
0642
0643 err_rpm_put:
0644 pm_runtime_put(&client->dev);
0645 err_unlock:
0646 mutex_unlock(&ov7740->mutex);
0647 return ret;
0648 }
0649
0650 static int ov7740_g_frame_interval(struct v4l2_subdev *sd,
0651 struct v4l2_subdev_frame_interval *ival)
0652 {
0653 struct v4l2_fract *tpf = &ival->interval;
0654
0655
0656 tpf->numerator = 1;
0657 tpf->denominator = 60;
0658
0659 return 0;
0660 }
0661
0662 static int ov7740_s_frame_interval(struct v4l2_subdev *sd,
0663 struct v4l2_subdev_frame_interval *ival)
0664 {
0665 struct v4l2_fract *tpf = &ival->interval;
0666
0667
0668 tpf->numerator = 1;
0669 tpf->denominator = 60;
0670
0671 return 0;
0672 }
0673
0674 static const struct v4l2_subdev_video_ops ov7740_subdev_video_ops = {
0675 .s_stream = ov7740_set_stream,
0676 .s_frame_interval = ov7740_s_frame_interval,
0677 .g_frame_interval = ov7740_g_frame_interval,
0678 };
0679
0680 static const struct reg_sequence ov7740_format_yuyv[] = {
0681 {0x12, 0x00},
0682 {0x36, 0x3f},
0683 {0x80, 0x7f},
0684 {0x83, 0x01},
0685 };
0686
0687 static const struct reg_sequence ov7740_format_bggr8[] = {
0688 {0x36, 0x2f},
0689 {0x80, 0x01},
0690 {0x83, 0x04},
0691 };
0692
0693 static const struct ov7740_pixfmt ov7740_formats[] = {
0694 {
0695 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
0696 .colorspace = V4L2_COLORSPACE_SRGB,
0697 .regs = ov7740_format_yuyv,
0698 .reg_num = ARRAY_SIZE(ov7740_format_yuyv),
0699 },
0700 {
0701 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
0702 .colorspace = V4L2_COLORSPACE_SRGB,
0703 .regs = ov7740_format_bggr8,
0704 .reg_num = ARRAY_SIZE(ov7740_format_bggr8),
0705 }
0706 };
0707 #define N_OV7740_FMTS ARRAY_SIZE(ov7740_formats)
0708
0709 static int ov7740_enum_mbus_code(struct v4l2_subdev *sd,
0710 struct v4l2_subdev_state *sd_state,
0711 struct v4l2_subdev_mbus_code_enum *code)
0712 {
0713 if (code->pad || code->index >= N_OV7740_FMTS)
0714 return -EINVAL;
0715
0716 code->code = ov7740_formats[code->index].mbus_code;
0717
0718 return 0;
0719 }
0720
0721 static int ov7740_enum_frame_interval(struct v4l2_subdev *sd,
0722 struct v4l2_subdev_state *sd_state,
0723 struct v4l2_subdev_frame_interval_enum *fie)
0724 {
0725 if (fie->pad)
0726 return -EINVAL;
0727
0728 if (fie->index >= 1)
0729 return -EINVAL;
0730
0731 if ((fie->width != VGA_WIDTH) || (fie->height != VGA_HEIGHT))
0732 return -EINVAL;
0733
0734 fie->interval.numerator = 1;
0735 fie->interval.denominator = 60;
0736
0737 return 0;
0738 }
0739
0740 static int ov7740_enum_frame_size(struct v4l2_subdev *sd,
0741 struct v4l2_subdev_state *sd_state,
0742 struct v4l2_subdev_frame_size_enum *fse)
0743 {
0744 if (fse->pad)
0745 return -EINVAL;
0746
0747 if (fse->index > 0)
0748 return -EINVAL;
0749
0750 fse->min_width = fse->max_width = VGA_WIDTH;
0751 fse->min_height = fse->max_height = VGA_HEIGHT;
0752
0753 return 0;
0754 }
0755
0756 static int ov7740_try_fmt_internal(struct v4l2_subdev *sd,
0757 struct v4l2_mbus_framefmt *fmt,
0758 const struct ov7740_pixfmt **ret_fmt,
0759 const struct ov7740_framesize **ret_frmsize)
0760 {
0761 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
0762 const struct ov7740_framesize *fsize = &ov7740_framesizes[0];
0763 int index, i;
0764
0765 for (index = 0; index < N_OV7740_FMTS; index++) {
0766 if (ov7740_formats[index].mbus_code == fmt->code)
0767 break;
0768 }
0769 if (index >= N_OV7740_FMTS) {
0770
0771 index = 0;
0772 fmt->code = ov7740_formats[0].mbus_code;
0773 }
0774 if (ret_fmt != NULL)
0775 *ret_fmt = ov7740_formats + index;
0776
0777 for (i = 0; i < ARRAY_SIZE(ov7740_framesizes); i++) {
0778 if ((fsize->width >= fmt->width) &&
0779 (fsize->height >= fmt->height)) {
0780 fmt->width = fsize->width;
0781 fmt->height = fsize->height;
0782 break;
0783 }
0784
0785 fsize++;
0786 }
0787 if (i >= ARRAY_SIZE(ov7740_framesizes)) {
0788 fsize = &ov7740_framesizes[0];
0789 fmt->width = fsize->width;
0790 fmt->height = fsize->height;
0791 }
0792 if (ret_frmsize != NULL)
0793 *ret_frmsize = fsize;
0794
0795 fmt->field = V4L2_FIELD_NONE;
0796 fmt->colorspace = ov7740_formats[index].colorspace;
0797
0798 ov7740->format = *fmt;
0799
0800 return 0;
0801 }
0802
0803 static int ov7740_set_fmt(struct v4l2_subdev *sd,
0804 struct v4l2_subdev_state *sd_state,
0805 struct v4l2_subdev_format *format)
0806 {
0807 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
0808 const struct ov7740_pixfmt *ovfmt;
0809 const struct ov7740_framesize *fsize;
0810 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
0811 struct v4l2_mbus_framefmt *mbus_fmt;
0812 #endif
0813 int ret;
0814
0815 mutex_lock(&ov7740->mutex);
0816 if (format->pad) {
0817 ret = -EINVAL;
0818 goto error;
0819 }
0820
0821 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
0822 ret = ov7740_try_fmt_internal(sd, &format->format, NULL, NULL);
0823 if (ret)
0824 goto error;
0825 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
0826 mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state,
0827 format->pad);
0828 *mbus_fmt = format->format;
0829 #endif
0830 mutex_unlock(&ov7740->mutex);
0831 return 0;
0832 }
0833
0834 ret = ov7740_try_fmt_internal(sd, &format->format, &ovfmt, &fsize);
0835 if (ret)
0836 goto error;
0837
0838 ov7740->fmt = ovfmt;
0839 ov7740->frmsize = fsize;
0840
0841 mutex_unlock(&ov7740->mutex);
0842 return 0;
0843
0844 error:
0845 mutex_unlock(&ov7740->mutex);
0846 return ret;
0847 }
0848
0849 static int ov7740_get_fmt(struct v4l2_subdev *sd,
0850 struct v4l2_subdev_state *sd_state,
0851 struct v4l2_subdev_format *format)
0852 {
0853 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
0854 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
0855 struct v4l2_mbus_framefmt *mbus_fmt;
0856 #endif
0857 int ret = 0;
0858
0859 mutex_lock(&ov7740->mutex);
0860 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
0861 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
0862 mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0);
0863 format->format = *mbus_fmt;
0864 ret = 0;
0865 #else
0866 ret = -EINVAL;
0867 #endif
0868 } else {
0869 format->format = ov7740->format;
0870 }
0871 mutex_unlock(&ov7740->mutex);
0872
0873 return ret;
0874 }
0875
0876 static const struct v4l2_subdev_pad_ops ov7740_subdev_pad_ops = {
0877 .enum_frame_interval = ov7740_enum_frame_interval,
0878 .enum_frame_size = ov7740_enum_frame_size,
0879 .enum_mbus_code = ov7740_enum_mbus_code,
0880 .get_fmt = ov7740_get_fmt,
0881 .set_fmt = ov7740_set_fmt,
0882 };
0883
0884 static const struct v4l2_subdev_ops ov7740_subdev_ops = {
0885 .core = &ov7740_subdev_core_ops,
0886 .video = &ov7740_subdev_video_ops,
0887 .pad = &ov7740_subdev_pad_ops,
0888 };
0889
0890 static void ov7740_get_default_format(struct v4l2_subdev *sd,
0891 struct v4l2_mbus_framefmt *format)
0892 {
0893 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
0894
0895 format->width = ov7740->frmsize->width;
0896 format->height = ov7740->frmsize->height;
0897 format->colorspace = ov7740->fmt->colorspace;
0898 format->code = ov7740->fmt->mbus_code;
0899 format->field = V4L2_FIELD_NONE;
0900 }
0901
0902 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
0903 static int ov7740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
0904 {
0905 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
0906 struct v4l2_mbus_framefmt *format =
0907 v4l2_subdev_get_try_format(sd, fh->state, 0);
0908
0909 mutex_lock(&ov7740->mutex);
0910 ov7740_get_default_format(sd, format);
0911 mutex_unlock(&ov7740->mutex);
0912
0913 return 0;
0914 }
0915
0916 static const struct v4l2_subdev_internal_ops ov7740_subdev_internal_ops = {
0917 .open = ov7740_open,
0918 };
0919 #endif
0920
0921 static int ov7740_probe_dt(struct i2c_client *client,
0922 struct ov7740 *ov7740)
0923 {
0924 ov7740->resetb_gpio = devm_gpiod_get_optional(&client->dev, "reset",
0925 GPIOD_OUT_HIGH);
0926 if (IS_ERR(ov7740->resetb_gpio)) {
0927 dev_info(&client->dev, "can't get %s GPIO\n", "reset");
0928 return PTR_ERR(ov7740->resetb_gpio);
0929 }
0930
0931 ov7740->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
0932 GPIOD_OUT_LOW);
0933 if (IS_ERR(ov7740->pwdn_gpio)) {
0934 dev_info(&client->dev, "can't get %s GPIO\n", "powerdown");
0935 return PTR_ERR(ov7740->pwdn_gpio);
0936 }
0937
0938 return 0;
0939 }
0940
0941 static int ov7740_detect(struct ov7740 *ov7740)
0942 {
0943 struct regmap *regmap = ov7740->regmap;
0944 unsigned int midh, midl, pidh, pidl;
0945 int ret;
0946
0947 ret = regmap_read(regmap, REG_MIDH, &midh);
0948 if (ret)
0949 return ret;
0950 if (midh != 0x7f)
0951 return -ENODEV;
0952
0953 ret = regmap_read(regmap, REG_MIDL, &midl);
0954 if (ret)
0955 return ret;
0956 if (midl != 0xa2)
0957 return -ENODEV;
0958
0959 ret = regmap_read(regmap, REG_PIDH, &pidh);
0960 if (ret)
0961 return ret;
0962 if (pidh != 0x77)
0963 return -ENODEV;
0964
0965 ret = regmap_read(regmap, REG_PIDL, &pidl);
0966 if (ret)
0967 return ret;
0968 if ((pidl != 0x40) && (pidl != 0x41) && (pidl != 0x42))
0969 return -ENODEV;
0970
0971 return 0;
0972 }
0973
0974 static int ov7740_init_controls(struct ov7740 *ov7740)
0975 {
0976 struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
0977 struct v4l2_ctrl_handler *ctrl_hdlr = &ov7740->ctrl_handler;
0978 int ret;
0979
0980 ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
0981 if (ret < 0)
0982 return ret;
0983
0984 ctrl_hdlr->lock = &ov7740->mutex;
0985 ov7740->auto_wb = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
0986 V4L2_CID_AUTO_WHITE_BALANCE,
0987 0, 1, 1, 1);
0988 ov7740->blue_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
0989 V4L2_CID_BLUE_BALANCE,
0990 0, 0xff, 1, 0x80);
0991 ov7740->red_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
0992 V4L2_CID_RED_BALANCE,
0993 0, 0xff, 1, 0x80);
0994
0995 ov7740->brightness = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
0996 V4L2_CID_BRIGHTNESS,
0997 -255, 255, 1, 0);
0998 ov7740->contrast = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
0999 V4L2_CID_CONTRAST,
1000 0, 127, 1, 0x20);
1001 ov7740->saturation = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1002 V4L2_CID_SATURATION, 0, 256, 1, 0x80);
1003 ov7740->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1004 V4L2_CID_HFLIP, 0, 1, 1, 0);
1005 ov7740->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1006 V4L2_CID_VFLIP, 0, 1, 1, 0);
1007
1008 ov7740->gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1009 V4L2_CID_GAIN, 0, 1023, 1, 500);
1010
1011 ov7740->auto_gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1012 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1013
1014 ov7740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1015 V4L2_CID_EXPOSURE, 0, 65535, 1, 500);
1016
1017 ov7740->auto_exposure = v4l2_ctrl_new_std_menu(ctrl_hdlr,
1018 &ov7740_ctrl_ops,
1019 V4L2_CID_EXPOSURE_AUTO,
1020 V4L2_EXPOSURE_MANUAL, 0,
1021 V4L2_EXPOSURE_AUTO);
1022
1023 v4l2_ctrl_auto_cluster(3, &ov7740->auto_wb, 0, false);
1024 v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true);
1025 v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure,
1026 V4L2_EXPOSURE_MANUAL, true);
1027
1028 if (ctrl_hdlr->error) {
1029 ret = ctrl_hdlr->error;
1030 dev_err(&client->dev, "controls initialisation failed (%d)\n",
1031 ret);
1032 goto error;
1033 }
1034
1035 ret = v4l2_ctrl_handler_setup(ctrl_hdlr);
1036 if (ret) {
1037 dev_err(&client->dev, "%s control init failed (%d)\n",
1038 __func__, ret);
1039 goto error;
1040 }
1041
1042 ov7740->subdev.ctrl_handler = ctrl_hdlr;
1043 return 0;
1044
1045 error:
1046 v4l2_ctrl_handler_free(ctrl_hdlr);
1047 mutex_destroy(&ov7740->mutex);
1048 return ret;
1049 }
1050
1051 static void ov7740_free_controls(struct ov7740 *ov7740)
1052 {
1053 v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
1054 mutex_destroy(&ov7740->mutex);
1055 }
1056
1057 #define OV7740_MAX_REGISTER 0xff
1058 static const struct regmap_config ov7740_regmap_config = {
1059 .reg_bits = 8,
1060 .val_bits = 8,
1061 .max_register = OV7740_MAX_REGISTER,
1062 };
1063
1064 static int ov7740_probe(struct i2c_client *client)
1065 {
1066 struct ov7740 *ov7740;
1067 struct v4l2_subdev *sd;
1068 int ret;
1069
1070 ov7740 = devm_kzalloc(&client->dev, sizeof(*ov7740), GFP_KERNEL);
1071 if (!ov7740)
1072 return -ENOMEM;
1073
1074 ov7740->xvclk = devm_clk_get(&client->dev, "xvclk");
1075 if (IS_ERR(ov7740->xvclk)) {
1076 ret = PTR_ERR(ov7740->xvclk);
1077 dev_err(&client->dev,
1078 "OV7740: fail to get xvclk: %d\n", ret);
1079 return ret;
1080 }
1081
1082 ret = ov7740_probe_dt(client, ov7740);
1083 if (ret)
1084 return ret;
1085
1086 ov7740->regmap = devm_regmap_init_sccb(client, &ov7740_regmap_config);
1087 if (IS_ERR(ov7740->regmap)) {
1088 ret = PTR_ERR(ov7740->regmap);
1089 dev_err(&client->dev, "Failed to allocate register map: %d\n",
1090 ret);
1091 return ret;
1092 }
1093
1094 sd = &ov7740->subdev;
1095 v4l2_i2c_subdev_init(sd, client, &ov7740_subdev_ops);
1096
1097 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1098 sd->internal_ops = &ov7740_subdev_internal_ops;
1099 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
1100 #endif
1101
1102 #if defined(CONFIG_MEDIA_CONTROLLER)
1103 ov7740->pad.flags = MEDIA_PAD_FL_SOURCE;
1104 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1105 ret = media_entity_pads_init(&sd->entity, 1, &ov7740->pad);
1106 if (ret)
1107 return ret;
1108 #endif
1109
1110 ret = ov7740_set_power(ov7740, 1);
1111 if (ret)
1112 return ret;
1113
1114 pm_runtime_set_active(&client->dev);
1115 pm_runtime_enable(&client->dev);
1116
1117 ret = ov7740_detect(ov7740);
1118 if (ret)
1119 goto error_detect;
1120
1121 mutex_init(&ov7740->mutex);
1122
1123 ret = ov7740_init_controls(ov7740);
1124 if (ret)
1125 goto error_init_controls;
1126
1127 v4l_info(client, "chip found @ 0x%02x (%s)\n",
1128 client->addr << 1, client->adapter->name);
1129
1130 ov7740->fmt = &ov7740_formats[0];
1131 ov7740->frmsize = &ov7740_framesizes[0];
1132
1133 ov7740_get_default_format(sd, &ov7740->format);
1134
1135 ret = v4l2_async_register_subdev(sd);
1136 if (ret)
1137 goto error_async_register;
1138
1139 pm_runtime_idle(&client->dev);
1140
1141 return 0;
1142
1143 error_async_register:
1144 v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
1145 error_init_controls:
1146 ov7740_free_controls(ov7740);
1147 error_detect:
1148 pm_runtime_disable(&client->dev);
1149 pm_runtime_set_suspended(&client->dev);
1150 ov7740_set_power(ov7740, 0);
1151 media_entity_cleanup(&ov7740->subdev.entity);
1152
1153 return ret;
1154 }
1155
1156 static int ov7740_remove(struct i2c_client *client)
1157 {
1158 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1159 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
1160
1161 mutex_destroy(&ov7740->mutex);
1162 v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
1163 media_entity_cleanup(&ov7740->subdev.entity);
1164 v4l2_async_unregister_subdev(sd);
1165 ov7740_free_controls(ov7740);
1166
1167 pm_runtime_get_sync(&client->dev);
1168 pm_runtime_disable(&client->dev);
1169 pm_runtime_set_suspended(&client->dev);
1170 pm_runtime_put_noidle(&client->dev);
1171
1172 ov7740_set_power(ov7740, 0);
1173 return 0;
1174 }
1175
1176 static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
1177 {
1178 struct v4l2_subdev *sd = dev_get_drvdata(dev);
1179 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
1180
1181 ov7740_set_power(ov7740, 0);
1182
1183 return 0;
1184 }
1185
1186 static int __maybe_unused ov7740_runtime_resume(struct device *dev)
1187 {
1188 struct v4l2_subdev *sd = dev_get_drvdata(dev);
1189 struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
1190
1191 return ov7740_set_power(ov7740, 1);
1192 }
1193
1194 static const struct i2c_device_id ov7740_id[] = {
1195 { "ov7740", 0 },
1196 { }
1197 };
1198 MODULE_DEVICE_TABLE(i2c, ov7740_id);
1199
1200 static const struct dev_pm_ops ov7740_pm_ops = {
1201 SET_RUNTIME_PM_OPS(ov7740_runtime_suspend, ov7740_runtime_resume, NULL)
1202 };
1203
1204 static const struct of_device_id ov7740_of_match[] = {
1205 {.compatible = "ovti,ov7740", },
1206 { },
1207 };
1208 MODULE_DEVICE_TABLE(of, ov7740_of_match);
1209
1210 static struct i2c_driver ov7740_i2c_driver = {
1211 .driver = {
1212 .name = "ov7740",
1213 .pm = &ov7740_pm_ops,
1214 .of_match_table = of_match_ptr(ov7740_of_match),
1215 },
1216 .probe_new = ov7740_probe,
1217 .remove = ov7740_remove,
1218 .id_table = ov7740_id,
1219 };
1220 module_i2c_driver(ov7740_i2c_driver);
1221
1222 MODULE_DESCRIPTION("The V4L2 driver for Omnivision 7740 sensor");
1223 MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
1224 MODULE_LICENSE("GPL v2");