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

Commit 22a756ee authored by Mark Brown's avatar Mark Brown
Browse files

Merge branch 'for-2.6.37' into for-2.6.38

parents 839d271c 776065e3
Loading
Loading
Loading
Loading
+4 −6
Original line number Original line Diff line number Diff line
@@ -39,7 +39,6 @@ struct max98088_cdata {
};
};


struct max98088_priv {
struct max98088_priv {
       u8 reg_cache[M98088_REG_CNT];
       enum max98088_type devtype;
       enum max98088_type devtype;
       void *control_data;
       void *control_data;
       struct max98088_pdata *pdata;
       struct max98088_pdata *pdata;
@@ -1589,7 +1588,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,


static void max98088_sync_cache(struct snd_soc_codec *codec)
static void max98088_sync_cache(struct snd_soc_codec *codec)
{
{
       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
       u16 *reg_cache = codec->reg_cache;
       int i;
       int i;


       if (!codec->cache_sync)
       if (!codec->cache_sync)
@@ -1600,14 +1599,14 @@ static void max98088_sync_cache(struct snd_soc_codec *codec)
       /* write back cached values if they're writeable and
       /* write back cached values if they're writeable and
        * different from the hardware default.
        * different from the hardware default.
        */
        */
       for (i = 1; i < ARRAY_SIZE(max98088->reg_cache); i++) {
       for (i = 1; i < codec->driver->reg_cache_size; i++) {
               if (!max98088_access[i].writable)
               if (!max98088_access[i].writable)
                       continue;
                       continue;


               if (max98088->reg_cache[i] == max98088_reg[i])
               if (reg_cache[i] == max98088_reg[i])
                       continue;
                       continue;


               snd_soc_write(codec, i, max98088->reg_cache[i]);
               snd_soc_write(codec, i, reg_cache[i]);
       }
       }


       codec->cache_sync = 0;
       codec->cache_sync = 0;
@@ -1952,7 +1951,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
       int ret = 0;
       int ret = 0;


       codec->cache_sync = 1;
       codec->cache_sync = 1;
       memcpy(codec->reg_cache, max98088_reg, sizeof(max98088_reg));


       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
       if (ret != 0) {
       if (ret != 0) {
+5 −4
Original line number Original line Diff line number Diff line
@@ -40,7 +40,6 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
/* codec private data */
/* codec private data */
struct wm8523_priv {
struct wm8523_priv {
	enum snd_soc_control_type control_type;
	enum snd_soc_control_type control_type;
	u16 reg_cache[WM8523_REGISTER_COUNT];
	struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
	struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
	unsigned int sysclk;
	unsigned int sysclk;
	unsigned int rate_constraint_list[WM8523_NUM_RATES];
	unsigned int rate_constraint_list[WM8523_NUM_RATES];
@@ -314,6 +313,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
				 enum snd_soc_bias_level level)
				 enum snd_soc_bias_level level)
{
{
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
	u16 *reg_cache = codec->reg_cache;
	int ret, i;
	int ret, i;


	switch (level) {
	switch (level) {
@@ -344,7 +344,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
			/* Sync back default/cached values */
			/* Sync back default/cached values */
			for (i = WM8523_AIF_CTRL1;
			for (i = WM8523_AIF_CTRL1;
			     i < WM8523_MAX_REGISTER; i++)
			     i < WM8523_MAX_REGISTER; i++)
				snd_soc_write(codec, i, wm8523->reg_cache[i]);
				snd_soc_write(codec, i, reg_cache[i]);




			msleep(100);
			msleep(100);
@@ -414,6 +414,7 @@ static int wm8523_resume(struct snd_soc_codec *codec)
static int wm8523_probe(struct snd_soc_codec *codec)
static int wm8523_probe(struct snd_soc_codec *codec)
{
{
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
	u16 *reg_cache = codec->reg_cache;
	int ret, i;
	int ret, i;


	codec->hw_write = (hw_write_t)i2c_master_send;
	codec->hw_write = (hw_write_t)i2c_master_send;
@@ -470,8 +471,8 @@ static int wm8523_probe(struct snd_soc_codec *codec)
	}
	}


	/* Change some default settings - latch VU and enable ZC */
	/* Change some default settings - latch VU and enable ZC */
	wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
	reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
	wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
	reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;


	wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);


+5 −5
Original line number Original line Diff line number Diff line
@@ -40,7 +40,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
/* codec private data */
/* codec private data */
struct wm8741_priv {
struct wm8741_priv {
	enum snd_soc_control_type control_type;
	enum snd_soc_control_type control_type;
	u16 reg_cache[WM8741_REGISTER_COUNT];
	struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
	struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
	unsigned int sysclk;
	unsigned int sysclk;
	struct snd_pcm_hw_constraint_list *sysclk_constraints;
	struct snd_pcm_hw_constraint_list *sysclk_constraints;
@@ -422,6 +421,7 @@ static int wm8741_resume(struct snd_soc_codec *codec)
static int wm8741_probe(struct snd_soc_codec *codec)
static int wm8741_probe(struct snd_soc_codec *codec)
{
{
	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
	u16 *reg_cache = codec->reg_cache;
	int ret = 0;
	int ret = 0;


	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
@@ -437,10 +437,10 @@ static int wm8741_probe(struct snd_soc_codec *codec)
	}
	}


	/* Change some default settings - latch VU */
	/* Change some default settings - latch VU */
	wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
	reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
	wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
	reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
	wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
	reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
	wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
	reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;


	snd_soc_add_controls(codec, wm8741_snd_controls,
	snd_soc_add_controls(codec, wm8741_snd_controls,
			     ARRAY_SIZE(wm8741_snd_controls));
			     ARRAY_SIZE(wm8741_snd_controls));
+83 −143
Original line number Original line Diff line number Diff line
@@ -64,22 +64,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
 * are using 2 wire for device control, so we cache them instead.
 * are using 2 wire for device control, so we cache them instead.
 */
 */
static const u16 wm8753_reg[] = {
static const u16 wm8753_reg[] = {
	0x0008, 0x0000, 0x000a, 0x000a,
	0x0000, 0x0008, 0x0000, 0x000a,
	0x0033, 0x0000, 0x0007, 0x00ff,
	0x000a, 0x0033, 0x0000, 0x0007,
	0x00ff, 0x000f, 0x000f, 0x007b,
	0x00ff, 0x00ff, 0x000f, 0x000f,
	0x0000, 0x0032, 0x0000, 0x00c3,
	0x007b, 0x0000, 0x0032, 0x0000,
	0x00c3, 0x00c0, 0x0000, 0x0000,
	0x00c3, 0x00c3, 0x00c0, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0055,
	0x0005, 0x0050, 0x0055, 0x0050,
	0x0055, 0x0050, 0x0055, 0x0079,
	0x0079, 0x0079, 0x0079, 0x0079,
	0x0000, 0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000, 0x0000,
	0x0097, 0x0097, 0x0000, 0x0004,
	0x0055, 0x0005, 0x0050, 0x0055,
	0x0000, 0x0083, 0x0024, 0x01ba,
	0x0050, 0x0055, 0x0050, 0x0055,
	0x0000, 0x0083, 0x0024, 0x01ba,
	0x0079, 0x0079, 0x0079, 0x0079,
	0x0000, 0x0000, 0x0000
	0x0079, 0x0000, 0x0000, 0x0000,
	0x0000, 0x0097, 0x0097, 0x0000,
	0x0004, 0x0000, 0x0083, 0x0024,
	0x01ba, 0x0000, 0x0083, 0x0024,
	0x01ba, 0x0000, 0x0000, 0x0000
};
};


/* codec private data */
/* codec private data */
@@ -87,57 +87,10 @@ struct wm8753_priv {
	enum snd_soc_control_type control_type;
	enum snd_soc_control_type control_type;
	unsigned int sysclk;
	unsigned int sysclk;
	unsigned int pcmclk;
	unsigned int pcmclk;
	u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
	int dai_func;
	int dai_func;
};
};


/*
#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
 * read wm8753 register cache
 */
static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
	unsigned int reg)
{
	u16 *cache = codec->reg_cache;
	if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
		return -1;
	return cache[reg - 1];
}

/*
 * write wm8753 register cache
 */
static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
	unsigned int reg, unsigned int value)
{
	u16 *cache = codec->reg_cache;
	if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
		return;
	cache[reg - 1] = value;
}

/*
 * write to the WM8753 register space
 */
static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
	unsigned int value)
{
	u8 data[2];

	/* data is
	 *   D15..D9 WM8753 register offset
	 *   D8...D0 register data
	 */
	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
	data[1] = value & 0x00ff;

	wm8753_write_reg_cache(codec, reg, value);
	if (codec->hw_write(codec->control_data, data, 2) == 2)
		return 0;
	else
		return -EIO;
}

#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)


/*
/*
 * WM8753 Controls
 * WM8753 Controls
@@ -217,7 +170,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
	struct snd_ctl_elem_value *ucontrol)
{
{
	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
	int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
	int mode = snd_soc_read(codec, WM8753_IOCTL);


	ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
	ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
	return 0;
	return 0;
@@ -227,7 +180,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
	struct snd_ctl_elem_value *ucontrol)
{
{
	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
	int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
	int mode = snd_soc_read(codec, WM8753_IOCTL);
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);


	if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
	if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
@@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
	if (pll_id == WM8753_PLL1) {
	if (pll_id == WM8753_PLL1) {
		offset = 0;
		offset = 0;
		enable = 0x10;
		enable = 0x10;
		reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
		reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
	} else {
	} else {
		offset = 4;
		offset = 4;
		enable = 0x8;
		enable = 0x8;
		reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7;
		reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
	}
	}


	if (!freq_in || !freq_out) {
	if (!freq_in || !freq_out) {
		/* disable PLL  */
		/* disable PLL  */
		wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
		snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
		wm8753_write(codec, WM8753_CLOCK, reg);
		snd_soc_write(codec, WM8753_CLOCK, reg);
		return 0;
		return 0;
	} else {
	} else {
		u16 value = 0;
		u16 value = 0;
@@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
		/* set up N and K PLL divisor ratios */
		/* set up N and K PLL divisor ratios */
		/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
		/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
		value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
		value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
		wm8753_write(codec, WM8753_PLL1CTL2 + offset, value);
		snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);


		/* bits 8:0 = PLL_K[17:9] */
		/* bits 8:0 = PLL_K[17:9] */
		value = (pll_div.k & 0x03fe00) >> 9;
		value = (pll_div.k & 0x03fe00) >> 9;
		wm8753_write(codec, WM8753_PLL1CTL3 + offset, value);
		snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);


		/* bits 8:0 = PLL_K[8:0] */
		/* bits 8:0 = PLL_K[8:0] */
		value = pll_div.k & 0x0001ff;
		value = pll_div.k & 0x0001ff;
		wm8753_write(codec, WM8753_PLL1CTL4 + offset, value);
		snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);


		/* set PLL as input and enable */
		/* set PLL as input and enable */
		wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
		snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
			(pll_div.div2 << 3));
			(pll_div.div2 << 3));
		wm8753_write(codec, WM8753_CLOCK, reg | enable);
		snd_soc_write(codec, WM8753_CLOCK, reg | enable);
	}
	}
	return 0;
	return 0;
}
}
@@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
		unsigned int fmt)
		unsigned int fmt)
{
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct snd_soc_codec *codec = codec_dai->codec;
	u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
	u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;


	/* interface format */
	/* interface format */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
		return -EINVAL;
		return -EINVAL;
	}
	}


	wm8753_write(codec, WM8753_PCM, voice);
	snd_soc_write(codec, WM8753_PCM, voice);
	return 0;
	return 0;
}
}


