aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2007-09-10 18:45:50 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 10:49:30 -0400
commitbfc4e8616679226b1f113a46df491e233c8dc338 (patch)
tree83bc8f06e320d4f003f30bf9223a7869b7048976 /sound
parent23d4635ed336c7dadb3590ee7d275ac612f06ebf (diff)
[ALSA] Fix CS4270 volume control and optimize I2C operations
The volume control for the CS4270 ASoC driver was inverted - raising the volume level with alsamixer would decrease the actual volume. This patch also improves the performance of the I2C code (used to change register settings) by only performing an I2C write if the new value is different from the value that's in the register cache. Signed-off-by: Timur Tabi <timur@freescale.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/cs4270.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 43d50a4d8089..5d601ad6da70 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -294,19 +294,24 @@ static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec,
294static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg, 294static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
295 unsigned int value) 295 unsigned int value)
296{ 296{
297 u8 *cache = codec->reg_cache;
298
297 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) 299 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
298 return -EIO; 300 return -EIO;
299 301
300 if (i2c_smbus_write_byte_data(codec->control_data, reg, value) == 0) { 302 /* Only perform an I2C operation if the new value is different */
303 if (cache[reg - CS4270_FIRSTREG] != value) {
304 struct i2c_client *client = codec->control_data;
305 if (i2c_smbus_write_byte_data(client, reg, value)) {
306 printk(KERN_ERR "cs4270: I2C write failed\n");
307 return -EIO;
308 }
309
301 /* We've written to the hardware, so update the cache */ 310 /* We've written to the hardware, so update the cache */
302 u8 *cache = codec->reg_cache;
303 cache[reg - CS4270_FIRSTREG] = value; 311 cache[reg - CS4270_FIRSTREG] = value;
304 return 0;
305 } else {
306 printk(KERN_ERR "cs4270: I2C write of register %u failed\n",
307 reg);
308 return -EIO;
309 } 312 }
313
314 return 0;
310} 315}
311 316
312/* 317/*
@@ -521,7 +526,7 @@ static int cs4270_i2c_detach(struct i2c_client *client)
521/* A list of non-DAPM controls that the CS4270 supports */ 526/* A list of non-DAPM controls that the CS4270 supports */
522static const struct snd_kcontrol_new cs4270_snd_controls[] = { 527static const struct snd_kcontrol_new cs4270_snd_controls[] = {
523 SOC_DOUBLE_R("Master Playback Volume", 528 SOC_DOUBLE_R("Master Playback Volume",
524 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 0) 529 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
525}; 530};
526 531
527static struct i2c_driver cs4270_i2c_driver = { 532static struct i2c_driver cs4270_i2c_driver = {