2 * programming the msp34* sound processor family
4 * (c) 1997-2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
6 * what works and what doesn't:
9 * Support for Hauppauge cards added (decoding handled by tuner) added by
10 * Frederic Crozat <fcrozat@mail.dotcom.fr>
13 * should work. The stereo modes are backward compatible to FM-mono,
14 * therefore FM-Mono should be allways available.
16 * FM-Stereo (B/G, used in germany)
17 * should work, with autodetect
19 * FM-Stereo (satellite)
20 * should work, no autodetect (i.e. default is mono, but you can
21 * switch to stereo -- untested)
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>
29 * - better SAT support
32 * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch)
33 * using soundcore instead of OSS
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>
52 #include <asm/pgtable.h>
53 #include <linux/smp_lock.h>
56 #define __KERNEL_SYSCALLS__
57 #include <linux/unistd.h>
59 #include "audiochip.h"
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
,
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) */
91 int main
, second
; /* sound carrier */
93 int left
, right
; /* volume */
97 struct task_struct
*thread
;
100 struct semaphore
*notify
;
101 int active
,restart
,rmmod
;
104 struct timer_list wake_stereo
;
107 #define MSP3400_MAX 4
108 static struct i2c_client
*msps
[MSP3400_MAX
];
110 #define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
112 /* ---------------------------------------------------------------------- */
114 #define dprintk if (debug) printk
116 MODULE_PARM(once
,"i");
117 MODULE_PARM(debug
,"i");
118 MODULE_PARM(simple
,"i");
119 MODULE_PARM(amsound
,"i");
120 MODULE_PARM(dolby
,"i");
122 /* ---------------------------------------------------------------------- */
124 #define I2C_MSP3400C 0x80
125 #define I2C_MSP3400C_DEM 0x10
126 #define I2C_MSP3400C_DFP 0x12
128 /* ----------------------------------------------------------------------- */
129 /* functions for talking to the MSP3400C Sound processor */
131 static int msp3400c_reset(struct i2c_client
*client
)
133 static char reset_off
[3] = { 0x00, 0x80, 0x00 };
134 static char reset_on
[3] = { 0x00, 0x00, 0x00 };
136 i2c_master_send(client
,reset_off
,3); /* XXX ignore errors here */
137 if (3 != i2c_master_send(client
,reset_on
, 3)) {
138 printk(KERN_ERR
"msp3400: chip reset failed, penguin on i2c bus?\n");
145 msp3400c_read(struct i2c_client
*client
, int dev
, int addr
)
149 unsigned char write
[3];
150 unsigned char read
[2];
151 struct i2c_msg msgs
[2] = {
152 { client
->addr
, 0, 3, write
},
153 { client
->addr
, I2C_M_RD
, 2, read
}
156 write
[1] = addr
>> 8;
157 write
[2] = addr
& 0xff;
159 for (err
= 0; err
< 3;) {
160 if (2 == i2c_transfer(client
->adapter
,msgs
,2))
163 printk(KERN_WARNING
"msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n",
165 current
->state
= TASK_INTERRUPTIBLE
;
166 schedule_timeout(HZ
/10);
169 printk(KERN_WARNING
"msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
170 msp3400c_reset(client
);
173 return read
[0] << 8 | read
[1];
177 msp3400c_write(struct i2c_client
*client
, int dev
, int addr
, int val
)
180 unsigned char buffer
[5];
183 buffer
[1] = addr
>> 8;
184 buffer
[2] = addr
& 0xff;
185 buffer
[3] = val
>> 8;
186 buffer
[4] = val
& 0xff;
188 for (err
= 0; err
< 3;) {
189 if (5 == i2c_master_send(client
, buffer
, 5))
192 printk(KERN_WARNING
"msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n",
194 current
->state
= TASK_INTERRUPTIBLE
;
195 schedule_timeout(HZ
/10);
198 printk(KERN_WARNING
"msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
199 msp3400c_reset(client
);
205 /* ------------------------------------------------------------------------ */
207 /* This macro is allowed for *constants* only, gcc must calculate it
208 at compile time. Remember -- no floats in kernel mode */
209 #define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
211 #define MSP_MODE_AM_DETECT 0
212 #define MSP_MODE_FM_RADIO 2
213 #define MSP_MODE_FM_TERRA 3
214 #define MSP_MODE_FM_SAT 4
215 #define MSP_MODE_FM_NICAM1 5
216 #define MSP_MODE_FM_NICAM2 6
217 #define MSP_MODE_AM_NICAM 7
218 #define MSP_MODE_BTSC 8
220 static struct MSP_INIT_DATA_DEM
{
229 } msp_init_data
[] = {
230 /* AM (for carrier detect / msp3400) */
231 { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
232 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
233 0x00d0, 0x0500, 0x0020, 0x3000},
235 /* AM (for carrier detect / msp3410) */
236 { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
237 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
238 0x00d0, 0x0100, 0x0020, 0x3000},
241 { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
242 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
243 0x00d0, 0x0480, 0x0020, 0x3000 },
245 /* Terrestial FM-mono + FM-stereo */
246 { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 },
247 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
248 0x00d0, 0x0480, 0x0030, 0x3000},
251 { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 },
252 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
253 0x00c6, 0x0480, 0x0000, 0x3000},
255 /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
256 { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 },
257 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
258 0x00d0, 0x0040, 0x0120, 0x3000},
260 /* NICAM/FM -- I (6.0/6.552) */
261 { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 },
262 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
263 0x00d0, 0x0040, 0x0120, 0x3000},
265 /* NICAM/AM -- L (6.5/5.85) */
266 { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 },
267 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
268 0x00c6, 0x0140, 0x0120, 0x7c03},
271 struct CARRIER_DETECT
{
276 static struct CARRIER_DETECT carrier_detect_main
[] = {
278 { MSP_CARRIER(4.5), "4.5 NTSC" },
279 { MSP_CARRIER(5.5), "5.5 PAL B/G" },
280 { MSP_CARRIER(6.0), "6.0 PAL I" },
281 { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }
284 static struct CARRIER_DETECT carrier_detect_55
[] = {
286 { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },
287 { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }
290 static struct CARRIER_DETECT carrier_detect_65
[] = {
291 /* PAL SAT / SECAM */
292 { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" },
293 { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },
294 { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },
295 { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },
296 { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },
297 { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },
300 #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
302 /* ------------------------------------------------------------------------ */
304 static void msp3400c_setcarrier(struct i2c_client
*client
, int cdo1
, int cdo2
)
306 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0093, cdo1
& 0xfff);
307 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x009b, cdo1
>> 12);
308 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x00a3, cdo2
& 0xfff);
309 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x00ab, cdo2
>> 12);
310 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0056, 0); /*LOAD_REG_1/2*/
313 static void msp3400c_setvolume(struct i2c_client
*client
, int left
, int right
)
317 vol
= (left
> right
) ? left
: right
;
318 val
= (vol
* 0x73 / 65535) << 8;
321 balance
= ((right
-left
) * 127) / vol
;
323 dprintk("msp34xx: setvolume: %d:%d 0x%02x 0x%02x\n",
324 left
,right
,val
>>8,balance
);
325 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0000, val
); /* loudspeaker */
326 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0006, val
); /* headphones */
327 /* scart - on/off only */
328 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0007, val
? 0x4000 : 0);
329 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0001, balance
<< 8);
332 static void msp3400c_setbass(struct i2c_client
*client
, int bass
)
334 int val
= ((bass
-32768) * 0x60 / 65535) << 8;
336 dprintk("msp34xx: setbass: %d 0x%02x\n",bass
, val
>>8);
337 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0002, val
); /* loudspeaker */
340 static void msp3400c_settreble(struct i2c_client
*client
, int treble
)
342 int val
= ((treble
-32768) * 0x60 / 65535) << 8;
344 dprintk("msp34xx: settreble: %d 0x%02x\n",treble
, val
>>8);
345 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0003, val
); /* loudspeaker */
348 static void msp3400c_setmode(struct i2c_client
*client
, int type
)
350 struct msp3400c
*msp
= client
->data
;
353 dprintk("msp3400: setmode: %d\n",type
);
355 msp
->stereo
= VIDEO_SOUND_MONO
;
357 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x00bb, /* ad_cv */
358 msp_init_data
[type
].ad_cv
);
360 for (i
= 5; i
>= 0; i
--) /* fir 1 */
361 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0001,
362 msp_init_data
[type
].fir1
[i
]);
364 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0005, 0x0004); /* fir 2 */
365 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0005, 0x0040);
366 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0005, 0x0000);
367 for (i
= 5; i
>= 0; i
--)
368 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0005,
369 msp_init_data
[type
].fir2
[i
]);
371 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0083, /* MODE_REG */
372 msp_init_data
[type
].mode_reg
);
374 msp3400c_setcarrier(client
, msp_init_data
[type
].cdo1
,
375 msp_init_data
[type
].cdo2
);
377 msp3400c_write(client
,I2C_MSP3400C_DEM
, 0x0056, 0); /*LOAD_REG_1/2*/
380 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0008,
382 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0009,
384 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000b,
385 msp_init_data
[type
].dfp_src
);
387 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0008,
388 msp_init_data
[type
].dfp_src
);
389 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0009,
390 msp_init_data
[type
].dfp_src
);
392 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000a,
393 msp_init_data
[type
].dfp_src
);
394 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000e,
395 msp_init_data
[type
].dfp_matrix
);
399 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0010, 0x5a00); /* was: 0x3000 */
403 /* turn on/off nicam + stereo */
404 static void msp3400c_setstereo(struct i2c_client
*client
, int mode
)
406 struct msp3400c
*msp
= client
->data
;
407 int nicam
=0; /* channel source: FM/AM or nicam */
410 /* switch demodulator */
412 case MSP_MODE_FM_TERRA
:
413 dprintk("msp3400: FM setstereo: %d\n",mode
);
414 msp3400c_setcarrier(client
,msp
->second
,msp
->main
);
416 case VIDEO_SOUND_STEREO
:
417 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000e, 0x3001);
419 case VIDEO_SOUND_MONO
:
420 case VIDEO_SOUND_LANG1
:
421 case VIDEO_SOUND_LANG2
:
422 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000e, 0x3000);
426 case MSP_MODE_FM_SAT
:
427 dprintk("msp3400: SAT setstereo: %d\n",mode
);
429 case VIDEO_SOUND_MONO
:
430 msp3400c_setcarrier(client
, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
432 case VIDEO_SOUND_STEREO
:
433 msp3400c_setcarrier(client
, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
435 case VIDEO_SOUND_LANG1
:
436 msp3400c_setcarrier(client
, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
438 case VIDEO_SOUND_LANG2
:
439 msp3400c_setcarrier(client
, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
443 case MSP_MODE_FM_NICAM1
:
444 case MSP_MODE_FM_NICAM2
:
445 case MSP_MODE_AM_NICAM
:
446 dprintk("msp3400: NICAM setstereo: %d\n",mode
);
447 msp3400c_setcarrier(client
,msp
->second
,msp
->main
);
452 dprintk("msp3400: BTSC setstereo: %d\n",mode
);
456 dprintk("msp3400: mono setstereo\n");
462 case VIDEO_SOUND_STEREO
:
463 src
= 0x0020 | nicam
;
466 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0005,0x4000);
469 case VIDEO_SOUND_MONO
:
470 if (msp
->mode
== MSP_MODE_AM_NICAM
) {
471 dprintk("msp3400: switching to AM mono\n");
472 /* AM mono decoding is handled by tuner, not MSP chip */
473 /* so let's redirect sound from tuner via SCART */
474 /* volume prescale for SCART */
475 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000d, 0x1900);
476 /* SCART switching control register*/
477 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0013, 0xe900);
481 case VIDEO_SOUND_LANG1
:
482 src
= 0x0000 | nicam
;
484 case VIDEO_SOUND_LANG2
:
485 src
= 0x0010 | nicam
;
489 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0008,0x0520);
490 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0009,0x0620);
491 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000a,src
);
492 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000b,src
);
494 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0008,src
);
495 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0009,src
);
496 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x000a,src
);
501 msp3400c_print_mode(struct msp3400c
*msp
)
503 if (msp
->main
== msp
->second
) {
504 printk("msp3400: mono sound carrier: %d.%03d MHz\n",
505 msp
->main
/910000,(msp
->main
/910)%1000);
507 printk("msp3400: main sound carrier: %d.%03d MHz\n",
508 msp
->main
/910000,(msp
->main
/910)%1000);
510 if (msp
->mode
== MSP_MODE_FM_NICAM1
||
511 msp
->mode
== MSP_MODE_FM_NICAM2
)
512 printk("msp3400: NICAM/FM carrier : %d.%03d MHz\n",
513 msp
->second
/910000,(msp
->second
/910)%1000);
514 if (msp
->mode
== MSP_MODE_AM_NICAM
)
515 printk("msp3400: NICAM/AM carrier : %d.%03d MHz\n",
516 msp
->second
/910000,(msp
->second
/910)%1000);
517 if (msp
->mode
== MSP_MODE_FM_TERRA
&&
518 msp
->main
!= msp
->second
) {
519 printk("msp3400: FM-stereo carrier : %d.%03d MHz\n",
520 msp
->second
/910000,(msp
->second
/910)%1000);
524 /* ----------------------------------------------------------------------- */
526 struct REGISTER_DUMP
{
531 struct REGISTER_DUMP d1
[] = {
532 { 0x007e, "autodetect" },
533 { 0x0023, "C_AD_BITS " },
534 { 0x0038, "ADD_BITS " },
535 { 0x003e, "CIB_BITS " },
536 { 0x0057, "ERROR_RATE" },
540 autodetect_stereo(struct i2c_client
*client
)
542 struct msp3400c
*msp
= client
->data
;
544 int newstereo
= msp
->stereo
;
545 int newnicam
= msp
->nicam_on
;
549 case MSP_MODE_FM_TERRA
:
550 val
= msp3400c_read(client
, I2C_MSP3400C_DFP
, 0x18);
553 dprintk("msp34xx: stereo detect register: %d\n",val
);
556 newstereo
= VIDEO_SOUND_STEREO
| VIDEO_SOUND_MONO
;
557 } else if (val
< -4096) {
558 newstereo
= VIDEO_SOUND_LANG1
| VIDEO_SOUND_LANG2
;
560 newstereo
= VIDEO_SOUND_MONO
;
564 case MSP_MODE_FM_NICAM1
:
565 case MSP_MODE_FM_NICAM2
:
566 case MSP_MODE_AM_NICAM
:
567 val
= msp3400c_read(client
, I2C_MSP3400C_DEM
, 0x23);
568 dprintk("msp34xx: nicam sync=%d, mode=%d\n",val
& 1, (val
& 0x1e) >> 1);
572 switch ((val
& 0x1e) >> 1) {
575 newstereo
= VIDEO_SOUND_STEREO
;
579 newstereo
= VIDEO_SOUND_MONO
584 newstereo
= VIDEO_SOUND_MONO
589 newstereo
= VIDEO_SOUND_MONO
;
595 newstereo
= VIDEO_SOUND_MONO
;
599 val
= msp3400c_read(client
, I2C_MSP3400C_DEM
, 0x200);
600 dprintk("msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
602 (val
& 0x0002) ? "no" : "yes",
603 (val
& 0x0004) ? "no" : "yes",
604 (val
& 0x0040) ? "stereo" : "mono",
605 (val
& 0x0080) ? ", nicam 2nd mono" : "",
606 (val
& 0x0100) ? ", bilingual/SAP" : "");
607 newstereo
= VIDEO_SOUND_MONO
;
608 if (val
& 0x0040) newstereo
|= VIDEO_SOUND_STEREO
;
609 if (val
& 0x0100) newstereo
|= VIDEO_SOUND_LANG1
;
612 if (newstereo
!= msp
->stereo
) {
614 dprintk("msp34xx: watch: stereo %d => %d\n",
615 msp
->stereo
,newstereo
);
616 msp
->stereo
= newstereo
;
618 if (newnicam
!= msp
->nicam_on
) {
620 dprintk("msp34xx: watch: nicam %d => %d\n",
621 msp
->nicam_on
,newnicam
);
622 msp
->nicam_on
= newnicam
;
628 * A kernel thread for msp3400 control -- we don't want to block the
629 * in the ioctl while doing the sound carrier & stereo detect
632 static void msp3400c_stereo_wake(unsigned long data
)
634 struct msp3400c
*msp
= (struct msp3400c
*)data
; /* XXX alpha ??? */
636 wake_up_interruptible(&msp
->wq
);
639 /* stereo/multilang monitoring */
640 static void watch_stereo(struct i2c_client
*client
)
642 struct msp3400c
*msp
= client
->data
;
644 if (autodetect_stereo(client
)) {
645 if (msp
->stereo
& VIDEO_SOUND_STEREO
)
646 msp3400c_setstereo(client
,VIDEO_SOUND_STEREO
);
647 else if (msp
->stereo
& VIDEO_SOUND_LANG1
)
648 msp3400c_setstereo(client
,VIDEO_SOUND_LANG1
);
650 msp3400c_setstereo(client
,VIDEO_SOUND_MONO
);
653 msp
->watch_stereo
= 0;
654 if (msp
->watch_stereo
)
655 mod_timer(&msp
->wake_stereo
, jiffies
+5*HZ
);
658 static int msp3400c_thread(void *data
)
660 struct i2c_client
*client
= data
;
661 struct msp3400c
*msp
= client
->data
;
663 struct CARRIER_DETECT
*cd
;
664 int count
, max1
,max2
,val1
,val2
, val
,this;
671 sigfillset(¤t
->blocked
);
672 strcpy(current
->comm
,"msp3400");
674 msp
->thread
= current
;
680 printk("msp3400: daemon started\n");
681 if(msp
->notify
!= NULL
)
688 printk("msp3400: thread: sleep\n");
689 interruptible_sleep_on(&msp
->wq
);
691 printk("msp3400: thread: wakeup\n");
692 if (msp
->rmmod
|| signal_pending(current
))
695 if (VIDEO_MODE_RADIO
== msp
->norm
)
696 continue; /* nothing to do */
700 if (msp
->watch_stereo
) {
701 watch_stereo(client
);
706 /* some time for the tuner to sync */
707 current
->state
= TASK_INTERRUPTIBLE
;
708 schedule_timeout(HZ
/5);
709 if (signal_pending(current
))
714 msp3400c_setvolume(client
, 0, 0);
715 msp3400c_setmode(client
, MSP_MODE_AM_DETECT
/* +1 */ );
718 del_timer(&msp
->wake_stereo
);
719 msp
->watch_stereo
= 0;
721 /* carrier detect pass #1 -- main carrier */
722 cd
= carrier_detect_main
; count
= CARRIER_COUNT(carrier_detect_main
);
724 if (amsound
&& (msp
->norm
== VIDEO_MODE_SECAM
)) {
725 /* autodetect doesn't work well with AM ... */
728 dprintk("msp3400: AM sound override\n");
731 for (this = 0; this < count
; this++) {
732 msp3400c_setcarrier(client
, cd
[this].cdo
,cd
[this].cdo
);
734 current
->state
= TASK_INTERRUPTIBLE
;
735 schedule_timeout(HZ
/10);
736 if (signal_pending(current
))
741 val
= msp3400c_read(client
, I2C_MSP3400C_DFP
, 0x1b);
745 val1
= val
, max1
= this;
746 dprintk("msp3400: carrier1 val: %5d / %s\n", val
,cd
[this].name
);
749 /* carrier detect pass #2 -- second (stereo) carrier */
752 cd
= carrier_detect_55
; count
= CARRIER_COUNT(carrier_detect_55
);
755 cd
= carrier_detect_65
; count
= CARRIER_COUNT(carrier_detect_65
);
760 cd
= NULL
; count
= 0;
764 if (amsound
&& (msp
->norm
== VIDEO_MODE_SECAM
)) {
765 /* autodetect doesn't work well with AM ... */
766 cd
= NULL
; count
= 0; max2
= 0;
768 for (this = 0; this < count
; this++) {
769 msp3400c_setcarrier(client
, cd
[this].cdo
,cd
[this].cdo
);
771 current
->state
= TASK_INTERRUPTIBLE
;
772 schedule_timeout(HZ
/10);
773 if (signal_pending(current
))
778 val
= msp3400c_read(client
, I2C_MSP3400C_DFP
, 0x1b);
782 val2
= val
, max2
= this;
783 dprintk("msp3400: carrier2 val: %5d / %s\n", val
,cd
[this].name
);
786 /* programm the msp3400 according to the results */
787 msp
->main
= carrier_detect_main
[max1
].cdo
;
792 msp
->second
= carrier_detect_55
[max2
].cdo
;
793 msp3400c_setmode(client
, MSP_MODE_FM_TERRA
);
795 msp3400c_setstereo(client
, VIDEO_SOUND_MONO
);
796 msp
->watch_stereo
= 1;
797 } else if (max2
== 1 && msp
->nicam
) {
799 msp
->second
= carrier_detect_55
[max2
].cdo
;
800 msp3400c_setmode(client
, MSP_MODE_FM_NICAM1
);
802 msp3400c_setcarrier(client
, msp
->second
, msp
->main
);
803 msp
->watch_stereo
= 1;
810 msp
->second
= MSP_CARRIER(6.552);
811 msp3400c_setmode(client
, MSP_MODE_FM_NICAM2
);
813 msp3400c_setcarrier(client
, msp
->second
, msp
->main
);
814 msp
->watch_stereo
= 1;
817 if (max2
== 1 || max2
== 2) {
819 msp
->second
= carrier_detect_65
[max2
].cdo
;
820 msp3400c_setmode(client
, MSP_MODE_FM_TERRA
);
822 msp3400c_setstereo(client
, VIDEO_SOUND_MONO
);
823 msp
->watch_stereo
= 1;
824 } else if (max2
== 0 &&
825 msp
->norm
== VIDEO_MODE_SECAM
) {
826 /* L NICAM or AM-mono */
827 msp
->second
= carrier_detect_65
[max2
].cdo
;
828 msp3400c_setmode(client
, MSP_MODE_AM_NICAM
);
830 msp3400c_setstereo(client
, VIDEO_SOUND_MONO
);
831 msp3400c_setcarrier(client
, msp
->second
, msp
->main
);
832 msp
->watch_stereo
= 1;
833 } else if (max2
== 0 && msp
->nicam
) {
835 msp
->second
= carrier_detect_65
[max2
].cdo
;
836 msp3400c_setmode(client
, MSP_MODE_FM_NICAM1
);
838 msp3400c_setcarrier(client
, msp
->second
, msp
->main
);
839 msp
->watch_stereo
= 1;
847 msp
->second
= carrier_detect_main
[max1
].cdo
;
848 msp3400c_setmode(client
, MSP_MODE_FM_TERRA
);
850 msp3400c_setcarrier(client
, msp
->second
, msp
->main
);
851 msp
->stereo
= VIDEO_SOUND_MONO
;
852 msp3400c_setstereo(client
, VIDEO_SOUND_MONO
);
857 msp3400c_setvolume(client
, msp
->left
, msp
->right
);
859 if (msp
->watch_stereo
)
860 mod_timer(&msp
->wake_stereo
, jiffies
+5*HZ
);
863 msp3400c_print_mode(msp
);
869 dprintk("msp3400: thread: exit\n");
873 if(msp
->notify
!= NULL
)
878 /* ----------------------------------------------------------------------- */
879 /* this one uses the automatic sound standard detection of newer */
880 /* msp34xx chip versions */
882 static struct MODES
{
887 { 0x0000, 0, 0, "ERROR" },
888 { 0x0001, 0, 0, "autodetect start" },
889 { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" },
890 { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" },
891 { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
892 { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
893 { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
894 { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
895 { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
896 { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
897 { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
898 { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
899 { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
900 { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
901 { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
902 { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" },
903 { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" },
904 { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" },
905 { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" },
906 { -1, 0, 0, NULL
}, /* EOF */
909 static int msp3410d_thread(void *data
)
911 struct i2c_client
*client
= data
;
912 struct msp3400c
*msp
= client
->data
;
920 sigfillset(¤t
->blocked
);
921 strcpy(current
->comm
,"msp3410 [auto]");
923 msp
->thread
= current
;
929 printk("msp3410: daemon started\n");
930 if(msp
->notify
!= NULL
)
937 printk("msp3410: thread: sleep\n");
938 interruptible_sleep_on(&msp
->wq
);
940 printk("msp3410: thread: wakeup\n");
941 if (msp
->rmmod
|| signal_pending(current
))
944 if (VIDEO_MODE_RADIO
== msp
->norm
)
945 continue; /* nothing to do */
949 if (msp
->watch_stereo
) {
950 watch_stereo(client
);
955 /* some time for the tuner to sync */
956 current
->state
= TASK_INTERRUPTIBLE
;
957 schedule_timeout(HZ
/5);
958 if (signal_pending(current
))
963 del_timer(&msp
->wake_stereo
);
964 msp
->watch_stereo
= 0;
966 /* put into sane state (and mute) */
967 msp3400c_reset(client
);
969 /* start autodetect */
975 case VIDEO_MODE_NTSC
: /* BTSC */
979 case VIDEO_MODE_SECAM
:
988 msp3400c_write(client
, I2C_MSP3400C_DEM
, 0x30, mode
);
989 msp3400c_write(client
, I2C_MSP3400C_DEM
, 0x20, std
);
990 msp3400c_write(client
, I2C_MSP3400C_DFP
, 0x0e, 0x2403);
991 msp3400c_write(client
, I2C_MSP3400C_DFP
, 0x10, 0x5a00);
994 for (i
= 0; modelist
[i
].name
!= NULL
; i
++)
995 if (modelist
[i
].retval
== std
)
997 printk("msp3410: setting mode: %s (0x%04x)\n",
998 modelist
[i
].name
? modelist
[i
].name
: "unknown",std
);
1002 /* programmed some specific mode */
1005 /* triggered autodetect */
1007 current
->state
= TASK_INTERRUPTIBLE
;
1008 schedule_timeout(HZ
/10);
1009 if (signal_pending(current
))
1015 val
= msp3400c_read(client
, I2C_MSP3400C_DEM
, 0x7e);
1018 dprintk("msp3410: detection still in progress\n");
1021 for (i
= 0; modelist
[i
].name
!= NULL
; i
++)
1022 if (modelist
[i
].retval
== val
)
1024 dprintk("msp3410: current mode: %s (0x%04x)\n",
1025 modelist
[i
].name
? modelist
[i
].name
: "unknown",
1027 msp
->main
= modelist
[i
].main
;
1028 msp
->second
= modelist
[i
].second
;
1030 if (amsound
&& (msp
->norm
== VIDEO_MODE_SECAM
) && (val
!= 0x0009)) {
1031 /* autodetection has failed, let backup */
1032 dprintk("msp3410: autodetection failed, switching to backup mode: %s (0x%04x)\n",
1033 modelist
[8].name
? modelist
[8].name
: "unknown",val
);
1035 msp3400c_write(client
, I2C_MSP3400C_DEM
, 0x20, val
);
1038 /* set prescale / stereo */
1041 msp
->mode
= MSP_MODE_AM_NICAM
;
1042 msp
->stereo
= VIDEO_SOUND_MONO
;
1043 msp3400c_setstereo(client
,VIDEO_SOUND_MONO
);
1044 msp
->watch_stereo
= 1;
1046 case 0x0020: /* BTSC */
1047 /* just turn on stereo */
1048 msp
->mode
= MSP_MODE_BTSC
;
1049 msp
->stereo
= VIDEO_SOUND_STEREO
;
1050 msp
->watch_stereo
= 1;
1051 msp3400c_setstereo(client
,VIDEO_SOUND_STEREO
);
1053 msp3400c_write(client
, I2C_MSP3400C_DFP
, 0x0e, 0x2403); /* FM */
1056 msp
->mode
= MSP_MODE_FM_TERRA
;
1057 msp
->stereo
= VIDEO_SOUND_MONO
;
1058 msp
->watch_stereo
= 1;
1061 msp3400c_write(client
, I2C_MSP3400C_DFP
, 0x0e, 0x2403); /* FM */
1062 msp3400c_write(client
, I2C_MSP3400C_DFP
, 0x10, 0x5a00); /* NICAM */
1067 msp3400c_setbass(client
, msp
->bass
);
1068 msp3400c_settreble(client
, msp
->treble
);
1069 msp3400c_setvolume(client
, msp
->left
, msp
->right
);
1071 if (msp
->watch_stereo
)
1072 mod_timer(&msp
->wake_stereo
, jiffies
+HZ
);
1078 dprintk("msp3410: thread: exit\n");
1082 if(msp
->notify
!= NULL
)
1087 /* ----------------------------------------------------------------------- */
1089 static int msp_attach(struct i2c_adapter
*adap
, int addr
,
1090 unsigned short flags
, int kind
);
1091 static int msp_detach(struct i2c_client
*client
);
1092 static int msp_probe(struct i2c_adapter
*adap
);
1093 static int msp_command(struct i2c_client
*client
, unsigned int cmd
, void *arg
);
1095 static struct i2c_driver driver
= {
1096 "i2c msp3400 driver",
1097 I2C_DRIVERID_MSP3400
,
1104 static struct i2c_client client_template
=
1114 static int msp_attach(struct i2c_adapter
*adap
, int addr
,
1115 unsigned short flags
, int kind
)
1117 DECLARE_MUTEX_LOCKED(sem
);
1118 struct msp3400c
*msp
;
1119 struct i2c_client
*c
;
1122 client_template
.adapter
= adap
;
1123 client_template
.addr
= addr
;
1125 if (-1 == msp3400c_reset(&client_template
)) {
1126 dprintk("msp3400: no chip found\n");
1130 if (NULL
== (c
= kmalloc(sizeof(struct i2c_client
),GFP_KERNEL
)))
1132 memcpy(c
,&client_template
,sizeof(struct i2c_client
));
1133 if (NULL
== (msp
= kmalloc(sizeof(struct msp3400c
),GFP_KERNEL
))) {
1138 memset(msp
,0,sizeof(struct msp3400c
));
1142 msp
->treble
= 32768;
1144 init_waitqueue_head(&msp
->wq
);
1146 if (-1 == msp3400c_reset(c
)) {
1148 dprintk("msp3400: no chip found\n");
1152 rev1
= msp3400c_read(c
, I2C_MSP3400C_DFP
, 0x1e);
1153 rev2
= msp3400c_read(c
, I2C_MSP3400C_DFP
, 0x1f);
1154 if (0 == rev1
&& 0 == rev2
) {
1156 printk("msp3400: error while reading chip version\n");
1161 /* this will turn on a 1kHz beep - might be useful for debugging... */
1162 msp3400c_write(client
,I2C_MSP3400C_DFP
, 0x0014, 0x1040);
1165 sprintf(c
->name
,"MSP34%02d%c-%c%d",
1166 (rev2
>>8)&0xff, (rev1
&0xff)+'@', ((rev1
>>8)&0xff)+'@', rev2
&0x1f);
1167 msp
->nicam
= (((rev2
>>8)&0xff) != 00) ? 1 : 0;
1171 /* msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; */
1172 msp
->simple
= ((rev1
&0xff)+'@' > 'C');
1174 /* use insmod option */
1175 msp
->simple
= simple
;
1178 /* timer for stereo checking */
1179 msp
->wake_stereo
.function
= msp3400c_stereo_wake
;
1180 msp
->wake_stereo
.data
= (unsigned long)msp
;
1182 /* hello world :-) */
1183 printk(KERN_INFO
"msp3400: init: chip=%s",c
->name
);
1185 printk(", has NICAM support");
1188 /* startup control thread */
1191 kernel_thread(msp
->simple
? msp3410d_thread
: msp3400c_thread
,
1195 wake_up_interruptible(&msp
->wq
);
1197 #ifdef REGISTER_MIXER
1198 if ((msp
->mixer_num
= register_sound_mixer(&msp3400c_mixer_fops
,mixer
)) < 0)
1199 printk(KERN_ERR
"msp3400c: cannot allocate mixer device\n");
1202 /* update our own array */
1203 for (i
= 0; i
< MSP3400_MAX
; i
++) {
1204 if (NULL
== msps
[i
]) {
1211 i2c_attach_client(c
);
1215 static int msp_detach(struct i2c_client
*client
)
1217 DECLARE_MUTEX_LOCKED(sem
);
1218 struct msp3400c
*msp
= (struct msp3400c
*)client
->data
;
1221 #ifdef REGISTER_MIXER
1222 if (msp
->mixer_num
>= 0)
1223 unregister_sound_mixer(msp
->mixer_num
);
1226 /* shutdown control thread */
1227 del_timer(&msp
->wake_stereo
);
1232 wake_up_interruptible(&msp
->wq
);
1236 msp3400c_reset(client
);
1238 /* update our own array */
1239 for (i
= 0; i
< MSP3400_MAX
; i
++) {
1240 if (client
== msps
[i
]) {
1246 i2c_detach_client(client
);
1253 static int msp_probe(struct i2c_adapter
*adap
)
1255 if (adap
->id
== (I2C_ALGO_BIT
| I2C_HW_B_BT848
))
1256 return i2c_probe(adap
, &addr_data
, msp_attach
);
1260 static int msp_command(struct i2c_client
*client
,unsigned int cmd
, void *arg
)
1262 struct msp3400c
*msp
= (struct msp3400c
*)client
->data
;
1264 int *iarg
= (int*)arg
;
1270 case AUDC_SET_RADIO
:
1271 msp
->norm
= VIDEO_MODE_RADIO
;
1272 msp
->watch_stereo
=0;
1273 del_timer(&msp
->wake_stereo
);
1275 msp3400c_reset(client
);
1276 msp3400c_write(client
, I2C_MSP3400C_DEM
, 0x30, 0x0003); /* automatic */
1277 msp3400c_write(client
, I2C_MSP3400C_DEM
, 0x20, 0x0040); /* FM Radio */
1278 msp3400c_write(client
, I2C_MSP3400C_DFP
, 0x0e, 0x2403); /* FM prescale */
1279 msp3400c_setbass(client
, msp
->bass
);
1280 msp3400c_settreble(client
, msp
->treble
);
1281 msp3400c_setvolume(client
, msp
->left
, msp
->right
);
1283 msp3400c_setmode(client
,MSP_MODE_FM_RADIO
);
1284 msp3400c_setcarrier(client
, MSP_CARRIER(10.7),MSP_CARRIER(10.7));
1285 msp3400c_setvolume(client
,msp
->left
, msp
->right
);
1289 /* --- v4l ioctls --- */
1290 /* take care: bttv does userspace copying, we'll get a
1291 kernel pointer here... */
1294 struct video_audio
*va
= arg
;
1296 va
->flags
|= VIDEO_AUDIO_VOLUME
|
1299 va
->volume
=MAX(msp
->left
,msp
->right
);
1300 va
->balance
=(32768*MIN(msp
->left
,msp
->right
))/
1301 (va
->volume
? va
->volume
: 1);
1302 va
->balance
=(msp
->left
<msp
->right
)?
1303 (65535-va
->balance
) : va
->balance
;
1304 va
->bass
= msp
->bass
;
1305 va
->treble
= msp
->treble
;
1307 autodetect_stereo(client
);
1308 va
->mode
= msp
->stereo
;
1313 struct video_audio
*va
= arg
;
1315 msp
->left
= (MIN(65536 - va
->balance
,32768) *
1316 va
->volume
) / 32768;
1317 msp
->right
= (MIN(va
->balance
,32768) *
1318 va
->volume
) / 32768;
1319 msp
->bass
= va
->bass
;
1320 msp
->treble
= va
->treble
;
1321 msp3400c_setvolume(client
,msp
->left
, msp
->right
);
1322 msp3400c_setbass(client
,msp
->bass
);
1323 msp3400c_settreble(client
,msp
->treble
);
1325 if (va
->mode
!= 0) {
1326 msp
->watch_stereo
=0;
1327 del_timer(&msp
->wake_stereo
);
1328 msp
->stereo
= va
->mode
;
1329 msp3400c_setstereo(client
,va
->mode
);
1335 struct video_channel
*vc
= arg
;
1337 msp
->norm
= vc
->norm
;
1342 /* new channel -- kick audio carrier scan */
1343 msp3400c_setvolume(client
,0,0);
1344 msp
->watch_stereo
=0;
1345 del_timer(&msp
->wake_stereo
);
1348 wake_up_interruptible(&msp
->wq
);
1352 /* --- v4l2 ioctls --- */
1356 /* --- old, obsolete interface --- */
1357 case AUDC_SET_TVNORM
:
1360 case AUDC_SWITCH_MUTE
:
1361 /* channels switching step one -- mute */
1362 msp
->watch_stereo
=0;
1363 del_timer(&msp
->wake_stereo
);
1364 msp3400c_setvolume(client
,0,0);
1366 case AUDC_NEWCHANNEL
:
1367 /* channels switching step two -- trigger sound carrier scan */
1368 msp
->watch_stereo
=0;
1369 del_timer(&msp
->wake_stereo
);
1372 wake_up_interruptible(&msp
->wq
);
1375 case AUDC_GET_VOLUME_LEFT
:
1378 case AUDC_GET_VOLUME_RIGHT
:
1381 case AUDC_SET_VOLUME_LEFT
:
1383 msp3400c_setvolume(client
,msp
->left
, msp
->right
);
1385 case AUDC_SET_VOLUME_RIGHT
:
1387 msp3400c_setvolume(client
,msp
->left
, msp
->right
);
1395 msp3400c_setbass(client
,msp
->bass
);
1398 case AUDC_GET_TREBLE
:
1399 *sarg
= msp
->treble
;
1401 case AUDC_SET_TREBLE
:
1402 msp
->treble
= *sarg
;
1403 msp3400c_settreble(client
,msp
->treble
);
1406 case AUDC_GET_STEREO
:
1407 autodetect_stereo(client
);
1408 *sarg
= msp
->stereo
;
1410 case AUDC_SET_STEREO
:
1412 msp
->watch_stereo
=0;
1413 del_timer(&msp
->wake_stereo
);
1414 msp
->stereo
= *sarg
;
1415 msp3400c_setstereo(client
,*sarg
);
1422 *sarg
= ((int)msp3400c_read(client
, I2C_MSP3400C_DFP
, 0x1b) +
1423 (int)msp3400c_read(client
, I2C_MSP3400C_DFP
, 0x1c));
1432 /* ----------------------------------------------------------------------- */
1434 int msp3400_init_module(void)
1436 i2c_add_driver(&driver
);
1440 void msp3400_cleanup_module(void)
1442 i2c_del_driver(&driver
);
1445 module_init(msp3400_init_module
);
1446 module_exit(msp3400_cleanup_module
);
1449 * Overrides for Emacs so that we follow Linus's tabbing style.
1450 * ---------------------------------------------------------------------------