@@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_codec *codec = rtd->codec;
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
	u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
	u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
	u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
	u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;


	/* bit size */
	/* bit size */
	switch (params_format(params)) {
	switch (params_format(params)) {
@@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
	/* sample rate */
	/* sample rate */
	if (params_rate(params) * 384 == wm8753->pcmclk)
	if (params_rate(params) * 384 == wm8753->pcmclk)
		srate |= 0x80;
		srate |= 0x80;
	wm8753_write(codec, WM8753_SRATE1, srate);
	snd_soc_write(codec, WM8753_SRATE1, srate);


	wm8753_write(codec, WM8753_PCM, voice);
	snd_soc_write(codec, WM8753_PCM, voice);
	return 0;
	return 0;
}
}


@@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
	struct snd_soc_codec *codec = codec_dai->codec;
	struct snd_soc_codec *codec = codec_dai->codec;
	u16 voice, ioctl;
	u16 voice, ioctl;


	voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f;
	voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
	ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d;
	ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;


	/* set master/slave audio interface */
	/* set master/slave audio interface */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
		return -EINVAL;
		return -EINVAL;
	}
	}


	wm8753_write(codec, WM8753_PCM, voice);
	snd_soc_write(codec, WM8753_PCM, voice);
	wm8753_write(codec, WM8753_IOCTL, ioctl);
	snd_soc_write(codec, WM8753_IOCTL, ioctl);
	return 0;
	return 0;
}
}


