2 * saa7191.c - Philips SAA7191 video decoder driver
4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
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.
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/delay.h>
15 #include <linux/errno.h>
17 #include <linux/kernel.h>
18 #include <linux/major.h>
19 #include <linux/slab.h>
21 #include <linux/sched.h>
23 #include <linux/videodev.h>
24 #include <linux/video_decoder.h>
25 #include <linux/i2c.h>
29 #define SAA7191_MODULE_VERSION "0.0.3"
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");
36 #define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO)
39 struct i2c_client
*client
;
41 /* the register values are stored here as the actual
42 * I2C-registers are write-only */
43 unsigned char reg
[25];
49 static struct i2c_driver i2c_driver_saa7191
;
51 static const unsigned char initseq
[] = {
53 0x50, /* SAA7191_REG_IDEL */
54 0x30, /* SAA7191_REG_HSYB */
55 0x00, /* SAA7191_REG_HSYS */
56 0xe8, /* SAA7191_REG_HCLB */
57 0xb6, /* SAA7191_REG_HCLS */
58 0xf4, /* SAA7191_REG_HPHI */
59 0x01, /* SAA7191_REG_LUMA - chrominance trap active (CVBS) */
60 0x00, /* SAA7191_REG_HUEC */
61 0xf8, /* SAA7191_REG_CKTQ */
62 0xf8, /* SAA7191_REG_CKTS */
63 0x90, /* SAA7191_REG_PLSE */
64 0x90, /* SAA7191_REG_SESE */
65 0x00, /* SAA7191_REG_GAIN */
66 0x0c, /* SAA7191_REG_STDC - not SECAM, slow time constant */
67 0x78, /* SAA7191_REG_IOCK - chrominance from CVBS, GPSW1 & 2 off */
68 0x99, /* SAA7191_REG_CTL3 - automatic field detection */
69 0x00, /* SAA7191_REG_CTL4 */
70 0x2c, /* SAA7191_REG_CHCV */
73 0x34, /* SAA7191_REG_HS6B */
74 0x0a, /* SAA7191_REG_HS6S */
75 0xf4, /* SAA7191_REG_HC6B */
76 0xce, /* SAA7191_REG_HC6S */
77 0xf4, /* SAA7191_REG_HP6I */
80 /* SAA7191 register handling */
82 static unsigned char saa7191_read_reg(struct i2c_client
*client
,
85 return ((struct saa7191
*)i2c_get_clientdata(client
))->reg
[reg
];
88 static int saa7191_read_status(struct i2c_client
*client
,
93 ret
= i2c_master_recv(client
, value
, 1);
95 printk(KERN_ERR
"SAA7191: saa7191_read_status(): read failed");
103 static int saa7191_write_reg(struct i2c_client
*client
, unsigned char reg
,
107 ((struct saa7191
*)i2c_get_clientdata(client
))->reg
[reg
] = value
;
108 return i2c_smbus_write_byte_data(client
, reg
, value
);
111 /* the first byte of data must be the first subaddress number (register) */
112 static int saa7191_write_block(struct i2c_client
*client
,
113 unsigned char length
, unsigned char *data
)
118 struct saa7191
*decoder
= (struct saa7191
*)i2c_get_clientdata(client
);
119 for (i
= 0; i
< (length
- 1); i
++) {
120 decoder
->reg
[data
[0] + i
] = data
[i
+ 1];
123 ret
= i2c_master_send(client
, data
, length
);
125 printk(KERN_ERR
"SAA7191: saa7191_write_block(): "
133 /* Helper functions */
135 static int saa7191_set_input(struct i2c_client
*client
, int input
)
137 unsigned char luma
= saa7191_read_reg(client
, SAA7191_REG_LUMA
);
138 unsigned char iock
= saa7191_read_reg(client
, SAA7191_REG_IOCK
);
142 case SAA7191_INPUT_COMPOSITE
: /* Set Composite input */
143 iock
&= ~(SAA7191_IOCK_CHRS
| SAA7191_IOCK_GPSW1
144 | SAA7191_IOCK_GPSW2
);
145 /* Chrominance trap active */
146 luma
&= ~SAA7191_LUMA_BYPS
;
148 case SAA7191_INPUT_SVIDEO
: /* Set S-Video input */
149 iock
|= SAA7191_IOCK_CHRS
| SAA7191_IOCK_GPSW2
;
150 /* Chrominance trap bypassed */
151 luma
|= SAA7191_LUMA_BYPS
;
157 err
= saa7191_write_reg(client
, SAA7191_REG_LUMA
, luma
);
160 err
= saa7191_write_reg(client
, SAA7191_REG_IOCK
, iock
);
167 static int saa7191_set_norm(struct i2c_client
*client
, int norm
)
169 struct saa7191
*decoder
= i2c_get_clientdata(client
);
170 unsigned char stdc
= saa7191_read_reg(client
, SAA7191_REG_STDC
);
171 unsigned char ctl3
= saa7191_read_reg(client
, SAA7191_REG_CTL3
);
172 unsigned char chcv
= saa7191_read_reg(client
, SAA7191_REG_CHCV
);
176 case SAA7191_NORM_AUTO
: {
177 unsigned char status
;
179 // does status depend on current norm ?
180 if (saa7191_read_status(client
, &status
))
183 stdc
&= ~SAA7191_STDC_SECS
;
184 ctl3
&= ~SAA7191_CTL3_FSEL
;
185 ctl3
|= SAA7191_CTL3_AUFD
;
186 chcv
= (status
& SAA7191_STATUS_FIDT
)
187 ? SAA7191_CHCV_NTSC
: SAA7191_CHCV_PAL
;
190 case SAA7191_NORM_PAL
:
191 stdc
&= ~SAA7191_STDC_SECS
;
192 ctl3
&= ~(SAA7191_CTL3_AUFD
| SAA7191_CTL3_FSEL
);
193 chcv
= SAA7191_CHCV_PAL
;
195 case SAA7191_NORM_NTSC
:
196 stdc
&= ~SAA7191_STDC_SECS
;
197 ctl3
&= ~SAA7191_CTL3_AUFD
;
198 ctl3
|= SAA7191_CTL3_FSEL
;
199 chcv
= SAA7191_CHCV_NTSC
;
201 case SAA7191_NORM_SECAM
:
202 stdc
|= SAA7191_STDC_SECS
;
203 ctl3
&= ~(SAA7191_CTL3_AUFD
| SAA7191_CTL3_FSEL
);
204 chcv
= SAA7191_CHCV_PAL
;
210 err
= saa7191_write_reg(client
, SAA7191_REG_CTL3
, ctl3
);
213 err
= saa7191_write_reg(client
, SAA7191_REG_STDC
, stdc
);
216 err
= saa7191_write_reg(client
, SAA7191_REG_CHCV
, chcv
);
220 decoder
->norm
= norm
;
225 static int saa7191_get_controls(struct i2c_client
*client
,
226 struct saa7191_control
*ctrl
)
228 unsigned char hue
= saa7191_read_reg(client
, SAA7191_REG_HUEC
);
229 unsigned char stdc
= saa7191_read_reg(client
, SAA7191_REG_STDC
);
238 ctrl
->vtrc
= (stdc
& SAA7191_STDC_VTRC
)
239 ? SAA7191_VALUE_ENABLED
: SAA7191_VALUE_DISABLED
;
244 static int saa7191_set_controls(struct i2c_client
*client
,
245 struct saa7191_control
*ctrl
)
249 if (ctrl
->hue
>= 0) {
250 unsigned char hue
= ctrl
->hue
& 0xff;
256 err
= saa7191_write_reg(client
, SAA7191_REG_HUEC
, hue
);
260 if (ctrl
->vtrc
>= 0) {
262 saa7191_read_reg(client
, SAA7191_REG_STDC
);
265 stdc
|= SAA7191_STDC_VTRC
;
267 stdc
&= ~SAA7191_STDC_VTRC
;
270 err
= saa7191_write_reg(client
, SAA7191_REG_STDC
, stdc
);
280 static int saa7191_attach(struct i2c_adapter
*adap
, int addr
, int kind
)
283 struct saa7191
*decoder
;
284 struct i2c_client
*client
;
286 printk(KERN_INFO
"Philips SAA7191 driver version %s\n",
287 SAA7191_MODULE_VERSION
);
289 client
= kmalloc(sizeof(*client
), GFP_KERNEL
);
292 decoder
= kmalloc(sizeof(*decoder
), GFP_KERNEL
);
295 goto out_free_client
;
298 memset(client
, 0, sizeof(struct i2c_client
));
299 memset(decoder
, 0, sizeof(struct saa7191
));
302 client
->adapter
= adap
;
303 client
->driver
= &i2c_driver_saa7191
;
305 strcpy(client
->name
, "saa7191 client");
306 i2c_set_clientdata(client
, decoder
);
308 decoder
->client
= client
;
310 err
= i2c_attach_client(client
);
312 goto out_free_decoder
;
314 decoder
->input
= SAA7191_INPUT_COMPOSITE
;
315 decoder
->norm
= SAA7191_NORM_AUTO
;
317 err
= saa7191_write_block(client
, sizeof(initseq
),
318 (unsigned char *)initseq
);
320 printk(KERN_ERR
"SAA7191 initialization failed\n");
321 goto out_detach_client
;
324 printk(KERN_INFO
"SAA7191 initialized\n");
329 i2c_detach_client(client
);
337 static int saa7191_probe(struct i2c_adapter
*adap
)
339 /* Always connected to VINO */
340 if (adap
->id
== VINO_ADAPTER
)
341 return saa7191_attach(adap
, SAA7191_ADDR
, 0);
342 /* Feel free to add probe here :-) */
346 static int saa7191_detach(struct i2c_client
*client
)
348 struct saa7191
*decoder
= i2c_get_clientdata(client
);
350 i2c_detach_client(client
);
356 static int saa7191_command(struct i2c_client
*client
, unsigned int cmd
,
359 struct saa7191
*decoder
= i2c_get_clientdata(client
);
362 case DECODER_GET_CAPABILITIES
: {
363 struct video_decoder_capability
*cap
= arg
;
365 cap
->flags
= VIDEO_DECODER_PAL
| VIDEO_DECODER_NTSC
|
366 VIDEO_DECODER_SECAM
| VIDEO_DECODER_AUTO
;
367 cap
->inputs
= (client
->adapter
->id
== VINO_ADAPTER
) ? 2 : 1;
371 case DECODER_GET_STATUS
: {
373 unsigned char status
;
376 if (saa7191_read_status(client
, &status
)) {
379 if ((status
& SAA7191_STATUS_HLCK
) == 0)
380 res
|= DECODER_STATUS_GOOD
;
381 if (status
& SAA7191_STATUS_CODE
)
382 res
|= DECODER_STATUS_COLOR
;
383 switch (decoder
->norm
) {
384 case SAA7191_NORM_NTSC
:
385 res
|= DECODER_STATUS_NTSC
;
387 case SAA7191_NORM_PAL
:
388 res
|= DECODER_STATUS_PAL
;
390 case SAA7191_NORM_SECAM
:
391 res
|= DECODER_STATUS_SECAM
;
393 case SAA7191_NORM_AUTO
:
395 if (status
& SAA7191_STATUS_FIDT
)
396 res
|= DECODER_STATUS_NTSC
;
398 res
|= DECODER_STATUS_PAL
;
404 case DECODER_SET_NORM
: {
408 case VIDEO_MODE_AUTO
:
409 return saa7191_set_norm(client
, SAA7191_NORM_AUTO
);
411 return saa7191_set_norm(client
, SAA7191_NORM_PAL
);
412 case VIDEO_MODE_NTSC
:
413 return saa7191_set_norm(client
, SAA7191_NORM_NTSC
);
414 case VIDEO_MODE_SECAM
:
415 return saa7191_set_norm(client
, SAA7191_NORM_SECAM
);
421 case DECODER_SET_INPUT
: {
424 switch (client
->adapter
->id
) {
426 return saa7191_set_input(client
, *iarg
);
433 case DECODER_SET_OUTPUT
: {
436 /* not much choice of outputs */
441 case DECODER_ENABLE_OUTPUT
: {
445 case DECODER_SET_PICTURE
: {
446 struct video_picture
*pic
= arg
;
450 val
= (pic
->hue
>> 8) - 0x80;
451 err
= saa7191_write_reg(client
, SAA7191_REG_HUEC
, val
);
456 case DECODER_SAA7191_GET_STATUS
: {
457 struct saa7191_status
*status
= arg
;
458 unsigned char status_reg
;
460 if (saa7191_read_status(client
, &status_reg
))
462 status
->signal
= ((status_reg
& SAA7191_STATUS_HLCK
) == 0)
463 ? SAA7191_VALUE_ENABLED
: SAA7191_VALUE_DISABLED
;
464 status
->ntsc
= (status_reg
& SAA7191_STATUS_FIDT
)
465 ? SAA7191_VALUE_ENABLED
: SAA7191_VALUE_DISABLED
;
466 status
->color
= (status_reg
& SAA7191_STATUS_CODE
)
467 ? SAA7191_VALUE_ENABLED
: SAA7191_VALUE_DISABLED
;
469 status
->input
= decoder
->input
;
470 status
->norm
= decoder
->norm
;
472 case DECODER_SAA7191_SET_NORM
: {
474 return saa7191_set_norm(client
, *norm
);
476 case DECODER_SAA7191_GET_CONTROLS
: {
477 struct saa7191_control
*ctrl
= arg
;
478 return saa7191_get_controls(client
, ctrl
);
480 case DECODER_SAA7191_SET_CONTROLS
: {
481 struct saa7191_control
*ctrl
= arg
;
482 return saa7191_set_controls(client
, ctrl
);
491 static struct i2c_driver i2c_driver_saa7191
= {
492 .owner
= THIS_MODULE
,
494 .id
= I2C_DRIVERID_SAA7191
,
495 .flags
= I2C_DF_NOTIFY
,
496 .attach_adapter
= saa7191_probe
,
497 .detach_client
= saa7191_detach
,
498 .command
= saa7191_command
501 static int saa7191_init(void)
503 return i2c_add_driver(&i2c_driver_saa7191
);
506 static void saa7191_exit(void)
508 i2c_del_driver(&i2c_driver_saa7191
);
511 module_init(saa7191_init
);
512 module_exit(saa7191_exit
);