aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/omap/Kconfig2
-rw-r--r--sound/soc/omap/omap-abe.c4
-rwxr-xr-xsound/soc/omap/sdp4430.c196
3 files changed, 166 insertions, 36 deletions
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index ffcfeee..caeccc7 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -115,6 +115,8 @@ config SND_OMAP_SOC_SDP4430
select SND_SOC_DMIC
select SND_OMAP_SOC_DMIC
select SND_OMAP_SOC_ABE_DSP
+ select SND_OMAP_SOC_MCASP
+ select SND_OMAP_SOC_SPDIF
help
Say Y if you want to add support for SoC audio on Texas Instruments
SDP4430 or PandaBoard.
diff --git a/sound/soc/omap/omap-abe.c b/sound/soc/omap/omap-abe.c
index da5ba44..b05dfe8 100644
--- a/sound/soc/omap/omap-abe.c
+++ b/sound/soc/omap/omap-abe.c
@@ -342,7 +342,7 @@ static void enable_be_port(struct snd_soc_pcm_runtime *be,
/* BT_DL connection to McBSP 1 ports */
format.f = 8000;
- format.samp_format = MONO_RSHIFTED_16;
+ format.samp_format = STEREO_RSHIFTED_16;
abe_connect_serial_port(BT_VX_DL_PORT, &format, MCBSP1_TX);
omap_abe_port_enable(abe_priv->abe,
abe_priv->port[OMAP_ABE_BE_PORT_BT_VX_DL]);
@@ -355,7 +355,7 @@ static void enable_be_port(struct snd_soc_pcm_runtime *be,
/* BT_UL connection to McBSP 1 ports */
format.f = 8000;
- format.samp_format = MONO_RSHIFTED_16;
+ format.samp_format = STEREO_RSHIFTED_16;
abe_connect_serial_port(BT_VX_UL_PORT, &format, MCBSP1_RX);
omap_abe_port_enable(abe_priv->abe,
abe_priv->port[OMAP_ABE_BE_PORT_BT_VX_UL]);
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 9fc42e7..ece0d24 100755
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -35,6 +35,7 @@
#include <plat/mux.h>
#include <plat/mcbsp.h>
+#include <linux/gpio.h>
#include "omap-mcpdm.h"
#include "omap-abe.h"
#include "omap-abe-dsp.h"
@@ -42,10 +43,31 @@
#include "omap-mcbsp.h"
#include "../codecs/twl6040.h"
+#include "../../../arch/arm/mach-omap2/board-tuna.h"
+
+#define TUNA_MAIN_MIC_GPIO 48
+#define TUNA_SUB_MIC_GPIO 171
+
static int twl6040_power_mode;
static int mcbsp_cfg;
static struct snd_soc_codec *twl6040_codec;
+int omap4_tuna_get_type(void);
+
+static int main_mic_bias_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ gpio_set_value(TUNA_MAIN_MIC_GPIO, SND_SOC_DAPM_EVENT_ON(event));
+ return 0;
+}
+
+static int sub_mic_bias_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ gpio_set_value(TUNA_SUB_MIC_GPIO, SND_SOC_DAPM_EVENT_ON(event));
+ return 0;
+}
+
static int sdp4430_modem_mcbsp_configure(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, int flag)
{
@@ -67,18 +89,46 @@ static int sdp4430_modem_mcbsp_configure(struct snd_pcm_substream *substream,
modem_substream[substream->stream]->private_data;
if (!mcbsp_cfg) {
- /* Set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
-
- if (unlikely(ret < 0)) {
- printk(KERN_ERR "can't set Modem cpu DAI configuration\n");
- goto exit;
+ if (omap4_tuna_get_type() == TUNA_TYPE_TORO) {
+ /* Set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai,
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS);
+ if (unlikely(ret < 0)) {
+ printk(KERN_ERR "can't set Modem cpu DAI format\n");
+ goto exit;
+ }
+
+ /* McBSP2 fclk reparented to ABE_24M_FCLK */
+ ret = snd_soc_dai_set_sysclk(modem_rtd->cpu_dai,
+ OMAP_MCBSP_SYSCLK_CLKS_FCLK,
+ 32 * 96 * params_rate(params),
+ SND_SOC_CLOCK_IN);
+ if (unlikely(ret < 0)) {
+ printk(KERN_ERR "can't set Modem cpu DAI sysclk\n");
+ goto exit;
+ }
+
+ /* assuming McBSP2 is S16_LE stereo */
+ ret = snd_soc_dai_set_clkdiv(modem_rtd->cpu_dai, 0, 96);
+ if (unlikely(ret < 0)) {
+ printk(KERN_ERR "can't set Modem cpu DAI clkdiv\n");
+ goto exit;
+ }
} else {
- mcbsp_cfg = 1;
+ /* Set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai,
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM);
+
+ if (unlikely(ret < 0)) {
+ printk(KERN_ERR "can't set Modem cpu DAI configuration\n");
+ goto exit;
+ }
}
+ mcbsp_cfg = 1;
}
if (params != NULL) {
@@ -186,25 +236,28 @@ static int sdp4430_mcbsp_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
- unsigned int be_id;
+ int ret = 0, channels = 0;
+ unsigned int be_id, fmt;
be_id = rtd->dai_link->be_id;
- if (be_id == OMAP_ABE_DAI_MM_FM) {
- /* Set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
- } else if (be_id == OMAP_ABE_DAI_BT_VX) {
- ret = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_DSP_B |
- SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_CBM_CFM);
+ if (be_id == OMAP_ABE_DAI_BT_VX) {
+ if (machine_is_tuna())
+ fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ else
+ fmt = SND_SOC_DAIFMT_DSP_B |
+ SND_SOC_DAIFMT_NB_IF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ } else {
+ fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
}
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
printk(KERN_ERR "can't set cpu DAI configuration\n");
return ret;
@@ -216,11 +269,25 @@ static int sdp4430_mcbsp_hw_params(struct snd_pcm_substream *substream,
*/
/* Set McBSP clock to external */
ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK,
- 64 * params_rate(params),
+ 32 * 96 * params_rate(params),
SND_SOC_CLOCK_IN);
if (ret < 0)
printk(KERN_ERR "can't set cpu system clock\n");
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 96);
+ if (ret < 0)
+ printk(KERN_ERR "can't set McBSP cpu DAI clkdiv\n");
+
+ /*
+ * Configure McBSP internal buffer threshold
+ * for playback/record
+ */
+ channels = params_channels(params);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ omap_mcbsp_set_tx_threshold(cpu_dai->id, channels);
+ else
+ omap_mcbsp_set_rx_threshold(cpu_dai->id, channels);
+
return ret;
}
@@ -238,7 +305,7 @@ static int mcbsp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
if (be_id == OMAP_ABE_DAI_MM_FM)
channels->min = 2;
else if (be_id == OMAP_ABE_DAI_BT_VX)
- channels->min = 1;
+ channels->min = 2;
snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
SNDRV_PCM_HW_PARAM_FIRST_MASK],
SNDRV_PCM_FORMAT_S16_LE);
@@ -292,7 +359,15 @@ static const struct snd_kcontrol_new sdp4430_controls[] = {
/* SDP4430 machine DAPM */
static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
- SND_SOC_DAPM_MIC("Ext Mic", NULL),
+
+ SND_SOC_DAPM_MIC("Ext Main Mic", NULL),
+ SND_SOC_DAPM_MIC("Ext Sub Mic", NULL),
+ SND_SOC_DAPM_MICBIAS_E("Ext Main Mic Bias", SND_SOC_NOPM, 0, 0,
+ main_mic_bias_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_MICBIAS_E("Ext Sub Mic Bias", SND_SOC_NOPM, 0, 0,
+ sub_mic_bias_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SPK("Ext Spk", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_HP("Headset Stereophone", NULL),
@@ -302,9 +377,10 @@ static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
static const struct snd_soc_dapm_route audio_map[] = {
/* External Mics: MAINMIC, SUBMIC with bias*/
- {"MAINMIC", NULL, "Main Mic Bias"},
- {"SUBMIC", NULL, "Main Mic Bias"},
- {"Main Mic Bias", NULL, "Ext Mic"},
+ {"MAINMIC", NULL, "Ext Main Mic Bias"},
+ {"SUBMIC", NULL, "Ext Sub Mic Bias"},
+ {"Ext Main Mic Bias" , NULL, "Ext Main Mic"},
+ {"Ext Sub Mic Bias" , NULL, "Ext Sub Mic"},
/* External Speakers: HFL, HFR */
{"Ext Spk", NULL, "HFL"},
@@ -371,7 +447,10 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* SDP4430 connected pins */
- snd_soc_dapm_enable_pin(dapm, "Ext Mic");
+ if (machine_is_tuna()) {
+ snd_soc_dapm_enable_pin(dapm, "Ext Main Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Sub Mic");
+ }
snd_soc_dapm_enable_pin(dapm, "Ext Spk");
snd_soc_dapm_enable_pin(dapm, "AFML");
snd_soc_dapm_enable_pin(dapm, "AFMR");
@@ -379,7 +458,10 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
/* allow audio paths from the audio modem to run during suspend */
- snd_soc_dapm_ignore_suspend(dapm, "Ext Mic");
+ if (machine_is_tuna()) {
+ snd_soc_dapm_ignore_suspend(dapm, "Ext Main Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Ext Sub Mic");
+ }
snd_soc_dapm_ignore_suspend(dapm, "Ext Spk");
snd_soc_dapm_ignore_suspend(dapm, "AFML");
snd_soc_dapm_ignore_suspend(dapm, "AFMR");
@@ -460,6 +542,12 @@ static int sdp4430_bt_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static int sdp4430_spdif_init(struct snd_soc_pcm_runtime *rtd)
+{
+ rtd->pmdown_time = 0;
+ return 0;
+}
+
static int sdp4430_stream_event(struct snd_soc_dapm_context *dapm)
{
/*
@@ -678,6 +766,17 @@ static struct snd_soc_dai_link sdp4430_dai[] = {
.ops = &sdp4430_mcpdm_ops,
.ignore_suspend = 1,
},
+ {
+ .name = "SPDIF",
+ .stream_name = "SPDIF",
+ .cpu_dai_name = "omap-mcasp-dai",
+ .codec_dai_name = "dit-hifi", /* dummy s/pdif transciever
+ * driver */
+ .platform_name = "omap-pcm-audio",
+ .ignore_suspend = 1,
+ .no_codec = 1,
+ .init = sdp4430_spdif_init,
+ },
/*
* Backend DAIs - i.e. dynamically matched interfaces, invisible to userspace.
@@ -843,20 +942,38 @@ static int __init sdp4430_soc_init(void)
{
int ret;
- if (!machine_is_omap_4430sdp() && !machine_is_omap4_panda()) {
- pr_debug("Not SDP4430 or PandaBoard!\n");
+ if (!machine_is_omap_4430sdp() && !machine_is_omap4_panda() &&
+ !machine_is_tuna()) {
+ pr_debug("Not SDP4430, PandaBoard or Tuna!\n");
return -ENODEV;
}
printk(KERN_INFO "SDP4430 SoC init\n");
+
+ if (machine_is_tuna()) {
+ ret = gpio_request(TUNA_MAIN_MIC_GPIO, "MAIN_MICBIAS_EN");
+ if (ret)
+ goto mainmic_gpio_err;
+
+ gpio_direction_output(TUNA_MAIN_MIC_GPIO, 0);
+
+ ret = gpio_request(TUNA_SUB_MIC_GPIO, "SUB_MICBIAS_EN");
+ if (ret)
+ goto submic_gpio_err;
+ gpio_direction_output(TUNA_SUB_MIC_GPIO, 0);
+ }
+
if (machine_is_omap_4430sdp())
snd_soc_sdp4430.name = "SDP4430";
else if (machine_is_omap4_panda())
snd_soc_sdp4430.name = "Panda";
+ else if (machine_is_tuna())
+ snd_soc_sdp4430.name = "Tuna";
sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
if (!sdp4430_snd_device) {
printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto device_err;
}
ret = snd_soc_register_dais(&sdp4430_snd_device->dev, dai, ARRAY_SIZE(dai));
@@ -876,12 +993,23 @@ static int __init sdp4430_soc_init(void)
err:
printk(KERN_ERR "Unable to add platform device\n");
platform_device_put(sdp4430_snd_device);
+device_err:
+ if (machine_is_tuna())
+ gpio_free(TUNA_SUB_MIC_GPIO);
+submic_gpio_err:
+ if (machine_is_tuna())
+ gpio_free(TUNA_MAIN_MIC_GPIO);
+mainmic_gpio_err:
return ret;
}
module_init(sdp4430_soc_init);
static void __exit sdp4430_soc_exit(void)
{
+ if (machine_is_tuna()) {
+ gpio_free(TUNA_SUB_MIC_GPIO);
+ gpio_free(TUNA_MAIN_MIC_GPIO);
+ }
platform_device_unregister(sdp4430_snd_device);
}
module_exit(sdp4430_soc_exit);