From 4ebcf44ba8606b3e2d267cecd7b396b846cf06b0 Mon Sep 17 00:00:00 2001 From: Linqiang Pu Date: Wed, 2 May 2012 21:37:27 +0800 Subject: dmaengine/dma_slave: fix merge issue. Change-Id: I0931f4ef7a5464dd32d8c703288a137fc77857ce Signed-off-by: Linqiang Pu Reviewed-on: http://git-master/r/100090 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Laxman Dewangan --- sound/soc/sh/siu_pcm.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index de9abd032fd4..5cfcc655e95f 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -180,13 +180,8 @@ static int siu_pcm_rd_set(struct siu_port *port_info, sg_dma_len(&sg) = size; sg_dma_address(&sg) = buff; -<<<<<<< HEAD - desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan, - &sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -======= desc = dmaengine_prep_slave_sg(siu_stream->chan, &sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); ->>>>>>> 1605282... dmaengine/dma_slave: introduce inline wrappers if (!desc) { dev_err(dev, "Failed to allocate dma descriptor\n"); return -ENOMEM; -- cgit v1.2.3 From 691d79e075d5f841853b248de6f5a6849e8dc906 Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Tue, 8 May 2012 16:44:59 +0530 Subject: asoc:codecs: tiaic326x: remove minidsp support disable the flags for turning off the mini dsp support Change-Id: Ieb0b18fc3cc1143cbd0a315c85688d2f1ae4efe1 Reviewed-on: http://git-master/r/101233 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Nikesh Oswal Reviewed-by: Scott Peterson --- sound/soc/codecs/tlv320aic326x.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/tlv320aic326x.h b/sound/soc/codecs/tlv320aic326x.h index a31cc9eca5ca..ebd673a20445 100644 --- a/sound/soc/codecs/tlv320aic326x.h +++ b/sound/soc/codecs/tlv320aic326x.h @@ -36,7 +36,7 @@ /* Enable register caching on write */ #define EN_REG_CACHE 1 -#define MULTIBYTE_CONFIG_SUPPORT +//#define MULTIBYTE_CONFIG_SUPPORT /*Setting all codec reg/write locally*/ /* This definition is added as the snd_ direct call are @@ -45,12 +45,12 @@ page, so fix that before commenting this line*/ #define LOCAL_REG_ACCESS 1 /* Macro to enable the inclusion of tiload kernel driver */ -#define AIC3262_TiLoad +//#define AIC3262_TiLoad /* Macro enables or disables support for miniDSP in the driver */ /* Enable the AIC3262_TiLoad macro first before enabling these macros */ -#define CONFIG_MINI_DSP +//#define CONFIG_MINI_DSP /*#undef CONFIG_MINI_DSP*/ /* Enable or disable controls to have Input routing*/ -- cgit v1.2.3 From 2b9e2850f6a2f500ccbfa0f1df92b8becb91efda Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Tue, 8 May 2012 16:46:06 +0530 Subject: asoc:codecs: aic326x: change alsa ctrls for headphone driver Use non-inverting type alsa control for headphones as same have been used for spk and recv Change-Id: I39d2613071063782dff8151b07ef46ca8e16db5c Signed-off-by: Nikesh Oswal Reviewed-on: http://git-master/r/101234 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Scott Peterson --- sound/soc/codecs/tlv320aic326x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/tlv320aic326x.c b/sound/soc/codecs/tlv320aic326x.c index 8bbd295a3328..ce8b5bc6cd95 100644 --- a/sound/soc/codecs/tlv320aic326x.c +++ b/sound/soc/codecs/tlv320aic326x.c @@ -2547,13 +2547,13 @@ static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { SOC_DAPM_SINGLE("MAL Switch", HP_AMP_CNTL_R1, 7, 1, 0), SOC_DAPM_SINGLE("LDAC Switch", HP_AMP_CNTL_R1, 5, 1, 0), SOC_DAPM_SINGLE_TLV("LOL-B1 Volume", HP_AMP_CNTL_R2, 0, - 0x7f, 1, lo_hp_tlv), + 0x7f, 0, lo_hp_tlv), }; /* Right HPR Mixer */ static const struct snd_kcontrol_new hpr_output_mixer_controls[] = { SOC_DAPM_SINGLE_TLV("LOR-B1 Volume", HP_AMP_CNTL_R3, 0, - 0x7f, 1, lo_hp_tlv), + 0x7f, 0, lo_hp_tlv), SOC_DAPM_SINGLE("LDAC Switch", HP_AMP_CNTL_R1, 2, 1, 0), SOC_DAPM_SINGLE("RDAC Switch", HP_AMP_CNTL_R1, 4, 1, 0), SOC_DAPM_SINGLE("MAR Switch", HP_AMP_CNTL_R1, 6, 1, 0), -- cgit v1.2.3 From b676926984f3f0fb53d29b01daf9eeb0f7012128 Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Tue, 8 May 2012 16:47:40 +0530 Subject: asoc: tegra: pcm: If there is no dma information exit from trigger If there is no dma information exit from trigger, this is required for the dummy voice call playback and capture streams Change-Id: I5276e7ebb72c17268a9785204fea9f395b2e5d3a Signed-off-by: Nikesh Oswal Reviewed-on: http://git-master/r/101235 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra_pcm.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 3b475a24c9a8..6ba3c9fa4461 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -257,9 +257,15 @@ int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *runtime = substream->runtime; struct tegra_runtime_data *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct tegra_pcm_dma_params * dmap; unsigned long flags; int i; + dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + if (!dmap) + return 0; + switch (cmd) { case SNDRV_PCM_TRIGGER_START: prtd->dma_pos = 0; -- cgit v1.2.3 From 398862ca28a284ff610ca471e831eec820cf5170 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Rawat Date: Mon, 26 Mar 2012 16:33:25 +0530 Subject: asoc: codecs: rt5640: resolve compilation time warnings bug 949219 Change-Id: I4409eaff4042967133cc948452ca8e52d15b2d18 Signed-off-by: Sanjay Singh Rawat Reviewed-on: http://git-master/r/92279 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani --- sound/soc/codecs/rt5640.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index cd84ed0858ac..8407c638cf8a 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -25,7 +25,7 @@ #include #include "rt5640.h" -#if (CONFIG_SND_SOC_RT5642_MODULE | CONFIG_SND_SOC_RT5642) +#if defined(CONFIG_SND_SOC_RT5642_MODULE) || defined(CONFIG_SND_SOC_RT5642) #include "rt5640-dsp.h" #endif @@ -1179,8 +1179,6 @@ static int spk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - static unsigned int spkl_out_enable; - static unsigned int spkr_out_enable; switch (event) { case SND_SOC_DAPM_POST_PMU: @@ -1206,9 +1204,6 @@ static int spk_event(struct snd_soc_dapm_widget *w, static int hp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; - static unsigned int hp_out_enable; - switch (event) { case SND_SOC_DAPM_POST_PMU: pr_info("hp_event --SND_SOC_DAPM_POST_PMU\n"); @@ -1820,9 +1815,8 @@ static int get_sdp_info(struct snd_soc_codec *codec, int dai_id) ret |= RT5640_U_IF3; break; -#if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ - CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) - +#if defined(CONFIG_SND_SOC_RT5643_MODULE) || defined(CONFIG_SND_SOC_RT5643) || \ + defined(CONFIG_SND_SOC_RT5646_MODULE) || defined(CONFIG_SND_SOC_RT5646) case RT5640_AIF3: if (val == RT5640_IF_312 || val == RT5640_IF_321) ret |= RT5640_U_IF1; @@ -1922,8 +1916,8 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream, RT5640_I2S_DL_MASK, val_len); snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk); } -#if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ - CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) +#if defined(CONFIG_SND_SOC_RT5643_MODULE) || defined(CONFIG_SND_SOC_RT5643) || \ + defined(CONFIG_SND_SOC_RT5646_MODULE) || defined(CONFIG_SND_SOC_RT5646) if (dai_sel & RT5640_U_IF3) { mask_clk = RT5640_I2S_BCLK_MS3_MASK | RT5640_I2S_PD3_MASK; val_clk = bclk_ms << RT5640_I2S_BCLK_MS3_SFT | @@ -2006,8 +2000,8 @@ static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK | RT5640_I2S_DF_MASK, reg_val); } -#if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ - CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) +#if defined(CONFIG_SND_SOC_RT5643_MODULE) || defined(CONFIG_SND_SOC_RT5643) || \ + defined(CONFIG_SND_SOC_RT5646_MODULE) || defined(CONFIG_SND_SOC_RT5646) if (dai_sel & RT5640_U_IF3) { snd_soc_update_bits(codec, RT5640_I2S3_SDP, RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK | @@ -2135,10 +2129,8 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, break; case RT5640_PLL1_S_BCLK1: case RT5640_PLL1_S_BCLK2: - -#if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ - CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) - +#if defined(CONFIG_SND_SOC_RT5643_MODULE) || defined(CONFIG_SND_SOC_RT5643) || \ + defined(CONFIG_SND_SOC_RT5646_MODULE) || defined(CONFIG_SND_SOC_RT5646) case RT5640_PLL1_S_BCLK3: #endif @@ -2358,8 +2350,7 @@ static int rt5640_probe(struct snd_soc_codec *codec) rt5640_reg_init(codec); #endif - -#if (CONFIG_SND_SOC_RT5642_MODULE | CONFIG_SND_SOC_RT5642) +#if defined(CONFIG_SND_SOC_RT5642_MODULE) || defined(CONFIG_SND_SOC_RT5642) rt5640_register_dsp(codec); #endif @@ -2458,8 +2449,8 @@ struct snd_soc_dai_driver rt5640_dai[] = { }, .ops = &rt5640_aif_dai_ops, }, -#if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ - CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) +#if defined(CONFIG_SND_SOC_RT5643_MODULE) || defined(CONFIG_SND_SOC_RT5643) || \ + defined(CONFIG_SND_SOC_RT5646_MODULE) || defined(CONFIG_SND_SOC_RT5646) { .name = "rt5640-aif3", .id = RT5640_AIF3, -- cgit v1.2.3 From d9ae4ef0984e3b1c1284e39d2ebf1c0558cfaa6f Mon Sep 17 00:00:00 2001 From: Simone Willett Date: Tue, 8 May 2012 16:31:49 -0700 Subject: Revert "asoc:codecs: tiaic326x: remove minidsp support" This reverts commit 774fa71fc9834fbdcb297048d9e9a4bc7b944b48 Change-Id: Ib187dff51d3b2fd2b2ac0c98a53abe07c99148aa Reviewed-on: http://git-master/r/101359 Reviewed-by: Simone Willett Tested-by: Simone Willett --- sound/soc/codecs/tlv320aic326x.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/tlv320aic326x.h b/sound/soc/codecs/tlv320aic326x.h index ebd673a20445..a31cc9eca5ca 100644 --- a/sound/soc/codecs/tlv320aic326x.h +++ b/sound/soc/codecs/tlv320aic326x.h @@ -36,7 +36,7 @@ /* Enable register caching on write */ #define EN_REG_CACHE 1 -//#define MULTIBYTE_CONFIG_SUPPORT +#define MULTIBYTE_CONFIG_SUPPORT /*Setting all codec reg/write locally*/ /* This definition is added as the snd_ direct call are @@ -45,12 +45,12 @@ page, so fix that before commenting this line*/ #define LOCAL_REG_ACCESS 1 /* Macro to enable the inclusion of tiload kernel driver */ -//#define AIC3262_TiLoad +#define AIC3262_TiLoad /* Macro enables or disables support for miniDSP in the driver */ /* Enable the AIC3262_TiLoad macro first before enabling these macros */ -//#define CONFIG_MINI_DSP +#define CONFIG_MINI_DSP /*#undef CONFIG_MINI_DSP*/ /* Enable or disable controls to have Input routing*/ -- cgit v1.2.3 From b472fc27e733c371b9d35a3946b2142ca1a4a6eb Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Thu, 10 May 2012 12:23:45 +0530 Subject: Revert "asoc: tegra: Add TDM mode support" This reverts commit dfa00e184b5fe0d4d48fa62a15fc956de9b6b65c. This is causing a regresssion. Bug: 977319 Change-Id: I4fe6daf88b2988978f089194f2931691eeb0eb09 Signed-off-by: Nikesh Oswal Reviewed-on: http://git-master/r/101687 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Vijaya Bhaskar Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra30_ahub.c | 172 +---------------------------- sound/soc/tegra/tegra30_ahub.h | 16 --- sound/soc/tegra/tegra30_i2s.c | 238 +---------------------------------------- sound/soc/tegra/tegra30_i2s.h | 14 +-- 4 files changed, 9 insertions(+), 431 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index ea772f40464b..710d9465b4b0 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -116,15 +116,6 @@ void tegra30_ahub_disable_clocks(void) clk_disable(ahub->clk_d_audio); } -/* - * for TDM mode, ahub has to run faster than I2S controller. This will avoid - * FIFO overflow/underflow, the causes of slot-hopping symptoms - */ -void tegra30_ahub_clock_set_rate(int rate) -{ - clk_set_rate(ahub->clk_d_audio, rate); -} - #ifdef CONFIG_DEBUG_FS static inline u32 tegra30_ahub_read(u32 space, u32 reg) { @@ -281,116 +272,6 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, return 0; } -int tegra30_ahub_rx_fifo_is_busy(enum tegra30_ahub_rxcif rxcif) -{ - int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; - int reg, val; - - reg = TEGRA30_AHUB_CHANNEL_STATUS + - (channel * TEGRA30_AHUB_CHANNEL_STATUS_STRIDE); - - val = tegra30_apbif_read(reg); - val &= TEGRA30_AHUB_CHANNEL_STATUS_RX_TRIG; - - return val; -} - -int tegra30_ahub_tx_fifo_is_busy(enum tegra30_ahub_txcif txcif) -{ - int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; - int reg, val; - - reg = TEGRA30_AHUB_CHANNEL_STATUS + - (channel * TEGRA30_AHUB_CHANNEL_STATUS_STRIDE); - - val = tegra30_apbif_read(reg); - val &= TEGRA30_AHUB_CHANNEL_STATUS_TX_TRIG; - - return val; -} - -int tegra30_ahub_rx_fifo_clear(enum tegra30_ahub_rxcif rxcif) -{ - int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; - int reg, val; - - reg = TEGRA30_AHUB_CHANNEL_CLEAR + - (channel * TEGRA30_AHUB_CHANNEL_CLEAR_STRIDE); - - val = tegra30_apbif_read(reg); - val |= TEGRA30_AHUB_CHANNEL_CLEAR_RX_SOFT_RESET; - tegra30_apbif_write(reg, val); - - tegra30_ahub_disable_clocks(); - - return 0; -} - -int tegra30_ahub_tx_fifo_clear(enum tegra30_ahub_txcif txcif) -{ - int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; - int reg, val; - - reg = TEGRA30_AHUB_CHANNEL_CLEAR + - (channel * TEGRA30_AHUB_CHANNEL_CLEAR_STRIDE); - - val = tegra30_apbif_read(reg); - val |= TEGRA30_AHUB_CHANNEL_CLEAR_TX_SOFT_RESET; - tegra30_apbif_write(reg, val); - - tegra30_ahub_disable_clocks(); - - return 0; -} - -int tegra30_ahub_set_rx_fifo_pack_mode(enum tegra30_ahub_rxcif rxcif, - unsigned int pack_mode) -{ - int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; - int reg, val; - - tegra30_ahub_enable_clocks(); - reg = TEGRA30_AHUB_CHANNEL_CTRL + - (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); - val = tegra30_apbif_read(reg); - - val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK; - val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN; - - if ((pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16) || - (pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_8_4)) - val |= (TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN | - pack_mode); - tegra30_apbif_write(reg, val); - tegra30_ahub_disable_clocks(); - - return 0; -} - -int tegra30_ahub_set_tx_fifo_pack_mode(enum tegra30_ahub_txcif txcif, - unsigned int pack_mode) -{ - int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; - int reg, val; - - tegra30_ahub_enable_clocks(); - reg = TEGRA30_AHUB_CHANNEL_CTRL + - (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); - val = tegra30_apbif_read(reg); - - val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK; - val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN; - - if ((pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16) || - (pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_8_4)) - val |= (TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN | - pack_mode); - tegra30_apbif_write(reg, val); - tegra30_ahub_disable_clocks(); - - return 0; -} - int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif) { int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; @@ -418,6 +299,8 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif) val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN; tegra30_apbif_write(reg, val); + tegra30_ahub_disable_clocks(); + return 0; } @@ -503,6 +386,8 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif) val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN; tegra30_apbif_write(reg, val); + tegra30_ahub_disable_clocks(); + return 0; } @@ -595,54 +480,6 @@ int tegra30_ahub_set_tx_cif_channels(enum tegra30_ahub_txcif txcif, return 0; } -int tegra30_ahub_set_rx_cif_bits(enum tegra30_ahub_rxcif rxcif, - unsigned int audio_bits, - unsigned int client_bits) -{ - int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; - unsigned int reg, val; - - tegra30_ahub_enable_clocks(); - - reg = TEGRA30_AHUB_CIF_RX_CTRL + - (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE); - val = tegra30_apbif_read(reg); - val &= ~(TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_MASK | - TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_MASK); - val |= ((audio_bits) << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | - ((client_bits) << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT); - tegra30_apbif_write(reg, val); - - tegra30_ahub_disable_clocks(); - - return 0; -} - -int tegra30_ahub_set_tx_cif_bits(enum tegra30_ahub_txcif txcif, - unsigned int audio_bits, - unsigned int client_bits) -{ - int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; - unsigned int reg, val; - - tegra30_ahub_enable_clocks(); - - reg = TEGRA30_AHUB_CIF_TX_CTRL + - (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE); - val = tegra30_apbif_read(reg); - val &= ~(TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_MASK | - TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_MASK); - val |= ((audio_bits) << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | - ((client_bits) << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT); - - tegra30_apbif_write(reg, val); - - tegra30_ahub_disable_clocks(); - - return 0; -} - - static int __devinit tegra30_ahub_probe(struct platform_device *pdev) { struct resource *res0, *res1, *region; @@ -670,7 +507,6 @@ static int __devinit tegra30_ahub_probe(struct platform_device *pdev) goto err_free; } clkm_rate = clk_get_rate(clk_get_parent(ahub->clk_d_audio)); - while (clkm_rate > 12000000) clkm_rate >>= 1; diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index 2c0f5aab4db1..7de1b7c86c7f 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -464,7 +464,6 @@ enum tegra30_ahub_rxcif { extern void tegra30_ahub_enable_clocks(void); extern void tegra30_ahub_disable_clocks(void); -extern void tegra30_ahub_clock_set_rate(int rate); extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, unsigned long *fiforeg, @@ -472,13 +471,8 @@ extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, extern int tegra30_ahub_set_rx_cif_channels(enum tegra30_ahub_rxcif rxcif, unsigned int audio_ch, unsigned int client_ch); -extern int tegra30_ahub_set_rx_cif_bits(enum tegra30_ahub_rxcif rxcif, - unsigned int audio_bits, - unsigned int client_bits); extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); -extern int tegra30_ahub_set_rx_fifo_pack_mode(enum tegra30_ahub_rxcif rxcif, - unsigned int pack_mode); extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, @@ -487,24 +481,14 @@ extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, extern int tegra30_ahub_set_tx_cif_channels(enum tegra30_ahub_txcif txcif, unsigned int audio_ch, unsigned int client_ch); -extern int tegra30_ahub_set_tx_cif_bits(enum tegra30_ahub_txcif txcif, - unsigned int audio_bits, - unsigned int client_bits); extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); -extern int tegra30_ahub_set_tx_fifo_pack_mode(enum tegra30_ahub_txcif txcif, - unsigned int pack_mode); extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif, enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); -extern int tegra30_ahub_rx_fifo_is_busy(enum tegra30_ahub_rxcif rxcif); -extern int tegra30_ahub_tx_fifo_is_busy(enum tegra30_ahub_txcif txcif); -extern int tegra30_ahub_rx_fifo_clear(enum tegra30_ahub_rxcif rxcif); -extern int tegra30_ahub_tx_fifo_clear(enum tegra30_ahub_txcif txcif); - #ifdef CONFIG_PM extern int tegra30_ahub_apbif_resume(void); #endif diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index c2750bfbef64..02d1038ea36e 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -281,194 +280,6 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, return 0; } -static void tegra30_i2s_set_channel_bit_count(struct tegra30_i2s *i2s, - int i2sclock, int srate) -{ - int sym_bitclk, bitcnt; - u32 val; - - bitcnt = (i2sclock / (2 * srate)) - 1; - sym_bitclk = !(i2sclock % (2 * srate)); - - val = bitcnt << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; - - if (!sym_bitclk) - val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; - - tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); -} - -static void tegra30_i2s_set_data_offset(struct tegra30_i2s *i2s) -{ - u32 val; - int rx_data_offset = i2s->dsp_config.rx_data_offset; - int tx_data_offset = i2s->dsp_config.tx_data_offset; - - val = (rx_data_offset << - TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | - (tx_data_offset << - TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); - - tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); -} - -static void tegra30_i2s_set_slot_control(struct tegra30_i2s *i2s, int stream) -{ - u32 val; - int tx_mask = i2s->dsp_config.tx_mask; - int rx_mask = i2s->dsp_config.rx_mask; - - val = tegra30_i2s_read(i2s, TEGRA30_I2S_SLOT_CTRL); - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - val &= ~TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_MASK; - val |= (tx_mask << TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_SHIFT); - } else { - val &= ~TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_MASK; - val |= (rx_mask << TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT); - } - - val &= ~TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK; - val |= (i2s->dsp_config.num_slots - 1) - << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT; - - tegra30_i2s_write(i2s, TEGRA30_I2S_SLOT_CTRL, val); -} - -static int tegra30_i2s_tdm_setup_clocks(struct device *dev, - struct tegra30_i2s *i2s, int *i2sclock) -{ - int ret; - - if (i2s->reg_ctrl & TEGRA30_I2S_CTRL_MASTER_ENABLE) { - - ret = clk_set_parent(i2s->clk_i2s, i2s->clk_pll_a_out0); - if (ret) { - dev_err(dev, "Can't set parent of I2S clock\n"); - return ret; - } - ret = clk_set_rate(i2s->clk_i2s, *i2sclock); - if (ret) { - dev_err(dev, "Can't set I2S clock rate: %d\n", ret); - return ret; - } - } else { - - ret = clk_set_rate(i2s->clk_i2s_sync, *i2sclock); - if (ret) { - dev_err(dev, "Can't set I2S sync clock rate\n"); - return ret; - } - - ret = clk_set_rate(i2s->clk_audio_2x, *i2sclock); - if (ret) { - dev_err(dev, "Can't set audio2x clock rate\n"); - return ret; - } - - ret = clk_set_parent(i2s->clk_i2s, i2s->clk_audio_2x); - if (ret) { - dev_err(dev, "Can't set parent of audio2x clock\n"); - return ret; - } - } - return ret; -} - - -static int tegra30_i2s_tdm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct device *dev = substream->pcm->card->dev; - struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); - u32 val; - int i2s_client_ch, i2s_audio_ch, i2s_audio_bits, i2s_client_bits; - int i2sclock, srate; - int ret; - - srate = params_rate(params); - - i2sclock = srate * - i2s->dsp_config.num_slots * - i2s->dsp_config.slot_width; - - ret = tegra30_i2s_tdm_setup_clocks(dev, i2s, &i2sclock); - if (ret) - return -EINVAL; - - /* Run ahub clock greater than i2sclock */ - tegra30_ahub_clock_set_rate(i2sclock*2); - - tegra30_i2s_enable_clocks(i2s); - - tegra30_i2s_set_channel_bit_count(i2s, i2sclock*2, srate); - - i2s_client_ch = i2s->dsp_config.num_slots; - i2s_audio_ch = i2s->dsp_config.num_slots; - - i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; - switch (i2s->dsp_config.slot_width) { - case 16: - i2s_audio_bits = TEGRA30_AUDIOCIF_BITS_16; - i2s_client_bits = TEGRA30_AUDIOCIF_BITS_16; - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; - break; - case 32: - i2s_audio_bits = TEGRA30_AUDIOCIF_BITS_32; - i2s_client_bits = TEGRA30_AUDIOCIF_BITS_32; - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_32; - break; - } - - val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | - ((i2s_audio_ch - 1) << - TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | - ((i2s_client_ch - 1) << - TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) | - (i2s_audio_bits << - TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | - (i2s_client_bits << - TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); - - tegra30_ahub_set_tx_cif_channels(i2s->txcif, - i2s_audio_ch, - i2s_client_ch); - tegra30_ahub_set_tx_cif_bits(i2s->txcif, - i2s_audio_bits, - i2s_client_bits); - tegra30_ahub_set_tx_fifo_pack_mode(i2s->txcif, 0); - - } else { - val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); - - tegra30_ahub_set_rx_cif_channels(i2s->rxcif, - i2s_audio_ch, - i2s_client_ch); - tegra30_ahub_set_rx_cif_bits(i2s->rxcif, - i2s_audio_bits, - i2s_client_bits); - tegra30_ahub_set_rx_fifo_pack_mode(i2s->rxcif, 0); - } - - tegra30_i2s_set_slot_control(i2s, substream->stream); - - tegra30_i2s_set_data_offset(i2s); - - i2s->reg_ch_ctrl &= ~TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_MASK; - i2s->reg_ch_ctrl |= (i2s->dsp_config.slot_width - 1) << - TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_SHIFT; - tegra30_i2s_write(i2s, TEGRA30_I2S_CH_CTRL, i2s->reg_ch_ctrl); - - tegra30_i2s_disable_clocks(i2s); - - return 0; -} - static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -489,12 +300,6 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - /* TDM mode */ - if ((i2s->reg_ctrl & TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC) && - (i2s->dsp_config.slot_width > 2)) - return tegra30_i2s_tdm_hw_params(substream, params, dai); - - srate = params_rate(params); if (i2s->reg_ctrl & TEGRA30_I2S_CTRL_MASTER_ENABLE) { @@ -618,16 +423,12 @@ static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) { - int dcnt = 10; - /* if this is the only user of i2s tx then disable it*/ tegra30_ahub_disable_tx_fifo(i2s->txcif); + /* if this is the only user of i2s tx then disable it*/ if (i2s->playback_ref_count == 1) { i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); } - while (tegra30_ahub_tx_fifo_is_busy(i2s->txcif) && dcnt--) - udelay(100); - tegra30_ahub_tx_fifo_clear(i2s->txcif); } static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) @@ -641,15 +442,11 @@ static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) { - int dcnt = 10; tegra30_ahub_disable_rx_fifo(i2s->rxcif); if (!i2s->is_call_mode_rec) { i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); } - while (tegra30_ahub_rx_fifo_is_busy(i2s->rxcif) && dcnt--) - udelay(100); - tegra30_ahub_rx_fifo_clear(i2s->rxcif); } static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, @@ -703,33 +500,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai) tegra30_i2s_disable_clocks(i2s); #endif - /* Default values for DSP mode */ - i2s->dsp_config.num_slots = 1; - i2s->dsp_config.slot_width = 2; - i2s->dsp_config.tx_mask = 1; - i2s->dsp_config.rx_mask = 1; - i2s->dsp_config.rx_data_offset = 1; - i2s->dsp_config.tx_data_offset = 1; - - - return 0; -} - -int tegra30_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai, - unsigned int tx_mask, - unsigned int rx_mask, - int slots, - int slot_width) -{ - struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); - - i2s->dsp_config.num_slots = slots; - i2s->dsp_config.slot_width = slot_width; - i2s->dsp_config.tx_mask = tx_mask; - i2s->dsp_config.rx_mask = rx_mask; - i2s->dsp_config.rx_data_offset = 0; - i2s->dsp_config.tx_data_offset = 0; - return 0; } @@ -764,7 +534,6 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { .set_fmt = tegra30_i2s_set_fmt, .hw_params = tegra30_i2s_hw_params, .trigger = tegra30_i2s_trigger, - .set_tdm_slot = tegra30_i2s_set_tdm_slot, }; #define TEGRA30_I2S_DAI(id) \ @@ -774,13 +543,13 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { .resume = tegra30_i2s_resume, \ .playback = { \ .channels_min = 1, \ - .channels_max = 16, \ + .channels_max = 2, \ .rates = SNDRV_PCM_RATE_8000_96000, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ .capture = { \ .channels_min = 1, \ - .channels_max = 16, \ + .channels_max = 2, \ .rates = SNDRV_PCM_RATE_8000_96000, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ @@ -1058,6 +827,7 @@ static __devinit int tegra30_i2s_platform_probe(struct platform_device *pdev) ret = PTR_ERR(i2s->clk_i2s); goto exit; } + i2s->clk_i2s_sync = clk_get(&pdev->dev, "ext_audio_sync"); if (IS_ERR(i2s->clk_i2s_sync)) { dev_err(&pdev->dev, "Can't retrieve i2s_sync clock\n"); diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index 0992bf0d5b17..b9baddd5db8e 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h @@ -176,7 +176,7 @@ /* Number of slots in frame, minus 1 */ #define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT 16 #define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK_US 7 -#define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK (TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK_US << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT) +#define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK (TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOT_MASK_US << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOT_SHIFT) /* TDM mode slot enable bitmask */ #define TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT 8 @@ -231,16 +231,6 @@ /* Number of i2s controllers*/ #define TEGRA30_NR_I2S_IFC 5 -struct dsp_config_t { - int num_slots; - int rx_mask; - int tx_mask; - int slot_width; - int rx_data_offset; - int tx_data_offset; -}; - - struct tegra30_i2s { int id; struct clk *clk_i2s; @@ -264,8 +254,6 @@ struct tegra30_i2s { #endif int call_record_dam_ifc; int is_call_mode_rec; - - struct dsp_config_t dsp_config; }; struct codec_config { -- cgit v1.2.3 From 81bbcfffed65ce86dbe365ca7676bb0eb09ee4a1 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Rawat Date: Fri, 6 Apr 2012 18:54:06 +0530 Subject: asoc: codecs: resolve compilation time warnings Bug 949219 Change-Id: I9c2a0aa22432c586a7e72273ad935d42332e873f Signed-off-by: Sanjay Singh Rawat Reviewed-on: http://git-master/r/95087 Reviewed-by: Rohan Somvanshi Tested-by: Rohan Somvanshi --- sound/soc/codecs/aic326x_tiload.c | 5 ++-- sound/soc/codecs/base_main_Rate48_pps_driver.h | 11 --------- sound/soc/codecs/rt5639.c | 2 -- sound/soc/codecs/second_rate_pps_driver.h | 7 ------ sound/soc/codecs/tlv320aic326x.c | 20 +++++++--------- sound/soc/codecs/tlv320aic326x.h | 5 ++-- sound/soc/codecs/tlv320aic326x_mini-dsp.c | 32 +++++++++++++------------ sound/soc/codecs/tlv320aic326x_minidsp_config.c | 11 +++------ sound/soc/codecs/wm8903.c | 2 ++ 9 files changed, 37 insertions(+), 58 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/aic326x_tiload.c b/sound/soc/codecs/aic326x_tiload.c index 00aa4d4ce7d7..07615dc5ebd7 100644 --- a/sound/soc/codecs/aic326x_tiload.c +++ b/sound/soc/codecs/aic326x_tiload.c @@ -61,7 +61,8 @@ static void aic3262_dump_page(struct i2c_client *i2c, u8 page); /* externs */ extern int aic3262_change_page(struct snd_soc_codec *codec, u8 new_page); extern int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book); -extern int aic3262_write(struct snd_soc_codec *codec, u16 reg, u8 value); +extern int aic3262_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value); int aic3262_driver_init(struct snd_soc_codec *codec); /************** Dynamic aic3262 driver, TI LOAD support ***************/ @@ -236,7 +237,7 @@ static ssize_t tiload_write(struct file *file, const char __user * buf, return i2c_master_send(i2c, wr_data, count); } -static int tiload_ioctl( struct file *filp, +static long tiload_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int num = 0; diff --git a/sound/soc/codecs/base_main_Rate48_pps_driver.h b/sound/soc/codecs/base_main_Rate48_pps_driver.h index 4d6f227cc42e..dff91858940e 100644 --- a/sound/soc/codecs/base_main_Rate48_pps_driver.h +++ b/sound/soc/codecs/base_main_Rate48_pps_driver.h @@ -16,17 +16,6 @@ static control base_speaker_SRS_VOLUME_controls[] = { static char * base_speaker_SRS_VOLUME_control_names[] = { }; -/*//INSTRUCTIONS & COEFFICIENTS -typedef struct { - u8 reg_off; - u8 reg_val; -} reg_value;*/ - -static char * base_speaker_SRS_REG_Section_names[] = { - "miniDSP_A_reg_values", - "miniDSP_D_reg_values", -}; - reg_value base_speaker_SRS_REG_init_Section_program[] = { { 0,0x0}, { 0x7F,0x00}, diff --git a/sound/soc/codecs/rt5639.c b/sound/soc/codecs/rt5639.c index e8841e0d6e4d..c9b14e9f0bc1 100644 --- a/sound/soc/codecs/rt5639.c +++ b/sound/soc/codecs/rt5639.c @@ -1198,8 +1198,6 @@ static int spk_event(struct snd_soc_dapm_widget *w, static int hp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; - switch (event) { case SND_SOC_DAPM_POST_PMU: printk("hp_event --SND_SOC_DAPM_POST_PMU\n"); diff --git a/sound/soc/codecs/second_rate_pps_driver.h b/sound/soc/codecs/second_rate_pps_driver.h index c6c128a027dd..9956c08bcd80 100644 --- a/sound/soc/codecs/second_rate_pps_driver.h +++ b/sound/soc/codecs/second_rate_pps_driver.h @@ -14,13 +14,6 @@ static control main44_VOLUME_controls[] = { static char *main44_VOLUME_control_names[] = { }; - - -static char *main44_REG_Section_names[] = { - "miniDSP_A_reg_values", - "miniDSP_D_reg_values", -}; - reg_value main44_REG_Section_init_program[] = { { 0,0x0}, { 0x7F,0x00}, diff --git a/sound/soc/codecs/tlv320aic326x.c b/sound/soc/codecs/tlv320aic326x.c index ce8b5bc6cd95..5d6b92904d56 100644 --- a/sound/soc/codecs/tlv320aic326x.c +++ b/sound/soc/codecs/tlv320aic326x.c @@ -81,9 +81,6 @@ static u8 aic3262_reg_ctl; * This function reprograms the clock dividers etc. this flag can be used to * disable this when the clock dividers are programmed by pps config file */ -static int soc_static_freq_config = 1; -static struct aic3262_priv *aic3262_priv_data; -static struct i2c_client *i2c_pdev; static struct snd_soc_codec *aic3262_codec; /* @@ -849,7 +846,6 @@ static const struct aic3262_rate_divs aic3262_divs[] = { static void aic3262_multi_i2s_dump_regs(struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; - struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); unsigned int counter; DBG(KERN_INFO "#%s: Dai Active %d ASI%d REGS DUMP\n", @@ -1965,7 +1961,7 @@ static int aic3262_multi_i2s_hw_params(struct snd_pcm_substream *substream, * We can use this function to disable the DAC and ADC specific inputs from the * individual ASI Ports of the Audio Codec. */ -static int aic3262_multi_i2s_shutdown(struct snd_pcm_substream *substream, +static void aic3262_multi_i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -2106,7 +2102,7 @@ static int aic3262_multi_i2s_shutdown(struct snd_pcm_substream *substream, aic3262->active_count--; } err: - return 0; + return; } @@ -3565,7 +3561,7 @@ void aic3262_write_reg_cache(struct snd_soc_codec *codec, *---------------------------------------------------------------------------- */ -u8 aic3262_read(struct snd_soc_codec *codec, u16 reg) +unsigned int aic3262_read(struct snd_soc_codec *codec, unsigned int reg) { struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); u8 value; @@ -3573,7 +3569,7 @@ u8 aic3262_read(struct snd_soc_codec *codec, u16 reg) u16 *cache = codec->reg_cache; u16 cmd; u8 buffer[2]; - int rc; + int rc = 0; reg = reg % 128; if (reg >= AIC3262_CACHEREGNUM) { @@ -3619,7 +3615,8 @@ u8 aic3262_read(struct snd_soc_codec *codec, u16 reg) * *---------------------------------------------------------------------------- */ -int aic3262_write(struct snd_soc_codec *codec, u16 reg, u8 value) +int aic3262_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) { struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); u8 data[2]; @@ -3855,8 +3852,6 @@ int i2c_verify_book0(struct snd_soc_codec *codec) static int aic3262_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); - u8 value; switch (level) { /* full On */ case SND_SOC_BIAS_ON: @@ -4400,6 +4395,7 @@ static int aic3262_spi_write(struct spi_device *spi, const char *data, int len) return len; } +#ifdef RUN_DELAYED_WORK /* * This function forces any delayed work to be queued and run. */ @@ -4418,6 +4414,8 @@ static int run_delayed_work(struct delayed_work *dwork) } return ret; } +#endif + static int __devinit aic3262_spi_probe(struct spi_device *spi) { int ret; diff --git a/sound/soc/codecs/tlv320aic326x.h b/sound/soc/codecs/tlv320aic326x.h index a31cc9eca5ca..fe1d4f12d1ef 100644 --- a/sound/soc/codecs/tlv320aic326x.h +++ b/sound/soc/codecs/tlv320aic326x.h @@ -657,11 +657,12 @@ extern int aic326x_headset_detect(struct snd_soc_codec *codec, extern int aic326x_headset_button_init(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int jack_type); -extern u8 aic3262_read(struct snd_soc_codec *codec, u16 reg); +extern unsigned int aic3262_read(struct snd_soc_codec *codec, unsigned int reg); extern u16 aic3262_read_2byte(struct snd_soc_codec *codec, u16 reg); extern int aic3262_reset_cache(struct snd_soc_codec *codec); extern int aic3262_change_page(struct snd_soc_codec *codec, u8 new_page); -extern int aic3262_write(struct snd_soc_codec *codec, u16 reg, u8 value); +extern int aic3262_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value); extern void aic3262_write_reg_cache(struct snd_soc_codec *codec, u16 reg, u8 value); extern int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book); diff --git a/sound/soc/codecs/tlv320aic326x_mini-dsp.c b/sound/soc/codecs/tlv320aic326x_mini-dsp.c index 6d55abb4dac8..0ef0fd09760c 100644 --- a/sound/soc/codecs/tlv320aic326x_mini-dsp.c +++ b/sound/soc/codecs/tlv320aic326x_mini-dsp.c @@ -601,25 +601,27 @@ struct process_flow{ int set_minidsp_mode(struct snd_soc_codec *codec, int new_mode, int new_config) { - - if (codec == NULL) { - printk(KERN_INFO "%s codec is NULL\n",__func__); - } - struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct aic3262_priv *aic326x; + struct snd_soc_dapm_context *dapm; struct process_flow * pflows = &miniDSP_programs[new_mode]; - u8 reg63, reg81, pll_pow, ndac_pow, mdac_pow, nadc_pow, madc_pow; - + u8 pll_pow, ndac_pow, mdac_pow, nadc_pow; u8 adc_status,dac_status; - u8 reg, val; - u8 shift; - volatile u16 counter; - int (*ptransfer)(struct snd_soc_codec *codec, - reg_value *program_ptr, - int size); + int (*ptransfer)(struct snd_soc_codec *codec, reg_value *program_ptr, + int size); printk("%s:New Switch mode = %d New Config= %d\n", __func__, new_mode,new_config); + + if (codec == NULL) { + printk(KERN_INFO "%s codec is NULL\n", __func__); + return 0; + } + aic326x = snd_soc_codec_get_drvdata(codec); + dapm = &codec->dapm; + + printk(KERN_INFO "%s:New Switch mode = %d New Config= %d\n", __func__, + new_mode, new_config); + if (new_mode >= ARRAY_SIZE(miniDSP_programs)) return 0; // error condition if (new_config > MAXCONFIG) @@ -1231,7 +1233,7 @@ static int __new_control_put_minidsp_mux(struct snd_kcontrol *kcontrol, int ret_val = -1, array_size; control *array; char **array_names; - char *control_name, *control_name1, *control_name2; + char *control_name, *control_name1; struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec); i2c = codec->control_data; diff --git a/sound/soc/codecs/tlv320aic326x_minidsp_config.c b/sound/soc/codecs/tlv320aic326x_minidsp_config.c index e34ffbe2ca82..97a41c3ecf2b 100644 --- a/sound/soc/codecs/tlv320aic326x_minidsp_config.c +++ b/sound/soc/codecs/tlv320aic326x_minidsp_config.c @@ -347,17 +347,12 @@ int aic3262_add_multiconfig_controls(struct snd_soc_codec *codec) *--------------------------------------------------------------------------- */ void minidsp_multiconfig(struct snd_soc_codec *codec, - reg_value *a_patch, int a_size, - reg_value *d_patch, int d_size) + reg_value *a_patch, int a_size, reg_value *d_patch, int d_size) { - struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec); - int val1,val2; int adc_status,dac_status; int (*ptransfer)(struct snd_soc_codec *codec, - reg_value *program_ptr, - int size); - -printk("======in the config_multiconfiguration function==== \n"); + reg_value *program_ptr, int size); + printk(KERN_INFO "======in the config_multiconfiguration function====\n"); #ifndef MULTIBYTE_I2C ptransfer = byte_i2c_array_transfer; #else diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index df4d0ee6f975..2a2d16886989 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1404,6 +1404,7 @@ static struct { { 1500, 0x9, 0x2, 2 }, }; +#ifdef SYS_BCLK_RATIO /* CLK_SYS/BCLK ratios - multiplied by 10 due to .5s */ static struct { int ratio; @@ -1427,6 +1428,7 @@ static struct { { 440, 19 }, { 480, 20 }, }; +#endif /* Sample rates for DSP */ static struct { -- cgit v1.2.3 From 9de840ea6eaa98d5bd836b132f5d1cbaaaaeeea3 Mon Sep 17 00:00:00 2001 From: Ankit Gupta Date: Thu, 3 May 2012 15:06:27 +0530 Subject: asoc: tegra: pcm: Add support for setting bias level Allow setting bias level to turn off clock extern1 when codec is idle for Enterprise (Maxim 98088 codec). Bug 984678 Signed-off-by: Ankit Gupta Change-Id: I09538dafe6c6f01547ff989de3c23933c9745db0 Reviewed-on: http://git-master/r/100286 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Scott Peterson Reviewed-by: Manoj Gangwal Tested-by: Ankit Gupta (Engrg-SW) --- sound/soc/tegra/tegra_pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 6ba3c9fa4461..1b4b949841aa 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -425,7 +425,7 @@ void tegra_pcm_free(struct snd_pcm *pcm) static int tegra_pcm_probe(struct snd_soc_platform *platform) { - if(machine_is_kai()) + if(machine_is_kai() || machine_is_tegra_enterprise()) platform->dapm.idle_bias_off = 1; return 0; -- cgit v1.2.3 From e463cd94c8a523c00624616ea94a5f20e4e5d3dc Mon Sep 17 00:00:00 2001 From: Ankit Gupta Date: Thu, 3 May 2012 15:15:31 +0530 Subject: asoc: codecs: spdif: Add support for setting bias level Allow setting bias level to turn off clock extern1 on enterprise when codec is idle. Added a dummy widget to make the target_bias_level to BIAS_OFF as per required by the new ALSA kernel. Bug 984678 Signed-off-by: Ankit Gupta Change-Id: I29de405c26286eee0a49e655f1d4236f6093ce8a Reviewed-on: http://git-master/r/100287 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Manoj Gangwal Reviewed-by: Scott Peterson Tested-by: Ankit Gupta (Engrg-SW) --- sound/soc/codecs/spdif_transciever.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c index 16ea0ed77355..6173b3a5b082 100644 --- a/sound/soc/codecs/spdif_transciever.c +++ b/sound/soc/codecs/spdif_transciever.c @@ -77,7 +77,7 @@ static struct snd_soc_dai_driver dit_stub_dai = { static int spdif_dit_probe(struct platform_device *pdev) { - if(machine_is_kai()) + if(machine_is_kai() || machine_is_tegra_enterprise()) return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dit1, &dit_stub_dai, 1); else -- cgit v1.2.3 From 71c2ea698d4c1c7d91247ebf638dd33f1563ac26 Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Fri, 11 May 2012 19:53:27 +0530 Subject: asoc:tegra: Enable I2S tx in voice call Associated with I2S there is a playback ref count, when we open the I2S for plyabck it is incremented and during voice call we check if its not zero then enable the tX. This logic fails if the start-trigger is not called for the prior playback stream. Hence we unconditionally enable the tx, which is harmless Bug: 981806 Change-Id: I66aafda596e2b2b03745e93f3e851dedc3b8ef5d Signed-off-by: Nikesh Oswal Reviewed-on: http://git-master/r/101996 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra30_i2s.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 02d1038ea36e..aba964281349 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -726,10 +726,7 @@ int tegra30_make_voice_call_connections(struct codec_config *codec_info, tegra30_dam_enable(bb_i2s->dam_ifc, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN0_SRC); - /* if this is the only user of i2s tx then enable it*/ - if (codec_i2s->playback_ref_count == 1) - codec_i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; - + codec_i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; codec_i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX; tegra30_i2s_write(codec_i2s, TEGRA30_I2S_CTRL, codec_i2s->reg_ctrl); -- cgit v1.2.3 From 0172fb19ebf3e5fb667b37e64bf3473ccdd1bc35 Mon Sep 17 00:00:00 2001 From: Ankit Gupta Date: Mon, 14 May 2012 18:43:23 +0530 Subject: asoc: tegra: MAX98088 machine: Add support for setting bias level Allow setting bias level to turn off clock extern1 when codec is idle for enterprise board. (Maxim 98088 codec) Bug 984678 Change-Id: Ib01be71362ab0c5525f570693b41db73777875e6 Signed-off-by: Ankit Gupta Reviewed-on: http://git-master/r/102240 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Manoj Gangwal Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra_max98088.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_max98088.c b/sound/soc/tegra/tegra_max98088.c index 63a067338dc4..8c0e3935ad02 100644 --- a/sound/soc/tegra/tegra_max98088.c +++ b/sound/soc/tegra/tegra_max98088.c @@ -96,6 +96,7 @@ struct tegra_max98088 { #endif enum snd_soc_bias_level bias_level; struct snd_soc_card *pcard; + volatile int clock_enabled; }; static int tegra_call_mode_info(struct snd_kcontrol *kcontrol, @@ -926,6 +927,7 @@ static int tegra_max98088_init(struct snd_soc_pcm_runtime *rtd) machine->pcard = card; machine->bias_level = SND_SOC_BIAS_STANDBY; + machine->clock_enabled = 1; if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); @@ -1070,8 +1072,11 @@ static int tegra30_soc_set_bias_level(struct snd_soc_card *card, struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card); if (machine->bias_level == SND_SOC_BIAS_OFF && - level != SND_SOC_BIAS_OFF) + level != SND_SOC_BIAS_OFF && (!machine->clock_enabled)) { + machine->clock_enabled = 1; tegra_asoc_utils_clk_enable(&machine->util_data); + machine->bias_level = level; + } return 0; } @@ -1082,8 +1087,10 @@ static int tegra30_soc_set_bias_level_post(struct snd_soc_card *card, struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card); if (machine->bias_level != SND_SOC_BIAS_OFF && - level == SND_SOC_BIAS_OFF) + level == SND_SOC_BIAS_OFF && (machine->clock_enabled)) { + machine->clock_enabled = 0; tegra_asoc_utils_clk_disable(&machine->util_data); + } machine->bias_level = level; @@ -1156,6 +1163,7 @@ static __devinit int tegra_max98088_driver_probe(struct platform_device *pdev) tegra_max98088_i2s_dai_name[machine->codec_info[BT_SCO].i2s_id]; #endif + card->dapm.idle_bias_off = 1; ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", -- cgit v1.2.3 From ac0ba404dea9e3c0524fb300b94c032ba8b710a2 Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Tue, 8 May 2012 16:42:49 +0530 Subject: asoc:codecs: tiaic326x: remove mini dsp support disable the compilation of minidsp specific code, we are disabling the minidsp in codec because the driver is not stable and different customers are using different process flows for mini dsp Change-Id: I08f8f485f1a379773f2f1f7ae2fd1b3a89c45d07 Signed-off-by: Nikesh Oswal Reviewed-on: http://git-master/r/101232 Reviewed-by: Simone Willett Tested-by: Simone Willett --- sound/soc/codecs/Makefile | 3 +-- sound/soc/codecs/tlv320aic326x.h | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 2eaef5b52e08..d80b7bbff2e8 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -35,8 +35,7 @@ snd-soc-stac9766-objs := stac9766.o snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic26-objs := tlv320aic26.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o -snd-soc-tlv320aic326x-objs := tlv320aic326x.o tlv320aic326x_minidsp_config.o -snd-soc-tlv320aic326x-objs += tlv320aic326x_mini-dsp.o aic326x_tiload.o +snd-soc-tlv320aic326x-objs := tlv320aic326x.o snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o snd-soc-tlv320dac33-objs := tlv320dac33.o snd-soc-twl4030-objs := twl4030.o diff --git a/sound/soc/codecs/tlv320aic326x.h b/sound/soc/codecs/tlv320aic326x.h index fe1d4f12d1ef..bfcbefc5c079 100644 --- a/sound/soc/codecs/tlv320aic326x.h +++ b/sound/soc/codecs/tlv320aic326x.h @@ -36,7 +36,7 @@ /* Enable register caching on write */ #define EN_REG_CACHE 1 -#define MULTIBYTE_CONFIG_SUPPORT +//#define MULTIBYTE_CONFIG_SUPPORT /*Setting all codec reg/write locally*/ /* This definition is added as the snd_ direct call are @@ -45,12 +45,12 @@ page, so fix that before commenting this line*/ #define LOCAL_REG_ACCESS 1 /* Macro to enable the inclusion of tiload kernel driver */ -#define AIC3262_TiLoad +//#define AIC3262_TiLoad /* Macro enables or disables support for miniDSP in the driver */ /* Enable the AIC3262_TiLoad macro first before enabling these macros */ -#define CONFIG_MINI_DSP +//#define CONFIG_MINI_DSP /*#undef CONFIG_MINI_DSP*/ /* Enable or disable controls to have Input routing*/ -- cgit v1.2.3 From 6b7e887d5742406d988cb6f797846a83f00a31bb Mon Sep 17 00:00:00 2001 From: Nitin Pai Date: Tue, 24 Apr 2012 15:57:51 +0530 Subject: asoc: tegra: Add TDM mode support Added TDM mode support in I2S driver. Added support functions in AHUB to pass audio/client bits. Added support functions in AHUB to pass audio/client channels. Fixed the stopping of I2S/TDM by clearing the fifo. Bug 948478 Signed-off-by: Nitin Pai Change-Id: I560f4ab5b71e4833931934275272a094241241fe Reviewed-on: http://git-master/r/103840 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Ravindra Lokhande Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra30_ahub.c | 127 ++++++++++++++++++++++ sound/soc/tegra/tegra30_ahub.h | 14 +++ sound/soc/tegra/tegra30_i2s.c | 236 ++++++++++++++++++++++++++++++++++++++++- sound/soc/tegra/tegra30_i2s.h | 14 ++- 4 files changed, 386 insertions(+), 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 710d9465b4b0..30b7e481acc4 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -116,6 +116,15 @@ void tegra30_ahub_disable_clocks(void) clk_disable(ahub->clk_d_audio); } +/* + * for TDM mode, ahub has to run faster than I2S controller. This will avoid + * FIFO overflow/underflow, the causes of slot-hopping symptoms + */ +void tegra30_ahub_clock_set_rate(int rate) +{ + clk_set_rate(ahub->clk_d_audio, rate); +} + #ifdef CONFIG_DEBUG_FS static inline u32 tegra30_ahub_read(u32 space, u32 reg) { @@ -272,6 +281,75 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, return 0; } +int tegra30_ahub_rx_fifo_is_enabled(int i2s_id) +{ + int val, mask; + + val = tegra30_apbif_read(TEGRA30_AHUB_I2S_LIVE_STATUS); + mask = (TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_RX_FIFO_ENABLED << (i2s_id*2)); + val &= mask; + return val; +} + +int tegra30_ahub_tx_fifo_is_enabled(int i2s_id) +{ + int val, mask; + + val = tegra30_apbif_read(TEGRA30_AHUB_I2S_LIVE_STATUS); + mask = (TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_TX_FIFO_ENABLED << (i2s_id*2)); + val &= mask; + + return val; +} + +int tegra30_ahub_set_rx_fifo_pack_mode(enum tegra30_ahub_rxcif rxcif, + unsigned int pack_mode) +{ + int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; + int reg, val; + + tegra30_ahub_enable_clocks(); + reg = TEGRA30_AHUB_CHANNEL_CTRL + + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); + val = tegra30_apbif_read(reg); + + val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK; + val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN; + + if ((pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16) || + (pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_8_4)) + val |= (TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN | + pack_mode); + tegra30_apbif_write(reg, val); + tegra30_ahub_disable_clocks(); + + return 0; +} + +int tegra30_ahub_set_tx_fifo_pack_mode(enum tegra30_ahub_txcif txcif, + unsigned int pack_mode) +{ + int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; + int reg, val; + + tegra30_ahub_enable_clocks(); + reg = TEGRA30_AHUB_CHANNEL_CTRL + + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); + val = tegra30_apbif_read(reg); + + val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK; + val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN; + + if ((pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16) || + (pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_8_4)) + val |= (TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN | + pack_mode); + tegra30_apbif_write(reg, val); + tegra30_ahub_disable_clocks(); + + return 0; +} + int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif) { int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; @@ -480,6 +558,54 @@ int tegra30_ahub_set_tx_cif_channels(enum tegra30_ahub_txcif txcif, return 0; } +int tegra30_ahub_set_rx_cif_bits(enum tegra30_ahub_rxcif rxcif, + unsigned int audio_bits, + unsigned int client_bits) +{ + int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; + unsigned int reg, val; + + tegra30_ahub_enable_clocks(); + + reg = TEGRA30_AHUB_CIF_RX_CTRL + + (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE); + val = tegra30_apbif_read(reg); + val &= ~(TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_MASK | + TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_MASK); + val |= ((audio_bits) << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | + ((client_bits) << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT); + tegra30_apbif_write(reg, val); + + tegra30_ahub_disable_clocks(); + + return 0; +} + +int tegra30_ahub_set_tx_cif_bits(enum tegra30_ahub_txcif txcif, + unsigned int audio_bits, + unsigned int client_bits) +{ + int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; + unsigned int reg, val; + + tegra30_ahub_enable_clocks(); + + reg = TEGRA30_AHUB_CIF_TX_CTRL + + (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE); + val = tegra30_apbif_read(reg); + val &= ~(TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_MASK | + TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_MASK); + val |= ((audio_bits) << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | + ((client_bits) << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT); + + tegra30_apbif_write(reg, val); + + tegra30_ahub_disable_clocks(); + + return 0; +} + + static int __devinit tegra30_ahub_probe(struct platform_device *pdev) { struct resource *res0, *res1, *region; @@ -507,6 +633,7 @@ static int __devinit tegra30_ahub_probe(struct platform_device *pdev) goto err_free; } clkm_rate = clk_get_rate(clk_get_parent(ahub->clk_d_audio)); + while (clkm_rate > 12000000) clkm_rate >>= 1; diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index 7de1b7c86c7f..8dc27abc5aed 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -464,6 +464,7 @@ enum tegra30_ahub_rxcif { extern void tegra30_ahub_enable_clocks(void); extern void tegra30_ahub_disable_clocks(void); +extern void tegra30_ahub_clock_set_rate(int rate); extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, unsigned long *fiforeg, @@ -471,8 +472,13 @@ extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, extern int tegra30_ahub_set_rx_cif_channels(enum tegra30_ahub_rxcif rxcif, unsigned int audio_ch, unsigned int client_ch); +extern int tegra30_ahub_set_rx_cif_bits(enum tegra30_ahub_rxcif rxcif, + unsigned int audio_bits, + unsigned int client_bits); extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); +extern int tegra30_ahub_set_rx_fifo_pack_mode(enum tegra30_ahub_rxcif rxcif, + unsigned int pack_mode); extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, @@ -481,14 +487,22 @@ extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, extern int tegra30_ahub_set_tx_cif_channels(enum tegra30_ahub_txcif txcif, unsigned int audio_ch, unsigned int client_ch); +extern int tegra30_ahub_set_tx_cif_bits(enum tegra30_ahub_txcif txcif, + unsigned int audio_bits, + unsigned int client_bits); extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); +extern int tegra30_ahub_set_tx_fifo_pack_mode(enum tegra30_ahub_txcif txcif, + unsigned int pack_mode); extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif, enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); +extern int tegra30_ahub_rx_fifo_is_enabled(int i2s_id); +extern int tegra30_ahub_tx_fifo_is_enabled(int i2s_id); + #ifdef CONFIG_PM extern int tegra30_ahub_apbif_resume(void); #endif diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index aba964281349..449359837efb 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -280,6 +281,194 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, return 0; } +static void tegra30_i2s_set_channel_bit_count(struct tegra30_i2s *i2s, + int i2sclock, int srate) +{ + int sym_bitclk, bitcnt; + u32 val; + + bitcnt = (i2sclock / (2 * srate)) - 1; + sym_bitclk = !(i2sclock % (2 * srate)); + + val = bitcnt << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; + + if (!sym_bitclk) + val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; + + tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); +} + +static void tegra30_i2s_set_data_offset(struct tegra30_i2s *i2s) +{ + u32 val; + int rx_data_offset = i2s->dsp_config.rx_data_offset; + int tx_data_offset = i2s->dsp_config.tx_data_offset; + + val = (rx_data_offset << + TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | + (tx_data_offset << + TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); + + tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); +} + +static void tegra30_i2s_set_slot_control(struct tegra30_i2s *i2s, int stream) +{ + u32 val; + int tx_mask = i2s->dsp_config.tx_mask; + int rx_mask = i2s->dsp_config.rx_mask; + + val = tegra30_i2s_read(i2s, TEGRA30_I2S_SLOT_CTRL); + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + val &= ~TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_MASK; + val |= (tx_mask << TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_SHIFT); + } else { + val &= ~TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_MASK; + val |= (rx_mask << TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT); + } + + val &= ~TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK; + val |= (i2s->dsp_config.num_slots - 1) + << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT; + + tegra30_i2s_write(i2s, TEGRA30_I2S_SLOT_CTRL, val); +} + +static int tegra30_i2s_tdm_setup_clocks(struct device *dev, + struct tegra30_i2s *i2s, int *i2sclock) +{ + int ret; + + if (i2s->reg_ctrl & TEGRA30_I2S_CTRL_MASTER_ENABLE) { + + ret = clk_set_parent(i2s->clk_i2s, i2s->clk_pll_a_out0); + if (ret) { + dev_err(dev, "Can't set parent of I2S clock\n"); + return ret; + } + ret = clk_set_rate(i2s->clk_i2s, *i2sclock); + if (ret) { + dev_err(dev, "Can't set I2S clock rate: %d\n", ret); + return ret; + } + } else { + + ret = clk_set_rate(i2s->clk_i2s_sync, *i2sclock); + if (ret) { + dev_err(dev, "Can't set I2S sync clock rate\n"); + return ret; + } + + ret = clk_set_rate(i2s->clk_audio_2x, *i2sclock); + if (ret) { + dev_err(dev, "Can't set audio2x clock rate\n"); + return ret; + } + + ret = clk_set_parent(i2s->clk_i2s, i2s->clk_audio_2x); + if (ret) { + dev_err(dev, "Can't set parent of audio2x clock\n"); + return ret; + } + } + return ret; +} + + +static int tegra30_i2s_tdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct device *dev = substream->pcm->card->dev; + struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); + u32 val; + int i2s_client_ch, i2s_audio_ch, i2s_audio_bits, i2s_client_bits; + int i2sclock, srate; + int ret; + + srate = params_rate(params); + + i2sclock = srate * + i2s->dsp_config.num_slots * + i2s->dsp_config.slot_width; + + ret = tegra30_i2s_tdm_setup_clocks(dev, i2s, &i2sclock); + if (ret) + return -EINVAL; + + /* Run ahub clock greater than i2sclock */ + tegra30_ahub_clock_set_rate(i2sclock*2); + + tegra30_i2s_enable_clocks(i2s); + + tegra30_i2s_set_channel_bit_count(i2s, i2sclock*2, srate); + + i2s_client_ch = i2s->dsp_config.num_slots; + i2s_audio_ch = i2s->dsp_config.num_slots; + + i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; + switch (i2s->dsp_config.slot_width) { + case 16: + i2s_audio_bits = TEGRA30_AUDIOCIF_BITS_16; + i2s_client_bits = TEGRA30_AUDIOCIF_BITS_16; + i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; + break; + case 32: + i2s_audio_bits = TEGRA30_AUDIOCIF_BITS_32; + i2s_client_bits = TEGRA30_AUDIOCIF_BITS_32; + i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_32; + break; + } + + val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | + ((i2s_audio_ch - 1) << + TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | + ((i2s_client_ch - 1) << + TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) | + (i2s_audio_bits << + TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | + (i2s_client_bits << + TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; + tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); + + tegra30_ahub_set_tx_cif_channels(i2s->txcif, + i2s_audio_ch, + i2s_client_ch); + tegra30_ahub_set_tx_cif_bits(i2s->txcif, + i2s_audio_bits, + i2s_client_bits); + tegra30_ahub_set_tx_fifo_pack_mode(i2s->txcif, 0); + + } else { + val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; + tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); + + tegra30_ahub_set_rx_cif_channels(i2s->rxcif, + i2s_audio_ch, + i2s_client_ch); + tegra30_ahub_set_rx_cif_bits(i2s->rxcif, + i2s_audio_bits, + i2s_client_bits); + tegra30_ahub_set_rx_fifo_pack_mode(i2s->rxcif, 0); + } + + tegra30_i2s_set_slot_control(i2s, substream->stream); + + tegra30_i2s_set_data_offset(i2s); + + i2s->reg_ch_ctrl &= ~TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_MASK; + i2s->reg_ch_ctrl |= (i2s->dsp_config.slot_width - 1) << + TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_SHIFT; + tegra30_i2s_write(i2s, TEGRA30_I2S_CH_CTRL, i2s->reg_ch_ctrl); + + tegra30_i2s_disable_clocks(i2s); + + return 0; +} + static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -300,6 +489,12 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } + /* TDM mode */ + if ((i2s->reg_ctrl & TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC) && + (i2s->dsp_config.slot_width > 2)) + return tegra30_i2s_tdm_hw_params(substream, params, dai); + + srate = params_rate(params); if (i2s->reg_ctrl & TEGRA30_I2S_CTRL_MASTER_ENABLE) { @@ -423,12 +618,15 @@ static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) { - tegra30_ahub_disable_tx_fifo(i2s->txcif); + int dcnt = 10; /* if this is the only user of i2s tx then disable it*/ + tegra30_ahub_disable_tx_fifo(i2s->txcif); if (i2s->playback_ref_count == 1) { i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); } + while (tegra30_ahub_tx_fifo_is_enabled(i2s->id) && dcnt--) + udelay(100); } static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) @@ -442,11 +640,14 @@ static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) { + int dcnt = 10; tegra30_ahub_disable_rx_fifo(i2s->rxcif); if (!i2s->is_call_mode_rec) { i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); } + while (tegra30_ahub_rx_fifo_is_enabled(i2s->id) && dcnt--) + udelay(100); } static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, @@ -500,6 +701,33 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai) tegra30_i2s_disable_clocks(i2s); #endif + /* Default values for DSP mode */ + i2s->dsp_config.num_slots = 1; + i2s->dsp_config.slot_width = 2; + i2s->dsp_config.tx_mask = 1; + i2s->dsp_config.rx_mask = 1; + i2s->dsp_config.rx_data_offset = 1; + i2s->dsp_config.tx_data_offset = 1; + + + return 0; +} + +int tegra30_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai, + unsigned int tx_mask, + unsigned int rx_mask, + int slots, + int slot_width) +{ + struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); + + i2s->dsp_config.num_slots = slots; + i2s->dsp_config.slot_width = slot_width; + i2s->dsp_config.tx_mask = tx_mask; + i2s->dsp_config.rx_mask = rx_mask; + i2s->dsp_config.rx_data_offset = 0; + i2s->dsp_config.tx_data_offset = 0; + return 0; } @@ -534,6 +762,7 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { .set_fmt = tegra30_i2s_set_fmt, .hw_params = tegra30_i2s_hw_params, .trigger = tegra30_i2s_trigger, + .set_tdm_slot = tegra30_i2s_set_tdm_slot, }; #define TEGRA30_I2S_DAI(id) \ @@ -543,13 +772,13 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { .resume = tegra30_i2s_resume, \ .playback = { \ .channels_min = 1, \ - .channels_max = 2, \ + .channels_max = 16, \ .rates = SNDRV_PCM_RATE_8000_96000, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ .capture = { \ .channels_min = 1, \ - .channels_max = 2, \ + .channels_max = 16, \ .rates = SNDRV_PCM_RATE_8000_96000, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ @@ -824,7 +1053,6 @@ static __devinit int tegra30_i2s_platform_probe(struct platform_device *pdev) ret = PTR_ERR(i2s->clk_i2s); goto exit; } - i2s->clk_i2s_sync = clk_get(&pdev->dev, "ext_audio_sync"); if (IS_ERR(i2s->clk_i2s_sync)) { dev_err(&pdev->dev, "Can't retrieve i2s_sync clock\n"); diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index b9baddd5db8e..0992bf0d5b17 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h @@ -176,7 +176,7 @@ /* Number of slots in frame, minus 1 */ #define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT 16 #define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK_US 7 -#define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK (TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOT_MASK_US << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOT_SHIFT) +#define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK (TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK_US << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT) /* TDM mode slot enable bitmask */ #define TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT 8 @@ -231,6 +231,16 @@ /* Number of i2s controllers*/ #define TEGRA30_NR_I2S_IFC 5 +struct dsp_config_t { + int num_slots; + int rx_mask; + int tx_mask; + int slot_width; + int rx_data_offset; + int tx_data_offset; +}; + + struct tegra30_i2s { int id; struct clk *clk_i2s; @@ -254,6 +264,8 @@ struct tegra30_i2s { #endif int call_record_dam_ifc; int is_call_mode_rec; + + struct dsp_config_t dsp_config; }; struct codec_config { -- cgit v1.2.3 From 4e88128f3c4c40bf3b6cd1146dffe6a5156fef04 Mon Sep 17 00:00:00 2001 From: Nitin Pai Date: Tue, 22 May 2012 12:04:15 +0530 Subject: asoc: tegra: P1852 machine: Add TDM mode settings Pass TDM mode variables for CPU dai. Codec Id is not passed properly, hence use dual instances of the dai_link operations. Bug 948478 Change-Id: I13188d5001b8f9c2f2f67ee7a9d3bec89311037d Signed-off-by: Bob Johnston Reviewed-on: http://git-master/r/103793 Reviewed-by: Nitin Pai Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra_p1852.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_p1852.c b/sound/soc/tegra/tegra_p1852.c index 9506a1c842df..85b4cee30c5f 100644 --- a/sound/soc/tegra/tegra_p1852.c +++ b/sound/soc/tegra/tegra_p1852.c @@ -49,7 +49,8 @@ struct tegra_p1852 { }; static int tegra_p1852_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params, + int codec_id) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; @@ -61,7 +62,6 @@ static int tegra_p1852_hw_params(struct snd_pcm_substream *substream, int i2s_daifmt = 0; int err; struct tegra_p1852_platform_data *pdata; - int codec_id = codec_dai->id; pdata = machine->pdata; @@ -120,15 +120,39 @@ static int tegra_p1852_hw_params(struct snd_pcm_substream *substream, dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } - err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) dev_info(card->dev, "codec_dai clock not set\n"); + if (pdata->codec_info[codec_id].i2s_format == + format_tdm) { + err = snd_soc_dai_set_tdm_slot(cpu_dai, + pdata->codec_info[codec_id].rx_mask, + pdata->codec_info[codec_id].tx_mask, + pdata->codec_info[codec_id].num_slots, + pdata->codec_info[codec_id].slot_width); + if (err < 0) + dev_err(card->dev, "cpu_dai tdm mode setting not done\n"); + } + return 0; } +static int tegra_p1852_hw_params_controller1( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + return tegra_p1852_hw_params(substream, params, 0); +} + +static int tegra_p1852_hw_params_controller2( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + return tegra_p1852_hw_params(substream, params, 1); +} + static int tegra_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -139,8 +163,12 @@ static int tegra_hw_free(struct snd_pcm_substream *substream) return 0; } -static struct snd_soc_ops tegra_p1852_ops = { - .hw_params = tegra_p1852_hw_params, +static struct snd_soc_ops tegra_p1852_ops_controller1 = { + .hw_params = tegra_p1852_hw_params_controller1, + .hw_free = tegra_hw_free, +}; +static struct snd_soc_ops tegra_p1852_ops_controller2 = { + .hw_params = tegra_p1852_hw_params_controller2, .hw_free = tegra_hw_free, }; @@ -149,13 +177,13 @@ static struct snd_soc_dai_link tegra_p1852_dai_link[] = { .name = "I2S-TDM-1", .stream_name = "TEGRA PCM", .platform_name = "tegra-pcm-audio", - .ops = &tegra_p1852_ops, + .ops = &tegra_p1852_ops_controller1, }, { .name = "I2S-TDM-2", .stream_name = "TEGRA PCM", .platform_name = "tegra-pcm-audio", - .ops = &tegra_p1852_ops, + .ops = &tegra_p1852_ops_controller2, } }; -- cgit v1.2.3 From 8e9dc6ce7d8cafba0e65123b2f76320309e8388c Mon Sep 17 00:00:00 2001 From: Ankit Gupta Date: Wed, 23 May 2012 11:55:13 +0530 Subject: asoc: tegra: utils: fix for multiple instances of extern1 clock. The extern1 codec clock was not getting switched off whenever codec goes below BIAS_OFF level. Moreover, there were two instances of extern1 clock whenever codec was on. Reason behind this was that, those codecs for which probe function was called and were not present on board, turned on their extern1 clock, but clean up routine (for switch device register failure) was not able to turn off the clock. With this change, a conditional check is put to turn off the clock. (Bug 984678) Signed-off-by: Ankit Gupta Change-Id: I585ecf73c0cabca856592dcd84e67588dfe13beb Reviewed-on: http://git-master/r/104073 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Ankit Gupta (Engrg-SW) Reviewed-by: Prashant Gaikwad Reviewed-by: Bharat Nihalani --- sound/soc/tegra/tegra_asoc_utils.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index b134f0808afa..dfbafa061993 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -276,6 +276,10 @@ void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data) clk_put(data->clk_out1); clk_put(data->clk_cdev1); + /* Just to make sure that clk_cdev1 should turn off in case if it is + * switched on by some codec whose hw switch is not registered.*/ + if (tegra_is_clk_enabled(data->clk_cdev1)) + clk_disable(data->clk_cdev1); if (!IS_ERR(data->clk_pll_a_out0)) clk_put(data->clk_pll_a_out0); -- cgit v1.2.3 From 98c26489fd954b63655c805ff87b8dd6368b31d5 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Rawat Date: Tue, 22 May 2012 10:27:38 +0530 Subject: ASoC: resolve compilation time warnings Bug 949219 Change-Id: If7b4dd928cc5a808fd1a674bcc5f31c9a396a043 Signed-off-by: Sanjay Singh Rawat Reviewed-on: http://git-master/r/103772 Reviewed-by: Simone Willett Tested-by: Simone Willett --- sound/soc/tegra/tegra20_das.c | 6 +++--- sound/soc/tegra/tegra20_das.h | 4 ++-- sound/soc/tegra/tegra_asoc_utils.c | 2 +- sound/soc/tegra/tegra_wm8753.c | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index 0774d360399a..29c4582cfa79 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -50,7 +50,7 @@ static inline u32 tegra20_das_read(u32 reg) } #ifdef CONFIG_PM -int tegra20_das_resume() +int tegra20_das_resume(void) { int i, reg; @@ -67,7 +67,7 @@ int tegra20_das_resume() } #endif -int tegra20_das_set_tristate(int dap_id, int is_tristate) +void tegra20_das_set_tristate(int dap_id, int is_tristate) { enum tegra_pingroup pin; enum tegra_tristate tristate; @@ -86,7 +86,7 @@ int tegra20_das_set_tristate(int dap_id, int is_tristate) pin = TEGRA_PINGROUP_DAP4; break; default: - return -EINVAL; + return; } if (is_tristate) diff --git a/sound/soc/tegra/tegra20_das.h b/sound/soc/tegra/tegra20_das.h index 0d58c7d1bc3f..5cd2d07d43b8 100644 --- a/sound/soc/tegra/tegra20_das.h +++ b/sound/soc/tegra/tegra20_das.h @@ -98,7 +98,7 @@ struct tegra20_das { #ifdef CONFIG_PM /* Restores the das registers from cache */ -extern int tegra20_das_resume(); +extern int tegra20_das_resume(void); #endif /* * Terminology: @@ -143,6 +143,6 @@ extern int tegra20_das_connect_dap_to_dap(int dap_id, int other_dap_sel, */ extern int tegra20_das_connect_dac_to_dap(int dac_id, int dap_sel); -extern int tegra20_das_set_tristate(int dap_id, int is_tristate); +extern void tegra20_das_set_tristate(int dap_id, int is_tristate); #endif diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index dfbafa061993..a189fb5c61c1 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -31,7 +31,7 @@ int g_is_call_mode; -bool tegra_is_voice_call_active() +bool tegra_is_voice_call_active(void) { if (g_is_call_mode) return true; diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 795356875ba4..99d0b19c7106 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -379,7 +379,6 @@ static int tegra_bt_call_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_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); -- cgit v1.2.3 From 97b5fcb955784c5245debc020473318dd45e5683 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Rawat Date: Thu, 24 May 2012 16:39:37 +0530 Subject: ASoC: tegra: treat compilation warning as error Bug 949219 Change-Id: Ic8976b008772220299369369427a80dd370df596 Signed-off-by: Sanjay Singh Rawat Reviewed-on: http://git-master/r/104419 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani --- sound/soc/tegra/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 9c4346aa265c..7af02a69b8ae 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -1,5 +1,7 @@ GCOV_PROFILE := y +subdir-ccflags-y := -Werror + # Tegra platform Support snd-soc-tegra-pcm-objs := tegra_pcm.o snd-soc-tegra-tdm-pcm-objs := tegra_tdm_pcm.o -- cgit v1.2.3 From bd09096c7b6431f31d312e45689f59215a0e1356 Mon Sep 17 00:00:00 2001 From: Sumit Bhattacharya Date: Fri, 20 Apr 2012 17:41:16 +0530 Subject: ASoC: Tegra: Add support for AVP rendering Add alsa controls to specify which alsa device is used by AVP to render audio. Also add support for disabling DMA interrupt when AVP renders audio. Also add couple of alsa controls to query DMA channel ID and DMA buffer physical address. Bug 968814 Signed-off-by: Sumit Bhattacharya Change-Id: If593329db72bf00d97f7433f5c54e13500281253 Reviewed-on: http://git-master/r/97916 Reviewed-by: Rohan Somvanshi Tested-by: Rohan Somvanshi --- sound/soc/tegra/tegra_aic326x.c | 4 ++ sound/soc/tegra/tegra_asoc_utils.c | 132 +++++++++++++++++++++++++++++++++++++ sound/soc/tegra/tegra_asoc_utils.h | 4 ++ sound/soc/tegra/tegra_max98088.c | 4 ++ sound/soc/tegra/tegra_max98095.c | 4 ++ sound/soc/tegra/tegra_pcm.c | 18 +++-- sound/soc/tegra/tegra_pcm.h | 1 + sound/soc/tegra/tegra_rt5640.c | 5 ++ sound/soc/tegra/tegra_wm8753.c | 4 ++ sound/soc/tegra/tegra_wm8903.c | 4 ++ 10 files changed, 176 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_aic326x.c b/sound/soc/tegra/tegra_aic326x.c index a5c6fc0aecb7..4cacb6758eb8 100644 --- a/sound/soc/tegra/tegra_aic326x.c +++ b/sound/soc/tegra/tegra_aic326x.c @@ -1062,6 +1062,10 @@ static int tegra_aic326x_init(struct snd_soc_pcm_runtime *rtd) if (ret < 0) return ret; + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS_EXT ON"); snd_soc_dapm_force_enable_pin(dapm,"MICBIAS_INT ON"); snd_soc_dapm_sync(dapm); diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index a189fb5c61c1..6ab5b2d46a1f 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -27,6 +27,9 @@ #include +#include + +#include "tegra_pcm.h" #include "tegra_asoc_utils.h" int g_is_call_mode; @@ -40,6 +43,115 @@ bool tegra_is_voice_call_active(void) } EXPORT_SYMBOL_GPL(tegra_is_voice_call_active); +static int tegra_get_avp_device(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = data->avp_device_id; + return 0; +} + +static int tegra_set_avp_device(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol); + struct snd_soc_card *card = data->card; + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + struct tegra_runtime_data *prtd; + int id, old_id = data->avp_device_id; + + id = ucontrol->value.integer.value[0]; + if ((id >= card->num_rtd) || (id < 0)) + id = -1; + + if (old_id >= 0) { + rtd = &card->rtd[old_id]; + substream = + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (substream && substream->runtime) { + prtd = substream->runtime->private_data; + if (prtd->running) + return -EBUSY; + if (prtd) + prtd->disable_intr = false; + } + } + + if (id >= 0) { + rtd = &card->rtd[id]; + substream = + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (substream && substream->runtime) { + prtd = substream->runtime->private_data; + if (prtd->running) + return -EBUSY; + if (prtd) + prtd->disable_intr = true; + } + } + data->avp_device_id = id; + return 1; +} + +static int tegra_get_dma_ch_id(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol); + struct snd_soc_card *card = data->card; + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + struct tegra_runtime_data *prtd; + + ucontrol->value.integer.value[0] = -1; + if (data->avp_device_id < 0) + return 0; + + rtd = &card->rtd[data->avp_device_id]; + substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream || !substream->runtime) + return 0; + + prtd = substream->runtime->private_data; + if (!prtd || !prtd->dma_chan) + return 0; + + ucontrol->value.integer.value[0] = + tegra_dma_get_channel_id(prtd->dma_chan); + return 0; +} + +static int tegra_get_dma_addr(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol); + struct snd_soc_card *card = data->card; + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + + ucontrol->value.integer.value[0] = 0; + if (data->avp_device_id < 0) + return 0; + + rtd = &card->rtd[data->avp_device_id]; + substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream || !substream->runtime) + return 0; + + ucontrol->value.integer.value[0] = substream->runtime->dma_addr; + return 0; +} + +struct snd_kcontrol_new tegra_avp_controls[] = { + SOC_SINGLE_EXT("AVP alsa device select", 0, 0, TEGRA_ALSA_MAX_DEVICES, \ + 0, tegra_get_avp_device, tegra_set_avp_device), + SOC_SINGLE_EXT("AVP DMA channel id", 0, 0, TEGRA_DMA_MAX_CHANNELS, \ + 0, tegra_get_dma_ch_id, NULL), + SOC_SINGLE_EXT("AVP DMA address", 0, 0, 0xFFFFFFFF, \ + 0, tegra_get_dma_addr, NULL), +}; + int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, int mclk) { @@ -152,6 +264,26 @@ int tegra_asoc_utils_clk_disable(struct tegra_asoc_utils_data *data) } EXPORT_SYMBOL_GPL(tegra_asoc_utils_clk_disable); +int tegra_asoc_utils_register_ctls(struct tegra_asoc_utils_data *data) +{ + int i; + int ret = 0; + + /* Add AVP related alsa controls */ + data->avp_device_id = -1; + for (i = 0; i < ARRAY_SIZE(tegra_avp_controls); i++) { + ret = snd_ctl_add(data->card->snd_card, + snd_ctl_new1(&tegra_avp_controls[i], data)); + if (ret < 0) { + dev_err(data->dev, "Can't add avp alsa controls"); + return ret; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(tegra_asoc_utils_register_ctls); + int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev, struct snd_soc_card *card) { diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h index 512df0d54eb1..0423f02b76cc 100644 --- a/sound/soc/tegra/tegra_asoc_utils.h +++ b/sound/soc/tegra/tegra_asoc_utils.h @@ -25,6 +25,8 @@ #define TEGRA30_I2S_MASTER_PLAYBACK 1 +#define TEGRA_ALSA_MAX_DEVICES 6 +#define TEGRA_DMA_MAX_CHANNELS 32 struct clk; struct device; @@ -41,6 +43,7 @@ struct tegra_asoc_utils_data { int set_baseclock; int set_mclk; int lock_count; + int avp_device_id; }; int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, @@ -52,6 +55,7 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); int tegra_asoc_utils_clk_enable(struct tegra_asoc_utils_data *data); int tegra_asoc_utils_clk_disable(struct tegra_asoc_utils_data *data); +int tegra_asoc_utils_register_ctls(struct tegra_asoc_utils_data *data); #endif diff --git a/sound/soc/tegra/tegra_max98088.c b/sound/soc/tegra/tegra_max98088.c index 8c0e3935ad02..82c2b930a39e 100644 --- a/sound/soc/tegra/tegra_max98088.c +++ b/sound/soc/tegra/tegra_max98088.c @@ -1009,6 +1009,10 @@ static int tegra_max98088_init(struct snd_soc_pcm_runtime *rtd) if (ret < 0) return ret; + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + snd_soc_dapm_nc_pin(dapm, "INA1"); snd_soc_dapm_nc_pin(dapm, "INA2"); snd_soc_dapm_nc_pin(dapm, "INB1"); diff --git a/sound/soc/tegra/tegra_max98095.c b/sound/soc/tegra/tegra_max98095.c index 95295ef4151e..b3bed37ac715 100644 --- a/sound/soc/tegra/tegra_max98095.c +++ b/sound/soc/tegra/tegra_max98095.c @@ -542,6 +542,10 @@ static int tegra_max98095_init(struct snd_soc_pcm_runtime *rtd) tegra_max98095_hp_jack_pins); #endif + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + /* max98095_headset_detect(codec, &tegra_max98095_hp_jack, SND_JACK_HEADSET); */ diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 1b4b949841aa..f471fafff2ac 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -52,8 +52,8 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = { .channels_min = 1, .channels_max = 2, .period_bytes_min = 128, - .period_bytes_max = PAGE_SIZE, - .periods_min = 2, + .period_bytes_max = PAGE_SIZE * 2, + .periods_min = 1, .periods_max = 8, .buffer_bytes_max = PAGE_SIZE * 8, .fifo_size = 4, @@ -272,6 +272,15 @@ int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) prtd->dma_pos_end = frames_to_bytes(runtime, runtime->periods * runtime->period_size); prtd->period_index = 0; prtd->dma_req_idx = 0; + if (prtd->disable_intr) { + prtd->dma_req_count = 1; + prtd->dma_req[0].complete = NULL; + } else if (!prtd->dma_req[0].complete) { + prtd->dma_req[0].complete = dma_complete_callback; + prtd->dma_req_count = + (MAX_DMA_REQ_COUNT <= runtime->periods) ? + MAX_DMA_REQ_COUNT : runtime->periods; + } /* Fall-through */ case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: @@ -289,8 +298,9 @@ int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) spin_unlock_irqrestore(&prtd->lock, flags); tegra_dma_cancel(prtd->dma_chan); for (i = 0; i < prtd->dma_req_count; i++) { - if (prtd->dma_req[i].status == - -TEGRA_DMA_REQ_ERROR_ABORTED) + if (prtd->dma_req[i].complete && + (prtd->dma_req[i].status == + -TEGRA_DMA_REQ_ERROR_ABORTED)) prtd->dma_req[i].complete(&prtd->dma_req[i]); } break; diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h index 7fe22788004b..b63de32023e8 100644 --- a/sound/soc/tegra/tegra_pcm.h +++ b/sound/soc/tegra/tegra_pcm.h @@ -53,6 +53,7 @@ struct tegra_runtime_data { struct tegra_dma_req dma_req[MAX_DMA_REQ_COUNT]; struct tegra_dma_channel *dma_chan; int dma_req_count; + int disable_intr; }; int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd); diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index 231b0ee61308..765eb59fabae 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -547,6 +547,11 @@ static int tegra_rt5640_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_add_routes(dapm, cardhu_audio_map, ARRAY_SIZE(cardhu_audio_map)); + + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + /* FIXME: Calculate automatically based on DAPM routes? */ snd_soc_dapm_nc_pin(dapm, "LOUTL"); snd_soc_dapm_nc_pin(dapm, "LOUTR"); diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 99d0b19c7106..f7c7a4c6b5a1 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -782,6 +782,10 @@ static int tegra_wm8753_init(struct snd_soc_pcm_runtime *rtd) if (ret < 0) return ret; + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + snd_soc_dapm_nc_pin(dapm, "ACIN"); snd_soc_dapm_nc_pin(dapm, "ACOP"); snd_soc_dapm_nc_pin(dapm, "OUT3"); diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index ce608b007bef..147546575233 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -660,6 +660,10 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, machine_is_cardhu() ? SND_JACK_MICROPHONE : 0); + ret = tegra_asoc_utils_register_ctls(&machine->util_data); + if (ret < 0) + return ret; + snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); /* FIXME: Calculate automatically based on DAPM routes? */ -- cgit v1.2.3 From 3e8b5c5460b795c3e50f8221c7ee12858264ae76 Mon Sep 17 00:00:00 2001 From: Manoj Gangwal Date: Thu, 24 May 2012 19:30:36 +0530 Subject: asoc: codecs: ALC5639/40: Change to reduce codec pwr in lp0 Bug 964287 1) Add support for resetting the codec while entering in lp0 state to save codec power in lpo for KAI. 2) Fix for cache sync. 3) Add index sync functionality. Change-Id: I04039eb55944bfe7f06e6a1405ac3c810c5688a1 Signed-off-by: Manoj Gangwal Reviewed-on: http://git-master/r/104480 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Tested-by: Daniel Solomon Reviewed-by: Scott Peterson --- sound/soc/codecs/rt5639.c | 24 ++++++++++++++++++++++++ sound/soc/codecs/rt5640.c | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/rt5639.c b/sound/soc/codecs/rt5639.c index c9b14e9f0bc1..13190e21404b 100644 --- a/sound/soc/codecs/rt5639.c +++ b/sound/soc/codecs/rt5639.c @@ -105,6 +105,18 @@ static int rt5639_reg_init(struct snd_soc_codec *codec) } #endif +static int rt5639_index_sync(struct snd_soc_codec *codec) +{ + int i; + + for (i = 0; i < RT5639_INIT_REG_LEN; i++) + if (RT5639_PRIV_INDEX == init_list[i].reg || + RT5639_PRIV_DATA == init_list[i].reg) + snd_soc_write(codec, init_list[i].reg, + init_list[i].val); + return 0; +} + static const u16 rt5639_reg[RT5639_VENDOR_ID2 + 1] = { [RT5639_RESET] = 0x0008, [RT5639_SPK_VOL] = 0xc8c8, @@ -2213,7 +2225,9 @@ static int rt5639_set_bias_level(struct snd_soc_codec *codec, RT5639_PWR_FV1 | RT5639_PWR_FV2, RT5639_PWR_FV1 | RT5639_PWR_FV2); codec->cache_only = false; + codec->cache_sync = 1; snd_soc_cache_sync(codec); + rt5639_index_sync(codec); } break; @@ -2311,13 +2325,23 @@ static int rt5639_remove(struct snd_soc_codec *codec) #ifdef CONFIG_PM static int rt5639_suspend(struct snd_soc_codec *codec, pm_message_t state) { + rt5639_reset(codec); rt5639_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } static int rt5639_resume(struct snd_soc_codec *codec) { + int ret = 0 ; + + codec->cache_sync = 1; + ret = snd_soc_cache_sync(codec); + if (ret) { + dev_err(codec->dev,"Failed to sync cache: %d\n", ret); + return ret; + } rt5639_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; } #else diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 8407c638cf8a..49256e2d151d 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -106,6 +106,18 @@ static int rt5640_reg_init(struct snd_soc_codec *codec) } #endif +static int rt5640_index_sync(struct snd_soc_codec *codec) +{ + int i; + + for (i = 0; i < RT5640_INIT_REG_LEN; i++) + if (RT5640_PRIV_INDEX == init_list[i].reg || + RT5640_PRIV_DATA == init_list[i].reg) + snd_soc_write(codec, init_list[i].reg, + init_list[i].val); + return 0; +} + static const u16 rt5640_reg[RT5640_VENDOR_ID2 + 1] = { [RT5640_RESET] = 0x000c, [RT5640_SPK_VOL] = 0xc8c8, @@ -2269,7 +2281,9 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, RT5640_PWR_FV1 | RT5640_PWR_FV2, RT5640_PWR_FV1 | RT5640_PWR_FV2); codec->cache_only = false; + codec->cache_sync = 1; snd_soc_cache_sync(codec); + rt5640_index_sync(codec); } break; @@ -2381,6 +2395,7 @@ static int rt5640_remove(struct snd_soc_codec *codec) #ifdef CONFIG_PM static int rt5640_suspend(struct snd_soc_codec *codec, pm_message_t state) { + rt5640_reset(codec); rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_write(codec, RT5640_PWR_ANLG1, 0); @@ -2389,6 +2404,14 @@ static int rt5640_suspend(struct snd_soc_codec *codec, pm_message_t state) static int rt5640_resume(struct snd_soc_codec *codec) { + int ret = 0 ; + + codec->cache_sync = 1; + ret = snd_soc_cache_sync(codec); + if (ret) { + dev_err(codec->dev,"Failed to sync cache: %d\n", ret); + return ret; + } rt5640_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; -- cgit v1.2.3 From ee944d7e32042a63c7e8068c04e00c2fe0330301 Mon Sep 17 00:00:00 2001 From: Juha Tukkinen Date: Wed, 30 May 2012 17:04:48 +0300 Subject: ASoC: tegra: remove compilation warning Ensure i2s_client_bits and i2s_audio_bits do not get used uninitialized. Bug 949219 Change-Id: Ibdd7f2598278639388d2c2afb5843f2471375ea2 Signed-off-by: Juha Tukkinen Reviewed-on: http://git-master/r/105426 Reviewed-by: Sachin Nikam Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Sanjay Singh Rawat --- sound/soc/tegra/tegra30_i2s.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 449359837efb..8be00b840fb5 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -418,6 +418,10 @@ static int tegra30_i2s_tdm_hw_params(struct snd_pcm_substream *substream, i2s_client_bits = TEGRA30_AUDIOCIF_BITS_32; i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_32; break; + default: + dev_err(dev, "unknown slot_width %d\n", + i2s->dsp_config.slot_width); + return -EINVAL; } val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | -- cgit v1.2.3 From a828242259b8fb216d76d28619f1ae2927932645 Mon Sep 17 00:00:00 2001 From: Nitin Pai Date: Wed, 30 May 2012 18:31:46 +0530 Subject: asoc: tegra: p1852: Use pcm-driver from platform Use the pcm-driver specified from platform/board specified file. Bug 991926 Change-Id: I9e4c9a3f76bacb22de817273a2281ac9b8959c43 Signed-off-by: Nitin Pai Reviewed-on: http://git-master/r/105415 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bob Johnston GVS: Gerrit_Virtual_Submit Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra_p1852.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_p1852.c b/sound/soc/tegra/tegra_p1852.c index 85b4cee30c5f..199bb8046636 100644 --- a/sound/soc/tegra/tegra_p1852.c +++ b/sound/soc/tegra/tegra_p1852.c @@ -227,6 +227,9 @@ static __devinit int tegra_p1852_driver_probe(struct platform_device *pdev) pdata->codec_info[i].codec_dai_name; tegra_p1852_dai_link[i].name = pdata->codec_info[i].name; + if (pdata->codec_info[i].pcm_driver) + tegra_p1852_dai_link[i].platform_name = + pdata->codec_info[i].pcm_driver; } ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev, card); -- cgit v1.2.3 From f9417ad159c43ae90f25c0ef978e2c37294d27a1 Mon Sep 17 00:00:00 2001 From: Nitin Pai Date: Thu, 24 May 2012 17:16:03 +0530 Subject: asoc: tegra: Fix setting rate for clk_audio_2x - For slave mode, clk_audio_2x needs to be programmed to bitclock value. Setting this frequency is not possible if the parent clock has different frequency. Hence change the parent of this clock to i2s_sync clock first before setting the rate. - Fixed setting uninitialized variables. Bug 948478 Change-Id: Ieb4656e6e114d3a9b815f44003a476c4b9892059 Signed-off-by: Nitin Pai Reviewed-on: http://git-master/r/104445 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bob Johnston GVS: Gerrit_Virtual_Submit Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra30_i2s.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 8be00b840fb5..a50b853135ae 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -346,6 +346,7 @@ static int tegra30_i2s_tdm_setup_clocks(struct device *dev, dev_err(dev, "Can't set parent of I2S clock\n"); return ret; } + ret = clk_set_rate(i2s->clk_i2s, *i2sclock); if (ret) { dev_err(dev, "Can't set I2S clock rate: %d\n", ret); @@ -359,6 +360,13 @@ static int tegra30_i2s_tdm_setup_clocks(struct device *dev, return ret; } + ret = clk_set_parent(clk_get_parent(i2s->clk_audio_2x), + i2s->clk_i2s_sync); + if (ret) { + dev_err(dev, "Can't set parent of audio2x clock\n"); + return ret; + } + ret = clk_set_rate(i2s->clk_audio_2x, *i2sclock); if (ret) { dev_err(dev, "Can't set audio2x clock rate\n"); @@ -367,7 +375,7 @@ static int tegra30_i2s_tdm_setup_clocks(struct device *dev, ret = clk_set_parent(i2s->clk_i2s, i2s->clk_audio_2x); if (ret) { - dev_err(dev, "Can't set parent of audio2x clock\n"); + dev_err(dev, "Can't set parent of i2s clock\n"); return ret; } } @@ -382,7 +390,8 @@ static int tegra30_i2s_tdm_hw_params(struct snd_pcm_substream *substream, struct device *dev = substream->pcm->card->dev; struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); u32 val; - int i2s_client_ch, i2s_audio_ch, i2s_audio_bits, i2s_client_bits; + int i2s_client_ch, i2s_audio_ch; + int i2s_audio_bits = 0, i2s_client_bits = 0; int i2sclock, srate; int ret; -- cgit v1.2.3 From 8e83ca8bde2e1c42df08f37840226c9d07d4af69 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Wed, 6 Jun 2012 15:28:40 -0400 Subject: asoc: max98095: probe with no device there fix There is path through which registering a card will fail to probe, but that error code is not propogated back to the tegra machine driver. To catch this case in the machine driver's probe routine, we need to ensure that after registering the card, the card is instantiated and fail probe if not. Change-Id: I64ba952685ef193a3b248502943771c518396808 Signed-off-by: Rhyland Klein Reviewed-on: http://git-master/r/106837 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra_max98095.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_max98095.c b/sound/soc/tegra/tegra_max98095.c index b3bed37ac715..701571d23251 100644 --- a/sound/soc/tegra/tegra_max98095.c +++ b/sound/soc/tegra/tegra_max98095.c @@ -658,8 +658,17 @@ static __devinit int tegra_max98095_driver_probe(struct platform_device *pdev) goto err_switch_unregister; } + if (!card->instantiated) { + ret = -ENODEV; + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err_unregister_card; + } + return 0; +err_unregister_card: + snd_soc_unregister_card(card); err_switch_unregister: #ifdef CONFIG_SWITCH switch_dev_unregister(&wired_switch_dev); -- cgit v1.2.3 From daf2ee7b9eefb84d2140152786ba8a19674b4fe6 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Wed, 30 May 2012 14:34:47 -0400 Subject: sound: soc: tegra: fix compilation errors Several compilation errors popped up when building the 3.1 kernel for chrome. Warnings included callback structure changing and not being updated in the max98095 codec driver and unused labels. With these change I am able to compile in the max98095 codec support and wm8903 without build errors. Bug 986933 Change-Id: Ia8b2511f54b031eadcad8c74efa88be9288f25fb Signed-off-by: Rhyland Klein Reviewed-on: http://git-master/r/105464 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra_max98095.c | 4 +++- sound/soc/tegra/tegra_wm8903.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_max98095.c b/sound/soc/tegra/tegra_max98095.c index 701571d23251..d065b78164ac 100644 --- a/sound/soc/tegra/tegra_max98095.c +++ b/sound/soc/tegra/tegra_max98095.c @@ -581,6 +581,7 @@ static struct snd_soc_dai_link tegra_max98095_dai[] = { }; static int tegra30_soc_set_bias_level(struct snd_soc_card *card, + struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card); @@ -595,6 +596,7 @@ static int tegra30_soc_set_bias_level(struct snd_soc_card *card, } static int tegra30_soc_set_bias_level_post(struct snd_soc_card *card, + struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card); @@ -672,8 +674,8 @@ err_unregister_card: err_switch_unregister: #ifdef CONFIG_SWITCH switch_dev_unregister(&wired_switch_dev); -#endif err_fini_utils: +#endif tegra_asoc_utils_fini(&machine->util_data); err_free_machine: kfree(machine); diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 147546575233..063aefe50507 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -902,8 +902,8 @@ err_unregister_card: err_unregister_switch: #ifdef CONFIG_SWITCH switch_dev_unregister(&tegra_wm8903_headset_switch); -#endif err_fini_utils: +#endif tegra_asoc_utils_fini(&machine->util_data); err_free_machine: kfree(machine); -- cgit v1.2.3 From 8f751e925da2510ded1003976186a379853b134e Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Fri, 22 Jun 2012 12:54:52 +0530 Subject: asoc: tegra: Change HW disabling dequence and I2S clock parent Change HW disabling dequence and I2S clock parent in slave mode for voice call use-case Bug: 1005176 Signed-off-by: Nikesh Oswal Reviewed-on: http://git-master/r/110529 (cherry picked from commit 4b138cdeb3374575bde9f49d0c644faa91ced68f) Change-Id: Ia037ed5ef45d38972c3e1e1a78b4b7b7f39d8f72 Reviewed-on: http://git-master/r/114444 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Nikesh Oswal Reviewed-by: Scott Peterson --- sound/soc/tegra/tegra30_ahub.c | 37 +++++++++++ sound/soc/tegra/tegra30_ahub.h | 4 ++ sound/soc/tegra/tegra30_dam.c | 47 ++++++++++--- sound/soc/tegra/tegra30_i2s.c | 147 +++++++++++++++++++++++++++++------------ 4 files changed, 183 insertions(+), 52 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 30b7e481acc4..6fac8fc0177b 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -3,6 +3,7 @@ * * Author: Stephen Warren * Copyright (C) 2011 - NVIDIA, Inc. + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -302,6 +303,42 @@ int tegra30_ahub_tx_fifo_is_enabled(int i2s_id) return val; } +int tegra30_ahub_dam_ch0_is_enabled(int dam_id) +{ + int val, mask; + + val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) + + (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE)); + mask = TEGRA30_AHUB_DAM_LIVE_STATUS_RX0_ENABLED; + val &= mask; + + return val; +} + +int tegra30_ahub_dam_ch1_is_enabled(int dam_id) +{ + int val, mask; + + val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) + + (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE)); + mask = TEGRA30_AHUB_DAM_LIVE_STATUS_RX1_ENABLED; + val &= mask; + + return val; +} + +int tegra30_ahub_dam_tx_is_enabled(int dam_id) +{ + int val, mask; + + val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) + + (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE)); + mask = TEGRA30_AHUB_DAM_LIVE_STATUS_TX_ENABLED; + val &= mask; + + return val; +} + int tegra30_ahub_set_rx_fifo_pack_mode(enum tegra30_ahub_rxcif rxcif, unsigned int pack_mode) { diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index 8dc27abc5aed..b5fd2363f080 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -3,6 +3,7 @@ * * Author: Stephen Warren * Copyright (C) 2011 - NVIDIA, Inc. + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -502,6 +503,9 @@ extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_rx_fifo_is_enabled(int i2s_id); extern int tegra30_ahub_tx_fifo_is_enabled(int i2s_id); +extern int tegra30_ahub_dam_ch0_is_enabled(int dam_id); +extern int tegra30_ahub_dam_ch1_is_enabled(int dam_id); +extern int tegra30_ahub_dam_tx_is_enabled(int dam_id); #ifdef CONFIG_PM extern int tegra30_ahub_apbif_resume(void); diff --git a/sound/soc/tegra/tegra30_dam.c b/sound/soc/tegra/tegra30_dam.c index d308179110c9..8460266d0d66 100644 --- a/sound/soc/tegra/tegra30_dam.c +++ b/sound/soc/tegra/tegra30_dam.c @@ -3,6 +3,7 @@ * * Author: Nikesh Oswal * Copyright (C) 2011 - NVIDIA, Inc. + * Copyright (C) 2012, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -27,6 +28,7 @@ #include #include #include +#include #include #include #include "tegra30_dam.h" @@ -455,6 +457,8 @@ int tegra30_dam_set_acif(int ifc, int chid, unsigned int audio_channels, void tegra30_dam_enable(int ifc, int on, int chid) { u32 old_val, val, enreg; + u32 old_val_dam, val_dam; + int dcnt = 10; struct tegra30_dam_context *dam = dams_cont_info[ifc]; if (ifc >= TEGRA30_NR_DAM_IFC) @@ -476,19 +480,46 @@ void tegra30_dam_enable(int ifc, int on, int chid) val &= ~TEGRA30_DAM_CH0_CTRL_EN; } - if (val != old_val) - tegra30_dam_writel(dam, val, enreg); - - old_val = val = tegra30_dam_readl(dam, TEGRA30_DAM_CTRL); + old_val_dam = val_dam = tegra30_dam_readl(dam, TEGRA30_DAM_CTRL); if (dam->ch_enable_refcnt[dam_ch_in0] || dam->ch_enable_refcnt[dam_ch_in1]) - val |= TEGRA30_DAM_CTRL_DAM_EN; + val_dam |= TEGRA30_DAM_CTRL_DAM_EN; else - val &= ~TEGRA30_DAM_CTRL_DAM_EN; + val_dam &= ~TEGRA30_DAM_CTRL_DAM_EN; + + if (val != old_val) { + tegra30_dam_writel(dam, val, enreg); + + if (!on) { + if (chid == dam_ch_in0) { + while (tegra30_ahub_dam_ch0_is_enabled(ifc) + && dcnt--) + udelay(100); + + dcnt = 10; + } + else { + while (tegra30_ahub_dam_ch1_is_enabled(ifc) + && dcnt--) + udelay(100); + + dcnt = 10; + } + } + } + + if (old_val_dam != val_dam) { + tegra30_dam_writel(dam, val_dam, TEGRA30_DAM_CTRL); + + if (!on) { + while (tegra30_ahub_dam_tx_is_enabled(ifc) && dcnt--) + udelay(100); - if (old_val != val) - tegra30_dam_writel(dam, val, TEGRA30_DAM_CTRL); + dcnt = 10; + } + + } } void tegra30_dam_ch0_set_datasync(struct tegra30_dam_context *dam, int datasync) diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index a50b853135ae..72e64470008a 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -7,6 +7,7 @@ * Based on code copyright/by: * * Copyright (c) 2009-2010, NVIDIA Corporation. + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. * Scott Peterson * * Copyright (C) 2010 Google, Inc. @@ -811,7 +812,47 @@ static int configure_baseband_i2s(struct tegra30_i2s *i2s, int is_i2smaster, int is_formatdsp, int channels, int rate, int bitsize) { u32 val; - int i2sclock, bitcnt; + int i2sclock, bitcnt, ret; + + i2sclock = rate * channels * bitsize * 2; + + /* additional 8 for baseband */ + if (is_formatdsp) + i2sclock *= 8; + + if (is_i2smaster) { + ret = clk_set_parent(i2s->clk_i2s, i2s->clk_pll_a_out0); + if (ret) { + pr_err("Can't set parent of I2S clock\n"); + return ret; + } + + ret = clk_set_rate(i2s->clk_i2s, i2sclock); + if (ret) { + pr_err("Can't set I2S clock rate: %d\n", ret); + return ret; + } + } else { + ret = clk_set_rate(i2s->clk_i2s_sync, i2sclock); + if (ret) { + pr_err("Can't set I2S sync clock rate\n"); + return ret; + } + + ret = clk_set_rate(i2s->clk_audio_2x, i2sclock); + if (ret) { + pr_err("Can't set I2S sync clock rate\n"); + return ret; + } + + ret = clk_set_parent(i2s->clk_i2s, i2s->clk_audio_2x); + if (ret) { + pr_err("Can't set parent of audio2x clock\n"); + return ret; + } + } + + tegra30_i2s_enable_clocks(i2s); i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | TEGRA30_I2S_CTRL_LRCK_MASK | @@ -846,14 +887,6 @@ static int configure_baseband_i2s(struct tegra30_i2s *i2s, int is_i2smaster, (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); - i2sclock = rate * channels * bitsize * 2; - - /* additional 8 for baseband */ - if (is_formatdsp) - i2sclock *= 8; - - clk_set_rate(i2s->clk_i2s, i2sclock); - if (is_formatdsp) { bitcnt = (i2sclock/rate) - 1; val = bitcnt << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; @@ -916,8 +949,6 @@ int tegra30_make_voice_call_connections(struct codec_config *codec_info, codec_i2s = &i2scont[codec_info->i2s_id]; bb_i2s = &i2scont[bb_info->i2s_id]; - tegra30_i2s_enable_clocks(codec_i2s); - tegra30_i2s_enable_clocks(bb_i2s); /* increment the codec i2s playback ref count */ codec_i2s->playback_ref_count++; @@ -985,61 +1016,89 @@ int tegra30_break_voice_call_connections(struct codec_config *codec_info, { struct tegra30_i2s *codec_i2s; struct tegra30_i2s *bb_i2s; + int dcnt = 10; codec_i2s = &i2scont[codec_info->i2s_id]; bb_i2s = &i2scont[bb_info->i2s_id]; - /* disconnect the ahub connections */ - - /* if this is the only user of i2s tx then break ahub - i2s rx connection */ - if (codec_i2s->playback_ref_count == 1) - tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_I2S0_RX0 - + codec_info->i2s_id); + /*Disable Codec I2S RX (TX to ahub)*/ + codec_i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; + tegra30_i2s_write(codec_i2s, TEGRA30_I2S_CTRL, codec_i2s->reg_ctrl); - tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_I2S0_RX0 - + bb_info->i2s_id); - tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 - + (codec_i2s->dam_ifc*2)); - tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 - + (bb_i2s->dam_ifc*2)); + while (tegra30_ahub_rx_fifo_is_enabled(codec_i2s->id) && dcnt--) + udelay(100); - /* disable the i2s */ + dcnt = 10; - /* if this is the only user of i2s tx then disable it*/ - if (codec_i2s->playback_ref_count == 1) - codec_i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; + /*Disable baseband DAM*/ + tegra30_dam_enable(bb_i2s->dam_ifc, TEGRA30_DAM_DISABLE, + TEGRA30_DAM_CHIN0_SRC); + tegra30_dam_free_channel(bb_i2s->dam_ifc, TEGRA30_DAM_CHIN0_SRC); + bb_i2s->dam_ch_refcount--; + if (!bb_i2s->dam_ch_refcount) + tegra30_dam_free_controller(bb_i2s->dam_ifc); - codec_i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; - tegra30_i2s_write(codec_i2s, TEGRA30_I2S_CTRL, codec_i2s->reg_ctrl); + /*Disable baseband I2S TX (RX from ahub)*/ bb_i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; + tegra30_i2s_write(bb_i2s, TEGRA30_I2S_CTRL, bb_i2s->reg_ctrl); + + while (tegra30_ahub_tx_fifo_is_enabled(bb_i2s->id) && dcnt--) + udelay(100); + + dcnt = 10; + + /*Disable baseband I2S RX (TX to ahub)*/ bb_i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; tegra30_i2s_write(bb_i2s, TEGRA30_I2S_CTRL, bb_i2s->reg_ctrl); - tegra30_i2s_disable_clocks(codec_i2s); - tegra30_i2s_disable_clocks(bb_i2s); - /* decrement the codec i2s playback ref count */ - codec_i2s->playback_ref_count--; - bb_i2s->playback_ref_count--; + while (tegra30_ahub_rx_fifo_is_enabled(bb_i2s->id) && dcnt--) + udelay(100); - /* disable the codec dam */ + dcnt = 10; + + /*Disable Codec DAM*/ tegra30_dam_enable(codec_i2s->dam_ifc, TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN0_SRC); - tegra30_dam_disable_clock(codec_i2s->dam_ifc); tegra30_dam_free_channel(codec_i2s->dam_ifc, TEGRA30_DAM_CHIN0_SRC); codec_i2s->dam_ch_refcount--; if (!codec_i2s->dam_ch_refcount) tegra30_dam_free_controller(codec_i2s->dam_ifc); - /* disable the bb dam */ - tegra30_dam_enable(bb_i2s->dam_ifc, TEGRA30_DAM_DISABLE, - TEGRA30_DAM_CHIN0_SRC); + /*Disable Codec I2S TX (RX from ahub)*/ + if (codec_i2s->playback_ref_count == 1) + codec_i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; + + tegra30_i2s_write(codec_i2s, TEGRA30_I2S_CTRL, codec_i2s->reg_ctrl); + + while (tegra30_ahub_tx_fifo_is_enabled(codec_i2s->id) && dcnt--) + udelay(100); + + dcnt = 10; + + /* Disconnect the ahub connections */ + /* If this is the only user of i2s tx then break ahub + i2s rx connection */ + if (codec_i2s->playback_ref_count == 1) + tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_I2S0_RX0 + + codec_info->i2s_id); + + tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_I2S0_RX0 + + bb_info->i2s_id); + tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + + (codec_i2s->dam_ifc*2)); + tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + + (bb_i2s->dam_ifc*2)); + + /* Decrement the codec and bb i2s playback ref count */ + codec_i2s->playback_ref_count--; + bb_i2s->playback_ref_count--; + + /* Disable the clocks */ + tegra30_i2s_disable_clocks(codec_i2s); + tegra30_i2s_disable_clocks(bb_i2s); + tegra30_dam_disable_clock(codec_i2s->dam_ifc); tegra30_dam_disable_clock(bb_i2s->dam_ifc); - tegra30_dam_free_channel(bb_i2s->dam_ifc, TEGRA30_DAM_CHIN0_SRC); - bb_i2s->dam_ch_refcount--; - if (!bb_i2s->dam_ch_refcount) - tegra30_dam_free_controller(bb_i2s->dam_ifc); return 0; } -- cgit v1.2.3 From 328ca1a833b594b574b9f4f82a25ba8613bad3e5 Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Fri, 29 Jun 2012 16:26:33 +0530 Subject: asoc: codecs: max98088: Headset Detection Add code for headset detection according to that state transitions mentioned for JKSNS field in the max98088 codec datasheet Bug: 110529 Bug: 1008246 Signed-off-by: Nikesh Oswal Reviewed-on: http://git-master/r/112127 (cherry picked from commit 12a2259e0e9cf7da4bf64bad2a97c32cec41477c) Change-Id: I7d45b210dd02f181e71a08d9b3de7cff109dd88b Reviewed-on: http://git-master/r/114445 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Nikesh Oswal Reviewed-by: Scott Peterson --- sound/soc/codecs/max98088.c | 29 +++++++++++++++++++++-------- sound/soc/codecs/max98088.h | 5 +++++ 2 files changed, 26 insertions(+), 8 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index e2ad10d2deaa..b2b31f912b74 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -57,6 +57,8 @@ struct max98088_priv { unsigned int extmic_mode; int irq; struct snd_soc_jack *headset_jack; + unsigned int jk_sns; + int jack_report; }; static const u8 max98088_reg[M98088_REG_CNT] = { @@ -1968,19 +1970,28 @@ static void max98088_handle_pdata(struct snd_soc_codec *codec) int max98088_report_jack(struct snd_soc_codec *codec) { struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); - unsigned int value; - int jack_report = 0; + unsigned int jk_sns_curr; + int jack_report_curr = 0; /* Read the Jack Status Register*/ - value = snd_soc_read(codec, M98088_REG_02_JACK_STAUS); + jk_sns_curr = (snd_soc_read(codec, M98088_REG_02_JACK_STAUS)) + & (M98088_JKSNS_7 | M98088_JKSNS_6); + + if (max98088->jk_sns == M98088_NONE && jk_sns_curr == M98088_HP) + jack_report_curr = SND_JACK_HEADPHONE; + else if (max98088->jk_sns == M98088_NONE && jk_sns_curr == M98088_HS) + jack_report_curr = SND_JACK_HEADSET; + else if ((max98088->jk_sns == M98088_HP || max98088->jk_sns == M98088_HS) + && jk_sns_curr == M98088_NONE) + jack_report_curr = 0; + else + jack_report_curr = max98088->jack_report; - if ((value & M98088_JKSNS_7) == 0) - jack_report |= SND_JACK_HEADPHONE; - if (value & M98088_JKSNS_6) - jack_report |= SND_JACK_MICROPHONE; + max98088->jack_report = jack_report_curr; + max98088->jk_sns = jk_sns_curr; snd_soc_jack_report(max98088->headset_jack, - jack_report, SND_JACK_HEADSET); + jack_report_curr, SND_JACK_HEADSET); return 0; } @@ -2001,6 +2012,8 @@ int max98088_headset_detect(struct snd_soc_codec *codec, { struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); max98088->headset_jack = jack; + max98088->jk_sns = M98088_NONE; + max98088->jack_report = 0; if (max98088->irq) { if (type & SND_JACK_HEADSET) { diff --git a/sound/soc/codecs/max98088.h b/sound/soc/codecs/max98088.h index cf4b04d2d07a..81ccf4b4caee 100644 --- a/sound/soc/codecs/max98088.h +++ b/sound/soc/codecs/max98088.h @@ -222,6 +222,11 @@ #define M98088_BYTE1(w) ((w >> 8) & 0xff) #define M98088_BYTE0(w) (w & 0xff) +/* HeadPhone and HeadSet detection Bitmasks */ +#define M98088_HP 0 +#define M98088_HS M98088_JKSNS_6 +#define M98088_NONE (M98088_JKSNS_7 | M98088_JKSNS_6) + int max98088_headset_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, enum snd_jack_types type); -- cgit v1.2.3