summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mx25/mx25_3stack.c3
-rw-r--r--arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c29
-rw-r--r--arch/arm/mach-mx35/mx35_3stack.c5
-rw-r--r--arch/arm/mach-mx35/mx35_3stack_pmic_mc13892.c12
-rw-r--r--arch/arm/mach-mx37/mx37_3stack.c5
-rw-r--r--arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c42
-rw-r--r--arch/arm/mach-mx51/mx51_3stack.c3
-rw-r--r--arch/arm/mach-mx51/mx51_babbage.c8
-rw-r--r--arch/arm/mach-mx51/mx51_babbage_pmic_mc13892.c35
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h8
-rw-r--r--sound/soc/codecs/ak4647.c4
-rw-r--r--sound/soc/codecs/bluetooth.c14
-rw-r--r--sound/soc/codecs/sgtl5000.c93
-rw-r--r--sound/soc/codecs/sgtl5000.h6
-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
24 files changed, 502 insertions, 303 deletions
diff --git a/arch/arm/mach-mx25/mx25_3stack.c b/arch/arm/mach-mx25/mx25_3stack.c
index fd0d30121f57..a956950913f8 100644
--- a/arch/arm/mach-mx25/mx25_3stack.c
+++ b/arch/arm/mach-mx25/mx25_3stack.c
@@ -333,9 +333,6 @@ static struct mxc_audio_platform_data sgtl5000_data = {
.ext_port = 4,
.hp_irq = IOMUX_TO_IRQ(MX25_PIN_A10),
.hp_status = headphone_det_status,
- .vddio = 1800000,
- .vdda = 3300000,
- .vddd = 0,
.sysclk = 8300000,
};
diff --git a/arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c b/arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c
index 95fbf66fe564..fdb91131143d 100644
--- a/arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c
+++ b/arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c
@@ -35,6 +35,27 @@
struct mc34704;
+static struct regulator_consumer_supply rcpu_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDA",
+ .dev_name = "0-000a",
+ },
+ {
+ /* sgtl5000 */
+ .supply = "VDDD",
+ .dev_name = "0-000a",
+ },
+};
+
+static struct regulator_consumer_supply rddr_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDIO",
+ .dev_name = "0-000a",
+ },
+};
+
static struct regulator_init_data rbklt_init = {
.constraints = {
.name = "REG1_BKLT",
@@ -58,7 +79,9 @@ static struct regulator_init_data rcpu_init = {
mV_to_uV(REG2_V_MV * (1000 + REG2_DVS_MAX_PCT * 10) /
1000),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- }
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rcpu_consumers),
+ .consumer_supplies = rcpu_consumers,
};
static struct regulator_init_data rcore_init = {
@@ -84,7 +107,9 @@ static struct regulator_init_data rddr_init = {
mV_to_uV(REG4_V_MV * (1000 + REG4_DVS_MAX_PCT * 10) /
1000),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- }
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rddr_consumers),
+ .consumer_supplies = rddr_consumers,
};
static struct regulator_init_data rpers_init = {
diff --git a/arch/arm/mach-mx35/mx35_3stack.c b/arch/arm/mach-mx35/mx35_3stack.c
index 02fed337d772..1231d5e59e2f 100644
--- a/arch/arm/mach-mx35/mx35_3stack.c
+++ b/arch/arm/mach-mx35/mx35_3stack.c
@@ -865,12 +865,7 @@ static struct mxc_audio_platform_data sgtl5000_data = {
.ext_port = 4,
.hp_irq = MXC_PSEUDO_IRQ_HEADPHONE,
.hp_status = sgtl5000_headphone_det_status,
- .vddio_reg = NULL,
- .vdda_reg = "VCAM",
.amp_enable = mxc_sgtl5000_amp_enable,
- .vddio = 0,
- .vdda = 3000000,
- .vddd = 0,
.sysclk = 12000000,
.init = mxc_sgtl5000_plat_init,
.finit = mxc_sgtl5000_plat_finit,
diff --git a/arch/arm/mach-mx35/mx35_3stack_pmic_mc13892.c b/arch/arm/mach-mx35/mx35_3stack_pmic_mc13892.c
index 44cccc564c2e..b20be8208483 100644
--- a/arch/arm/mach-mx35/mx35_3stack_pmic_mc13892.c
+++ b/arch/arm/mach-mx35/mx35_3stack_pmic_mc13892.c
@@ -44,6 +44,14 @@ static struct regulator_consumer_supply sw1_consumers[] = {
}
};
+static struct regulator_consumer_supply vcam_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDA",
+ .dev_name = "0-000a",
+ },
+};
+
struct mc13892;
static struct regulator_init_data sw1_init = {
@@ -195,7 +203,9 @@ static struct regulator_init_data vcam_init = {
.valid_ops_mask =
REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL,
- }
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcam_consumers),
+ .consumer_supplies = vcam_consumers,
};
static struct regulator_init_data vgen1_init = {
diff --git a/arch/arm/mach-mx37/mx37_3stack.c b/arch/arm/mach-mx37/mx37_3stack.c
index b62b2b8f179c..acd36bc2cd9e 100644
--- a/arch/arm/mach-mx37/mx37_3stack.c
+++ b/arch/arm/mach-mx37/mx37_3stack.c
@@ -755,12 +755,7 @@ static struct mxc_audio_platform_data sgtl5000_data = {
.ext_port = 5,
.hp_irq = IOMUX_TO_IRQ(MX37_PIN_AUD5_RXFS),
.hp_status = headphone_det_status,
- .vddio_reg = "SW3",
- .vdda_reg = "VAUDIO",
.amp_enable = mxc_sgtl5000_amp_enable,
- .vddio = 1850000,
- .vdda = 2775000,
- .vddd = 0,
.init = mxc_sgtl5000_plat_init,
.finit = mxc_sgtl5000_plat_finit,
};
diff --git a/arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c b/arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c
index 0ab86ff29a3f..f80a61cf00e1 100644
--- a/arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c
+++ b/arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/regulator/machine.h>
+#include <linux/mfd/wm8350/audio.h>
#include <linux/mfd/wm8350/core.h>
#include <linux/mfd/wm8350/pmic.h>
#include <linux/mfd/wm8350/gpio.h>
@@ -35,6 +36,17 @@ static struct regulator_consumer_supply dcdc1_consumers[] = {
}
};
+static struct regulator_consumer_supply dcdc3_consumers[] = {
+ {
+ .supply = "AVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "HPVDD",
+ .dev_name = "1-001a",
+ },
+};
+
static struct regulator_init_data dcdc1_data = {
.constraints = {
.name = "DCDC1",
@@ -107,6 +119,8 @@ static struct regulator_init_data dcdc3_data = {
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.apply_uV = 1,
},
+ .num_consumer_supplies = ARRAY_SIZE(dcdc3_consumers),
+ .consumer_supplies = dcdc3_consumers,
};
static struct regulator_init_data ldo1_data = {
@@ -217,12 +231,30 @@ static struct platform_device mxc_wm8350_devices[] = {
},
};
+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,
+};
+
struct mxc_audio_platform_data imx_3stack_audio_platform_data = {
.ssi_num = 2,
.src_port = 2,
.ext_port = 5,
- .regulator1 = "DCDC6",
- .regulator2 = "DCDC3",
};
static struct platform_device *imx_snd_device;
@@ -271,6 +303,8 @@ static int mx37_wm8350_init(struct wm8350 *wm8350)
/* register sound */
pr_info("Registering imx37_snd_device");
+ wm8350->codec.platform_data = &imx_3stack_wm8350_setup;
+
imx_snd_device = platform_device_alloc("wm8350-imx-3stack-audio", -1);
if (!imx_snd_device) {
ret = -ENOMEM;
@@ -334,10 +368,10 @@ static __init int wm8350_regulator_init(void)
wm8350_global_regulator
[i])))) {
regulator_enable(regulator);
- if (wm8350_global_regulator[i] == "DCDC4")
+ if (strcmp(wm8350_global_regulator[i], "DCDC4") == 0)
ret =
regulator_set_voltage(regulator, 1250000, 1250000);
- else if (wm8350_global_regulator[i] == "DCDC1") {
+ else if (strcmp(wm8350_global_regulator[i], "DCDC1") == 0) {
ret =
regulator_set_voltage(regulator, 1050000, 1050000);
regulator_set_mode(regulator, REGULATOR_MODE_FAST);
diff --git a/arch/arm/mach-mx51/mx51_3stack.c b/arch/arm/mach-mx51/mx51_3stack.c
index 0ff08e977f0c..39ddfbb6d0a4 100644
--- a/arch/arm/mach-mx51/mx51_3stack.c
+++ b/arch/arm/mach-mx51/mx51_3stack.c
@@ -1049,9 +1049,6 @@ static struct mxc_audio_platform_data sgtl5000_data = {
.hp_irq = IOMUX_TO_IRQ(MX51_PIN_EIM_A26),
.hp_status = headphone_det_status,
.amp_enable = mxc_sgtl5000_amp_enable,
- .vddio = 1800000,
- .vdda = 1800000,
- .vddd = 1200000,
.sysclk = 12000000,
.init = mxc_sgtl5000_plat_init,
.finit = mxc_sgtl5000_plat_finit,
diff --git a/arch/arm/mach-mx51/mx51_babbage.c b/arch/arm/mach-mx51/mx51_babbage.c
index 860e687a8cc2..11955f80ce39 100644
--- a/arch/arm/mach-mx51/mx51_babbage.c
+++ b/arch/arm/mach-mx51/mx51_babbage.c
@@ -812,13 +812,7 @@ static struct mxc_audio_platform_data sgtl5000_data = {
.ext_port = 3,
.hp_irq = IOMUX_TO_IRQ(MX51_PIN_NANDF_CS0),
.hp_status = headphone_det_status,
- .vddio_reg = "VVIDEO",
- .vdda_reg = "VDIG",
- .vddd_reg = "VGEN1",
.amp_enable = mxc_sgtl5000_amp_enable,
- .vddio = 2775000,
- .vdda = 1650000,
- .vddd = 1200000,
.sysclk = 12288000,
};
@@ -840,8 +834,6 @@ static void mxc_init_sgtl5000(void)
{
if (cpu_is_mx51_rev(CHIP_REV_1_1) == 2) {
sgtl5000_data.sysclk = 26000000;
- sgtl5000_data.vddd_reg = NULL;
- sgtl5000_data.vddd = 0;
}
gpio_request(IOMUX_TO_GPIO(MX51_PIN_EIM_A23), "eim_a23");
diff --git a/arch/arm/mach-mx51/mx51_babbage_pmic_mc13892.c b/arch/arm/mach-mx51/mx51_babbage_pmic_mc13892.c
index 2b1efe1a2e4a..8165e12d1356 100644
--- a/arch/arm/mach-mx51/mx51_babbage_pmic_mc13892.c
+++ b/arch/arm/mach-mx51/mx51_babbage_pmic_mc13892.c
@@ -85,6 +85,27 @@ static struct regulator_consumer_supply sw1_consumers[] = {
}
};
+static struct regulator_consumer_supply vdig_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDA",
+ .dev_name = "1-000a",
+ },
+ {
+ /* sgtl5000 */
+ .supply = "VDDD",
+ .dev_name = "1-000a",
+ },
+};
+
+static struct regulator_consumer_supply vvideo_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDIO",
+ .dev_name = "1-000a",
+ },
+};
+
struct mc13892;
static struct regulator_init_data sw1_init = {
@@ -169,11 +190,13 @@ static struct regulator_init_data swbst_init = {
static struct regulator_init_data vdig_init = {
.constraints = {
.name = "VDIG",
- .min_uV = mV_to_uV(1050),
- .max_uV = mV_to_uV(1800),
+ .min_uV = mV_to_uV(1650),
+ .max_uV = mV_to_uV(1650),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.boot_on = 1,
- }
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vdig_consumers),
+ .consumer_supplies = vdig_consumers,
};
static struct regulator_init_data vpll_init = {
@@ -204,7 +227,9 @@ static struct regulator_init_data vvideo_init = {
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
.apply_uV =1,
- }
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vvideo_consumers),
+ .consumer_supplies = vvideo_consumers,
};
static struct regulator_init_data vaudio_init = {
@@ -240,7 +265,7 @@ static struct regulator_init_data vgen1_init = {
.constraints = {
.name = "VGEN1",
.min_uV = mV_to_uV(1200),
- .max_uV = mV_to_uV(3150),
+ .max_uV = mV_to_uV(1200),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
}
};
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index f1cbce461cac..a15d63ce4112 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -236,18 +236,10 @@ struct mxc_audio_platform_data {
int intr_id_hp;
int ext_ram;
struct clk *ssi_clk[2];
- char *regulator1;
- char *regulator2;
int hp_irq;
int (*hp_status) (void);
- char *vddio_reg;
- char *vdda_reg;
- char *vddd_reg;
- int vddio; /* voltage of VDDIO (uv) */
- int vdda; /* voltage of vdda (uv) */
- int vddd; /* voltage of vddd (uv), 0 if not connected */
int sysclk;
int (*init) (void); /* board specific init */
diff --git a/sound/soc/codecs/ak4647.c b/sound/soc/codecs/ak4647.c
index 46e2e8cbcacc..c3d14e99be0e 100644
--- a/sound/soc/codecs/ak4647.c
+++ b/sound/soc/codecs/ak4647.c
@@ -45,9 +45,9 @@ int ak4647_read_reg(unsigned int reg, u8 *value)
{
s32 retval;
retval = i2c_smbus_read_byte_data(ak4647_i2c_client, reg);
- if (-1 == retval) {
+ if (retval < 0) {
pr_err("%s:read reg errorr:reg=%x,val=%x\n",
- __func__, reg, *value);
+ __func__, reg, retval);
return -1;
} else {
*value = (u8) retval;
diff --git a/sound/soc/codecs/bluetooth.c b/sound/soc/codecs/bluetooth.c
index ee6c49f67280..2d4c13b4f0af 100644
--- a/sound/soc/codecs/bluetooth.c
+++ b/sound/soc/codecs/bluetooth.c
@@ -142,6 +142,20 @@ struct snd_soc_codec_device soc_codec_dev_bt = {
};
EXPORT_SYMBOL_GPL(soc_codec_dev_bt);
+static int __init bluetooth_modinit(void)
+{
+ return snd_soc_register_dai(&bt_dai);
+}
+
+module_init(bluetooth_modinit);
+
+static void __exit bluetooth_exit(void)
+{
+ snd_soc_unregister_dai(&bt_dai);
+}
+
+module_exit(bluetooth_exit);
+
MODULE_DESCRIPTION("ASoC bluetooth codec driver");
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 3d754dea05ba..9cc8756ccccd 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -15,13 +15,14 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
-#include <mach/hardware.h>
+#include <linux/regulator/consumer.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
+#include <mach/hardware.h>
#include "sgtl5000.h"
@@ -34,6 +35,12 @@ struct sgtl5000_priv {
int capture_channels;
int playback_active;
int capture_active;
+ struct regulator *reg_vddio;
+ struct regulator *reg_vdda;
+ struct regulator *reg_vddd;
+ int vddio; /* voltage of VDDIO (mv) */
+ int vdda; /* voltage of vdda (mv) */
+ int vddd; /* voltage of vddd (mv), 0 if not connected */
struct snd_pcm_substream *master_substream;
struct snd_pcm_substream *slave_substream;
};
@@ -933,7 +940,6 @@ static struct snd_soc_codec *sgtl5000_codec;
static int sgtl5000_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct sgtl5000_platform_data *plat = socdev->codec_data;
struct snd_soc_codec *codec = sgtl5000_codec;
struct sgtl5000_priv *sgtl5000 = codec->private_data;
u16 reg, ana_pwr, lreg_ctrl, ref_ctrl, lo_ctrl, short_ctrl, sss;
@@ -961,7 +967,7 @@ static int sgtl5000_probe(struct platform_device *pdev)
sss = SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT;
/* workaround for rev 0x11: use vddd linear regulator */
- if (!plat->vddd || (sgtl5000->rev >= 0x11)) {
+ if (!sgtl5000->vddd || (sgtl5000->rev >= 0x11)) {
/* set VDDD to 1.2v */
lreg_ctrl |= 0x8 << SGTL5000_LINREG_VDDD_SHIFT;
/* power internal linear regulator */
@@ -971,14 +977,14 @@ static int sgtl5000_probe(struct platform_device *pdev)
ana_pwr &= ~SGTL5000_STARTUP_POWERUP;
ana_pwr &= ~SGTL5000_LINREG_SIMPLE_POWERUP;
}
- if (plat->vddio < 3100 && plat->vdda < 3100) {
+ if (sgtl5000->vddio < 3100 && sgtl5000->vdda < 3100) {
/* Enable VDDC charge pump */
ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
}
- if (plat->vddio >= 3100 && plat->vdda >= 3100) {
+ if (sgtl5000->vddio >= 3100 && sgtl5000->vdda >= 3100) {
/* VDDC use VDDIO rail */
lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
- if (plat->vddio >= 3100)
+ if (sgtl5000->vddio >= 3100)
lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
SGTL5000_VDDC_MAN_ASSN_SHIFT;
}
@@ -987,7 +993,7 @@ static int sgtl5000_probe(struct platform_device *pdev)
ana_pwr |= reg & (SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
/* set ADC/DAC ref voltage to vdda/2 */
- vag = plat->vdda / 2;
+ vag = sgtl5000->vdda / 2;
if (vag <= SGTL5000_ANA_GND_BASE)
vag = 0;
else if (vag >= SGTL5000_ANA_GND_BASE + SGTL5000_ANA_GND_STP *
@@ -998,7 +1004,7 @@ static int sgtl5000_probe(struct platform_device *pdev)
ref_ctrl |= vag << SGTL5000_ANA_GND_SHIFT;
/* set line out ref voltage to vddio/2 */
- vag = plat->vddio / 2;
+ vag = sgtl5000->vddio / 2;
if (vag <= SGTL5000_LINE_OUT_GND_BASE)
vag = 0;
else if (vag >= SGTL5000_LINE_OUT_GND_BASE + SGTL5000_LINE_OUT_GND_STP *
@@ -1110,6 +1116,7 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
{
struct sgtl5000_priv *sgtl5000;
struct snd_soc_codec *codec;
+ struct regulator *reg;
int ret = 0;
u32 val;
@@ -1137,11 +1144,44 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
i2c_set_clientdata(client, codec);
codec->control_data = client;
+ reg = regulator_get(&client->dev, "VDDIO");
+ if (!IS_ERR(reg))
+ sgtl5000->reg_vddio = reg;
+
+ reg = regulator_get(&client->dev, "VDDA");
+ if (!IS_ERR(reg))
+ sgtl5000->reg_vdda = reg;
+
+ reg = regulator_get(&client->dev, "VDDD");
+ if (!IS_ERR(reg))
+ sgtl5000->reg_vddd = reg;
+
+ if (sgtl5000->reg_vdda) {
+ sgtl5000->vdda =
+ regulator_get_voltage(sgtl5000->reg_vdda) / 1000;
+ regulator_enable(sgtl5000->reg_vdda);
+ }
+ if (sgtl5000->reg_vddio) {
+ sgtl5000->vddio =
+ regulator_get_voltage(sgtl5000->reg_vddio) / 1000;
+ regulator_enable(sgtl5000->reg_vddio);
+ }
+ if (sgtl5000->reg_vddd) {
+ sgtl5000->vddd =
+ regulator_get_voltage(sgtl5000->reg_vddd) / 1000;
+ regulator_enable(sgtl5000->reg_vddd);
+ } else {
+ sgtl5000->vddd = 0; /* use internal regulator */
+ }
+
+ msleep(1);
+
val = sgtl5000_read(codec, SGTL5000_CHIP_ID);
if (((val & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
SGTL5000_PARTID_PART_ID) {
pr_err("Device with ID register %x is not a SGTL5000\n", val);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_codec_reg;
}
sgtl5000->rev = (val & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
@@ -1168,15 +1208,32 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
ret = snd_soc_register_codec(codec);
if (ret != 0) {
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- return ret;
+ goto err_codec_reg;
}
ret = snd_soc_register_dai(&sgtl5000_dai);
if (ret != 0) {
dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
- return ret;
+ goto err_codec_reg;
}
+ return 0;
+
+err_codec_reg:
+ if (sgtl5000->reg_vddd)
+ regulator_disable(sgtl5000->reg_vddd);
+ if (sgtl5000->reg_vdda)
+ regulator_disable(sgtl5000->reg_vdda);
+ if (sgtl5000->reg_vddio)
+ regulator_disable(sgtl5000->reg_vddio);
+ if (sgtl5000->reg_vddd)
+ regulator_put(sgtl5000->reg_vddd);
+ if (sgtl5000->reg_vdda)
+ regulator_put(sgtl5000->reg_vdda);
+ if (sgtl5000->reg_vddio)
+ regulator_put(sgtl5000->reg_vddio);
+ kfree(sgtl5000);
+ kfree(codec);
return ret;
}
@@ -1187,6 +1244,20 @@ static __devexit int sgtl5000_i2c_remove(struct i2c_client *client)
snd_soc_unregister_dai(&sgtl5000_dai);
snd_soc_unregister_codec(codec);
+
+ if (sgtl5000->reg_vddio) {
+ regulator_disable(sgtl5000->reg_vddio);
+ regulator_put(sgtl5000->reg_vddio);
+ }
+ if (sgtl5000->reg_vddd) {
+ regulator_disable(sgtl5000->reg_vddd);
+ regulator_put(sgtl5000->reg_vddd);
+ }
+ if (sgtl5000->reg_vdda) {
+ regulator_disable(sgtl5000->reg_vdda);
+ regulator_put(sgtl5000->reg_vdda);
+ }
+
kfree(codec);
kfree(sgtl5000);
sgtl5000_codec = NULL;
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index 177be05b486c..e37b124f67dd 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -396,10 +396,4 @@ extern struct snd_soc_codec_device soc_codec_dev_sgtl5000;
#define SGTL5000_SYSCLK 0x00
#define SGTL5000_LRCLK 0x01
-struct sgtl5000_platform_data {
- int vddio; /* voltage of VDDIO (mv) */
- int vdda; /* voltage of vdda (mv) */
- int vddd; /* voltage of vddd (mv), 0 if not connected */
-};
-
#endif
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