Title: [9623] trunk/sound/soc/codecs: driver:codec: task[#6322] update and clean up the driver
Revision
9623
Author
cliff
Date
2011-02-22 21:11:23 -0500 (Tue, 22 Feb 2011)

Log Message

driver:codec: task[#6322] update and clean up the driver

Modified Paths

Diff

Modified: trunk/sound/soc/codecs/adau1701.c (9622 => 9623)


--- trunk/sound/soc/codecs/adau1701.c	2011-02-19 11:48:04 UTC (rev 9622)
+++ trunk/sound/soc/codecs/adau1701.c	2011-02-23 02:11:23 UTC (rev 9623)
@@ -1,5 +1,5 @@
 /*
- * Driver for ADAU1701 sound codec
+ * Driver for ADAU1701 SigmaDSP processor
  *
  * Copyright 2011 Analog Devices Inc.
  *
@@ -30,122 +30,78 @@
 #define ADAU1701_VERSION "0.10"
 #define ADAU1701_FIRMWARE "SigmaDSP_fw.bin"
 
-static const u16 adau1701_reg_defaults[] = {
-	0x0000,     /* R0 */
-	0x0000,     /* R1 */
-	0x0000,     /* R2 */
-	0x0000,     /* R3 */
-	0x0000,     /* R4 */
-	0x0000,     /* R5 */
-	0x0000,     /* R6 */
-	0x0000,     /* R7 */
-	0x0000,     /* R8 */
-	0x0000,     /* R9 */
-	0x0000,     /* R10 */
-	0x0000,     /* R11 */
-	0x0000,     /* R12 */
-	0x0000,     /* R13 */
-	0x0000,     /* R14 */
-	0x0000,     /* R15 */
-	0x0000,     /* R16 */
-	0x0000,     /* R17 */
-	0x0000,     /* R18 */
-	0x0000,     /* R19 */
-	0x0000,     /* R20 */
-	0x0000,     /* R21 */
-	0x0000,     /* R22 */
-	0x0000,     /* R23 */
-	0x0000,     /* R24 */
-	0x0000,     /* R25 */
-	0x0000,     /* R26 */
-	0x0000,     /* R27 */
-	0x0000,     /* R28  - DSP Core Control */
-	0x0000,     /* R29 */
-	0x0000,     /* R30  - Serial Output Control */
-	0x0000,     /* R31  - Serial Input Control*/
-	0x0000,     /* R32 */
-	0x0000,     /* R33 */
-	0x0000,     /* R34  - Auxiliary ADC and Power Control */
-	0x0000,     /* R35 */
-	0x0000,     /* R36  - Auxiliary ADC Enable*/
-	0x0000,     /* R37  - DAC Setup */
-};
-
 /* codec private data */
 struct adau1701_priv {
 	struct snd_soc_codec *codec;
+	enum snd_soc_control_type control_type;
 };
 
 /*
- * write register cache
+ * Write a ADAU1701 register,since the register length is from 1 to 5,
+ * So, use our own read/write functions instead of snd_soc_read/write.
  */
-static inline int adau1701_write_reg_cache(struct snd_soc_codec *codec,
-	unsigned int reg, unsigned int value)
+static int adau1701_write_register(struct snd_soc_codec *codec,
+	u16 reg_address, u8 length, u32 value)
 {
-	u16 *cache = codec->reg_cache;
-
-	if (reg < ADAU1701_FIRSTREG)
-		reg = reg + ADAU1701_FIRSTREG;
-
-	if ((reg < ADAU1701_FIRSTREG) || (reg > ADAU1701_LASTREG))
-		return -1;
-
-	cache[reg - ADAU1701_FIRSTREG] = value;
-
-	return 0;
-}
-
-/*
- * write a multibyte ADAU1701 register
- */
-static int adau1701_write_reg_block(struct snd_soc_codec *codec,
-	unsigned int reg, u8 length, u8 *values)
-{
+	int ret;
 	int count = length + 2; /*data plus 16bit register address*/
 	u8 buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 
-	buf[0] = (u8)(reg >> 8);
-	buf[1] = (u8)(reg & 0xFF);
+	if (length == 0)
+		return -1;
+	buf[0] = (reg_address >> 8) & 0xFF;
+	buf[1] = reg_address & 0xFF;
+	if (length == 1)
+		buf[2] = value & 0xFF;
+	else if (length == 2) {
+		buf[2] = (value >> 8) & 0xFF;
+		buf[3] = value & 0xFF;
+	} else if (length == 3) {
+		buf[2] = (value >> 16) & 0xFF;
+		buf[3] = (value >> 8) & 0xFF;
+		buf[4] = value & 0xFF;
+	}
+	ret = i2c_master_send(codec->control_data, buf, count);
 
-	if (length > 0)
-		memcpy(&buf[2], values, length);
+	return ret;
 
-	if (codec->hw_write(codec->control_data, buf, count) == count)
-		return 0;
-	else {
-		dev_err(codec->dev, "address block write failed.");
-		return -EIO;
-	}
 }
 
 /*
- * read ADAU1701 hw register and update cache
+ * read ADAU1701 hw register
  */
-static int adau1701_read_reg_byte(struct snd_soc_codec *codec,
-	u16 reg)
+static u32 adau1701_read_register(struct snd_soc_codec *codec,
+	u16 reg_address, u8 length)
 {
 	u8 addr[2];
-	u8 buf[1] = {0};
+	u8 buf[2];
+	u32 value = 0;
+	int ret;
 
-	if (reg < ADAU1701_FIRSTREG)
-		reg = reg + ADAU1701_FIRSTREG;
+	if (reg_address < ADAU1701_FIRSTREG)
+		reg_address = reg_address + ADAU1701_FIRSTREG;
 
-	if ((reg < ADAU1701_FIRSTREG) || (reg > ADAU1701_LASTREG))
+	if ((reg_address < ADAU1701_FIRSTREG) || (reg_address > ADAU1701_LASTREG))
 		return -EIO;
 
-	addr[0] = (u8)(reg >> 8);
-	addr[1] = (u8)(reg & 0xFF);
+	addr[0] = (reg_address >> 8) & 0xFF;
+	addr[1] = reg_address & 0xFF;
 
 	/* write the 2byte read address */
-	if (codec->hw_write(codec->control_data, addr, 2) != 2) {
-		printk(KERN_ERR "read_reg_byte:address write failed.");
-		return -EIO;
-	}
+	ret = i2c_master_send(codec->control_data, addr, 2);
+	if (ret)
+		return ret;
 
-	if (i2c_master_recv(codec->control_data, buf, 1) != 1)
-		return -EIO;
-
-	return buf[0];
+	if (length == 1) {
+		if (i2c_master_recv(codec->control_data, buf, 1) != 1)
+			return -EIO;
+		value = buf[0];
+	} else if (length == 2) {
+		if (i2c_master_recv(codec->control_data, buf, 2) != 2)
+			return -EIO;
+		value = (buf[0] << 8) | buf[1];
+	}
+	return value;
 }
 
 static int adau1701_setprogram(struct snd_soc_codec *codec)
@@ -161,11 +117,12 @@
 				struct snd_soc_dai *dai)
 {
 	struct snd_soc_codec *codec = dai->codec;
-	int ret = 0;
+	int reg = 0;
 
-	snd_soc_write(codec, ADAU1701_OSCIPOW, 0x0);
+	reg = SEROCTL_MASTER | SEROCTL_OBF16 | SEROCTL_OLF1024;
+	adau1701_write_register(codec, ADAU1701_SEROCTL, 2, reg);
 
-	return ret;
+	return 0;
 }
 
 static void adau1701_shutdown(struct snd_pcm_substream *substream,
@@ -173,24 +130,24 @@
 {
 	struct snd_soc_codec *codec = dai->codec;
 
-	snd_soc_write(codec, ADAU1701_OSCIPOW, 0x02);
-
+	adau1701_write_register(codec, ADAU1701_SEROCTL, 2, 0);
 }
 
 static int adau1701_mute(struct snd_soc_dai *dai, int mute)
 {
 	struct snd_soc_codec *codec = dai->codec;
 	u16 reg = 0;
+
 	if (mute) {
 		/* mute inputs/outputs */
-		reg = snd_soc_read(codec, ADAU1701_AUXNPOW);
-		reg |= AUXNPOW_AAPD | AUXNPOW_D1PD | AUXNPOW_D0PD;
-		snd_soc_write(codec, ADAU1701_AUXNPOW, reg);
+		reg = adau1701_read_register(codec, ADAU1701_AUXNPOW, 2);
+		reg |= AUXNPOW_AAPD | AUXNPOW_D0PD | AUXNPOW_D1PD | AUXNPOW_D2PD | AUXNPOW_D3PD;
+		adau1701_write_register(codec, ADAU1701_AUXNPOW, 2, reg);
 	} else {
 		/* unmute inputs/outputs */
-		reg = snd_soc_read(codec, ADAU1701_AUXNPOW);
-		reg &= ~(AUXNPOW_AAPD | AUXNPOW_D1PD | AUXNPOW_D0PD);
-		snd_soc_write(codec, ADAU1701_AUXNPOW, reg);
+		reg = adau1701_read_register(codec, ADAU1701_AUXNPOW, 2);
+		reg &= ~(AUXNPOW_AAPD | AUXNPOW_D0PD | AUXNPOW_D1PD | AUXNPOW_D2PD | AUXNPOW_D3PD);
+		adau1701_write_register(codec, ADAU1701_AUXNPOW, 2, reg);
 	}
 
 	return 0;
@@ -200,9 +157,9 @@
 		unsigned int fmt)
 {
 	struct snd_soc_codec *codec = codec_dai->codec;
-	u8 reg = 0;
+	u32 reg = 0;
 
-	reg = adau1701_read_reg_byte(codec, (u16)ADAU1701_SERITL1);
+	reg = adau1701_read_register(codec, ADAU1701_SERITL1, 1);
 	/* interface format */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
@@ -224,8 +181,8 @@
 		return 0;
 	}
 
-	/* set I2S iface format*/
-	adau1701_write_reg_block(codec, ADAU1701_SERITL1, 1, &reg);
+	/* set iface format*/
+	adau1701_write_register(codec, ADAU1701_SERITL1, 1, reg);
 	return 0;
 }
 