@@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,


	switch (div_id) {
	switch (div_id) {
	case WM8753_PCMDIV:
	case WM8753_PCMDIV:
		reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f;
		reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
		wm8753_write(codec, WM8753_CLOCK, reg | div);
		snd_soc_write(codec, WM8753_CLOCK, reg | div);
		break;
		break;
	case WM8753_BCLKDIV:
	case WM8753_BCLKDIV:
		reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7;
		reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
		wm8753_write(codec, WM8753_SRATE2, reg | div);
		snd_soc_write(codec, WM8753_SRATE2, reg | div);
		break;
		break;
	case WM8753_VXCLKDIV:
	case WM8753_VXCLKDIV:
		reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f;
		reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
		wm8753_write(codec, WM8753_SRATE2, reg | div);
		snd_soc_write(codec, WM8753_SRATE2, reg | div);
		break;
		break;
	default:
	default:
		return -EINVAL;
		return -EINVAL;
@@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
		unsigned int fmt)
		unsigned int fmt)
{
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct snd_soc_codec *codec = codec_dai->codec;
	u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
	u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;


	/* interface format */
	/* interface format */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
		return -EINVAL;
		return -EINVAL;
	}
	}


	wm8753_write(codec, WM8753_HIFI, hifi);
	snd_soc_write(codec, WM8753_HIFI, hifi);
	return 0;
	return 0;
}
}


