root/drivers/media/i2c/ov7740.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ov7740_get_register
  2. ov7740_set_register
  3. ov7740_set_power
  4. ov7740_set_white_balance
  5. ov7740_set_saturation
  6. ov7740_set_gain
  7. ov7740_set_autogain
  8. ov7740_set_brightness
  9. ov7740_set_contrast
  10. ov7740_get_gain
  11. ov7740_get_exp
  12. ov7740_set_exp
  13. ov7740_set_autoexp
  14. ov7740_get_volatile_ctrl
  15. ov7740_set_ctrl
  16. ov7740_start_streaming
  17. ov7740_set_stream
  18. ov7740_g_frame_interval
  19. ov7740_s_frame_interval
  20. ov7740_enum_mbus_code
  21. ov7740_enum_frame_interval
  22. ov7740_enum_frame_size
  23. ov7740_try_fmt_internal
  24. ov7740_set_fmt
  25. ov7740_get_fmt
  26. ov7740_get_default_format
  27. ov7740_open
  28. ov7740_probe_dt
  29. ov7740_detect
  30. ov7740_init_controls
  31. ov7740_free_controls
  32. ov7740_probe
  33. ov7740_remove
  34. ov7740_runtime_suspend
  35. ov7740_runtime_resume

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (c) 2017 Microchip Corporation.
   3 
   4 #include <linux/clk.h>
   5 #include <linux/delay.h>
   6 #include <linux/gpio/consumer.h>
   7 #include <linux/i2c.h>
   8 #include <linux/module.h>
   9 #include <linux/pm_runtime.h>
  10 #include <linux/regmap.h>
  11 #include <media/v4l2-ctrls.h>
  12 #include <media/v4l2-event.h>
  13 #include <media/v4l2-image-sizes.h>
  14 #include <media/v4l2-subdev.h>
  15 
  16 #define REG_OUTSIZE_LSB 0x34
  17 
  18 /* OV7740 register tables */
  19 #define REG_GAIN        0x00    /* Gain lower 8 bits (rest in vref) */
  20 #define REG_BGAIN       0x01    /* blue gain */
  21 #define REG_RGAIN       0x02    /* red gain */
  22 #define REG_GGAIN       0x03    /* green gain */
  23 #define REG_REG04       0x04    /* analog setting, don't change*/
  24 #define REG_BAVG        0x05    /* b channel average */
  25 #define REG_GAVG        0x06    /* g channel average */
  26 #define REG_RAVG        0x07    /* r channel average */
  27 
  28 #define REG_REG0C       0x0C    /* filp enable */
  29 #define REG0C_IMG_FLIP          0x80
  30 #define REG0C_IMG_MIRROR        0x40
  31 
  32 #define REG_REG0E       0x0E    /* blc line */
  33 #define REG_HAEC        0x0F    /* auto exposure cntrl */
  34 #define REG_AEC         0x10    /* auto exposure cntrl */
  35 
  36 #define REG_CLK         0x11    /* Clock control */
  37 #define REG_REG55       0x55    /* Clock PLL DIV/PreDiv */
  38 
  39 #define REG_REG12       0x12
  40 
  41 #define REG_REG13       0x13    /* auto/manual AGC, AEC, Write Balance*/
  42 #define REG13_AEC_EN    0x01
  43 #define REG13_AGC_EN    0x04
  44 
  45 #define REG_REG14       0x14
  46 #define REG_CTRL15      0x15
  47 #define REG15_GAIN_MSB  0x03
  48 
  49 #define REG_REG16       0x16
  50 
  51 #define REG_MIDH        0x1C    /* manufacture id byte */
  52 #define REG_MIDL        0x1D    /* manufacture id byre */
  53 #define REG_PIDH        0x0A    /* Product ID MSB */
  54 #define REG_PIDL        0x0B    /* Product ID LSB */
  55 
  56 #define REG_84          0x84    /* lots of stuff */
  57 #define REG_REG38       0x38    /* sub-addr */
  58 
  59 #define REG_AHSTART     0x17    /* Horiz start high bits */
  60 #define REG_AHSIZE      0x18
  61 #define REG_AVSTART     0x19    /* Vert start high bits */
  62 #define REG_AVSIZE      0x1A
  63 #define REG_PSHFT       0x1b    /* Pixel delay after HREF */
  64 
  65 #define REG_HOUTSIZE    0x31
  66 #define REG_VOUTSIZE    0x32
  67 #define REG_HVSIZEOFF   0x33
  68 #define REG_REG34       0x34    /* DSP output size H/V LSB*/
  69 
  70 #define REG_ISP_CTRL00  0x80
  71 #define ISPCTRL00_AWB_EN        0x10
  72 #define ISPCTRL00_AWB_GAIN_EN   0x04
  73 
  74 #define REG_YGAIN       0xE2    /* ygain for contrast control */
  75 
  76 #define REG_YBRIGHT       0xE3
  77 #define REG_SGNSET        0xE4
  78 #define SGNSET_YBRIGHT_MASK       0x08
  79 
  80 #define REG_USAT        0xDD
  81 #define REG_VSAT        0xDE
  82 
  83 
  84 struct ov7740 {
  85         struct v4l2_subdev subdev;
  86 #if defined(CONFIG_MEDIA_CONTROLLER)
  87         struct media_pad pad;
  88 #endif
  89         struct v4l2_mbus_framefmt format;
  90         const struct ov7740_pixfmt *fmt;  /* Current format */
  91         const struct ov7740_framesize *frmsize;
  92         struct regmap *regmap;
  93         struct clk *xvclk;
  94         struct v4l2_ctrl_handler ctrl_handler;
  95         struct {
  96                 /* gain cluster */
  97                 struct v4l2_ctrl *auto_gain;
  98                 struct v4l2_ctrl *gain;
  99         };
 100         struct {
 101                 struct v4l2_ctrl *auto_wb;
 102                 struct v4l2_ctrl *blue_balance;
 103                 struct v4l2_ctrl *red_balance;
 104         };
 105         struct {
 106                 struct v4l2_ctrl *hflip;
 107                 struct v4l2_ctrl *vflip;
 108         };
 109         struct {
 110                 /* exposure cluster */
 111                 struct v4l2_ctrl *auto_exposure;
 112                 struct v4l2_ctrl *exposure;
 113         };
 114         struct {
 115                 /* saturation/hue cluster */
 116                 struct v4l2_ctrl *saturation;
 117                 struct v4l2_ctrl *hue;
 118         };
 119         struct v4l2_ctrl *brightness;
 120         struct v4l2_ctrl *contrast;
 121 
 122         struct mutex mutex;     /* To serialize asynchronus callbacks */
 123         bool streaming;         /* Streaming on/off */
 124 
 125         struct gpio_desc *resetb_gpio;
 126         struct gpio_desc *pwdn_gpio;
 127 };
 128 
 129 struct ov7740_pixfmt {
 130         u32 mbus_code;
 131         enum v4l2_colorspace colorspace;
 132         const struct reg_sequence *regs;
 133         u32 reg_num;
 134 };
 135 
 136 struct ov7740_framesize {
 137         u16 width;
 138         u16 height;
 139         const struct reg_sequence *regs;
 140         u32 reg_num;
 141 };
 142 
 143 static const struct reg_sequence ov7740_vga[] = {
 144         {0x55, 0x40},
 145         {0x11, 0x02},
 146 
 147         {0xd5, 0x10},
 148         {0x0c, 0x12},
 149         {0x0d, 0x34},
 150         {0x17, 0x25},
 151         {0x18, 0xa0},
 152         {0x19, 0x03},
 153         {0x1a, 0xf0},
 154         {0x1b, 0x89},
 155         {0x22, 0x03},
 156         {0x29, 0x18},
 157         {0x2b, 0xf8},
 158         {0x2c, 0x01},
 159         {REG_HOUTSIZE, 0xa0},
 160         {REG_VOUTSIZE, 0xf0},
 161         {0x33, 0xc4},
 162         {REG_OUTSIZE_LSB, 0x0},
 163         {0x35, 0x05},
 164         {0x04, 0x60},
 165         {0x27, 0x80},
 166         {0x3d, 0x0f},
 167         {0x3e, 0x80},
 168         {0x3f, 0x40},
 169         {0x40, 0x7f},
 170         {0x41, 0x6a},
 171         {0x42, 0x29},
 172         {0x44, 0x22},
 173         {0x45, 0x41},
 174         {0x47, 0x02},
 175         {0x49, 0x64},
 176         {0x4a, 0xa1},
 177         {0x4b, 0x40},
 178         {0x4c, 0x1a},
 179         {0x4d, 0x50},
 180         {0x4e, 0x13},
 181         {0x64, 0x00},
 182         {0x67, 0x88},
 183         {0x68, 0x1a},
 184 
 185         {0x14, 0x28},
 186         {0x24, 0x3c},
 187         {0x25, 0x30},
 188         {0x26, 0x72},
 189         {0x50, 0x97},
 190         {0x51, 0x1f},
 191         {0x52, 0x00},
 192         {0x53, 0x00},
 193         {0x20, 0x00},
 194         {0x21, 0xcf},
 195         {0x50, 0x4b},
 196         {0x38, 0x14},
 197         {0xe9, 0x00},
 198         {0x56, 0x55},
 199         {0x57, 0xff},
 200         {0x58, 0xff},
 201         {0x59, 0xff},
 202         {0x5f, 0x04},
 203         {0xec, 0x00},
 204         {0x13, 0xff},
 205 
 206         {0x81, 0x3f},
 207         {0x82, 0x32},
 208         {0x38, 0x11},
 209         {0x84, 0x70},
 210         {0x85, 0x00},
 211         {0x86, 0x03},
 212         {0x87, 0x01},
 213         {0x88, 0x05},
 214         {0x89, 0x30},
 215         {0x8d, 0x30},
 216         {0x8f, 0x85},
 217         {0x93, 0x30},
 218         {0x95, 0x85},
 219         {0x99, 0x30},
 220         {0x9b, 0x85},
 221 
 222         {0x9c, 0x08},
 223         {0x9d, 0x12},
 224         {0x9e, 0x23},
 225         {0x9f, 0x45},
 226         {0xa0, 0x55},
 227         {0xa1, 0x64},
 228         {0xa2, 0x72},
 229         {0xa3, 0x7f},
 230         {0xa4, 0x8b},
 231         {0xa5, 0x95},
 232         {0xa6, 0xa7},
 233         {0xa7, 0xb5},
 234         {0xa8, 0xcb},
 235         {0xa9, 0xdd},
 236         {0xaa, 0xec},
 237         {0xab, 0x1a},
 238 
 239         {0xce, 0x78},
 240         {0xcf, 0x6e},
 241         {0xd0, 0x0a},
 242         {0xd1, 0x0c},
 243         {0xd2, 0x84},
 244         {0xd3, 0x90},
 245         {0xd4, 0x1e},
 246 
 247         {0x5a, 0x24},
 248         {0x5b, 0x1f},
 249         {0x5c, 0x88},
 250         {0x5d, 0x60},
 251 
 252         {0xac, 0x6e},
 253         {0xbe, 0xff},
 254         {0xbf, 0x00},
 255 
 256         {0x0f, 0x1d},
 257         {0x0f, 0x1f},
 258 };
 259 
 260 static const struct ov7740_framesize ov7740_framesizes[] = {
 261         {
 262                 .width          = VGA_WIDTH,
 263                 .height         = VGA_HEIGHT,
 264                 .regs           = ov7740_vga,
 265                 .reg_num        = ARRAY_SIZE(ov7740_vga),
 266         },
 267 };
 268 
 269 #ifdef CONFIG_VIDEO_ADV_DEBUG
 270 static int ov7740_get_register(struct v4l2_subdev *sd,
 271                                struct v4l2_dbg_register *reg)
 272 {
 273         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 274         struct regmap *regmap = ov7740->regmap;
 275         unsigned int val = 0;
 276         int ret;
 277 
 278         ret = regmap_read(regmap, reg->reg & 0xff, &val);
 279         reg->val = val;
 280         reg->size = 1;
 281 
 282         return ret;
 283 }
 284 
 285 static int ov7740_set_register(struct v4l2_subdev *sd,
 286                                const struct v4l2_dbg_register *reg)
 287 {
 288         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 289         struct regmap *regmap = ov7740->regmap;
 290 
 291         regmap_write(regmap, reg->reg & 0xff, reg->val & 0xff);
 292 
 293         return 0;
 294 }
 295 #endif
 296 
 297 static int ov7740_set_power(struct ov7740 *ov7740, int on)
 298 {
 299         int ret;
 300 
 301         if (on) {
 302                 ret = clk_prepare_enable(ov7740->xvclk);
 303                 if (ret)
 304                         return ret;
 305 
 306                 if (ov7740->pwdn_gpio)
 307                         gpiod_direction_output(ov7740->pwdn_gpio, 0);
 308 
 309                 if (ov7740->resetb_gpio) {
 310                         gpiod_set_value(ov7740->resetb_gpio, 1);
 311                         usleep_range(500, 1000);
 312                         gpiod_set_value(ov7740->resetb_gpio, 0);
 313                         usleep_range(3000, 5000);
 314                 }
 315         } else {
 316                 clk_disable_unprepare(ov7740->xvclk);
 317 
 318                 if (ov7740->pwdn_gpio)
 319                         gpiod_direction_output(ov7740->pwdn_gpio, 0);
 320         }
 321 
 322         return 0;
 323 }
 324 
 325 static const struct v4l2_subdev_core_ops ov7740_subdev_core_ops = {
 326         .log_status = v4l2_ctrl_subdev_log_status,
 327 #ifdef CONFIG_VIDEO_ADV_DEBUG
 328         .g_register = ov7740_get_register,
 329         .s_register = ov7740_set_register,
 330 #endif
 331         .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
 332         .unsubscribe_event = v4l2_event_subdev_unsubscribe,
 333 };
 334 
 335 static int ov7740_set_white_balance(struct ov7740 *ov7740, int awb)
 336 {
 337         struct regmap *regmap = ov7740->regmap;
 338         unsigned int value;
 339         int ret;
 340 
 341         ret = regmap_read(regmap, REG_ISP_CTRL00, &value);
 342         if (!ret) {
 343                 if (awb)
 344                         value |= (ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
 345                 else
 346                         value &= ~(ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
 347                 ret = regmap_write(regmap, REG_ISP_CTRL00, value);
 348                 if (ret)
 349                         return ret;
 350         }
 351 
 352         if (!awb) {
 353                 ret = regmap_write(regmap, REG_BGAIN,
 354                                    ov7740->blue_balance->val);
 355                 if (ret)
 356                         return ret;
 357 
 358                 ret = regmap_write(regmap, REG_RGAIN, ov7740->red_balance->val);
 359                 if (ret)
 360                         return ret;
 361         }
 362 
 363         return 0;
 364 }
 365 
 366 static int ov7740_set_saturation(struct regmap *regmap, int value)
 367 {
 368         int ret;
 369 
 370         ret = regmap_write(regmap, REG_USAT, (unsigned char)value);
 371         if (ret)
 372                 return ret;
 373 
 374         return regmap_write(regmap, REG_VSAT, (unsigned char)value);
 375 }
 376 
 377 static int ov7740_set_gain(struct regmap *regmap, int value)
 378 {
 379         int ret;
 380 
 381         ret = regmap_write(regmap, REG_GAIN, value & 0xff);
 382         if (ret)
 383                 return ret;
 384 
 385         ret = regmap_update_bits(regmap, REG_CTRL15,
 386                                  REG15_GAIN_MSB, (value >> 8) & 0x3);
 387         if (!ret)
 388                 ret = regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
 389 
 390         return ret;
 391 }
 392 
 393 static int ov7740_set_autogain(struct regmap *regmap, int value)
 394 {
 395         unsigned int reg;
 396         int ret;
 397 
 398         ret = regmap_read(regmap, REG_REG13, &reg);
 399         if (ret)
 400                 return ret;
 401         if (value)
 402                 reg |= REG13_AGC_EN;
 403         else
 404                 reg &= ~REG13_AGC_EN;
 405         return regmap_write(regmap, REG_REG13, reg);
 406 }
 407 
 408 static int ov7740_set_brightness(struct regmap *regmap, int value)
 409 {
 410         /* Turn off AEC/AGC */
 411         regmap_update_bits(regmap, REG_REG13, REG13_AEC_EN, 0);
 412         regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
 413 
 414         if (value >= 0) {
 415                 regmap_write(regmap, REG_YBRIGHT, (unsigned char)value);
 416                 regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 0);
 417         } else{
 418                 regmap_write(regmap, REG_YBRIGHT, (unsigned char)(-value));
 419                 regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 1);
 420         }
 421 
 422         return 0;
 423 }
 424 
 425 static int ov7740_set_contrast(struct regmap *regmap, int value)
 426 {
 427         return regmap_write(regmap, REG_YGAIN, (unsigned char)value);
 428 }
 429 
 430 static int ov7740_get_gain(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
 431 {
 432         struct regmap *regmap = ov7740->regmap;
 433         unsigned int value0, value1;
 434         int ret;
 435 
 436         if (!ctrl->val)
 437                 return 0;
 438 
 439         ret = regmap_read(regmap, REG_GAIN, &value0);
 440         if (ret)
 441                 return ret;
 442         ret = regmap_read(regmap, REG_CTRL15, &value1);
 443         if (ret)
 444                 return ret;
 445 
 446         ov7740->gain->val = (value1 << 8) | (value0 & 0xff);
 447 
 448         return 0;
 449 }
 450 
 451 static int ov7740_get_exp(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
 452 {
 453         struct regmap *regmap = ov7740->regmap;
 454         unsigned int value0, value1;
 455         int ret;
 456 
 457         if (ctrl->val == V4L2_EXPOSURE_MANUAL)
 458                 return 0;
 459 
 460         ret = regmap_read(regmap, REG_AEC, &value0);
 461         if (ret)
 462                 return ret;
 463         ret = regmap_read(regmap, REG_HAEC, &value1);
 464         if (ret)
 465                 return ret;
 466 
 467         ov7740->exposure->val = (value1 << 8) | (value0 & 0xff);
 468 
 469         return 0;
 470 }
 471 
 472 static int ov7740_set_exp(struct regmap *regmap, int value)
 473 {
 474         int ret;
 475 
 476         /* Turn off AEC/AGC */
 477         ret = regmap_update_bits(regmap, REG_REG13,
 478                                  REG13_AEC_EN | REG13_AGC_EN, 0);
 479         if (ret)
 480                 return ret;
 481 
 482         ret = regmap_write(regmap, REG_AEC, (unsigned char)value);
 483         if (ret)
 484                 return ret;
 485 
 486         return regmap_write(regmap, REG_HAEC, (unsigned char)(value >> 8));
 487 }
 488 
 489 static int ov7740_set_autoexp(struct regmap *regmap,
 490                               enum v4l2_exposure_auto_type value)
 491 {
 492         unsigned int reg;
 493         int ret;
 494 
 495         ret = regmap_read(regmap, REG_REG13, &reg);
 496         if (!ret) {
 497                 if (value == V4L2_EXPOSURE_AUTO)
 498                         reg |= (REG13_AEC_EN | REG13_AGC_EN);
 499                 else
 500                         reg &= ~(REG13_AEC_EN | REG13_AGC_EN);
 501                 ret = regmap_write(regmap, REG_REG13, reg);
 502         }
 503 
 504         return ret;
 505 }
 506 
 507 
 508 static int ov7740_get_volatile_ctrl(struct v4l2_ctrl *ctrl)
 509 {
 510         struct ov7740 *ov7740 = container_of(ctrl->handler,
 511                                              struct ov7740, ctrl_handler);
 512         int ret;
 513 
 514         switch (ctrl->id) {
 515         case V4L2_CID_AUTOGAIN:
 516                 ret = ov7740_get_gain(ov7740, ctrl);
 517                 break;
 518         case V4L2_CID_EXPOSURE_AUTO:
 519                 ret = ov7740_get_exp(ov7740, ctrl);
 520                 break;
 521         default:
 522                 ret = -EINVAL;
 523                 break;
 524         }
 525         return ret;
 526 }
 527 
 528 static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
 529 {
 530         struct ov7740 *ov7740 = container_of(ctrl->handler,
 531                                              struct ov7740, ctrl_handler);
 532         struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
 533         struct regmap *regmap = ov7740->regmap;
 534         int ret;
 535         u8 val;
 536 
 537         if (!pm_runtime_get_if_in_use(&client->dev))
 538                 return 0;
 539 
 540         switch (ctrl->id) {
 541         case V4L2_CID_AUTO_WHITE_BALANCE:
 542                 ret = ov7740_set_white_balance(ov7740, ctrl->val);
 543                 break;
 544         case V4L2_CID_SATURATION:
 545                 ret = ov7740_set_saturation(regmap, ctrl->val);
 546                 break;
 547         case V4L2_CID_BRIGHTNESS:
 548                 ret = ov7740_set_brightness(regmap, ctrl->val);
 549                 break;
 550         case V4L2_CID_CONTRAST:
 551                 ret = ov7740_set_contrast(regmap, ctrl->val);
 552                 break;
 553         case V4L2_CID_VFLIP:
 554                 val = ctrl->val ? REG0C_IMG_FLIP : 0x00;
 555                 ret = regmap_update_bits(regmap, REG_REG0C,
 556                                          REG0C_IMG_FLIP, val);
 557                 break;
 558         case V4L2_CID_HFLIP:
 559                 val = ctrl->val ? REG0C_IMG_MIRROR : 0x00;
 560                 ret = regmap_update_bits(regmap, REG_REG0C,
 561                                          REG0C_IMG_MIRROR, val);
 562                 break;
 563         case V4L2_CID_AUTOGAIN:
 564                 if (!ctrl->val)
 565                         ret = ov7740_set_gain(regmap, ov7740->gain->val);
 566                 else
 567                         ret = ov7740_set_autogain(regmap, ctrl->val);
 568                 break;
 569 
 570         case V4L2_CID_EXPOSURE_AUTO:
 571                 if (ctrl->val == V4L2_EXPOSURE_MANUAL)
 572                         ret = ov7740_set_exp(regmap, ov7740->exposure->val);
 573                 else
 574                         ret = ov7740_set_autoexp(regmap, ctrl->val);
 575                 break;
 576         default:
 577                 ret = -EINVAL;
 578                 break;
 579         }
 580 
 581         pm_runtime_put(&client->dev);
 582 
 583         return ret;
 584 }
 585 
 586 static const struct v4l2_ctrl_ops ov7740_ctrl_ops = {
 587         .g_volatile_ctrl = ov7740_get_volatile_ctrl,
 588         .s_ctrl = ov7740_set_ctrl,
 589 };
 590 
 591 static int ov7740_start_streaming(struct ov7740 *ov7740)
 592 {
 593         int ret;
 594 
 595         if (ov7740->fmt) {
 596                 ret = regmap_multi_reg_write(ov7740->regmap,
 597                                              ov7740->fmt->regs,
 598                                              ov7740->fmt->reg_num);
 599                 if (ret)
 600                         return ret;
 601         }
 602 
 603         if (ov7740->frmsize) {
 604                 ret = regmap_multi_reg_write(ov7740->regmap,
 605                                              ov7740->frmsize->regs,
 606                                              ov7740->frmsize->reg_num);
 607                 if (ret)
 608                         return ret;
 609         }
 610 
 611         return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);
 612 }
 613 
 614 static int ov7740_set_stream(struct v4l2_subdev *sd, int enable)
 615 {
 616         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 617         struct i2c_client *client = v4l2_get_subdevdata(sd);
 618         int ret = 0;
 619 
 620         mutex_lock(&ov7740->mutex);
 621         if (ov7740->streaming == enable) {
 622                 mutex_unlock(&ov7740->mutex);
 623                 return 0;
 624         }
 625 
 626         if (enable) {
 627                 ret = pm_runtime_get_sync(&client->dev);
 628                 if (ret < 0) {
 629                         pm_runtime_put_noidle(&client->dev);
 630                         goto err_unlock;
 631                 }
 632 
 633                 ret = ov7740_start_streaming(ov7740);
 634                 if (ret)
 635                         goto err_rpm_put;
 636         } else {
 637                 pm_runtime_put(&client->dev);
 638         }
 639 
 640         ov7740->streaming = enable;
 641 
 642         mutex_unlock(&ov7740->mutex);
 643         return ret;
 644 
 645 err_rpm_put:
 646         pm_runtime_put(&client->dev);
 647 err_unlock:
 648         mutex_unlock(&ov7740->mutex);
 649         return ret;
 650 }
 651 
 652 static int ov7740_g_frame_interval(struct v4l2_subdev *sd,
 653                                    struct v4l2_subdev_frame_interval *ival)
 654 {
 655         struct v4l2_fract *tpf = &ival->interval;
 656 
 657 
 658         tpf->numerator = 1;
 659         tpf->denominator = 60;
 660 
 661         return 0;
 662 }
 663 
 664 static int ov7740_s_frame_interval(struct v4l2_subdev *sd,
 665                                    struct v4l2_subdev_frame_interval *ival)
 666 {
 667         struct v4l2_fract *tpf = &ival->interval;
 668 
 669 
 670         tpf->numerator = 1;
 671         tpf->denominator = 60;
 672 
 673         return 0;
 674 }
 675 
 676 static const struct v4l2_subdev_video_ops ov7740_subdev_video_ops = {
 677         .s_stream = ov7740_set_stream,
 678         .s_frame_interval = ov7740_s_frame_interval,
 679         .g_frame_interval = ov7740_g_frame_interval,
 680 };
 681 
 682 static const struct reg_sequence ov7740_format_yuyv[] = {
 683         {0x12, 0x00},
 684         {0x36, 0x3f},
 685         {0x80, 0x7f},
 686         {0x83, 0x01},
 687 };
 688 
 689 static const struct reg_sequence ov7740_format_bggr8[] = {
 690         {0x36, 0x2f},
 691         {0x80, 0x01},
 692         {0x83, 0x04},
 693 };
 694 
 695 static const struct ov7740_pixfmt ov7740_formats[] = {
 696         {
 697                 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
 698                 .colorspace = V4L2_COLORSPACE_SRGB,
 699                 .regs = ov7740_format_yuyv,
 700                 .reg_num = ARRAY_SIZE(ov7740_format_yuyv),
 701         },
 702         {
 703                 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
 704                 .colorspace = V4L2_COLORSPACE_SRGB,
 705                 .regs = ov7740_format_bggr8,
 706                 .reg_num = ARRAY_SIZE(ov7740_format_bggr8),
 707         }
 708 };
 709 #define N_OV7740_FMTS ARRAY_SIZE(ov7740_formats)
 710 
 711 static int ov7740_enum_mbus_code(struct v4l2_subdev *sd,
 712                                  struct v4l2_subdev_pad_config *cfg,
 713                                  struct v4l2_subdev_mbus_code_enum *code)
 714 {
 715         if (code->pad || code->index >= N_OV7740_FMTS)
 716                 return -EINVAL;
 717 
 718         code->code = ov7740_formats[code->index].mbus_code;
 719 
 720         return 0;
 721 }
 722 
 723 static int ov7740_enum_frame_interval(struct v4l2_subdev *sd,
 724                                 struct v4l2_subdev_pad_config *cfg,
 725                                 struct v4l2_subdev_frame_interval_enum *fie)
 726 {
 727         if (fie->pad)
 728                 return -EINVAL;
 729 
 730         if (fie->index >= 1)
 731                 return -EINVAL;
 732 
 733         if ((fie->width != VGA_WIDTH) || (fie->height != VGA_HEIGHT))
 734                 return -EINVAL;
 735 
 736         fie->interval.numerator = 1;
 737         fie->interval.denominator = 60;
 738 
 739         return 0;
 740 }
 741 
 742 static int ov7740_enum_frame_size(struct v4l2_subdev *sd,
 743                                   struct v4l2_subdev_pad_config *cfg,
 744                                   struct v4l2_subdev_frame_size_enum *fse)
 745 {
 746         if (fse->pad)
 747                 return -EINVAL;
 748 
 749         if (fse->index > 0)
 750                 return -EINVAL;
 751 
 752         fse->min_width = fse->max_width = VGA_WIDTH;
 753         fse->min_height = fse->max_height = VGA_HEIGHT;
 754 
 755         return 0;
 756 }
 757 
 758 static int ov7740_try_fmt_internal(struct v4l2_subdev *sd,
 759                                    struct v4l2_mbus_framefmt *fmt,
 760                                    const struct ov7740_pixfmt **ret_fmt,
 761                                    const struct ov7740_framesize **ret_frmsize)
 762 {
 763         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 764         const struct ov7740_framesize *fsize = &ov7740_framesizes[0];
 765         int index, i;
 766 
 767         for (index = 0; index < N_OV7740_FMTS; index++) {
 768                 if (ov7740_formats[index].mbus_code == fmt->code)
 769                         break;
 770         }
 771         if (index >= N_OV7740_FMTS) {
 772                 /* default to first format */
 773                 index = 0;
 774                 fmt->code = ov7740_formats[0].mbus_code;
 775         }
 776         if (ret_fmt != NULL)
 777                 *ret_fmt = ov7740_formats + index;
 778 
 779         for (i = 0; i < ARRAY_SIZE(ov7740_framesizes); i++) {
 780                 if ((fsize->width >= fmt->width) &&
 781                     (fsize->height >= fmt->height)) {
 782                         fmt->width = fsize->width;
 783                         fmt->height = fsize->height;
 784                         break;
 785                 }
 786 
 787                 fsize++;
 788         }
 789         if (i >= ARRAY_SIZE(ov7740_framesizes)) {
 790                 fsize = &ov7740_framesizes[0];
 791                 fmt->width = fsize->width;
 792                 fmt->height = fsize->height;
 793         }
 794         if (ret_frmsize != NULL)
 795                 *ret_frmsize = fsize;
 796 
 797         fmt->field = V4L2_FIELD_NONE;
 798         fmt->colorspace = ov7740_formats[index].colorspace;
 799 
 800         ov7740->format = *fmt;
 801 
 802         return 0;
 803 }
 804 
 805 static int ov7740_set_fmt(struct v4l2_subdev *sd,
 806                           struct v4l2_subdev_pad_config *cfg,
 807                           struct v4l2_subdev_format *format)
 808 {
 809         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 810         const struct ov7740_pixfmt *ovfmt;
 811         const struct ov7740_framesize *fsize;
 812 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 813         struct v4l2_mbus_framefmt *mbus_fmt;
 814 #endif
 815         int ret;
 816 
 817         mutex_lock(&ov7740->mutex);
 818         if (format->pad) {
 819                 ret = -EINVAL;
 820                 goto error;
 821         }
 822 
 823         if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
 824                 ret = ov7740_try_fmt_internal(sd, &format->format, NULL, NULL);
 825                 if (ret)
 826                         goto error;
 827 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 828                 mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
 829                 *mbus_fmt = format->format;
 830 #endif
 831                 mutex_unlock(&ov7740->mutex);
 832                 return 0;
 833         }
 834 
 835         ret = ov7740_try_fmt_internal(sd, &format->format, &ovfmt, &fsize);
 836         if (ret)
 837                 goto error;
 838 
 839         ov7740->fmt = ovfmt;
 840         ov7740->frmsize = fsize;
 841 
 842         mutex_unlock(&ov7740->mutex);
 843         return 0;
 844 
 845 error:
 846         mutex_unlock(&ov7740->mutex);
 847         return ret;
 848 }
 849 
 850 static int ov7740_get_fmt(struct v4l2_subdev *sd,
 851                           struct v4l2_subdev_pad_config *cfg,
 852                           struct v4l2_subdev_format *format)
 853 {
 854         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 855 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 856         struct v4l2_mbus_framefmt *mbus_fmt;
 857 #endif
 858         int ret = 0;
 859 
 860         mutex_lock(&ov7740->mutex);
 861         if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
 862 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 863                 mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
 864                 format->format = *mbus_fmt;
 865                 ret = 0;
 866 #else
 867                 ret = -EINVAL;
 868 #endif
 869         } else {
 870                 format->format = ov7740->format;
 871         }
 872         mutex_unlock(&ov7740->mutex);
 873 
 874         return ret;
 875 }
 876 
 877 static const struct v4l2_subdev_pad_ops ov7740_subdev_pad_ops = {
 878         .enum_frame_interval = ov7740_enum_frame_interval,
 879         .enum_frame_size = ov7740_enum_frame_size,
 880         .enum_mbus_code = ov7740_enum_mbus_code,
 881         .get_fmt = ov7740_get_fmt,
 882         .set_fmt = ov7740_set_fmt,
 883 };
 884 
 885 static const struct v4l2_subdev_ops ov7740_subdev_ops = {
 886         .core   = &ov7740_subdev_core_ops,
 887         .video  = &ov7740_subdev_video_ops,
 888         .pad    = &ov7740_subdev_pad_ops,
 889 };
 890 
 891 static void ov7740_get_default_format(struct v4l2_subdev *sd,
 892                                       struct v4l2_mbus_framefmt *format)
 893 {
 894         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 895 
 896         format->width = ov7740->frmsize->width;
 897         format->height = ov7740->frmsize->height;
 898         format->colorspace = ov7740->fmt->colorspace;
 899         format->code = ov7740->fmt->mbus_code;
 900         format->field = V4L2_FIELD_NONE;
 901 }
 902 
 903 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 904 static int ov7740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 905 {
 906         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 907         struct v4l2_mbus_framefmt *format =
 908                                 v4l2_subdev_get_try_format(sd, fh->pad, 0);
 909 
 910         mutex_lock(&ov7740->mutex);
 911         ov7740_get_default_format(sd, format);
 912         mutex_unlock(&ov7740->mutex);
 913 
 914         return 0;
 915 }
 916 
 917 static const struct v4l2_subdev_internal_ops ov7740_subdev_internal_ops = {
 918         .open = ov7740_open,
 919 };
 920 #endif
 921 
 922 static int ov7740_probe_dt(struct i2c_client *client,
 923                            struct ov7740 *ov7740)
 924 {
 925         ov7740->resetb_gpio = devm_gpiod_get_optional(&client->dev, "reset",
 926                         GPIOD_OUT_HIGH);
 927         if (IS_ERR(ov7740->resetb_gpio)) {
 928                 dev_info(&client->dev, "can't get %s GPIO\n", "reset");
 929                 return PTR_ERR(ov7740->resetb_gpio);
 930         }
 931 
 932         ov7740->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
 933                         GPIOD_OUT_LOW);
 934         if (IS_ERR(ov7740->pwdn_gpio)) {
 935                 dev_info(&client->dev, "can't get %s GPIO\n", "powerdown");
 936                 return PTR_ERR(ov7740->pwdn_gpio);
 937         }
 938 
 939         return 0;
 940 }
 941 
 942 static int ov7740_detect(struct ov7740 *ov7740)
 943 {
 944         struct regmap *regmap = ov7740->regmap;
 945         unsigned int midh, midl, pidh, pidl;
 946         int ret;
 947 
 948         ret = regmap_read(regmap, REG_MIDH, &midh);
 949         if (ret)
 950                 return ret;
 951         if (midh != 0x7f)
 952                 return -ENODEV;
 953 
 954         ret = regmap_read(regmap, REG_MIDL, &midl);
 955         if (ret)
 956                 return ret;
 957         if (midl != 0xa2)
 958                 return -ENODEV;
 959 
 960         ret = regmap_read(regmap, REG_PIDH, &pidh);
 961         if (ret)
 962                 return ret;
 963         if (pidh != 0x77)
 964                 return -ENODEV;
 965 
 966         ret = regmap_read(regmap, REG_PIDL, &pidl);
 967         if (ret)
 968                 return ret;
 969         if ((pidl != 0x40) && (pidl != 0x41) && (pidl != 0x42))
 970                 return -ENODEV;
 971 
 972         return 0;
 973 }
 974 
 975 static int ov7740_init_controls(struct ov7740 *ov7740)
 976 {
 977         struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
 978         struct v4l2_ctrl_handler *ctrl_hdlr = &ov7740->ctrl_handler;
 979         int ret;
 980 
 981         ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
 982         if (ret < 0)
 983                 return ret;
 984 
 985         ctrl_hdlr->lock = &ov7740->mutex;
 986         ov7740->auto_wb = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
 987                                           V4L2_CID_AUTO_WHITE_BALANCE,
 988                                           0, 1, 1, 1);
 989         ov7740->blue_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
 990                                                V4L2_CID_BLUE_BALANCE,
 991                                                0, 0xff, 1, 0x80);
 992         ov7740->red_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
 993                                               V4L2_CID_RED_BALANCE,
 994                                               0, 0xff, 1, 0x80);
 995 
 996         ov7740->brightness = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
 997                                              V4L2_CID_BRIGHTNESS,
 998                                              -255, 255, 1, 0);
 999         ov7740->contrast = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1000                                            V4L2_CID_CONTRAST,