@@ -235,23 +192,21 @@
 	u16 reg;
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		reg = snd_soc_read(codec, ADAU1701_AUXNPOW);
-		reg &= ~(AUXNPOW_AAPD | AUXNPOW_D1PD | AUXNPOW_D0PD |\
-			AUXNPOW_VBPD | AUXNPOW_VRPD);
-		snd_soc_write(codec, ADAU1701_AUXNPOW, reg);
+		reg = adau1701_read_register(codec, ADAU1701_AUXNPOW, 2);
+		reg &= ~(AUXNPOW_AAPD | AUXNPOW_D0PD | AUXNPOW_D1PD |  AUXNPOW_D2PD |
+			 AUXNPOW_D3PD | AUXNPOW_VBPD | AUXNPOW_VRPD);
+		adau1701_write_register(codec, ADAU1701_AUXNPOW, 2, reg);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_write(codec, ADAU1701_OSCIPOW, 0x02);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* everything off, dac mute, inactive */
-		snd_soc_write(codec, ADAU1701_OSCIPOW, 0x02);
-		reg = snd_soc_read(codec, ADAU1701_AUXNPOW);
-		reg |= AUXNPOW_AAPD | AUXNPOW_D1PD | AUXNPOW_D0PD |\
-			AUXNPOW_VBPD | AUXNPOW_VRPD;
-		snd_soc_write(codec, ADAU1701_AUXNPOW, reg);
+		reg = adau1701_read_register(codec, ADAU1701_AUXNPOW, 2);
+		reg |= AUXNPOW_AAPD | AUXNPOW_D0PD | AUXNPOW_D1PD |  AUXNPOW_D2PD |
+			 AUXNPOW_D3PD | AUXNPOW_VBPD | AUXNPOW_VRPD;
+		adau1701_write_register(codec, ADAU1701_AUXNPOW, 2, reg);
 		break;
 
 	}
