diff options
| author | Johannes Berg <johannes@sipsolutions.net> | 2006-07-10 07:44:41 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-10 16:24:20 -0400 |
| commit | 50099328e4fe7c9f8981f408071a1ff82d59ddf8 (patch) | |
| tree | 9597a3329541609117d4647451729bcd8ca9605d /sound/aoa/codecs | |
| parent | 3e5102ad70aaafe49823a02b368c0c3032c91439 (diff) | |
[PATCH] aoa: tas: add missing bass/treble controls
This patch adds the bass/treble controls to snd-aoa that snd-powermac always
had for tas3004 based machines.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'sound/aoa/codecs')
| -rw-r--r-- | sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h | 134 | ||||
| -rw-r--r-- | sound/aoa/codecs/snd-aoa-codec-tas.c | 116 |
2 files changed, 247 insertions, 3 deletions
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h new file mode 100644 index 000000000000..69b61136fd54 --- /dev/null +++ b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | /* | ||
| 2 | * This file is only included exactly once! | ||
| 3 | * | ||
| 4 | * The tables here are derived from the tas3004 datasheet, | ||
| 5 | * modulo typo corrections and some smoothing... | ||
| 6 | */ | ||
| 7 | |||
| 8 | #define TAS3004_TREBLE_MIN 0 | ||
| 9 | #define TAS3004_TREBLE_MAX 72 | ||
| 10 | #define TAS3004_BASS_MIN 0 | ||
| 11 | #define TAS3004_BASS_MAX 72 | ||
| 12 | #define TAS3004_TREBLE_ZERO 36 | ||
| 13 | #define TAS3004_BASS_ZERO 36 | ||
| 14 | |||
| 15 | static u8 tas3004_treble_table[] = { | ||
| 16 | 150, /* -18 dB */ | ||
| 17 | 149, | ||
| 18 | 148, | ||
| 19 | 147, | ||
| 20 | 146, | ||
| 21 | 145, | ||
| 22 | 144, | ||
| 23 | 143, | ||
| 24 | 142, | ||
| 25 | 141, | ||
| 26 | 140, | ||
| 27 | 139, | ||
| 28 | 138, | ||
| 29 | 137, | ||
| 30 | 136, | ||
| 31 | 135, | ||
| 32 | 134, | ||
| 33 | 133, | ||
| 34 | 132, | ||
| 35 | 131, | ||
| 36 | 130, | ||
| 37 | 129, | ||
| 38 | 128, | ||
| 39 | 127, | ||
| 40 | 126, | ||
| 41 | 125, | ||
| 42 | 124, | ||
| 43 | 123, | ||
| 44 | 122, | ||
| 45 | 121, | ||
| 46 | 120, | ||
| 47 | 119, | ||
| 48 | 118, | ||
| 49 | 117, | ||
| 50 | 116, | ||
| 51 | 115, | ||
| 52 | 114, /* 0 dB */ | ||
| 53 | 113, | ||
| 54 | 112, | ||
| 55 | 111, | ||
| 56 | 109, | ||
| 57 | 108, | ||
| 58 | 107, | ||
| 59 | 105, | ||
| 60 | 104, | ||
| 61 | 103, | ||
| 62 | 101, | ||
| 63 | 99, | ||
| 64 | 98, | ||
| 65 | 96, | ||
| 66 | 93, | ||
| 67 | 91, | ||
| 68 | 89, | ||
| 69 | 86, | ||
| 70 | 83, | ||
| 71 | 81, | ||
| 72 | 77, | ||
| 73 | 74, | ||
| 74 | 71, | ||
| 75 | 67, | ||
| 76 | 63, | ||
| 77 | 59, | ||
| 78 | 54, | ||
| 79 | 49, | ||
| 80 | 44, | ||
| 81 | 38, | ||
| 82 | 32, | ||
| 83 | 26, | ||
| 84 | 19, | ||
| 85 | 10, | ||
| 86 | 4, | ||
| 87 | 2, | ||
| 88 | 1, /* +18 dB */ | ||
| 89 | }; | ||
| 90 | |||
| 91 | static inline u8 tas3004_treble(int idx) | ||
| 92 | { | ||
| 93 | return tas3004_treble_table[idx]; | ||
| 94 | } | ||
| 95 | |||
| 96 | /* I only save the difference here to the treble table | ||
| 97 | * so that the binary is smaller... | ||
| 98 | * I have also ignored completely differences of | ||
| 99 | * +/- 1 | ||
| 100 | */ | ||
| 101 | static s8 tas3004_bass_diff_to_treble[] = { | ||
| 102 | 2, /* 7 dB, offset 50 */ | ||
| 103 | 2, | ||
| 104 | 2, | ||
| 105 | 2, | ||
| 106 | 2, | ||
| 107 | 1, | ||
| 108 | 2, | ||
| 109 | 2, | ||
| 110 | 2, | ||
| 111 | 3, | ||
| 112 | 4, | ||
| 113 | 4, | ||
| 114 | 5, | ||
| 115 | 6, | ||
| 116 | 7, | ||
| 117 | 8, | ||
| 118 | 9, | ||
| 119 | 10, | ||
| 120 | 11, | ||
| 121 | 14, | ||
| 122 | 13, | ||
| 123 | 8, | ||
| 124 | 1, /* 18 dB */ | ||
| 125 | }; | ||
| 126 | |||
| 127 | static inline u8 tas3004_bass(int idx) | ||
| 128 | { | ||
| 129 | u8 result = tas3004_treble_table[idx]; | ||
| 130 | |||
| 131 | if (idx >= 50) | ||
| 132 | result += tas3004_bass_diff_to_treble[idx-50]; | ||
| 133 | return result; | ||
| 134 | } | ||
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c index 009f57576f9c..16c0b6b0a805 100644 --- a/sound/aoa/codecs/snd-aoa-codec-tas.c +++ b/sound/aoa/codecs/snd-aoa-codec-tas.c | |||
| @@ -72,6 +72,7 @@ MODULE_DESCRIPTION("tas codec driver for snd-aoa"); | |||
| 72 | 72 | ||
| 73 | #include "snd-aoa-codec-tas.h" | 73 | #include "snd-aoa-codec-tas.h" |
| 74 | #include "snd-aoa-codec-tas-gain-table.h" | 74 | #include "snd-aoa-codec-tas-gain-table.h" |
| 75 | #include "snd-aoa-codec-tas-basstreble.h" | ||
| 75 | #include "../aoa.h" | 76 | #include "../aoa.h" |
| 76 | #include "../soundbus/soundbus.h" | 77 | #include "../soundbus/soundbus.h" |
| 77 | 78 | ||
| @@ -87,6 +88,7 @@ struct tas { | |||
| 87 | hw_enabled:1; | 88 | hw_enabled:1; |
| 88 | u8 cached_volume_l, cached_volume_r; | 89 | u8 cached_volume_l, cached_volume_r; |
| 89 | u8 mixer_l[3], mixer_r[3]; | 90 | u8 mixer_l[3], mixer_r[3]; |
| 91 | u8 bass, treble; | ||
| 90 | u8 acr; | 92 | u8 acr; |
| 91 | int drc_range; | 93 | int drc_range; |
| 92 | }; | 94 | }; |
| @@ -128,6 +130,22 @@ static void tas3004_set_drc(struct tas *tas) | |||
| 128 | tas_write_reg(tas, TAS_REG_DRC, 6, val); | 130 | tas_write_reg(tas, TAS_REG_DRC, 6, val); |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 133 | static void tas_set_treble(struct tas *tas) | ||
| 134 | { | ||
| 135 | u8 tmp; | ||
| 136 | |||
| 137 | tmp = tas3004_treble(tas->treble); | ||
| 138 | tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp); | ||
| 139 | } | ||
| 140 | |||
| 141 | static void tas_set_bass(struct tas *tas) | ||
| 142 | { | ||
| 143 | u8 tmp; | ||
| 144 | |||
| 145 | tmp = tas3004_bass(tas->bass); | ||
| 146 | tas_write_reg(tas, TAS_REG_BASS, 1, &tmp); | ||
| 147 | } | ||
| 148 | |||
| 131 | static void tas_set_volume(struct tas *tas) | 149 | static void tas_set_volume(struct tas *tas) |
| 132 | { | 150 | { |
| 133 | u8 block[6]; | 151 | u8 block[6]; |
| @@ -485,6 +503,89 @@ static struct snd_kcontrol_new capture_source_control = { | |||
| 485 | .put = tas_snd_capture_source_put, | 503 | .put = tas_snd_capture_source_put, |
| 486 | }; | 504 | }; |
| 487 | 505 | ||
| 506 | static int tas_snd_treble_info(struct snd_kcontrol *kcontrol, | ||
| 507 | struct snd_ctl_elem_info *uinfo) | ||
| 508 | { | ||
| 509 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
| 510 | uinfo->count = 1; | ||
| 511 | uinfo->value.integer.min = TAS3004_TREBLE_MIN; | ||
| 512 | uinfo->value.integer.max = TAS3004_TREBLE_MAX; | ||
| 513 | return 0; | ||
| 514 | } | ||
| 515 | |||
| 516 | static int tas_snd_treble_get(struct snd_kcontrol *kcontrol, | ||
| 517 | struct snd_ctl_elem_value *ucontrol) | ||
| 518 | { | ||
| 519 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
| 520 | |||
| 521 | ucontrol->value.integer.value[0] = tas->treble; | ||
| 522 | return 0; | ||
| 523 | } | ||
| 524 | |||
| 525 | static int tas_snd_treble_put(struct snd_kcontrol *kcontrol, | ||
| 526 | struct snd_ctl_elem_value *ucontrol) | ||
| 527 | { | ||
| 528 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
| 529 | |||
| 530 | if (tas->treble == ucontrol->value.integer.value[0]) | ||
| 531 | return 0; | ||
| 532 | |||
| 533 | tas->treble = ucontrol->value.integer.value[0]; | ||
| 534 | if (tas->hw_enabled) | ||
| 535 | tas_set_treble(tas); | ||
| 536 | return 1; | ||
| 537 | } | ||
| 538 | |||
| 539 | static struct snd_kcontrol_new treble_control = { | ||
| 540 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 541 | .name = "Treble", | ||
| 542 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
| 543 | .info = tas_snd_treble_info, | ||
| 544 | .get = tas_snd_treble_get, | ||
| 545 | .put = tas_snd_treble_put, | ||
| 546 | }; | ||
| 547 | |||
| 548 | static int tas_snd_bass_info(struct snd_kcontrol *kcontrol, | ||
| 549 | struct snd_ctl_elem_info *uinfo) | ||
| 550 | { | ||
| 551 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
| 552 | uinfo->count = 1; | ||
| 553 | uinfo->value.integer.min = TAS3004_BASS_MIN; | ||
| 554 | uinfo->value.integer.max = TAS3004_BASS_MAX; | ||
| 555 | return 0; | ||
| 556 | } | ||
| 557 | |||
| 558 | static int tas_snd_bass_get(struct snd_kcontrol *kcontrol, | ||
| 559 | struct snd_ctl_elem_value *ucontrol) | ||
| 560 | { | ||
| 561 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
| 562 | |||
| 563 | ucontrol->value.integer.value[0] = tas->bass; | ||
| 564 | return 0; | ||
| 565 | } | ||
| 566 | |||
| 567 | static int tas_snd_bass_put(struct snd_kcontrol *kcontrol, | ||
| 568 | struct snd_ctl_elem_value *ucontrol) | ||
| 569 | { | ||
| 570 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
| 571 | |||
| 572 | if (tas->bass == ucontrol->value.integer.value[0]) | ||
| 573 | return 0; | ||
| 574 | |||
| 575 | tas->bass = ucontrol->value.integer.value[0]; | ||
| 576 | if (tas->hw_enabled) | ||
| 577 | tas_set_bass(tas); | ||
| 578 | return 1; | ||
| 579 | } | ||
| 580 | |||
| 581 | static struct snd_kcontrol_new bass_control = { | ||
| 582 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 583 | .name = "Bass", | ||
| 584 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
| 585 | .info = tas_snd_bass_info, | ||
| 586 | .get = tas_snd_bass_get, | ||
| 587 | .put = tas_snd_bass_put, | ||
| 588 | }; | ||
| 488 | 589 | ||
| 489 | static struct transfer_info tas_transfers[] = { | 590 | static struct transfer_info tas_transfers[] = { |
| 490 | { | 591 | { |
| @@ -541,9 +642,10 @@ static int tas_reset_init(struct tas *tas) | |||
| 541 | tas3004_set_drc(tas); | 642 | tas3004_set_drc(tas); |
| 542 | 643 | ||
| 543 | /* Set treble & bass to 0dB */ | 644 | /* Set treble & bass to 0dB */ |
| 544 | tmp = 114; | 645 | tas->treble = TAS3004_TREBLE_ZERO; |
| 545 | tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp); | 646 | tas->bass = TAS3004_BASS_ZERO; |
| 546 | tas_write_reg(tas, TAS_REG_BASS, 1, &tmp); | 647 | tas_set_treble(tas); |
| 648 | tas_set_bass(tas); | ||
| 547 | 649 | ||
| 548 | tas->acr &= ~TAS_ACR_ANALOG_PDOWN; | 650 | tas->acr &= ~TAS_ACR_ANALOG_PDOWN; |
| 549 | if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr)) | 651 | if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr)) |
| @@ -682,6 +784,14 @@ static int tas_init_codec(struct aoa_codec *codec) | |||
| 682 | if (err) | 784 | if (err) |
| 683 | goto error; | 785 | goto error; |
| 684 | 786 | ||
| 787 | err = aoa_snd_ctl_add(snd_ctl_new1(&treble_control, tas)); | ||
| 788 | if (err) | ||
| 789 | goto error; | ||
| 790 | |||
| 791 | err = aoa_snd_ctl_add(snd_ctl_new1(&bass_control, tas)); | ||
| 792 | if (err) | ||
| 793 | goto error; | ||
| 794 | |||
| 685 | return 0; | 795 | return 0; |
| 686 | error: | 796 | error: |
| 687 | tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); | 797 | tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); |
