aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c140
1 files changed, 131 insertions, 9 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 8863eddbac02..a2f1da8b4646 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -53,13 +53,15 @@
53/* dapm power sequences - make this per codec in the future */ 53/* dapm power sequences - make this per codec in the future */
54static int dapm_up_seq[] = { 54static int dapm_up_seq[] = {
55 snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, 55 snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic,
56 snd_soc_dapm_mux, snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_pga, 56 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac,
57 snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post 57 snd_soc_dapm_mixer, snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp,
58 snd_soc_dapm_spk, snd_soc_dapm_post
58}; 59};
59static int dapm_down_seq[] = { 60static int dapm_down_seq[] = {
60 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, 61 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
61 snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic, 62 snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic,
62 snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_post 63 snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_value_mux,
64 snd_soc_dapm_post
63}; 65};
64 66
65static int dapm_status = 1; 67static int dapm_status = 1;
@@ -134,6 +136,25 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
134 } 136 }
135 } 137 }
136 break; 138 break;
139 case snd_soc_dapm_value_mux: {
140 struct soc_enum *e = (struct soc_enum *)
141 w->kcontrols[i].private_value;
142 int val, item;
143
144 val = snd_soc_read(w->codec, e->reg);
145 val = (val >> e->shift_l) & e->mask;
146 for (item = 0; item < e->max; item++) {
147 if (val == e->values[item])
148 break;
149 }
150
151 p->connect = 0;
152 for (i = 0; i < e->max; i++) {
153 if (!(strcmp(p->name, e->texts[i])) && item == i)
154 p->connect = 1;
155 }
156 }
157 break;
137 /* does not effect routing - always connected */ 158 /* does not effect routing - always connected */
138 case snd_soc_dapm_pga: 159 case snd_soc_dapm_pga:
139 case snd_soc_dapm_output: 160 case snd_soc_dapm_output:
@@ -653,6 +674,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
653 case snd_soc_dapm_vmid: 674 case snd_soc_dapm_vmid:
654 continue; 675 continue;
655 case snd_soc_dapm_mux: 676 case snd_soc_dapm_mux:
677 case snd_soc_dapm_value_mux:
656 case snd_soc_dapm_output: 678 case snd_soc_dapm_output:
657 case snd_soc_dapm_input: 679 case snd_soc_dapm_input:
658 case snd_soc_dapm_switch: 680 case snd_soc_dapm_switch:
@@ -698,7 +720,8 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
698 struct snd_soc_dapm_path *path; 720 struct snd_soc_dapm_path *path;
699 int found = 0; 721 int found = 0;
700 722
701 if (widget->id != snd_soc_dapm_mux) 723 if (widget->id != snd_soc_dapm_mux &&
724 widget->id != snd_soc_dapm_value_mux)
702 return -ENODEV; 725 return -ENODEV;
703 726
704 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val)) 727 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val))
@@ -960,6 +983,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
960 path->connect = 1; 983 path->connect = 1;
961 return 0; 984 return 0;
962 case snd_soc_dapm_mux: 985 case snd_soc_dapm_mux:
986 case snd_soc_dapm_value_mux:
963 ret = dapm_connect_mux(codec, wsource, wsink, path, control, 987 ret = dapm_connect_mux(codec, wsource, wsink, path, control,
964 &wsink->kcontrols[0]); 988 &wsink->kcontrols[0]);
965 if (ret != 0) 989 if (ret != 0)
@@ -1047,6 +1071,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1047 dapm_new_mixer(codec, w); 1071 dapm_new_mixer(codec, w);
1048 break; 1072 break;
1049 case snd_soc_dapm_mux: 1073 case snd_soc_dapm_mux:
1074 case snd_soc_dapm_value_mux:
1050 dapm_new_mux(codec, w); 1075 dapm_new_mux(codec, w);
1051 break; 1076 break;
1052 case snd_soc_dapm_adc: 1077 case snd_soc_dapm_adc:
@@ -1077,7 +1102,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
1077/** 1102/**
1078 * snd_soc_dapm_get_volsw - dapm mixer get callback 1103 * snd_soc_dapm_get_volsw - dapm mixer get callback
1079 * @kcontrol: mixer control 1104 * @kcontrol: mixer control
1080 * @uinfo: control element information 1105 * @ucontrol: control element information
1081 * 1106 *
1082 * Callback to get the value of a dapm mixer control. 1107 * Callback to get the value of a dapm mixer control.
1083 * 1108 *
@@ -1122,7 +1147,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
1122/** 1147/**
1123 * snd_soc_dapm_put_volsw - dapm mixer set callback 1148 * snd_soc_dapm_put_volsw - dapm mixer set callback
1124 * @kcontrol: mixer control 1149 * @kcontrol: mixer control
1125 * @uinfo: control element information 1150 * @ucontrol: control element information
1126 * 1151 *
1127 * Callback to set the value of a dapm mixer control. 1152 * Callback to set the value of a dapm mixer control.
1128 * 1153 *
@@ -1193,7 +1218,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
1193/** 1218/**
1194 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback 1219 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
1195 * @kcontrol: mixer control 1220 * @kcontrol: mixer control
1196 * @uinfo: control element information 1221 * @ucontrol: control element information
1197 * 1222 *
1198 * Callback to get the value of a dapm enumerated double mixer control. 1223 * Callback to get the value of a dapm enumerated double mixer control.
1199 * 1224 *
@@ -1221,7 +1246,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
1221/** 1246/**
1222 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback 1247 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
1223 * @kcontrol: mixer control 1248 * @kcontrol: mixer control
1224 * @uinfo: control element information 1249 * @ucontrol: control element information
1225 * 1250 *
1226 * Callback to set the value of a dapm enumerated double mixer control. 1251 * Callback to set the value of a dapm enumerated double mixer control.
1227 * 1252 *
@@ -1274,6 +1299,103 @@ out:
1274EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1299EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1275 1300
1276/** 1301/**
1302 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
1303 * callback
1304 * @kcontrol: mixer control
1305 * @ucontrol: control element information
1306 *
1307 * Callback to get the value of a dapm semi enumerated double mixer control.
1308 *
1309 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1310 * used for handling bitfield coded enumeration for example.
1311 *
1312 * Returns 0 for success.
1313 */
1314int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
1315 struct snd_ctl_elem_value *ucontrol)
1316{
1317 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1318 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1319 unsigned short reg_val, val, mux;
1320
1321 reg_val = snd_soc_read(widget->codec, e->reg);
1322 val = (reg_val >> e->shift_l) & e->mask;
1323 for (mux = 0; mux < e->max; mux++) {
1324 if (val == e->values[mux])
1325 break;
1326 }
1327 ucontrol->value.enumerated.item[0] = mux;
1328 if (e->shift_l != e->shift_r) {
1329 val = (reg_val >> e->shift_r) & e->mask;
1330 for (mux = 0; mux < e->max; mux++) {
1331 if (val == e->values[mux])
1332 break;
1333 }
1334 ucontrol->value.enumerated.item[1] = mux;
1335 }
1336
1337 return 0;
1338}
1339EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
1340
1341/**
1342 * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set
1343 * callback
1344 * @kcontrol: mixer control
1345 * @ucontrol: control element information
1346 *
1347 * Callback to set the value of a dapm semi enumerated double mixer control.
1348 *
1349 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1350 * used for handling bitfield coded enumeration for example.
1351 *
1352 * Returns 0 for success.
1353 */
1354int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1355 struct snd_ctl_elem_value *ucontrol)
1356{
1357 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1358 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1359 unsigned short val, mux;
1360 unsigned short mask;
1361 int ret = 0;
1362
1363 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1364 return -EINVAL;
1365 mux = ucontrol->value.enumerated.item[0];
1366 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
1367 mask = e->mask << e->shift_l;
1368 if (e->shift_l != e->shift_r) {
1369 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1370 return -EINVAL;
1371 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
1372 mask |= e->mask << e->shift_r;
1373 }
1374
1375 mutex_lock(&widget->codec->mutex);
1376 widget->value = val;
1377 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1378 if (widget->event) {
1379 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1380 ret = widget->event(widget,
1381 kcontrol, SND_SOC_DAPM_PRE_REG);
1382 if (ret < 0)
1383 goto out;
1384 }
1385 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1386 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1387 ret = widget->event(widget,
1388 kcontrol, SND_SOC_DAPM_POST_REG);
1389 } else
1390 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1391
1392out:
1393 mutex_unlock(&widget->codec->mutex);
1394 return ret;
1395}
1396EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
1397
1398/**
1277 * snd_soc_dapm_new_control - create new dapm control 1399 * snd_soc_dapm_new_control - create new dapm control
1278 * @codec: audio codec 1400 * @codec: audio codec
1279 * @widget: widget template 1401 * @widget: widget template
@@ -1419,7 +1541,7 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1419 1541
1420/** 1542/**
1421 * snd_soc_dapm_enable_pin - enable pin. 1543 * snd_soc_dapm_enable_pin - enable pin.
1422 * @snd_soc_codec: SoC codec 1544 * @codec: SoC codec
1423 * @pin: pin name 1545 * @pin: pin name
1424 * 1546 *
1425 * Enables input/output pin and it's parents or children widgets iff there is 1547 * Enables input/output pin and it's parents or children widgets iff there is