@@ -320,38 +275,40 @@
 
 static int adau1701_reg_init(struct snd_soc_codec *codec)
 {
-	u16 reg16;
-	u8 reg[3];
+	u32 reg;
+	int ret = 0;
 
-	reg16 = DSPCTRL_DAM | DSPCTRL_ADM;
-	snd_soc_write(codec, ADAU1701_DSPCTRL, reg16);
+	reg = DSPCTRL_DAM | DSPCTRL_ADM;
+	adau1701_write_register(codec, ADAU1701_DSPCTRL, 2, reg);
 	/* Load default program */
-	adau1701_setprogram(codec);
-	reg16 = DSPCTRL_DAM | DSPCTRL_ADM;
-	snd_soc_write(codec, ADAU1701_DSPCTRL, reg16);
-	reg[0] = 0x80;
-	adau1701_write_reg_block(codec, ADAU1701_DSPRES, 1, &reg[0]);
-	snd_soc_write(codec, ADAU1701_SEROCTL, 0);
-	/* PLLMODE1 = 1, PLLMODE0 = 0, 256*fs */
-	snd_soc_write(codec, ADAU1701_SEROCTL, 0x0d00);
-	reg[0] = 0;
-	adau1701_write_reg_block(codec, ADAU1701_SERITL1, 1, &reg[0]);
-	reg[0] = MPCONF_SDATAP | MPCONF_SDATAP << 4;
-	reg[1] = 0;
-	reg[2] = MPCONF_SDATAP;
-	adau1701_write_reg_block(codec, ADAU1701_MPCONF0, 3, &reg[0]);
-	adau1701_write_reg_block(codec, ADAU1701_MPCONF1, 3, &reg[0]);
-	snd_soc_write(codec, ADAU1701_AUXNPOW, 0);
-	reg16 = AUXADCE_AAEN;
-	snd_soc_write(codec, ADAU1701_AUXADCE, reg16);
-	reg16 = DACSET_DACEN;
-	snd_soc_write(codec, ADAU1701_DACSET, reg16);
-	reg16 = DSPCTRL_DAM | DSPCTRL_ADM | DSPCTRL_CR;
-	snd_soc_write(codec, ADAU1701_DSPCTRL, reg16);
-	/* power-down oscillator */
-	snd_soc_write(codec, ADAU1701_OSCIPOW, 0x02);
-
-	return 0;
+	ret = adau1701_setprogram(codec);
+	if (ret < 0) {
+		printk(KERN_ERR "Loading program data failed\n");
+		goto error;
+	}
+	reg = DSPCTRL_DAM | DSPCTRL_ADM;
+	adau1701_write_register(codec, ADAU1701_DSPCTRL, 2, reg);
+	reg = 0x08;
+	adau1701_write_register(codec, ADAU1701_DSPRES, 1, reg);
+	adau1701_write_register(codec, ADAU1701_SEROCTL, 2, 0);
+	adau1701_write_register(codec, ADAU1701_SERITL1, 1, 0);
+	/* Configure the multipurpose pins as serial in/out pins */
+	reg = MPCONF_SDATAP | MPCONF_SDATAP << 16 | MPCONF_SDATAP << 20;
+	adau1701_write_register(codec, ADAU1701_MPCONF0, 3, reg);
+	reg = MPCONF_AUXADC << 8 | MPCONF_SDATAP << 12 | MPCONF_SDATAP << 16 |
+		MPCONF_SDATAP << 20;
+	adau1701_write_register(codec, ADAU1701_MPCONF1, 3, reg);
+	adau1701_write_register(codec, ADAU1701_AUXNPOW, 2, 0);
+	reg = AUXADCE_AAEN;
+	adau1701_write_register(codec, ADAU1701_AUXADCE, 2, reg);
+	reg = DACSET_DACEN;
+	adau1701_write_register(codec, ADAU1701_DACSET, 2, reg);
+	reg = DSPCTRL_DAM | DSPCTRL_ADM | DSPCTRL_CR;
+	adau1701_write_register(codec, ADAU1701_DSPCTRL, 2, reg);
+	/* Power-up the oscillator */
+	adau1701_write_register(codec, ADAU1701_OSCIPOW, 2, 0);
+error:
+	return ret;
 }
 
 static int adau1701_probe(struct snd_soc_codec *codec)