@@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
	struct snd_soc_codec *codec = codec_dai->codec;
	struct snd_soc_codec *codec = codec_dai->codec;
	u16 ioctl, hifi;
	u16 ioctl, hifi;


	hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f;
	hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
	ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae;
	ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;


	/* set master/slave audio interface */
	/* set master/slave audio interface */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
		return -EINVAL;
		return -EINVAL;
	}
	}


	wm8753_write(codec, WM8753_HIFI, hifi);
	snd_soc_write(codec, WM8753_HIFI, hifi);
	wm8753_write(codec, WM8753_IOCTL, ioctl);
	snd_soc_write(codec, WM8753_IOCTL, ioctl);
	return 0;
	return 0;
}
}


@@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_codec *codec = rtd->codec;
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
	u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
	u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
	u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
	u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
	int coeff;
	int coeff;


	/* is digital filter coefficient valid ? */
	/* is digital filter coefficient valid ? */
@@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
		printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
		printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
		return coeff;
		return coeff;
	}
	}
	wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
	snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
		coeff_div[coeff].usb);
		coeff_div[coeff].usb);


	/* bit size */
	/* bit size */
@@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
		break;
		break;
	}
	}


	wm8753_write(codec, WM8753_HIFI, hifi);
	snd_soc_write(codec, WM8753_HIFI, hifi);
	return 0;
	return 0;
}
}


@@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
	u16 clock;
	u16 clock;


	/* set clk source as pcmclk */
	/* set clk source as pcmclk */
	clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
	wm8753_write(codec, WM8753_CLOCK, clock);
	snd_soc_write(codec, WM8753_CLOCK, clock);


	if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
	if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
		return -EINVAL;
		return -EINVAL;
@@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
	u16 clock;
	u16 clock;


	/* set clk source as pcmclk */
	/* set clk source as pcmclk */
	clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
	wm8753_write(codec, WM8753_CLOCK, clock);
	snd_soc_write(codec, WM8753_CLOCK, clock);


	if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
	if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
		return -EINVAL;
		return -EINVAL;
@@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
	u16 clock;
	u16 clock;


	/* set clk source as mclk */
	/* set clk source as mclk */
	clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
	wm8753_write(codec, WM8753_CLOCK, clock | 0x4);
	snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);


	if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
	if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
		return -EINVAL;
		return -EINVAL;
