Modify uda1380 driver to use soc-cache stuff

Signed-off-by: Arnaud Patard <arnaud.patard@rtp-net.org>
---
Index: linux-2.6/sound/soc/codecs/uda1380.c
===================================================================
--- linux-2.6.orig/sound/soc/codecs/uda1380.c	2010-07-03 23:01:14.221886431 +0200
+++ linux-2.6/sound/soc/codecs/uda1380.c	2010-07-03 23:29:47.629906781 +0200
@@ -56,128 +56,28 @@ static const u16 uda1380_reg[UDA1380_CAC
 	0x0000, 0x0000, 0x0000, 0x0000,
 	0x0000, 0x8000, 0x0002, 0x0000,
 };
-
-static unsigned long uda1380_cache_dirty;
-
-/*
- * read uda1380 register cache
- */
-static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
-	unsigned int reg)
-{
-	u16 *cache = codec->reg_cache;
-	if (reg == UDA1380_RESET)
-		return 0;
-	if (reg >= UDA1380_CACHEREGNUM)
-		return -1;
-	return cache[reg];
-}
-
-/*
- * write uda1380 register cache
- */
-static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
-	u16 reg, unsigned int value)
-{
-	u16 *cache = codec->reg_cache;
-
-	if (reg >= UDA1380_CACHEREGNUM)
-		return;
-	if ((reg >= 0x10) && (cache[reg] != value))
-		set_bit(reg - 0x10, &uda1380_cache_dirty);
-	cache[reg] = value;
-}
-
-/*
- * write to the UDA1380 register space
- */
-static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
-	unsigned int value)
-{
-	u8 data[3];
-
-	/* data is
-	 *   data[0] is register offset
-	 *   data[1] is MS byte
-	 *   data[2] is LS byte
-	 */
-	data[0] = reg;
-	data[1] = (value & 0xff00) >> 8;
-	data[2] = value & 0x00ff;
-
-	uda1380_write_reg_cache(codec, reg, value);
-
-	/* the interpolator & decimator regs must only be written when the
-	 * codec DAI is active.
-	 */
-	if (!codec->active && (reg >= UDA1380_MVOL))
-		return 0;
-	pr_debug("uda1380: hw write %x val %x\n", reg, value);
-	if (codec->hw_write(codec->control_data, data, 3) == 3) {
-		unsigned int val;
-		i2c_master_send(codec->control_data, data, 1);
-		i2c_master_recv(codec->control_data, data, 2);
-		val = (data[0]<<8) | data[1];
-		if (val != value) {
-			pr_debug("uda1380: READ BACK VAL %x\n",
-					(data[0]<<8) | data[1]);
-			return -EIO;
-		}
-		if (reg >= 0x10)
-			clear_bit(reg - 0x10, &uda1380_cache_dirty);
-		return 0;
-	} else
-		return -EIO;
-}
-
 static void uda1380_sync_cache(struct snd_soc_codec *codec)
 {
 	int reg;
-	u8 data[3];
 	u16 *cache = codec->reg_cache;
 
-	/* Sync reg_cache with the hardware */
-	for (reg = 0; reg < UDA1380_MVOL; reg++) {
-		data[0] = reg;
-		data[1] = (cache[reg] & 0xff00) >> 8;
-		data[2] = cache[reg] & 0x00ff;
-		if (codec->hw_write(codec->control_data, data, 3) != 3)
-			dev_err(codec->dev, "%s: write to reg 0x%x failed\n",
-				__func__, reg);
+	for (reg = 0; reg < UDA1380_CACHEREGNUM; reg++) {
+		if (cache[reg] == uda1380_reg[reg])
+			continue;
+		snd_soc_write(codec, reg, cache[reg]);
 	}
-
-	for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
-		set_bit(reg - 0x10, &uda1380_cache_dirty);
 }
 
 static int uda1380_reset(struct snd_soc_codec *codec)
 {
-	u8 data[3];
-
-	data[0] = UDA1380_RESET;
-	data[1] = 0;
-	data[2] = 0;
-
-	if (codec->hw_write(codec->control_data, data, 3) != 3) {
-		dev_err(codec->dev, "%s: failed\n", __func__);
-		return -EIO;
-	}
-
-	return 0;
+	return snd_soc_write(codec, UDA1380_RESET, 0);
 }
 
 static void uda1380_flush_work(struct work_struct *work)
 {
-	int bit, reg;
-
-	for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
-		reg = 0x10 + bit;
-		pr_debug("uda1380: flush reg %x val %x:\n", reg,
-				uda1380_read_reg_cache(uda1380_codec, reg));
-		uda1380_write(uda1380_codec, reg,
-				uda1380_read_reg_cache(uda1380_codec, reg));
-		clear_bit(bit, &uda1380_cache_dirty);
-	}
+	uda1380_codec->cache_only = 0;
+	uda1380_sync_cache(uda1380_codec);
+	uda1380_codec->cache_sync = 0;
 }
 
 /* declarations of ALSA reg_elem_REAL controls */
