diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-04-14 07:18:27 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-04-14 07:19:04 -0400 |
commit | 6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch) | |
tree | 021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /sound/soc/codecs/wm8753.c | |
parent | 682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff) | |
parent | a385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (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.c | 195 |
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 | */ |
68 | static const u16 wm8753_reg[] = { | 69 | static 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 | ||
136 | static bool wm8753_volatile(struct device *dev, unsigned int reg) | ||
137 | { | ||
138 | return reg == WM8753_RESET; | ||
139 | } | ||
140 | |||
141 | static 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 */ |
88 | struct wm8753_priv { | 147 | struct 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) | |||
1383 | static int wm8753_suspend(struct snd_soc_codec *codec) | 1442 | static 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 | ||
1389 | static int wm8753_resume(struct snd_soc_codec *codec) | 1449 | static 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 | }; |
1492 | MODULE_DEVICE_TABLE(of, wm8753_of_match); | 1539 | MODULE_DEVICE_TABLE(of, wm8753_of_match); |
1493 | 1540 | ||
1541 | static 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) |
1495 | static int __devinit wm8753_spi_probe(struct spi_device *spi) | 1555 | static 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 | |||
1584 | err_regmap: | ||
1585 | regmap_exit(wm8753->regmap); | ||
1586 | err: | ||
1511 | return ret; | 1587 | return ret; |
1512 | } | 1588 | } |
1513 | 1589 | ||
1514 | static int __devexit wm8753_spi_remove(struct spi_device *spi) | 1590 | static 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 | |||
1642 | err_regmap: | ||
1643 | regmap_exit(wm8753->regmap); | ||
1644 | err: | ||
1550 | return ret; | 1645 | return ret; |
1551 | } | 1646 | } |
1552 | 1647 | ||
1553 | static __devexit int wm8753_i2c_remove(struct i2c_client *client) | 1648 | static __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 | ||