summaryrefslogtreecommitdiff
path: root/sound/soc/ux500/ux500_ab8500.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/ux500/ux500_ab8500.c')
-rw-r--r--sound/soc/ux500/ux500_ab8500.c110
1 files changed, 71 insertions, 39 deletions
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;
}