aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8903.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-05-20 06:00:43 -0400
committerTakashi Iwai <tiwai@suse.de>2010-05-20 06:00:43 -0400
commitd71f4cece4bd97d05592836202fc04ff2e7817e3 (patch)
tree6c877c7a938758b1323d9c97d46b9c536e618c69 /sound/soc/codecs/wm8903.c
parent19008bdacb9f7841166ebafe0aef361ee582ffbf (diff)
parentad8332c1302bcb4f80d593fd3eb477be9d7f5604 (diff)
Merge branch 'topic/asoc' into for-linus
Conflicts: sound/soc/codecs/ad1938.c
Diffstat (limited to 'sound/soc/codecs/wm8903.c')
-rw-r--r--sound/soc/codecs/wm8903.c217
1 files changed, 196 insertions, 21 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fa5f99fde68b..bf08282d5ee5 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -11,26 +11,27 @@
11 * 11 *
12 * TODO: 12 * TODO:
13 * - TDM mode configuration. 13 * - TDM mode configuration.
14 * - Mic detect.
15 * - Digital microphone support. 14 * - Digital microphone support.
16 * - Interrupt support (mic detect and sequencer).
17 */ 15 */
18 16
19#include <linux/module.h> 17#include <linux/module.h>
20#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
21#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/completion.h>
22#include <linux/delay.h> 21#include <linux/delay.h>
23#include <linux/pm.h> 22#include <linux/pm.h>
24#include <linux/i2c.h> 23#include <linux/i2c.h>
25#include <linux/platform_device.h> 24#include <linux/platform_device.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/jack.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h> 32#include <sound/soc-dapm.h>
33#include <sound/initval.h> 33#include <sound/initval.h>
34#include <sound/wm8903.h>
34 35
35#include "wm8903.h" 36#include "wm8903.h"
36 37
@@ -222,6 +223,14 @@ struct wm8903_priv {
222 int playback_active; 223 int playback_active;
223 int capture_active; 224 int capture_active;
224 225
226 struct completion wseq;
227
228 struct snd_soc_jack *mic_jack;
229 int mic_det;
230 int mic_short;
231 int mic_last_report;
232 int mic_delay;
233
225 struct snd_pcm_substream *master_substream; 234 struct snd_pcm_substream *master_substream;
226 struct snd_pcm_substream *slave_substream; 235 struct snd_pcm_substream *slave_substream;
227}; 236};
@@ -244,13 +253,14 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
244{ 253{
245 u16 reg[5]; 254 u16 reg[5];
246 struct i2c_client *i2c = codec->control_data; 255 struct i2c_client *i2c = codec->control_data;
256 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
247 257
248 BUG_ON(start > 48); 258 BUG_ON(start > 48);
249 259
250 /* Enable the sequencer */ 260 /* Enable the sequencer if it's not already on */
251 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0); 261 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
252 reg[0] |= WM8903_WSEQ_ENA; 262 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
253 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); 263 reg[0] | WM8903_WSEQ_ENA);
254 264
255 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start); 265 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
256 266
@@ -258,20 +268,19 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
258 start | WM8903_WSEQ_START); 268 start | WM8903_WSEQ_START);
259 269
260 /* Wait for it to complete. If we have the interrupt wired up then 270 /* Wait for it to complete. If we have the interrupt wired up then
261 * we could block waiting for an interrupt, though polling may still 271 * that will break us out of the poll early.
262 * be desirable for diagnostic purposes.
263 */ 272 */
264 do { 273 do {
265 msleep(10); 274 wait_for_completion_timeout(&wm8903->wseq,
275 msecs_to_jiffies(10));
266 276
267 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4); 277 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
268 } while (reg[4] & WM8903_WSEQ_BUSY); 278 } while (reg[4] & WM8903_WSEQ_BUSY);
269 279
270 dev_dbg(&i2c->dev, "Sequence complete\n"); 280 dev_dbg(&i2c->dev, "Sequence complete\n");
271 281
272 /* Disable the sequencer again */ 282 /* Disable the sequencer again if we enabled it */
273 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 283 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
274 reg[0] & ~WM8903_WSEQ_ENA);
275 284
276 return 0; 285 return 0;
277} 286}
@@ -412,7 +421,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
412{ 421{
413 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 422 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
414 struct snd_soc_codec *codec = widget->codec; 423 struct snd_soc_codec *codec = widget->codec;
415 struct wm8903_priv *wm8903 = codec->private_data; 424 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
416 struct i2c_client *i2c = codec->control_data; 425 struct i2c_client *i2c = codec->control_data;
417 u16 reg; 426 u16 reg;
418 int ret; 427 int ret;
@@ -993,7 +1002,7 @@ static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
993 int clk_id, unsigned int freq, int dir) 1002 int clk_id, unsigned int freq, int dir)
994{ 1003{
995 struct snd_soc_codec *codec = codec_dai->codec; 1004 struct snd_soc_codec *codec = codec_dai->codec;
996 struct wm8903_priv *wm8903 = codec->private_data; 1005 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
997 1006
998 wm8903->sysclk = freq; 1007 wm8903->sysclk = freq;
999 1008
@@ -1221,7 +1230,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
1221 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1230 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1222 struct snd_soc_device *socdev = rtd->socdev; 1231 struct snd_soc_device *socdev = rtd->socdev;
1223 struct snd_soc_codec *codec = socdev->card->codec; 1232 struct snd_soc_codec *codec = socdev->card->codec;
1224 struct wm8903_priv *wm8903 = codec->private_data; 1233 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1225 struct i2c_client *i2c = codec->control_data; 1234 struct i2c_client *i2c = codec->control_data;
1226 struct snd_pcm_runtime *master_runtime; 1235 struct snd_pcm_runtime *master_runtime;
1227 1236
@@ -1257,7 +1266,7 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream,
1257 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1266 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1258 struct snd_soc_device *socdev = rtd->socdev; 1267 struct snd_soc_device *socdev = rtd->socdev;
1259 struct snd_soc_codec *codec = socdev->card->codec; 1268 struct snd_soc_codec *codec = socdev->card->codec;
1260 struct wm8903_priv *wm8903 = codec->private_data; 1269 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1261 1270
1262 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1271 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1263 wm8903->playback_active--; 1272 wm8903->playback_active--;
@@ -1277,7 +1286,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1286 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1278 struct snd_soc_device *socdev = rtd->socdev; 1287 struct snd_soc_device *socdev = rtd->socdev;
1279 struct snd_soc_codec *codec = socdev->card->codec; 1288 struct snd_soc_codec *codec = socdev->card->codec;
1280 struct wm8903_priv *wm8903 = codec->private_data; 1289 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1281 struct i2c_client *i2c = codec->control_data; 1290 struct i2c_client *i2c = codec->control_data;
1282 int fs = params_rate(params); 1291 int fs = params_rate(params);
1283 int bclk; 1292 int bclk;
@@ -1436,6 +1445,116 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1436 return 0; 1445 return 0;
1437} 1446}
1438 1447
1448/**
1449 * wm8903_mic_detect - Enable microphone detection via the WM8903 IRQ
1450 *
1451 * @codec: WM8903 codec
1452 * @jack: jack to report detection events on
1453 * @det: value to report for presence detection
1454 * @shrt: value to report for short detection
1455 *
1456 * Enable microphone detection via IRQ on the WM8903. If GPIOs are
1457 * being used to bring out signals to the processor then only platform
1458 * data configuration is needed for WM8903 and processor GPIOs should
1459 * be configured using snd_soc_jack_add_gpios() instead.
1460 *
1461 * The current threasholds for detection should be configured using
1462 * micdet_cfg in the platform data. Using this function will force on
1463 * the microphone bias for the device.
1464 */
1465int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
1466 int det, int shrt)
1467{
1468 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1469 int irq_mask = WM8903_MICDET_EINT | WM8903_MICSHRT_EINT;
1470
1471 dev_dbg(codec->dev, "Enabling microphone detection: %x %x\n",
1472 det, shrt);
1473
1474 /* Store the configuration */
1475 wm8903->mic_jack = jack;
1476 wm8903->mic_det = det;
1477 wm8903->mic_short = shrt;
1478
1479 /* Enable interrupts we've got a report configured for */
1480 if (det)
1481 irq_mask &= ~WM8903_MICDET_EINT;
1482 if (shrt)
1483 irq_mask &= ~WM8903_MICSHRT_EINT;
1484
1485 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
1486 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT,
1487 irq_mask);
1488
1489 if (det && shrt) {
1490 /* Enable mic detection, this may not have been set through
1491 * platform data (eg, if the defaults are OK). */
1492 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1493 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1494 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
1495 WM8903_MICDET_ENA, WM8903_MICDET_ENA);
1496 } else {
1497 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
1498 WM8903_MICDET_ENA, 0);
1499 }
1500
1501 return 0;
1502}
1503EXPORT_SYMBOL_GPL(wm8903_mic_detect);
1504
1505static irqreturn_t wm8903_irq(int irq, void *data)
1506{
1507 struct wm8903_priv *wm8903 = data;
1508 struct snd_soc_codec *codec = &wm8903->codec;
1509 int mic_report;
1510 int int_pol;
1511 int int_val = 0;
1512 int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK);
1513
1514 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
1515
1516 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1517 dev_dbg(codec->dev, "Write sequencer done\n");
1518 complete(&wm8903->wseq);
1519 }
1520
1521 /*
1522 * The rest is microphone jack detection. We need to manually
1523 * invert the polarity of the interrupt after each event - to
1524 * simplify the code keep track of the last state we reported
1525 * and just invert the relevant bits in both the report and
1526 * the polarity register.
1527 */
1528 mic_report = wm8903->mic_last_report;
1529 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
1530
1531 if (int_val & WM8903_MICSHRT_EINT) {
1532 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
1533
1534 mic_report ^= wm8903->mic_short;
1535 int_pol ^= WM8903_MICSHRT_INV;
1536 }
1537
1538 if (int_val & WM8903_MICDET_EINT) {
1539 dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol);
1540
1541 mic_report ^= wm8903->mic_det;
1542 int_pol ^= WM8903_MICDET_INV;
1543
1544 msleep(wm8903->mic_delay);
1545 }
1546
1547 snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1,
1548 WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol);
1549
1550 snd_soc_jack_report(wm8903->mic_jack, mic_report,
1551 wm8903->mic_short | wm8903->mic_det);
1552
1553 wm8903->mic_last_report = mic_report;
1554
1555 return IRQ_HANDLED;
1556}
1557
1439#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ 1558#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
1440 SNDRV_PCM_RATE_11025 | \ 1559 SNDRV_PCM_RATE_11025 | \
1441 SNDRV_PCM_RATE_16000 | \ 1560 SNDRV_PCM_RATE_16000 | \
@@ -1510,7 +1629,6 @@ static int wm8903_resume(struct platform_device *pdev)
1510 1629
1511 /* Bring the codec back up to standby first to minimise pop/clicks */ 1630 /* Bring the codec back up to standby first to minimise pop/clicks */
1512 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1631 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1513 wm8903_set_bias_level(codec, codec->suspend_bias_level);
1514 1632
1515 /* Sync back everything else */ 1633 /* Sync back everything else */
1516 if (tmp_cache) { 1634 if (tmp_cache) {
@@ -1530,9 +1648,11 @@ static struct snd_soc_codec *wm8903_codec;
1530static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, 1648static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1531 const struct i2c_device_id *id) 1649 const struct i2c_device_id *id)
1532{ 1650{
1651 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
1533 struct wm8903_priv *wm8903; 1652 struct wm8903_priv *wm8903;
1534 struct snd_soc_codec *codec; 1653 struct snd_soc_codec *codec;
1535 int ret; 1654 int ret, i;
1655 int trigger, irq_pol;
1536 u16 val; 1656 u16 val;
1537 1657
1538 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); 1658 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
@@ -1554,8 +1674,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1554 codec->num_dai = 1; 1674 codec->num_dai = 1;
1555 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache); 1675 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1556 codec->reg_cache = &wm8903->reg_cache[0]; 1676 codec->reg_cache = &wm8903->reg_cache[0];
1557 codec->private_data = wm8903; 1677 snd_soc_codec_set_drvdata(codec, wm8903);
1558 codec->volatile_register = wm8903_volatile_register; 1678 codec->volatile_register = wm8903_volatile_register;
1679 init_completion(&wm8903->wseq);
1559 1680
1560 i2c_set_clientdata(i2c, codec); 1681 i2c_set_clientdata(i2c, codec);
1561 codec->control_data = i2c; 1682 codec->control_data = i2c;
@@ -1579,6 +1700,53 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1579 1700
1580 wm8903_reset(codec); 1701 wm8903_reset(codec);
1581 1702
1703 /* Set up GPIOs and microphone detection */
1704 if (pdata) {
1705 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1706 if (!pdata->gpio_cfg[i])
1707 continue;
1708
1709 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1710 pdata->gpio_cfg[i] & 0xffff);
1711 }
1712
1713 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
1714 pdata->micdet_cfg);
1715
1716 /* Microphone detection needs the WSEQ clock */
1717 if (pdata->micdet_cfg)
1718 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1719 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1720
1721 wm8903->mic_delay = pdata->micdet_delay;
1722 }
1723
1724 if (i2c->irq) {
1725 if (pdata && pdata->irq_active_low) {
1726 trigger = IRQF_TRIGGER_LOW;
1727 irq_pol = WM8903_IRQ_POL;
1728 } else {
1729 trigger = IRQF_TRIGGER_HIGH;
1730 irq_pol = 0;
1731 }
1732
1733 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
1734 WM8903_IRQ_POL, irq_pol);
1735
1736 ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq,
1737 trigger | IRQF_ONESHOT,
1738 "wm8903", wm8903);
1739 if (ret != 0) {
1740 dev_err(&i2c->dev, "Failed to request IRQ: %d\n",
1741 ret);
1742 goto err;
1743 }
1744
1745 /* Enable write sequencer interrupts */
1746 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
1747 WM8903_IM_WSEQ_BUSY_EINT, 0);
1748 }
1749
1582 /* power on device */ 1750 /* power on device */
1583 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1751 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1584 1752
@@ -1619,7 +1787,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1619 ret = snd_soc_register_codec(codec); 1787 ret = snd_soc_register_codec(codec);
1620 if (ret != 0) { 1788 if (ret != 0) {
1621 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); 1789 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1622 goto err; 1790 goto err_irq;
1623 } 1791 }
1624 1792
1625 ret = snd_soc_register_dai(&wm8903_dai); 1793 ret = snd_soc_register_dai(&wm8903_dai);
@@ -1632,6 +1800,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1632 1800
1633err_codec: 1801err_codec:
1634 snd_soc_unregister_codec(codec); 1802 snd_soc_unregister_codec(codec);
1803err_irq:
1804 if (i2c->irq)
1805 free_irq(i2c->irq, wm8903);
1635err: 1806err:
1636 wm8903_codec = NULL; 1807 wm8903_codec = NULL;
1637 kfree(wm8903); 1808 kfree(wm8903);
@@ -1641,13 +1812,17 @@ err:
1641static __devexit int wm8903_i2c_remove(struct i2c_client *client) 1812static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1642{ 1813{
1643 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1814 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1815 struct wm8903_priv *priv = snd_soc_codec_get_drvdata(codec);
1644 1816
1645 snd_soc_unregister_dai(&wm8903_dai); 1817 snd_soc_unregister_dai(&wm8903_dai);
1646 snd_soc_unregister_codec(codec); 1818 snd_soc_unregister_codec(codec);
1647 1819
1648 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1820 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1649 1821
1650 kfree(codec->private_data); 1822 if (client->irq)
1823 free_irq(client->irq, priv);
1824
1825 kfree(priv);
1651 1826
1652 wm8903_codec = NULL; 1827 wm8903_codec = NULL;
1653 wm8903_dai.dev = NULL; 1828 wm8903_dai.dev = NULL;