Commit 5f17e79cdf530b1a6090c65730e5656ac9c19eaa

Authored by Johannes Berg
Committed by Takashi Iwai
1 parent 45e513b689

ALSA: snd-aoa: handle master-amp if present

Some machines have a master amp GPIO that needs to be toggled to
get sound output, in addition to speaker/headphone/line-out amps.
This makes snd-aoa handle it, if present in the device tree, thus
making snd-aoa be able to output sound on PowerMac3,6, which was
previously handled by snd-powermac which also doesn't use the
master amp GPIO.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

Showing 3 changed files with 25 additions and 1 deletions Side-by-side Diff

sound/aoa/aoa-gpio.h
... ... @@ -34,10 +34,12 @@
34 34 void (*set_headphone)(struct gpio_runtime *rt, int on);
35 35 void (*set_speakers)(struct gpio_runtime *rt, int on);
36 36 void (*set_lineout)(struct gpio_runtime *rt, int on);
  37 + void (*set_master)(struct gpio_runtime *rt, int on);
37 38  
38 39 int (*get_headphone)(struct gpio_runtime *rt);
39 40 int (*get_speakers)(struct gpio_runtime *rt);
40 41 int (*get_lineout)(struct gpio_runtime *rt);
  42 + int (*get_master)(struct gpio_runtime *rt);
41 43  
42 44 void (*set_hw_reset)(struct gpio_runtime *rt, int on);
43 45  
sound/aoa/core/gpio-feature.c
... ... @@ -14,7 +14,7 @@
14 14 #include <linux/interrupt.h>
15 15 #include "../aoa.h"
16 16  
17   -/* TODO: these are 20 global variables
  17 +/* TODO: these are lots of global variables
18 18 * that aren't used on most machines...
19 19 * Move them into a dynamically allocated
20 20 * structure and use that.
... ... @@ -23,6 +23,7 @@
23 23 /* these are the GPIO numbers (register addresses as offsets into
24 24 * the GPIO space) */
25 25 static int headphone_mute_gpio;
  26 +static int master_mute_gpio;
26 27 static int amp_mute_gpio;
27 28 static int lineout_mute_gpio;
28 29 static int hw_reset_gpio;
... ... @@ -32,6 +33,7 @@
32 33  
33 34 /* see the SWITCH_GPIO macro */
34 35 static int headphone_mute_gpio_activestate;
  36 +static int master_mute_gpio_activestate;
35 37 static int amp_mute_gpio_activestate;
36 38 static int lineout_mute_gpio_activestate;
37 39 static int hw_reset_gpio_activestate;
... ... @@ -156,6 +158,7 @@
156 158 FTR_GPIO(headphone, 0);
157 159 FTR_GPIO(amp, 1);
158 160 FTR_GPIO(lineout, 2);
  161 +FTR_GPIO(master, 3);
159 162  
160 163 static void ftr_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
161 164 {
... ... @@ -172,6 +175,8 @@
172 175 hw_reset_gpio, v);
173 176 }
174 177  
  178 +static struct gpio_methods methods;
  179 +
175 180 static void ftr_gpio_all_amps_off(struct gpio_runtime *rt)
176 181 {
177 182 int saved;
... ... @@ -181,6 +186,8 @@
181 186 ftr_gpio_set_headphone(rt, 0);
182 187 ftr_gpio_set_amp(rt, 0);
183 188 ftr_gpio_set_lineout(rt, 0);
  189 + if (methods.set_master)
  190 + ftr_gpio_set_master(rt, 0);
184 191 rt->implementation_private = saved;
185 192 }
186 193  
... ... @@ -193,6 +200,8 @@
193 200 ftr_gpio_set_headphone(rt, (s>>0)&1);
194 201 ftr_gpio_set_amp(rt, (s>>1)&1);
195 202 ftr_gpio_set_lineout(rt, (s>>2)&1);
  203 + if (methods.set_master)
  204 + ftr_gpio_set_master(rt, (s>>3)&1);
196 205 }
197 206  
198 207 static void ftr_handle_notify(struct work_struct *work)
... ... @@ -231,6 +240,12 @@
231 240 get_gpio("hw-reset", "audio-hw-reset",
232 241 &hw_reset_gpio,
233 242 &hw_reset_gpio_activestate);
  243 + if (get_gpio("master-mute", NULL,
  244 + &master_mute_gpio,
  245 + &master_mute_gpio_activestate)) {
  246 + methods.set_master = ftr_gpio_set_master;
  247 + methods.get_master = ftr_gpio_get_master;
  248 + }
234 249  
235 250 headphone_detect_node = get_gpio("headphone-detect", NULL,
236 251 &headphone_detect_gpio,
sound/aoa/fabrics/layout.c
... ... @@ -600,6 +600,7 @@
600 600 struct snd_kcontrol *headphone_ctrl;
601 601 struct snd_kcontrol *lineout_ctrl;
602 602 struct snd_kcontrol *speaker_ctrl;
  603 + struct snd_kcontrol *master_ctrl;
603 604 struct snd_kcontrol *headphone_detected_ctrl;
604 605 struct snd_kcontrol *lineout_detected_ctrl;
605 606  
... ... @@ -651,6 +652,7 @@
651 652 AMP_CONTROL(headphone, "Headphone Switch");
652 653 AMP_CONTROL(speakers, "Speakers Switch");
653 654 AMP_CONTROL(lineout, "Line-Out Switch");
  655 +AMP_CONTROL(master, "Master Switch");
654 656  
655 657 static int detect_choice_get(struct snd_kcontrol *kcontrol,
656 658 struct snd_ctl_elem_value *ucontrol)
... ... @@ -891,6 +893,11 @@
891 893 lineout = codec->gpio->methods->get_detect(codec->gpio,
892 894 AOA_NOTIFY_LINE_OUT);
893 895  
  896 + if (codec->gpio->methods->set_master) {
  897 + ctl = snd_ctl_new1(&master_ctl, codec->gpio);
  898 + ldev->master_ctrl = ctl;
  899 + aoa_snd_ctl_add(ctl);
  900 + }
894 901 while (cc->connected) {
895 902 if (cc->connected & CC_SPEAKERS) {
896 903 if (headphones <= 0 && lineout <= 0)