diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-07-04 03:12:50 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-07-04 03:12:50 -0400 |
commit | f68d891d85c8f9ab1af663ed3ceac18ad58dbabe (patch) | |
tree | d92db7af512307ab5282eb62f3dd1741ac71d21f /sound/pci | |
parent | 5780b627e24113323427c102175296ae43dfb9d7 (diff) | |
parent | 3fd877d32cac31292628fb8f443543fc1989b49b (diff) |
Merge branch 'topic/hda-beep' into topic/hda
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/es1968.c | 2 | ||||
-rw-r--r-- | sound/pci/fm801.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/Kconfig | 7 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.c | 82 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.h | 5 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 19 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 6 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 4 |
8 files changed, 49 insertions, 80 deletions
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 67f47d891959..52b5c0bf90c1 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -2769,7 +2769,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2769 | chip->tea.ops = &snd_es1968_tea_ops; | 2769 | chip->tea.ops = &snd_es1968_tea_ops; |
2770 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); | 2770 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); |
2771 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 2771 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
2772 | if (!snd_tea575x_init(&chip->tea)) | 2772 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) |
2773 | printk(KERN_INFO "es1968: detected TEA575x radio\n"); | 2773 | printk(KERN_INFO "es1968: detected TEA575x radio\n"); |
2774 | #endif | 2774 | #endif |
2775 | 2775 | ||
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index f69662322750..b32e8024ea86 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -1254,7 +1254,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1254 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 1254 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
1255 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && | 1255 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && |
1256 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { | 1256 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { |
1257 | if (snd_tea575x_init(&chip->tea)) { | 1257 | if (snd_tea575x_init(&chip->tea, THIS_MODULE)) { |
1258 | snd_printk(KERN_ERR "TEA575x radio not found\n"); | 1258 | snd_printk(KERN_ERR "TEA575x radio not found\n"); |
1259 | snd_fm801_free(chip); | 1259 | snd_fm801_free(chip); |
1260 | return -ENODEV; | 1260 | return -ENODEV; |
@@ -1263,7 +1263,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1263 | /* autodetect tuner connection */ | 1263 | /* autodetect tuner connection */ |
1264 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { | 1264 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { |
1265 | chip->tea575x_tuner = tea575x_tuner; | 1265 | chip->tea575x_tuner = tea575x_tuner; |
1266 | if (!snd_tea575x_init(&chip->tea)) { | 1266 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) { |
1267 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", | 1267 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", |
1268 | get_tea575x_gpio(chip)->name); | 1268 | get_tea575x_gpio(chip)->name); |
1269 | break; | 1269 | break; |
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index d03079764189..194d625c1f83 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -53,15 +53,14 @@ config SND_HDA_INPUT_BEEP | |||
53 | driver. This interface is used to generate digital beeps. | 53 | driver. This interface is used to generate digital beeps. |
54 | 54 | ||
55 | config SND_HDA_INPUT_BEEP_MODE | 55 | config SND_HDA_INPUT_BEEP_MODE |
56 | int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)" | 56 | int "Digital beep registration mode (0=off, 1=on)" |
57 | depends on SND_HDA_INPUT_BEEP=y | 57 | depends on SND_HDA_INPUT_BEEP=y |
58 | default "1" | 58 | default "1" |
59 | range 0 2 | 59 | range 0 1 |
60 | help | 60 | help |
61 | Set 0 to disable the digital beep interface for HD-audio by default. | 61 | Set 0 to disable the digital beep interface for HD-audio by default. |
62 | Set 1 to always enable the digital beep interface for HD-audio by | 62 | Set 1 to always enable the digital beep interface for HD-audio by |
63 | default. Set 2 to control the beep device registration to input | 63 | default. |
64 | layer using a "Beep Switch" in mixer applications. | ||
65 | 64 | ||
66 | config SND_HDA_INPUT_JACK | 65 | config SND_HDA_INPUT_JACK |
67 | bool "Support jack plugging notification via input layer" | 66 | bool "Support jack plugging notification via input layer" |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 60738e52b8f9..0bc2315b181d 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -162,50 +162,20 @@ static int snd_hda_do_attach(struct hda_beep *beep) | |||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | static void snd_hda_do_register(struct work_struct *work) | ||
166 | { | ||
167 | struct hda_beep *beep = | ||
168 | container_of(work, struct hda_beep, register_work); | ||
169 | |||
170 | mutex_lock(&beep->mutex); | ||
171 | if (beep->enabled && !beep->dev) | ||
172 | snd_hda_do_attach(beep); | ||
173 | mutex_unlock(&beep->mutex); | ||
174 | } | ||
175 | |||
176 | static void snd_hda_do_unregister(struct work_struct *work) | ||
177 | { | ||
178 | struct hda_beep *beep = | ||
179 | container_of(work, struct hda_beep, unregister_work.work); | ||
180 | |||
181 | mutex_lock(&beep->mutex); | ||
182 | if (!beep->enabled && beep->dev) | ||
183 | snd_hda_do_detach(beep); | ||
184 | mutex_unlock(&beep->mutex); | ||
185 | } | ||
186 | |||
187 | int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) | 165 | int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) |
188 | { | 166 | { |
189 | struct hda_beep *beep = codec->beep; | 167 | struct hda_beep *beep = codec->beep; |
190 | enable = !!enable; | 168 | if (!beep) |
191 | if (beep == NULL) | ||
192 | return 0; | 169 | return 0; |
170 | enable = !!enable; | ||
193 | if (beep->enabled != enable) { | 171 | if (beep->enabled != enable) { |
194 | beep->enabled = enable; | 172 | beep->enabled = enable; |
195 | if (!enable) { | 173 | if (!enable) { |
174 | cancel_work_sync(&beep->beep_work); | ||
196 | /* turn off beep */ | 175 | /* turn off beep */ |
197 | snd_hda_codec_write(beep->codec, beep->nid, 0, | 176 | snd_hda_codec_write(beep->codec, beep->nid, 0, |
198 | AC_VERB_SET_BEEP_CONTROL, 0); | 177 | AC_VERB_SET_BEEP_CONTROL, 0); |
199 | } | 178 | } |
200 | if (beep->mode == HDA_BEEP_MODE_SWREG) { | ||
201 | if (enable) { | ||
202 | cancel_delayed_work(&beep->unregister_work); | ||
203 | schedule_work(&beep->register_work); | ||
204 | } else { | ||
205 | schedule_delayed_work(&beep->unregister_work, | ||
206 | HZ); | ||
207 | } | ||
208 | } | ||
209 | return 1; | 179 | return 1; |
210 | } | 180 | } |
211 | return 0; | 181 | return 0; |
@@ -215,6 +185,7 @@ EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device); | |||
215 | int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | 185 | int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) |
216 | { | 186 | { |
217 | struct hda_beep *beep; | 187 | struct hda_beep *beep; |
188 | int err; | ||
218 | 189 | ||
219 | if (!snd_hda_get_bool_hint(codec, "beep")) | 190 | if (!snd_hda_get_bool_hint(codec, "beep")) |
220 | return 0; /* disabled explicitly by hints */ | 191 | return 0; /* disabled explicitly by hints */ |
@@ -232,21 +203,16 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | |||
232 | 203 | ||
233 | beep->nid = nid; | 204 | beep->nid = nid; |
234 | beep->codec = codec; | 205 | beep->codec = codec; |
235 | beep->mode = codec->beep_mode; | ||
236 | codec->beep = beep; | 206 | codec->beep = beep; |
237 | 207 | ||
238 | INIT_WORK(&beep->register_work, &snd_hda_do_register); | ||
239 | INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister); | ||
240 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); | 208 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); |
241 | mutex_init(&beep->mutex); | 209 | mutex_init(&beep->mutex); |
242 | 210 | ||
243 | if (beep->mode == HDA_BEEP_MODE_ON) { | 211 | err = snd_hda_do_attach(beep); |
244 | int err = snd_hda_do_attach(beep); | 212 | if (err < 0) { |
245 | if (err < 0) { | 213 | kfree(beep); |
246 | kfree(beep); | 214 | codec->beep = NULL; |
247 | codec->beep = NULL; | 215 | return err; |
248 | return err; | ||
249 | } | ||
250 | } | 216 | } |
251 | 217 | ||
252 | return 0; | 218 | return 0; |
@@ -257,8 +223,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
257 | { | 223 | { |
258 | struct hda_beep *beep = codec->beep; | 224 | struct hda_beep *beep = codec->beep; |
259 | if (beep) { | 225 | if (beep) { |
260 | cancel_work_sync(&beep->register_work); | ||
261 | cancel_delayed_work(&beep->unregister_work); | ||
262 | if (beep->dev) | 226 | if (beep->dev) |
263 | snd_hda_do_detach(beep); | 227 | snd_hda_do_detach(beep); |
264 | codec->beep = NULL; | 228 | codec->beep = NULL; |
@@ -266,3 +230,31 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
266 | } | 230 | } |
267 | } | 231 | } |
268 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); | 232 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); |
233 | |||
234 | /* get/put callbacks for beep mute mixer switches */ | ||
235 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | ||
236 | struct snd_ctl_elem_value *ucontrol) | ||
237 | { | ||
238 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
239 | struct hda_beep *beep = codec->beep; | ||
240 | if (beep) { | ||
241 | ucontrol->value.integer.value[0] = | ||
242 | ucontrol->value.integer.value[1] = | ||
243 | beep->enabled; | ||
244 | return 0; | ||
245 | } | ||
246 | return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | ||
247 | } | ||
248 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get_beep); | ||
249 | |||
250 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | ||
251 | struct snd_ctl_elem_value *ucontrol) | ||
252 | { | ||
253 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
254 | struct hda_beep *beep = codec->beep; | ||
255 | if (beep) | ||
256 | snd_hda_enable_beep_device(codec, | ||
257 | *ucontrol->value.integer.value); | ||
258 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
259 | } | ||
260 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); | ||
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 55f0647458c7..4dc6933bc655 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -26,21 +26,16 @@ | |||
26 | 26 | ||
27 | #define HDA_BEEP_MODE_OFF 0 | 27 | #define HDA_BEEP_MODE_OFF 0 |
28 | #define HDA_BEEP_MODE_ON 1 | 28 | #define HDA_BEEP_MODE_ON 1 |
29 | #define HDA_BEEP_MODE_SWREG 2 | ||
30 | 29 | ||
31 | /* beep information */ | 30 | /* beep information */ |
32 | struct hda_beep { | 31 | struct hda_beep { |
33 | struct input_dev *dev; | 32 | struct input_dev *dev; |
34 | struct hda_codec *codec; | 33 | struct hda_codec *codec; |
35 | unsigned int mode; | ||
36 | char phys[32]; | 34 | char phys[32]; |
37 | int tone; | 35 | int tone; |
38 | hda_nid_t nid; | 36 | hda_nid_t nid; |
39 | unsigned int enabled:1; | 37 | unsigned int enabled:1; |
40 | unsigned int request_enable:1; | ||
41 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ | 38 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ |
42 | struct work_struct register_work; /* registration work */ | ||
43 | struct delayed_work unregister_work; /* unregistration work */ | ||
44 | struct work_struct beep_work; /* scheduled task for beep event */ | 39 | struct work_struct beep_work; /* scheduled task for beep event */ |
45 | struct mutex mutex; | 40 | struct mutex mutex; |
46 | }; | 41 | }; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 14bc1c8f5326..20580bf69697 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -2676,25 +2676,6 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | |||
2676 | } | 2676 | } |
2677 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); | 2677 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); |
2678 | 2678 | ||
2679 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
2680 | /** | ||
2681 | * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch | ||
2682 | * | ||
2683 | * This function calls snd_hda_enable_beep_device(), which behaves differently | ||
2684 | * depending on beep_mode option. | ||
2685 | */ | ||
2686 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | ||
2687 | struct snd_ctl_elem_value *ucontrol) | ||
2688 | { | ||
2689 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2690 | long *valp = ucontrol->value.integer.value; | ||
2691 | |||
2692 | snd_hda_enable_beep_device(codec, *valp); | ||
2693 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
2694 | } | ||
2695 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); | ||
2696 | #endif /* CONFIG_SND_HDA_INPUT_BEEP */ | ||
2697 | |||
2698 | /* | 2679 | /* |
2699 | * bound volume controls | 2680 | * bound volume controls |
2700 | * | 2681 | * |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 86758dded981..796472d1ff5a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -72,7 +72,7 @@ static int enable_msi = -1; | |||
72 | static char *patch[SNDRV_CARDS]; | 72 | static char *patch[SNDRV_CARDS]; |
73 | #endif | 73 | #endif |
74 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 74 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
75 | static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = | 75 | static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = |
76 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; | 76 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; |
77 | #endif | 77 | #endif |
78 | 78 | ||
@@ -103,9 +103,9 @@ module_param_array(patch, charp, NULL, 0444); | |||
103 | MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); | 103 | MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); |
104 | #endif | 104 | #endif |
105 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 105 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
106 | module_param_array(beep_mode, int, NULL, 0444); | 106 | module_param_array(beep_mode, bool, NULL, 0444); |
107 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " | 107 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " |
108 | "(0=off, 1=on, 2=mute switch on/off) (default=1)."); | 108 | "(0=off, 1=on) (default=1)."); |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 111 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 9a096a8e0fc5..1b4c12941baa 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -89,7 +89,7 @@ | |||
89 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 89 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
90 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ | 90 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ |
91 | .info = snd_hda_mixer_amp_switch_info, \ | 91 | .info = snd_hda_mixer_amp_switch_info, \ |
92 | .get = snd_hda_mixer_amp_switch_get, \ | 92 | .get = snd_hda_mixer_amp_switch_get_beep, \ |
93 | .put = snd_hda_mixer_amp_switch_put_beep, \ | 93 | .put = snd_hda_mixer_amp_switch_put_beep, \ |
94 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | 94 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } |
95 | #else | 95 | #else |
@@ -121,6 +121,8 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, | |||
121 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | 121 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, |
122 | struct snd_ctl_elem_value *ucontrol); | 122 | struct snd_ctl_elem_value *ucontrol); |
123 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 123 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
124 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | ||
125 | struct snd_ctl_elem_value *ucontrol); | ||
124 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | 126 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, |
125 | struct snd_ctl_elem_value *ucontrol); | 127 | struct snd_ctl_elem_value *ucontrol); |
126 | #endif | 128 | #endif |