@@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int wm8753_mute(struct snd_soc_dai *dai, int mute)
static int wm8753_mute(struct snd_soc_dai *dai, int mute)
{
{
	struct snd_soc_codec *codec = dai->codec;
	struct snd_soc_codec *codec = dai->codec;
	u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
	u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);


	/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
	/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
	 * make sure we check if they are not both active when we mute */
	 * make sure we check if they are not both active when we mute */
	if (mute && wm8753->dai_func == 1) {
	if (mute && wm8753->dai_func == 1) {
		if (!codec->active)
		if (!codec->active)
			wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
			snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
	} else {
	} else {
		if (mute)
		if (mute)
			wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
			snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
		else
		else
			wm8753_write(codec, WM8753_DAC, mute_reg);
			snd_soc_write(codec, WM8753_DAC, mute_reg);
	}
	}


	return 0;
	return 0;
@@ -1273,23 +1226,23 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
static int wm8753_set_bias_level(struct snd_soc_codec *codec,
static int wm8753_set_bias_level(struct snd_soc_codec *codec,
				 enum snd_soc_bias_level level)
				 enum snd_soc_bias_level level)
{
{
	u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
	u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;


	switch (level) {
	switch (level) {
	case SND_SOC_BIAS_ON:
	case SND_SOC_BIAS_ON:
		/* set vmid to 50k and unmute dac */
		/* set vmid to 50k and unmute dac */
		wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
		snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
		break;
		break;
	case SND_SOC_BIAS_PREPARE:
	case SND_SOC_BIAS_PREPARE:
		/* set vmid to 5k for quick power up */
		/* set vmid to 5k for quick power up */
		wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
		snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
		break;
		break;
	case SND_SOC_BIAS_STANDBY:
	case SND_SOC_BIAS_STANDBY:
		/* mute dac and set vmid to 500k, enable VREF */
		/* mute dac and set vmid to 500k, enable VREF */
		wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
		snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
		break;
		break;
	case SND_SOC_BIAS_OFF:
	case SND_SOC_BIAS_OFF:
		wm8753_write(codec, WM8753_PWR1, 0x0001);
		snd_soc_write(codec, WM8753_PWR1, 0x0001);
		break;
		break;
	}
	}
	codec->dapm.bias_level = level;
	codec->dapm.bias_level = level;
@@ -1477,7 +1430,7 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
		else
		else
			dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
			dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
	}
	}
	wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
	snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
}
}


static void wm8753_work(struct work_struct *work)
static void wm8753_work(struct work_struct *work)
@@ -1497,22 +1450,19 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)


static int wm8753_resume(struct snd_soc_codec *codec)
static int wm8753_resume(struct snd_soc_codec *codec)
{
{
	u16 *reg_cache = codec->reg_cache;
	int i;
	int i;
	u8 data[2];
	u16 *cache = codec->reg_cache;


	/* Sync reg_cache with the hardware */
	/* Sync reg_cache with the hardware */
	for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
	for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
		if (i + 1 == WM8753_RESET)
		if (i == WM8753_RESET)
			continue;
			continue;


		/* No point in writing hardware default values back */
		/* No point in writing hardware default values back */
		if (cache[i] == wm8753_reg[i])
		if (reg_cache[i] == wm8753_reg[i])
			continue;
			continue;


		data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
		snd_soc_write(codec, i, reg_cache[i]);
		data[1] = cache[i] & 0x00ff;
		codec->hw_write(codec->control_data, data, 2);
	}
	}


	wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1531,7 +1481,7 @@ static int wm8753_resume(struct snd_soc_codec *codec)
static int wm8753_probe(struct snd_soc_codec *codec)
static int wm8753_probe(struct snd_soc_codec *codec)
{
{
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
	int ret = 0, reg;
	int ret;


	INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
	INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);


@@ -1556,26 +1506,16 @@ static int wm8753_probe(struct snd_soc_codec *codec)
			      msecs_to_jiffies(caps_charge));
			      msecs_to_jiffies(caps_charge));


	/* set the update bits */
	/* set the update bits */
	reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
	snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
	wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
	snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
	snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
	wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
	snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_LADC);
	snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
	wm8753_write(codec, WM8753_LADC, reg | 0x0100);
	snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_RADC);
	snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
	wm8753_write(codec, WM8753_RADC, reg | 0x0100);
	snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
	snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
	wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
	snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
	wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
	wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
	wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
	wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
	reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
	wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);


	snd_soc_add_controls(codec, wm8753_snd_controls,
	snd_soc_add_controls(codec, wm8753_snd_controls,
			     ARRAY_SIZE(wm8753_snd_controls));
			     ARRAY_SIZE(wm8753_snd_controls));
