Skip to content

Commit 49e2e35

Browse files
Shenghao-Dingbroonie
authored andcommitted
ASoC: tas2781: Add Calibration Kcontrols for Chromebook
Add calibration related kcontrol for speaker impedance calibration and speaker leakage check for Chromebook. Signed-off-by: Shenghao Ding <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 0b117e5 commit 49e2e35

File tree

4 files changed

+1030
-11
lines changed

4 files changed

+1030
-11
lines changed

include/sound/tas2781.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,59 @@
4949
/*I2C Checksum */
5050
#define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E)
5151

52+
/* XM_340 */
53+
#define TASDEVICE_XM_A1_REG TASDEVICE_REG(0x64, 0x63, 0x3c)
54+
/* XM_341 */
55+
#define TASDEVICE_XM_A2_REG TASDEVICE_REG(0x64, 0x63, 0x38)
56+
5257
/* Volume control */
5358
#define TAS2563_DVC_LVL TASDEVICE_REG(0x00, 0x02, 0x0C)
5459
#define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1A)
5560
#define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03)
5661
#define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1)
5762

63+
#define TAS2563_IDLE TASDEVICE_REG(0x00, 0x00, 0x3e)
64+
#define TAS2563_PRM_R0_REG TASDEVICE_REG(0x00, 0x0f, 0x34)
65+
66+
#define TAS2563_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x02, 0x70)
67+
#define TAS2563_RUNTIME_RE_REG TASDEVICE_REG(0x64, 0x02, 0x48)
68+
69+
#define TAS2563_PRM_ENFF_REG TASDEVICE_REG(0x00, 0x0d, 0x54)
70+
#define TAS2563_PRM_DISTCK_REG TASDEVICE_REG(0x00, 0x0d, 0x58)
71+
#define TAS2563_PRM_TE_SCTHR_REG TASDEVICE_REG(0x00, 0x0f, 0x60)
72+
#define TAS2563_PRM_PLT_FLAG_REG TASDEVICE_REG(0x00, 0x0d, 0x74)
73+
#define TAS2563_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x0d, 0x7c)
74+
/* prm_Int_B0 */
75+
#define TAS2563_TE_TA1_REG TASDEVICE_REG(0x00, 0x10, 0x0c)
76+
/* prm_Int_A1 */
77+
#define TAS2563_TE_TA1_AT_REG TASDEVICE_REG(0x00, 0x10, 0x10)
78+
/* prm_TE_Beta */
79+
#define TAS2563_TE_TA2_REG TASDEVICE_REG(0x00, 0x0f, 0x64)
80+
/* prm_TE_Beta1 */
81+
#define TAS2563_TE_AT_REG TASDEVICE_REG(0x00, 0x0f, 0x68)
82+
/* prm_TE_1_Beta1 */
83+
#define TAS2563_TE_DT_REG TASDEVICE_REG(0x00, 0x0f, 0x70)
84+
85+
#define TAS2781_PRM_INT_MASK_REG TASDEVICE_REG(0x00, 0x00, 0x3b)
86+
#define TAS2781_PRM_CLK_CFG_REG TASDEVICE_REG(0x00, 0x00, 0x5c)
87+
#define TAS2781_PRM_RSVD_REG TASDEVICE_REG(0x00, 0x01, 0x19)
88+
#define TAS2781_PRM_TEST_57_REG TASDEVICE_REG(0x00, 0xfd, 0x39)
89+
#define TAS2781_PRM_TEST_62_REG TASDEVICE_REG(0x00, 0xfd, 0x3e)
90+
#define TAS2781_PRM_PVDD_UVLO_REG TASDEVICE_REG(0x00, 0x00, 0x71)
91+
#define TAS2781_PRM_CHNL_0_REG TASDEVICE_REG(0x00, 0x00, 0x03)
92+
#define TAS2781_PRM_NG_CFG0_REG TASDEVICE_REG(0x00, 0x00, 0x35)
93+
#define TAS2781_PRM_IDLE_CH_DET_REG TASDEVICE_REG(0x00, 0x00, 0x66)
94+
#define TAS2781_PRM_PLT_FLAG_REG TASDEVICE_REG(0x00, 0x14, 0x38)
95+
#define TAS2781_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x14, 0x40)
96+
#define TAS2781_PRM_SINEGAIN2_REG TASDEVICE_REG(0x00, 0x14, 0x44)
97+
98+
#define TAS2781_TEST_UNLOCK_REG TASDEVICE_REG(0x00, 0xFD, 0x0D)
99+
#define TAS2781_TEST_PAGE_UNLOCK 0x0D
100+
101+
#define TAS2781_RUNTIME_LATCH_RE_REG TASDEVICE_REG(0x00, 0x00, 0x49)
102+
#define TAS2781_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x62, 0x48)
103+
#define TAS2781_RUNTIME_RE_REG TASDEVICE_REG(0x64, 0x63, 0x44)
104+
58105
#define TASDEVICE_CMD_SING_W 0x1
59106
#define TASDEVICE_CMD_BURST 0x2
60107
#define TASDEVICE_CMD_DELAY 0x3
@@ -70,7 +117,15 @@ enum device_catlog_id {
70117
OTHERS
71118
};
72119

