Commit cb7b7696 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'for-2.6.35' of...

Merge branch 'for-2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6 into topic/asoc
parents b28528a1 07779fdd
......@@ -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>
......@@ -49,11 +50,18 @@
#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)
......
......@@ -50,6 +50,18 @@
#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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment