From 6204f33cd5fa94562a2adcd93c4eae27dbc67d9c Mon Sep 17 00:00:00 2001 From: zhouwl Date: Mon, 20 Apr 2020 13:00:46 +0800 Subject: [PATCH] ASoC: aw882xx driver update This is Awinic official release, the key change is i2c_read function, use i2c_transfer to replace the old one, add thread_lock to protect i2c operation safety, in order to resolve a potential no sound risk after supporting different audio scenarios feature. NO_PROP_NEEDED: aw882xx doesn't use in bq-shm2018 products. Change-Id: I3daeb35c6a349c65bdb723d7f12430634abbf8f2 Signed-off-by: zhouwl Reviewed-on: https://gerrit.mot.com/1537490 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Hujun Liao Reviewed-by: Wen Xie Submit-Approved: Jira Key Reviewed-by: Yunfei Guo --- sound/soc/codecs/aw882xx.c | 54 ++++++++++++++++++++++++---------- sound/soc/codecs/aw882xx.h | 2 ++ sound/soc/codecs/aw882xx_reg.h | 18 ++++++++++-- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/sound/soc/codecs/aw882xx.c b/sound/soc/codecs/aw882xx.c index 973bcd49d788..c148b9eaea18 100644 --- a/sound/soc/codecs/aw882xx.c +++ b/sound/soc/codecs/aw882xx.c @@ -173,25 +173,36 @@ static int aw882xx_i2c_writes(struct aw882xx *aw882xx, } static int aw882xx_i2c_reads(struct aw882xx *aw882xx, - unsigned char reg_addr, unsigned char *buf, unsigned int len) + unsigned char reg_addr, unsigned char *data_buf, unsigned int data_len) { - int ret = -1; + int ret; + struct i2c_msg msg[] = { + [0] = { + .addr = aw882xx->i2c->addr, + .flags = 0, + .len = sizeof(uint8_t), + .buf = ®_addr, + }, + [1] = { + .addr = aw882xx->i2c->addr, + .flags = I2C_M_RD, + .len = data_len, + .buf = data_buf, + }, + }; - ret = i2c_smbus_write_byte(aw882xx->i2c, reg_addr); + ret = i2c_transfer(aw882xx->i2c->adapter, msg, ARRAY_SIZE(msg)); if (ret < 0) { pr_err("%s: i2c master send error, ret=%d\n", __func__, ret); return ret; - } - - ret = i2c_master_recv(aw882xx->i2c, buf, len); - if (ret != len) { + } else if (ret != AW882XX_I2C_READ_MSG_NUM) { pr_err("%s: couldn't read registers, return %d bytes\n", __func__, ret); - return ret; + return -ENXIO; } - return ret; + return 0; } static int aw882xx_i2c_write(struct aw882xx *aw882xx, @@ -343,7 +354,7 @@ static int aw882xx_sysst_check(struct aw882xx *aw882xx) for (i = 0; i < AW882XX_SYSST_CHECK_MAX; i++) { aw882xx_i2c_read(aw882xx, AW882XX_SYSST_REG, ®_val); - if ((reg_val & (~AW882XX_SYSST_CHECK_MASK)) == + if (((reg_val & (~AW882XX_SYSST_CHECK_MASK)) & AW882XX_SYSST_CHECK) == AW882XX_SYSST_CHECK) { ret = 0; break; @@ -453,9 +464,11 @@ static int aw882xx_set_vcalb(struct aw882xx *aw882xx) static void aw882xx_send_cali_re_to_dsp(struct aw882xx *aw882xx) { - int ret; - ret = aw_send_afe_cal_apr(AFE_PARAM_ID_AWDSP_RX_RE_L, - &aw882xx->cali_re, sizeof(int32_t), true); + int ret = 0; + if ((aw882xx != NULL) && (aw882xx->cali_re != ERRO_CALI_VALUE)) { + ret = aw_send_afe_cal_apr(AFE_PARAM_ID_AWDSP_RX_RE_L, + &aw882xx->cali_re, sizeof(int32_t), true); + } if (ret) pr_err("%s : set cali re to dsp failed 0x%x\n", __func__ , AFE_PARAM_ID_AWDSP_RX_RE_L); @@ -469,9 +482,9 @@ static void aw882xx_start(struct aw882xx *aw882xx) ret = aw882xx_get_cali_re_form_nv(&cali_re); if (ret < 0) { - cali_re = (DEFAULT_CALI_VALUE << 12); + cali_re = ERRO_CALI_VALUE; pr_err("%s: use default vaule %d", - __func__ , DEFAULT_CALI_VALUE); + __func__ , ERRO_CALI_VALUE); } ret = aw882xx_set_cali_re(aw882xx, cali_re); if (ret < 0) @@ -1223,6 +1236,7 @@ static int aw882xx_hw_params(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec; struct aw882xx *aw882xx = snd_soc_codec_get_drvdata(codec); unsigned int rate = 0; + uint32_t cco_mux_value; int reg_value = 0; int width = 0; @@ -1240,30 +1254,40 @@ static int aw882xx_hw_params(struct snd_pcm_substream *substream, switch (rate) { case 8000: reg_value = AW882XX_I2SSR_8KHZ_VALUE; + cco_mux_value = AW882XX_I2S_CCO_MUX_8_16_32KHZ_VALUE; break; case 16000: reg_value = AW882XX_I2SSR_16KHZ_VALUE; + cco_mux_value = AW882XX_I2S_CCO_MUX_8_16_32KHZ_VALUE; break; case 32000: reg_value = AW882XX_I2SSR_32KHZ_VALUE; + cco_mux_value = AW882XX_I2S_CCO_MUX_8_16_32KHZ_VALUE; break; case 44100: reg_value = AW882XX_I2SSR_44P1KHZ_VALUE; + cco_mux_value = AW882XX_I2S_CCO_MUX_EXC_8_16_32KHZ_VALUE; break; case 48000: reg_value = AW882XX_I2SSR_48KHZ_VALUE; + cco_mux_value = AW882XX_I2S_CCO_MUX_EXC_8_16_32KHZ_VALUE; break; case 96000: reg_value = AW882XX_I2SSR_96KHZ_VALUE; + cco_mux_value = AW882XX_I2S_CCO_MUX_EXC_8_16_32KHZ_VALUE; break; case 192000: reg_value = AW882XX_I2SSR_192KHZ_VALUE; + cco_mux_value = AW882XX_I2S_CCO_MUX_EXC_8_16_32KHZ_VALUE; break; default: reg_value = AW882XX_I2SSR_48KHZ_VALUE; + cco_mux_value = AW882XX_I2S_CCO_MUX_EXC_8_16_32KHZ_VALUE; pr_err("%s: rate can not support\n", __func__); break; } + aw882xx_i2c_write_bits(aw882xx, AW882XX_PLLCTRL1_REG, + AW882XX_I2S_CCO_MUX_MASK, cco_mux_value); /* set chip rate */ if (-1 != reg_value) { diff --git a/sound/soc/codecs/aw882xx.h b/sound/soc/codecs/aw882xx.h index 56743fe7192b..032a890d2bd3 100644 --- a/sound/soc/codecs/aw882xx.h +++ b/sound/soc/codecs/aw882xx.h @@ -7,6 +7,7 @@ * (See Linux kernel documentation: Documentation/i2c/writing-clients) */ #define MAX_I2C_BUFFER_SIZE 65536 +#define AW882XX_I2C_READ_MSG_NUM 2 #define AW882XX_FLAG_START_ON_MUTE (1 << 0) #define AW882XX_FLAG_SKIP_INTERRUPTS (1 << 1) @@ -25,6 +26,7 @@ #define DEFAULT_CALI_VALUE (7) +#define ERRO_CALI_VALUE (0) #define AFE_PARAM_ID_AWDSP_RX_SET_ENABLE (0x10013D11) #define AFE_PARAM_ID_AWDSP_RX_PARAMS (0x10013D12) #define AFE_PARAM_ID_AWDSP_TX_SET_ENABLE (0x10013D13) diff --git a/sound/soc/codecs/aw882xx_reg.h b/sound/soc/codecs/aw882xx_reg.h index 19beba16740b..5b1c179211ac 100644 --- a/sound/soc/codecs/aw882xx_reg.h +++ b/sound/soc/codecs/aw882xx_reg.h @@ -407,9 +407,7 @@ const unsigned char aw882xx_reg_access[AW882XX_REG_MAX] = { AW882XX_PLLS_LOCKED_VALUE)) #define AW882XX_SYSST_CHECK \ - (AW882XX_BSTS_FINISHED_VALUE | \ - AW882XX_SWS_SWITCHING_VALUE | \ - AW882XX_CLKS_TRIG_VALUE | \ + (AW882XX_CLKS_TRIG_VALUE | \ AW882XX_PLLS_LOCKED_VALUE) #define AW882XX_IIS_CHECK_MASK \ @@ -1176,6 +1174,20 @@ const unsigned char aw882xx_reg_access[AW882XX_REG_MAX] = { #define AW882XX_I2SSR_MASK \ (~(((1<