aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7191.c
diff options
context:
space:
mode:
authorLadislav Michl <ladis@linux-mips.org>2005-09-01 11:07:34 -0400
committerRalf Baechle <ralf@linux-mips.org>2005-11-07 13:05:41 -0500
commita637a114f36b94a1ad8b9867f43bac0414958420 (patch)
tree3ad9a5c60817c8d0b4e2de30672da706c44ecbfa /drivers/media/video/saa7191.c
parenta06d61c648890ad7e86d5ea04bd6999b254db193 (diff)
VINO driver version 0.0.5.
Second cut of the VINO / Indycam driver for the Silicon Graphics Indy, much more feature complete and bug free.
Diffstat (limited to 'drivers/media/video/saa7191.c')
-rw-r--r--drivers/media/video/saa7191.c533
1 files changed, 417 insertions, 116 deletions
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index 3ddbb62312be..cbca896e8cfa 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -26,71 +26,95 @@
26 26
27#include "saa7191.h" 27#include "saa7191.h"
28 28
29#define SAA7191_MODULE_VERSION "0.0.3" 29#define SAA7191_MODULE_VERSION "0.0.5"
30 30
31MODULE_DESCRIPTION("Philips SAA7191 video decoder driver"); 31MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
32MODULE_VERSION(SAA7191_MODULE_VERSION); 32MODULE_VERSION(SAA7191_MODULE_VERSION);
33MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>"); 33MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
34MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
35 35
36// #define SAA7191_DEBUG
37
38#ifdef SAA7191_DEBUG
39#define dprintk(x...) printk("SAA7191: " x);
40#else
41#define dprintk(x...)
42#endif
43
44#define SAA7191_SYNC_COUNT 30
45#define SAA7191_SYNC_DELAY 100 /* milliseconds */
46
36struct saa7191 { 47struct saa7191 {
37 struct i2c_client *client; 48 struct i2c_client *client;
38 49
39 /* the register values are stored here as the actual 50 /* the register values are stored here as the actual
40 * I2C-registers are write-only */ 51 * I2C-registers are write-only */
41 unsigned char reg[25]; 52 u8 reg[25];
42 53
43 unsigned char norm; 54 int input;
44 unsigned char input; 55 int norm;
45}; 56};
46 57
47static struct i2c_driver i2c_driver_saa7191; 58static struct i2c_driver i2c_driver_saa7191;
48 59
49static const unsigned char initseq[] = { 60static const u8 initseq[] = {
50 0, /* Subaddress */ 61 0, /* Subaddress */
51 0x50, /* SAA7191_REG_IDEL */ 62
52 0x30, /* SAA7191_REG_HSYB */ 63 0x50, /* (0x50) SAA7191_REG_IDEL */
53 0x00, /* SAA7191_REG_HSYS */ 64
54 0xe8, /* SAA7191_REG_HCLB */ 65 /* 50 Hz signal timing */
55 0xb6, /* SAA7191_REG_HCLS */ 66 0x30, /* (0x30) SAA7191_REG_HSYB */
56 0xf4, /* SAA7191_REG_HPHI */ 67 0x00, /* (0x00) SAA7191_REG_HSYS */
57 0x01, /* SAA7191_REG_LUMA - chrominance trap active (CVBS) */ 68 0xe8, /* (0xe8) SAA7191_REG_HCLB */
58 0x00, /* SAA7191_REG_HUEC */ 69 0xb6, /* (0xb6) SAA7191_REG_HCLS */
59 0xf8, /* SAA7191_REG_CKTQ */ 70 0xf4, /* (0xf4) SAA7191_REG_HPHI */
60 0xf8, /* SAA7191_REG_CKTS */ 71
61 0x90, /* SAA7191_REG_PLSE */ 72 /* control */
62 0x90, /* SAA7191_REG_SESE */ 73 SAA7191_LUMA_APER_1, /* (0x01) SAA7191_REG_LUMA - CVBS mode */
63 0x00, /* SAA7191_REG_GAIN */ 74 0x00, /* (0x00) SAA7191_REG_HUEC */
64 0x0c, /* SAA7191_REG_STDC - not SECAM, slow time constant */ 75 0xf8, /* (0xf8) SAA7191_REG_CKTQ */
65 0x78, /* SAA7191_REG_IOCK - chrominance from CVBS, GPSW1 & 2 off */ 76 0xf8, /* (0xf8) SAA7191_REG_CKTS */
66 0x99, /* SAA7191_REG_CTL3 - automatic field detection */ 77 0x90, /* (0x90) SAA7191_REG_PLSE */
67 0x00, /* SAA7191_REG_CTL4 */ 78 0x90, /* (0x90) SAA7191_REG_SESE */
68 0x2c, /* SAA7191_REG_CHCV */ 79 0x00, /* (0x00) SAA7191_REG_GAIN */
80 SAA7191_STDC_NFEN | SAA7191_STDC_HRMV, /* (0x0c) SAA7191_REG_STDC
81 * - not SECAM,
82 * slow time constant */
83 SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
84 | SAA7191_IOCK_OEDY, /* (0x78) SAA7191_REG_IOCK
85 * - chroma from CVBS, GPSW1 & 2 off */
86 SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
87 | SAA7191_CTL3_YDEL0, /* (0x99) SAA7191_REG_CTL3
88 * - automatic field detection */
89 0x00, /* (0x00) SAA7191_REG_CTL4 */
90 0x2c, /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
69 0x00, /* unused */ 91 0x00, /* unused */
70 0x00, /* unused */ 92 0x00, /* unused */
71 0x34, /* SAA7191_REG_HS6B */ 93
72 0x0a, /* SAA7191_REG_HS6S */ 94 /* 60 Hz signal timing */
73 0xf4, /* SAA7191_REG_HC6B */ 95 0x34, /* (0x34) SAA7191_REG_HS6B */
74 0xce, /* SAA7191_REG_HC6S */ 96 0x0a, /* (0x0a) SAA7191_REG_HS6S */
75 0xf4, /* SAA7191_REG_HP6I */ 97 0xf4, /* (0xf4) SAA7191_REG_HC6B */
98 0xce, /* (0xce) SAA7191_REG_HC6S */
99 0xf4, /* (0xf4) SAA7191_REG_HP6I */
76}; 100};
77 101
78/* SAA7191 register handling */ 102/* SAA7191 register handling */
79 103
80static unsigned char saa7191_read_reg(struct i2c_client *client, 104static u8 saa7191_read_reg(struct i2c_client *client,
81 unsigned char reg) 105 u8 reg)
82{ 106{
83 return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg]; 107 return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
84} 108}
85 109
86static int saa7191_read_status(struct i2c_client *client, 110static int saa7191_read_status(struct i2c_client *client,
87 unsigned char *value) 111 u8 *value)
88{ 112{
89 int ret; 113 int ret;
90 114
91 ret = i2c_master_recv(client, value, 1); 115 ret = i2c_master_recv(client, value, 1);
92 if (ret < 0) { 116 if (ret < 0) {
93 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed"); 117 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
94 return ret; 118 return ret;
95 } 119 }
96 120
@@ -98,17 +122,16 @@ static int saa7191_read_status(struct i2c_client *client,
98} 122}
99 123
100 124
101static int saa7191_write_reg(struct i2c_client *client, unsigned char reg, 125static int saa7191_write_reg(struct i2c_client *client, u8 reg,
102 unsigned char value) 126 u8 value)
103{ 127{
104
105 ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value; 128 ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
106 return i2c_smbus_write_byte_data(client, reg, value); 129 return i2c_smbus_write_byte_data(client, reg, value);
107} 130}
108 131
109/* the first byte of data must be the first subaddress number (register) */ 132/* the first byte of data must be the first subaddress number (register) */
110static int saa7191_write_block(struct i2c_client *client, 133static int saa7191_write_block(struct i2c_client *client,
111 unsigned char length, unsigned char *data) 134 u8 length, u8 *data)
112{ 135{
113 int i; 136 int i;
114 int ret; 137 int ret;
@@ -121,7 +144,7 @@ static int saa7191_write_block(struct i2c_client *client,
121 ret = i2c_master_send(client, data, length); 144 ret = i2c_master_send(client, data, length);
122 if (ret < 0) { 145 if (ret < 0) {
123 printk(KERN_ERR "SAA7191: saa7191_write_block(): " 146 printk(KERN_ERR "SAA7191: saa7191_write_block(): "
124 "write failed"); 147 "write failed\n");
125 return ret; 148 return ret;
126 } 149 }
127 150
@@ -132,8 +155,9 @@ static int saa7191_write_block(struct i2c_client *client,
132 155
133static int saa7191_set_input(struct i2c_client *client, int input) 156static int saa7191_set_input(struct i2c_client *client, int input)
134{ 157{
135 unsigned char luma = saa7191_read_reg(client, SAA7191_REG_LUMA); 158 struct saa7191 *decoder = i2c_get_clientdata(client);
136 unsigned char iock = saa7191_read_reg(client, SAA7191_REG_IOCK); 159 u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
160 u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
137 int err; 161 int err;
138 162
139 switch (input) { 163 switch (input) {
@@ -159,32 +183,20 @@ static int saa7191_set_input(struct i2c_client *client, int input)
159 if (err) 183 if (err)
160 return -EIO; 184 return -EIO;
161 185
186 decoder->input = input;
187
162 return 0; 188 return 0;
163} 189}
164 190
165static int saa7191_set_norm(struct i2c_client *client, int norm) 191static int saa7191_set_norm(struct i2c_client *client, int norm)
166{ 192{
167 struct saa7191 *decoder = i2c_get_clientdata(client); 193 struct saa7191 *decoder = i2c_get_clientdata(client);
168 unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC); 194 u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
169 unsigned char ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); 195 u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
170 unsigned char chcv = saa7191_read_reg(client, SAA7191_REG_CHCV); 196 u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
171 int err; 197 int err;
172 198
173 switch(norm) { 199 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: 200 case SAA7191_NORM_PAL:
189 stdc &= ~SAA7191_STDC_SECS; 201 stdc &= ~SAA7191_STDC_SECS;
190 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); 202 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
@@ -217,60 +229,335 @@ static int saa7191_set_norm(struct i2c_client *client, int norm)
217 229
218 decoder->norm = norm; 230 decoder->norm = norm;
219 231
232 dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
233 stdc, chcv);
234 dprintk("norm: %d\n", norm);
235
220 return 0; 236 return 0;
221} 237}
222 238
223static int saa7191_get_controls(struct i2c_client *client, 239static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
224 struct saa7191_control *ctrl)
225{ 240{
226 unsigned char hue = saa7191_read_reg(client, SAA7191_REG_HUEC); 241 int i = 0;
227 unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
228 242
229 if (hue < 0x80) { 243 dprintk("Checking for signal...\n");
230 hue += 0x80; 244
231 } else { 245 for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
232 hue -= 0x80; 246 if (saa7191_read_status(client, status))
247 return -EIO;
248
249 if (((*status) & SAA7191_STATUS_HLCK) == 0) {
250 dprintk("Signal found\n");
251 return 0;
252 }
253
254 msleep(SAA7191_SYNC_DELAY);
233 } 255 }
234 ctrl->hue = hue;
235 256
236 ctrl->vtrc = (stdc & SAA7191_STDC_VTRC) 257 dprintk("No signal\n");
237 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
238 258
239 return 0; 259 return -EBUSY;
240} 260}
241 261
242static int saa7191_set_controls(struct i2c_client *client, 262static int saa7191_autodetect_norm_extended(struct i2c_client *client)
243 struct saa7191_control *ctrl)
244{ 263{
245 int err; 264 u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
265 u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
266 u8 status;
267 int err = 0;
246 268
247 if (ctrl->hue >= 0) { 269 dprintk("SAA7191 extended signal auto-detection...\n");
248 unsigned char hue = ctrl->hue & 0xff; 270
249 if (hue < 0x80) { 271 stdc &= ~SAA7191_STDC_SECS;
250 hue += 0x80; 272 ctl3 &= ~(SAA7191_CTL3_FSEL);
251 } else { 273
252 hue -= 0x80; 274 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
275 if (err) {
276 err = -EIO;
277 goto out;
278 }
279 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
280 if (err) {
281 err = -EIO;
282 goto out;
283 }
284
285 ctl3 |= SAA7191_CTL3_AUFD;
286 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
287 if (err) {
288 err = -EIO;
289 goto out;
290 }
291
292 msleep(SAA7191_SYNC_DELAY);
293
294 err = saa7191_wait_for_signal(client, &status);
295 if (err)
296 goto out;
297
298 if (status & SAA7191_STATUS_FIDT) {
299 /* 60Hz signal -> NTSC */
300 dprintk("60Hz signal: NTSC\n");
301 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
302 }
303
304 /* 50Hz signal */
305 dprintk("50Hz signal: Trying PAL...\n");
306
307 /* try PAL first */
308 err = saa7191_set_norm(client, SAA7191_NORM_PAL);
309 if (err)
310 goto out;
311
312 msleep(SAA7191_SYNC_DELAY);
313
314 err = saa7191_wait_for_signal(client, &status);
315 if (err)
316 goto out;
317
318 /* not 50Hz ? */
319 if (status & SAA7191_STATUS_FIDT) {
320 dprintk("No 50Hz signal\n");
321 err = -EAGAIN;
322 goto out;
323 }
324
325 if (status & SAA7191_STATUS_CODE) {
326 dprintk("PAL\n");
327 return 0;
328 }
329
330 dprintk("No color detected with PAL - Trying SECAM...\n");
331
332 /* no color detected ? -> try SECAM */
333 err = saa7191_set_norm(client,
334 SAA7191_NORM_SECAM);
335 if (err)
336 goto out;
337
338 msleep(SAA7191_SYNC_DELAY);
339
340 err = saa7191_wait_for_signal(client, &status);
341 if (err)
342 goto out;
343
344 /* not 50Hz ? */
345 if (status & SAA7191_STATUS_FIDT) {
346 dprintk("No 50Hz signal\n");
347 err = -EAGAIN;
348 goto out;
349 }
350
351 if (status & SAA7191_STATUS_CODE) {
352 /* Color detected -> SECAM */
353 dprintk("SECAM\n");
354 return 0;
355 }
356
357 dprintk("No color detected with SECAM - Going back to PAL.\n");
358
359 /* still no color detected ?
360 * -> set norm back to PAL */
361 err = saa7191_set_norm(client,
362 SAA7191_NORM_PAL);
363 if (err)
364 goto out;
365
366out:
367 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
368 if (ctl3 & SAA7191_CTL3_AUFD) {
369 ctl3 &= ~(SAA7191_CTL3_AUFD);
370 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
371 if (err) {
372 err = -EIO;
253 } 373 }
254 err = saa7191_write_reg(client, SAA7191_REG_HUEC, hue);
255 if (err)
256 return -EIO;
257 } 374 }
258 if (ctrl->vtrc >= 0) {
259 unsigned char stdc =
260 saa7191_read_reg(client, SAA7191_REG_STDC);
261 375
262 if (ctrl->vtrc) { 376 return err;
263 stdc |= SAA7191_STDC_VTRC; 377}
264 } else { 378
265 stdc &= ~SAA7191_STDC_VTRC; 379static int saa7191_autodetect_norm(struct i2c_client *client)
380{
381 u8 status;
382
383 dprintk("SAA7191 signal auto-detection...\n");
384
385 dprintk("Reading status...\n");
386
387 if (saa7191_read_status(client, &status))
388 return -EIO;
389
390 dprintk("Checking for signal...\n");
391
392 /* no signal ? */
393 if (status & SAA7191_STATUS_HLCK) {
394 dprintk("No signal\n");
395 return -EBUSY;
396 }
397
398 dprintk("Signal found\n");
399
400 if (status & SAA7191_STATUS_FIDT) {
401 /* 60hz signal -> NTSC */
402 dprintk("NTSC\n");
403 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
404 } else {
405 /* 50hz signal -> PAL */
406 dprintk("PAL\n");
407 return saa7191_set_norm(client, SAA7191_NORM_PAL);
408 }
409}
410
411static int saa7191_get_control(struct i2c_client *client,
412 struct saa7191_control *ctrl)
413{
414 u8 reg;
415 int ret = 0;
416
417 switch (ctrl->type) {
418 case SAA7191_CONTROL_BANDPASS:
419 case SAA7191_CONTROL_BANDPASS_WEIGHT:
420 case SAA7191_CONTROL_CORING:
421 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
422 switch (ctrl->type) {
423 case SAA7191_CONTROL_BANDPASS:
424 ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
425 >> SAA7191_LUMA_BPSS_SHIFT;
426 break;
427 case SAA7191_CONTROL_BANDPASS_WEIGHT:
428 ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
429 >> SAA7191_LUMA_APER_SHIFT;
430 break;
431 case SAA7191_CONTROL_CORING:
432 ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
433 >> SAA7191_LUMA_CORI_SHIFT;
434 break;
266 } 435 }
436 break;
437 case SAA7191_CONTROL_FORCE_COLOUR:
438 case SAA7191_CONTROL_CHROMA_GAIN:
439 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
440 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
441 ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
442 else
443 ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
444 >> SAA7191_GAIN_LFIS_SHIFT;
445 break;
446 case SAA7191_CONTROL_HUE:
447 reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
448 if (reg < 0x80)
449 reg += 0x80;
450 else
451 reg -= 0x80;
452 ctrl->value = (s32)reg;
453 break;
454 case SAA7191_CONTROL_VTRC:
455 reg = saa7191_read_reg(client, SAA7191_REG_STDC);
456 ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
457 break;
458 case SAA7191_CONTROL_LUMA_DELAY:
459 reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
460 ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
461 >> SAA7191_CTL3_YDEL_SHIFT;
462 if (ctrl->value >= 4)
463 ctrl->value -= 8;
464 break;
465 case SAA7191_CONTROL_VNR:
466 reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
467 ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
468 >> SAA7191_CTL4_VNOI_SHIFT;
469 break;
470 default:
471 ret = -EINVAL;
472 }
267 473
268 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); 474 return ret;
269 if (err) 475}
270 return -EIO; 476
477static int saa7191_set_control(struct i2c_client *client,
478 struct saa7191_control *ctrl)
479{
480 u8 reg;
481 int ret = 0;
482
483 switch (ctrl->type) {
484 case SAA7191_CONTROL_BANDPASS:
485 case SAA7191_CONTROL_BANDPASS_WEIGHT:
486 case SAA7191_CONTROL_CORING:
487 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
488 switch (ctrl->type) {
489 case SAA7191_CONTROL_BANDPASS:
490 reg &= ~SAA7191_LUMA_BPSS_MASK;
491 reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
492 & SAA7191_LUMA_BPSS_MASK;
493 break;
494 case SAA7191_CONTROL_BANDPASS_WEIGHT:
495 reg &= ~SAA7191_LUMA_APER_MASK;
496 reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
497 & SAA7191_LUMA_APER_MASK;
498 break;
499 case SAA7191_CONTROL_CORING:
500 reg &= ~SAA7191_LUMA_CORI_MASK;
501 reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
502 & SAA7191_LUMA_CORI_MASK;
503 break;
504 }
505 ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
506 break;
507 case SAA7191_CONTROL_FORCE_COLOUR:
508 case SAA7191_CONTROL_CHROMA_GAIN:
509 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
510 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
511 if (ctrl->value)
512 reg |= SAA7191_GAIN_COLO;
513 else
514 reg &= ~SAA7191_GAIN_COLO;
515 } else {
516 reg &= ~SAA7191_GAIN_LFIS_MASK;
517 reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
518 & SAA7191_GAIN_LFIS_MASK;
519 }
520 ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
521 break;
522 case SAA7191_CONTROL_HUE:
523 reg = ctrl->value & 0xff;
524 if (reg < 0x80)
525 reg += 0x80;
526 else
527 reg -= 0x80;
528 ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
529 break;
530 case SAA7191_CONTROL_VTRC:
531 reg = saa7191_read_reg(client, SAA7191_REG_STDC);
532 if (ctrl->value)
533 reg |= SAA7191_STDC_VTRC;
534 else
535 reg &= ~SAA7191_STDC_VTRC;
536 ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
537 break;
538 case SAA7191_CONTROL_LUMA_DELAY: {
539 s32 value = ctrl->value;
540 if (value < 0)
541 value += 8;
542 reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
543 reg &= ~SAA7191_CTL3_YDEL_MASK;
544 reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
545 & SAA7191_CTL3_YDEL_MASK;
546 ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
547 break;
548 }
549 case SAA7191_CONTROL_VNR:
550 reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
551 reg &= ~SAA7191_CTL4_VNOI_MASK;
552 reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
553 & SAA7191_CTL4_VNOI_MASK;
554 ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
555 break;
556 default:
557 ret = -EINVAL;
271 } 558 }
272 559
273 return 0; 560 return ret;
274} 561}
275 562
276/* I2C-interface */ 563/* I2C-interface */
@@ -309,11 +596,7 @@ static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
309 if (err) 596 if (err)
310 goto out_free_decoder; 597 goto out_free_decoder;
311 598
312 decoder->input = SAA7191_INPUT_COMPOSITE; 599 err = saa7191_write_block(client, sizeof(initseq), (u8 *)initseq);
313 decoder->norm = SAA7191_NORM_AUTO;
314
315 err = saa7191_write_block(client, sizeof(initseq),
316 (unsigned char *)initseq);
317 if (err) { 600 if (err) {
318 printk(KERN_ERR "SAA7191 initialization failed\n"); 601 printk(KERN_ERR "SAA7191 initialization failed\n");
319 goto out_detach_client; 602 goto out_detach_client;
@@ -321,6 +604,14 @@ static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
321 604
322 printk(KERN_INFO "SAA7191 initialized\n"); 605 printk(KERN_INFO "SAA7191 initialized\n");
323 606
607 decoder->input = SAA7191_INPUT_COMPOSITE;
608 decoder->norm = SAA7191_NORM_PAL;
609
610 err = saa7191_autodetect_norm(client);
611 if (err && (err != -EBUSY)) {
612 printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
613 }
614
324 return 0; 615 return 0;
325 616
326out_detach_client: 617out_detach_client:
@@ -368,7 +659,7 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
368 } 659 }
369 case DECODER_GET_STATUS: { 660 case DECODER_GET_STATUS: {
370 int *iarg = arg; 661 int *iarg = arg;
371 unsigned char status; 662 u8 status;
372 int res = 0; 663 int res = 0;
373 664
374 if (saa7191_read_status(client, &status)) { 665 if (saa7191_read_status(client, &status)) {
@@ -404,7 +695,7 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
404 695
405 switch (*iarg) { 696 switch (*iarg) {
406 case VIDEO_MODE_AUTO: 697 case VIDEO_MODE_AUTO:
407 return saa7191_set_norm(client, SAA7191_NORM_AUTO); 698 return saa7191_autodetect_norm(client);
408 case VIDEO_MODE_PAL: 699 case VIDEO_MODE_PAL:
409 return saa7191_set_norm(client, SAA7191_NORM_PAL); 700 return saa7191_set_norm(client, SAA7191_NORM_PAL);
410 case VIDEO_MODE_NTSC: 701 case VIDEO_MODE_NTSC:
@@ -446,38 +737,48 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
446 int err; 737 int err;
447 738
448 val = (pic->hue >> 8) - 0x80; 739 val = (pic->hue >> 8) - 0x80;
740
449 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val); 741 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
450 if (err) 742 if (err)
451 return -EIO; 743 return -EIO;
744
452 break; 745 break;
453 } 746 }
454 case DECODER_SAA7191_GET_STATUS: { 747 case DECODER_SAA7191_GET_STATUS: {
455 struct saa7191_status *status = arg; 748 struct saa7191_status *status = arg;
456 unsigned char status_reg; 749 u8 status_reg;
457 750
458 if (saa7191_read_status(client, &status_reg)) 751 if (saa7191_read_status(client, &status_reg))
459 return -EIO; 752 return -EIO;
753
460 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0) 754 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
461 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED; 755 ? 1 : 0;
462 status->ntsc = (status_reg & SAA7191_STATUS_FIDT) 756 status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
463 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED; 757 ? 1 : 0;
464 status->color = (status_reg & SAA7191_STATUS_CODE) 758 status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
465 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
466 759
467 status->input = decoder->input; 760 status->input = decoder->input;
468 status->norm = decoder->norm; 761 status->norm = decoder->norm;
762
763 break;
469 } 764 }
470 case DECODER_SAA7191_SET_NORM: { 765 case DECODER_SAA7191_SET_NORM: {
471 int *norm = arg; 766 int *norm = arg;
472 return saa7191_set_norm(client, *norm); 767
768 switch (*norm) {
769 case SAA7191_NORM_AUTO:
770 return saa7191_autodetect_norm(client);
771 case SAA7191_NORM_AUTO_EXT:
772 return saa7191_autodetect_norm_extended(client);
773 default:
774 return saa7191_set_norm(client, *norm);
775 }
473 } 776 }
474 case DECODER_SAA7191_GET_CONTROLS: { 777 case DECODER_SAA7191_GET_CONTROL: {
475 struct saa7191_control *ctrl = arg; 778 return saa7191_get_control(client, arg);
476 return saa7191_get_controls(client, ctrl);
477 } 779 }
478 case DECODER_SAA7191_SET_CONTROLS: { 780 case DECODER_SAA7191_SET_CONTROL: {
479 struct saa7191_control *ctrl = arg; 781 return saa7191_set_control(client, arg);
480 return saa7191_set_controls(client, ctrl);
481 } 782 }
482 default: 783 default:
483 return -EINVAL; 784 return -EINVAL;
@@ -488,12 +789,12 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
488 789
489static struct i2c_driver i2c_driver_saa7191 = { 790static struct i2c_driver i2c_driver_saa7191 = {
490 .owner = THIS_MODULE, 791 .owner = THIS_MODULE,
491 .name = "saa7191", 792 .name = "saa7191",
492 .id = I2C_DRIVERID_SAA7191, 793 .id = I2C_DRIVERID_SAA7191,
493 .flags = I2C_DF_NOTIFY, 794 .flags = I2C_DF_NOTIFY,
494 .attach_adapter = saa7191_probe, 795 .attach_adapter = saa7191_probe,
495 .detach_client = saa7191_detach, 796 .detach_client = saa7191_detach,
496 .command = saa7191_command 797 .command = saa7191_command
497}; 798};
498 799
499static int saa7191_init(void) 800static int saa7191_init(void)