120+
struct bulk_reg_val {
121+
int reg;
122+
unsigned char val[4];
123+
unsigned char val_len;
124+
bool is_locked;
125+
};
126+
73127
struct tasdevice {
128+
struct bulk_reg_val *cali_data_backup;
74129
struct tasdevice_fw *cali_data_fmw;
75130
unsigned int dev_addr;
76131
unsigned int err_code;
@@ -81,9 +136,19 @@ struct tasdevice {
81136
bool is_loaderr;
82137
};
83138

139+
struct cali_reg {
140+
unsigned int r0_reg;
141+
unsigned int r0_low_reg;
142+
unsigned int invr0_reg;
143+
unsigned int pow_reg;
144+
unsigned int tlimit_reg;
145+
};
146+
84147
struct calidata {
85148
unsigned char *data;
86149
unsigned long total_sz;
150+
struct cali_reg cali_reg_array;
151+
unsigned int cali_dat_sz_per_dev;
87152
};
88153

89154
struct tasdevice_priv {
@@ -119,6 +184,7 @@ struct tasdevice_priv {
119184
bool force_fwload_status;
120185
bool playback_started;
121186
bool isacpi;
187+
bool is_user_space_calidata;
122188
unsigned int global_addr;
123189

124190
int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv,
@@ -145,6 +211,8 @@ int tasdevice_init(struct tasdevice_priv *tas_priv);
145211
void tasdevice_remove(struct tasdevice_priv *tas_priv);
146212
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
147213
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
214+
int tasdev_chn_switch(struct tasdevice_priv *tas_priv,
215+
unsigned short chn);
148216
int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
149217
unsigned short chn, unsigned int reg, unsigned int *value);
150218
int tasdevice_dev_write(struct tasdevice_priv *tas_priv,

sound/soc/codecs/tas2781-comlib.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,32 @@ static int tasdevice_change_chn_book(struct tasdevice_priv *tas_priv,
8888
return ret;
8989
}
9090

91+
int tasdev_chn_switch(struct tasdevice_priv *tas_priv,
92+
unsigned short chn)
93+
{
94+
struct i2c_client *client = (struct i2c_client *)tas_priv->client;
95+
struct tasdevice *tasdev = &tas_priv->tasdevice[chn];
96+
struct regmap *map = tas_priv->regmap;
97+
int ret;
98+
99+
if (client->addr != tasdev->dev_addr) {
100+
client->addr = tasdev->dev_addr;
101+
/* All devices share the same regmap, clear the page
102+
* inside regmap once switching to another device.
103+
* Register 0 at any pages and any books inside tas2781
104+
* is the same one for page-switching.
105+
*/
106+
ret = regmap_write(map, TASDEVICE_PAGE_SELECT, 0);
107+
if (ret < 0) {
108+
dev_err(tas_priv->dev, "%s, E=%d\n", __func__, ret);
109+
return ret;
110+
}
111+
return 1;
112+
}
113+
return 0;
114+
}
115+
EXPORT_SYMBOL_GPL(tasdev_chn_switch);
116+
91117
int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
92118
unsigned short chn, unsigned int reg, unsigned int *val)
93119
{

sound/soc/codecs/tas2781-fmwlib.c

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,20 +2151,61 @@ static int tasdevice_load_data(struct tasdevice_priv *tas_priv,
21512151

21522152
static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i)
21532153
{
2154+
struct tasdevice_fw *cal_fmw = priv->tasdevice[i].cali_data_fmw;
2155+
struct calidata *cali_data = &priv->cali_data;
2156+
struct cali_reg *p = &cali_data->cali_reg_array;
2157+
unsigned char *data = cali_data->data;
21542158
struct tasdevice_calibration *cal;
2155-
struct tasdevice_fw *cal_fmw;
2159+
int k = i * (cali_data->cali_dat_sz_per_dev + 1);
2160+
int rc;
21562161

2157-
cal_fmw = priv->tasdevice[i].cali_data_fmw;
2162+
/* Load the calibrated data from cal bin file */
2163+
if (!priv->is_user_space_calidata && cal_fmw) {
2164+
cal = cal_fmw->calibrations;
21582165

2159-
/* No calibrated data for current devices, playback will go ahead. */
2160-
if (!cal_fmw)
2166+
if (cal)
2167+
load_calib_data(priv, &cal->dev_data);
21612168
return;
2162-
2163-
cal = cal_fmw->calibrations;
2164-
if (!cal)
2169+
}
2170+
if (!priv->is_user_space_calidata)
2171+
return;
2172+
/* load calibrated data from user space */
2173+
if (data[k] != i) {
2174+
dev_err(priv->dev, "%s: no cal-data for dev %d from usr-spc\n",
2175+
__func__, i);
21652176
return;
2177+
}
2178+
k++;
21662179

2167-
load_calib_data(priv, &cal->dev_data);
2180+
rc = tasdevice_dev_bulk_write(priv, i, p->r0_reg, &(data[k]), 4);
2181+
if (rc < 0) {
2182+
dev_err(priv->dev, "chn %d r0_reg bulk_wr err = %d\n", i, rc);
2183+
return;
2184+
}
2185+
k += 4;
2186+
rc = tasdevice_dev_bulk_write(priv, i, p->r0_low_reg, &(data[k]), 4);
2187+
if (rc < 0) {
2188+
dev_err(priv->dev, "chn %d r0_low_reg err = %d\n", i, rc);
2189+
return;
2190+
}
2191+
k += 4;
2192+
rc = tasdevice_dev_bulk_write(priv, i, p->invr0_reg, &(data[k]), 4);
2193+
if (rc < 0) {
2194+
dev_err(priv->dev, "chn %d invr0_reg err = %d\n", i, rc);
2195+
return;
2196+
}
2197+
k += 4;
2198+
rc = tasdevice_dev_bulk_write(priv, i, p->pow_reg, &(data[k]), 4);
2199+
if (rc < 0) {
2200+
dev_err(priv->dev, "chn %d pow_reg bulk_wr err = %d\n", i, rc);
2201+
return;
2202+
}
2203+
k += 4;
2204+
rc = tasdevice_dev_bulk_write(priv, i, p->tlimit_reg, &(data[k]), 4);
2205+
if (rc < 0) {
2206+
dev_err(priv->dev, "chn %d tlimit_reg err = %d\n", i, rc);
2207+
return;
2208+
}
21682209
}
21692210

21702211
int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
@@ -2259,9 +2300,10 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
22592300
tas_priv->tasdevice[i].cur_conf = cfg_no;
22602301
}
22612302
}
2262-
} else
2303+
} else {
22632304
dev_dbg(tas_priv->dev, "%s: Unneeded loading dsp conf %d\n",
22642305
__func__, cfg_no);
2306+
}
22652307

22662308
status |= cfg_info[rca_conf_no]->active_dev;
22672309

0 commit comments

Comments
 (0)