@@ -361,14 +318,14 @@
 	struct adau1701_priv *adau1701 = snd_soc_codec_get_drvdata(codec);
 
 	adau1701->codec = codec;
-	ret = adau1701_reg_init(codec);
+	ret = snd_soc_codec_set_cache_io(codec, 16, 16, adau1701->control_type);
 	if (ret < 0) {
-		dev_err(codec->dev, "failed to initialize\n");
+		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
 	}
-	ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
+	ret = adau1701_reg_init(codec);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+		dev_err(codec->dev, "failed to initialize\n");
 		return ret;
 	}
 	ret = device_create_file(codec->dev, &dev_attr_dsp);
@@ -378,7 +335,6 @@
 	return ret;
 }
 
-/* remove everything here */
 static int adau1701_remove(struct snd_soc_codec *codec)
 {
 	adau1701_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -391,9 +347,6 @@
 	.suspend =	adau1701_suspend,
 	.resume =	adau1701_resume,
 	.set_bias_level = adau1701_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(adau1701_reg_defaults),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = adau1701_reg_defaults,
 };
 
 static __devinit int adau1701_i2c_probe(struct i2c_client *i2c,
@@ -406,6 +359,7 @@
 	if (adau1701 == NULL)
 		return -ENOMEM;
 
+	adau1701->control_type = SND_SOC_I2C;
 	i2c_set_clientdata(i2c, adau1701);
 	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_adau1701, &adau1701_dai, 1);
 	if (ret < 0)
