aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h2
-rw-r--r--sound/pci/cs5535audio/cs5535audio_olpc.c54
2 files changed, 26 insertions, 30 deletions
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 31ecb33ffff9..22737fc9ed03 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -103,6 +103,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci);
103void __devinit olpc_prequirks(struct snd_card *card, 103void __devinit olpc_prequirks(struct snd_card *card,
104 struct snd_ac97_template *ac97); 104 struct snd_ac97_template *ac97);
105int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97); 105int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
106void olpc_analog_input(struct snd_ac97 *ac97, int on);
106#else 107#else
107static inline void olpc_prequirks(struct snd_card *card, 108static inline void olpc_prequirks(struct snd_card *card,
108 struct snd_ac97_template *ac97) { } 109 struct snd_ac97_template *ac97) { }
@@ -110,6 +111,7 @@ static inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
110{ 111{
111 return 0; 112 return 0;
112} 113}
114static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { }
113#endif 115#endif
114 116
115int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio); 117int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c
index f20e74182725..597395e6e358 100644
--- a/sound/pci/cs5535audio/cs5535audio_olpc.c
+++ b/sound/pci/cs5535audio/cs5535audio_olpc.c
@@ -7,12 +7,29 @@
7#include <asm/olpc.h> 7#include <asm/olpc.h>
8#include "cs5535audio.h" 8#include "cs5535audio.h"
9 9
10/* OLPC has an additional feature on top of regular AD1888 codec 10/*
11features. This is support for an analog input mode. This is a 11 * OLPC has an additional feature on top of the regular AD1888 codec features.
122 step process. First, to turn off the AD1888 codec bias voltage 12 * It has an Analog Input mode that is switched into (after disabling the
13and high pass filter. Second, to tell the embedded controller to 13 * High Pass Filter) via GPIO. It is supported on B2 and later models.
14reroute from a capacitive trace to a direct trace using an analog 14 */
15switch. The *_ec()s are what talk to that controller */ 15void olpc_analog_input(struct snd_ac97 *ac97, int on)
16{
17 int err;
18
19 /* update the High Pass Filter (via AC97_AD_TEST2) */
20 err = snd_ac97_update_bits(ac97, AC97_AD_TEST2,
21 1 << AC97_AD_HPFD_SHIFT, on << AC97_AD_HPFD_SHIFT);
22 if (err < 0) {
23 snd_printk(KERN_ERR "setting High Pass Filter - %d\n", err);
24 return;
25 }
26
27 /* set Analog Input through GPIO */
28 if (on)
29 geode_gpio_set(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
30 else
31 geode_gpio_clear(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
32}
16 33
17static int snd_cs5535audio_ctl_info(struct snd_kcontrol *kcontrol, 34static int snd_cs5535audio_ctl_info(struct snd_kcontrol *kcontrol,
18 struct snd_ctl_elem_info *uinfo) 35 struct snd_ctl_elem_info *uinfo)
@@ -24,8 +41,6 @@ static int snd_cs5535audio_ctl_info(struct snd_kcontrol *kcontrol,
24 return 0; 41 return 0;
25} 42}
26 43
27#define AD1888_VREFOUT_EN_BIT (1 << 2)
28#define AD1888_HPF_EN_BIT (1 << 12)
29static int snd_cs5535audio_ctl_get(struct snd_kcontrol *kcontrol, 44static int snd_cs5535audio_ctl_get(struct snd_kcontrol *kcontrol,
30 struct snd_ctl_elem_value *ucontrol) 45 struct snd_ctl_elem_value *ucontrol)
31{ 46{
@@ -42,30 +57,9 @@ static int snd_cs5535audio_ctl_get(struct snd_kcontrol *kcontrol,
42static int snd_cs5535audio_ctl_put(struct snd_kcontrol *kcontrol, 57static int snd_cs5535audio_ctl_put(struct snd_kcontrol *kcontrol,
43 struct snd_ctl_elem_value *ucontrol) 58 struct snd_ctl_elem_value *ucontrol)
44{ 59{
45 int err;
46 struct cs5535audio *cs5535au = snd_kcontrol_chip(kcontrol); 60 struct cs5535audio *cs5535au = snd_kcontrol_chip(kcontrol);
47 u8 value;
48 struct snd_ac97 *ac97 = cs5535au->ac97;
49
50 /* value is 1 if analog input is desired */
51 value = ucontrol->value.integer.value[0];
52
53 /* turns off High Pass Filter if 1 */
54 if (value)
55 err = snd_ac97_update_bits(ac97, AC97_AD_TEST2,
56 AD1888_HPF_EN_BIT, AD1888_HPF_EN_BIT);
57 else
58 err = snd_ac97_update_bits(ac97, AC97_AD_TEST2,
59 AD1888_HPF_EN_BIT, 0);
60 if (err < 0)
61 snd_printk(KERN_ERR "Error updating AD_TEST2 %d\n", err);
62
63 /* B2 and newer writes directly to a GPIO pin */
64 if (value)
65 geode_gpio_set(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
66 else
67 geode_gpio_clear(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
68 61
62 olpc_analog_input(cs5535au->ac97, ucontrol->value.integer.value[0]);
69 return 1; 63 return 1;
70} 64}
71 65