aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/twl4030.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-11-23 06:45:05 -0500
committerTakashi Iwai <tiwai@suse.de>2010-11-23 06:45:05 -0500
commit2ab46c9390e74368a38ddb5aa525124518df8b69 (patch)
tree631e686fb11709add69f07b4fd1e5aaa10f232de /sound/soc/codecs/twl4030.c
parent9e18e1869f5ebac69f0d881fe97a198ebc0834db (diff)
parent5b3b0fa8fb0db9645b56361cdc9a9d0ddbc35e4d (diff)
Merge branch 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6 into topic/asoc
Conflicts: sound/soc/codecs/tpa6130a2.c
Diffstat (limited to 'sound/soc/codecs/twl4030.c')
-rw-r--r--sound/soc/codecs/twl4030.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index f4602e8b67cc..50d3caf1191c 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -233,6 +233,16 @@ static int twl4030_write(struct snd_soc_codec *codec,
233 return 0; 233 return 0;
234} 234}
235 235
236static inline void twl4030_wait_ms(int time)
237{
238 if (time < 60) {
239 time *= 1000;
240 usleep_range(time, time + 500);
241 } else {
242 msleep(time);
243 }
244}
245
236static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 246static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
237{ 247{
238 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 248 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -338,10 +348,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
338 twl4030_write(codec, TWL4030_REG_ANAMICL, 348 twl4030_write(codec, TWL4030_REG_ANAMICL,
339 reg | TWL4030_CNCL_OFFSET_START); 349 reg | TWL4030_CNCL_OFFSET_START);
340 350
341 /* wait for offset cancellation to complete */ 351 /*
352 * Wait for offset cancellation to complete.
353 * Since this takes a while, do not slam the i2c.
354 * Start polling the status after ~20ms.
355 */
356 msleep(20);
342 do { 357 do {
343 /* this takes a little while, so don't slam i2c */ 358 usleep_range(1000, 2000);
344 udelay(2000);
345 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, 359 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
346 TWL4030_REG_ANAMICL); 360 TWL4030_REG_ANAMICL);
347 } while ((i++ < 100) && 361 } while ((i++ < 100) &&
@@ -725,9 +739,12 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
725 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 739 /* Base values for ramp delay calculation: 2^19 - 2^26 */
726 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 740 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
727 8388608, 16777216, 33554432, 67108864}; 741 8388608, 16777216, 33554432, 67108864};
742 unsigned int delay;
728 743
729 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); 744 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
730 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 745 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
746 delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
747 twl4030->sysclk) + 1;
731 748
732 /* Enable external mute control, this dramatically reduces 749 /* Enable external mute control, this dramatically reduces
733 * the pop-noise */ 750 * the pop-noise */
@@ -751,16 +768,14 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
751 hs_pop |= TWL4030_RAMP_EN; 768 hs_pop |= TWL4030_RAMP_EN;
752 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 769 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
753 /* Wait ramp delay time + 1, so the VMID can settle */ 770 /* Wait ramp delay time + 1, so the VMID can settle */
754 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 771 twl4030_wait_ms(delay);
755 twl4030->sysclk) + 1);
756 } else { 772 } else {
757 /* Headset ramp-down _not_ according to 773 /* Headset ramp-down _not_ according to
758 * the TRM, but in a way that it is working */ 774 * the TRM, but in a way that it is working */
759 hs_pop &= ~TWL4030_RAMP_EN; 775 hs_pop &= ~TWL4030_RAMP_EN;
760 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 776 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
761 /* Wait ramp delay time + 1, so the VMID can settle */ 777 /* Wait ramp delay time + 1, so the VMID can settle */
762 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 778 twl4030_wait_ms(delay);
763 twl4030->sysclk) + 1);
764 /* Bypass the reg_cache to mute the headset */ 779 /* Bypass the reg_cache to mute the headset */
765 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 780 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
766 hs_gain & (~0x0f), 781 hs_gain & (~0x0f),
@@ -835,7 +850,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
835 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); 850 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
836 851
837 if (twl4030->digimic_delay) 852 if (twl4030->digimic_delay)
838 mdelay(twl4030->digimic_delay); 853 twl4030_wait_ms(twl4030->digimic_delay);
839 return 0; 854 return 0;
840} 855}
841 856
@@ -2258,9 +2273,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2258 2273
2259static int twl4030_soc_remove(struct snd_soc_codec *codec) 2274static int twl4030_soc_remove(struct snd_soc_codec *codec)
2260{ 2275{
2276 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2277
2261 /* Reset registers to their chip default before leaving */ 2278 /* Reset registers to their chip default before leaving */
2262 twl4030_reset_registers(codec); 2279 twl4030_reset_registers(codec);
2263 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2280 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2281 kfree(twl4030);
2264 return 0; 2282 return 0;
2265} 2283}
2266 2284
@@ -2292,10 +2310,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2292 2310
2293static int __devexit twl4030_codec_remove(struct platform_device *pdev) 2311static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2294{ 2312{
2295 struct twl4030_priv *twl4030 = dev_get_drvdata(&pdev->dev);
2296
2297 snd_soc_unregister_codec(&pdev->dev); 2313 snd_soc_unregister_codec(&pdev->dev);
2298 kfree(twl4030);
2299 return 0; 2314 return 0;
2300} 2315}
2301 2316