alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* How to handle special SPI read/write for ASoC codec driver?
@ 2011-08-25 11:03 Ashish Chavan
  0 siblings, 0 replies; 2+ messages in thread
From: Ashish Chavan @ 2011-08-25 11:03 UTC (permalink / raw)
  To: alsa-devel

Hi,
   I am working on updating ASoC codec driver for Dialog's DA7210 codec
(sound/soc/codec/da7210.c). I am planning to add SPI support and have a
query.

DA7210 codec has total 136, 8 bit registers (0x88). It supports 8 bit
address and 8 bit data format for SPI. One out of eight address bits is
used to indicate read/write operation, so effectively there are only
seven bits to represent address. So, directly we can only address 128 (0
to 127) registers.

In order to make other upper registers (128 to 136) addressable, DA7210
provides a special PAGE1 register addressed at (0x00 / 0x80). This PAGE1
register basically acts as an offset to normal registers addresses. If
PAGE1 register's value is "0x0" then, register address "0" actually maps
to 0th register. But if page register's value is "0x80", then register
address "0" actually maps to 128th register, register "2" maps to 129th
reg, and so on.

While adding support for SPI, I need to add this logic of setting
correct page while reading and writing. AFAIK, the proper place to add
this extra logic is read/write functions on codec. i.e. something
similar to,

@@ -208,6 +208,38 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
 
 	BUG_ON(codec->driver->volatile_register);
 
+#if defined(CONFIG_SPI_MASTER)
+	/*
+	 * spi_page member of private data stores current status of page
+	 * register. 0 => page 0 selected, 1 => page 1 selected
+	 */
+	struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+	if(reg >= 80){
+		/* We are writing register in page 1 */
+		if(!da7210->spi_page){
+			/* Need to set page register first */
+			data[0] = 0x00;
+			data[1] = 0x80;		/* need to set seventh bit */
+			if (2 != codec->hw_write(codec->control_data, data, 2))
+				return -EIO;
+			cache[0] = 0x80;	/* Update cache */
+			da7210->spi_page = 1;	/* Update local status */
+		}
+			
+	}else {
+		/* We are writing register in page 0 */
+		if(da7210->spi_page){
+			/* Need to reset page register first */
+			data[0] = 0x80;
+			data[1] = 0x00;		/* need to reset seventh bit */
+			if (2 != codec->hw_write(codec->control_data, data, 2))
+				return -EIO;
+			cache[80] = 0x00;	/* Update cache */
+			da7210->spi_page = 0;	/* Update local status */
+		}
+	}
+#endif
+
 	data[0] = reg & 0xff;
 	data[1] = value & 0xff;
 
Any comments on this code?

Is there any better place to put this extra logic? Any way to accommodate this in to generic soc-io functions?



Thanks,

-- Ashish

^ permalink raw reply	[flat|nested] 2+ messages in thread
* How to handle special SPI read/write for ASoC codec driver?
@ 2011-08-25 11:09 Ashish Chavan
  0 siblings, 0 replies; 2+ messages in thread
From: Ashish Chavan @ 2011-08-25 11:09 UTC (permalink / raw)
  To: alsa-devel

Hi,
   I am working on updating ASoC codec driver for Dialog's DA7210 codec
(sound/soc/codec/da7210.c). I am planning to add SPI support and have a
query.

DA7210 codec has total 136, 8 bit registers (0x88). It supports 8 bit
address and 8 bit data format for SPI. One out of eight address bits is
used to indicate read/write operation, so effectively there are only
seven bits to represent address. So, directly we can only address 128 (0
to 127) registers.

In order to make other upper registers (128 to 136) addressable, DA7210
provides a special PAGE1 register addressed at (0x00 / 0x80). This PAGE1
register basically acts as an offset to normal registers addresses. If
PAGE1 register's value is "0x0" then, register address "0" actually maps
to 0th register. But if page register's value is "0x80", then register
address "0" actually maps to 128th register, register "2" maps to 129th
reg, and so on.

While adding support for SPI, I need to add this logic of setting
correct page while reading and writing. AFAIK, the proper place to add
this extra logic is read/write functions on codec. i.e. something
similar to, 

@@ -208,6 +208,38 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
 
 	BUG_ON(codec->driver->volatile_register);
 
+#if defined(CONFIG_SPI_MASTER)
+	/*
+	 * spi_page member of private data stores current status of page
+	 * register. 0 => page 0 selected, 1 => page 1 selected
+	 */
+	struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+	if(reg >= 0x80){
+		/* We are writing register in page 1 */
+		if(!da7210->spi_page){
+			/* Need to set page register first */
+			data[0] = 0x00;
+			data[1] = 0x80;		/* need to set seventh bit */
+			if (2 != codec->hw_write(codec->control_data, data, 2))
+				return -EIO;
+			cache[0] = 0x80;	/* Update cache */
+			da7210->spi_page = 1;	/* Update local status */
+		}
+			
+	}else {
+		/* We are writing register in page 0 */
+		if(da7210->spi_page){
+			/* Need to reset page register first */
+			data[0] = 0x80;
+			data[1] = 0x00;		/* need to reset seventh bit */
+			if (2 != codec->hw_write(codec->control_data, data, 2))
+				return -EIO;
+			cache[0x80] = 0x00;	/* Update cache */
+			da7210->spi_page = 0;	/* Update local status */
+		}
+	}
+#endif
+
 	data[0] = reg & 0xff;
 	data[1] = value & 0xff;
 
Any comments on this code?

Is there any better place to put this extra logic? Any way to accommodate this in to generic soc-io functions?


Thanks,

-- Ashish

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-08-25 10:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-25 11:03 How to handle special SPI read/write for ASoC codec driver? Ashish Chavan
  -- strict thread matches above, loose matches on Subject: below --
2011-08-25 11:09 Ashish Chavan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).