diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/msp3400.c | 642 |
1 files changed, 272 insertions, 370 deletions
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 39058d3b2e61..627c3110d3e3 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -158,8 +158,8 @@ static const int bl_dfp[] = { | |||
158 | 0x0b, 0x0d, 0x0e, 0x10 | 158 | 0x0b, 0x0d, 0x0e, 0x10 |
159 | }; | 159 | }; |
160 | 160 | ||
161 | #define HAVE_NICAM(state) (((state->rev2>>8) & 0xff) != 00) | 161 | #define HAVE_NICAM(state) (((state->rev2 >> 8) & 0xff) != 0) |
162 | #define HAVE_RADIO(state) ((state->rev1 & 0x0f) >= 'G'-'@') | 162 | #define HAVE_RADIO(state) ((state->rev1 & 0x0f) >= 'G'-'@') |
163 | 163 | ||
164 | struct msp_state { | 164 | struct msp_state { |
165 | int rev1, rev2; | 165 | int rev1, rev2; |
@@ -181,7 +181,7 @@ struct msp_state { | |||
181 | int rxsubchans; | 181 | int rxsubchans; |
182 | 182 | ||
183 | int muted; | 183 | int muted; |
184 | int left, right; /* volume */ | 184 | int volume, balance; |
185 | int bass, treble; | 185 | int bass, treble; |
186 | 186 | ||
187 | /* shadow register set */ | 187 | /* shadow register set */ |
@@ -217,9 +217,9 @@ static int msp_reset(struct i2c_client *client) | |||
217 | }; | 217 | }; |
218 | 218 | ||
219 | msp_dbg3("msp_reset\n"); | 219 | msp_dbg3("msp_reset\n"); |
220 | if (1 != i2c_transfer(client->adapter, &reset[0], 1) || | 220 | if (i2c_transfer(client->adapter, &reset[0], 1) != 1 || |
221 | 1 != i2c_transfer(client->adapter, &reset[1], 1) || | 221 | i2c_transfer(client->adapter, &reset[1], 1) != 1 || |
222 | 2 != i2c_transfer(client->adapter, test, 2)) { | 222 | i2c_transfer(client->adapter, test, 2) != 2) { |
223 | msp_err("chip reset failed\n"); | 223 | msp_err("chip reset failed\n"); |
224 | return -1; | 224 | return -1; |
225 | } | 225 | } |
@@ -241,14 +241,14 @@ static int msp_read(struct i2c_client *client, int dev, int addr) | |||
241 | write[2] = addr & 0xff; | 241 | write[2] = addr & 0xff; |
242 | 242 | ||
243 | for (err = 0; err < 3; err++) { | 243 | for (err = 0; err < 3; err++) { |
244 | if (2 == i2c_transfer(client->adapter, msgs, 2)) | 244 | if (i2c_transfer(client->adapter, msgs, 2) == 2) |
245 | break; | 245 | break; |
246 | msp_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err, | 246 | msp_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err, |
247 | dev, addr); | 247 | dev, addr); |
248 | current->state = TASK_INTERRUPTIBLE; | 248 | current->state = TASK_INTERRUPTIBLE; |
249 | schedule_timeout(msecs_to_jiffies(10)); | 249 | schedule_timeout(msecs_to_jiffies(10)); |
250 | } | 250 | } |
251 | if (3 == err) { | 251 | if (err == 3) { |
252 | msp_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n"); | 252 | msp_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n"); |
253 | msp_reset(client); | 253 | msp_reset(client); |
254 | return -1; | 254 | return -1; |
@@ -281,14 +281,14 @@ static int msp_write(struct i2c_client *client, int dev, int addr, int val) | |||
281 | 281 | ||
282 | msp_dbg3("msp_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); | 282 | msp_dbg3("msp_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); |
283 | for (err = 0; err < 3; err++) { | 283 | for (err = 0; err < 3; err++) { |
284 | if (5 == i2c_master_send(client, buffer, 5)) | 284 | if (i2c_master_send(client, buffer, 5) == 5) |
285 | break; | 285 | break; |
286 | msp_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err, | 286 | msp_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err, |
287 | dev, addr); | 287 | dev, addr); |
288 | current->state = TASK_INTERRUPTIBLE; | 288 | current->state = TASK_INTERRUPTIBLE; |
289 | schedule_timeout(msecs_to_jiffies(10)); | 289 | schedule_timeout(msecs_to_jiffies(10)); |
290 | } | 290 | } |
291 | if (3 == err) { | 291 | if (err == 3) { |
292 | msp_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n"); | 292 | msp_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n"); |
293 | msp_reset(client); | 293 | msp_reset(client); |
294 | return -1; | 294 | return -1; |
@@ -306,6 +306,70 @@ static inline int msp_write_dsp(struct i2c_client *client, int addr, int val) | |||
306 | return msp_write(client, I2C_MSP_DSP, addr, val); | 306 | return msp_write(client, I2C_MSP_DSP, addr, val); |
307 | } | 307 | } |
308 | 308 | ||
309 | /* ----------------------------------------------------------------------- * | ||
310 | * bits 9 8 5 - SCART DSP input Select: | ||
311 | * 0 0 0 - SCART 1 to DSP input (reset position) | ||
312 | * 0 1 0 - MONO to DSP input | ||
313 | * 1 0 0 - SCART 2 to DSP input | ||
314 | * 1 1 1 - Mute DSP input | ||
315 | * | ||
316 | * bits 11 10 6 - SCART 1 Output Select: | ||
317 | * 0 0 0 - undefined (reset position) | ||
318 | * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS) | ||
319 | * 1 0 0 - MONO input to SCART 1 Output | ||
320 | * 1 1 0 - SCART 1 DA to SCART 1 Output | ||
321 | * 0 0 1 - SCART 2 DA to SCART 1 Output | ||
322 | * 0 1 1 - SCART 1 Input to SCART 1 Output | ||
323 | * 1 1 1 - Mute SCART 1 Output | ||
324 | * | ||
325 | * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART): | ||
326 | * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position) | ||
327 | * 0 1 0 - SCART 1 Input to SCART 2 Output | ||
328 | * 1 0 0 - MONO input to SCART 2 Output | ||
329 | * 0 0 1 - SCART 2 DA to SCART 2 Output | ||
330 | * 0 1 1 - SCART 2 Input to SCART 2 Output | ||
331 | * 1 1 0 - Mute SCART 2 Output | ||
332 | * | ||
333 | * Bits 4 to 0 should be zero. | ||
334 | * ----------------------------------------------------------------------- */ | ||
335 | |||
336 | static int scarts[3][9] = { | ||
337 | /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ | ||
338 | /* SCART DSP Input select */ | ||
339 | { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, | ||
340 | /* SCART1 Output select */ | ||
341 | { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, | ||
342 | /* SCART2 Output select */ | ||
343 | { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, | ||
344 | }; | ||
345 | |||
346 | static char *scart_names[] = { | ||
347 | "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" | ||
348 | }; | ||
349 | |||
350 | static void msp_set_scart(struct i2c_client *client, int in, int out) | ||
351 | { | ||
352 | struct msp_state *state = i2c_get_clientdata(client); | ||
353 | |||
354 | state->in_scart=in; | ||
355 | |||
356 | if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { | ||
357 | if (-1 == scarts[out][in]) | ||
358 | return; | ||
359 | |||
360 | state->acb &= ~scarts[out][SCART_MASK]; | ||
361 | state->acb |= scarts[out][in]; | ||
362 | } else | ||
363 | state->acb = 0xf60; /* Mute Input and SCART 1 Output */ | ||
364 | |||
365 | msp_dbg1("scart switch: %s => %d (ACB=0x%04x)\n", | ||
366 | scart_names[in], out, state->acb); | ||
367 | msp_write_dsp(client, 0x13, state->acb); | ||
368 | |||
369 | /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ | ||
370 | msp_write_dem(client, 0x40, state->i2s_mode); | ||
371 | } | ||
372 | |||
309 | /* ------------------------------------------------------------------------ */ | 373 | /* ------------------------------------------------------------------------ */ |
310 | 374 | ||
311 | /* This macro is allowed for *constants* only, gcc must calculate it | 375 | /* This macro is allowed for *constants* only, gcc must calculate it |
@@ -322,7 +386,7 @@ static inline int msp_write_dsp(struct i2c_client *client, int addr, int val) | |||
322 | #define MSP_MODE_BTSC 8 | 386 | #define MSP_MODE_BTSC 8 |
323 | #define MSP_MODE_EXTERN 9 | 387 | #define MSP_MODE_EXTERN 9 |
324 | 388 | ||
325 | static struct MSP_INIT_DATA_DEM { | 389 | static struct msp3400c_init_data_dem { |
326 | int fir1[6]; | 390 | int fir1[6]; |
327 | int fir2[6]; | 391 | int fir2[6]; |
328 | int cdo1; | 392 | int cdo1; |
@@ -331,7 +395,7 @@ static struct MSP_INIT_DATA_DEM { | |||
331 | int mode_reg; | 395 | int mode_reg; |
332 | int dfp_src; | 396 | int dfp_src; |
333 | int dfp_matrix; | 397 | int dfp_matrix; |
334 | } msp_init_data[] = { | 398 | } msp3400c_init_data[] = { |
335 | { /* AM (for carrier detect / msp3400) */ | 399 | { /* AM (for carrier detect / msp3400) */ |
336 | {75, 19, 36, 35, 39, 40}, | 400 | {75, 19, 36, 35, 39, 40}, |
337 | {75, 19, 36, 35, 39, 40}, | 401 | {75, 19, 36, 35, 39, 40}, |
@@ -375,12 +439,12 @@ static struct MSP_INIT_DATA_DEM { | |||
375 | }, | 439 | }, |
376 | }; | 440 | }; |
377 | 441 | ||
378 | struct CARRIER_DETECT { | 442 | struct msp3400c_carrier_detect { |
379 | int cdo; | 443 | int cdo; |
380 | char *name; | 444 | char *name; |
381 | }; | 445 | }; |
382 | 446 | ||
383 | static struct CARRIER_DETECT carrier_detect_main[] = { | 447 | static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = { |
384 | /* main carrier */ | 448 | /* main carrier */ |
385 | { MSP_CARRIER(4.5), "4.5 NTSC" }, | 449 | { MSP_CARRIER(4.5), "4.5 NTSC" }, |
386 | { MSP_CARRIER(5.5), "5.5 PAL B/G" }, | 450 | { MSP_CARRIER(5.5), "5.5 PAL B/G" }, |
@@ -388,13 +452,13 @@ static struct CARRIER_DETECT carrier_detect_main[] = { | |||
388 | { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" } | 452 | { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" } |
389 | }; | 453 | }; |
390 | 454 | ||
391 | static struct CARRIER_DETECT carrier_detect_55[] = { | 455 | static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = { |
392 | /* PAL B/G */ | 456 | /* PAL B/G */ |
393 | { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" }, | 457 | { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" }, |
394 | { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" } | 458 | { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" } |
395 | }; | 459 | }; |
396 | 460 | ||
397 | static struct CARRIER_DETECT carrier_detect_65[] = { | 461 | static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = { |
398 | /* PAL SAT / SECAM */ | 462 | /* PAL SAT / SECAM */ |
399 | { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" }, | 463 | { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" }, |
400 | { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" }, | 464 | { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" }, |
@@ -404,72 +468,6 @@ static struct CARRIER_DETECT carrier_detect_65[] = { | |||
404 | { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" }, | 468 | { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" }, |
405 | }; | 469 | }; |
406 | 470 | ||
407 | #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) | ||
408 | |||
409 | /* ----------------------------------------------------------------------- * | ||
410 | * bits 9 8 5 - SCART DSP input Select: | ||
411 | * 0 0 0 - SCART 1 to DSP input (reset position) | ||
412 | * 0 1 0 - MONO to DSP input | ||
413 | * 1 0 0 - SCART 2 to DSP input | ||
414 | * 1 1 1 - Mute DSP input | ||
415 | * | ||
416 | * bits 11 10 6 - SCART 1 Output Select: | ||
417 | * 0 0 0 - undefined (reset position) | ||
418 | * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS) | ||
419 | * 1 0 0 - MONO input to SCART 1 Output | ||
420 | * 1 1 0 - SCART 1 DA to SCART 1 Output | ||
421 | * 0 0 1 - SCART 2 DA to SCART 1 Output | ||
422 | * 0 1 1 - SCART 1 Input to SCART 1 Output | ||
423 | * 1 1 1 - Mute SCART 1 Output | ||
424 | * | ||
425 | * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART): | ||
426 | * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position) | ||
427 | * 0 1 0 - SCART 1 Input to SCART 2 Output | ||
428 | * 1 0 0 - MONO input to SCART 2 Output | ||
429 | * 0 0 1 - SCART 2 DA to SCART 2 Output | ||
430 | * 0 1 1 - SCART 2 Input to SCART 2 Output | ||
431 | * 1 1 0 - Mute SCART 2 Output | ||
432 | * | ||
433 | * Bits 4 to 0 should be zero. | ||
434 | * ----------------------------------------------------------------------- */ | ||
435 | |||
436 | static int scarts[3][9] = { | ||
437 | /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ | ||
438 | /* SCART DSP Input select */ | ||
439 | { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, | ||
440 | /* SCART1 Output select */ | ||
441 | { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, | ||
442 | /* SCART2 Output select */ | ||
443 | { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, | ||
444 | }; | ||
445 | |||
446 | static char *scart_names[] = { | ||
447 | "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" | ||
448 | }; | ||
449 | |||
450 | static void msp_set_scart(struct i2c_client *client, int in, int out) | ||
451 | { | ||
452 | struct msp_state *state = i2c_get_clientdata(client); | ||
453 | |||
454 | state->in_scart=in; | ||
455 | |||
456 | if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { | ||
457 | if (-1 == scarts[out][in]) | ||
458 | return; | ||
459 | |||
460 | state->acb &= ~scarts[out][SCART_MASK]; | ||
461 | state->acb |= scarts[out][in]; | ||
462 | } else | ||
463 | state->acb = 0xf60; /* Mute Input and SCART 1 Output */ | ||
464 | |||
465 | msp_dbg1("scart switch: %s => %d (ACB=0x%04x)\n", | ||
466 | scart_names[in], out, state->acb); | ||
467 | msp_write_dsp(client, 0x13, state->acb); | ||
468 | |||
469 | /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ | ||
470 | msp_write_dem(client, 0x40, state->i2s_mode); | ||
471 | } | ||
472 | |||
473 | /* ------------------------------------------------------------------------ */ | 471 | /* ------------------------------------------------------------------------ */ |
474 | 472 | ||
475 | static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) | 473 | static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) |
@@ -481,42 +479,35 @@ static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) | |||
481 | msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ | 479 | msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ |
482 | } | 480 | } |
483 | 481 | ||
484 | static void msp_set_volume(struct i2c_client *client, | 482 | static void msp_set_mute(struct i2c_client *client) |
485 | int muted, int left, int right) | 483 | { |
486 | { | 484 | msp_dbg1("mute audio\n"); |
487 | int vol = 0, val = 0, balance = 0; | 485 | msp_write_dsp(client, 0x0000, 0); /* loudspeaker */ |
488 | 486 | msp_write_dsp(client, 0x0006, 0); /* headphones */ | |
489 | if (!muted) { | ||
490 | vol = (left > right) ? left : right; | ||
491 | val = (vol * 0x7f / 65535) << 8; | ||
492 | } | ||
493 | if (vol > 0) { | ||
494 | balance = ((right - left) * 127) / vol; | ||
495 | } | ||
496 | |||
497 | msp_dbg1("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", | ||
498 | muted ? "on" : "off", left, right, val >> 8, balance); | ||
499 | msp_write_dsp(client, 0x0000, val); /* loudspeaker */ | ||
500 | msp_write_dsp(client, 0x0006, val); /* headphones */ | ||
501 | msp_write_dsp(client, 0x0007, | ||
502 | muted ? 0x1 : (val | 0x1)); | ||
503 | msp_write_dsp(client, 0x0001, balance << 8); | ||
504 | } | 487 | } |
505 | 488 | ||
506 | static void msp_set_bass(struct i2c_client *client, int bass) | 489 | static void msp_set_audio(struct i2c_client *client) |
507 | { | 490 | { |
508 | int val = ((bass-32768) * 0x60 / 65535) << 8; | 491 | struct msp_state *state = i2c_get_clientdata(client); |
492 | int val = 0, bal = 0, bass, treble; | ||
509 | 493 | ||
510 | msp_dbg1("setbass: %d 0x%02x\n", bass, val >> 8); | 494 | if (!state->muted) |
511 | msp_write_dsp(client, 0x0002, val); /* loudspeaker */ | 495 | val = (state->volume * 0x7f / 65535) << 8; |
512 | } | 496 | if (val) |
497 | bal = (state->balance / 256) - 128; | ||
498 | bass = ((state->bass - 32768) * 0x60 / 65535) << 8; | ||
499 | treble = ((state->treble - 32768) * 0x60 / 65535) << 8; | ||
513 | 500 | ||
514 | static void msp_set_treble(struct i2c_client *client, int treble) | 501 | msp_dbg1("mute=%s volume=%d balance=%d bass=%d treble=%d\n", |
515 | { | 502 | state->muted ? "on" : "off", state->volume, state->balance, |
516 | int val = ((treble-32768) * 0x60 / 65535) << 8; | 503 | state->bass, state->treble); |
517 | 504 | ||
518 | msp_dbg1("settreble: %d 0x%02x\n",treble, val>>8); | 505 | msp_write_dsp(client, 0x0000, val); /* loudspeaker */ |
519 | msp_write_dsp(client, 0x0003, val); /* loudspeaker */ | 506 | msp_write_dsp(client, 0x0006, val); /* headphones */ |
507 | msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1)); | ||
508 | msp_write_dsp(client, 0x0001, bal << 8); | ||
509 | msp_write_dsp(client, 0x0002, bass); /* loudspeaker */ | ||
510 | msp_write_dsp(client, 0x0003, treble); /* loudspeaker */ | ||
520 | } | 511 | } |
521 | 512 | ||
522 | static void msp3400c_setmode(struct i2c_client *client, int type) | 513 | static void msp3400c_setmode(struct i2c_client *client, int type) |
@@ -530,24 +521,24 @@ static void msp3400c_setmode(struct i2c_client *client, int type) | |||
530 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | 521 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
531 | 522 | ||
532 | msp_write_dem(client, 0x00bb, /* ad_cv */ | 523 | msp_write_dem(client, 0x00bb, /* ad_cv */ |
533 | msp_init_data[type].ad_cv); | 524 | msp3400c_init_data[type].ad_cv); |
534 | 525 | ||
535 | for (i = 5; i >= 0; i--) /* fir 1 */ | 526 | for (i = 5; i >= 0; i--) /* fir 1 */ |
536 | msp_write_dem(client, 0x0001, | 527 | msp_write_dem(client, 0x0001, |
537 | msp_init_data[type].fir1[i]); | 528 | msp3400c_init_data[type].fir1[i]); |
538 | 529 | ||
539 | msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ | 530 | msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ |
540 | msp_write_dem(client, 0x0005, 0x0040); | 531 | msp_write_dem(client, 0x0005, 0x0040); |
541 | msp_write_dem(client, 0x0005, 0x0000); | 532 | msp_write_dem(client, 0x0005, 0x0000); |
542 | for (i = 5; i >= 0; i--) | 533 | for (i = 5; i >= 0; i--) |
543 | msp_write_dem(client, 0x0005, | 534 | msp_write_dem(client, 0x0005, |
544 | msp_init_data[type].fir2[i]); | 535 | msp3400c_init_data[type].fir2[i]); |
545 | 536 | ||
546 | msp_write_dem(client, 0x0083, /* MODE_REG */ | 537 | msp_write_dem(client, 0x0083, /* MODE_REG */ |
547 | msp_init_data[type].mode_reg); | 538 | msp3400c_init_data[type].mode_reg); |
548 | 539 | ||
549 | msp3400c_setcarrier(client, msp_init_data[type].cdo1, | 540 | msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1, |
550 | msp_init_data[type].cdo2); | 541 | msp3400c_init_data[type].cdo2); |
551 | 542 | ||
552 | msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ | 543 | msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ |
553 | 544 | ||
@@ -557,19 +548,19 @@ static void msp3400c_setmode(struct i2c_client *client, int type) | |||
557 | msp_write_dsp(client, 0x0009, | 548 | msp_write_dsp(client, 0x0009, |
558 | 0x0620); /* I2S2 */ | 549 | 0x0620); /* I2S2 */ |
559 | msp_write_dsp(client, 0x000b, | 550 | msp_write_dsp(client, 0x000b, |
560 | msp_init_data[type].dfp_src); | 551 | msp3400c_init_data[type].dfp_src); |
561 | } else { | 552 | } else { |
562 | msp_write_dsp(client, 0x0008, | 553 | msp_write_dsp(client, 0x0008, |
563 | msp_init_data[type].dfp_src); | 554 | msp3400c_init_data[type].dfp_src); |
564 | msp_write_dsp(client, 0x0009, | 555 | msp_write_dsp(client, 0x0009, |
565 | msp_init_data[type].dfp_src); | 556 | msp3400c_init_data[type].dfp_src); |
566 | msp_write_dsp(client, 0x000b, | 557 | msp_write_dsp(client, 0x000b, |
567 | msp_init_data[type].dfp_src); | 558 | msp3400c_init_data[type].dfp_src); |
568 | } | 559 | } |
569 | msp_write_dsp(client, 0x000a, | 560 | msp_write_dsp(client, 0x000a, |
570 | msp_init_data[type].dfp_src); | 561 | msp3400c_init_data[type].dfp_src); |
571 | msp_write_dsp(client, 0x000e, | 562 | msp_write_dsp(client, 0x000e, |
572 | msp_init_data[type].dfp_matrix); | 563 | msp3400c_init_data[type].dfp_matrix); |
573 | 564 | ||
574 | if (HAVE_NICAM(state)) { | 565 | if (HAVE_NICAM(state)) { |
575 | /* nicam prescale */ | 566 | /* nicam prescale */ |
@@ -701,8 +692,7 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode) | |||
701 | } | 692 | } |
702 | } | 693 | } |
703 | 694 | ||
704 | static void | 695 | static void msp3400c_print_mode(struct i2c_client *client) |
705 | msp3400c_print_mode(struct i2c_client *client) | ||
706 | { | 696 | { |
707 | struct msp_state *state = i2c_get_clientdata(client); | 697 | struct msp_state *state = i2c_get_clientdata(client); |
708 | 698 | ||
@@ -739,7 +729,7 @@ static void msp3400c_restore_dfp(struct i2c_client *client) | |||
739 | } | 729 | } |
740 | 730 | ||
741 | /* if the dfp_regs is set, set what's in there. Otherwise, set the default value */ | 731 | /* if the dfp_regs is set, set what's in there. Otherwise, set the default value */ |
742 | static int msp_write_dfp_with_default(struct i2c_client *client, | 732 | static int msp34xxg_write_dfp_with_default(struct i2c_client *client, |
743 | int addr, int default_value) | 733 | int addr, int default_value) |
744 | { | 734 | { |
745 | struct msp_state *state = i2c_get_clientdata(client); | 735 | struct msp_state *state = i2c_get_clientdata(client); |
@@ -751,19 +741,6 @@ static int msp_write_dfp_with_default(struct i2c_client *client, | |||
751 | 741 | ||
752 | /* ----------------------------------------------------------------------- */ | 742 | /* ----------------------------------------------------------------------- */ |
753 | 743 | ||
754 | struct REGISTER_DUMP { | ||
755 | int addr; | ||
756 | char *name; | ||
757 | }; | ||
758 | |||
759 | struct REGISTER_DUMP d1[] = { | ||
760 | {0x007e, "autodetect"}, | ||
761 | {0x0023, "C_AD_BITS "}, | ||
762 | {0x0038, "ADD_BITS "}, | ||
763 | {0x003e, "CIB_BITS "}, | ||
764 | {0x0057, "ERROR_RATE"}, | ||
765 | }; | ||
766 | |||
767 | static int autodetect_stereo(struct i2c_client *client) | 744 | static int autodetect_stereo(struct i2c_client *client) |
768 | { | 745 | { |
769 | struct msp_state *state = i2c_get_clientdata(client); | 746 | struct msp_state *state = i2c_get_clientdata(client); |
@@ -899,7 +876,7 @@ static int msp3400c_thread(void *data) | |||
899 | { | 876 | { |
900 | struct i2c_client *client = data; | 877 | struct i2c_client *client = data; |
901 | struct msp_state *state = i2c_get_clientdata(client); | 878 | struct msp_state *state = i2c_get_clientdata(client); |
902 | struct CARRIER_DETECT *cd; | 879 | struct msp3400c_carrier_detect *cd; |
903 | int count, max1,max2,val1,val2, val,this; | 880 | int count, max1,max2,val1,val2, val,this; |
904 | 881 | ||
905 | 882 | ||
@@ -919,12 +896,12 @@ static int msp3400c_thread(void *data) | |||
919 | MSP_MODE_EXTERN == state->mode) { | 896 | MSP_MODE_EXTERN == state->mode) { |
920 | /* no carrier scan, just unmute */ | 897 | /* no carrier scan, just unmute */ |
921 | msp_info("thread: no carrier scan\n"); | 898 | msp_info("thread: no carrier scan\n"); |
922 | msp_set_volume(client, state->muted, state->left, state->right); | 899 | msp_set_audio(client); |
923 | continue; | 900 | continue; |
924 | } | 901 | } |
925 | 902 | ||
926 | /* mute */ | 903 | /* mute */ |
927 | msp_set_volume(client, state->muted, 0, 0); | 904 | msp_set_mute(client); |
928 | msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); | 905 | msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); |
929 | val1 = val2 = 0; | 906 | val1 = val2 = 0; |
930 | max1 = max2 = -1; | 907 | max1 = max2 = -1; |
@@ -935,8 +912,8 @@ static int msp3400c_thread(void *data) | |||
935 | goto restart; | 912 | goto restart; |
936 | 913 | ||
937 | /* carrier detect pass #1 -- main carrier */ | 914 | /* carrier detect pass #1 -- main carrier */ |
938 | cd = carrier_detect_main; | 915 | cd = msp3400c_carrier_detect_main; |
939 | count = CARRIER_COUNT(carrier_detect_main); | 916 | count = ARRAY_SIZE(msp3400c_carrier_detect_main); |
940 | 917 | ||
941 | if (amsound && (state->norm == VIDEO_MODE_SECAM)) { | 918 | if (amsound && (state->norm == VIDEO_MODE_SECAM)) { |
942 | /* autodetect doesn't work well with AM ... */ | 919 | /* autodetect doesn't work well with AM ... */ |
@@ -960,12 +937,12 @@ static int msp3400c_thread(void *data) | |||
960 | /* carrier detect pass #2 -- second (stereo) carrier */ | 937 | /* carrier detect pass #2 -- second (stereo) carrier */ |
961 | switch (max1) { | 938 | switch (max1) { |
962 | case 1: /* 5.5 */ | 939 | case 1: /* 5.5 */ |
963 | cd = carrier_detect_55; | 940 | cd = msp3400c_carrier_detect_55; |
964 | count = CARRIER_COUNT(carrier_detect_55); | 941 | count = ARRAY_SIZE(msp3400c_carrier_detect_55); |
965 | break; | 942 | break; |
966 | case 3: /* 6.5 */ | 943 | case 3: /* 6.5 */ |
967 | cd = carrier_detect_65; | 944 | cd = msp3400c_carrier_detect_65; |
968 | count = CARRIER_COUNT(carrier_detect_65); | 945 | count = ARRAY_SIZE(msp3400c_carrier_detect_65); |
969 | break; | 946 | break; |
970 | case 0: /* 4.5 */ | 947 | case 0: /* 4.5 */ |
971 | case 2: /* 6.0 */ | 948 | case 2: /* 6.0 */ |
@@ -994,19 +971,19 @@ static int msp3400c_thread(void *data) | |||
994 | } | 971 | } |
995 | 972 | ||
996 | /* program the msp3400 according to the results */ | 973 | /* program the msp3400 according to the results */ |
997 | state->main = carrier_detect_main[max1].cdo; | 974 | state->main = msp3400c_carrier_detect_main[max1].cdo; |
998 | switch (max1) { | 975 | switch (max1) { |
999 | case 1: /* 5.5 */ | 976 | case 1: /* 5.5 */ |
1000 | if (max2 == 0) { | 977 | if (max2 == 0) { |
1001 | /* B/G FM-stereo */ | 978 | /* B/G FM-stereo */ |
1002 | state->second = carrier_detect_55[max2].cdo; | 979 | state->second = msp3400c_carrier_detect_55[max2].cdo; |
1003 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 980 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); |
1004 | state->nicam_on = 0; | 981 | state->nicam_on = 0; |
1005 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | 982 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
1006 | state->watch_stereo = 1; | 983 | state->watch_stereo = 1; |
1007 | } else if (max2 == 1 && HAVE_NICAM(state)) { | 984 | } else if (max2 == 1 && HAVE_NICAM(state)) { |
1008 | /* B/G NICAM */ | 985 | /* B/G NICAM */ |
1009 | state->second = carrier_detect_55[max2].cdo; | 986 | state->second = msp3400c_carrier_detect_55[max2].cdo; |
1010 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); | 987 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); |
1011 | state->nicam_on = 1; | 988 | state->nicam_on = 1; |
1012 | msp3400c_setcarrier(client, state->second, state->main); | 989 | msp3400c_setcarrier(client, state->second, state->main); |
@@ -1026,7 +1003,7 @@ static int msp3400c_thread(void *data) | |||
1026 | case 3: /* 6.5 */ | 1003 | case 3: /* 6.5 */ |
1027 | if (max2 == 1 || max2 == 2) { | 1004 | if (max2 == 1 || max2 == 2) { |
1028 | /* D/K FM-stereo */ | 1005 | /* D/K FM-stereo */ |
1029 | state->second = carrier_detect_65[max2].cdo; | 1006 | state->second = msp3400c_carrier_detect_65[max2].cdo; |
1030 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 1007 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); |
1031 | state->nicam_on = 0; | 1008 | state->nicam_on = 0; |
1032 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | 1009 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
@@ -1034,7 +1011,7 @@ static int msp3400c_thread(void *data) | |||
1034 | } else if (max2 == 0 && | 1011 | } else if (max2 == 0 && |
1035 | state->norm == VIDEO_MODE_SECAM) { | 1012 | state->norm == VIDEO_MODE_SECAM) { |
1036 | /* L NICAM or AM-mono */ | 1013 | /* L NICAM or AM-mono */ |
1037 | state->second = carrier_detect_65[max2].cdo; | 1014 | state->second = msp3400c_carrier_detect_65[max2].cdo; |
1038 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); | 1015 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); |
1039 | state->nicam_on = 0; | 1016 | state->nicam_on = 0; |
1040 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | 1017 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
@@ -1044,7 +1021,7 @@ static int msp3400c_thread(void *data) | |||
1044 | state->watch_stereo = 1; | 1021 | state->watch_stereo = 1; |
1045 | } else if (max2 == 0 && HAVE_NICAM(state)) { | 1022 | } else if (max2 == 0 && HAVE_NICAM(state)) { |
1046 | /* D/K NICAM */ | 1023 | /* D/K NICAM */ |
1047 | state->second = carrier_detect_65[max2].cdo; | 1024 | state->second = msp3400c_carrier_detect_65[max2].cdo; |
1048 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); | 1025 | msp3400c_setmode(client, MSP_MODE_FM_NICAM1); |
1049 | state->nicam_on = 1; | 1026 | state->nicam_on = 1; |
1050 | msp3400c_setcarrier(client, state->second, state->main); | 1027 | msp3400c_setcarrier(client, state->second, state->main); |
@@ -1056,7 +1033,7 @@ static int msp3400c_thread(void *data) | |||
1056 | case 0: /* 4.5 */ | 1033 | case 0: /* 4.5 */ |
1057 | default: | 1034 | default: |
1058 | no_second: | 1035 | no_second: |
1059 | state->second = carrier_detect_main[max1].cdo; | 1036 | state->second = msp3400c_carrier_detect_main[max1].cdo; |
1060 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 1037 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); |
1061 | state->nicam_on = 0; | 1038 | state->nicam_on = 0; |
1062 | msp3400c_setcarrier(client, state->second, state->main); | 1039 | msp3400c_setcarrier(client, state->second, state->main); |
@@ -1066,7 +1043,7 @@ static int msp3400c_thread(void *data) | |||
1066 | } | 1043 | } |
1067 | 1044 | ||
1068 | /* unmute */ | 1045 | /* unmute */ |
1069 | msp_set_volume(client, state->muted, state->left, state->right); | 1046 | msp_set_audio(client); |
1070 | msp3400c_restore_dfp(client); | 1047 | msp3400c_restore_dfp(client); |
1071 | 1048 | ||
1072 | if (debug) | 1049 | if (debug) |
@@ -1191,7 +1168,7 @@ static int msp3410d_thread(void *data) | |||
1191 | if (state->mode == MSP_MODE_EXTERN) { | 1168 | if (state->mode == MSP_MODE_EXTERN) { |
1192 | /* no carrier scan needed, just unmute */ | 1169 | /* no carrier scan needed, just unmute */ |
1193 | msp_dbg1("thread: no carrier scan\n"); | 1170 | msp_dbg1("thread: no carrier scan\n"); |
1194 | msp_set_volume(client, state->muted, state->left, state->right); | 1171 | msp_set_audio(client); |
1195 | continue; | 1172 | continue; |
1196 | } | 1173 | } |
1197 | 1174 | ||
@@ -1311,9 +1288,7 @@ static int msp3410d_thread(void *data) | |||
1311 | } | 1288 | } |
1312 | 1289 | ||
1313 | /* unmute, restore misc registers */ | 1290 | /* unmute, restore misc registers */ |
1314 | msp_set_bass(client, state->bass); | 1291 | msp_set_audio(client); |
1315 | msp_set_treble(client, state->treble); | ||
1316 | msp_set_volume(client, state->muted, state->left, state->right); | ||
1317 | msp_write_dsp(client, 0x13, state->acb); | 1292 | msp_write_dsp(client, 0x13, state->acb); |
1318 | msp_write_dem(client, 0x40, state->i2s_mode); | 1293 | msp_write_dem(client, 0x40, state->i2s_mode); |
1319 | msp3400c_restore_dfp(client); | 1294 | msp3400c_restore_dfp(client); |
@@ -1335,7 +1310,40 @@ static int msp3410d_thread(void *data) | |||
1335 | /* select which are available in the newer G versions */ | 1310 | /* select which are available in the newer G versions */ |
1336 | /* struct msp: only norm, acb and source are really used in this mode */ | 1311 | /* struct msp: only norm, acb and source are really used in this mode */ |
1337 | 1312 | ||
1338 | static void msp34xxg_set_source(struct i2c_client *client, int source); | 1313 | /* set the same 'source' for the loudspeaker, scart and quasi-peak detector |
1314 | * the value for source is the same as bit 15:8 of DFP registers 0x08, | ||
1315 | * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B | ||
1316 | * | ||
1317 | * this function replaces msp3400c_setstereo | ||
1318 | */ | ||
1319 | static void msp34xxg_set_source(struct i2c_client *client, int source) | ||
1320 | { | ||
1321 | struct msp_state *state = i2c_get_clientdata(client); | ||
1322 | |||
1323 | /* fix matrix mode to stereo and let the msp choose what | ||
1324 | * to output according to 'source', as recommended | ||
1325 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | ||
1326 | */ | ||
1327 | int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20); | ||
1328 | |||
1329 | msp_dbg1("set source to %d (0x%x)\n", source, value); | ||
1330 | /* Loudspeaker Output */ | ||
1331 | msp_write_dsp(client, 0x08, value); | ||
1332 | /* SCART1 DA Output */ | ||
1333 | msp_write_dsp(client, 0x0a, value); | ||
1334 | /* Quasi-peak detector */ | ||
1335 | msp_write_dsp(client, 0x0c, value); | ||
1336 | /* | ||
1337 | * set identification threshold. Personally, I | ||
1338 | * I set it to a higher value that the default | ||
1339 | * of 0x190 to ignore noisy stereo signals. | ||
1340 | * this needs tuning. (recommended range 0x00a0-0x03c0) | ||
1341 | * 0x7f0 = forced mono mode | ||
1342 | */ | ||
1343 | /* a2 threshold for stereo/bilingual */ | ||
1344 | msp_write_dem(client, 0x22, stereo_threshold); | ||
1345 | state->source = source; | ||
1346 | } | ||
1339 | 1347 | ||
1340 | /* (re-)initialize the msp34xxg, according to the current norm in state->norm | 1348 | /* (re-)initialize the msp34xxg, according to the current norm in state->norm |
1341 | * return 0 if it worked, -1 if it failed | 1349 | * return 0 if it worked, -1 if it failed |
@@ -1343,15 +1351,14 @@ static void msp34xxg_set_source(struct i2c_client *client, int source); | |||
1343 | static int msp34xxg_reset(struct i2c_client *client) | 1351 | static int msp34xxg_reset(struct i2c_client *client) |
1344 | { | 1352 | { |
1345 | struct msp_state *state = i2c_get_clientdata(client); | 1353 | struct msp_state *state = i2c_get_clientdata(client); |
1346 | int modus,std; | 1354 | int modus, std; |
1347 | 1355 | ||
1348 | if (msp_reset(client)) | 1356 | if (msp_reset(client)) |
1349 | return -1; | 1357 | return -1; |
1350 | 1358 | ||
1351 | /* make sure that input/output is muted (paranoid mode) */ | 1359 | /* make sure that input/output is muted (paranoid mode) */ |
1352 | if (msp_write_dsp(client, | 1360 | /* ACB, mute DSP input, mute SCART 1 */ |
1353 | 0x13, /* ACB */ | 1361 | if (msp_write_dsp(client, 0x13, 0x0f20)) |
1354 | 0x0f20 /* mute DSP input, mute SCART 1 */)) | ||
1355 | return -1; | 1362 | return -1; |
1356 | 1363 | ||
1357 | msp_write_dem(client, 0x40, state->i2s_mode); | 1364 | msp_write_dem(client, 0x40, state->i2s_mode); |
@@ -1359,27 +1366,23 @@ static int msp34xxg_reset(struct i2c_client *client) | |||
1359 | /* step-by-step initialisation, as described in the manual */ | 1366 | /* step-by-step initialisation, as described in the manual */ |
1360 | modus = msp_modus(client, state->norm); | 1367 | modus = msp_modus(client, state->norm); |
1361 | std = msp_standard(state->norm); | 1368 | std = msp_standard(state->norm); |
1362 | modus &= ~0x03; /* STATUS_CHANGE=0 */ | 1369 | modus &= ~0x03; /* STATUS_CHANGE = 0 */ |
1363 | modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ | 1370 | modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION = 1 */ |
1364 | if (msp_write_dem(client, 0x30/*MODUS*/, modus)) | 1371 | if (msp_write_dem(client, 0x30, modus)) |
1365 | return -1; | 1372 | return -1; |
1366 | if (msp_write_dem(client, 0x20/*standard*/, std)) | 1373 | if (msp_write_dem(client, 0x20, std)) |
1367 | return -1; | 1374 | return -1; |
1368 | 1375 | ||
1369 | /* write the dfps that may have an influence on | 1376 | /* write the dfps that may have an influence on |
1370 | standard/audio autodetection right now */ | 1377 | standard/audio autodetection right now */ |
1371 | msp34xxg_set_source(client, state->source); | 1378 | msp34xxg_set_source(client, state->source); |
1372 | 1379 | ||
1373 | if (msp_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */ | 1380 | /* AM/FM Prescale, default: [15:8] 75khz deviation */ |
1374 | 0x3000 | 1381 | if (msp34xxg_write_dfp_with_default(client, 0x0e, 0x3000)) |
1375 | /* default: [15:8] 75khz deviation */ | ||
1376 | )) | ||
1377 | return -1; | 1382 | return -1; |
1378 | 1383 | ||
1379 | if (msp_write_dfp_with_default(client, 0x10, /* NICAM Prescale */ | 1384 | /* NICAM Prescale, default: 9db gain (as recommended) */ |
1380 | 0x5a00 | 1385 | if (msp34xxg_write_dfp_with_default(client, 0x10, 0x5a00)) |
1381 | /* default: 9db gain (as recommended) */ | ||
1382 | )) | ||
1383 | return -1; | 1386 | return -1; |
1384 | 1387 | ||
1385 | return 0; | 1388 | return 0; |
@@ -1396,7 +1399,7 @@ static int msp34xxg_thread(void *data) | |||
1396 | state->source = 1; /* default */ | 1399 | state->source = 1; /* default */ |
1397 | for (;;) { | 1400 | for (;;) { |
1398 | msp_dbg2("msp34xxg thread: sleep\n"); | 1401 | msp_dbg2("msp34xxg thread: sleep\n"); |
1399 | msp_sleep(state,-1); | 1402 | msp_sleep(state, -1); |
1400 | msp_dbg2("msp34xxg thread: wakeup\n"); | 1403 | msp_dbg2("msp34xxg thread: wakeup\n"); |
1401 | 1404 | ||
1402 | restart: | 1405 | restart: |
@@ -1414,7 +1417,7 @@ static int msp34xxg_thread(void *data) | |||
1414 | /* watch autodetect */ | 1417 | /* watch autodetect */ |
1415 | msp_dbg1("triggered autodetect, waiting for result\n"); | 1418 | msp_dbg1("triggered autodetect, waiting for result\n"); |
1416 | for (i = 0; i < 10; i++) { | 1419 | for (i = 0; i < 10; i++) { |
1417 | if (msp_sleep(state,100)) | 1420 | if (msp_sleep(state, 100)) |
1418 | goto restart; | 1421 | goto restart; |
1419 | 1422 | ||
1420 | /* check results */ | 1423 | /* check results */ |
@@ -1425,7 +1428,7 @@ static int msp34xxg_thread(void *data) | |||
1425 | } | 1428 | } |
1426 | msp_dbg1("detection still in progress\n"); | 1429 | msp_dbg1("detection still in progress\n"); |
1427 | } | 1430 | } |
1428 | if (0x01 == std) { | 1431 | if (std == 1) { |
1429 | msp_dbg1("detection still in progress after 10 tries. giving up.\n"); | 1432 | msp_dbg1("detection still in progress after 10 tries. giving up.\n"); |
1430 | continue; | 1433 | continue; |
1431 | } | 1434 | } |
@@ -1436,11 +1439,7 @@ static int msp34xxg_thread(void *data) | |||
1436 | msp_standard_mode_name(std), std); | 1439 | msp_standard_mode_name(std), std); |
1437 | 1440 | ||
1438 | /* unmute: dispatch sound to scart output, set scart volume */ | 1441 | /* unmute: dispatch sound to scart output, set scart volume */ |
1439 | msp_dbg1("unmute\n"); | 1442 | msp_set_audio(client); |
1440 | |||
1441 | msp_set_bass(client, state->bass); | ||
1442 | msp_set_treble(client, state->treble); | ||
1443 | msp_set_volume(client, state->muted, state->left, state->right); | ||
1444 | 1443 | ||
1445 | /* restore ACB */ | 1444 | /* restore ACB */ |
1446 | if (msp_write_dsp(client, 0x13, state->acb)) | 1445 | if (msp_write_dsp(client, 0x13, state->acb)) |
@@ -1452,52 +1451,13 @@ static int msp34xxg_thread(void *data) | |||
1452 | return 0; | 1451 | return 0; |
1453 | } | 1452 | } |
1454 | 1453 | ||
1455 | /* set the same 'source' for the loudspeaker, scart and quasi-peak detector | ||
1456 | * the value for source is the same as bit 15:8 of DFP registers 0x08, | ||
1457 | * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B | ||
1458 | * | ||
1459 | * this function replaces msp3400c_setstereo | ||
1460 | */ | ||
1461 | static void msp34xxg_set_source(struct i2c_client *client, int source) | ||
1462 | { | ||
1463 | struct msp_state *state = i2c_get_clientdata(client); | ||
1464 | |||
1465 | /* fix matrix mode to stereo and let the msp choose what | ||
1466 | * to output according to 'source', as recommended | ||
1467 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | ||
1468 | */ | ||
1469 | int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); | ||
1470 | msp_dbg1("set source to %d (0x%x)\n", source, value); | ||
1471 | msp_write_dsp(client, | ||
1472 | 0x08, /* Loudspeaker Output */ | ||
1473 | value); | ||
1474 | msp_write_dsp(client, | ||
1475 | 0x0a, /* SCART1 DA Output */ | ||
1476 | value); | ||
1477 | msp_write_dsp(client, | ||
1478 | 0x0c, /* Quasi-peak detector */ | ||
1479 | value); | ||
1480 | /* | ||
1481 | * set identification threshold. Personally, I | ||
1482 | * I set it to a higher value that the default | ||
1483 | * of 0x190 to ignore noisy stereo signals. | ||
1484 | * this needs tuning. (recommended range 0x00a0-0x03c0) | ||
1485 | * 0x7f0 = forced mono mode | ||
1486 | */ | ||
1487 | msp_write_dem(client, | ||
1488 | 0x22, /* a2 threshold for stereo/bilingual */ | ||
1489 | stereo_threshold); | ||
1490 | state->source=source; | ||
1491 | } | ||
1492 | |||
1493 | static void msp34xxg_detect_stereo(struct i2c_client *client) | 1454 | static void msp34xxg_detect_stereo(struct i2c_client *client) |
1494 | { | 1455 | { |
1495 | struct msp_state *state = i2c_get_clientdata(client); | 1456 | struct msp_state *state = i2c_get_clientdata(client); |
1496 | 1457 | ||
1497 | int status = msp_read_dem(client, | 1458 | int status = msp_read_dem(client, 0x0200); |
1498 | 0x0200 /* STATUS */); | 1459 | int is_bilingual = status & 0x100; |
1499 | int is_bilingual = status&0x100; | 1460 | int is_stereo = status & 0x40; |
1500 | int is_stereo = status&0x40; | ||
1501 | 1461 | ||
1502 | state->rxsubchans = 0; | 1462 | state->rxsubchans = 0; |
1503 | if (is_stereo) | 1463 | if (is_stereo) |
@@ -1505,7 +1465,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client) | |||
1505 | else | 1465 | else |
1506 | state->rxsubchans |= V4L2_TUNER_SUB_MONO; | 1466 | state->rxsubchans |= V4L2_TUNER_SUB_MONO; |
1507 | if (is_bilingual) { | 1467 | if (is_bilingual) { |
1508 | state->rxsubchans |= V4L2_TUNER_SUB_LANG1|V4L2_TUNER_SUB_LANG2; | 1468 | state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; |
1509 | /* I'm supposed to check whether it's SAP or not | 1469 | /* I'm supposed to check whether it's SAP or not |
1510 | * and set only LANG2/SAP in this case. Yet, the MSP | 1470 | * and set only LANG2/SAP in this case. Yet, the MSP |
1511 | * does a lot of work to hide this and handle everything | 1471 | * does a lot of work to hide this and handle everything |
@@ -1524,17 +1484,17 @@ static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | |||
1524 | 1484 | ||
1525 | switch (audmode) { | 1485 | switch (audmode) { |
1526 | case V4L2_TUNER_MODE_MONO: | 1486 | case V4L2_TUNER_MODE_MONO: |
1527 | source=0; /* mono only */ | 1487 | source = 0; /* mono only */ |
1528 | break; | 1488 | break; |
1529 | case V4L2_TUNER_MODE_STEREO: | 1489 | case V4L2_TUNER_MODE_STEREO: |
1530 | source=1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */ | 1490 | source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */ |
1531 | /* problem: that could also mean 2 (scart input) */ | 1491 | /* problem: that could also mean 2 (scart input) */ |
1532 | break; | 1492 | break; |
1533 | case V4L2_TUNER_MODE_LANG1: | 1493 | case V4L2_TUNER_MODE_LANG1: |
1534 | source=3; /* stereo or A */ | 1494 | source = 3; /* stereo or A */ |
1535 | break; | 1495 | break; |
1536 | case V4L2_TUNER_MODE_LANG2: | 1496 | case V4L2_TUNER_MODE_LANG2: |
1537 | source=4; /* stereo or B */ | 1497 | source = 4; /* stereo or B */ |
1538 | break; | 1498 | break; |
1539 | default: | 1499 | default: |
1540 | audmode = 0; | 1500 | audmode = 0; |
@@ -1550,11 +1510,11 @@ static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | |||
1550 | 1510 | ||
1551 | static void msp_wake_thread(struct i2c_client *client) | 1511 | static void msp_wake_thread(struct i2c_client *client) |
1552 | { | 1512 | { |
1553 | struct msp_state *state = i2c_get_clientdata(client); | 1513 | struct msp_state *state = i2c_get_clientdata(client); |
1554 | 1514 | ||
1555 | if (NULL == state->kthread) | 1515 | if (NULL == state->kthread) |
1556 | return; | 1516 | return; |
1557 | msp_set_volume(client,state->muted,0,0); | 1517 | msp_set_mute(client); |
1558 | state->watch_stereo = 0; | 1518 | state->watch_stereo = 0; |
1559 | state->restart = 1; | 1519 | state->restart = 1; |
1560 | wake_up_interruptible(&state->wq); | 1520 | wake_up_interruptible(&state->wq); |
@@ -1572,7 +1532,7 @@ static int mode_v4l2_to_v4l1(int rxsubchans) | |||
1572 | mode |= VIDEO_SOUND_LANG2; | 1532 | mode |= VIDEO_SOUND_LANG2; |
1573 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) | 1533 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) |
1574 | mode |= VIDEO_SOUND_LANG1; | 1534 | mode |= VIDEO_SOUND_LANG1; |
1575 | if (0 == mode) | 1535 | if (mode == 0) |
1576 | mode |= VIDEO_SOUND_MONO; | 1536 | mode |= VIDEO_SOUND_MONO; |
1577 | return mode; | 1537 | return mode; |
1578 | } | 1538 | } |
@@ -1644,7 +1604,7 @@ static struct v4l2_queryctrl msp_qctrl[] = { | |||
1644 | 1604 | ||
1645 | static void msp_any_set_audmode(struct i2c_client *client, int audmode) | 1605 | static void msp_any_set_audmode(struct i2c_client *client, int audmode) |
1646 | { | 1606 | { |
1647 | struct msp_state *state = i2c_get_clientdata(client); | 1607 | struct msp_state *state = i2c_get_clientdata(client); |
1648 | 1608 | ||
1649 | switch (state->opmode) { | 1609 | switch (state->opmode) { |
1650 | case OPMODE_MANUAL: | 1610 | case OPMODE_MANUAL: |
@@ -1660,94 +1620,68 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode) | |||
1660 | 1620 | ||
1661 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | 1621 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) |
1662 | { | 1622 | { |
1663 | struct msp_state *state = i2c_get_clientdata(client); | 1623 | struct msp_state *state = i2c_get_clientdata(client); |
1664 | 1624 | ||
1665 | switch (ctrl->id) { | 1625 | switch (ctrl->id) { |
1666 | case V4L2_CID_AUDIO_MUTE: | 1626 | case V4L2_CID_AUDIO_MUTE: |
1667 | ctrl->value = state->muted; | 1627 | ctrl->value = state->muted; |
1668 | return 0; | 1628 | break; |
1629 | |||
1669 | case V4L2_CID_AUDIO_BALANCE: | 1630 | case V4L2_CID_AUDIO_BALANCE: |
1670 | { | 1631 | ctrl->value = state->balance; |
1671 | int volume = max(state->left, state->right); | 1632 | break; |
1672 | 1633 | ||
1673 | ctrl->value = (32768 * min(state->left, state->right)) / | ||
1674 | (volume ? volume : 1); | ||
1675 | ctrl->value = (state->left < state->right) ? | ||
1676 | (65535 - ctrl->value) : ctrl->value; | ||
1677 | if (0 == volume) | ||
1678 | ctrl->value = 32768; | ||
1679 | return 0; | ||
1680 | } | ||
1681 | case V4L2_CID_AUDIO_BASS: | 1634 | case V4L2_CID_AUDIO_BASS: |
1682 | ctrl->value = state->bass; | 1635 | ctrl->value = state->bass; |
1683 | return 0; | 1636 | break; |
1637 | |||
1684 | case V4L2_CID_AUDIO_TREBLE: | 1638 | case V4L2_CID_AUDIO_TREBLE: |
1685 | ctrl->value = state->treble; | 1639 | ctrl->value = state->treble; |
1686 | return 0; | 1640 | break; |
1641 | |||
1687 | case V4L2_CID_AUDIO_VOLUME: | 1642 | case V4L2_CID_AUDIO_VOLUME: |
1688 | ctrl->value = max(state->left, state->right); | 1643 | ctrl->value = state->volume; |
1689 | return 0; | 1644 | break; |
1645 | |||
1690 | default: | 1646 | default: |
1691 | return -EINVAL; | 1647 | return -EINVAL; |
1692 | } | 1648 | } |
1649 | return 0; | ||
1693 | } | 1650 | } |
1694 | 1651 | ||
1695 | static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | 1652 | static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) |
1696 | { | 1653 | { |
1697 | struct msp_state *state = i2c_get_clientdata(client); | 1654 | struct msp_state *state = i2c_get_clientdata(client); |
1698 | int set_volume = 0, balance, volume; | ||
1699 | 1655 | ||
1700 | switch (ctrl->id) { | 1656 | switch (ctrl->id) { |
1701 | case V4L2_CID_AUDIO_MUTE: | 1657 | case V4L2_CID_AUDIO_MUTE: |
1702 | if (ctrl->value < 0 || ctrl->value >= 2) | 1658 | if (ctrl->value < 0 || ctrl->value >= 2) |
1703 | return -ERANGE; | 1659 | return -ERANGE; |
1704 | state->muted = ctrl->value; | 1660 | state->muted = ctrl->value; |
1705 | msp_set_volume(client, state->muted, state->left, state->right); | ||
1706 | return 0; | ||
1707 | |||
1708 | case V4L2_CID_AUDIO_BALANCE: | ||
1709 | balance = ctrl->value; | ||
1710 | volume = max(state->left, state->right); | ||
1711 | set_volume = 1; | ||
1712 | break; | 1661 | break; |
1713 | 1662 | ||
1714 | case V4L2_CID_AUDIO_BASS: | 1663 | case V4L2_CID_AUDIO_BASS: |
1715 | state->bass = ctrl->value; | 1664 | state->bass = ctrl->value; |
1716 | msp_set_bass(client, state->bass); | 1665 | break; |
1717 | return 0; | ||
1718 | 1666 | ||
1719 | case V4L2_CID_AUDIO_TREBLE: | 1667 | case V4L2_CID_AUDIO_TREBLE: |
1720 | state->treble = ctrl->value; | 1668 | state->treble = ctrl->value; |
1721 | msp_set_treble(client, state->treble); | 1669 | break; |
1722 | return 0; | ||
1723 | |||
1724 | case V4L2_CID_AUDIO_VOLUME: | ||
1725 | volume = max(state->left, state->right); | ||
1726 | 1670 | ||
1727 | balance = (32768 * min(state->left, state->right)) / | 1671 | case V4L2_CID_AUDIO_BALANCE: |
1728 | (volume ? volume : 1); | 1672 | state->balance = ctrl->value; |
1729 | balance = (state->left < state->right) ? | 1673 | break; |
1730 | (65535 - balance) : balance; | ||
1731 | if (volume == 0) | ||
1732 | balance = 32768; | ||
1733 | 1674 | ||
1734 | volume = ctrl->value; | 1675 | case V4L2_CID_AUDIO_VOLUME: |
1735 | set_volume = 1; | 1676 | state->volume = ctrl->value; |
1677 | if (state->volume == 0) | ||
1678 | state->balance = 32768; | ||
1736 | break; | 1679 | break; |
1737 | 1680 | ||
1738 | default: | 1681 | default: |
1739 | return -EINVAL; | 1682 | return -EINVAL; |
1740 | } | 1683 | } |
1741 | 1684 | msp_set_audio(client); | |
1742 | if (set_volume) { | ||
1743 | state->left = (min(65536 - balance, 32768) * volume) / 32768; | ||
1744 | state->right = (min(balance, 32768) * volume) / 32768; | ||
1745 | |||
1746 | msp_dbg2("volume=%d, balance=%d, left=%d, right=%d", | ||
1747 | volume, balance, state->left, state->right); | ||
1748 | |||
1749 | msp_set_volume(client, state->muted, state->left, state->right); | ||
1750 | } | ||
1751 | return 0; | 1685 | return 0; |
1752 | } | 1686 | } |
1753 | 1687 | ||
@@ -1757,10 +1691,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1757 | u16 *sarg = arg; | 1691 | u16 *sarg = arg; |
1758 | int scart = 0; | 1692 | int scart = 0; |
1759 | 1693 | ||
1694 | if (debug >= 2) | ||
1695 | v4l_i2c_print_ioctl(client, cmd); | ||
1696 | |||
1760 | switch (cmd) { | 1697 | switch (cmd) { |
1761 | case AUDC_SET_INPUT: | 1698 | case AUDC_SET_INPUT: |
1762 | msp_dbg1("AUDC_SET_INPUT(%d)\n",*sarg); | ||
1763 | |||
1764 | if (*sarg == state->input) | 1699 | if (*sarg == state->input) |
1765 | break; | 1700 | break; |
1766 | state->input = *sarg; | 1701 | state->input = *sarg; |
@@ -1800,7 +1735,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1800 | break; | 1735 | break; |
1801 | 1736 | ||
1802 | case AUDC_SET_RADIO: | 1737 | case AUDC_SET_RADIO: |
1803 | msp_dbg1("AUDC_SET_RADIO\n"); | ||
1804 | state->norm = VIDEO_MODE_RADIO; | 1738 | state->norm = VIDEO_MODE_RADIO; |
1805 | msp_dbg1("switching to radio mode\n"); | 1739 | msp_dbg1("switching to radio mode\n"); |
1806 | state->watch_stereo = 0; | 1740 | state->watch_stereo = 0; |
@@ -1810,7 +1744,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1810 | msp3400c_setmode(client, MSP_MODE_FM_RADIO); | 1744 | msp3400c_setmode(client, MSP_MODE_FM_RADIO); |
1811 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | 1745 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), |
1812 | MSP_CARRIER(10.7)); | 1746 | MSP_CARRIER(10.7)); |
1813 | msp_set_volume(client, state->muted, state->left, state->right); | 1747 | msp_set_audio(client); |
1814 | break; | 1748 | break; |
1815 | case OPMODE_AUTODETECT: | 1749 | case OPMODE_AUTODETECT: |
1816 | case OPMODE_AUTOSELECT: | 1750 | case OPMODE_AUTOSELECT: |
@@ -1852,7 +1786,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1852 | { | 1786 | { |
1853 | struct video_audio *va = arg; | 1787 | struct video_audio *va = arg; |
1854 | 1788 | ||
1855 | msp_dbg1("VIDIOCGAUDIO\n"); | ||
1856 | va->flags |= VIDEO_AUDIO_VOLUME | | 1789 | va->flags |= VIDEO_AUDIO_VOLUME | |
1857 | VIDEO_AUDIO_BASS | | 1790 | VIDEO_AUDIO_BASS | |
1858 | VIDEO_AUDIO_TREBLE | | 1791 | VIDEO_AUDIO_TREBLE | |
@@ -1862,13 +1795,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1862 | 1795 | ||
1863 | if (state->muted) | 1796 | if (state->muted) |
1864 | va->flags |= VIDEO_AUDIO_MUTE; | 1797 | va->flags |= VIDEO_AUDIO_MUTE; |
1865 | va->volume = max(state->left, state->right); | 1798 | va->volume = state->volume; |
1866 | va->balance = (32768 * min(state->left, state->right)) / | 1799 | va->balance = state->volume ? state->balance : 32768; |
1867 | (va->volume ? va->volume : 1); | ||
1868 | va->balance = (state->left < state->right) ? | ||
1869 | (65535 - va->balance) : va->balance; | ||
1870 | if (0 == va->volume) | ||
1871 | va->balance = 32768; | ||
1872 | va->bass = state->bass; | 1800 | va->bass = state->bass; |
1873 | va->treble = state->treble; | 1801 | va->treble = state->treble; |
1874 | 1802 | ||
@@ -1881,19 +1809,12 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1881 | { | 1809 | { |
1882 | struct video_audio *va = arg; | 1810 | struct video_audio *va = arg; |
1883 | 1811 | ||
1884 | msp_dbg1("VIDIOCSAUDIO\n"); | ||
1885 | state->muted = (va->flags & VIDEO_AUDIO_MUTE); | 1812 | state->muted = (va->flags & VIDEO_AUDIO_MUTE); |
1886 | state->left = (min(65536 - va->balance, 32768) * | 1813 | state->volume = va->volume; |
1887 | va->volume) / 32768; | 1814 | state->balance = va->balance; |
1888 | state->right = (min((int)va->balance, 32768) * va->volume) / 32768; | ||
1889 | state->bass = va->bass; | 1815 | state->bass = va->bass; |
1890 | state->treble = va->treble; | 1816 | state->treble = va->treble; |
1891 | msp_dbg1("vol %d, bal %d, flags %x, left %d, right %d, bass %d, treble %d, mode %x\n", | 1817 | msp_set_audio(client); |
1892 | va->volume, va->balance, va->flags, state->left, | ||
1893 | state->right, state->bass, state->treble, state->mode); | ||
1894 | msp_set_volume(client, state->muted, state->left, state->right); | ||
1895 | msp_set_bass(client, state->bass); | ||
1896 | msp_set_treble(client, state->treble); | ||
1897 | 1818 | ||
1898 | if (va->mode != 0 && state->norm != VIDEO_MODE_RADIO) | 1819 | if (va->mode != 0 && state->norm != VIDEO_MODE_RADIO) |
1899 | msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); | 1820 | msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); |
@@ -1904,7 +1825,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1904 | { | 1825 | { |
1905 | struct video_channel *vc = arg; | 1826 | struct video_channel *vc = arg; |
1906 | 1827 | ||
1907 | msp_dbg1("VIDIOCSCHAN (norm=%d)\n",vc->norm); | ||
1908 | state->norm = vc->norm; | 1828 | state->norm = vc->norm; |
1909 | msp_wake_thread(client); | 1829 | msp_wake_thread(client); |
1910 | break; | 1830 | break; |
@@ -1914,7 +1834,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1914 | case VIDIOC_S_FREQUENCY: | 1834 | case VIDIOC_S_FREQUENCY: |
1915 | { | 1835 | { |
1916 | /* new channel -- kick audio carrier scan */ | 1836 | /* new channel -- kick audio carrier scan */ |
1917 | msp_dbg1("VIDIOCSFREQ\n"); | ||
1918 | msp_wake_thread(client); | 1837 | msp_wake_thread(client); |
1919 | break; | 1838 | break; |
1920 | } | 1839 | } |
@@ -1924,7 +1843,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1924 | { | 1843 | { |
1925 | struct msp_matrix *mspm = arg; | 1844 | struct msp_matrix *mspm = arg; |
1926 | 1845 | ||
1927 | msp_dbg1("MSP_SET_MATRIX\n"); | ||
1928 | msp_set_scart(client, mspm->input, mspm->output); | 1846 | msp_set_scart(client, mspm->input, mspm->output); |
1929 | break; | 1847 | break; |
1930 | } | 1848 | } |
@@ -1936,11 +1854,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1936 | 1854 | ||
1937 | /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/ | 1855 | /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/ |
1938 | if (*id & V4L2_STD_PAL) { | 1856 | if (*id & V4L2_STD_PAL) { |
1939 | state->norm=VIDEO_MODE_PAL; | 1857 | state->norm = VIDEO_MODE_PAL; |
1940 | } else if (*id & V4L2_STD_SECAM) { | 1858 | } else if (*id & V4L2_STD_SECAM) { |
1941 | state->norm=VIDEO_MODE_SECAM; | 1859 | state->norm = VIDEO_MODE_SECAM; |
1942 | } else { | 1860 | } else { |
1943 | state->norm=VIDEO_MODE_NTSC; | 1861 | state->norm = VIDEO_MODE_NTSC; |
1944 | } | 1862 | } |
1945 | 1863 | ||
1946 | msp_wake_thread(client); | 1864 | msp_wake_thread(client); |
@@ -1957,16 +1875,16 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1957 | i->type = V4L2_INPUT_TYPE_TUNER; | 1875 | i->type = V4L2_INPUT_TYPE_TUNER; |
1958 | switch (i->index) { | 1876 | switch (i->index) { |
1959 | case AUDIO_RADIO: | 1877 | case AUDIO_RADIO: |
1960 | strcpy(i->name,"Radio"); | 1878 | strcpy(i->name, "Radio"); |
1961 | break; | 1879 | break; |
1962 | case AUDIO_EXTERN_1: | 1880 | case AUDIO_EXTERN_1: |
1963 | strcpy(i->name,"Extern 1"); | 1881 | strcpy(i->name, "Extern 1"); |
1964 | break; | 1882 | break; |
1965 | case AUDIO_EXTERN_2: | 1883 | case AUDIO_EXTERN_2: |
1966 | strcpy(i->name,"Extern 2"); | 1884 | strcpy(i->name, "Extern 2"); |
1967 | break; | 1885 | break; |
1968 | case AUDIO_TUNER: | 1886 | case AUDIO_TUNER: |
1969 | strcpy(i->name,"Television"); | 1887 | strcpy(i->name, "Television"); |
1970 | break; | 1888 | break; |
1971 | default: | 1889 | default: |
1972 | return -EINVAL; | 1890 | return -EINVAL; |
@@ -1978,20 +1896,20 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1978 | { | 1896 | { |
1979 | struct v4l2_audio *a = arg; | 1897 | struct v4l2_audio *a = arg; |
1980 | 1898 | ||
1981 | memset(a,0,sizeof(*a)); | 1899 | memset(a, 0, sizeof(*a)); |
1982 | 1900 | ||
1983 | switch (a->index) { | 1901 | switch (a->index) { |
1984 | case AUDIO_RADIO: | 1902 | case AUDIO_RADIO: |
1985 | strcpy(a->name,"Radio"); | 1903 | strcpy(a->name, "Radio"); |
1986 | break; | 1904 | break; |
1987 | case AUDIO_EXTERN_1: | 1905 | case AUDIO_EXTERN_1: |
1988 | strcpy(a->name,"Extern 1"); | 1906 | strcpy(a->name, "Extern 1"); |
1989 | break; | 1907 | break; |
1990 | case AUDIO_EXTERN_2: | 1908 | case AUDIO_EXTERN_2: |
1991 | strcpy(a->name,"Extern 2"); | 1909 | strcpy(a->name, "Extern 2"); |
1992 | break; | 1910 | break; |
1993 | case AUDIO_TUNER: | 1911 | case AUDIO_TUNER: |
1994 | strcpy(a->name,"Television"); | 1912 | strcpy(a->name, "Television"); |
1995 | break; | 1913 | break; |
1996 | default: | 1914 | default: |
1997 | return -EINVAL; | 1915 | return -EINVAL; |
@@ -1999,7 +1917,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1999 | 1917 | ||
2000 | msp_any_detect_stereo(client); | 1918 | msp_any_detect_stereo(client); |
2001 | if (state->audmode == V4L2_TUNER_MODE_STEREO) { | 1919 | if (state->audmode == V4L2_TUNER_MODE_STEREO) { |
2002 | a->capability=V4L2_AUDCAP_STEREO; | 1920 | a->capability = V4L2_AUDCAP_STEREO; |
2003 | } | 1921 | } |
2004 | 1922 | ||
2005 | break; | 1923 | break; |
@@ -2032,10 +1950,10 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
2032 | if (scart) { | 1950 | if (scart) { |
2033 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | 1951 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; |
2034 | state->audmode = V4L2_TUNER_MODE_STEREO; | 1952 | state->audmode = V4L2_TUNER_MODE_STEREO; |
2035 | msp_set_scart(client,scart,0); | 1953 | msp_set_scart(client, scart, 0); |
2036 | msp_write_dsp(client,0x000d,0x1900); | 1954 | msp_write_dsp(client, 0x000d, 0x1900); |
2037 | } | 1955 | } |
2038 | if (sarg->capability==V4L2_AUDCAP_STEREO) { | 1956 | if (sarg->capability == V4L2_AUDCAP_STEREO) { |
2039 | state->audmode = V4L2_TUNER_MODE_STEREO; | 1957 | state->audmode = V4L2_TUNER_MODE_STEREO; |
2040 | } else { | 1958 | } else { |
2041 | state->audmode &= ~V4L2_TUNER_MODE_STEREO; | 1959 | state->audmode &= ~V4L2_TUNER_MODE_STEREO; |
@@ -2053,14 +1971,13 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
2053 | vt->audmode = state->audmode; | 1971 | vt->audmode = state->audmode; |
2054 | vt->rxsubchans = state->rxsubchans; | 1972 | vt->rxsubchans = state->rxsubchans; |
2055 | vt->capability = V4L2_TUNER_CAP_STEREO | | 1973 | vt->capability = V4L2_TUNER_CAP_STEREO | |
2056 | V4L2_TUNER_CAP_LANG1| | 1974 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; |
2057 | V4L2_TUNER_CAP_LANG2; | ||
2058 | break; | 1975 | break; |
2059 | } | 1976 | } |
2060 | 1977 | ||
2061 | case VIDIOC_S_TUNER: | 1978 | case VIDIOC_S_TUNER: |
2062 | { | 1979 | { |
2063 | struct v4l2_tuner *vt=(struct v4l2_tuner *)arg; | 1980 | struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; |
2064 | 1981 | ||
2065 | /* only set audmode */ | 1982 | /* only set audmode */ |
2066 | if (vt->audmode != -1 && vt->audmode != 0) | 1983 | if (vt->audmode != -1 && vt->audmode != 0) |
@@ -2070,20 +1987,20 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
2070 | 1987 | ||
2071 | case VIDIOC_G_AUDOUT: | 1988 | case VIDIOC_G_AUDOUT: |
2072 | { | 1989 | { |
2073 | struct v4l2_audioout *a=(struct v4l2_audioout *)arg; | 1990 | struct v4l2_audioout *a = (struct v4l2_audioout *)arg; |
2074 | int idx=a->index; | 1991 | int idx = a->index; |
2075 | 1992 | ||
2076 | memset(a,0,sizeof(*a)); | 1993 | memset(a, 0, sizeof(*a)); |
2077 | 1994 | ||
2078 | switch (idx) { | 1995 | switch (idx) { |
2079 | case 0: | 1996 | case 0: |
2080 | strcpy(a->name,"Scart1 Out"); | 1997 | strcpy(a->name, "Scart1 Out"); |
2081 | break; | 1998 | break; |
2082 | case 1: | 1999 | case 1: |
2083 | strcpy(a->name,"Scart2 Out"); | 2000 | strcpy(a->name, "Scart2 Out"); |
2084 | break; | 2001 | break; |
2085 | case 2: | 2002 | case 2: |
2086 | strcpy(a->name,"I2S Out"); | 2003 | strcpy(a->name, "I2S Out"); |
2087 | break; | 2004 | break; |
2088 | default: | 2005 | default: |
2089 | return -EINVAL; | 2006 | return -EINVAL; |
@@ -2094,29 +2011,29 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
2094 | 2011 | ||
2095 | case VIDIOC_S_AUDOUT: | 2012 | case VIDIOC_S_AUDOUT: |
2096 | { | 2013 | { |
2097 | struct v4l2_audioout *a=(struct v4l2_audioout *)arg; | 2014 | struct v4l2_audioout *a = (struct v4l2_audioout *)arg; |
2098 | 2015 | ||
2099 | if (a->index<0||a->index>2) | 2016 | if (a->index < 0 || a->index > 2) |
2100 | return -EINVAL; | 2017 | return -EINVAL; |
2101 | 2018 | ||
2102 | msp_dbg1("Setting audio out on msp34xx to input %i\n",a->index); | 2019 | msp_dbg1("Setting audio out on msp34xx to input %i\n", a->index); |
2103 | msp_set_scart(client,state->in_scart,a->index+1); | 2020 | msp_set_scart(client, state->in_scart, a->index + 1); |
2104 | 2021 | ||
2105 | break; | 2022 | break; |
2106 | } | 2023 | } |
2107 | 2024 | ||
2108 | case VIDIOC_INT_I2S_CLOCK_FREQ: | 2025 | case VIDIOC_INT_I2S_CLOCK_FREQ: |
2109 | { | 2026 | { |
2110 | u32 *a=(u32 *)arg; | 2027 | u32 *a = (u32 *)arg; |
2111 | 2028 | ||
2112 | msp_dbg1("Setting I2S speed to %d\n",*a); | 2029 | msp_dbg1("Setting I2S speed to %d\n", *a); |
2113 | 2030 | ||
2114 | switch (*a) { | 2031 | switch (*a) { |
2115 | case 1024000: | 2032 | case 1024000: |
2116 | state->i2s_mode=0; | 2033 | state->i2s_mode = 0; |
2117 | break; | 2034 | break; |
2118 | case 2048000: | 2035 | case 2048000: |
2119 | state->i2s_mode=1; | 2036 | state->i2s_mode = 1; |
2120 | break; | 2037 | break; |
2121 | default: | 2038 | default: |
2122 | return -EINVAL; | 2039 | return -EINVAL; |
@@ -2129,41 +2046,26 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
2129 | struct v4l2_queryctrl *qc = arg; | 2046 | struct v4l2_queryctrl *qc = arg; |
2130 | int i; | 2047 | int i; |
2131 | 2048 | ||
2132 | msp_dbg1("VIDIOC_QUERYCTRL\n"); | ||
2133 | |||
2134 | for (i = 0; i < ARRAY_SIZE(msp_qctrl); i++) | 2049 | for (i = 0; i < ARRAY_SIZE(msp_qctrl); i++) |
2135 | if (qc->id && qc->id == msp_qctrl[i].id) { | 2050 | if (qc->id && qc->id == msp_qctrl[i].id) { |
2136 | memcpy(qc, &(msp_qctrl[i]), | 2051 | memcpy(qc, &msp_qctrl[i], sizeof(*qc)); |
2137 | sizeof(*qc)); | ||
2138 | return 0; | 2052 | return 0; |
2139 | } | 2053 | } |
2140 | |||
2141 | return -EINVAL; | 2054 | return -EINVAL; |
2142 | } | 2055 | } |
2143 | 2056 | ||
2144 | case VIDIOC_G_CTRL: | 2057 | case VIDIOC_G_CTRL: |
2145 | { | 2058 | return msp_get_ctrl(client, arg); |
2146 | struct v4l2_control *ctrl = arg; | ||
2147 | msp_dbg1("VIDIOC_G_CTRL\n"); | ||
2148 | |||
2149 | return msp_get_ctrl(client, ctrl); | ||
2150 | } | ||
2151 | 2059 | ||
2152 | case VIDIOC_S_CTRL: | 2060 | case VIDIOC_S_CTRL: |
2153 | { | 2061 | return msp_set_ctrl(client, arg); |
2154 | struct v4l2_control *ctrl = arg; | ||
2155 | |||
2156 | msp_dbg1("VIDIOC_S_CTRL\n"); | ||
2157 | |||
2158 | return msp_set_ctrl(client, ctrl); | ||
2159 | } | ||
2160 | 2062 | ||
2161 | case VIDIOC_LOG_STATUS: | 2063 | case VIDIOC_LOG_STATUS: |
2162 | msp_any_detect_stereo(client); | 2064 | msp_any_detect_stereo(client); |
2163 | msp_info("%s rev1 = 0x%04x rev2 = 0x%04x\n", | 2065 | msp_info("%s rev1 = 0x%04x rev2 = 0x%04x\n", |
2164 | client->name, state->rev1, state->rev2); | 2066 | client->name, state->rev1, state->rev2); |
2165 | msp_info("Volume: left %d right %d bass %d treble %d%s\n", | 2067 | msp_info("Audio: volume %d balance %d bass %d treble %d%s\n", |
2166 | state->left, state->right, | 2068 | state->volume, state->balance, |
2167 | state->bass, state->treble, | 2069 | state->bass, state->treble, |
2168 | state->muted ? " (muted)" : ""); | 2070 | state->muted ? " (muted)" : ""); |
2169 | msp_info("Mode: %s (%s%s)\n", msp_standard_mode_name(state->mode), | 2071 | msp_info("Mode: %s (%s%s)\n", msp_standard_mode_name(state->mode), |
@@ -2233,8 +2135,8 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
2233 | 2135 | ||
2234 | memset(state, 0, sizeof(*state)); | 2136 | memset(state, 0, sizeof(*state)); |
2235 | state->norm = VIDEO_MODE_NTSC; | 2137 | state->norm = VIDEO_MODE_NTSC; |
2236 | state->left = 58880; /* 0db gain */ | 2138 | state->volume = 58880; /* 0db gain */ |
2237 | state->right = 58880; /* 0db gain */ | 2139 | state->balance = 32768; /* 0db gain */ |
2238 | state->bass = 32768; | 2140 | state->bass = 32768; |
2239 | state->treble = 32768; | 2141 | state->treble = 32768; |
2240 | state->input = -1; | 2142 | state->input = -1; |
@@ -2255,7 +2157,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
2255 | return -1; | 2157 | return -1; |
2256 | } | 2158 | } |
2257 | 2159 | ||
2258 | msp_set_volume(client, state->muted, state->left, state->right); | 2160 | msp_set_audio(client); |
2259 | 2161 | ||
2260 | snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d", | 2162 | snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d", |
2261 | ((state->rev1 >> 4) & 0x0f) + '3', | 2163 | ((state->rev1 >> 4) & 0x0f) + '3', |
@@ -2308,7 +2210,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
2308 | if (thread_func) { | 2210 | if (thread_func) { |
2309 | state->kthread = kthread_run(thread_func, client, "msp34xx"); | 2211 | state->kthread = kthread_run(thread_func, client, "msp34xx"); |
2310 | 2212 | ||
2311 | if (NULL == state->kthread) | 2213 | if (state->kthread == NULL) |
2312 | msp_warn("kernel_thread() failed\n"); | 2214 | msp_warn("kernel_thread() failed\n"); |
2313 | msp_wake_thread(client); | 2215 | msp_wake_thread(client); |
2314 | } | 2216 | } |