On 06/26/2017 08:03 AM, H. Nikolaus Schaller wrote:
> 
>> Am 22.06.2017 um 17:05 schrieb Hugues Fruchet <hugues.fruc...@st.com>:
>>
>> Add a first support of OV9655 variant.
>> Because of register set slightly different from OV9650/9652,
>> not all of the driver features are supported (controls).
>> Supported resolutions are limited to VGA, QVGA, QQVGA.
>> Supported format is limited to RGB565.
>> Controls are limited to color bar test pattern for test purpose.
>>
>> Signed-off-by: H. Nikolaus Schaller <h...@goldelico.com>
>> Signed-off-by: Hugues Fruchet <hugues.fruc...@st.com>
>> ---
>> drivers/media/i2c/Kconfig  |   4 +-
>> drivers/media/i2c/ov9650.c | 486 
>> ++++++++++++++++++++++++++++++++++++++++++---
>> 2 files changed, 457 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
>> index efea14d..a8f638c 100644
>> --- a/drivers/media/i2c/Kconfig
>> +++ b/drivers/media/i2c/Kconfig
>> @@ -594,11 +594,11 @@ config VIDEO_OV7670
>>        controller.
>>
>> config VIDEO_OV9650
>> -    tristate "OmniVision OV9650/OV9652 sensor support"
>> +    tristate "OmniVision OV9650/OV9652/OV9655 sensor support"
>>      depends on GPIOLIB && I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
>>      ---help---
>>        This is a V4L2 sensor-level driver for the Omnivision
>> -      OV9650 and OV9652 camera sensors.
>> +      OV9650 and OV9652 and OV9655 camera sensors.
>>
>> config VIDEO_VS6624
>>      tristate "ST VS6624 sensor support"
>> diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
>> index a9d268d..c0819af 100644
>> --- a/drivers/media/i2c/ov9650.c
>> +++ b/drivers/media/i2c/ov9650.c
>> @@ -1,5 +1,5 @@
>> /*
>> - * Omnivision OV9650/OV9652 CMOS Image Sensor driver
>> + * Omnivision OV9650/OV9652/OV9655 CMOS Image Sensor driver
>>   *
>>   * Copyright (C) 2013, Sylwester Nawrocki <sylvester.nawro...@gmail.com>
>>   *
>> @@ -7,6 +7,15 @@
>>   * by Vladimir Fonov.
>>   * Copyright (c) 2010, Vladimir Fonov
>>   *
>> + *
>> + * Copyright (C) STMicroelectronics SA 2017
>> + * Author: Hugues Fruchet <hugues.fruc...@st.com> for STMicroelectronics.
>> + *
>> + * OV9655 initial support based on a driver written by H. Nikolaus Schaller:
>> + *   
>> http://git.goldelico.com/?p=gta04-kernel.git;a=shortlog;h=refs/heads/work/hns/video/ov9655
>> + * OV9655 registers sequence from STM32CubeF7 embedded software, see:
>> + *   
>> https://developer.mbed.org/teams/ST/code/BSP_DISCO_F746NG/file/e1d9da7fe856/Drivers/BSP/Components/ov9655/ov9655.c
>> + *
>>   * This program is free software; you can redistribute it and/or modify
>>   * it under the terms of the GNU General Public License version 2 as
>>   * published by the Free Software Foundation.
>> @@ -58,14 +67,21 @@
>> #define REG_PID                      0x0a    /* Product ID MSB */
>> #define REG_VER                      0x0b    /* Product ID LSB */
>> #define REG_COM3             0x0c
>> -#define  COM3_SWAP          0x40
>> +#define  COM3_COLORBAR              0x80
>> +#define  COM3_RGB565                0x00
>> +#define  COM3_SWAP          0x40    /* Doesn't work in RGB */
>> +#define  COM3_RESETB                0x08
>> #define  COM3_VARIOPIXEL1    0x04
>> +#define  OV9655_SINGLEFRAME 0x01
>> #define REG_COM4             0x0d    /* Vario Pixels  */
>> #define  COM4_VARIOPIXEL2    0x80
>> +#define  OV9655_TRISTATE            /* seems to have a different function */
>> #define REG_COM5             0x0e    /* System clock options */
>> #define  COM5_SLAVE_MODE     0x10
>> -#define  COM5_SYSTEMCLOCK48MHZ      0x80
>> +#define  COM5_SYSTEMCLOCK48MHZ      0x80    /* not on OV9655 */
>> +#define  OV9655_EXPOSURESTEP        0x01
>> #define REG_COM6             0x0f    /* HREF & ADBLC options */
>> +#define  COM6_BLC_OPTICAL   0x40    /* Optical black */
>> #define REG_AECH             0x10    /* Exposure value, AEC[9:2] */
>> #define REG_CLKRC            0x11    /* Clock control */
>> #define  CLK_EXT             0x40    /* Use external clock directly */
>> @@ -74,13 +90,18 @@
>> #define  COM7_RESET          0x80
>> #define  COM7_FMT_MASK               0x38
>> #define  COM7_FMT_VGA                0x40
>> -#define      COM7_FMT_CIF           0x20
>> +#define  COM7_FMT_CIF               0x20
>> #define  COM7_FMT_QVGA               0x10
>> #define  COM7_FMT_QCIF               0x08
>> -#define      COM7_RGB               0x04
>> -#define      COM7_YUV               0x00
>> -#define      COM7_BAYER             0x01
>> -#define      COM7_PBAYER            0x05
>> +#define  COM7_RGB           0x04
>> +#define  COM7_YUV           0x00
>> +#define  COM7_BAYER         0x01
>> +#define  COM7_PBAYER                0x05
>> +#define  OV9655_COM7_VGA    0x60
>> +#define  OV9655_COM7_RAWRGB 0x00    /* different format encoding */
>> +#define  OV9655_COM7_RAWRGBINT      0x01
>> +#define  OV9655_COM7_YUV    0x02
>> +#define  OV9655_COM7_RGB    0x03
>> #define REG_COM8             0x13    /* AGC/AEC options */
>> #define  COM8_FASTAEC                0x80    /* Enable fast AGC/AEC */
>> #define  COM8_AECSTEP                0x40    /* Unlimited AEC step size */
>> @@ -89,14 +110,23 @@
>> #define  COM8_AWB            0x02    /* White balance enable */
>> #define  COM8_AEC            0x01    /* Auto exposure enable */
>> #define REG_COM9             0x14    /* Gain ceiling */
>> -#define  COM9_GAIN_CEIL_MASK        0x70    /* */
>> +#define  COM9_GAIN_CEIL_MASK        0x70
>> +#define  COM9_GAIN_CEIL_16X 0x30
>> +#define  OV9655_COM9_EXPTIMING      0x08
>> +#define  OV9655_COM9_VSYNCDROP      0x04
>> +#define  OV9655_COM9_AECDROP        0x02
>> #define REG_COM10            0x15    /* PCLK, HREF, HSYNC signals polarity */
>> +#define  OV9655_SLAVE_PIN   0x80    /* SLHS/SLVS instead of RESETB/PWDN */
>> #define  COM10_HSYNC         0x40    /* HSYNC instead of HREF */
>> #define  COM10_PCLK_HB               0x20    /* Suppress PCLK on horiz blank 
>> */
>> -#define  COM10_HREF_REV             0x08    /* Reverse HREF */
>> +#define  OV9655_COM10_PCLK_REV              0x10    /* PCLK reverse */
>> +#define  COM10_HREF_REV     0x08    /* Reverse HREF */
>> #define  COM10_VS_LEAD               0x04    /* VSYNC on clock leading edge 
>> */
>> +#define  OV9655_COM10_RESET_OPTION  0x04    /* Reset signal end point */
>> #define  COM10_VS_NEG                0x02    /* VSYNC negative */
>> #define  COM10_HS_NEG                0x01    /* HSYNC negative */
>> +#define OV9655_REG16                0x16    /* dummy frame and blanking */
>> +#define   OV9655_REG16_DUMMY_8      0x20    /* dummy frame when gain > 8 */
>> #define REG_HSTART           0x17    /* Horiz start high bits */
>> #define REG_HSTOP            0x18    /* Horiz stop high bits */
>> #define REG_VSTART           0x19    /* Vert start high bits */
>> @@ -117,6 +147,7 @@
>> #define REG_BBIAS            0x27    /* B channel output bias */
>> #define REG_GBBIAS           0x28    /* Gb channel output bias */
>> #define REG_GRCOM            0x29    /* Analog BLC & regulator */
>> +#define OV9655_PREGAIN              0x29
>> #define REG_EXHCH            0x2a    /* Dummy pixel insert MSB */
>> #define REG_EXHCL            0x2b    /* Dummy pixel insert LSB */
>> #define REG_RBIAS            0x2c    /* R channel output bias */
>> @@ -127,12 +158,30 @@
>> #define REG_HSYEN            0x31    /* HSYNC falling edge delay LSB*/
>> #define REG_HREF             0x32    /* HREF pieces */
>> #define REG_CHLF             0x33    /* reserved */
>> +#define OV9655_CLKF         0x33    /* Array current control */
>> +#define OV9655_AREF1                0x34    /* Array reference control */
>> +#define OV9655_AREF2                0x35    /* Array reference control */
>> +#define OV9655_AREF3                0x36    /* Array reference control */
>> #define REG_ADC                      0x37    /* reserved */
>> +#define OV9655_ADC          0x37    /* ADC Control 1 (Range adjustment) */
>> #define REG_ACOM             0x38    /* reserved */
>> -#define REG_OFON            0x39    /* Power down register */
>> +#define OV9655_ADC2         0x38    /* ADC Control 2 (Range adjustment) */
>> +#define REG_OFON            0x39    /* Power down register (ov9650 only) */
>> #define  OFON_PWRDN          0x08    /* Power down bit */
>> +#define OV9655_AREF4                0x39    /* Array reference control */
>> #define REG_TSLB             0x3a    /* YUVU format */
>> +#define  OV9655_PCLKDELAY2NS        0x40
>> +#define  OV9655_PCLKDELAY4NS        0x80
>> +#define  OV9655_PCLKDELAY6NS        0xc0
>> +#define  OV9655_OUTREVERSE  0x20
>> +#define  OV9655_FIXEDUV     0x10
>> #define  TSLB_YUYV_MASK              0x0c    /* UYVY or VYUY - see com13 */
>> +#define  TSLB_YUYV          0x00
>> +#define  TSLB_YVYU          0x04
>> +#define  TSLB_VYUY          0x08
>> +#define  TSLB_UYVY          0x0c
>> +#define  OV9655_BANDINGAUTO 0x02
>> +
>> #define REG_COM11            0x3b    /* Night mode, banding filter enable */
>> #define  COM11_NIGHT         0x80    /* Night mode enable */
>> #define  COM11_NMFR          0x60    /* Two bit NM frame rate */
>> @@ -142,25 +191,38 @@
>> #define  COM12_HREF          0x80    /* HREF always */
>> #define REG_COM13            0x3d    /* Gamma selection, Color matrix en. */
>> #define  COM13_GAMMA         0x80    /* Gamma enable */
>> -#define      COM13_UVSAT            0x40    /* UV saturation auto 
>> adjustment */
>> +#define  COM13_UVSAT                0x40    /* UV saturation auto 
>> adjustment */
>> +#define  COM13_Y_DELAY              0x08    /* Delay Y channel */
>> #define  COM13_UVSWAP                0x01    /* V before U - w/TSLB */
>> #define REG_COM14            0x3e    /* Edge enhancement options */
>> #define  COM14_EDGE_EN               0x02
>> #define  COM14_EEF_X2                0x01
>> +#define OV9655_REG_COM14    0x3e    /* pixel correction/zoom ON/OFF sel. */
>> +#define  OV9655_COM14_BLACK_PIX     0x08    /* Black pixel correction */
>> +#define  OV9655_COM14_WHITE_PIX     0x04    /* White pixel correction */
>> +#define  OV9655_COM14_ZOOM  0x02    /* Zoom function ON */
>> #define REG_EDGE             0x3f    /* Edge enhancement factor */
>> #define  EDGE_FACTOR_MASK    0x0f
>> #define REG_COM15            0x40    /* Output range, RGB 555/565 */
>> #define  COM15_R10F0         0x00    /* Data range 10 to F0 */
>> -#define      COM15_R01FE            0x80    /* 01 to FE */
>> +#define  COM15_R01FE                0x80    /* 01 to FE */
>> #define  COM15_R00FF         0xc0    /* 00 to FF */
>> #define  COM15_RGB565                0x10    /* RGB565 output */
>> #define  COM15_RGB555                0x30    /* RGB555 output */
>> #define  COM15_SWAPRB                0x04    /* Swap R&B */
>> #define REG_COM16            0x41    /* Color matrix coeff options */
>> #define REG_COM17            0x42    /* Single frame out, banding filter */
>> +#define OV9655_REG_COM17    0x42    /* Denoise, edge, auto gain, ... */
>> +#define   OV9655_COM17_EDGE_AUTO    0x40    /* Edge auto */
>> +#define   OV9655_COM17_DENOISE_AUTO 0x80    /* Denoise auto */
>> +#define OV9655_REG_RSVD(__n)        (0x43 + (__n) - 1) /* reserved but 
>> used... */
>> /* n = 1...9, 0x4f..0x57 */
>> -#define     REG_MTX(__n)            (0x4f + (__n) - 1)
>> +#define REG_MTX(__n)                (0x4f + (__n) - 1)
>> #define REG_MTXS             0x58
>> +#define REG_AWBOP(__n)              (0x59 + (__n) - 1) /* AWB control 
>> options */
>> +#define REG_BLMT            0x5F    /* AWB Blue Component Gain Limit */
>> +#define REG_RLMT            0x60    /* AWB Red Component Gain Limit */
>> +#define REG_GLMT            0x61    /* AWB Green Component Gain Limit */
>> /* Lens Correction Option 1...5, __n = 0...5 */
>> #define REG_LCC(__n)         (0x62 + (__n) - 1)
>> #define  LCC5_LCC_ENABLE     0x01    /* LCC5, enable lens correction */
>> @@ -170,10 +232,26 @@
>> #define REG_HV                       0x69    /* Manual banding filter MSB */
>> #define REG_MBD                      0x6a    /* Manual banding filter value 
>> */
>> #define REG_DBLV             0x6b    /* reserved */
>> +#define OV9655_REG_DBLV             0x6b    /* PLL, DVDD regu bypass, 
>> bandgap */
>> +#define  OV9655_DBLV_BANDGAP        0x0a    /* default value */
>> +#define  OV9655_DBLV_LDO_BYPASS     0x10
>> +#define  OV9655_DBLV_PLL_BYPASS     0x00
>> +#define  OV9655_DBLV_PLL_4X 0x40
>> +#define  OV9655_DBLV_PLL_6X 0x80
>> +#define  OV9655_DBLV_PLL_8X 0xc0
>> #define REG_GSP                      0x6c    /* Gamma curve */
>> #define  GSP_LEN             15
>> +#define OV9655_REG_DNSTH    0x70    /* De-noise Function Threshold Adj. */
>> +#define OV9655_REG_POIDX    0x72    /* Pixel output index */
>> +#define OV9655_REG_PCKDV    0x73    /* Pixel Clock Output Selection */
>> +#define OV9655_REG_XINDX    0x74    /* Horizontal Scaling Down Coeff. */
>> +#define OV9655_REG_YINDX    0x75    /* Vertical Scaling Down Coeff. */
>> +#define OV9655_REG_SLOP             0x7A    /* Gamma Curve Highest Segment 
>> Slope */
>> +#define OV9655_REG_GAM(__n) (0x7B + (__n) - 1)      /* Gamma curve */
>> #define REG_GST                      0x7c    /* Gamma curve */
>> #define  GST_LEN             15
>> +#define OV9655_REG_COM18    0x8b    /* Zoom mode in VGA */
>> +#define OV9655_REG_COM19    0x8c    /* UV adjustment */
>> #define REG_COM21            0x8b
>> #define REG_COM22            0x8c    /* Edge enhancement, denoising */
>> #define  COM22_WHTPCOR               0x02    /* White pixel correction 
>> enable */
>> @@ -181,6 +259,8 @@
>> #define  COM22_DENOISE               0x10    /* White pixel correction 
>> option */
>> #define REG_COM23            0x8d    /* Color bar test, color gain */
>> #define  COM23_TEST_MODE     0x10
>> +#define OV9655_REG_COM20    0x8d
>> +#define  OV9655_COM20_TEST_MODE     0x10
>> #define REG_DBLC1            0x8f    /* Digital BLC */
>> #define REG_DBLC_B           0x90    /* Digital BLC B channel offset */
>> #define REG_DBLC_R           0x91    /* Digital BLC R channel offset */
>> @@ -193,6 +273,17 @@
>> #define REG_AECHM            0xa1    /* Exposure value - bits AEC[15:10] */
>> #define REG_BD50ST           0xa2    /* Banding filter value for 50Hz */
>> #define REG_BD60ST           0xa3    /* Banding filter value for 60Hz */
>> +#define OV9655_REG_COM21    0xa4    /* Digital gain */
>> +#define OV9655_REG_AWB_GREEN        0xa6    /* AWB green */
>> +#define OV9655_REG_REF_A8   0xa8    /* Analog Reference Control */
>> +#define OV9655_REG_REF_A9   0xa9    /* Analog Reference Control */
>> +#define OV9655_REG_BLC(__n) (0xac + (__n) - 1) /* Black Level Control */
>> +#define OV9655_REG_CTRLB4   0xb4    /* UV adjustment */
>> +#define OV9655_REG_ADBOFF   0xbc    /* ADC B channel offset setting */
>> +#define OV9655_REG_ADROFF   0xbd    /* ADC R channel offset setting */
>> +#define OV9655_REG_ADGBOFF  0xbe    /* ADC Gb channel offset setting */
>> +#define OV9655_REG_ADGEOFF  0xbf    /* ADC Gr channel offset setting */
>> +#define OV9655_REG_COM24    0xc7    /* Pixel clock frequency selection */
>> #define REG_NULL             0xff    /* Array end token */
>>
>> #define DEF_CLKRC            0x80
>> @@ -200,6 +291,7 @@
>> #define OV965X_ID(_msb, _lsb)        ((_msb) << 8 | (_lsb))
>> #define OV9650_ID            0x9650
>> #define OV9652_ID            0x9652
>> +#define OV9655V5_ID         0x9657
>>
>> struct ov965x_ctrls {
>>      struct v4l2_ctrl_handler handler;
>> @@ -458,6 +550,292 @@ struct ov965x_pixfmt {
>>      {{ 1,   25  }, { QVGA_WIDTH, QVGA_HEIGHT }, 1 },  /* 25 fps */
>> };
>>
>> +/* OV9655 */
>> +static const struct i2c_rv ov9655_init_regs[] = {
>> +    { REG_GAIN, 0x00 },
>> +    { REG_BLUE, 0x80 },
>> +    { REG_RED, 0x80 },
>> +    { REG_VREF, 0x02 },
>> +    { REG_COM1, 0x03 },
>> +    { REG_COM2, 0x01 },/* Output drive x2 */
>> +    { REG_COM3, COM3_RGB565 },/* Output drive x2, RGB565 */
>> +    { REG_COM5, 0x60 | OV9655_EXPOSURESTEP },/* 0x60 ? */
>> +    { REG_COM6, COM6_BLC_OPTICAL },
>> +    { REG_CLKRC, 0x01 },/* F(internal clk) = F(input clk) / 2 */
>> +    { REG_COM7, OV9655_COM7_VGA | OV9655_COM7_YUV },
>> +    { REG_COM8, COM8_FASTAEC | COM8_AECSTEP |
>> +                    COM8_AGC | COM8_AWB | COM8_AEC },
>> +    { REG_COM9, COM9_GAIN_CEIL_16X | OV9655_COM9_EXPTIMING |
>> +                    OV9655_COM9_AECDROP },
>> +    { OV9655_REG16, OV9655_REG16_DUMMY_8 | 0x4 },
>> +    { REG_HSTART, 0x18 },
>> +    { REG_HSTOP, 0x04 },
>> +    { REG_VSTART, 0x01 },
>> +    { REG_VSTOP, 0x81 },
>> +    { REG_MVFP, 0x00 },/* No mirror/flip */
>> +    { REG_AEW, 0x3c },
>> +    { REG_AEB, 0x36 },
>> +    { REG_VPT, 0x72 },
>> +    { REG_BBIAS, 0x08 },
>> +    { REG_GBBIAS, 0x08 },
>> +    { OV9655_PREGAIN, 0x15 },
>> +    { REG_EXHCH, 0x00 },
>> +    { REG_EXHCL, 0x00 },
>> +    { REG_RBIAS, 0x08 },
>> +    { REG_HREF, 0x12 },/* QVGA */
>> +    { REG_CHLF, 0x00 },
>> +    { OV9655_AREF1, 0x3f },
>> +    { OV9655_AREF2, 0x00 },
>> +    { OV9655_AREF3, 0x3a },
>> +    { OV9655_ADC2, 0x72 },
>> +    { OV9655_AREF4, 0x57 },
>> +    { REG_TSLB, OV9655_PCLKDELAY6NS | TSLB_UYVY },
>> +    { REG_COM11, 0x04 },/* 0x04 ? */
>> +    { REG_COM13, COM13_GAMMA | 0x10 |
>> +                    COM13_Y_DELAY | COM13_UVSWAP },/* 0x10 ? */
>> +    {OV9655_REG_COM14, OV9655_COM14_ZOOM }, /* QVGA */
>> +    { REG_EDGE, 0xc1 },
>> +    { REG_COM15, COM15_R00FF },/* Full range output */
>> +    { REG_COM16, 0x41 },/* 0x41 ? */
>> +    { OV9655_REG_COM17, OV9655_COM17_EDGE_AUTO |
>> +                    OV9655_COM17_DENOISE_AUTO },
>> +    { OV9655_REG_RSVD(1), 0x0a },
>> +    { OV9655_REG_RSVD(2), 0xf0 },
>> +    { OV9655_REG_RSVD(3), 0x46 },
>> +    { OV9655_REG_RSVD(4), 0x62 },
>> +    { OV9655_REG_RSVD(5), 0x2a },
>> +    { OV9655_REG_RSVD(6), 0x3c },
>> +    { OV9655_REG_RSVD(7), 0xfc },
>> +    { OV9655_REG_RSVD(8), 0xfc },
>> +    { OV9655_REG_RSVD(9), 0x7f },
>> +    { OV9655_REG_RSVD(10), 0x7f },
>> +    { OV9655_REG_RSVD(11), 0x7f },
>> +    { REG_MTX(1), 0x98 },
>> +    { REG_MTX(2), 0x98 },
>> +    { REG_MTX(3), 0x00 },
>> +    { REG_MTX(4), 0x28 },
>> +    { REG_MTX(5), 0x70 },
>> +    { REG_MTX(6), 0x98 },
>> +    { REG_MTXS, 0x1a },
>> +    { REG_AWBOP(1), 0x85 },
>> +    { REG_AWBOP(2), 0xa9 },
>> +    { REG_AWBOP(3), 0x64 },
>> +    { REG_AWBOP(4), 0x84 },
>> +    { REG_AWBOP(5), 0x53 },
>> +    { REG_AWBOP(6), 0x0e },
>> +    { REG_BLMT, 0xf0 },
>> +    { REG_RLMT, 0xf0 },
>> +    { REG_GLMT, 0xf0 },
>> +    { REG_LCC(1), 0x00 },
>> +    { REG_LCC(2), 0x00 },
>> +    { REG_LCC(3), 0x02 },
>> +    { REG_LCC(4), 0x20 },
>> +    { REG_LCC(5), 0x00 },
>> +    { 0x69, 0x0a },/* Reserved... */
>> +    { OV9655_REG_DBLV, OV9655_DBLV_PLL_4X | OV9655_DBLV_LDO_BYPASS |
>> +                    OV9655_DBLV_BANDGAP },
>> +    { 0x6c, 0x04 },/* Reserved... */
>> +    { 0x6d, 0x55 },/* Reserved... */
>> +    { 0x6e, 0x00 },/* Reserved... */
>> +    { 0x6f, 0x9d },/* Reserved... */
>> +    { OV9655_REG_DNSTH, 0x21 },
>> +    { 0x71, 0x78 },/* Reserved... */
>> +    { OV9655_REG_POIDX, 0x11 },/* QVGA */
>> +    { OV9655_REG_PCKDV, 0x01 },/* QVGA */
>> +    { OV9655_REG_XINDX, 0x10 },
>> +    { OV9655_REG_YINDX, 0x10 },
>> +    { 0x76, 0x01 },/* Reserved... */
>> +    { 0x77, 0x02 },/* Reserved... */
>> +    { 0x7A, 0x12 },/* Reserved... */
>> +    { OV9655_REG_GAM(1), 0x08 },
>> +    { OV9655_REG_GAM(2), 0x16 },
>> +    { OV9655_REG_GAM(3), 0x30 },
>> +    { OV9655_REG_GAM(4), 0x5e },
>> +    { OV9655_REG_GAM(5), 0x72 },
>> +    { OV9655_REG_GAM(6), 0x82 },
>> +    { OV9655_REG_GAM(7), 0x8e },
>> +    { OV9655_REG_GAM(8), 0x9a },
>> +    { OV9655_REG_GAM(9), 0xa4 },
>> +    { OV9655_REG_GAM(10), 0xac },
>> +    { OV9655_REG_GAM(11), 0xb8 },
>> +    { OV9655_REG_GAM(12), 0xc3 },
>> +    { OV9655_REG_GAM(13), 0xd6 },
>> +    { OV9655_REG_GAM(14), 0xe6 },
>> +    { OV9655_REG_GAM(15), 0xf2 },
>> +    { 0x8a, 0x24 },/* Reserved... */
>> +    { OV9655_REG_COM19, 0x80 },
>> +    { 0x90, 0x7d },/* Reserved... */
>> +    { 0x91, 0x7b },/* Reserved... */
>> +    { REG_LCCFB, 0x02 },
>> +    { REG_LCCFR, 0x02 },
>> +    { REG_DBLC_GB, 0x7a },
>> +    { REG_DBLC_GR, 0x79 },
>> +    { REG_AECHM, 0x40 },
>> +    { OV9655_REG_COM21, 0x50 },
>> +    { 0xa5, 0x68 },/* Reserved... */
>> +    { OV9655_REG_AWB_GREEN, 0x4a },
>> +    { OV9655_REG_REF_A8, 0xc1 },
>> +    { OV9655_REG_REF_A9, 0xef },
>> +    { 0xaa, 0x92 },/* Reserved... */
>> +    { 0xab, 0x04 },/* Reserved... */
>> +    { OV9655_REG_BLC(1), 0x80 },
>> +    { OV9655_REG_BLC(2), 0x80 },
>> +    { OV9655_REG_BLC(3), 0x80 },
>> +    { OV9655_REG_BLC(4), 0x80 },
>> +    { OV9655_REG_BLC(7), 0xf2 },
>> +    { OV9655_REG_BLC(8), 0x20 },
>> +    { OV9655_REG_CTRLB4, 0x20 },
>> +    { 0xb5, 0x00 },/* Reserved... */
>> +    { 0xb6, 0xaf },/* Reserved... */
>> +    { 0xb6, 0xaf },/* Reserved... */
>> +    { 0xbb, 0xae },/* Reserved... */
>> +    { OV9655_REG_ADBOFF, 0x7f },
>> +    { OV9655_REG_ADROFF, 0x7f },
>> +    { OV9655_REG_ADGBOFF, 0x7f },
>> +    { OV9655_REG_ADGEOFF, 0x7f },
>> +    { OV9655_REG_ADGEOFF, 0x7f },
>> +    { 0xc0, 0xaa },/* Reserved... */
>> +    { 0xc1, 0xc0 },/* Reserved... */
>> +    { 0xc2, 0x01 },/* Reserved... */
>> +    { 0xc3, 0x4e },/* Reserved... */
>> +    { 0xc6, 0x05 },/* Reserved... */
>> +    { OV9655_REG_COM24, 0x81 },/* QVGA */
>> +    { 0xc9, 0xe0 },/* Reserved... */
>> +    { 0xca, 0xe8 },/* Reserved... */
>> +    { 0xcb, 0xf0 },/* Reserved... */
>> +    { 0xcc, 0xd8 },/* Reserved... */
>> +    { 0xcd, 0x93 },/* Reserved... */
>> +    { REG_COM7, OV9655_COM7_VGA | OV9655_COM7_RGB },
>> +    { REG_COM15, COM15_RGB565 },
>> +    { REG_NULL, 0}
>> +};
>> +
>> +static const struct i2c_rv ov9655_qvga_regs[] = {
>> +    { REG_HREF, 0x12 },
>> +    { OV9655_REG_COM14, OV9655_COM14_ZOOM },
>> +    { OV9655_REG_POIDX, 0x11 },
>> +    { OV9655_REG_PCKDV, 0x01 },
>> +    { OV9655_REG_COM24, 0x81 },
>> +    { REG_NULL, 0}
>> +};
>> +
>> +static const struct i2c_rv ov9655_qqvga_regs[] = {
>> +    { REG_HREF, 0xa4 },
>> +    { REG_COM14, OV9655_COM14_BLACK_PIX | OV9655_COM14_WHITE_PIX |
>> +                    OV9655_COM14_ZOOM },
>> +    { OV9655_REG_POIDX, 0x22 },
>> +    { OV9655_REG_PCKDV, 0x02 },
>> +    { OV9655_REG_COM24, 0x82 },
>> +    { REG_NULL, 0}
>> +};
>> +
>> +static const struct i2c_rv ov9655_vga_regs[] = {
>> +    { REG_GAIN, 0x11 },
>> +    { REG_VREF, 0x12 },
>> +    { REG_B_AVE, 0x2e },
>> +    { REG_GB_AVE, 0x2e },
>> +    { REG_GR_AVE, 0x2e },
>> +    { REG_R_AVE, 0x2e },
>> +    { REG_COM6, 0x48 },
>> +    { REG_AECH, 0x7b },
>> +    { REG_CLKRC, 0x03 },
>> +    { REG_COM8, COM8_FASTAEC | COM8_AECSTEP | COM8_BFILT |
>> +                    COM8_AGC | COM8_AWB | COM8_AEC },
>> +    { REG_HSTART, 0x16 },
>> +    { REG_HSTOP, 0x02 },
>> +    { REG_VSTART, 0x01 },
>> +    { REG_VSTOP, 0x3d },
>> +    { REG_MVFP, 0x04 },
>> +    { REG_YAVE, 0x2e },
>> +    { REG_HREF, 0xff },
>> +    { OV9655_AREF1, 0x3d },
>> +    { OV9655_AREF3, 0xfa },
>> +    { REG_TSLB, 0xcc },
>> +    { REG_COM11, 0xcc },
>> +    { REG_COM14, 0x0c },
>> +    { REG_EDGE, 0x82 },
>> +    { REG_COM15, COM15_R00FF | COM15_RGB565 },/* full range */
>> +    { REG_COM16, 0x40 },
>> +    { OV9655_REG_RSVD(1), 0x14 },
>> +    { OV9655_REG_RSVD(2), 0xf0 },
>> +    { OV9655_REG_RSVD(3), 0x46 },
>> +    { OV9655_REG_RSVD(4), 0x62 },
>> +    { OV9655_REG_RSVD(5), 0x2a },
>> +    { OV9655_REG_RSVD(6), 0x3c },
>> +    { OV9655_REG_RSVD(8), 0xe9 },
>> +    { OV9655_REG_RSVD(9), 0xdd },
>> +    { OV9655_REG_RSVD(10), 0xdd },
>> +    { OV9655_REG_RSVD(11), 0xdd },
>> +    { OV9655_REG_RSVD(12), 0xdd },
>> +    { REG_LCC(1), 0x00 },
>> +    { REG_LCC(2), 0x00 },
>> +    { REG_LCC(3), 0x02 },
>> +    { REG_LCC(4), 0x20 },
>> +    { REG_LCC(5), 0x01 },
>> +    { REG_GSP, 0x0c },
>> +    { 0x6f, 0x9e },/* Reserved... */
>> +    { OV9655_REG_DNSTH, 0x06 },
>> +    { OV9655_REG_POIDX, 0x00 },
>> +    { OV9655_REG_PCKDV, 0x00 },
>> +    { OV9655_REG_XINDX, 0x3a },
>> +    { OV9655_REG_YINDX, 0x35 },
>> +    { OV9655_REG_SLOP, 0x20 },
>> +    { OV9655_REG_GAM(1), 0x1c },
>> +    { OV9655_REG_GAM(2), 0x28 },
>> +    { OV9655_REG_GAM(3), 0x3c },
>> +    { OV9655_REG_GAM(4), 0x5a },
>> +    { OV9655_REG_GAM(5), 0x68 },
>> +    { OV9655_REG_GAM(6), 0x76 },
>> +    { OV9655_REG_GAM(7), 0x80 },
>> +    { OV9655_REG_GAM(8), 0x88 },
>> +    { OV9655_REG_GAM(9), 0x8f },
>> +    { OV9655_REG_GAM(10), 0x96 },
>> +    { OV9655_REG_GAM(11), 0xa3 },
>> +    { OV9655_REG_GAM(12), 0xaf },
>> +    { OV9655_REG_GAM(13), 0xc4 },
>> +    { OV9655_REG_GAM(14), 0xd7 },
>> +    { OV9655_REG_GAM(15), 0xe8 },
>> +    { 0x8a, 0x23 },/* Reserved... */
>> +    { OV9655_REG_COM19, 0x8d },
>> +    { 0x90, 0x92 },/* Reserved... */
>> +    { 0x91, 0x92 },/* Reserved... */
>> +    { REG_DBLC_GB, 0x90 },
>> +    { REG_DBLC_GR, 0x90 },
>> +    { OV9655_REG_AWB_GREEN, 0x40 },
>> +    { OV9655_REG_ADBOFF, 0x02 },
>> +    { OV9655_REG_ADROFF, 0x01 },
>> +    { OV9655_REG_ADGBOFF, 0x02 },
>> +    { OV9655_REG_ADGEOFF, 0x01 },
>> +    { 0xc1, 0xc8 },/* Reserved... */
>> +    { 0xc6, 0x85 },/* Reserved... */
>> +    { OV9655_REG_COM24, 0x80 },
>> +    { REG_NULL, 0}
>> +};
>> +
>> +static const struct ov965x_framesize ov9655_framesizes[] = {
>> +    {
>> +            .width          = VGA_WIDTH,
>> +            .height         = VGA_HEIGHT,
>> +            .regs           = ov9655_vga_regs,
>> +            .max_exp_lines  = 498,
>> +    }, {
>> +            .width          = QVGA_WIDTH,
>> +            .height         = QVGA_HEIGHT,
>> +            .regs           = ov9655_qvga_regs,
>> +            .max_exp_lines  = 248,
>> +    },
>> +    {
>> +            .width          = QQVGA_WIDTH,
>> +            .height         = QQVGA_HEIGHT,
>> +            .regs           = ov9655_qqvga_regs,
>> +            .max_exp_lines  = 124,
>> +    },
>> +};
>> +
>> +static const struct ov965x_pixfmt ov9655_formats[] = {
>> +    { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, 0x08},
>> +};
>> +
>> static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
>> {
>>      return &container_of(ctrl->handler, struct ov965x, ctrls.handler)->sd;
>> @@ -894,12 +1272,16 @@ static int ov965x_set_test_pattern(struct ov965x 
>> *ov965x, int value)
>> {
>>      int ret;
>>      u8 reg;
>> +    u8 addr = (ov965x->id == OV9655V5_ID) ?
>> +                    REG_COM3 : REG_COM23;
>> +    u8 mask = (ov965x->id == OV9655V5_ID) ?
>> +                    COM3_COLORBAR : COM23_TEST_MODE;
>>
>> -    ret = ov965x_read(ov965x->client, REG_COM23, &reg);
>> +    ret = ov965x_read(ov965x->client, addr, &reg);
>>      if (ret < 0)
>>              return ret;
>> -    reg = value ? reg | COM23_TEST_MODE : reg & ~COM23_TEST_MODE;
>> -    return ov965x_write(ov965x->client, REG_COM23, reg);
>> +    reg = value ? reg | mask : reg & ~mask;
>> +    return ov965x_write(ov965x->client, addr, reg);
>> }
>>
>> static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
>> @@ -1102,6 +1484,30 @@ static int ov965x_initialize_controls(struct ov965x 
>> *ov965x)
>>      return 0;
>> }
>>
>> +static int ov9655_initialize_controls(struct ov965x *ov965x)
>> +{
>> +    const struct v4l2_ctrl_ops *ops = &ov965x_ctrl_ops;
>> +    struct ov965x_ctrls *ctrls = &ov965x->ctrls;
>> +    struct v4l2_ctrl_handler *hdl = &ctrls->handler;
>> +    int ret;
>> +
>> +    ret = v4l2_ctrl_handler_init(hdl, 16);
>> +    if (ret < 0)
>> +            return ret;
>> +
>> +    v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
>> +                                 ARRAY_SIZE(test_pattern_menu) - 1, 0, 0,
>> +                                 test_pattern_menu);
>> +    if (hdl->error) {
>> +            ret = hdl->error;
>> +            v4l2_ctrl_handler_free(hdl);
>> +            return ret;
>> +    }
>> +
>> +    ov965x->sd.ctrl_handler = hdl;
>> +    return 0;
>> +}
>> +
>> /*
>>   * V4L2 subdev video and pad level operations
>>   */
>> @@ -1518,9 +1924,15 @@ static int ov965x_detect_sensor(struct v4l2_subdev 
>> *sd)
>>
>>      if (!ret) {
>>              ov965x->id = OV965X_ID(pid, ver);
>> -            if (ov965x->id == OV9650_ID || ov965x->id == OV9652_ID) {
>> +            switch (ov965x->id) {
>> +            case OV9650_ID:
>> +            case OV9652_ID:
>>                      v4l2_info(sd, "Found OV%04X sensor\n", ov965x->id);
>> -            } else {
>> +                    break;
>> +            case OV9655V5_ID:
>> +                    v4l2_info(sd, "Found OV%04X sensor\n", ov965x->id - 2);
>> +                    break;
>> +            default:
>>                      v4l2_err(sd, "Sensor detection failed (%04X, %d)\n",
>>                               ov965x->id, ret);
>>                      ret = -ENODEV;
>> @@ -1598,18 +2010,28 @@ static int ov965x_probe(struct i2c_client *client,
>>      if (ret < 0)
>>              goto err_me;
>>
>> -    ov965x->init_regs = ov965x_init_regs;
>> -    ov965x->initialize_controls = ov965x_initialize_controls;
>> -    ov965x->framesizes = ov965x_framesizes;
>> -    ov965x->nb_of_framesizes = ARRAY_SIZE(ov965x_framesizes);
>> -    ov965x->formats = ov965x_formats;
>> -    ov965x->nb_of_formats = ARRAY_SIZE(ov965x_formats);
>> -    ov965x->intervals = ov965x_intervals;
>> -    ov965x->nb_of_intervals = ARRAY_SIZE(ov965x_intervals);
>> -    ov965x->fiv = &ov965x_intervals[0];
>> -    ov965x->set_frame_interval = __ov965x_set_frame_interval;
>> -    ov965x->update_exposure_ctrl = ov965x_update_exposure_ctrl;
>> -    ov965x->set_params = __ov965x_set_params;
>> +    if (ov965x->id != OV9655V5_ID) {
>> +            ov965x->init_regs = ov965x_init_regs;
>> +            ov965x->initialize_controls = ov965x_initialize_controls;
>> +            ov965x->framesizes = ov965x_framesizes;
>> +            ov965x->nb_of_framesizes = ARRAY_SIZE(ov965x_framesizes);
>> +            ov965x->formats = ov965x_formats;
>> +            ov965x->nb_of_formats = ARRAY_SIZE(ov965x_formats);
>> +            ov965x->intervals = ov965x_intervals;
>> +            ov965x->nb_of_intervals = ARRAY_SIZE(ov965x_intervals);
>> +            ov965x->fiv = &ov965x_intervals[0];
>> +            ov965x->set_frame_interval = __ov965x_set_frame_interval;
>> +            ov965x->update_exposure_ctrl = ov965x_update_exposure_ctrl;
>> +            ov965x->set_params = __ov965x_set_params;
>> +    } else {
>> +            ov965x->init_regs = ov9655_init_regs;
>> +            ov965x->initialize_controls = ov9655_initialize_controls;
>> +            ov965x->framesizes = ov9655_framesizes;
>> +            ov965x->nb_of_framesizes = ARRAY_SIZE(ov9655_framesizes);
>> +            ov965x->formats = ov9655_formats;
>> +            ov965x->nb_of_formats = ARRAY_SIZE(ov9655_formats);
>> +            ov965x->set_params = ov965x_set_frame_size;
>> +    };
>>
>>      ov965x->frame_size = &ov965x->framesizes[0];
>>      ov965x_get_default_format(ov965x, &ov965x->format);
>> @@ -1652,6 +2074,7 @@ static int ov965x_remove(struct i2c_client *client)
>> static const struct i2c_device_id ov965x_id[] = {
>>      { "OV9650", 0x9650 },
>>      { "OV9652", 0x9652 },
>> +    { "OV9655", 0x9655 },
> 
> i2c device ids should be lower case to match compatible-strings in DT for
> automatic modprobing.
> 
> Please pick/merge/copy&paste
> 
> <http://git.goldelico.com/?p=gta04-kernel.git;a=blobdiff;f=drivers/media/i2c/ov9650.c;h=c310cbee131665893d2d1df0ab1246bd9b1d41fe;hp=ed5d0a53a9c72036d6e017094b68111b5eb7f00d;hb=115b9c59202aa2fb1fecb691ebeef51220d363b8;hpb=da8ae2b038a448c8f822b3a4f20ed378db6d2934>
> 
> With this change I get:
> 
> root@letux:~# dmesg|fgrep ov96
> [   12.727600] ov965x: Found OV9655 sensor
> [   12.747711] ov965x 1-0030: ov965x driver probed
> root@letux:~#
> 
> during probe.
> 

Thanks for patch, I'll fix in v2 !

>>      { /* sentinel */ }
>> };
>> MODULE_DEVICE_TABLE(i2c, ov965x_id);
>> @@ -1659,6 +2082,7 @@ static int ov965x_remove(struct i2c_client *client)
>> static const struct of_device_id ov965x_of_match[] = {
>>      { .compatible = "ovti,ov9650", .data = (void *)0x9650 },
>>      { .compatible = "ovti,ov9652", .data = (void *)0x9652 },
>> +    { .compatible = "ovti,ov9655", .data = (void *)0x9655 },
>>      { /* sentinel */ }
>> };
>> MODULE_DEVICE_TABLE(of, ov965x_of_match);
>> -- 
>> 1.9.1
>>
> 

Reply via email to