aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8753.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-11-21 11:32:03 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-01-20 08:58:20 -0500
commitd3398ff05907167f463e119421b053ce043741d1 (patch)
tree741eedfb4ddc3dbb8c465ab855823e8d1eae1a64 /sound/soc/codecs/wm8753.c
parentbfea3abb804f5ab97c5da3da7c6386664531d698 (diff)
ASoC: Convert WM8753 to direct regmap API usage
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8753.c')
-rw-r--r--sound/soc/codecs/wm8753.c186
1 files changed, 139 insertions, 47 deletions
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index b114c19f530a..21ed75de41f3 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -39,6 +39,7 @@
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/of_device.h> 41#include <linux/of_device.h>
42#include <linux/regmap.h>
42#include <linux/spi/spi.h> 43#include <linux/spi/spi.h>
43#include <linux/slab.h> 44#include <linux/slab.h>
44#include <sound/core.h> 45#include <sound/core.h>
@@ -65,28 +66,86 @@ static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
65 * We can't read the WM8753 register space when we 66 * We can't read the WM8753 register space when we
66 * are using 2 wire for device control, so we cache them instead. 67 * are using 2 wire for device control, so we cache them instead.
67 */ 68 */
68static const u16 wm8753_reg[] = { 69static const struct reg_default wm8753_reg_defaults[] = {
69 0x0000, 0x0008, 0x0000, 0x000a, 70 { 0x00, 0x0000 },
70 0x000a, 0x0033, 0x0000, 0x0007, 71 { 0x01, 0x0008 },
71 0x00ff, 0x00ff, 0x000f, 0x000f, 72 { 0x02, 0x0000 },
72 0x007b, 0x0000, 0x0032, 0x0000, 73 { 0x03, 0x000a },
73 0x00c3, 0x00c3, 0x00c0, 0x0000, 74 { 0x04, 0x000a },
74 0x0000, 0x0000, 0x0000, 0x0000, 75 { 0x05, 0x0033 },
75 0x0000, 0x0000, 0x0000, 0x0000, 76 { 0x06, 0x0000 },
76 0x0000, 0x0000, 0x0000, 0x0000, 77 { 0x07, 0x0007 },
77 0x0055, 0x0005, 0x0050, 0x0055, 78 { 0x08, 0x00ff },
78 0x0050, 0x0055, 0x0050, 0x0055, 79 { 0x09, 0x00ff },
79 0x0079, 0x0079, 0x0079, 0x0079, 80 { 0x0a, 0x000f },
80 0x0079, 0x0000, 0x0000, 0x0000, 81 { 0x0b, 0x000f },
81 0x0000, 0x0097, 0x0097, 0x0000, 82 { 0x0c, 0x007b },
82 0x0004, 0x0000, 0x0083, 0x0024, 83 { 0x0d, 0x0000 },
83 0x01ba, 0x0000, 0x0083, 0x0024, 84 { 0x0e, 0x0032 },
84 0x01ba, 0x0000, 0x0000, 0x0000 85 { 0x0f, 0x0000 },
86 { 0x10, 0x00c3 },
87 { 0x11, 0x00c3 },
88 { 0x12, 0x00c0 },
89 { 0x13, 0x0000 },
90 { 0x14, 0x0000 },
91 { 0x15, 0x0000 },
92 { 0x16, 0x0000 },
93 { 0x17, 0x0000 },
94 { 0x18, 0x0000 },
95 { 0x19, 0x0000 },
96 { 0x1a, 0x0000 },
97 { 0x1b, 0x0000 },
98 { 0x1c, 0x0000 },
99 { 0x1d, 0x0000 },
100 { 0x1e, 0x0000 },
101 { 0x1f, 0x0000 },
102 { 0x20, 0x0055 },
103 { 0x21, 0x0005 },
104 { 0x22, 0x0050 },
105 { 0x23, 0x0055 },
106 { 0x24, 0x0050 },
107 { 0x25, 0x0055 },
108 { 0x26, 0x0050 },
109 { 0x27, 0x0055 },
110 { 0x28, 0x0079 },
111 { 0x29, 0x0079 },
112 { 0x2a, 0x0079 },
113 { 0x2b, 0x0079 },
114 { 0x2c, 0x0079 },
115 { 0x2d, 0x0000 },
116 { 0x2e, 0x0000 },
117 { 0x2f, 0x0000 },
118 { 0x30, 0x0000 },
119 { 0x31, 0x0097 },
120 { 0x32, 0x0097 },
121 { 0x33, 0x0000 },
122 { 0x34, 0x0004 },
123 { 0x35, 0x0000 },
124 { 0x36, 0x0083 },
125 { 0x37, 0x0024 },
126 { 0x38, 0x01ba },
127 { 0x39, 0x0000 },
128 { 0x3a, 0x0083 },
129 { 0x3b, 0x0024 },
130 { 0x3c, 0x01ba },
131 { 0x3d, 0x0000 },
132 { 0x3e, 0x0000 },
133 { 0x3f, 0x0000 },
85}; 134};
86 135
136static bool wm8753_volatile(struct device *dev, unsigned int reg)
137{
138 return reg == WM8753_RESET;
139}
140
141static bool wm8753_writeable(struct device *dev, unsigned int reg)
142{
143 return reg <= WM8753_ADCTL2;
144}
145
87/* codec private data */ 146/* codec private data */
88struct wm8753_priv { 147struct wm8753_priv {
89 enum snd_soc_control_type control_type; 148 struct regmap *regmap;
90 unsigned int sysclk; 149 unsigned int sysclk;
91 unsigned int pcmclk; 150 unsigned int pcmclk;
92 151
@@ -1383,25 +1442,15 @@ static void wm8753_work(struct work_struct *work)
1383static int wm8753_suspend(struct snd_soc_codec *codec) 1442static int wm8753_suspend(struct snd_soc_codec *codec)
1384{ 1443{
1385 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1444 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1445 codec->cache_sync = 1;
1386 return 0; 1446 return 0;
1387} 1447}
1388 1448
1389static int wm8753_resume(struct snd_soc_codec *codec) 1449static int wm8753_resume(struct snd_soc_codec *codec)
1390{ 1450{
1391 u16 *reg_cache = codec->reg_cache; 1451 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1392 int i;
1393
1394 /* Sync reg_cache with the hardware */
1395 for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
1396 if (i == WM8753_RESET)
1397 continue;
1398
1399 /* No point in writing hardware default values back */
1400 if (reg_cache[i] == wm8753_reg[i])
1401 continue;
1402 1452
1403 snd_soc_write(codec, i, reg_cache[i]); 1453 regcache_sync(wm8753->regmap);
1404 }
1405 1454
1406 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1455 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1407 1456
@@ -1423,7 +1472,8 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1423 1472
1424 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); 1473 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
1425 1474
1426 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type); 1475 codec->control_data = wm8753->regmap;
1476 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
1427 if (ret < 0) { 1477 if (ret < 0) {
1428 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1478 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1429 return ret; 1479 return ret;
@@ -1473,9 +1523,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1473 .suspend = wm8753_suspend, 1523 .suspend = wm8753_suspend,
1474 .resume = wm8753_resume, 1524 .resume = wm8753_resume,
1475 .set_bias_level = wm8753_set_bias_level, 1525 .set_bias_level = wm8753_set_bias_level,
1476 .reg_cache_size = ARRAY_SIZE(wm8753_reg),
1477 .reg_word_size = sizeof(u16),
1478 .reg_cache_default = wm8753_reg,
1479 1526
1480 .controls = wm8753_snd_controls, 1527 .controls = wm8753_snd_controls,
1481 .num_controls = ARRAY_SIZE(wm8753_snd_controls), 1528 .num_controls = ARRAY_SIZE(wm8753_snd_controls),
@@ -1491,6 +1538,19 @@ static const struct of_device_id wm8753_of_match[] = {
1491}; 1538};
1492MODULE_DEVICE_TABLE(of, wm8753_of_match); 1539MODULE_DEVICE_TABLE(of, wm8753_of_match);
1493 1540
1541static const struct regmap_config wm8753_regmap = {
1542 .reg_bits = 7,
1543 .val_bits = 9,
1544
1545 .max_register = WM8753_ADCTL2,
1546 .writeable_reg = wm8753_writeable,
1547 .volatile_reg = wm8753_volatile,
1548
1549 .cache_type = REGCACHE_RBTREE,
1550 .reg_defaults = wm8753_reg_defaults,
1551 .num_reg_defaults = ARRAY_SIZE(wm8753_reg_defaults),
1552};
1553
1494#if defined(CONFIG_SPI_MASTER) 1554#if defined(CONFIG_SPI_MASTER)
1495static int __devinit wm8753_spi_probe(struct spi_device *spi) 1555static int __devinit wm8753_spi_probe(struct spi_device *spi)
1496{ 1556{
@@ -1501,20 +1561,36 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi)
1501 if (wm8753 == NULL) 1561 if (wm8753 == NULL)
1502 return -ENOMEM; 1562 return -ENOMEM;
1503 1563
1504 wm8753->control_type = SND_SOC_SPI;
1505 spi_set_drvdata(spi, wm8753); 1564 spi_set_drvdata(spi, wm8753);
1506 1565
1507 ret = snd_soc_register_codec(&spi->dev, 1566 wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap);
1508 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); 1567 if (IS_ERR(wm8753->regmap)) {
1509 if (ret < 0) 1568 ret = PTR_ERR(wm8753->regmap);
1510 kfree(wm8753); 1569 dev_err(&spi->dev, "Failed to allocate register map: %d\n",
1570 ret);
1571 goto err;
1572 }
1573
1574 ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753,
1575 wm8753_dai, ARRAY_SIZE(wm8753_dai));
1576 if (ret != 0) {
1577 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
1578 goto err_regmap;
1579 }
1580err_regmap:
1581 regmap_exit(wm8753->regmap);
1582err:
1583 kfree(wm8753);
1511 return ret; 1584 return ret;
1512} 1585}
1513 1586
1514static int __devexit wm8753_spi_remove(struct spi_device *spi) 1587static int __devexit wm8753_spi_remove(struct spi_device *spi)
1515{ 1588{
1589 struct wm8753_priv *wm8753 = spi_get_drvdata(spi);
1590
1516 snd_soc_unregister_codec(&spi->dev); 1591 snd_soc_unregister_codec(&spi->dev);
1517 kfree(spi_get_drvdata(spi)); 1592 regmap_exit(wm8753->regmap);
1593 kfree(wm8753);
1518 return 0; 1594 return 0;
1519} 1595}
1520 1596
@@ -1541,19 +1617,35 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1541 return -ENOMEM; 1617 return -ENOMEM;
1542 1618
1543 i2c_set_clientdata(i2c, wm8753); 1619 i2c_set_clientdata(i2c, wm8753);
1544 wm8753->control_type = SND_SOC_I2C;
1545 1620
1546 ret = snd_soc_register_codec(&i2c->dev, 1621 wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap);
1547 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); 1622 if (IS_ERR(wm8753->regmap)) {
1548 if (ret < 0) 1623 ret = PTR_ERR(wm8753->regmap);
1549 kfree(wm8753); 1624 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1625 ret);
1626 goto err;
1627 }
1628
1629 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753,
1630 wm8753_dai, ARRAY_SIZE(wm8753_dai));
1631 if (ret != 0) {
1632 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
1633 goto err_regmap;
1634 }
1635err_regmap:
1636 regmap_exit(wm8753->regmap);
1637err:
1638 kfree(wm8753);
1550 return ret; 1639 return ret;
1551} 1640}
1552 1641
1553static __devexit int wm8753_i2c_remove(struct i2c_client *client) 1642static __devexit int wm8753_i2c_remove(struct i2c_client *client)
1554{ 1643{
1644 struct wm8753_priv *wm8753 = i2c_get_clientdata(client);
1645
1555 snd_soc_unregister_codec(&client->dev); 1646 snd_soc_unregister_codec(&client->dev);
1556 kfree(i2c_get_clientdata(client)); 1647 regmap_exit(wm8753->regmap);
1648 kfree(wm8753);
1557 return 0; 1649 return 0;
1558} 1650}
1559 1651