aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 075244ef41eb..0accdba211f9 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -188,7 +188,7 @@
188 .private_value = (unsigned long)&xenum } 188 .private_value = (unsigned long)&xenum }
189#define SOC_DAPM_VALUE_ENUM(xname, xenum) \ 189#define SOC_DAPM_VALUE_ENUM(xname, xenum) \
190{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 190{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
191 .info = snd_soc_info_value_enum_double, \ 191 .info = snd_soc_info_enum_double, \
192 .get = snd_soc_dapm_get_value_enum_double, \ 192 .get = snd_soc_dapm_get_value_enum_double, \
193 .put = snd_soc_dapm_put_value_enum_double, \ 193 .put = snd_soc_dapm_put_value_enum_double, \
194 .private_value = (unsigned long)&xenum } 194 .private_value = (unsigned long)&xenum }
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 9d5a0362a055..7039343e8a78 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 }
@@ -224,8 +224,6 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
224 struct snd_ctl_elem_value *ucontrol); 224 struct snd_ctl_elem_value *ucontrol);
225int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, 225int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
226 struct snd_ctl_elem_value *ucontrol); 226 struct snd_ctl_elem_value *ucontrol);
227int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
228 struct snd_ctl_elem_info *uinfo);
229int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol, 227int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
230 struct snd_ctl_elem_value *ucontrol); 228 struct snd_ctl_elem_value *ucontrol);
231int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol, 229int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
@@ -453,17 +451,6 @@ struct soc_enum {
453 unsigned char shift_l; 451 unsigned char shift_l;
454 unsigned char shift_r; 452 unsigned char shift_r;
455 unsigned int max; 453 unsigned int max;
456 const char **texts;
457 void *dapm;
458};
459
460/* semi enumerated kcontrol */
461struct soc_value_enum {
462 unsigned short reg;
463 unsigned short reg2;
464 unsigned char shift_l;
465 unsigned char shift_r;
466 unsigned int max;
467 unsigned int mask; 454 unsigned int mask;
468 const char **texts; 455 const char **texts;
469 const unsigned int *values; 456 const unsigned int *values;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 253063fd319a..ddc9f37d863f 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,
@@ -1265,6 +1265,8 @@ static int twl4030_remove(struct platform_device *pdev)
1265 struct snd_soc_codec *codec = socdev->codec; 1265 struct snd_soc_codec *codec = socdev->codec;
1266 1266
1267 printk(KERN_INFO "TWL4030 Audio Codec remove\n"); 1267 printk(KERN_INFO "TWL4030 Audio Codec remove\n");
1268 snd_soc_free_pcms(socdev);
1269 snd_soc_dapm_free(socdev);
1268 kfree(codec); 1270 kfree(codec);
1269 1271
1270 return 0; 1272 return 0;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d3b97a7542e0..8313d52a6e8c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1616,37 +1616,6 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1616EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); 1616EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
1617 1617
1618/** 1618/**
1619 * snd_soc_info_value_enum_double - semi enumerated double mixer info callback
1620 * @kcontrol: mixer control
1621 * @uinfo: control element information
1622 *
1623 * Callback to provide information about a double semi enumerated
1624 * mixer control.
1625 *
1626 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1627 * used for handling bitfield coded enumeration for example.
1628 *
1629 * Returns 0 for success.
1630 */
1631int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
1632 struct snd_ctl_elem_info *uinfo)
1633{
1634 struct soc_value_enum *e = (struct soc_value_enum *)
1635 kcontrol->private_value;
1636
1637 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1638 uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
1639 uinfo->value.enumerated.items = e->max;
1640
1641 if (uinfo->value.enumerated.item > e->max - 1)
1642 uinfo->value.enumerated.item = e->max - 1;
1643 strcpy(uinfo->value.enumerated.name,
1644 e->texts[uinfo->value.enumerated.item]);
1645 return 0;
1646}
1647EXPORT_SYMBOL_GPL(snd_soc_info_value_enum_double);
1648
1649/**
1650 * snd_soc_get_value_enum_double - semi enumerated double mixer get callback 1619 * snd_soc_get_value_enum_double - semi enumerated double mixer get callback
1651 * @kcontrol: mixer control 1620 * @kcontrol: mixer control
1652 * @ucontrol: control element information 1621 * @ucontrol: control element information
@@ -1662,8 +1631,7 @@ int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
1662 struct snd_ctl_elem_value *ucontrol) 1631 struct snd_ctl_elem_value *ucontrol)
1663{ 1632{
1664 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1633 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1665 struct soc_value_enum *e = (struct soc_value_enum *) 1634 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1666 kcontrol->private_value;
1667 unsigned short reg_val, val, mux; 1635 unsigned short reg_val, val, mux;
1668 1636
1669 reg_val = snd_soc_read(codec, e->reg); 1637 reg_val = snd_soc_read(codec, e->reg);
@@ -1702,8 +1670,7 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
1702 struct snd_ctl_elem_value *ucontrol) 1670 struct snd_ctl_elem_value *ucontrol)
1703{ 1671{
1704 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1672 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1705 struct soc_value_enum *e = (struct soc_value_enum *) 1673 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1706 kcontrol->private_value;
1707 unsigned short val; 1674 unsigned short val;
1708 unsigned short mask; 1675 unsigned short mask;
1709 1676
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index a35ce69d9d78..3a759c2872a8 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -139,7 +139,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
139 } 139 }
140 break; 140 break;
141 case snd_soc_dapm_value_mux: { 141 case snd_soc_dapm_value_mux: {
142 struct soc_value_enum *e = (struct soc_value_enum *) 142 struct soc_enum *e = (struct soc_enum *)
143 w->kcontrols[i].private_value; 143 w->kcontrols[i].private_value;
144 int val, item; 144 int val, item;
145 145
@@ -202,30 +202,6 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
202 return -ENODEV; 202 return -ENODEV;
203} 203}
204 204
205/* connect value_mux widget to it's interconnecting audio paths */
206static int dapm_connect_value_mux(struct snd_soc_codec *codec,
207 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
208 struct snd_soc_dapm_path *path, const char *control_name,
209 const struct snd_kcontrol_new *kcontrol)
210{
211 struct soc_value_enum *e = (struct soc_value_enum *)
212 kcontrol->private_value;
213 int i;
214
215 for (i = 0; i < e->max; i++) {
216 if (!(strcmp(control_name, e->texts[i]))) {
217 list_add(&path->list, &codec->dapm_paths);
218 list_add(&path->list_sink, &dest->sources);
219 list_add(&path->list_source, &src->sinks);
220 path->name = (char *)e->texts[i];
221 dapm_set_path_status(dest, path, 0);
222 return 0;
223 }
224 }
225
226 return -ENODEV;
227}
228
229/* connect mixer widget to it's interconnecting audio paths */ 205/* connect mixer widget to it's interconnecting audio paths */
230static int dapm_connect_mixer(struct snd_soc_codec *codec, 206static int dapm_connect_mixer(struct snd_soc_codec *codec,
231 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 207 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
@@ -795,45 +771,6 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
795 return 0; 771 return 0;
796} 772}
797 773
798/* test and update the power status of a value_mux widget */
799static int dapm_value_mux_update_power(struct snd_soc_dapm_widget *widget,
800 struct snd_kcontrol *kcontrol, int mask,
801 int mux, int val, struct soc_value_enum *e)
802{
803 struct snd_soc_dapm_path *path;
804 int found = 0;
805
806 if (widget->id != snd_soc_dapm_value_mux)
807 return -ENODEV;
808
809 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val))
810 return 0;
811
812 /* find dapm widget path assoc with kcontrol */
813 list_for_each_entry(path, &widget->codec->dapm_paths, list) {
814 if (path->kcontrol != kcontrol)
815 continue;
816
817 if (!path->name || !e->texts[mux])
818 continue;
819
820 found = 1;
821 /* we now need to match the string in the enum to the path */
822 if (!(strcmp(path->name, e->texts[mux])))
823 path->connect = 1; /* new connection */
824 else
825 path->connect = 0; /* old connection must be
826 powered down */
827 }
828
829 if (found) {
830 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
831 dump_dapm(widget->codec, "mux power update");
832 }
833
834 return 0;
835}
836
837/* test and update the power status of a mixer or switch widget */ 774/* test and update the power status of a mixer or switch widget */
838static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 775static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
839 struct snd_kcontrol *kcontrol, int reg, 776 struct snd_kcontrol *kcontrol, int reg,
@@ -1068,17 +1005,12 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1068 path->connect = 1; 1005 path->connect = 1;
1069 return 0; 1006 return 0;
1070 case snd_soc_dapm_mux: 1007 case snd_soc_dapm_mux:
1008 case snd_soc_dapm_value_mux:
1071 ret = dapm_connect_mux(codec, wsource, wsink, path, control, 1009 ret = dapm_connect_mux(codec, wsource, wsink, path, control,
1072 &wsink->kcontrols[0]); 1010 &wsink->kcontrols[0]);
1073 if (ret != 0) 1011 if (ret != 0)
1074 goto err; 1012 goto err;
1075 break; 1013 break;
1076 case snd_soc_dapm_value_mux:
1077 ret = dapm_connect_value_mux(codec, wsource, wsink, path,
1078 control, &wsink->kcontrols[0]);
1079 if (ret != 0)
1080 goto err;
1081 break;
1082 case snd_soc_dapm_switch: 1014 case snd_soc_dapm_switch:
1083 case snd_soc_dapm_mixer: 1015 case snd_soc_dapm_mixer:
1084 case snd_soc_dapm_mixer_named_ctl: 1016 case snd_soc_dapm_mixer_named_ctl:
@@ -1407,8 +1339,7 @@ int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
1407 struct snd_ctl_elem_value *ucontrol) 1339 struct snd_ctl_elem_value *ucontrol)
1408{ 1340{
1409 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1341 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1410 struct soc_value_enum *e = (struct soc_value_enum *) 1342 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1411 kcontrol->private_value;
1412 unsigned short reg_val, val, mux; 1343 unsigned short reg_val, val, mux;
1413 1344
1414 reg_val = snd_soc_read(widget->codec, e->reg); 1345 reg_val = snd_soc_read(widget->codec, e->reg);
@@ -1448,8 +1379,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1448 struct snd_ctl_elem_value *ucontrol) 1379 struct snd_ctl_elem_value *ucontrol)
1449{ 1380{
1450 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1381 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1451 struct soc_value_enum *e = (struct soc_value_enum *) 1382 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1452 kcontrol->private_value;
1453 unsigned short val, mux; 1383 unsigned short val, mux;
1454 unsigned short mask; 1384 unsigned short mask;
1455 int ret = 0; 1385 int ret = 0;
@@ -1468,7 +1398,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1468 1398
1469 mutex_lock(&widget->codec->mutex); 1399 mutex_lock(&widget->codec->mutex);
1470 widget->value = val; 1400 widget->value = val;
1471 dapm_value_mux_update_power(widget, kcontrol, mask, mux, val, e); 1401 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1472 if (widget->event) { 1402 if (widget->event) {
1473 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1403 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1474 ret = widget->event(widget, 1404 ret = widget->event(widget,