[alsa-devel] [patch 0/4] ASoC S3C24XX/Simtec support
re-worked against ASoC git branch
Will be away from until 26th, any comments will be sorted when back.
--
Add core support for the range of S3C24XX Simtec boards with TLV320AIC23 CODECs on them. Since there are also boards with similar IIS routing the AMP and the configuration code is placed in a core file for re-use with other CODEC bindings.
Signed-off-by: Ben Dooks ben@simtec.co.uk
--- arch/arm/plat-s3c/include/plat/audio-simtec.h | 37 ++ sound/soc/s3c24xx/Kconfig | 12 sound/soc/s3c24xx/Makefile | 4 sound/soc/s3c24xx/s3c24xx_simtec.c | 394 +++++++++++++++++++++++++ sound/soc/s3c24xx/s3c24xx_simtec.h | 22 + sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c | 137 ++++++++ 6 files changed, 606 insertions(+)
Index: b/sound/soc/s3c24xx/Kconfig =================================================================== --- a/sound/soc/s3c24xx/Kconfig 2009-08-20 08:37:52.000000000 +0100 +++ b/sound/soc/s3c24xx/Kconfig 2009-08-20 08:37:55.000000000 +0100 @@ -79,3 +79,15 @@ config SND_S3C24XX_SOC_S3C24XX_UDA134X select SND_S3C24XX_SOC_I2S select SND_SOC_L3 select SND_SOC_UDA134X + +config SND_S3C24XX_SOC_SIMTEC + tristate + help + Internal node for common S3C24XX/Simtec suppor + +config SND_S3C24XX_SOC_SIMTEC_TLV320AIC23 + tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" + depends on SND_S3C24XX_SOC + select SND_S3C24XX_SOC_I2S + select SND_SOC_TLV320AIC23 + select SND_S3C24XX_SOC_SIMTEC Index: b/sound/soc/s3c24xx/Makefile =================================================================== --- a/sound/soc/s3c24xx/Makefile 2009-08-20 08:37:52.000000000 +0100 +++ b/sound/soc/s3c24xx/Makefile 2009-08-20 08:37:55.000000000 +0100 @@ -20,6 +20,8 @@ snd-soc-neo1973-gta02-wm8753-objs := neo snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o +snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o +snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o @@ -27,3 +29,5 @@ obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o +obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o +obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o Index: b/sound/soc/s3c24xx/s3c24xx_simtec.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/sound/soc/s3c24xx/s3c24xx_simtec.c 2009-08-20 08:37:55.000000000 +0100 @@ -0,0 +1,394 @@ +/* sound/soc/s3c24xx/s3c24xx_simtec.c + * + * Copyright 2009 Simtec Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/clk.h> +#include <linux/i2c.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> + +#include <plat/audio-simtec.h> + +#include "s3c24xx-pcm.h" +#include "s3c24xx-i2s.h" +#include "s3c24xx_simtec.h" + +static struct s3c24xx_audio_simtec_pdata *pdata; +static struct clk *xtal_clk; + +static int spk_gain; +static int spk_unmute; + +/** + * speaker_gain_get - read the speaker gain setting. + * @kcontrol: The control for the speaker gain. + * @ucontrol: The value that needs to be updated. + * + * Read the value for the AMP gain control. + */ +static int speaker_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = spk_gain; + return 0; +} + +/** + * speaker_gain_set - set the value of the speaker amp gain + * @value: The value to write. + */ +static void speaker_gain_set(int value) +{ + gpio_set_value_cansleep(pdata->amp_gain[0], value & 1); + gpio_set_value_cansleep(pdata->amp_gain[1], value >> 1); +} + +/** + * speaker_gain_put - set the speaker gain setting. + * @kcontrol: The control for the speaker gain. + * @ucontrol: The value that needs to be set. + * + * Set the value of the speaker gain from the specified + * @ucontrol setting. + * + * Note, if the speaker amp is muted, then we do not set a gain value + * as at-least one of the ICs that is fitted will try and power up even + * if the main control is set to off. + */ +static int speaker_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int value = ucontrol->value.integer.value[0]; + + spk_gain = value; + + if (!spk_unmute) + speaker_gain_set(value); + + return 0; +} + +static const struct snd_kcontrol_new amp_gain_controls[] = { + SOC_SINGLE_EXT("Speaker Gain", 0, 0, 3, 0, + speaker_gain_get, speaker_gain_put), +}; + +/** + * spk_unmute_state - set the unmute state of the speaker + * @to: zero to unmute, non-zero to ununmute. + */ +static void spk_unmute_state(int to) +{ + pr_debug("%s: to=%d\n", __func__, to); + + spk_unmute = to; + gpio_set_value(pdata->amp_gpio, to); + + /* if we're umuting, also re-set the gain */ + if (to && pdata->amp_gain[0] > 0) + speaker_gain_set(spk_gain); +} + +/** + * speaker_unmute_get - read the speaker unmute setting. + * @kcontrol: The control for the speaker gain. + * @ucontrol: The value that needs to be updated. + * + * Read the value for the AMP gain control. + */ +static int speaker_unmute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = spk_unmute; + return 0; +} + +/** + * speaker_unmute_put - set the speaker unmute setting. + * @kcontrol: The control for the speaker gain. + * @ucontrol: The value that needs to be set. + * + * Set the value of the speaker gain from the specified + * @ucontrol setting. + */ +static int speaker_unmute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + spk_unmute_state(ucontrol->value.integer.value[0]); + return 0; +} + +/* This is added as a manual control as the speaker amps create clicks + * when their power state is changed, which are far more noticeable than + * anything produced by the CODEC itself. + */ +static const struct snd_kcontrol_new amp_unmute_controls[] = { + SOC_SINGLE_EXT("Speaker Switch", 0, 0, 1, 0, + speaker_unmute_get, speaker_unmute_put), +}; + +void simtec_audio_init(struct snd_soc_codec *codec) +{ + if (pdata->amp_gpio > 0) { + pr_debug("%s: adding amp routes\n", __func__); + + snd_soc_add_controls(codec, amp_unmute_controls, + ARRAY_SIZE(amp_unmute_controls)); + } + + if (pdata->amp_gain[0] > 0) { + pr_debug("%s: adding amp controls\n", __func__); + snd_soc_add_controls(codec, amp_gain_controls, + ARRAY_SIZE(amp_gain_controls)); + } +} +EXPORT_SYMBOL_GPL(simtec_audio_init); + +#define CODEC_CLOCK 12000000 + +/** + * simtec_hw_params - update hardware parameters + * @substream: The audio substream instance. + * @params: The parameters requested. + * + * Update the codec data routing and configuration settings + * from the supplied data. + */ +static int simtec_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + int ret; + + /* Set the CODEC as the bus clock master, I2S */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret) { + pr_err("%s: failed set cpu dai format\n", __func__); + return ret; + } + + /* Set the CODEC as the bus clock master */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret) { + pr_err("%s: failed set codec dai format\n", __func__); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, 0, + CODEC_CLOCK, SND_SOC_CLOCK_IN); + if (ret) { + pr_err( "%s: failed setting codec sysclk\n", __func__); + return ret; + } + + if (pdata->use_mpllin) { + ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_MPLL, + 0, SND_SOC_CLOCK_OUT); + + if (ret) { + pr_err("%s: failed to set MPLLin as clksrc\n", + __func__); + return ret; + } + } + + if (pdata->output_cdclk) { + int cdclk_scale; + + cdclk_scale = clk_get_rate(xtal_clk) / CODEC_CLOCK; + cdclk_scale--; + + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, + cdclk_scale); + } + + return 0; +} + +static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd) +{ + /* call any board supplied startup code, this currently only + * covers the bast/vr1000 which have a CPLD in the way of the + * LRCLK */ + if (pd->startup) + pd->startup(); + + return 0; +} + +static struct snd_soc_ops simtec_snd_ops = { + .hw_params = simtec_hw_params, +}; + +/** + * attach_gpio_amp - get and configure the necessary gpios + * @dev: The device we're probing. + * @pd: The platform data supplied by the board. + * + * If there is a GPIO based amplifier attached to the board, claim + * the necessary GPIO lines for it, and set default values. + */ +static int attach_gpio_amp(struct device *dev, + struct s3c24xx_audio_simtec_pdata *pd) +{ + int ret; + + /* attach gpio amp gain (if any) */ + if (pdata->amp_gain[0] > 0) { + ret = gpio_request(pd->amp_gain[0], "gpio-amp-gain0"); + if (ret) { + dev_err(dev, "cannot get amp gpio gain0\n"); + return ret; + } + + ret = gpio_request(pd->amp_gain[1], "gpio-amp-gain1"); + if (ret) { + dev_err(dev, "cannot get amp gpio gain1\n"); + gpio_free(pdata->amp_gain[0]); + return ret; + } + + gpio_direction_output(pd->amp_gain[0], 0); + gpio_direction_output(pd->amp_gain[1], 0); + } + + /* note, curently we assume GPA0 isn't valid amp */ + if (pdata->amp_gpio > 0) { + ret = gpio_request(pd->amp_gpio, "gpio-amp"); + if (ret) { + dev_err(dev, "cannot get amp gpio %d (%d)\n", + pd->amp_gpio, ret); + goto err_amp; + } + + /* set the amp off at startup */ + spk_unmute_state(0); + } + + return 0; + +err_amp: + if (pd->amp_gain[0] > 0) { + gpio_free(pd->amp_gain[0]); + gpio_free(pd->amp_gain[1]); + } + + return ret; +} + +static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd) +{ + if (pd->amp_gain[0] > 0) { + gpio_free(pd->amp_gain[0]); + gpio_free(pd->amp_gain[1]); + } + + if (pd->amp_gpio > 0) + gpio_free(pd->amp_gpio); +} + +#ifdef CONFIG_PM +int simtec_audio_resume(struct device *dev) +{ + simtec_call_startup(pdata); + return 0; +} + +struct dev_pm_ops simtec_audio_pmops = { + .resume = simtec_audio_resume, +}; +EXPORT_SYMBOL_GPL(simtec_audio_pmops); +#endif + +int __devinit simtec_audio_core_probe(struct platform_device *pdev, + struct snd_soc_device *socdev) +{ + struct platform_device *snd_dev; + int ret; + + socdev->card->dai_link->ops = &simtec_snd_ops; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data supplied\n"); + return -EINVAL; + } + + simtec_call_startup(pdata); + + xtal_clk = clk_get(&pdev->dev, "xtal"); + if (IS_ERR(xtal_clk)) { + dev_err(&pdev->dev, "could not get clkout0\n"); + return -EINVAL; + } + + dev_info(&pdev->dev, "xtal rate is %ld\n", clk_get_rate(xtal_clk)); + + ret = attach_gpio_amp(&pdev->dev, pdata); + if (ret) + goto err_clk; + + snd_dev = platform_device_alloc("soc-audio", -1); + if (!snd_dev) { + dev_err(&pdev->dev, "failed to alloc soc-audio devicec\n"); + ret = -ENOMEM; + goto err_gpio; + } + + platform_set_drvdata(snd_dev, socdev); + socdev->dev = &snd_dev->dev; + + ret = platform_device_add(snd_dev); + if (ret) { + dev_err(&pdev->dev, "failed to add soc-audio dev\n"); + goto err_pdev; + } + + platform_set_drvdata(pdev, snd_dev); + return 0; + +err_pdev: + platform_device_put(snd_dev); + +err_gpio: + detach_gpio_amp(pdata); + +err_clk: + clk_put(xtal_clk); + return ret; +} +EXPORT_SYMBOL_GPL(simtec_audio_core_probe); + +int __devexit simtec_audio_remove(struct platform_device *pdev) +{ + struct platform_device *snd_dev = platform_get_drvdata(pdev); + + platform_device_unregister(snd_dev); + + detach_gpio_amp(pdata); + clk_put(xtal_clk); + return 0; +} +EXPORT_SYMBOL_GPL(simtec_audio_remove); + +MODULE_AUTHOR("Ben Dooks ben@simtec.co.uk"); +MODULE_DESCRIPTION("ALSA SoC Simtec Audio common support"); +MODULE_LICENSE("GPL"); Index: b/arch/arm/plat-s3c/include/plat/audio-simtec.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/arch/arm/plat-s3c/include/plat/audio-simtec.h 2009-08-20 08:37:55.000000000 +0100 @@ -0,0 +1,37 @@ +/* arch/arm/plat-s3c/include/plat/audio-simtec.h + * + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks ben@simtec.co.uk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Simtec Audio support. +*/ + +/** + * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio + * @use_mpllin: Select codec clock from MPLLin + * @output_cdclk: Need to output CDCLK to the codec + * @have_mic: Set if we have a MIC socket + * @have_lout: Set if we have a LineOut socket + * @amp_gpio: GPIO pin to enable the AMP + * @amp_gain: Option GPIO to control AMP gain + */ +struct s3c24xx_audio_simtec_pdata { + unsigned int use_mpllin:1; + unsigned int output_cdclk:1; + + unsigned int have_mic:1; + unsigned int have_lout:1; + + int amp_gpio; + int amp_gain[2]; + + void (*startup)(void); +}; + +extern int simtec_audio_add(const char *codec_name, + struct s3c24xx_audio_simtec_pdata *pdata); Index: b/sound/soc/s3c24xx/s3c24xx_simtec.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/sound/soc/s3c24xx/s3c24xx_simtec.h 2009-08-20 08:37:55.000000000 +0100 @@ -0,0 +1,22 @@ +/* sound/soc/s3c24xx/s3c24xx_simtec.h + * + * Copyright 2009 Simtec Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +extern void simtec_audio_init(struct snd_soc_codec *codec); + +extern int simtec_audio_core_probe(struct platform_device *pdev, + struct snd_soc_device *socdev); + +extern int simtec_audio_remove(struct platform_device *pdev); + +#ifdef CONFIG_PM +extern struct dev_pm_ops simtec_audio_pmops; +#define simtec_audio_pm &simtec_audio_pmops +#else +#define simtec_audio_pm NULL +#endif Index: b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c 2009-08-20 08:37:55.000000000 +0100 @@ -0,0 +1,137 @@ +/* sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c + * + * Copyright 2009 Simtec Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/platform_device.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> + +#include <plat/audio-simtec.h> + +#include "s3c24xx-pcm.h" +#include "s3c24xx-i2s.h" +#include "s3c24xx_simtec.h" + +#include "../codecs/tlv320aic23.h" + +/* supported machines: + * + * Machine Connections AMP + * ------- ----------- --- + * BAST MIC, HPOUT, LOUT, LIN TPA2001D1 (HPOUTL,R) (gain hardwired) + * VR1000 HPOUT, LIN None + * VR2000 LIN, LOUT, MIC, HP LM4871 (HPOUTL,R) + * DePicture LIN, LOUT, MIC, HP LM4871 (HPOUTL,R) + * Anubis LIN, LOUT, MIC, HP TPA2001D1 (HPOUTL,R) + */ + +static const struct snd_soc_dapm_widget dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_LINE("Line In", NULL), + SND_SOC_DAPM_LINE("Line Out", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), +}; + +static const struct snd_soc_dapm_route base_map[] = { + { "Headphone Jack", NULL, "LHPOUT"}, + { "Headphone Jack", NULL, "RHPOUT"}, + + { "Line Out", NULL, "LOUT" }, + { "Line Out", NULL, "ROUT" }, + + { "LLINEIN", NULL, "Line In"}, + { "RLINEIN", NULL, "Line In"}, + + { "MICIN", NULL, "Mic Jack"}, +}; + +/** + * simtec_tlv320aic23_init - initialise and add controls + * @codec; The codec instance to attach to. + * + * Attach our controls and configure the necessary codec + * mappings for our sound card instance. +*/ +static int simtec_tlv320aic23_init(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, dapm_widgets, + ARRAY_SIZE(dapm_widgets)); + + snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map)); + + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Line In"); + snd_soc_dapm_enable_pin(codec, "Line Out"); + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + + simtec_audio_init(codec); + snd_soc_dapm_sync(codec); + + return 0; +} + +static struct snd_soc_dai_link simtec_dai_aic23 = { + .name = "tlv320aic23", + .stream_name = "TLV320AIC23", + .cpu_dai = &s3c24xx_i2s_dai, + .codec_dai = &tlv320aic23_dai, + .init = simtec_tlv320aic23_init, +}; + +/* simtec audio machine driver */ +static struct snd_soc_card snd_soc_machine_simtec_aic23 = { + .name = "Simtec", + .platform = &s3c24xx_soc_platform, + .dai_link = &simtec_dai_aic23, + .num_links = 1, +}; + +/* simtec audio subsystem */ +static struct snd_soc_device simtec_snd_devdata_aic23 = { + .card = &snd_soc_machine_simtec_aic23, + .codec_dev = &soc_codec_dev_tlv320aic23, +}; + +static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) +{ + return simtec_audio_core_probe(pd, &simtec_snd_devdata_aic23); +} + +static struct platform_driver simtec_audio_tlv320aic23_platdrv = { + .driver = { + .owner = THIS_MODULE, + .name = "s3c24xx-simtec-tlv320aic23", + .pm = simtec_audio_pm, + }, + .probe = simtec_audio_tlv320aic23_probe, + .remove = __devexit_p(simtec_audio_remove), +}; + +MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23"); + +static int __init simtec_tlv320aic23_modinit(void) +{ + return platform_driver_register(&simtec_audio_tlv320aic23_platdrv); +} + +static void __exit simtec_tlv320aic23_modexit(void) +{ + platform_driver_unregister(&simtec_audio_tlv320aic23_platdrv); +} + +module_init(simtec_tlv320aic23_modinit); +module_exit(simtec_tlv320aic23_modexit); + +MODULE_AUTHOR("Ben Dooks ben@simtec.co.uk"); +MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); +MODULE_LICENSE("GPL");
--
The tlv320aic3x driver managed its own i2c device, instead of an extant one created by the board support code. Change the code to make it so that the driver binds to an extant (in this case i2c) device.
Add explict tlv320aic33 as well as tlv320aic3x to the supported device table and remove the old driver bindings from the users of this code.
Signed-off-by: Ben Dooks ben@simtec.co.uk
--- sound/soc/codecs/tlv320aic3x.c | 221 ++++++++++++++++++++-------------------- sound/soc/codecs/tlv320aic3x.h | 2 sound/soc/davinci/davinci-evm.c | 2 sound/soc/omap/n810.c | 2 sound/soc/s6000/s6105-ipcam.c | 2 5 files changed, 116 insertions(+), 113 deletions(-)
Index: b/sound/soc/codecs/tlv320aic3x.c =================================================================== --- a/sound/soc/codecs/tlv320aic3x.c 2009-08-20 08:37:52.000000000 +0100 +++ b/sound/soc/codecs/tlv320aic3x.c 2009-08-20 08:38:01.000000000 +0100 @@ -53,6 +53,7 @@
/* codec private data */ struct aic3x_priv { + struct snd_soc_codec codec; unsigned int sysclk; int master; }; @@ -1156,11 +1157,13 @@ static int aic3x_resume(struct platform_ * initialise the AIC3X driver * register the mixer and dsp interfaces with the kernel */ -static int aic3x_init(struct snd_soc_device *socdev) +static int aic3x_init(struct snd_soc_codec *codec) { - struct snd_soc_codec *codec = socdev->card->codec; - struct aic3x_setup_data *setup = socdev->codec_data; - int reg, ret = 0; + int reg; + + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths);
codec->name = "tlv320aic3x"; codec->owner = THIS_MODULE; @@ -1177,13 +1180,6 @@ static int aic3x_init(struct snd_soc_dev aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); aic3x_write(codec, AIC3X_RESET, SOFT_RESET);
- /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - printk(KERN_ERR "aic3x: failed to create pcms\n"); - goto pcm_err; - } - /* DAC default volume and mute */ aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON); aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON); @@ -1250,30 +1246,51 @@ static int aic3x_init(struct snd_soc_dev /* off, with power on */ aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- /* setup GPIO functions */ - aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); - aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); + return 0; +}
- snd_soc_add_controls(codec, aic3x_snd_controls, - ARRAY_SIZE(aic3x_snd_controls)); - aic3x_add_widgets(codec); - ret = snd_soc_init_card(socdev); +static struct snd_soc_codec *aic3x_codec; + +static int aic3x_register(struct snd_soc_codec *codec) +{ + int ret; + + ret = aic3x_init(codec); if (ret < 0) { - printk(KERN_ERR "aic3x: failed to register card\n"); - goto card_err; + dev_err(codec->dev, "Failed to initialise device\n"); + return ret; }
- return ret; + aic3x_codec = codec;
-card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - kfree(codec->reg_cache); - return ret; + ret = snd_soc_register_codec(codec); + if (ret) { + dev_err(codec->dev, "Failed to register codec\n"); + return ret; + } + + ret = snd_soc_register_dai(&aic3x_dai); + if (ret) { + dev_err(codec->dev, "Failed to register dai\n"); + snd_soc_unregister_codec(codec); + return ret; + } + + return 0; }
-static struct snd_soc_device *aic3x_socdev; +static int aic3x_unregister(struct aic3x_priv *aic3x) +{ + aic3x_set_bias_level(&aic3x->codec, SND_SOC_BIAS_OFF); + + snd_soc_unregister_dai(&aic3x_dai); + snd_soc_unregister_codec(&aic3x->codec); + + kfree(aic3x); + aic3x_codec = NULL; + + return 0; +}
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) /* @@ -1288,28 +1305,36 @@ static struct snd_soc_device *aic3x_socd static int aic3x_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct snd_soc_device *socdev = aic3x_socdev; - struct snd_soc_codec *codec = socdev->card->codec; - int ret; + struct snd_soc_codec *codec; + struct aic3x_priv *aic3x;
- i2c_set_clientdata(i2c, codec); + aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); + if (aic3x == NULL) { + dev_err(&i2c->dev, "failed to create private data\n"); + return -ENOMEM; + } + + codec = &aic3x->codec; + codec->dev = &i2c->dev; + codec->private_data = aic3x; codec->control_data = i2c; + codec->hw_write = (hw_write_t) i2c_master_send;
- ret = aic3x_init(socdev); - if (ret < 0) - printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); - return ret; + i2c_set_clientdata(i2c, aic3x); + + return aic3x_register(codec); }
static int aic3x_i2c_remove(struct i2c_client *client) { - struct snd_soc_codec *codec = i2c_get_clientdata(client); - kfree(codec->reg_cache); - return 0; + struct aic3x_priv *aic3x = i2c_get_clientdata(client); + + return aic3x_unregister(aic3x); }
static const struct i2c_device_id aic3x_i2c_id[] = { { "tlv320aic3x", 0 }, + { "tlv320aic33", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); @@ -1320,50 +1345,28 @@ static struct i2c_driver aic3x_i2c_drive .name = "aic3x I2C Codec", .owner = THIS_MODULE, }, - .probe = aic3x_i2c_probe, + .probe = aic3x_i2c_probe, .remove = aic3x_i2c_remove, .id_table = aic3x_i2c_id, };
-static int aic3x_add_i2c_device(struct platform_device *pdev, - const struct aic3x_setup_data *setup) +static inline void aic3x_i2c_init(void) { - struct i2c_board_info info; - struct i2c_adapter *adapter; - struct i2c_client *client; int ret;
ret = i2c_add_driver(&aic3x_i2c_driver); - if (ret != 0) { - dev_err(&pdev->dev, "can't add i2c driver\n"); - return ret; - } - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = setup->i2c_address; - strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE); - - adapter = i2c_get_adapter(setup->i2c_bus); - if (!adapter) { - dev_err(&pdev->dev, "can't get i2c adapter %d\n", - setup->i2c_bus); - goto err_driver; - } - - client = i2c_new_device(adapter, &info); - i2c_put_adapter(adapter); - if (!client) { - dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", - (unsigned int)info.addr); - goto err_driver; - } - - return 0; + if (ret) + printk(KERN_ERR "%s: error regsitering i2c driver, %d\n", + __func__, ret); +}
-err_driver: +static inline void aic3x_i2c_exit(void) +{ i2c_del_driver(&aic3x_i2c_driver); - return -ENODEV; } +#else +static inline void aic3x_i2c_init(void) { } +static inline void aic3x_i2c_exit(void) { } #endif
static int aic3x_probe(struct platform_device *pdev) @@ -1371,42 +1374,52 @@ static int aic3x_probe(struct platform_d struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct aic3x_setup_data *setup; struct snd_soc_codec *codec; - struct aic3x_priv *aic3x; int ret = 0;
- printk(KERN_INFO "AIC3X Audio Codec %s\n", AIC3X_VERSION); + codec = aic3x_codec; + if (!codec) { + dev_err(&pdev->dev, "Codec not registered\n"); + return -ENODEV; + }
+ socdev->card->codec = codec; setup = socdev->codec_data; - codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (codec == NULL) - return -ENOMEM;
- aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); - if (aic3x == NULL) { - kfree(codec); - return -ENOMEM; + if (!setup) { + dev_err(&pdev->dev, "No setup data supplied\n"); + return -EINVAL; }
- codec->private_data = aic3x; - socdev->card->codec = codec; - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); + /* setup GPIO functions */ + aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); + aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4);
- aic3x_socdev = socdev; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - if (setup->i2c_address) { - codec->hw_write = (hw_write_t) i2c_master_send; - ret = aic3x_add_i2c_device(pdev, setup); + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + printk(KERN_ERR "aic3x: failed to create pcms\n"); + goto pcm_err; } -#else - /* Add other interfaces here */ -#endif
- if (ret != 0) { - kfree(codec->private_data); - kfree(codec); + snd_soc_add_controls(codec, aic3x_snd_controls, + ARRAY_SIZE(aic3x_snd_controls)); + + aic3x_add_widgets(codec); + + ret = snd_soc_init_card(socdev); + if (ret < 0) { + printk(KERN_ERR "aic3x: failed to register card\n"); + goto card_err; } + + return ret; + +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + +pcm_err: + kfree(codec->reg_cache); return ret; }
@@ -1421,12 +1434,8 @@ static int aic3x_remove(struct platform_
snd_soc_free_pcms(socdev); snd_soc_dapm_free(socdev); -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_unregister_device(codec->control_data); - i2c_del_driver(&aic3x_i2c_driver); -#endif - kfree(codec->private_data); - kfree(codec); + + kfree(codec->reg_cache);
return 0; } @@ -1441,13 +1450,15 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
static int __init aic3x_modinit(void) { - return snd_soc_register_dai(&aic3x_dai); + aic3x_i2c_init(); + + return 0; } module_init(aic3x_modinit);
static void __exit aic3x_exit(void) { - snd_soc_unregister_dai(&aic3x_dai); + aic3x_i2c_exit(); } module_exit(aic3x_exit);
Index: b/sound/soc/omap/n810.c =================================================================== --- a/sound/soc/omap/n810.c 2009-08-20 08:37:32.000000000 +0100 +++ b/sound/soc/omap/n810.c 2009-08-20 08:38:01.000000000 +0100 @@ -322,8 +322,6 @@ static struct snd_soc_card snd_soc_n810
/* Audio private data */ static struct aic3x_setup_data n810_aic33_setup = { - .i2c_bus = 2, - .i2c_address = 0x18, .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED, .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT, }; Index: b/sound/soc/s6000/s6105-ipcam.c =================================================================== --- a/sound/soc/s6000/s6105-ipcam.c 2009-08-20 08:37:32.000000000 +0100 +++ b/sound/soc/s6000/s6105-ipcam.c 2009-08-20 08:38:01.000000000 +0100 @@ -189,8 +189,6 @@ static struct snd_soc_card snd_soc_card_
/* s6105 audio private data */ static struct aic3x_setup_data s6105_aic3x_setup = { - .i2c_bus = 0, - .i2c_address = 0x18, };
/* s6105 audio subsystem */ Index: b/sound/soc/davinci/davinci-evm.c =================================================================== --- a/sound/soc/davinci/davinci-evm.c 2009-08-20 08:37:52.000000000 +0100 +++ b/sound/soc/davinci/davinci-evm.c 2009-08-20 08:38:01.000000000 +0100 @@ -207,8 +207,6 @@ static struct snd_soc_card da850_snd_soc
/* evm audio private data */ static struct aic3x_setup_data evm_aic3x_setup = { - .i2c_bus = 1, - .i2c_address = 0x1b, };
/* dm6467 evm audio private data */ Index: b/sound/soc/codecs/tlv320aic3x.h =================================================================== --- a/sound/soc/codecs/tlv320aic3x.h 2009-08-20 08:37:32.000000000 +0100 +++ b/sound/soc/codecs/tlv320aic3x.h 2009-08-20 08:38:01.000000000 +0100 @@ -282,8 +282,6 @@ int aic3x_headset_detected(struct snd_so int aic3x_button_pressed(struct snd_soc_codec *codec);
struct aic3x_setup_data { - int i2c_bus; - unsigned short i2c_address; unsigned int gpio_func[2]; };
--
On Thu, Aug 20, 2009 at 10:50:41PM +0100, Ben Dooks wrote:
struct aic3x_setup_data {
- int i2c_bus;
- unsigned short i2c_address; unsigned int gpio_func[2];
};
I'll apply this but it should really be refactored to make this proper platform data for the CODEC; that can be dealt with in a future patch.
Fixup the device changes by modifying the files that we just removed the explicit device creation from with i2c_register_board_info() until this can be moved into the relevant board files.
Signed-off-by: Ben Dooks ben@simtec.co.uk
--- sound/soc/davinci/davinci-evm.c | 10 ++++++++++ sound/soc/omap/n810.c | 10 ++++++++++ sound/soc/s6000/s6105-ipcam.c | 10 ++++++++++ 3 files changed, 30 insertions(+)
Index: b/sound/soc/s6000/s6105-ipcam.c =================================================================== --- a/sound/soc/s6000/s6105-ipcam.c 2009-08-20 08:38:01.000000000 +0100 +++ b/sound/soc/s6000/s6105-ipcam.c 2009-08-20 08:45:26.000000000 +0100 @@ -14,6 +14,7 @@ #include <linux/timer.h> #include <linux/interrupt.h> #include <linux/platform_device.h> +#include <linux/i2c.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> @@ -209,10 +210,19 @@ static struct s6000_snd_platform_data __
static struct platform_device *s6105_snd_device;
+/* temporary i2c device creation until this can be moved into the machine + * support file. +*/ +static struct i2c_board_info i2c_device[] = { + { I2C_BOARD_INFO("tlv320aic33", 0x18), } +}; + static int __init s6105_init(void) { int ret;
+ i2c_register_board_info(0, i2c_device, ARRAY_SIZE(i2c_device)); + s6105_snd_device = platform_device_alloc("soc-audio", -1); if (!s6105_snd_device) return -ENOMEM; Index: b/sound/soc/davinci/davinci-evm.c =================================================================== --- a/sound/soc/davinci/davinci-evm.c 2009-08-20 08:38:01.000000000 +0100 +++ b/sound/soc/davinci/davinci-evm.c 2009-08-20 08:45:26.000000000 +0100 @@ -14,6 +14,7 @@ #include <linux/timer.h> #include <linux/interrupt.h> #include <linux/platform_device.h> +#include <linux/i2c.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> @@ -249,6 +250,13 @@ static struct snd_soc_device da850_evm_s
static struct platform_device *evm_snd_device;
+/* temporary i2c device creation until this can be moved into the machine + * support file. +*/ +static struct i2c_board_info i2c_device[] = { + { I2C_BOARD_INFO("tlv320aic33", 0x1b), } +}; + static int __init evm_init(void) { struct snd_soc_device *evm_snd_dev_data; @@ -273,6 +281,8 @@ static int __init evm_init(void) } else return -EINVAL;
+ i2c_register_board_info(1, i2c_device, ARRAY_SIZE(i2c_device)); + evm_snd_device = platform_device_alloc("soc-audio", index); if (!evm_snd_device) return -ENOMEM; Index: b/sound/soc/omap/n810.c =================================================================== --- a/sound/soc/omap/n810.c 2009-08-20 08:38:01.000000000 +0100 +++ b/sound/soc/omap/n810.c 2009-08-20 08:45:26.000000000 +0100 @@ -22,6 +22,7 @@ */
#include <linux/clk.h> +#include <linux/i2c.h> #include <linux/platform_device.h> #include <sound/core.h> #include <sound/pcm.h> @@ -335,6 +336,13 @@ static struct snd_soc_device n810_snd_de
static struct platform_device *n810_snd_device;
+/* temporary i2c device creation until this can be moved into the machine + * support file. +*/ +static struct i2c_board_info i2c_device[] = { + { I2C_BOARD_INFO("tlv320aic3x", 0x1b), } +}; + static int __init n810_soc_init(void) { int err; @@ -343,6 +351,8 @@ static int __init n810_soc_init(void) if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax())) return -ENODEV;
+ i2c_register_board_info(1, i2c_device, ARRAY_SIZE(i2c_device)); + n810_snd_device = platform_device_alloc("soc-audio", -1); if (!n810_snd_device) return -ENOMEM;
--
Add support for the tlv320aic3x CODEC on the Simtec Hermes board.
Signed-off-by: Ben Dooks ben@simtec.co.uk
--- sound/soc/s3c24xx/Kconfig | 7 + sound/soc/s3c24xx/Makefile | 3 sound/soc/s3c24xx/s3c24xx_simtec_hermes.c | 153 ++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+)
Index: b/sound/soc/s3c24xx/Kconfig =================================================================== --- a/sound/soc/s3c24xx/Kconfig 2009-08-20 08:37:55.000000000 +0100 +++ b/sound/soc/s3c24xx/Kconfig 2009-08-20 08:45:31.000000000 +0100 @@ -91,3 +91,10 @@ config SND_S3C24XX_SOC_SIMTEC_TLV320AIC2 select SND_S3C24XX_SOC_I2S select SND_SOC_TLV320AIC23 select SND_S3C24XX_SOC_SIMTEC + +config SND_S3C24XX_SOC_SIMTEC_HERMES + tristate "SoC I2S Audio support for Simtec Hermes board" + depends on SND_S3C24XX_SOC + select SND_S3C24XX_SOC_I2S + select SND_SOC_TLV320AIC3X + select SND_S3C24XX_SOC_SIMTEC Index: b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c 2009-08-20 08:45:31.000000000 +0100 @@ -0,0 +1,153 @@ +/* sound/soc/s3c24xx/s3c24xx_simtec_hermes.c + * + * Copyright 2009 Simtec Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/platform_device.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> + +#include <plat/audio-simtec.h> + +#include "s3c24xx-pcm.h" +#include "s3c24xx-i2s.h" +#include "s3c24xx_simtec.h" + +#include "../codecs/tlv320aic3x.h" + +static const struct snd_soc_dapm_widget dapm_widgets[] = { + SND_SOC_DAPM_LINE("GSM Out", NULL), + SND_SOC_DAPM_LINE("GSM In", NULL), + SND_SOC_DAPM_LINE("Line In", NULL), + SND_SOC_DAPM_LINE("Line Out", NULL), + SND_SOC_DAPM_LINE("ZV", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), +}; + +static const struct snd_soc_dapm_route base_map[] = { + /* Headphone connected to HP{L,R}OUT and HP{L,R}COM */ + + { "Headphone Jack", NULL, "HPLOUT" }, + { "Headphone Jack", NULL, "HPLCOM" }, + { "Headphone Jack", NULL, "HPROUT" }, + { "Headphone Jack", NULL, "HPRCOM" }, + + /* ZV connected to Line1 */ + + { "LINE1L", NULL, "ZV" }, + { "LINE1R", NULL, "ZV" }, + + /* Line In connected to Line2 */ + + { "LINE2L", NULL, "Line In" }, + { "LINE2R", NULL, "Line In" }, + + /* Microphone connected to MIC3R and MIC_BIAS */ + + { "MIC3L", NULL, "Mic Jack" }, + + /* GSM connected to MONO_LOUT and MIC3L (in) */ + + { "GSM Out", NULL, "MONO_LOUT" }, + { "MIC3L", NULL, "GSM In" }, + + /* Speaker is connected to LINEOUT{LN,LP,RN,RP}, however we are + * not using the DAPM to power it up and down as there it makes + * a click when powering up. */ +}; + +/** + * simtec_hermes_init - initialise and add controls + * @codec; The codec instance to attach to. + * + * Attach our controls and configure the necessary codec + * mappings for our sound card instance. +*/ +static int simtec_hermes_init(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, dapm_widgets, + ARRAY_SIZE(dapm_widgets)); + + snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map)); + + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Line In"); + snd_soc_dapm_enable_pin(codec, "Line Out"); + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + + simtec_audio_init(codec); + snd_soc_dapm_sync(codec); + + return 0; +} + +static struct aic3x_setup_data codec_setup = { +}; + +static struct snd_soc_dai_link simtec_dai_aic33 = { + .name = "tlv320aic33", + .stream_name = "TLV320AIC33", + .cpu_dai = &s3c24xx_i2s_dai, + .codec_dai = &aic3x_dai, + .init = simtec_hermes_init, +}; + +/* simtec audio machine driver */ +static struct snd_soc_card snd_soc_machine_simtec_aic33 = { + .name = "Simtec-Hermes", + .platform = &s3c24xx_soc_platform, + .dai_link = &simtec_dai_aic33, + .num_links = 1, +}; + +/* simtec audio subsystem */ +static struct snd_soc_device simtec_snd_devdata_aic33 = { + .card = &snd_soc_machine_simtec_aic33, + .codec_dev = &soc_codec_dev_aic3x, + .codec_data = &codec_setup, +}; + +static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) +{ + dev_info(&pd->dev, "probing....\n"); + return simtec_audio_core_probe(pd, &simtec_snd_devdata_aic33); +} + +static struct platform_driver simtec_audio_hermes_platdrv = { + .driver = { + .owner = THIS_MODULE, + .name = "s3c24xx-simtec-hermes-snd", + .pm = simtec_audio_pm, + }, + .probe = simtec_audio_hermes_probe, + .remove = __devexit_p(simtec_audio_remove), +}; + +MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd"); + +static int __init simtec_hermes_modinit(void) +{ + return platform_driver_register(&simtec_audio_hermes_platdrv); +} + +static void __exit simtec_hermes_modexit(void) +{ + platform_driver_unregister(&simtec_audio_hermes_platdrv); +} + +module_init(simtec_hermes_modinit); +module_exit(simtec_hermes_modexit); + +MODULE_AUTHOR("Ben Dooks ben@simtec.co.uk"); +MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); +MODULE_LICENSE("GPL"); Index: b/sound/soc/s3c24xx/Makefile =================================================================== --- a/sound/soc/s3c24xx/Makefile 2009-08-20 08:37:55.000000000 +0100 +++ b/sound/soc/s3c24xx/Makefile 2009-08-20 08:45:31.000000000 +0100 @@ -21,6 +21,7 @@ snd-soc-smdk2443-wm9710-objs := smdk2443 snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o +snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o @@ -30,4 +31,6 @@ obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o +obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o +
--
participants (2)
-
Ben Dooks
-
Mark Brown