Unverified Commit 49e2e353 authored by Shenghao Ding's avatar Shenghao Ding Committed by Mark Brown
Browse files

ASoC: tas2781: Add Calibration Kcontrols for Chromebook



Add calibration related kcontrol for speaker impedance calibration and
speaker leakage check for Chromebook.

Signed-off-by: default avatarShenghao Ding <shenghao-ding@ti.com>
Link: https://patch.msgid.link/20240911232739.1509-1-shenghao-ding@ti.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 0b117e58
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -49,12 +49,59 @@
/*I2C Checksum */
#define TASDEVICE_I2CChecksum		TASDEVICE_REG(0x0, 0x0, 0x7E)

/* XM_340 */
#define	TASDEVICE_XM_A1_REG	TASDEVICE_REG(0x64, 0x63, 0x3c)
/* XM_341 */
#define	TASDEVICE_XM_A2_REG	TASDEVICE_REG(0x64, 0x63, 0x38)

/* Volume control */
#define TAS2563_DVC_LVL			TASDEVICE_REG(0x00, 0x02, 0x0C)
#define TAS2781_DVC_LVL			TASDEVICE_REG(0x0, 0x0, 0x1A)
#define TAS2781_AMP_LEVEL		TASDEVICE_REG(0x0, 0x0, 0x03)
#define TAS2781_AMP_LEVEL_MASK		GENMASK(5, 1)

#define TAS2563_IDLE		TASDEVICE_REG(0x00, 0x00, 0x3e)
#define TAS2563_PRM_R0_REG		TASDEVICE_REG(0x00, 0x0f, 0x34)

#define TAS2563_RUNTIME_RE_REG_TF	TASDEVICE_REG(0x64, 0x02, 0x70)
#define TAS2563_RUNTIME_RE_REG		TASDEVICE_REG(0x64, 0x02, 0x48)

#define TAS2563_PRM_ENFF_REG		TASDEVICE_REG(0x00, 0x0d, 0x54)
#define TAS2563_PRM_DISTCK_REG		TASDEVICE_REG(0x00, 0x0d, 0x58)
#define TAS2563_PRM_TE_SCTHR_REG	TASDEVICE_REG(0x00, 0x0f, 0x60)
#define TAS2563_PRM_PLT_FLAG_REG	TASDEVICE_REG(0x00, 0x0d, 0x74)
#define TAS2563_PRM_SINEGAIN_REG	TASDEVICE_REG(0x00, 0x0d, 0x7c)
/* prm_Int_B0 */
#define TAS2563_TE_TA1_REG		TASDEVICE_REG(0x00, 0x10, 0x0c)
/* prm_Int_A1 */
#define TAS2563_TE_TA1_AT_REG		TASDEVICE_REG(0x00, 0x10, 0x10)
/* prm_TE_Beta */
#define TAS2563_TE_TA2_REG		TASDEVICE_REG(0x00, 0x0f, 0x64)
/* prm_TE_Beta1 */
#define TAS2563_TE_AT_REG		TASDEVICE_REG(0x00, 0x0f, 0x68)
/* prm_TE_1_Beta1 */
#define TAS2563_TE_DT_REG		TASDEVICE_REG(0x00, 0x0f, 0x70)

#define TAS2781_PRM_INT_MASK_REG	TASDEVICE_REG(0x00, 0x00, 0x3b)
#define TAS2781_PRM_CLK_CFG_REG		TASDEVICE_REG(0x00, 0x00, 0x5c)
#define TAS2781_PRM_RSVD_REG		TASDEVICE_REG(0x00, 0x01, 0x19)
#define TAS2781_PRM_TEST_57_REG		TASDEVICE_REG(0x00, 0xfd, 0x39)
#define TAS2781_PRM_TEST_62_REG		TASDEVICE_REG(0x00, 0xfd, 0x3e)
#define TAS2781_PRM_PVDD_UVLO_REG	TASDEVICE_REG(0x00, 0x00, 0x71)
#define TAS2781_PRM_CHNL_0_REG		TASDEVICE_REG(0x00, 0x00, 0x03)
#define TAS2781_PRM_NG_CFG0_REG		TASDEVICE_REG(0x00, 0x00, 0x35)
#define TAS2781_PRM_IDLE_CH_DET_REG	TASDEVICE_REG(0x00, 0x00, 0x66)
#define TAS2781_PRM_PLT_FLAG_REG	TASDEVICE_REG(0x00, 0x14, 0x38)
#define TAS2781_PRM_SINEGAIN_REG	TASDEVICE_REG(0x00, 0x14, 0x40)
#define TAS2781_PRM_SINEGAIN2_REG	TASDEVICE_REG(0x00, 0x14, 0x44)

#define TAS2781_TEST_UNLOCK_REG		TASDEVICE_REG(0x00, 0xFD, 0x0D)
#define TAS2781_TEST_PAGE_UNLOCK	0x0D

#define TAS2781_RUNTIME_LATCH_RE_REG	TASDEVICE_REG(0x00, 0x00, 0x49)
#define TAS2781_RUNTIME_RE_REG_TF	TASDEVICE_REG(0x64, 0x62, 0x48)
#define TAS2781_RUNTIME_RE_REG		TASDEVICE_REG(0x64, 0x63, 0x44)

