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(¤t->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(¤t->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
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.