@@ -421,7 +321,7 @@ static int uda1380_set_dai_fmt_both(stru
 	int iface;
 
 	/* set up DAI based upon fmt */
-	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+	iface = snd_soc_read(codec, UDA1380_IFACE);
 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -439,7 +339,7 @@ static int uda1380_set_dai_fmt_both(stru
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
 		return -EINVAL;
 
-	uda1380_write(codec, UDA1380_IFACE, iface);
+	snd_soc_write(codec, UDA1380_IFACE, iface);
 
 	return 0;
 }
@@ -451,7 +351,7 @@ static int uda1380_set_dai_fmt_playback(
 	int iface;
 
 	/* set up DAI based upon fmt */
-	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+	iface = snd_soc_read(codec, UDA1380_IFACE);
 	iface &= ~R01_SFORI_MASK;
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -469,7 +369,7 @@ static int uda1380_set_dai_fmt_playback(
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
 		return -EINVAL;
 
-	uda1380_write(codec, UDA1380_IFACE, iface);
+	snd_soc_write(codec, UDA1380_IFACE, iface);
 
 	return 0;
 }
@@ -481,7 +381,7 @@ static int uda1380_set_dai_fmt_capture(s
 	int iface;
 
 	/* set up DAI based upon fmt */
-	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+	iface = snd_soc_read(codec, UDA1380_IFACE);
 	iface &= ~(R01_SIM | R01_SFORO_MASK);
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -498,7 +398,7 @@ static int uda1380_set_dai_fmt_capture(s
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
 		iface |= R01_SIM;
 
-	uda1380_write(codec, UDA1380_IFACE, iface);
+	snd_soc_write(codec, UDA1380_IFACE, iface);
 
 	return 0;
 }
@@ -510,18 +410,19 @@ static int uda1380_trigger(struct snd_pc
 	struct snd_soc_device *socdev = rtd->socdev;
 	struct snd_soc_codec *codec = socdev->card->codec;
 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
-	int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
+	int mixer = snd_soc_read(codec, UDA1380_MIXER);
 
+	codec->cache_only = 1;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		uda1380_write(codec, UDA1380_MIXER,
+		snd_soc_write(codec, UDA1380_MIXER,
 					mixer & ~R14_SILENCE);
 		schedule_work(&uda1380->work);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		uda1380_write(codec, UDA1380_MIXER,
+		snd_soc_write(codec, UDA1380_MIXER,
 					mixer | R14_SILENCE);
 		schedule_work(&uda1380->work);
 		break;
@@ -536,12 +437,12 @@ static int uda1380_pcm_hw_params(struct
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_device *socdev = rtd->socdev;
 	struct snd_soc_codec *codec = socdev->card->codec;
-	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
+	u16 clk = snd_soc_read(codec, UDA1380_CLK);
 
 	/* set WSPLL power and divider if running from this clock */
 	if (clk & R00_DAC_CLK) {
 		int rate = params_rate(params);
-		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
+		u16 pm = snd_soc_read(codec, UDA1380_PM);
 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
 		switch (rate) {
 		case 6250 ... 12500:
@@ -557,7 +458,7 @@ static int uda1380_pcm_hw_params(struct
 			clk |= 0x3;
 			break;
 		}
-		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
+		snd_soc_write(codec, UDA1380_PM, R02_PON_PLL | pm);
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -565,7 +466,7 @@ static int uda1380_pcm_hw_params(struct
 	else
 		clk |= R00_EN_ADC | R00_EN_DEC;
 
-	uda1380_write(codec, UDA1380_CLK, clk);
+	snd_soc_write(codec, UDA1380_CLK, clk);
 	return 0;
 }
 
@@ -575,12 +476,12 @@ static void uda1380_pcm_shutdown(struct
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_device *socdev = rtd->socdev;
 	struct snd_soc_codec *codec = socdev->card->codec;
-	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
+	u16 clk = snd_soc_read(codec, UDA1380_CLK);
 
 	/* shut down WSPLL power if running from this clock */
 	if (clk & R00_DAC_CLK) {
-		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
-		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
+		u16 pm = snd_soc_read(codec, UDA1380_PM);
+		snd_soc_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -588,13 +489,13 @@ static void uda1380_pcm_shutdown(struct
 	else
 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
 
-	uda1380_write(codec, UDA1380_CLK, clk);
+	snd_soc_write(codec, UDA1380_CLK, clk);
 }
 
 static int uda1380_set_bias_level(struct snd_soc_codec *codec,
 	enum snd_soc_bias_level level)
 {
-	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
+	int pm = snd_soc_read(codec, UDA1380_PM);
 	struct uda1380_platform_data *pdata = codec->dev->platform_data;
 
 	if (codec->bias_level == level)
@@ -604,7 +505,7 @@ static int uda1380_set_bias_level(struct
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		/* ADC, DAC on */
-		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
+		snd_soc_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
@@ -613,17 +514,17 @@ static int uda1380_set_bias_level(struct
 
 			switch (pdata->dac_clk) {
 			case UDA1380_DAC_CLK_SYSCLK:
-				uda1380_write_reg_cache(codec, UDA1380_CLK, 0);
+				snd_soc_write(codec, UDA1380_CLK, 0);
 				break;
 			case UDA1380_DAC_CLK_WSPLL:
-				uda1380_write_reg_cache(codec, UDA1380_CLK,
+				snd_soc_write(codec, UDA1380_CLK,
 					R00_DAC_CLK);
 				break;
 			}
 
 			uda1380_sync_cache(codec);
 		}
-		uda1380_write(codec, UDA1380_PM, 0x0);
+		snd_soc_write(codec, UDA1380_PM, 0x0);
 		break;
 	case SND_SOC_BIAS_OFF:
 		pdata->set_power(0);
@@ -798,8 +699,6 @@ static int uda1380_register(struct uda13
 	snd_soc_codec_set_drvdata(codec, uda1380);
 	codec->name = "UDA1380";
 	codec->owner = THIS_MODULE;
-	codec->read = uda1380_read_reg_cache;
-	codec->write = uda1380_write;
 	codec->bias_level = SND_SOC_BIAS_OFF;
 	codec->set_bias_level = uda1380_set_bias_level;
 	codec->dai = uda1380_dai;
@@ -871,6 +770,12 @@ static __devinit int uda1380_i2c_probe(s
 
 	codec->dev = &i2c->dev;
 
+	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to set cache i/o %d", ret);
+		return ret;
+	}
+
 	ret = uda1380_register(uda1380);
 	if (ret != 0)
 		kfree(uda1380);
