Merge branch 'for-2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc...
authorTakashi Iwai <tiwai@suse.de>
Tue, 27 Apr 2010 13:35:59 +0000 (15:35 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 27 Apr 2010 13:35:59 +0000 (15:35 +0200)
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tlv320dac33.c

index 556123b4059cdc137ecb106f0e0e4ca03fbf1561..584bc1e67f763dd892c6af4b7ae8874c52b2220d 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
 #include <linux/platform_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 
 #include "tlv320aic3x.h"
 
-#define AIC3X_VERSION "0.2"
+#define AIC3X_NUM_SUPPLIES     4
+static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
+       "IOVDD",        /* I/O Voltage */
+       "DVDD",         /* Digital Core Voltage */
+       "AVDD",         /* Analog DAC Voltage */
+       "DRVDD",        /* ADC Analog and Output Driver Voltage */
+};
 
 /* codec private data */
 struct aic3x_priv {
        struct snd_soc_codec codec;
+       struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
        unsigned int sysclk;
        int master;
 };
@@ -999,7 +1007,8 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-               /* all power is driven by DAPM system */
+               break;
+       case SND_SOC_BIAS_PREPARE:
                if (aic3x->master) {
                        /* enable pll */
                        reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
@@ -1007,48 +1016,9 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
                                    reg | PLL_ENABLE);
                }
                break;
-       case SND_SOC_BIAS_PREPARE:
-               break;
        case SND_SOC_BIAS_STANDBY:
-               /*
-                * all power is driven by DAPM system,
-                * so output power is safe if bypass was set
-                */
-               if (aic3x->master) {
-                       /* disable pll */
-                       reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
-                       aic3x_write(codec, AIC3X_PLL_PROGA_REG,
-                                   reg & ~PLL_ENABLE);
-               }
-               break;
+               /* fall through and disable pll */
        case SND_SOC_BIAS_OFF:
-               /* force all power off */
-               reg = aic3x_read_reg_cache(codec, LINE1L_2_LADC_CTRL);
-               aic3x_write(codec, LINE1L_2_LADC_CTRL, reg & ~LADC_PWR_ON);
-               reg = aic3x_read_reg_cache(codec, LINE1R_2_RADC_CTRL);
-               aic3x_write(codec, LINE1R_2_RADC_CTRL, reg & ~RADC_PWR_ON);
-
-               reg = aic3x_read_reg_cache(codec, DAC_PWR);
-               aic3x_write(codec, DAC_PWR, reg & ~(LDAC_PWR_ON | RDAC_PWR_ON));
-
-               reg = aic3x_read_reg_cache(codec, HPLOUT_CTRL);
-               aic3x_write(codec, HPLOUT_CTRL, reg & ~HPLOUT_PWR_ON);
-               reg = aic3x_read_reg_cache(codec, HPROUT_CTRL);
-               aic3x_write(codec, HPROUT_CTRL, reg & ~HPROUT_PWR_ON);
-
-               reg = aic3x_read_reg_cache(codec, HPLCOM_CTRL);
-               aic3x_write(codec, HPLCOM_CTRL, reg & ~HPLCOM_PWR_ON);
-               reg = aic3x_read_reg_cache(codec, HPRCOM_CTRL);
-               aic3x_write(codec, HPRCOM_CTRL, reg & ~HPRCOM_PWR_ON);
-
-               reg = aic3x_read_reg_cache(codec, MONOLOPM_CTRL);
-               aic3x_write(codec, MONOLOPM_CTRL, reg & ~MONOLOPM_PWR_ON);
-
-               reg = aic3x_read_reg_cache(codec, LLOPM_CTRL);
-               aic3x_write(codec, LLOPM_CTRL, reg & ~LLOPM_PWR_ON);
-               reg = aic3x_read_reg_cache(codec, RLOPM_CTRL);
-               aic3x_write(codec, RLOPM_CTRL, reg & ~RLOPM_PWR_ON);
-
                if (aic3x->master) {
                        /* disable pll */
                        reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
@@ -1308,6 +1278,9 @@ static int aic3x_unregister(struct aic3x_priv *aic3x)
        snd_soc_unregister_dai(&aic3x_dai);
        snd_soc_unregister_codec(&aic3x->codec);
 
+       regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
+       regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
+
        kfree(aic3x);
        aic3x_codec = NULL;
 
@@ -1329,6 +1302,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
 {
        struct snd_soc_codec *codec;
        struct aic3x_priv *aic3x;
+       int ret, i;
 
        aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
        if (aic3x == NULL) {
@@ -1344,7 +1318,30 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, aic3x);
 
+       for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
+               aic3x->supplies[i].supply = aic3x_supply_names[i];
+
+       ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
+                                aic3x->supplies);
+       if (ret != 0) {
+               dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+               goto err_get;
+       }
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
+                                   aic3x->supplies);
+       if (ret != 0) {
+               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+               goto err_enable;
+       }
+
        return aic3x_register(codec);
