From 728384a10b673dbd9819b524852df23142ee2fdd Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 24 Oct 2014 21:50:04 +0400 Subject: ARM: pxa: spitz: register spitz-audio device Register spitz-audio device to be used by ASoC driver to bind ASoC platform driver. Currently old 'soc-audio' approach is used, which needs to be replaced with proper device. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Mark Brown --- arch/arm/mach-pxa/spitz.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 840c3a48e72..962a7f31f59 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -923,6 +923,14 @@ static void __init spitz_i2c_init(void) static inline void spitz_i2c_init(void) {} #endif +/****************************************************************************** + * Audio devices + ******************************************************************************/ +static inline void spitz_audio_init(void) +{ + platform_device_register_simple("spitz-audio", -1, NULL, 0); +} + /****************************************************************************** * Machine init ******************************************************************************/ @@ -970,6 +978,7 @@ static void __init spitz_init(void) spitz_nor_init(); spitz_nand_init(); spitz_i2c_init(); + spitz_audio_init(); } static void __init spitz_fixup(struct tag *tags, char **cmdline) -- cgit v1.2.3-70-g09d2 From ecf0015161b2220879fcd41c030761b4eb561b95 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 24 Oct 2014 21:50:05 +0400 Subject: ASoC: pxa: Convert spitz to use snd_soc_register_card() Use snd_soc_register_card() instead of creating a "soc-audio" platform device. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Mark Brown --- sound/soc/pxa/spitz.c | 52 +++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 1373b017a95..d7d5fb20ea6 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -305,19 +305,15 @@ static struct snd_soc_card snd_soc_spitz = { .num_dapm_routes = ARRAY_SIZE(spitz_audio_map), }; -static struct platform_device *spitz_snd_device; - -static int __init spitz_init(void) +static int spitz_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &snd_soc_spitz; int ret; - if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) - return -ENODEV; - - if (machine_is_borzoi() || machine_is_spitz()) - spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS; - else + if (machine_is_akita()) spitz_mic_gpio = AKITA_GPIO_MIC_BIAS; + else + spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS; ret = gpio_request(spitz_mic_gpio, "MIC GPIO"); if (ret) @@ -327,37 +323,45 @@ static int __init spitz_init(void) if (ret) goto err2; - spitz_snd_device = platform_device_alloc("soc-audio", -1); - if (!spitz_snd_device) { - ret = -ENOMEM; + card->dev = &pdev->dev; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); goto err2; } - platform_set_drvdata(spitz_snd_device, &snd_soc_spitz); - - ret = platform_device_add(spitz_snd_device); - if (ret) - goto err3; - return 0; -err3: - platform_device_put(spitz_snd_device); err2: gpio_free(spitz_mic_gpio); err1: return ret; } -static void __exit spitz_exit(void) +static int spitz_remove(struct platform_device *pdev) { - platform_device_unregister(spitz_snd_device); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); gpio_free(spitz_mic_gpio); + return 0; } -module_init(spitz_init); -module_exit(spitz_exit); +static struct platform_driver spitz_driver = { + .driver = { + .name = "spitz-audio", + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + }, + .probe = spitz_probe, + .remove = spitz_remove, +}; + +module_platform_driver(spitz_driver); MODULE_AUTHOR("Richard Purdie"); MODULE_DESCRIPTION("ALSA SoC Spitz"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:spitz-audio"); -- cgit v1.2.3-70-g09d2 From 4539441690cd31ae7d42e6f080033911a1788440 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 3 Nov 2014 19:33:02 +0100 Subject: ASoC: mioa701_wm9713: Don't opencode CODEC register access Properly use snd_soc_update_bits() instead of manually calling the CODEC driver's read and write callbacks. The later will stop working once the wm9713 driver has been converted to regmap. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/pxa/mioa701_wm9713.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index 595eee341e9..a6b2be20cc0 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -127,15 +127,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; - unsigned short reg; /* Prepare GPIO8 for rear speaker amplifier */ - reg = codec->driver->read(codec, AC97_GPIO_CFG); - codec->driver->write(codec, AC97_GPIO_CFG, reg | 0x0100); + snd_soc_update_bits(codec, AC97_GPIO_CFG, 0x100, 0x100); /* Prepare MIC input */ - reg = codec->driver->read(codec, AC97_3D_CONTROL); - codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000); + snd_soc_update_bits(codec, AC97_3D_CONTROL, 0xc000, 0xc000); return 0; } -- cgit v1.2.3-70-g09d2 From ff7c532c3ae570981a46663d5810dda913d468d9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 9 Nov 2014 20:41:51 +0100 Subject: ASoC: omap: enable sound support on n900 on devicetree-based boot With device tree, it is possible (and encouraged) to build N900 kernels without CONFIG_MACH_NOKIA_RX51. Update config file to enable the driver build in this case. This makes sound work on my n900 under 3.18-rc1. Signed-off-by: Pavel Machek Signed-off-by: Mark Brown --- sound/soc/omap/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index d44463a7b0f..2738b198441 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -25,15 +25,15 @@ config SND_OMAP_SOC_N810 Say Y if you want to add support for SoC audio on Nokia N810. config SND_OMAP_SOC_RX51 - tristate "SoC Audio support for Nokia RX-51" - depends on SND_OMAP_SOC && ARM && (MACH_NOKIA_RX51 || COMPILE_TEST) && I2C + tristate "SoC Audio support for Nokia N900 (RX-51)" + depends on SND_OMAP_SOC && ARM && I2C select SND_OMAP_SOC_MCBSP select SND_SOC_TLV320AIC3X select SND_SOC_TPA6130A2 depends on GPIOLIB help - Say Y if you want to add support for SoC audio on Nokia RX-51 - hardware. This is also known as Nokia N900 product. + Say Y if you want to add support for SoC audio on Nokia N900 + cellphone. config SND_OMAP_SOC_AMS_DELTA tristate "SoC Audio support for Amstrad E3 (Delta) videophone" -- cgit v1.2.3-70-g09d2 From 8c2727f97b4825adaad43bf98632abc9940345a4 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 10 Nov 2014 17:49:30 -0200 Subject: ASoC: mxs: mxs-saif: Register the irq with the device name Instead of registering the irq name with the driver name, it's better to pass the device name so that we have a more explicit indication as to what saif instance the irq is related: $ cat /proc/interrupts CPU0 ... 214: 4 - 59 80042000.saif 215: 0 - 58 80046000.saif Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 231d7e7b071..83b2fea0921 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -773,7 +773,7 @@ static int mxs_saif_probe(struct platform_device *pdev) saif->dev = &pdev->dev; ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0, - "mxs-saif", saif); + dev_name(&pdev->dev), saif); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); return ret; -- cgit v1.2.3-70-g09d2 From 6d3efa40790ad1286cfa032df6d3c9a2748a695e Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Sat, 15 Nov 2014 22:51:46 +0300 Subject: ASoC: pxa: prepare/unprepare clocks in pxa-ssp Change clk_enable/disable() calls to clk_prepare_enable() and clk_disable_unrepapre(). Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Mark Brown --- sound/soc/pxa/pxa-ssp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index a8e09743307..cbba063a721 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -97,7 +97,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, int ret = 0; if (!cpu_dai->active) { - clk_enable(ssp->clk); + clk_prepare_enable(ssp->clk); pxa_ssp_disable(ssp); } @@ -121,7 +121,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, if (!cpu_dai->active) { pxa_ssp_disable(ssp); - clk_disable(ssp->clk); + clk_disable_unprepare(ssp->clk); } kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); @@ -136,7 +136,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) struct ssp_device *ssp = priv->ssp; if (!cpu_dai->active) - clk_enable(ssp->clk); + clk_prepare_enable(ssp->clk); priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0); priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1); @@ -144,7 +144,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) priv->psp = __raw_readl(ssp->mmio_base + SSPSP); pxa_ssp_disable(ssp); - clk_disable(ssp->clk); + clk_disable_unprepare(ssp->clk); return 0; } @@ -154,7 +154,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) struct ssp_device *ssp = priv->ssp; uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE; - clk_enable(ssp->clk); + clk_prepare_enable(ssp->clk); __raw_writel(sssr, ssp->mmio_base + SSSR); __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0); @@ -165,7 +165,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) if (cpu_dai->active) pxa_ssp_enable(ssp); else - clk_disable(ssp->clk); + clk_disable_unprepare(ssp->clk); return 0; } @@ -256,11 +256,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, /* The SSP clock must be disabled when changing SSP clock mode * on PXA2xx. On PXA3xx it must be enabled when doing so. */ if (ssp->type != PXA3xx_SSP) - clk_disable(ssp->clk); + clk_disable_unprepare(ssp->clk); val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0; pxa_ssp_write_reg(ssp, SSCR0, val); if (ssp->type != PXA3xx_SSP) - clk_enable(ssp->clk); + clk_prepare_enable(ssp->clk); return 0; } -- cgit v1.2.3-70-g09d2 From bb66f2dc197d9cf1daaa82609302204d71c70389 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 17 Nov 2014 14:05:27 +0100 Subject: ASoC: omap-mcbsp: Deletion of an unnecessary check before the function call "kfree" The kfree() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/mcbsp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 86c75384c3c..68a12520537 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c @@ -621,8 +621,7 @@ void omap_mcbsp_free(struct omap_mcbsp *mcbsp) mcbsp->reg_cache = NULL; spin_unlock(&mcbsp->lock); - if (reg_cache) - kfree(reg_cache); + kfree(reg_cache); } /* -- cgit v1.2.3-70-g09d2 From 93b0f3eeebdce6f32417187b5d24ea218a3e7fb4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 25 Nov 2014 13:16:12 +0100 Subject: ASoC: core: add multi-codec support in DT This patch exports a core function which handles the DT description of multi-codec links (as: "sound-dai = <&hdmi 0>, <&spdif_codec>;") and creates a CODEC component array in the DAI link. Signed-off-by: Jean-Francois Moine Signed-off-by: Mark Brown --- include/sound/soc.h | 3 ++ sound/soc/soc-core.c | 110 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 98 insertions(+), 15 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 7ba7130037a..2750e6ad012 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1451,6 +1451,9 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, struct device_node **framemaster); int snd_soc_of_get_dai_name(struct device_node *of_node, const char **dai_name); +int snd_soc_of_get_dai_link_codecs(struct device *dev, + struct device_node *of_node, + struct snd_soc_dai_link *dai_link); #include diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e..72a3ad04704 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4750,36 +4750,30 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt); -int snd_soc_of_get_dai_name(struct device_node *of_node, - const char **dai_name) +static int snd_soc_get_dai_name(struct of_phandle_args *args, + const char **dai_name) { struct snd_soc_component *pos; - struct of_phandle_args args; - int ret; - - ret = of_parse_phandle_with_args(of_node, "sound-dai", - "#sound-dai-cells", 0, &args); - if (ret) - return ret; - - ret = -EPROBE_DEFER; + int ret = -EPROBE_DEFER; mutex_lock(&client_mutex); list_for_each_entry(pos, &component_list, list) { - if (pos->dev->of_node != args.np) + if (pos->dev->of_node != args->np) continue; if (pos->driver->of_xlate_dai_name) { - ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name); + ret = pos->driver->of_xlate_dai_name(pos, + args, + dai_name); } else { int id = -1; - switch (args.args_count) { + switch (args->args_count) { case 0: id = 0; /* same as dai_drv[0] */ break; case 1: - id = args.args[0]; + id = args->args[0]; break; default: /* not supported */ @@ -4801,6 +4795,21 @@ int snd_soc_of_get_dai_name(struct device_node *of_node, break; } mutex_unlock(&client_mutex); + return ret; +} + +int snd_soc_of_get_dai_name(struct device_node *of_node, + const char **dai_name) +{ + struct of_phandle_args args; + int ret; + + ret = of_parse_phandle_with_args(of_node, "sound-dai", + "#sound-dai-cells", 0, &args); + if (ret) + return ret; + + ret = snd_soc_get_dai_name(&args, dai_name); of_node_put(args.np); @@ -4808,6 +4817,77 @@ int snd_soc_of_get_dai_name(struct device_node *of_node, } EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name); +/* + * snd_soc_of_get_dai_link_codecs - Parse a list of CODECs in the devicetree + * @dev: Card device + * @of_node: Device node + * @dai_link: DAI link + * + * Builds an array of CODEC DAI components from the DAI link property + * 'sound-dai'. + * The array is set in the DAI link and the number of DAIs is set accordingly. + * The device nodes in the array (of_node) must be dereferenced by the caller. + * + * Returns 0 for success + */ +int snd_soc_of_get_dai_link_codecs(struct device *dev, + struct device_node *of_node, + struct snd_soc_dai_link *dai_link) +{ + struct of_phandle_args args; + struct snd_soc_dai_link_component *component; + char *name; + int index, num_codecs, ret; + + /* Count the number of CODECs */ + name = "sound-dai"; + num_codecs = of_count_phandle_with_args(of_node, name, + "#sound-dai-cells"); + if (num_codecs <= 0) { + if (num_codecs == -ENOENT) + dev_err(dev, "No 'sound-dai' property\n"); + else + dev_err(dev, "Bad phandle in 'sound-dai'\n"); + return num_codecs; + } + component = devm_kzalloc(dev, + sizeof *component * num_codecs, + GFP_KERNEL); + if (!component) + return -ENOMEM; + dai_link->codecs = component; + dai_link->num_codecs = num_codecs; + + /* Parse the list */ + for (index = 0, component = dai_link->codecs; + index < dai_link->num_codecs; + index++, component++) { + ret = of_parse_phandle_with_args(of_node, name, + "#sound-dai-cells", + index, &args); + if (ret) + goto err; + component->of_node = args.np; + ret = snd_soc_get_dai_name(&args, &component->dai_name); + if (ret < 0) + goto err; + } + return 0; +err: + for (index = 0, component = dai_link->codecs; + index < dai_link->num_codecs; + index++, component++) { + if (!component->of_node) + break; + of_node_put(component->of_node); + component->of_node = NULL; + } + dai_link->codecs = NULL; + dai_link->num_codecs = 0; + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs); + static int __init snd_soc_init(void) { #ifdef CONFIG_DEBUG_FS -- cgit v1.2.3-70-g09d2 From d206f66177ab7cd69d79c7e01b43f45d935f43dd Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 27 Nov 2014 13:01:59 -0200 Subject: ASoC: mxs-sgtl5000: Remove MCLK restriction According to the sgtl5000 datasheet the MCLK frequency range restriction of 8 to 27 MHz only applies when the PLL is used - synchronous SYS_MCLK input mode. mxs-sgtl5000 machine sets the codec as slave, and mx28 generates MCLK in the range of 256*fs, 384*fs or 512*fs, which is called asynchronous SYS_MCLK input. In asynchronous SYS_MCLK we cannot have the 8 to 27 MHz check because if we want to play a 8KHz sample rate track, with a MCLK of 8k * 512 = 4.096MHz the current check would return -EINVAL, which is not correct. Remove the 8 to 27MHz frequency check, since this only applies to the synchronous SYS_MCLK input case. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-sgtl5000.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 61822cc53bd..3bba6cfe4f2 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -49,13 +49,6 @@ static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream, break; } - /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */ - if (mclk < 8000000 || mclk > 27000000) { - dev_err(codec_dai->dev, "Invalid mclk frequency: %u.%03uMHz\n", - mclk / 1000000, mclk / 1000 % 1000); - return -EINVAL; - } - /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */ ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0); if (ret) { -- cgit v1.2.3-70-g09d2