From 168db50d967e09133feda8247d4dcb3c73437766 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Wed, 9 Dec 2009 13:29:20 +0900 Subject: ASoC: S3C64XX: Remove unnecessary header includes Removed redundant header includes which make no difference to compilation. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c64xx-i2s.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index cc7edb5f792..8feb029b99f 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -15,16 +15,10 @@ #include #include #include -#include #include -#include #include #include -#include -#include -#include -#include #include #include -- cgit v1.2.3 From 0fe692292a26f57b6522fe859cc8b2549ec0cd97 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Wed, 9 Dec 2009 13:29:25 +0900 Subject: ASoC: S3C64XX: Compress and generalize the CPU driver The driver can be 'generalized' a bit by not hardcoding '2'(the number of I2Sv3 controllers that the driver can handle) at many places, instead we define a macro for it. That makes it easier to increase number of controllers by changing the parameter at just one place, this will be useful when there is support for newer SoCs, which have the same controller, only more in number. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c64xx-i2s.c | 114 +++++++++++++++------------------------- 1 file changed, 41 insertions(+), 73 deletions(-) (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 8feb029b99f..93ed3aad163 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -32,6 +32,11 @@ #include "s3c-dma.h" #include "s3c64xx-i2s.h" +/* The value should be set to maximum of the total number + * of I2Sv3 controllers that any supported SoC has. + */ +#define MAX_I2SV3 2 + static struct s3c2410_dma_client s3c64xx_dma_client_out = { .name = "I2S PCM Stereo out" }; @@ -40,37 +45,12 @@ static struct s3c2410_dma_client s3c64xx_dma_client_in = { .name = "I2S PCM Stereo in" }; -static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[2] = { - [0] = { - .channel = DMACH_I2S0_OUT, - .client = &s3c64xx_dma_client_out, - .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD, - .dma_size = 4, - }, - [1] = { - .channel = DMACH_I2S1_OUT, - .client = &s3c64xx_dma_client_out, - .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD, - .dma_size = 4, - }, -}; - -static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[2] = { - [0] = { - .channel = DMACH_I2S0_IN, - .client = &s3c64xx_dma_client_in, - .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD, - .dma_size = 4, - }, - [1] = { - .channel = DMACH_I2S1_IN, - .client = &s3c64xx_dma_client_in, - .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD, - .dma_size = 4, - }, -}; +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]; -static struct s3c_i2sv2_info s3c64xx_i2s[2]; +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) { @@ -163,55 +143,13 @@ static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { .set_sysclk = s3c64xx_i2s_set_sysclk, }; -struct snd_soc_dai s3c64xx_i2s_dai[] = { - { - .name = "s3c64xx-i2s", - .id = 0, - .probe = s3c64xx_i2s_probe, - .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", - .id = 1, - .probe = s3c64xx_i2s_probe, - .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, - }, -}; -EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); - static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) { struct s3c_i2sv2_info *i2s; struct snd_soc_dai *dai; int ret; - if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) { + if (pdev->id >= MAX_I2SV3) { dev_err(&pdev->dev, "id %d out of range\n", pdev->id); return -EINVAL; } @@ -219,10 +157,40 @@ 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->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; + } + + 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"); -- cgit v1.2.3 From fc93ea2f9315eda2ec8645c2f8bcc30f75a6b88e Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Wed, 27 Jan 2010 14:59:08 +0900 Subject: ASoC: AC97: S3C: Add controller driver Add the AC97 controller driver for Samsung SoCs that have one. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 6 +- sound/soc/s3c24xx/Makefile | 3 +- sound/soc/s3c24xx/s3c-ac97.c | 518 +++++++++++++++++++++++++++++++++++++++++++ sound/soc/s3c24xx/s3c-ac97.h | 23 ++ 4 files changed, 548 insertions(+), 2 deletions(-) create mode 100644 sound/soc/s3c24xx/s3c-ac97.c create mode 100644 sound/soc/s3c24xx/s3c-ac97.h (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index b489f1ae103..ad3690ec3de 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -32,7 +32,11 @@ config SND_S3C2443_SOC_AC97 select S3C2410_DMA select AC97_BUS select SND_SOC_AC97_BUS - + +config SND_S3C_SOC_AC97 + tristate + select SND_SOC_AC97_BUS + config SND_S3C24XX_SOC_NEO1973_WM8753 tristate "SoC I2S Audio support for NEO1973 - WM8753" depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index b744657733d..b7411bd59f3 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -4,12 +4,14 @@ snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o +snd-soc-s3c-ac97-objs := s3c-ac97.o snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o snd-soc-s3c-pcm-objs := s3c-pcm.o obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o +obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o @@ -37,4 +39,3 @@ 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 obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o - diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c new file mode 100644 index 00000000000..ee8ed9d7e70 --- /dev/null +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -0,0 +1,518 @@ +/* sound/soc/s3c24xx/s3c-ac97.c + * + * ALSA SoC Audio Layer - S3C AC97 Controller driver + * Evolved from s3c2443-ac97.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * Credits: Graeme Gregory, Sean Choi + * + * 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 +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "s3c-dma.h" +#include "s3c-ac97.h" + +#define AC_CMD_ADDR(x) (x << 16) +#define AC_CMD_DATA(x) (x & 0xffff) + +struct s3c_ac97_info { + unsigned state; + struct clk *ac97_clk; + void __iomem *regs; + struct mutex lock; + struct completion done; +}; +static struct s3c_ac97_info s3c_ac97; + +static struct s3c2410_dma_client s3c_dma_client_out = { + .name = "AC97 PCMOut" +}; + +static struct s3c2410_dma_client s3c_dma_client_in = { + .name = "AC97 PCMIn" +}; + +static struct s3c2410_dma_client s3c_dma_client_micin = { + .name = "AC97 MicIn" +}; + +static struct s3c_dma_params s3c_ac97_pcm_out = { + .client = &s3c_dma_client_out, + .dma_size = 4, +}; + +static struct s3c_dma_params s3c_ac97_pcm_in = { + .client = &s3c_dma_client_in, + .dma_size = 4, +}; + +static struct s3c_dma_params s3c_ac97_mic_in = { + .client = &s3c_dma_client_micin, + .dma_size = 4, +}; + +static void s3c_ac97_activate(struct snd_ac97 *ac97) +{ + u32 ac_glbctrl, stat; + + stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; + if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) + return; /* Return if already active */ + + INIT_COMPLETION(s3c_ac97.done); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + printk(KERN_ERR "AC97: Unable to activate!"); +} + +static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, + unsigned short reg) +{ + u32 ac_glbctrl, ac_codec_cmd; + u32 stat, addr, data; + + mutex_lock(&s3c_ac97.lock); + + s3c_ac97_activate(ac97); + + INIT_COMPLETION(s3c_ac97.done); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + udelay(50); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + printk(KERN_ERR "AC97: Unable to read!"); + + stat = readl(s3c_ac97.regs + S3C_AC97_STAT); + addr = (stat >> 16) & 0x7f; + data = (stat & 0xffff); + + if (addr != reg) + printk(KERN_ERR "s3c-ac97: req addr = %02x, rep addr = %02x\n", reg, addr); + + mutex_unlock(&s3c_ac97.lock); + + return (unsigned short)data; +} + +static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, + unsigned short val) +{ + u32 ac_glbctrl, ac_codec_cmd; + + mutex_lock(&s3c_ac97.lock); + + s3c_ac97_activate(ac97); + + INIT_COMPLETION(s3c_ac97.done); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + udelay(50); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + printk(KERN_ERR "AC97: Unable to write!"); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + mutex_unlock(&s3c_ac97.lock); +} + +static void s3c_ac97_cold_reset(struct snd_ac97 *ac97) +{ + writel(S3C_AC97_GLBCTRL_COLDRESET, + s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); +} + +static void s3c_ac97_warm_reset(struct snd_ac97 *ac97) +{ + u32 stat; + + stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; + if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) + return; /* Return if already active */ + + writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + s3c_ac97_activate(ac97); +} + +static irqreturn_t s3c_ac97_irq(int irq, void *dev_id) +{ + u32 ac_glbctrl, ac_glbstat; + + ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT); + + if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) { + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + complete(&s3c_ac97.done); + } + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= (1<<30); /* Clear interrupt */ + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + return IRQ_HANDLED; +} + +struct snd_ac97_bus_ops soc_ac97_ops = { + .read = s3c_ac97_read, + .write = s3c_ac97_write, + .warm_reset = s3c_ac97_warm_reset, + .reset = s3c_ac97_cold_reset, +}; +EXPORT_SYMBOL_GPL(soc_ac97_ops); + +static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + cpu_dai->dma_data = &s3c_ac97_pcm_out; + else + cpu_dai->dma_data = &s3c_ac97_pcm_in; + + return 0; +} + +static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + u32 ac_glbctrl; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int channel = ((struct s3c_dma_params *) + rtd->dai->cpu_dai->dma_data)->channel; + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; + else + ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; + else + ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + } + + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); + + return 0; +} + +static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + return -ENODEV; + else + cpu_dai->dma_data = &s3c_ac97_mic_in; + + return 0; +} + +static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + u32 ac_glbctrl; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int channel = ((struct s3c_dma_params *) + rtd->dai->cpu_dai->dma_data)->channel; + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA; + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + } + + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); + + return 0; +} + +static struct snd_soc_dai_ops s3c_ac97_dai_ops = { + .hw_params = s3c_ac97_hw_params, + .trigger = s3c_ac97_trigger, +}; + +static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { + .hw_params = s3c_ac97_hw_mic_params, + .trigger = s3c_ac97_mic_trigger, +}; + +struct snd_soc_dai s3c_ac97_dai[] = { + [S3C_AC97_DAI_PCM] = { + .name = "s3c-ac97", + .id = S3C_AC97_DAI_PCM, + .ac97_control = 1, + .playback = { + .stream_name = "AC97 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .stream_name = "AC97 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &s3c_ac97_dai_ops, + }, + [S3C_AC97_DAI_MIC] = { + .name = "s3c-ac97-mic", + .id = S3C_AC97_DAI_MIC, + .ac97_control = 1, + .capture = { + .stream_name = "AC97 Mic Capture", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &s3c_ac97_mic_dai_ops, + }, +}; +EXPORT_SYMBOL_GPL(s3c_ac97_dai); + +static __devinit int s3c_ac97_probe(struct platform_device *pdev) +{ + struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; + struct s3c_audio_pdata *ac97_pdata; + int ret; + + ac97_pdata = pdev->dev.platform_data; + if (!ac97_pdata || !ac97_pdata->cfg_gpio) { + dev_err(&pdev->dev, "cfg_gpio callback not provided!\n"); + return -EINVAL; + } + + /* Check for availability of necessary resource */ + dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dmatx_res) { + dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n"); + return -ENXIO; + } + + dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!dmarx_res) { + dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n"); + return -ENXIO; + } + + dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2); + if (!dmamic_res) { + dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n"); + return -ENXIO; + } + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem_res) { + dev_err(&pdev->dev, "Unable to get register resource\n"); + return -ENXIO; + } + + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq_res) { + dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); + return -ENXIO; + } + + if (!request_mem_region(mem_res->start, + resource_size(mem_res), "s3c-ac97")) { + dev_err(&pdev->dev, "Unable to request register region\n"); + return -EBUSY; + } + + s3c_ac97_pcm_out.channel = dmatx_res->start; + s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; + s3c_ac97_pcm_in.channel = dmarx_res->start; + s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; + s3c_ac97_mic_in.channel = dmamic_res->start; + s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; + + init_completion(&s3c_ac97.done); + mutex_init(&s3c_ac97.lock); + + s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); + if (s3c_ac97.regs == NULL) { + dev_err(&pdev->dev, "Unable to ioremap register region\n"); + ret = -ENXIO; + goto err1; + } + + s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); + if (IS_ERR(s3c_ac97.ac97_clk)) { + dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n"); + ret = -ENODEV; + goto err2; + } + clk_enable(s3c_ac97.ac97_clk); + + if (ac97_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + ret = -EINVAL; + goto err3; + } + + ret = request_irq(irq_res->start, s3c_ac97_irq, + IRQF_DISABLED, "AC97", NULL); + if (ret < 0) { + printk(KERN_ERR "s3c-ac97: interrupt request failed.\n"); + 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)); + if (ret) + goto err5; + + return 0; + +err5: + free_irq(irq_res->start, NULL); +err4: +err3: + clk_disable(s3c_ac97.ac97_clk); + clk_put(s3c_ac97.ac97_clk); +err2: + iounmap(s3c_ac97.regs); +err1: + release_mem_region(mem_res->start, resource_size(mem_res)); + + return ret; +} + +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)); + + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (irq_res) + free_irq(irq_res->start, NULL); + + clk_disable(s3c_ac97.ac97_clk); + clk_put(s3c_ac97.ac97_clk); + + iounmap(s3c_ac97.regs); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (mem_res) + release_mem_region(mem_res->start, resource_size(mem_res)); + + return 0; +} + +static struct platform_driver s3c_ac97_driver = { + .probe = s3c_ac97_probe, + .remove = s3c_ac97_remove, + .driver = { + .name = "s3c-ac97", + .owner = THIS_MODULE, + }, +}; + +static int __init s3c_ac97_init(void) +{ + return platform_driver_register(&s3c_ac97_driver); +} +module_init(s3c_ac97_init); + +static void __exit s3c_ac97_exit(void) +{ + platform_driver_unregister(&s3c_ac97_driver); +} +module_exit(s3c_ac97_exit); + +MODULE_AUTHOR("Jaswinder Singh, "); +MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/s3c24xx/s3c-ac97.h new file mode 100644 index 00000000000..278198379de --- /dev/null +++ b/sound/soc/s3c24xx/s3c-ac97.h @@ -0,0 +1,23 @@ +/* sound/soc/s3c24xx/s3c-ac97.h + * + * ALSA SoC Audio Layer - S3C AC97 Controller driver + * Evolved from s3c2443-ac97.h + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * Credits: Graeme Gregory, Sean Choi + * + * 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. + */ + +#ifndef __S3C_AC97_H_ +#define __S3C_AC97_H_ + +#define S3C_AC97_DAI_PCM 0 +#define S3C_AC97_DAI_MIC 1 + +extern struct snd_soc_dai s3c_ac97_dai[]; + +#endif /* __S3C_AC97_H_ */ -- cgit v1.2.3 From ff6e64dabf66b8e4e7def21857320085fc68db6b Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Wed, 27 Jan 2010 14:59:19 +0900 Subject: ASoC: AC97: SMDK: Add wm9713 machine driver This patch adds the common machine driver for SMDKs that have a WM9713 codec attched to the AC97 controller. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 8 ++++ sound/soc/s3c24xx/Makefile | 2 + sound/soc/s3c24xx/smdk_wm9713.c | 97 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 sound/soc/s3c24xx/smdk_wm9713.c (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index ad3690ec3de..d1c6f939246 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -115,3 +115,11 @@ config SND_S3C24XX_SOC_SIMTEC_HERMES select SND_S3C24XX_SOC_I2S select SND_SOC_TLV320AIC3X select SND_S3C24XX_SOC_SIMTEC + +config SND_SOC_SMDK_WM9713 + tristate "SoC AC97 Audio support for SMDK with WM9713" + depends on SND_S3C24XX_SOC && MACH_SMDK6410 + select SND_SOC_WM9713 + select SND_S3C_SOC_AC97 + help + Sat Y if you want to add support for SoC audio on the SMDK. diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index b7411bd59f3..1117678ae4e 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -28,6 +28,7 @@ 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 snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o +snd-soc-smdk-wm9713-objs := smdk_wm9713.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 @@ -39,3 +40,4 @@ 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 obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o +obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c new file mode 100644 index 00000000000..7dd933f7cbf --- /dev/null +++ b/sound/soc/s3c24xx/smdk_wm9713.c @@ -0,0 +1,97 @@ +/* + * smdk_wm9713.c -- SoC audio for SMDK + * + * Copyright 2010 Samsung Electronics Co. Ltd. + * Author: Jaswinder Singh Brar + * + * 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 +#include +#include + +#include "../codecs/wm9713.h" +#include "s3c-dma.h" +#include "s3c-ac97.h" + +static struct snd_soc_card smdk; + +/* + Playback (HeadPhone):- + Headphone Playback Switch - On + $ amixer cset numid=4 1 + + Right Headphone Out Mux - Headphone + $ amixer cset numid=92 2 + Left Headphone Out Mux - Headphone + $ amixer cset numid=93 2 + + Right HP Mixer PCM Playback Switch - On + $ amixer cset numid=75 1 + Left HP Mixer PCM Playback Switch - On + $ amixer cset numid=81 1 + + Capture (LineIn):- + Right Capture Source - Line + $ amixer cset numid=86 2 + Left Capture Source - Line + $ amixer cset numid=87 2 +*/ + +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], +}; + +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_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) + 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_ac97_device); + if (ret) + platform_device_put(smdk_snd_ac97_device); + + return ret; +} + +static void __exit smdk_exit(void) +{ + platform_device_unregister(smdk_snd_ac97_device); +} + +module_init(smdk_init); +module_exit(smdk_exit); + +/* Module information */ +MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com"); +MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 1ec2963a8cd5fbc5f49dfa20c94229f1b46d1968 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Wed, 27 Jan 2010 15:01:03 +0900 Subject: ASoC: AC97: SMDK2443: Switch to s3c-ac97.c Switch to use s3c-ac97.c AC97 controller driver. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 4 +++- sound/soc/s3c24xx/smdk2443_wm9710.c | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index d1c6f939246..8b62798a04b 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -75,8 +75,10 @@ config SND_S3C64XX_SOC_WM8580 config SND_S3C24XX_SOC_SMDK2443_WM9710 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" depends on SND_S3C24XX_SOC && MACH_SMDK2443 - select SND_S3C2443_SOC_AC97 + select S3C2410_DMA + select AC97_BUS select SND_SOC_AC97_CODEC + select SND_S3C_SOC_AC97 help Say Y if you want to add support for SoC audio on smdk2443 with the WM9710. diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c index 12b783b12fc..362258835e8 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c @@ -21,7 +21,7 @@ #include "../codecs/ac97.h" #include "s3c-dma.h" -#include "s3c24xx-ac97.h" +#include "s3c-ac97.h" static struct snd_soc_card smdk2443; @@ -29,7 +29,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai = &s3c2443_ac97_dai[0], + .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM], .codec_dai = &ac97_dai, }, }; -- cgit v1.2.3 From c67d90ffd43a6cf18def21a0de7db56504d78295 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Wed, 27 Jan 2010 15:02:04 +0900 Subject: ASoC: AC97: LN2440SBC: Switch to s3c-ac97.c Switch to use s3c-ac97.c AC97 controller driver. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 7 +++---- sound/soc/s3c24xx/ln2440sbc_alc650.c | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 8b62798a04b..69d143e3ab2 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -29,9 +29,6 @@ config SND_S3C_SOC_PCM config SND_S3C2443_SOC_AC97 tristate - select S3C2410_DMA - select AC97_BUS - select SND_SOC_AC97_BUS config SND_S3C_SOC_AC97 tristate @@ -86,8 +83,10 @@ config SND_S3C24XX_SOC_SMDK2443_WM9710 config SND_S3C24XX_SOC_LN2440SBC_ALC650 tristate "SoC AC97 Audio support for LN2440SBC - ALC650" depends on SND_S3C24XX_SOC && ARCH_S3C2410 - select SND_S3C2443_SOC_AC97 + select S3C2410_DMA + select AC97_BUS select SND_SOC_AC97_CODEC + select SND_S3C_SOC_AC97 help Say Y if you want to add support for SoC audio on ln2440sbc with the ALC650. diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c index d00d359a03e..ffa954fe693 100644 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c @@ -25,7 +25,7 @@ #include "../codecs/ac97.h" #include "s3c-dma.h" -#include "s3c24xx-ac97.h" +#include "s3c-ac97.h" static struct snd_soc_card ln2440sbc; @@ -33,7 +33,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai = &s3c2443_ac97_dai[0], + .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM], .codec_dai = &ac97_dai, }, }; -- cgit v1.2.3 From 7beba4d50d5f70c3851f608927882959d532671c Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Wed, 27 Jan 2010 15:04:36 +0900 Subject: ASoC: AC97: S3C2443: Remove unused driver Since, we have generic AC97 controller driver and all the machines have moved to that, there is no need for old s3c2443-ac97.c to exist. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 3 - sound/soc/s3c24xx/Makefile | 2 - sound/soc/s3c24xx/s3c2443-ac97.c | 432 --------------------------------------- sound/soc/s3c24xx/s3c24xx-ac97.h | 25 --- 4 files changed, 462 deletions(-) delete mode 100644 sound/soc/s3c24xx/s3c2443-ac97.c delete mode 100644 sound/soc/s3c24xx/s3c24xx-ac97.h (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 69d143e3ab2..15fe57e5a23 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -27,9 +27,6 @@ config SND_S3C64XX_SOC_I2S config SND_S3C_SOC_PCM tristate -config SND_S3C2443_SOC_AC97 - tristate - config SND_S3C_SOC_AC97 tristate select SND_SOC_AC97_BUS diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 1117678ae4e..df071a376fa 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -3,14 +3,12 @@ snd-soc-s3c24xx-objs := s3c-dma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o -snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o snd-soc-s3c-ac97-objs := s3c-ac97.o snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o snd-soc-s3c-pcm-objs := s3c-pcm.o obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o -obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c deleted file mode 100644 index 0191e3acb0b..00000000000 --- a/sound/soc/s3c24xx/s3c2443-ac97.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * s3c2443-ac97.c -- ALSA Soc Audio Layer - * - * (c) 2007 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * Copyright (C) 2005, Sean Choi - * All rights reserved. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "s3c-dma.h" -#include "s3c24xx-ac97.h" - -struct s3c24xx_ac97_info { - void __iomem *regs; - struct clk *ac97_clk; -}; -static struct s3c24xx_ac97_info s3c24xx_ac97; - -static DECLARE_COMPLETION(ac97_completion); -static u32 codec_ready; -static DEFINE_MUTEX(ac97_mutex); - -static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - u32 ac_glbctrl; - u32 ac_codec_cmd; - u32 stat, addr, data; - - mutex_lock(&ac97_mutex); - - codec_ready = S3C_AC97_GLBSTAT_CODECREADY; - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - wait_for_completion(&ac97_completion); - - stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT); - addr = (stat >> 16) & 0x7f; - data = (stat & 0xffff); - - if (addr != reg) - printk(KERN_ERR "s3c24xx-ac97: req addr = %02x," - " rep addr = %02x\n", reg, addr); - - mutex_unlock(&ac97_mutex); - - return (unsigned short)data; -} - -static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - u32 ac_glbctrl; - u32 ac_codec_cmd; - - mutex_lock(&ac97_mutex); - - codec_ready = S3C_AC97_GLBSTAT_CODECREADY; - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - wait_for_completion(&ac97_completion); - - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - mutex_unlock(&ac97_mutex); - -} - -static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); -} - -static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA | - S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); -} - -static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id) -{ - int status; - u32 ac_glbctrl; - - status = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & codec_ready; - - if (status) { - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - complete(&ac97_completion); - } - return IRQ_HANDLED; -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = s3c2443_ac97_read, - .write = s3c2443_ac97_write, - .warm_reset = s3c2443_ac97_warm_reset, - .reset = s3c2443_ac97_cold_reset, -}; - -static struct s3c2410_dma_client s3c2443_dma_client_out = { - .name = "AC97 PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c2443_dma_client_in = { - .name = "AC97 PCM Stereo in" -}; - -static struct s3c2410_dma_client s3c2443_dma_client_micin = { - .name = "AC97 Mic Mono in" -}; - -static struct s3c_dma_params s3c2443_ac97_pcm_stereo_out = { - .client = &s3c2443_dma_client_out, - .channel = DMACH_PCM_OUT, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - .dma_size = 4, -}; - -static struct s3c_dma_params s3c2443_ac97_pcm_stereo_in = { - .client = &s3c2443_dma_client_in, - .channel = DMACH_PCM_IN, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - .dma_size = 4, -}; - -static struct s3c_dma_params s3c2443_ac97_mic_mono_in = { - .client = &s3c2443_dma_client_micin, - .channel = DMACH_MIC_IN, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, - .dma_size = 4, -}; - -static int s3c2443_ac97_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ - int ret; - u32 ac_glbctrl; - - s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100); - if (s3c24xx_ac97.regs == NULL) - return -ENXIO; - - s3c24xx_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); - if (s3c24xx_ac97.ac97_clk == NULL) { - printk(KERN_ERR "s3c2443-ac97 failed to get ac97_clock\n"); - iounmap(s3c24xx_ac97.regs); - return -ENODEV; - } - clk_enable(s3c24xx_ac97.ac97_clk); - - s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET); - s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC); - s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK); - s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI); - s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - ret = request_irq(IRQ_S3C244x_AC97, s3c2443_ac97_irq, - IRQF_DISABLED, "AC97", NULL); - if (ret < 0) { - printk(KERN_ERR "s3c24xx-ac97: interrupt request failed.\n"); - clk_disable(s3c24xx_ac97.ac97_clk); - clk_put(s3c24xx_ac97.ac97_clk); - iounmap(s3c24xx_ac97.regs); - } - return ret; -} - -static void s3c2443_ac97_remove(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ - free_irq(IRQ_S3C244x_AC97, NULL); - clk_disable(s3c24xx_ac97.ac97_clk); - clk_put(s3c24xx_ac97.ac97_clk); - iounmap(s3c24xx_ac97.regs); -} - -static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out; - else - cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in; - - return 0; -} - -static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - u32 ac_glbctrl; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int channel = ((struct s3c_dma_params *) - rtd->dai->cpu_dai->dma_data)->channel; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; - else - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; - else - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; - break; - } - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); - - return 0; -} - -static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in; - - return 0; -} - -static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - u32 ac_glbctrl; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int channel = ((struct s3c_dma_params *) - rtd->dai->cpu_dai->dma_data)->channel; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; - } - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); - - return 0; -} - -#define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ - SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) - -static struct snd_soc_dai_ops s3c2443_ac97_dai_ops = { - .hw_params = s3c2443_ac97_hw_params, - .trigger = s3c2443_ac97_trigger, -}; - -static struct snd_soc_dai_ops s3c2443_ac97_mic_dai_ops = { - .hw_params = s3c2443_ac97_hw_mic_params, - .trigger = s3c2443_ac97_mic_trigger, -}; - -struct snd_soc_dai s3c2443_ac97_dai[] = { -{ - .name = "s3c2443-ac97", - .id = 0, - .ac97_control = 1, - .probe = s3c2443_ac97_probe, - .remove = s3c2443_ac97_remove, - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 2, - .channels_max = 2, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 2, - .channels_max = 2, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c2443_ac97_dai_ops, -}, -{ - .name = "pxa2xx-ac97-mic", - .id = 1, - .ac97_control = 1, - .capture = { - .stream_name = "AC97 Mic Capture", - .channels_min = 1, - .channels_max = 1, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c2443_ac97_mic_dai_ops, -}, -}; -EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -static int __init s3c2443_ac97_init(void) -{ - return snd_soc_register_dais(s3c2443_ac97_dai, - ARRAY_SIZE(s3c2443_ac97_dai)); -} -module_init(s3c2443_ac97_init); - -static void __exit s3c2443_ac97_exit(void) -{ - snd_soc_unregister_dais(s3c2443_ac97_dai, - ARRAY_SIZE(s3c2443_ac97_dai)); -} -module_exit(s3c2443_ac97_exit); - - -MODULE_AUTHOR("Graeme Gregory"); -MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h deleted file mode 100644 index e96f941a810..00000000000 --- a/sound/soc/s3c24xx/s3c24xx-ac97.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * s3c24xx-ac97.c -- ALSA Soc Audio Layer - * - * (c) 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.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. - * - * Revision history - * 10th Nov 2006 Initial version. - */ - -#ifndef S3C24XXAC97_H_ -#define S3C24XXAC97_H_ - -#define AC_CMD_ADDR(x) (x << 16) -#define AC_CMD_DATA(x) (x & 0xffff) - -extern struct snd_soc_dai s3c2443_ac97_dai[]; - -#endif /*S3C24XXAC97_H_*/ -- cgit v1.2.3 From 583b2be626b047eeb4f9a26721e38fe4992b2d02 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 27 Jan 2010 20:54:13 +0000 Subject: ASoC: Note jumper settings for smdk_wm9713 driver on SMDK6410 The board supports both GPIO sets for the AC97 bus and the analogue outputs can be switched between this and the WM8580 so add some comments saying what the setup the standard kernel expects is. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/smdk_wm9713.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c index 7dd933f7cbf..6fa2c9d17d7 100644 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ b/sound/soc/s3c24xx/smdk_wm9713.c @@ -21,6 +21,12 @@ static struct snd_soc_card smdk; +/* + * Default CFG switch settings to use this driver: + * + * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off + */ + /* Playback (HeadPhone):- Headphone Playback Switch - On -- cgit v1.2.3 From 9e9d04c05fd01018da35fa1daa9bda844cac6162 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 29 Jan 2010 10:57:07 +0900 Subject: ASoC: AC97: SMDK-WM9713: Convert notes from cset to sset It's more robust when references are provided in control names rather than numid. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/smdk_wm9713.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c index 6fa2c9d17d7..24fd39f38cc 100644 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ b/sound/soc/s3c24xx/smdk_wm9713.c @@ -29,24 +29,15 @@ static struct snd_soc_card smdk; /* Playback (HeadPhone):- - Headphone Playback Switch - On - $ amixer cset numid=4 1 - - Right Headphone Out Mux - Headphone - $ amixer cset numid=92 2 - Left Headphone Out Mux - Headphone - $ amixer cset numid=93 2 - - Right HP Mixer PCM Playback Switch - On - $ amixer cset numid=75 1 - Left HP Mixer PCM Playback Switch - On - $ amixer cset numid=81 1 + $ amixer sset 'Headphone' unmute + $ amixer sset 'Right Headphone Out Mux' 'Headphone' + $ amixer sset 'Left Headphone Out Mux' 'Headphone' + $ amixer sset 'Right HP Mixer PCM' unmute + $ amixer sset 'Left HP Mixer PCM' unmute Capture (LineIn):- - Right Capture Source - Line - $ amixer cset numid=86 2 - Left Capture Source - Line - $ amixer cset numid=87 2 + $ amixer sset 'Right Capture Source' 'Line' + $ amixer sset 'Left Capture Source' 'Line' */ static struct snd_soc_dai_link smdk_dai = { -- cgit v1.2.3 From 59cdd9bc057a54384a7838231dd2672a89dff2ac Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 1 Feb 2010 23:22:16 -0800 Subject: ASoC: Fix continuation line formats String constants that are continued on subsequent lines with \ are not good. Signed-off-by: Joe Perches Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-pcm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound/soc/s3c24xx') diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c index 9e61a7c2d9a..a98f40c3cd2 100644 --- a/sound/soc/s3c24xx/s3c-pcm.c +++ b/sound/soc/s3c24xx/s3c-pcm.c @@ -229,8 +229,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, spin_unlock_irqrestore(&pcm->lock, flags); - dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs \ - SCLK_DIV=%d SYNC_DIV=%d\n", + dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n", clk_get_rate(clk), pcm->sclk_per_fs, sclk_div, sync_div); -- cgit v1.2.3