Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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/slab.h>
 21 
 22 #include <linux/videodev.h>
 23 #include <linux/video_decoder.h>
 24 #include <linux/i2c.h>
 25 
 26 #include "saa7191.h"
 27 
 28 #define SAA7191_MODULE_VERSION  "0.0.5"
 29 
 30 MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
 31 MODULE_VERSION(SAA7191_MODULE_VERSION);
 32 MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
 33 MODULE_LICENSE("GPL");
 34 
 35 // #define SAA7191_DEBUG
 36 
 37 #ifdef SAA7191_DEBUG
 38 #define dprintk(x...) printk("SAA7191: " x);
 39 #else
 40 #define dprintk(x...)
 41 #endif
 42 
 43 #define SAA7191_SYNC_COUNT      30
 44 #define SAA7191_SYNC_DELAY      100     /* milliseconds */
 45 
 46 struct saa7191 {
 47         struct i2c_client *client;
 48 
 49         /* the register values are stored here as the actual
 50          * I2C-registers are write-only */
 51         u8 reg[25];
 52 
 53         int input;
 54         int norm;
 55 };
 56 
 57 static struct i2c_driver i2c_driver_saa7191;
 58 
 59 static const u8 initseq[] = {
 60         0,      /* Subaddress */
 61 
 62         0x50,   /* (0x50) SAA7191_REG_IDEL */
 63 
 64         /* 50 Hz signal timing */
 65         0x30,   /* (0x30) SAA7191_REG_HSYB */
 66         0x00,   /* (0x00) SAA7191_REG_HSYS */
 67         0xe8,   /* (0xe8) SAA7191_REG_HCLB */
 68         0xb6,   /* (0xb6) SAA7191_REG_HCLS */
 69         0xf4,   /* (0xf4) SAA7191_REG_HPHI */
 70 
 71         /* control */
 72         SAA7191_LUMA_APER_1,    /* (0x01) SAA7191_REG_LUMA - CVBS mode */
 73         0x00,   /* (0x00) SAA7191_REG_HUEC */
 74         0xf8,   /* (0xf8) SAA7191_REG_CKTQ */
 75         0xf8,   /* (0xf8) SAA7191_REG_CKTS */
 76         0x90,   /* (0x90) SAA7191_REG_PLSE */
 77         0x90,   /* (0x90) SAA7191_REG_SESE */
 78         0x00,   /* (0x00) SAA7191_REG_GAIN */
 79         SAA7191_STDC_NFEN | SAA7191_STDC_HRMV,  /* (0x0c) SAA7191_REG_STDC
 80                                                  * - not SECAM,
 81                                                  * slow time constant */
 82         SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
 83         | SAA7191_IOCK_OEDY,    /* (0x78) SAA7191_REG_IOCK
 84                                  * - chroma from CVBS, GPSW1 & 2 off */
 85         SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
 86         | SAA7191_CTL3_YDEL0,   /* (0x99) SAA7191_REG_CTL3
 87                                  * - automatic field detection */
 88         0x00,   /* (0x00) SAA7191_REG_CTL4 */
 89         0x2c,   /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
 90         0x00,   /* unused */
 91         0x00,   /* unused */
 92 
 93         /* 60 Hz signal timing */
 94         0x34,   /* (0x34) SAA7191_REG_HS6B */
 95         0x0a,   /* (0x0a) SAA7191_REG_HS6S */
 96         0xf4,   /* (0xf4) SAA7191_REG_HC6B */
 97         0xce,   /* (0xce) SAA7191_REG_HC6S */
 98         0xf4,   /* (0xf4) SAA7191_REG_HP6I */
 99 };
