aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
authorJonathan Woithe <jwoithe@physics.adelaide.edu.au>2006-02-28 05:43:27 -0500
committerJaroslav Kysela <perex@suse.cz>2006-03-22 04:32:49 -0500
commit5c8f858d71054960f08c46703a3f0fb36a752079 (patch)
tree926bb7a5d62b691a52f108f8027160e3524dcc0e /sound/pci/hda/patch_realtek.c
parentd57fdac0691d500d5c697e452f769335b22a75e3 (diff)
[ALSA] HDA/ALC260: 4/7 - add GPIO switches to test model
Modules: HDA Codec driver This patch adds 'test' model mixer switches for the GPIO controls found on the ALC260. It has been found that some laptops (eg: Acer) can use these to enable particular controls, so it would be useful to have access to these via the 'test' model. It will make testing new models easy, especially if certain outputs cannot be made to work any other way. This patch *should* work, but because the GPIO pins don't do anything in my laptop I cannot personally verify that all this works as expected. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c66
1 files changed, 64 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 80ba6c753c33..4f6dea23d8b2 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -342,6 +342,58 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
342 .put = alc_pin_mode_put, \ 342 .put = alc_pin_mode_put, \
343 .private_value = nid | (dir<<16) } 343 .private_value = nid | (dir<<16) }
344 344
345/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
346 * together using a mask with more than one bit set. This control is
347 * currently used only by the ALC260 test model. At this stage they are not
348 * needed for any "production" models.
349 */
350#ifdef CONFIG_SND_DEBUG
351static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
352{
353 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
354 uinfo->count = 1;
355 uinfo->value.integer.min = 0;
356 uinfo->value.integer.max = 1;
357 return 0;
358}
359static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
360{
361 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
362 hda_nid_t nid = kcontrol->private_value & 0xffff;
363 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
364 long *valp = ucontrol->value.integer.value;
365 unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00);
366
367 *valp = (val & mask) != 0;
368 return 0;
369}
370static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
371{
372 signed int change;
373 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
374 hda_nid_t nid = kcontrol->private_value & 0xffff;
375 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
376 long val = *ucontrol->value.integer.value;
377 unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00);
378
379 /* Set/unset the masked GPIO bit(s) as needed */
380 change = (val==0?0:mask) != (gpio_data & mask);
381 if (val==0)
382 gpio_data &= ~mask;
383 else
384 gpio_data |= mask;
385 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data);
386
387 return change;
388}
389#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
390 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
391 .info = alc_gpio_data_info, \
392 .get = alc_gpio_data_get, \
393 .put = alc_gpio_data_put, \
394 .private_value = nid | (mask<<16) }
395#endif /* CONFIG_SND_DEBUG */
396
345/* 397/*
346 * set up from the preset table 398 * set up from the preset table
347 */ 399 */
@@ -2874,11 +2926,21 @@ static struct snd_kcontrol_new alc260_test_mixer[] = {
2874 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 2926 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
2875 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 2927 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
2876 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 2928 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
2929
2930 /* Controls for GPIO pins, assuming they are configured as outputs */
2931 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
2932 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
2933 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
2934 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
2935
2877 { } /* end */ 2936 { } /* end */
2878}; 2937};
2879static struct hda_verb alc260_test_init_verbs[] = { 2938static struct hda_verb alc260_test_init_verbs[] = {
2880 /* Disable all GPIOs */ 2939 /* Enable all GPIOs as outputs with an initial value of 0 */
2881 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 2940 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
2941 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
2942 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
2943
2882 /* Enable retasking pins as output, initially without power amp */ 2944 /* Enable retasking pins as output, initially without power amp */
2883 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2945 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2884 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2946 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},