aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/ux500
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/ux500')
-rw-r--r--sound/soc/ux500/Kconfig6
-rw-r--r--sound/soc/ux500/mop500.c7
-rw-r--r--sound/soc/ux500/mop500_ab8500.c64
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c168
-rw-r--r--sound/soc/ux500/ux500_msp_dai.h9
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c144
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.h77
-rw-r--r--sound/soc/ux500/ux500_pcm.c262
-rw-r--r--sound/soc/ux500/ux500_pcm.h14
9 files changed, 247 insertions, 504 deletions
diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig
index 069330d82be..aa5011894c7 100644
--- a/sound/soc/ux500/Kconfig
+++ b/sound/soc/ux500/Kconfig
@@ -16,12 +16,12 @@ config SND_SOC_UX500_PLAT_MSP_I2S
config SND_SOC_UX500_PLAT_DMA
tristate "Platform - DB8500 (DMA)"
depends on SND_SOC_UX500
- select SND_SOC_DMAENGINE_PCM
+ select SND_SOC_GENERIC_DMAENGINE_PCM
help
Say Y if you want to enable the Ux500 platform-driver.
-+config SND_SOC_UX500_MACH_MOP500
-+ tristate "Machine - MOP500 (Ux500 + AB8500)"
+config SND_SOC_UX500_MACH_MOP500
+ tristate "Machine - MOP500 (Ux500 + AB8500)"
depends on AB8500_CORE && AB8500_GPADC && SND_SOC_UX500
select SND_SOC_AB8500_CODEC
select SND_SOC_UX500_PLAT_MSP_I2S
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index ae699073878..b3b66aa98dc 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -24,10 +24,10 @@
#include "ux500_pcm.h"
#include "ux500_msp_dai.h"
-#include <mop500_ab8500.h>
+#include "mop500_ab8500.h"
/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */
-struct snd_soc_dai_link mop500_dai_links[] = {
+static struct snd_soc_dai_link mop500_dai_links[] = {
{
.name = "ab8500_0",
.stream_name = "ab8500_0",
@@ -52,6 +52,7 @@ struct snd_soc_dai_link mop500_dai_links[] = {
static struct snd_soc_card mop500_card = {
.name = "MOP500-card",
+ .owner = THIS_MODULE,
.probe = NULL,
.dai_link = mop500_dai_links,
.num_links = ARRAY_SIZE(mop500_dai_links),
@@ -90,6 +91,8 @@ static int mop500_of_probe(struct platform_device *pdev,
for (i = 0; i < 2; i++) {
mop500_dai_links[i].cpu_of_node = msp_np[i];
mop500_dai_links[i].cpu_dai_name = NULL;
+ mop500_dai_links[i].platform_of_node = msp_np[i];
+ mop500_dai_links[i].platform_name = NULL;
mop500_dai_links[i].codec_of_node = codec_np;
mop500_dai_links[i].codec_name = NULL;
}
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c
index 78cce236693..be4f1ac7cd5 100644
--- a/sound/soc/ux500/mop500_ab8500.c
+++ b/sound/soc/ux500/mop500_ab8500.c
@@ -16,8 +16,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/clk.h>
-
-#include <mach/hardware.h>
+#include <linux/mutex.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -26,6 +25,7 @@
#include "ux500_pcm.h"
#include "ux500_msp_dai.h"
+#include "mop500_ab8500.h"
#include "../codecs/ab8500-codec.h"
#define TX_SLOT_MONO 0x0008
@@ -45,6 +45,12 @@
static unsigned int tx_slots = DEF_TX_SLOTS;
static unsigned int rx_slots = DEF_RX_SLOTS;
+/* Configuration consistency parameters */
+static DEFINE_MUTEX(mop500_ab8500_params_lock);
+static unsigned long mop500_ab8500_usage;
+static int mop500_ab8500_rate;
+static int mop500_ab8500_channels;
+
/* Clocks */
static const char * const enum_mclk[] = {
"SYSCLK",
@@ -127,9 +133,9 @@ static int mop500_ab8500_set_mclk(struct device *dev,
static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct mop500_ab8500_drvdata *drvdata =
- snd_soc_card_get_drvdata(codec->card);
+ snd_soc_card_get_drvdata(card);
ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;
@@ -139,9 +145,9 @@ static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct mop500_ab8500_drvdata *drvdata =
- snd_soc_card_get_drvdata(codec->card);
+ snd_soc_card_get_drvdata(card);
unsigned int val = ucontrol->value.enumerated.item[0];
if (val > (unsigned int)MCLK_ULPCLK)
@@ -162,16 +168,6 @@ static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
SOC_ENUM_EXT("Master Clock Select",
soc_enum_mclk,
mclk_input_control_get, mclk_input_control_put),
- /* Digital interface - Clocks */
- SOC_SINGLE("Digital Interface Master Generator Switch",
- AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENMASTGEN,
- 1, 0),
- SOC_SINGLE("Digital Interface 0 Bit-clock Switch",
- AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK0,
- 1, 0),
- SOC_SINGLE("Digital Interface 1 Bit-clock Switch",
- AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK1,
- 1, 0),
SOC_DAPM_PIN_SWITCH("Headset Left"),
SOC_DAPM_PIN_SWITCH("Headset Right"),
SOC_DAPM_PIN_SWITCH("Earpiece"),
@@ -195,7 +191,7 @@ static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
/* ASoC */
-int mop500_ab8500_startup(struct snd_pcm_substream *substream)
+static int mop500_ab8500_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -204,7 +200,7 @@ int mop500_ab8500_startup(struct snd_pcm_substream *substream)
snd_soc_card_get_drvdata(rtd->card));
}
-void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
+static void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct device *dev = rtd->card->dev;
@@ -218,7 +214,7 @@ void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
rx_slots = DEF_RX_SLOTS;
}
-int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
+static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -242,6 +238,21 @@ int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
substream->name,
substream->number);
+ /* Ensure configuration consistency between DAIs */
+ mutex_lock(&mop500_ab8500_params_lock);
+ if (mop500_ab8500_usage) {
+ if (mop500_ab8500_rate != params_rate(params) ||
+ mop500_ab8500_channels != params_channels(params)) {
+ mutex_unlock(&mop500_ab8500_params_lock);
+ return -EBUSY;
+ }
+ } else {
+ mop500_ab8500_rate = params_rate(params);
+ mop500_ab8500_channels = params_channels(params);
+ }
+ __set_bit(cpu_dai->id, &mop500_ab8500_usage);
+ mutex_unlock(&mop500_ab8500_params_lock);
+
channels = params_channels(params);
switch (params_format(params)) {
@@ -340,9 +351,22 @@ int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
return 0;
}
+static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ mutex_lock(&mop500_ab8500_params_lock);
+ __clear_bit(cpu_dai->id, &mop500_ab8500_usage);
+ mutex_unlock(&mop500_ab8500_params_lock);
+
+ return 0;
+}
+
struct snd_soc_ops mop500_ab8500_ops[] = {
{
.hw_params = mop500_ab8500_hw_params,
+ .hw_free = mop500_ab8500_hw_free,
.startup = mop500_ab8500_startup,
.shutdown = mop500_ab8500_shutdown,
}
@@ -387,7 +411,7 @@ int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
drvdata->mclk_sel = MCLK_ULPCLK;
/* Add controls */
- ret = snd_soc_add_codec_controls(codec, mop500_ab8500_ctrls,
+ ret = snd_soc_add_card_controls(rtd->card, mop500_ab8500_ctrls,
ARRAY_SIZE(mop500_ab8500_ctrls));
if (ret < 0) {
pr_err("%s: Failed to add machine-controls (%d)!\n",
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 94a3e5705aa..5f4807b2c00 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -17,14 +17,14 @@
#include <linux/bitops.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/dbx500-prcmu.h>
-
-#include <mach/hardware.h>
-#include <mach/msp.h>
+#include <linux/platform_data/asoc-ux500-msp.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
+#include <sound/dmaengine_pcm.h>
#include "ux500_msp_i2s.h"
#include "ux500_msp_dai.h"
@@ -656,19 +656,52 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
return ret;
}
-static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
+static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai)
{
struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
+ struct snd_dmaengine_dai_dma_data *playback_dma_data;
+ struct snd_dmaengine_dai_dma_data *capture_dma_data;
+
+ playback_dma_data = devm_kzalloc(dai->dev,
+ sizeof(*playback_dma_data),
+ GFP_KERNEL);
+ if (!playback_dma_data)
+ return -ENOMEM;
+
+ capture_dma_data = devm_kzalloc(dai->dev,
+ sizeof(*capture_dma_data),
+ GFP_KERNEL);
+ if (!capture_dma_data)
+ return -ENOMEM;
+
+ playback_dma_data->addr = drvdata->msp->playback_dma_data.tx_rx_addr;
+ capture_dma_data->addr = drvdata->msp->capture_dma_data.tx_rx_addr;
+
+ playback_dma_data->maxburst = 4;
+ capture_dma_data->maxburst = 4;
- drvdata->playback_dma_data.dma_cfg = drvdata->msp->dma_cfg_tx;
- drvdata->capture_dma_data.dma_cfg = drvdata->msp->dma_cfg_rx;
+ snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data);
+
+ return 0;
+}
+
+static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
+{
+ struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
+ struct msp_i2s_platform_data *pdata = dai->dev->platform_data;
+ int ret;
- dai->playback_dma_data = &drvdata->playback_dma_data;
- dai->capture_dma_data = &drvdata->capture_dma_data;
+ if (!pdata) {
+ ret = ux500_msp_dai_of_probe(dai);
+ return ret;
+ }
- drvdata->playback_dma_data.data_size = drvdata->slot_width;
- drvdata->capture_dma_data.data_size = drvdata->slot_width;
+ drvdata->msp->playback_dma_data.data_size = drvdata->slot_width;
+ drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;
+ snd_soc_dai_init_dma_data(dai,
+ &drvdata->msp->playback_dma_data,
+ &drvdata->msp->capture_dma_data);
return 0;
}
@@ -685,96 +718,37 @@ static struct snd_soc_dai_ops ux500_msp_dai_ops[] = {
}
};
-static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = {
- {
- .name = "ux500-msp-i2s.0",
- .probe = ux500_msp_dai_probe,
- .id = 0,
- .suspend = NULL,
- .resume = NULL,
- .playback = {
- .channels_min = UX500_MSP_MIN_CHANNELS,
- .channels_max = UX500_MSP_MAX_CHANNELS,
- .rates = UX500_I2S_RATES,
- .formats = UX500_I2S_FORMATS,
- },
- .capture = {
- .channels_min = UX500_MSP_MIN_CHANNELS,
- .channels_max = UX500_MSP_MAX_CHANNELS,
- .rates = UX500_I2S_RATES,
- .formats = UX500_I2S_FORMATS,
- },
- .ops = ux500_msp_dai_ops,
- },
- {
- .name = "ux500-msp-i2s.1",
- .probe = ux500_msp_dai_probe,
- .id = 1,
- .suspend = NULL,
- .resume = NULL,
- .playback = {
- .channels_min = UX500_MSP_MIN_CHANNELS,
- .channels_max = UX500_MSP_MAX_CHANNELS,
- .rates = UX500_I2S_RATES,
- .formats = UX500_I2S_FORMATS,
- },
- .capture = {
- .channels_min = UX500_MSP_MIN_CHANNELS,
- .channels_max = UX500_MSP_MAX_CHANNELS,
- .rates = UX500_I2S_RATES,
- .formats = UX500_I2S_FORMATS,
- },
- .ops = ux500_msp_dai_ops,
- },
- {
- .name = "ux500-msp-i2s.2",
- .id = 2,
- .probe = ux500_msp_dai_probe,
- .suspend = NULL,
- .resume = NULL,
- .playback = {
- .channels_min = UX500_MSP_MIN_CHANNELS,
- .channels_max = UX500_MSP_MAX_CHANNELS,
- .rates = UX500_I2S_RATES,
- .formats = UX500_I2S_FORMATS,
- },
- .capture = {
- .channels_min = UX500_MSP_MIN_CHANNELS,
- .channels_max = UX500_MSP_MAX_CHANNELS,
- .rates = UX500_I2S_RATES,
- .formats = UX500_I2S_FORMATS,
- },
- .ops = ux500_msp_dai_ops,
- },
- {
- .name = "ux500-msp-i2s.3",
- .probe = ux500_msp_dai_probe,
- .id = 3,
- .suspend = NULL,
- .resume = NULL,
- .playback = {
- .channels_min = UX500_MSP_MIN_CHANNELS,
- .channels_max = UX500_MSP_MAX_CHANNELS,
- .rates = UX500_I2S_RATES,
- .formats = UX500_I2S_FORMATS,
- },
- .capture = {
- .channels_min = UX500_MSP_MIN_CHANNELS,
- .channels_max = UX500_MSP_MAX_CHANNELS,
- .rates = UX500_I2S_RATES,
- .formats = UX500_I2S_FORMATS,
- },
- .ops = ux500_msp_dai_ops,
- },
+static struct snd_soc_dai_driver ux500_msp_dai_drv = {
+ .probe = ux500_msp_dai_probe,
+ .suspend = NULL,
+ .resume = NULL,
+ .playback.channels_min = UX500_MSP_MIN_CHANNELS,
+ .playback.channels_max = UX500_MSP_MAX_CHANNELS,
+ .playback.rates = UX500_I2S_RATES,
+ .playback.formats = UX500_I2S_FORMATS,
+ .capture.channels_min = UX500_MSP_MIN_CHANNELS,
+ .capture.channels_max = UX500_MSP_MAX_CHANNELS,
+ .capture.rates = UX500_I2S_RATES,
+ .capture.formats = UX500_I2S_FORMATS,
+ .ops = ux500_msp_dai_ops,
};
+static const struct snd_soc_component_driver ux500_msp_component = {
+ .name = "ux500-msp",
+};
+
+
static int ux500_msp_drv_probe(struct platform_device *pdev)
{
struct ux500_msp_i2s_drvdata *drvdata;
+ struct msp_i2s_platform_data *pdata = pdev->dev.platform_data;
+ struct device_node *np = pdev->dev.of_node;
int ret = 0;
- dev_dbg(&pdev->dev, "%s: Enter (pdev->name = %s).\n", __func__,
- pdev->name);
+ if (!pdata && !np) {
+ dev_err(&pdev->dev, "No platform data or Device Tree found\n");
+ return -ENODEV;
+ }
drvdata = devm_kzalloc(&pdev->dev,
sizeof(struct ux500_msp_i2s_drvdata),
@@ -825,8 +799,8 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
}
dev_set_drvdata(&pdev->dev, drvdata);
- ret = snd_soc_register_dai(&pdev->dev,
- &ux500_msp_dai_drv[drvdata->msp->id]);
+ ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component,
+ &ux500_msp_dai_drv, 1);
if (ret < 0) {
dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n",
__func__, drvdata->msp->id);
@@ -844,7 +818,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
return 0;
err_reg_plat:
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv));
+ snd_soc_unregister_component(&pdev->dev);
err_init_msp:
clk_put(drvdata->clk);
err_clk:
@@ -861,7 +835,7 @@ static int ux500_msp_drv_remove(struct platform_device *pdev)
ux500_pcm_unregister_platform(pdev);
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv));
+ snd_soc_unregister_component(&pdev->dev);
devm_regulator_put(drvdata->reg_vape);
prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s");
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index 9c778d9c383..312ae535e35 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -35,13 +35,8 @@
#define FRAME_PER_8_SLOTS 138
#define FRAME_PER_16_SLOTS 277
-#ifndef CONFIG_SND_SOC_UX500_AB5500
#define UX500_MSP_INTERNAL_CLOCK_FREQ 40000000
#define UX500_MSP1_INTERNAL_CLOCK_FREQ UX500_MSP_INTERNAL_CLOCK_FREQ
-#else
-#define UX500_MSP_INTERNAL_CLOCK_FREQ 13000000
-#define UX500_MSP1_INTERNAL_CLOCK_FREQ (UX500_MSP_INTERNAL_CLOCK_FREQ * 2)
-#endif
#define UX500_MSP_MIN_CHANNELS 1
#define UX500_MSP_MAX_CHANNELS 8
@@ -56,15 +51,11 @@ enum ux500_msp_clock_id {
struct ux500_msp_i2s_drvdata {
struct ux500_msp *msp;
struct regulator *reg_vape;
- struct ux500_msp_dma_params playback_dma_data;
- struct ux500_msp_dma_params capture_dma_data;
unsigned int fmt;
unsigned int tx_mask;
unsigned int rx_mask;
int slots;
int slot_width;
- u8 configured;
- int data_delay;
/* Clocks */
unsigned int master_clk;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index a26c6bf0a29..959d7b4edf5 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -15,22 +15,16 @@
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/pinctrl/consumer.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of.h>
-
-#include <mach/hardware.h>
-#include <mach/msp.h>
+#include <linux/platform_data/asoc-ux500-msp.h>
#include <sound/soc.h>
#include "ux500_msp_i2s.h"
-/* MSP1/3 Tx/Rx usage protection */
-static DEFINE_SPINLOCK(msp_rxtx_lock);
-
/* Protocol desciptors */
static const struct msp_protdesc prot_descs[] = {
{ /* I2S */
@@ -358,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp,
static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
{
- int status = 0, retval = 0;
+ int status = 0;
u32 reg_val_DMACR, reg_val_GCR;
- unsigned long flags;
-
- /* Check msp state whether in RUN or CONFIGURED Mode */
- if (msp->msp_state == MSP_STATE_IDLE) {
- spin_lock_irqsave(&msp_rxtx_lock, flags);
- if (msp->pinctrl_rxtx_ref == 0 &&
- !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) {
- retval = pinctrl_select_state(msp->pinctrl_p,
- msp->pinctrl_def);
- if (retval)
- pr_err("could not set MSP defstate\n");
- }
- if (!retval)
- msp->pinctrl_rxtx_ref++;
- spin_unlock_irqrestore(&msp_rxtx_lock, flags);
- }
/* Configure msp with protocol dependent settings */
configure_protocol(msp, config);
@@ -389,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
}
/* Make sure the correct DMA-directions are configured */
- if ((config->direction & MSP_DIR_RX) && (!msp->dma_cfg_rx)) {
+ if ((config->direction & MSP_DIR_RX) &&
+ !msp->capture_dma_data.dma_cfg) {
dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
__func__);
return -EINVAL;
}
- if ((config->direction == MSP_DIR_TX) && (!msp->dma_cfg_tx)) {
+ if ((config->direction == MSP_DIR_TX) &&
+ !msp->playback_dma_data.dma_cfg) {
dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
__func__);
return -EINVAL;
@@ -632,8 +612,7 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
{
- int status = 0, retval = 0;
- unsigned long flags;
+ int status = 0;
dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
@@ -645,18 +624,6 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
(~(FRAME_GEN_ENABLE | SRG_ENABLE))),
msp->registers + MSP_GCR);
- spin_lock_irqsave(&msp_rxtx_lock, flags);
- WARN_ON(!msp->pinctrl_rxtx_ref);
- msp->pinctrl_rxtx_ref--;
- if (msp->pinctrl_rxtx_ref == 0 &&
- !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) {
- retval = pinctrl_select_state(msp->pinctrl_p,
- msp->pinctrl_sleep);
- if (retval)
- pr_err("could not set MSP sleepstate\n");
- }
- spin_unlock_irqrestore(&msp_rxtx_lock, flags);
-
writel(0, msp->registers + MSP_GCR);
writel(0, msp->registers + MSP_TCF);
writel(0, msp->registers + MSP_RCF);
@@ -679,38 +646,63 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
}
+static int ux500_msp_i2s_of_init_msp(struct platform_device *pdev,
+ struct ux500_msp *msp,
+ struct msp_i2s_platform_data **platform_data)
+{
+ struct msp_i2s_platform_data *pdata;
+
+ *platform_data = devm_kzalloc(&pdev->dev,
+ sizeof(struct msp_i2s_platform_data),
+ GFP_KERNEL);
+ pdata = *platform_data;
+ if (!pdata)
+ return -ENOMEM;
+
+ msp->playback_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
+ sizeof(struct stedma40_chan_cfg),
+ GFP_KERNEL);
+ if (!msp->playback_dma_data.dma_cfg)
+ return -ENOMEM;
+
+ msp->capture_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
+ sizeof(struct stedma40_chan_cfg),
+ GFP_KERNEL);
+ if (!msp->capture_dma_data.dma_cfg)
+ return -ENOMEM;
+
+ return 0;
+}
+
int ux500_msp_i2s_init_msp(struct platform_device *pdev,
struct ux500_msp **msp_p,
struct msp_i2s_platform_data *platform_data)
{
struct resource *res = NULL;
- struct i2s_controller *i2s_cont;
struct device_node *np = pdev->dev.of_node;
struct ux500_msp *msp;
+ int ret;
*msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
msp = *msp_p;
if (!msp)
return -ENOMEM;
- if (np) {
- if (!platform_data) {
- platform_data = devm_kzalloc(&pdev->dev,
- sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
- if (!platform_data)
- return -ENOMEM;
- }
- } else
- if (!platform_data)
+ if (!platform_data) {
+ if (np) {
+ ret = ux500_msp_i2s_of_init_msp(pdev, msp,
+ &platform_data);
+ if (ret)
+ return ret;
+ } else
return -EINVAL;
+ } else {
+ msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
+ msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
+ msp->id = platform_data->id;
+ }
- dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
- pdev->name, platform_data->id);
-
- msp->id = platform_data->id;
msp->dev = &pdev->dev;
- msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx;
- msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
@@ -719,6 +711,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
return -ENOMEM;
}
+ msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR;
+ msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR;
+
msp->registers = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (msp->registers == NULL) {
@@ -729,41 +724,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
msp->msp_state = MSP_STATE_IDLE;
msp->loopback_enable = 0;
- /* I2S-controller is allocated and added in I2S controller class. */
- i2s_cont = devm_kzalloc(&pdev->dev, sizeof(*i2s_cont), GFP_KERNEL);
- if (!i2s_cont) {
- dev_err(&pdev->dev,
- "%s: ERROR: Failed to allocate I2S-controller!\n",
- __func__);
- return -ENOMEM;
- }
- i2s_cont->dev.parent = &pdev->dev;
- i2s_cont->data = (void *)msp;
- i2s_cont->id = (s16)msp->id;
- snprintf(i2s_cont->name, sizeof(i2s_cont->name), "ux500-msp-i2s.%04x",
- msp->id);
- dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name);
- msp->i2s_cont = i2s_cont;
-
- msp->pinctrl_p = pinctrl_get(msp->dev);
- if (IS_ERR(msp->pinctrl_p))
- dev_err(&pdev->dev, "could not get MSP pinctrl\n");
- else {
- msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p,
- PINCTRL_STATE_DEFAULT);
- if (IS_ERR(msp->pinctrl_def)) {
- dev_err(&pdev->dev,
- "could not get MSP defstate (%li)\n",
- PTR_ERR(msp->pinctrl_def));
- }
- msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p,
- PINCTRL_STATE_SLEEP);
- if (IS_ERR(msp->pinctrl_sleep))
- dev_err(&pdev->dev,
- "could not get MSP idlestate (%li)\n",
- PTR_ERR(msp->pinctrl_def));
- }
-
return 0;
}
@@ -771,8 +731,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
struct ux500_msp *msp)
{
dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
-
- device_unregister(&msp->i2s_cont->dev);
}
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 1311c0df762..875de0f68b8 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -16,8 +16,7 @@
#define UX500_MSP_I2S_H
#include <linux/platform_device.h>
-
-#include <mach/msp.h>
+#include <linux/platform_data/asoc-ux500-msp.h>
#define MSP_INPUT_FREQ_APB 48000000
@@ -343,11 +342,6 @@ enum msp_compress_mode {
MSP_COMPRESS_MODE_A_LAW = 3
};
-enum msp_spi_burst_mode {
- MSP_SPI_BURST_MODE_DISABLE = 0,
- MSP_SPI_BURST_MODE_ENABLE = 1
-};
-
enum msp_expand_mode {
MSP_EXPAND_MODE_LINEAR = 0,
MSP_EXPAND_MODE_LINEAR_SIGNED = 1,
@@ -372,13 +366,6 @@ enum msp_protocol {
*/
#define MAX_MSP_BACKUP_REGS 36
-enum enum_i2s_controller {
- MSP_0_I2S_CONTROLLER = 0,
- MSP_1_I2S_CONTROLLER,
- MSP_2_I2S_CONTROLLER,
- MSP_3_I2S_CONTROLLER,
-};
-
enum i2s_direction_t {
MSP_DIR_TX = 0x01,
MSP_DIR_RX = 0x02,
@@ -456,32 +443,6 @@ struct msp_protdesc {
u32 clocks_per_frame;
};
-struct i2s_message {
- enum i2s_direction_t i2s_direction;
- void *txdata;
- void *rxdata;
- size_t txbytes;
- size_t rxbytes;
- int dma_flag;
- int tx_offset;
- int rx_offset;
- bool cyclic_dma;
- dma_addr_t buf_addr;
- size_t buf_len;
- size_t period_len;
-};
-
-struct i2s_controller {
- struct module *owner;
- unsigned int id;
- unsigned int class;
- const struct i2s_algorithm *algo; /* the algorithm to access the bus */
- void *data;
- struct mutex bus_lock;
- struct device dev; /* the controller device */
- char name[48];
-};
-
struct ux500_msp_config {
unsigned int f_inputclk;
unsigned int rx_clk_sel;
@@ -493,8 +454,6 @@ struct ux500_msp_config {
unsigned int tx_fsync_sel;
unsigned int rx_fifo_config;
unsigned int tx_fifo_config;
- unsigned int spi_clk_mode;
- unsigned int spi_burst_mode;
unsigned int loopback_enable;
unsigned int tx_data_enable;
unsigned int default_protdesc;
@@ -504,45 +463,31 @@ struct ux500_msp_config {
unsigned int direction;
unsigned int protocol;
unsigned int frame_freq;
- unsigned int frame_size;
enum msp_data_size data_size;
unsigned int def_elem_len;
unsigned int iodelay;
- void (*handler) (void *data);
- void *tx_callback_data;
- void *rx_callback_data;
+};
+
+struct ux500_msp_dma_params {
+ unsigned int data_size;
+ dma_addr_t tx_rx_addr;
+ struct stedma40_chan_cfg *dma_cfg;
};
struct ux500_msp {
- enum enum_i2s_controller id;
+ int id;
void __iomem *registers;
struct device *dev;
- struct i2s_controller *i2s_cont;
- struct stedma40_chan_cfg *dma_cfg_rx;
- struct stedma40_chan_cfg *dma_cfg_tx;
- struct dma_chan *tx_pipeid;
- struct dma_chan *rx_pipeid;
+ struct ux500_msp_dma_params playback_dma_data;
+ struct ux500_msp_dma_params capture_dma_data;
enum msp_state msp_state;
- int (*transfer) (struct ux500_msp *msp, struct i2s_message *message);
- struct timer_list notify_timer;
int def_elem_len;
unsigned int dir_busy;
int loopback_enable;
- u32 backup_regs[MAX_MSP_BACKUP_REGS];
unsigned int f_bitclk;
- /* Pin modes */
- struct pinctrl *pinctrl_p;
- struct pinctrl_state *pinctrl_def;
- struct pinctrl_state *pinctrl_sleep;
- /* Reference Count */
- int pinctrl_rxtx_ref;
-};
-
-struct ux500_msp_dma_params {
- unsigned int data_size;
- struct stedma40_chan_cfg *dma_cfg;
};
+struct msp_i2s_platform_data;
int ux500_msp_i2s_init_msp(struct platform_device *pdev,
struct ux500_msp **msp_p,
struct msp_i2s_platform_data *platform_data);
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 846fa82a58d..51a66a87305 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -28,41 +28,17 @@
#include "ux500_msp_i2s.h"
#include "ux500_pcm.h"
-static struct snd_pcm_hardware ux500_pcm_hw_playback = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_PAUSE,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_LE |
- SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_U16_BE,
- .rates = SNDRV_PCM_RATE_KNOT,
- .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
- .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
- .channels_min = UX500_PLATFORM_MIN_CHANNELS,
- .channels_max = UX500_PLATFORM_MAX_CHANNELS,
- .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
- .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
- .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
- .periods_min = UX500_PLATFORM_PERIODS_MIN,
- .periods_max = UX500_PLATFORM_PERIODS_MAX,
-};
+#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
+#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
+#define UX500_PLATFORM_PERIODS_MIN 2
+#define UX500_PLATFORM_PERIODS_MAX 48
+#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
-static struct snd_pcm_hardware ux500_pcm_hw_capture = {
+static const struct snd_pcm_hardware ux500_pcm_hw = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_PAUSE,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_LE |
- SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_U16_BE,
- .rates = SNDRV_PCM_RATE_KNOT,
- .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE,
- .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE,
- .channels_min = UX500_PLATFORM_MIN_CHANNELS,
- .channels_max = UX500_PLATFORM_MAX_CHANNELS,
.buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
.period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
.period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
@@ -70,83 +46,33 @@ static struct snd_pcm_hardware ux500_pcm_hw_capture = {
.periods_max = UX500_PLATFORM_PERIODS_MAX,
};
-static void ux500_pcm_dma_hw_free(struct device *dev,
- struct snd_pcm_substream *substream)
+static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_substream *substream)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_dma_buffer *buf = runtime->dma_buffer_p;
-
- if (runtime->dma_area == NULL)
- return;
-
- if (buf != &substream->dma_buffer) {
- dma_free_coherent(buf->dev.dev, buf->bytes, buf->area,
- buf->addr);
- kfree(runtime->dma_buffer_p);
- }
-
- snd_pcm_set_runtime_buffer(substream, NULL);
-}
-
-static int ux500_pcm_open(struct snd_pcm_substream *substream)
-{
- int stream_id = substream->pstr->stream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *dai = rtd->cpu_dai;
- struct device *dev = dai->dev;
- int ret;
- struct ux500_msp_dma_params *dma_params;
u16 per_data_width, mem_data_width;
struct stedma40_chan_cfg *dma_cfg;
+ struct ux500_msp_dma_params *dma_params;
- dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
- snd_pcm_stream_str(substream));
-
- dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__);
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
- snd_soc_set_runtime_hwparams(substream,
- &ux500_pcm_hw_playback);
- else
- snd_soc_set_runtime_hwparams(substream,
- &ux500_pcm_hw_capture);
-
- /* ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0) {
- dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n",
- __func__, ret);
- return ret;
- }
-
- dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__,
- snd_pcm_stream_str(substream));
- runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
- ux500_pcm_hw_playback : ux500_pcm_hw_capture;
+ dma_params = snd_soc_dai_get_dma_data(dai, substream);
+ dma_cfg = dma_params->dma_cfg;
- mem_data_width = STEDMA40_HALFWORD_WIDTH;
+ mem_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
- dma_params = snd_soc_dai_get_dma_data(dai, substream);
switch (dma_params->data_size) {
case 32:
- per_data_width = STEDMA40_WORD_WIDTH;
+ per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
break;
case 16:
- per_data_width = STEDMA40_HALFWORD_WIDTH;
+ per_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
break;
case 8:
- per_data_width = STEDMA40_BYTE_WIDTH;
+ per_data_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
break;
default:
- per_data_width = STEDMA40_WORD_WIDTH;
- dev_warn(rtd->platform->dev,
- "%s: Unknown data-size (%d)! Assuming 32 bits.\n",
- __func__, dma_params->data_size);
+ per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
}
- dma_cfg = dma_params->dma_cfg;
-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
dma_cfg->src_info.data_width = mem_data_width;
dma_cfg->dst_info.data_width = per_data_width;
@@ -155,137 +81,74 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream)
dma_cfg->dst_info.data_width = mem_data_width;
}
-
- ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg);
- if (ret) {
- dev_dbg(dai->dev,
- "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n",
- __func__, ret);
- return ret;
- }
-
- snd_dmaengine_pcm_set_data(substream, dma_cfg);
-
- return 0;
-}
-
-static int ux500_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *dai = rtd->cpu_dai;
-
- dev_dbg(dai->dev, "%s: Enter\n", __func__);
-
- snd_dmaengine_pcm_close(substream);
-
- return 0;
+ return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg);
}
-static int ux500_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
+static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct dma_slave_config *slave_config)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_dma_buffer *buf = runtime->dma_buffer_p;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int ret = 0;
- int size;
-
- dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__);
-
- size = params_buffer_bytes(hw_params);
-
- if (buf) {
- if (buf->bytes >= size)
- goto out;
- ux500_pcm_dma_hw_free(NULL, substream);
- }
+ struct msp_i2s_platform_data *pdata = rtd->cpu_dai->dev->platform_data;
+ struct snd_dmaengine_dai_dma_data *snd_dma_params;
+ struct ux500_msp_dma_params *ste_dma_params;
+ dma_addr_t dma_addr;
+ int ret;
- if (substream->dma_buffer.area != NULL &&
- substream->dma_buffer.bytes >= size) {
- buf = &substream->dma_buffer;
+ if (pdata) {
+ ste_dma_params =
+ snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ dma_addr = ste_dma_params->tx_rx_addr;
} else {
- buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
- if (!buf)
- goto nomem;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = NULL;
- buf->area = dma_alloc_coherent(NULL, size, &buf->addr,
- GFP_KERNEL);
- buf->bytes = size;
- buf->private_data = NULL;
-
- if (!buf->area)
- goto free;
+ snd_dma_params =
+ snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ dma_addr = snd_dma_params->addr;
}
- snd_pcm_set_runtime_buffer(substream, buf);
- ret = 1;
- out:
- runtime->dma_bytes = size;
- return ret;
- free:
- kfree(buf);
- nomem:
- return -ENOMEM;
-}
+ ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
+ if (ret)
+ return ret;
-static int ux500_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ slave_config->dst_maxburst = 4;
+ slave_config->src_maxburst = 4;
- dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__);
+ slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
- ux500_pcm_dma_hw_free(NULL, substream);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ slave_config->dst_addr = dma_addr;
+ else
+ slave_config->src_addr = dma_addr;
return 0;
}
-static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
- dev_dbg(rtd->platform->dev, "%s: Enter.\n", __func__);
-
- return dma_mmap_coherent(NULL, vma, runtime->dma_area,
- runtime->dma_addr, runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops ux500_pcm_ops = {
- .open = ux500_pcm_open,
- .close = ux500_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = ux500_pcm_hw_params,
- .hw_free = ux500_pcm_hw_free,
- .trigger = snd_dmaengine_pcm_trigger,
- .pointer = snd_dmaengine_pcm_pointer_no_residue,
- .mmap = ux500_pcm_mmap
+static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = {
+ .pcm_hardware = &ux500_pcm_hw,
+ .compat_request_channel = ux500_pcm_request_chan,
+ .prealloc_buffer_size = 128 * 1024,
+ .prepare_slave_config = ux500_pcm_prepare_slave_config,
};
-int ux500_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_pcm *pcm = rtd->pcm;
-
- dev_dbg(rtd->platform->dev, "%s: Enter (id = '%s').\n", __func__,
- pcm->id);
-
- pcm->info_flags = 0;
-
- return 0;
-}
-
-static struct snd_soc_platform_driver ux500_pcm_soc_drv = {
- .ops = &ux500_pcm_ops,
- .pcm_new = ux500_pcm_new,
+static const struct snd_dmaengine_pcm_config ux500_dmaengine_of_pcm_config = {
+ .compat_request_channel = ux500_pcm_request_chan,
+ .prepare_slave_config = ux500_pcm_prepare_slave_config,
};
int ux500_pcm_register_platform(struct platform_device *pdev)
{
+ const struct snd_dmaengine_pcm_config *pcm_config;
+ struct device_node *np = pdev->dev.of_node;
int ret;
- ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv);
+ if (np)
+ pcm_config = &ux500_dmaengine_of_pcm_config;
+ else
+ pcm_config = &ux500_dmaengine_pcm_config;
+
+ ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config,
+ SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
+ SND_DMAENGINE_PCM_FLAG_COMPAT);
if (ret < 0) {
dev_err(&pdev->dev,
"%s: ERROR: Failed to register platform '%s' (%d)!\n",
@@ -299,8 +162,7 @@ EXPORT_SYMBOL_GPL(ux500_pcm_register_platform);
int ux500_pcm_unregister_platform(struct platform_device *pdev)
{
- snd_soc_unregister_platform(&pdev->dev);
-
+ snd_dmaengine_pcm_unregister(&pdev->dev);
return 0;
}
EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform);
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
index 76d344476af..d76e1aff645 100644
--- a/sound/soc/ux500/ux500_pcm.h
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -18,20 +18,6 @@
#include <linux/workqueue.h>
-#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000
-#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000
-#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000
-#define UX500_PLATFORM_MAX_RATE_CAPTURE 48000
-
-#define UX500_PLATFORM_MIN_CHANNELS 1
-#define UX500_PLATFORM_MAX_CHANNELS 8
-
-#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
-#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
-#define UX500_PLATFORM_PERIODS_MIN 2
-#define UX500_PLATFORM_PERIODS_MAX 48
-#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
-
int ux500_pcm_register_platform(struct platform_device *pdev);
int ux500_pcm_unregister_platform(struct platform_device *pdev);