100 
101 /* SAA7191 register handling */
102 
103 static u8 saa7191_read_reg(struct i2c_client *client,
104                            u8 reg)
105 {
106         return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
107 }
108 
109 static int saa7191_read_status(struct i2c_client *client,
110                                u8 *value)
111 {
112         int ret;
113 
114         ret = i2c_master_recv(client, value, 1);
115         if (ret < 0) {
116                 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
117                 return ret;
118         }
119 
120         return 0;
121 }
122 
123 
124 static int saa7191_write_reg(struct i2c_client *client, u8 reg,
125                              u8 value)
126 {
127         ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
128         return i2c_smbus_write_byte_data(client, reg, value);
129 }
130 
131 /* the first byte of data must be the first subaddress number (register) */
132 static int saa7191_write_block(struct i2c_client *client,
133                                u8 length, const u8 *data)
134 {
135         int i;
136         int ret;
137 
138         struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
139         for (i = 0; i < (length - 1); i++) {
140                 decoder->reg[data[0] + i] = data[i + 1];
141         }
142 
143         ret = i2c_master_send(client, data, length);
144         if (ret < 0) {
145                 printk(KERN_ERR "SAA7191: saa7191_write_block(): "
146                        "write failed\n");
147                 return ret;
148         }
149 
150         return 0;
151 }
152 
153 /* Helper functions */
154 
155 static int saa7191_set_input(struct i2c_client *client, int input)
156 {
157         struct saa7191 *decoder = i2c_get_clientdata(client);
158         u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
159         u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
160         int err;
161 
162         switch (input) {
163         case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
164                 iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
165                           | SAA7191_IOCK_GPSW2);
166                 /* Chrominance trap active */
167                 luma &= ~SAA7191_LUMA_BYPS;
168                 break;
169         case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
170                 iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
171                 /* Chrominance trap bypassed */
172                 luma |= SAA7191_LUMA_BYPS;
173                 break;
174         default:
175                 return -EINVAL;
176         }
177 
178         err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
179         if (err)
180                 return -EIO;
181         err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
182         if (err)
183                 return -EIO;
184 
185         decoder->input = input;
186 
187         return 0;
188 }
189 
190 static int saa7191_set_norm(struct i2c_client *client, int norm)
191 {
192         struct saa7191 *decoder = i2c_get_clientdata(client);
193         u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
194         u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
195         u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
196         int err;
197 
198         switch(norm) {
199         case SAA7191_NORM_PAL:
200                 stdc &= ~SAA7191_STDC_SECS;
201                 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
202                 chcv = SAA7191_CHCV_PAL;
203                 break;
204         case SAA7191_NORM_NTSC:
205                 stdc &= ~SAA7191_STDC_SECS;
206                 ctl3 &= ~SAA7191_CTL3_AUFD;
207                 ctl3 |= SAA7191_CTL3_FSEL;
208                 chcv = SAA7191_CHCV_NTSC;
209                 break;
210         case SAA7191_NORM_SECAM:
211                 stdc |= SAA7191_STDC_SECS;
212                 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
213                 chcv = SAA7191_CHCV_PAL;
214                 break;
215         default:
216                 return -EINVAL;
217         }
218 
219         err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
220         if (err)
221                 return -EIO;
222         err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
223         if (err)
224                 return -EIO;
225         err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
226         if (err)
227                 return -EIO;
228 
229         decoder->norm = norm;
230 
231         dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
232                 stdc, chcv);
233         dprintk("norm: %d\n", norm);
234 
235         return 0;
236 }
237 
238 static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
239 {
240         int i = 0;
241 
242         dprintk("Checking for signal...\n");
243 
244         for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
245                 if (saa7191_read_status(client, status))
246                         return -EIO;
247 
248                 if (((*status) & SAA7191_STATUS_HLCK) == 0) {
249                         dprintk("Signal found\n");
250                         return 0;
251                 }
252 
253                 msleep(SAA7191_SYNC_DELAY);
254         }
255 
256         dprintk("No signal\n");
257 
258         return -EBUSY;
259 }
260 
261 static int saa7191_autodetect_norm_extended(struct i2c_client *client)
262 {
263         u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
264         u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
265         u8 status;
266         int err = 0;
267 
268         dprintk("SAA7191 extended signal auto-detection...\n");
269 
270         stdc &= ~SAA7191_STDC_SECS;
271         ctl3 &= ~(SAA7191_CTL3_FSEL);
272 
273         err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
274         if (err) {
275                 err = -EIO;
276                 goto out;
277         }
278         err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
279         if (err) {
280                 err = -EIO;
281                 goto out;
282         }
283 
284         ctl3 |= SAA7191_CTL3_AUFD;
285         err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
286         if (err) {
287                 err = -EIO;
288                 goto out;
289         }
290 
291         msleep(SAA7191_SYNC_DELAY);
292 
293         err = saa7191_wait_for_signal(client, &status);
294         if (err)
295                 goto out;
296 
297         if (status & SAA7191_STATUS_FIDT) {
298                 /* 60Hz signal -> NTSC */
299                 dprintk("60Hz signal: NTSC\n");
300                 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
301         }
302 
303         /* 50Hz signal */
304         dprintk("50Hz signal: Trying PAL...\n");
305 
306         /* try PAL first */
307         err = saa7191_set_norm(client, SAA7191_NORM_PAL);
308         if (err)
309                 goto out;
310 
311         msleep(SAA7191_SYNC_DELAY);
312 
313         err = saa7191_wait_for_signal(client, &status);
314         if (err)
315                 goto out;
316 
317         /* not 50Hz ? */
318         if (status & SAA7191_STATUS_FIDT) {
319                 dprintk("No 50Hz signal\n");
320                 err = -EAGAIN;
321                 goto out;
322         }
323 
324         if (status & SAA7191_STATUS_CODE) {
325                 dprintk("PAL\n");
326                 return 0;
327         }
328 
329         dprintk("No color detected with PAL - Trying SECAM...\n");
330 
331         /* no color detected ? -> try SECAM */
332         err = saa7191_set_norm(client,
333                                SAA7191_NORM_SECAM);
334         if (err)
335                 goto out;
336 
337         msleep(SAA7191_SYNC_DELAY);
338 
339         err = saa7191_wait_for_signal(client, &status);
340         if (err)
341                 goto out;
342 
343         /* not 50Hz ? */
344         if (status & SAA7191_STATUS_FIDT) {
345                 dprintk("No 50Hz signal\n");
346                 err = -EAGAIN;
347                 goto out;
348         }
349 
350         if (status & SAA7191_STATUS_CODE) {
351                 /* Color detected -> SECAM */
352                 dprintk("SECAM\n");
353                 return 0;
354         }
355 
356         dprintk("No color detected with SECAM - Going back to PAL.\n");
357 
358         /* still no color detected ?
359          * -> set norm back to PAL */
360         err = saa7191_set_norm(client,
361                                SAA7191_NORM_PAL);
362         if (err)
363                 goto out;
364 
365 out:
366         ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
367         if (ctl3 & SAA7191_CTL3_AUFD) {
368                 ctl3 &= ~(SAA7191_CTL3_AUFD);
369                 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
370                 if (err) {
371                         err = -EIO;
372                 }
373         }
374 
375         return err;
376 }
377 
378 static int saa7191_autodetect_norm(struct i2c_client *client)
379 {
380         u8 status;
381 
382         dprintk("SAA7191 signal auto-detection...\n");
383 
384         dprintk("Reading status...\n");
385 
386         if (saa7191_read_status(client, &status))
387                 return -EIO;
388 
389         dprintk("Checking for signal...\n");
390 
391         /* no signal ? */
392         if (status & SAA7191_STATUS_HLCK) {
393                 dprintk("No signal\n");
394                 return -EBUSY;
395         }
396 
397         dprintk("Signal found\n");
398 
399         if (status & SAA7191_STATUS_FIDT) {
400                 /* 60hz signal -> NTSC */
401                 dprintk("NTSC\n");
402                 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
403         } else {
404                 /* 50hz signal -> PAL */
405                 dprintk("PAL\n");
406                 return saa7191_set_norm(client, SAA7191_NORM_PAL);
407         }
408 }
409 
410 static int saa7191_get_control(struct i2c_client *client,
411                                struct saa7191_control *ctrl)
412 {
413         u8 reg;
414         int ret = 0;
415 
416         switch (ctrl->type) {
417         case SAA7191_CONTROL_BANDPASS:
418         case SAA7191_CONTROL_BANDPASS_WEIGHT:
419         case SAA7191_CONTROL_CORING:
420                 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
421                 switch (ctrl->type) {
422                 case SAA7191_CONTROL_BANDPASS:
423                         ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
424                                 >> SAA7191_LUMA_BPSS_SHIFT;
425                         break;
426                 case SAA7191_CONTROL_BANDPASS_WEIGHT:
427                         ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
428                                 >> SAA7191_LUMA_APER_SHIFT;
429                         break;
430                 case SAA7191_CONTROL_CORING:
431                         ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
432                                 >> SAA7191_LUMA_CORI_SHIFT;
433                         break;
434                 }
435                 break;
436         case SAA7191_CONTROL_FORCE_COLOUR:
437         case SAA7191_CONTROL_CHROMA_GAIN:
438                 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
439                 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
440                         ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
441                 else
442                         ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
443                                 >> SAA7191_GAIN_LFIS_SHIFT;
444                 break;
445         case SAA7191_CONTROL_HUE:
446                 reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
447                 if (reg < 0x80)
448                         reg += 0x80;
449                 else
450                         reg -= 0x80;
451                 ctrl->value = (s32)reg;
452                 break;
453         case SAA7191_CONTROL_VTRC:
454                 reg = saa7191_read_reg(client, SAA7191_REG_STDC);
455                 ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
456                 break;
457         case SAA7191_CONTROL_LUMA_DELAY:
458                 reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
459                 ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
460                         >> SAA7191_CTL3_YDEL_SHIFT;
461                 if (ctrl->value >= 4)
462                         ctrl->value -= 8;
463                 break;
464         case SAA7191_CONTROL_VNR:
465                 reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
466                 ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
467                         >> SAA7191_CTL4_VNOI_SHIFT;
468                 break;
469         default:
470                 ret = -EINVAL;
471         }
472 
473         return ret;
474 }
475 
476 static int saa7191_set_control(struct i2c_client *client,
477                                struct saa7191_control *ctrl)
478 {
479         u8 reg;
480         int ret = 0;
481 
482         switch (ctrl->type) {
483         case SAA7191_CONTROL_BANDPASS:
484         case SAA7191_CONTROL_BANDPASS_WEIGHT:
485         case SAA7191_CONTROL_CORING:
486                 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
487                 switch (ctrl->type) {
488                 case SAA7191_CONTROL_BANDPASS:
489                         reg &= ~SAA7191_LUMA_BPSS_MASK;
490                         reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
491                                 & SAA7191_LUMA_BPSS_MASK;
492                         break;
493                 case SAA7191_CONTROL_BANDPASS_WEIGHT:
494                         reg &= ~SAA7191_LUMA_APER_MASK;
495                         reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
496                                 & SAA7191_LUMA_APER_MASK;
497                         break;
498                 case SAA7191_CONTROL_CORING:
499                         reg &= ~SAA7191_LUMA_CORI_MASK;
500                         reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
501                                 & SAA7191_LUMA_CORI_MASK;
502                         break;
503                 }
504                 ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
505                 break;
506         case SAA7191_CONTROL_FORCE_COLOUR:
507         case SAA7191_CONTROL_CHROMA_GAIN:
508                 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
509                 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
510                         if (ctrl->value)
511                                 reg |= SAA7191_GAIN_COLO;
512                         else
513                                 reg &= ~SAA7191_GAIN_COLO;
514                 } else {
515                         reg &= ~SAA7191_GAIN_LFIS_MASK;
516                         reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
517                                 & SAA7191_GAIN_LFIS_MASK;
518                 }
519                 ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
520                 break;
521         case SAA7191_CONTROL_HUE:
522                 reg = ctrl->value & 0xff;
523                 if (reg < 0x80)
524                         reg += 0x80;
525                 else
526                         reg -= 0x80;
527                 ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
528                 break;
529         case SAA7191_CONTROL_VTRC:
530                 reg = saa7191_read_reg(client, SAA7191_REG_STDC);
531                 if (ctrl->value)
532                         reg |= SAA7191_STDC_VTRC;
533                 else
534                         reg &= ~SAA7191_STDC_VTRC;
535                 ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
536                 break;
537         case SAA7191_CONTROL_LUMA_DELAY: {
538                 s32 value = ctrl->value;
539                 if (value < 0)
540                         value += 8;
541                 reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
542                 reg &= ~SAA7191_CTL3_YDEL_MASK;
543                 reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
544                         & SAA7191_CTL3_YDEL_MASK;
545                 ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
546                 break;
547         }
548         case SAA7191_CONTROL_VNR:
549                 reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
550                 reg &= ~SAA7191_CTL4_VNOI_MASK;
551                 reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
552                         & SAA7191_CTL4_VNOI_MASK;
553                 ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
554                 break;
555         default:
556                 ret = -EINVAL;
557         }
558 
559         return ret;
560 }
561 
562 /* I2C-interface */
563 
564 static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
565 {
566         int err = 0;
567         struct saa7191 *decoder;
568         struct i2c_client *client;
569 
570         printk(KERN_INFO "Philips SAA7191 driver version %s\n",
571                SAA7191_MODULE_VERSION);
572 
573         client = kzalloc(sizeof(*client), GFP_KERNEL);
574         if (!client)
575                 return -ENOMEM;
576         decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
577         if (!decoder) {
578                 err = -ENOMEM;
579                 goto out_free_client;
580         }
581 
582         client->addr = addr;
583         client->adapter = adap;
584         client->driver = &i2c_driver_saa7191;
585         client->flags = 0;
586         strcpy(client->name, "saa7191 client");
587         i2c_set_clientdata(client, decoder);
588 
589         decoder->client = client;
590 
591         err = i2c_attach_client(client);
592         if (err)
593                 goto out_free_decoder;
594 
595         err = saa7191_write_block(client, sizeof(initseq), initseq);
596         if (err) {
597                 printk(KERN_ERR "SAA7191 initialization failed\n");
598                 goto out_detach_client;
599         }
600 
601         printk(KERN_INFO "SAA7191 initialized\n");
602 
603         decoder->input = SAA7191_INPUT_COMPOSITE;
604         decoder->norm = SAA7191_NORM_PAL;
605 
606         err = saa7191_autodetect_norm(client);
607         if (err && (err != -EBUSY)) {
608                 printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
609         }
610 
611         return 0;
612 
613 out_detach_client:
614         i2c_detach_client(client);
615 out_free_decoder:
616         kfree(decoder);
617 out_free_client:
618         kfree(client);
619         return err;
620 }
621 
622 static int saa7191_probe(struct i2c_adapter *adap)
623 {
624         /* Always connected to VINO */
625         if (adap->id == I2C_HW_SGI_VINO)
626                 return saa7191_attach(adap, SAA7191_ADDR, 0);
627         /* Feel free to add probe here :-) */
628         return -ENODEV;
629 }
630 
631 static int saa7191_detach(struct i2c_client *client)
632 {
633         struct saa7191 *decoder = i2c_get_clientdata(client);
634 
635         i2c_detach_client(client);
636         kfree(decoder);
637         kfree(client);
638         return 0;
639 }
640 
641 static int saa7191_command(struct i2c_client *client, unsigned int cmd,
642                            void *arg)
643 {
644         struct saa7191 *decoder = i2c_get_clientdata(client);
645 
646         switch (cmd) {
647         case DECODER_GET_CAPABILITIES: {
648                 struct video_decoder_capability *cap = arg;
649 
650                 cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
651                               VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
652                 cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
653                 cap->outputs = 1;
654                 break;
655         }
656         case DECODER_GET_STATUS: {
657                 int *iarg = arg;
658                 u8 status;
659                 int res = 0;
660 
661                 if (saa7191_read_status(client, &status)) {
662                         return -EIO;
663                 }
664                 if ((status & SAA7191_STATUS_HLCK) == 0)
665                         res |= DECODER_STATUS_GOOD;
666                 if (status & SAA7191_STATUS_CODE)
667                         res |= DECODER_STATUS_COLOR;
668                 switch (decoder->norm) {
669                 case SAA7191_NORM_NTSC:
670                         res |= DECODER_STATUS_NTSC;
671                         break;
672                 case SAA7191_NORM_PAL:
673                         res |= DECODER_STATUS_PAL;
674                         break;
675                 case SAA7191_NORM_SECAM:
676                         res |= DECODER_STATUS_SECAM;
677                         break;
678                 case SAA7191_NORM_AUTO:
679                 default:
680                         if (status & SAA7191_STATUS_FIDT)
681                                 res |= DECODER_STATUS_NTSC;
682                         else
683                                 res |= DECODER_STATUS_PAL;
684                         break;
685                 }
686                 *iarg = res;
687                 break;
688         }
689         case DECODER_SET_NORM: {
690                 int *iarg = arg;
691 
692                 switch (*iarg) {
693                 case VIDEO_MODE_AUTO:
694                         return saa7191_autodetect_norm(client);
695                 case VIDEO_MODE_PAL:
696                         return saa7191_set_norm(client, SAA7191_NORM_PAL);
697                 case VIDEO_MODE_NTSC:
698                         return saa7191_set_norm(client, SAA7191_NORM_NTSC);
699                 case VIDEO_MODE_SECAM:
700                         return saa7191_set_norm(client, SAA7191_NORM_SECAM);
701                 default:
702                         return -EINVAL;
703                 }
704                 break;
705         }
706         case DECODER_SET_INPUT: {
707                 int *iarg = arg;
708 
709                 switch (client->adapter->id) {
710                 case I2C_HW_SGI_VINO:
711                         return saa7191_set_input(client, *iarg);
712                 default:
713                         if (*iarg != 0)
714                                 return -EINVAL;
715                 }
716                 break;
717         }
718         case DECODER_SET_OUTPUT: {
719                 int *iarg = arg;
720 
721                 /* not much choice of outputs */
722                 if (*iarg != 0)
723                         return -EINVAL;
724                 break;
725         }
726         case DECODER_ENABLE_OUTPUT: {
727                 /* Always enabled */
728                 break;
729         }
730         case DECODER_SET_PICTURE: {
731                 struct video_picture *pic = arg;
732                 unsigned val;
733                 int err;
734 
735                 val = (pic->hue >> 8) - 0x80;
736 
737                 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
738                 if (err)
739                         return -EIO;
740 
741                 break;
742         }
743         case DECODER_SAA7191_GET_STATUS: {
744                 struct saa7191_status *status = arg;
745                 u8 status_reg;
746 
747                 if (saa7191_read_status(client, &status_reg))
748                         return -EIO;
749 
750                 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
751                         ? 1 : 0;
752                 status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
753                         ? 1 : 0;
754                 status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
755 
756                 status->input = decoder->input;
757                 status->norm = decoder->norm;
758 
759                 break;
760         }
761         case DECODER_SAA7191_SET_NORM: {
762                 int *norm = arg;
763 
764                 switch (*norm) {
765                 case SAA7191_NORM_AUTO:
766                         return saa7191_autodetect_norm(client);
767                 case SAA7191_NORM_AUTO_EXT:
768                         return saa7191_autodetect_norm_extended(client);
769                 default:
770                         return saa7191_set_norm(client, *norm);
771                 }
772         }
773         case DECODER_SAA7191_GET_CONTROL: {
774                 return saa7191_get_control(client, arg);
775         }
776         case DECODER_SAA7191_SET_CONTROL: {
777                 return saa7191_set_control(client, arg);
778         }
779         default:
780                 return -EINVAL;
781         }
782 
783         return 0;
784 }
785 
786 static struct i2c_driver i2c_driver_saa7191 = {
787         .driver = {
788                 .name   = "saa7191",
789         },
790         .id             = I2C_DRIVERID_SAA7191,
791         .attach_adapter = saa7191_probe,
792         .detach_client  = saa7191_detach,
793         .command        = saa7191_command
794 };
795 
796 static int saa7191_init(void)
797 {
798         return i2c_add_driver(&i2c_driver_saa7191);
799 }
800 
801 static void saa7191_exit(void)
802 {
803         i2c_del_driver(&i2c_driver_saa7191);
804 }
805 
806 module_init(saa7191_init);
807 module_exit(saa7191_exit);
808 
  This page was automatically generated by the LXR engine.