@@ -430,7 +384,7 @@
 /* corgi i2c codec control layer */
 static struct i2c_driver adau1701_i2c_driver = {
 	.driver = {
-		.name = "adau1701",
+		.name = "adau1701-codec",
 		.owner = THIS_MODULE,
 	},
 	.probe    = adau1701_i2c_probe,
@@ -458,6 +412,6 @@
 }
 module_exit(adau1701_exit);
 
-MODULE_DESCRIPTION("ASoC ADAU1701 driver");
+MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver");
 MODULE_AUTHOR("Cliff Cai");
 MODULE_LICENSE("GPL");

Modified: trunk/sound/soc/codecs/adau1701.h (9622 => 9623)


--- trunk/sound/soc/codecs/adau1701.h	2011-02-19 11:48:04 UTC (rev 9622)
+++ trunk/sound/soc/codecs/adau1701.h	2011-02-23 02:11:23 UTC (rev 9623)
@@ -82,6 +82,17 @@
 #define MPCONF_SDATAPI		(0xC)
 #define MPCONF_AUXADC		(0xF)
 
+#define SEROCTL_MASTER		(0x0800)
+#define SEROCTL_OBF16		(0x0000)
+#define SEROCTL_OBF8		(0x0200)
+#define SEROCTL_OBF4		(0x0400)
+#define SEROCTL_OBF2		(0x0600)
+
+#define SEROCTL_OLF1024		(0x0000)
+#define SEROCTL_OLF512		(0x0080)
+#define SEROCTL_OLF256		(0x0100)
+#define SEROCTL_OLFRSV		(0x0180)
+
 #define AUXNPOW_AAPD		(0x80)
 #define AUXNPOW_VBPD		(0x40)
 #define AUXNPOW_VRPD		(0x20)
@@ -94,7 +105,7 @@
 #define SERITL1_TDM		(2)
 
 #define	AUXADCE_AAEN		(1 << 15)
-
+#define OSCIPOW_OPD		(0x04)
 #define	DACSET_DACEN		(1)
 
 #endif
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to