aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_hwdep.c
diff options
context:
space:
mode:
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};