aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-01-12 08:05:50 -0500
committerTakashi Iwai <tiwai@suse.de>2009-01-12 08:05:50 -0500
commit9229f43f48d1b454a4e8b83985d0195b1760a550 (patch)
tree603bbbffb49d3243997de39310ce4c55861ddc92
parentc59765042f53a79a7a65585042ff463b69cb248c (diff)
parentc6d1662b229410e64092fe3a9caed6535fb3dc65 (diff)
Merge branch 'topic/asoc' into for-linus
-rw-r--r--include/sound/soc-dapm.h2
-rw-r--r--include/sound/soc.h15
-rw-r--r--sound/soc/codecs/twl4030.c12
-rw-r--r--sound/soc/soc-core.c37
-rw-r--r--sound/soc/soc-dapm.c80
5 files changed, 16 insertions, 130 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 4af1083e3287..93a4edb148b5 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -178,7 +178,7 @@
178 .private_value = (unsigned long)&xenum } 178 .private_value = (unsigned long)&xenum }
179#define SOC_DAPM_VALUE_ENUM(xname, xenum) \ 179#define SOC_DAPM_VALUE_ENUM(xname, xenum) \
180{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 180{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
181 .info = snd_soc_info_value_enum_double, \ 181 .info = snd_soc_info_enum_double, \
182 .get = snd_soc_dapm_get_value_enum_double, \ 182 .get = snd_soc_dapm_get_value_enum_double, \
183 .put = snd_soc_dapm_put_value_enum_double, \ 183 .put = snd_soc_dapm_put_value_enum_double, \
184 .private_value = (unsigned long)&xenum } 184 .private_value = (unsigned long)&xenum }
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 9b930d342116..24593ac3ea19 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -106,7 +106,7 @@
106 .private_value = (unsigned long)&xenum } 106 .private_value = (unsigned long)&xenum }
107#define SOC_VALUE_ENUM(xname, xenum) \ 107#define SOC_VALUE_ENUM(xname, xenum) \
108{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\ 108{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
109 .info = snd_soc_info_value_enum_double, \ 109 .info = snd_soc_info_enum_double, \
110 .get = snd_soc_get_value_enum_double, \ 110 .get = snd_soc_get_value_enum_double, \
111 .put = snd_soc_put_value_enum_double, \ 111 .put = snd_soc_put_value_enum_double, \
112 .private_value = (unsigned long)&xenum } 112 .private_value = (unsigned long)&xenum }
@@ -211,8 +211,6 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
211 struct snd_ctl_elem_value *ucontrol); 211 struct snd_ctl_elem_value *ucontrol);
212int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, 212int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_value *ucontrol); 213 struct snd_ctl_elem_value *ucontrol);
214int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
215 struct snd_ctl_elem_info *uinfo);
216int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol, 214int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
217 struct snd_ctl_elem_value *ucontrol); 215 struct snd_ctl_elem_value *ucontrol);
218int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol, 216int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
@@ -419,17 +417,6 @@ struct soc_enum {
419 unsigned char shift_l; 417 unsigned char shift_l;
420 unsigned char shift_r; 418 unsigned char shift_r;
421 unsigned int max; 419 unsigned int max;
422 const char **texts;
423 void *dapm;
424};
425
426/* semi enumerated kcontrol */
427struct soc_value_enum {
428 unsigned short reg;
429 unsigned short reg2;
430 unsigned char shift_l;
431 unsigned char shift_r;
432 unsigned int max;
433 unsigned int mask; 420 unsigned int mask;
434 const char **texts; 421 const char **texts;
435 const unsigned int *values; 422 const unsigned int *values;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index fd0f338374a7..ea370a4f86d5 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -197,7 +197,7 @@ static const char *twl4030_earpiece_texts[] =
197static const unsigned int twl4030_earpiece_values[] = 197static const unsigned int twl4030_earpiece_values[] =
198 {0x0, 0x1, 0x2, 0x4}; 198 {0x0, 0x1, 0x2, 0x4};
199 199
200static const struct soc_value_enum twl4030_earpiece_enum = 200static const struct soc_enum twl4030_earpiece_enum =
201 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7, 201 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
202 ARRAY_SIZE(twl4030_earpiece_texts), 202 ARRAY_SIZE(twl4030_earpiece_texts),
203 twl4030_earpiece_texts, 203 twl4030_earpiece_texts,
@@ -213,7 +213,7 @@ static const char *twl4030_predrivel_texts[] =
213static const unsigned int twl4030_predrivel_values[] = 213static const unsigned int twl4030_predrivel_values[] =
214 {0x0, 0x1, 0x2, 0x4}; 214 {0x0, 0x1, 0x2, 0x4};
215 215
216static const struct soc_value_enum twl4030_predrivel_enum = 216static const struct soc_enum twl4030_predrivel_enum =
217 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7, 217 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
218 ARRAY_SIZE(twl4030_predrivel_texts), 218 ARRAY_SIZE(twl4030_predrivel_texts),
219 twl4030_predrivel_texts, 219 twl4030_predrivel_texts,
@@ -229,7 +229,7 @@ static const char *twl4030_predriver_texts[] =
229static const unsigned int twl4030_predriver_values[] = 229static const unsigned int twl4030_predriver_values[] =
230 {0x0, 0x1, 0x2, 0x4}; 230 {0x0, 0x1, 0x2, 0x4};
231 231
232static const struct soc_value_enum twl4030_predriver_enum = 232static const struct soc_enum twl4030_predriver_enum =
233 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7, 233 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
234 ARRAY_SIZE(twl4030_predriver_texts), 234 ARRAY_SIZE(twl4030_predriver_texts),
235 twl4030_predriver_texts, 235 twl4030_predriver_texts,
@@ -317,7 +317,7 @@ static const char *twl4030_analoglmic_texts[] =
317static const unsigned int twl4030_analoglmic_values[] = 317static const unsigned int twl4030_analoglmic_values[] =
318 {0x0, 0x1, 0x2, 0x4, 0x8}; 318 {0x0, 0x1, 0x2, 0x4, 0x8};
319 319
320static const struct soc_value_enum twl4030_analoglmic_enum = 320static const struct soc_enum twl4030_analoglmic_enum =
321 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf, 321 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf,
322 ARRAY_SIZE(twl4030_analoglmic_texts), 322 ARRAY_SIZE(twl4030_analoglmic_texts),
323 twl4030_analoglmic_texts, 323 twl4030_analoglmic_texts,
@@ -333,7 +333,7 @@ static const char *twl4030_analogrmic_texts[] =
333static const unsigned int twl4030_analogrmic_values[] = 333static const unsigned int twl4030_analogrmic_values[] =
334 {0x0, 0x1, 0x4}; 334 {0x0, 0x1, 0x4};
335 335
336static const struct soc_value_enum twl4030_analogrmic_enum = 336static const struct soc_enum twl4030_analogrmic_enum =
337 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5, 337 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5,
338 ARRAY_SIZE(twl4030_analogrmic_texts), 338 ARRAY_SIZE(twl4030_analogrmic_texts),
339 twl4030_analogrmic_texts, 339 twl4030_analogrmic_texts,
@@ -1280,6 +1280,8 @@ static int twl4030_remove(struct platform_device *pdev)
1280 struct snd_soc_codec *codec = socdev->codec; 1280 struct snd_soc_codec *codec = socdev->codec;
1281 1281
1282 printk(KERN_INFO "TWL4030 Audio Codec remove\n"); 1282 printk(KERN_INFO "TWL4030 Audio Codec remove\n");
1283 snd_soc_free_pcms(socdev);
1284 snd_soc_dapm_free(socdev);
1283 kfree(codec); 1285 kfree(codec);
1284 1286
1285 return 0; 1287 return 0;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6cbe7e82f238..55fdb4abb179 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1585,37 +1585,6 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1585EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); 1585EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
1586 1586
1587/** 1587/**
1588 * snd_soc_info_value_enum_double - semi enumerated double mixer info callback
1589 * @kcontrol: mixer control
1590 * @uinfo: control element information
1591 *
1592 * Callback to provide information about a double semi enumerated
1593 * mixer control.
1594 *
1595 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1596 * used for handling bitfield coded enumeration for example.
1597 *
1598 * Returns 0 for success.
1599 */
1600int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
1601 struct snd_ctl_elem_info *uinfo)
1602{
1603 struct soc_value_enum *e = (struct soc_value_enum *)
1604 kcontrol->private_value;
1605
1606 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1607 uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
1608 uinfo->value.enumerated.items = e->max;
1609
1610 if (uinfo->value.enumerated.item > e->max - 1)
1611 uinfo->value.enumerated.item = e->max - 1;
1612 strcpy(uinfo->value.enumerated.name,
1613 e->texts[uinfo->value.enumerated.item]);
1614 return 0;
1615}
1616EXPORT_SYMBOL_GPL(snd_soc_info_value_enum_double);
1617
1618/**
1619 * snd_soc_get_value_enum_double - semi enumerated double mixer get callback 1588 * snd_soc_get_value_enum_double - semi enumerated double mixer get callback
1620 * @kcontrol: mixer control 1589 * @kcontrol: mixer control
1621 * @ucontrol: control element information 1590 * @ucontrol: control element information
@@ -1631,8 +1600,7 @@ int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
1631 struct snd_ctl_elem_value *ucontrol) 1600 struct snd_ctl_elem_value *ucontrol)
1632{ 1601{
1633 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1602 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1634 struct soc_value_enum *e = (struct soc_value_enum *) 1603 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1635 kcontrol->private_value;
1636 unsigned short reg_val, val, mux; 1604 unsigned short reg_val, val, mux;
1637 1605
1638 reg_val = snd_soc_read(codec, e->reg); 1606 reg_val = snd_soc_read(codec, e->reg);
@@ -1671,8 +1639,7 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
1671 struct snd_ctl_elem_value *ucontrol) 1639 struct snd_ctl_elem_value *ucontrol)
1672{ 1640{
1673 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1641 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1674 struct soc_value_enum *e = (struct soc_value_enum *) 1642 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1675 kcontrol->private_value;
1676 unsigned short val; 1643 unsigned short val;
1677 unsigned short mask; 1644 unsigned short mask;
1678 1645
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index ad0d801677c1..493a4e8aa273 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -137,7 +137,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
137 } 137 }
138 break; 138 break;
139 case snd_soc_dapm_value_mux: { 139 case snd_soc_dapm_value_mux: {
140 struct soc_value_enum *e = (struct soc_value_enum *) 140 struct soc_enum *e = (struct soc_enum *)
141 w->kcontrols[i].private_value; 141 w->kcontrols[i].private_value;
142 int val, item; 142 int val, item;
143 143
@@ -200,30 +200,6 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
200 return -ENODEV; 200 return -ENODEV;
201} 201}
202 202
203/* connect value_mux widget to it's interconnecting audio paths */
204static int dapm_connect_value_mux(struct snd_soc_codec *codec,
205 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
206 struct snd_soc_dapm_path *path, const char *control_name,
207 const struct snd_kcontrol_new *kcontrol)
208{
209 struct soc_value_enum *e = (struct soc_value_enum *)
210 kcontrol->private_value;
211 int i;
212
213 for (i = 0; i < e->max; i++) {
214 if (!(strcmp(control_name, e->texts[i]))) {
215 list_add(&path->list, &codec->dapm_paths);
216 list_add(&path->list_sink, &dest->sources);
217 list_add(&path->list_source, &src->sinks);
218 path->name = (char *)e->texts[i];
219 dapm_set_path_status(dest, path, 0);
220 return 0;
221 }
222 }
223
224 return -ENODEV;
225}
226
227/* connect mixer widget to it's interconnecting audio paths */ 203/* connect mixer widget to it's interconnecting audio paths */
228static int dapm_connect_mixer(struct snd_soc_codec *codec, 204static int dapm_connect_mixer(struct snd_soc_codec *codec,
229 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 205 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
@@ -774,45 +750,6 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
774 return 0; 750 return 0;
775} 751}
776 752
777/* test and update the power status of a value_mux widget */
778static int dapm_value_mux_update_power(struct snd_soc_dapm_widget *widget,
779 struct snd_kcontrol *kcontrol, int mask,
780 int mux, int val, struct soc_value_enum *e)
781{
782 struct snd_soc_dapm_path *path;
783 int found = 0;
784
785 if (widget->id != snd_soc_dapm_value_mux)
786 return -ENODEV;
787
788 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val))
789 return 0;
790
791 /* find dapm widget path assoc with kcontrol */
792 list_for_each_entry(path, &widget->codec->dapm_paths, list) {
793 if (path->kcontrol != kcontrol)
794 continue;
795
796 if (!path->name || !e->texts[mux])
797 continue;
798
799 found = 1;
800 /* we now need to match the string in the enum to the path */
801 if (!(strcmp(path->name, e->texts[mux])))
802 path->connect = 1; /* new connection */
803 else
804 path->connect = 0; /* old connection must be
805 powered down */
806 }
807
808 if (found) {
809 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
810 dump_dapm(widget->codec, "mux power update");
811 }
812
813 return 0;
814}
815
816/* test and update the power status of a mixer or switch widget */ 753/* test and update the power status of a mixer or switch widget */
817static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 754static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
818 struct snd_kcontrol *kcontrol, int reg, 755 struct snd_kcontrol *kcontrol, int reg,
@@ -1045,17 +982,12 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1045 path->connect = 1; 982 path->connect = 1;
1046 return 0; 983 return 0;
1047 case snd_soc_dapm_mux: 984 case snd_soc_dapm_mux:
985 case snd_soc_dapm_value_mux:
1048 ret = dapm_connect_mux(codec, wsource, wsink, path, control, 986 ret = dapm_connect_mux(codec, wsource, wsink, path, control,
1049 &wsink->kcontrols[0]); 987 &wsink->kcontrols[0]);
1050 if (ret != 0) 988 if (ret != 0)
1051 goto err; 989 goto err;
1052 break; 990 break;
1053 case snd_soc_dapm_value_mux:
1054 ret = dapm_connect_value_mux(codec, wsource, wsink, path,
1055 control, &wsink->kcontrols[0]);
1056 if (ret != 0)
1057 goto err;
1058 break;
1059 case snd_soc_dapm_switch: 991 case snd_soc_dapm_switch:
1060 case snd_soc_dapm_mixer: 992 case snd_soc_dapm_mixer:
1061 ret = dapm_connect_mixer(codec, wsource, wsink, path, control); 993 ret = dapm_connect_mixer(codec, wsource, wsink, path, control);
@@ -1382,8 +1314,7 @@ int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
1382 struct snd_ctl_elem_value *ucontrol) 1314 struct snd_ctl_elem_value *ucontrol)
1383{ 1315{
1384 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1316 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1385 struct soc_value_enum *e = (struct soc_value_enum *) 1317 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1386 kcontrol->private_value;
1387 unsigned short reg_val, val, mux; 1318 unsigned short reg_val, val, mux;
1388 1319
1389 reg_val = snd_soc_read(widget->codec, e->reg); 1320 reg_val = snd_soc_read(widget->codec, e->reg);
@@ -1423,8 +1354,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1423 struct snd_ctl_elem_value *ucontrol) 1354 struct snd_ctl_elem_value *ucontrol)
1424{ 1355{
1425 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1356 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1426 struct soc_value_enum *e = (struct soc_value_enum *) 1357 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1427 kcontrol->private_value;
1428 unsigned short val, mux; 1358 unsigned short val, mux;
1429 unsigned short mask; 1359 unsigned short mask;
1430 int ret = 0; 1360 int ret = 0;
@@ -1443,7 +1373,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1443 1373
1444 mutex_lock(&widget->codec->mutex); 1374 mutex_lock(&widget->codec->mutex);
1445 widget->value = val; 1375 widget->value = val;
1446 dapm_value_mux_update_power(widget, kcontrol, mask, mux, val, e); 1376 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1447 if (widget->event) { 1377 if (widget->event) {
1448 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1378 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1449 ret = widget->event(widget, 1379 ret = widget->event(widget,