manual update from upstream:
[deliverable/linux.git] / drivers / media / video / saa7191.c
1 /*
2 * saa7191.c - Philips SAA7191 video decoder driver
3 *
4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12 #include <linux/delay.h>
13 #include <linux/errno.h>
14 #include <linux/fs.h>
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/major.h>
18 #include <linux/module.h>
19 #include <linux/mm.h>
20 #include <linux/sched.h>
21 #include <linux/slab.h>
22
23 #include <linux/videodev.h>
24 #include <linux/video_decoder.h>
25 #include <linux/i2c.h>
26
27 #include "saa7191.h"
28
29 #define SAA7191_MODULE_VERSION "0.0.3"
30
31 MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
32 MODULE_VERSION(SAA7191_MODULE_VERSION);
33 MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
34 MODULE_LICENSE("GPL");
35
36 struct saa7191 {
37 struct i2c_client *client;
38
39 /* the register values are stored here as the actual
40 * I2C-registers are write-only */
41 unsigned char reg[25];
42
43 unsigned char norm;
44 unsigned char input;
45 };
46
47 static struct i2c_driver i2c_driver_saa7191;
48
49 static const unsigned char initseq[] = {
50 0, /* Subaddress */
51 0x50, /* SAA7191_REG_IDEL */
52 0x30, /* SAA7191_REG_HSYB */
53 0x00, /* SAA7191_REG_HSYS */
54 0xe8, /* SAA7191_REG_HCLB */
55 0xb6, /* SAA7191_REG_HCLS */
56 0xf4, /* SAA7191_REG_HPHI */
57 0x01, /* SAA7191_REG_LUMA - chrominance trap active (CVBS) */
58 0x00, /* SAA7191_REG_HUEC */
59 0xf8, /* SAA7191_REG_CKTQ */
60 0xf8, /* SAA7191_REG_CKTS */
61 0x90, /* SAA7191_REG_PLSE */
62 0x90, /* SAA7191_REG_SESE */
63 0x00, /* SAA7191_REG_GAIN */
64 0x0c, /* SAA7191_REG_STDC - not SECAM, slow time constant */
65 0x78, /* SAA7191_REG_IOCK - chrominance from CVBS, GPSW1 & 2 off */
66 0x99, /* SAA7191_REG_CTL3 - automatic field detection */
67 0x00, /* SAA7191_REG_CTL4 */
68 0x2c, /* SAA7191_REG_CHCV */
69 0x00, /* unused */
70 0x00, /* unused */
71 0x34, /* SAA7191_REG_HS6B */
72 0x0a, /* SAA7191_REG_HS6S */
73 0xf4, /* SAA7191_REG_HC6B */
74 0xce, /* SAA7191_REG_HC6S */
75 0xf4, /* SAA7191_REG_HP6I */
76 };
77
78 /* SAA7191 register handling */
79
80 static unsigned char saa7191_read_reg(struct i2c_client *client,
81 unsigned char reg)
82 {
83 return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
84 }
85
86 static int saa7191_read_status(struct i2c_client *client,
87 unsigned char *value)
88 {
89 int ret;
90
91 ret = i2c_master_recv(client, value, 1);
92 if (ret < 0) {
93 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed");
94 return ret;
95 }
96
97 return 0;
98 }
99
100
101 static int saa7191_write_reg(struct i2c_client *client, unsigned char reg,
102 unsigned char value)
103 {
104
105 ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
106 return i2c_smbus_write_byte_data(client, reg, value);
107 }
108
109 /* the first byte of data must be the first subaddress number (register) */
110 static int saa7191_write_block(struct i2c_client *client,
111 unsigned char length, unsigned char *data)
112 {
113 int i;
114 int ret;
115
116 struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
117 for (i = 0; i < (length - 1); i++) {
118 decoder->reg[data[0] + i] = data[i + 1];
119 }
120
121 ret = i2c_master_send(client, data, length);
122 if (ret < 0) {
123 printk(KERN_ERR "SAA7191: saa7191_write_block(): "
124 "write failed");
125 return ret;
126 }
127
128 return 0;
129 }
130
131 /* Helper functions */
132
133 static int saa7191_set_input(struct i2c_client *client, int input)
134 {
135 unsigned char luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
136 unsigned char iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
137 int err;
138
139 switch (input) {
140 case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
141 iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
142 | SAA7191_IOCK_GPSW2);
143 /* Chrominance trap active */
144 luma &= ~SAA7191_LUMA_BYPS;
145 break;
146 case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
147 iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
148 /* Chrominance trap bypassed */
149 luma |= SAA7191_LUMA_BYPS;
150 break;
151 default:
152 return -EINVAL;
153 }
154
155 err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
156 if (err)
157 return -EIO;
158 err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
159 if (err)
160 return -EIO;
161
162 return 0;
163 }
164
165 static int saa7191_set_norm(struct i2c_client *client, int norm)
166 {
167 struct saa7191 *decoder = i2c_get_clientdata(client);
168 unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
169 unsigned char ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
170 unsigned char chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
171 int err;
172
173 switch(norm) {
174 case SAA7191_NORM_AUTO: {
175 unsigned char status;
176
177 // does status depend on current norm ?
178 if (saa7191_read_status(client, &status))
179 return -EIO;
180
181 stdc &= ~SAA7191_STDC_SECS;
182 ctl3 &= ~SAA7191_CTL3_FSEL;
183 ctl3 |= SAA7191_CTL3_AUFD;
184 chcv = (status & SAA7191_STATUS_FIDT)
185 ? SAA7191_CHCV_NTSC : SAA7191_CHCV_PAL;
186 break;
187 }
188 case SAA7191_NORM_PAL:
189 stdc &= ~SAA7191_STDC_SECS;
190 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
191 chcv = SAA7191_CHCV_PAL;
192 break;
193 case SAA7191_NORM_NTSC:
194 stdc &= ~SAA7191_STDC_SECS;
195 ctl3 &= ~SAA7191_CTL3_AUFD;
196 ctl3 |= SAA7191_CTL3_FSEL;
197 chcv = SAA7191_CHCV_NTSC;
198 break;
199 case SAA7191_NORM_SECAM:
200 stdc |= SAA7191_STDC_SECS;
201 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
202 chcv = SAA7191_CHCV_PAL;
203 break;
204 default:
205 return -EINVAL;
206 }
207
208 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
209 if (err)
210 return -EIO;
211 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
212 if (err)
213 return -EIO;
214 err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
215 if (err)
216 return -EIO;
217
218 decoder->norm = norm;
219
220 return 0;
221 }
222
223 static int saa7191_get_controls(struct i2c_client *client,
224 struct saa7191_control *ctrl)
225 {
226 unsigned char hue = saa7191_read_reg(client, SAA7191_REG_HUEC);
227 unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
228
229 if (hue < 0x80) {
230 hue += 0x80;
231 } else {
232 hue -= 0x80;
233 }
234 ctrl->hue = hue;
235
236 ctrl->vtrc = (stdc & SAA7191_STDC_VTRC)
237 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
238
239 return 0;
240 }
241
242 static int saa7191_set_controls(struct i2c_client *client,
243 struct saa7191_control *ctrl)
244 {
245 int err;
246
247 if (ctrl->hue >= 0) {
248 unsigned char hue = ctrl->hue & 0xff;
249 if (hue < 0x80) {
250 hue += 0x80;
251 } else {
252 hue -= 0x80;
253 }
254 err = saa7191_write_reg(client, SAA7191_REG_HUEC, hue);
255 if (err)
256 return -EIO;
257 }
258 if (ctrl->vtrc >= 0) {
259 unsigned char stdc =
260 saa7191_read_reg(client, SAA7191_REG_STDC);
261
262 if (ctrl->vtrc) {
263 stdc |= SAA7191_STDC_VTRC;
264 } else {
265 stdc &= ~SAA7191_STDC_VTRC;
266 }
267
268 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
269 if (err)
270 return -EIO;
271 }
272
273 return 0;
274 }
275
276 /* I2C-interface */
277
278 static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
279 {
280 int err = 0;
281 struct saa7191 *decoder;
282 struct i2c_client *client;
283
284 printk(KERN_INFO "Philips SAA7191 driver version %s\n",
285 SAA7191_MODULE_VERSION);
286
287 client = kmalloc(sizeof(*client), GFP_KERNEL);
288 if (!client)
289 return -ENOMEM;
290 decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
291 if (!decoder) {
292 err = -ENOMEM;
293 goto out_free_client;
294 }
295
296 memset(client, 0, sizeof(struct i2c_client));
297 memset(decoder, 0, sizeof(struct saa7191));
298
299 client->addr = addr;
300 client->adapter = adap;
301 client->driver = &i2c_driver_saa7191;
302 client->flags = 0;
303 strcpy(client->name, "saa7191 client");
304 i2c_set_clientdata(client, decoder);
305
306 decoder->client = client;
307
308 err = i2c_attach_client(client);
309 if (err)
310 goto out_free_decoder;
311
312 decoder->input = SAA7191_INPUT_COMPOSITE;
313 decoder->norm = SAA7191_NORM_AUTO;
314
315 err = saa7191_write_block(client, sizeof(initseq),
316 (unsigned char *)initseq);
317 if (err) {
318 printk(KERN_ERR "SAA7191 initialization failed\n");
319 goto out_detach_client;
320 }
321
322 printk(KERN_INFO "SAA7191 initialized\n");
323
324 return 0;
325
326 out_detach_client:
327 i2c_detach_client(client);
328 out_free_decoder:
329 kfree(decoder);
330 out_free_client:
331 kfree(client);
332 return err;
333 }
334
335 static int saa7191_probe(struct i2c_adapter *adap)
336 {
337 /* Always connected to VINO */
338 if (adap->id == I2C_HW_SGI_VINO)
339 return saa7191_attach(adap, SAA7191_ADDR, 0);
340 /* Feel free to add probe here :-) */
341 return -ENODEV;
342 }
343
344 static int saa7191_detach(struct i2c_client *client)
345 {
346 struct saa7191 *decoder = i2c_get_clientdata(client);
347
348 i2c_detach_client(client);
349 kfree(decoder);
350 kfree(client);
351 return 0;
352 }
353
354 static int saa7191_command(struct i2c_client *client, unsigned int cmd,
355 void *arg)
356 {
357 struct saa7191 *decoder = i2c_get_clientdata(client);
358
359 switch (cmd) {
360 case DECODER_GET_CAPABILITIES: {
361 struct video_decoder_capability *cap = arg;
362
363 cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
364 VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
365 cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
366 cap->outputs = 1;
367 break;
368 }
369 case DECODER_GET_STATUS: {
370 int *iarg = arg;
371 unsigned char status;
372 int res = 0;
373
374 if (saa7191_read_status(client, &status)) {
375 return -EIO;
376 }
377 if ((status & SAA7191_STATUS_HLCK) == 0)
378 res |= DECODER_STATUS_GOOD;
379 if (status & SAA7191_STATUS_CODE)
380 res |= DECODER_STATUS_COLOR;
381 switch (decoder->norm) {
382 case SAA7191_NORM_NTSC:
383 res |= DECODER_STATUS_NTSC;
384 break;
385 case SAA7191_NORM_PAL:
386 res |= DECODER_STATUS_PAL;
387 break;
388 case SAA7191_NORM_SECAM:
389 res |= DECODER_STATUS_SECAM;
390 break;
391 case SAA7191_NORM_AUTO:
392 default:
393 if (status & SAA7191_STATUS_FIDT)
394 res |= DECODER_STATUS_NTSC;
395 else
396 res |= DECODER_STATUS_PAL;
397 break;
398 }
399 *iarg = res;
400 break;
401 }
402 case DECODER_SET_NORM: {
403 int *iarg = arg;
404
405 switch (*iarg) {
406 case VIDEO_MODE_AUTO:
407 return saa7191_set_norm(client, SAA7191_NORM_AUTO);
408 case VIDEO_MODE_PAL:
409 return saa7191_set_norm(client, SAA7191_NORM_PAL);
410 case VIDEO_MODE_NTSC:
411 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
412 case VIDEO_MODE_SECAM:
413 return saa7191_set_norm(client, SAA7191_NORM_SECAM);
414 default:
415 return -EINVAL;
416 }
417 break;
418 }
419 case DECODER_SET_INPUT: {
420 int *iarg = arg;
421
422 switch (client->adapter->id) {
423 case I2C_HW_SGI_VINO:
424 return saa7191_set_input(client, *iarg);
425 default:
426 if (*iarg != 0)
427 return -EINVAL;
428 }
429 break;
430 }
431 case DECODER_SET_OUTPUT: {
432 int *iarg = arg;
433
434 /* not much choice of outputs */
435 if (*iarg != 0)
436 return -EINVAL;
437 break;
438 }
439 case DECODER_ENABLE_OUTPUT: {
440 /* Always enabled */
441 break;
442 }
443 case DECODER_SET_PICTURE: {
444 struct video_picture *pic = arg;
445 unsigned val;
446 int err;
447
448 val = (pic->hue >> 8) - 0x80;
449 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
450 if (err)
451 return -EIO;
452 break;
453 }
454 case DECODER_SAA7191_GET_STATUS: {
455 struct saa7191_status *status = arg;
456 unsigned char status_reg;
457
458 if (saa7191_read_status(client, &status_reg))
459 return -EIO;
460 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
461 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
462 status->ntsc = (status_reg & SAA7191_STATUS_FIDT)
463 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
464 status->color = (status_reg & SAA7191_STATUS_CODE)
465 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
466
467 status->input = decoder->input;
468 status->norm = decoder->norm;
469 }
470 case DECODER_SAA7191_SET_NORM: {
471 int *norm = arg;
472 return saa7191_set_norm(client, *norm);
473 }
474 case DECODER_SAA7191_GET_CONTROLS: {
475 struct saa7191_control *ctrl = arg;
476 return saa7191_get_controls(client, ctrl);
477 }
478 case DECODER_SAA7191_SET_CONTROLS: {
479 struct saa7191_control *ctrl = arg;
480 return saa7191_set_controls(client, ctrl);
481 }
482 default:
483 return -EINVAL;
484 }
485
486 return 0;
487 }
488
489 static struct i2c_driver i2c_driver_saa7191 = {
490 .owner = THIS_MODULE,
491 .name = "saa7191",
492 .id = I2C_DRIVERID_SAA7191,
493 .flags = I2C_DF_NOTIFY,
494 .attach_adapter = saa7191_probe,
495 .detach_client = saa7191_detach,
496 .command = saa7191_command
497 };
498
499 static int saa7191_init(void)
500 {
501 return i2c_add_driver(&i2c_driver_saa7191);
502 }
503
504 static void saa7191_exit(void)
505 {
506 i2c_del_driver(&i2c_driver_saa7191);
507 }
508
509 module_init(saa7191_init);
510 module_exit(saa7191_exit);
This page took 0.043104 seconds and 6 git commands to generate.