summaryrefslogtreecommitdiff
path: root/sound/soc/imx
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/imx')
-rw-r--r--sound/soc/imx/imx-3stack-ak4647.c17
-rw-r--r--sound/soc/imx/imx-3stack-ak5702.c7
-rw-r--r--sound/soc/imx/imx-3stack-bt.c19
-rw-r--r--sound/soc/imx/imx-3stack-sgtl5000.c98
-rw-r--r--sound/soc/imx/imx-3stack-wm8350.c77
-rw-r--r--sound/soc/imx/imx-3stack-wm8580.c7
-rw-r--r--sound/soc/imx/imx-esai.c131
-rw-r--r--sound/soc/imx/imx-esai.h7
-rw-r--r--sound/soc/imx/imx-ssi.c167
-rw-r--r--sound/soc/imx/imx-ssi.h8
10 files changed, 298 insertions, 240 deletions
diff --git a/sound/soc/imx/imx-3stack-ak4647.c b/sound/soc/imx/imx-3stack-ak4647.c
index ed97f8130ec6..bb3606c57fd4 100644
--- a/sound/soc/imx/imx-3stack-ak4647.c
+++ b/sound/soc/imx/imx-3stack-ak4647.c
@@ -106,6 +106,7 @@ static int imx_3stack_hifi_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = pcm_link->codec_dai;
unsigned int channels = params_channels(params);
unsigned int rate = params_rate(params);
+ struct imx_ssi *ssi_mode = (struct imx_ssi *)cpu_dai->private_data;
int ret = 0;
u32 dai_format;
@@ -117,6 +118,12 @@ static int imx_3stack_hifi_hw_params(struct snd_pcm_substream *substream,
SND_SOC_DAIFMT_CBS_CFS;
#endif
+ ssi_mode->sync_mode = 1;
+ if (channels == 1)
+ ssi_mode->network_mode = 0;
+ else
+ ssi_mode->network_mode = 1;
+
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
if (ret < 0)
@@ -318,7 +325,6 @@ static int imx_3stack_ak4647_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link imx_3stack_dai = {
.name = "ak4647",
.stream_name = "ak4647",
- .cpu_dai = &imx_ssi_dai,
.codec_dai = &ak4647_hifi_dai,
.init = imx_3stack_ak4647_init,
.ops = &imx_3stack_hifi_ops,
@@ -345,18 +351,17 @@ static int __init imx_3stack_ak4647_probe(struct platform_device *pdev)
{
struct mxc_audio_platform_data *dev_data = pdev->dev.platform_data;
struct imx_3stack_priv *priv = &card_priv;
+ struct snd_soc_dai *ak4647_cpu_dai;
int ret = 0;
dev_data->init();
if (dev_data->src_port == 1)
- imx_ssi_dai.name = "imx-ssi-1";
+ ak4647_cpu_dai = &imx_ssi_dai[0];
else
- imx_ssi_dai.name = "imx-ssi-3";
+ ak4647_cpu_dai = &imx_ssi_dai[2];
- imx_ssi_dai.dev = &pdev->dev;
- imx_ssi_dai.symmetric_rates = 1;
- snd_soc_register_dai(&imx_ssi_dai);
+ imx_3stack_dai.cpu_dai = ak4647_cpu_dai;
/* Configure audio port 3 */
gpio_activate_audio_ports();
diff --git a/sound/soc/imx/imx-3stack-ak5702.c b/sound/soc/imx/imx-3stack-ak5702.c
index a13a57ab671a..7603c0f0ae19 100644
--- a/sound/soc/imx/imx-3stack-ak5702.c
+++ b/sound/soc/imx/imx-3stack-ak5702.c
@@ -65,6 +65,7 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = pcm_link->cpu_dai;
struct snd_soc_dai *codec_dai = pcm_link->codec_dai;
unsigned int rate = params_rate(params);
+ struct imx_esai *esai_mode = (struct imx_esai *)cpu_dai->private_data;
u32 dai_format;
if (clk_state.lr_clk_active > 1)
@@ -73,6 +74,9 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream,
dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;
+ esai_mode->sync_mode = 0;
+ esai_mode->network_mode = 1;
+
/* set codec DAI configuration */
snd_soc_dai_set_fmt(codec_dai, dai_format);
@@ -130,7 +134,6 @@ static int imx_3stack_ak5702_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link imx_3stack_dai = {
.name = "ak5702",
.stream_name = "ak5702",
- .cpu_dai = &imx_esai_dai,
.codec_dai = &ak5702_dai,
.init = imx_3stack_ak5702_init,
.ops = &imx_3stack_surround_ops,
@@ -161,7 +164,7 @@ static int __devinit imx_3stack_ak5702_probe(struct platform_device *pdev)
{
struct ak5702_setup_data *setup;
- imx_esai_dai.name = "imx-esai-txrx";
+ imx_3stack_dai.cpu_dai = &imx_esai_dai[2];
setup = kzalloc(sizeof(struct ak5702_setup_data), GFP_KERNEL);
setup->i2c_bus = 1;
diff --git a/sound/soc/imx/imx-3stack-bt.c b/sound/soc/imx/imx-3stack-bt.c
index ca0679797df8..28d47eeba62d 100644
--- a/sound/soc/imx/imx-3stack-bt.c
+++ b/sound/soc/imx/imx-3stack-bt.c
@@ -105,6 +105,7 @@ static int imx_3stack_bt_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai_link *pcm_link = rtd->dai;
struct snd_soc_dai *cpu_dai = pcm_link->cpu_dai;
unsigned int channels = params_channels(params);
+ struct imx_ssi *ssi_mode = (struct imx_ssi *)cpu_dai->private_data;
int ret = 0;
u32 dai_format;
@@ -116,6 +117,12 @@ static int imx_3stack_bt_hw_params(struct snd_pcm_substream *substream,
SND_SOC_DAIFMT_CBS_CFS;
#endif
+ ssi_mode->sync_mode = 1;
+ if (channels == 1)
+ ssi_mode->network_mode = 0;
+ else
+ ssi_mode->network_mode = 1;
+
/* set i.MX active slot mask */
snd_soc_dai_set_tdm_slot(cpu_dai,
channels == 1 ? 0xfffffffe : 0xfffffffc, 2);
@@ -152,7 +159,6 @@ static struct snd_soc_ops imx_3stack_bt_ops = {
static struct snd_soc_dai_link imx_3stack_dai = {
.name = "bluetooth",
.stream_name = "bluetooth",
- .cpu_dai = &imx_ssi_dai,
.codec_dai = &bt_dai,
.ops = &imx_3stack_bt_ops,
};
@@ -178,17 +184,14 @@ static int __init imx_3stack_bt_probe(struct platform_device *pdev)
{
struct mxc_audio_platform_data *dev_data = pdev->dev.platform_data;
struct imx_3stack_priv *priv = &card_priv;
-
- /* imx_3stack bt interface */
- imx_ssi_dai.private_data = dev_data;
- imx_ssi_dai.dev = &pdev->dev;
+ struct snd_soc_dai *bt_cpu_dai;
if (dev_data->src_port == 1)
- imx_ssi_dai.name = "imx-ssi-1";
+ bt_cpu_dai = &imx_ssi_dai[0];
else
- imx_ssi_dai.name = "imx-ssi-3";
+ bt_cpu_dai = &imx_ssi_dai[2];
- snd_soc_register_dai(&imx_ssi_dai);
+ imx_3stack_dai.cpu_dai = bt_cpu_dai;
/* Configure audio port */
imx_3stack_init_dam(dev_data->src_port, dev_data->ext_port);
diff --git a/sound/soc/imx/imx-3stack-sgtl5000.c b/sound/soc/imx/imx-3stack-sgtl5000.c
index 9dc060b52301..fed97f9c2655 100644
--- a/sound/soc/imx/imx-3stack-sgtl5000.c
+++ b/sound/soc/imx/imx-3stack-sgtl5000.c
@@ -20,7 +20,6 @@
#include <linux/pm.h>
#include <linux/bitops.h>
#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/irq.h>
@@ -68,9 +67,6 @@ struct imx_3stack_priv {
int sysclk;
int hw;
struct platform_device *pdev;
- struct regulator *reg_vddio;
- struct regulator *reg_vdda;
- struct regulator *reg_vddd;
};
static struct imx_3stack_priv card_priv;
@@ -84,6 +80,7 @@ static int imx_3stack_audio_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = machine->codec_dai;
struct imx_3stack_priv *priv = &card_priv;
unsigned int rate = params_rate(params);
+ struct imx_ssi *ssi_mode = (struct imx_ssi *)cpu_dai->private_data;
int ret = 0;
unsigned int channels = params_channels(params);
@@ -144,6 +141,12 @@ static int imx_3stack_audio_hw_params(struct snd_pcm_substream *substream,
SND_SOC_DAIFMT_CBS_CFS;
#endif
+ ssi_mode->sync_mode = 1;
+ if (channels == 1)
+ ssi_mode->network_mode = 0;
+ else
+ ssi_mode->network_mode = 1;
+
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
if (ret < 0)
@@ -532,29 +535,15 @@ static int imx_3stack_sgtl5000_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link imx_3stack_dai = {
.name = "SGTL5000",
.stream_name = "SGTL5000",
- .cpu_dai = &imx_ssi_dai,
.codec_dai = &sgtl5000_dai,
.init = imx_3stack_sgtl5000_init,
.ops = &imx_3stack_ops,
- .symmetric_rates = 1,
};
static int imx_3stack_card_remove(struct platform_device *pdev)
{
struct imx_3stack_priv *priv = &card_priv;
struct mxc_audio_platform_data *plat;
- if (priv->reg_vddio)
- regulator_disable(priv->reg_vddio);
- if (priv->reg_vddd)
- regulator_disable(priv->reg_vddd);
- if (priv->reg_vdda)
- regulator_disable(priv->reg_vdda);
- if (priv->reg_vdda)
- regulator_put(priv->reg_vdda);
- if (priv->reg_vddio)
- regulator_put(priv->reg_vddio);
- if (priv->reg_vddd)
- regulator_put(priv->reg_vddd);
if (priv->pdev) {
plat = priv->pdev->dev.platform_data;
if (plat->finit)
@@ -581,36 +570,21 @@ static int __devinit imx_3stack_sgtl5000_probe(struct platform_device *pdev)
{
struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
struct imx_3stack_priv *priv = &card_priv;
- struct sgtl5000_platform_data *codec_data;
- struct regulator *reg;
+ struct snd_soc_dai *sgtl5000_cpu_dai;
int ret = 0;
priv->sysclk = plat->sysclk;
priv->pdev = pdev;
- imx_ssi_dai.private_data = plat;
- imx_ssi_dai.dev = &pdev->dev;
-
- codec_data = kzalloc(sizeof(struct sgtl5000_platform_data), GFP_KERNEL);
- if (!codec_data) {
- ret = -ENOMEM;
- goto err_codec_data;
- }
- codec_data->vddio = plat->vddio / 1000; /* uV to mV */
- codec_data->vdda = plat->vdda / 1000;
- codec_data->vddd = plat->vddd / 1000;
- imx_3stack_snd_devdata.codec_data = codec_data;
-
gpio_activate_audio_ports();
imx_3stack_init_dam(plat->src_port, plat->ext_port);
if (plat->src_port == 2)
- imx_ssi_dai.name = "imx-ssi-3";
+ sgtl5000_cpu_dai = &imx_ssi_dai[2];
else
- imx_ssi_dai.name = "imx-ssi-1";
+ sgtl5000_cpu_dai = &imx_ssi_dai[0];
- imx_ssi_dai.symmetric_rates = 1;
- snd_soc_register_dai(&imx_ssi_dai);
+ imx_3stack_dai.cpu_dai = sgtl5000_cpu_dai;
ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);
if (ret < 0) {
@@ -621,44 +595,10 @@ static int __devinit imx_3stack_sgtl5000_probe(struct platform_device *pdev)
ret = -EINVAL;
if (plat->init && plat->init())
goto err_plat_init;
- if (plat->vddio_reg) {
- reg = regulator_get(&pdev->dev, plat->vddio_reg);
- if (IS_ERR(reg))
- goto err_reg_vddio;
- priv->reg_vddio = reg;
- }
- if (plat->vdda_reg) {
- reg = regulator_get(&pdev->dev, plat->vdda_reg);
- if (IS_ERR(reg))
- goto err_reg_vdda;
- priv->reg_vdda = reg;
- }
- if (plat->vddd_reg) {
- reg = regulator_get(&pdev->dev, plat->vddd_reg);
- if (IS_ERR(reg))
- goto err_reg_vddd;
- priv->reg_vddd = reg;
- }
-
- if (priv->reg_vdda) {
- ret = regulator_set_voltage(priv->reg_vdda,
- plat->vdda, plat->vdda);
- regulator_enable(priv->reg_vdda);
- }
- if (priv->reg_vddio) {
- regulator_set_voltage(priv->reg_vddio,
- plat->vddio, plat->vddio);
- regulator_enable(priv->reg_vddio);
- }
- if (priv->reg_vddd) {
- regulator_set_voltage(priv->reg_vddd, plat->vddd, plat->vddd);
- regulator_enable(priv->reg_vddd);
- }
/* The SGTL5000 has an internal reset that is deasserted 8 SYS_MCLK
cycles after all power rails have been brought up. After this time
communication can start */
- msleep(1);
if (plat->hp_status())
ret = request_irq(plat->hp_irq,
@@ -680,22 +620,11 @@ static int __devinit imx_3stack_sgtl5000_probe(struct platform_device *pdev)
return 0;
err_card_reg:
- if (priv->reg_vddd)
- regulator_put(priv->reg_vddd);
-err_reg_vddd:
- if (priv->reg_vdda)
- regulator_put(priv->reg_vdda);
-err_reg_vdda:
- if (priv->reg_vddio)
- regulator_put(priv->reg_vddio);
-err_reg_vddio:
if (plat->finit)
plat->finit();
err_plat_init:
driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
sysfs_err:
- kfree(codec_data);
-err_codec_data:
return ret;
}
@@ -706,9 +635,10 @@ static int imx_3stack_sgtl5000_remove(struct platform_device *pdev)
free_irq(plat->hp_irq, priv);
- driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
+ if (plat->finit)
+ plat->finit();
- kfree(imx_3stack_snd_devdata.codec_data);
+ driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
return 0;
}
diff --git a/sound/soc/imx/imx-3stack-wm8350.c b/sound/soc/imx/imx-3stack-wm8350.c
index e51cd907563b..fb1c0191f4ab 100644
--- a/sound/soc/imx/imx-3stack-wm8350.c
+++ b/sound/soc/imx/imx-3stack-wm8350.c
@@ -169,8 +169,8 @@ static int imx_3stack_audio_hw_params(struct snd_pcm_substream *substream,
snd_pcm_format_t format = params_format(params);
unsigned int rate = params_rate(params);
unsigned int channels = params_channels(params);
+ struct imx_ssi *ssi_mode = (struct imx_ssi *)cpu_dai->private_data;
u32 dai_format;
- int clk_id;
/* only need to do this once as capture and playback are sync */
if (priv->lr_clk_active > 1)
@@ -193,10 +193,26 @@ static int imx_3stack_audio_hw_params(struct snd_pcm_substream *substream,
#if WM8350_SSI_MASTER
/* codec FLL input is 32768 kHz from MCLK */
snd_soc_dai_set_pll(codec_dai, 0, 32768, wm8350_audio[i].sysclk);
+#else
+ /* codec FLL input is rate from DAC LRC */
+ snd_soc_dai_set_pll(codec_dai, 0, rate, wm8350_audio[i].sysclk);
+#endif
+#if WM8350_SSI_MASTER
dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;
+ ssi_mode->sync_mode = 1;
+ if (channels == 1)
+ ssi_mode->network_mode = 0;
+ else
+ ssi_mode->network_mode = 1;
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
+ if (ret < 0)
+ return ret;
+
/* set cpu DAI configuration */
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
dai_format &= ~SND_SOC_DAIFMT_INV_MASK;
@@ -204,19 +220,22 @@ static int imx_3stack_audio_hw_params(struct snd_pcm_substream *substream,
dai_format |= SND_SOC_DAIFMT_NB_IF;
}
+ /* set i.MX active slot mask */
+ snd_soc_dai_set_tdm_slot(cpu_dai,
+ channels == 1 ? 0xfffffffe : 0xfffffffc,
+ channels);
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
+ if (ret < 0)
+ return ret;
+
/* set 32KHZ as the codec system clock for DAC and ADC */
- clk_id = WM8350_MCLK_SEL_PLL_32K;
+ snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_32K,
+ wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
#else
- /* codec FLL input is rate from DAC LRC */
- snd_soc_dai_set_pll(codec_dai, 0, rate, wm8350_audio[i].sysclk);
-
dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS;
- /* set DAC LRC as the codec system clock for DAC and ADC */
- clk_id = WM8350_MCLK_SEL_PLL_DAC;
-#endif
-
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
if (ret < 0)
@@ -232,8 +251,10 @@ static int imx_3stack_audio_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- snd_soc_dai_set_sysclk(codec_dai, clk_id,
+ /* set DAC LRC as the codec system clock for DAC and ADC */
+ snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_DAC,
wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
+#endif
/* set the SSI system clock as input (unused) */
snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_IN);
@@ -301,27 +322,6 @@ static struct snd_soc_ops imx_3stack_ops = {
.hw_params = imx_3stack_audio_hw_params,
};
-/* need to refine these */
-static struct wm8350_audio_platform_data imx_3stack_wm8350_setup = {
- .vmid_discharge_msecs = 1000,
- .drain_msecs = 30,
- .cap_discharge_msecs = 700,
- .vmid_charge_msecs = 700,
- .vmid_s_curve = WM8350_S_CURVE_SLOW,
- .dis_out4 = WM8350_DISCHARGE_SLOW,
- .dis_out3 = WM8350_DISCHARGE_SLOW,
- .dis_out2 = WM8350_DISCHARGE_SLOW,
- .dis_out1 = WM8350_DISCHARGE_SLOW,
- .vroi_out4 = WM8350_TIE_OFF_500R,
- .vroi_out3 = WM8350_TIE_OFF_500R,
- .vroi_out2 = WM8350_TIE_OFF_500R,
- .vroi_out1 = WM8350_TIE_OFF_500R,
- .vroi_enable = 0,
- .codec_current_on = WM8350_CODEC_ISEL_1_0,
- .codec_current_standby = WM8350_CODEC_ISEL_0_5,
- .codec_current_charge = WM8350_CODEC_ISEL_1_5,
-};
-
static void imx_3stack_init_dam(int ssi_port, int dai_port)
{
unsigned int ssi_ptcr = 0;
@@ -567,7 +567,6 @@ static int imx_3stack_wm8350_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link imx_3stack_dai = {
.name = "WM8350",
.stream_name = "WM8350",
- .cpu_dai = &imx_ssi_dai,
.codec_dai = &wm8350_dai,
.init = imx_3stack_wm8350_init,
.ops = &imx_3stack_ops,
@@ -580,7 +579,6 @@ static int imx_3stack_machine_probe(struct platform_device *pdev)
struct wm8350 *wm8350 = priv->wm8350;
socdev->codec_data = wm8350;
- wm8350->codec.platform_data = &imx_3stack_wm8350_setup;
return 0;
}
@@ -603,27 +601,22 @@ static int __devinit imx_3stack_wm8350_probe(struct platform_device *pdev)
struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
struct imx_3stack_priv *priv = &machine_priv;
struct wm8350 *wm8350 = plat->priv;
+ struct snd_soc_dai *wm8350_cpu_dai;
int ret = 0;
u16 reg;
priv->pdev = pdev;
priv->wm8350 = wm8350;
- imx_ssi_dai.private_data = plat;
- imx_ssi_dai.dev = &pdev->dev;
-
- imx_3stack_wm8350_setup.regulator1 = plat->regulator1;
- imx_3stack_wm8350_setup.regulator2 = plat->regulator2;
-
gpio_activate_audio_ports();
imx_3stack_init_dam(plat->src_port, plat->ext_port);
if (plat->src_port == 2)
- imx_ssi_dai.name = "imx-ssi-3";
+ wm8350_cpu_dai = &imx_ssi_dai[2];
else
- imx_ssi_dai.name = "imx-ssi-1";
+ wm8350_cpu_dai = &imx_ssi_dai[0];
- snd_soc_register_dai(&imx_ssi_dai);
+ imx_3stack_dai.cpu_dai = wm8350_cpu_dai;
ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);
if (ret < 0) {
diff --git a/sound/soc/imx/imx-3stack-wm8580.c b/sound/soc/imx/imx-3stack-wm8580.c
index 0dc7b88d1441..4e468132f406 100644
--- a/sound/soc/imx/imx-3stack-wm8580.c
+++ b/sound/soc/imx/imx-3stack-wm8580.c
@@ -127,6 +127,7 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream,
u32 dai_format;
unsigned int pll_out = 0, lrclk_ratio = 0;
unsigned int channel = params_channels(params);
+ struct imx_esai *esai_mode = (struct imx_esai *)cpu_dai->private_data;
if (clk_state.lr_clk_active > 1)
return 0;
@@ -225,6 +226,9 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream,
dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;
+ esai_mode->sync_mode = 0;
+ esai_mode->network_mode = 1;
+
/* set codec DAI configuration */
snd_soc_dai_set_fmt(codec_dai, dai_format);
@@ -337,7 +341,6 @@ static int imx_3stack_wm8580_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link imx_3stack_dai = {
.name = "wm8580",
.stream_name = "wm8580",
- .cpu_dai = &imx_esai_dai,
.codec_dai = wm8580_dai,
.init = imx_3stack_wm8580_init,
.ops = &imx_3stack_surround_ops,
@@ -370,7 +373,7 @@ static int __devinit imx_3stack_wm8580_probe(struct platform_device *pdev)
{
struct wm8580_setup_data *setup;
- imx_esai_dai.name = "imx-esai-txrx";
+ imx_3stack_dai.cpu_dai = &imx_esai_dai[2];
setup = kzalloc(sizeof(struct wm8580_setup_data), GFP_KERNEL);
setup->spi = 1;
diff --git a/sound/soc/imx/imx-esai.c b/sound/soc/imx/imx-esai.c
index 795e3d4bc704..71dd62cff509 100644
--- a/sound/soc/imx/imx-esai.c
+++ b/sound/soc/imx/imx-esai.c
@@ -320,6 +320,7 @@
#define ESAI_RX_DIV_FP 5
static int imx_esai_txrx_state;
+static struct imx_esai imx_esai_priv[3];
static int imx_esai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
int clk_id, unsigned int freq, int dir)
@@ -422,35 +423,25 @@ static int imx_esai_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
static int imx_esai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
unsigned int mask, int slots)
{
- u32 tcr, rcr, tccr, rccr;
+ u32 tccr, rccr;
if (cpu_dai->id & IMX_DAI_ESAI_TX) {
- tcr = __raw_readl(ESAI_TCR);
tccr = __raw_readl(ESAI_TCCR);
- tcr &= ESAI_TCR_TMOD_MASK;
- tcr |= ESAI_TCR_TMOD_NETWORK;
-
tccr &= ESAI_TCCR_TDC_MASK;
tccr |= ESAI_TCCR_TDC(slots - 1);
- __raw_writel(tcr, ESAI_TCR);
__raw_writel(tccr, ESAI_TCCR);
__raw_writel((mask & 0xffff), ESAI_TSMA);
__raw_writel(((mask >> 16) & 0xffff), ESAI_TSMB);
}
if (cpu_dai->id & IMX_DAI_ESAI_RX) {
- rcr = __raw_readl(ESAI_RCR);
rccr = __raw_readl(ESAI_RCCR);
- rcr &= ESAI_RCR_RMOD_MASK;
- rcr |= ESAI_RCR_RMOD_NETWORK;
-
rccr &= ESAI_RCCR_RDC_MASK;
rccr |= ESAI_RCCR_RDC(slots - 1);
- __raw_writel(rcr, ESAI_RCR);
__raw_writel(rccr, ESAI_RCCR);
__raw_writel((mask & 0xffff), ESAI_RSMA);
__raw_writel(((mask >> 16) & 0xffff), ESAI_RSMB);
@@ -466,7 +457,7 @@ static int imx_esai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
*/
static int imx_esai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
- bool sync_mode = cpu_dai->symmetric_rates;
+ struct imx_esai *esai_mode = (struct imx_esai *)cpu_dai->private_data;
u32 tcr, tccr, rcr, rccr, saicr;
tcr = __raw_readl(ESAI_TCR);
@@ -549,11 +540,21 @@ static int imx_esai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
}
/* sync */
- if (sync_mode)
+ if (esai_mode->sync_mode)
saicr |= ESAI_SAICR_SYNC;
else
saicr &= ~ESAI_SAICR_SYNC;
+ tcr &= ESAI_TCR_TMOD_MASK;
+ rcr &= ESAI_RCR_RMOD_MASK;
+ if (esai_mode->network_mode) {
+ tcr |= ESAI_TCR_TMOD_NETWORK;
+ rcr |= ESAI_RCR_RMOD_NETWORK;
+ } else {
+ tcr |= ESAI_TCR_TMOD_NORMAL;
+ rcr |= ESAI_RCR_RMOD_NORMAL;
+ }
+
if (cpu_dai->id & IMX_DAI_ESAI_TX) {
__raw_writel(tcr, ESAI_TCR);
__raw_writel(tccr, ESAI_TCCR);
@@ -828,17 +829,6 @@ static int imx_esai_resume(struct snd_soc_dai *dai)
static int imx_esai_probe(struct platform_device *pdev, struct snd_soc_dai *dai)
{
- if (!strcmp("imx-esai-tx", dai->name))
- dai->id = IMX_DAI_ESAI_TX;
- else if (!strcmp("imx-esai-rx", dai->name))
- dai->id = IMX_DAI_ESAI_RX;
- else if (!strcmp("imx-esai-txrx", dai->name))
- dai->id = IMX_DAI_ESAI_TXRX;
- else {
- pr_err("%s: invalid device %s\n", __func__, dai->name);
- return -ENODEV;
- }
-
imx_esai_txrx_state = 0;
esai_clk = clk_get(NULL, "esai_clk");
@@ -870,30 +860,91 @@ static struct snd_soc_dai_ops imx_esai_dai_ops = {
.set_tdm_slot = imx_esai_set_dai_tdm_slot,
};
-struct snd_soc_dai imx_esai_dai = {
- .name = "imx-esai",
- .id = 0,
- .probe = imx_esai_probe,
- .remove = imx_esai_remove,
- .suspend = imx_esai_suspend,
- .resume = imx_esai_resume,
- .playback = {
+struct snd_soc_dai imx_esai_dai[] = {
+ {
+ .name = "imx-esai-tx",
+ .id = IMX_DAI_ESAI_TX,
+ .probe = imx_esai_probe,
+ .remove = imx_esai_remove,
+ .suspend = imx_esai_suspend,
+ .resume = imx_esai_resume,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 6,
+ .rates = IMX_ESAI_RATES,
+ .formats = IMX_ESAI_FORMATS,
+ },
+ .capture = {
+ .channels_min = 1,
+ .channels_max = 4,
+ .rates = IMX_ESAI_RATES,
+ .formats = IMX_ESAI_FORMATS,
+ },
+ .ops = &imx_esai_dai_ops,
+ .private_data = &imx_esai_priv[0],
+ },
+ {
+ .name = "imx-esai-rx",
+ .id = IMX_DAI_ESAI_RX,
+ .probe = imx_esai_probe,
+ .remove = imx_esai_remove,
+ .suspend = imx_esai_suspend,
+ .resume = imx_esai_resume,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 6,
+ .rates = IMX_ESAI_RATES,
+ .formats = IMX_ESAI_FORMATS,
+ },
+ .capture = {
+ .channels_min = 1,
+ .channels_max = 4,
+ .rates = IMX_ESAI_RATES,
+ .formats = IMX_ESAI_FORMATS,
+ },
+ .ops = &imx_esai_dai_ops,
+ .private_data = &imx_esai_priv[1],
+ },
+ {
+ .name = "imx-esai-txrx",
+ .id = IMX_DAI_ESAI_TXRX,
+ .probe = imx_esai_probe,
+ .remove = imx_esai_remove,
+ .suspend = imx_esai_suspend,
+ .resume = imx_esai_resume,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 6,
+ .rates = IMX_ESAI_RATES,
+ .formats = IMX_ESAI_FORMATS,
+ },
+ .capture = {
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 4,
.rates = IMX_ESAI_RATES,
.formats = IMX_ESAI_FORMATS,
},
- .capture = {
- .channels_min = 1,
- .channels_max = 4,
- .rates = IMX_ESAI_RATES,
- .formats = IMX_ESAI_FORMATS,
- },
- .ops = &imx_esai_dai_ops,
+ .ops = &imx_esai_dai_ops,
+ .private_data = &imx_esai_priv[2],
+ },
+
};
EXPORT_SYMBOL_GPL(imx_esai_dai);
+static int __init imx_esai_init(void)
+{
+ return snd_soc_register_dais(imx_esai_dai, ARRAY_SIZE(imx_esai_dai));
+}
+
+static void __exit imx_esai_exit(void)
+{
+ snd_soc_unregister_dais(imx_esai_dai, ARRAY_SIZE(imx_esai_dai));
+}
+
+module_init(imx_esai_init);
+module_exit(imx_esai_exit);
+
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("i.MX ASoC ESAI driver");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/imx-esai.h b/sound/soc/imx/imx-esai.h
index 8ac2e3fbe6d3..58ad601c119f 100644
--- a/sound/soc/imx/imx-esai.h
+++ b/sound/soc/imx/imx-esai.h
@@ -20,6 +20,11 @@
#define IMX_DAI_ESAI_RX 0x08
#define IMX_DAI_ESAI_TXRX (IMX_DAI_ESAI_TX | IMX_DAI_ESAI_RX)
-extern struct snd_soc_dai imx_esai_dai;
+struct imx_esai {
+ bool network_mode;
+ bool sync_mode;
+};
+
+extern struct snd_soc_dai imx_esai_dai[];
#endif
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 2dba33b8c270..14cc967695dc 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -39,12 +39,7 @@
#include "imx-ssi.h"
#include "imx-pcm.h"
-/* private info */
-struct imx_ssi {
- bool network_mode;
-};
-
-static struct imx_ssi imx_ssi_data[IMX_DAI_SSI3];
+static struct imx_ssi imx_ssi_data[4];
/* debug */
#define IMX_SSI_DEBUG 0
@@ -194,11 +189,8 @@ static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
unsigned int mask, int slots)
{
- bool network_mode = (!(mask & 0x2));
u32 stmsk, srmsk, stccr;
- imx_ssi_data[cpu_dai->id].network_mode = network_mode;
-
if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) {
if (__raw_readl(SSI1_SCR) & SSI_SCR_SSIEN)
return 0;
@@ -236,12 +228,9 @@ static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
*/
static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
- bool sync_mode = cpu_dai->symmetric_rates;
- bool network_mode;
+ struct imx_ssi *ssi_mode = (struct imx_ssi *)cpu_dai->private_data;
u32 stcr = 0, srcr = 0, scr;
- network_mode = imx_ssi_data[cpu_dai->id].network_mode;
-
if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1)
scr = __raw_readl(SSI1_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
else
@@ -303,7 +292,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
case SND_SOC_DAIFMT_CBS_CFS:
stcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR;
if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
- && network_mode) {
+ && ssi_mode->network_mode) {
scr &= ~SSI_SCR_I2S_MODE_MASK;
scr |= SSI_SCR_I2S_MODE_MSTR;
}
@@ -318,7 +307,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
break;
case SND_SOC_DAIFMT_CBM_CFM:
if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
- && network_mode) {
+ && ssi_mode->network_mode) {
scr &= ~SSI_SCR_I2S_MODE_MASK;
scr |= SSI_SCR_I2S_MODE_SLAVE;
}
@@ -326,11 +315,11 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
}
/* sync */
- if (sync_mode)
+ if (ssi_mode->sync_mode)
scr |= SSI_SCR_SYN;
/* tdm - only for stereo atm */
- if (network_mode)
+ if (ssi_mode->network_mode)
scr |= SSI_SCR_NET;
if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) {
@@ -451,8 +440,9 @@ static int imx_ssi_hw_rx_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *cpu_dai)
{
- bool sync_mode = cpu_dai->symmetric_rates;
u32 srccr, srcr, sier;
+ struct imx_ssi *ssi_mode = (struct imx_ssi *)cpu_dai->private_data;
+ bool sync_mode = ssi_mode->sync_mode;
if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) {
srccr =
@@ -690,29 +680,16 @@ static irqreturn_t ssi2_irq(int irq, void *dev_id)
static int imx_ssi_probe(struct platform_device *pdev, struct snd_soc_dai *dai)
{
- if (!strcmp(dai->name, "imx-ssi-1"))
- dai->id = IMX_DAI_SSI0;
- else if (!strcmp(dai->name, "imx-ssi-2"))
- dai->id = IMX_DAI_SSI1;
- else if (!strcmp(dai->name, "imx-ssi-3"))
- dai->id = IMX_DAI_SSI2;
- else if (!strcmp(dai->name, "imx-ssi-4"))
- dai->id = IMX_DAI_SSI3;
- else {
- printk(KERN_ERR "%s: invalid device %s\n", __func__, dai->name);
- return -ENODEV;
- }
-
- if ((!strcmp(dai->name, "imx-ssi-1")) ||
- (!strcmp(dai->name, "imx-ssi-2")))
+ if ((!strcmp(dai->name, "imx-ssi-1-0")) ||
+ (!strcmp(dai->name, "imx-ssi-1-1")))
if (request_irq(MXC_INT_SSI1, ssi1_irq, 0, "ssi1", dai)) {
printk(KERN_ERR "%s: failure requesting irq %s\n",
__func__, "ssi1");
return -EBUSY;
}
- if ((!strcmp(dai->name, "imx-ssi-3")) ||
- (!strcmp(dai->name, "imx-ssi-4")))
+ if ((!strcmp(dai->name, "imx-ssi-2-0")) ||
+ (!strcmp(dai->name, "imx-ssi-2-1")))
if (request_irq(MXC_INT_SSI2, ssi2_irq, 0, "ssi2", dai)) {
printk(KERN_ERR "%s: failure requesting irq %s\n",
__func__, "ssi2");
@@ -725,12 +702,12 @@ static int imx_ssi_probe(struct platform_device *pdev, struct snd_soc_dai *dai)
static void imx_ssi_remove(struct platform_device *pdev,
struct snd_soc_dai *dai)
{
- if ((!strcmp(dai->name, "imx-ssi-1")) ||
- (!strcmp(dai->name, "imx-ssi-2")))
+ if ((!strcmp(dai->name, "imx-ssi-1-0")) ||
+ (!strcmp(dai->name, "imx-ssi-1-1")))
free_irq(MXC_INT_SSI1, dai);
- if ((!strcmp(dai->name, "imx-ssi-3")) ||
- (!strcmp(dai->name, "imx-ssi-4")))
+ if ((!strcmp(dai->name, "imx-ssi-2-0")) ||
+ (!strcmp(dai->name, "imx-ssi-2-1")))
free_irq(MXC_INT_SSI2, dai);
}
@@ -757,29 +734,111 @@ static struct snd_soc_dai_ops imx_ssi_dai_ops = {
.set_tdm_slot = imx_ssi_set_dai_tdm_slot,
};
-struct snd_soc_dai imx_ssi_dai = {
- .name = "imx-ssi",
- .id = 0,
- .probe = imx_ssi_probe,
- .suspend = imx_ssi_suspend,
- .remove = imx_ssi_remove,
- .resume = imx_ssi_resume,
- .playback = {
+struct snd_soc_dai imx_ssi_dai[] = {
+ {
+ .name = "imx-ssi-1-0",
+ .id = IMX_DAI_SSI0,
+ .probe = imx_ssi_probe,
+ .suspend = imx_ssi_suspend,
+ .remove = imx_ssi_remove,
+ .resume = imx_ssi_resume,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = IMX_SSI_RATES,
+ .formats = IMX_SSI_FORMATS,
+ },
+ .capture = {
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = IMX_SSI_RATES,
+ .formats = IMX_SSI_FORMATS,
+ },
+ .ops = &imx_ssi_dai_ops,
+ .private_data = &imx_ssi_data[IMX_DAI_SSI0],
+ },
+ {
+ .name = "imx-ssi-1-1",
+ .id = IMX_DAI_SSI1,
+ .probe = imx_ssi_probe,
+ .suspend = imx_ssi_suspend,
+ .remove = imx_ssi_remove,
+ .resume = imx_ssi_resume,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = IMX_SSI_RATES,
+ .formats = IMX_SSI_FORMATS,
+ },
+ .capture = {
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = IMX_SSI_RATES,
+ .formats = IMX_SSI_FORMATS,
+ },
+ .ops = &imx_ssi_dai_ops,
+ .private_data = &imx_ssi_data[IMX_DAI_SSI1],
+ },
+ {
+ .name = "imx-ssi-2-0",
+ .id = IMX_DAI_SSI2,
+ .probe = imx_ssi_probe,
+ .suspend = imx_ssi_suspend,
+ .remove = imx_ssi_remove,
+ .resume = imx_ssi_resume,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = IMX_SSI_RATES,
+ .formats = IMX_SSI_FORMATS,
+ },
+ .capture = {
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = IMX_SSI_RATES,
+ .formats = IMX_SSI_FORMATS,
+ },
+ .ops = &imx_ssi_dai_ops,
+ .private_data = &imx_ssi_data[IMX_DAI_SSI2],
+ },
+ {
+ .name = "imx-ssi-2-1",
+ .id = IMX_DAI_SSI3,
+ .probe = imx_ssi_probe,
+ .suspend = imx_ssi_suspend,
+ .remove = imx_ssi_remove,
+ .resume = imx_ssi_resume,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = IMX_SSI_RATES,
+ .formats = IMX_SSI_FORMATS,
+ },
+ .capture = {
.channels_min = 1,
.channels_max = 2,
.rates = IMX_SSI_RATES,
.formats = IMX_SSI_FORMATS,
},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = IMX_SSI_RATES,
- .formats = IMX_SSI_FORMATS,
- },
- .ops = &imx_ssi_dai_ops,
+ .ops = &imx_ssi_dai_ops,
+ .private_data = &imx_ssi_data[IMX_DAI_SSI3],
+ },
};
+
EXPORT_SYMBOL_GPL(imx_ssi_dai);
+static int __init imx_ssi_init(void)
+{
+ return snd_soc_register_dais(imx_ssi_dai, ARRAY_SIZE(imx_ssi_dai));
+}
+
+static void __exit imx_ssi_exit(void)
+{
+ snd_soc_unregister_dais(imx_ssi_dai, ARRAY_SIZE(imx_ssi_dai));
+}
+
+module_init(imx_ssi_init);
+module_exit(imx_ssi_exit);
MODULE_AUTHOR
("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
MODULE_DESCRIPTION("i.MX ASoC I2S driver");
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index ffb27e9d2aea..387e992b397f 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -213,6 +213,12 @@
#define IMX_SSI_DIV_2_OFF (~SSI_STCCR_DIV2)
#define IMX_SSI_DIV_2_ON SSI_STCCR_DIV2
-extern struct snd_soc_dai imx_ssi_dai;
+/* private info */
+struct imx_ssi {
+ bool network_mode;
+ bool sync_mode;
+};
+
+extern struct snd_soc_dai imx_ssi_dai[];
#endif