Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb7b7696 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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
Loading
Loading
Loading
Loading
+39 −42
Original line number Diff line number Diff line
@@ -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)
+238 −12
Original line number Diff line number Diff line
@@ -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,6 +683,12 @@ 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);

	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;