Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * tw9910 Video Driver
0004  *
0005  * Copyright (C) 2017 Jacopo Mondi <jacopo+renesas@jmondi.org>
0006  *
0007  * Copyright (C) 2008 Renesas Solutions Corp.
0008  * Kuninori Morimoto <morimoto.kuninori@renesas.com>
0009  *
0010  * Based on ov772x driver,
0011  *
0012  * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
0013  * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
0014  * Copyright (C) 2008 Magnus Damm
0015  * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
0016  */
0017 
0018 #include <linux/clk.h>
0019 #include <linux/delay.h>
0020 #include <linux/gpio/consumer.h>
0021 #include <linux/i2c.h>
0022 #include <linux/init.h>
0023 #include <linux/kernel.h>
0024 #include <linux/module.h>
0025 #include <linux/slab.h>
0026 #include <linux/v4l2-mediabus.h>
0027 #include <linux/videodev2.h>
0028 
0029 #include <media/i2c/tw9910.h>
0030 #include <media/v4l2-subdev.h>
0031 
0032 #define GET_ID(val)  ((val & 0xF8) >> 3)
0033 #define GET_REV(val) (val & 0x07)
0034 
0035 /*
0036  * register offset
0037  */
0038 #define ID      0x00 /* Product ID Code Register */
0039 #define STATUS1     0x01 /* Chip Status Register I */
0040 #define INFORM      0x02 /* Input Format */
0041 #define OPFORM      0x03 /* Output Format Control Register */
0042 #define DLYCTR      0x04 /* Hysteresis and HSYNC Delay Control */
0043 #define OUTCTR1     0x05 /* Output Control I */
0044 #define ACNTL1      0x06 /* Analog Control Register 1 */
0045 #define CROP_HI     0x07 /* Cropping Register, High */
0046 #define VDELAY_LO   0x08 /* Vertical Delay Register, Low */
0047 #define VACTIVE_LO  0x09 /* Vertical Active Register, Low */
0048 #define HDELAY_LO   0x0A /* Horizontal Delay Register, Low */
0049 #define HACTIVE_LO  0x0B /* Horizontal Active Register, Low */
0050 #define CNTRL1      0x0C /* Control Register I */
0051 #define VSCALE_LO   0x0D /* Vertical Scaling Register, Low */
0052 #define SCALE_HI    0x0E /* Scaling Register, High */
0053 #define HSCALE_LO   0x0F /* Horizontal Scaling Register, Low */
0054 #define BRIGHT      0x10 /* BRIGHTNESS Control Register */
0055 #define CONTRAST    0x11 /* CONTRAST Control Register */
0056 #define SHARPNESS   0x12 /* SHARPNESS Control Register I */
0057 #define SAT_U       0x13 /* Chroma (U) Gain Register */
0058 #define SAT_V       0x14 /* Chroma (V) Gain Register */
0059 #define HUE     0x15 /* Hue Control Register */
0060 #define CORING1     0x17
0061 #define CORING2     0x18 /* Coring and IF compensation */
0062 #define VBICNTL     0x19 /* VBI Control Register */
0063 #define ACNTL2      0x1A /* Analog Control 2 */
0064 #define OUTCTR2     0x1B /* Output Control 2 */
0065 #define SDT     0x1C /* Standard Selection */
0066 #define SDTR        0x1D /* Standard Recognition */
0067 #define TEST        0x1F /* Test Control Register */
0068 #define CLMPG       0x20 /* Clamping Gain */
0069 #define IAGC        0x21 /* Individual AGC Gain */
0070 #define AGCGAIN     0x22 /* AGC Gain */
0071 #define PEAKWT      0x23 /* White Peak Threshold */
0072 #define CLMPL       0x24 /* Clamp level */
0073 #define SYNCT       0x25 /* Sync Amplitude */
0074 #define MISSCNT     0x26 /* Sync Miss Count Register */
0075 #define PCLAMP      0x27 /* Clamp Position Register */
0076 #define VCNTL1      0x28 /* Vertical Control I */
0077 #define VCNTL2      0x29 /* Vertical Control II */
0078 #define CKILL       0x2A /* Color Killer Level Control */
0079 #define COMB        0x2B /* Comb Filter Control */
0080 #define LDLY        0x2C /* Luma Delay and H Filter Control */
0081 #define MISC1       0x2D /* Miscellaneous Control I */
0082 #define LOOP        0x2E /* LOOP Control Register */
0083 #define MISC2       0x2F /* Miscellaneous Control II */
0084 #define MVSN        0x30 /* Macrovision Detection */
0085 #define STATUS2     0x31 /* Chip STATUS II */
0086 #define HFREF       0x32 /* H monitor */
0087 #define CLMD        0x33 /* CLAMP MODE */
0088 #define IDCNTL      0x34 /* ID Detection Control */
0089 #define CLCNTL1     0x35 /* Clamp Control I */
0090 #define ANAPLLCTL   0x4C
0091 #define VBIMIN      0x4D
0092 #define HSLOWCTL    0x4E
0093 #define WSS3        0x4F
0094 #define FILLDATA    0x50
0095 #define SDID        0x51
0096 #define DID     0x52
0097 #define WSS1        0x53
0098 #define WSS2        0x54
0099 #define VVBI        0x55
0100 #define LCTL6       0x56
0101 #define LCTL7       0x57
0102 #define LCTL8       0x58
0103 #define LCTL9       0x59
0104 #define LCTL10      0x5A
0105 #define LCTL11      0x5B
0106 #define LCTL12      0x5C
0107 #define LCTL13      0x5D
0108 #define LCTL14      0x5E
0109 #define LCTL15      0x5F
0110 #define LCTL16      0x60
0111 #define LCTL17      0x61
0112 #define LCTL18      0x62
0113 #define LCTL19      0x63
0114 #define LCTL20      0x64
0115 #define LCTL21      0x65
0116 #define LCTL22      0x66
0117 #define LCTL23      0x67
0118 #define LCTL24      0x68
0119 #define LCTL25      0x69
0120 #define LCTL26      0x6A
0121 #define HSBEGIN     0x6B
0122 #define HSEND       0x6C
0123 #define OVSDLY      0x6D
0124 #define OVSEND      0x6E
0125 #define VBIDELAY    0x6F
0126 
0127 /*
0128  * register detail
0129  */
0130 
0131 /* INFORM */
0132 #define FC27_ON     0x40 /* 1 : Input crystal clock frequency is 27MHz */
0133 #define FC27_FF     0x00 /* 0 : Square pixel mode. */
0134              /*     Must use 24.54MHz for 60Hz field rate */
0135              /*     source or 29.5MHz for 50Hz field rate */
0136 #define IFSEL_S     0x10 /* 01 : S-video decoding */
0137 #define IFSEL_C     0x00 /* 00 : Composite video decoding */
0138              /* Y input video selection */
0139 #define YSEL_M0     0x00 /*  00 : Mux0 selected */
0140 #define YSEL_M1     0x04 /*  01 : Mux1 selected */
0141 #define YSEL_M2     0x08 /*  10 : Mux2 selected */
0142 #define YSEL_M3     0x10 /*  11 : Mux3 selected */
0143 
0144 /* OPFORM */
0145 #define MODE        0x80 /* 0 : CCIR601 compatible YCrCb 4:2:2 format */
0146              /* 1 : ITU-R-656 compatible data sequence format */
0147 #define LEN         0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */
0148              /* 1 : 16-bit YCrCb 4:2:2 output format.*/
0149 #define LLCMODE     0x20 /* 1 : LLC output mode. */
0150              /* 0 : free-run output mode */
0151 #define AINC        0x10 /* Serial interface auto-indexing control */
0152              /* 0 : auto-increment */
0153              /* 1 : non-auto */
0154 #define VSCTL       0x08 /* 1 : Vertical out ctrl by DVALID */
0155              /* 0 : Vertical out ctrl by HACTIVE and DVALID */
0156 #define OEN_TRI_SEL_MASK    0x07
0157 #define OEN_TRI_SEL_ALL_ON  0x00 /* Enable output for Rev0/Rev1 */
0158 #define OEN_TRI_SEL_ALL_OFF_r0  0x06 /* All tri-stated for Rev0 */
0159 #define OEN_TRI_SEL_ALL_OFF_r1  0x07 /* All tri-stated for Rev1 */
0160 
0161 /* OUTCTR1 */
0162 #define VSP_LO      0x00 /* 0 : VS pin output polarity is active low */
0163 #define VSP_HI      0x80 /* 1 : VS pin output polarity is active high. */
0164              /* VS pin output control */
0165 #define VSSL_VSYNC  0x00 /*   0 : VSYNC  */
0166 #define VSSL_VACT   0x10 /*   1 : VACT   */
0167 #define VSSL_FIELD  0x20 /*   2 : FIELD  */
0168 #define VSSL_VVALID 0x30 /*   3 : VVALID */
0169 #define VSSL_ZERO   0x70 /*   7 : 0      */
0170 #define HSP_LOW     0x00 /* 0 : HS pin output polarity is active low */
0171 #define HSP_HI      0x08 /* 1 : HS pin output polarity is active high.*/
0172              /* HS pin output control */
0173 #define HSSL_HACT   0x00 /*   0 : HACT   */
0174 #define HSSL_HSYNC  0x01 /*   1 : HSYNC  */
0175 #define HSSL_DVALID 0x02 /*   2 : DVALID */
0176 #define HSSL_HLOCK  0x03 /*   3 : HLOCK  */
0177 #define HSSL_ASYNCW 0x04 /*   4 : ASYNCW */
0178 #define HSSL_ZERO   0x07 /*   7 : 0      */
0179 
0180 /* ACNTL1 */
0181 #define SRESET      0x80 /* resets the device to its default state
0182               * but all register content remain unchanged.
0183               * This bit is self-resetting.
0184               */
0185 #define ACNTL1_PDN_MASK 0x0e
0186 #define CLK_PDN     0x08 /* system clock power down */
0187 #define Y_PDN       0x04 /* Luma ADC power down */
0188 #define C_PDN       0x02 /* Chroma ADC power down */
0189 
0190 /* ACNTL2 */
0191 #define ACNTL2_PDN_MASK 0x40
0192 #define PLL_PDN     0x40 /* PLL power down */
0193 
0194 /* VBICNTL */
0195 
0196 /* RTSEL : control the real time signal output from the MPOUT pin */
0197 #define RTSEL_MASK  0x07
0198 #define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
0199 #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
0200 #define RTSEL_SLOCK 0x02 /* 0010 = S-lock */
0201 #define RTSEL_VLOCK 0x03 /* 0011 = V-lock */
0202 #define RTSEL_MONO  0x04 /* 0100 = MONO */
0203 #define RTSEL_DET50 0x05 /* 0101 = DET50 */
0204 #define RTSEL_FIELD 0x06 /* 0110 = FIELD */
0205 #define RTSEL_RTCO  0x07 /* 0111 = RTCO ( Real Time Control ) */
0206 
0207 /* HSYNC start and end are constant for now */
0208 #define HSYNC_START 0x0260
0209 #define HSYNC_END   0x0300
0210 
0211 /*
0212  * structure
0213  */
0214 
0215 struct regval_list {
0216     unsigned char reg_num;
0217     unsigned char value;
0218 };
0219 
0220 struct tw9910_scale_ctrl {
0221     char           *name;
0222     unsigned short  width;
0223     unsigned short  height;
0224     u16             hscale;
0225     u16             vscale;
0226 };
0227 
0228 struct tw9910_priv {
0229     struct v4l2_subdev      subdev;
0230     struct clk          *clk;
0231     struct tw9910_video_info    *info;
0232     struct gpio_desc        *pdn_gpio;
0233     struct gpio_desc        *rstb_gpio;
0234     const struct tw9910_scale_ctrl  *scale;
0235     v4l2_std_id         norm;
0236     u32             revision;
0237 };
0238 
0239 static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
0240     {
0241         .name   = "NTSC SQ",
0242         .width  = 640,
0243         .height = 480,
0244         .hscale = 0x0100,
0245         .vscale = 0x0100,
0246     },
0247     {
0248         .name   = "NTSC CCIR601",
0249         .width  = 720,
0250         .height = 480,
0251         .hscale = 0x0100,
0252         .vscale = 0x0100,
0253     },
0254     {
0255         .name   = "NTSC SQ (CIF)",
0256         .width  = 320,
0257         .height = 240,
0258         .hscale = 0x0200,
0259         .vscale = 0x0200,
0260     },
0261     {
0262         .name   = "NTSC CCIR601 (CIF)",
0263         .width  = 360,
0264         .height = 240,
0265         .hscale = 0x0200,
0266         .vscale = 0x0200,
0267     },
0268     {
0269         .name   = "NTSC SQ (QCIF)",
0270         .width  = 160,
0271         .height = 120,
0272         .hscale = 0x0400,
0273         .vscale = 0x0400,
0274     },
0275     {
0276         .name   = "NTSC CCIR601 (QCIF)",
0277         .width  = 180,
0278         .height = 120,
0279         .hscale = 0x0400,
0280         .vscale = 0x0400,
0281     },
0282 };
0283 
0284 static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
0285     {
0286         .name   = "PAL SQ",
0287         .width  = 768,
0288         .height = 576,
0289         .hscale = 0x0100,
0290         .vscale = 0x0100,
0291     },
0292     {
0293         .name   = "PAL CCIR601",
0294         .width  = 720,
0295         .height = 576,
0296         .hscale = 0x0100,
0297         .vscale = 0x0100,
0298     },
0299     {
0300         .name   = "PAL SQ (CIF)",
0301         .width  = 384,
0302         .height = 288,
0303         .hscale = 0x0200,
0304         .vscale = 0x0200,
0305     },
0306     {
0307         .name   = "PAL CCIR601 (CIF)",
0308         .width  = 360,
0309         .height = 288,
0310         .hscale = 0x0200,
0311         .vscale = 0x0200,
0312     },
0313     {
0314         .name   = "PAL SQ (QCIF)",
0315         .width  = 192,
0316         .height = 144,
0317         .hscale = 0x0400,
0318         .vscale = 0x0400,
0319     },
0320     {
0321         .name   = "PAL CCIR601 (QCIF)",
0322         .width  = 180,
0323         .height = 144,
0324         .hscale = 0x0400,
0325         .vscale = 0x0400,
0326     },
0327 };
0328 
0329 /*
0330  * general function
0331  */
0332 static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
0333 {
0334     return container_of(i2c_get_clientdata(client), struct tw9910_priv,
0335                 subdev);
0336 }
0337 
0338 static int tw9910_mask_set(struct i2c_client *client, u8 command,
0339                u8 mask, u8 set)
0340 {
0341     s32 val = i2c_smbus_read_byte_data(client, command);
0342 
0343     if (val < 0)
0344         return val;
0345 
0346     val &= ~mask;
0347     val |= set & mask;
0348 
0349     return i2c_smbus_write_byte_data(client, command, val);
0350 }
0351 
0352 static int tw9910_set_scale(struct i2c_client *client,
0353                 const struct tw9910_scale_ctrl *scale)
0354 {
0355     int ret;
0356 
0357     ret = i2c_smbus_write_byte_data(client, SCALE_HI,
0358                     (scale->vscale & 0x0F00) >> 4 |
0359                     (scale->hscale & 0x0F00) >> 8);
0360     if (ret < 0)
0361         return ret;
0362 
0363     ret = i2c_smbus_write_byte_data(client, HSCALE_LO,
0364                     scale->hscale & 0x00FF);
0365     if (ret < 0)
0366         return ret;
0367 
0368     ret = i2c_smbus_write_byte_data(client, VSCALE_LO,
0369                     scale->vscale & 0x00FF);
0370 
0371     return ret;
0372 }
0373 
0374 static int tw9910_set_hsync(struct i2c_client *client)
0375 {
0376     struct tw9910_priv *priv = to_tw9910(client);
0377     int ret;
0378 
0379     /* bit 10 - 3 */
0380     ret = i2c_smbus_write_byte_data(client, HSBEGIN,
0381                     (HSYNC_START & 0x07F8) >> 3);
0382     if (ret < 0)
0383         return ret;
0384 
0385     /* bit 10 - 3 */
0386     ret = i2c_smbus_write_byte_data(client, HSEND,
0387                     (HSYNC_END & 0x07F8) >> 3);
0388     if (ret < 0)
0389         return ret;
0390 
0391     /* So far only revisions 0 and 1 have been seen. */
0392     /* bit 2 - 0 */
0393     if (priv->revision == 1)
0394         ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
0395                       (HSYNC_START & 0x0007) << 4 |
0396                       (HSYNC_END   & 0x0007));
0397 
0398     return ret;
0399 }
0400 
0401 static void tw9910_reset(struct i2c_client *client)
0402 {
0403     tw9910_mask_set(client, ACNTL1, SRESET, SRESET);
0404     usleep_range(1000, 5000);
0405 }
0406 
0407 static int tw9910_power(struct i2c_client *client, int enable)
0408 {
0409     int ret;
0410     u8 acntl1;
0411     u8 acntl2;
0412 
0413     if (enable) {
0414         acntl1 = 0;
0415         acntl2 = 0;
0416     } else {
0417         acntl1 = CLK_PDN | Y_PDN | C_PDN;
0418         acntl2 = PLL_PDN;
0419     }
0420 
0421     ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1);
0422     if (ret < 0)
0423         return ret;
0424 
0425     return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
0426 }
0427 
0428 static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
0429                               u32 width, u32 height)
0430 {
0431     const struct tw9910_scale_ctrl *scale;
0432     const struct tw9910_scale_ctrl *ret = NULL;
0433     __u32 diff = 0xffffffff, tmp;
0434     int size, i;
0435 
0436     if (norm & V4L2_STD_NTSC) {
0437         scale = tw9910_ntsc_scales;
0438         size = ARRAY_SIZE(tw9910_ntsc_scales);
0439     } else if (norm & V4L2_STD_PAL) {
0440         scale = tw9910_pal_scales;
0441         size = ARRAY_SIZE(tw9910_pal_scales);
0442     } else {
0443         return NULL;
0444     }
0445 
0446     for (i = 0; i < size; i++) {
0447         tmp = abs(width - scale[i].width) +
0448               abs(height - scale[i].height);
0449         if (tmp < diff) {
0450             diff = tmp;
0451             ret = scale + i;
0452         }
0453     }
0454 
0455     return ret;
0456 }
0457 
0458 /*
0459  * subdevice operations
0460  */
0461 static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
0462 {
0463     struct i2c_client *client = v4l2_get_subdevdata(sd);
0464     struct tw9910_priv *priv = to_tw9910(client);
0465     u8 val;
0466     int ret;
0467 
0468     if (!enable) {
0469         switch (priv->revision) {
0470         case 0:
0471             val = OEN_TRI_SEL_ALL_OFF_r0;
0472             break;
0473         case 1:
0474             val = OEN_TRI_SEL_ALL_OFF_r1;
0475             break;
0476         default:
0477             dev_err(&client->dev, "un-supported revision\n");
0478             return -EINVAL;
0479         }
0480     } else {
0481         val = OEN_TRI_SEL_ALL_ON;
0482 
0483         if (!priv->scale) {
0484             dev_err(&client->dev, "norm select error\n");
0485             return -EPERM;
0486         }
0487 
0488         dev_dbg(&client->dev, "%s %dx%d\n",
0489             priv->scale->name,
0490             priv->scale->width,
0491             priv->scale->height);
0492     }
0493 
0494     ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
0495     if (ret < 0)
0496         return ret;
0497 
0498     return tw9910_power(client, enable);
0499 }
0500 
0501 static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
0502 {
0503     struct i2c_client *client = v4l2_get_subdevdata(sd);
0504     struct tw9910_priv *priv = to_tw9910(client);
0505 
0506     *norm = priv->norm;
0507 
0508     return 0;
0509 }
0510 
0511 static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
0512 {
0513     struct i2c_client *client = v4l2_get_subdevdata(sd);
0514     struct tw9910_priv *priv = to_tw9910(client);
0515     const unsigned int hact = 720;
0516     const unsigned int hdelay = 15;
0517     unsigned int vact;
0518     unsigned int vdelay;
0519     int ret;
0520 
0521     if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
0522         return -EINVAL;
0523 
0524     priv->norm = norm;
0525     if (norm & V4L2_STD_525_60) {
0526         vact = 240;
0527         vdelay = 18;
0528         ret = tw9910_mask_set(client, VVBI, 0x10, 0x10);
0529     } else {
0530         vact = 288;
0531         vdelay = 24;
0532         ret = tw9910_mask_set(client, VVBI, 0x10, 0x00);
0533     }
0534     if (!ret)
0535         ret = i2c_smbus_write_byte_data(client, CROP_HI,
0536                         ((vdelay >> 2) & 0xc0)  |
0537                         ((vact >> 4) & 0x30)    |
0538                         ((hdelay >> 6) & 0x0c)  |
0539                         ((hact >> 8) & 0x03));
0540     if (!ret)
0541         ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
0542                         vdelay & 0xff);
0543     if (!ret)
0544         ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
0545                         vact & 0xff);
0546 
0547     return ret;
0548 }
0549 
0550 #ifdef CONFIG_VIDEO_ADV_DEBUG
0551 static int tw9910_g_register(struct v4l2_subdev *sd,
0552                  struct v4l2_dbg_register *reg)
0553 {
0554     struct i2c_client *client = v4l2_get_subdevdata(sd);
0555     int ret;
0556 
0557     if (reg->reg > 0xff)
0558         return -EINVAL;
0559 
0560     reg->size = 1;
0561     ret = i2c_smbus_read_byte_data(client, reg->reg);
0562     if (ret < 0)
0563         return ret;
0564 
0565     /*
0566      * ret      = int
0567      * reg->val = __u64
0568      */
0569     reg->val = (__u64)ret;
0570 
0571     return 0;
0572 }
0573 
0574 static int tw9910_s_register(struct v4l2_subdev *sd,
0575                  const struct v4l2_dbg_register *reg)
0576 {
0577     struct i2c_client *client = v4l2_get_subdevdata(sd);
0578 
0579     if (reg->reg > 0xff ||
0580         reg->val > 0xff)
0581         return -EINVAL;
0582 
0583     return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
0584 }
0585 #endif
0586 
0587 static void tw9910_set_gpio_value(struct gpio_desc *desc, int value)
0588 {
0589     if (desc) {
0590         gpiod_set_value(desc, value);
0591         usleep_range(500, 1000);
0592     }
0593 }
0594 
0595 static int tw9910_power_on(struct tw9910_priv *priv)
0596 {
0597     struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
0598     int ret;
0599 
0600     if (priv->clk) {
0601         ret = clk_prepare_enable(priv->clk);
0602         if (ret)
0603             return ret;
0604     }
0605 
0606     tw9910_set_gpio_value(priv->pdn_gpio, 0);
0607 
0608     /*
0609      * FIXME: The reset signal is connected to a shared GPIO on some
0610      * platforms (namely the SuperH Migo-R). Until a framework becomes
0611      * available to handle this cleanly, request the GPIO temporarily
0612      * to avoid conflicts.
0613      */
0614     priv->rstb_gpio = gpiod_get_optional(&client->dev, "rstb",
0615                          GPIOD_OUT_LOW);
0616     if (IS_ERR(priv->rstb_gpio)) {
0617         dev_info(&client->dev, "Unable to get GPIO \"rstb\"");
0618         clk_disable_unprepare(priv->clk);
0619         tw9910_set_gpio_value(priv->pdn_gpio, 1);
0620         return PTR_ERR(priv->rstb_gpio);
0621     }
0622 
0623     if (priv->rstb_gpio) {
0624         tw9910_set_gpio_value(priv->rstb_gpio, 1);
0625         tw9910_set_gpio_value(priv->rstb_gpio, 0);
0626 
0627         gpiod_put(priv->rstb_gpio);
0628     }
0629 
0630     return 0;
0631 }
0632 
0633 static int tw9910_power_off(struct tw9910_priv *priv)
0634 {
0635     clk_disable_unprepare(priv->clk);
0636     tw9910_set_gpio_value(priv->pdn_gpio, 1);
0637 
0638     return 0;
0639 }
0640 
0641 static int tw9910_s_power(struct v4l2_subdev *sd, int on)
0642 {
0643     struct i2c_client *client = v4l2_get_subdevdata(sd);
0644     struct tw9910_priv *priv = to_tw9910(client);
0645 
0646     return on ? tw9910_power_on(priv) : tw9910_power_off(priv);
0647 }
0648 
0649 static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
0650 {
0651     struct i2c_client *client = v4l2_get_subdevdata(sd);
0652     struct tw9910_priv *priv = to_tw9910(client);
0653     int ret = -EINVAL;
0654     u8 val;
0655 
0656     /* Select suitable norm. */
0657     priv->scale = tw9910_select_norm(priv->norm, *width, *height);
0658     if (!priv->scale)
0659         goto tw9910_set_fmt_error;
0660 
0661     /* Reset hardware. */
0662     tw9910_reset(client);
0663 
0664     /* Set bus width. */
0665     val = 0x00;
0666     if (priv->info->buswidth == 16)
0667         val = LEN;
0668 
0669     ret = tw9910_mask_set(client, OPFORM, LEN, val);
0670     if (ret < 0)
0671         goto tw9910_set_fmt_error;
0672 
0673     /* Select MPOUT behavior. */
0674     switch (priv->info->mpout) {
0675     case TW9910_MPO_VLOSS:
0676         val = RTSEL_VLOSS; break;
0677     case TW9910_MPO_HLOCK:
0678         val = RTSEL_HLOCK; break;
0679     case TW9910_MPO_SLOCK:
0680         val = RTSEL_SLOCK; break;
0681     case TW9910_MPO_VLOCK:
0682         val = RTSEL_VLOCK; break;
0683     case TW9910_MPO_MONO:
0684         val = RTSEL_MONO;  break;
0685     case TW9910_MPO_DET50:
0686         val = RTSEL_DET50; break;
0687     case TW9910_MPO_FIELD:
0688         val = RTSEL_FIELD; break;
0689     case TW9910_MPO_RTCO:
0690         val = RTSEL_RTCO;  break;
0691     default:
0692         val = 0;
0693     }
0694 
0695     ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
0696     if (ret < 0)
0697         goto tw9910_set_fmt_error;
0698 
0699     /* Set scale. */
0700     ret = tw9910_set_scale(client, priv->scale);
0701     if (ret < 0)
0702         goto tw9910_set_fmt_error;
0703 
0704     /* Set hsync. */
0705     ret = tw9910_set_hsync(client);
0706     if (ret < 0)
0707         goto tw9910_set_fmt_error;
0708 
0709     *width = priv->scale->width;
0710     *height = priv->scale->height;
0711 
0712     return ret;
0713 
0714 tw9910_set_fmt_error:
0715 
0716     tw9910_reset(client);
0717     priv->scale = NULL;
0718 
0719     return ret;
0720 }
0721 
0722 static int tw9910_get_selection(struct v4l2_subdev *sd,
0723                 struct v4l2_subdev_state *sd_state,
0724                 struct v4l2_subdev_selection *sel)
0725 {
0726     struct i2c_client *client = v4l2_get_subdevdata(sd);
0727     struct tw9910_priv *priv = to_tw9910(client);
0728 
0729     if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
0730         return -EINVAL;
0731     /* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported. */
0732     if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS)
0733         return -EINVAL;
0734 
0735     sel->r.left = 0;
0736     sel->r.top  = 0;
0737     if (priv->norm & V4L2_STD_NTSC) {
0738         sel->r.width    = 640;
0739         sel->r.height   = 480;
0740     } else {
0741         sel->r.width    = 768;
0742         sel->r.height   = 576;
0743     }
0744 
0745     return 0;
0746 }
0747 
0748 static int tw9910_get_fmt(struct v4l2_subdev *sd,
0749               struct v4l2_subdev_state *sd_state,
0750               struct v4l2_subdev_format *format)
0751 {
0752     struct v4l2_mbus_framefmt *mf = &format->format;
0753     struct i2c_client *client = v4l2_get_subdevdata(sd);
0754     struct tw9910_priv *priv = to_tw9910(client);
0755 
0756     if (format->pad)
0757         return -EINVAL;
0758 
0759     if (!priv->scale) {
0760         priv->scale = tw9910_select_norm(priv->norm, 640, 480);
0761         if (!priv->scale)
0762             return -EINVAL;
0763     }
0764 
0765     mf->width   = priv->scale->width;
0766     mf->height  = priv->scale->height;
0767     mf->code    = MEDIA_BUS_FMT_UYVY8_2X8;
0768     mf->colorspace  = V4L2_COLORSPACE_SMPTE170M;
0769     mf->field   = V4L2_FIELD_INTERLACED_BT;
0770 
0771     return 0;
0772 }
0773 
0774 static int tw9910_s_fmt(struct v4l2_subdev *sd,
0775             struct v4l2_mbus_framefmt *mf)
0776 {
0777     u32 width = mf->width, height = mf->height;
0778     int ret;
0779 
0780     WARN_ON(mf->field != V4L2_FIELD_ANY &&
0781         mf->field != V4L2_FIELD_INTERLACED_BT);
0782 
0783     /* Check color format. */
0784     if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8)
0785         return -EINVAL;
0786 
0787     mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
0788 
0789     ret = tw9910_set_frame(sd, &width, &height);
0790     if (ret)
0791         return ret;
0792 
0793     mf->width   = width;
0794     mf->height  = height;
0795 
0796     return 0;
0797 }
0798 
0799 static int tw9910_set_fmt(struct v4l2_subdev *sd,
0800               struct v4l2_subdev_state *sd_state,
0801               struct v4l2_subdev_format *format)
0802 {
0803     struct v4l2_mbus_framefmt *mf = &format->format;
0804     struct i2c_client *client = v4l2_get_subdevdata(sd);
0805     struct tw9910_priv *priv = to_tw9910(client);
0806     const struct tw9910_scale_ctrl *scale;
0807 
0808     if (format->pad)
0809         return -EINVAL;
0810 
0811     if (mf->field == V4L2_FIELD_ANY) {
0812         mf->field = V4L2_FIELD_INTERLACED_BT;
0813     } else if (mf->field != V4L2_FIELD_INTERLACED_BT) {
0814         dev_err(&client->dev, "Field type %d invalid\n", mf->field);
0815         return -EINVAL;
0816     }
0817 
0818     mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
0819     mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
0820 
0821     /* Select suitable norm. */
0822     scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
0823     if (!scale)
0824         return -EINVAL;
0825 
0826     mf->width   = scale->width;
0827     mf->height  = scale->height;
0828 
0829     if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
0830         return tw9910_s_fmt(sd, mf);
0831 
0832     sd_state->pads->try_fmt = *mf;
0833 
0834     return 0;
0835 }
0836 
0837 static int tw9910_video_probe(struct i2c_client *client)
0838 {
0839     struct tw9910_priv *priv = to_tw9910(client);
0840     s32 id;
0841     int ret;
0842 
0843     /* TW9910 only use 8 or 16 bit bus width. */
0844     if (priv->info->buswidth != 16 && priv->info->buswidth != 8) {
0845         dev_err(&client->dev, "bus width error\n");
0846         return -ENODEV;
0847     }
0848 
0849     ret = tw9910_s_power(&priv->subdev, 1);
0850     if (ret < 0)
0851         return ret;
0852 
0853     /*
0854      * Check and show Product ID.
0855      * So far only revisions 0 and 1 have been seen.
0856      */
0857     id = i2c_smbus_read_byte_data(client, ID);
0858     priv->revision = GET_REV(id);
0859     id = GET_ID(id);
0860 
0861     if (id != 0x0b || priv->revision > 0x01) {
0862         dev_err(&client->dev, "Product ID error %x:%x\n",
0863             id, priv->revision);
0864         ret = -ENODEV;
0865         goto done;
0866     }
0867 
0868     dev_info(&client->dev, "tw9910 Product ID %0x:%0x\n",
0869          id, priv->revision);
0870 
0871     priv->norm = V4L2_STD_NTSC;
0872     priv->scale = &tw9910_ntsc_scales[0];
0873 
0874 done:
0875     tw9910_s_power(&priv->subdev, 0);
0876 
0877     return ret;
0878 }
0879 
0880 static const struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
0881 #ifdef CONFIG_VIDEO_ADV_DEBUG
0882     .g_register = tw9910_g_register,
0883     .s_register = tw9910_s_register,
0884 #endif
0885     .s_power    = tw9910_s_power,
0886 };
0887 
0888 static int tw9910_enum_mbus_code(struct v4l2_subdev *sd,
0889                  struct v4l2_subdev_state *sd_state,
0890                  struct v4l2_subdev_mbus_code_enum *code)
0891 {
0892     if (code->pad || code->index)
0893         return -EINVAL;
0894 
0895     code->code = MEDIA_BUS_FMT_UYVY8_2X8;
0896 
0897     return 0;
0898 }
0899 
0900 static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
0901 {
0902     *norm = V4L2_STD_NTSC | V4L2_STD_PAL;
0903 
0904     return 0;
0905 }
0906 
0907 static const struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
0908     .s_std      = tw9910_s_std,
0909     .g_std      = tw9910_g_std,
0910     .s_stream   = tw9910_s_stream,
0911     .g_tvnorms  = tw9910_g_tvnorms,
0912 };
0913 
0914 static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = {
0915     .enum_mbus_code = tw9910_enum_mbus_code,
0916     .get_selection  = tw9910_get_selection,
0917     .get_fmt    = tw9910_get_fmt,
0918     .set_fmt    = tw9910_set_fmt,
0919 };
0920 
0921 static const struct v4l2_subdev_ops tw9910_subdev_ops = {
0922     .core   = &tw9910_subdev_core_ops,
0923     .video  = &tw9910_subdev_video_ops,
0924     .pad    = &tw9910_subdev_pad_ops,
0925 };
0926 
0927 /*
0928  * i2c_driver function
0929  */
0930 
0931 static int tw9910_probe(struct i2c_client *client,
0932             const struct i2c_device_id *did)
0933 
0934 {
0935     struct tw9910_priv      *priv;
0936     struct tw9910_video_info    *info;
0937     struct i2c_adapter      *adapter = client->adapter;
0938     int ret;
0939 
0940     if (!client->dev.platform_data) {
0941         dev_err(&client->dev, "TW9910: missing platform data!\n");
0942         return -EINVAL;
0943     }
0944 
0945     info = client->dev.platform_data;
0946 
0947     if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
0948         dev_err(&client->dev,
0949             "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n");
0950         return -EIO;
0951     }
0952 
0953     priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
0954     if (!priv)
0955         return -ENOMEM;
0956 
0957     priv->info = info;
0958 
0959     v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
0960 
0961     priv->clk = clk_get(&client->dev, "xti");
0962     if (PTR_ERR(priv->clk) == -ENOENT) {
0963         priv->clk = NULL;
0964     } else if (IS_ERR(priv->clk)) {
0965         dev_err(&client->dev, "Unable to get xti clock\n");
0966         return PTR_ERR(priv->clk);
0967     }
0968 
0969     priv->pdn_gpio = gpiod_get_optional(&client->dev, "pdn",
0970                         GPIOD_OUT_HIGH);
0971     if (IS_ERR(priv->pdn_gpio)) {
0972         dev_info(&client->dev, "Unable to get GPIO \"pdn\"");
0973         ret = PTR_ERR(priv->pdn_gpio);
0974         goto error_clk_put;
0975     }
0976 
0977     ret = tw9910_video_probe(client);
0978     if (ret < 0)
0979         goto error_gpio_put;
0980 
0981     ret = v4l2_async_register_subdev(&priv->subdev);
0982     if (ret)
0983         goto error_gpio_put;
0984 
0985     return ret;
0986 
0987 error_gpio_put:
0988     if (priv->pdn_gpio)
0989         gpiod_put(priv->pdn_gpio);
0990 error_clk_put:
0991     clk_put(priv->clk);
0992 
0993     return ret;
0994 }
0995 
0996 static int tw9910_remove(struct i2c_client *client)
0997 {
0998     struct tw9910_priv *priv = to_tw9910(client);
0999 
1000     if (priv->pdn_gpio)
1001         gpiod_put(priv->pdn_gpio);
1002     clk_put(priv->clk);
1003     v4l2_async_unregister_subdev(&priv->subdev);
1004 
1005     return 0;
1006 }
1007 
1008 static const struct i2c_device_id tw9910_id[] = {
1009     { "tw9910", 0 },
1010     { }
1011 };
1012 MODULE_DEVICE_TABLE(i2c, tw9910_id);
1013 
1014 static struct i2c_driver tw9910_i2c_driver = {
1015     .driver = {
1016         .name = "tw9910",
1017     },
1018     .probe    = tw9910_probe,
1019     .remove   = tw9910_remove,
1020     .id_table = tw9910_id,
1021 };
1022 
1023 module_i2c_driver(tw9910_i2c_driver);
1024 
1025 MODULE_DESCRIPTION("V4L2 driver for TW9910 video decoder");
1026 MODULE_AUTHOR("Kuninori Morimoto");
1027 MODULE_LICENSE("GPL v2");