diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-11-05 09:16:07 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-11-05 09:16:07 -0400 |
commit | a8ea54da5e47bde9ba19230bb3609b0502a288c3 (patch) | |
tree | 6b7bb369d86ab185e4a30a0d58ce485f9a00e7e8 | |
parent | 11e16eb365f4f6979cfcb2a2d379338b383590d9 (diff) | |
parent | 6424dca23e6b5a2f7a19a69cf7c0990b11717b00 (diff) | |
download | blackbird-obmc-linux-a8ea54da5e47bde9ba19230bb3609b0502a288c3.tar.gz blackbird-obmc-linux-a8ea54da5e47bde9ba19230bb3609b0502a288c3.zip |
Merge branch 'for-2.6.37' into HEAD
-rw-r--r-- | sound/soc/codecs/tlv320dac33.c | 36 | ||||
-rw-r--r-- | sound/soc/codecs/tpa6130a2.c | 6 | ||||
-rw-r--r-- | sound/soc/codecs/wm8962.c | 5 | ||||
-rw-r--r-- | sound/soc/imx/eukrea-tlv320.c | 8 | ||||
-rw-r--r-- | sound/soc/imx/imx-pcm-dma-mx2.c | 221 | ||||
-rw-r--r-- | sound/soc/imx/imx-ssi.c | 44 | ||||
-rw-r--r-- | sound/soc/imx/imx-ssi.h | 4 | ||||
-rw-r--r-- | sound/soc/imx/phycore-ac97.c | 5 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 9 |
9 files changed, 173 insertions, 165 deletions
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index d251ff54a2d3..c5ab8c805771 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -58,7 +58,7 @@ (1000000000 / ((rate * 1000) / samples)) #define US_TO_SAMPLES(rate, us) \ - (rate / (1000000 / us)) + (rate / (1000000 / (us < 1000000 ? us : 1000000))) #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) @@ -200,7 +200,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, u8 *value) { struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - int val; + int val, ret = 0; *value = reg & 0xff; @@ -210,6 +210,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, if (val < 0) { dev_err(codec->dev, "Read failed (%d)\n", val); value[0] = dac33_read_reg_cache(codec, reg); + ret = val; } else { value[0] = val; dac33_write_reg_cache(codec, reg, val); @@ -218,7 +219,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, value[0] = dac33_read_reg_cache(codec, reg); } - return 0; + return ret; } static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, @@ -329,13 +330,18 @@ static void dac33_init_chip(struct snd_soc_codec *codec) dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); } -static inline void dac33_read_id(struct snd_soc_codec *codec) +static inline int dac33_read_id(struct snd_soc_codec *codec) { + int i, ret = 0; u8 reg; - dac33_read(codec, DAC33_DEVICE_ID_MSB, ®); - dac33_read(codec, DAC33_DEVICE_ID_LSB, ®); - dac33_read(codec, DAC33_DEVICE_REV_ID, ®); + for (i = 0; i < 3; i++) { + ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, ®); + if (ret < 0) + break; + } + + return ret; } static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) @@ -1076,6 +1082,9 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) /* Number of samples under i2c latency */ dac33->alarm_threshold = US_TO_SAMPLES(rate, dac33->mode1_latency); + nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - + dac33->alarm_threshold; + if (dac33->auto_fifo_config) { if (period_size <= dac33->alarm_threshold) /* @@ -1086,6 +1095,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) ((dac33->alarm_threshold / period_size) + (dac33->alarm_threshold % period_size ? 1 : 0)); + else if (period_size > nsample_limit) + dac33->nsample = nsample_limit; else dac33->nsample = period_size; } else { @@ -1097,8 +1108,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) */ dac33->nsample_max = substream->runtime->buffer_size - period_size; - nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - - dac33->alarm_threshold; + if (dac33->nsample_max > nsample_limit) dac33->nsample_max = nsample_limit; @@ -1414,9 +1424,15 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) dev_err(codec->dev, "Failed to power up codec: %d\n", ret); goto err_power; } - dac33_read_id(codec); + ret = dac33_read_id(codec); dac33_hard_power(codec, 0); + if (ret < 0) { + dev_err(codec->dev, "Failed to read chip ID: %d\n", ret); + ret = -ENODEV; + goto err_power; + } + /* Check if the IRQ number is valid and request it */ if (dac33->irq >= 0) { ret = request_irq(dac33->irq, dac33_interrupt_handler, diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 329acc1a2074..ee4fb201de60 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -119,13 +119,13 @@ static int tpa6130a2_power(int power) { struct tpa6130a2_data *data; u8 val; - int ret; + int ret = 0; BUG_ON(tpa6130a2_client == NULL); data = i2c_get_clientdata(tpa6130a2_client); mutex_lock(&data->mutex); - if (power) { + if (power && !data->power_state) { /* Power on */ if (data->power_gpio >= 0) gpio_set_value(data->power_gpio, 1); @@ -153,7 +153,7 @@ static int tpa6130a2_power(int power) val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val &= ~TPA6130A2_SWS; tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); - } else { + } else if (!power && data->power_state) { /* set SWS */ val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val |= TPA6130A2_SWS; diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 2eaf9bb36b57..3fc63b43c6a1 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3502,8 +3502,11 @@ static ssize_t wm8962_beep_set(struct device *dev, { struct wm8962_priv *wm8962 = dev_get_drvdata(dev); long int time; + int ret; - strict_strtol(buf, 10, &time); + ret = strict_strtol(buf, 10, &time); + if (ret != 0) + return ret; input_event(wm8962->beep, EV_SND, SND_TONE, time); diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c index b59675257ce5..dd4fffdbd177 100644 --- a/sound/soc/imx/eukrea-tlv320.c +++ b/sound/soc/imx/eukrea-tlv320.c @@ -34,8 +34,8 @@ static int eukrea_tlv320_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; ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | @@ -79,10 +79,10 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = { static struct snd_soc_dai_link eukrea_tlv320_dai = { .name = "tlv320aic23", .stream_name = "TLV320AIC23", - .codec_dai = "tlv320aic23-hifi", + .codec_dai_name = "tlv320aic23-hifi", .platform_name = "imx-pcm-audio.0", .codec_name = "tlv320aic23-codec.0-001a", - .cpu_dai = "imx-ssi.0", + .cpu_dai_name = "imx-ssi.0", .ops = &eukrea_tlv320_snd_ops, }; diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index fd493ee1428e..671ef8dd524c 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -20,6 +20,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/dmaengine.h> #include <sound/core.h> #include <sound/initval.h> @@ -27,165 +28,146 @@ #include <sound/pcm_params.h> #include <sound/soc.h> -#include <mach/dma-mx1-mx2.h> +#include <mach/dma.h> #include "imx-ssi.h" struct imx_pcm_runtime_data { - int sg_count; - struct scatterlist *sg_list; - int period; + int period_bytes; int periods; - unsigned long dma_addr; int dma; - struct snd_pcm_substream *substream; unsigned long offset; unsigned long size; - unsigned long period_cnt; void *buf; int period_time; + struct dma_async_tx_descriptor *desc; + struct dma_chan *dma_chan; + struct imx_dma_data dma_data; }; -/* Called by the DMA framework when a period has elapsed */ -static void imx_ssi_dma_progression(int channel, void *data, - struct scatterlist *sg) +static void audio_dma_irq(void *data) { - struct snd_pcm_substream *substream = data; + struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data; struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; - if (!sg) - return; - - runtime = iprtd->substream->runtime; + iprtd->offset += iprtd->period_bytes; + iprtd->offset %= iprtd->period_bytes * iprtd->periods; - iprtd->offset = sg->dma_address - runtime->dma_addr; - - snd_pcm_period_elapsed(iprtd->substream); + snd_pcm_period_elapsed(substream); } -static void imx_ssi_dma_callback(int channel, void *data) +static bool filter(struct dma_chan *chan, void *param) { - pr_err("%s shouldn't be called\n", __func__); -} + struct imx_pcm_runtime_data *iprtd = param; -static void snd_imx_dma_err_callback(int channel, void *data, int err) -{ - struct snd_pcm_substream *substream = data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct imx_pcm_dma_params *dma_params = - snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - int ret; + if (!imx_dma_is_general_purpose(chan)) + return false; - pr_err("DMA timeout on channel %d -%s%s%s%s\n", - channel, - err & IMX_DMA_ERR_BURST ? " burst" : "", - err & IMX_DMA_ERR_REQUEST ? " request" : "", - err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", - err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); + chan->private = &iprtd->dma_data; - imx_dma_disable(iprtd->dma); - ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, - IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, - substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - DMA_MODE_WRITE : DMA_MODE_READ); - if (!ret) - imx_dma_enable(iprtd->dma); + return true; } -static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) +static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct imx_pcm_dma_params *dma_params; struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; + struct dma_slave_config slave_config; + dma_cap_mask_t mask; + enum dma_slave_buswidth buswidth; int ret; dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); - if (iprtd->dma < 0) { - pr_err("Failed to claim the audio DMA\n"); - return -ENODEV; - } + iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI; + iprtd->dma_data.priority = DMA_PRIO_HIGH; + iprtd->dma_data.dma_request = dma_params->dma; - ret = imx_dma_setup_handlers(iprtd->dma, - imx_ssi_dma_callback, - snd_imx_dma_err_callback, substream); - if (ret) - goto out; + /* Try to grab a DMA channel */ + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); + if (!iprtd->dma_chan) + return -EINVAL; - ret = imx_dma_setup_progression_handler(iprtd->dma, - imx_ssi_dma_progression); - if (ret) { - pr_err("Failed to setup the DMA handler\n"); - goto out; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; + break; + default: + return 0; } - ret = imx_dma_config_channel(iprtd->dma, - IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO, - IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, - dma_params->dma, 1); - if (ret < 0) { - pr_err("Cannot configure DMA channel: %d\n", ret); - goto out; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + slave_config.direction = DMA_TO_DEVICE; + slave_config.dst_addr = dma_params->dma_addr; + slave_config.dst_addr_width = buswidth; + slave_config.dst_maxburst = dma_params->burstsize; + } else { + slave_config.direction = DMA_FROM_DEVICE; + slave_config.src_addr = dma_params->dma_addr; + slave_config.src_addr_width = buswidth; + slave_config.src_maxburst = dma_params->burstsize; } - imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2); + ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); + if (ret) + return ret; return 0; -out: - imx_dma_free(iprtd->dma); - return ret; } static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; - int i; unsigned long dma_addr; + struct dma_chan *chan; + struct imx_pcm_dma_params *dma_params; + int ret; - imx_ssi_dma_alloc(substream); + dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + ret = imx_ssi_dma_alloc(substream, params); + if (ret) + return ret; + chan = iprtd->dma_chan; iprtd->size = params_buffer_bytes(params); iprtd->periods = params_periods(params); - iprtd->period = params_period_bytes(params); + iprtd->period_bytes = params_period_bytes(params); iprtd->offset = 0; iprtd->period_time = HZ / (params_rate(params) / params_period_size(params)); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - if (iprtd->sg_count != iprtd->periods) { - kfree(iprtd->sg_list); - - iprtd->sg_list = kcalloc(iprtd->periods + 1, - sizeof(struct scatterlist), GFP_KERNEL); - if (!iprtd->sg_list) - return -ENOMEM; - iprtd->sg_count = iprtd->periods + 1; - } - - sg_init_table(iprtd->sg_list, iprtd->sg_count); dma_addr = runtime->dma_addr; - for (i = 0; i < iprtd->periods; i++) { - iprtd->sg_list[i].page_link = 0; - iprtd->sg_list[i].offset = 0; - iprtd->sg_list[i].dma_address = dma_addr; - iprtd->sg_list[i].length = iprtd->period; - dma_addr += iprtd->period; + iprtd->buf = (unsigned int *)substream->dma_buffer.area; + + iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr, + iprtd->period_bytes * iprtd->periods, + iprtd->period_bytes, + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + DMA_TO_DEVICE : DMA_FROM_DEVICE); + if (!iprtd->desc) { + dev_err(&chan->dev->device, "cannot prepare slave dma\n"); + return -EINVAL; } - /* close the loop */ - iprtd->sg_list[iprtd->sg_count - 1].offset = 0; - iprtd->sg_list[iprtd->sg_count - 1].length = 0; - iprtd->sg_list[iprtd->sg_count - 1].page_link = - ((unsigned long) iprtd->sg_list | 0x01) & ~0x02; + iprtd->desc->callback = audio_dma_irq; + iprtd->desc->callback_param = substream; + return 0; } @@ -194,41 +176,21 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; - if (iprtd->dma >= 0) { - imx_dma_free(iprtd->dma); - iprtd->dma = -EINVAL; + if (iprtd->dma_chan) { + dma_release_channel(iprtd->dma_chan); + iprtd->dma_chan = NULL; } - kfree(iprtd->sg_list); - iprtd->sg_list = NULL; - return 0; } static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) { - struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct imx_pcm_dma_params *dma_params; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - int err; dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - iprtd->substream = substream; - iprtd->buf = (unsigned int *)substream->dma_buffer.area; - iprtd->period_cnt = 0; - - pr_debug("%s: buf: %p period: %d periods: %d\n", - __func__, iprtd->buf, iprtd->period, iprtd->periods); - - err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, - IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, - substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - DMA_MODE_WRITE : DMA_MODE_READ); - if (err) - return err; - return 0; } @@ -241,14 +203,14 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - imx_dma_enable(iprtd->dma); + dmaengine_submit(iprtd->desc); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - imx_dma_disable(iprtd->dma); + dmaengine_terminate_all(iprtd->dma_chan); break; default: @@ -263,6 +225,9 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; + pr_debug("%s: %ld %ld\n", __func__, iprtd->offset, + bytes_to_frames(substream->runtime, iprtd->offset)); + return bytes_to_frames(substream->runtime, iprtd->offset); } @@ -279,7 +244,7 @@ static struct snd_pcm_hardware snd_imx_hardware = { .channels_max = 2, .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, .period_bytes_min = 128, - .period_bytes_max = 16 * 1024, + .period_bytes_max = 65535, /* Limited by SDMA engine */ .periods_min = 2, .periods_max = 255, .fifo_size = 0, @@ -304,11 +269,23 @@ static int snd_imx_open(struct snd_pcm_substream *substream) } snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); + + return 0; +} + +static int snd_imx_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; + + kfree(iprtd); + return 0; } static struct snd_pcm_ops imx_pcm_ops = { .open = snd_imx_open, + .close = snd_imx_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_imx_pcm_hw_params, .hw_free = snd_imx_pcm_hw_free, @@ -340,7 +317,6 @@ static struct platform_driver imx_pcm_driver = { .name = "imx-pcm-audio", .owner = THIS_MODULE, }, - .probe = imx_soc_platform_probe, .remove = __devexit_p(imx_soc_platform_remove), }; @@ -356,4 +332,3 @@ static void __exit snd_imx_pcm_exit(void) platform_driver_unregister(&imx_pcm_driver); } module_exit(snd_imx_pcm_exit); - diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index d4bd345b0a8d..d2d98c75ee8a 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -439,7 +439,22 @@ void imx_pcm_free(struct snd_pcm *pcm) } EXPORT_SYMBOL_GPL(imx_pcm_free); +static int imx_ssi_dai_probe(struct snd_soc_dai *dai) +{ + struct imx_ssi *ssi = dev_get_drvdata(dai->dev); + uint32_t val; + + snd_soc_dai_set_drvdata(dai, ssi); + + val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | + SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize); + writel(val, ssi->base + SSI_SFCSR); + + return 0; +} + static struct snd_soc_dai_driver imx_ssi_dai = { + .probe = imx_ssi_dai_probe, .playback = { .channels_min = 2, .channels_max = 2, @@ -455,20 +470,6 @@ static struct snd_soc_dai_driver imx_ssi_dai = { .ops = &imx_ssi_pcm_dai_ops, }; -static int imx_ssi_dai_probe(struct snd_soc_dai *dai) -{ - struct imx_ssi *ssi = dev_get_drvdata(dai->dev); - uint32_t val; - - snd_soc_dai_set_drvdata(dai, ssi); - - val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | - SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize); - writel(val, ssi->base + SSI_SFCSR); - - return 0; -} - static struct snd_soc_dai_driver imx_ac97_dai = { .probe = imx_ssi_dai_probe, .ac97_control = 1, @@ -677,7 +678,17 @@ static int imx_ssi_probe(struct platform_device *pdev) goto failed_register; } - ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id); + ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id); + if (!ssi->soc_platform_pdev_fiq) + goto failed_pdev_fiq_alloc; + platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi); + ret = platform_device_add(ssi->soc_platform_pdev_fiq); + if (ret) { + dev_err(&pdev->dev, "failed to add platform device\n"); + goto failed_pdev_fiq_add; + } + + ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id); if (!ssi->soc_platform_pdev) goto failed_pdev_alloc; platform_set_drvdata(ssi->soc_platform_pdev, ssi); @@ -692,6 +703,9 @@ static int imx_ssi_probe(struct platform_device *pdev) failed_pdev_add: platform_device_put(ssi->soc_platform_pdev); failed_pdev_alloc: +failed_pdev_fiq_add: + platform_device_put(ssi->soc_platform_pdev_fiq); +failed_pdev_fiq_alloc: snd_soc_unregister_dai(&pdev->dev); failed_register: failed_ac97: diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h index 53b780d9b2b0..a4406a134892 100644 --- a/sound/soc/imx/imx-ssi.h +++ b/sound/soc/imx/imx-ssi.h @@ -185,6 +185,9 @@ #define DRV_NAME "imx-ssi" +#include <linux/dmaengine.h> +#include <mach/dma.h> + struct imx_pcm_dma_params { int dma; unsigned long dma_addr; @@ -212,6 +215,7 @@ struct imx_ssi { int enabled; struct platform_device *soc_platform_pdev; + struct platform_device *soc_platform_pdev_fiq; }; struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c index 6a65dd705519..39f23734781a 100644 --- a/sound/soc/imx/phycore-ac97.c +++ b/sound/soc/imx/phycore-ac97.c @@ -20,9 +20,6 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include "../codecs/wm9712.h" -#include "imx-ssi.h" - static struct snd_soc_card imx_phycore; static struct snd_soc_ops imx_phycore_hifi_ops = { @@ -41,7 +38,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = { }; static struct snd_soc_card imx_phycore = { - .name = "PhyCORE-audio", + .name = "PhyCORE-ac97-audio", .dai_link = imx_phycore_dai_ac97, .num_links = ARRAY_SIZE(imx_phycore_dai_ac97), }; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4360436ef035..2198936cfb68 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3062,8 +3062,10 @@ int snd_soc_register_dais(struct device *dev, for (i = 0; i < count; i++) { dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); - if (dai == NULL) - return -ENOMEM; + if (dai == NULL) { + ret = -ENOMEM; + goto err; + } /* create DAI component name */ dai->name = fmt_multiple_name(dev, &dai_drv[i]); @@ -3282,9 +3284,6 @@ int snd_soc_register_codec(struct device *dev, return 0; error: - for (i--; i >= 0; i--) - snd_soc_unregister_dai(dev); - if (codec->reg_cache) kfree(codec->reg_cache); kfree(codec->name); |