Read/Write registers by i2c directly. Add dac volume control.
authorTracy Yi <tracy-yi@ti.com>
Mon, 19 Feb 2018 15:57:50 +0000 (23:57 +0800)
committerTracy Yi <tracy-yi@ti.com>
Mon, 19 Feb 2018 15:57:50 +0000 (23:57 +0800)
Signed-off-by: Tracy Yi <tracy-yi@ti.com>
tas2770-codec.c
tas2770-regmap.c

index 1dabd7b7b9d74796d7875abe7fa956c3f41b9090..8238b7b7cd987d0c3d9cb7d9080500ad0d2ebcb6 100644 (file)
@@ -54,52 +54,86 @@ static unsigned int tas2770_codec_read(struct snd_soc_codec *codec,
 {
        struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
        int nResult = 0;
-       unsigned int value = 0;
-
-       mutex_lock(&pTAS2770->dev_lock);
-
-       nResult = regmap_read(pTAS2770->regmap, reg, &value);
+       unsigned int value;
+       nResult = tas2770_read(pTAS2770, reg);
 
        if (nResult < 0)
                dev_err(pTAS2770->dev, "%s, ERROR, reg=0x%x, E=%d\n",
                        __func__, reg, nResult);
-       else
+       else {
+               value = nResult;
                dev_dbg(pTAS2770->dev, "%s, reg: 0x%x, value: 0x%x\n",
                                __func__, reg, value);
+       }
+       return nResult;
+}
 
+int tas2770_read(struct tas2770_priv *pTAS2770, unsigned int reg)
+{
+       int nResult = 0;
+       struct i2c_msg msg_buf[2];
+       unsigned char data1, data2;
+
+       data2 = (unsigned char)reg;
+       msg_buf[0].addr = pTAS2770->mnAddr;
+       msg_buf[0].len = 1;
+       msg_buf[0].flags = 0;
+       msg_buf[0].buf = &data2;
+
+       msg_buf[1].addr = pTAS2770->mnAddr;
+       msg_buf[1].len = 1;
+       msg_buf[1].flags = I2C_M_RD;
+       msg_buf[1].buf = &data1;
+
+       mutex_lock(&pTAS2770->dev_lock);
+       nResult = i2c_transfer(pTAS2770->adapter, msg_buf, 2);
        mutex_unlock(&pTAS2770->dev_lock);
 
        if (nResult >= 0)
-               return value;
+               return data1;
        else
                return nResult;
 }
 
 
 static int tas2770_codec_write(struct snd_soc_codec *codec, unsigned int reg,
-       unsigned int value)
+               unsigned int value)
 {
-       struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
-
        int nResult = 0;
+       struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
 
-       mutex_lock(&pTAS2770->dev_lock);
+       nResult = tas2770_write(pTAS2770, reg, value);
 
-       nResult = regmap_write(pTAS2770->regmap, reg, value);
        if (nResult < 0)
                dev_err(pTAS2770->dev, "%s, ERROR, reg=0x%x, E=%d\n",
                        __func__, reg, nResult);
        else
                dev_dbg(pTAS2770->dev, "%s, reg: 0x%x, 0x%x\n",
                        __func__, reg, value);
+       return nResult;
+}
 
+int tas2770_write(struct tas2770_priv *pTAS2770,  unsigned int reg, unsigned int value)
+{
+       int nResult = 0;
+       struct i2c_msg msg;
+       unsigned char data[2];
+
+       msg.addr = pTAS2770->mnAddr;
+       msg.len = 2;
+       msg.flags = 0;
+       msg.buf = data;
+
+       data[0] = (unsigned char)reg;
+       data[1] = (unsigned char)value;
+
+       mutex_lock(&pTAS2770->dev_lock);
+       nResult = i2c_transfer(pTAS2770->adapter, &msg, 1);
        mutex_unlock(&pTAS2770->dev_lock);
 
        return nResult;
-
 }
 
-
 static int tas2770_codec_suspend(struct snd_soc_codec *codec)
 {
        struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
@@ -508,11 +542,15 @@ static int tas2770_codec_remove(struct snd_soc_codec *codec)
 }
 
 static DECLARE_TLV_DB_SCALE(tas2770_digital_tlv, 1100, 50, 0);
+static DECLARE_TLV_DB_SCALE(tas2770_playback_volume, -10000, 50, 0);
 
 static const struct snd_kcontrol_new tas2770_snd_controls[] = {
        SOC_SINGLE_TLV("Amp Output Level", TAS2770_PlaybackConfigurationReg0,
                0, TAS2770_PlaybackConfigurationReg0_AmplifierLevel40_Mask, 0,
                tas2770_digital_tlv),
+       SOC_SINGLE_TLV("Playback Volume", TAS2770_PlaybackConfigurationReg2,
+               0, TAS2770_PlaybackConfigurationReg2_DVCPCM70_Mask, 0,
+               tas2770_playback_volume),
 };
 
 static struct snd_soc_codec_driver soc_codec_driver_tas2770 = {
index 8038b28cf0e37924bb42204bedef6c7fdecf2dc6..2570843485ae4acc1059682131c0038dece1f7c3 100644 (file)
@@ -61,6 +61,7 @@ static bool tas2770_volatile(struct device *dev, unsigned int reg)
        switch (reg) {
        case TAS2770_Page: /* regmap implementation requires this */
        case TAS2770_SoftwareReset: /* always clears after write */
+       case TAS2770_PowerControl:
        case TAS2770_BrownOutPreventionReg0:/* has a self clearing bit */
        case TAS2770_LiveInterruptReg0:
        case TAS2770_LiveInterruptReg1:
@@ -361,7 +362,8 @@ static int tas2770_i2c_probe(struct i2c_client *client,
                disable_irq_nosync(pTAS2770->mnIRQ);
                INIT_DELAYED_WORK(&pTAS2770->irq_work, irq_work_routine);
        }
-
+       pTAS2770->mnAddr = client->addr;
+       pTAS2770->adapter = client->adapter;
        pTAS2770->hw_reset = tas2770_hw_reset;
        pTAS2770->enableIRQ = tas2770_enableIRQ;
        pTAS2770->runtime_suspend = tas2770_runtime_suspend;