+
+err_enable:
+       regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
+err_get:
+       kfree(aic3x);
+       return ret;
 }
 
 static int aic3x_i2c_remove(struct i2c_client *client)
index 824bb354ebc9757995bd64201e0b6b1345c17503..3eddaec728c1a864aeb1d36ce7d9f765e734e678 100644 (file)
 
 #define LATENCY_TIME_MS                20
 
+#define MODE7_LTHR             10
+#define MODE7_UTHR             (DAC33_BUFFER_SIZE_SAMPLES - 10)
+
+#define BURST_BASEFREQ_HZ      49152000
+
+#define SAMPLES_TO_US(rate, samples) \
+       (1000000000 / ((rate * 1000) / samples))
+
+#define US_TO_SAMPLES(rate, us) \
+       (rate / (1000000 / us))
+
+
 static struct snd_soc_codec *tlv320dac33_codec;
 
 enum dac33_state {
@@ -92,9 +104,18 @@ struct tlv320dac33_priv {
        enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
        unsigned int nsample;           /* burst read amount from host */
        u8 burst_bclkdiv;               /* BCLK divider value in burst mode */
+       unsigned int burst_rate;        /* Interface speed in Burst modes */
 
        int keep_bclk;                  /* Keep the BCLK continuously running
                                         * in FIFO modes */
+       spinlock_t lock;
+       unsigned long long t_stamp1;    /* Time stamp for FIFO modes to */
+       unsigned long long t_stamp2;    /* calculate the FIFO caused delay */
+
+       unsigned int mode1_us_burst;    /* Time to burst read n number of
+                                        * samples */
+       unsigned int mode7_us_to_lthr;  /* Time to reach lthr from uthr */
+
        enum dac33_state state;
 };
 
@@ -384,10 +405,14 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
                return 0;
 
        if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
-           ucontrol->value.integer.value[0] > dac33->nsample_max)
+           ucontrol->value.integer.value[0] > dac33->nsample_max) {
                ret = -EINVAL;
-       else
+       } else {
                dac33->nsample = ucontrol->value.integer.value[0];
+               /* Re calculate the burst time */
+               dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
+                                                     dac33->nsample);
+       }
 
        return ret;
 }
@@ -557,13 +582,34 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
        switch (dac33->fifo_mode) {
        case DAC33_FIFO_MODE1:
                dac33_write16(codec, DAC33_NSAMPLE_MSB,
-                               DAC33_THRREG(dac33->nsample));
+                       DAC33_THRREG(dac33->nsample + dac33->alarm_threshold));
+
+               /* Take the timestamps */
+               spin_lock_irq(&dac33->lock);
+               dac33->t_stamp2 = ktime_to_us(ktime_get());
+               dac33->t_stamp1 = dac33->t_stamp2;
+               spin_unlock_irq(&dac33->lock);
+
                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));
+               dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
                break;
        case DAC33_FIFO_MODE7:
+               /* Take the timestamp */
+               spin_lock_irq(&dac33->lock);
+               dac33->t_stamp1 = ktime_to_us(ktime_get());
+               /* Move back the timestamp with drain time */
+               dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
+               spin_unlock_irq(&dac33->lock);
+
                dac33_write16(codec, DAC33_PREFILL_MSB,
-                               DAC33_THRREG(10));
+                               DAC33_THRREG(MODE7_LTHR));
+
+               /* Enable Upper Threshold IRQ */
+               dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
                break;
        default:
                dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
