From 7be4ba24a3ea53bc8ade841635e4d4a59e98ceb5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 18 Jul 2011 13:17:13 +0900 Subject: ASoC: Mark cache as dirty when suspending Since quite a few drivers are not managing to flag the cache as needing to be resynced after suspend and it's a reasonable thing to do flag the cache as needing sync automatically when suspending. The expectation is that systems will mainly only keep the CODEC powered when doing audio through the CODEC so we won't actually suspend the device anyway; drivers which want to can override this behaviour when they resume. Signed-off-by: Mark Brown Acked-by: Liam Girdwood Cc: stable@kernel.org --- sound/soc/soc-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index e44267f66216..93109a4e2bc8 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -577,6 +577,7 @@ int snd_soc_suspend(struct device *dev) case SND_SOC_BIAS_OFF: codec->driver->suspend(codec, PMSG_SUSPEND); codec->suspended = 1; + codec->cache_sync = 1; break; default: dev_dbg(codec->dev, "CODEC is on over suspend\n"); -- cgit v1.2.2 From 1c8371d61e3a8e65fe6ef4ac535d1cd6d8ec7650 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 17 Jul 2011 18:00:26 +0200 Subject: ASoC: core: make comments fit the code In one comment, cpu_dai was mentioned although codec_dai was used in the code. Also, fix the name for the card dai list which has no seperation into card_dai and codec_dai. Signed-off-by: Wolfram Sang Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 93109a4e2bc8..83ad8ca27490 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1141,7 +1141,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) } } cpu_dai->probed = 1; - /* mark cpu_dai as probed and add to card cpu_dai list */ + /* mark cpu_dai as probed and add to card dai list */ list_add(&cpu_dai->card_list, &card->dai_dev_list); } @@ -1172,7 +1172,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) } } - /* mark cpu_dai as probed and add to card cpu_dai list */ + /* mark codec_dai as probed and add to card dai list */ codec_dai->probed = 1; list_add(&codec_dai->card_list, &card->dai_dev_list); } -- cgit v1.2.2 From e94a4062c88e5245fef91ceac86788ae336f755b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 18 Jul 2011 17:53:03 +0200 Subject: ASoC: sgtl5000: refactor registering internal ldo The code for registering the internal ldo was present twice. Turn it into a function instead. Also, inform the user if LDO is used now. Signed-off-by: Wolfram Sang Tested-by: Dong Aisheng Tested-by: Shawn Guo Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/sgtl5000.c | 69 ++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 38 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index ff29380c9ed3..17af336892a7 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1218,6 +1218,34 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) return 0; } +static int sgtl5000_replace_vddd_with_ldo(struct snd_soc_codec *codec) +{ + struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); + int ret; + + /* set internal ldo to 1.2v */ + ret = ldo_regulator_register(codec, &ldo_init_data, LDO_VOLTAGE); + if (ret) { + dev_err(codec->dev, + "Failed to register vddd internal supplies: %d\n", ret); + return ret; + } + + sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), + sgtl5000->supplies); + + if (ret) { + ldo_regulator_remove(codec); + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + dev_info(codec->dev, "Using internal LDO instead of VDDD\n"); + return 0; +} + static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) { u16 reg; @@ -1235,30 +1263,9 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) if (!ret) external_vddd = 1; else { - /* set internal ldo to 1.2v */ - int voltage = LDO_VOLTAGE; - - ret = ldo_regulator_register(codec, &ldo_init_data, voltage); - if (ret) { - dev_err(codec->dev, - "Failed to register vddd internal supplies: %d\n", - ret); - return ret; - } - - sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME; - - ret = regulator_bulk_get(codec->dev, - ARRAY_SIZE(sgtl5000->supplies), - sgtl5000->supplies); - - if (ret) { - ldo_regulator_remove(codec); - dev_err(codec->dev, - "Failed to request supplies: %d\n", ret); - + ret = sgtl5000_replace_vddd_with_ldo(codec); + if (ret) return ret; - } } ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), @@ -1287,7 +1294,6 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) * roll back to use internal LDO */ if (external_vddd && rev >= 0x11) { - int voltage = LDO_VOLTAGE; /* disable all regulator first */ regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); @@ -1295,23 +1301,10 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); - ret = ldo_regulator_register(codec, &ldo_init_data, voltage); + ret = sgtl5000_replace_vddd_with_ldo(codec); if (ret) return ret; - sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME; - - ret = regulator_bulk_get(codec->dev, - ARRAY_SIZE(sgtl5000->supplies), - sgtl5000->supplies); - if (ret) { - ldo_regulator_remove(codec); - dev_err(codec->dev, - "Failed to request supplies: %d\n", ret); - - return ret; - } - ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); if (ret) -- cgit v1.2.2 From 09bddc8eb26eeb976efcfde9569b5ad1d9b77574 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 18 Jul 2011 17:53:04 +0200 Subject: ASoC: sgtl5000: guide user when regulator support is needed Print a hint when the user has a setup where CONFIG_REGULATOR is really needed to make the driver work. Signed-off-by: Wolfram Sang Tested-by: Dong Aisheng Tested-by: Shawn Guo Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/sgtl5000.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 17af336892a7..76258f2a2ffb 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -907,6 +907,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec, struct regulator_init_data *init_data, int voltage) { + dev_err(codec->dev, "this setup needs regulator support in the kernel\n"); return -EINVAL; } -- cgit v1.2.2 From 3198b9eb514fd27dd15c55f36b17ac2cddade1a5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Jul 2011 13:50:10 +0100 Subject: ASoC: Acknowledge WM8962 interrupts before acting on them This closes the small race between a status being read in response to an interrupt and clearing the interrupt, meaning that if the status changes between those periods we might not get a reassertion of the interrupt. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8962.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 8499c563a9b5..60d740ebeb5b 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3409,6 +3409,9 @@ static irqreturn_t wm8962_irq(int irq, void *data) active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); active &= ~mask; + /* Acknowledge the interrupts */ + snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); + if (active & WM8962_FLL_LOCK_EINT) { dev_dbg(codec->dev, "FLL locked\n"); complete(&wm8962->fll_lock); @@ -3433,9 +3436,6 @@ static irqreturn_t wm8962_irq(int irq, void *data) msecs_to_jiffies(250)); } - /* Acknowledge the interrupts */ - snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); - return IRQ_HANDLED; } -- cgit v1.2.2 From 3012f43eaf7592d8121426918e43e3b5db013aff Mon Sep 17 00:00:00 2001 From: "Rajashekhara, Sudhakar" Date: Wed, 20 Jul 2011 17:36:04 +0530 Subject: ASoC: davinci: fix codec start and stop functions According to DM365 voice codec data sheet at [1], before starting recording or playback, ADC/DAC modules should follow a reset and enable cycle. Writing a 1 to the ADC/DAC bit in the register resets the module and clearing the bit to 0 will enable the module. But the driver seems to be doing the reverse of it. [1] http://focus.ti.com/lit/ug/sprufi9b/sprufi9b.pdf Signed-off-by: Rajashekhara, Sudhakar Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/davinci/davinci-vcif.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index 9259f1f34899..c957e9e4a73f 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c @@ -62,9 +62,9 @@ static void davinci_vcif_start(struct snd_pcm_substream *substream) w = readl(davinci_vc->base + DAVINCI_VC_CTRL); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1); + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0); else - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1); + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0); writel(w, davinci_vc->base + DAVINCI_VC_CTRL); } @@ -80,9 +80,9 @@ static void davinci_vcif_stop(struct snd_pcm_substream *substream) /* Reset transmitter/receiver and sample rate/frame sync generators */ w = readl(davinci_vc->base + DAVINCI_VC_CTRL); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0); + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1); else - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0); + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1); writel(w, davinci_vc->base + DAVINCI_VC_CTRL); } -- cgit v1.2.2 From 82d1d521036eb3f5aae48b847f939d99a44c18bb Mon Sep 17 00:00:00 2001 From: "Rajashekhara, Sudhakar" Date: Wed, 20 Jul 2011 17:37:18 +0530 Subject: ASoC: davinci: add missing break statement In davinci_vcif_trigger() function, a break() statement was missing causing the davinci_vcif_stop() function to be called as a fallback after calling davinci_vcif_start(). Signed-off-by: Rajashekhara, Sudhakar Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/davinci/davinci-vcif.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc') diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index c957e9e4a73f..1f11525d97e8 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c @@ -159,6 +159,7 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: davinci_vcif_start(substream); + break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -- cgit v1.2.2 From 61100f405de5c16a0866de7843ed442090436e6a Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Wed, 20 Jul 2011 17:07:12 +0900 Subject: ASoC: SAMSUNG: Modify I2S driver to support idma Previously, I2S driver only can support system dma. In this patch, i2s driver can support internal dma too. IDMA h/w configuration is initialized on idma.c Signed-off-by: Sangbeom Kim Acked-by: Liam Girdwood Acked-by: Jassi Brar Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 1568eea31f41..c086b78539ee 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -21,6 +21,7 @@ #include #include "dma.h" +#include "idma.h" #include "i2s.h" #include "i2s-regs.h" @@ -60,6 +61,7 @@ struct i2s_dai { /* DMA parameters */ struct s3c_dma_params dma_playback; struct s3c_dma_params dma_capture; + struct s3c_dma_params idma_playback; u32 quirks; u32 suspend_i2smod; u32 suspend_i2scon; @@ -877,6 +879,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) if (i2s->quirks & QUIRK_NEED_RSTCLR) writel(CON_RSTCLR, i2s->addr + I2SCON); + if (i2s->quirks & QUIRK_SEC_DAI) + idma_reg_addr_init((void *)i2s->addr, + i2s->sec_dai->idma_playback.dma_addr); + probe_exit: /* Reset any constraint on RFS and BFS */ i2s->rfs = 0; @@ -1077,6 +1083,7 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) sec_dai->dma_playback.dma_size = 4; sec_dai->base = regs_base; sec_dai->quirks = quirks; + sec_dai->idma_playback.dma_addr = i2s_cfg->idma_addr; sec_dai->pri_dai = pri_dai; pri_dai->sec_dai = sec_dai; } -- cgit v1.2.2 From d7c3e9525ac8e898f1156a1f3a7c5038f6560186 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Wed, 20 Jul 2011 17:07:13 +0900 Subject: ASoC: SAMSUNG: Add I2S0 internal dma driver I2S in Exynos4 and S5PC110(S5PV210) has a internal dma. It can be used low power audio mode and 2nd channel transfer. This patch can support idma. Signed-off-by: Sangbeom Kim Acked-by: Jassi Brar Acked-by: Liam Girdwood Acked-by: Jassi Brar Signed-off-by: Mark Brown --- sound/soc/samsung/Makefile | 2 + sound/soc/samsung/idma.c | 453 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/samsung/idma.h | 26 +++ 3 files changed, 481 insertions(+) create mode 100644 sound/soc/samsung/idma.c create mode 100644 sound/soc/samsung/idma.h (limited to 'sound/soc') diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 9eb3b12eb72f..8509d3c4366e 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -1,5 +1,6 @@ # S3c24XX Platform Support snd-soc-s3c24xx-objs := dma.o +snd-soc-idma-objs := idma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o snd-soc-ac97-objs := ac97.o @@ -16,6 +17,7 @@ obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o +obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-idma.o # S3C24XX Machine Support snd-soc-jive-wm8750-objs := jive_wm8750.o diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c new file mode 100644 index 000000000000..ebde0740ab19 --- /dev/null +++ b/sound/soc/samsung/idma.c @@ -0,0 +1,453 @@ +/* + * sound/soc/samsung/idma.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * I2S0's Internal DMA driver + * + * 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 +#include +#include +#include + +#include "i2s.h" +#include "idma.h" +#include "dma.h" +#include "i2s-regs.h" + +#define ST_RUNNING (1<<0) +#define ST_OPENED (1<<1) + +static const struct snd_pcm_hardware idma_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_U24_LE | + SNDRV_PCM_FMTBIT_U8 | + SNDRV_PCM_FMTBIT_S8, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = MAX_IDMA_BUFFER, + .period_bytes_min = 128, + .period_bytes_max = MAX_IDMA_PERIOD, + .periods_min = 1, + .periods_max = 2, +}; + +struct idma_ctrl { + spinlock_t lock; + int state; + dma_addr_t start; + dma_addr_t pos; + dma_addr_t end; + dma_addr_t period; + dma_addr_t periodsz; + void *token; + void (*cb)(void *dt, int bytes_xfer); +}; + +static struct idma_info { + spinlock_t lock; + void __iomem *regs; + dma_addr_t lp_tx_addr; +} idma; + +static void idma_getpos(dma_addr_t *src) +{ + *src = idma.lp_tx_addr + + (readl(idma.regs + I2STRNCNT) & 0xffffff) * 4; +} + +static int idma_enqueue(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct idma_ctrl *prtd = substream->runtime->private_data; + u32 val; + + spin_lock(&prtd->lock); + prtd->token = (void *) substream; + spin_unlock(&prtd->lock); + + /* Internal DMA Level0 Interrupt Address */ + val = idma.lp_tx_addr + prtd->periodsz; + writel(val, idma.regs + I2SLVL0ADDR); + + /* Start address0 of I2S internal DMA operation. */ + val = idma.lp_tx_addr; + writel(val, idma.regs + I2SSTR0); + + /* + * Transfer block size for I2S internal DMA. + * Should decide transfer size before start dma operation + */ + val = readl(idma.regs + I2SSIZE); + val &= ~(I2SSIZE_TRNMSK << I2SSIZE_SHIFT); + val |= (((runtime->dma_bytes >> 2) & + I2SSIZE_TRNMSK) << I2SSIZE_SHIFT); + writel(val, idma.regs + I2SSIZE); + + val = readl(idma.regs + I2SAHB); + val |= AHB_INTENLVL0; + writel(val, idma.regs + I2SAHB); + + return 0; +} + +static void idma_setcallbk(struct snd_pcm_substream *substream, + void (*cb)(void *, int)) +{ + struct idma_ctrl *prtd = substream->runtime->private_data; + + spin_lock(&prtd->lock); + prtd->cb = cb; + spin_unlock(&prtd->lock); +} + +static void idma_control(int op) +{ + u32 val = readl(idma.regs + I2SAHB); + + spin_lock(&idma.lock); + + switch (op) { + case LPAM_DMA_START: + val |= (AHB_INTENLVL0 | AHB_DMAEN); + break; + case LPAM_DMA_STOP: + val &= ~(AHB_INTENLVL0 | AHB_DMAEN); + break; + default: + spin_unlock(&idma.lock); + return; + } + + writel(val, idma.regs + I2SAHB); + spin_unlock(&idma.lock); +} + +static void idma_done(void *id, int bytes_xfer) +{ + struct snd_pcm_substream *substream = id; + struct idma_ctrl *prtd = substream->runtime->private_data; + + if (prtd && (prtd->state & ST_RUNNING)) + snd_pcm_period_elapsed(substream); +} + +static int idma_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct idma_ctrl *prtd = substream->runtime->private_data; + u32 mod = readl(idma.regs + I2SMOD); + u32 ahb = readl(idma.regs + I2SAHB); + + ahb |= (AHB_DMARLD | AHB_INTMASK); + mod |= MOD_TXS_IDMA; + writel(ahb, idma.regs + I2SAHB); + writel(mod, idma.regs + I2SMOD); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + runtime->dma_bytes = params_buffer_bytes(params); + + prtd->start = prtd->pos = runtime->dma_addr; + prtd->period = params_periods(params); + prtd->periodsz = params_period_bytes(params); + prtd->end = runtime->dma_addr + runtime->dma_bytes; + + idma_setcallbk(substream, idma_done); + + return 0; +} + +static int idma_hw_free(struct snd_pcm_substream *substream) +{ + snd_pcm_set_runtime_buffer(substream, NULL); + + return 0; +} + +static int idma_prepare(struct snd_pcm_substream *substream) +{ + struct idma_ctrl *prtd = substream->runtime->private_data; + + prtd->pos = prtd->start; + + /* flush the DMA channel */ + idma_control(LPAM_DMA_STOP); + idma_enqueue(substream); + + return 0; +} + +static int idma_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct idma_ctrl *prtd = substream->runtime->private_data; + int ret = 0; + + spin_lock(&prtd->lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + prtd->state |= ST_RUNNING; + idma_control(LPAM_DMA_START); + break; + + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + prtd->state &= ~ST_RUNNING; + idma_control(LPAM_DMA_STOP); + break; + + default: + ret = -EINVAL; + break; + } + + spin_unlock(&prtd->lock); + + return ret; +} + +static snd_pcm_uframes_t + idma_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct idma_ctrl *prtd = runtime->private_data; + dma_addr_t src; + unsigned long res; + + spin_lock(&prtd->lock); + + idma_getpos(&src); + res = src - prtd->start; + + spin_unlock(&prtd->lock); + + return bytes_to_frames(substream->runtime, res); +} + +static int idma_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned long size, offset; + int ret; + + /* From snd_pcm_lib_mmap_iomem */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_IO; + size = vma->vm_end - vma->vm_start; + offset = vma->vm_pgoff << PAGE_SHIFT; + ret = io_remap_pfn_range(vma, vma->vm_start, + (runtime->dma_addr + offset) >> PAGE_SHIFT, + size, vma->vm_page_prot); + + return ret; +} + +static irqreturn_t iis_irq(int irqno, void *dev_id) +{ + struct idma_ctrl *prtd = (struct idma_ctrl *)dev_id; + u32 iiscon, iisahb, val, addr; + + iisahb = readl(idma.regs + I2SAHB); + iiscon = readl(idma.regs + I2SCON); + + val = (iisahb & AHB_LVL0INT) ? AHB_CLRLVL0INT : 0; + + if (val) { + iisahb |= val; + writel(iisahb, idma.regs + I2SAHB); + + addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr; + addr += prtd->periodsz; + addr %= (prtd->end - prtd->start); + addr += idma.lp_tx_addr; + + writel(addr, idma.regs + I2SLVL0ADDR); + + if (prtd->cb) + prtd->cb(prtd->token, prtd->period); + } + + return IRQ_HANDLED; +} + +static int idma_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct idma_ctrl *prtd; + int ret; + + snd_soc_set_runtime_hwparams(substream, &idma_hardware); + + prtd = kzalloc(sizeof(struct idma_ctrl), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + ret = request_irq(IRQ_I2S0, iis_irq, 0, "i2s", prtd); + if (ret < 0) { + pr_err("fail to claim i2s irq , ret = %d\n", ret); + kfree(prtd); + return ret; + } + + spin_lock_init(&prtd->lock); + + runtime->private_data = prtd; + + return 0; +} + +static int idma_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct idma_ctrl *prtd = runtime->private_data; + + free_irq(IRQ_I2S0, prtd); + + if (!prtd) + pr_err("idma_close called with prtd == NULL\n"); + + kfree(prtd); + + return 0; +} + +static struct snd_pcm_ops idma_ops = { + .open = idma_open, + .close = idma_close, + .ioctl = snd_pcm_lib_ioctl, + .trigger = idma_trigger, + .pointer = idma_pointer, + .mmap = idma_mmap, + .hw_params = idma_hw_params, + .hw_free = idma_hw_free, + .prepare = idma_prepare, +}; + +static void idma_free(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + + substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream) + return; + + buf = &substream->dma_buffer; + if (!buf->area) + return; + + iounmap(buf->area); + + buf->area = NULL; + buf->addr = 0; +} + +static int preallocate_idma_buffer(struct snd_pcm *pcm, int stream) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *buf = &substream->dma_buffer; + + buf->dev.dev = pcm->card->dev; + buf->private_data = NULL; + + /* Assign PCM buffer pointers */ + buf->dev.type = SNDRV_DMA_TYPE_CONTINUOUS; + buf->addr = idma.lp_tx_addr; + buf->bytes = idma_hardware.buffer_bytes_max; + buf->area = (unsigned char *)ioremap(buf->addr, buf->bytes); + + return 0; +} + +static u64 idma_mask = DMA_BIT_MASK(32); + +static int idma_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + struct snd_soc_dai *dai = rtd->cpu_dai; + struct snd_pcm *pcm = rtd->pcm; + int ret = 0; + + if (!card->dev->dma_mask) + card->dev->dma_mask = &idma_mask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + + if (dai->driver->playback.channels_min) + ret = preallocate_idma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK); + + return ret; +} + +void idma_reg_addr_init(void *regs, dma_addr_t addr) +{ + spin_lock_init(&idma.lock); + idma.regs = regs; + idma.lp_tx_addr = addr; +} + +struct snd_soc_platform_driver asoc_idma_platform = { + .ops = &idma_ops, + .pcm_new = idma_new, + .pcm_free = idma_free, +}; + +static int __devinit asoc_idma_platform_probe(struct platform_device *pdev) +{ + return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); +} + +static int __devexit asoc_idma_platform_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static struct platform_driver asoc_idma_driver = { + .driver = { + .name = "samsung-idma", + .owner = THIS_MODULE, + }, + + .probe = asoc_idma_platform_probe, + .remove = __devexit_p(asoc_idma_platform_remove), +}; + +static int __init asoc_idma_init(void) +{ + return platform_driver_register(&asoc_idma_driver); +} +module_init(asoc_idma_init); + +static void __exit asoc_idma_exit(void) +{ + platform_driver_unregister(&asoc_idma_driver); +} +module_exit(asoc_idma_exit); + +MODULE_AUTHOR("Jaswinder Singh, "); +MODULE_DESCRIPTION("Samsung ASoC IDMA Driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/idma.h b/sound/soc/samsung/idma.h new file mode 100644 index 000000000000..48273216166e --- /dev/null +++ b/sound/soc/samsung/idma.h @@ -0,0 +1,26 @@ +/* + * sound/soc/samsung/idma.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * http://www.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. + * + */ + +#ifndef __SND_SOC_SAMSUNG_IDMA_H_ +#define __SND_SOC_SAMSUNG_IDMA_H_ + +extern void idma_reg_addr_init(void *regs, dma_addr_t addr); + +/* dma_state */ +#define LPAM_DMA_STOP 0 +#define LPAM_DMA_START 1 + +#define MAX_IDMA_PERIOD (128 * 1024) +#define MAX_IDMA_BUFFER (160 * 1024) + +#endif /* __SND_SOC_SAMSUNG_IDMA_H_ */ -- cgit v1.2.2 From 4805608ac1d1a60ca926ff81b1ebd3145f7adf78 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Wed, 20 Jul 2011 12:23:33 +0100 Subject: ASoC: dapm - Add methods to retrieve snd_card and soc_card from dapm context. In preparation for ASoC Dynamic PCM (AKA DSP) support. Provide convenience methods to retrieve the soc_card or snd_card from a DAPM context. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index fbfcda062839..7e15914b3633 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -124,6 +124,36 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); } +/* get snd_card from DAPM context */ +static inline struct snd_card *dapm_get_snd_card( + struct snd_soc_dapm_context *dapm) +{ + if (dapm->codec) + return dapm->codec->card->snd_card; + else if (dapm->platform) + return dapm->platform->card->snd_card; + else + BUG(); + + /* unreachable */ + return NULL; +} + +/* get soc_card from DAPM context */ +static inline struct snd_soc_card *dapm_get_soc_card( + struct snd_soc_dapm_context *dapm) +{ + if (dapm->codec) + return dapm->codec->card; + else if (dapm->platform) + return dapm->platform->card; + else + BUG(); + + /* unreachable */ + return NULL; +} + static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) { if (w->codec) -- cgit v1.2.2 From a0c27ab2421c47dc7c53f797fffcc0d17cdb122c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 21 Jul 2011 14:58:05 +0100 Subject: ASoC: Revert "ASoC: SAMSUNG: Add I2S0 internal dma driver" This reverts commit d7c3e9525ac8e898f1156a1f3a7c5038f6560186 as it does not currently build due to missing dependencies in the Samsung tree. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/Makefile | 2 - sound/soc/samsung/idma.c | 453 --------------------------------------------- sound/soc/samsung/idma.h | 26 --- 3 files changed, 481 deletions(-) delete mode 100644 sound/soc/samsung/idma.c delete mode 100644 sound/soc/samsung/idma.h (limited to 'sound/soc') diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 8509d3c4366e..9eb3b12eb72f 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -1,6 +1,5 @@ # S3c24XX Platform Support snd-soc-s3c24xx-objs := dma.o -snd-soc-idma-objs := idma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o snd-soc-ac97-objs := ac97.o @@ -17,7 +16,6 @@ obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o -obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-idma.o # S3C24XX Machine Support snd-soc-jive-wm8750-objs := jive_wm8750.o diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c deleted file mode 100644 index ebde0740ab19..000000000000 --- a/sound/soc/samsung/idma.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * sound/soc/samsung/idma.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * I2S0's Internal DMA driver - * - * 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 -#include -#include -#include - -#include "i2s.h" -#include "idma.h" -#include "dma.h" -#include "i2s-regs.h" - -#define ST_RUNNING (1<<0) -#define ST_OPENED (1<<1) - -static const struct snd_pcm_hardware idma_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_U24_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = MAX_IDMA_BUFFER, - .period_bytes_min = 128, - .period_bytes_max = MAX_IDMA_PERIOD, - .periods_min = 1, - .periods_max = 2, -}; - -struct idma_ctrl { - spinlock_t lock; - int state; - dma_addr_t start; - dma_addr_t pos; - dma_addr_t end; - dma_addr_t period; - dma_addr_t periodsz; - void *token; - void (*cb)(void *dt, int bytes_xfer); -}; - -static struct idma_info { - spinlock_t lock; - void __iomem *regs; - dma_addr_t lp_tx_addr; -} idma; - -static void idma_getpos(dma_addr_t *src) -{ - *src = idma.lp_tx_addr + - (readl(idma.regs + I2STRNCNT) & 0xffffff) * 4; -} - -static int idma_enqueue(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct idma_ctrl *prtd = substream->runtime->private_data; - u32 val; - - spin_lock(&prtd->lock); - prtd->token = (void *) substream; - spin_unlock(&prtd->lock); - - /* Internal DMA Level0 Interrupt Address */ - val = idma.lp_tx_addr + prtd->periodsz; - writel(val, idma.regs + I2SLVL0ADDR); - - /* Start address0 of I2S internal DMA operation. */ - val = idma.lp_tx_addr; - writel(val, idma.regs + I2SSTR0); - - /* - * Transfer block size for I2S internal DMA. - * Should decide transfer size before start dma operation - */ - val = readl(idma.regs + I2SSIZE); - val &= ~(I2SSIZE_TRNMSK << I2SSIZE_SHIFT); - val |= (((runtime->dma_bytes >> 2) & - I2SSIZE_TRNMSK) << I2SSIZE_SHIFT); - writel(val, idma.regs + I2SSIZE); - - val = readl(idma.regs + I2SAHB); - val |= AHB_INTENLVL0; - writel(val, idma.regs + I2SAHB); - - return 0; -} - -static void idma_setcallbk(struct snd_pcm_substream *substream, - void (*cb)(void *, int)) -{ - struct idma_ctrl *prtd = substream->runtime->private_data; - - spin_lock(&prtd->lock); - prtd->cb = cb; - spin_unlock(&prtd->lock); -} - -static void idma_control(int op) -{ - u32 val = readl(idma.regs + I2SAHB); - - spin_lock(&idma.lock); - - switch (op) { - case LPAM_DMA_START: - val |= (AHB_INTENLVL0 | AHB_DMAEN); - break; - case LPAM_DMA_STOP: - val &= ~(AHB_INTENLVL0 | AHB_DMAEN); - break; - default: - spin_unlock(&idma.lock); - return; - } - - writel(val, idma.regs + I2SAHB); - spin_unlock(&idma.lock); -} - -static void idma_done(void *id, int bytes_xfer) -{ - struct snd_pcm_substream *substream = id; - struct idma_ctrl *prtd = substream->runtime->private_data; - - if (prtd && (prtd->state & ST_RUNNING)) - snd_pcm_period_elapsed(substream); -} - -static int idma_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct idma_ctrl *prtd = substream->runtime->private_data; - u32 mod = readl(idma.regs + I2SMOD); - u32 ahb = readl(idma.regs + I2SAHB); - - ahb |= (AHB_DMARLD | AHB_INTMASK); - mod |= MOD_TXS_IDMA; - writel(ahb, idma.regs + I2SAHB); - writel(mod, idma.regs + I2SMOD); - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - - prtd->start = prtd->pos = runtime->dma_addr; - prtd->period = params_periods(params); - prtd->periodsz = params_period_bytes(params); - prtd->end = runtime->dma_addr + runtime->dma_bytes; - - idma_setcallbk(substream, idma_done); - - return 0; -} - -static int idma_hw_free(struct snd_pcm_substream *substream) -{ - snd_pcm_set_runtime_buffer(substream, NULL); - - return 0; -} - -static int idma_prepare(struct snd_pcm_substream *substream) -{ - struct idma_ctrl *prtd = substream->runtime->private_data; - - prtd->pos = prtd->start; - - /* flush the DMA channel */ - idma_control(LPAM_DMA_STOP); - idma_enqueue(substream); - - return 0; -} - -static int idma_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct idma_ctrl *prtd = substream->runtime->private_data; - int ret = 0; - - spin_lock(&prtd->lock); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - prtd->state |= ST_RUNNING; - idma_control(LPAM_DMA_START); - break; - - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - prtd->state &= ~ST_RUNNING; - idma_control(LPAM_DMA_STOP); - break; - - default: - ret = -EINVAL; - break; - } - - spin_unlock(&prtd->lock); - - return ret; -} - -static snd_pcm_uframes_t - idma_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct idma_ctrl *prtd = runtime->private_data; - dma_addr_t src; - unsigned long res; - - spin_lock(&prtd->lock); - - idma_getpos(&src); - res = src - prtd->start; - - spin_unlock(&prtd->lock); - - return bytes_to_frames(substream->runtime, res); -} - -static int idma_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long size, offset; - int ret; - - /* From snd_pcm_lib_mmap_iomem */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - vma->vm_flags |= VM_IO; - size = vma->vm_end - vma->vm_start; - offset = vma->vm_pgoff << PAGE_SHIFT; - ret = io_remap_pfn_range(vma, vma->vm_start, - (runtime->dma_addr + offset) >> PAGE_SHIFT, - size, vma->vm_page_prot); - - return ret; -} - -static irqreturn_t iis_irq(int irqno, void *dev_id) -{ - struct idma_ctrl *prtd = (struct idma_ctrl *)dev_id; - u32 iiscon, iisahb, val, addr; - - iisahb = readl(idma.regs + I2SAHB); - iiscon = readl(idma.regs + I2SCON); - - val = (iisahb & AHB_LVL0INT) ? AHB_CLRLVL0INT : 0; - - if (val) { - iisahb |= val; - writel(iisahb, idma.regs + I2SAHB); - - addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr; - addr += prtd->periodsz; - addr %= (prtd->end - prtd->start); - addr += idma.lp_tx_addr; - - writel(addr, idma.regs + I2SLVL0ADDR); - - if (prtd->cb) - prtd->cb(prtd->token, prtd->period); - } - - return IRQ_HANDLED; -} - -static int idma_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct idma_ctrl *prtd; - int ret; - - snd_soc_set_runtime_hwparams(substream, &idma_hardware); - - prtd = kzalloc(sizeof(struct idma_ctrl), GFP_KERNEL); - if (prtd == NULL) - return -ENOMEM; - - ret = request_irq(IRQ_I2S0, iis_irq, 0, "i2s", prtd); - if (ret < 0) { - pr_err("fail to claim i2s irq , ret = %d\n", ret); - kfree(prtd); - return ret; - } - - spin_lock_init(&prtd->lock); - - runtime->private_data = prtd; - - return 0; -} - -static int idma_close(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct idma_ctrl *prtd = runtime->private_data; - - free_irq(IRQ_I2S0, prtd); - - if (!prtd) - pr_err("idma_close called with prtd == NULL\n"); - - kfree(prtd); - - return 0; -} - -static struct snd_pcm_ops idma_ops = { - .open = idma_open, - .close = idma_close, - .ioctl = snd_pcm_lib_ioctl, - .trigger = idma_trigger, - .pointer = idma_pointer, - .mmap = idma_mmap, - .hw_params = idma_hw_params, - .hw_free = idma_hw_free, - .prepare = idma_prepare, -}; - -static void idma_free(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - - substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; - if (!substream) - return; - - buf = &substream->dma_buffer; - if (!buf->area) - return; - - iounmap(buf->area); - - buf->area = NULL; - buf->addr = 0; -} - -static int preallocate_idma_buffer(struct snd_pcm *pcm, int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - - /* Assign PCM buffer pointers */ - buf->dev.type = SNDRV_DMA_TYPE_CONTINUOUS; - buf->addr = idma.lp_tx_addr; - buf->bytes = idma_hardware.buffer_bytes_max; - buf->area = (unsigned char *)ioremap(buf->addr, buf->bytes); - - return 0; -} - -static u64 idma_mask = DMA_BIT_MASK(32); - -static int idma_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; - struct snd_pcm *pcm = rtd->pcm; - int ret = 0; - - if (!card->dev->dma_mask) - card->dev->dma_mask = &idma_mask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - - if (dai->driver->playback.channels_min) - ret = preallocate_idma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - - return ret; -} - -void idma_reg_addr_init(void *regs, dma_addr_t addr) -{ - spin_lock_init(&idma.lock); - idma.regs = regs; - idma.lp_tx_addr = addr; -} - -struct snd_soc_platform_driver asoc_idma_platform = { - .ops = &idma_ops, - .pcm_new = idma_new, - .pcm_free = idma_free, -}; - -static int __devinit asoc_idma_platform_probe(struct platform_device *pdev) -{ - return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); -} - -static int __devexit asoc_idma_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver asoc_idma_driver = { - .driver = { - .name = "samsung-idma", - .owner = THIS_MODULE, - }, - - .probe = asoc_idma_platform_probe, - .remove = __devexit_p(asoc_idma_platform_remove), -}; - -static int __init asoc_idma_init(void) -{ - return platform_driver_register(&asoc_idma_driver); -} -module_init(asoc_idma_init); - -static void __exit asoc_idma_exit(void) -{ - platform_driver_unregister(&asoc_idma_driver); -} -module_exit(asoc_idma_exit); - -MODULE_AUTHOR("Jaswinder Singh, "); -MODULE_DESCRIPTION("Samsung ASoC IDMA Driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/idma.h b/sound/soc/samsung/idma.h deleted file mode 100644 index 48273216166e..000000000000 --- a/sound/soc/samsung/idma.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * sound/soc/samsung/idma.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd - * http://www.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. - * - */ - -#ifndef __SND_SOC_SAMSUNG_IDMA_H_ -#define __SND_SOC_SAMSUNG_IDMA_H_ - -extern void idma_reg_addr_init(void *regs, dma_addr_t addr); - -/* dma_state */ -#define LPAM_DMA_STOP 0 -#define LPAM_DMA_START 1 - -#define MAX_IDMA_PERIOD (128 * 1024) -#define MAX_IDMA_BUFFER (160 * 1024) - -#endif /* __SND_SOC_SAMSUNG_IDMA_H_ */ -- cgit v1.2.2