ALSA: hda - Add forgotten module alias for Nvidia MCP67 HDMI
[linux-2.6] / sound / core / vmaster.c
1 /*
2  * Virtual master and slave controls
3  *
4  *  Copyright (c) 2008 by Takashi Iwai <tiwai@suse.de>
5  *
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License as
8  *  published by the Free Software Foundation, version 2.
9  *
10  */
11
12 #include <linux/slab.h>
13 #include <sound/core.h>
14 #include <sound/control.h>
15 #include <sound/tlv.h>
16
17 /*
18  * a subset of information returned via ctl info callback
19  */
20 struct link_ctl_info {
21         int type;               /* value type */
22         int count;              /* item count */
23         int min_val, max_val;   /* min, max values */
24 };
25
26 /*
27  * link master - this contains a list of slave controls that are
28  * identical types, i.e. info returns the same value type and value
29  * ranges, but may have different number of counts.
30  *
31  * The master control is so far only mono volume/switch for simplicity.
32  * The same value will be applied to all slaves.
33  */
34 struct link_master {
35         struct list_head slaves;
36         struct link_ctl_info info;
37         int val;                /* the master value */
38         unsigned int tlv[4];
39 };
40
41 /*
42  * link slave - this contains a slave control element
43  *
44  * It fakes the control callbacsk with additional attenuation by the
45  * master control.  A slave may have either one or two channels.
46  */
47
48 struct link_slave {
49         struct list_head list;
50         struct link_master *master;
51         struct link_ctl_info info;
52         int vals[2];            /* current values */
53         struct snd_kcontrol slave; /* the copy of original control entry */
54 };
55
56 /* get the slave ctl info and save the initial values */
57 static int slave_init(struct link_slave *slave)
58 {
59         struct snd_ctl_elem_info *uinfo;
60         struct snd_ctl_elem_value *uctl;
61         int err, ch;
62
63         if (slave->info.count)
64                 return 0; /* already initialized */
65
66         uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL);
67         if (!uinfo)
68                 return -ENOMEM;
69         uinfo->id = slave->slave.id;
70         err = slave->slave.info(&slave->slave, uinfo);
71         if (err < 0) {
72                 kfree(uinfo);
73                 return err;
74         }
75         slave->info.type = uinfo->type;
76         slave->info.count = uinfo->count;
77         if (slave->info.count > 2  ||
78             (slave->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER &&
79              slave->info.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN)) {
80                 snd_printk(KERN_ERR "invalid slave element\n");
81                 kfree(uinfo);
82                 return -EINVAL;
83         }
84         slave->info.min_val = uinfo->value.integer.min;
85         slave->info.max_val = uinfo->value.integer.max;
86         kfree(uinfo);
87
88         uctl = kmalloc(sizeof(*uctl), GFP_KERNEL);
89         if (!uctl)
90                 return -ENOMEM;
91         uctl->id = slave->slave.id;
92         err = slave->slave.get(&slave->slave, uctl);
93         for (ch = 0; ch < slave->info.count; ch++)
94                 slave->vals[ch] = uctl->value.integer.value[ch];
95         kfree(uctl);
96         return 0;
97 }
98
99 /* initialize master volume */
100 static int master_init(struct link_master *master)
101 {
102         struct link_slave *slave;
103
104         if (master->info.count)
105                 return 0; /* already initialized */
106
107         list_for_each_entry(slave, &master->slaves, list) {
108                 int err = slave_init(slave);
109                 if (err < 0)
110                         return err;
111                 master->info = slave->info;
112                 master->info.count = 1; /* always mono */
113                 /* set full volume as default (= no attenuation) */
114                 master->val = master->info.max_val;
115                 return 0;
116         }
117         return -ENOENT;
118 }
119
120 static int slave_get_val(struct link_slave *slave,
121                          struct snd_ctl_elem_value *ucontrol)
122 {
123         int err, ch;
124
125         err = slave_init(slave);
126         if (err < 0)
127                 return err;
128         for (ch = 0; ch < slave->info.count; ch++)
129                 ucontrol->value.integer.value[ch] = slave->vals[ch];
130         return 0;
131 }
132
133 static int slave_put_val(struct link_slave *slave,
134                          struct snd_ctl_elem_value *ucontrol)
135 {
136         int err, ch, vol;
137
138         err = master_init(slave->master);
139         if (err < 0)
140                 return err;
141
142         switch (slave->info.type) {
143         case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
144                 for (ch = 0; ch < slave->info.count; ch++)
145                         ucontrol->value.integer.value[ch] &=
146                                 !!slave->master->val;
147                 break;
148         case SNDRV_CTL_ELEM_TYPE_INTEGER:
149                 for (ch = 0; ch < slave->info.count; ch++) {
150                         /* max master volume is supposed to be 0 dB */
151                         vol = ucontrol->value.integer.value[ch];
152                         vol += slave->master->val - slave->master->info.max_val;
153                         if (vol < slave->info.min_val)
154                                 vol = slave->info.min_val;
155                         else if (vol > slave->info.max_val)
156                                 vol = slave->info.max_val;
157                         ucontrol->value.integer.value[ch] = vol;
158                 }
159                 break;
160         }
161         return slave->slave.put(&slave->slave, ucontrol);
162 }
163
164 /*
165  * ctl callbacks for slaves
166  */
167 static int slave_info(struct snd_kcontrol *kcontrol,
168                       struct snd_ctl_elem_info *uinfo)
169 {
170         struct link_slave *slave = snd_kcontrol_chip(kcontrol);
171         return slave->slave.info(&slave->slave, uinfo);
172 }
173
174 static int slave_get(struct snd_kcontrol *kcontrol,
175                      struct snd_ctl_elem_value *ucontrol)
176 {
177         struct link_slave *slave = snd_kcontrol_chip(kcontrol);
178         return slave_get_val(slave, ucontrol);
179 }
180
181 static int slave_put(struct snd_kcontrol *kcontrol,
182                      struct snd_ctl_elem_value *ucontrol)
183 {
184         struct link_slave *slave = snd_kcontrol_chip(kcontrol);
185         int err, ch, changed = 0;
186
187         err = slave_init(slave);
188         if (err < 0)
189                 return err;
190         for (ch = 0; ch < slave->info.count; ch++) {
191                 if (slave->vals[ch] != ucontrol->value.integer.value[ch]) {
192                         changed = 1;
193                         slave->vals[ch] = ucontrol->value.integer.value[ch];
194                 }
195         }
196         if (!changed)
197                 return 0;
198         return slave_put_val(slave, ucontrol);
199 }
200
201 static int slave_tlv_cmd(struct snd_kcontrol *kcontrol,
202                          int op_flag, unsigned int size,
203                          unsigned int __user *tlv)
204 {
205         struct link_slave *slave = snd_kcontrol_chip(kcontrol);
206         /* FIXME: this assumes that the max volume is 0 dB */
207         return slave->slave.tlv.c(&slave->slave, op_flag, size, tlv);
208 }
209
210 static void slave_free(struct snd_kcontrol *kcontrol)
211 {
212         struct link_slave *slave = snd_kcontrol_chip(kcontrol);
213         if (slave->slave.private_free)
214                 slave->slave.private_free(&slave->slave);
215         if (slave->master)
216                 list_del(&slave->list);
217         kfree(slave);
218 }
219
220 /*
221  * Add a slave control to the group with the given master control
222  *
223  * All slaves must be the same type (returning the same information
224  * via info callback).  The fucntion doesn't check it, so it's your
225  * responsibility.
226  *
227  * Also, some additional limitations:
228  * - at most two channels
229  * - logarithmic volume control (dB level), no linear volume
230  * - master can only attenuate the volume, no gain
231  */
232 int snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave)
233 {
234         struct link_master *master_link = snd_kcontrol_chip(master);
235         struct link_slave *srec;
236
237         srec = kzalloc(sizeof(*srec) +
238                        slave->count * sizeof(*slave->vd), GFP_KERNEL);
239         if (!srec)
240                 return -ENOMEM;
241         srec->slave = *slave;
242         memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd));
243         srec->master = master_link;
244
245         /* override callbacks */
246         slave->info = slave_info;
247         slave->get = slave_get;
248         slave->put = slave_put;
249         if (slave->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK)
250                 slave->tlv.c = slave_tlv_cmd;
251         slave->private_data = srec;
252         slave->private_free = slave_free;
253
254         list_add_tail(&srec->list, &master_link->slaves);
255         return 0;
256 }
257
258 EXPORT_SYMBOL(snd_ctl_add_slave);
259
260 /*
261  * ctl callbacks for master controls
262  */
263 static int master_info(struct snd_kcontrol *kcontrol,
264                       struct snd_ctl_elem_info *uinfo)
265 {
266         struct link_master *master = snd_kcontrol_chip(kcontrol);
267         int ret;
268
269         ret = master_init(master);
270         if (ret < 0)
271                 return ret;
272         uinfo->type = master->info.type;
273         uinfo->count = master->info.count;
274         uinfo->value.integer.min = master->info.min_val;
275         uinfo->value.integer.max = master->info.max_val;
276         return 0;
277 }
278
279 static int master_get(struct snd_kcontrol *kcontrol,
280                       struct snd_ctl_elem_value *ucontrol)
281 {
282         struct link_master *master = snd_kcontrol_chip(kcontrol);
283         int err = master_init(master);
284         if (err < 0)
285                 return err;
286         ucontrol->value.integer.value[0] = master->val;
287         return 0;
288 }
289
290 static int master_put(struct snd_kcontrol *kcontrol,
291                       struct snd_ctl_elem_value *ucontrol)
292 {
293         struct link_master *master = snd_kcontrol_chip(kcontrol);
294         struct link_slave *slave;
295         struct snd_ctl_elem_value *uval;
296         int err, old_val;
297
298         err = master_init(master);
299         if (err < 0)
300                 return err;
301         old_val = master->val;
302         if (ucontrol->value.integer.value[0] == old_val)
303                 return 0;
304
305         uval = kmalloc(sizeof(*uval), GFP_KERNEL);
306         if (!uval)
307                 return -ENOMEM;
308         list_for_each_entry(slave, &master->slaves, list) {
309                 master->val = old_val;
310                 uval->id = slave->slave.id;
311                 slave_get_val(slave, uval);
312                 master->val = ucontrol->value.integer.value[0];
313                 slave_put_val(slave, uval);
314         }
315         kfree(uval);
316         return 1;
317 }
318
319 static void master_free(struct snd_kcontrol *kcontrol)
320 {
321         struct link_master *master = snd_kcontrol_chip(kcontrol);
322         struct link_slave *slave;
323
324         list_for_each_entry(slave, &master->slaves, list)
325                 slave->master = NULL;
326         kfree(master);
327 }
328
329
330 /*
331  * Create a virtual master control with the given name
332  */
333 struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
334                                                  const unsigned int *tlv)
335 {
336         struct link_master *master;
337         struct snd_kcontrol *kctl;
338         struct snd_kcontrol_new knew;
339
340         memset(&knew, 0, sizeof(knew));
341         knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
342         knew.name = name;
343         knew.info = master_info;
344
345         master = kzalloc(sizeof(*master), GFP_KERNEL);
346         if (!master)
347                 return NULL;
348         INIT_LIST_HEAD(&master->slaves);
349
350         kctl = snd_ctl_new1(&knew, master);
351         if (!kctl) {
352                 kfree(master);
353                 return NULL;
354         }
355         /* override some callbacks */
356         kctl->info = master_info;
357         kctl->get = master_get;
358         kctl->put = master_put;
359         kctl->private_free = master_free;
360
361         /* additional (constant) TLV read */
362         if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) {
363                 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
364                 memcpy(master->tlv, tlv, sizeof(master->tlv));
365                 kctl->tlv.p = master->tlv;
366         }
367
368         return kctl;
369 }
370
371 EXPORT_SYMBOL(snd_ctl_make_virtual_master);