aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_hwdep.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-07-30 09:01:46 -0400
committerTakashi Iwai <tiwai@suse.de>2008-10-12 20:43:03 -0400
commit11aeff082ad9bd00e8475bf1630c3264344d3764 (patch)
treefc00a9f4ccaa392032f09acbbd7d460f2e4d17de /sound/pci/hda/hda_hwdep.c
parentd7ffba19ce4c1b153d502a89d829400bf76d6c11 (diff)
ALSA: hda - Add init_verbs entries
This patch enables the additional init verbs for each codec. The verbs can be entered via hwdep sysfs file. These verbs are executed at reconfiguring the codec for non-standard setups like overriding the pin-defcfg. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_hwdep.c')
-rw-r--r--sound/pci/hda/hda_hwdep.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 214772c8b556..f3400d75eba4 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -96,6 +96,17 @@ static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
96 return 0; 96 return 0;
97} 97}
98 98
99static void clear_hwdep_elements(struct hda_codec *codec)
100{
101 /* clear init verbs */
102 snd_array_free(&codec->init_verbs);
103}
104
105static void hwdep_free(struct snd_hwdep *hwdep)
106{
107 clear_hwdep_elements(hwdep->private_data);
108}
109
99int __devinit snd_hda_create_hwdep(struct hda_codec *codec) 110int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
100{ 111{
101 char hwname[16]; 112 char hwname[16];
@@ -110,6 +121,7 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
110 sprintf(hwdep->name, "HDA Codec %d", codec->addr); 121 sprintf(hwdep->name, "HDA Codec %d", codec->addr);
111 hwdep->iface = SNDRV_HWDEP_IFACE_HDA; 122 hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
112 hwdep->private_data = codec; 123 hwdep->private_data = codec;
124 hwdep->private_free = hwdep_free;
113 hwdep->exclusive = 1; 125 hwdep->exclusive = 1;
114 126
115 hwdep->ops.open = hda_hwdep_open; 127 hwdep->ops.open = hda_hwdep_open;
@@ -118,6 +130,8 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
118 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; 130 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
119#endif 131#endif
120 132
133 snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32);
134
121 return 0; 135 return 0;
122} 136}
123 137
@@ -128,6 +142,7 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
128static int clear_codec(struct hda_codec *codec) 142static int clear_codec(struct hda_codec *codec)
129{ 143{
130 snd_hda_codec_reset(codec); 144 snd_hda_codec_reset(codec);
145 clear_hwdep_elements(codec);
131 return 0; 146 return 0;
132} 147}
133 148
@@ -244,6 +259,27 @@ static ssize_t type##_store(struct device *dev, \
244CODEC_ACTION_STORE(reconfig); 259CODEC_ACTION_STORE(reconfig);
245CODEC_ACTION_STORE(clear); 260CODEC_ACTION_STORE(clear);
246 261
262static ssize_t init_verbs_store(struct device *dev,
263 struct device_attribute *attr,
264 const char *buf, size_t count)
265{
266 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
267 struct hda_codec *codec = hwdep->private_data;
268 char *p;
269 struct hda_verb verb, *v;
270
271 verb.nid = simple_strtoul(buf, &p, 0);
272 verb.verb = simple_strtoul(p, &p, 0);
273 verb.param = simple_strtoul(p, &p, 0);
274 if (!verb.nid || !verb.verb || !verb.param)
275 return -EINVAL;
276 v = snd_array_new(&codec->init_verbs);
277 if (!v)
278 return -ENOMEM;
279 *v = verb;
280 return count;
281}
282
247#define CODEC_ATTR_RW(type) \ 283#define CODEC_ATTR_RW(type) \
248 __ATTR(type, 0644, type##_show, type##_store) 284 __ATTR(type, 0644, type##_show, type##_store)
249#define CODEC_ATTR_RO(type) \ 285#define CODEC_ATTR_RO(type) \
@@ -259,6 +295,7 @@ static struct device_attribute codec_attrs[] = {
259 CODEC_ATTR_RO(mfg), 295 CODEC_ATTR_RO(mfg),
260 CODEC_ATTR_RW(name), 296 CODEC_ATTR_RW(name),
261 CODEC_ATTR_RW(modelname), 297 CODEC_ATTR_RW(modelname),
298 CODEC_ATTR_WO(init_verbs),
262 CODEC_ATTR_WO(reconfig), 299 CODEC_ATTR_WO(reconfig),
263 CODEC_ATTR_WO(clear), 300 CODEC_ATTR_WO(clear),
264}; 301};