#define TASDEVICE_CMD_SING_W		0x1
#define TASDEVICE_CMD_BURST		0x2
#define TASDEVICE_CMD_DELAY		0x3
@@ -70,7 +117,15 @@ enum device_catlog_id {
	OTHERS
};

struct bulk_reg_val {
	int reg;
	unsigned char val[4];
	unsigned char val_len;
	bool is_locked;
};

struct tasdevice {
	struct bulk_reg_val *cali_data_backup;
	struct tasdevice_fw *cali_data_fmw;
	unsigned int dev_addr;
	unsigned int err_code;
@@ -81,9 +136,19 @@ struct tasdevice {
	bool is_loaderr;
};

struct cali_reg {
	unsigned int r0_reg;
	unsigned int r0_low_reg;
	unsigned int invr0_reg;
	unsigned int pow_reg;
	unsigned int tlimit_reg;
};

struct calidata {
	unsigned char *data;
	unsigned long total_sz;
	struct cali_reg cali_reg_array;
	unsigned int cali_dat_sz_per_dev;
};

struct tasdevice_priv {
@@ -119,6 +184,7 @@ struct tasdevice_priv {
	bool force_fwload_status;
	bool playback_started;
	bool isacpi;
	bool is_user_space_calidata;
	unsigned int global_addr;

	int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv,
@@ -145,6 +211,8 @@ int tasdevice_init(struct tasdevice_priv *tas_priv);
void tasdevice_remove(struct tasdevice_priv *tas_priv);
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
int tasdev_chn_switch(struct tasdevice_priv *tas_priv,
	unsigned short chn);
int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned int *value);
int tasdevice_dev_write(struct tasdevice_priv *tas_priv,
+26 −0
Original line number Diff line number Diff line
@@ -88,6 +88,32 @@ static int tasdevice_change_chn_book(struct tasdevice_priv *tas_priv,
	return ret;
}

int tasdev_chn_switch(struct tasdevice_priv *tas_priv,
	unsigned short chn)
{
	struct i2c_client *client = (struct i2c_client *)tas_priv->client;
	struct tasdevice *tasdev = &tas_priv->tasdevice[chn];
	struct regmap *map = tas_priv->regmap;
	int ret;

	if (client->addr != tasdev->dev_addr) {
		client->addr = tasdev->dev_addr;
		/* All devices share the same regmap, clear the page
		 * inside regmap once switching to another device.
		 * Register 0 at any pages and any books inside tas2781
		 * is the same one for page-switching.
		 */
		ret = regmap_write(map, TASDEVICE_PAGE_SELECT, 0);
		if (ret < 0) {
			dev_err(tas_priv->dev, "%s, E=%d\n", __func__, ret);
			return ret;
		}
		return 1;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(tasdev_chn_switch);

int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned int *val)
{
+51 −9
Original line number Diff line number Diff line
@@ -2151,20 +2151,61 @@ static int tasdevice_load_data(struct tasdevice_priv *tas_priv,

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

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

	/* No calibrated data for current devices, playback will go ahead. */
	if (!cal_fmw)
		if (cal)
			load_calib_data(priv, &cal->dev_data);
		return;

	cal = cal_fmw->calibrations;
	if (!cal)
	}
	if (!priv->is_user_space_calidata)
		return;
	/* load calibrated data from user space */
	if (data[k] != i) {
		dev_err(priv->dev, "%s: no cal-data for dev %d from usr-spc\n",
			__func__, i);
		return;
	}
	k++;

	load_calib_data(priv, &cal->dev_data);
	rc = tasdevice_dev_bulk_write(priv, i, p->r0_reg, &(data[k]), 4);
	if (rc < 0) {
		dev_err(priv->dev, "chn %d r0_reg bulk_wr err = %d\n", i, rc);
		return;
	}
	k += 4;
	rc = tasdevice_dev_bulk_write(priv, i, p->r0_low_reg, &(data[k]), 4);
	if (rc < 0) {
		dev_err(priv->dev, "chn %d r0_low_reg err = %d\n", i, rc);
		return;
	}
	k += 4;
	rc = tasdevice_dev_bulk_write(priv, i, p->invr0_reg, &(data[k]), 4);
	if (rc < 0) {
		dev_err(priv->dev, "chn %d invr0_reg err = %d\n", i, rc);
		return;
	}
	k += 4;
	rc = tasdevice_dev_bulk_write(priv, i, p->pow_reg, &(data[k]), 4);
	if (rc < 0) {
		dev_err(priv->dev, "chn %d pow_reg bulk_wr err = %d\n", i, rc);
		return;
	}
	k += 4;
	rc = tasdevice_dev_bulk_write(priv, i, p->tlimit_reg, &(data[k]), 4);
	if (rc < 0) {
		dev_err(priv->dev, "chn %d tlimit_reg err = %d\n", i, rc);
		return;
	}
}

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

	status |= cfg_info[rca_conf_no]->active_dev;

+885 −2

File changed.

Preview size limit exceeded, changes collapsed.