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.c148
1 files changed, 123 insertions, 25 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1d70829464ef..7ff04ad2a97e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -28,6 +28,7 @@
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/debugfs.h> 29#include <linux/debugfs.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <sound/ac97_codec.h>
31#include <sound/core.h> 32#include <sound/core.h>
32#include <sound/pcm.h> 33#include <sound/pcm.h>
33#include <sound/pcm_params.h> 34#include <sound/pcm_params.h>
@@ -619,8 +620,9 @@ static struct snd_pcm_ops soc_pcm_ops = {
619 620
620#ifdef CONFIG_PM 621#ifdef CONFIG_PM
621/* powers down audio subsystem for suspend */ 622/* powers down audio subsystem for suspend */
622static int soc_suspend(struct platform_device *pdev, pm_message_t state) 623static int soc_suspend(struct device *dev)
623{ 624{
625 struct platform_device *pdev = to_platform_device(dev);
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 626 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
625 struct snd_soc_card *card = socdev->card; 627 struct snd_soc_card *card = socdev->card;
626 struct snd_soc_platform *platform = card->platform; 628 struct snd_soc_platform *platform = card->platform;
@@ -656,7 +658,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
656 snd_pcm_suspend_all(card->dai_link[i].pcm); 658 snd_pcm_suspend_all(card->dai_link[i].pcm);
657 659
658 if (card->suspend_pre) 660 if (card->suspend_pre)
659 card->suspend_pre(pdev, state); 661 card->suspend_pre(pdev, PMSG_SUSPEND);
660 662
661 for (i = 0; i < card->num_links; i++) { 663 for (i = 0; i < card->num_links; i++) {
662 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 664 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
@@ -682,7 +684,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
682 } 684 }
683 685
684 if (codec_dev->suspend) 686 if (codec_dev->suspend)
685 codec_dev->suspend(pdev, state); 687 codec_dev->suspend(pdev, PMSG_SUSPEND);
686 688
687 for (i = 0; i < card->num_links; i++) { 689 for (i = 0; i < card->num_links; i++) {
688 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 690 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
@@ -691,7 +693,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
691 } 693 }
692 694
693 if (card->suspend_post) 695 if (card->suspend_post)
694 card->suspend_post(pdev, state); 696 card->suspend_post(pdev, PMSG_SUSPEND);
695 697
696 return 0; 698 return 0;
697} 699}
@@ -765,8 +767,9 @@ static void soc_resume_deferred(struct work_struct *work)
765} 767}
766 768
767/* powers up audio subsystem after a suspend */ 769/* powers up audio subsystem after a suspend */
768static int soc_resume(struct platform_device *pdev) 770static int soc_resume(struct device *dev)
769{ 771{
772 struct platform_device *pdev = to_platform_device(dev);
770 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 773 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
771 struct snd_soc_card *card = socdev->card; 774 struct snd_soc_card *card = socdev->card;
772 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai; 775 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
@@ -788,6 +791,44 @@ static int soc_resume(struct platform_device *pdev)
788 return 0; 791 return 0;
789} 792}
790 793
794/**
795 * snd_soc_suspend_device: Notify core of device suspend
796 *
797 * @dev: Device being suspended.
798 *
799 * In order to ensure that the entire audio subsystem is suspended in a
800 * coordinated fashion ASoC devices should suspend themselves when
801 * called by ASoC. When the standard kernel suspend process asks the
802 * device to suspend it should call this function to initiate a suspend
803 * of the entire ASoC card.
804 *
805 * \note Currently this function is stubbed out.
806 */
807int snd_soc_suspend_device(struct device *dev)
808{
809 return 0;
810}
811EXPORT_SYMBOL_GPL(snd_soc_suspend_device);
812
813/**
814 * snd_soc_resume_device: Notify core of device resume
815 *
816 * @dev: Device being resumed.
817 *
818 * In order to ensure that the entire audio subsystem is resumed in a
819 * coordinated fashion ASoC devices should resume themselves when called
820 * by ASoC. When the standard kernel resume process asks the device
821 * to resume it should call this function. Once all the components of
822 * the card have notified that they are ready to be resumed the card
823 * will be resumed.
824 *
825 * \note Currently this function is stubbed out.
826 */
827int snd_soc_resume_device(struct device *dev)
828{
829 return 0;
830}
831EXPORT_SYMBOL_GPL(snd_soc_resume_device);
791#else 832#else
792#define soc_suspend NULL 833#define soc_suspend NULL
793#define soc_resume NULL 834#define soc_resume NULL
@@ -981,16 +1022,39 @@ static int soc_remove(struct platform_device *pdev)
981 return 0; 1022 return 0;
982} 1023}
983 1024
1025static int soc_poweroff(struct device *dev)
1026{
1027 struct platform_device *pdev = to_platform_device(dev);
1028 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1029 struct snd_soc_card *card = socdev->card;
1030
1031 if (!card->instantiated)
1032 return 0;
1033
1034 /* Flush out pmdown_time work - we actually do want to run it
1035 * now, we're shutting down so no imminent restart. */
1036 run_delayed_work(&card->delayed_work);
1037
1038 snd_soc_dapm_shutdown(socdev);
1039
1040 return 0;
1041}
1042
1043static struct dev_pm_ops soc_pm_ops = {
1044 .suspend = soc_suspend,
1045 .resume = soc_resume,
1046 .poweroff = soc_poweroff,
1047};
1048
984/* ASoC platform driver */ 1049/* ASoC platform driver */
985static struct platform_driver soc_driver = { 1050static struct platform_driver soc_driver = {
986 .driver = { 1051 .driver = {
987 .name = "soc-audio", 1052 .name = "soc-audio",
988 .owner = THIS_MODULE, 1053 .owner = THIS_MODULE,
1054 .pm = &soc_pm_ops,
989 }, 1055 },
990 .probe = soc_probe, 1056 .probe = soc_probe,
991 .remove = soc_remove, 1057 .remove = soc_remove,
992 .suspend = soc_suspend,
993 .resume = soc_resume,
994}; 1058};
995 1059
996/* create a new pcm */ 1060/* create a new pcm */
@@ -1062,6 +1126,23 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1062 return ret; 1126 return ret;
1063} 1127}
1064 1128
1129/**
1130 * snd_soc_codec_volatile_register: Report if a register is volatile.
1131 *
1132 * @codec: CODEC to query.
1133 * @reg: Register to query.
1134 *
1135 * Boolean function indiciating if a CODEC register is volatile.
1136 */
1137int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg)
1138{
1139 if (codec->volatile_register)
1140 return codec->volatile_register(reg);
1141 else
1142 return 0;
1143}
1144EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
1145
1065/* codec register dump */ 1146/* codec register dump */
1066static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 1147static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
1067{ 1148{
@@ -1075,6 +1156,9 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
1075 1156
1076 count += sprintf(buf, "%s registers\n", codec->name); 1157 count += sprintf(buf, "%s registers\n", codec->name);
1077 for (i = 0; i < codec->reg_cache_size; i += step) { 1158 for (i = 0; i < codec->reg_cache_size; i += step) {
1159 if (codec->readable_register && !codec->readable_register(i))
1160 continue;
1161
1078 count += sprintf(buf + count, "%2x: ", i); 1162 count += sprintf(buf + count, "%2x: ", i);
1079 if (count >= PAGE_SIZE - 1) 1163 if (count >= PAGE_SIZE - 1)
1080 break; 1164 break;
@@ -1183,10 +1267,18 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1183 if (!codec->debugfs_pop_time) 1267 if (!codec->debugfs_pop_time)
1184 printk(KERN_WARNING 1268 printk(KERN_WARNING
1185 "Failed to create pop time debugfs file\n"); 1269 "Failed to create pop time debugfs file\n");
1270
1271 codec->debugfs_dapm = debugfs_create_dir("dapm", debugfs_root);
1272 if (!codec->debugfs_dapm)
1273 printk(KERN_WARNING
1274 "Failed to create DAPM debugfs directory\n");
1275
1276 snd_soc_dapm_debugfs_init(codec);
1186} 1277}
1187 1278
1188static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 1279static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1189{ 1280{
1281 debugfs_remove_recursive(codec->debugfs_dapm);
1190 debugfs_remove(codec->debugfs_pop_time); 1282 debugfs_remove(codec->debugfs_pop_time);
1191 debugfs_remove(codec->debugfs_reg); 1283 debugfs_remove(codec->debugfs_reg);
1192} 1284}
@@ -1264,10 +1356,10 @@ EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
1264 * Returns 1 for change else 0. 1356 * Returns 1 for change else 0.
1265 */ 1357 */
1266int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 1358int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
1267 unsigned short mask, unsigned short value) 1359 unsigned int mask, unsigned int value)
1268{ 1360{
1269 int change; 1361 int change;
1270 unsigned short old, new; 1362 unsigned int old, new;
1271 1363
1272 mutex_lock(&io_mutex); 1364 mutex_lock(&io_mutex);
1273 old = snd_soc_read(codec, reg); 1365 old = snd_soc_read(codec, reg);
@@ -1294,10 +1386,10 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits);
1294 * Returns 1 for change else 0. 1386 * Returns 1 for change else 0.
1295 */ 1387 */
1296int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, 1388int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
1297 unsigned short mask, unsigned short value) 1389 unsigned int mask, unsigned int value)
1298{ 1390{
1299 int change; 1391 int change;
1300 unsigned short old, new; 1392 unsigned int old, new;
1301 1393
1302 mutex_lock(&io_mutex); 1394 mutex_lock(&io_mutex);
1303 old = snd_soc_read(codec, reg); 1395 old = snd_soc_read(codec, reg);
@@ -1381,8 +1473,11 @@ int snd_soc_init_card(struct snd_soc_device *socdev)
1381 continue; 1473 continue;
1382 } 1474 }
1383 } 1475 }
1384 if (card->dai_link[i].codec_dai->ac97_control) 1476 if (card->dai_link[i].codec_dai->ac97_control) {
1385 ac97 = 1; 1477 ac97 = 1;
1478 snd_ac97_dev_add_pdata(codec->ac97,
1479 card->dai_link[i].cpu_dai->ac97_pdata);
1480 }
1386 } 1481 }
1387 snprintf(codec->card->shortname, sizeof(codec->card->shortname), 1482 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1388 "%s", card->name); 1483 "%s", card->name);
@@ -1586,7 +1681,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
1586{ 1681{
1587 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1682 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1588 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1683 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1589 unsigned short val, bitmask; 1684 unsigned int val, bitmask;
1590 1685
1591 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1686 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1592 ; 1687 ;
@@ -1615,8 +1710,8 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1615{ 1710{
1616 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1711 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1617 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1712 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1618 unsigned short val; 1713 unsigned int val;
1619 unsigned short mask, bitmask; 1714 unsigned int mask, bitmask;
1620 1715
1621 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1716 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1622 ; 1717 ;
@@ -1652,7 +1747,7 @@ int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
1652{ 1747{
1653 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1748 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1654 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1749 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1655 unsigned short reg_val, val, mux; 1750 unsigned int reg_val, val, mux;
1656 1751
1657 reg_val = snd_soc_read(codec, e->reg); 1752 reg_val = snd_soc_read(codec, e->reg);
1658 val = (reg_val >> e->shift_l) & e->mask; 1753 val = (reg_val >> e->shift_l) & e->mask;
@@ -1691,8 +1786,8 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
1691{ 1786{
1692 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1787 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1693 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1788 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1694 unsigned short val; 1789 unsigned int val;
1695 unsigned short mask; 1790 unsigned int mask;
1696 1791
1697 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1792 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1698 return -EINVAL; 1793 return -EINVAL;
@@ -1852,7 +1947,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1852 int max = mc->max; 1947 int max = mc->max;
1853 unsigned int mask = (1 << fls(max)) - 1; 1948 unsigned int mask = (1 << fls(max)) - 1;
1854 unsigned int invert = mc->invert; 1949 unsigned int invert = mc->invert;
1855 unsigned short val, val2, val_mask; 1950 unsigned int val, val2, val_mask;
1856 1951
1857 val = (ucontrol->value.integer.value[0] & mask); 1952 val = (ucontrol->value.integer.value[0] & mask);
1858 if (invert) 1953 if (invert)
@@ -1918,7 +2013,7 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
1918 unsigned int reg2 = mc->rreg; 2013 unsigned int reg2 = mc->rreg;
1919 unsigned int shift = mc->shift; 2014 unsigned int shift = mc->shift;
1920 int max = mc->max; 2015 int max = mc->max;
1921 unsigned int mask = (1<<fls(max))-1; 2016 unsigned int mask = (1 << fls(max)) - 1;
1922 unsigned int invert = mc->invert; 2017 unsigned int invert = mc->invert;
1923 2018
1924 ucontrol->value.integer.value[0] = 2019 ucontrol->value.integer.value[0] =
@@ -1958,7 +2053,7 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1958 unsigned int mask = (1 << fls(max)) - 1; 2053 unsigned int mask = (1 << fls(max)) - 1;
1959 unsigned int invert = mc->invert; 2054 unsigned int invert = mc->invert;
1960 int err; 2055 int err;
1961 unsigned short val, val2, val_mask; 2056 unsigned int val, val2, val_mask;
1962 2057
1963 val_mask = mask << shift; 2058 val_mask = mask << shift;
1964 val = (ucontrol->value.integer.value[0] & mask); 2059 val = (ucontrol->value.integer.value[0] & mask);
@@ -2050,7 +2145,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2050 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2145 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2051 unsigned int reg = mc->reg; 2146 unsigned int reg = mc->reg;
2052 int min = mc->min; 2147 int min = mc->min;
2053 unsigned short val; 2148 unsigned int val;
2054 2149
2055 val = (ucontrol->value.integer.value[0]+min) & 0xff; 2150 val = (ucontrol->value.integer.value[0]+min) & 0xff;
2056 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; 2151 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
@@ -2136,17 +2231,20 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
2136/** 2231/**
2137 * snd_soc_dai_set_tdm_slot - configure DAI TDM. 2232 * snd_soc_dai_set_tdm_slot - configure DAI TDM.
2138 * @dai: DAI 2233 * @dai: DAI
2139 * @mask: DAI specific mask representing used slots. 2234 * @tx_mask: bitmask representing active TX slots.
2235 * @rx_mask: bitmask representing active RX slots.
2140 * @slots: Number of slots in use. 2236 * @slots: Number of slots in use.
2237 * @slot_width: Width in bits for each slot.
2141 * 2238 *
2142 * Configures a DAI for TDM operation. Both mask and slots are codec and DAI 2239 * Configures a DAI for TDM operation. Both mask and slots are codec and DAI
2143 * specific. 2240 * specific.
2144 */ 2241 */
2145int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 2242int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2146 unsigned int mask, int slots) 2243 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
2147{ 2244{
2148 if (dai->ops && dai->ops->set_tdm_slot) 2245 if (dai->ops && dai->ops->set_tdm_slot)
2149 return dai->ops->set_tdm_slot(dai, mask, slots); 2246 return dai->ops->set_tdm_slot(dai, tx_mask, rx_mask,
2247 slots, slot_width);
2150 else 2248 else
2151 return -EINVAL; 2249 return -EINVAL;
2152} 2250}