Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2017 Microchip Corporation.
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 /* OV7740 register tables */
0019 #define REG_GAIN    0x00    /* Gain lower 8 bits (rest in vref) */
0020 #define REG_BGAIN   0x01    /* blue gain */
0021 #define REG_RGAIN   0x02    /* red gain */
0022 #define REG_GGAIN   0x03    /* green gain */
0023 #define REG_REG04   0x04    /* analog setting, don't change*/
0024 #define REG_BAVG    0x05    /* b channel average */
0025 #define REG_GAVG    0x06    /* g channel average */
0026 #define REG_RAVG    0x07    /* r channel average */
0027 
0028 #define REG_REG0C   0x0C    /* filp enable */
0029 #define REG0C_IMG_FLIP      0x80
0030 #define REG0C_IMG_MIRROR    0x40
0031 
0032 #define REG_REG0E   0x0E    /* blc line */
0033 #define REG_HAEC    0x0F    /* auto exposure cntrl */
0034 #define REG_AEC     0x10    /* auto exposure cntrl */
0035 
0036 #define REG_CLK     0x11    /* Clock control */
0037 #define REG_REG55   0x55    /* Clock PLL DIV/PreDiv */
0038 
0039 #define REG_REG12   0x12
0040 
0041 #define REG_REG13   0x13    /* auto/manual AGC, AEC, Write Balance*/
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    /* manufacture id byte */
0052 #define REG_MIDL    0x1D    /* manufacture id byre */
0053 #define REG_PIDH    0x0A    /* Product ID MSB */
0054 #define REG_PIDL    0x0B    /* Product ID LSB */
0055 
0056 #define REG_84      0x84    /* lots of stuff */
0057 #define REG_REG38   0x38    /* sub-addr */
0058 
0059 #define REG_AHSTART 0x17    /* Horiz start high bits */
0060 #define REG_AHSIZE  0x18
0061 #define REG_AVSTART 0x19    /* Vert start high bits */
0062 #define REG_AVSIZE  0x1A
0063 #define REG_PSHFT   0x1b    /* Pixel delay after HREF */
0064 
0065 #define REG_HOUTSIZE    0x31
0066 #define REG_VOUTSIZE    0x32
0067 #define REG_HVSIZEOFF   0x33
0068 #define REG_REG34   0x34    /* DSP output size H/V LSB*/
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    /* ygain for contrast control */
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;  /* Current format */
0091     const struct ov7740_framesize *frmsize;
0092     struct regmap *regmap;
0093     struct clk *xvclk;
0094     struct v4l2_ctrl_handler ctrl_handler;
0095     struct {
0096         /* gain cluster */
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         /* exposure cluster */
0111         struct v4l2_ctrl *auto_exposure;
0112         struct v4l2_ctrl *exposure;
0113     };
0114     struct {
0115         /* saturation/hue cluster */
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; /* To serialize asynchronus callbacks */
0123     bool streaming;     /* Streaming on/off */
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, &reg);
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     /* Turn off AEC/AGC */
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     /* Turn off AEC/AGC */
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, &reg);
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         /* default to first format */
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     { /* sentinel */ }
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     { /* sentinel */ },
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");