aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@linaro.org>2011-05-05 11:18:52 +0200
committerHenrik Aberg <henrik.aberg@stericsson.com>2011-05-18 09:39:45 +0200
commit039189e1a229f095d64dd21cd02ebe457005c2c5 (patch)
tree184b158d8984a7302d81e2de5dece5f19e4e9892 /sound
parent7ce95a4396e9cdd49f254abc8a75dbe9b7725230 (diff)
Ux500 ASoC: Adaptations in the AB8500-parts for U8500.
Support added for more channels and more formats and configuration possibilities. Added controls in AB8500-codec for fsbitclk and master generator. Change-Id: I2ea60c54c3892340b4a0d1771a1efdb504cc2495 Signed-off-by: Ola Lilja <elilola@steludxu2785.(none)> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/18279 Tested-by: Ola LILJA2 <ola.o.lilja@stericsson.com> Reviewed-by: Roger NILSSON1 <roger.xr.nilsson@stericsson.com> Conflicts: arch/arm/mach-ux500/board-mop500.c
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/ab8500.c208
-rw-r--r--sound/soc/codecs/ab8500.h3
-rw-r--r--sound/soc/codecs/cg29xx.c6
-rw-r--r--sound/soc/ux500/ux500_ab8500.c110
-rw-r--r--sound/soc/ux500/ux500_av8100.c12
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c4
-rw-r--r--sound/soc/ux500/ux500_pcm.c17
7 files changed, 263 insertions, 97 deletions
diff --git a/sound/soc/codecs/ab8500.c b/sound/soc/codecs/ab8500.c
index 2d2142082a7..b9685518ae1 100644
--- a/sound/soc/codecs/ab8500.c
+++ b/sound/soc/codecs/ab8500.c
@@ -1059,6 +1059,7 @@ static DECLARE_TLV_DB_SCALE(lin2hs_gain_tlv, -3800, 200, 1);
static const char *enum_ena_dis[] = {"Enabled", "Disabled"};
static const char *enum_dis_ena[] = {"Disabled", "Enabled"};
+
static SOC_ENUM_SINGLE_DECL(soc_enum_hshpen,
REG_ANACONF1, REG_ANACONF1_HSHPEN, enum_dis_ena);
static SOC_ENUM_SINGLE_DECL(soc_enum_hslowpow,
@@ -1145,7 +1146,14 @@ static const char *enum_fadespeed[] = {"1ms", "4ms", "8ms", "16ms"};
static SOC_ENUM_SINGLE_DECL(soc_enum_fadespeed,
REG_HSRDIGGAIN, REG_HSRDIGGAIN_FADESPEED, enum_fadespeed);
-/* XXX move to DAPM */
+static SOC_ENUM_SINGLE_DECL(soc_enum_mastgen,
+ REG_DIGIFCONF1, REG_DIGIFCONF1_ENMASTGEN, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_fsbitclk0,
+ REG_DIGIFCONF1, REG_DIGIFCONF1_ENFSBITCLK0, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_fsbitclk1,
+ REG_DIGIFCONF1, REG_DIGIFCONF1_ENFSBITCLK1, enum_dis_ena);
+
+/* TODO: move to DAPM */
static SOC_ENUM_SINGLE_DECL(soc_enum_enfirsids,
REG_SIDFIRCONF, REG_SIDFIRCONF_ENFIRSIDS, enum_dis_ena);
static SOC_ENUM_SINGLE_DECL(soc_enum_parlhf,
@@ -1220,7 +1228,7 @@ static struct snd_kcontrol_new ab8500_snd_controls[] = {
REG_PWMGENCONFX_PWMVIBXDUTCYC,
REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX, NORMAL),
- /* XXX move to DAPM */
+ /* TODO: move to DAPM */
SOC_ENUM("Sidetone Playback Switch", soc_enum_enfirsids),
SOC_ENUM("IHF L and R Bridge Playback Route", soc_enum_parlhf),
SOC_ENUM("Vibra 1 and 2 Bridge Playback Route", soc_enum_parlvib),
@@ -1280,6 +1288,10 @@ static struct snd_kcontrol_new ab8500_snd_controls[] = {
REG_DIGLINHSLGAIN, REG_DIGLINHSRGAIN,
REG_DIGLINHSXGAIN_LINTOHSXGAIN,
REG_DIGLINHSXGAIN_LINTOHSXGAIN_MAX, INVERT, lin2hs_gain_tlv),
+
+ SOC_ENUM("Digital Interface Master Generator Switch", soc_enum_mastgen),
+ SOC_ENUM("Digital Interface 0 Bit-clock Switch", soc_enum_fsbitclk0),
+ SOC_ENUM("Digital Interface 1 Bit-clock Switch", soc_enum_fsbitclk1),
};
static int ab8500_add_widgets(struct snd_soc_codec *codec)
@@ -1305,6 +1317,63 @@ static int ab8500_add_widgets(struct snd_soc_codec *codec)
return 0;
}
+int ab8500_set_word_length(struct snd_soc_dai *dai, unsigned int wl)
+{
+ unsigned int clear_mask;
+ unsigned int set_mask = 0;
+ struct snd_soc_codec *codec = dai->codec;
+
+ clear_mask = BMASK(REG_DIGIFCONF2_IF0WL0) | BMASK(REG_DIGIFCONF2_IF0WL1);
+
+ switch (wl) {
+ case 16:
+ break;
+ case 20:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0WL0);
+ break;
+ case 24:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1);
+ break;
+ case 32:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1) |
+ BMASK(REG_DIGIFCONF2_IF0WL0);
+ break;
+ default:
+ pr_err("%s: Unsupporter word-length 0x%x\n", __func__, wl);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: Word-length: %d bits.\n", __func__, wl);
+ ab8500_update_audio_reg(codec, REG_DIGIFCONF2, clear_mask, set_mask);
+
+ return 0;
+}
+
+int ab8500_set_bit_delay(struct snd_soc_dai *dai, unsigned int delay)
+{
+ unsigned int clear_mask;
+ unsigned int set_mask = 0;
+ struct snd_soc_codec *codec = dai->codec;
+
+ clear_mask = BMASK(REG_DIGIFCONF2_IF0DEL);
+
+ switch (delay) {
+ case 0:
+ break;
+ case 1:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0DEL);
+ break;
+ default:
+ pr_err("%s: Unsupported bit-delay (0x%x)!\n", __func__, delay);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: Bit-delay: %d bits.\n", __func__, delay);
+ ab8500_update_audio_reg(codec, REG_DIGIFCONF2, clear_mask, set_mask);
+
+ return 0;
+}
+
static int ab8500_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
{
@@ -1388,16 +1457,16 @@ static int set_dai_clock_gate(struct snd_soc_codec *codec, unsigned int fmt)
clear_mask = BMASK(REG_DIGIFCONF1_ENMASTGEN) |
BMASK(REG_DIGIFCONF1_ENFSBITCLK0);
- set_mask = 0;
+
+ set_mask = BMASK(REG_DIGIFCONF1_ENMASTGEN);
switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
case SND_SOC_DAIFMT_CONT: /* continuous clock */
- pr_info("- Clock is not gated\n");
- set_mask |= BMASK(REG_DIGIFCONF1_ENMASTGEN);
+ pr_info("- Clock is continous.\n");
set_mask |= BMASK(REG_DIGIFCONF1_ENFSBITCLK0);
break;
case SND_SOC_DAIFMT_GATED: /* clock is gated */
- pr_info("- Clock IS gated\n");
+ pr_info("- Clock is gated.\n");
break;
default:
pr_err("Unsupporter clock mask 0x%x\n",
@@ -1435,22 +1504,26 @@ static int ab8500_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
}
/* Setting data transfer format */
- clear_mask = REG_MASK_ALL;
+ clear_mask = BMASK(REG_DIGIFCONF2_IF0FORMAT0) |
+ BMASK(REG_DIGIFCONF2_IF0FORMAT1) |
+ BMASK(REG_DIGIFCONF2_FSYNC0P) |
+ BMASK(REG_DIGIFCONF2_BITCLK0P);
+
set_mask = 0;
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S: /* I2S mode */
pr_info("- FORMAT I2S\n");
set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT1);
- set_mask |= BMASK(REG_DIGIFCONF2_IF0DEL);
- /* 32 bit */
- set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1) |
- BMASK(REG_DIGIFCONF2_IF0WL0);
+ /* 32 bit, 0 delay */
+ ab8500_set_word_length(dai, 32);
+ ab8500_set_bit_delay(dai, 0);
+
break;
case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */
pr_info("- FORMAT DSP A\n");
- set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT0);
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT1);
break;
case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */
pr_info("- FORMAT DSP B\n");
@@ -1496,9 +1569,8 @@ static int ab8500_set_dai_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask,
int slots, int slot_width)
{
- int data;
struct snd_soc_codec *codec = dai->codec;
- unsigned int clear_mask;
+ unsigned int set_mask, clear_mask, slots_active;
/* Only 16 bit slot width is supported at the moment in TDM mode */
if (slot_width != 16) {
@@ -1507,48 +1579,98 @@ static int ab8500_set_dai_tdm_slot(struct snd_soc_dai *dai,
return -EINVAL;
}
- /* Set the TDM clocking according to slot count */
+ /* Setup TDM clocking according to slot count */
+ pr_debug("%s: Slots, total: %d\n", __func__, slots);
+ clear_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) |
+ BMASK(REG_DIGIFCONF1_IF0BITCLKOS1);
switch (slots) {
case 2:
- data = REG_MASK_NONE;
+ set_mask = REG_MASK_NONE;
break;
case 4:
- data = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0);
+ set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0);
break;
case 8:
- data = BMASK(REG_DIGIFCONF1_IF0BITCLKOS1);
+ set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS1);
break;
case 16:
- data = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) |
+ set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) |
BMASK(REG_DIGIFCONF1_IF0BITCLKOS1);
break;
default:
- pr_err("%s: Unsupported slots %d.\n", __func__, slots);
+ pr_err("%s: Unsupported number of slots (%d)!\n", __func__, slots);
return -EINVAL;
}
+ ab8500_update_audio_reg(codec, REG_DIGIFCONF1, clear_mask, set_mask);
- ab8500_update_audio_reg(codec, REG_DIGIFCONF1,
- BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) |
- BMASK(REG_DIGIFCONF1_IF0BITCLKOS1),
- data);
-
- /* XXX Make slot configuration as a control */
-
+ /* Setup TDM DA according to active tx slots */
clear_mask = REG_DASLOTCONFX_SLTODAX_MASK;
+ slots_active = hweight32(tx_mask);
+ pr_debug("%s: Slots, active, TX: %d\n", __func__, slots_active);
+ switch (slots_active) {
+ case 0:
+ break;
+ case 1:
+ /* Slot 9 -> DA_IN1 & DA_IN3 */
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF1, clear_mask, 9);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF3, clear_mask, 9);
+ break;
+ case 2:
+ /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF1, clear_mask, 9);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF3, clear_mask, 9);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF2, clear_mask, 11);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF4, clear_mask, 11);
- /* DA_IN1/3/5 receives slot 9, DA_IN2/4/6 receives slot 11 */
- ab8500_update_audio_reg(codec, REG_DASLOTCONF1, clear_mask, 9);
- ab8500_update_audio_reg(codec, REG_DASLOTCONF2, clear_mask, 11);
- ab8500_update_audio_reg(codec, REG_DASLOTCONF3, clear_mask, 9);
- ab8500_update_audio_reg(codec, REG_DASLOTCONF4, clear_mask, 11);
- ab8500_update_audio_reg(codec, REG_DASLOTCONF5, clear_mask, 9);
- ab8500_update_audio_reg(codec, REG_DASLOTCONF6, clear_mask, 11);
+ break;
+ case 8:
+ /* Slot 8-15 -> DA_IN1-DA_IN8 */
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF1, clear_mask, 8);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF2, clear_mask, 9);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF3, clear_mask, 10);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF4, clear_mask, 11);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF5, clear_mask, 12);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF6, clear_mask, 13);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF7, clear_mask, 14);
+ ab8500_update_audio_reg(codec, REG_DASLOTCONF8, clear_mask, 15);
- /* AD_OUT3 transmits slots 0 & 1 */
- ab8500_update_audio_reg(codec, REG_ADSLOTSEL1,
+ break;
+ default:
+ pr_err("%s: Unsupported number of active TX-slots (%d)!\n", __func__, slots_active);
+ return -EINVAL;
+ }
+
+ /* Setup TDM AD according to active RX-slots */
+ slots_active = hweight32(rx_mask);
+ pr_debug("%s: Slots, active, RX: %d\n", __func__, slots_active);
+ switch (slots_active) {
+ case 0:
+ break;
+ case 1:
+ /* AD_OUT3 -> slot 0 & 1 */
+ ab8500_update_audio_reg(codec, REG_ADSLOTSEL1,
REG_MASK_ALL,
BMASK(REG_ADSLOTSELX_ODDX_1) |
BMASK(REG_ADSLOTSELX_EVENX_1));
+ break;
+ case 2:
+ /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */
+ ab8500_update_audio_reg(codec, REG_ADSLOTSEL1,
+ REG_MASK_ALL,
+ BMASK(REG_ADSLOTSELX_ODDX_0) |
+ BMASK(REG_ADSLOTSELX_EVENX_1));
+ break;
+ case 8:
+ /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */
+ ab8500_update_audio_reg(codec, REG_ADSLOTSEL1,
+ REG_MASK_ALL,
+ BMASK(REG_ADSLOTSELX_ODDX_0) |
+ BMASK(REG_ADSLOTSELX_EVENX_1));
+ break;
+ default:
+ pr_err("%s: Unsupported number of active RX-slots (%d)!\n", __func__, slots_active);
+ return -EINVAL;
+ }
return 0;
}
@@ -1560,7 +1682,7 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = {
.playback = {
.stream_name = "ab8500_0p",
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 8,
.rates = AB8500_SUPPORTED_RATE,
.formats = AB8500_SUPPORTED_FMT,
},
@@ -1583,7 +1705,7 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = {
.capture = {
.stream_name = "ab8500_0c",
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 8,
.rates = AB8500_SUPPORTED_RATE,
.formats = AB8500_SUPPORTED_FMT,
},
@@ -1720,12 +1842,16 @@ struct snd_soc_codec_driver ab8500_codec_drv = {
.reg_cache_default = ab8500_reg_cache,
};
-static int __devinit ab8500_codec_drv_probe(struct platform_device *pdev)
+static int ab8500_codec_drv_probe(struct platform_device *pdev)
{
int err;
+ struct ab8500_codec_dai_data *dai_data;
pr_debug("%s: Enter.\n", __func__);
+ platform_set_drvdata(pdev, dai_data);
+
+ pr_info("%s: Register codec.\n", __func__);
err = snd_soc_register_codec(&pdev->dev,
&ab8500_codec_drv,
ab8500_codec_dai,
@@ -1739,7 +1865,7 @@ static int __devinit ab8500_codec_drv_probe(struct platform_device *pdev)
return err;
}
-static int __devexit ab8500_codec_drv_remove(struct platform_device *pdev)
+static int ab8500_codec_drv_remove(struct platform_device *pdev)
{
pr_debug("%s Enter.\n", __func__);
@@ -1769,7 +1895,7 @@ static struct platform_driver ab8500_codec_platform_drv = {
.owner = THIS_MODULE,
},
.probe = ab8500_codec_drv_probe,
- .remove = __devexit_p(ab8500_codec_drv_remove),
+ .remove = ab8500_codec_drv_remove,
.suspend = ab8500_codec_drv_suspend,
.resume = ab8500_codec_drv_resume,
};
diff --git a/sound/soc/codecs/ab8500.h b/sound/soc/codecs/ab8500.h
index 415d73a87a5..ef3e4907878 100644
--- a/sound/soc/codecs/ab8500.h
+++ b/sound/soc/codecs/ab8500.h
@@ -22,6 +22,9 @@ extern struct snd_soc_codec_driver soc_codec_dev_ab8500;
#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
+int ab8500_set_word_length(struct snd_soc_dai *dai, unsigned int wl);
+int ab8500_set_bit_delay(struct snd_soc_dai *dai, unsigned int delay);
+
/* AB8500 audio bank (0x0d) register definitions */
#define REG_POWERUP 0x00
diff --git a/sound/soc/codecs/cg29xx.c b/sound/soc/codecs/cg29xx.c
index 56b23be8e97..272f8f9287b 100644
--- a/sound/soc/codecs/cg29xx.c
+++ b/sound/soc/codecs/cg29xx.c
@@ -651,7 +651,7 @@ struct snd_soc_codec_driver cg29xx_codec_drv = {
.write = cg29xx_codec_write,
};
-static __devinit int cg29xx_codec_drv_probe(struct platform_device *pdev)
+static int cg29xx_codec_drv_probe(struct platform_device *pdev)
{
int ret;
struct cg29xx_codec_dai_data *dai_data;
@@ -714,7 +714,7 @@ static __devinit int cg29xx_codec_drv_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit cg29xx_codec_drv_remove(struct platform_device *pdev)
+static int cg29xx_codec_drv_remove(struct platform_device *pdev)
{
(void)cg2900_audio_close(&codec_private.session);
@@ -741,7 +741,7 @@ static struct platform_driver cg29xx_codec_platform_drv = {
.owner = THIS_MODULE,
},
.probe = cg29xx_codec_drv_probe,
- .remove = __devexit_p(cg29xx_codec_drv_remove),
+ .remove = cg29xx_codec_drv_remove,
.suspend = cg29xx_codec_drv_suspend,
.resume = cg29xx_codec_drv_resume,
};
diff --git a/sound/soc/ux500/ux500_ab8500.c b/sound/soc/ux500/ux500_ab8500.c
index 6cb36b43904..44b1164a75a 100644
--- a/sound/soc/ux500/ux500_ab8500.c
+++ b/sound/soc/ux500/ux500_ab8500.c
@@ -28,20 +28,19 @@
#include "ux500_msp_dai.h"
#include "../codecs/ab8500.h"
-#define AB8500_DAIFMT_TDM_MASTER \
- (SND_SOC_DAIFMT_DSP_B | \
- SND_SOC_DAIFMT_CBM_CFM | \
- SND_SOC_DAIFMT_NB_NF | \
- SND_SOC_DAIFMT_CONT)
-
#define TX_SLOT_MONO 0x0008
#define TX_SLOT_STEREO 0x000a
#define RX_SLOT_MONO 0x0001
#define RX_SLOT_STEREO 0x0003
+#define TX_SLOT_8CH 0x00FF
+#define RX_SLOT_8CH 0x00FF
#define DEF_TX_SLOTS TX_SLOT_STEREO
#define DEF_RX_SLOTS RX_SLOT_MONO
+#define DRIVERMODE_NORMAL 0
+#define DRIVERMODE_CODEC_ONLY 1
+
static struct snd_soc_jack jack;
/* Slot configuration */
@@ -155,11 +154,13 @@ int ux500_ab8500_hw_params(
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int channels, ret = 0;
+ unsigned int fmt;
+ int channels, ret = 0, slots, slot_width, driver_mode;
+ bool streamIsPlayback;
- pr_info("%s: Enter\n", __func__);
+ pr_debug("%s: Enter\n", __func__);
- pr_info("%s: substream->pcm->name = %s\n"
+ pr_debug("%s: substream->pcm->name = %s\n"
"substream->pcm->id = %s.\n"
"substream->name = %s.\n"
"substream->number = %d.\n",
@@ -169,49 +170,80 @@ int ux500_ab8500_hw_params(
substream->name,
substream->number);
- ret = snd_soc_dai_set_fmt(codec_dai, AB8500_DAIFMT_TDM_MASTER);
+ channels = params_channels(params);
+
+ /* Setup codec depending on driver-mode */
+ driver_mode = (channels == 8) ?
+ DRIVERMODE_CODEC_ONLY : DRIVERMODE_NORMAL;
+ pr_debug("%s: Driver-mode: %s.\n",
+ __func__,
+ (driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY");
+ if (driver_mode == DRIVERMODE_NORMAL) {
+ ab8500_set_bit_delay(codec_dai, 0);
+ ab8500_set_word_length(codec_dai, 16);
+ fmt = SND_SOC_DAIFMT_DSP_B |
+ SND_SOC_DAIFMT_CBM_CFM |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CONT;
+ } else {
+ ab8500_set_bit_delay(codec_dai, 1);
+ ab8500_set_word_length(codec_dai, 20);
+ fmt = SND_SOC_DAIFMT_DSP_B |
+ SND_SOC_DAIFMT_CBM_CFM |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_GATED;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
if (ret < 0) {
- pr_err("%s: snd_soc_dai_set_fmt failed codec_dai %d.\n",
- __func__, ret);
+ pr_err("%s: snd_soc_dai_set_fmt failed for codec_dai (ret = %d).\n",
+ __func__,
+ ret);
return ret;
}
- ret = snd_soc_dai_set_fmt(cpu_dai, AB8500_DAIFMT_TDM_MASTER);
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
- pr_err("%s: snd_soc_dai_set_fmt cpu_dai %d.\n",
- __func__, ret);
+ pr_err("%s: snd_soc_dai_set_fmt for cpu_dai (ret = %d).\n",
+ __func__,
+ ret);
return ret;
}
- channels = params_channels(params);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (channels == 1)
- tx_slots = TX_SLOT_MONO;
- else if (channels == 2)
- tx_slots = TX_SLOT_STEREO;
- else
- return -EINVAL;
- } else {
- if (channels == 1)
- rx_slots = RX_SLOT_MONO;
- else if (channels == 2)
- rx_slots = RX_SLOT_STEREO;
- else
- return -EINVAL;
+ /* Setup TDM-slots */
+
+ streamIsPlayback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+ switch (channels) {
+ case 1:
+ slots = 16;
+ slot_width = 16;
+ tx_slots = (streamIsPlayback) ? TX_SLOT_MONO : 0;
+ rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_MONO;
+ break;
+ case 2:
+ slots = 16;
+ slot_width = 16;
+ tx_slots = (streamIsPlayback) ? TX_SLOT_STEREO : 0;
+ rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_STEREO;
+ break;
+ case 8:
+ slots = 16;
+ slot_width = 16;
+ tx_slots = (streamIsPlayback) ? TX_SLOT_8CH : 0;
+ rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_8CH;
+ break;
+ default:
+ return -EINVAL;
}
- pr_info("%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n",
+ pr_debug("%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n",
__func__, tx_slots, rx_slots);
- ret = snd_soc_dai_set_tdm_slot(cpu_dai,
- tx_slots, rx_slots,
- 16, 16);
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots,
+ slots, slot_width);
- pr_info("%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n",
+ pr_debug("%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n",
__func__, tx_slots, rx_slots);
- ret += snd_soc_dai_set_tdm_slot(codec_dai,
- tx_slots, rx_slots,
- 16, 16);
+ ret += snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots, slot_width);
return ret;
}
diff --git a/sound/soc/ux500/ux500_av8100.c b/sound/soc/ux500/ux500_av8100.c
index 9497b7b6636..5c7213001a0 100644
--- a/sound/soc/ux500/ux500_av8100.c
+++ b/sound/soc/ux500/ux500_av8100.c
@@ -16,20 +16,28 @@
#include "ux500_av8100.h"
#include "ux500_msp_dai.h"
+static const char *stream_str(struct snd_pcm_substream *substream)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ return "Playback";
+ else
+ return "Capture";
+}
+
static int ux500_av8100_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int channels = params_channels(params);
+ int channels = params_channels(params);
unsigned int tx_mask, fmt;
enum hdmi_channel_allocation hdmi_ca;
enum hdmi_audio_channel_count hdmi_cc;
struct hdmi_audio_settings as;
int ret;
- pr_debug("%s: Enter.\n", __func__);
+ pr_debug("%s: Enter (%s).\n", __func__, stream_str(substream));
pr_debug("%s: substream->pcm->name = %s.\n", __func__, substream->pcm->name);
pr_debug("%s: substream->pcm->id = %s.\n", __func__, substream->pcm->id);
pr_debug("%s: substream->name = %s.\n", __func__, substream->name);
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index d145c54e654..06f71a173d4 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -891,7 +891,7 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = {
};
EXPORT_SYMBOL(ux500_msp_dai_drv);
-static int __devinit ux500_msp_drv_probe(struct i2s_device *i2s_dev)
+static int ux500_msp_drv_probe(struct i2s_device *i2s_dev)
{
int ret = 0;
struct ux500_platform_drvdata *drvdata;
@@ -966,7 +966,7 @@ static struct i2s_driver i2sdrv_i2s_v1 = {
.owner = THIS_MODULE,
},
.probe = ux500_msp_drv_probe,
- .remove = __devexit_p(ux500_msp_drv_remove),
+ .remove = ux500_msp_drv_remove,
.id_table = dev_id_table_v1,
};
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 491cfef0c00..6ad088d8028 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -136,7 +136,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream)
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) {
@@ -171,9 +170,8 @@ static int ux500_pcm_close(struct snd_pcm_substream *substream)
return 0;
}
-static int ux500_pcm_hw_params(
- struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
+static int ux500_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dma_buffer *buf = runtime->dma_buffer_p;
@@ -369,7 +367,7 @@ struct snd_soc_platform_driver ux500_pcm_soc_drv = {
};
EXPORT_SYMBOL(ux500_pcm_soc_drv);
-static int __devinit ux500_pcm_drv_probe(struct platform_device *pdev)
+static int ux500_pcm_drv_probe(struct platform_device *pdev)
{
int ret;
@@ -386,7 +384,7 @@ static int __devinit ux500_pcm_drv_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ux500_pcm_drv_remove(struct platform_device *pdev)
+static int ux500_pcm_drv_remove(struct platform_device *pdev)
{
pr_debug("%s: Unregister ux500-pcm SoC platform driver.\n", __func__);
snd_soc_unregister_platform(&pdev->dev);
@@ -396,12 +394,12 @@ static int __devexit ux500_pcm_drv_remove(struct platform_device *pdev)
static struct platform_driver ux500_pcm_drv = {
.driver = {
- .name = "ux500-pcm",
- .owner = THIS_MODULE,
+ .name = "ux500-pcm",
+ .owner = THIS_MODULE,
},
.probe = ux500_pcm_drv_probe,
- .remove = __devexit_p(ux500_pcm_drv_remove),
+ .remove = ux500_pcm_drv_remove,
};
static int __init ux500_pcm_drv_init(void)
@@ -411,7 +409,6 @@ static int __init ux500_pcm_drv_init(void)
return platform_driver_register(&ux500_pcm_drv);
}
-
static void __exit ux500_pcm_drv_exit(void)
{
pr_debug("%s: Unregister ux500-pcm platform driver.\n", __func__);