]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.drivers/alsa-hda-beep
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / alsa-hda-beep
CommitLineData
2cb7cef9
BS
1From: Takashi Iwai <tiwai@suse.de>
2Subject: ALSA: hda - Add digital beep support
3Patch-mainline: 2.6.28-rc1
4References: bnc#398459, bnc#398455
5
6Add the support of digital beep for devices without analog beep.
7
8Signed-off-by: Takashi Iwai <tiwai@suse.de>
9
10---
11diff -ruN a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
12--- a/sound/pci/hda/hda_beep.c
13+++ b/sound/pci/hda/hda_beep.c
14@@ -0,0 +1,134 @@
15+/*
16+ * Digital Beep Input Interface for HD-audio codec
17+ *
18+ * Author: Matthew Ranostay <mranostay@embeddedalley.com>
19+ * Copyright (c) 2008 Embedded Alley Solutions Inc
20+ *
21+ * This driver is free software; you can redistribute it and/or modify
22+ * it under the terms of the GNU General Public License as published by
23+ * the Free Software Foundation; either version 2 of the License, or
24+ * (at your option) any later version.
25+ *
26+ * This driver is distributed in the hope that it will be useful,
27+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29+ * GNU General Public License for more details.
30+ *
31+ * You should have received a copy of the GNU General Public License
32+ * along with this program; if not, write to the Free Software
33+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34+ */
35+
36+#include <linux/input.h>
37+#include <linux/pci.h>
38+#include <linux/workqueue.h>
39+#include <sound/core.h>
40+#include "hda_beep.h"
41+
42+enum {
43+ DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */
44+ DIGBEEP_HZ_MIN = 93750, /* 93.750 Hz */
45+ DIGBEEP_HZ_MAX = 12000000, /* 12 KHz */
46+};
47+
48+static void snd_hda_generate_beep(struct work_struct *work)
49+{
50+ struct hda_beep *beep =
51+ container_of(work, struct hda_beep, beep_work);
52+ struct hda_codec *codec = beep->codec;
53+
54+ /* generate tone */
55+ snd_hda_codec_write_cache(codec, beep->nid, 0,
56+ AC_VERB_SET_BEEP_CONTROL, beep->tone);
57+}
58+
59+static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
60+ unsigned int code, int hz)
61+{
62+ struct hda_beep *beep = input_get_drvdata(dev);
63+
64+ switch (code) {
65+ case SND_BELL:
66+ if (hz)
67+ hz = 1000;
68+ case SND_TONE:
69+ hz *= 1000; /* fixed point */
70+ hz = hz - DIGBEEP_HZ_MIN;
71+ if (hz < 0)
72+ hz = 0; /* turn off PC beep*/
73+ else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
74+ hz = 0xff;
75+ else {
76+ hz /= DIGBEEP_HZ_STEP;
77+ hz++;
78+ }
79+ break;
80+ default:
81+ return -1;
82+ }
83+ beep->tone = hz;
84+
85+ /* schedule beep event */
86+ schedule_work(&beep->beep_work);
87+ return 0;
88+}
89+
90+int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
91+{
92+ struct input_dev *input_dev;
93+ struct hda_beep *beep;
94+ int err;
95+
96+ beep = kzalloc(sizeof(*beep), GFP_KERNEL);
97+ if (beep == NULL)
98+ return -ENOMEM;
99+ snprintf(beep->phys, sizeof(beep->phys),
100+ "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
101+ input_dev = input_allocate_device();
102+
103+ /* setup digital beep device */
104+ input_dev->name = "HDA Digital PCBeep";
105+ input_dev->phys = beep->phys;
106+ input_dev->id.bustype = BUS_PCI;
107+
108+ input_dev->id.vendor = codec->vendor_id >> 16;
109+ input_dev->id.product = codec->vendor_id & 0xffff;
110+ input_dev->id.version = 0x01;
111+
112+ input_dev->evbit[0] = BIT_MASK(EV_SND);
113+ input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
114+ input_dev->event = snd_hda_beep_event;
115+ input_dev->dev.parent = &codec->bus->pci->dev;
116+ input_set_drvdata(input_dev, beep);
117+
118+ err = input_register_device(input_dev);
119+ if (err < 0) {
120+ input_free_device(input_dev);
121+ kfree(beep);
122+ return err;
123+ }
124+
125+ /* enable linear scale */
126+ snd_hda_codec_write(codec, nid, 0,
127+ AC_VERB_SET_DIGI_CONVERT_2, 0x01);
128+
129+ beep->nid = nid;
130+ beep->dev = input_dev;
131+ beep->codec = codec;
132+ codec->beep = beep;
133+
134+ INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
135+ return 0;
136+}
137+
138+void snd_hda_detach_beep_device(struct hda_codec *codec)
139+{
140+ struct hda_beep *beep = codec->beep;
141+ if (beep) {
142+ cancel_work_sync(&beep->beep_work);
143+ flush_scheduled_work();
144+
145+ input_unregister_device(beep->dev);
146+ kfree(beep);
147+ }
148+}
149diff -ruN a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
150--- a/sound/pci/hda/hda_beep.h
151+++ b/sound/pci/hda/hda_beep.h
152@@ -0,0 +1,44 @@
153+/*
154+ * Digital Beep Input Interface for HD-audio codec
155+ *
156+ * Author: Matthew Ranostay <mranostay@embeddedalley.com>
157+ * Copyright (c) 2008 Embedded Alley Solutions Inc
158+ *
159+ * This driver is free software; you can redistribute it and/or modify
160+ * it under the terms of the GNU General Public License as published by
161+ * the Free Software Foundation; either version 2 of the License, or
162+ * (at your option) any later version.
163+ *
164+ * This driver is distributed in the hope that it will be useful,
165+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
166+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
167+ * GNU General Public License for more details.
168+ *
169+ * You should have received a copy of the GNU General Public License
170+ * along with this program; if not, write to the Free Software
171+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
172+ */
173+
174+#ifndef __SOUND_HDA_BEEP_H
175+#define __SOUND_HDA_BEEP_H
176+
177+#include "hda_codec.h"
178+
179+/* beep information */
180+struct hda_beep {
181+ struct input_dev *dev;
182+ struct hda_codec *codec;
183+ char phys[32];
184+ int tone;
185+ int nid;
186+ struct work_struct beep_work; /* scheduled task for beep event */
187+};
188+
189+#ifdef CONFIG_SND_HDA_INPUT_BEEP
190+int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
191+void snd_hda_detach_beep_device(struct hda_codec *codec);
192+#else
193+#define snd_hda_attach_beep_device(...)
194+#define snd_hda_detach_beep_device(...)
195+#endif
196+#endif
197diff -ruN a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
198--- a/sound/pci/hda/Makefile
199+++ b/sound/pci/hda/Makefile
200@@ -5,6 +5,7 @@
201 snd-hda-intel-y += hda_codec.o
202 snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o
203 snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
204+snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
205 snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
206 snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o
207 snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o
208diff -ruN a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
209--- a/sound/pci/hda/hda_codec.h
210+++ b/sound/pci/hda/hda_codec.h
211@@ -449,6 +449,7 @@
212 */
213
214 struct hda_bus;
215+struct hda_beep;
216 struct hda_codec;
217 struct hda_pcm;
218 struct hda_pcm_stream;
219@@ -634,6 +635,9 @@
220 /* codec specific info */
221 void *spec;
222
223+ /* beep device */
224+ struct hda_beep *beep;
225+
226 /* widget capabilities cache */
227 unsigned int num_nodes;
228 hda_nid_t start_nid;
229diff -ruN a/sound/pci/Kconfig b/sound/pci/Kconfig
230--- a/sound/pci/Kconfig
231+++ b/sound/pci/Kconfig
232@@ -517,6 +517,14 @@
233 This interface can be used for out-of-band communication
234 with codecs for debugging purposes.
235
236+config SND_HDA_INPUT_BEEP
237+ bool "Support digital beep via input layer"
238+ depends on SND_HDA_INTEL
239+ depends on INPUT=y || INPUT=SND_HDA_INTEL
240+ help
241+ Say Y here to build a digital beep interface for HD-audio
242+ driver. This interface is used to generate digital beeps.
243+
244 config SND_HDA_CODEC_REALTEK
245 bool "Build Realtek HD-audio codec support"
246 depends on SND_HDA_INTEL