+18 −19
Original line number Original line Diff line number Diff line
@@ -49,8 +49,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
/* codec private data */
/* codec private data */
struct wm8904_priv {
struct wm8904_priv {


	u16 reg_cache[WM8904_MAX_REGISTER + 1];

	enum wm8904_type devtype;
	enum wm8904_type devtype;
	void *control_data;
	void *control_data;


@@ -2094,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)


static void wm8904_sync_cache(struct snd_soc_codec *codec)
static void wm8904_sync_cache(struct snd_soc_codec *codec)
{
{
	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
	u16 *reg_cache = codec->reg_cache;
	int i;
	int i;


	if (!codec->cache_sync)
	if (!codec->cache_sync)
@@ -2105,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
	/* Sync back cached values if they're different from the
	/* Sync back cached values if they're different from the
	 * hardware default.
	 * hardware default.
	 */
	 */
	for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
	for (i = 1; i < codec->driver->reg_cache_size; i++) {
		if (!wm8904_access[i].writable)
		if (!wm8904_access[i].writable)
			continue;
			continue;


		if (wm8904->reg_cache[i] == wm8904_reg[i])
		if (reg_cache[i] == wm8904_reg[i])
			continue;
			continue;


		snd_soc_write(codec, i, wm8904->reg_cache[i]);
		snd_soc_write(codec, i, reg_cache[i]);
	}
	}


	codec->cache_sync = 0;
	codec->cache_sync = 0;
@@ -2371,6 +2369,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
{
{
	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
	struct wm8904_pdata *pdata = wm8904->pdata;
	struct wm8904_pdata *pdata = wm8904->pdata;
	u16 *reg_cache = codec->reg_cache;
	int ret, i;
	int ret, i;


	codec->cache_sync = 1;
	codec->cache_sync = 1;
@@ -2437,19 +2436,19 @@ static int wm8904_probe(struct snd_soc_codec *codec)
	}
	}


	/* Change some default settings - latch VU and enable ZC */
	/* Change some default settings - latch VU and enable ZC */
	wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
	reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
	wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
	reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
	wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
	reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
	wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
	reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
	wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
	reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
		WM8904_HPOUTLZC;
		WM8904_HPOUTLZC;
	wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
	reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
		WM8904_HPOUTRZC;
		WM8904_HPOUTRZC;
	wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
	reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
		WM8904_LINEOUTLZC;
		WM8904_LINEOUTLZC;
	wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
	reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
		WM8904_LINEOUTRZC;
		WM8904_LINEOUTRZC;
	wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
	reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;


	/* Apply configuration from the platform data. */
	/* Apply configuration from the platform data. */
	if (wm8904->pdata) {
	if (wm8904->pdata) {
@@ -2457,23 +2456,23 @@ static int wm8904_probe(struct snd_soc_codec *codec)
			if (!pdata->gpio_cfg[i])
			if (!pdata->gpio_cfg[i])
				continue;
				continue;


			wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i]
			reg_cache[WM8904_GPIO_CONTROL_1 + i]
				= pdata->gpio_cfg[i] & 0xffff;
				= pdata->gpio_cfg[i] & 0xffff;
		}
		}


		/* Zero is the default value for these anyway */
		/* Zero is the default value for these anyway */
		for (i = 0; i < WM8904_MIC_REGS; i++)
		for (i = 0; i < WM8904_MIC_REGS; i++)
			wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
			reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
				= pdata->mic_cfg[i];
				= pdata->mic_cfg[i];
	}
	}


	/* Set Class W by default - this will be managed by the Class
	/* Set Class W by default - this will be managed by the Class
	 * G widget at runtime where bypass paths are available.
	 * G widget at runtime where bypass paths are available.
	 */
	 */
	wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
	reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;


	/* Use normal bias source */
	/* Use normal bias source */
	wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
	reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;


	wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);


Loading