aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8753.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-04-14 07:18:27 -0400
committerIngo Molnar <mingo@kernel.org>2012-04-14 07:19:04 -0400
commit6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch)
tree021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /sound/soc/codecs/wm8753.c
parent682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff)
parenta385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff)
Merge branch 'perf/core' into perf/uprobes
Merge in latest upstream (and the latest perf development tree), to prepare for tooling changes, and also to pick up v3.4 MM changes that the uprobes code needs to take care of. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'sound/soc/codecs/wm8753.c')
-rw-r--r--sound/soc/codecs/wm8753.c195
1 files changed, 146 insertions, 49 deletions
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index b114c19f530a..e27e7b62b365 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,30 +1538,62 @@ 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{
1497 struct wm8753_priv *wm8753; 1557 struct wm8753_priv *wm8753;
1498 int ret; 1558 int ret;
1499 1559
1500 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1560 wm8753 = devm_kzalloc(&spi->dev, sizeof(struct wm8753_priv),
1561 GFP_KERNEL);
1501 if (wm8753 == NULL) 1562 if (wm8753 == NULL)
1502 return -ENOMEM; 1563 return -ENOMEM;
1503 1564
1504 wm8753->control_type = SND_SOC_SPI;
1505 spi_set_drvdata(spi, wm8753); 1565 spi_set_drvdata(spi, wm8753);
1506 1566
1507 ret = snd_soc_register_codec(&spi->dev, 1567 wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap);
1508 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); 1568 if (IS_ERR(wm8753->regmap)) {
1509 if (ret < 0) 1569 ret = PTR_ERR(wm8753->regmap);
1510 kfree(wm8753); 1570 dev_err(&spi->dev, "Failed to allocate register map: %d\n",
1571 ret);
1572 goto err;
1573 }
1574
1575 ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753,
1576 wm8753_dai, ARRAY_SIZE(wm8753_dai));
1577 if (ret != 0) {
1578 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
1579 goto err_regmap;
1580 }
1581
1582 return 0;
1583
1584err_regmap:
1585 regmap_exit(wm8753->regmap);
1586err:
1511 return ret; 1587 return ret;
1512} 1588}
1513 1589
1514static int __devexit wm8753_spi_remove(struct spi_device *spi) 1590static int __devexit wm8753_spi_remove(struct spi_device *spi)
1515{ 1591{
1592 struct wm8753_priv *wm8753 = spi_get_drvdata(spi);
1593
1516 snd_soc_unregister_codec(&spi->dev); 1594 snd_soc_unregister_codec(&spi->dev);
1517 kfree(spi_get_drvdata(spi)); 1595 regmap_exit(wm8753->regmap);
1596 kfree(wm8753);
1518 return 0; 1597 return 0;
1519} 1598}
1520 1599
@@ -1536,24 +1615,42 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1536 struct wm8753_priv *wm8753; 1615 struct wm8753_priv *wm8753;
1537 int ret; 1616 int ret;
1538 1617
1539 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1618 wm8753 = devm_kzalloc(&i2c->dev, sizeof(struct wm8753_priv),
1619 GFP_KERNEL);
1540 if (wm8753 == NULL) 1620 if (wm8753 == NULL)
1541 return -ENOMEM; 1621 return -ENOMEM;
1542 1622
1543 i2c_set_clientdata(i2c, wm8753); 1623 i2c_set_clientdata(i2c, wm8753);
1544 wm8753->control_type = SND_SOC_I2C;
1545 1624
1546 ret = snd_soc_register_codec(&i2c->dev, 1625 wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap);
1547 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); 1626 if (IS_ERR(wm8753->regmap)) {
1548 if (ret < 0) 1627 ret = PTR_ERR(wm8753->regmap);
1549 kfree(wm8753); 1628 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1629 ret);
1630 goto err;
1631 }
1632
1633 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753,
1634 wm8753_dai, ARRAY_SIZE(wm8753_dai));
1635 if (ret != 0) {
1636 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
1637 goto err_regmap;
1638 }
1639
1640 return 0;
1641
1642err_regmap:
1643 regmap_exit(wm8753->regmap);
1644err:
1550 return ret; 1645 return ret;
1551} 1646}
1552 1647
1553static __devexit int wm8753_i2c_remove(struct i2c_client *client) 1648static __devexit int wm8753_i2c_remove(struct i2c_client *client)
1554{ 1649{
1650 struct wm8753_priv *wm8753 = i2c_get_clientdata(client);
1651
1555 snd_soc_unregister_codec(&client->dev); 1652 snd_soc_unregister_codec(&client->dev);
1556 kfree(i2c_get_clientdata(client)); 1653 regmap_exit(wm8753->regmap);
1557 return 0; 1654 return 0;
1558} 1655}
1559 1656