@@ -580,6 +626,11 @@ static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
 
        switch (dac33->fifo_mode) {
        case DAC33_FIFO_MODE1:
+               /* Take the timestamp */
+               spin_lock_irq(&dac33->lock);
+               dac33->t_stamp2 = ktime_to_us(ktime_get());
+               spin_unlock_irq(&dac33->lock);
+
                dac33_write16(codec, DAC33_NSAMPLE_MSB,
                                DAC33_THRREG(dac33->nsample));
                break;
@@ -632,7 +683,13 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
        struct snd_soc_codec *codec = dev;
        struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
 
-       queue_work(dac33->dac33_wq, &dac33->work);
+       spin_lock(&dac33->lock);
+       dac33->t_stamp1 = ktime_to_us(ktime_get());
+       spin_unlock(&dac33->lock);
+
+       /* Do not schedule the workqueue in Mode7 */
+       if (dac33->fifo_mode != DAC33_FIFO_MODE7)
+               queue_work(dac33->dac33_wq, &dac33->work);
 
        return IRQ_HANDLED;
 }
@@ -782,11 +839,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
        case DAC33_FIFO_MODE1:
                dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
                            DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
-               dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
                break;
        case DAC33_FIFO_MODE7:
-               /* Disable all interrupts */
-               dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
+               dac33_write(codec, DAC33_FIFO_IRQ_MODE_A,
+                       DAC33_UTM(DAC33_FIFO_IRQ_MODE_LEVEL));
                break;
        default:
                /* in FIFO bypass mode, the interrupts are not used */
@@ -864,10 +920,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
                 * Configure the threshold levels, and leave 10 sample space
                 * at the bottom, and also at the top of the FIFO
                 */
-               dac33_write16(codec, DAC33_UTHR_MSB,
-                       DAC33_THRREG(DAC33_BUFFER_SIZE_SAMPLES - 10));
-               dac33_write16(codec, DAC33_LTHR_MSB,
-                       DAC33_THRREG(10));
+               dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(MODE7_UTHR));
+               dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR));
                break;
        default:
                break;
@@ -886,6 +940,10 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
        struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
        unsigned int nsample_limit;
 
+       /* In bypass mode we don't need to calculate */
+       if (!dac33->fifo_mode)
+               return;
+
        /* Number of samples (16bit, stereo) in one period */
        dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
 
@@ -919,6 +977,24 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
 
        if (dac33->nsample > dac33->nsample_max)
                dac33->nsample = dac33->nsample_max;
+
+       switch (dac33->fifo_mode) {
+       case DAC33_FIFO_MODE1:
+               dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
+                                                     dac33->nsample);
+               dac33->t_stamp1 = 0;
+               dac33->t_stamp2 = 0;
+               break;
+       case DAC33_FIFO_MODE7:
+               dac33->mode7_us_to_lthr =
+                                       SAMPLES_TO_US(substream->runtime->rate,
+                                               MODE7_UTHR - MODE7_LTHR + 1);
+               dac33->t_stamp1 = 0;
+               break;
+       default:
+               break;
+       }
+
 }
 
 static int dac33_pcm_prepare(struct snd_pcm_substream *substream,
@@ -963,6 +1039,151 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
        return ret;
 }
 
