diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/omap/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/omap/omap-abe.c | 4 | ||||
-rwxr-xr-x | sound/soc/omap/sdp4430.c | 196 |
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(¶ms->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); |