diff options
-rw-r--r-- | arch/arm/mach-mx3/clock-imx31.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-mx3/clock-imx35.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-mx3/devices.c | 4 | ||||
-rw-r--r-- | arch/arm/plat-mxc/audmux-v2.c | 4 | ||||
-rw-r--r-- | include/sound/wm8962.h | 1 | ||||
-rw-r--r-- | sound/soc/codecs/wm8804.c | 49 | ||||
-rw-r--r-- | sound/soc/codecs/wm8962.c | 228 | ||||
-rw-r--r-- | sound/soc/codecs/wm8962.h | 4 | ||||
-rw-r--r-- | sound/soc/imx/eukrea-tlv320.c | 2 | ||||
-rw-r--r-- | sound/soc/imx/imx-ssi.c | 2 | ||||
-rw-r--r-- | sound/soc/imx/phycore-ac97.c | 2 | ||||
-rw-r--r-- | sound/soc/imx/wm1133-ev1.c | 2 |
12 files changed, 265 insertions, 41 deletions
diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c index 9b52a67abf2d..9a9eb6de6127 100644 --- a/arch/arm/mach-mx3/clock-imx31.c +++ b/arch/arm/mach-mx3/clock-imx31.c | |||
@@ -558,8 +558,8 @@ static struct clk_lookup lookups[] = { | |||
558 | _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) | 558 | _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) |
559 | _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) | 559 | _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) |
560 | _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) | 560 | _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) |
561 | _REGISTER_CLOCK("imx-ssi-dai.0", NULL, ssi1_clk) | 561 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) |
562 | _REGISTER_CLOCK("imx-ssi-dai.1", NULL, ssi2_clk) | 562 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) |
563 | _REGISTER_CLOCK(NULL, "firi", firi_clk) | 563 | _REGISTER_CLOCK(NULL, "firi", firi_clk) |
564 | _REGISTER_CLOCK(NULL, "ata", ata_clk) | 564 | _REGISTER_CLOCK(NULL, "ata", ata_clk) |
565 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) | 565 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) |
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c index f29c3e91fa3a..d3af0fdf8475 100644 --- a/arch/arm/mach-mx3/clock-imx35.c +++ b/arch/arm/mach-mx3/clock-imx35.c | |||
@@ -464,8 +464,8 @@ static struct clk_lookup lookups[] = { | |||
464 | _REGISTER_CLOCK(NULL, "sdma", sdma_clk) | 464 | _REGISTER_CLOCK(NULL, "sdma", sdma_clk) |
465 | _REGISTER_CLOCK(NULL, "spba", spba_clk) | 465 | _REGISTER_CLOCK(NULL, "spba", spba_clk) |
466 | _REGISTER_CLOCK(NULL, "spdif", spdif_clk) | 466 | _REGISTER_CLOCK(NULL, "spdif", spdif_clk) |
467 | _REGISTER_CLOCK("imx-ssi-dai.0", NULL, ssi1_clk) | 467 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) |
468 | _REGISTER_CLOCK("imx-ssi-dai.1", NULL, ssi2_clk) | 468 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) |
469 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) | 469 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) |
470 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) | 470 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) |
471 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) | 471 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) |
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 90eccba66d00..a4fd1a26fc91 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c | |||
@@ -327,14 +327,14 @@ static struct resource imx_ssi_resources1[] = { | |||
327 | }; | 327 | }; |
328 | 328 | ||
329 | struct platform_device imx_ssi_device0 = { | 329 | struct platform_device imx_ssi_device0 = { |
330 | .name = "imx-ssi-dai", | 330 | .name = "imx-ssi", |
331 | .id = 0, | 331 | .id = 0, |
332 | .num_resources = ARRAY_SIZE(imx_ssi_resources0), | 332 | .num_resources = ARRAY_SIZE(imx_ssi_resources0), |
333 | .resource = imx_ssi_resources0, | 333 | .resource = imx_ssi_resources0, |
334 | }; | 334 | }; |
335 | 335 | ||
336 | struct platform_device imx_ssi_device1 = { | 336 | struct platform_device imx_ssi_device1 = { |
337 | .name = "imx-ssi-dai", | 337 | .name = "imx-ssi", |
338 | .id = 1, | 338 | .id = 1, |
339 | .num_resources = ARRAY_SIZE(imx_ssi_resources1), | 339 | .num_resources = ARRAY_SIZE(imx_ssi_resources1), |
340 | .resource = imx_ssi_resources1, | 340 | .resource = imx_ssi_resources1, |
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c index 910374d1d486..f9e7cdbd0005 100644 --- a/arch/arm/plat-mxc/audmux-v2.c +++ b/arch/arm/plat-mxc/audmux-v2.c | |||
@@ -45,9 +45,9 @@ static const char *audmux_port_string(int port) | |||
45 | { | 45 | { |
46 | switch (port) { | 46 | switch (port) { |
47 | case MX31_AUDMUX_PORT1_SSI0: | 47 | case MX31_AUDMUX_PORT1_SSI0: |
48 | return "imx-ssi-dai.0"; | 48 | return "imx-ssi.0"; |
49 | case MX31_AUDMUX_PORT2_SSI1: | 49 | case MX31_AUDMUX_PORT2_SSI1: |
50 | return "imx-ssi-dai.1"; | 50 | return "imx-ssi.1"; |
51 | case MX31_AUDMUX_PORT3_SSI_PINS_3: | 51 | case MX31_AUDMUX_PORT3_SSI_PINS_3: |
52 | return "SSI3"; | 52 | return "SSI3"; |
53 | case MX31_AUDMUX_PORT4_SSI_PINS_4: | 53 | case MX31_AUDMUX_PORT4_SSI_PINS_4: |
diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h index 9722aac5a138..2b5306c503fb 100644 --- a/include/sound/wm8962.h +++ b/include/sound/wm8962.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #define WM8962_GPIO_SET 0x10000 | 15 | #define WM8962_GPIO_SET 0x10000 |
16 | 16 | ||
17 | struct wm8962_pdata { | 17 | struct wm8962_pdata { |
18 | int gpio_base; | ||
18 | u32 gpio_init[WM8962_MAX_GPIO]; | 19 | u32 gpio_init[WM8962_MAX_GPIO]; |
19 | 20 | ||
20 | /* Setup for microphone detection, raw value to be written to | 21 | /* Setup for microphone detection, raw value to be written to |
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index ca7d9eea1264..2657f5c7ff08 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -390,36 +390,41 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id, | |||
390 | int source, unsigned int freq_in, | 390 | int source, unsigned int freq_in, |
391 | unsigned int freq_out) | 391 | unsigned int freq_out) |
392 | { | 392 | { |
393 | int ret; | ||
394 | struct snd_soc_codec *codec; | 393 | struct snd_soc_codec *codec; |
395 | struct pll_div pll_div = { 0 }; | ||
396 | 394 | ||
397 | codec = dai->codec; | 395 | codec = dai->codec; |
398 | if (freq_in && freq_out) { | 396 | if (!freq_in || !freq_out) { |
397 | /* disable the PLL */ | ||
398 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); | ||
399 | return 0; | ||
400 | } else { | ||
401 | int ret; | ||
402 | struct pll_div pll_div; | ||
403 | |||
399 | ret = pll_factors(&pll_div, freq_out, freq_in); | 404 | ret = pll_factors(&pll_div, freq_out, freq_in); |
400 | if (ret) | 405 | if (ret) |
401 | return ret; | 406 | return ret; |
402 | } | ||
403 | 407 | ||
404 | /* power down the PLL before reprogramming it */ | 408 | /* power down the PLL before reprogramming it */ |
405 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0); | 409 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); |
406 | 410 | ||
407 | if (!freq_in || !freq_out) | 411 | if (!freq_in || !freq_out) |
408 | return 0; | 412 | return 0; |
409 | |||
410 | /* set PLLN and PRESCALE */ | ||
411 | snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10, | ||
412 | pll_div.n | (pll_div.prescale << 4)); | ||
413 | /* set mclkdiv and freqmode */ | ||
414 | snd_soc_update_bits(codec, WM8804_PLL5, 0x3 | 0x8, | ||
415 | pll_div.freqmode | (pll_div.mclkdiv << 3)); | ||
416 | /* set PLLK */ | ||
417 | snd_soc_write(codec, WM8804_PLL1, pll_div.k & 0xff); | ||
418 | snd_soc_write(codec, WM8804_PLL2, (pll_div.k >> 8) & 0xff); | ||
419 | snd_soc_write(codec, WM8804_PLL3, pll_div.k >> 16); | ||
420 | 413 | ||
421 | /* power up the PLL */ | 414 | /* set PLLN and PRESCALE */ |
422 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); | 415 | snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10, |
416 | pll_div.n | (pll_div.prescale << 4)); | ||
417 | /* set mclkdiv and freqmode */ | ||
418 | snd_soc_update_bits(codec, WM8804_PLL5, 0x3 | 0x8, | ||
419 | pll_div.freqmode | (pll_div.mclkdiv << 3)); | ||
420 | /* set PLLK */ | ||
421 | snd_soc_write(codec, WM8804_PLL1, pll_div.k & 0xff); | ||
422 | snd_soc_write(codec, WM8804_PLL2, (pll_div.k >> 8) & 0xff); | ||
423 | snd_soc_write(codec, WM8804_PLL3, pll_div.k >> 16); | ||
424 | |||
425 | /* power up the PLL */ | ||
426 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0); | ||
427 | } | ||
423 | 428 | ||
424 | return 0; | 429 | return 0; |
425 | } | 430 | } |
@@ -669,7 +674,7 @@ static struct snd_soc_dai_ops wm8804_dai_ops = { | |||
669 | SNDRV_PCM_FMTBIT_S24_LE) | 674 | SNDRV_PCM_FMTBIT_S24_LE) |
670 | 675 | ||
671 | static struct snd_soc_dai_driver wm8804_dai = { | 676 | static struct snd_soc_dai_driver wm8804_dai = { |
672 | .name = "wm8804-s/pdif", | 677 | .name = "wm8804-spdif", |
673 | .playback = { | 678 | .playback = { |
674 | .stream_name = "Playback", | 679 | .stream_name = "Playback", |
675 | .channels_min = 2, | 680 | .channels_min = 2, |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index be34146a775b..6d30f3464bad 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/gcd.h> | 19 | #include <linux/gcd.h> |
20 | #include <linux/gpio.h> | ||
20 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
21 | #include <linux/input.h> | 22 | #include <linux/input.h> |
22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
@@ -24,6 +25,7 @@ | |||
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
25 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
26 | #include <sound/core.h> | 27 | #include <sound/core.h> |
28 | #include <sound/jack.h> | ||
27 | #include <sound/pcm.h> | 29 | #include <sound/pcm.h> |
28 | #include <sound/pcm_params.h> | 30 | #include <sound/pcm_params.h> |
29 | #include <sound/soc.h> | 31 | #include <sound/soc.h> |
@@ -62,6 +64,9 @@ struct wm8962_priv { | |||
62 | int fll_fref; | 64 | int fll_fref; |
63 | int fll_fout; | 65 | int fll_fout; |
64 | 66 | ||
67 | struct delayed_work mic_work; | ||
68 | struct snd_soc_jack *jack; | ||
69 | |||
65 | struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES]; | 70 | struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES]; |
66 | struct notifier_block disable_nb[WM8962_NUM_SUPPLIES]; | 71 | struct notifier_block disable_nb[WM8962_NUM_SUPPLIES]; |
67 | 72 | ||
@@ -70,6 +75,10 @@ struct wm8962_priv { | |||
70 | struct work_struct beep_work; | 75 | struct work_struct beep_work; |
71 | int beep_rate; | 76 | int beep_rate; |
72 | #endif | 77 | #endif |
78 | |||
79 | #ifdef CONFIG_GPIOLIB | ||
80 | struct gpio_chip gpio_chip; | ||
81 | #endif | ||
73 | }; | 82 | }; |
74 | 83 | ||
75 | /* We can't use the same notifier block for more than one supply and | 84 | /* We can't use the same notifier block for more than one supply and |
@@ -911,12 +920,6 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec) | |||
911 | int clocking2 = 0; | 920 | int clocking2 = 0; |
912 | int aif2 = 0; | 921 | int aif2 = 0; |
913 | 922 | ||
914 | /* If the CODEC is powered on we can configure BCLK */ | ||
915 | if (codec->bias_level != SND_SOC_BIAS_OFF) { | ||
916 | dev_dbg(codec->dev, "Bias is off, can't configure BCLK\n"); | ||
917 | return; | ||
918 | } | ||
919 | |||
920 | if (!wm8962->bclk) { | 923 | if (!wm8962->bclk) { |
921 | dev_dbg(codec->dev, "No BCLK rate configured\n"); | 924 | dev_dbg(codec->dev, "No BCLK rate configured\n"); |
922 | return; | 925 | return; |
@@ -1463,9 +1466,40 @@ static struct snd_soc_dai_driver wm8962_dai = { | |||
1463 | .symmetric_rates = 1, | 1466 | .symmetric_rates = 1, |
1464 | }; | 1467 | }; |
1465 | 1468 | ||
1469 | static void wm8962_mic_work(struct work_struct *work) | ||
1470 | { | ||
1471 | struct wm8962_priv *wm8962 = container_of(work, | ||
1472 | struct wm8962_priv, | ||
1473 | mic_work.work); | ||
1474 | struct snd_soc_codec *codec = wm8962->codec; | ||
1475 | int status = 0; | ||
1476 | int irq_pol = 0; | ||
1477 | int reg; | ||
1478 | |||
1479 | reg = snd_soc_read(codec, WM8962_ADDITIONAL_CONTROL_4); | ||
1480 | |||
1481 | if (reg & WM8962_MICDET_STS) { | ||
1482 | status |= SND_JACK_MICROPHONE; | ||
1483 | irq_pol |= WM8962_MICD_IRQ_POL; | ||
1484 | } | ||
1485 | |||
1486 | if (reg & WM8962_MICSHORT_STS) { | ||
1487 | status |= SND_JACK_BTN_0; | ||
1488 | irq_pol |= WM8962_MICSCD_IRQ_POL; | ||
1489 | } | ||
1490 | |||
1491 | snd_soc_jack_report(wm8962->jack, status, | ||
1492 | SND_JACK_MICROPHONE | SND_JACK_BTN_0); | ||
1493 | |||
1494 | snd_soc_update_bits(codec, WM8962_MICINT_SOURCE_POL, | ||
1495 | WM8962_MICSCD_IRQ_POL | | ||
1496 | WM8962_MICD_IRQ_POL, irq_pol); | ||
1497 | } | ||
1498 | |||
1466 | static irqreturn_t wm8962_irq(int irq, void *data) | 1499 | static irqreturn_t wm8962_irq(int irq, void *data) |
1467 | { | 1500 | { |
1468 | struct snd_soc_codec *codec = data; | 1501 | struct snd_soc_codec *codec = data; |
1502 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
1469 | int mask; | 1503 | int mask; |
1470 | int active; | 1504 | int active; |
1471 | 1505 | ||
@@ -1480,12 +1514,59 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
1480 | if (active & WM8962_TEMP_SHUT_EINT) | 1514 | if (active & WM8962_TEMP_SHUT_EINT) |
1481 | dev_crit(codec->dev, "Thermal shutdown\n"); | 1515 | dev_crit(codec->dev, "Thermal shutdown\n"); |
1482 | 1516 | ||
1517 | if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { | ||
1518 | dev_dbg(codec->dev, "Microphone event detected\n"); | ||
1519 | |||
1520 | schedule_delayed_work(&wm8962->mic_work, | ||
1521 | msecs_to_jiffies(250)); | ||
1522 | } | ||
1523 | |||
1483 | /* Acknowledge the interrupts */ | 1524 | /* Acknowledge the interrupts */ |
1484 | snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); | 1525 | snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); |
1485 | 1526 | ||
1486 | return IRQ_HANDLED; | 1527 | return IRQ_HANDLED; |
1487 | } | 1528 | } |
1488 | 1529 | ||
1530 | /** | ||
1531 | * wm8962_mic_detect - Enable microphone detection via the WM8962 IRQ | ||
1532 | * | ||
1533 | * @codec: WM8962 codec | ||
1534 | * @jack: jack to report detection events on | ||
1535 | * | ||
1536 | * Enable microphone detection via IRQ on the WM8962. If GPIOs are | ||
1537 | * being used to bring out signals to the processor then only platform | ||
1538 | * data configuration is needed for WM8962 and processor GPIOs should | ||
1539 | * be configured using snd_soc_jack_add_gpios() instead. | ||
1540 | * | ||
1541 | * If no jack is supplied detection will be disabled. | ||
1542 | */ | ||
1543 | int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | ||
1544 | { | ||
1545 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
1546 | int irq_mask, enable; | ||
1547 | |||
1548 | wm8962->jack = jack; | ||
1549 | if (jack) { | ||
1550 | irq_mask = 0; | ||
1551 | enable = WM8962_MICDET_ENA; | ||
1552 | } else { | ||
1553 | irq_mask = WM8962_MICD_EINT | WM8962_MICSCD_EINT; | ||
1554 | enable = 0; | ||
1555 | } | ||
1556 | |||
1557 | snd_soc_update_bits(codec, WM8962_INTERRUPT_STATUS_2_MASK, | ||
1558 | WM8962_MICD_EINT | WM8962_MICSCD_EINT, irq_mask); | ||
1559 | snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4, | ||
1560 | WM8962_MICDET_ENA, enable); | ||
1561 | |||
1562 | /* Send an initial empty report */ | ||
1563 | snd_soc_jack_report(wm8962->jack, 0, | ||
1564 | SND_JACK_MICROPHONE | SND_JACK_BTN_0); | ||
1565 | |||
1566 | return 0; | ||
1567 | } | ||
1568 | EXPORT_SYMBOL_GPL(wm8962_mic_detect); | ||
1569 | |||
1489 | #ifdef CONFIG_PM | 1570 | #ifdef CONFIG_PM |
1490 | static int wm8962_resume(struct snd_soc_codec *codec) | 1571 | static int wm8962_resume(struct snd_soc_codec *codec) |
1491 | { | 1572 | { |
@@ -1652,6 +1733,132 @@ static void wm8962_free_beep(struct snd_soc_codec *codec) | |||
1652 | } | 1733 | } |
1653 | #endif | 1734 | #endif |
1654 | 1735 | ||
1736 | static void wm8962_set_gpio_mode(struct snd_soc_codec *codec, int gpio) | ||
1737 | { | ||
1738 | int mask = 0; | ||
1739 | int val = 0; | ||
1740 | |||
1741 | /* Some of the GPIOs are behind MFP configuration and need to | ||
1742 | * be put into GPIO mode. */ | ||
1743 | switch (gpio) { | ||
1744 | case 2: | ||
1745 | mask = WM8962_CLKOUT2_SEL_MASK; | ||
1746 | val = 1 << WM8962_CLKOUT2_SEL_SHIFT; | ||
1747 | break; | ||
1748 | case 3: | ||
1749 | mask = WM8962_CLKOUT3_SEL_MASK; | ||
1750 | val = 1 << WM8962_CLKOUT3_SEL_SHIFT; | ||
1751 | break; | ||
1752 | default: | ||
1753 | break; | ||
1754 | } | ||
1755 | |||
1756 | if (mask) | ||
1757 | snd_soc_update_bits(codec, WM8962_ANALOGUE_CLOCKING1, | ||
1758 | mask, val); | ||
1759 | } | ||
1760 | |||
1761 | #ifdef CONFIG_GPIOLIB | ||
1762 | static inline struct wm8962_priv *gpio_to_wm8962(struct gpio_chip *chip) | ||
1763 | { | ||
1764 | return container_of(chip, struct wm8962_priv, gpio_chip); | ||
1765 | } | ||
1766 | |||
1767 | static int wm8962_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
1768 | { | ||
1769 | struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); | ||
1770 | struct snd_soc_codec *codec = wm8962->codec; | ||
1771 | |||
1772 | /* The WM8962 GPIOs aren't linearly numbered. For simplicity | ||
1773 | * we export linear numbers and error out if the unsupported | ||
1774 | * ones are requsted. | ||
1775 | */ | ||
1776 | switch (offset + 1) { | ||
1777 | case 2: | ||
1778 | case 3: | ||
1779 | case 5: | ||
1780 | case 6: | ||
1781 | break; | ||
1782 | default: | ||
1783 | return -EINVAL; | ||
1784 | } | ||
1785 | |||
1786 | wm8962_set_gpio_mode(codec, offset + 1); | ||
1787 | |||
1788 | return 0; | ||
1789 | } | ||
1790 | |||
1791 | static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
1792 | { | ||
1793 | struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); | ||
1794 | struct snd_soc_codec *codec = wm8962->codec; | ||
1795 | |||
1796 | snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, | ||
1797 | WM8962_GP2_LVL, value << WM8962_GP2_LVL_SHIFT); | ||
1798 | } | ||
1799 | |||
1800 | static int wm8962_gpio_direction_out(struct gpio_chip *chip, | ||
1801 | unsigned offset, int value) | ||
1802 | { | ||
1803 | struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); | ||
1804 | struct snd_soc_codec *codec = wm8962->codec; | ||
1805 | int val; | ||
1806 | |||
1807 | /* Force function 1 (logic output) */ | ||
1808 | val = (1 << WM8962_GP2_FN_SHIFT) | (value << WM8962_GP2_LVL_SHIFT); | ||
1809 | |||
1810 | return snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, | ||
1811 | WM8962_GP2_FN_MASK | WM8962_GP2_LVL, val); | ||
1812 | } | ||
1813 | |||
1814 | static struct gpio_chip wm8962_template_chip = { | ||
1815 | .label = "wm8962", | ||
1816 | .owner = THIS_MODULE, | ||
1817 | .request = wm8962_gpio_request, | ||
1818 | .direction_output = wm8962_gpio_direction_out, | ||
1819 | .set = wm8962_gpio_set, | ||
1820 | .can_sleep = 1, | ||
1821 | }; | ||
1822 | |||
1823 | static void wm8962_init_gpio(struct snd_soc_codec *codec) | ||
1824 | { | ||
1825 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
1826 | struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); | ||
1827 | int ret; | ||
1828 | |||
1829 | wm8962->gpio_chip = wm8962_template_chip; | ||
1830 | wm8962->gpio_chip.ngpio = WM8962_MAX_GPIO; | ||
1831 | wm8962->gpio_chip.dev = codec->dev; | ||
1832 | |||
1833 | if (pdata && pdata->gpio_base) | ||
1834 | wm8962->gpio_chip.base = pdata->gpio_base; | ||
1835 | else | ||
1836 | wm8962->gpio_chip.base = -1; | ||
1837 | |||
1838 | ret = gpiochip_add(&wm8962->gpio_chip); | ||
1839 | if (ret != 0) | ||
1840 | dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); | ||
1841 | } | ||
1842 | |||
1843 | static void wm8962_free_gpio(struct snd_soc_codec *codec) | ||
1844 | { | ||
1845 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
1846 | int ret; | ||
1847 | |||
1848 | ret = gpiochip_remove(&wm8962->gpio_chip); | ||
1849 | if (ret != 0) | ||
1850 | dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); | ||
1851 | } | ||
1852 | #else | ||
1853 | static void wm8962_init_gpio(struct snd_soc_codec *codec) | ||
1854 | { | ||
1855 | } | ||
1856 | |||
1857 | static void wm8962_free_gpio(struct snd_soc_codec *codec) | ||
1858 | { | ||
1859 | } | ||
1860 | #endif | ||
1861 | |||
1655 | static int wm8962_probe(struct snd_soc_codec *codec) | 1862 | static int wm8962_probe(struct snd_soc_codec *codec) |
1656 | { | 1863 | { |
1657 | int ret; | 1864 | int ret; |
@@ -1662,6 +1869,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
1662 | int i, trigger, irq_pol; | 1869 | int i, trigger, irq_pol; |
1663 | 1870 | ||
1664 | wm8962->codec = codec; | 1871 | wm8962->codec = codec; |
1872 | INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); | ||
1665 | 1873 | ||
1666 | codec->cache_sync = 1; | 1874 | codec->cache_sync = 1; |
1667 | codec->idle_bias_off = 1; | 1875 | codec->idle_bias_off = 1; |
@@ -1749,9 +1957,11 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
1749 | if (pdata) { | 1957 | if (pdata) { |
1750 | /* Apply static configuration for GPIOs */ | 1958 | /* Apply static configuration for GPIOs */ |
1751 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) | 1959 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) |
1752 | if (pdata->gpio_init[i]) | 1960 | if (pdata->gpio_init[i]) { |
1961 | wm8962_set_gpio_mode(codec, i + 1); | ||
1753 | snd_soc_write(codec, 0x200 + i, | 1962 | snd_soc_write(codec, 0x200 + i, |
1754 | pdata->gpio_init[i] & 0xffff); | 1963 | pdata->gpio_init[i] & 0xffff); |
1964 | } | ||
1755 | 1965 | ||
1756 | /* Put the speakers into mono mode? */ | 1966 | /* Put the speakers into mono mode? */ |
1757 | if (pdata->spk_mono) | 1967 | if (pdata->spk_mono) |
@@ -1784,6 +1994,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
1784 | wm8962_add_widgets(codec); | 1994 | wm8962_add_widgets(codec); |
1785 | 1995 | ||
1786 | wm8962_init_beep(codec); | 1996 | wm8962_init_beep(codec); |
1997 | wm8962_init_gpio(codec); | ||
1787 | 1998 | ||
1788 | if (i2c->irq) { | 1999 | if (i2c->irq) { |
1789 | if (pdata && pdata->irq_active_low) { | 2000 | if (pdata && pdata->irq_active_low) { |
@@ -1834,6 +2045,9 @@ static int wm8962_remove(struct snd_soc_codec *codec) | |||
1834 | if (i2c->irq) | 2045 | if (i2c->irq) |
1835 | free_irq(i2c->irq, codec); | 2046 | free_irq(i2c->irq, codec); |
1836 | 2047 | ||
2048 | cancel_delayed_work_sync(&wm8962->mic_work); | ||
2049 | |||
2050 | wm8962_free_gpio(codec); | ||
1837 | wm8962_free_beep(codec); | 2051 | wm8962_free_beep(codec); |
1838 | for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) | 2052 | for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) |
1839 | regulator_unregister_notifier(wm8962->supplies[i].consumer, | 2053 | regulator_unregister_notifier(wm8962->supplies[i].consumer, |
diff --git a/sound/soc/codecs/wm8962.h b/sound/soc/codecs/wm8962.h index 6145399acb16..2af6c9371fcc 100644 --- a/sound/soc/codecs/wm8962.h +++ b/sound/soc/codecs/wm8962.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #define _WM8962_H | 14 | #define _WM8962_H |
15 | 15 | ||
16 | #include <asm/types.h> | 16 | #include <asm/types.h> |
17 | #include <sound/soc.h> | ||
17 | 18 | ||
18 | #define WM8962_SYSCLK_MCLK 1 | 19 | #define WM8962_SYSCLK_MCLK 1 |
19 | #define WM8962_SYSCLK_FLL 2 | 20 | #define WM8962_SYSCLK_FLL 2 |
@@ -181,6 +182,7 @@ | |||
181 | #define WM8962_EQ39 0x175 | 182 | #define WM8962_EQ39 0x175 |
182 | #define WM8962_EQ40 0x176 | 183 | #define WM8962_EQ40 0x176 |
183 | #define WM8962_EQ41 0x177 | 184 | #define WM8962_EQ41 0x177 |
185 | #define WM8962_GPIO_BASE 0x200 | ||
184 | #define WM8962_GPIO_2 0x201 | 186 | #define WM8962_GPIO_2 0x201 |
185 | #define WM8962_GPIO_3 0x202 | 187 | #define WM8962_GPIO_3 0x202 |
186 | #define WM8962_GPIO_5 0x204 | 188 | #define WM8962_GPIO_5 0x204 |
@@ -3784,4 +3786,6 @@ struct wm8962_reg_access { | |||
3784 | extern | 3786 | extern |
3785 | const struct wm8962_reg_access wm8962_reg_access[WM8962_MAX_REGISTER + 1]; | 3787 | const struct wm8962_reg_access wm8962_reg_access[WM8962_MAX_REGISTER + 1]; |
3786 | 3788 | ||
3789 | int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); | ||
3790 | |||
3787 | #endif | 3791 | #endif |
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c index 807f736ee294..b59675257ce5 100644 --- a/sound/soc/imx/eukrea-tlv320.c +++ b/sound/soc/imx/eukrea-tlv320.c | |||
@@ -82,7 +82,7 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = { | |||
82 | .codec_dai = "tlv320aic23-hifi", | 82 | .codec_dai = "tlv320aic23-hifi", |
83 | .platform_name = "imx-pcm-audio.0", | 83 | .platform_name = "imx-pcm-audio.0", |
84 | .codec_name = "tlv320aic23-codec.0-001a", | 84 | .codec_name = "tlv320aic23-codec.0-001a", |
85 | .cpu_dai = "imx-ssi-dai.0", | 85 | .cpu_dai = "imx-ssi.0", |
86 | .ops = &eukrea_tlv320_snd_ops, | 86 | .ops = &eukrea_tlv320_snd_ops, |
87 | }; | 87 | }; |
88 | 88 | ||
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 26716e9626f4..d4bd345b0a8d 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
@@ -734,7 +734,7 @@ static struct platform_driver imx_ssi_driver = { | |||
734 | .remove = __devexit_p(imx_ssi_remove), | 734 | .remove = __devexit_p(imx_ssi_remove), |
735 | 735 | ||
736 | .driver = { | 736 | .driver = { |
737 | .name = "imx-ssi-dai", | 737 | .name = "imx-ssi", |
738 | .owner = THIS_MODULE, | 738 | .owner = THIS_MODULE, |
739 | }, | 739 | }, |
740 | }; | 740 | }; |
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c index 65f0f99ca6dd..6a65dd705519 100644 --- a/sound/soc/imx/phycore-ac97.c +++ b/sound/soc/imx/phycore-ac97.c | |||
@@ -34,7 +34,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = { | |||
34 | .stream_name = "HiFi", | 34 | .stream_name = "HiFi", |
35 | .codec_dai_name = "wm9712-hifi", | 35 | .codec_dai_name = "wm9712-hifi", |
36 | .codec_name = "wm9712-codec", | 36 | .codec_name = "wm9712-codec", |
37 | .cpu_dai_name = "imx-ssi-dai.0", | 37 | .cpu_dai_name = "imx-ssi.0", |
38 | .platform_name = "imx-fiq-pcm-audio.0", | 38 | .platform_name = "imx-fiq-pcm-audio.0", |
39 | .ops = &imx_phycore_hifi_ops, | 39 | .ops = &imx_phycore_hifi_ops, |
40 | }, | 40 | }, |
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c index 74068636c1d8..30fdb15065be 100644 --- a/sound/soc/imx/wm1133-ev1.c +++ b/sound/soc/imx/wm1133-ev1.c | |||
@@ -243,7 +243,7 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) | |||
243 | static struct snd_soc_dai_link wm1133_ev1_dai = { | 243 | static struct snd_soc_dai_link wm1133_ev1_dai = { |
244 | .name = "WM1133-EV1", | 244 | .name = "WM1133-EV1", |
245 | .stream_name = "Audio", | 245 | .stream_name = "Audio", |
246 | .cpu_dai_name = "imx-ssi-dai.0", | 246 | .cpu_dai_name = "imx-ssi.0", |
247 | .codec_dai_name = "wm8350-hifi", | 247 | .codec_dai_name = "wm8350-hifi", |
248 | .platform_name = "imx-fiq-pcm-audio.0", | 248 | .platform_name = "imx-fiq-pcm-audio.0", |
249 | .codec_name = "wm8350-codec.0-0x1a", | 249 | .codec_name = "wm8350-codec.0-0x1a", |