diff options
Diffstat (limited to 'sound')
-rwxr-xr-x | sound/soc/codecs/tlv320aic326x.c | 461 | ||||
-rwxr-xr-x | sound/soc/codecs/tlv320aic326x.h | 13 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_aic326x.c | 37 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_wm8753.c | 9 |
4 files changed, 165 insertions, 355 deletions
diff --git a/sound/soc/codecs/tlv320aic326x.c b/sound/soc/codecs/tlv320aic326x.c index 40b6093737e4..9f1874328b28 100755 --- a/sound/soc/codecs/tlv320aic326x.c +++ b/sound/soc/codecs/tlv320aic326x.c @@ -49,7 +49,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> -#include <linux/spi/spi.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -120,17 +119,6 @@ static int soc_static_freq_config = 1; * Function Prototype ***************************************************************************** */ -static int aic3262_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai); - -static int aic3262_mute(struct snd_soc_dai *dai, int mute); - -static int aic3262_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir); - -static int aic3262_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt); - static int aic3262_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level); @@ -416,8 +404,8 @@ int snd_soc_get_volsw_2r_n(struct snd_kcontrol *kcontrol, } /* Read, update the corresponding Registers */ - val = (snd_soc_read(codec, reg) >> shift) & mask; - val2 = (snd_soc_read(codec, reg2) >> shift) & mask; + val = (aic3262_read(codec, reg) >> shift) & mask; + val2 = (aic3262_read(codec, reg2) >> shift) & mask; if (!strcmp(kcontrol->id.name, "PCM Playback Volume")) { ucontrol->value.integer.value[0] = @@ -612,8 +600,12 @@ static int __new_control_put(struct snd_kcontrol *kcontrol, aic3262->page_no = data[1]; DBG("reg = %d val = %x\n", data[0], data[1]); - +#if defined(LOCAL_REG_ACCESS) + if (codec->hw_write(codec->control_data, data, 2) != 2) + ret = -EIO; +#else ret = snd_soc_write(codec, data[0], data[1]); +#endif if (ret) printk(KERN_ERR "Error in i2c write\n"); @@ -894,11 +886,11 @@ static void aic3262_multi_i2s_dump_regs(struct snd_soc_dai *dai) aic3262_read(codec, counter)); } - /*DBG(KERN_INFO "#Page1 REGS..\n"); + DBG(KERN_INFO "#Page1 REGS..\n"); for (counter = 128; counter < 176; counter++) { DBG(KERN_INFO "#%2d -> 0x%x\n", (counter % 128), aic3262_read(codec, counter)); - }*/ + } DBG(KERN_INFO "#Page4 REGS..\n"); for (counter = 512; counter < 631; counter++) { @@ -1376,9 +1368,6 @@ static int aic3262_multi_i2s_asi2_set_dai_fmt(struct snd_soc_dai *codec_dai, */ iface_reg = aic3262_read(codec, ASI2_BUS_FMT); clk_reg = aic3262_read(codec, ASI2_BWCLK_CNTL_REG); - /* - iface_reg = ifce_reg & ~(3 << 6 | 3 << 2); - */ /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -1592,8 +1581,6 @@ static int aic3262_multi_i2s_set_dai_sysclk(struct snd_soc_dai *codec_dai, switch (freq) { case AIC3262_FREQ_12000000: case AIC3262_FREQ_12288000: - aic3262->sysclk = freq; - return 0; case AIC3262_FREQ_24000000: aic3262->sysclk = freq; return 0; @@ -2172,7 +2159,7 @@ static int aic3262_multi_i2s_hw_free(struct snd_pcm_substream *substream, */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && (dacregoffset != 0)) { - printk(KERN_INFO "#%s: Disabling Pg %d Reg %d DAC Inputs ..\n", + DBG(KERN_INFO "#%s: Disabling Pg %d Reg %d DAC Inputs ..\n", __func__, (dacregoffset/128), (dacregoffset % 128)); dacpath = aic3262_read(codec, dacregoffset); @@ -2237,13 +2224,6 @@ err: * The PCM bit format supported are 16, 20, 24 and 32 bits *---------------------------------------------------------------------------- */ -struct snd_soc_dai_ops aic3262_dai_ops = { - .hw_params = aic3262_hw_params, - .digital_mute = aic3262_mute, - .set_sysclk = aic3262_set_dai_sysclk, - .set_fmt = aic3262_set_dai_fmt, -}; - struct snd_soc_dai_ops aic3262_multi_i2s_dai_ops = { .hw_params = aic3262_multi_i2s_hw_params, .digital_mute = aic3262_multi_i2s_mute, @@ -2730,11 +2710,16 @@ int aic3262_change_page(struct snd_soc_codec *codec, u8 new_page) data[1] = new_page; aic3262->page_no = new_page; +#if defined(LOCAL_REG_ACCESS) + if (codec->hw_write(codec->control_data, data, 2) != 2) + ret = -EIO; +#else ret = snd_soc_write(codec, data[0], data[1]); +#endif if (ret) printk(KERN_ERR "Error in changing page to %d\n", new_page); - DBG("# Changing page to %d\r\n", new_page); + /*DBG("# Changing page to %d\r\n", new_page);*/ return ret; } @@ -2759,11 +2744,16 @@ int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book) if (ret) return ret; +#if defined(LOCAL_REG_ACCESS) + if (codec->hw_write(codec->control_data, data, 2) != 2) + ret = -EIO; +#else ret = snd_soc_write(codec, data[0], data[1]); +#endif if (ret) printk(KERN_ERR "Error in changing Book\n"); - DBG("# Changing book to %d\r\n", new_book); + /*DBG("# Changing book to %d\r\n", new_book);*/ return ret; } @@ -2777,6 +2767,7 @@ int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book) void aic3262_write_reg_cache(struct snd_soc_codec *codec, u16 reg, u8 value) { +#if defined(EN_REG_CACHE) u8 *cache = codec->reg_cache; if (reg >= AIC3262_CACHEREGNUM) @@ -2784,6 +2775,7 @@ void aic3262_write_reg_cache(struct snd_soc_codec *codec, if (cache) cache[reg] = value; +#endif } /* @@ -2804,7 +2796,12 @@ u8 aic3262_read(struct snd_soc_codec *codec, u16 reg) if (aic3262->page_no != page) aic3262_change_page(codec, page); +#if defined(LOCAL_REG_ACCESS) + i2c_master_send(codec->control_data, (char *)®, 1); + i2c_master_recv(codec->control_data, &value, 1); +#else value = snd_soc_read(codec, reg); +#endif /*DBG("r %2x %02x\r\n", reg, value);*/ return value; } @@ -2845,8 +2842,14 @@ int aic3262_write(struct snd_soc_codec *codec, u16 reg, u8 value) /*DBG("w %2x %02x\r\n", data[AIC3262_REG_OFFSET_INDEX], data[AIC3262_REG_DATA_INDEX]);*/ + +#if defined(LOCAL_REG_ACCESS) + if (codec->hw_write(codec->control_data, data, 2) != 2) + ret = -EIO; +#else ret = snd_soc_write(codec, data[AIC3262_REG_OFFSET_INDEX], data[AIC3262_REG_DATA_INDEX]); +#endif if (ret) printk(KERN_ERR "Error in i2c write\n"); @@ -2873,7 +2876,7 @@ int aic3262_write__(struct i2c_client *client, const char *buf, int count) ret = i2c_master_send(client, data, 2); if (ret < 2) { printk( - KERN_ERR"I2C write Error : bytes written = %d\n\n", ret); + KERN_ERR "I2C write Error : bytes written = %d\n\n", ret); return -EIO; } @@ -2892,6 +2895,13 @@ int aic3262_reset_cache(struct snd_soc_codec *codec) memcpy(codec->reg_cache, aic3262_reg, sizeof(aic3262_reg)); return 0; } + + codec->reg_cache = kmemdup(aic3262_reg, + sizeof(aic3262_reg), GFP_KERNEL); + if (!codec->reg_cache) { + printk(KERN_ERR "aic32x4: kmemdup failed\n"); + return -ENOMEM; + } #endif return 0; } @@ -2939,15 +2949,17 @@ static int aic3262_add_controls(struct snd_soc_codec *codec) { int err; + DBG("%s++\n", __func__); + err = snd_soc_add_controls(codec, aic3262_snd_controls, - ARRAY_SIZE(aic3262_snd_controls)); + ARRAY_SIZE(aic3262_snd_controls)); if (err < 0) { printk(KERN_ERR "Invalid control\n"); return err; } err = snd_soc_add_controls(codec, aic3262_snd_controls2, - ARRAY_SIZE(aic3262_snd_controls2)); + ARRAY_SIZE(aic3262_snd_controls2)); if (err < 0) { printk(KERN_ERR "Invalid control\n"); return err; @@ -3004,9 +3016,15 @@ static int aic3262_add_widgets(struct snd_soc_codec *codec) int reg_def_conf(struct snd_soc_codec *codec) { int i = 0, ret; + DBG(KERN_INFO "#%s: Invoked..\n", __func__); - aic3262_change_page(codec, 0); - aic3262_change_book(codec, 0); + ret = aic3262_change_page(codec, 0); + if (ret != 0) + return ret; + + ret = aic3262_change_book(codec, 0); + if (ret != 0) + return ret; /* Configure the Codec with the default Initialization Values */ for (i = 0; i < reg_init_size; i++) { @@ -3015,6 +3033,7 @@ int reg_def_conf(struct snd_soc_codec *codec) if (ret) break; } + DBG(KERN_INFO "#%s: Done..\n", __func__); return ret; } @@ -3046,295 +3065,17 @@ int i2c_verify_book0(struct snd_soc_codec *codec) k = 4; }*/ for (i = 0; i <= 127; i++) { +#if defined(LOCAL_REG_ACCESS) + val1 = i2c_smbus_read_byte_data(codec->control_data, i); +#else val1 = snd_soc_read(codec, i); +#endif /* printk("[%d][%d]=[0x%2x]\n",k,i,val1); */ } } return 0; } - - -/* - *---------------------------------------------------------------------------- - * Function : aic3262_hw_params - * Purpose : This function is to set the hardware parameters for AIC3262. - * The functions set the sample rate and audio serial data word - * length. - * - *---------------------------------------------------------------------------- - */ -static int aic3262_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); - int i, j; - u8 data; - - aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - i = aic3262_get_divs(aic3262->sysclk, params_rate(params)); - - i2c_verify_book0(codec); - - if (i < 0) { - printk(KERN_ERR "sampling rate not supported\n"); - return i; - } - - if (soc_static_freq_config) { - /*We will fix R value to 1 and make P & J=K.D as varialble */ - - /* Setting P & R values are set to 1 and 1 at init*/ - - /* J value */ - aic3262_write(codec, PLL_J_REG, aic3262_divs[i].pll_j); - - /* MSB & LSB for D value */ - - aic3262_write(codec, PLL_D_MSB, (aic3262_divs[i].pll_d >> 8)); - aic3262_write(codec, PLL_D_LSB, - (aic3262_divs[i].pll_d & AIC3262_8BITS_MASK)); - - /* NDAC divider value */ - data = aic3262_read(codec, NDAC_DIV_POW_REG); - DBG(KERN_INFO "# reading NDAC = %d , NDAC_DIV_POW_REG = %x\n", - aic3262_divs[i].ndac, data); - aic3262_write(codec, NDAC_DIV_POW_REG, - ((data & 0x80)|(aic3262_divs[i].ndac))); - DBG(KERN_INFO "# writing NDAC = %d , NDAC_DIV_POW_REG = %x\n", - aic3262_divs[i].ndac, - ((data & 0x80)|(aic3262_divs[i].ndac))); - - /* MDAC divider value */ - data = aic3262_read(codec, MDAC_DIV_POW_REG); - DBG(KERN_INFO "# reading MDAC = %d , MDAC_DIV_POW_REG = %x\n", - aic3262_divs[i].mdac, data); - aic3262_write(codec, MDAC_DIV_POW_REG, - ((data & 0x80)|(aic3262_divs[i].mdac))); - DBG(KERN_INFO "# writing MDAC = %d , MDAC_DIV_POW_REG = %x\n", - aic3262_divs[i].mdac, ((data & 0x80)|(aic3262_divs[i].mdac))); - - /* DOSR MSB & LSB values */ - aic3262_write(codec, DOSR_MSB_REG, aic3262_divs[i].dosr >> 8); - DBG(KERN_INFO "# writing DOSR_MSB_REG = %d\n", - (aic3262_divs[i].dosr >> 8)); - aic3262_write(codec, DOSR_LSB_REG, - aic3262_divs[i].dosr & AIC3262_8BITS_MASK); - DBG(KERN_INFO "# writing DOSR_LSB_REG = %d\n", - (aic3262_divs[i].dosr & AIC3262_8BITS_MASK)); - - /* NADC divider value */ - data = aic3262_read(codec, NADC_DIV_POW_REG); - aic3262_write(codec, NADC_DIV_POW_REG, - ((data & 0x80)|(aic3262_divs[i].nadc))); - DBG(KERN_INFO "# writing NADC_DIV_POW_REG = %d\n", - aic3262_divs[i].nadc); - - /* MADC divider value */ - data = aic3262_read(codec, MADC_DIV_POW_REG); - aic3262_write(codec, MADC_DIV_POW_REG, - ((data & 0x80)|(aic3262_divs[i].madc))); - DBG(KERN_INFO "# writing MADC_DIV_POW_REG = %d\n", - aic3262_divs[i].madc); - - /* AOSR value */ - aic3262_write(codec, AOSR_REG, aic3262_divs[i].aosr); - DBG(KERN_INFO "# writing AOSR = %d\n", aic3262_divs[i].aosr); - } - - - data = aic3262_read(codec, ASI1_BUS_FMT); - - data = data & 0xe7; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - data = data | 0x00; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - data |= (0x08); - break; - case SNDRV_PCM_FORMAT_S24_LE: - data |= (0x10); - break; - case SNDRV_PCM_FORMAT_S32_LE: - data |= (0x18); - break; - } - - /* configure the respective Registers for the above configuration */ - aic3262_write(codec, ASI1_BUS_FMT, data); - - for (j = 0; j < NO_FEATURE_REGS; j++) { - aic3262_write(codec, - aic3262_divs[i].codec_specific_regs[j].reg_offset, - aic3262_divs[i].codec_specific_regs[j].reg_val); - } - - aic3262_set_bias_level(codec, SND_SOC_BIAS_ON); - return 0; -} - -/* - *---------------------------------------------------------------------------- - * Function : aic3262_mute - * Purpose : This function is to mute or unmute the left and right DAC - * - *---------------------------------------------------------------------------- - */ -static int aic3262_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); - - DBG(KERN_INFO "#aic3262 codec : mute started\n"); - if (mute) { - DBG("Mute if part\n"); - - if (!aic3262->mute_codec) { - dac_reg = aic3262_read(codec, DAC_MVOL_CONF); - adc_gain = aic3262_read(codec, ADC_FINE_GAIN); - hpl = aic3262_read(codec, HPL_VOL); - hpr = aic3262_read(codec, HPR_VOL); - rec_amp = aic3262_read(codec, REC_AMP_CNTL_R5); - rampr = aic3262_read(codec, RAMPR_VOL); - spk_amp = aic3262_read(codec, SPK_AMP_CNTL_R4); - } - DBG("spk_reg = %2x\n\n", spk_amp); - - aic3262_write(codec, DAC_MVOL_CONF, ((dac_reg & 0xF3) | 0x0C)); - aic3262_write(codec, ADC_FINE_GAIN, ((adc_gain & 0x77) | 0x88)); - aic3262_write(codec, HPL_VOL, 0xB9); - aic3262_write(codec, HPR_VOL, 0xB9); - aic3262_write(codec, REC_AMP_CNTL_R5, 0x39); - aic3262_write(codec, RAMPR_VOL, 0x39); - aic3262_write(codec, SPK_AMP_CNTL_R4, 0x00); - aic3262->mute_codec = 1; - } else { - DBG("Mute else part\n"); - aic3262_write(codec, DAC_MVOL_CONF, (dac_reg & 0xF3)); - mdelay(5); - aic3262_write(codec, ADC_FINE_GAIN, (adc_gain & 0x77)); - mdelay(5); - aic3262_write(codec, HPL_VOL, hpl); - mdelay(5); - aic3262_write(codec, HPR_VOL, hpr); - mdelay(5); - aic3262_write(codec, REC_AMP_CNTL_R5, rec_amp); - mdelay(5); - aic3262_write(codec, RAMPR_VOL, rampr); - mdelay(5); - aic3262_write(codec, SPK_AMP_CNTL_R4, spk_amp); - mdelay(5); - aic3262->mute_codec = 0; - } - DBG(KERN_INFO "#aic3262 codec : mute ended\n"); - return 0; -} - -/* - *---------------------------------------------------------------------------- - * Function : aic3262_set_dai_sysclk - * Purpose : This function is to set the DAI system clock - * - *---------------------------------------------------------------------------- - */ -static int aic3262_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); - - switch (freq) { - case AIC3262_FREQ_12000000: - case AIC3262_FREQ_12288000: - aic3262->sysclk = freq; - return 0; - case AIC3262_FREQ_24000000: - aic3262->sysclk = freq; - return 0; - break; - } - printk(KERN_ERR "Invalid frequency to set DAI system clock\n"); - return -EINVAL; -} - -/* - *---------------------------------------------------------------------------- - * Function : aic3262_set_dai_fmt - * Purpose : This function is to set the DAI format - * - *---------------------------------------------------------------------------- - */ -static int aic3262_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); - u8 iface_reg, clk_reg; - - iface_reg = aic3262_read(codec, ASI1_BUS_FMT); - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - DBG("setdai_fmt : SND_SOC_DAIFMT_CBM_CFM : master=1\n"); - aic3262->master = 1; - /*Test added */ - clk_reg = aic3262_read(codec, ASI1_BWCLK_CNTL_REG); - clk_reg = (clk_reg & 0x03); - aic3262_write(codec, ASI1_BWCLK_CNTL_REG, - (clk_reg | 0x24)); - break; - case SND_SOC_DAIFMT_CBS_CFS: - DBG("setdai_fmt : SND_SOC_DAIFMT_CBS_CFS : master=0\n"); - aic3262->master = 0; - /*Test added */ - clk_reg = aic3262_read(codec, ASI1_BWCLK_CNTL_REG); - aic3262_write(codec, ASI1_BWCLK_CNTL_REG, - (clk_reg & 0x03)); - break; - case SND_SOC_DAIFMT_CBS_CFM: /*new case..just for debugging*/ - DBG("SND_SOC_DAIFMT_CBS_CFM\n"); - aic3262->master = 0; - break; - default: - printk(KERN_ERR "Invalid DAI master/slave interface\n"); - return -EINVAL; - } - - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface_reg = (iface_reg & 0x1f); - break; - case SND_SOC_DAIFMT_DSP_A: - iface_reg = (iface_reg & 0x1f) | 0x20; - break; - case SND_SOC_DAIFMT_RIGHT_J: - iface_reg = (iface_reg & 0x1f) | 0x40; - break; - case SND_SOC_DAIFMT_LEFT_J: - iface_reg = (iface_reg & 0x1f) | 0x60; - break; - case SND_SOC_DAIFMT_DSP_B: - iface_reg = (iface_reg & 0x1f) | 0x80; - /* voice call need data offset in 1 bitclock */ - aic3262_write(codec, ASI1_LCH_OFFSET, 1); - break; - default: - printk(KERN_ERR "Invalid DAI interface format\n"); - return -EINVAL; - } - - aic3262_write(codec, ASI1_BUS_FMT, iface_reg); - - return 0; -} - /* *---------------------------------------------------------------------------- * Function : aic3262_set_bias_level @@ -3478,7 +3219,7 @@ static int aic3262_set_bias_level(struct snd_soc_codec *codec, static int aic3262_suspend(struct snd_soc_codec *codec, pm_message_t state) { struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); - + DBG(KERN_INFO "#%s: Invoked..\n", __func__); if (aic3262) disable_irq(aic3262->irq); @@ -3501,21 +3242,25 @@ static int aic3262_resume(struct snd_soc_codec *codec) int ret = 0; struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec); u8 *cache = codec->reg_cache; + DBG(KERN_INFO "#%s: Invoked..\n", __func__); ret = aic3262_change_page(codec, 0); if (ret) return ret; - +#if defined(EN_REG_CACHE) /* Sync reg_cache with the hardware */ for (i = 0; i < ARRAY_SIZE(aic3262_reg); i++) { data[0] = i % 128; data[1] = cache[i]; - +#if defined(LOCAL_REG_ACCESS) + codec->hw_write(codec->control_data, data, 2); +#else ret = snd_soc_write(codec, data[0], data[1]); if (ret) break; +#endif } - +#endif if (!ret) { aic3262_change_page(codec, 0); aic3262_set_bias_level(codec, SND_SOC_BIAS_ON); @@ -3525,6 +3270,24 @@ static int aic3262_resume(struct snd_soc_codec *codec) } return ret; } +/* + *---------------------------------------------------------------------------- + * Function : aic3262_hw_read + * Purpose : This is a low level harware read function. + * + *---------------------------------------------------------------------------- + */ +unsigned int aic3262_hw_read(struct snd_soc_codec *codec, unsigned int count) +{ + struct i2c_client *client = codec->control_data; + unsigned int buf; + + if (count > (sizeof(unsigned int))) + return 0; + + i2c_master_recv(client, (char *)&buf, count); + return buf; +} /* * aic3262_jack_handler @@ -3541,14 +3304,16 @@ static irqreturn_t aic3262_jack_handler(int irq, void *data) DBG("%s++\n", __func__); + aic3262_change_page(codec, 0); + /* Read the Jack Status Register*/ - value = snd_soc_read(codec, STICKY_FLAG2); + value = aic3262_read(codec, STICKY_FLAG2); DBG(KERN_INFO "reg44 0x%x\n", value); - value = snd_soc_read(codec, INT_FLAG2); + value = aic3262_read(codec, INT_FLAG2); DBG("reg46 0x%x\n", value); - value = snd_soc_read(codec, DAC_FLAG_R1); + value = aic3262_read(codec, DAC_FLAG_R1); DBG("reg37 0x%x\n", value); micbits = value & DAC_FLAG_MIC_MASKBITS; @@ -3558,26 +3323,30 @@ static irqreturn_t aic3262_jack_handler(int irq, void *data) DBG("hsbits 0x%x\n", hsbits); /* sleep for debounce time */ - msleep(aic3262->pdata->debounce_time_ms); + /*msleep(aic3262->pdata->debounce_time_ms);*/ /* No Headphone or Headset*/ if (!micbits && !hsbits) { + DBG("no headset/headphone\n"); snd_soc_jack_report(aic3262->headset_jack, 0, SND_JACK_HEADSET); } /* Headphone Detected */ if ((micbits == DAC_FLAG_R1_NOMIC) || (hsbits)) { + DBG("headphone\n"); snd_soc_jack_report(aic3262->headset_jack, SND_JACK_HEADPHONE, SND_JACK_HEADSET); } /* Headset Detected - only with capless */ if (micbits == DAC_FLAG_R1_MIC) { + DBG("headset\n"); snd_soc_jack_report(aic3262->headset_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); } + DBG("%s--\n", __func__); return IRQ_HANDLED; } @@ -3670,18 +3439,33 @@ static int aic3262_probe(struct snd_soc_codec *codec) DBG(KERN_INFO "#%s: Invoked..\n", __func__); +#if defined(EN_REG_CACHE) + codec->reg_cache = + kmemdup(aic3262_reg, sizeof(aic3262_reg), GFP_KERNEL); + + if (!codec->reg_cache) { + printk(KERN_ERR "aic3262: kmemdup failed\n"); + return -ENOMEM; + } +#else /* Setting cache bypass - not to overwrite the cache registers, Codec registers have 4 pages which is not handled in the common cache code properly - bypass it in write value and save it using separate call*/ codec->cache_bypass = 1; +#endif +#if defined(LOCAL_REG_ACCESS) + codec->control_data = aic3262->control_data; + codec->hw_write = (hw_write_t) aic3262_write__; + codec->hw_read = aic3262_hw_read; +#else ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } - +#endif ret = reg_def_conf(codec); if (ret != 0) { printk(KERN_ERR "Failed to init TI codec: %d\n", ret); @@ -3700,11 +3484,11 @@ static int aic3262_probe(struct snd_soc_codec *codec) dev_err(codec->dev, "Failed to request IRQ: %d\n", ret); return ret; } else - printk(KERN_INFO + DBG(KERN_INFO "#%s: irq Registration for IRQ %d done..\n", __func__, aic3262->irq); } else { - printk(KERN_INFO "#%s: I2C IRQ Configuration is Wrong. \ + DBG(KERN_INFO "#%s: I2C IRQ Configuration is Wrong. \ Please check it..\n", __func__); } @@ -3729,6 +3513,7 @@ static int aic3262_probe(struct snd_soc_codec *codec) aic3262_add_multiconfig_controls(codec); #endif + DBG(KERN_INFO "#%s: done..\n", __func__); return ret; } @@ -3763,10 +3548,15 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3262 = { .suspend = aic3262_suspend, .resume = aic3262_resume, .set_bias_level = aic3262_set_bias_level, +#if defined(LOCAL_REG_ACCESS) + .read = aic3262_read, + .write = aic3262_write, +#endif +#if !defined(EN_REG_CACHE) .reg_cache_size = ARRAY_SIZE(aic3262_reg), - .reg_word_size = sizeof(u16), + .reg_word_size = sizeof(u8), .reg_cache_default = aic3262_reg, - .compress_type = SND_SOC_FLAT_COMPRESSION, +#endif }; @@ -3802,6 +3592,9 @@ static __devinit int aic3262_codec_probe(struct i2c_client *i2c, } i2c_set_clientdata(i2c, aic3262); +#if defined(LOCAL_REG_ACCESS) + aic3262->control_data = i2c; +#endif aic3262->control_type = SND_SOC_I2C; aic3262->irq = i2c->irq; aic3262->pdata = i2c->dev.platform_data; @@ -3828,7 +3621,7 @@ static __devinit int aic3262_codec_probe(struct i2c_client *i2c, if (ret < 0) kfree(aic3262); - + DBG(KERN_INFO "#%s: Done ret %d\n", __func__, ret); return ret; } @@ -3859,7 +3652,7 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic3262_id); static struct i2c_driver tlv320aic3262_i2c_driver = { .driver = { - .name = "tlv320aic3262", + .name = "aic3262-codec", .owner = THIS_MODULE, }, .probe = aic3262_codec_probe, diff --git a/sound/soc/codecs/tlv320aic326x.h b/sound/soc/codecs/tlv320aic326x.h index e6e67350a5e8..259ecb110787 100755 --- a/sound/soc/codecs/tlv320aic326x.h +++ b/sound/soc/codecs/tlv320aic326x.h @@ -28,11 +28,17 @@ /* Enable this macro allow for different ASI formats */ /*#define ASI_MULTI_FMT*/ #undef ASI_MULTI_FMT + /* Enable register caching on write */ -#define EN_REG_CACHE +#define EN_REG_CACHE 1 #define MULTIBYTE_CONFIG_SUPPORT +/*Setting all codec reg/write locally*/ +/* This definition is added as the snd_ direct call are +result some issue with cache. Common code doesnot support +page, so fix that before commenting this line*/ +#define LOCAL_REG_ACCESS 1 /* Macro enables or disables support for miniDSP in the driver */ /* Enable the AIC3262_TiLoad macro first before enabling these macros */ @@ -57,7 +63,7 @@ #define AIC3262_MULTI_I2S 1 /* Driver Debug Messages Enabled */ -#define DEBUG +/*#define DEBUG*/ #ifdef DEBUG #define DBG(x...) printk(x) @@ -519,6 +525,9 @@ struct aic3262_priv { u8 adc_clkin_option; int irq; struct snd_soc_jack *headset_jack; +#if defined(LOCAL_REG_ACCESS) + void *control_data; +#endif }; /* diff --git a/sound/soc/tegra/tegra_aic326x.c b/sound/soc/tegra/tegra_aic326x.c index 635756379f23..77cc53ad9090 100644 --- a/sound/soc/tegra/tegra_aic326x.c +++ b/sound/soc/tegra/tegra_aic326x.c @@ -588,11 +588,11 @@ static int tegra_aic326x_bt_voice_call_hw_params( static void tegra_aic326x_bt_voice_call_shutdown( struct snd_pcm_substream *substream) { +#ifndef CONFIG_ARCH_TEGRA_2x_SOC struct snd_soc_pcm_runtime *rtd = substream->private_data; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(rtd->codec->card); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC machine->codec_info[BT_SCO].rate = 0; machine->codec_info[BT_SCO].channels = 0; #endif @@ -915,7 +915,7 @@ static struct snd_soc_dai_link tegra_aic326x_dai[] = { .codec_dai_name = "dit-hifi", .ops = &tegra_aic326x_bt_ops, }, - /*[DAI_LINK_VOICE_CALL] = { + [DAI_LINK_VOICE_CALL] = { .name = "VOICE CALL", .stream_name = "VOICE CALL PCM", .codec_name = "aic3262-codec.4-0018", @@ -923,7 +923,7 @@ static struct snd_soc_dai_link tegra_aic326x_dai[] = { .cpu_dai_name = "dit-hifi", .codec_dai_name = "aic3262-asi2", .ops = &tegra_aic326x_voice_call_ops, - },*/ + }, /* TODO - enabling this cause binding issue- figure out */ /*[DAI_LINK_BT_VOICE_CALL] = { .name = "BT VOICE CALL", @@ -971,16 +971,6 @@ static __devinit int tegra_aic326x_driver_probe(struct platform_device *pdev) platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); -#ifdef CONFIG_SWITCH - /* Add h2w switch class support */ - ret = switch_dev_register(&aic326x_wired_switch_dev); - if (ret < 0) { - dev_err(&pdev->dev, "not able to register switch device %d\n", - ret); - goto err_fini_utils; - } -#endif - #ifndef CONFIG_ARCH_TEGRA_2x_SOC for (i = 0; i < NUM_I2S_DEVICES ; i++) machine->codec_info[i].i2s_id = pdata->audio_port_id[i]; @@ -999,15 +989,28 @@ static __devinit int tegra_aic326x_driver_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_switch_unregister; + goto err_fini_utils; } - return 0; + if (!card->instantiated) { + dev_err(&pdev->dev, "No TI AIC3262 codec\n"); + goto err_unregister_card; + } -err_switch_unregister: #ifdef CONFIG_SWITCH - switch_dev_unregister(&aic326x_wired_switch_dev); + /* Add h2w switch class support */ + ret = switch_dev_register(&aic326x_wired_switch_dev); + if (ret < 0) { + dev_err(&pdev->dev, "not able to register switch device %d\n", + ret); + goto err_unregister_card; + } #endif + + return 0; + +err_unregister_card: + snd_soc_unregister_card(card); err_fini_utils: tegra_asoc_utils_fini(&machine->util_data); err_free_machine: diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index bc9e3104b605..2405a0fe1320 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -81,7 +81,6 @@ static int tegra_wm8753_hw_params(struct snd_pcm_substream *substream, struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, i2s_daifmt; int err; - srate = params_rate(params); switch (srate) { case 8000: @@ -571,6 +570,7 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev) struct tegra_wm8753_platform_data *pdata; int ret; + pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No platform data supplied\n"); @@ -600,11 +600,16 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev) goto err_fini_utils; } + if (!card->instantiated) { + dev_err(&pdev->dev, "No WM8753 codec\n"); + goto err_unregister_card; + } + #ifdef CONFIG_SWITCH /* Add h2w swith class support */ ret = switch_dev_register(&wired_switch_dev); if (ret < 0) { - dev_err(&pdev->dev, "not able to register switch device\n", + dev_err(&pdev->dev, "not able to register switch device %d\n", ret); goto err_unregister_card; } |