+static snd_pcm_sframes_t dac33_dai_delay(
+                       struct snd_pcm_substream *substream,
+                       struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_codec *codec = socdev->card->codec;
+       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       unsigned long long t0, t1, t_now;
+       unsigned int time_delta;
+       int samples_out, samples_in, samples;
+       snd_pcm_sframes_t delay = 0;
+
+       switch (dac33->fifo_mode) {
+       case DAC33_FIFO_BYPASS:
+               break;
+       case DAC33_FIFO_MODE1:
+               spin_lock(&dac33->lock);
+               t0 = dac33->t_stamp1;
+               t1 = dac33->t_stamp2;
+               spin_unlock(&dac33->lock);
+               t_now = ktime_to_us(ktime_get());
+
+               /* We have not started to fill the FIFO yet, delay is 0 */
+               if (!t1)
+                       goto out;
+
+               if (t0 > t1) {
+                       /*
+                        * Phase 1:
+                        * After Alarm threshold, and before nSample write
+                        */
+                       time_delta = t_now - t0;
+                       samples_out = time_delta ? US_TO_SAMPLES(
+                                               substream->runtime->rate,
+                                               time_delta) : 0;
+
+                       if (likely(dac33->alarm_threshold > samples_out))
+                               delay = dac33->alarm_threshold - samples_out;
+                       else
+                               delay = 0;
+               } else if ((t_now - t1) <= dac33->mode1_us_burst) {
+                       /*
+                        * Phase 2:
+                        * After nSample write (during burst operation)
+                        */
+                       time_delta = t_now - t0;
+                       samples_out = time_delta ? US_TO_SAMPLES(
+                                               substream->runtime->rate,
+                                               time_delta) : 0;
+
+                       time_delta = t_now - t1;
+                       samples_in = time_delta ? US_TO_SAMPLES(
+                                               dac33->burst_rate,
+                                               time_delta) : 0;
+
+                       samples = dac33->alarm_threshold;
+                       samples += (samples_in - samples_out);
+
+                       if (likely(samples > 0))
+                               delay = samples;
+                       else
+                               delay = 0;
+               } else {
+                       /*
+                        * Phase 3:
+                        * After burst operation, before next alarm threshold
+                        */
+                       time_delta = t_now - t0;
+                       samples_out = time_delta ? US_TO_SAMPLES(
+                                               substream->runtime->rate,
+                                               time_delta) : 0;
+
+                       samples_in = dac33->nsample;
+                       samples = dac33->alarm_threshold;
+                       samples += (samples_in - samples_out);
+
+                       if (likely(samples > 0))
+                               delay = samples > DAC33_BUFFER_SIZE_SAMPLES ?
+                                       DAC33_BUFFER_SIZE_SAMPLES : samples;
+                       else
+                               delay = 0;
+               }
+               break;
+       case DAC33_FIFO_MODE7:
+               spin_lock(&dac33->lock);
+               t0 = dac33->t_stamp1;
+               spin_unlock(&dac33->lock);
+               t_now = ktime_to_us(ktime_get());
+
+               /* We have not started to fill the FIFO yet, delay is 0 */
+               if (!t0)
+                       goto out;
+
+               if (t_now <= t0) {
+                       /*
+                        * Either the timestamps are messed or equal. Report
+                        * maximum delay
+                        */
+                       delay = MODE7_UTHR;
+                       goto out;
+               }
+
+               time_delta = t_now - t0;
+               if (time_delta <= dac33->mode7_us_to_lthr) {
+                       /*
+                       * Phase 1:
+                       * After burst (draining phase)
+                       */
+                       samples_out = US_TO_SAMPLES(
+                                       substream->runtime->rate,
+                                       time_delta);
+
+                       if (likely(MODE7_UTHR > samples_out))
+                               delay = MODE7_UTHR - samples_out;
+                       else
+                               delay = 0;
+               } else {
+                       /*
+                       * Phase 2:
+                       * During burst operation
+                       */
+                       time_delta = time_delta - dac33->mode7_us_to_lthr;
+
+                       samples_out = US_TO_SAMPLES(
+                                       substream->runtime->rate,
+                                       time_delta);
+                       samples_in = US_TO_SAMPLES(
+                                       dac33->burst_rate,
+                                       time_delta);
+                       delay = MODE7_LTHR + samples_in - samples_out;
+
+                       if (unlikely(delay > MODE7_UTHR))
+                               delay = MODE7_UTHR;
+               }
+               break;
+       default:
+               dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
+                                                       dac33->fifo_mode);
+               break;
+       }
+out:
+       return delay;
+}
+
 static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
@@ -1174,6 +1395,7 @@ static struct snd_soc_dai_ops dac33_dai_ops = {
        .hw_params      = dac33_hw_params,
        .prepare        = dac33_pcm_prepare,
        .trigger        = dac33_pcm_trigger,
+       .delay          = dac33_dai_delay,
        .set_sysclk     = dac33_set_dai_sysclk,
        .set_fmt        = dac33_set_dai_fmt,
 };
@@ -1214,6 +1436,7 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
 
        mutex_init(&codec->mutex);
        mutex_init(&dac33->mutex);
+       spin_lock_init(&dac33->lock);
        INIT_LIST_HEAD(&codec->dapm_widgets);
        INIT_LIST_HEAD(&codec->dapm_paths);
 
@@ -1238,9 +1461,12 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
 
        dac33->power_gpio = pdata->power_gpio;
        dac33->burst_bclkdiv = pdata->burst_bclkdiv;
+       /* Pre calculate the burst rate */
+       dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
        dac33->keep_bclk = pdata->keep_bclk;
        dac33->irq = client->irq;
        dac33->nsample = NSAMPLE_MAX;
+       dac33->nsample_max = NSAMPLE_MAX;
        /* Disable FIFO use by default */
        dac33->fifo_mode = DAC33_FIFO_BYPASS;