diff options
| author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-01-09 12:32:39 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2006-01-09 12:32:39 -0500 |
| commit | e93fa17eb103bad5d2ee7141a988040f077d2a78 (patch) | |
| tree | 5fb67543d5b14d7716d711e0d9be501625a53b9c | |
| parent | 5e453dc757385ec892a818e4e3b5de027987ced9 (diff) | |
V4L/DVB (3271): more cleanups, simplify volume/balance/bass/treble handling
- Continue cleanup effort:
- more cosmetic changes
- combine volume, balance, bass and treble into one audio
function. Revert old 2.4 code that crept in.
- print internal ioctls using new debug function.
- marked all msp3400c (aka manual) functions as such.
- removed some unused data structures.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
| -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 | } |
