diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-12 17:40:28 +0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-12 17:40:28 +0400 |
commit | cf7af01aa77ec1b17687f5328ce0a598709efd59 (patch) | |
tree | 4cc46339721366c7498dacf5ebac01906be273e7 /sound/soc/s3c24xx | |
parent | 6f341d14811550d863ba804ce6ec7757a7145081 (diff) | |
parent | 5dcba5d6741d4533e0ef696507f93f2a4c738efb (diff) | |
download | linux-cf7af01aa77ec1b17687f5328ce0a598709efd59.tar.xz |
Merge branch 'topic/multi-component' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6 into for-2.6.37
Diffstat (limited to 'sound/soc/s3c24xx')
31 files changed, 1105 insertions, 440 deletions
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 213963ac3c28..1cdc37bd58f4 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -131,3 +131,21 @@ config SND_S3C64XX_SOC_SMARTQ depends on SND_S3C24XX_SOC && MACH_SMARTQ select SND_S3C64XX_SOC_I2S select SND_SOC_WM8750 + +config SND_S5PC110_SOC_AQUILA_WM8994 + tristate "SoC I2S Audio support for AQUILA - WM8994" + depends on SND_S3C24XX_SOC && MACH_AQUILA + select SND_S3C64XX_SOC_I2S_V4 + select SND_SOC_WM8994 + help + Say Y if you want to add support for SoC audio on aquila + with the WM8994. + +config SND_S5PV210_SOC_GONI_WM8994 + tristate "SoC I2S Audio support for GONI - WM8994" + depends on SND_S3C24XX_SOC && MACH_GONI + select SND_S3C64XX_SOC_I2S_V4 + select SND_SOC_WM8994 + help + Say Y if you want to add support for SoC audio on goni + with the WM8994. diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 50172c385d90..47ed6d70b90b 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -30,6 +30,8 @@ snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o snd-soc-smdk-wm9713-objs := smdk_wm9713.o snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o +snd-soc-aquila-wm8994-objs := aquila_wm8994.o +snd-soc-goni-wm8994-objs := goni_wm8994.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 @@ -43,3 +45,5 @@ obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv32 obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o +obj-$(CONFIG_SND_S5PC110_SOC_AQUILA_WM8994) += snd-soc-aquila-wm8994.o +obj-$(CONFIG_SND_S5PV210_SOC_GONI_WM8994) += snd-soc-goni-wm8994.o diff --git a/sound/soc/s3c24xx/aquila_wm8994.c b/sound/soc/s3c24xx/aquila_wm8994.c new file mode 100644 index 000000000000..235d1973f7d0 --- /dev/null +++ b/sound/soc/s3c24xx/aquila_wm8994.c @@ -0,0 +1,295 @@ +/* + * aquila_wm8994.c + * + * Copyright (C) 2010 Samsung Electronics Co.Ltd + * Author: Chanwoo Choi <cw00.choi@samsung.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/jack.h> +#include <asm/mach-types.h> +#include <mach/gpio.h> +#include <mach/regs-clock.h> + +#include <linux/mfd/wm8994/core.h> +#include <linux/mfd/wm8994/registers.h> +#include "../codecs/wm8994.h" +#include "s3c-dma.h" +#include "s3c64xx-i2s.h" + +static struct snd_soc_card aquila; +static struct platform_device *aquila_snd_device; + +/* 3.5 pie jack */ +static struct snd_soc_jack jack; + +/* 3.5 pie jack detection DAPM pins */ +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, { + .pin = "Headset Stereophone", + .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | + SND_JACK_AVOUT, + }, +}; + +/* 3.5 pie jack detection gpios */ +static struct snd_soc_jack_gpio jack_gpios[] = { + { + .gpio = S5PV210_GPH0(6), + .name = "DET_3.5", + .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | + SND_JACK_AVOUT, + .debounce_time = 200, + }, +}; + +static const struct snd_soc_dapm_widget aquila_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_SPK("Ext Rcv", NULL), + SND_SOC_DAPM_HP("Headset Stereophone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Main Mic", NULL), + SND_SOC_DAPM_MIC("2nd Mic", NULL), + SND_SOC_DAPM_LINE("Radio In", NULL), +}; + +static const struct snd_soc_dapm_route aquila_dapm_routes[] = { + {"Ext Spk", NULL, "SPKOUTLP"}, + {"Ext Spk", NULL, "SPKOUTLN"}, + + {"Ext Rcv", NULL, "HPOUT2N"}, + {"Ext Rcv", NULL, "HPOUT2P"}, + + {"Headset Stereophone", NULL, "HPOUT1L"}, + {"Headset Stereophone", NULL, "HPOUT1R"}, + + {"IN1RN", NULL, "Headset Mic"}, + {"IN1RP", NULL, "Headset Mic"}, + + {"IN1RN", NULL, "2nd Mic"}, + {"IN1RP", NULL, "2nd Mic"}, + + {"IN1LN", NULL, "Main Mic"}, + {"IN1LP", NULL, "Main Mic"}, + + {"IN2LN", NULL, "Radio In"}, + {"IN2RN", NULL, "Radio In"}, +}; + +static int aquila_wm8994_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + int ret; + + /* add aquila specific widgets */ + snd_soc_dapm_new_controls(codec, aquila_dapm_widgets, + ARRAY_SIZE(aquila_dapm_widgets)); + + /* set up aquila specific audio routes */ + snd_soc_dapm_add_routes(codec, aquila_dapm_routes, + ARRAY_SIZE(aquila_dapm_routes)); + + /* set endpoints to not connected */ + snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN"); + snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); + snd_soc_dapm_nc_pin(codec, "LINEOUT1N"); + snd_soc_dapm_nc_pin(codec, "LINEOUT1P"); + snd_soc_dapm_nc_pin(codec, "LINEOUT2N"); + snd_soc_dapm_nc_pin(codec, "LINEOUT2P"); + snd_soc_dapm_nc_pin(codec, "SPKOUTRN"); + snd_soc_dapm_nc_pin(codec, "SPKOUTRP"); + + snd_soc_dapm_sync(codec); + + /* Headset jack detection */ + ret = snd_soc_jack_new(&aquila, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, + &jack); + if (ret) + return ret; + + ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); + if (ret) + return ret; + + ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); + if (ret) + return ret; + + return 0; +} + +static int aquila_hifi_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->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int pll_out = 24000000; + int ret = 0; + + /* set the cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the cpu system clock */ + ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK, + 0, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the codec FLL */ + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, + params_rate(params) * 256); + if (ret < 0) + return ret; + + /* set the codec system clock */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, + params_rate(params) * 256, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops aquila_hifi_ops = { + .hw_params = aquila_hifi_hw_params, +}; + +static int aquila_voice_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->codec_dai; + unsigned int pll_out = 24000000; + int ret = 0; + + if (params_rate(params) != 8000) + return -EINVAL; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | + SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the codec FLL */ + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, + params_rate(params) * 256); + if (ret < 0) + return ret; + + /* set the codec system clock */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, + params_rate(params) * 256, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_dai_driver voice_dai = { + .name = "aquila-voice-dai", + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, +}; + +static struct snd_soc_ops aquila_voice_ops = { + .hw_params = aquila_voice_hw_params, +}; + +static struct snd_soc_dai_link aquila_dai[] = { +{ + .name = "WM8994", + .stream_name = "WM8994 HiFi", + .cpu_dai_name = "s3c64xx-i2s-v4", + .codec_dai_name = "wm8994-hifi", + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8994-codec.0-0x1a", + .init = aquila_wm8994_init, + .ops = &aquila_hifi_ops, +}, { + .name = "WM8994 Voice", + .stream_name = "Voice", + .cpu_dai_name = "aquila-voice-dai", + .codec_dai_name = "wm8994-voice", + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8994-codec.0-0x1a", + .ops = &aquila_voice_ops, +}, +}; + +static struct snd_soc_card aquila = { + .name = "aquila", + .dai_link = aquila_dai, + .num_links = ARRAY_SIZE(aquila_dai), +}; + +static int __init aquila_init(void) +{ + int ret; + + if (!machine_is_aquila()) + return -ENODEV; + + aquila_snd_device = platform_device_alloc("soc-audio", -1); + if (!aquila_snd_device) + return -ENOMEM; + + /* register voice DAI here */ + ret = snd_soc_register_dai(&aquila_snd_device->dev, &voice_dai); + if (ret) + return ret; + + platform_set_drvdata(aquila_snd_device, &aquila); + ret = platform_device_add(aquila_snd_device); + + if (ret) + platform_device_put(aquila_snd_device); + + return ret; +} + +static void __exit aquila_exit(void) +{ + platform_device_unregister(aquila_snd_device); +} + +module_init(aquila_init); +module_exit(aquila_exit); + +/* Module information */ +MODULE_DESCRIPTION("ALSA SoC WM8994 Aquila(S5PC110)"); +MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/s3c24xx/goni_wm8994.c new file mode 100644 index 000000000000..694f702cc8e2 --- /dev/null +++ b/sound/soc/s3c24xx/goni_wm8994.c @@ -0,0 +1,298 @@ +/* + * goni_wm8994.c + * + * Copyright (C) 2010 Samsung Electronics Co.Ltd + * Author: Chanwoo Choi <cw00.choi@samsung.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/jack.h> +#include <asm/mach-types.h> +#include <mach/gpio.h> +#include <mach/regs-clock.h> + +#include <linux/mfd/wm8994/core.h> +#include <linux/mfd/wm8994/registers.h> +#include "../codecs/wm8994.h" +#include "s3c-dma.h" +#include "s3c64xx-i2s.h" + +static struct snd_soc_card goni; +static struct platform_device *goni_snd_device; + +/* 3.5 pie jack */ +static struct snd_soc_jack jack; + +/* 3.5 pie jack detection DAPM pins */ +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, { + .pin = "Headset Stereophone", + .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | + SND_JACK_AVOUT, + }, +}; + +/* 3.5 pie jack detection gpios */ +static struct snd_soc_jack_gpio jack_gpios[] = { + { + .gpio = S5PV210_GPH0(6), + .name = "DET_3.5", + .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | + SND_JACK_AVOUT, + .debounce_time = 200, + }, +}; + +static const struct snd_soc_dapm_widget goni_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Ext Left Spk", NULL), + SND_SOC_DAPM_SPK("Ext Right Spk", NULL), + SND_SOC_DAPM_SPK("Ext Rcv", NULL), + SND_SOC_DAPM_HP("Headset Stereophone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Main Mic", NULL), + SND_SOC_DAPM_MIC("2nd Mic", NULL), + SND_SOC_DAPM_LINE("Radio In", NULL), +}; + +static const struct snd_soc_dapm_route goni_dapm_routes[] = { + {"Ext Left Spk", NULL, "SPKOUTLP"}, + {"Ext Left Spk", NULL, "SPKOUTLN"}, + + {"Ext Right Spk", NULL, "SPKOUTRP"}, + {"Ext Right Spk", NULL, "SPKOUTRN"}, + + {"Ext Rcv", NULL, "HPOUT2N"}, + {"Ext Rcv", NULL, "HPOUT2P"}, + + {"Headset Stereophone", NULL, "HPOUT1L"}, + {"Headset Stereophone", NULL, "HPOUT1R"}, + + {"IN1RN", NULL, "Headset Mic"}, + {"IN1RP", NULL, "Headset Mic"}, + + {"IN1RN", NULL, "2nd Mic"}, + {"IN1RP", NULL, "2nd Mic"}, + + {"IN1LN", NULL, "Main Mic"}, + {"IN1LP", NULL, "Main Mic"}, + + {"IN2LN", NULL, "Radio In"}, + {"IN2RN", NULL, "Radio In"}, +}; + +static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + int ret; + + /* add goni specific widgets */ + snd_soc_dapm_new_controls(codec, goni_dapm_widgets, + ARRAY_SIZE(goni_dapm_widgets)); + + /* set up goni specific audio routes */ + snd_soc_dapm_add_routes(codec, goni_dapm_routes, + ARRAY_SIZE(goni_dapm_routes)); + + /* set endpoints to not connected */ + snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN"); + snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); + snd_soc_dapm_nc_pin(codec, "LINEOUT1N"); + snd_soc_dapm_nc_pin(codec, "LINEOUT1P"); + snd_soc_dapm_nc_pin(codec, "LINEOUT2N"); + snd_soc_dapm_nc_pin(codec, "LINEOUT2P"); + + snd_soc_dapm_sync(codec); + + /* Headset jack detection */ + ret = snd_soc_jack_new(&goni, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, + &jack); + if (ret) + return ret; + + ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); + if (ret) + return ret; + + ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); + if (ret) + return ret; + + return 0; +} + +static int goni_hifi_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->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int pll_out = 24000000; + int ret = 0; + + /* set the cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the cpu system clock */ + ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK, + 0, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the codec FLL */ + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, + params_rate(params) * 256); + if (ret < 0) + return ret; + + /* set the codec system clock */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, + params_rate(params) * 256, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops goni_hifi_ops = { + .hw_params = goni_hifi_hw_params, +}; + +static int goni_voice_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->codec_dai; + unsigned int pll_out = 24000000; + int ret = 0; + + if (params_rate(params) != 8000) + return -EINVAL; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | + SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the codec FLL */ + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, + params_rate(params) * 256); + if (ret < 0) + return ret; + + /* set the codec system clock */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, + params_rate(params) * 256, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_dai_driver voice_dai = { + .name = "goni-voice-dai", + .id = 0, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, +}; + +static struct snd_soc_ops goni_voice_ops = { + .hw_params = goni_voice_hw_params, +}; + +static struct snd_soc_dai_link goni_dai[] = { +{ + .name = "WM8994", + .stream_name = "WM8994 HiFi", + .cpu_dai_name = "s3c64xx-i2s-v4", + .codec_dai_name = "wm8994-hifi", + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8994-codec.0-0x1a", + .init = goni_wm8994_init, + .ops = &goni_hifi_ops, +}, { + .name = "WM8994 Voice", + .stream_name = "Voice", + .cpu_dai_name = "goni-voice-dai", + .codec_dai_name = "wm8994-voice", + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8994-codec.0-0x1a", + .ops = &goni_voice_ops, +}, +}; + +static struct snd_soc_card goni = { + .name = "goni", + .dai_link = goni_dai, + .num_links = ARRAY_SIZE(goni_dai), +}; + +static int __init goni_init(void) +{ + int ret; + + if (!machine_is_goni()) + return -ENODEV; + + goni_snd_device = platform_device_alloc("soc-audio", -1); + if (!goni_snd_device) + return -ENOMEM; + + /* register voice DAI here */ + ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai); + if (ret) + return ret; + + platform_set_drvdata(goni_snd_device, &goni); + ret = platform_device_add(goni_snd_device); + + if (ret) + platform_device_put(goni_snd_device); + + return ret; +} + +static void __exit goni_exit(void) +{ + platform_device_unregister(goni_snd_device); +} + +module_init(goni_init); +module_exit(goni_exit); + +/* Module information */ +MODULE_DESCRIPTION("ALSA SoC WM8994 GONI(S5PV210)"); +MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c index 8c108b121c10..49605cd83947 100644 --- a/sound/soc/s3c24xx/jive_wm8750.c +++ b/sound/soc/s3c24xx/jive_wm8750.c @@ -49,8 +49,8 @@ static int jive_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; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct s3c_i2sv2_rate_calc div; unsigned int clk = 0; int ret = 0; @@ -108,8 +108,9 @@ static struct snd_soc_ops jive_ops = { .hw_params = jive_hw_params, }; -static int jive_wm8750_init(struct snd_soc_codec *codec) +static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; int err; /* These endpoints are not being used. */ @@ -138,8 +139,10 @@ static int jive_wm8750_init(struct snd_soc_codec *codec) static struct snd_soc_dai_link jive_dai = { .name = "wm8750", .stream_name = "WM8750", - .cpu_dai = &s3c2412_i2s_dai, - .codec_dai = &wm8750_dai, + .cpu_dai_name = "s3c2412-i2s", + .codec_dai_name = "wm8750-hifi", + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8750-codec.0-0x1a", .init = jive_wm8750_init, .ops = &jive_ops, }; @@ -147,17 +150,10 @@ static struct snd_soc_dai_link jive_dai = { /* jive audio machine driver */ static struct snd_soc_card snd_soc_machine_jive = { .name = "Jive", - .platform = &s3c24xx_soc_platform, .dai_link = &jive_dai, .num_links = 1, }; -/* jive audio subsystem */ -static struct snd_soc_device jive_snd_devdata = { - .card = &snd_soc_machine_jive, - .codec_dev = &soc_codec_dev_wm8750, -}; - static struct platform_device *jive_snd_device; static int __init jive_init(void) @@ -173,8 +169,7 @@ static int __init jive_init(void) if (!jive_snd_device) return -ENOMEM; - platform_set_drvdata(jive_snd_device, &jive_snd_devdata); - jive_snd_devdata.dev = &jive_snd_device->dev; + platform_set_drvdata(jive_snd_device, &snd_soc_machine_jive); ret = platform_device_add(jive_snd_device); if (ret) diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c index ffa954fe6931..abe64abe8c84 100644 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c @@ -23,7 +23,6 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> -#include "../codecs/ac97.h" #include "s3c-dma.h" #include "s3c-ac97.h" @@ -33,23 +32,19 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM], - .codec_dai = &ac97_dai, + .cpu_dai_name = "s3c-ac97", + .codec_dai_name = "ac97-hifi", + .codec_name = "ac97-codec", + .platform_name = "s3c24xx-pcm-audio", }, }; static struct snd_soc_card ln2440sbc = { .name = "LN2440SBC", - .platform = &s3c24xx_soc_platform, .dai_link = ln2440sbc_dai, .num_links = ARRAY_SIZE(ln2440sbc_dai), }; -static struct snd_soc_device ln2440sbc_snd_ac97_devdata = { - .card = &ln2440sbc, - .codec_dev = &soc_codec_dev_ac97, -}; - static struct platform_device *ln2440sbc_snd_ac97_device; static int __init ln2440sbc_init(void) @@ -60,9 +55,7 @@ static int __init ln2440sbc_init(void) if (!ln2440sbc_snd_ac97_device) return -ENOMEM; - platform_set_drvdata(ln2440sbc_snd_ac97_device, - &ln2440sbc_snd_ac97_devdata); - ln2440sbc_snd_ac97_devdata.dev = &ln2440sbc_snd_ac97_device->dev; + platform_set_drvdata(ln2440sbc_snd_ac97_device, &ln2440sbc); ret = platform_device_add(ln2440sbc_snd_ac97_device); if (ret) diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c index 209c25994c7e..c457bfd8297c 100644 --- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c @@ -41,8 +41,8 @@ static int neo1973_gta02_hifi_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; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int pll_out = 0, bclk = 0; int ret = 0; unsigned long iis_clkrate; @@ -130,7 +130,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream, static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; /* disable the PLL */ return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); @@ -149,7 +149,7 @@ static int neo1973_gta02_voice_hw_params( 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 *codec_dai = rtd->codec_dai; unsigned int pcmdiv = 0; int ret = 0; unsigned long iis_clkrate; @@ -194,7 +194,7 @@ static int neo1973_gta02_voice_hw_params( static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; /* disable the PLL */ return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); @@ -262,7 +262,7 @@ static int lm4853_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(value)); + gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event)); return 0; } @@ -330,8 +330,9 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = { * This is an example machine initialisation for a wm8753 connected to a * neo1973 GTA02. */ -static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) +static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; int err; /* set up NC codec pins */ @@ -378,9 +379,8 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) /* * BT Codec DAI */ -static struct snd_soc_dai bt_dai = { - .name = "Bluetooth", - .id = 0, +static struct snd_soc_dai_driver bt_dai = { + .name = "bluetooth-dai", .playback = { .channels_min = 1, .channels_max = 1, @@ -397,32 +397,30 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = { { /* Hifi Playback - for similatious use with voice below */ .name = "WM8753", .stream_name = "WM8753 HiFi", - .cpu_dai = &s3c24xx_i2s_dai, - .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], + .cpu_dai_name = "s3c24xx-i2s", + .codec_dai_name = "wm8753-hifi", .init = neo1973_gta02_wm8753_init, + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8753-codec.0-0x1a", .ops = &neo1973_gta02_hifi_ops, }, { /* Voice via BT */ .name = "Bluetooth", .stream_name = "Voice", - .cpu_dai = &bt_dai, - .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], + .cpu_dai_name = "bluetooth-dai", + .codec_dai_name = "wm8753-voice", .ops = &neo1973_gta02_voice_ops, + .codec_name = "wm8753-codec.0-0x1a", + .platform_name = "s3c24xx-pcm-audio", }, }; static struct snd_soc_card neo1973_gta02 = { .name = "neo1973-gta02", - .platform = &s3c24xx_soc_platform, .dai_link = neo1973_gta02_dai, .num_links = ARRAY_SIZE(neo1973_gta02_dai), }; -static struct snd_soc_device neo1973_gta02_snd_devdata = { - .card = &neo1973_gta02, - .codec_dev = &soc_codec_dev_wm8753, -}; - static struct platform_device *neo1973_gta02_snd_device; static int __init neo1973_gta02_init(void) @@ -435,18 +433,18 @@ static int __init neo1973_gta02_init(void) return -ENODEV; } - /* register bluetooth DAI here */ - ret = snd_soc_register_dai(&bt_dai); - if (ret) - return ret; - neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1); if (!neo1973_gta02_snd_device) return -ENOMEM; - platform_set_drvdata(neo1973_gta02_snd_device, - &neo1973_gta02_snd_devdata); - neo1973_gta02_snd_devdata.dev = &neo1973_gta02_snd_device->dev; + /* register bluetooth DAI here */ + ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, -1, &bt_dai); + if (ret) { + platform_device_put(neo1973_gta02_snd_device); + return ret; + } + + platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02); ret = platform_device_add(neo1973_gta02_snd_device); if (ret) { @@ -461,7 +459,7 @@ static int __init neo1973_gta02_init(void) goto err_unregister_device; } - ret = gpio_direction_output(GTA02_GPIO_AMP_HP_IN, 1); + ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1); if (ret) { pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN); goto err_free_gpio_hp_in; @@ -493,7 +491,7 @@ module_init(neo1973_gta02_init); static void __exit neo1973_gta02_exit(void) { - snd_soc_unregister_dai(&bt_dai); + snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev, -1); platform_device_unregister(neo1973_gta02_snd_device); gpio_free(GTA02_GPIO_HP_IN); gpio_free(GTA02_GPIO_AMP_SHUT); diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 0cb4f86f6d1e..d7a39a0fe99b 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -57,8 +57,8 @@ static int neo1973_hifi_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; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int pll_out = 0, bclk = 0; int ret = 0; unsigned long iis_clkrate; @@ -147,7 +147,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; pr_debug("Entered %s\n", __func__); @@ -167,7 +167,7 @@ static int neo1973_voice_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 *codec_dai = rtd->codec_dai; unsigned int pcmdiv = 0; int ret = 0; unsigned long iis_clkrate; @@ -213,7 +213,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; pr_debug("Entered %s\n", __func__); @@ -499,8 +499,9 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { * neo1973 II. It is missing logic to detect hp/mic insertions and logic * to re-route the audio in such an event. */ -static int neo1973_wm8753_init(struct snd_soc_codec *codec) +static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; int err; pr_debug("Entered %s\n", __func__); @@ -538,8 +539,7 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec) * BT Codec DAI */ static struct snd_soc_dai bt_dai = { - .name = "Bluetooth", - .id = 0, + .name = "bluetooth-dai", .playback = { .channels_min = 1, .channels_max = 1, @@ -556,32 +556,30 @@ static struct snd_soc_dai_link neo1973_dai[] = { { /* Hifi Playback - for similatious use with voice below */ .name = "WM8753", .stream_name = "WM8753 HiFi", - .cpu_dai = &s3c24xx_i2s_dai, - .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], + .platform_name = "s3c24xx-pcm-audio", + .cpu_dai_name = "s3c24xx-i2s", + .codec_dai_name = "wm8753-hifi", + .codec_name = "wm8753-codec.0-0x1a", .init = neo1973_wm8753_init, .ops = &neo1973_hifi_ops, }, { /* Voice via BT */ .name = "Bluetooth", .stream_name = "Voice", - .cpu_dai = &bt_dai, - .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], + .platform_name = "s3c24xx-pcm-audio", + .cpu_dai_name = "bluetooth-dai", + .codec_dai_name = "wm8753-voice", + .codec_name = "wm8753-codec.0-0x1a", .ops = &neo1973_voice_ops, }, }; static struct snd_soc_card neo1973 = { .name = "neo1973", - .platform = &s3c24xx_soc_platform, .dai_link = neo1973_dai, .num_links = ARRAY_SIZE(neo1973_dai), }; -static struct snd_soc_device neo1973_snd_devdata = { - .card = &neo1973, - .codec_dev = &soc_codec_dev_wm8753, -}; - static int lm4857_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -673,8 +671,7 @@ static int __init neo1973_init(void) if (!neo1973_snd_device) return -ENOMEM; - platform_set_drvdata(neo1973_snd_device, &neo1973_snd_devdata); - neo1973_snd_devdata.dev = &neo1973_snd_device->dev; + platform_set_drvdata(neo1973_snd_device, &neo1973); ret = platform_device_add(neo1973_snd_device); if (ret) { diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index 31f6d45b6384..26f4ed90a0ee 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -222,7 +222,7 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct s3c_dma_params *dma_data; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -241,7 +241,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, u32 ac_glbctrl; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) @@ -277,7 +277,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return -ENODEV; @@ -293,7 +293,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, u32 ac_glbctrl; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; @@ -328,10 +328,9 @@ static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { .trigger = s3c_ac97_mic_trigger, }; -struct snd_soc_dai s3c_ac97_dai[] = { +static struct snd_soc_dai_driver s3c_ac97_dai[] = { [S3C_AC97_DAI_PCM] = { .name = "s3c-ac97", - .id = S3C_AC97_DAI_PCM, .ac97_control = 1, .playback = { .stream_name = "AC97 Playback", @@ -349,7 +348,6 @@ struct snd_soc_dai s3c_ac97_dai[] = { }, [S3C_AC97_DAI_MIC] = { .name = "s3c-ac97-mic", - .id = S3C_AC97_DAI_MIC, .ac97_control = 1, .capture = { .stream_name = "AC97 Mic Capture", @@ -360,7 +358,6 @@ struct snd_soc_dai s3c_ac97_dai[] = { .ops = &s3c_ac97_mic_dai_ops, }, }; -EXPORT_SYMBOL_GPL(s3c_ac97_dai); static __devinit int s3c_ac97_probe(struct platform_device *pdev) { @@ -449,10 +446,8 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) goto err4; } - s3c_ac97_dai[S3C_AC97_DAI_PCM].dev = &pdev->dev; - s3c_ac97_dai[S3C_AC97_DAI_MIC].dev = &pdev->dev; - - ret = snd_soc_register_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); + ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, + ARRAY_SIZE(s3c_ac97_dai)); if (ret) goto err5; @@ -476,7 +471,7 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev) { struct resource *mem_res, *irq_res; - snd_soc_unregister_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_res) @@ -518,3 +513,4 @@ module_exit(s3c_ac97_exit); MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c-ac97"); diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/s3c24xx/s3c-ac97.h index 278198379def..5dcedd07fdbb 100644 --- a/sound/soc/s3c24xx/s3c-ac97.h +++ b/sound/soc/s3c24xx/s3c-ac97.h @@ -18,6 +18,4 @@ #define S3C_AC97_DAI_PCM 0 #define S3C_AC97_DAI_MIC 1 -extern struct snd_soc_dai s3c_ac97_dai[]; - #endif /* __S3C_AC97_H_ */ diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c index 1b61c23ff300..54bff83c98b4 100644 --- a/sound/soc/s3c24xx/s3c-dma.c +++ b/sound/soc/s3c24xx/s3c-dma.c @@ -147,7 +147,7 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned long totbytes = params_buffer_bytes(params); struct s3c_dma_params *dma = - snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); int ret = 0; @@ -441,14 +441,14 @@ static int s3c_dma_new(struct snd_card *card, if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; - if (dai->playback.channels_min) { + if (dai->driver->playback.channels_min) { ret = s3c_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (dai->capture.channels_min) { + if (dai->driver->capture.channels_min) { ret = s3c_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -458,26 +458,46 @@ static int s3c_dma_new(struct snd_card *card, return ret; } -struct snd_soc_platform s3c24xx_soc_platform = { - .name = "s3c24xx-audio", - .pcm_ops = &s3c_dma_ops, +static struct snd_soc_platform_driver s3c24xx_soc_platform = { + .ops = &s3c_dma_ops, .pcm_new = s3c_dma_new, .pcm_free = s3c_dma_free_dma_buffers, }; -EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); -static int __init s3c24xx_soc_platform_init(void) +static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev) { - return snd_soc_register_platform(&s3c24xx_soc_platform); + return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform); } -module_init(s3c24xx_soc_platform_init); -static void __exit s3c24xx_soc_platform_exit(void) +static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&s3c24xx_soc_platform); + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static struct platform_driver s3c24xx_pcm_driver = { + .driver = { + .name = "s3c24xx-pcm-audio", + .owner = THIS_MODULE, + }, + + .probe = s3c24xx_soc_platform_probe, + .remove = __devexit_p(s3c24xx_soc_platform_remove), +}; + +static int __init snd_s3c24xx_pcm_init(void) +{ + return platform_driver_register(&s3c24xx_pcm_driver); +} +module_init(snd_s3c24xx_pcm_init); + +static void __exit snd_s3c24xx_pcm_exit(void) +{ + platform_driver_unregister(&s3c24xx_pcm_driver); } -module_exit(s3c24xx_soc_platform_exit); +module_exit(snd_s3c24xx_pcm_exit); MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); MODULE_DESCRIPTION("Samsung S3C Audio DMA module"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c24xx-pcm-audio"); diff --git a/sound/soc/s3c24xx/s3c-dma.h b/sound/soc/s3c24xx/s3c-dma.h index 69bb6bf6fc1c..748c07d7c075 100644 --- a/sound/soc/s3c24xx/s3c-dma.h +++ b/sound/soc/s3c24xx/s3c-dma.h @@ -25,7 +25,6 @@ struct s3c_dma_params { #define S3C24XX_DAI_I2S 0 /* platform data */ -extern struct snd_soc_platform s3c24xx_soc_platform; extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; #endif diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 64376b2aac73..b3866d5b19e9 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -49,7 +49,7 @@ static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) { - return cpu_dai->private_data; + return snd_soc_dai_get_drvdata(cpu_dai); } #define bit_set(v, b) (((v) & (b)) ? 1 : 0) @@ -307,11 +307,9 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) + struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai_link *dai = rtd->dai; - struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); + struct s3c_i2sv2_info *i2s = to_info(dai); struct s3c_dma_params *dma_data; u32 iismod; @@ -322,7 +320,7 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, else dma_data = i2s->dma_capture; - snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); + snd_soc_dai_set_dma_data(dai, substream, dma_data); /* Working copies of register */ iismod = readl(i2s->regs + S3C2412_IISMOD); @@ -396,12 +394,12 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_i2sv2_info *i2s = to_info(rtd->dai->cpu_dai); + struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai); int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); unsigned long irqs; int ret = 0; struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); pr_debug("Entered %s\n", __func__); @@ -640,36 +638,17 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, } EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate); -int s3c_i2sv2_probe(struct platform_device *pdev, - struct snd_soc_dai *dai, +int s3c_i2sv2_probe(struct snd_soc_dai *dai, struct s3c_i2sv2_info *i2s, unsigned long base) { - struct device *dev = &pdev->dev; + struct device *dev = dai->dev; unsigned int iismod; i2s->dev = dev; /* record our i2s structure for later use in the callbacks */ - dai->private_data = i2s; - - if (!base) { - struct resource *res = platform_get_resource(pdev, - IORESOURCE_MEM, - 0); - if (!res) { - dev_err(dev, "Unable to get register resource\n"); - return -ENXIO; - } - - if (!request_mem_region(res->start, resource_size(res), - "s3c64xx-i2s-v4")) { - dev_err(dev, "Unable to request register region\n"); - return -EBUSY; - } - - base = res->start; - } + snd_soc_dai_set_drvdata(dai, i2s); i2s->regs = ioremap(base, 0x100); if (i2s->regs == NULL) { @@ -752,9 +731,10 @@ static int s3c2412_i2s_resume(struct snd_soc_dai *dai) #define s3c2412_i2s_resume NULL #endif -int s3c_i2sv2_register_dai(struct snd_soc_dai *dai) +int s3c_i2sv2_register_dai(struct device *dev, int id, + struct snd_soc_dai_driver *drv) { - struct snd_soc_dai_ops *ops = dai->ops; + struct snd_soc_dai_ops *ops = drv->ops; ops->trigger = s3c2412_i2s_trigger; if (!ops->hw_params) @@ -767,10 +747,10 @@ int s3c_i2sv2_register_dai(struct snd_soc_dai *dai) if (!ops->delay) ops->delay = s3c2412_i2s_delay; - dai->suspend = s3c2412_i2s_suspend; - dai->resume = s3c2412_i2s_resume; + drv->suspend = s3c2412_i2s_suspend; + drv->resume = s3c2412_i2s_resume; - return snd_soc_register_dai(dai); + return snd_soc_register_dai(dev, drv); } EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/s3c24xx/s3c-i2s-v2.h index 766f43a13d8b..d45830151484 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.h +++ b/sound/soc/s3c24xx/s3c-i2s-v2.h @@ -66,6 +66,8 @@ struct s3c_i2sv2_info { u32 suspend_iismod; u32 suspend_iiscon; u32 suspend_iispsr; + + unsigned long base; }; extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai); @@ -81,23 +83,24 @@ extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, /** * s3c_i2sv2_probe - probe for i2s device helper - * @pdev: The platform device supplied to the original probe. * @dai: The ASoC DAI structure supplied to the original probe. * @i2s: Our local i2s structure to fill in. * @base: The base address for the registers. */ -extern int s3c_i2sv2_probe(struct platform_device *pdev, - struct snd_soc_dai *dai, +extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, struct s3c_i2sv2_info *i2s, unsigned long base); /** * s3c_i2sv2_register_dai - register dai with soc core - * @dai: The snd_soc_dai structure to register + * @dev: DAI device + * @id: DAI ID + * @drv: The driver structure to register * * Fill in any missing fields and then register the given dai with the * soc core. */ -extern int s3c_i2sv2_register_dai(struct snd_soc_dai *dai); +extern int s3c_i2sv2_register_dai(struct device *dev, int id, + struct snd_soc_dai_driver *drv); #endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c index 326f0a9e7e30..6174e26e433e 100644 --- a/sound/soc/s3c24xx/s3c-pcm.c +++ b/sound/soc/s3c24xx/s3c-pcm.c @@ -64,11 +64,6 @@ static struct s3c_dma_params s3c_pcm_stereo_in[] = { static struct s3c_pcm_info s3c_pcm[2]; -static inline struct s3c_pcm_info *to_info(struct snd_soc_dai *cpu_dai) -{ - return cpu_dai->private_data; -} - static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on) { void __iomem *regs = pcm->regs; @@ -132,7 +127,7 @@ static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_pcm_info *pcm = to_info(rtd->dai->cpu_dai); + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); unsigned long flags; dev_dbg(pcm->dev, "Entered %s\n", __func__); @@ -176,8 +171,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *socdai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai_link *dai = rtd->dai; - struct s3c_pcm_info *pcm = to_info(dai->cpu_dai); + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); struct s3c_dma_params *dma_data; void __iomem *regs = pcm->regs; struct clk *clk; @@ -192,7 +186,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, else dma_data = pcm->dma_capture; - snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); + snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); /* Strictly check for sample size */ switch (params_format(params)) { @@ -242,7 +236,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { - struct s3c_pcm_info *pcm = to_info(cpu_dai); + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); void __iomem *regs = pcm->regs; unsigned long flags; int ret = 0; @@ -313,7 +307,7 @@ exit: static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { - struct s3c_pcm_info *pcm = to_info(cpu_dai); + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); switch (div_id) { case S3C_PCM_SCLK_PER_FS: @@ -330,7 +324,7 @@ static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai, static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { - struct s3c_pcm_info *pcm = to_info(cpu_dai); + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); void __iomem *regs = pcm->regs; u32 clkctl = readl(regs + S3C_PCM_CLKCTL); @@ -366,10 +360,9 @@ static struct snd_soc_dai_ops s3c_pcm_dai_ops = { #define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 -#define S3C_PCM_DECLARE(n) \ +#define S3C_PCM_DAI_DECLARE \ { \ - .name = "samsung-pcm", \ - .id = (n), \ + .name = "samsung-dai", \ .symmetric_rates = 1, \ .ops = &s3c_pcm_dai_ops, \ .playback = { \ @@ -386,16 +379,15 @@ static struct snd_soc_dai_ops s3c_pcm_dai_ops = { }, \ } -struct snd_soc_dai s3c_pcm_dai[] = { - S3C_PCM_DECLARE(0), - S3C_PCM_DECLARE(1), +struct snd_soc_dai_driver s3c_pcm_dai[] = { + S3C_PCM_DAI_DECLARE, + S3C_PCM_DAI_DECLARE, }; EXPORT_SYMBOL_GPL(s3c_pcm_dai); static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) { struct s3c_pcm_info *pcm; - struct snd_soc_dai *dai; struct resource *mem_res, *dmatx_res, *dmarx_res; struct s3c_audio_pdata *pcm_pdata; int ret; @@ -437,9 +429,6 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) spin_lock_init(&pcm->lock); - dai = &s3c_pcm_dai[pdev->id]; - dai->dev = &pdev->dev; - /* Default is 128fs */ pcm->sclk_per_fs = 128; @@ -452,7 +441,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) clk_enable(pcm->cclk); /* record our pcm structure for later use in the callbacks */ - dai->private_data = pcm; + dev_set_drvdata(&pdev->dev, pcm); if (!request_mem_region(mem_res->start, resource_size(mem_res), "samsung-pcm")) { @@ -476,7 +465,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) } clk_enable(pcm->pclk); - ret = snd_soc_register_dai(dai); + ret = snd_soc_register_dai(&pdev->dev, s3c_pcm_dai); if (ret != 0) { dev_err(&pdev->dev, "failed to get pcm_clock\n"); goto err5; @@ -514,6 +503,8 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; struct resource *mem_res; + snd_soc_unregister_dai(&pdev->dev); + iounmap(pcm->regs); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -531,7 +522,7 @@ static struct platform_driver s3c_pcm_driver = { .probe = s3c_pcm_dev_probe, .remove = s3c_pcm_dev_remove, .driver = { - .name = "samsung-pcm", + .name = "samsung-pcm-audio", .owner = THIS_MODULE, }, }; @@ -552,3 +543,4 @@ module_exit(s3c_pcm_exit); MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); MODULE_DESCRIPTION("S3C PCM Controller Driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-pcm-audio"); diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c index 709adef9d043..4a861cfa52c5 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/s3c24xx/s3c2412-i2s.c @@ -65,26 +65,20 @@ static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { static struct s3c_i2sv2_info s3c2412_i2s; -static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) -{ - return cpu_dai->private_data; -} - -static int s3c2412_i2s_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) +static int s3c2412_i2s_probe(struct snd_soc_dai *dai) { int ret; pr_debug("Entered %s\n", __func__); - ret = s3c_i2sv2_probe(pdev, dai, &s3c2412_i2s, S3C2410_PA_IIS); + ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); if (ret) return ret; s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; - s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk"); + s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); if (s3c2412_i2s.iis_cclk == NULL) { pr_err("failed to get i2sclk clock\n"); iounmap(s3c2412_i2s.regs); @@ -108,11 +102,20 @@ static int s3c2412_i2s_probe(struct platform_device *pdev, return 0; } +static int s3c2412_i2s_remove(struct snd_soc_dai *dai) +{ + clk_disable(s3c2412_i2s.iis_cclk); + clk_put(s3c2412_i2s.iis_cclk); + iounmap(s3c2412_i2s.regs); + + return 0; +} + static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *cpu_dai) { - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); + struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); struct s3c_dma_params *dma_data; u32 iismod; @@ -152,10 +155,9 @@ static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { .hw_params = s3c2412_i2s_hw_params, }; -struct snd_soc_dai s3c2412_i2s_dai = { - .name = "s3c2412-i2s", - .id = 0, +static struct snd_soc_dai_driver s3c2412_i2s_dai = { .probe = s3c2412_i2s_probe, + .remove = s3c2412_i2s_remove, .playback = { .channels_min = 2, .channels_max = 2, @@ -170,17 +172,36 @@ struct snd_soc_dai s3c2412_i2s_dai = { }, .ops = &s3c2412_i2s_dai_ops, }; -EXPORT_SYMBOL_GPL(s3c2412_i2s_dai); + +static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) +{ + return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai); +} + +static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_dai(&pdev->dev); + return 0; +} + +static struct platform_driver s3c2412_iis_driver = { + .probe = s3c2412_iis_dev_probe, + .remove = s3c2412_iis_dev_remove, + .driver = { + .name = "s3c2412-iis", + .owner = THIS_MODULE, + }, +}; static int __init s3c2412_i2s_init(void) { - return s3c_i2sv2_register_dai(&s3c2412_i2s_dai); + return platform_driver_register(&s3c2412_iis_driver); } module_init(s3c2412_i2s_init); static void __exit s3c2412_i2s_exit(void) { - snd_soc_unregister_dai(&s3c2412_i2s_dai); + platform_driver_unregister(&s3c2412_iis_driver); } module_exit(s3c2412_i2s_exit); @@ -188,3 +209,4 @@ module_exit(s3c2412_i2s_exit); MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c2412-iis"); diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/s3c24xx/s3c2412-i2s.h index 0b5686b4d5c3..01a0471ac65c 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.h +++ b/sound/soc/s3c24xx/s3c2412-i2s.h @@ -24,6 +24,4 @@ #define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK #define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS -extern struct snd_soc_dai s3c2412_i2s_dai; - #endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */ diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index c3ac890a3986..e060daaa458f 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -252,7 +252,7 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, else dma_data = &s3c24xx_i2s_pcm_stereo_in; - snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data); + snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); /* Working copies of register */ iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); @@ -280,9 +280,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + snd_soc_dai_get_dma_data(dai, substream); pr_debug("Entered %s\n", __func__); @@ -387,8 +386,7 @@ u32 s3c24xx_i2s_get_clockrate(void) } EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); -static int s3c24xx_i2s_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) +static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) { pr_debug("Entered %s\n", __func__); @@ -396,7 +394,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev, if (s3c24xx_i2s.regs == NULL) return -ENXIO; - s3c24xx_i2s.iis_clk = clk_get(&pdev->dev, "iis"); + s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); if (s3c24xx_i2s.iis_clk == NULL) { pr_err("failed to get iis_clock\n"); iounmap(s3c24xx_i2s.regs); @@ -465,9 +463,7 @@ static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { .set_sysclk = s3c24xx_i2s_set_sysclk, }; -struct snd_soc_dai s3c24xx_i2s_dai = { - .name = "s3c24xx-i2s", - .id = 0, +static struct snd_soc_dai_driver s3c24xx_i2s_dai = { .probe = s3c24xx_i2s_probe, .suspend = s3c24xx_i2s_suspend, .resume = s3c24xx_i2s_resume, @@ -483,17 +479,36 @@ struct snd_soc_dai s3c24xx_i2s_dai = { .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &s3c24xx_i2s_dai_ops, }; -EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); + +static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev) +{ + return snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai); +} + +static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_dai(&pdev->dev); + return 0; +} + +static struct platform_driver s3c24xx_iis_driver = { + .probe = s3c24xx_iis_dev_probe, + .remove = s3c24xx_iis_dev_remove, + .driver = { + .name = "s3c24xx-iis", + .owner = THIS_MODULE, + }, +}; static int __init s3c24xx_i2s_init(void) { - return snd_soc_register_dai(&s3c24xx_i2s_dai); + return platform_driver_register(&s3c24xx_iis_driver); } module_init(s3c24xx_i2s_init); static void __exit s3c24xx_i2s_exit(void) { - snd_soc_unregister_dai(&s3c24xx_i2s_dai); + platform_driver_unregister(&s3c24xx_iis_driver); } module_exit(s3c24xx_i2s_exit); @@ -501,3 +516,4 @@ module_exit(s3c24xx_i2s_exit); MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c24xx-iis"); diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h index 726d91cf4e1c..f9ca04edacb7 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.h +++ b/sound/soc/s3c24xx/s3c24xx-i2s.h @@ -32,6 +32,4 @@ u32 s3c24xx_i2s_get_clockrate(void); -extern struct snd_soc_dai s3c24xx_i2s_dai; - #endif /*S3C24XXI2S_H_*/ diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c index 4984754f3298..c4c111442010 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec.c @@ -139,8 +139,10 @@ static const struct snd_kcontrol_new amp_unmute_controls[] = { speaker_unmute_get, speaker_unmute_put), }; -void simtec_audio_init(struct snd_soc_codec *codec) +void simtec_audio_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; + if (pdata->amp_gpio > 0) { pr_debug("%s: adding amp routes\n", __func__); @@ -170,8 +172,8 @@ 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; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret; /* Set the CODEC as the bus clock master, I2S */ @@ -319,12 +321,12 @@ EXPORT_SYMBOL_GPL(simtec_audio_pmops); #endif int __devinit simtec_audio_core_probe(struct platform_device *pdev, - struct snd_soc_device *socdev) + struct snd_soc_card *card) { struct platform_device *snd_dev; int ret; - socdev->card->dai_link->ops = &simtec_snd_ops; + card->dai_link->ops = &simtec_snd_ops; pdata = pdev->dev.platform_data; if (!pdata) { @@ -353,8 +355,7 @@ int __devinit simtec_audio_core_probe(struct platform_device *pdev, goto err_gpio; } - platform_set_drvdata(snd_dev, socdev); - socdev->dev = &snd_dev->dev; + platform_set_drvdata(snd_dev, card); ret = platform_device_add(snd_dev); if (ret) { diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/s3c24xx/s3c24xx_simtec.h index e18faee30cce..e63d5ff9c41f 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.h +++ b/sound/soc/s3c24xx/s3c24xx_simtec.h @@ -7,10 +7,10 @@ * published by the Free Software Foundation. */ -extern void simtec_audio_init(struct snd_soc_codec *codec); +extern void simtec_audio_init(struct snd_soc_pcm_runtime *rtd); extern int simtec_audio_core_probe(struct platform_device *pdev, - struct snd_soc_device *socdev); + struct snd_soc_card *card); extern int simtec_audio_remove(struct platform_device *pdev); diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c index bdf8951af8e3..f88453735ae2 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c @@ -73,8 +73,10 @@ static const struct snd_soc_dapm_route base_map[] = { * Attach our controls and configure the necessary codec * mappings for our sound card instance. */ -static int simtec_hermes_init(struct snd_soc_codec *codec) +static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; + snd_soc_dapm_new_controls(codec, dapm_widgets, ARRAY_SIZE(dapm_widgets)); @@ -85,42 +87,33 @@ static int simtec_hermes_init(struct snd_soc_codec *codec) snd_soc_dapm_enable_pin(codec, "Line Out"); snd_soc_dapm_enable_pin(codec, "Mic Jack"); - simtec_audio_init(codec); + simtec_audio_init(rtd); 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, + .codec_name = "tlv320aic3x-codec.0-0x1a", + .cpu_dai_name = "s3c24xx-i2s", + .codec_dai_name = "tlv320aic3x-hifi", + .platform_name = "s3c24xx-pcm-audio", .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); + return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic33); } static struct platform_driver simtec_audio_hermes_platdrv = { diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c index 185c0acb5ce6..c0967593510d 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c @@ -62,8 +62,10 @@ static const struct snd_soc_dapm_route base_map[] = { * Attach our controls and configure the necessary codec * mappings for our sound card instance. */ -static int simtec_tlv320aic23_init(struct snd_soc_codec *codec) +static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; + snd_soc_dapm_new_controls(codec, dapm_widgets, ARRAY_SIZE(dapm_widgets)); @@ -74,7 +76,7 @@ static int simtec_tlv320aic23_init(struct snd_soc_codec *codec) snd_soc_dapm_enable_pin(codec, "Line Out"); snd_soc_dapm_enable_pin(codec, "Mic Jack"); - simtec_audio_init(codec); + simtec_audio_init(rtd); snd_soc_dapm_sync(codec); return 0; @@ -83,28 +85,23 @@ static int simtec_tlv320aic23_init(struct snd_soc_codec *codec) static struct snd_soc_dai_link simtec_dai_aic23 = { .name = "tlv320aic23", .stream_name = "TLV320AIC23", - .cpu_dai = &s3c24xx_i2s_dai, - .codec_dai = &tlv320aic23_dai, + .codec_name = "tlv320aic3x-codec.0-0x1a", + .cpu_dai_name = "s3c24xx-i2s", + .codec_dai_name = "tlv320aic3x-hifi", + .platform_name = "s3c24xx-pcm-audio", .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); + return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23); } static struct platform_driver simtec_audio_tlv320aic23_platdrv = { diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c index 052d59659c29..bd48ffbde880 100644 --- a/sound/soc/s3c24xx/s3c24xx_uda134x.c +++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c @@ -133,8 +133,8 @@ static int s3c24xx_uda134x_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; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int clk = 0; int ret = 0; int clk_source, fs_mode; @@ -227,14 +227,15 @@ static struct snd_soc_ops s3c24xx_uda134x_ops = { static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { .name = "UDA134X", .stream_name = "UDA134X", - .codec_dai = &uda134x_dai, - .cpu_dai = &s3c24xx_i2s_dai, + .codec_name = "uda134x-hifi", + .codec_dai_name = "uda134x-hifi", + .cpu_dai_name = "s3c24xx-i2s", .ops = &s3c24xx_uda134x_ops, + .platform_name = "s3c24xx-pcm-audio", }; static struct snd_soc_card snd_soc_s3c24xx_uda134x = { .name = "S3C24XX_UDA134X", - .platform = &s3c24xx_soc_platform, .dai_link = &s3c24xx_uda134x_dai_link, .num_links = 1, }; @@ -256,6 +257,7 @@ static void setmode(int v) gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0); } +/* FIXME - This must be codec platform data but in which board file ?? */ static struct uda134x_platform_data s3c24xx_uda134x = { .l3 = { .setdat = setdat, @@ -270,12 +272,6 @@ static struct uda134x_platform_data s3c24xx_uda134x = { }, }; -static struct snd_soc_device s3c24xx_uda134x_snd_devdata = { - .card = &snd_soc_s3c24xx_uda134x, - .codec_dev = &soc_codec_dev_uda134x, - .codec_data = &s3c24xx_uda134x, -}; - static int s3c24xx_uda134x_setup_pin(int pin, char *fun) { if (gpio_request(pin, "s3c24xx_uda134x") < 0) { @@ -325,8 +321,7 @@ static int s3c24xx_uda134x_probe(struct platform_device *pdev) } platform_set_drvdata(s3c24xx_uda134x_snd_device, - &s3c24xx_uda134x_snd_devdata); - s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev; + &snd_soc_s3c24xx_uda134x); ret = platform_device_add(s3c24xx_uda134x_snd_device); if (ret) { printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c index 06db130030a1..a13415a85a45 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c @@ -16,9 +16,7 @@ #include <sound/soc.h> #include <sound/pcm_params.h> -#include <mach/gpio-bank-c.h> -#include <mach/gpio-bank-h.h> -#include <plat/gpio-cfg.h> +#include <plat/audio.h> #include <mach/map.h> #include <mach/dma.h> @@ -39,34 +37,23 @@ static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out; static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in; static struct s3c_i2sv2_info s3c64xx_i2sv4; -struct snd_soc_dai s3c64xx_i2s_v4_dai; -EXPORT_SYMBOL_GPL(s3c64xx_i2s_v4_dai); - -static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) +static int s3c64xx_i2sv4_probe(struct snd_soc_dai *dai) { - return cpu_dai->private_data; -} + struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4; + int ret = 0; -static int s3c64xx_i2sv4_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ - /* configure GPIO for i2s port */ - s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0); - s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1); - s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2); - s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK); - s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK); - s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK); - s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI); + snd_soc_dai_set_drvdata(dai, i2s); - return 0; + ret = s3c_i2sv2_probe(dai, i2s, i2s->base); + + return ret; } static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *cpu_dai) { - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); + struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); struct s3c_dma_params *dma_data; u32 iismod; @@ -104,51 +91,79 @@ static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = { .hw_params = s3c_i2sv4_hw_params, }; +static struct snd_soc_dai_driver s3c64xx_i2s_v4_dai = { + .symmetric_rates = 1, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS, + }, + .probe = s3c64xx_i2sv4_probe, + .ops = &s3c64xx_i2sv4_dai_ops, +}; + static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev) { + struct s3c_audio_pdata *i2s_pdata; struct s3c_i2sv2_info *i2s; - struct snd_soc_dai *dai; + struct resource *res; int ret; i2s = &s3c64xx_i2sv4; - dai = &s3c64xx_i2s_v4_dai; - - if (dai->dev) { - dev_dbg(dai->dev, "%s: \ - I2Sv4 instance already registered!\n", __func__); - return -EBUSY; - } - - dai->dev = &pdev->dev; - dai->name = "s3c64xx-i2s-v4"; - dai->id = 0; - dai->symmetric_rates = 1; - dai->playback.channels_min = 2; - dai->playback.channels_max = 2; - dai->playback.rates = S3C64XX_I2S_RATES; - dai->playback.formats = S3C64XX_I2S_FMTS; - dai->capture.channels_min = 2; - dai->capture.channels_max = 2; - dai->capture.rates = S3C64XX_I2S_RATES; - dai->capture.formats = S3C64XX_I2S_FMTS; - dai->probe = s3c64xx_i2sv4_probe; - dai->ops = &s3c64xx_i2sv4_dai_ops; i2s->feature |= S3C_FEATURE_CDCLKCON; i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in; i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out; - i2s->dma_capture->channel = DMACH_HSI_I2SV40_RX; - i2s->dma_capture->dma_addr = S3C64XX_PA_IISV4 + S3C2412_IISRXD; - i2s->dma_playback->channel = DMACH_HSI_I2SV40_TX; - i2s->dma_playback->dma_addr = S3C64XX_PA_IISV4 + S3C2412_IISTXD; + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); + return -ENXIO; + } + i2s->dma_playback->channel = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); + return -ENXIO; + } + i2s->dma_capture->channel = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); + return -ENXIO; + } + + if (!request_mem_region(res->start, resource_size(res), + "s3c64xx-i2s-v4")) { + dev_err(&pdev->dev, "Unable to request SFR region\n"); + return -EBUSY; + } + i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD; + i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD; i2s->dma_capture->client = &s3c64xx_dma_client_in; i2s->dma_capture->dma_size = 4; i2s->dma_playback->client = &s3c64xx_dma_client_out; i2s->dma_playback->dma_size = 4; + i2s->base = res->start; + + i2s_pdata = pdev->dev.platform_data; + if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + return -EINVAL; + } + i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); if (IS_ERR(i2s->iis_cclk)) { dev_err(&pdev->dev, "failed to get audio-bus\n"); @@ -158,19 +173,13 @@ static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev) clk_enable(i2s->iis_cclk); - ret = s3c_i2sv2_probe(pdev, dai, i2s, 0); - if (ret) - goto err_clk; - - ret = s3c_i2sv2_register_dai(dai); + ret = s3c_i2sv2_register_dai(&pdev->dev, pdev->id, &s3c64xx_i2s_v4_dai); if (ret != 0) goto err_i2sv2; return 0; err_i2sv2: - /* Not implemented for I2Sv2 core yet */ -err_clk: clk_put(i2s->iis_cclk); err: return ret; @@ -178,7 +187,7 @@ err: static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev) { - dev_err(&pdev->dev, "Device removal not yet supported\n"); + snd_soc_unregister_dai(&pdev->dev); return 0; } @@ -207,3 +216,4 @@ module_exit(s3c64xx_i2sv4_exit); MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c64xx-iis-v4"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 1d85cb85a7d2..ae7acb6c4f1d 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -12,15 +12,15 @@ * published by the Free Software Foundation. */ +#include <linux/module.h> #include <linux/clk.h> #include <linux/gpio.h> #include <linux/io.h> +#include <linux/slab.h> #include <sound/soc.h> -#include <mach/gpio-bank-d.h> -#include <mach/gpio-bank-e.h> -#include <plat/gpio-cfg.h> +#include <plat/audio.h> #include <mach/map.h> #include <mach/dma.h> @@ -46,45 +46,107 @@ static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3]; static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3]; static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3]; -struct snd_soc_dai s3c64xx_i2s_dai[MAX_I2SV3]; -EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); - -static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) +struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) { - return cpu_dai->private_data; + struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai); + u32 iismod = readl(i2s->regs + S3C2412_IISMOD); + + if (iismod & S3C2412_IISMOD_IMS_SYSMUX) + return i2s->iis_cclk; + else + return i2s->iis_pclk; } +EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); -static int s3c64xx_i2s_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) +static int s3c64xx_i2s_probe(struct snd_soc_dai *dai) { - /* configure GPIO for i2s port */ - switch (dai->id) { - case 0: - s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); - s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); - s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK); - s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI); - s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0); - break; - case 1: - s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK); - s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK); - s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK); - s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI); - s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0); + struct s3c_i2sv2_info *i2s; + int ret; + + if (dai->id >= MAX_I2SV3) { + dev_err(dai->dev, "id %d out of range\n", dai->id); + return -EINVAL; + } + + i2s = &s3c64xx_i2s[dai->id]; + snd_soc_dai_set_drvdata(dai, i2s); + + i2s->iis_cclk = clk_get(dai->dev, "audio-bus"); + if (IS_ERR(i2s->iis_cclk)) { + dev_err(dai->dev, "failed to get audio-bus\n"); + ret = PTR_ERR(i2s->iis_cclk); + goto err; } + clk_enable(i2s->iis_cclk); + + ret = s3c_i2sv2_probe(dai, i2s, i2s->base); + if (ret) + goto err_clk; + return 0; + +err_clk: + clk_disable(i2s->iis_cclk); + clk_put(i2s->iis_cclk); +err: + kfree(i2s); + return ret; } +static int s3c64xx_i2s_remove(struct snd_soc_dai *dai) +{ + struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai); + + clk_disable(i2s->iis_cclk); + clk_put(i2s->iis_cclk); + kfree(i2s); + return 0; +} static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops; +static struct snd_soc_dai_driver s3c64xx_i2s_dai[MAX_I2SV3] = { +{ + .name = "s3c64xx-i2s-0", + .probe = s3c64xx_i2s_probe, + .remove = s3c64xx_i2s_remove, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS,}, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS,}, + .ops = &s3c64xx_i2s_dai_ops, + .symmetric_rates = 1, +}, { + .name = "s3c64xx-i2s-1", + .probe = s3c64xx_i2s_probe, + .remove = s3c64xx_i2s_remove, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS,}, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS,}, + .ops = &s3c64xx_i2s_dai_ops, + .symmetric_rates = 1, +},}; + static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) { + struct s3c_audio_pdata *i2s_pdata; struct s3c_i2sv2_info *i2s; - struct snd_soc_dai *dai; - int ret; + struct resource *res; + int i, ret; if (pdev->id >= MAX_I2SV3) { dev_err(&pdev->dev, "id %d out of range\n", pdev->id); @@ -92,74 +154,63 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) } i2s = &s3c64xx_i2s[pdev->id]; - dai = &s3c64xx_i2s_dai[pdev->id]; - dai->dev = &pdev->dev; - dai->name = "s3c64xx-i2s"; - dai->id = pdev->id; - dai->symmetric_rates = 1; - dai->playback.channels_min = 2; - dai->playback.channels_max = 2; - dai->playback.rates = S3C64XX_I2S_RATES; - dai->playback.formats = S3C64XX_I2S_FMTS; - dai->capture.channels_min = 2; - dai->capture.channels_max = 2; - dai->capture.rates = S3C64XX_I2S_RATES; - dai->capture.formats = S3C64XX_I2S_FMTS; - dai->probe = s3c64xx_i2s_probe; - dai->ops = &s3c64xx_i2s_dai_ops; - - i2s->feature |= S3C_FEATURE_CDCLKCON; i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; - if (pdev->id == 0) { - i2s->dma_capture->channel = DMACH_I2S0_IN; - i2s->dma_capture->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD; - i2s->dma_playback->channel = DMACH_I2S0_OUT; - i2s->dma_playback->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD; - } else { - i2s->dma_capture->channel = DMACH_I2S1_IN; - i2s->dma_capture->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD; - i2s->dma_playback->channel = DMACH_I2S1_OUT; - i2s->dma_playback->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD; + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); + return -ENXIO; + } + i2s->dma_playback->channel = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); + return -ENXIO; + } + i2s->dma_capture->channel = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); + return -ENXIO; } + if (!request_mem_region(res->start, resource_size(res), + "s3c64xx-i2s")) { + dev_err(&pdev->dev, "Unable to request SFR region\n"); + return -EBUSY; + } + i2s->base = res->start; + + i2s_pdata = pdev->dev.platform_data; + if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + return -EINVAL; + } + i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD; + i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD; + i2s->dma_capture->client = &s3c64xx_dma_client_in; i2s->dma_capture->dma_size = 4; i2s->dma_playback->client = &s3c64xx_dma_client_out; i2s->dma_playback->dma_size = 4; - i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); - if (IS_ERR(i2s->iis_cclk)) { - dev_err(&pdev->dev, "failed to get audio-bus\n"); - ret = PTR_ERR(i2s->iis_cclk); - goto err; + for (i = 0; i < ARRAY_SIZE(s3c64xx_i2s_dai); i++) { + ret = s3c_i2sv2_register_dai(&pdev->dev, i, + &s3c64xx_i2s_dai[i]); + if (ret != 0) + return ret; } - clk_enable(i2s->iis_cclk); - - ret = s3c_i2sv2_probe(pdev, dai, i2s, 0); - if (ret) - goto err_clk; - - ret = s3c_i2sv2_register_dai(dai); - if (ret != 0) - goto err_i2sv2; - return 0; - -err_i2sv2: - /* Not implemented for I2Sv2 core yet */ -err_clk: - clk_put(i2s->iis_cclk); -err: - return ret; } static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev) { - dev_err(&pdev->dev, "Device removal not yet supported\n"); + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c64xx_i2s_dai)); return 0; } @@ -188,3 +239,4 @@ module_exit(s3c64xx_i2s_exit); MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c64xx-iis"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h index 7a40f43d1d51..19bd444bf8a6 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.h +++ b/sound/soc/s3c24xx/s3c64xx-i2s.h @@ -36,7 +36,5 @@ struct clk; (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE) -extern struct snd_soc_dai s3c64xx_i2s_dai[]; -extern struct snd_soc_dai s3c64xx_i2s_v4_dai; #endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c index b480348140b0..dd20ca7f4681 100644 --- a/sound/soc/s3c24xx/smartq_wm8987.c +++ b/sound/soc/s3c24xx/smartq_wm8987.c @@ -211,8 +211,10 @@ static struct snd_soc_dai_link smartq_dai[] = { { .name = "wm8987", .stream_name = "SmartQ Hi-Fi", - .cpu_dai = &s3c64xx_i2s_dai[0], - .codec_dai = &wm8750_dai, + .cpu_dai_name = "s3c64xx-i2s.0", + .codec_dai_name = "wm8750-hifi", + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8750-codec.0-0x1a", .init = smartq_wm8987_init, .ops = &smartq_hifi_ops, }, @@ -220,16 +222,10 @@ static struct snd_soc_dai_link smartq_dai[] = { static struct snd_soc_card snd_soc_smartq = { .name = "SmartQ", - .platform = &s3c24xx_soc_platform, .dai_link = smartq_dai, .num_links = ARRAY_SIZE(smartq_dai), }; -static struct snd_soc_device smartq_snd_devdata = { - .card = &snd_soc_smartq, - .codec_dev = &soc_codec_dev_wm8750, -}; - static struct platform_device *smartq_snd_device; static int __init smartq_init(void) @@ -245,8 +241,7 @@ static int __init smartq_init(void) if (!smartq_snd_device) return -ENOMEM; - platform_set_drvdata(smartq_snd_device, &smartq_snd_devdata); - smartq_snd_devdata.dev = &smartq_snd_device->dev; + platform_set_drvdata(smartq_snd_device, &snd_soc_smartq); ret = platform_device_add(smartq_snd_device); if (ret) { diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c index 362258835e8d..66f9e222220b 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c @@ -19,7 +19,6 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> -#include "../codecs/ac97.h" #include "s3c-dma.h" #include "s3c-ac97.h" @@ -29,23 +28,19 @@ static struct snd_soc_dai_link smdk2443_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM], - .codec_dai = &ac97_dai, + .cpu_dai_name = "s3c-ac97-dai", + .codec_dai_name = "ac97-hifi", + .codec_name = "ac97-codec", + .platform_name = "s3c24xx-pcm-audio", }, }; static struct snd_soc_card smdk2443 = { .name = "SMDK2443", - .platform = &s3c24xx_soc_platform, .dai_link = smdk2443_dai, .num_links = ARRAY_SIZE(smdk2443_dai), }; -static struct snd_soc_device smdk2443_snd_ac97_devdata = { - .card = &smdk2443, - .codec_dev = &soc_codec_dev_ac97, -}; - static struct platform_device *smdk2443_snd_ac97_device; static int __init smdk2443_init(void) @@ -56,9 +51,7 @@ static int __init smdk2443_init(void) if (!smdk2443_snd_ac97_device) return -ENOMEM; - platform_set_drvdata(smdk2443_snd_ac97_device, - &smdk2443_snd_ac97_devdata); - smdk2443_snd_ac97_devdata.dev = &smdk2443_snd_ac97_device->dev; + platform_set_drvdata(smdk2443_snd_ac97_device, &smdk2443); ret = platform_device_add(smdk2443_snd_ac97_device); if (ret) diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c index 4926acaaa8b0..5c21e26da075 100644 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c @@ -35,8 +35,8 @@ static int smdk64xx_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 *cpu_dai = rtd->dai->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; unsigned int pll_out; int bfs, rfs, ret; @@ -180,8 +180,10 @@ static const struct snd_soc_dapm_route audio_map_rx[] = { {"Rear", NULL, "VOUT3R"}, }; -static int smdk64xx_wm8580_init_paiftx(struct snd_soc_codec *codec) +static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; + /* Add smdk64xx specific Capture widgets */ snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt, ARRAY_SIZE(wm8580_dapm_widgets_cpt)); @@ -200,8 +202,10 @@ static int smdk64xx_wm8580_init_paiftx(struct snd_soc_codec *codec) return 0; } -static int smdk64xx_wm8580_init_paifrx(struct snd_soc_codec *codec) +static int smdk64xx_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; + /* Add smdk64xx specific Playback widgets */ snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk, ARRAY_SIZE(wm8580_dapm_widgets_pbk)); @@ -219,16 +223,20 @@ static struct snd_soc_dai_link smdk64xx_dai[] = { { /* Primary Playback i/f */ .name = "WM8580 PAIF RX", .stream_name = "Playback", - .cpu_dai = &s3c64xx_i2s_v4_dai, - .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX], + .cpu_dai_name = "s3c64xx-iis-v4", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8580-codec.0-001b", .init = smdk64xx_wm8580_init_paifrx, .ops = &smdk64xx_ops, }, { /* Primary Capture i/f */ .name = "WM8580 PAIF TX", .stream_name = "Capture", - .cpu_dai = &s3c64xx_i2s_v4_dai, - .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX], + .cpu_dai_name = "s3c64xx-iis-v4", + .codec_dai_name = "wm8580-hifi-capture", + .platform_name = "s3c24xx-pcm-audio", + .codec_name = "wm8580-codec.0-001b", .init = smdk64xx_wm8580_init_paiftx, .ops = &smdk64xx_ops, }, @@ -236,16 +244,10 @@ static struct snd_soc_dai_link smdk64xx_dai[] = { static struct snd_soc_card smdk64xx = { .name = "smdk64xx", - .platform = &s3c24xx_soc_platform, .dai_link = smdk64xx_dai, .num_links = ARRAY_SIZE(smdk64xx_dai), }; -static struct snd_soc_device smdk64xx_snd_devdata = { - .card = &smdk64xx, - .codec_dev = &soc_codec_dev_wm8580, -}; - static struct platform_device *smdk64xx_snd_device; static int __init smdk64xx_audio_init(void) @@ -256,8 +258,7 @@ static int __init smdk64xx_audio_init(void) if (!smdk64xx_snd_device) return -ENOMEM; - platform_set_drvdata(smdk64xx_snd_device, &smdk64xx_snd_devdata); - smdk64xx_snd_devdata.dev = &smdk64xx_snd_device->dev; + platform_set_drvdata(smdk64xx_snd_device, &smdk64xx); ret = platform_device_add(smdk64xx_snd_device); if (ret) diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c index 5527b9e88c98..90108a7a0a8e 100644 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ b/sound/soc/s3c24xx/smdk_wm9713.c @@ -46,40 +46,50 @@ static struct snd_soc_card smdk; static struct snd_soc_dai_link smdk_dai = { .name = "AC97", .stream_name = "AC97 PCM", - .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM], - .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI], + .platform_name = "s3c24xx-pcm-audio", + .cpu_dai_name = "s3c-ac97-dai", + .codec_dai_name = "wm9713-hifi", + .codec_name = "wm9713-codec", }; static struct snd_soc_card smdk = { .name = "SMDK", - .platform = &s3c24xx_soc_platform, .dai_link = &smdk_dai, .num_links = 1, }; -static struct snd_soc_device smdk_snd_ac97_devdata = { - .card = &smdk, - .codec_dev = &soc_codec_dev_wm9713, -}; - +static struct platform_device *smdk_snd_wm9713_device; static struct platform_device *smdk_snd_ac97_device; static int __init smdk_init(void) { int ret; - smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1); - if (!smdk_snd_ac97_device) + smdk_snd_wm9713_device = platform_device_alloc("wm9713-codec", -1); + if (!smdk_snd_wm9713_device) return -ENOMEM; - platform_set_drvdata(smdk_snd_ac97_device, - &smdk_snd_ac97_devdata); - smdk_snd_ac97_devdata.dev = &smdk_snd_ac97_device->dev; + ret = platform_device_add(smdk_snd_wm9713_device); + if (ret) + goto err; + + smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1); + if (!smdk_snd_ac97_device) { + ret = -ENOMEM; + goto err; + } + + platform_set_drvdata(smdk_snd_ac97_device, &smdk); ret = platform_device_add(smdk_snd_ac97_device); - if (ret) + if (ret) { platform_device_put(smdk_snd_ac97_device); + goto err; + } + return 0; +err: + platform_device_put(smdk_snd_wm9713_device); return ret; } |