diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2008-01-16 02:32:08 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:30:00 -0500 |
commit | ccc80fb467a88ceb7ce1b68546632b91e5ba6c18 (patch) | |
tree | 097f13a250fa155faeacc1fb127a000cc19ebbb6 /sound/pci/oxygen | |
parent | e85e09250ab552fab6925bcde7c77746101b2d40 (diff) |
[ALSA] oxygen: add control filter to model struct
Allow the models to modify mixer controls before they are added to the
card.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/oxygen')
-rw-r--r-- | sound/pci/oxygen/oxygen.c | 14 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen.h | 5 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 20 | ||||
-rw-r--r-- | sound/pci/oxygen/virtuoso.c | 28 |
4 files changed, 46 insertions, 21 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index e2dda16d5dcc..adf91cc3e1ae 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <sound/control.h> | ||
32 | #include <sound/core.h> | 33 | #include <sound/core.h> |
33 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
34 | #include <sound/pcm.h> | 35 | #include <sound/pcm.h> |
@@ -244,18 +245,27 @@ static void set_ak5385_params(struct oxygen *chip, | |||
244 | 245 | ||
245 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | 246 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); |
246 | 247 | ||
248 | static int ak4396_control_filter(struct snd_kcontrol_new *template) | ||
249 | { | ||
250 | if (!strcmp(template->name, "Master Playback Volume")) { | ||
251 | template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; | ||
252 | template->tlv.p = ak4396_db_scale; | ||
253 | } | ||
254 | return 0; | ||
255 | } | ||
256 | |||
247 | static const struct oxygen_model model_generic = { | 257 | static const struct oxygen_model model_generic = { |
248 | .shortname = "C-Media CMI8788", | 258 | .shortname = "C-Media CMI8788", |
249 | .longname = "C-Media Oxygen HD Audio", | 259 | .longname = "C-Media Oxygen HD Audio", |
250 | .chip = "CMI8788", | 260 | .chip = "CMI8788", |
251 | .owner = THIS_MODULE, | 261 | .owner = THIS_MODULE, |
252 | .init = generic_init, | 262 | .init = generic_init, |
263 | .control_filter = ak4396_control_filter, | ||
253 | .cleanup = generic_cleanup, | 264 | .cleanup = generic_cleanup, |
254 | .set_dac_params = set_ak4396_params, | 265 | .set_dac_params = set_ak4396_params, |
255 | .set_adc_params = set_wm8785_params, | 266 | .set_adc_params = set_wm8785_params, |
256 | .update_dac_volume = update_ak4396_volume, | 267 | .update_dac_volume = update_ak4396_volume, |
257 | .update_dac_mute = update_ak4396_mute, | 268 | .update_dac_mute = update_ak4396_mute, |
258 | .dac_tlv = ak4396_db_scale, | ||
259 | .used_channels = OXYGEN_CHANNEL_A | | 269 | .used_channels = OXYGEN_CHANNEL_A | |
260 | OXYGEN_CHANNEL_C | | 270 | OXYGEN_CHANNEL_C | |
261 | OXYGEN_CHANNEL_SPDIF | | 271 | OXYGEN_CHANNEL_SPDIF | |
@@ -269,12 +279,12 @@ static const struct oxygen_model model_meridian = { | |||
269 | .chip = "CMI8788", | 279 | .chip = "CMI8788", |
270 | .owner = THIS_MODULE, | 280 | .owner = THIS_MODULE, |
271 | .init = meridian_init, | 281 | .init = meridian_init, |
282 | .control_filter = ak4396_control_filter, | ||
272 | .cleanup = generic_cleanup, | 283 | .cleanup = generic_cleanup, |
273 | .set_dac_params = set_ak4396_params, | 284 | .set_dac_params = set_ak4396_params, |
274 | .set_adc_params = set_ak5385_params, | 285 | .set_adc_params = set_ak5385_params, |
275 | .update_dac_volume = update_ak4396_volume, | 286 | .update_dac_volume = update_ak4396_volume, |
276 | .update_dac_mute = update_ak4396_mute, | 287 | .update_dac_mute = update_ak4396_mute, |
277 | .dac_tlv = ak4396_db_scale, | ||
278 | .used_channels = OXYGEN_CHANNEL_B | | 288 | .used_channels = OXYGEN_CHANNEL_B | |
279 | OXYGEN_CHANNEL_C | | 289 | OXYGEN_CHANNEL_C | |
280 | OXYGEN_CHANNEL_SPDIF | | 290 | OXYGEN_CHANNEL_SPDIF | |
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 9b0234d81d4e..7278c1563597 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
@@ -35,6 +35,7 @@ struct pci_dev; | |||
35 | struct snd_card; | 35 | struct snd_card; |
36 | struct snd_pcm_substream; | 36 | struct snd_pcm_substream; |
37 | struct snd_pcm_hw_params; | 37 | struct snd_pcm_hw_params; |
38 | struct snd_kcontrol_new; | ||
38 | struct snd_rawmidi; | 39 | struct snd_rawmidi; |
39 | struct oxygen_model; | 40 | struct oxygen_model; |
40 | 41 | ||
@@ -71,6 +72,7 @@ struct oxygen_model { | |||
71 | const char *chip; | 72 | const char *chip; |
72 | struct module *owner; | 73 | struct module *owner; |
73 | void (*init)(struct oxygen *chip); | 74 | void (*init)(struct oxygen *chip); |
75 | int (*control_filter)(struct snd_kcontrol_new *template); | ||
74 | int (*mixer_init)(struct oxygen *chip); | 76 | int (*mixer_init)(struct oxygen *chip); |
75 | void (*cleanup)(struct oxygen *chip); | 77 | void (*cleanup)(struct oxygen *chip); |
76 | void (*set_dac_params)(struct oxygen *chip, | 78 | void (*set_dac_params)(struct oxygen *chip, |
@@ -79,10 +81,7 @@ struct oxygen_model { | |||
79 | struct snd_pcm_hw_params *params); | 81 | struct snd_pcm_hw_params *params); |
80 | void (*update_dac_volume)(struct oxygen *chip); | 82 | void (*update_dac_volume)(struct oxygen *chip); |
81 | void (*update_dac_mute)(struct oxygen *chip); | 83 | void (*update_dac_mute)(struct oxygen *chip); |
82 | const unsigned int *dac_tlv; | ||
83 | u8 used_channels; | 84 | u8 used_channels; |
84 | u8 cd_in_from_video_in; | ||
85 | u8 dac_minimum_volume; | ||
86 | u8 function_flags; | 85 | u8 function_flags; |
87 | }; | 86 | }; |
88 | 87 | ||
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 8b08e6d02cc9..fae7c0f060a0 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -27,11 +27,9 @@ | |||
27 | static int dac_volume_info(struct snd_kcontrol *ctl, | 27 | static int dac_volume_info(struct snd_kcontrol *ctl, |
28 | struct snd_ctl_elem_info *info) | 28 | struct snd_ctl_elem_info *info) |
29 | { | 29 | { |
30 | struct oxygen *chip = ctl->private_data; | ||
31 | |||
32 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 30 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
33 | info->count = 8; | 31 | info->count = 8; |
34 | info->value.integer.min = chip->model->dac_minimum_volume; | 32 | info->value.integer.min = 0; |
35 | info->value.integer.max = 0xff; | 33 | info->value.integer.max = 0xff; |
36 | return 0; | 34 | return 0; |
37 | } | 35 | } |
@@ -525,14 +523,10 @@ static const struct snd_kcontrol_new controls[] = { | |||
525 | { | 523 | { |
526 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 524 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
527 | .name = "Master Playback Volume", | 525 | .name = "Master Playback Volume", |
528 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | 526 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
529 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
530 | .info = dac_volume_info, | 527 | .info = dac_volume_info, |
531 | .get = dac_volume_get, | 528 | .get = dac_volume_get, |
532 | .put = dac_volume_put, | 529 | .put = dac_volume_put, |
533 | .tlv = { | ||
534 | .p = NULL, /* set later */ | ||
535 | }, | ||
536 | }, | 530 | }, |
537 | { | 531 | { |
538 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 532 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -635,18 +629,18 @@ static int add_controls(struct oxygen *chip, | |||
635 | [CONTROL_AUX_CAPTURE_SWITCH] = "Aux Capture Switch", | 629 | [CONTROL_AUX_CAPTURE_SWITCH] = "Aux Capture Switch", |
636 | }; | 630 | }; |
637 | unsigned int i, j; | 631 | unsigned int i, j; |
632 | struct snd_kcontrol_new template; | ||
638 | struct snd_kcontrol *ctl; | 633 | struct snd_kcontrol *ctl; |
639 | int err; | 634 | int err; |
640 | 635 | ||
641 | for (i = 0; i < count; ++i) { | 636 | for (i = 0; i < count; ++i) { |
637 | template = controls[i]; | ||
638 | err = chip->model->control_filter(&template); | ||
639 | if (err < 0) | ||
640 | return err; | ||
642 | ctl = snd_ctl_new1(&controls[i], chip); | 641 | ctl = snd_ctl_new1(&controls[i], chip); |
643 | if (!ctl) | 642 | if (!ctl) |
644 | return -ENOMEM; | 643 | return -ENOMEM; |
645 | if (!strcmp(ctl->id.name, "Master Playback Volume")) | ||
646 | ctl->tlv.p = chip->model->dac_tlv; | ||
647 | else if (chip->model->cd_in_from_video_in && | ||
648 | !strncmp(ctl->id.name, "CD Capture ", 11)) | ||
649 | ctl->private_value ^= AC97_CD ^ AC97_VIDEO; | ||
650 | err = snd_ctl_add(chip->card, ctl); | 644 | err = snd_ctl_add(chip->card, ctl); |
651 | if (err < 0) | 645 | if (err < 0) |
652 | return err; | 646 | return err; |
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 0574fa19dca6..bea34f10d447 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c | |||
@@ -32,6 +32,8 @@ | |||
32 | 32 | ||
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/mutex.h> | ||
36 | #include <sound/ac97_codec.h> | ||
35 | #include <sound/control.h> | 37 | #include <sound/control.h> |
36 | #include <sound/core.h> | 38 | #include <sound/core.h> |
37 | #include <sound/initval.h> | 39 | #include <sound/initval.h> |
@@ -167,6 +169,16 @@ static void set_cs5381_params(struct oxygen *chip, | |||
167 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, value, 0x000c); | 169 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, value, 0x000c); |
168 | } | 170 | } |
169 | 171 | ||
172 | static int pcm1796_volume_info(struct snd_kcontrol *ctl, | ||
173 | struct snd_ctl_elem_info *info) | ||
174 | { | ||
175 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
176 | info->count = 8; | ||
177 | info->value.integer.min = 0x0f; | ||
178 | info->value.integer.max = 0xff; | ||
179 | return 0; | ||
180 | } | ||
181 | |||
170 | static int alt_switch_get(struct snd_kcontrol *ctl, | 182 | static int alt_switch_get(struct snd_kcontrol *ctl, |
171 | struct snd_ctl_elem_value *value) | 183 | struct snd_ctl_elem_value *value) |
172 | { | 184 | { |
@@ -207,6 +219,18 @@ static const struct snd_kcontrol_new alt_switch = { | |||
207 | 219 | ||
208 | static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0); | 220 | static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0); |
209 | 221 | ||
222 | static int xonar_control_filter(struct snd_kcontrol_new *template) | ||
223 | { | ||
224 | if (!strcmp(template->name, "Master Playback Volume")) { | ||
225 | template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; | ||
226 | template->info = pcm1796_volume_info, | ||
227 | template->tlv.p = pcm1796_db_scale; | ||
228 | } else if (!strncmp(template->name, "CD Capture ", 11)) { | ||
229 | template->private_value ^= AC97_CD ^ AC97_VIDEO; | ||
230 | } | ||
231 | return 0; | ||
232 | } | ||
233 | |||
210 | static int xonar_mixer_init(struct oxygen *chip) | 234 | static int xonar_mixer_init(struct oxygen *chip) |
211 | { | 235 | { |
212 | return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); | 236 | return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); |
@@ -217,19 +241,17 @@ static const struct oxygen_model model_xonar = { | |||
217 | .longname = "Asus Virtuoso 200", | 241 | .longname = "Asus Virtuoso 200", |
218 | .chip = "AV200", | 242 | .chip = "AV200", |
219 | .init = xonar_init, | 243 | .init = xonar_init, |
244 | .control_filter = xonar_control_filter, | ||
220 | .mixer_init = xonar_mixer_init, | 245 | .mixer_init = xonar_mixer_init, |
221 | .cleanup = xonar_cleanup, | 246 | .cleanup = xonar_cleanup, |
222 | .set_dac_params = set_pcm1796_params, | 247 | .set_dac_params = set_pcm1796_params, |
223 | .set_adc_params = set_cs5381_params, | 248 | .set_adc_params = set_cs5381_params, |
224 | .update_dac_volume = update_pcm1796_volume, | 249 | .update_dac_volume = update_pcm1796_volume, |
225 | .update_dac_mute = update_pcm1796_mute, | 250 | .update_dac_mute = update_pcm1796_mute, |
226 | .dac_tlv = pcm1796_db_scale, | ||
227 | .used_channels = OXYGEN_CHANNEL_B | | 251 | .used_channels = OXYGEN_CHANNEL_B | |
228 | OXYGEN_CHANNEL_C | | 252 | OXYGEN_CHANNEL_C | |
229 | OXYGEN_CHANNEL_SPDIF | | 253 | OXYGEN_CHANNEL_SPDIF | |
230 | OXYGEN_CHANNEL_MULTICH, | 254 | OXYGEN_CHANNEL_MULTICH, |
231 | .cd_in_from_video_in = 1, | ||
232 | .dac_minimum_volume = 15, | ||
233 | .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, | 255 | .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, |
234 | }; | 256 | }; |
235 | 257 | ||