2 * programming the msp34* sound processor family
4 * (c) 1997,1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
6 * what works and what doesn't:
9 * probably doesn't (untested)
12 * should work. The stereo modes are backward compatible to FM-mono,
13 * therefore FM-Mono should be allways available.
15 * FM-Stereo (B/G, used in germany)
16 * should work, with autodetect
18 * FM-Stereo (satellite)
19 * should work, no autodetect (i.e. default is mono, but you can
20 * switch to stereo -- untested)
22 * NICAM (B/G, used in UK, Scandinavia and Spain)
23 * should work, with autodetect. Support for NICAM was added by
24 * Pekka Pietikainen <pp@netppl.fi>
28 * - better SAT support
31 * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch)
32 * using soundcore instead of OSS
36 #include <linux/module.h>
37 #include <linux/version.h>
38 #include <linux/kernel.h>
39 #include <linux/sched.h>
40 #include <linux/string.h>
41 #include <linux/timer.h>
42 #include <linux/delay.h>
43 #include <linux/errno.h>
44 #include <linux/malloc.h>
46 #include <asm/pgtable.h>
47 #include <linux/smp_lock.h>
51 #define __KERNEL_SYSCALLS__
52 #include <linux/unistd.h>
54 #include <linux/i2c.h>
55 #include <linux/videodev.h>
60 /* sound mixer stuff */
61 #include <linux/config.h>
63 #if LINUX_VERSION_CODE > 0x020140 /* need modular sound driver */
64 # if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
65 # define REGISTER_MIXER 1
70 static int debug
= 0; /* insmod parameter */
79 int main
, second
; /* sound carrier */
81 int left
, right
; /* volume */
85 struct task_struct
*thread
;
86 struct wait_queue
*wq
;
87 struct semaphore
*notify
;
88 int active
,restart
,rmmod
;
91 struct timer_list wake_stereo
;
94 #define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
96 /* ---------------------------------------------------------------------- */
98 #define dprintk if (debug) printk
100 #if LINUX_VERSION_CODE < 0x020100
102 #define signal_pending(current) (current->signal & ~current->blocked)
103 #define sigfillset(set)
104 #define mdelay(x) udelay(1000*x)
106 MODULE_PARM(debug
,"i");
109 #if LINUX_VERSION_CODE < 0x02017f
110 void schedule_timeout(int j
)
112 current
->timeout
= jiffies
+ j
;
117 /* ---------------------------------------------------------------------- */
119 #define I2C_MSP3400C 0x80
120 #define I2C_MSP3400C_DEM 0x10
121 #define I2C_MSP3400C_DFP 0x12
123 /* ----------------------------------------------------------------------- */
124 /* functions for talking to the MSP3400C Sound processor */
126 static int msp3400c_reset(struct i2c_bus
*bus
)
132 i2c_sendbyte(bus
, I2C_MSP3400C
,2000);
133 i2c_sendbyte(bus
, 0x00,0);
134 i2c_sendbyte(bus
, 0x80,0);
135 i2c_sendbyte(bus
, 0x00,0);
139 if (0 != i2c_sendbyte(bus
, I2C_MSP3400C
,2000) ||
140 0 != i2c_sendbyte(bus
, 0x00,0) ||
141 0 != i2c_sendbyte(bus
, 0x00,0) ||
142 0 != i2c_sendbyte(bus
, 0x00,0)) {
144 printk(KERN_ERR
"msp3400: chip reset failed, penguin on i2c bus?\n");
152 msp3400c_read(struct i2c_bus
*bus
, int dev
, int addr
)
157 if (0 != i2c_sendbyte(bus
, I2C_MSP3400C
,2000) ||
158 0 != i2c_sendbyte(bus
, dev
+1, 0) ||
159 0 != i2c_sendbyte(bus
, addr
>> 8, 0) ||
160 0 != i2c_sendbyte(bus
, addr
& 0xff, 0)) {
164 if (0 != i2c_sendbyte(bus
, I2C_MSP3400C
+1,2000)) {
167 val
|= (int)i2c_readbyte(bus
,0) << 8;
168 val
|= (int)i2c_readbyte(bus
,1);
173 printk(KERN_WARNING
"msp3400: I/O error, trying reset (read %s 0x%x)\n",
174 (dev
== I2C_MSP3400C_DEM
) ? "Demod" : "Audio", addr
);
181 msp3400c_write(struct i2c_bus
*bus
, int dev
, int addr
, int val
)
186 if (0 != i2c_sendbyte(bus
, I2C_MSP3400C
,2000) ||
187 0 != i2c_sendbyte(bus
, dev
, 0) ||
188 0 != i2c_sendbyte(bus
, addr
>> 8, 0) ||
189 0 != i2c_sendbyte(bus
, addr
& 0xff, 0) ||
190 0 != i2c_sendbyte(bus
, val
>> 8, 0) ||
191 0 != i2c_sendbyte(bus
, val
& 0xff, 0))
195 printk(KERN_WARNING
"msp3400: I/O error, trying reset (write %s 0x%x)\n",
196 (dev
== I2C_MSP3400C_DEM
) ? "Demod" : "Audio", addr
);
202 /* ------------------------------------------------------------------------ */
204 /* This macro is allowed for *constants* only, gcc must calculate it
205 at compile time. Remember -- no floats in kernel mode */
206 #define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
208 #define MSP_MODE_AM_DETECT 0
209 #define MSP_MODE_FM_RADIO 2
210 #define MSP_MODE_FM_TERRA 3
211 #define MSP_MODE_FM_SAT 4
212 #define MSP_MODE_FM_NICAM1 5
213 #define MSP_MODE_FM_NICAM2 6
215 static struct MSP_INIT_DATA_DEM
{
224 } msp_init_data
[] = {
225 /* AM (for carrier detect / msp3400) */
226 { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
227 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
228 0x00d0, 0x0500, 0x0020, 0x3000},
230 /* AM (for carrier detect / msp3410) */
231 { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
232 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
233 0x00d0, 0x0100, 0x0020, 0x3000},
236 { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
237 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
238 0x00d0, 0x0480, 0x0020, 0x3000 },
240 /* Terrestial FM-mono + FM-stereo */
241 { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 },
242 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
243 0x00d0, 0x0480, 0x0030, 0x3000},
246 { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 },
247 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
248 0x00c6, 0x0480, 0x0000, 0x3000},
251 { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 },
252 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
253 0x00d0, 0x0040, 0x0120, 0x3000},
256 { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 },
257 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
258 0x00d0, 0x0040, 0x0120, 0x3000},
261 struct CARRIER_DETECT
{
266 static struct CARRIER_DETECT carrier_detect_main
[] = {
268 { MSP_CARRIER(4.5), "4.5 NTSC" },
269 { MSP_CARRIER(5.5), "5.5 PAL B/G" },
270 { MSP_CARRIER(6.0), "6.0 PAL I" },
271 { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }
274 static struct CARRIER_DETECT carrier_detect_55
[] = {
276 { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },
277 { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }
280 static struct CARRIER_DETECT carrier_detect_65
[] = {
281 /* PAL SAT / SECAM */
282 { MSP_CARRIER(5.85), "5.85 PAL D/K NICAM" },
283 { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },
284 { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },
285 { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },
286 { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },
287 { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },
290 #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
292 /* ------------------------------------------------------------------------ */
294 static void msp3400c_setcarrier(struct i2c_bus
*bus
, int cdo1
, int cdo2
)
296 msp3400c_write(bus
,I2C_MSP3400C_DEM
, 0x0093, cdo1
& 0xfff);
297 msp3400c_write(bus
,I2C_MSP3400C_DEM
, 0x009b, cdo1
>> 12);
298 msp3400c_write(bus
,I2C_MSP3400C_DEM
, 0x00a3, cdo2
& 0xfff);
299 msp3400c_write(bus
,I2C_MSP3400C_DEM
, 0x00ab, cdo2
>> 12);
300 msp3400c_write(bus
,I2C_MSP3400C_DEM
, 0x0056, 0); /*LOAD_REG_1/2*/
303 static void msp3400c_setvolume(struct i2c_bus
*bus
, int left
, int right
)
307 vol
= (left
> right
) ? left
: right
;
308 val
= (vol
* 0x73 / 65535) << 8;
311 balance
= ((right
-left
) * 127) / vol
;
313 dprintk("msp3400: setvolume: %d:%d 0x%02x 0x%02x\n",
314 left
,right
,val
>>8,balance
);
315 msp3400c_write(bus
,I2C_MSP3400C_DFP
, 0x0000, val
); /* loudspeaker */
316 msp3400c_write(bus
,I2C_MSP3400C_DFP
, 0x0006, val
); /* headphones */
317 /* scart - on/off only */
318 msp3400c_write(bus
,I2C_MSP3400C_DFP
, 0x0007, val
? 0x4000 : 0);
319 msp3400c_write(bus
,I2C_MSP3400C_DFP
, 0x0001, balance
<< 8);
322 static void msp3400c_setbass(struct i2c_bus
*bus
, int bass
)
324 int val
= ((bass
-32768) * 0x60 / 65535) << 8;
326 dprintk("msp3400: setbass: %d 0x%02x\n",bass
, val
>>8);
327 msp3400c_write(bus
,I2C_MSP3400C_DFP
, 0x0002, val
); /* loudspeaker */
330 static void msp3400c_settreble(struct i2c_bus
*bus
, int treble
)
332 int val
= ((treble
-32768) * 0x60 / 65535) << 8;
334 dprintk("msp3400: settreble: %d 0x%02x\n",treble
, val
>>8);
335 msp3400c_write(bus
,I2C_MSP3400C_DFP
, 0x0003, val
); /* loudspeaker */
338 static void msp3400c_setmode(struct msp3400c
*msp
, int type
)
342 dprintk("msp3400: setmode: %d\n",type
);
344 msp
->stereo
= VIDEO_SOUND_MONO
;
346 msp3400c_write(msp
->bus
,I2C_MSP3400C_DEM
, 0x00bb, /* ad_cv */
347 msp_init_data
[type
].ad_cv
);
349 for (i
= 5; i
>= 0; i
--) /* fir 1 */
350 msp3400c_write(msp
->bus
,I2C_MSP3400C_DEM
, 0x0001,
351 msp_init_data
[type
].fir1
[i
]);
353 msp3400c_write(msp
->bus
,I2C_MSP3400C_DEM
, 0x0005, 0x0004); /* fir 2 */
354 msp3400c_write(msp
->bus
,I2C_MSP3400C_DEM
, 0x0005, 0x0040);
355 msp3400c_write(msp
->bus
,I2C_MSP3400C_DEM
, 0x0005, 0x0000);
356 for (i
= 5; i
>= 0; i
--)
357 msp3400c_write(msp
->bus
,I2C_MSP3400C_DEM
, 0x0005,
358 msp_init_data
[type
].fir2
[i
]);
360 msp3400c_write(msp
->bus
,I2C_MSP3400C_DEM
, 0x0083, /* MODE_REG */
361 msp_init_data
[type
].mode_reg
);
363 msp3400c_setcarrier(msp
->bus
, msp_init_data
[type
].cdo1
,
364 msp_init_data
[type
].cdo2
);
366 msp3400c_write(msp
->bus
,I2C_MSP3400C_DEM
, 0x0056, 0); /*LOAD_REG_1/2*/
368 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0008,
369 msp_init_data
[type
].dfp_src
);
370 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0009,
371 msp_init_data
[type
].dfp_src
);
372 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x000a,
373 msp_init_data
[type
].dfp_src
);
374 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x000e,
375 msp_init_data
[type
].dfp_matrix
);
378 /* msp3410 needs some more initialization */
379 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0010, 0x3000);
383 static void msp3400c_setstereo(struct msp3400c
*msp
, int mode
)
385 int nicam
=0; /* channel source: FM/AM or nicam */
387 /* switch demodulator */
389 case MSP_MODE_FM_TERRA
:
390 dprintk("msp3400: FM setstereo: %d\n",mode
);
392 msp3400c_setcarrier(msp
->bus
,msp
->second
,msp
->main
);
394 case VIDEO_SOUND_STEREO
:
395 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x000e, 0x3001);
397 case VIDEO_SOUND_MONO
:
398 case VIDEO_SOUND_LANG1
:
399 case VIDEO_SOUND_LANG2
:
400 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x000e, 0x3000);
404 case MSP_MODE_FM_SAT
:
405 dprintk("msp3400: SAT setstereo: %d\n",mode
);
408 case VIDEO_SOUND_MONO
:
409 msp3400c_setcarrier(msp
->bus
, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
411 case VIDEO_SOUND_STEREO
:
412 msp3400c_setcarrier(msp
->bus
, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
414 case VIDEO_SOUND_LANG1
:
415 msp3400c_setcarrier(msp
->bus
, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
417 case VIDEO_SOUND_LANG2
:
418 msp3400c_setcarrier(msp
->bus
, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
422 case MSP_MODE_FM_NICAM1
:
423 case MSP_MODE_FM_NICAM2
:
424 dprintk("msp3400: NICAM setstereo: %d\n",mode
);
426 msp3400c_setcarrier(msp
->bus
,msp
->second
,msp
->main
);
430 /* can't do stereo - abort here */
436 case VIDEO_SOUND_STEREO
:
437 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0008,0x0020|nicam
);
438 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0009,0x0020|nicam
);
439 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x000a,0x0020|nicam
);
441 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0005,0x4000);
444 case VIDEO_SOUND_MONO
:
445 case VIDEO_SOUND_LANG1
:
446 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0008,0x0000|nicam
);
447 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0009,0x0000|nicam
);
448 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x000a,0x0000|nicam
);
450 case VIDEO_SOUND_LANG2
:
451 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0008,0x0010|nicam
);
452 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0009,0x0010|nicam
);
453 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x000a,0x0010|nicam
);
459 msp3400c_print_mode(struct msp3400c
*msp
)
461 if (msp
->main
== msp
->second
) {
462 printk("msp3400: mono sound carrier: %d.%03d MHz\n",
463 msp
->main
/910000,(msp
->main
/910)%1000);
465 printk("msp3400: main sound carrier: %d.%03d MHz\n",
466 msp
->main
/910000,(msp
->main
/910)%1000);
468 if (msp
->mode
== MSP_MODE_FM_NICAM1
||
469 msp
->mode
== MSP_MODE_FM_NICAM2
)
470 printk("msp3400: NICAM carrier : %d.%03d MHz\n",
471 msp
->second
/910000,(msp
->second
/910)%1000);
472 if (msp
->mode
== MSP_MODE_FM_TERRA
&&
473 msp
->main
!= msp
->second
) {
474 printk("msp3400: FM-stereo carrier : %d.%03d MHz\n",
475 msp
->second
/910000,(msp
->second
/910)%1000);
479 /* ----------------------------------------------------------------------- */
481 struct REGISTER_DUMP
{
486 struct REGISTER_DUMP d1
[] = {
487 { 0x007e, "autodetect" },
488 { 0x0023, "C_AD_BITS " },
489 { 0x0038, "ADD_BITS " },
490 { 0x003e, "CIB_BITS " },
491 { 0x0057, "ERROR_RATE" },
495 * A kernel thread for msp3400 control -- we don't want to block the
496 * in the ioctl while doing the sound carrier & stereo detect
499 static void msp3400c_stereo_wake(unsigned long data
)
501 struct msp3400c
*msp
= (struct msp3400c
*)data
; /* XXX alpha ??? */
503 wake_up_interruptible(&msp
->wq
);
506 static int msp3400c_thread(void *data
)
508 struct msp3400c
*msp
= data
;
510 struct CARRIER_DETECT
*cd
;
511 int count
, max1
,max2
,val1
,val2
, val
,this;
520 current
->session
= 1;
522 sigfillset(¤t
->blocked
);
523 current
->fs
->umask
= 0;
524 strcpy(current
->comm
,"msp3400");
527 msp
->thread
= current
;
533 dprintk("msp3400: thread: start\n");
534 if(msp
->notify
!= NULL
)
541 printk("msp3400: thread: sleep\n");
542 interruptible_sleep_on(&msp
->wq
);
544 printk("msp3400: thread: wakeup\n");
545 if (msp
->rmmod
|| signal_pending(current
))
548 if (VIDEO_MODE_RADIO
== msp
->norm
)
549 continue; /* nothing to do */
553 if (msp
->watch_stereo
) {
554 /* do that stereo/multilang handling */
555 LOCK_I2C_BUS(msp
->bus
);
556 newstereo
= msp
->stereo
;
558 case MSP_MODE_FM_TERRA
:
559 val
= msp3400c_read(msp
->bus
, I2C_MSP3400C_DFP
, 0x18);
560 dprintk("msp3400: stereo detect register: %d\n",val
);
563 newstereo
= VIDEO_SOUND_STEREO
;
564 } else if (val
< -4096) {
565 newstereo
= VIDEO_SOUND_LANG1
;
567 newstereo
= VIDEO_SOUND_MONO
;
570 case MSP_MODE_FM_NICAM1
:
571 case MSP_MODE_FM_NICAM2
:
572 val
= msp3400c_read(msp
->bus
, I2C_MSP3400C_DEM
, 0x23);
573 switch ((val
& 0x1e) >> 1) {
576 newstereo
= VIDEO_SOUND_STEREO
;
579 newstereo
= VIDEO_SOUND_MONO
;
584 if (msp
->stereo
!= newstereo
) {
585 dprintk("msp3400: watch: stereo %d ==> %d\n",
586 msp
->stereo
,newstereo
);
587 msp3400c_setstereo(msp
,newstereo
);
589 UNLOCK_I2C_BUS(msp
->bus
);
590 if (msp
->watch_stereo
) {
591 del_timer(&msp
->wake_stereo
);
592 msp
->wake_stereo
.expires
= jiffies
+ 5*HZ
;
593 add_timer(&msp
->wake_stereo
);
601 LOCK_I2C_BUS(msp
->bus
);
602 msp3400c_setvolume(msp
->bus
, 0, 0);
603 msp3400c_setmode(msp
, MSP_MODE_AM_DETECT
);
606 del_timer(&msp
->wake_stereo
);
607 msp
->watch_stereo
= 0;
609 /* carrier detect pass #1 -- main carrier */
610 cd
= carrier_detect_main
; count
= CARRIER_COUNT(carrier_detect_main
);
611 for (this = 0; this < count
; this++) {
612 msp3400c_setcarrier(msp
->bus
, cd
[this].cdo
,cd
[this].cdo
);
613 UNLOCK_I2C_BUS(msp
->bus
);
615 current
->state
= TASK_INTERRUPTIBLE
;
616 schedule_timeout(HZ
/25);
617 if (signal_pending(current
))
624 LOCK_I2C_BUS(msp
->bus
);
625 val
= msp3400c_read(msp
->bus
, I2C_MSP3400C_DFP
, 0x1b);
627 val1
= val
, max1
= this;
628 dprintk("msp3400: carrier1 val: %5d / %s\n", val
,cd
[this].name
);
631 /* carrier detect pass #2 -- second (stereo) carrier */
634 cd
= carrier_detect_55
; count
= CARRIER_COUNT(carrier_detect_55
);
637 cd
= carrier_detect_65
; count
= CARRIER_COUNT(carrier_detect_65
);
642 cd
= NULL
; count
= 0;
645 for (this = 0; this < count
; this++) {
646 msp3400c_setcarrier(msp
->bus
, cd
[this].cdo
,cd
[this].cdo
);
647 UNLOCK_I2C_BUS(msp
->bus
);
649 current
->state
= TASK_INTERRUPTIBLE
;
650 schedule_timeout(HZ
/25);
651 if (signal_pending(current
))
658 LOCK_I2C_BUS(msp
->bus
);
659 val
= msp3400c_read(msp
->bus
, I2C_MSP3400C_DFP
, 0x1b);
661 val2
= val
, max2
= this;
662 dprintk("msp3400: carrier2 val: %5d / %s\n", val
,cd
[this].name
);
665 /* programm the msp3400 according to the results */
666 msp
->main
= carrier_detect_main
[max1
].cdo
;
671 msp
->second
= carrier_detect_55
[max2
].cdo
;
672 msp3400c_setmode(msp
, MSP_MODE_FM_TERRA
);
673 msp3400c_setstereo(msp
, VIDEO_SOUND_MONO
);
674 msp
->watch_stereo
= 1;
675 } else if (max2
== 1 && msp
->nicam
) {
677 msp
->second
= carrier_detect_55
[max2
].cdo
;
678 msp3400c_setmode(msp
, MSP_MODE_FM_NICAM1
);
679 msp3400c_setcarrier(msp
->bus
, msp
->second
, msp
->main
);
680 msp
->watch_stereo
= 1;
687 msp
->second
= MSP_CARRIER(6.552);
688 msp3400c_setmode(msp
, MSP_MODE_FM_NICAM2
);
689 msp3400c_setcarrier(msp
->bus
, msp
->second
, msp
->main
);
690 msp
->watch_stereo
= 1;
693 if (max2
== 1 || max2
== 2) {
695 msp
->second
= carrier_detect_65
[max2
].cdo
;
696 msp3400c_setmode(msp
, MSP_MODE_FM_TERRA
);
697 msp3400c_setstereo(msp
, VIDEO_SOUND_MONO
);
698 msp
->watch_stereo
= 1;
699 } else if (max2
== 0 && msp
->nicam
) {
701 msp
->second
= carrier_detect_65
[max2
].cdo
;
702 msp3400c_setmode(msp
, MSP_MODE_FM_NICAM1
);
703 msp3400c_setcarrier(msp
->bus
, msp
->second
, msp
->main
);
704 msp
->watch_stereo
= 1;
712 msp
->second
= carrier_detect_main
[max1
].cdo
;
713 msp3400c_setmode(msp
, MSP_MODE_FM_TERRA
);
714 msp3400c_setcarrier(msp
->bus
, msp
->second
, msp
->main
);
719 msp3400c_setvolume(msp
->bus
, msp
->left
, msp
->right
);
720 UNLOCK_I2C_BUS(msp
->bus
);
722 if (msp
->watch_stereo
) {
723 del_timer(&msp
->wake_stereo
);
724 msp
->wake_stereo
.expires
= jiffies
+ 2*HZ
;
725 add_timer(&msp
->wake_stereo
);
729 msp3400c_print_mode(msp
);
735 dprintk("msp3400: thread: exit\n");
739 if(msp
->notify
!= NULL
)
745 #if 0 /* not finished yet */
747 static int msp3410d_thread(void *data
)
750 struct msp3400c
*msp
= data
;
751 struct semaphore sem
= MUTEX_LOCKED
;
757 current
->session
= 1;
759 sigfillset(¤t
->blocked
);
760 current
->fs
->umask
= 0;
761 strcpy(current
->comm
,"msp3410 (nicam)");
764 msp
->thread
= current
;
766 /* unlock_kernel(); */
768 dprintk("msp3410: thread: start\n");
769 if(msp
->notify
!= NULL
)
775 dprintk("msp3410: thread: sleep\n");
776 down_interruptible(&sem
);
778 dprintk("msp3410: thread: wakeup\n");
782 if (VIDEO_MODE_RADIO
== msp
->norm
)
783 continue; /* nothing to do */
788 LOCK_I2C_BUS(msp
->bus
);
790 msp3400c_setvolume(msp
->bus
, 0);
791 /* quick & dirty hack:
792 get the audio proccessor into some useful state */
793 msp3400c_setmode(msp
, MSP_MODE_FM_NICAM1
);
794 /* kick autodetect */
795 msp3400c_write(msp
->bus
, I2C_MSP3400C_DFP
, 0x20, 0x01);
796 msp3400c_write(msp
->bus
, I2C_MSP3400C_DFP
, 0x21, 0x01);
797 UNLOCK_I2C_BUS(msp
->bus
);
800 current
->state
= TASK_INTERRUPTIBLE
;
801 current
->timeout
= jiffies
+ HZ
;
803 if (signal_pending(current
))
810 LOCK_I2C_BUS(msp
->bus
);
811 /* debug register dump */
812 for (i
= 0; i
< sizeof(d1
)/sizeof(struct REGISTER_DUMP
); i
++) {
813 val
= msp3400c_read(msp
->bus
,I2C_MSP3400C_DEM
,d1
[i
].addr
);
814 printk(KERN_DEBUG
"msp3400: %s = 0x%x\n",d1
[i
].name
,val
);
817 msp3400c_setvolume(msp
->bus
, msp
->volume
);
818 UNLOCK_I2C_BUS(msp
->bus
);
824 dprintk("msp3410: thread: exit\n");
829 if(msp
->notify
!= NULL
)
835 /* ----------------------------------------------------------------------- */
836 /* mixer stuff -- with the modular sound driver in 2.1.x we can easily */
837 /* register the msp3400 as mixer device */
839 #ifdef REGISTER_MIXER
841 #include <linux/sound.h>
842 #include <linux/soundcard.h>
843 #include <asm/uaccess.h>
845 static struct msp3400c
*mspmix
= NULL
; /* ugly hack, should do something more sensible */
846 static int mixer_num
;
847 static int mixer_modcnt
= 0;
848 static struct semaphore mixer_sem
= MUTEX
;
850 static int mix_to_v4l(int i
)
854 r
= ((i
& 0xff) * 65536 + 50) / 100;
855 if (r
> 65535) r
= 65535;
860 static int v4l_to_mix(int i
)
864 r
= (i
* 100 + 32768) / 65536;
865 if (r
> 100) r
= 100;
870 static int v4l_to_mix2(int l
, int r
)
872 r
= (r
* 100 + 32768) / 65536;
873 if (r
> 100) r
= 100;
875 l
= (l
* 100 + 32768) / 65536;
876 if (l
> 100) l
= 100;
882 msp3400c_mixer_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
887 if (cmd
== SOUND_MIXER_INFO
) {
889 strncpy(info
.id
, "MSP3400", sizeof(info
.id
));
890 strncpy(info
.name
, "MSP 3400", sizeof(info
.name
));
891 info
.modify_counter
= mixer_modcnt
;
892 if (copy_to_user((void *)arg
, &info
, sizeof(info
)))
896 if (cmd
== SOUND_OLD_MIXER_INFO
) {
897 _old_mixer_info info
;
898 strncpy(info
.id
, "MSP3400", sizeof(info
.id
));
899 strncpy(info
.name
, "MSP 3400", sizeof(info
.name
));
900 if (copy_to_user((void *)arg
, &info
, sizeof(info
)))
904 if (cmd
== OSS_GETVERSION
)
905 return put_user(SOUND_VERSION
, (int *)arg
);
907 if (_SIOC_DIR(cmd
) & _SIOC_WRITE
)
908 if (get_user(val
, (int *)arg
))
918 case MIXER_READ(SOUND_MIXER_RECMASK
):
919 case MIXER_READ(SOUND_MIXER_CAPS
):
920 case MIXER_READ(SOUND_MIXER_RECSRC
):
921 case MIXER_WRITE(SOUND_MIXER_RECSRC
):
925 case MIXER_READ(SOUND_MIXER_STEREODEVS
):
926 ret
= SOUND_MASK_VOLUME
;
928 case MIXER_READ(SOUND_MIXER_DEVMASK
):
929 ret
= SOUND_MASK_VOLUME
| SOUND_MASK_BASS
| SOUND_MASK_TREBLE
;
932 case MIXER_WRITE(SOUND_MIXER_VOLUME
):
933 mspmix
->left
= mix_to_v4l(val
);
934 mspmix
->right
= mix_to_v4l(val
>> 8);
935 LOCK_I2C_BUS(mspmix
->bus
);
936 msp3400c_setvolume(mspmix
->bus
,mspmix
->left
,mspmix
->right
);
937 UNLOCK_I2C_BUS(mspmix
->bus
);
940 case MIXER_READ(SOUND_MIXER_VOLUME
):
941 ret
= v4l_to_mix2(mspmix
->left
, mspmix
->right
);
944 case MIXER_WRITE(SOUND_MIXER_BASS
):
945 mspmix
->bass
= mix_to_v4l(val
);
946 LOCK_I2C_BUS(mspmix
->bus
);
947 msp3400c_setbass(mspmix
->bus
,mspmix
->bass
);
948 UNLOCK_I2C_BUS(mspmix
->bus
);
951 case MIXER_READ(SOUND_MIXER_BASS
):
952 ret
= v4l_to_mix(mspmix
->bass
);
955 case MIXER_WRITE(SOUND_MIXER_TREBLE
):
956 mspmix
->treble
= mix_to_v4l(val
);
957 LOCK_I2C_BUS(mspmix
->bus
);
958 msp3400c_settreble(mspmix
->bus
,mspmix
->treble
);
959 UNLOCK_I2C_BUS(mspmix
->bus
);
962 case MIXER_READ(SOUND_MIXER_TREBLE
):
963 ret
= v4l_to_mix(mspmix
->treble
);
971 if (put_user(ret
, (int *)arg
))
977 msp3400c_mixer_open(struct inode
*inode
, struct file
*file
)
984 msp3400c_mixer_release(struct inode
*inode
, struct file
*file
)
991 msp3400c_mixer_llseek(struct file
*file
, loff_t offset
, int origin
)
996 static /*const*/ struct file_operations msp3400c_mixer_fops
= {
997 &msp3400c_mixer_llseek
,
1002 &msp3400c_mixer_ioctl
,
1004 &msp3400c_mixer_open
,
1006 &msp3400c_mixer_release
,
1009 NULL
, /* check_media_change */
1010 NULL
, /* revalidate */
1016 /* ----------------------------------------------------------------------- */
1018 static int msp3400c_attach(struct i2c_device
*device
)
1020 struct semaphore sem
= MUTEX_LOCKED
;
1021 struct msp3400c
*msp
;
1025 device
->data
= msp
= kmalloc(sizeof(struct msp3400c
),GFP_KERNEL
);
1028 memset(msp
,0,sizeof(struct msp3400c
));
1029 msp
->bus
= device
->bus
;
1033 msp
->treble
= 32768;
1035 LOCK_I2C_BUS(msp
->bus
);
1036 if (-1 == msp3400c_reset(msp
->bus
)) {
1037 UNLOCK_I2C_BUS(msp
->bus
);
1039 dprintk("msp3400: no chip found\n");
1043 rev1
= msp3400c_read(msp
->bus
, I2C_MSP3400C_DFP
, 0x1e);
1044 rev2
= msp3400c_read(msp
->bus
, I2C_MSP3400C_DFP
, 0x1f);
1045 if (0 == rev1
&& 0 == rev2
) {
1046 UNLOCK_I2C_BUS(msp
->bus
);
1048 printk("msp3400: error while reading chip version\n");
1052 msp3400c_setmode(msp
, MSP_MODE_FM_TERRA
);
1053 msp3400c_setvolume(msp
->bus
, msp
->left
, msp
->right
);
1054 msp3400c_setbass(msp
->bus
, msp
->bass
);
1055 msp3400c_settreble(msp
->bus
, msp
->treble
);
1058 /* this will turn on a 1kHz beep - might be useful for debugging... */
1059 msp3400c_write(msp
->bus
,I2C_MSP3400C_DFP
, 0x0014, 0x1040);
1061 UNLOCK_I2C_BUS(msp
->bus
);
1063 sprintf(device
->name
,"MSP34%02d%c-%c%d",
1064 (rev2
>>8)&0xff, (rev1
&0xff)+'@', ((rev1
>>8)&0xff)+'@', rev2
&0x1f);
1065 msp
->nicam
= (((rev2
>>8)&0xff) != 00) ? 1 : 0;
1067 /* timer for stereo checking */
1068 msp
->wake_stereo
.function
= msp3400c_stereo_wake
;
1069 msp
->wake_stereo
.data
= (unsigned long)msp
;
1071 /* startup control thread */
1075 kernel_thread(msp3400c_thread
, (void *)msp
, 0);
1078 wake_up_interruptible(&msp
->wq
);
1080 printk(KERN_INFO
"msp3400: init: chip=%s",device
->name
);
1082 printk(", has NICAM support");
1083 #ifdef REGISTER_MIXER
1092 static int msp3400c_detach(struct i2c_device
*device
)
1094 struct semaphore sem
= MUTEX_LOCKED
;
1095 struct msp3400c
*msp
= (struct msp3400c
*)device
->data
;
1098 #ifdef REGISTER_MIXER
1104 /* shutdown control thread */
1105 del_timer(&msp
->wake_stereo
);
1110 wake_up_interruptible(&msp
->wq
);
1115 LOCK_I2C_BUS(msp
->bus
);
1116 msp3400c_reset(msp
->bus
);
1117 UNLOCK_I2C_BUS(msp
->bus
);
1124 static int msp3400c_command(struct i2c_device
*device
,
1125 unsigned int cmd
, void *arg
)
1127 struct msp3400c
*msp
= (struct msp3400c
*)device
->data
;
1128 int *iarg
= (int*)arg
;
1134 msp
->norm
= VIDEO_MODE_RADIO
;
1135 msp
->watch_stereo
=0;
1136 del_timer(&msp
->wake_stereo
);
1137 LOCK_I2C_BUS(msp
->bus
);
1138 msp3400c_setmode(msp
,MSP_MODE_FM_RADIO
);
1139 msp3400c_setcarrier(msp
->bus
, MSP_CARRIER(10.7),MSP_CARRIER(10.7));
1140 msp3400c_setvolume(msp
->bus
,msp
->left
, msp
->right
);
1141 UNLOCK_I2C_BUS(msp
->bus
);
1143 case MSP_SET_TVNORM
:
1146 case MSP_SWITCH_MUTE
:
1147 /* channels switching step one -- mute */
1148 msp
->watch_stereo
=0;
1149 del_timer(&msp
->wake_stereo
);
1150 LOCK_I2C_BUS(msp
->bus
);
1151 msp3400c_setvolume(msp
->bus
,0,0);
1152 UNLOCK_I2C_BUS(msp
->bus
);
1154 case MSP_NEWCHANNEL
:
1155 /* channels switching step two -- trigger sound carrier scan */
1156 msp
->watch_stereo
=0;
1157 del_timer(&msp
->wake_stereo
);
1160 wake_up_interruptible(&msp
->wq
);
1163 case MSP_GET_VOLUME
:
1164 *sarg
= (msp
->left
> msp
->right
) ? msp
->left
: msp
->right
;
1166 case MSP_SET_VOLUME
:
1167 msp
->left
= msp
->right
= *sarg
;
1168 LOCK_I2C_BUS(msp
->bus
);
1169 msp3400c_setvolume(msp
->bus
,msp
->left
, msp
->right
);
1170 UNLOCK_I2C_BUS(msp
->bus
);
1178 LOCK_I2C_BUS(msp
->bus
);
1179 msp3400c_setbass(msp
->bus
,msp
->bass
);
1180 UNLOCK_I2C_BUS(msp
->bus
);
1183 case MSP_GET_TREBLE
:
1184 *sarg
= msp
->treble
;
1186 case MSP_SET_TREBLE
:
1187 msp
->treble
= *sarg
;
1188 LOCK_I2C_BUS(msp
->bus
);
1189 msp3400c_settreble(msp
->bus
,msp
->treble
);
1190 UNLOCK_I2C_BUS(msp
->bus
);
1193 case MSP_GET_STEREO
:
1194 *sarg
= msp
->stereo
;
1196 case MSP_SET_STEREO
:
1198 msp
->watch_stereo
=0;
1199 del_timer(&msp
->wake_stereo
);
1200 LOCK_I2C_BUS(msp
->bus
);
1201 msp3400c_setstereo(msp
,*sarg
);
1202 UNLOCK_I2C_BUS(msp
->bus
);
1207 LOCK_I2C_BUS(msp
->bus
);
1208 *sarg
= ((int)msp3400c_read(msp
->bus
, I2C_MSP3400C_DFP
, 0x1b) +
1209 (int)msp3400c_read(msp
->bus
, I2C_MSP3400C_DFP
, 0x1c));
1210 UNLOCK_I2C_BUS(msp
->bus
);
1219 /* ----------------------------------------------------------------------- */
1221 struct i2c_driver i2c_driver_msp
= {
1222 "msp3400", /* name */
1223 I2C_DRIVERID_MSP3400
, /* ID */
1224 I2C_MSP3400C
, I2C_MSP3400C
, /* addr range */
1232 int init_module(void)
1234 int msp3400c_init(void)
1237 i2c_register_driver(&i2c_driver_msp
);
1238 #ifdef REGISTER_MIXER
1239 if ((mixer_num
= register_sound_mixer(&msp3400c_mixer_fops
, -1)) < 0)
1240 printk(KERN_ERR
"msp3400c: cannot allocate mixer device\n");
1246 void cleanup_module(void)
1248 i2c_unregister_driver(&i2c_driver_msp
);
1249 #ifdef REGISTER_MIXER
1251 unregister_sound_mixer(mixer_num
);
1257 * Overrides for Emacs so that we follow Linus's tabbing style.
1258 * ---------------------------------------------------------------------------