Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Video Capture Driver (Video for Linux 1/2)
0004  * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
0005  *
0006  * This module is an interface to the KS0127 video decoder chip.
0007  *
0008  * Copyright (C) 1999  Ryan Drake <stiletto@mediaone.net>
0009  *
0010  *****************************************************************************
0011  *
0012  * Modified and extended by
0013  *  Mike Bernson <mike@mlb.org>
0014  *  Gerard v.d. Horst
0015  *  Leon van Stuivenberg <l.vanstuivenberg@chello.nl>
0016  *  Gernot Ziegler <gz@lysator.liu.se>
0017  *
0018  * Version History:
0019  * V1.0 Ryan Drake     Initial version by Ryan Drake
0020  * V1.1 Gerard v.d. Horst  Added some debugoutput, reset the video-standard
0021  */
0022 
0023 #include <linux/init.h>
0024 #include <linux/module.h>
0025 #include <linux/delay.h>
0026 #include <linux/errno.h>
0027 #include <linux/kernel.h>
0028 #include <linux/i2c.h>
0029 #include <linux/videodev2.h>
0030 #include <linux/slab.h>
0031 #include <media/v4l2-device.h>
0032 #include "ks0127.h"
0033 
0034 MODULE_DESCRIPTION("KS0127 video decoder driver");
0035 MODULE_AUTHOR("Ryan Drake");
0036 MODULE_LICENSE("GPL");
0037 
0038 /* Addresses */
0039 #define I2C_KS0127_ADDON   0xD8
0040 #define I2C_KS0127_ONBOARD 0xDA
0041 
0042 
0043 /* ks0127 control registers */
0044 #define KS_STAT     0x00
0045 #define KS_CMDA     0x01
0046 #define KS_CMDB     0x02
0047 #define KS_CMDC     0x03
0048 #define KS_CMDD     0x04
0049 #define KS_HAVB     0x05
0050 #define KS_HAVE     0x06
0051 #define KS_HS1B     0x07
0052 #define KS_HS1E     0x08
0053 #define KS_HS2B     0x09
0054 #define KS_HS2E     0x0a
0055 #define KS_AGC      0x0b
0056 #define KS_HXTRA    0x0c
0057 #define KS_CDEM     0x0d
0058 #define KS_PORTAB   0x0e
0059 #define KS_LUMA     0x0f
0060 #define KS_CON      0x10
0061 #define KS_BRT      0x11
0062 #define KS_CHROMA   0x12
0063 #define KS_CHROMB   0x13
0064 #define KS_DEMOD    0x14
0065 #define KS_SAT      0x15
0066 #define KS_HUE      0x16
0067 #define KS_VERTIA   0x17
0068 #define KS_VERTIB   0x18
0069 #define KS_VERTIC   0x19
0070 #define KS_HSCLL    0x1a
0071 #define KS_HSCLH    0x1b
0072 #define KS_VSCLL    0x1c
0073 #define KS_VSCLH    0x1d
0074 #define KS_OFMTA    0x1e
0075 #define KS_OFMTB    0x1f
0076 #define KS_VBICTL   0x20
0077 #define KS_CCDAT2   0x21
0078 #define KS_CCDAT1   0x22
0079 #define KS_VBIL30   0x23
0080 #define KS_VBIL74   0x24
0081 #define KS_VBIL118  0x25
0082 #define KS_VBIL1512 0x26
0083 #define KS_TTFRAM   0x27
0084 #define KS_TESTA    0x28
0085 #define KS_UVOFFH   0x29
0086 #define KS_UVOFFL   0x2a
0087 #define KS_UGAIN    0x2b
0088 #define KS_VGAIN    0x2c
0089 #define KS_VAVB     0x2d
0090 #define KS_VAVE     0x2e
0091 #define KS_CTRACK   0x2f
0092 #define KS_POLCTL   0x30
0093 #define KS_REFCOD   0x31
0094 #define KS_INVALY   0x32
0095 #define KS_INVALU   0x33
0096 #define KS_INVALV   0x34
0097 #define KS_UNUSEY   0x35
0098 #define KS_UNUSEU   0x36
0099 #define KS_UNUSEV   0x37
0100 #define KS_USRSAV   0x38
0101 #define KS_USREAV   0x39
0102 #define KS_SHS1A    0x3a
0103 #define KS_SHS1B    0x3b
0104 #define KS_SHS1C    0x3c
0105 #define KS_CMDE     0x3d
0106 #define KS_VSDEL    0x3e
0107 #define KS_CMDF     0x3f
0108 #define KS_GAMMA0   0x40
0109 #define KS_GAMMA1   0x41
0110 #define KS_GAMMA2   0x42
0111 #define KS_GAMMA3   0x43
0112 #define KS_GAMMA4   0x44
0113 #define KS_GAMMA5   0x45
0114 #define KS_GAMMA6   0x46
0115 #define KS_GAMMA7   0x47
0116 #define KS_GAMMA8   0x48
0117 #define KS_GAMMA9   0x49
0118 #define KS_GAMMA10  0x4a
0119 #define KS_GAMMA11  0x4b
0120 #define KS_GAMMA12  0x4c
0121 #define KS_GAMMA13  0x4d
0122 #define KS_GAMMA14  0x4e
0123 #define KS_GAMMA15  0x4f
0124 #define KS_GAMMA16  0x50
0125 #define KS_GAMMA17  0x51
0126 #define KS_GAMMA18  0x52
0127 #define KS_GAMMA19  0x53
0128 #define KS_GAMMA20  0x54
0129 #define KS_GAMMA21  0x55
0130 #define KS_GAMMA22  0x56
0131 #define KS_GAMMA23  0x57
0132 #define KS_GAMMA24  0x58
0133 #define KS_GAMMA25  0x59
0134 #define KS_GAMMA26  0x5a
0135 #define KS_GAMMA27  0x5b
0136 #define KS_GAMMA28  0x5c
0137 #define KS_GAMMA29  0x5d
0138 #define KS_GAMMA30  0x5e
0139 #define KS_GAMMA31  0x5f
0140 #define KS_GAMMAD0  0x60
0141 #define KS_GAMMAD1  0x61
0142 #define KS_GAMMAD2  0x62
0143 #define KS_GAMMAD3  0x63
0144 #define KS_GAMMAD4  0x64
0145 #define KS_GAMMAD5  0x65
0146 #define KS_GAMMAD6  0x66
0147 #define KS_GAMMAD7  0x67
0148 #define KS_GAMMAD8  0x68
0149 #define KS_GAMMAD9  0x69
0150 #define KS_GAMMAD10 0x6a
0151 #define KS_GAMMAD11 0x6b
0152 #define KS_GAMMAD12 0x6c
0153 #define KS_GAMMAD13 0x6d
0154 #define KS_GAMMAD14 0x6e
0155 #define KS_GAMMAD15 0x6f
0156 #define KS_GAMMAD16 0x70
0157 #define KS_GAMMAD17 0x71
0158 #define KS_GAMMAD18 0x72
0159 #define KS_GAMMAD19 0x73
0160 #define KS_GAMMAD20 0x74
0161 #define KS_GAMMAD21 0x75
0162 #define KS_GAMMAD22 0x76
0163 #define KS_GAMMAD23 0x77
0164 #define KS_GAMMAD24 0x78
0165 #define KS_GAMMAD25 0x79
0166 #define KS_GAMMAD26 0x7a
0167 #define KS_GAMMAD27 0x7b
0168 #define KS_GAMMAD28 0x7c
0169 #define KS_GAMMAD29 0x7d
0170 #define KS_GAMMAD30 0x7e
0171 #define KS_GAMMAD31 0x7f
0172 
0173 
0174 /****************************************************************************
0175 * mga_dev : represents one ks0127 chip.
0176 ****************************************************************************/
0177 
0178 struct adjust {
0179     int contrast;
0180     int bright;
0181     int hue;
0182     int ugain;
0183     int vgain;
0184 };
0185 
0186 struct ks0127 {
0187     struct v4l2_subdev sd;
0188     v4l2_std_id norm;
0189     u8      regs[256];
0190 };
0191 
0192 static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd)
0193 {
0194     return container_of(sd, struct ks0127, sd);
0195 }
0196 
0197 
0198 static int debug; /* insmod parameter */
0199 
0200 module_param(debug, int, 0);
0201 MODULE_PARM_DESC(debug, "Debug output");
0202 
0203 static u8 reg_defaults[64];
0204 
0205 static void init_reg_defaults(void)
0206 {
0207     static int initialized;
0208     u8 *table = reg_defaults;
0209 
0210     if (initialized)
0211         return;
0212     initialized = 1;
0213 
0214     table[KS_CMDA]     = 0x2c;  /* VSE=0, CCIR 601, autodetect standard */
0215     table[KS_CMDB]     = 0x12;  /* VALIGN=0, AGC control and input */
0216     table[KS_CMDC]     = 0x00;  /* Test options */
0217     /* clock & input select, write 1 to PORTA */
0218     table[KS_CMDD]     = 0x01;
0219     table[KS_HAVB]     = 0x00;  /* HAV Start Control */
0220     table[KS_HAVE]     = 0x00;  /* HAV End Control */
0221     table[KS_HS1B]     = 0x10;  /* HS1 Start Control */
0222     table[KS_HS1E]     = 0x00;  /* HS1 End Control */
0223     table[KS_HS2B]     = 0x00;  /* HS2 Start Control */
0224     table[KS_HS2E]     = 0x00;  /* HS2 End Control */
0225     table[KS_AGC]      = 0x53;  /* Manual setting for AGC */
0226     table[KS_HXTRA]    = 0x00;  /* Extra Bits for HAV and HS1/2 */
0227     table[KS_CDEM]     = 0x00;  /* Chroma Demodulation Control */
0228     table[KS_PORTAB]   = 0x0f;  /* port B is input, port A output GPPORT */
0229     table[KS_LUMA]     = 0x01;  /* Luma control */
0230     table[KS_CON]      = 0x00;  /* Contrast Control */
0231     table[KS_BRT]      = 0x00;  /* Brightness Control */
0232     table[KS_CHROMA]   = 0x2a;  /* Chroma control A */
0233     table[KS_CHROMB]   = 0x90;  /* Chroma control B */
0234     table[KS_DEMOD]    = 0x00;  /* Chroma Demodulation Control & Status */
0235     table[KS_SAT]      = 0x00;  /* Color Saturation Control*/
0236     table[KS_HUE]      = 0x00;  /* Hue Control */
0237     table[KS_VERTIA]   = 0x00;  /* Vertical Processing Control A */
0238     /* Vertical Processing Control B, luma 1 line delayed */
0239     table[KS_VERTIB]   = 0x12;
0240     table[KS_VERTIC]   = 0x0b;  /* Vertical Processing Control C */
0241     table[KS_HSCLL]    = 0x00;  /* Horizontal Scaling Ratio Low */
0242     table[KS_HSCLH]    = 0x00;  /* Horizontal Scaling Ratio High */
0243     table[KS_VSCLL]    = 0x00;  /* Vertical Scaling Ratio Low */
0244     table[KS_VSCLH]    = 0x00;  /* Vertical Scaling Ratio High */
0245     /* 16 bit YCbCr 4:2:2 output; I can't make the bt866 like 8 bit /Sam */
0246     table[KS_OFMTA]    = 0x30;
0247     table[KS_OFMTB]    = 0x00;  /* Output Control B */
0248     /* VBI Decoder Control; 4bit fmt: avoid Y overflow */
0249     table[KS_VBICTL]   = 0x5d;
0250     table[KS_CCDAT2]   = 0x00;  /* Read Only register */
0251     table[KS_CCDAT1]   = 0x00;  /* Read Only register */
0252     table[KS_VBIL30]   = 0xa8;  /* VBI data decoding options */
0253     table[KS_VBIL74]   = 0xaa;  /* VBI data decoding options */
0254     table[KS_VBIL118]  = 0x2a;  /* VBI data decoding options */
0255     table[KS_VBIL1512] = 0x00;  /* VBI data decoding options */
0256     table[KS_TTFRAM]   = 0x00;  /* Teletext frame alignment pattern */
0257     table[KS_TESTA]    = 0x00;  /* test register, shouldn't be written */
0258     table[KS_UVOFFH]   = 0x00;  /* UV Offset Adjustment High */
0259     table[KS_UVOFFL]   = 0x00;  /* UV Offset Adjustment Low */
0260     table[KS_UGAIN]    = 0x00;  /* U Component Gain Adjustment */
0261     table[KS_VGAIN]    = 0x00;  /* V Component Gain Adjustment */
0262     table[KS_VAVB]     = 0x07;  /* VAV Begin */
0263     table[KS_VAVE]     = 0x00;  /* VAV End */
0264     table[KS_CTRACK]   = 0x00;  /* Chroma Tracking Control */
0265     table[KS_POLCTL]   = 0x41;  /* Timing Signal Polarity Control */
0266     table[KS_REFCOD]   = 0x80;  /* Reference Code Insertion Control */
0267     table[KS_INVALY]   = 0x10;  /* Invalid Y Code */
0268     table[KS_INVALU]   = 0x80;  /* Invalid U Code */
0269     table[KS_INVALV]   = 0x80;  /* Invalid V Code */
0270     table[KS_UNUSEY]   = 0x10;  /* Unused Y Code */
0271     table[KS_UNUSEU]   = 0x80;  /* Unused U Code */
0272     table[KS_UNUSEV]   = 0x80;  /* Unused V Code */
0273     table[KS_USRSAV]   = 0x00;  /* reserved */
0274     table[KS_USREAV]   = 0x00;  /* reserved */
0275     table[KS_SHS1A]    = 0x00;  /* User Defined SHS1 A */
0276     /* User Defined SHS1 B, ALT656=1 on 0127B */
0277     table[KS_SHS1B]    = 0x80;
0278     table[KS_SHS1C]    = 0x00;  /* User Defined SHS1 C */
0279     table[KS_CMDE]     = 0x00;  /* Command Register E */
0280     table[KS_VSDEL]    = 0x00;  /* VS Delay Control */
0281     /* Command Register F, update -immediately- */
0282     /* (there might come no vsync)*/
0283     table[KS_CMDF]     = 0x02;
0284 }
0285 
0286 
0287 /* We need to manually read because of a bug in the KS0127 chip.
0288  *
0289  * An explanation from kayork@mail.utexas.edu:
0290  *
0291  * During I2C reads, the KS0127 only samples for a stop condition
0292  * during the place where the acknowledge bit should be. Any standard
0293  * I2C implementation (correctly) throws in another clock transition
0294  * at the 9th bit, and the KS0127 will not recognize the stop condition
0295  * and will continue to clock out data.
0296  *
0297  * So we have to do the read ourself.  Big deal.
0298  *     workaround in i2c-algo-bit
0299  */
0300 
0301 
0302 static u8 ks0127_read(struct v4l2_subdev *sd, u8 reg)
0303 {
0304     struct i2c_client *client = v4l2_get_subdevdata(sd);
0305     char val = 0;
0306     struct i2c_msg msgs[] = {
0307         {
0308             .addr = client->addr,
0309             .len = sizeof(reg),
0310             .buf = &reg
0311         },
0312         {
0313             .addr = client->addr,
0314             .flags = I2C_M_RD | I2C_M_NO_RD_ACK,
0315             .len = sizeof(val),
0316             .buf = &val
0317         }
0318     };
0319     int ret;
0320 
0321     ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
0322     if (ret != ARRAY_SIZE(msgs))
0323         v4l2_dbg(1, debug, sd, "read error\n");
0324 
0325     return val;
0326 }
0327 
0328 
0329 static void ks0127_write(struct v4l2_subdev *sd, u8 reg, u8 val)
0330 {
0331     struct i2c_client *client = v4l2_get_subdevdata(sd);
0332     struct ks0127 *ks = to_ks0127(sd);
0333     char msg[] = { reg, val };
0334 
0335     if (i2c_master_send(client, msg, sizeof(msg)) != sizeof(msg))
0336         v4l2_dbg(1, debug, sd, "write error\n");
0337 
0338     ks->regs[reg] = val;
0339 }
0340 
0341 
0342 /* generic bit-twiddling */
0343 static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v)
0344 {
0345     struct ks0127 *ks = to_ks0127(sd);
0346 
0347     u8 val = ks->regs[reg];
0348     val = (val & and_v) | or_v;
0349     ks0127_write(sd, reg, val);
0350 }
0351 
0352 
0353 
0354 /****************************************************************************
0355 * ks0127 private api
0356 ****************************************************************************/
0357 static void ks0127_init(struct v4l2_subdev *sd)
0358 {
0359     u8 *table = reg_defaults;
0360     int i;
0361 
0362     v4l2_dbg(1, debug, sd, "reset\n");
0363     msleep(1);
0364 
0365     /* initialize all registers to known values */
0366     /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
0367 
0368     for (i = 1; i < 33; i++)
0369         ks0127_write(sd, i, table[i]);
0370 
0371     for (i = 35; i < 40; i++)
0372         ks0127_write(sd, i, table[i]);
0373 
0374     for (i = 41; i < 56; i++)
0375         ks0127_write(sd, i, table[i]);
0376 
0377     for (i = 58; i < 64; i++)
0378         ks0127_write(sd, i, table[i]);
0379 
0380 
0381     if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) {
0382         v4l2_dbg(1, debug, sd, "ks0122s found\n");
0383         return;
0384     }
0385 
0386     switch (ks0127_read(sd, KS_CMDE) & 0x0f) {
0387     case 0:
0388         v4l2_dbg(1, debug, sd, "ks0127 found\n");
0389         break;
0390 
0391     case 9:
0392         v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
0393         break;
0394 
0395     default:
0396         v4l2_dbg(1, debug, sd, "unknown revision\n");
0397         break;
0398     }
0399 }
0400 
0401 static int ks0127_s_routing(struct v4l2_subdev *sd,
0402                 u32 input, u32 output, u32 config)
0403 {
0404     struct ks0127 *ks = to_ks0127(sd);
0405 
0406     switch (input) {
0407     case KS_INPUT_COMPOSITE_1:
0408     case KS_INPUT_COMPOSITE_2:
0409     case KS_INPUT_COMPOSITE_3:
0410     case KS_INPUT_COMPOSITE_4:
0411     case KS_INPUT_COMPOSITE_5:
0412     case KS_INPUT_COMPOSITE_6:
0413         v4l2_dbg(1, debug, sd,
0414             "s_routing %d: Composite\n", input);
0415         /* autodetect 50/60 Hz */
0416         ks0127_and_or(sd, KS_CMDA,   0xfc, 0x00);
0417         /* VSE=0 */
0418         ks0127_and_or(sd, KS_CMDA,   ~0x40, 0x00);
0419         /* set input line */
0420         ks0127_and_or(sd, KS_CMDB,   0xb0, input);
0421         /* non-freerunning mode */
0422         ks0127_and_or(sd, KS_CMDC,   0x70, 0x0a);
0423         /* analog input */
0424         ks0127_and_or(sd, KS_CMDD,   0x03, 0x00);
0425         /* enable chroma demodulation */
0426         ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
0427         /* chroma trap, HYBWR=1 */
0428         ks0127_and_or(sd, KS_LUMA,   0x00,
0429                    (reg_defaults[KS_LUMA])|0x0c);
0430         /* scaler fullbw, luma comb off */
0431         ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
0432         /* manual chroma comb .25 .5 .25 */
0433         ks0127_and_or(sd, KS_VERTIC, 0x0f, 0x90);
0434 
0435         /* chroma path delay */
0436         ks0127_and_or(sd, KS_CHROMB, 0x0f, 0x90);
0437 
0438         ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
0439         ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
0440         ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
0441         ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
0442         break;
0443 
0444     case KS_INPUT_SVIDEO_1:
0445     case KS_INPUT_SVIDEO_2:
0446     case KS_INPUT_SVIDEO_3:
0447         v4l2_dbg(1, debug, sd,
0448             "s_routing %d: S-Video\n", input);
0449         /* autodetect 50/60 Hz */
0450         ks0127_and_or(sd, KS_CMDA,   0xfc, 0x00);
0451         /* VSE=0 */
0452         ks0127_and_or(sd, KS_CMDA,   ~0x40, 0x00);
0453         /* set input line */
0454         ks0127_and_or(sd, KS_CMDB,   0xb0, input);
0455         /* non-freerunning mode */
0456         ks0127_and_or(sd, KS_CMDC,   0x70, 0x0a);
0457         /* analog input */
0458         ks0127_and_or(sd, KS_CMDD,   0x03, 0x00);
0459         /* enable chroma demodulation */
0460         ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
0461         ks0127_and_or(sd, KS_LUMA, 0x00,
0462                    reg_defaults[KS_LUMA]);
0463         /* disable luma comb */
0464         ks0127_and_or(sd, KS_VERTIA, 0x08,
0465                    (reg_defaults[KS_VERTIA]&0xf0)|0x01);
0466         ks0127_and_or(sd, KS_VERTIC, 0x0f,
0467                    reg_defaults[KS_VERTIC]&0xf0);
0468 
0469         ks0127_and_or(sd, KS_CHROMB, 0x0f,
0470                    reg_defaults[KS_CHROMB]&0xf0);
0471 
0472         ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
0473         ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
0474         ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
0475         ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
0476         break;
0477 
0478     case KS_INPUT_YUV656:
0479         v4l2_dbg(1, debug, sd, "s_routing 15: YUV656\n");
0480         if (ks->norm & V4L2_STD_525_60)
0481             /* force 60 Hz */
0482             ks0127_and_or(sd, KS_CMDA,   0xfc, 0x03);
0483         else
0484             /* force 50 Hz */
0485             ks0127_and_or(sd, KS_CMDA,   0xfc, 0x02);
0486 
0487         ks0127_and_or(sd, KS_CMDA,   0xff, 0x40); /* VSE=1 */
0488         /* set input line and VALIGN */
0489         ks0127_and_or(sd, KS_CMDB,   0xb0, (input | 0x40));
0490         /* freerunning mode, */
0491         /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0  VMEM=1*/
0492         ks0127_and_or(sd, KS_CMDC,   0x70, 0x87);
0493         /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
0494         ks0127_and_or(sd, KS_CMDD,   0x03, 0x08);
0495         /* disable chroma demodulation */
0496         ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x30);
0497         /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
0498         ks0127_and_or(sd, KS_LUMA,   0x00, 0x71);
0499         ks0127_and_or(sd, KS_VERTIC, 0x0f,
0500                    reg_defaults[KS_VERTIC]&0xf0);
0501 
0502         /* scaler fullbw, luma comb off */
0503         ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
0504 
0505         ks0127_and_or(sd, KS_CHROMB, 0x0f,
0506                    reg_defaults[KS_CHROMB]&0xf0);
0507 
0508         ks0127_and_or(sd, KS_CON, 0x00, 0x00);
0509         ks0127_and_or(sd, KS_BRT, 0x00, 32);    /* spec: 34 */
0510             /* spec: 229 (e5) */
0511         ks0127_and_or(sd, KS_SAT, 0x00, 0xe8);
0512         ks0127_and_or(sd, KS_HUE, 0x00, 0);
0513 
0514         ks0127_and_or(sd, KS_UGAIN, 0x00, 238);
0515         ks0127_and_or(sd, KS_VGAIN, 0x00, 0x00);
0516 
0517         /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
0518         ks0127_and_or(sd, KS_UVOFFH, 0x00, 0x4f);
0519         ks0127_and_or(sd, KS_UVOFFL, 0x00, 0x00);
0520         break;
0521 
0522     default:
0523         v4l2_dbg(1, debug, sd,
0524             "s_routing: Unknown input %d\n", input);
0525         break;
0526     }
0527 
0528     /* hack: CDMLPF sometimes spontaneously switches on; */
0529     /* force back off */
0530     ks0127_write(sd, KS_DEMOD, reg_defaults[KS_DEMOD]);
0531     return 0;
0532 }
0533 
0534 static int ks0127_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
0535 {
0536     struct ks0127 *ks = to_ks0127(sd);
0537 
0538     /* Set to automatic SECAM/Fsc mode */
0539     ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
0540 
0541     ks->norm = std;
0542     if (std & V4L2_STD_NTSC) {
0543         v4l2_dbg(1, debug, sd,
0544             "s_std: NTSC_M\n");
0545         ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
0546     } else if (std & V4L2_STD_PAL_N) {
0547         v4l2_dbg(1, debug, sd,
0548             "s_std: NTSC_N (fixme)\n");
0549         ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
0550     } else if (std & V4L2_STD_PAL) {
0551         v4l2_dbg(1, debug, sd,
0552             "s_std: PAL_N\n");
0553         ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
0554     } else if (std & V4L2_STD_PAL_M) {
0555         v4l2_dbg(1, debug, sd,
0556             "s_std: PAL_M (fixme)\n");
0557         ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
0558     } else if (std & V4L2_STD_SECAM) {
0559         v4l2_dbg(1, debug, sd,
0560             "s_std: SECAM\n");
0561 
0562         /* set to secam autodetection */
0563         ks0127_and_or(sd, KS_CHROMA, 0xdf, 0x20);
0564         ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
0565         schedule_timeout_interruptible(HZ/10+1);
0566 
0567         /* did it autodetect? */
0568         if (!(ks0127_read(sd, KS_DEMOD) & 0x40))
0569             /* force to secam mode */
0570             ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x0f);
0571     } else {
0572         v4l2_dbg(1, debug, sd, "s_std: Unknown norm %llx\n",
0573                    (unsigned long long)std);
0574     }
0575     return 0;
0576 }
0577 
0578 static int ks0127_s_stream(struct v4l2_subdev *sd, int enable)
0579 {
0580     v4l2_dbg(1, debug, sd, "s_stream(%d)\n", enable);
0581     if (enable) {
0582         /* All output pins on */
0583         ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x30);
0584         /* Obey the OEN pin */
0585         ks0127_and_or(sd, KS_CDEM, 0x7f, 0x00);
0586     } else {
0587         /* Video output pins off */
0588         ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x00);
0589         /* Ignore the OEN pin */
0590         ks0127_and_or(sd, KS_CDEM, 0x7f, 0x80);
0591     }
0592     return 0;
0593 }
0594 
0595 static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
0596 {
0597     int stat = V4L2_IN_ST_NO_SIGNAL;
0598     u8 status;
0599     v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
0600 
0601     status = ks0127_read(sd, KS_STAT);
0602     if (!(status & 0x20))        /* NOVID not set */
0603         stat = 0;
0604     if (!(status & 0x01)) {           /* CLOCK set */
0605         stat |= V4L2_IN_ST_NO_COLOR;
0606         std = V4L2_STD_UNKNOWN;
0607     } else {
0608         if ((status & 0x08))           /* PALDET set */
0609             std &= V4L2_STD_PAL;
0610         else
0611             std &= V4L2_STD_NTSC;
0612     }
0613     if ((status & 0x10))           /* PALDET set */
0614         std &= V4L2_STD_525_60;
0615     else
0616         std &= V4L2_STD_625_50;
0617     if (pstd)
0618         *pstd = std;
0619     if (pstatus)
0620         *pstatus = stat;
0621     return 0;
0622 }
0623 
0624 static int ks0127_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
0625 {
0626     v4l2_dbg(1, debug, sd, "querystd\n");
0627     return ks0127_status(sd, NULL, std);
0628 }
0629 
0630 static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
0631 {
0632     v4l2_dbg(1, debug, sd, "g_input_status\n");
0633     return ks0127_status(sd, status, NULL);
0634 }
0635 
0636 /* ----------------------------------------------------------------------- */
0637 
0638 static const struct v4l2_subdev_video_ops ks0127_video_ops = {
0639     .s_std = ks0127_s_std,
0640     .s_routing = ks0127_s_routing,
0641     .s_stream = ks0127_s_stream,
0642     .querystd = ks0127_querystd,
0643     .g_input_status = ks0127_g_input_status,
0644 };
0645 
0646 static const struct v4l2_subdev_ops ks0127_ops = {
0647     .video = &ks0127_video_ops,
0648 };
0649 
0650 /* ----------------------------------------------------------------------- */
0651 
0652 
0653 static int ks0127_probe(struct i2c_client *client, const struct i2c_device_id *id)
0654 {
0655     struct ks0127 *ks;
0656     struct v4l2_subdev *sd;
0657 
0658     v4l_info(client, "%s chip found @ 0x%x (%s)\n",
0659         client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
0660         client->addr << 1, client->adapter->name);
0661 
0662     ks = devm_kzalloc(&client->dev, sizeof(*ks), GFP_KERNEL);
0663     if (ks == NULL)
0664         return -ENOMEM;
0665     sd = &ks->sd;
0666     v4l2_i2c_subdev_init(sd, client, &ks0127_ops);
0667 
0668     /* power up */
0669     init_reg_defaults();
0670     ks0127_write(sd, KS_CMDA, 0x2c);
0671     mdelay(10);
0672 
0673     /* reset the device */
0674     ks0127_init(sd);
0675     return 0;
0676 }
0677 
0678 static int ks0127_remove(struct i2c_client *client)
0679 {
0680     struct v4l2_subdev *sd = i2c_get_clientdata(client);
0681 
0682     v4l2_device_unregister_subdev(sd);
0683     ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
0684     ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
0685     return 0;
0686 }
0687 
0688 static const struct i2c_device_id ks0127_id[] = {
0689     { "ks0127", 0 },
0690     { "ks0127b", 0 },
0691     { "ks0122s", 0 },
0692     { }
0693 };
0694 MODULE_DEVICE_TABLE(i2c, ks0127_id);
0695 
0696 static struct i2c_driver ks0127_driver = {
0697     .driver = {
0698         .name   = "ks0127",
0699     },
0700     .probe      = ks0127_probe,
0701     .remove     = ks0127_remove,
0702     .id_table   = ks0127_id,
0703 };
0704 
0705 module_i2c_driver(ks0127_driver);