ASoC: tlv320aic26: Convert to direct regmap API usage
authorMark Brown <broonie@linaro.org>
Wed, 25 Sep 2013 12:29:44 +0000 (13:29 +0100)
committerMark Brown <broonie@linaro.org>
Wed, 25 Sep 2013 12:30:59 +0000 (13:30 +0100)
This moves us towards being able to remove the duplicated register I/O
code in ASoC.

The datasheet and the driver document the device as having a register map
divided into pages but since the paging is actually done by sending the
page address and the register address with each transaction this is no
different to having a simple register address. The datasheet does also
document the low five bits of the 16 bit "command" as unused which we could
represent as padding but it seems simpler and less confusing to things
that use block transfers or autoincrement to represent these as part of
the register address.

Signed-off-by: Mark Brown <broonie@linaro.org>
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic26.h

index 4d8244750f233fe1c90c0387fe6f68c8cfc80052..94a658fa6d97408e84682cea3e3ecc4c9a01cc1d 100644 (file)
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
 /* AIC26 driver private data */
 struct aic26 {
        struct spi_device *spi;
+       struct regmap *regmap;
        struct snd_soc_codec *codec;
        int master;
        int datfm;
@@ -40,72 +41,6 @@ struct aic26 {
        int keyclick_len;
 };
 
-/* ---------------------------------------------------------------------
- * Register access routines
- */
-static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
-                                  unsigned int reg)
-{
-       struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
-       u16 *cache = codec->reg_cache;
-       u16 cmd, value;
-       u8 buffer[2];
-       int rc;
-
-       if (reg >= AIC26_NUM_REGS) {
-               WARN_ON_ONCE(1);
-               return 0;
-       }
-
-       /* Do SPI transfer; first 16bits are command; remaining is
-        * register contents */
-       cmd = AIC26_READ_COMMAND_WORD(reg);
-       buffer[0] = (cmd >> 8) & 0xff;
-       buffer[1] = cmd & 0xff;
-       rc = spi_write_then_read(aic26->spi, buffer, 2, buffer, 2);
-       if (rc) {
-               dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
-               return -EIO;
-       }
-       value = (buffer[0] << 8) | buffer[1];
-
-       /* Update the cache before returning with the value */
-       cache[reg] = value;
-       return value;
-}
-
-static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
-                          unsigned int value)
-{
-       struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
-       u16 *cache = codec->reg_cache;
-       u16 cmd;
-       u8 buffer[4];
-       int rc;
-
-       if (reg >= AIC26_NUM_REGS) {
-               WARN_ON_ONCE(1);
-               return -EINVAL;
-       }
-
-       /* Do SPI transfer; first 16bits are command; remaining is data
-        * to write into register */
-       cmd = AIC26_WRITE_COMMAND_WORD(reg);
-       buffer[0] = (cmd >> 8) & 0xff;
-       buffer[1] = cmd & 0xff;
-       buffer[2] = value >> 8;
-       buffer[3] = value;
-       rc = spi_write(aic26->spi, buffer, 4);
-       if (rc) {
-               dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
-               return -EIO;
-       }
-
-       /* update cache before returning */
-       cache[reg] = value;
-       return 0;
-}
-
 static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = {
 SND_SOC_DAPM_INPUT("MICIN"),
 SND_SOC_DAPM_INPUT("AUX"),
@@ -360,6 +295,8 @@ static int aic26_probe(struct snd_soc_codec *codec)
        struct aic26 *aic26 = dev_get_drvdata(codec->dev);
        int ret, reg;
 
+       snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
+
        aic26->codec = codec;
 
        /* Reset the codec to power on defaults */
@@ -385,8 +322,6 @@ static int aic26_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver aic26_soc_codec_dev = {
        .probe = aic26_probe,
-       .read = aic26_reg_read,
-       .write = aic26_reg_write,
        .controls = aic26_snd_controls,
        .num_controls = ARRAY_SIZE(aic26_snd_controls),
        .dapm_widgets = tlv320aic26_dapm_widgets,
@@ -395,6 +330,11 @@ static struct snd_soc_codec_driver aic26_soc_codec_dev = {
        .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes),
 };
 
+static const struct regmap_config aic26_regmap = {
+       .reg_bits = 16,
+       .val_bits = 16,
+};
+
 /* ---------------------------------------------------------------------
  * SPI device portion of driver: probe and release routines and SPI
  *                              driver registration.
@@ -411,6 +351,10 @@ static int aic26_spi_probe(struct spi_device *spi)
        if (!aic26)
                return -ENOMEM;
 
+       aic26->regmap = devm_regmap_init_spi(spi, &aic26_regmap);
+       if (IS_ERR(aic26->regmap))
+               return PTR_ERR(aic26->regmap);
+
        /* Initialize the driver data */
        aic26->spi = spi;
        dev_set_drvdata(&spi->dev, aic26);
index 67f19c3bebe6a88a6d86a81f32b2f6dca25c65ec..629b85e75409383df910d448eabb97b2e8b5dc8e 100644 (file)
@@ -9,10 +9,7 @@
 #define _TLV320AIC16_H_
 
 /* AIC26 Registers */
-#define AIC26_READ_COMMAND_WORD(addr)  ((1 << 15) | (addr << 5))
-#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
-#define AIC26_PAGE_ADDR(page, offset)  ((page << 6) | offset)
-#define AIC26_NUM_REGS                 AIC26_PAGE_ADDR(3, 0)
+#define AIC26_PAGE_ADDR(page, offset)  ((page << 11) | offset << 5)
 
 /* Page 0: Auxiliary data registers */
 #define AIC26_REG_BAT1                 AIC26_PAGE_ADDR(0, 0x05)