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 ]

Diff markup

Differences between /linux/drivers/media/radio/radio-cadet.c (Version 2.6.31.13) and /linux/drivers/media/radio/radio-cadet.c (Version 2.6.25)


  1 /* radio-cadet.c - A video4linux driver for th      1 /* radio-cadet.c - A video4linux driver for the ADS Cadet AM/FM Radio Card
  2  *                                                  2  *
  3  * by Fred Gleason <fredg@wava.com>                 3  * by Fred Gleason <fredg@wava.com>
  4  * Version 0.3.3                                    4  * Version 0.3.3
  5  *                                                  5  *
  6  * (Loosely) based on code for the Aztech radi      6  * (Loosely) based on code for the Aztech radio card by
  7  *                                                  7  *
  8  * Russell Kroll    (rkroll@exploits.org)           8  * Russell Kroll    (rkroll@exploits.org)
  9  * Quay Ly                                          9  * Quay Ly
 10  * Donald Song                                     10  * Donald Song
 11  * Jason Lewis      (jlewis@twilight.vtc.vsc.e     11  * Jason Lewis      (jlewis@twilight.vtc.vsc.edu)
 12  * Scott McGrath    (smcgrath@twilight.vtc.vsc     12  * Scott McGrath    (smcgrath@twilight.vtc.vsc.edu)
 13  * William McGrath  (wmcgrath@twilight.vtc.vsc     13  * William McGrath  (wmcgrath@twilight.vtc.vsc.edu)
 14  *                                                 14  *
 15  * History:                                        15  * History:
 16  * 2000-04-29   Russell Kroll <rkroll@exploits     16  * 2000-04-29   Russell Kroll <rkroll@exploits.org>
 17  *              Added ISAPnP detection for Lin     17  *              Added ISAPnP detection for Linux 2.3/2.4
 18  *                                                 18  *
 19  * 2001-01-10   Russell Kroll <rkroll@exploits     19  * 2001-01-10   Russell Kroll <rkroll@exploits.org>
 20  *              Removed dead CONFIG_RADIO_CADE     20  *              Removed dead CONFIG_RADIO_CADET_PORT code
 21  *              PnP detection on load is now d     21  *              PnP detection on load is now default (no args necessary)
 22  *                                                 22  *
 23  * 2002-01-17   Adam Belay <ambx1@neo.rr.com>      23  * 2002-01-17   Adam Belay <ambx1@neo.rr.com>
 24  *              Updated to latest pnp code         24  *              Updated to latest pnp code
 25  *                                                 25  *
 26  * 2003-01-31   Alan Cox <alan@lxorguk.ukuu.or !!  26  * 2003-01-31   Alan Cox <alan@redhat.com>
 27  *              Cleaned up locking, delay code     27  *              Cleaned up locking, delay code, general odds and ends
 28  *                                                 28  *
 29  * 2006-07-30   Hans J. Koch <koch@hjk-az.de>      29  * 2006-07-30   Hans J. Koch <koch@hjk-az.de>
 30  *              Changed API to V4L2                30  *              Changed API to V4L2
 31  */                                                31  */
 32                                                    32 
 33 #include <linux/version.h>                         33 #include <linux/version.h>
 34 #include <linux/module.h>       /* Modules         34 #include <linux/module.h>       /* Modules                      */
 35 #include <linux/init.h>         /* Initdata        35 #include <linux/init.h>         /* Initdata                     */
 36 #include <linux/ioport.h>       /* request_reg     36 #include <linux/ioport.h>       /* request_region               */
 37 #include <linux/delay.h>        /* udelay          37 #include <linux/delay.h>        /* udelay                       */
                                                   >>  38 #include <asm/io.h>             /* outb, outb_p                 */
                                                   >>  39 #include <asm/uaccess.h>        /* copy to/from user            */
 38 #include <linux/videodev2.h>    /* V4L2 API de     40 #include <linux/videodev2.h>    /* V4L2 API defs                */
                                                   >>  41 #include <media/v4l2-common.h>
 39 #include <linux/param.h>                           42 #include <linux/param.h>
 40 #include <linux/pnp.h>                             43 #include <linux/pnp.h>
 41 #include <linux/io.h>           /* outb, outb_ << 
 42 #include <media/v4l2-device.h>                 << 
 43 #include <media/v4l2-ioctl.h>                  << 
 44                                                << 
 45 MODULE_AUTHOR("Fred Gleason, Russell Kroll, Qu << 
 46 MODULE_DESCRIPTION("A driver for the ADS Cadet << 
 47 MODULE_LICENSE("GPL");                         << 
 48                                                << 
 49 static int io = -1;             /* default to  << 
 50 static int radio_nr = -1;                      << 
 51                                                << 
 52 module_param(io, int, 0);                      << 
 53 MODULE_PARM_DESC(io, "I/O address of Cadet car << 
 54 module_param(radio_nr, int, 0);                << 
 55                                                << 
 56 #define CADET_VERSION KERNEL_VERSION(0, 3, 3)  << 
 57                                                    44 
 58 #define RDS_BUFFER 256                             45 #define RDS_BUFFER 256
 59 #define RDS_RX_FLAG 1                              46 #define RDS_RX_FLAG 1
 60 #define MBS_RX_FLAG 2                              47 #define MBS_RX_FLAG 2
 61                                                    48 
 62 struct cadet {                                 !!  49 #define CADET_VERSION KERNEL_VERSION(0,3,3)
 63         struct v4l2_device v4l2_dev;           !!  50 
 64         struct video_device vdev;              !!  51 static struct v4l2_queryctrl radio_qctrl[] = {
 65         int io;                                !!  52         {
 66         int users;                             !!  53                 .id            = V4L2_CID_AUDIO_MUTE,
 67         int curtuner;                          !!  54                 .name          = "Mute",
 68         int tunestat;                          !!  55                 .minimum       = 0,
 69         int sigstrength;                       !!  56                 .maximum       = 1,
 70         wait_queue_head_t read_queue;          !!  57                 .default_value = 1,
 71         struct timer_list readtimer;           !!  58                 .type          = V4L2_CTRL_TYPE_BOOLEAN,
 72         __u8 rdsin, rdsout, rdsstat;           !!  59         },{
 73         unsigned char rdsbuf[RDS_BUFFER];      !!  60                 .id            = V4L2_CID_AUDIO_VOLUME,
 74         struct mutex lock;                     !!  61                 .name          = "Volume",
 75         int reading;                           !!  62                 .minimum       = 0,
                                                   >>  63                 .maximum       = 0xff,
                                                   >>  64                 .step          = 1,
                                                   >>  65                 .default_value = 0xff,
                                                   >>  66                 .type          = V4L2_CTRL_TYPE_INTEGER,
                                                   >>  67         }
 76 };                                                 68 };
 77                                                    69 
 78 static struct cadet cadet_card;                !!  70 static int io=-1;               /* default to isapnp activation */
                                                   >>  71 static int radio_nr = -1;
                                                   >>  72 static int users=0;
                                                   >>  73 static int curtuner=0;
                                                   >>  74 static int tunestat=0;
                                                   >>  75 static int sigstrength=0;
                                                   >>  76 static wait_queue_head_t read_queue;
                                                   >>  77 static struct timer_list readtimer;
                                                   >>  78 static __u8 rdsin=0,rdsout=0,rdsstat=0;
                                                   >>  79 static unsigned char rdsbuf[RDS_BUFFER];
                                                   >>  80 static spinlock_t cadet_io_lock;
                                                   >>  81 
                                                   >>  82 static int cadet_probe(void);
 79                                                    83 
 80 /*                                                 84 /*
 81  * Signal Strength Threshold Values                85  * Signal Strength Threshold Values
 82  * The V4L API spec does not define any partic     86  * The V4L API spec does not define any particular unit for the signal
 83  * strength value.  These values are in microv     87  * strength value.  These values are in microvolts of RF at the tuner's input.
 84  */                                                88  */
 85 static __u16 sigtable[2][4] = {                !!  89 static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
 86         {  5, 10, 30,  150 },                  << 
 87         { 28, 40, 63, 1000 }                   << 
 88 };                                             << 
 89                                                    90 
 90                                                    91 
 91 static int cadet_getstereo(struct cadet *dev)  !!  92 static int
                                                   >>  93 cadet_getstereo(void)
 92 {                                                  94 {
 93         int ret = V4L2_TUNER_SUB_MONO;             95         int ret = V4L2_TUNER_SUB_MONO;
 94                                                !!  96         if(curtuner != 0)       /* Only FM has stereo capability! */
 95         if (dev->curtuner != 0) /* Only FM has << 
 96                 return V4L2_TUNER_SUB_MONO;        97                 return V4L2_TUNER_SUB_MONO;
 97                                                    98 
 98         mutex_lock(&dev->lock);                !!  99         spin_lock(&cadet_io_lock);
 99         outb(7, dev->io);          /* Select t !! 100         outb(7,io);          /* Select tuner control */
100         if ((inb(dev->io + 1) & 0x40) == 0)    !! 101         if( (inb(io+1) & 0x40) == 0)
101                 ret = V4L2_TUNER_SUB_STEREO;      102                 ret = V4L2_TUNER_SUB_STEREO;
102         mutex_unlock(&dev->lock);              !! 103         spin_unlock(&cadet_io_lock);
103         return ret;                               104         return ret;
104 }                                                 105 }
105                                                   106 
106 static unsigned cadet_gettune(struct cadet *de !! 107 static unsigned
                                                   >> 108 cadet_gettune(void)
107 {                                                 109 {
108         int curvol, i;                         !! 110         int curvol,i;
109         unsigned fifo = 0;                     !! 111         unsigned fifo=0;
110                                                   112 
111         /*                                        113         /*
112          * Prepare for read                       114          * Prepare for read
113          */                                       115          */
114                                                   116 
115         mutex_lock(&dev->lock);                !! 117         spin_lock(&cadet_io_lock);
116                                                   118 
117         outb(7, dev->io);       /* Select tune !! 119         outb(7,io);       /* Select tuner control */
118         curvol = inb(dev->io + 1); /* Save cur !! 120         curvol=inb(io+1); /* Save current volume/mute setting */
119         outb(0x00, dev->io + 1);  /* Ensure WR !! 121         outb(0x00,io+1);  /* Ensure WRITE-ENABLE is LOW */
120         dev->tunestat = 0xffff;                !! 122         tunestat=0xffff;
121                                                   123 
122         /*                                        124         /*
123          * Read the shift register                125          * Read the shift register
124          */                                       126          */
125         for (i = 0; i < 25; i++) {             !! 127         for(i=0;i<25;i++) {
126                 fifo = (fifo << 1) | ((inb(dev !! 128                 fifo=(fifo<<1)|((inb(io+1)>>7)&0x01);
127                 if (i < 24) {                  !! 129                 if(i<24) {
128                         outb(0x01, dev->io + 1 !! 130                         outb(0x01,io+1);
129                         dev->tunestat &= inb(d !! 131                         tunestat&=inb(io+1);
130                         outb(0x00, dev->io + 1 !! 132                         outb(0x00,io+1);
131                 }                                 133                 }
132         }                                         134         }
133                                                   135 
134         /*                                        136         /*
135          * Restore volume/mute setting            137          * Restore volume/mute setting
136          */                                       138          */
137         outb(curvol, dev->io + 1);             !! 139         outb(curvol,io+1);
138         mutex_unlock(&dev->lock);              !! 140         spin_unlock(&cadet_io_lock);
139                                                   141 
140         return fifo;                              142         return fifo;
141 }                                                 143 }
142                                                   144 
143 static unsigned cadet_getfreq(struct cadet *de !! 145 static unsigned
                                                   >> 146 cadet_getfreq(void)
144 {                                                 147 {
145         int i;                                    148         int i;
146         unsigned freq = 0, test, fifo = 0;     !! 149         unsigned freq=0,test,fifo=0;
147                                                   150 
148         /*                                        151         /*
149          * Read current tuning                    152          * Read current tuning
150          */                                       153          */
151         fifo = cadet_gettune(dev);             !! 154         fifo=cadet_gettune();
152                                                   155 
153         /*                                        156         /*
154          * Convert to actual frequency            157          * Convert to actual frequency
155          */                                       158          */
156         if (dev->curtuner == 0) {    /* FM */  !! 159         if(curtuner==0) {    /* FM */
157                 test = 12500;                  !! 160                 test=12500;
158                 for (i = 0; i < 14; i++) {     !! 161                 for(i=0;i<14;i++) {
159                         if ((fifo & 0x01) != 0 !! 162                         if((fifo&0x01)!=0) {
160                                 freq += test;  !! 163                                 freq+=test;
161                         test = test << 1;      !! 164                         }
162                         fifo = fifo >> 1;      !! 165                         test=test<<1;
                                                   >> 166                         fifo=fifo>>1;
163                 }                                 167                 }
164                 freq -= 10700000;           /* !! 168                 freq-=10700000;           /* IF frequency is 10.7 MHz */
165                 freq = (freq * 16) / 1000000;  !! 169                 freq=(freq*16)/1000000;   /* Make it 1/16 MHz */
                                                   >> 170         }
                                                   >> 171         if(curtuner==1) {    /* AM */
                                                   >> 172                 freq=((fifo&0x7fff)-2010)*16;
166         }                                         173         }
167         if (dev->curtuner == 1)    /* AM */    << 
168                 freq = ((fifo & 0x7fff) - 2010 << 
169                                                   174 
170         return freq;                              175         return freq;
171 }                                                 176 }
172                                                   177 
173 static void cadet_settune(struct cadet *dev, u !! 178 static void
                                                   >> 179 cadet_settune(unsigned fifo)
174 {                                                 180 {
175         int i;                                    181         int i;
176         unsigned test;                            182         unsigned test;
177                                                   183 
178         mutex_lock(&dev->lock);                !! 184         spin_lock(&cadet_io_lock);
179                                                   185 
180         outb(7, dev->io);                /* Se !! 186         outb(7,io);                /* Select tuner control */
181         /*                                        187         /*
182          * Write the shift register               188          * Write the shift register
183          */                                       189          */
184         test = 0;                              !! 190         test=0;
185         test = (fifo >> 23) & 0x02;      /* Al !! 191         test=(fifo>>23)&0x02;      /* Align data for SDO */
186         test |= 0x1c;                /* SDM=1, !! 192         test|=0x1c;                /* SDM=1, SWE=1, SEN=1, SCK=0 */
187         outb(7, dev->io);                /* Se !! 193         outb(7,io);                /* Select tuner control */
188         outb(test, dev->io + 1);           /*  !! 194         outb(test,io+1);           /* Initialize for write */
189         for (i = 0; i < 25; i++) {             !! 195         for(i=0;i<25;i++) {
190                 test |= 0x01;              /*  !! 196                 test|=0x01;              /* Toggle SCK High */
191                 outb(test, dev->io + 1);       !! 197                 outb(test,io+1);
192                 test &= 0xfe;              /*  !! 198                 test&=0xfe;              /* Toggle SCK Low */
193                 outb(test, dev->io + 1);       !! 199                 outb(test,io+1);
194                 fifo = fifo << 1;            / !! 200                 fifo=fifo<<1;            /* Prepare the next bit */
195                 test = 0x1c | ((fifo >> 23) &  !! 201                 test=0x1c|((fifo>>23)&0x02);
196                 outb(test, dev->io + 1);       !! 202                 outb(test,io+1);
197         }                                         203         }
198         mutex_unlock(&dev->lock);              !! 204         spin_unlock(&cadet_io_lock);
199 }                                                 205 }
200                                                   206 
201 static void cadet_setfreq(struct cadet *dev, u !! 207 static void
                                                   >> 208 cadet_setfreq(unsigned freq)
202 {                                                 209 {
203         unsigned fifo;                            210         unsigned fifo;
204         int i, j, test;                        !! 211         int i,j,test;
205         int curvol;                               212         int curvol;
206                                                   213 
207         /*                                        214         /*
208          * Formulate a fifo command               215          * Formulate a fifo command
209          */                                       216          */
210         fifo = 0;                              !! 217         fifo=0;
211         if (dev->curtuner == 0) {    /* FM */  !! 218         if(curtuner==0) {    /* FM */
212                 test = 102400;                 !! 219                 test=102400;
213                 freq = (freq * 1000) / 16;     !! 220                 freq=(freq*1000)/16;       /* Make it kHz */
214                 freq += 10700;               / !! 221                 freq+=10700;               /* IF is 10700 kHz */
215                 for (i = 0; i < 14; i++) {     !! 222                 for(i=0;i<14;i++) {
216                         fifo = fifo << 1;      !! 223                         fifo=fifo<<1;
217                         if (freq >= test) {    !! 224                         if(freq>=test) {
218                                 fifo |= 0x01;  !! 225                                 fifo|=0x01;
219                                 freq -= test;  !! 226                                 freq-=test;
220                         }                         227                         }
221                         test = test >> 1;      !! 228                         test=test>>1;
222                 }                                 229                 }
223         }                                         230         }
224         if (dev->curtuner == 1) {    /* AM */  !! 231         if(curtuner==1) {    /* AM */
225                 fifo = (freq / 16) + 2010;     !! 232                 fifo=(freq/16)+2010;            /* Make it kHz */
226                 fifo |= 0x100000;            / !! 233                 fifo|=0x100000;            /* Select AM Band */
227         }                                         234         }
228                                                   235 
229         /*                                        236         /*
230          * Save current volume/mute setting       237          * Save current volume/mute setting
231          */                                       238          */
232                                                   239 
233         mutex_lock(&dev->lock);                !! 240         spin_lock(&cadet_io_lock);
234         outb(7, dev->io);                /* Se !! 241         outb(7,io);                /* Select tuner control */
235         curvol = inb(dev->io + 1);             !! 242         curvol=inb(io+1);
236         mutex_unlock(&dev->lock);              !! 243         spin_unlock(&cadet_io_lock);
237                                                   244 
238         /*                                        245         /*
239          * Tune the card                          246          * Tune the card
240          */                                       247          */
241         for (j = 3; j > -1; j--) {             !! 248         for(j=3;j>-1;j--) {
242                 cadet_settune(dev, fifo | (j < !! 249                 cadet_settune(fifo|(j<<16));
243                                                   250 
244                 mutex_lock(&dev->lock);        !! 251                 spin_lock(&cadet_io_lock);
245                 outb(7, dev->io);         /* S !! 252                 outb(7,io);         /* Select tuner control */
246                 outb(curvol, dev->io + 1);     !! 253                 outb(curvol,io+1);
247                 mutex_unlock(&dev->lock);      !! 254                 spin_unlock(&cadet_io_lock);
248                                                   255 
249                 msleep(100);                      256                 msleep(100);
250                                                   257 
251                 cadet_gettune(dev);            !! 258                 cadet_gettune();
252                 if ((dev->tunestat & 0x40) ==  !! 259                 if((tunestat & 0x40) == 0) {   /* Tuned */
253                         dev->sigstrength = sig !! 260                         sigstrength=sigtable[curtuner][j];
254                         return;                   261                         return;
255                 }                                 262                 }
256         }                                         263         }
257         dev->sigstrength = 0;                  !! 264         sigstrength=0;
258 }                                                 265 }
259                                                   266 
260                                                   267 
261 static int cadet_getvol(struct cadet *dev)     !! 268 static int
                                                   >> 269 cadet_getvol(void)
262 {                                                 270 {
263         int ret = 0;                              271         int ret = 0;
264                                                   272 
265         mutex_lock(&dev->lock);                !! 273         spin_lock(&cadet_io_lock);
266                                                   274 
267         outb(7, dev->io);                /* Se !! 275         outb(7,io);                /* Select tuner control */
268         if ((inb(dev->io + 1) & 0x20) != 0)    !! 276         if((inb(io + 1) & 0x20) != 0)
269                 ret = 0xffff;                     277                 ret = 0xffff;
270                                                   278 
271         mutex_unlock(&dev->lock);              !! 279         spin_unlock(&cadet_io_lock);
272         return ret;                               280         return ret;
273 }                                                 281 }
274                                                   282 
275                                                   283 
276 static void cadet_setvol(struct cadet *dev, in !! 284 static void
                                                   >> 285 cadet_setvol(int vol)
277 {                                                 286 {
278         mutex_lock(&dev->lock);                !! 287         spin_lock(&cadet_io_lock);
279         outb(7, dev->io);                /* Se !! 288         outb(7,io);                /* Select tuner control */
280         if (vol > 0)                           !! 289         if(vol>0)
281                 outb(0x20, dev->io + 1);       !! 290                 outb(0x20,io+1);
282         else                                      291         else
283                 outb(0x00, dev->io + 1);       !! 292                 outb(0x00,io+1);
284         mutex_unlock(&dev->lock);              !! 293         spin_unlock(&cadet_io_lock);
285 }                                                 294 }
286                                                   295 
287 static void cadet_handler(unsigned long data)  !! 296 static void
                                                   >> 297 cadet_handler(unsigned long data)
288 {                                                 298 {
289         struct cadet *dev = (void *)data;      !! 299         /*
                                                   >> 300          * Service the RDS fifo
                                                   >> 301          */
290                                                   302 
291         /* Service the RDS fifo */             !! 303         if(spin_trylock(&cadet_io_lock))
292         if (mutex_trylock(&dev->lock)) {       !! 304         {
293                 outb(0x3, dev->io);       /* S !! 305                 outb(0x3,io);       /* Select RDS Decoder Control */
294                 if ((inb(dev->io + 1) & 0x20)  !! 306                 if((inb(io+1)&0x20)!=0) {
295                         printk(KERN_CRIT "cade    307                         printk(KERN_CRIT "cadet: RDS fifo overflow\n");
296                 outb(0x80, dev->io);      /* S !! 308                 }
297                 while ((inb(dev->io) & 0x80) ! !! 309                 outb(0x80,io);      /* Select RDS fifo */
298                         dev->rdsbuf[dev->rdsin !! 310                 while((inb(io)&0x80)!=0) {
299                         if (dev->rdsin == dev- !! 311                         rdsbuf[rdsin]=inb(io+1);
                                                   >> 312                         if(rdsin==rdsout)
300                                 printk(KERN_WA    313                                 printk(KERN_WARNING "cadet: RDS buffer overflow\n");
301                         else                      314                         else
302                                 dev->rdsin++;  !! 315                                 rdsin++;
303                 }                                 316                 }
304                 mutex_unlock(&dev->lock);      !! 317                 spin_unlock(&cadet_io_lock);
305         }                                         318         }
306                                                   319 
307         /*                                        320         /*
308          * Service pending read                   321          * Service pending read
309          */                                       322          */
310         if (dev->rdsin != dev->rdsout)         !! 323         if( rdsin!=rdsout)
311                 wake_up_interruptible(&dev->re !! 324                 wake_up_interruptible(&read_queue);
312                                                   325 
313         /*                                        326         /*
314          * Clean up and exit                      327          * Clean up and exit
315          */                                       328          */
316         init_timer(&dev->readtimer);           !! 329         init_timer(&readtimer);
317         dev->readtimer.function = cadet_handle !! 330         readtimer.function=cadet_handler;
318         dev->readtimer.data = (unsigned long)0 !! 331         readtimer.data=(unsigned long)0;
319         dev->readtimer.expires = jiffies + mse !! 332         readtimer.expires=jiffies+msecs_to_jiffies(50);
320         add_timer(&dev->readtimer);            !! 333         add_timer(&readtimer);
321 }                                                 334 }
322                                                   335 
323                                                   336 
324 static ssize_t cadet_read(struct file *file, c !! 337 
                                                   >> 338 static ssize_t
                                                   >> 339 cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
325 {                                                 340 {
326         struct cadet *dev = video_drvdata(file !! 341         int i=0;
327         unsigned char readbuf[RDS_BUFFER];        342         unsigned char readbuf[RDS_BUFFER];
328         int i = 0;                             << 
329                                                   343 
330         if (dev->rdsstat == 0) {               !! 344         if(rdsstat==0) {
331                 mutex_lock(&dev->lock);        !! 345                 spin_lock(&cadet_io_lock);
332                 dev->rdsstat = 1;              !! 346                 rdsstat=1;
333                 outb(0x80, dev->io);        /* !! 347                 outb(0x80,io);        /* Select RDS fifo */
334                 mutex_unlock(&dev->lock);      !! 348                 spin_unlock(&cadet_io_lock);
335                 init_timer(&dev->readtimer);   !! 349                 init_timer(&readtimer);
336                 dev->readtimer.function = cade !! 350                 readtimer.function=cadet_handler;
337                 dev->readtimer.data = (unsigne !! 351                 readtimer.data=(unsigned long)0;
338                 dev->readtimer.expires = jiffi !! 352                 readtimer.expires=jiffies+msecs_to_jiffies(50);
339                 add_timer(&dev->readtimer);    !! 353                 add_timer(&readtimer);
340         }                                         354         }
341         if (dev->rdsin == dev->rdsout) {       !! 355         if(rdsin==rdsout) {
342                 if (file->f_flags & O_NONBLOCK    356                 if (file->f_flags & O_NONBLOCK)
343                         return -EWOULDBLOCK;      357                         return -EWOULDBLOCK;
344                 interruptible_sleep_on(&dev->r !! 358                 interruptible_sleep_on(&read_queue);
345         }                                         359         }
346         while (i < count && dev->rdsin != dev- !! 360         while( i<count && rdsin!=rdsout)
347                 readbuf[i++] = dev->rdsbuf[dev !! 361                 readbuf[i++]=rdsbuf[rdsout++];
348                                                   362 
349         if (copy_to_user(data, readbuf, i))    !! 363         if (copy_to_user(data,readbuf,i))
350                 return -EFAULT;                   364                 return -EFAULT;
351         return i;                                 365         return i;
352 }                                                 366 }
353                                                   367 
354                                                   368 
355 static int vidioc_querycap(struct file *file,     369 static int vidioc_querycap(struct file *file, void *priv,
356                                 struct v4l2_ca    370                                 struct v4l2_capability *v)
357 {                                                 371 {
358         strlcpy(v->driver, "ADS Cadet", sizeof !! 372         v->capabilities =
359         strlcpy(v->card, "ADS Cadet", sizeof(v !! 373                 V4L2_CAP_TUNER |
360         strlcpy(v->bus_info, "ISA", sizeof(v-> !! 374                 V4L2_CAP_READWRITE;
361         v->version = CADET_VERSION;               375         v->version = CADET_VERSION;
362         v->capabilities = V4L2_CAP_TUNER | V4L !! 376         strcpy(v->driver, "ADS Cadet");
                                                   >> 377         strcpy(v->card, "ADS Cadet");
363         return 0;                                 378         return 0;
364 }                                                 379 }
365                                                   380 
366 static int vidioc_g_tuner(struct file *file, v    381 static int vidioc_g_tuner(struct file *file, void *priv,
367                                 struct v4l2_tu    382                                 struct v4l2_tuner *v)
368 {                                                 383 {
369         struct cadet *dev = video_drvdata(file << 
370                                                << 
371         v->type = V4L2_TUNER_RADIO;               384         v->type = V4L2_TUNER_RADIO;
372         switch (v->index) {                       385         switch (v->index) {
373         case 0:                                   386         case 0:
374                 strlcpy(v->name, "FM", sizeof( !! 387                 strcpy(v->name, "FM");
375                 v->capability = V4L2_TUNER_CAP    388                 v->capability = V4L2_TUNER_CAP_STEREO;
376                 v->rangelow = 1400;     /* 87.    389                 v->rangelow = 1400;     /* 87.5 MHz */
377                 v->rangehigh = 1728;    /* 108    390                 v->rangehigh = 1728;    /* 108.0 MHz */
378                 v->rxsubchans = cadet_getstere !! 391                 v->rxsubchans=cadet_getstereo();
379                 switch (v->rxsubchans) {       !! 392                 switch (v->rxsubchans){
380                 case V4L2_TUNER_SUB_MONO:         393                 case V4L2_TUNER_SUB_MONO:
381                         v->audmode = V4L2_TUNE    394                         v->audmode = V4L2_TUNER_MODE_MONO;
382                         break;                    395                         break;
383                 case V4L2_TUNER_SUB_STEREO:       396                 case V4L2_TUNER_SUB_STEREO:
384                         v->audmode = V4L2_TUNE    397                         v->audmode = V4L2_TUNER_MODE_STEREO;
385                         break;                    398                         break;
386                 default:                       !! 399                 default: ;
387                         break;                 << 
388                 }                                 400                 }
389                 break;                            401                 break;
390         case 1:                                   402         case 1:
391                 strlcpy(v->name, "AM", sizeof( !! 403                 strcpy(v->name, "AM");
392                 v->capability = V4L2_TUNER_CAP    404                 v->capability = V4L2_TUNER_CAP_LOW;
393                 v->rangelow = 8320;      /* 52    405                 v->rangelow = 8320;      /* 520 kHz */
394                 v->rangehigh = 26400;    /* 16    406                 v->rangehigh = 26400;    /* 1650 kHz */
395                 v->rxsubchans = V4L2_TUNER_SUB    407                 v->rxsubchans = V4L2_TUNER_SUB_MONO;
396                 v->audmode = V4L2_TUNER_MODE_M    408                 v->audmode = V4L2_TUNER_MODE_MONO;
397                 break;                            409                 break;
398         default:                                  410         default:
399                 return -EINVAL;                   411                 return -EINVAL;
400         }                                         412         }
401         v->signal = dev->sigstrength; /* We mi !! 413         v->signal = sigstrength; /* We might need to modify scaling of this */
402         return 0;                                 414         return 0;
403 }                                                 415 }
404                                                   416 
405 static int vidioc_s_tuner(struct file *file, v    417 static int vidioc_s_tuner(struct file *file, void *priv,
406                                 struct v4l2_tu    418                                 struct v4l2_tuner *v)
407 {                                                 419 {
408         struct cadet *dev = video_drvdata(file !! 420         if((v->index != 0)&&(v->index != 1))
409                                                << 
410         if (v->index != 0 && v->index != 1)    << 
411                 return -EINVAL;                   421                 return -EINVAL;
412         dev->curtuner = v->index;              !! 422         curtuner = v->index;
413         return 0;                                 423         return 0;
414 }                                                 424 }
415                                                   425 
416 static int vidioc_g_frequency(struct file *fil    426 static int vidioc_g_frequency(struct file *file, void *priv,
417                                 struct v4l2_fr    427                                 struct v4l2_frequency *f)
418 {                                                 428 {
419         struct cadet *dev = video_drvdata(file !! 429         f->tuner = curtuner;
420                                                << 
421         f->tuner = dev->curtuner;              << 
422         f->type = V4L2_TUNER_RADIO;               430         f->type = V4L2_TUNER_RADIO;
423         f->frequency = cadet_getfreq(dev);     !! 431         f->frequency = cadet_getfreq();
424         return 0;                                 432         return 0;
425 }                                                 433 }
426                                                   434 
427                                                   435 
428 static int vidioc_s_frequency(struct file *fil    436 static int vidioc_s_frequency(struct file *file, void *priv,
429                                 struct v4l2_fr    437                                 struct v4l2_frequency *f)
430 {                                                 438 {
431         struct cadet *dev = video_drvdata(file << 
432                                                << 
433         if (f->type != V4L2_TUNER_RADIO)          439         if (f->type != V4L2_TUNER_RADIO)
434                 return -EINVAL;                   440                 return -EINVAL;
435         if (dev->curtuner == 0 && (f->frequenc !! 441         if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728)))
436                 return -EINVAL;                   442                 return -EINVAL;
437         if (dev->curtuner == 1 && (f->frequenc !! 443         if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400)))
438                 return -EINVAL;                   444                 return -EINVAL;
439         cadet_setfreq(dev, f->frequency);      !! 445         cadet_setfreq(f->frequency);
440         return 0;                                 446         return 0;
441 }                                                 447 }
442                                                   448 
443 static int vidioc_queryctrl(struct file *file,    449 static int vidioc_queryctrl(struct file *file, void *priv,
444                                 struct v4l2_qu    450                                 struct v4l2_queryctrl *qc)
445 {                                                 451 {
446         switch (qc->id) {                      !! 452         int i;
447         case V4L2_CID_AUDIO_MUTE:              !! 453 
448                 return v4l2_ctrl_query_fill(qc !! 454         for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
449         case V4L2_CID_AUDIO_VOLUME:            !! 455                 if (qc->id && qc->id == radio_qctrl[i].id) {
450                 return v4l2_ctrl_query_fill(qc !! 456                         memcpy(qc, &(radio_qctrl[i]),
                                                   >> 457                                                 sizeof(*qc));
                                                   >> 458                         return 0;
                                                   >> 459                 }
451         }                                         460         }
452         return -EINVAL;                           461         return -EINVAL;
453 }                                                 462 }
454                                                   463 
455 static int vidioc_g_ctrl(struct file *file, vo    464 static int vidioc_g_ctrl(struct file *file, void *priv,
456                                 struct v4l2_co    465                                 struct v4l2_control *ctrl)
457 {                                                 466 {
458         struct cadet *dev = video_drvdata(file !! 467         switch (ctrl->id){
459                                                << 
460         switch (ctrl->id) {                    << 
461         case V4L2_CID_AUDIO_MUTE: /* TODO: Han    468         case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
462                 ctrl->value = (cadet_getvol(de !! 469                 ctrl->value = (cadet_getvol() == 0);
463                 break;                            470                 break;
464         case V4L2_CID_AUDIO_VOLUME:               471         case V4L2_CID_AUDIO_VOLUME:
465                 ctrl->value = cadet_getvol(dev !! 472                 ctrl->value = cadet_getvol();
466                 break;                            473                 break;
467         default:                                  474         default:
468                 return -EINVAL;                   475                 return -EINVAL;
469         }                                         476         }
470         return 0;                                 477         return 0;
471 }                                                 478 }
472                                                   479 
473 static int vidioc_s_ctrl(struct file *file, vo    480 static int vidioc_s_ctrl(struct file *file, void *priv,
474                                 struct v4l2_co    481                                 struct v4l2_control *ctrl)
475 {                                                 482 {
476         struct cadet *dev = video_drvdata(file << 
477                                                << 
478         switch (ctrl->id){                        483         switch (ctrl->id){
479         case V4L2_CID_AUDIO_MUTE: /* TODO: Han    484         case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
480                 if (ctrl->value)                  485                 if (ctrl->value)
481                         cadet_setvol(dev, 0);  !! 486                         cadet_setvol(0);
482                 else                              487                 else
483                         cadet_setvol(dev, 0xff !! 488                         cadet_setvol(0xffff);
484                 break;                            489                 break;
485         case V4L2_CID_AUDIO_VOLUME:               490         case V4L2_CID_AUDIO_VOLUME:
486                 cadet_setvol(dev, ctrl->value) !! 491                 cadet_setvol(ctrl->value);
487                 break;                            492                 break;
488         default:                                  493         default:
489                 return -EINVAL;                   494                 return -EINVAL;
490         }                                         495         }
491         return 0;                                 496         return 0;
492 }                                                 497 }
493                                                   498 
494 static int vidioc_g_input(struct file *filp, v !! 499 static int vidioc_g_audio(struct file *file, void *priv,
                                                   >> 500                                 struct v4l2_audio *a)
495 {                                                 501 {
496         *i = 0;                                !! 502         if (a->index > 1)
                                                   >> 503                 return -EINVAL;
                                                   >> 504         strcpy(a->name, "Radio");
                                                   >> 505         a->capability = V4L2_AUDCAP_STEREO;
497         return 0;                                 506         return 0;
498 }                                                 507 }
499                                                   508 
500 static int vidioc_s_input(struct file *filp, v !! 509 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
501 {                                                 510 {
502         return i ? -EINVAL : 0;                !! 511         *i = 0;
                                                   >> 512         return 0;
503 }                                                 513 }
504                                                   514 
505 static int vidioc_g_audio(struct file *file, v !! 515 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
506                                 struct v4l2_au << 
507 {                                                 516 {
508         a->index = 0;                          !! 517         if (i != 0)
509         strlcpy(a->name, "Radio", sizeof(a->na !! 518                 return -EINVAL;
510         a->capability = V4L2_AUDCAP_STEREO;    << 
511         return 0;                                 519         return 0;
512 }                                                 520 }
513                                                   521 
514 static int vidioc_s_audio(struct file *file, v    522 static int vidioc_s_audio(struct file *file, void *priv,
515                                 struct v4l2_au    523                                 struct v4l2_audio *a)
516 {                                                 524 {
517         return a->index ? -EINVAL : 0;         !! 525         if (a->index != 0)
                                                   >> 526                 return -EINVAL;
                                                   >> 527         return 0;
518 }                                                 528 }
519                                                   529 
520 static int cadet_open(struct file *file)       !! 530 static int
                                                   >> 531 cadet_open(struct inode *inode, struct file *file)
521 {                                                 532 {
522         struct cadet *dev = video_drvdata(file !! 533         users++;
523                                                !! 534         if (1 == users) init_waitqueue_head(&read_queue);
524         dev->users++;                          << 
525         if (1 == dev->users)                   << 
526                 init_waitqueue_head(&dev->read << 
527         return 0;                                 535         return 0;
528 }                                                 536 }
529                                                   537 
530 static int cadet_release(struct file *file)    !! 538 static int
                                                   >> 539 cadet_release(struct inode *inode, struct file *file)
531 {                                                 540 {
532         struct cadet *dev = video_drvdata(file !! 541         users--;
533                                                !! 542         if (0 == users){
534         dev->users--;                          !! 543                 del_timer_sync(&readtimer);
535         if (0 == dev->users) {                 !! 544                 rdsstat=0;
536                 del_timer_sync(&dev->readtimer << 
537                 dev->rdsstat = 0;              << 
538         }                                         545         }
539         return 0;                                 546         return 0;
540 }                                                 547 }
541                                                   548 
542 static unsigned int cadet_poll(struct file *fi !! 549 static unsigned int
                                                   >> 550 cadet_poll(struct file *file, struct poll_table_struct *wait)
543 {                                                 551 {
544         struct cadet *dev = video_drvdata(file !! 552         poll_wait(file,&read_queue,wait);
545                                                !! 553         if(rdsin != rdsout)
546         poll_wait(file, &dev->read_queue, wait << 
547         if (dev->rdsin != dev->rdsout)         << 
548                 return POLLIN | POLLRDNORM;       554                 return POLLIN | POLLRDNORM;
549         return 0;                                 555         return 0;
550 }                                                 556 }
551                                                   557 
552                                                   558 
553 static const struct v4l2_file_operations cadet !! 559 static const struct file_operations cadet_fops = {
554         .owner          = THIS_MODULE,            560         .owner          = THIS_MODULE,
555         .open           = cadet_open,             561         .open           = cadet_open,
556         .release        = cadet_release,          562         .release        = cadet_release,
557         .read           = cadet_read,             563         .read           = cadet_read,
558         .ioctl          = video_ioctl2,           564         .ioctl          = video_ioctl2,
559         .poll           = cadet_poll,             565         .poll           = cadet_poll,
                                                   >> 566         .compat_ioctl   = v4l_compat_ioctl32,
                                                   >> 567         .llseek         = no_llseek,
560 };                                                568 };
561                                                   569 
562 static const struct v4l2_ioctl_ops cadet_ioctl !! 570 static struct video_device cadet_radio=
                                                   >> 571 {
                                                   >> 572         .owner          = THIS_MODULE,
                                                   >> 573         .name           = "Cadet radio",
                                                   >> 574         .type           = VID_TYPE_TUNER,
                                                   >> 575         .fops           = &cadet_fops,
563         .vidioc_querycap    = vidioc_querycap,    576         .vidioc_querycap    = vidioc_querycap,
564         .vidioc_g_tuner     = vidioc_g_tuner,     577         .vidioc_g_tuner     = vidioc_g_tuner,
565         .vidioc_s_tuner     = vidioc_s_tuner,     578         .vidioc_s_tuner     = vidioc_s_tuner,
566         .vidioc_g_frequency = vidioc_g_frequen    579         .vidioc_g_frequency = vidioc_g_frequency,
567         .vidioc_s_frequency = vidioc_s_frequen    580         .vidioc_s_frequency = vidioc_s_frequency,
568         .vidioc_queryctrl   = vidioc_queryctrl    581         .vidioc_queryctrl   = vidioc_queryctrl,
569         .vidioc_g_ctrl      = vidioc_g_ctrl,      582         .vidioc_g_ctrl      = vidioc_g_ctrl,
570         .vidioc_s_ctrl      = vidioc_s_ctrl,      583         .vidioc_s_ctrl      = vidioc_s_ctrl,
571         .vidioc_g_audio     = vidioc_g_audio,     584         .vidioc_g_audio     = vidioc_g_audio,
572         .vidioc_s_audio     = vidioc_s_audio,     585         .vidioc_s_audio     = vidioc_s_audio,
573         .vidioc_g_input     = vidioc_g_input,     586         .vidioc_g_input     = vidioc_g_input,
574         .vidioc_s_input     = vidioc_s_input,     587         .vidioc_s_input     = vidioc_s_input,
575 };                                                588 };
576                                                   589 
577 #ifdef CONFIG_PNP                                 590 #ifdef CONFIG_PNP
578                                                   591 
579 static struct pnp_device_id cadet_pnp_devices[    592 static struct pnp_device_id cadet_pnp_devices[] = {
580         /* ADS Cadet AM/FM Radio Card */          593         /* ADS Cadet AM/FM Radio Card */
581         {.id = "MSM0c24", .driver_data = 0},      594         {.id = "MSM0c24", .driver_data = 0},
582         {.id = ""}                                595         {.id = ""}
583 };                                                596 };
584                                                   597 
585 MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices);      598 MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices);
586                                                   599 
587 static int cadet_pnp_probe(struct pnp_dev *dev !! 600 static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
588 {                                                 601 {
589         if (!dev)                                 602         if (!dev)
590                 return -ENODEV;                   603                 return -ENODEV;
591         /* only support one device */             604         /* only support one device */
592         if (io > 0)                               605         if (io > 0)
593                 return -EBUSY;                    606                 return -EBUSY;
594                                                   607 
595         if (!pnp_port_valid(dev, 0))           !! 608         if (!pnp_port_valid(dev, 0)) {
596                 return -ENODEV;                   609                 return -ENODEV;
                                                   >> 610         }
597                                                   611 
598         io = pnp_port_start(dev, 0);              612         io = pnp_port_start(dev, 0);
599                                                   613 
600         printk(KERN_INFO "radio-cadet: PnP rep !! 614         printk ("radio-cadet: PnP reports device at %#x\n", io);
601                                                   615 
602         return io;                                616         return io;
603 }                                                 617 }
604                                                   618 
605 static struct pnp_driver cadet_pnp_driver = {     619 static struct pnp_driver cadet_pnp_driver = {
606         .name           = "radio-cadet",          620         .name           = "radio-cadet",
607         .id_table       = cadet_pnp_devices,      621         .id_table       = cadet_pnp_devices,
608         .probe          = cadet_pnp_probe,        622         .probe          = cadet_pnp_probe,
609         .remove         = NULL,                   623         .remove         = NULL,
610 };                                                624 };
611                                                   625 
612 #else                                             626 #else
613 static struct pnp_driver cadet_pnp_driver;        627 static struct pnp_driver cadet_pnp_driver;
614 #endif                                            628 #endif
615                                                   629 
616 static void cadet_probe(struct cadet *dev)     !! 630 static int cadet_probe(void)
617 {                                                 631 {
618         static int iovals[8] = { 0x330, 0x332, !! 632         static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
619         int i;                                    633         int i;
620                                                   634 
621         for (i = 0; i < 8; i++) {              !! 635         for(i=0;i<8;i++) {
622                 dev->io = iovals[i];           !! 636                 io=iovals[i];
623                 if (request_region(dev->io, 2, !! 637                 if (request_region(io, 2, "cadet-probe")) {
624                         cadet_setfreq(dev, 141 !! 638                         cadet_setfreq(1410);
625                         if (cadet_getfreq(dev) !! 639                         if(cadet_getfreq()==1410) {
626                                 release_region !! 640                                 release_region(io, 2);
627                                 return;        !! 641                                 return io;
628                         }                         642                         }
629                         release_region(dev->io !! 643                         release_region(io, 2);
630                 }                                 644                 }
631         }                                         645         }
632         dev->io = -1;                          !! 646         return -1;
633 }                                                 647 }
634                                                   648 
635 /*                                                649 /*
636  * io should only be set if the user has used     650  * io should only be set if the user has used something like
637  * isapnp (the userspace program) to initializ    651  * isapnp (the userspace program) to initialize this card for us
638  */                                               652  */
639                                                   653 
640 static int __init cadet_init(void)                654 static int __init cadet_init(void)
641 {                                                 655 {
642         struct cadet *dev = &cadet_card;       !! 656         spin_lock_init(&cadet_io_lock);
643         struct v4l2_device *v4l2_dev = &dev->v << 
644         int res;                               << 
645                                                   657 
646         strlcpy(v4l2_dev->name, "cadet", sizeo !! 658         /*
647         mutex_init(&dev->lock);                !! 659          *      If a probe was requested then probe ISAPnP first (safest)
648                                                !! 660          */
649         /* If a probe was requested then probe << 
650         if (io < 0)                               661         if (io < 0)
651                 pnp_register_driver(&cadet_pnp    662                 pnp_register_driver(&cadet_pnp_driver);
652         dev->io = io;                          !! 663         /*
                                                   >> 664          *      If that fails then probe unsafely if probe is requested
                                                   >> 665          */
                                                   >> 666         if(io < 0)
                                                   >> 667                 io = cadet_probe ();
653                                                   668 
654         /* If that fails then probe unsafely i !! 669         /*
655         if (dev->io < 0)                       !! 670          *      Else we bail out
656                 cadet_probe(dev);              !! 671          */
657                                                   672 
658         /* Else we bail out */                 !! 673         if(io < 0) {
659         if (dev->io < 0) {                     << 
660 #ifdef MODULE                                     674 #ifdef MODULE
661                 v4l2_err(v4l2_dev, "you must s !! 675                 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
662                 v4l2_err(v4l2_dev, "0x336, 0x3 << 
663 #endif                                            676 #endif
664                 goto fail;                        677                 goto fail;
665         }                                         678         }
666         if (!request_region(dev->io, 2, "cadet !! 679         if (!request_region(io,2,"cadet"))
667                 goto fail;                        680                 goto fail;
668                                                !! 681         if(video_register_device(&cadet_radio,VFL_TYPE_RADIO,radio_nr)==-1) {
669         res = v4l2_device_register(NULL, v4l2_ !! 682                 release_region(io,2);
670         if (res < 0) {                         << 
671                 release_region(dev->io, 2);    << 
672                 v4l2_err(v4l2_dev, "could not  << 
673                 goto fail;                        683                 goto fail;
674         }                                         684         }
675                                                !! 685         printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io);
676         strlcpy(dev->vdev.name, v4l2_dev->name << 
677         dev->vdev.v4l2_dev = v4l2_dev;         << 
678         dev->vdev.fops = &cadet_fops;          << 
679         dev->vdev.ioctl_ops = &cadet_ioctl_ops << 
680         dev->vdev.release = video_device_relea << 
681         video_set_drvdata(&dev->vdev, dev);    << 
682                                                << 
683         if (video_register_device(&dev->vdev,  << 
684                 v4l2_device_unregister(v4l2_de << 
685                 release_region(dev->io, 2);    << 
686                 goto fail;                     << 
687         }                                      << 
688         v4l2_info(v4l2_dev, "ADS Cadet Radio C << 
689         return 0;                                 686         return 0;
690 fail:                                             687 fail:
691         pnp_unregister_driver(&cadet_pnp_drive    688         pnp_unregister_driver(&cadet_pnp_driver);
692         return -ENODEV;                        !! 689         return -1;
693 }                                                 690 }
694                                                   691 
695 static void __exit cadet_exit(void)            << 
696 {                                              << 
697         struct cadet *dev = &cadet_card;       << 
698                                                   692 
699         video_unregister_device(&dev->vdev);   !! 693 
700         v4l2_device_unregister(&dev->v4l2_dev) !! 694 MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
701         release_region(dev->io, 2);            !! 695 MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
                                                   >> 696 MODULE_LICENSE("GPL");
                                                   >> 697 
                                                   >> 698 module_param(io, int, 0);
                                                   >> 699 MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
                                                   >> 700 module_param(radio_nr, int, 0);
                                                   >> 701 
                                                   >> 702 static void __exit cadet_cleanup_module(void)
                                                   >> 703 {
                                                   >> 704         video_unregister_device(&cadet_radio);
                                                   >> 705         release_region(io,2);
702         pnp_unregister_driver(&cadet_pnp_drive    706         pnp_unregister_driver(&cadet_pnp_driver);
703 }                                                 707 }
704                                                   708 
705 module_init(cadet_init);                          709 module_init(cadet_init);
706 module_exit(cadet_exit);                       !! 710 module_exit(cadet_cleanup_module);
707                                                   711 
708                                                   712 
  This page was automatically generated by the LXR engine.