1 From: Takashi Iwai <tiwai@suse.de>
2 Subject: ALSA: hda - Add digital beep support
3 Patch-mainline: 2.6.28-rc1
4 References: bnc#398459, bnc#398455
6 Add the support of digital beep for devices without analog beep.
8 Signed-off-by: Takashi Iwai <tiwai@suse.de>
11 diff -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
16 + * Digital Beep Input Interface for HD-audio codec
18 + * Author: Matthew Ranostay <mranostay@embeddedalley.com>
19 + * Copyright (c) 2008 Embedded Alley Solutions Inc
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.
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.
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
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"
43 + DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */
44 + DIGBEEP_HZ_MIN = 93750, /* 93.750 Hz */
45 + DIGBEEP_HZ_MAX = 12000000, /* 12 KHz */
48 +static void snd_hda_generate_beep(struct work_struct *work)
50 + struct hda_beep *beep =
51 + container_of(work, struct hda_beep, beep_work);
52 + struct hda_codec *codec = beep->codec;
55 + snd_hda_codec_write_cache(codec, beep->nid, 0,
56 + AC_VERB_SET_BEEP_CONTROL, beep->tone);
59 +static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
60 + unsigned int code, int hz)
62 + struct hda_beep *beep = input_get_drvdata(dev);
69 + hz *= 1000; /* fixed point */
70 + hz = hz - DIGBEEP_HZ_MIN;
72 + hz = 0; /* turn off PC beep*/
73 + else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
76 + hz /= DIGBEEP_HZ_STEP;
85 + /* schedule beep event */
86 + schedule_work(&beep->beep_work);
90 +int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
92 + struct input_dev *input_dev;
93 + struct hda_beep *beep;
96 + beep = kzalloc(sizeof(*beep), GFP_KERNEL);
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();
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;
108 + input_dev->id.vendor = codec->vendor_id >> 16;
109 + input_dev->id.product = codec->vendor_id & 0xffff;
110 + input_dev->id.version = 0x01;
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);
118 + err = input_register_device(input_dev);
120 + input_free_device(input_dev);
125 + /* enable linear scale */
126 + snd_hda_codec_write(codec, nid, 0,
127 + AC_VERB_SET_DIGI_CONVERT_2, 0x01);
130 + beep->dev = input_dev;
131 + beep->codec = codec;
132 + codec->beep = beep;
134 + INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
138 +void snd_hda_detach_beep_device(struct hda_codec *codec)
140 + struct hda_beep *beep = codec->beep;
142 + cancel_work_sync(&beep->beep_work);
143 + flush_scheduled_work();
145 + input_unregister_device(beep->dev);
149 diff -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
154 + * Digital Beep Input Interface for HD-audio codec
156 + * Author: Matthew Ranostay <mranostay@embeddedalley.com>
157 + * Copyright (c) 2008 Embedded Alley Solutions Inc
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.
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.
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
174 +#ifndef __SOUND_HDA_BEEP_H
175 +#define __SOUND_HDA_BEEP_H
177 +#include "hda_codec.h"
179 +/* beep information */
181 + struct input_dev *dev;
182 + struct hda_codec *codec;
186 + struct work_struct beep_work; /* scheduled task for beep event */
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);
193 +#define snd_hda_attach_beep_device(...)
194 +#define snd_hda_detach_beep_device(...)
197 diff -ruN a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
198 --- a/sound/pci/hda/Makefile
199 +++ b/sound/pci/hda/Makefile
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
208 diff -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
218 struct hda_pcm_stream;
220 /* codec specific info */
224 + struct hda_beep *beep;
226 /* widget capabilities cache */
227 unsigned int num_nodes;
229 diff -ruN a/sound/pci/Kconfig b/sound/pci/Kconfig
230 --- a/sound/pci/Kconfig
231 +++ b/sound/pci/Kconfig
233 This interface can be used for out-of-band communication
234 with codecs for debugging purposes.
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
241 + Say Y here to build a digital beep interface for HD-audio
242 + driver. This interface is used to generate digital beeps.
244 config SND_HDA_CODEC_REALTEK
245 bool "Build Realtek HD-audio codec support"
246 depends on SND_HDA_INTEL