~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/media/video/msp3400.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * programming the msp34* sound processor family
  3  *
  4  * (c) 1997-2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
  5  *
  6  * what works and what doesn't:
  7  *
  8  *  AM-Mono
  9  *      Support for Hauppauge cards added (decoding handled by tuner) added by
 10  *      Frederic Crozat <fcrozat@mail.dotcom.fr>
 11  *
 12  *  FM-Mono
 13  *      should work. The stereo modes are backward compatible to FM-mono,
 14  *      therefore FM-Mono should be allways available.
 15  *
 16  *  FM-Stereo (B/G, used in germany)
 17  *      should work, with autodetect
 18  *
 19  *  FM-Stereo (satellite)
 20  *      should work, no autodetect (i.e. default is mono, but you can
 21  *      switch to stereo -- untested)
 22  *
 23  *  NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
 24  *      should work, with autodetect. Support for NICAM was added by
 25  *      Pekka Pietikainen <pp@netppl.fi>
 26  *
 27  *
 28  * TODO:
 29  *   - better SAT support
 30  *
 31  *
 32  * 980623  Thomas Sailer (sailer@ife.ee.ethz.ch)
 33  *         using soundcore instead of OSS
 34  *
 35  */
 36 
 37 #include <linux/config.h>
 38 #include <linux/module.h>
 39 #include <linux/kernel.h>
 40 #include <linux/sched.h>
 41 #include <linux/string.h>
 42 #include <linux/timer.h>
 43 #include <linux/delay.h>
 44 #include <linux/errno.h>
 45 #include <linux/malloc.h>
 46 #include <linux/i2c.h>
 47 #include <linux/videodev.h>
 48 #include <asm/semaphore.h>
 49 #include <linux/init.h>
 50 
 51 #ifdef CONFIG_SMP
 52 #include <asm/pgtable.h>
 53 #include <linux/smp_lock.h>
 54 #endif
 55 /* kernel_thread */
 56 #define __KERNEL_SYSCALLS__
 57 #include <linux/unistd.h>
 58 
 59 #include "audiochip.h"
 60 
 61 /* Addresses to scan */
 62 static unsigned short normal_i2c[] = {I2C_CLIENT_END};
 63 static unsigned short normal_i2c_range[] = {0x40,0x40,I2C_CLIENT_END};
 64 static unsigned short probe[2]        = { I2C_CLIENT_END, I2C_CLIENT_END };
 65 static unsigned short probe_range[2]  = { I2C_CLIENT_END, I2C_CLIENT_END };
 66 static unsigned short ignore[2]       = { I2C_CLIENT_END, I2C_CLIENT_END };
 67 static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
 68 static unsigned short force[2]        = { I2C_CLIENT_END, I2C_CLIENT_END };
 69 static struct i2c_client_address_data addr_data = {
 70         normal_i2c, normal_i2c_range, 
 71         probe, probe_range, 
 72         ignore, ignore_range, 
 73         force
 74 };
 75 
 76 /* insmod parameters */
 77 static int debug   = 0;    /* debug output */
 78 static int once    = 0;    /* no continous stereo monitoring */
 79 static int amsound = 0;    /* hard-wire AM sound at 6.5 Hz (france),
 80                               the autoscan seems work well only with FM... */
 81 static int simple  = -1;   /* use short programming (>= msp3410 only) */
 82 static int dolby   = 0;
 83 
 84 struct msp3400c {
 85         int simple;
 86         int nicam;
 87         int mode;
 88         int norm;
 89         int stereo;
 90         int nicam_on;
 91         int acb;
 92         int main, second;       /* sound carrier */
 93 
 94         int muted;
 95         int left, right;        /* volume */
 96         int bass, treble;
 97 
 98         /* thread */
 99         struct task_struct  *thread;
100         wait_queue_head_t    wq;
101 
102         struct semaphore    *notify;
103         int                  active,restart,rmmod;
104 
105         int                  watch_stereo;
106         struct timer_list    wake_stereo;
107 };
108 
109 #define MSP3400_MAX 4
110 static struct i2c_client *msps[MSP3400_MAX];
111 
112 #define VIDEO_MODE_RADIO 16      /* norm magic for radio mode */
113 
114 /* ---------------------------------------------------------------------- */
115 
116 #define dprintk     if (debug) printk
117 
118 MODULE_PARM(once,"i");
119 MODULE_PARM(debug,"i");
120 MODULE_PARM(simple,"i");
121 MODULE_PARM(amsound,"i");
122 MODULE_PARM(dolby,"i");
123 
124 /* ---------------------------------------------------------------------- */
125 
126 #define I2C_MSP3400C       0x80
127 #define I2C_MSP3400C_DEM   0x10
128 #define I2C_MSP3400C_DFP   0x12
129 
130 /* ----------------------------------------------------------------------- */
131 /* functions for talking to the MSP3400C Sound processor                   */
132 
133 static int msp3400c_reset(struct i2c_client *client)
134 {
135         static char reset_off[3] = { 0x00, 0x80, 0x00 };
136         static char reset_on[3]  = { 0x00, 0x00, 0x00 };
137 
138         i2c_master_send(client,reset_off,3);  /* XXX ignore errors here */
139         if (3 != i2c_master_send(client,reset_on, 3)) {
140                 printk(KERN_ERR "msp3400: chip reset failed, penguin on i2c bus?\n");
141                 return -1;
142         }
143         return 0;
144 }
145 
146 static int
147 msp3400c_read(struct i2c_client *client, int dev, int addr)
148 {
149         int err;
150 
151         unsigned char write[3];
152         unsigned char read[2];
153         struct i2c_msg msgs[2] = {
154                 { client->addr, 0,        3, write },
155                 { client->addr, I2C_M_RD, 2, read  }
156         };
157         write[0] = dev+1;
158         write[1] = addr >> 8;
159         write[2] = addr & 0xff;
160 
161         for (err = 0; err < 3;) {
162                 if (2 == i2c_transfer(client->adapter,msgs,2))
163                         break;
164                 err++;
165                 printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n",
166                        err, dev, addr);
167                 current->state = TASK_INTERRUPTIBLE;
168                 schedule_timeout(HZ/10);
169         }
170         if (3 == err) {
171                 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
172                 msp3400c_reset(client);
173                 return -1;
174         }
175         return read[0] << 8 | read[1];
176 }
177 
178 static int
179 msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
180 {
181         int err;
182         unsigned char buffer[5];
183 
184         buffer[0] = dev;
185         buffer[1] = addr >> 8;
186         buffer[2] = addr &  0xff;
187         buffer[3] = val  >> 8;
188         buffer[4] = val  &  0xff;
189 
190         for (err = 0; err < 3;) {
191                 if (5 == i2c_master_send(client, buffer, 5))
192                         break;
193                 err++;
194                 printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n",
195                        err, dev, addr);
196                 current->state = TASK_INTERRUPTIBLE;
197                 schedule_timeout(HZ/10);
198         }
199         if (3 == err) {
200                 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
201                 msp3400c_reset(client);
202                 return -1;
203         }
204         return 0;
205 }
206 
207 /* ------------------------------------------------------------------------ */
208 
209 /* This macro is allowed for *constants* only, gcc must calculate it
210    at compile time.  Remember -- no floats in kernel mode */
211 #define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
212 
213 #define MSP_MODE_AM_DETECT   0
214 #define MSP_MODE_FM_RADIO    2
215 #define MSP_MODE_FM_TERRA    3
216 #define MSP_MODE_FM_SAT      4
217 #define MSP_MODE_FM_NICAM1   5
218 #define MSP_MODE_FM_NICAM2   6
219 #define MSP_MODE_AM_NICAM    7
220 #define MSP_MODE_BTSC        8
221 
222 static struct MSP_INIT_DATA_DEM {
223         int fir1[6];
224         int fir2[6];
225         int cdo1;
226         int cdo2;
227         int ad_cv;
228         int mode_reg;
229         int dfp_src;
230         int dfp_matrix;
231 } msp_init_data[] = {
232         /* AM (for carrier detect / msp3400) */
233         { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
234           MSP_CARRIER(5.5), MSP_CARRIER(5.5),
235           0x00d0, 0x0500,   0x0020, 0x3000},
236 
237         /* AM (for carrier detect / msp3410) */
238         { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
239           MSP_CARRIER(5.5), MSP_CARRIER(5.5),
240           0x00d0, 0x0100,   0x0020, 0x3000},
241 
242         /* FM Radio */
243         { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
244           MSP_CARRIER(10.7), MSP_CARRIER(10.7),
245           0x00d0, 0x0480, 0x0020, 0x3000 },
246 
247         /* Terrestial FM-mono + FM-stereo */
248         { {  3, 18, 27, 48, 66, 72 }, {  3, 18, 27, 48, 66, 72 },
249           MSP_CARRIER(5.5), MSP_CARRIER(5.5),
250           0x00d0, 0x0480,   0x0030, 0x3000},
251 
252         /* Sat FM-mono */
253         { {  1,  9, 14, 24, 33, 37 }, {  3, 18, 27, 48, 66, 72 },
254           MSP_CARRIER(6.5), MSP_CARRIER(6.5),
255           0x00c6, 0x0480,   0x0000, 0x3000},
256 
257         /* NICAM/FM --  B/G (5.5/5.85), D/K (6.5/5.85) */
258         { { -2, -8, -10, 10, 50, 86 }, {  3, 18, 27, 48, 66, 72 },
259           MSP_CARRIER(5.5), MSP_CARRIER(5.5),
260           0x00d0, 0x0040,   0x0120, 0x3000},
261 
262         /* NICAM/FM -- I (6.0/6.552) */
263         { {  2, 4, -6, -4, 40, 94 }, {  3, 18, 27, 48, 66, 72 },
264           MSP_CARRIER(6.0), MSP_CARRIER(6.0),
265           0x00d0, 0x0040,   0x0120, 0x3000},
266 
267         /* NICAM/AM -- L (6.5/5.85) */
268         { {  -2, -8, -10, 10, 50, 86 }, {  -4, -12, -9, 23, 79, 126 },
269           MSP_CARRIER(6.5), MSP_CARRIER(6.5),
270           0x00c6, 0x0140,   0x0120, 0x7c03},
271 };
272 
273 struct CARRIER_DETECT {
274         int   cdo;
275         char *name;
276 };
277 
278 static struct CARRIER_DETECT carrier_detect_main[] = {
279         /* main carrier */
280         { MSP_CARRIER(4.5),        "4.5   NTSC"                   }, 
281         { MSP_CARRIER(5.5),        "5.5   PAL B/G"                }, 
282         { MSP_CARRIER(6.0),        "6.0   PAL I"                  },
283         { MSP_CARRIER(6.5),        "6.5   PAL D/K + SAT + SECAM"  }
284 };
285 
286 static struct CARRIER_DETECT carrier_detect_55[] = {
287         /* PAL B/G */
288         { MSP_CARRIER(5.7421875),  "5.742 PAL B/G FM-stereo"     }, 
289         { MSP_CARRIER(5.85),       "5.85  PAL B/G NICAM"         }
290 };
291 
292 static struct CARRIER_DETECT carrier_detect_65[] = {
293         /* PAL SAT / SECAM */
294         { MSP_CARRIER(5.85),       "5.85  PAL D/K + SECAM NICAM" },
295         { MSP_CARRIER(6.2578125),  "6.25  PAL D/K1 FM-stereo" },
296         { MSP_CARRIER(6.7421875),  "6.74  PAL D/K2 FM-stereo" },
297         { MSP_CARRIER(7.02),       "7.02  PAL SAT FM-stereo s/b" },
298         { MSP_CARRIER(7.20),       "7.20  PAL SAT FM-stereo s"   },
299         { MSP_CARRIER(7.38),       "7.38  PAL SAT FM-stereo b"   },
300 };
301 
302 #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
303 
304 /* ----------------------------------------------------------------------- */
305 
306 #define SCART_MASK    0
307 #define SCART_IN1     1
308 #define SCART_IN2     2
309 #define SCART_IN1_DA  3
310 #define SCART_IN2_DA  4
311 #define SCART_IN3     5
312 #define SCART_IN4     6
313 #define SCART_MONO    7
314 #define SCART_MUTE    8
315 
316 static int scarts[3][9] = {
317   /* MASK    IN1     IN2     IN1_DA  IN2_DA  IN3     IN4     MONO    MUTE   */
318   {  0x0320, 0x0000, 0x0200, -1,     -1,     0x0300, 0x0020, 0x0100, 0x0320 },
319   {  0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
320   {  0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
321 };
322 
323 static char *scart_names[] = {
324   "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
325 };
326 
327 static void
328 msp3400c_set_scart(struct i2c_client *client, int in, int out)
329 {
330         struct msp3400c *msp = client->data;
331 
332         if (-1 == scarts[out][in])
333                 return;
334 
335         dprintk("msp34xx: scart switch: %s => %d\n",scart_names[in],out);
336         msp->acb &= ~scarts[out][SCART_MASK];
337         msp->acb |=  scarts[out][in];
338         msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
339 }
340 
341 /* ------------------------------------------------------------------------ */
342 
343 static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
344 {
345         msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
346         msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
347         msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff);
348         msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
349         msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
350 }
351 
352 static void msp3400c_setvolume(struct i2c_client *client,
353                                int muted, int left, int right)
354 {
355         int vol = 0,val = 0,balance = 0;
356 
357         if (!muted) {
358                 vol     = (left > right) ? left : right;
359                 val     = (vol * 0x73 / 65535) << 8;
360         }
361         if (vol > 0) {
362                 balance = ((right-left) * 127) / vol;
363         }
364 
365         dprintk("msp34xx: setvolume: mute=%s %d:%d  v=0x%02x b=0x%02x\n",
366                 muted ? "on" : "off", left, right, val>>8, balance);
367         msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
368         msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones  */
369         /* scart - on/off only */
370         msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, val ? 0x4000 : 0);
371         msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, balance << 8);
372 }
373 
374 static void msp3400c_setbass(struct i2c_client *client, int bass)
375 {
376         int val = ((bass-32768) * 0x60 / 65535) << 8;
377 
378         dprintk("msp34xx: setbass: %d 0x%02x\n",bass, val>>8);
379         msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
380 }
381 
382 static void msp3400c_settreble(struct i2c_client *client, int treble)
383 {
384         int val = ((treble-32768) * 0x60 / 65535) << 8;
385 
386         dprintk("msp34xx: settreble: %d 0x%02x\n",treble, val>>8);
387         msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
388 }
389 
390 static void msp3400c_setmode(struct i2c_client *client, int type)
391 {
392         struct msp3400c *msp = client->data;
393         int i;
394         
395         dprintk("msp3400: setmode: %d\n",type);
396         msp->mode   = type;
397         msp->stereo = VIDEO_SOUND_MONO;
398 
399         msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb,          /* ad_cv */
400                        msp_init_data[type].ad_cv);
401     
402         for (i = 5; i >= 0; i--)                                   /* fir 1 */
403                 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001,
404                                msp_init_data[type].fir1[i]);
405     
406         msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */
407         msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040);
408         msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000);
409         for (i = 5; i >= 0; i--)
410                 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005,
411                                msp_init_data[type].fir2[i]);
412     
413         msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083,     /* MODE_REG */
414                        msp_init_data[type].mode_reg);
415     
416         msp3400c_setcarrier(client, msp_init_data[type].cdo1,
417                             msp_init_data[type].cdo2);
418     
419         msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
420 
421         if (dolby) {
422                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
423                                0x0520); /* I2S1 */
424                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
425                                0x0620); /* I2S2 */
426                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
427                                msp_init_data[type].dfp_src);
428         } else {
429                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
430                                msp_init_data[type].dfp_src);
431                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
432                                msp_init_data[type].dfp_src);
433         }
434         msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
435                        msp_init_data[type].dfp_src);
436         msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e,
437                        msp_init_data[type].dfp_matrix);
438 
439         if (msp->nicam) {
440                 /* nicam prescale */
441                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */
442         }
443 }
444 
445 /* turn on/off nicam + stereo */
446 static void msp3400c_setstereo(struct i2c_client *client, int mode)
447 {
448         struct msp3400c *msp = client->data;
449         int nicam=0; /* channel source: FM/AM or nicam */
450         int src=0;
451 
452         /* switch demodulator */
453         switch (msp->mode) {
454         case MSP_MODE_FM_TERRA:
455                 dprintk("msp3400: FM setstereo: %d\n",mode);
456                 msp3400c_setcarrier(client,msp->second,msp->main);
457                 switch (mode) {
458                 case VIDEO_SOUND_STEREO:
459                         msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
460                         break;
461                 case VIDEO_SOUND_MONO:
462                 case VIDEO_SOUND_LANG1:
463                 case VIDEO_SOUND_LANG2:
464                         msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000);
465                         break;
466                 }
467                 break;
468         case MSP_MODE_FM_SAT:
469                 dprintk("msp3400: SAT setstereo: %d\n",mode);
470                 switch (mode) {
471                 case VIDEO_SOUND_MONO:
472                         msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
473                         break;
474                 case VIDEO_SOUND_STEREO:
475                         msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
476                         break;
477                 case VIDEO_SOUND_LANG1:
478                         msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
479                         break;
480                 case VIDEO_SOUND_LANG2:
481                         msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
482                         break;
483                 }
484                 break;
485         case MSP_MODE_FM_NICAM1:
486         case MSP_MODE_FM_NICAM2:
487         case MSP_MODE_AM_NICAM:
488                 dprintk("msp3400: NICAM setstereo: %d\n",mode);
489                 msp3400c_setcarrier(client,msp->second,msp->main);
490                 if (msp->nicam_on)
491                         nicam=0x0100;
492                 break;
493         case MSP_MODE_BTSC:
494                 dprintk("msp3400: BTSC setstereo: %d\n",mode);
495                 nicam=0x0300;
496                 break;
497         default:
498                 dprintk("msp3400: mono setstereo\n");
499                 return;
500         }
501 
502         /* switch audio */
503         switch (mode) {
504         case VIDEO_SOUND_STEREO:
505                 src = 0x0020 | nicam;
506 #if 0 
507                 /* spatial effect */
508                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000);
509 #endif
510                 break;
511         case VIDEO_SOUND_MONO:
512                 if (msp->mode == MSP_MODE_AM_NICAM) {
513                         dprintk("msp3400: switching to AM mono\n");
514                         /* AM mono decoding is handled by tuner, not MSP chip */
515                         /* SCART switching control register */
516                         msp3400c_set_scart(client,SCART_MONO,0);
517                         src = 0x0200;
518                         break;
519                 }
520         case VIDEO_SOUND_LANG1:
521                 src = 0x0000 | nicam;
522                 break;
523         case VIDEO_SOUND_LANG2:
524                 src = 0x0010 | nicam;
525                 break;
526         }
527         if (dolby) {
528                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
529                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
530                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
531                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
532         } else {
533                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src);
534                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src);
535                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
536         }
537 }
538 
539 static void
540 msp3400c_print_mode(struct msp3400c *msp)
541 {
542         if (msp->main == msp->second) {
543                 printk("msp3400: mono sound carrier: %d.%03d MHz\n",
544                        msp->main/910000,(msp->main/910)%1000);
545         } else {
546                 printk("msp3400: main sound carrier: %d.%03d MHz\n",
547                        msp->main/910000,(msp->main/910)%1000);
548         }
549         if (msp->mode == MSP_MODE_FM_NICAM1 ||
550             msp->mode == MSP_MODE_FM_NICAM2)
551                 printk("msp3400: NICAM/FM carrier   : %d.%03d MHz\n",
552                        msp->second/910000,(msp->second/910)%1000);
553         if (msp->mode == MSP_MODE_AM_NICAM)
554                 printk("msp3400: NICAM/AM carrier   : %d.%03d MHz\n",
555                        msp->second/910000,(msp->second/910)%1000);
556         if (msp->mode == MSP_MODE_FM_TERRA &&
557             msp->main != msp->second) {
558                 printk("msp3400: FM-stereo carrier : %d.%03d MHz\n",
559                        msp->second/910000,(msp->second/910)%1000);
560         }
561 }
562 
563 /* ----------------------------------------------------------------------- */
564 
565 struct REGISTER_DUMP {
566         int   addr;
567         char *name;
568 };
569 
570 struct REGISTER_DUMP d1[] = {
571         { 0x007e, "autodetect" },
572         { 0x0023, "C_AD_BITS " },
573         { 0x0038, "ADD_BITS  " },
574         { 0x003e, "CIB_BITS  " },
575         { 0x0057, "ERROR_RATE" },
576 };
577 
578 static int
579 autodetect_stereo(struct i2c_client *client)
580 {
581         struct msp3400c *msp = client->data;
582         int val;
583         int newstereo = msp->stereo;
584         int newnicam  = msp->nicam_on;
585         int update = 0;
586 
587         switch (msp->mode) {
588         case MSP_MODE_FM_TERRA:
589                 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
590                 if (val > 32768)
591                         val -= 65536;
592                 dprintk("msp34xx: stereo detect register: %d\n",val);
593                 
594                 if (val > 4096) {
595                         newstereo = VIDEO_SOUND_STEREO | VIDEO_SOUND_MONO;
596                 } else if (val < -4096) {
597                         newstereo = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
598                 } else {
599                         newstereo = VIDEO_SOUND_MONO;
600                 }
601                 newnicam = 0;
602                 break;
603         case MSP_MODE_FM_NICAM1:
604         case MSP_MODE_FM_NICAM2:
605         case MSP_MODE_AM_NICAM:
606                 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
607                 dprintk("msp34xx: nicam sync=%d, mode=%d\n",val & 1, (val & 0x1e) >> 1);
608 
609                 if (val & 1) {
610                         /* nicam synced */
611                         switch ((val & 0x1e) >> 1)  {
612                         case 0:
613                         case 8:
614                                 newstereo = VIDEO_SOUND_STEREO;
615                                 break;
616                         case 1:
617                         case 9:
618                                 newstereo = VIDEO_SOUND_MONO
619                                         | VIDEO_SOUND_LANG1;
620                                 break;
621                         case 2:
622                         case 10:
623                                 newstereo = VIDEO_SOUND_MONO
624                                         | VIDEO_SOUND_LANG1
625                                         | VIDEO_SOUND_LANG2;
626                                 break;
627                         default:
628                                 newstereo = VIDEO_SOUND_MONO;
629                                 break;
630                         }
631                         newnicam=1;
632                 } else {
633                         newnicam = 0;
634                         newstereo = VIDEO_SOUND_MONO;
635                 }
636                 break;
637         case MSP_MODE_BTSC:
638                 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
639                 dprintk("msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
640                         val,
641                         (val & 0x0002) ? "no"     : "yes",
642                         (val & 0x0004) ? "no"     : "yes",
643                         (val & 0x0040) ? "stereo" : "mono",
644                         (val & 0x0080) ? ", nicam 2nd mono" : "",
645                         (val & 0x0100) ? ", bilingual/SAP"  : "");
646                 newstereo = VIDEO_SOUND_MONO;
647                 if (val & 0x0040) newstereo |= VIDEO_SOUND_STEREO;
648                 if (val & 0x0100) newstereo |= VIDEO_SOUND_LANG1;
649                 break;
650         }
651         if (newstereo != msp->stereo) {
652                 update = 1;
653                 dprintk("msp34xx: watch: stereo %d => %d\n",
654                         msp->stereo,newstereo);
655                 msp->stereo   = newstereo;
656         }
657         if (newnicam != msp->nicam_on) {
658                 update = 1;
659                 dprintk("msp34xx: watch: nicam %d => %d\n",
660                         msp->nicam_on,newnicam);
661                 msp->nicam_on = newnicam;
662         }
663         return update;
664 }
665 
666 /*
667  * A kernel thread for msp3400 control -- we don't want to block the
668  * in the ioctl while doing the sound carrier & stereo detect
669  */
670 
671 static void msp3400c_stereo_wake(unsigned long data)
672 {
673         struct msp3400c *msp = (struct msp3400c*)data;   /* XXX alpha ??? */
674 
675         wake_up_interruptible(&msp->wq);
676 }
677 
678 /* stereo/multilang monitoring */
679 static void watch_stereo(struct i2c_client *client)
680 {
681         struct msp3400c *msp = client->data;
682 
683         if (autodetect_stereo(client)) {
684                 if (msp->stereo & VIDEO_SOUND_STEREO)
685                         msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
686                 else if (msp->stereo & VIDEO_SOUND_LANG1)
687                         msp3400c_setstereo(client,VIDEO_SOUND_LANG1);
688                 else
689                         msp3400c_setstereo(client,VIDEO_SOUND_MONO);
690         }
691         if (once)
692                 msp->watch_stereo = 0;
693         if (msp->watch_stereo)
694                 mod_timer(&msp->wake_stereo, jiffies+5*HZ);
695 }
696 
697 static int msp3400c_thread(void *data)
698 {
699         struct i2c_client *client = data;
700         struct msp3400c *msp = client->data;
701     
702         struct CARRIER_DETECT *cd;
703         int                   count, max1,max2,val1,val2, val,this;
704     
705 #ifdef CONFIG_SMP
706         lock_kernel();
707 #endif
708     
709         daemonize();
710         sigfillset(&current->blocked);
711         strcpy(current->comm,"msp3400");
712 
713         msp->thread = current;
714 
715 #ifdef CONFIG_SMP
716         unlock_kernel();
717 #endif
718 
719         printk("msp3400: daemon started\n");
720         if(msp->notify != NULL)
721                 up(msp->notify);
722                 
723         for (;;) {
724                 if (msp->rmmod)
725                         goto done;
726                 if (debug > 1)
727                         printk("msp3400: thread: sleep\n");
728                 interruptible_sleep_on(&msp->wq);
729                 if (debug > 1)
730                         printk("msp3400: thread: wakeup\n");
731                 if (msp->rmmod || signal_pending(current))
732                         goto done;
733 
734                 if (VIDEO_MODE_RADIO == msp->norm)
735                         continue;  /* nothing to do */
736         
737                 msp->active = 1;
738 
739                 if (msp->watch_stereo) {
740                         watch_stereo(client);
741                         msp->active = 0;
742                         continue;
743                 }
744 
745                 /* some time for the tuner to sync */
746                 current->state   = TASK_INTERRUPTIBLE;
747                 schedule_timeout(HZ/5);
748                 if (signal_pending(current))
749                         goto done;
750                 
751         restart:
752                 msp->restart = 0;
753                 msp3400c_setvolume(client, msp->muted, 0, 0);
754                 msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
755                 val1 = val2 = 0;
756                 max1 = max2 = -1;
757                 del_timer(&msp->wake_stereo);
758                 msp->watch_stereo = 0;
759 
760                 /* carrier detect pass #1 -- main carrier */
761                 cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);
762 
763                 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
764                         /* autodetect doesn't work well with AM ... */
765                         max1 = 3;
766                         count = 0;
767                         dprintk("msp3400: AM sound override\n");
768                 }
769 
770                 for (this = 0; this < count; this++) {
771                         msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
772 
773                         current->state   = TASK_INTERRUPTIBLE;
774                         schedule_timeout(HZ/10);
775                         if (signal_pending(current))
776                                 goto done;
777                         if (msp->restart)
778                                 msp->restart = 0;
779 
780                         val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
781                         if (val > 32768)
782                                 val -= 65536;
783                         if (val1 < val)
784                                 val1 = val, max1 = this;
785                         dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name);
786                 }
787         
788                 /* carrier detect pass #2 -- second (stereo) carrier */
789                 switch (max1) {
790                 case 1: /* 5.5 */
791                         cd = carrier_detect_55; count = CARRIER_COUNT(carrier_detect_55);
792                         break;
793                 case 3: /* 6.5 */
794                         cd = carrier_detect_65; count = CARRIER_COUNT(carrier_detect_65);
795                         break;
796                 case 0: /* 4.5 */
797                 case 2: /* 6.0 */
798                 default:
799                         cd = NULL; count = 0;
800                         break;
801                 }
802                 
803                 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
804                         /* autodetect doesn't work well with AM ... */
805                         cd = NULL; count = 0; max2 = 0;
806                 }
807                 for (this = 0; this < count; this++) {
808                         msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
809 
810                         current->state   = TASK_INTERRUPTIBLE;
811                         schedule_timeout(HZ/10);
812                         if (signal_pending(current))
813                                 goto done;
814                         if (msp->restart)
815                                 goto restart;
816 
817                         val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
818                         if (val > 32768)
819                                 val -= 65536;
820                         if (val2 < val)
821                                 val2 = val, max2 = this;
822                         dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name);
823                 }
824 
825                 /* programm the msp3400 according to the results */
826                 msp->main   = carrier_detect_main[max1].cdo;
827                 switch (max1) {
828                 case 1: /* 5.5 */
829                         if (max2 == 0) {
830                                 /* B/G FM-stereo */
831                                 msp->second = carrier_detect_55[max2].cdo;
832                                 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
833                                 msp->nicam_on = 0;
834                                 msp3400c_setstereo(client, VIDEO_SOUND_MONO);
835                                 msp->watch_stereo = 1;
836                         } else if (max2 == 1 && msp->nicam) {
837                                 /* B/G NICAM */
838                                 msp->second = carrier_detect_55[max2].cdo;
839                                 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
840                                 msp->nicam_on = 1;
841                                 msp3400c_setcarrier(client, msp->second, msp->main);
842                                 msp->watch_stereo = 1;
843                         } else {
844                                 goto no_second;
845                         }
846                         break;
847                 case 2: /* 6.0 */
848                         /* PAL I NICAM */
849                         msp->second = MSP_CARRIER(6.552);
850                         msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
851                         msp->nicam_on = 1;
852                         msp3400c_setcarrier(client, msp->second, msp->main);
853                         msp->watch_stereo = 1;
854                         break;
855                 case 3: /* 6.5 */
856                         if (max2 == 1 || max2 == 2) {
857                                 /* D/K FM-stereo */
858                                 msp->second = carrier_detect_65[max2].cdo;
859                                 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
860                                 msp->nicam_on = 0;
861                                 msp3400c_setstereo(client, VIDEO_SOUND_MONO);
862                                 msp->watch_stereo = 1;
863                         } else if (max2 == 0 &&
864                                    msp->norm == VIDEO_MODE_SECAM) {
865                                 /* L NICAM or AM-mono */
866                                 msp->second = carrier_detect_65[max2].cdo;
867                                 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
868                                 msp->nicam_on = 0;
869                                 msp3400c_setstereo(client, VIDEO_SOUND_MONO);
870                                 msp3400c_setcarrier(client, msp->second, msp->main);
871                                 /* volume prescale for SCART (AM mono input) */
872                                 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
873                                 msp->watch_stereo = 1;
874                         } else if (max2 == 0 && msp->nicam) {
875                                 /* D/K NICAM */
876                                 msp->second = carrier_detect_65[max2].cdo;
877                                 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
878                                 msp->nicam_on = 1;
879                                 msp3400c_setcarrier(client, msp->second, msp->main);
880                                 msp->watch_stereo = 1;
881                         } else {
882                                 goto no_second;
883                         }
884                         break;
885                 case 0: /* 4.5 */
886                 default:
887                 no_second:
888                         msp->second = carrier_detect_main[max1].cdo;
889                         msp3400c_setmode(client, MSP_MODE_FM_TERRA);
890                         msp->nicam_on = 0;
891                         msp3400c_setcarrier(client, msp->second, msp->main);
892                         msp->stereo = VIDEO_SOUND_MONO;
893                         msp3400c_setstereo(client, VIDEO_SOUND_MONO);
894                         break;
895                 }
896 
897                 /* unmute */
898                 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
899 
900                 if (msp->watch_stereo)
901                         mod_timer(&msp->wake_stereo, jiffies+5*HZ);
902 
903                 if (debug)
904                         msp3400c_print_mode(msp);
905                 
906                 msp->active = 0;
907         }
908 
909 done:
910         dprintk("msp3400: thread: exit\n");
911         msp->active = 0;
912         msp->thread = NULL;
913 
914         if(msp->notify != NULL)
915                 up_and_exit(msp->notify, 0);
916         return 0;
917 }
918 
919 /* ----------------------------------------------------------------------- */
920 /* this one uses the automatic sound standard detection of newer           */
921 /* msp34xx chip versions                                                   */
922 
923 static struct MODES {
924         int retval;
925         int main, second;
926         char *name;
927 } modelist[] = {
928         { 0x0000, 0, 0, "ERROR" },
929         { 0x0001, 0, 0, "autodetect start" },
930         { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72  M Dual FM-Stereo" },
931         { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74  B/G Dual FM-Stereo" },
932         { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25  D/K1 Dual FM-Stereo" },
933         { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74  D/K2 Dual FM-Stereo" },
934         { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  D/K FM-Mono (HDEV3)" },
935         { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85  B/G NICAM FM" },
936         { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  L NICAM AM" },
937         { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55  I NICAM FM" },
938         { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM" },
939         { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM (HDEV2)" },
940         { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Stereo" },
941         { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Mono + SAP" },
942         { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M EIA-J Japan Stereo" },
943         { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7  FM-Stereo Radio" },
944         { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  SAT-Mono" },
945         { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20  SAT-Stereo" },
946         { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2  SAT ADR" },
947         {     -1, 0, 0, NULL }, /* EOF */
948 };
949  
950 static int msp3410d_thread(void *data)
951 {
952         struct i2c_client *client = data;
953         struct msp3400c *msp = client->data;
954         int mode,val,i,std;
955     
956 #ifdef CONFIG_SMP
957         lock_kernel();
958 #endif
959     
960         daemonize();
961         sigfillset(&current->blocked);
962         strcpy(current->comm,"msp3410 [auto]");
963 
964         msp->thread = current;
965 
966 #ifdef CONFIG_SMP
967         unlock_kernel();
968 #endif
969 
970         printk("msp3410: daemon started\n");
971         if(msp->notify != NULL)
972                 up(msp->notify);
973                 
974         for (;;) {
975                 if (msp->rmmod)
976                         goto done;
977                 if (debug > 1)
978                         printk("msp3410: thread: sleep\n");
979                 interruptible_sleep_on(&msp->wq);
980                 if (debug > 1)
981                         printk("msp3410: thread: wakeup\n");
982                 if (msp->rmmod || signal_pending(current))
983                         goto done;
984 
985                 msp->active = 1;
986 
987                 if (msp->watch_stereo) {
988                         watch_stereo(client);
989                         msp->active = 0;
990                         continue;
991                 }
992         
993                 /* some time for the tuner to sync */
994                 current->state   = TASK_INTERRUPTIBLE;
995                 schedule_timeout(HZ/5);
996                 if (signal_pending(current))
997                         goto done;
998 
999         restart:
1000                 msp->restart = 0;
1001                 del_timer(&msp->wake_stereo);
1002                 msp->watch_stereo = 0;
1003 
1004                 /* put into sane state (and mute) */
1005                 msp3400c_reset(client);
1006 
1007                 /* set various prescales */
1008                 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */
1009                 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */
1010                 msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */
1011 
1012                 /* start autodetect */
1013                 switch (msp->norm) {
1014                 case VIDEO_MODE_PAL:
1015                         mode = 0x1003;
1016                         std  = 1;
1017                         break;
1018                 case VIDEO_MODE_NTSC:  /* BTSC */
1019                         mode = 0x2003;
1020                         std  = 0x0020;
1021                         break;
1022                 case VIDEO_MODE_SECAM: 
1023                         mode = 0x0003;
1024                         std  = 1;
1025                         break;
1026                 case VIDEO_MODE_RADIO: 
1027                         mode = 0x0003;
1028                         std  = 0x0040;
1029                         break;
1030                 default:
1031                         mode = 0x0003;
1032                         std  = 1;
1033                         break;
1034                 }
1035                 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
1036                 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
1037 
1038                 if (debug) {
1039                         int i;
1040                         for (i = 0; modelist[i].name != NULL; i++)
1041                                 if (modelist[i].retval == std)
1042                                         break;
1043                         printk("msp3410: setting mode: %s (0x%04x)\n",
1044                                modelist[i].name ? modelist[i].name : "unknown",std);
1045                 }
1046 
1047                 if (std != 1) {
1048                         /* programmed some specific mode */
1049                         val = std;
1050                 } else {
1051                         /* triggered autodetect */
1052                         for (;;) {
1053                                 current->state   = TASK_INTERRUPTIBLE;
1054                                 schedule_timeout(HZ/10);
1055                                 if (signal_pending(current))
1056                                         goto done;
1057                                 if (msp->restart)
1058                                         goto restart;
1059 
1060                                 /* check results */
1061                                 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1062                                 if (val < 0x07ff)
1063                                         break;
1064                                 dprintk("msp3410: detection still in progress\n");
1065                         }
1066                 }
1067                 for (i = 0; modelist[i].name != NULL; i++)
1068                         if (modelist[i].retval == val)
1069                                 break;
1070                 dprintk("msp3410: current mode: %s (0x%04x)\n",
1071                         modelist[i].name ? modelist[i].name : "unknown",
1072                         val);
1073                 msp->main   = modelist[i].main;
1074                 msp->second = modelist[i].second;
1075 
1076                 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
1077                         /* autodetection has failed, let backup */
1078                         dprintk("msp3410: autodetection failed, switching to backup mode: %s (0x%04x)\n",
1079                                 modelist[8].name ? modelist[8].name : "unknown",val);
1080                         val = 0x0009;
1081                         msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val);
1082                 }
1083 
1084                 /* set stereo */
1085                 switch (val) {
1086                 case 0x0008: /* B/G NICAM */
1087                 case 0x000a: /* I NICAM */
1088                         if (val == 0x0008)
1089                                 msp->mode = MSP_MODE_FM_NICAM1;
1090                         else
1091                                 msp->mode = MSP_MODE_FM_NICAM2;
1092                         /* just turn on stereo */
1093                         msp->stereo = VIDEO_SOUND_STEREO;
1094                         msp->nicam_on = 1;
1095                         msp->watch_stereo = 1;
1096                         msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
1097                         break;
1098                 case 0x0009:                    
1099                         msp->mode = MSP_MODE_AM_NICAM;
1100                         msp->stereo = VIDEO_SOUND_MONO;
1101                         msp->nicam_on = 1;
1102                         msp3400c_setstereo(client,VIDEO_SOUND_MONO);
1103                         msp->watch_stereo = 1;
1104                         break;
1105                 case 0x0020: /* BTSC */
1106                         /* just turn on stereo */
1107                         msp->mode   = MSP_MODE_BTSC;
1108                         msp->stereo = VIDEO_SOUND_STEREO;
1109                         msp->nicam_on = 0;
1110                         msp->watch_stereo = 1;
1111                         msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
1112                         break;
1113                 case 0x0040: /* FM radio */
1114                         msp->mode   = MSP_MODE_FM_RADIO;
1115                         msp->stereo = VIDEO_SOUND_STEREO;
1116                         msp->nicam_on = 0;
1117                         msp->watch_stereo = 0;
1118                         /* scart routing */
1119                         msp3400c_set_scart(client,SCART_IN2,0);
1120                         msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
1121                         break;
1122                 case 0x0003:
1123                         msp->mode   = MSP_MODE_FM_TERRA;
1124                         msp->stereo = VIDEO_SOUND_MONO;
1125                         msp->nicam_on = 0;
1126                         msp->watch_stereo = 1;
1127                         break;
1128                 }
1129                 
1130                 /* unmute */
1131                 msp3400c_setbass(client, msp->bass);
1132                 msp3400c_settreble(client, msp->treble);
1133                 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1134 
1135                 if (msp->watch_stereo)
1136                         mod_timer(&msp->wake_stereo, jiffies+HZ);
1137 
1138                 msp->active = 0;
1139         }
1140 
1141 done:
1142         dprintk("msp3410: thread: exit\n");
1143         msp->active = 0;
1144         msp->thread = NULL;
1145 
1146         if(msp->notify != NULL)
1147                 up(msp->notify);
1148         return 0;
1149 }
1150 
1151 /* ----------------------------------------------------------------------- */
1152 
1153 static int msp_attach(struct i2c_adapter *adap, int addr,
1154                       unsigned short flags, int kind);
1155 static int msp_detach(struct i2c_client *client);
1156 static int msp_probe(struct i2c_adapter *adap);
1157 static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
1158 
1159 static struct i2c_driver driver = {
1160         name:           "i2c msp3400 driver",
1161         id:             I2C_DRIVERID_MSP3400,
1162         flags:          I2C_DF_NOTIFY,
1163         attach_adapter: msp_probe,
1164         detach_client:  msp_detach,
1165         command:        msp_command,
1166 };
1167 
1168 static struct i2c_client client_template = 
1169 {
1170         name:   "(unset)",
1171         driver: &driver,
1172 };
1173 
1174 static int msp_attach(struct i2c_adapter *adap, int addr,
1175                       unsigned short flags, int kind)
1176 {
1177         DECLARE_MUTEX_LOCKED(sem);
1178         struct msp3400c *msp;
1179         struct i2c_client *c;
1180         int              rev1,rev2,i;
1181 
1182         client_template.adapter = adap;
1183         client_template.addr = addr;
1184 
1185         if (-1 == msp3400c_reset(&client_template)) {
1186                 dprintk("msp3400: no chip found\n");
1187                 return -1;
1188         }
1189         
1190         if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
1191                 return -ENOMEM;
1192         memcpy(c,&client_template,sizeof(struct i2c_client));
1193         if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
1194                 kfree(c);
1195                 return -ENOMEM;
1196         }
1197         
1198         memset(msp,0,sizeof(struct msp3400c));
1199         msp->left   = 65535;
1200         msp->right  = 65535;
1201         msp->bass   = 32768;
1202         msp->treble = 32768;
1203         c->data = msp;
1204         init_waitqueue_head(&msp->wq);
1205 
1206         if (-1 == msp3400c_reset(c)) {
1207                 kfree(msp);
1208                 dprintk("msp3400: no chip found\n");
1209                 return -1;
1210         }
1211     
1212         rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e);
1213         if (-1 != rev1)
1214                 rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f);
1215         if ((-1 == rev1) || (0 == rev1 && 0 == rev2)) {
1216                 kfree(msp);
1217                 printk("msp3400: error while reading chip version\n");
1218                 return -1;
1219         }
1220 
1221 #if 0
1222         /* this will turn on a 1kHz beep - might be useful for debugging... */
1223         msp3400c_write(client,I2C_MSP3400C_DFP, 0x0014, 0x1040);
1224 #endif
1225 
1226         sprintf(c->name,"MSP34%02d%c-%c%d",
1227                 (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
1228         msp->nicam = (((rev2>>8)&0xff) != 00) ? 1 : 0;
1229 
1230         if (simple == -1) {
1231                 /* default mode */
1232                 /* msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; */
1233                 msp->simple = ((rev1&0xff)+'@' > 'C');
1234         } else {
1235                 /* use insmod option */
1236                 msp->simple = simple;
1237         }
1238 
1239         /* timer for stereo checking */
1240         msp->wake_stereo.function = msp3400c_stereo_wake;
1241         msp->wake_stereo.data     = (unsigned long)msp;
1242 
1243         /* hello world :-) */
1244         printk(KERN_INFO "msp34xx: init: chip=%s",c->name);
1245         if (msp->nicam)
1246                 printk(", has NICAM support");
1247         printk("\n");
1248 
1249         /* startup control thread */
1250         MOD_INC_USE_COUNT;
1251         msp->notify = &sem;
1252         kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread,
1253                       (void *)c, 0);
1254         down(&sem);
1255         msp->notify = NULL;
1256         wake_up_interruptible(&msp->wq);
1257 
1258         /* update our own array */
1259         for (i = 0; i < MSP3400_MAX; i++) {
1260                 if (NULL == msps[i]) {
1261                         msps[i] = c;
1262                         break;
1263                 }
1264         }
1265         
1266         /* done */
1267         i2c_attach_client(c);
1268         return 0;
1269 }
1270 
1271 static int msp_detach(struct i2c_client *client)
1272 {
1273         DECLARE_MUTEX_LOCKED(sem);
1274         struct msp3400c *msp  = (struct msp3400c*)client->data;
1275         int i;
1276         
1277         /* shutdown control thread */
1278         del_timer(&msp->wake_stereo);
1279         if (msp->thread) 
1280         {
1281                 msp->notify = &sem;
1282                 msp->rmmod = 1;
1283                 wake_up_interruptible(&msp->wq);
1284                 down(&sem);
1285                 msp->notify = NULL;
1286         }
1287         msp3400c_reset(client);
1288 
1289         /* update our own array */
1290         for (i = 0; i < MSP3400_MAX; i++) {
1291                 if (client == msps[i]) {
1292                         msps[i] = NULL;
1293                         break;
1294                 }
1295         }
1296 
1297         i2c_detach_client(client);
1298         kfree(msp);
1299         kfree(client);
1300         MOD_DEC_USE_COUNT;
1301         return 0;
1302 }
1303 
1304 static int msp_probe(struct i2c_adapter *adap)
1305 {
1306         if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
1307                 return i2c_probe(adap, &addr_data, msp_attach);
1308         return 0;
1309 }
1310 
1311 static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
1312 {
1313         struct msp3400c *msp  = (struct msp3400c*)client->data;
1314         __u16           *sarg = arg;
1315 #if 0
1316         int             *iarg = (int*)arg;
1317 #endif
1318 
1319         switch (cmd) {
1320 
1321         case AUDC_SET_INPUT:
1322 #if 1
1323                 /* hauppauge 44xxx scart switching */
1324                 switch (*sarg) {
1325                 case AUDIO_RADIO:
1326                         msp3400c_set_scart(client,SCART_IN2,0);
1327                         break;
1328                 case AUDIO_EXTERN:
1329                         msp3400c_set_scart(client,SCART_IN1,0);
1330                         break;
1331                 default:
1332                         if (*sarg & AUDIO_MUTE)
1333                                 msp3400c_set_scart(client,SCART_MUTE,0);
1334                         break;
1335                 }
1336 #endif
1337                 break;
1338 
1339         case AUDC_SET_RADIO:
1340                 msp->norm = VIDEO_MODE_RADIO;
1341                 msp->watch_stereo=0;
1342                 del_timer(&msp->wake_stereo);
1343                 dprintk("msp34xx: switching to radio mode\n");
1344                 if (msp->simple) {
1345                         /* the thread will do for us */
1346                         msp3400c_setvolume(client,msp->muted,0,0);
1347                         if (msp->active)
1348                                 msp->restart = 1;
1349                         wake_up_interruptible(&msp->wq);
1350                 } else {
1351                         /* set msp3400 to FM radio mode */
1352                         msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1353                         msp3400c_setcarrier(client, MSP_CARRIER(10.7),MSP_CARRIER(10.7));
1354                         msp3400c_setvolume(client,msp->muted,msp->left,msp->right);                     
1355                 }
1356                 break;
1357 
1358         /* --- v4l ioctls --- */
1359         /* take care: bttv does userspace copying, we'll get a
1360            kernel pointer here... */
1361         case VIDIOCGAUDIO:
1362         {
1363                 struct video_audio *va = arg;
1364 
1365                 va->flags |= VIDEO_AUDIO_VOLUME |
1366                         VIDEO_AUDIO_BASS |
1367                         VIDEO_AUDIO_TREBLE |
1368                         VIDEO_AUDIO_MUTABLE;
1369                 if (msp->muted)
1370                         va->flags |= VIDEO_AUDIO_MUTE;
1371                 va->volume=MAX(msp->left,msp->right);
1372                 va->balance=(32768*MIN(msp->left,msp->right))/
1373                         (va->volume ? va->volume : 1);
1374                 va->balance=(msp->left<msp->right)?
1375                         (65535-va->balance) : va->balance;
1376                 va->bass = msp->bass;
1377                 va->treble = msp->treble;
1378 
1379                 if (msp->norm != VIDEO_MODE_RADIO) {
1380                         autodetect_stereo(client);
1381                         va->mode = msp->stereo;
1382                 }
1383                 break;
1384         }
1385         case VIDIOCSAUDIO:
1386         {
1387                 struct video_audio *va = arg;
1388 
1389                 msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
1390                 msp->left = (MIN(65536 - va->balance,32768) *
1391                              va->volume) / 32768;
1392                 msp->right = (MIN(va->balance,32768) *
1393                               va->volume) / 32768;
1394                 msp->bass = va->bass;
1395                 msp->treble = va->treble;
1396                 msp3400c_setvolume(client,msp->muted,msp->left,msp->right);
1397                 msp3400c_setbass(client,msp->bass);
1398                 msp3400c_settreble(client,msp->treble);
1399 
1400                 if (va->mode != 0) {
1401                         msp->watch_stereo=0;
1402                         del_timer(&msp->wake_stereo);
1403                         msp->stereo = va->mode;
1404                         msp3400c_setstereo(client,va->mode);
1405                 }
1406                 break;
1407         }
1408         case VIDIOCSCHAN:
1409         {
1410                 struct video_channel *vc = arg;
1411                 
1412                 dprintk("msp34xx: switching to TV mode\n");
1413                 msp->norm = vc->norm;
1414                 break;
1415         }
1416         case VIDIOCSFREQ:
1417         {
1418                 /* new channel -- kick audio carrier scan */
1419                 msp3400c_setvolume(client,msp->muted,0,0);
1420                 msp->watch_stereo=0;
1421                 del_timer(&msp->wake_stereo);
1422                 if (msp->active)
1423                         msp->restart = 1;
1424                 wake_up_interruptible(&msp->wq);
1425                 break;
1426         }
1427 
1428         /* --- v4l2 ioctls --- */
1429         /* NOT YET */
1430 
1431 #if 0
1432         /* --- old, obsolete interface --- */
1433         case AUDC_SET_TVNORM:
1434                 msp->norm = *iarg;
1435                 break;
1436         case AUDC_SWITCH_MUTE:
1437                 /* channels switching step one -- mute */
1438                 msp->watch_stereo=0;
1439                 del_timer(&msp->wake_stereo);
1440                 msp3400c_setvolume(client,0,0);
1441                 break;
1442         case AUDC_NEWCHANNEL:
1443                 /* channels switching step two -- trigger sound carrier scan */
1444                 msp->watch_stereo=0;
1445                 del_timer(&msp->wake_stereo);
1446                 if (msp->active)
1447                         msp->restart = 1;
1448                 wake_up_interruptible(&msp->wq);
1449                 break;
1450 
1451         case AUDC_GET_VOLUME_LEFT:
1452                 *sarg = msp->left;
1453                 break;
1454         case AUDC_GET_VOLUME_RIGHT:
1455                 *sarg = msp->right;
1456                 break;
1457         case AUDC_SET_VOLUME_LEFT:
1458                 msp->left = *sarg;
1459                 msp3400c_setvolume(client,msp->left, msp->right);
1460                 break;
1461         case AUDC_SET_VOLUME_RIGHT:
1462                 msp->right = *sarg;
1463                 msp3400c_setvolume(client,msp->left, msp->right);
1464                 break;
1465 
1466         case AUDC_GET_BASS:
1467                 *sarg = msp->bass;
1468                 break;
1469         case AUDC_SET_BASS:
1470                 msp->bass = *sarg;
1471                 msp3400c_setbass(client,msp->bass);
1472                 break;
1473 
1474         case AUDC_GET_TREBLE:
1475                 *sarg = msp->treble;
1476                 break;
1477         case AUDC_SET_TREBLE:
1478                 msp->treble = *sarg;
1479                 msp3400c_settreble(client,msp->treble);
1480                 break;
1481 
1482         case AUDC_GET_STEREO:   
1483                 autodetect_stereo(client);
1484                 *sarg = msp->stereo;            
1485                 break;
1486         case AUDC_SET_STEREO:
1487                 if (*sarg) {
1488                         msp->watch_stereo=0;
1489                         del_timer(&msp->wake_stereo);
1490                         msp->stereo = *sarg;
1491                         msp3400c_setstereo(client,*sarg);
1492                 }
1493                 break;
1494 
1495         case AUDC_GET_DC:
1496                 if (msp->simple)
1497                         break; /* fixme */
1498                 *sarg = ((int)msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b) +
1499                          (int)msp3400c_read(client, I2C_MSP3400C_DFP, 0x1c));
1500                 break;
1501 #endif
1502         default:
1503                 /* nothing */
1504         }
1505         return 0;
1506 }
1507 
1508 /* ----------------------------------------------------------------------- */
1509 
1510 int msp3400_init_module(void)
1511 {
1512         i2c_add_driver(&driver);
1513         return 0;
1514 }
1515 
1516 void msp3400_cleanup_module(void)
1517 {
1518         i2c_del_driver(&driver);
1519 }
1520 
1521 module_init(msp3400_init_module);
1522 module_exit(msp3400_cleanup_module);
1523 
1524 /*
1525  * Overrides for Emacs so that we follow Linus's tabbing style.
1526  * ---------------------------------------------------------------------------
1527  * Local variables:
1528  * c-basic-offset: 8
1529  * End:
1530  */
1531 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.