aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c143
1 files changed, 93 insertions, 50 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 83f1190293a8..462e635dfc74 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4,8 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Author: Liam Girdwood 7 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
8 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
9 * with code, comments and ideas from :- 8 * with code, comments and ideas from :-
10 * Richard Purdie <richard@openedhand.com> 9 * Richard Purdie <richard@openedhand.com>
11 * 10 *
@@ -340,6 +339,12 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
340 } 339 }
341 codec->active--; 340 codec->active--;
342 341
342 /* Muting the DAC suppresses artifacts caused during digital
343 * shutdown, for example from stopping clocks.
344 */
345 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
346 snd_soc_dai_digital_mute(codec_dai, 1);
347
343 if (cpu_dai->ops.shutdown) 348 if (cpu_dai->ops.shutdown)
344 cpu_dai->ops.shutdown(substream); 349 cpu_dai->ops.shutdown(substream);
345 350
@@ -970,9 +975,29 @@ static ssize_t codec_reg_show(struct device *dev,
970 step = codec->reg_cache_step; 975 step = codec->reg_cache_step;
971 976
972 count += sprintf(buf, "%s registers\n", codec->name); 977 count += sprintf(buf, "%s registers\n", codec->name);
973 for (i = 0; i < codec->reg_cache_size; i += step) 978 for (i = 0; i < codec->reg_cache_size; i += step) {
974 count += sprintf(buf + count, "%2x: %4x\n", i, 979 count += sprintf(buf + count, "%2x: ", i);
975 codec->read(codec, i)); 980 if (count >= PAGE_SIZE - 1)
981 break;
982
983 if (codec->display_register)
984 count += codec->display_register(codec, buf + count,
985 PAGE_SIZE - count, i);
986 else
987 count += snprintf(buf + count, PAGE_SIZE - count,
988 "%4x", codec->read(codec, i));
989
990 if (count >= PAGE_SIZE - 1)
991 break;
992
993 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
994 if (count >= PAGE_SIZE - 1)
995 break;
996 }
997
998 /* Truncate count; min() would cause a warning */
999 if (count >= PAGE_SIZE)
1000 count = PAGE_SIZE - 1;
976 1001
977 return count; 1002 return count;
978} 1003}
@@ -1296,10 +1321,10 @@ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
1296 1321
1297 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1322 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1298 uinfo->count = e->shift_l == e->shift_r ? 1 : 2; 1323 uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
1299 uinfo->value.enumerated.items = e->mask; 1324 uinfo->value.enumerated.items = e->max;
1300 1325
1301 if (uinfo->value.enumerated.item > e->mask - 1) 1326 if (uinfo->value.enumerated.item > e->max - 1)
1302 uinfo->value.enumerated.item = e->mask - 1; 1327 uinfo->value.enumerated.item = e->max - 1;
1303 strcpy(uinfo->value.enumerated.name, 1328 strcpy(uinfo->value.enumerated.name,
1304 e->texts[uinfo->value.enumerated.item]); 1329 e->texts[uinfo->value.enumerated.item]);
1305 return 0; 1330 return 0;
@@ -1322,7 +1347,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
1322 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1347 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1323 unsigned short val, bitmask; 1348 unsigned short val, bitmask;
1324 1349
1325 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1350 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1326 ; 1351 ;
1327 val = snd_soc_read(codec, e->reg); 1352 val = snd_soc_read(codec, e->reg);
1328 ucontrol->value.enumerated.item[0] 1353 ucontrol->value.enumerated.item[0]
@@ -1352,14 +1377,14 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1352 unsigned short val; 1377 unsigned short val;
1353 unsigned short mask, bitmask; 1378 unsigned short mask, bitmask;
1354 1379
1355 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1380 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1356 ; 1381 ;
1357 if (ucontrol->value.enumerated.item[0] > e->mask - 1) 1382 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1358 return -EINVAL; 1383 return -EINVAL;
1359 val = ucontrol->value.enumerated.item[0] << e->shift_l; 1384 val = ucontrol->value.enumerated.item[0] << e->shift_l;
1360 mask = (bitmask - 1) << e->shift_l; 1385 mask = (bitmask - 1) << e->shift_l;
1361 if (e->shift_l != e->shift_r) { 1386 if (e->shift_l != e->shift_r) {
1362 if (ucontrol->value.enumerated.item[1] > e->mask - 1) 1387 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1363 return -EINVAL; 1388 return -EINVAL;
1364 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 1389 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1365 mask |= (bitmask - 1) << e->shift_r; 1390 mask |= (bitmask - 1) << e->shift_r;
@@ -1386,10 +1411,10 @@ int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
1386 1411
1387 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1412 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1388 uinfo->count = 1; 1413 uinfo->count = 1;
1389 uinfo->value.enumerated.items = e->mask; 1414 uinfo->value.enumerated.items = e->max;
1390 1415
1391 if (uinfo->value.enumerated.item > e->mask - 1) 1416 if (uinfo->value.enumerated.item > e->max - 1)
1392 uinfo->value.enumerated.item = e->mask - 1; 1417 uinfo->value.enumerated.item = e->max - 1;
1393 strcpy(uinfo->value.enumerated.name, 1418 strcpy(uinfo->value.enumerated.name,
1394 e->texts[uinfo->value.enumerated.item]); 1419 e->texts[uinfo->value.enumerated.item]);
1395 return 0; 1420 return 0;
@@ -1434,9 +1459,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
1434int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, 1459int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
1435 struct snd_ctl_elem_info *uinfo) 1460 struct snd_ctl_elem_info *uinfo)
1436{ 1461{
1437 int max = (kcontrol->private_value >> 16) & 0xff; 1462 struct soc_mixer_control *mc =
1438 int shift = (kcontrol->private_value >> 8) & 0x0f; 1463 (struct soc_mixer_control *)kcontrol->private_value;
1439 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1464 int max = mc->max;
1465 unsigned int shift = mc->min;
1466 unsigned int rshift = mc->rshift;
1440 1467
1441 if (max == 1) 1468 if (max == 1)
1442 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1469 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -1462,13 +1489,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
1462int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, 1489int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
1463 struct snd_ctl_elem_value *ucontrol) 1490 struct snd_ctl_elem_value *ucontrol)
1464{ 1491{
1492 struct soc_mixer_control *mc =
1493 (struct soc_mixer_control *)kcontrol->private_value;
1465 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1494 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1466 int reg = kcontrol->private_value & 0xff; 1495 unsigned int reg = mc->reg;
1467 int shift = (kcontrol->private_value >> 8) & 0x0f; 1496 unsigned int shift = mc->shift;
1468 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1497 unsigned int rshift = mc->rshift;
1469 int max = (kcontrol->private_value >> 16) & 0xff; 1498 int max = mc->max;
1470 int mask = (1 << fls(max)) - 1; 1499 unsigned int mask = (1 << fls(max)) - 1;
1471 int invert = (kcontrol->private_value >> 24) & 0x01; 1500 unsigned int invert = mc->invert;
1472 1501
1473 ucontrol->value.integer.value[0] = 1502 ucontrol->value.integer.value[0] =
1474 (snd_soc_read(codec, reg) >> shift) & mask; 1503 (snd_soc_read(codec, reg) >> shift) & mask;
@@ -1499,13 +1528,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
1499int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, 1528int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1500 struct snd_ctl_elem_value *ucontrol) 1529 struct snd_ctl_elem_value *ucontrol)
1501{ 1530{
1531 struct soc_mixer_control *mc =
1532 (struct soc_mixer_control *)kcontrol->private_value;
1502 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1533 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1503 int reg = kcontrol->private_value & 0xff; 1534 unsigned int reg = mc->reg;
1504 int shift = (kcontrol->private_value >> 8) & 0x0f; 1535 unsigned int shift = mc->shift;
1505 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1536 unsigned int rshift = mc->rshift;
1506 int max = (kcontrol->private_value >> 16) & 0xff; 1537 int max = mc->max;
1507 int mask = (1 << fls(max)) - 1; 1538 unsigned int mask = (1 << fls(max)) - 1;
1508 int invert = (kcontrol->private_value >> 24) & 0x01; 1539 unsigned int invert = mc->invert;
1509 unsigned short val, val2, val_mask; 1540 unsigned short val, val2, val_mask;
1510 1541
1511 val = (ucontrol->value.integer.value[0] & mask); 1542 val = (ucontrol->value.integer.value[0] & mask);
@@ -1537,7 +1568,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
1537int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, 1568int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
1538 struct snd_ctl_elem_info *uinfo) 1569 struct snd_ctl_elem_info *uinfo)
1539{ 1570{
1540 int max = (kcontrol->private_value >> 12) & 0xff; 1571 struct soc_mixer_control *mc =
1572 (struct soc_mixer_control *)kcontrol->private_value;
1573 int max = mc->max;
1541 1574
1542 if (max == 1) 1575 if (max == 1)
1543 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1576 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -1563,13 +1596,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
1563int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, 1596int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
1564 struct snd_ctl_elem_value *ucontrol) 1597 struct snd_ctl_elem_value *ucontrol)
1565{ 1598{
1599 struct soc_mixer_control *mc =
1600 (struct soc_mixer_control *)kcontrol->private_value;
1566 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1567 int reg = kcontrol->private_value & 0xff; 1602 unsigned int reg = mc->reg;
1568 int reg2 = (kcontrol->private_value >> 24) & 0xff; 1603 unsigned int reg2 = mc->rreg;
1569 int shift = (kcontrol->private_value >> 8) & 0x0f; 1604 unsigned int shift = mc->shift;
1570 int max = (kcontrol->private_value >> 12) & 0xff; 1605 int max = mc->max;
1571 int mask = (1<<fls(max))-1; 1606 unsigned int mask = (1<<fls(max))-1;
1572 int invert = (kcontrol->private_value >> 20) & 0x01; 1607 unsigned int invert = mc->invert;
1573 1608
1574 ucontrol->value.integer.value[0] = 1609 ucontrol->value.integer.value[0] =
1575 (snd_soc_read(codec, reg) >> shift) & mask; 1610 (snd_soc_read(codec, reg) >> shift) & mask;
@@ -1598,13 +1633,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r);
1598int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, 1633int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1599 struct snd_ctl_elem_value *ucontrol) 1634 struct snd_ctl_elem_value *ucontrol)
1600{ 1635{
1636 struct soc_mixer_control *mc =
1637 (struct soc_mixer_control *)kcontrol->private_value;
1601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1638 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1602 int reg = kcontrol->private_value & 0xff; 1639 unsigned int reg = mc->reg;
1603 int reg2 = (kcontrol->private_value >> 24) & 0xff; 1640 unsigned int reg2 = mc->rreg;
1604 int shift = (kcontrol->private_value >> 8) & 0x0f; 1641 unsigned int shift = mc->shift;
1605 int max = (kcontrol->private_value >> 12) & 0xff; 1642 int max = mc->max;
1606 int mask = (1 << fls(max)) - 1; 1643 unsigned int mask = (1 << fls(max)) - 1;
1607 int invert = (kcontrol->private_value >> 20) & 0x01; 1644 unsigned int invert = mc->invert;
1608 int err; 1645 int err;
1609 unsigned short val, val2, val_mask; 1646 unsigned short val, val2, val_mask;
1610 1647
@@ -1641,8 +1678,10 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
1641int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, 1678int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_info *uinfo) 1679 struct snd_ctl_elem_info *uinfo)
1643{ 1680{
1644 int max = (signed char)((kcontrol->private_value >> 16) & 0xff); 1681 struct soc_mixer_control *mc =
1645 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1682 (struct soc_mixer_control *)kcontrol->private_value;
1683 int max = mc->max;
1684 int min = mc->min;
1646 1685
1647 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1686 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1648 uinfo->count = 2; 1687 uinfo->count = 2;
@@ -1664,9 +1703,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
1664int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, 1703int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
1665 struct snd_ctl_elem_value *ucontrol) 1704 struct snd_ctl_elem_value *ucontrol)
1666{ 1705{
1706 struct soc_mixer_control *mc =
1707 (struct soc_mixer_control *)kcontrol->private_value;
1667 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1708 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1668 int reg = kcontrol->private_value & 0xff; 1709 unsigned int reg = mc->reg;
1669 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1710 int min = mc->min;
1670 int val = snd_soc_read(codec, reg); 1711 int val = snd_soc_read(codec, reg);
1671 1712
1672 ucontrol->value.integer.value[0] = 1713 ucontrol->value.integer.value[0] =
@@ -1689,9 +1730,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8);
1689int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, 1730int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
1690 struct snd_ctl_elem_value *ucontrol) 1731 struct snd_ctl_elem_value *ucontrol)
1691{ 1732{
1733 struct soc_mixer_control *mc =
1734 (struct soc_mixer_control *)kcontrol->private_value;
1692 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1735 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1693 int reg = kcontrol->private_value & 0xff; 1736 unsigned int reg = mc->reg;
1694 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1737 int min = mc->min;
1695 unsigned short val; 1738 unsigned short val;
1696 1739
1697 val = (ucontrol->value.integer.value[0]+min) & 0xff; 1740 val = (ucontrol->value.integer.value[0]+min) & 0xff;
@@ -1842,7 +1885,7 @@ module_init(snd_soc_init);
1842module_exit(snd_soc_exit); 1885module_exit(snd_soc_exit);
1843 1886
1844/* Module information */ 1887/* Module information */
1845MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 1888MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1846MODULE_DESCRIPTION("ALSA SoC Core"); 1889MODULE_DESCRIPTION("ALSA SoC Core");
1847MODULE_LICENSE("GPL"); 1890MODULE_LICENSE("GPL");
1848MODULE_ALIAS("platform:soc-audio"); 1891MODULE_ALIAS("platform:soc-audio");