diff options
| author | Takashi Iwai <tiwai@suse.de> | 2010-10-05 01:50:11 -0400 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2010-10-05 01:50:11 -0400 |
| commit | 45605a87b3f34fb71bbc6446e2d49a469e9e10dd (patch) | |
| tree | fe46494f2f390288edf1b1a0b02fabf6d4a739a0 | |
| parent | a09f73fabbeac81f45969ad9ed59e74fae736873 (diff) | |
| parent | 6c20c807cf5a13f61193d39bb718f7a9b5df3813 (diff) | |
Merge branch 'for-2.6.37' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6 into topic/asoc
| -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", |
