diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-08-25 15:53:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:01:00 -0500 |
commit | 7a00d45cf017172c74d15bad0f9f14720efd69dd (patch) | |
tree | 1eb3baa89e0248587491daecb52096c5455e9440 /drivers/media/video | |
parent | dc3d75da05c3ff2dd6510c32a11deacced49d1a1 (diff) |
V4L/DVB (6419): V4L2 port of tda7432 from V4L1 api
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/tda7432.c | 232 |
1 files changed, 121 insertions, 111 deletions
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 43225802a551..b4d10f7a4e57 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Muting and tone control by Jonathan Isom <jisom@ematic.com> | 8 | * Muting and tone control by Jonathan Isom <jisom@ematic.com> |
9 | * | 9 | * |
10 | * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com> | 10 | * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com> |
11 | * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> | ||
11 | * This code is placed under the terms of the GNU General Public License | 12 | * This code is placed under the terms of the GNU General Public License |
12 | * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) | 13 | * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) |
13 | * Which was based on tda8425.c by Greg Alexander (c) 1998 | 14 | * Which was based on tda8425.c by Greg Alexander (c) 1998 |
@@ -276,7 +277,7 @@ static void do_tda7432_init(struct i2c_client *client) | |||
276 | t->volume = 0x3b ; /* -27dB Volume */ | 277 | t->volume = 0x3b ; /* -27dB Volume */ |
277 | if (loudness) /* Turn loudness on? */ | 278 | if (loudness) /* Turn loudness on? */ |
278 | t->volume |= TDA7432_LD_ON; | 279 | t->volume |= TDA7432_LD_ON; |
279 | t->muted = VIDEO_AUDIO_MUTE; | 280 | t->muted = 1; |
280 | t->treble = TDA7432_TREBLE_0DB; /* 0dB Treble */ | 281 | t->treble = TDA7432_TREBLE_0DB; /* 0dB Treble */ |
281 | t->bass = TDA7432_BASS_0DB; /* 0dB Bass */ | 282 | t->bass = TDA7432_BASS_0DB; /* 0dB Bass */ |
282 | t->lf = TDA7432_ATTEN_0DB; /* 0dB attenuation */ | 283 | t->lf = TDA7432_ATTEN_0DB; /* 0dB attenuation */ |
@@ -332,151 +333,160 @@ static int tda7432_detach(struct i2c_client *client) | |||
332 | return 0; | 333 | return 0; |
333 | } | 334 | } |
334 | 335 | ||
335 | static int tda7432_command(struct i2c_client *client, | 336 | static int tda7432_get_ctrl(struct i2c_client *client, |
336 | unsigned int cmd, void *arg) | 337 | struct v4l2_control *ctrl) |
337 | { | 338 | { |
338 | struct tda7432 *t = i2c_get_clientdata(client); | 339 | struct tda7432 *t = i2c_get_clientdata(client); |
339 | v4l_dbg(2, debug,client,"In tda7432_command\n"); | ||
340 | if (debug>1) | ||
341 | v4l_i2c_print_ioctl(client,cmd); | ||
342 | 340 | ||
343 | switch (cmd) { | 341 | switch (ctrl->id) { |
344 | /* --- v4l ioctls --- */ | 342 | case V4L2_CID_AUDIO_MUTE: |
345 | /* take care: bttv does userspace copying, we'll get a | 343 | ctrl->value=t->muted; |
346 | kernel pointer here... */ | 344 | return 0; |
347 | 345 | case V4L2_CID_AUDIO_VOLUME: | |
348 | /* Query card - scale from TDA7432 settings to V4L settings */ | ||
349 | case VIDIOCGAUDIO: | ||
350 | { | ||
351 | struct video_audio *va = arg; | ||
352 | |||
353 | va->flags |= VIDEO_AUDIO_VOLUME | | ||
354 | VIDEO_AUDIO_BASS | | ||
355 | VIDEO_AUDIO_TREBLE | | ||
356 | VIDEO_AUDIO_MUTABLE; | ||
357 | if (t->muted) | ||
358 | va->flags |= VIDEO_AUDIO_MUTE; | ||
359 | va->mode |= VIDEO_SOUND_STEREO; | ||
360 | /* Master volume control | ||
361 | * V4L volume is min 0, max 65535 | ||
362 | * TDA7432 Volume: | ||
363 | * Min (-79dB) is 0x6f | ||
364 | * Max (+20dB) is 0x07 (630) | ||
365 | * Max (0dB) is 0x20 (829) | ||
366 | * (Mask out bit 7 of vol - it's for the loudness setting) | ||
367 | */ | ||
368 | if (!maxvol){ /* max +20db */ | 346 | if (!maxvol){ /* max +20db */ |
369 | va->volume = ( 0x6f - (t->volume & 0x7F) ) * 630; | 347 | ctrl->value = ( 0x6f - (t->volume & 0x7F) ) * 630; |
370 | } else { /* max 0db */ | 348 | } else { /* max 0db */ |
371 | va->volume = ( 0x6f - (t->volume & 0x7F) ) * 829; | 349 | ctrl->value = ( 0x6f - (t->volume & 0x7F) ) * 829; |
372 | } | 350 | } |
373 | 351 | return 0; | |
374 | /* Balance depends on L,R attenuation | 352 | case V4L2_CID_AUDIO_BALANCE: |
375 | * V4L balance is 0 to 65535, middle is 32768 | 353 | { |
376 | * TDA7432 attenuation: min (0dB) is 0, max (-37.5dB) is 0x1f | ||
377 | * to scale up to V4L numbers, mult by 1057 | ||
378 | * attenuation exists for lf, lr, rf, rr | ||
379 | * we use only lf and rf (front channels) | ||
380 | */ | ||
381 | |||
382 | if ( (t->lf) < (t->rf) ) | 354 | if ( (t->lf) < (t->rf) ) |
383 | /* right is attenuated, balance shifted left */ | 355 | /* right is attenuated, balance shifted left */ |
384 | va->balance = (32768 - 1057*(t->rf)); | 356 | ctrl->value = (32768 - 1057*(t->rf)); |
385 | else | 357 | else |
386 | /* left is attenuated, balance shifted right */ | 358 | /* left is attenuated, balance shifted right */ |
387 | va->balance = (32768 + 1057*(t->lf)); | 359 | ctrl->value = (32768 + 1057*(t->lf)); |
388 | 360 | return 0; | |
361 | } | ||
362 | case V4L2_CID_AUDIO_BASS: | ||
363 | { | ||
389 | /* Bass/treble 4 bits each */ | 364 | /* Bass/treble 4 bits each */ |
390 | va->bass=t->bass; | 365 | int bass=t->bass; |
391 | if(va->bass >= 0x8) | 366 | if(bass >= 0x8) |
392 | va->bass = ~(va->bass - 0x8) & 0xf; | 367 | bass = ~(bass - 0x8) & 0xf; |
393 | va->bass = (va->bass << 12)+(va->bass << 8)+(va->bass << 4)+(va->bass); | 368 | ctrl->value = (bass << 12)+(bass << 8)+(bass << 4)+(bass); |
394 | va->treble=t->treble; | 369 | return 0; |
395 | if(va->treble >= 0x8) | ||
396 | va->treble = ~(va->treble - 0x8) & 0xf; | ||
397 | va->treble = (va->treble << 12)+(va->treble << 8)+(va->treble << 4)+(va->treble); | ||
398 | |||
399 | break; /* VIDIOCGAUDIO case */ | ||
400 | } | 370 | } |
401 | 371 | case V4L2_CID_AUDIO_TREBLE: | |
402 | /* Set card - scale from V4L settings to TDA7432 settings */ | ||
403 | case VIDIOCSAUDIO: | ||
404 | { | 372 | { |
405 | struct video_audio *va = arg; | 373 | int treble=t->treble; |
374 | if(treble >= 0x8) | ||
375 | treble = ~(treble - 0x8) & 0xf; | ||
376 | ctrl->value = (treble << 12)+(treble << 8)+(treble << 4)+(treble); | ||
377 | return 0; | ||
378 | } | ||
379 | } | ||
380 | return -EINVAL; | ||
381 | } | ||
406 | 382 | ||
407 | if(va->flags & VIDEO_AUDIO_VOLUME){ | 383 | static int tda7432_set_ctrl(struct i2c_client *client, |
408 | if(!maxvol){ /* max +20db */ | 384 | struct v4l2_control *ctrl) |
409 | t->volume = 0x6f - ((va->volume)/630); | 385 | { |
410 | } else { /* max 0db */ | 386 | struct tda7432 *t = i2c_get_clientdata(client); |
411 | t->volume = 0x6f - ((va->volume)/829); | ||
412 | } | ||
413 | 387 | ||
388 | switch (ctrl->id) { | ||
389 | case V4L2_CID_AUDIO_MUTE: | ||
390 | t->muted=ctrl->value; | ||
391 | break; | ||
392 | case V4L2_CID_AUDIO_VOLUME: | ||
393 | if(!maxvol){ /* max +20db */ | ||
394 | t->volume = 0x6f - ((ctrl->value)/630); | ||
395 | } else { /* max 0db */ | ||
396 | t->volume = 0x6f - ((ctrl->value)/829); | ||
397 | } | ||
414 | if (loudness) /* Turn on the loudness bit */ | 398 | if (loudness) /* Turn on the loudness bit */ |
415 | t->volume |= TDA7432_LD_ON; | 399 | t->volume |= TDA7432_LD_ON; |
416 | 400 | ||
417 | tda7432_write(client,TDA7432_VL, t->volume); | 401 | tda7432_write(client,TDA7432_VL, t->volume); |
418 | } | 402 | return 0; |
419 | 403 | case V4L2_CID_AUDIO_BALANCE: | |
420 | if(va->flags & VIDEO_AUDIO_BASS) | 404 | if (ctrl->value < 32768) { |
421 | { | ||
422 | t->bass = va->bass >> 12; | ||
423 | if(t->bass>= 0x8) | ||
424 | t->bass = (~t->bass & 0xf) + 0x8 ; | ||
425 | } | ||
426 | if(va->flags & VIDEO_AUDIO_TREBLE) | ||
427 | { | ||
428 | t->treble= va->treble >> 12; | ||
429 | if(t->treble>= 0x8) | ||
430 | t->treble = (~t->treble & 0xf) + 0x8 ; | ||
431 | } | ||
432 | if(va->flags & (VIDEO_AUDIO_TREBLE| VIDEO_AUDIO_BASS)) | ||
433 | tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble ); | ||
434 | |||
435 | if(va->flags & VIDEO_AUDIO_BALANCE) { | ||
436 | if (va->balance < 32768) | ||
437 | { | ||
438 | /* shifted to left, attenuate right */ | 405 | /* shifted to left, attenuate right */ |
439 | t->rr = (32768 - va->balance)/1057; | 406 | t->rr = (32768 - ctrl->value)/1057; |
440 | t->rf = t->rr; | 407 | t->rf = t->rr; |
441 | t->lr = TDA7432_ATTEN_0DB; | 408 | t->lr = TDA7432_ATTEN_0DB; |
442 | t->lf = TDA7432_ATTEN_0DB; | 409 | t->lf = TDA7432_ATTEN_0DB; |
443 | } | 410 | } else if(ctrl->value > 32769) { |
444 | else if(va->balance > 32769) | ||
445 | { | ||
446 | /* shifted to right, attenuate left */ | 411 | /* shifted to right, attenuate left */ |
447 | t->lf = (va->balance - 32768)/1057; | 412 | t->lf = (ctrl->value - 32768)/1057; |
448 | t->lr = t->lf; | 413 | t->lr = t->lf; |
449 | t->rr = TDA7432_ATTEN_0DB; | 414 | t->rr = TDA7432_ATTEN_0DB; |
450 | t->rf = TDA7432_ATTEN_0DB; | 415 | t->rf = TDA7432_ATTEN_0DB; |
451 | } | 416 | } else { |
452 | else | ||
453 | { | ||
454 | /* centered */ | 417 | /* centered */ |
455 | t->rr = TDA7432_ATTEN_0DB; | 418 | t->rr = TDA7432_ATTEN_0DB; |
456 | t->rf = TDA7432_ATTEN_0DB; | 419 | t->rf = TDA7432_ATTEN_0DB; |
457 | t->lf = TDA7432_ATTEN_0DB; | 420 | t->lf = TDA7432_ATTEN_0DB; |
458 | t->lr = TDA7432_ATTEN_0DB; | 421 | t->lr = TDA7432_ATTEN_0DB; |
459 | } | 422 | } |
460 | } | 423 | break; |
424 | case V4L2_CID_AUDIO_BASS: | ||
425 | t->bass = ctrl->value >> 12; | ||
426 | if(t->bass>= 0x8) | ||
427 | t->bass = (~t->bass & 0xf) + 0x8 ; | ||
428 | |||
429 | tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble ); | ||
430 | return 0; | ||
431 | case V4L2_CID_AUDIO_TREBLE: | ||
432 | t->treble= ctrl->value >> 12; | ||
433 | if(t->treble>= 0x8) | ||
434 | t->treble = (~t->treble & 0xf) + 0x8 ; | ||
435 | |||
436 | tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble ); | ||
437 | return 0; | ||
438 | default: | ||
439 | return -EINVAL; | ||
440 | } | ||
461 | 441 | ||
462 | t->muted=(va->flags & VIDEO_AUDIO_MUTE); | 442 | /* Used for both mute and balance changes */ |
463 | if (t->muted) | 443 | if (t->muted) |
464 | { | 444 | { |
465 | /* Mute & update balance*/ | 445 | /* Mute & update balance*/ |
466 | tda7432_write(client,TDA7432_LF, t->lf | TDA7432_MUTE); | 446 | tda7432_write(client,TDA7432_LF, t->lf | TDA7432_MUTE); |
467 | tda7432_write(client,TDA7432_LR, t->lr | TDA7432_MUTE); | 447 | tda7432_write(client,TDA7432_LR, t->lr | TDA7432_MUTE); |
468 | tda7432_write(client,TDA7432_RF, t->rf | TDA7432_MUTE); | 448 | tda7432_write(client,TDA7432_RF, t->rf | TDA7432_MUTE); |
469 | tda7432_write(client,TDA7432_RR, t->rr | TDA7432_MUTE); | 449 | tda7432_write(client,TDA7432_RR, t->rr | TDA7432_MUTE); |
470 | } else { | 450 | } else { |
471 | tda7432_write(client,TDA7432_LF, t->lf); | 451 | tda7432_write(client,TDA7432_LF, t->lf); |
472 | tda7432_write(client,TDA7432_LR, t->lr); | 452 | tda7432_write(client,TDA7432_LR, t->lr); |
473 | tda7432_write(client,TDA7432_RF, t->rf); | 453 | tda7432_write(client,TDA7432_RF, t->rf); |
474 | tda7432_write(client,TDA7432_RR, t->rr); | 454 | tda7432_write(client,TDA7432_RR, t->rr); |
475 | } | 455 | } |
456 | return 0; | ||
457 | } | ||
476 | 458 | ||
477 | break; | 459 | static int tda7432_command(struct i2c_client *client, |
460 | unsigned int cmd, void *arg) | ||
461 | { | ||
462 | v4l_dbg(2, debug,client,"In tda7432_command\n"); | ||
463 | if (debug>1) | ||
464 | v4l_i2c_print_ioctl(client,cmd); | ||
465 | |||
466 | switch (cmd) { | ||
467 | /* --- v4l ioctls --- */ | ||
468 | /* take care: bttv does userspace copying, we'll get a | ||
469 | kernel pointer here... */ | ||
470 | case VIDIOC_QUERYCTRL: | ||
471 | { | ||
472 | struct v4l2_queryctrl *qc = arg; | ||
473 | |||
474 | switch (qc->id) { | ||
475 | case V4L2_CID_AUDIO_MUTE: | ||
476 | case V4L2_CID_AUDIO_VOLUME: | ||
477 | case V4L2_CID_AUDIO_BALANCE: | ||
478 | case V4L2_CID_AUDIO_BASS: | ||
479 | case V4L2_CID_AUDIO_TREBLE: | ||
480 | default: | ||
481 | return -EINVAL; | ||
482 | } | ||
483 | return v4l2_ctrl_query_fill_std(qc); | ||
484 | } | ||
485 | case VIDIOC_S_CTRL: | ||
486 | return tda7432_set_ctrl(client, arg); | ||
478 | 487 | ||
479 | } /* end of VIDEOCSAUDIO case */ | 488 | case VIDIOC_G_CTRL: |
489 | return tda7432_get_ctrl(client, arg); | ||
480 | 490 | ||
481 | } /* end of (cmd) switch */ | 491 | } /* end of (cmd) switch */ |
482 | 492 | ||