0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
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
0039 #define I2C_KS0127_ADDON 0xD8
0040 #define I2C_KS0127_ONBOARD 0xDA
0041
0042
0043
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
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;
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;
0215 table[KS_CMDB] = 0x12;
0216 table[KS_CMDC] = 0x00;
0217
0218 table[KS_CMDD] = 0x01;
0219 table[KS_HAVB] = 0x00;
0220 table[KS_HAVE] = 0x00;
0221 table[KS_HS1B] = 0x10;
0222 table[KS_HS1E] = 0x00;
0223 table[KS_HS2B] = 0x00;
0224 table[KS_HS2E] = 0x00;
0225 table[KS_AGC] = 0x53;
0226 table[KS_HXTRA] = 0x00;
0227 table[KS_CDEM] = 0x00;
0228 table[KS_PORTAB] = 0x0f;
0229 table[KS_LUMA] = 0x01;
0230 table[KS_CON] = 0x00;
0231 table[KS_BRT] = 0x00;
0232 table[KS_CHROMA] = 0x2a;
0233 table[KS_CHROMB] = 0x90;
0234 table[KS_DEMOD] = 0x00;
0235 table[KS_SAT] = 0x00;
0236 table[KS_HUE] = 0x00;
0237 table[KS_VERTIA] = 0x00;
0238
0239 table[KS_VERTIB] = 0x12;
0240 table[KS_VERTIC] = 0x0b;
0241 table[KS_HSCLL] = 0x00;
0242 table[KS_HSCLH] = 0x00;
0243 table[KS_VSCLL] = 0x00;
0244 table[KS_VSCLH] = 0x00;
0245
0246 table[KS_OFMTA] = 0x30;
0247 table[KS_OFMTB] = 0x00;
0248
0249 table[KS_VBICTL] = 0x5d;
0250 table[KS_CCDAT2] = 0x00;
0251 table[KS_CCDAT1] = 0x00;
0252 table[KS_VBIL30] = 0xa8;
0253 table[KS_VBIL74] = 0xaa;
0254 table[KS_VBIL118] = 0x2a;
0255 table[KS_VBIL1512] = 0x00;
0256 table[KS_TTFRAM] = 0x00;
0257 table[KS_TESTA] = 0x00;
0258 table[KS_UVOFFH] = 0x00;
0259 table[KS_UVOFFL] = 0x00;
0260 table[KS_UGAIN] = 0x00;
0261 table[KS_VGAIN] = 0x00;
0262 table[KS_VAVB] = 0x07;
0263 table[KS_VAVE] = 0x00;
0264 table[KS_CTRACK] = 0x00;
0265 table[KS_POLCTL] = 0x41;
0266 table[KS_REFCOD] = 0x80;
0267 table[KS_INVALY] = 0x10;
0268 table[KS_INVALU] = 0x80;
0269 table[KS_INVALV] = 0x80;
0270 table[KS_UNUSEY] = 0x10;
0271 table[KS_UNUSEU] = 0x80;
0272 table[KS_UNUSEV] = 0x80;
0273 table[KS_USRSAV] = 0x00;
0274 table[KS_USREAV] = 0x00;
0275 table[KS_SHS1A] = 0x00;
0276
0277 table[KS_SHS1B] = 0x80;
0278 table[KS_SHS1C] = 0x00;
0279 table[KS_CMDE] = 0x00;
0280 table[KS_VSDEL] = 0x00;
0281
0282
0283 table[KS_CMDF] = 0x02;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
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 = ®
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
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
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
0366
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
0416 ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
0417
0418 ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
0419
0420 ks0127_and_or(sd, KS_CMDB, 0xb0, input);
0421
0422 ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
0423
0424 ks0127_and_or(sd, KS_CMDD, 0x03, 0x00);
0425
0426 ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
0427
0428 ks0127_and_or(sd, KS_LUMA, 0x00,
0429 (reg_defaults[KS_LUMA])|0x0c);
0430
0431 ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
0432
0433 ks0127_and_or(sd, KS_VERTIC, 0x0f, 0x90);
0434
0435
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
0450 ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
0451
0452 ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
0453
0454 ks0127_and_or(sd, KS_CMDB, 0xb0, input);
0455
0456 ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
0457
0458 ks0127_and_or(sd, KS_CMDD, 0x03, 0x00);
0459
0460 ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
0461 ks0127_and_or(sd, KS_LUMA, 0x00,
0462 reg_defaults[KS_LUMA]);
0463
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
0482 ks0127_and_or(sd, KS_CMDA, 0xfc, 0x03);
0483 else
0484
0485 ks0127_and_or(sd, KS_CMDA, 0xfc, 0x02);
0486
0487 ks0127_and_or(sd, KS_CMDA, 0xff, 0x40);
0488
0489 ks0127_and_or(sd, KS_CMDB, 0xb0, (input | 0x40));
0490
0491
0492 ks0127_and_or(sd, KS_CMDC, 0x70, 0x87);
0493
0494 ks0127_and_or(sd, KS_CMDD, 0x03, 0x08);
0495
0496 ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x30);
0497
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
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);
0510
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
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
0529
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
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
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
0568 if (!(ks0127_read(sd, KS_DEMOD) & 0x40))
0569
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
0583 ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x30);
0584
0585 ks0127_and_or(sd, KS_CDEM, 0x7f, 0x00);
0586 } else {
0587
0588 ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x00);
0589
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))
0603 stat = 0;
0604 if (!(status & 0x01)) {
0605 stat |= V4L2_IN_ST_NO_COLOR;
0606 std = V4L2_STD_UNKNOWN;
0607 } else {
0608 if ((status & 0x08))
0609 std &= V4L2_STD_PAL;
0610 else
0611 std &= V4L2_STD_NTSC;
0612 }
0613 if ((status & 0x10))
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
0669 init_reg_defaults();
0670 ks0127_write(sd, KS_CMDA, 0x2c);
0671 mdelay(10);
0672
0673
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);
0684 ks0127_write(sd, KS_CMDA, 0x2c | 0x80);
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);