1001                                            0, 127, 1, 0x20);
1002         ov7740->saturation = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1003                           V4L2_CID_SATURATION, 0, 256, 1, 0x80);
1004         ov7740->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1005                                         V4L2_CID_HFLIP, 0, 1, 1, 0);
1006         ov7740->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1007                                         V4L2_CID_VFLIP, 0, 1, 1, 0);
1008 
1009         ov7740->gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1010                                        V4L2_CID_GAIN, 0, 1023, 1, 500);
1011 
1012         ov7740->auto_gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1013                                             V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1014 
1015         ov7740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
1016                                            V4L2_CID_EXPOSURE, 0, 65535, 1, 500);
1017 
1018         ov7740->auto_exposure = v4l2_ctrl_new_std_menu(ctrl_hdlr,
1019                                         &ov7740_ctrl_ops,
1020                                         V4L2_CID_EXPOSURE_AUTO,
1021                                         V4L2_EXPOSURE_MANUAL, 0,
1022                                         V4L2_EXPOSURE_AUTO);
1023 
1024         v4l2_ctrl_auto_cluster(3, &ov7740->auto_wb, 0, false);
1025         v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true);
1026         v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure,
1027                                V4L2_EXPOSURE_MANUAL, true);
1028 
1029         if (ctrl_hdlr->error) {
1030                 ret = ctrl_hdlr->error;
1031                 dev_err(&client->dev, "controls initialisation failed (%d)\n",
1032                         ret);
1033                 goto error;
1034         }
1035 
1036         ret = v4l2_ctrl_handler_setup(ctrl_hdlr);
1037         if (ret) {
1038                 dev_err(&client->dev, "%s control init failed (%d)\n",
1039                         __func__, ret);
1040                 goto error;
1041         }
1042 
1043         ov7740->subdev.ctrl_handler = ctrl_hdlr;
1044         return 0;
1045 
1046 error:
1047         v4l2_ctrl_handler_free(ctrl_hdlr);
1048         mutex_destroy(&ov7740->mutex);
1049         return ret;
1050 }
1051 
1052 static void ov7740_free_controls(struct ov7740 *ov7740)
1053 {
1054         v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
1055         mutex_destroy(&ov7740->mutex);
1056 }
1057 
1058 #define OV7740_MAX_REGISTER     0xff
1059 static const struct regmap_config ov7740_regmap_config = {
1060         .reg_bits       = 8,
1061         .val_bits       = 8,
1062         .max_register   = OV7740_MAX_REGISTER,
1063 };
1064 
1065 static int ov7740_probe(struct i2c_client *client)
1066 {
1067         struct ov7740 *ov7740;
1068         struct v4l2_subdev *sd;
1069         int ret;
1070 
1071         if (!i2c_check_functionality(client->adapter,
1072                                      I2C_FUNC_SMBUS_BYTE_DATA)) {
1073                 dev_err(&client->dev,
1074                         "OV7740: I2C-Adapter doesn't support SMBUS\n");
1075                 return -EIO;
1076         }
1077 
1078         ov7740 = devm_kzalloc(&client->dev, sizeof(*ov7740), GFP_KERNEL);
1079         if (!ov7740)
1080                 return -ENOMEM;
1081 
1082         ov7740->xvclk = devm_clk_get(&client->dev, "xvclk");
1083         if (IS_ERR(ov7740->xvclk)) {
1084                 ret = PTR_ERR(ov7740->xvclk);
1085                 dev_err(&client->dev,
1086                         "OV7740: fail to get xvclk: %d\n", ret);
1087                 return ret;
1088         }
1089 
1090         ret = ov7740_probe_dt(client, ov7740);
1091         if (ret)
1092                 return ret;
1093 
1094         ov7740->regmap = devm_regmap_init_i2c(client, &ov7740_regmap_config);
1095         if (IS_ERR(ov7740->regmap)) {
1096                 ret = PTR_ERR(ov7740->regmap);
1097                 dev_err(&client->dev, "Failed to allocate register map: %d\n",
1098                         ret);
1099                 return ret;
1100         }
1101 
1102         sd = &ov7740->subdev;
1103         client->flags |= I2C_CLIENT_SCCB;
1104         v4l2_i2c_subdev_init(sd, client, &ov7740_subdev_ops);
1105 
1106 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1107         sd->internal_ops = &ov7740_subdev_internal_ops;
1108         sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
1109 #endif
1110 
1111 #if defined(CONFIG_MEDIA_CONTROLLER)
1112         ov7740->pad.flags = MEDIA_PAD_FL_SOURCE;
1113         sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1114         ret = media_entity_pads_init(&sd->entity, 1, &ov7740->pad);
1115         if (ret)
1116                 return ret;
1117 #endif
1118 
1119         ret = ov7740_set_power(ov7740, 1);
1120         if (ret)
1121                 return ret;
1122 
1123         pm_runtime_set_active(&client->dev);
1124         pm_runtime_enable(&client->dev);
1125 
1126         ret = ov7740_detect(ov7740);
1127         if (ret)
1128                 goto error_detect;
1129 
1130         mutex_init(&ov7740->mutex);
1131 
1132         ret = ov7740_init_controls(ov7740);
1133         if (ret)
1134                 goto error_init_controls;
1135 
1136         v4l_info(client, "chip found @ 0x%02x (%s)\n",
1137                         client->addr << 1, client->adapter->name);
1138 
1139         ov7740->fmt = &ov7740_formats[0];
1140         ov7740->frmsize = &ov7740_framesizes[0];
1141 
1142         ov7740_get_default_format(sd, &ov7740->format);
1143 
1144         ret = v4l2_async_register_subdev(sd);
1145         if (ret)
1146                 goto error_async_register;
1147 
1148         pm_runtime_idle(&client->dev);
1149 
1150         return 0;
1151 
1152 error_async_register:
1153         v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
1154 error_init_controls:
1155         ov7740_free_controls(ov7740);
1156 error_detect:
1157         pm_runtime_disable(&client->dev);
1158         pm_runtime_set_suspended(&client->dev);
1159         ov7740_set_power(ov7740, 0);
1160         media_entity_cleanup(&ov7740->subdev.entity);
1161 
1162         return ret;
1163 }
1164 
1165 static int ov7740_remove(struct i2c_client *client)
1166 {
1167         struct v4l2_subdev *sd = i2c_get_clientdata(client);
1168         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
1169 
1170         mutex_destroy(&ov7740->mutex);
1171         v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
1172         media_entity_cleanup(&ov7740->subdev.entity);
1173         v4l2_async_unregister_subdev(sd);
1174         ov7740_free_controls(ov7740);
1175 
1176         pm_runtime_get_sync(&client->dev);
1177         pm_runtime_disable(&client->dev);
1178         pm_runtime_set_suspended(&client->dev);
1179         pm_runtime_put_noidle(&client->dev);
1180 
1181         ov7740_set_power(ov7740, 0);
1182         return 0;
1183 }
1184 
1185 static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
1186 {
1187         struct i2c_client *client = to_i2c_client(dev);
1188         struct v4l2_subdev *sd = i2c_get_clientdata(client);
1189         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
1190 
1191         ov7740_set_power(ov7740, 0);
1192 
1193         return 0;
1194 }
1195 
1196 static int __maybe_unused ov7740_runtime_resume(struct device *dev)
1197 {
1198         struct i2c_client *client = to_i2c_client(dev);
1199         struct v4l2_subdev *sd = i2c_get_clientdata(client);
1200         struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
1201 
1202         return ov7740_set_power(ov7740, 1);
1203 }
1204 
1205 static const struct i2c_device_id ov7740_id[] = {
1206         { "ov7740", 0 },
1207         { /* sentinel */ }
1208 };
1209 MODULE_DEVICE_TABLE(i2c, ov7740_id);
1210 
1211 static const struct dev_pm_ops ov7740_pm_ops = {
1212         SET_RUNTIME_PM_OPS(ov7740_runtime_suspend, ov7740_runtime_resume, NULL)
1213 };
1214 
1215 static const struct of_device_id ov7740_of_match[] = {
1216         {.compatible = "ovti,ov7740", },
1217         { /* sentinel */ },
1218 };
1219 MODULE_DEVICE_TABLE(of, ov7740_of_match);
1220 
1221 static struct i2c_driver ov7740_i2c_driver = {
1222         .driver = {
1223                 .name = "ov7740",
1224                 .pm = &ov7740_pm_ops,
1225                 .of_match_table = of_match_ptr(ov7740_of_match),
1226         },
1227         .probe_new = ov7740_probe,
1228         .remove   = ov7740_remove,
1229         .id_table = ov7740_id,
1230 };
1231 module_i2c_driver(ov7740_i2c_driver);
1232 
1233 MODULE_DESCRIPTION("The V4L2 driver for Omnivision 7740 sensor");
1234 MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
1235 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */