[alsa-devel] [PATCH 0/2] ASoC: twl4030/tlv320dac33: convert to use usleep_range
Hello,
remove the long busy loop delays from the drivers, and replace it with more civilized usleep_range or in case of twl4030 msleep (when the needed delay is really long)
--- Peter Ujfalusi (2): ASoC: tlv320dac33: Use usleep_range for delays ASoC: TWL4030: Use usleep_range when appropriate
sound/soc/codecs/tlv320dac33.c | 10 ++++++---- sound/soc/codecs/twl4030.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 11 deletions(-)
Switch to use the more precise usleep_range instead of msleep(). Replace the udelay with usleep_range to remove the busy loop waiting.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/tlv320dac33.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 58349dc..d251ff5 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -669,6 +669,7 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec, static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) { struct snd_soc_codec *codec = dac33->codec; + unsigned int delay;
switch (dac33->fifo_mode) { case DAC33_FIFO_MODE1: @@ -684,8 +685,9 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) dac33_write16(codec, DAC33_PREFILL_MSB, DAC33_THRREG(dac33->alarm_threshold)); /* Enable Alarm Threshold IRQ with a delay */ - udelay(SAMPLES_TO_US(dac33->burst_rate, - dac33->alarm_threshold)); + delay = SAMPLES_TO_US(dac33->burst_rate, + dac33->alarm_threshold) + 1000; + usleep_range(delay, delay + 500); dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT); break; case DAC33_FIFO_MODE7: @@ -785,11 +787,11 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
static void dac33_oscwait(struct snd_soc_codec *codec) { - int timeout = 20; + int timeout = 60; u8 reg;
do { - msleep(1); + usleep_range(1000, 2000); dac33_read(codec, DAC33_INT_OSC_STATUS, ®); } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--); if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
On Fri, Oct 22, 2010 at 03:11:20PM +0300, Peter Ujfalusi wrote:
Switch to use the more precise usleep_range instead of msleep(). Replace the udelay with usleep_range to remove the busy loop waiting.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com
Acked-by: Mark Borwn broonie@opensource.wolfsonmicro.com
On Fri, 2010-10-22 at 08:32 -0700, Mark Brown wrote:
On Fri, Oct 22, 2010 at 03:11:20PM +0300, Peter Ujfalusi wrote:
Switch to use the more precise usleep_range instead of msleep(). Replace the udelay with usleep_range to remove the busy loop waiting.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com
Acked-by: Mark Borwn broonie@opensource.wolfsonmicro.com
Applied.
Thanks
Liam
Change the busy loop delays with usleep_range or msleep calls.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 33 ++++++++++++++++++++++++++------- 1 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index cbebec6..2ec330c 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, return 0; }
+static inline void twl4030_wait_ms(int time) +{ + if (time < 60) { + time *= 1000; + usleep_range(time, time + 500); + } else { + msleep(time); + } +} + static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) { struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); @@ -338,10 +348,18 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) twl4030_write(codec, TWL4030_REG_ANAMICL, reg | TWL4030_CNCL_OFFSET_START);
- /* wait for offset cancellation to complete */ + /* + * Wait for offset cancellation to complete. + * Since this takes a while, do not slam the i2c. + * The least amount of time is not known, but measurement showed, that + * the cancelation usually finishes 20 - 28 ms, when + * TWL4030_OFFSET_CNCL_SEL == 1. + * Start polling the status after 10ms. + */ + usleep_range(10000, 11000); do { /* this takes a little while, so don't slam i2c */ - udelay(2000); + usleep_range(1000, 2000); twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, TWL4030_REG_ANAMICL); } while ((i++ < 100) && @@ -725,9 +743,12 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) /* Base values for ramp delay calculation: 2^19 - 2^26 */ unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864}; + unsigned int delay;
hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); + delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / + twl4030->sysclk) + 1;
/* Enable external mute control, this dramatically reduces * the pop-noise */ @@ -751,16 +772,14 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) hs_pop |= TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Wait ramp delay time + 1, so the VMID can settle */ - mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / - twl4030->sysclk) + 1); + twl4030_wait_ms(delay); } else { /* Headset ramp-down _not_ according to * the TRM, but in a way that it is working */ hs_pop &= ~TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Wait ramp delay time + 1, so the VMID can settle */ - mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / - twl4030->sysclk) + 1); + twl4030_wait_ms(delay); /* Bypass the reg_cache to mute the headset */ twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f), @@ -835,7 +854,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w, struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
if (twl4030->digimic_delay) - mdelay(twl4030->digimic_delay); + twl4030_wait_ms(twl4030->digimic_delay); return 0; }
On Friday 22 October 2010 15:11:21 ext Peter Ujfalusi wrote:
Change the busy loop delays with usleep_range or msleep calls.
- /* wait for offset cancellation to complete */
- /*
* Wait for offset cancellation to complete.
* Since this takes a while, do not slam the i2c.
* The least amount of time is not known, but measurement showed, that
* the cancelation usually finishes 20 - 28 ms, when
* TWL4030_OFFSET_CNCL_SEL == 1.
* Start polling the status after 10ms.
*/
- usleep_range(10000, 11000); do { /* this takes a little while, so don't slam i2c */
I'll resend, and remove this comment, since it is not needed anymore...
udelay(2000);
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, TWL4030_REG_ANAMICL); } while ((i++ < 100) &&usleep_range(1000, 2000);
participants (3)
-
Liam Girdwood
-
Mark Brown
-
Peter Ujfalusi