Lines Matching +full:calibration +full:- +full:data

1 // SPDX-License-Identifier: GPL-2.0
7 // Author: Shenghao Ding <shenghao-ding@ti.com>
37 * The order of calibrated-data writing function is a bit different from the
38 * order in UEFI. Here is the conversion to match the order of calibrated-data
41 static void cali_cnv(unsigned char *data, unsigned int base, int offset) in cali_cnv() argument
45 memcpy(&reg_data, &data[base], sizeof(reg_data)); in cali_cnv()
46 /* the data order has to be swapped between r0_low_reg and inv0_reg */ in cali_cnv()
49 cpu_to_be32_array((__force __be32 *)(data + offset + 1), in cali_cnv()
55 struct calidata *cali_data = &p->cali_data; in tas2781_apply_calib()
56 struct cali_reg *r = &cali_data->cali_reg_array; in tas2781_apply_calib()
57 unsigned char *data = cali_data->data; in tas2781_apply_calib() local
58 unsigned int *tmp_val = (unsigned int *)data; in tas2781_apply_calib()
72 * New features were added in calibrated Data V3: in tas2781_apply_calib()
73 * 1. Added calibration registers address define in in tas2781_apply_calib()
75 * New features were added in calibrated Data V2: in tas2781_apply_calib()
77 * uniqie_id for multi-link solutions in tas2781_apply_calib()
80 * Layout of calibrated data V2 in UEFI(total 256 bytes): in tas2781_apply_calib()
82 * Data-Group-Sum (4 bytes) in tas2781_apply_calib()
83 * TimeStamp of Calibration (4 bytes) in tas2781_apply_calib()
84 * for (i = 0; i < Data-Group-Sum; i++) { in tas2781_apply_calib()
85 * if (Data type != 0x80) (4 bytes) in tas2781_apply_calib()
86 * Calibrated Data of Device #i (20 bytes) in tas2781_apply_calib()
88 * Calibration registers address (5*4 = 20 bytes) in tas2781_apply_calib()
89 * # V2: No reg addr in data grp section. in tas2781_apply_calib()
95 crc = crc32(~0, data, (3 + tmp_val[1] * 6) * 4) ^ ~0; in tas2781_apply_calib()
98 cali_data->total_sz = 0; in tas2781_apply_calib()
99 dev_err(p->dev, "%s: CRC error\n", __func__); in tas2781_apply_calib()
108 buf = &data[(oft + i + 1) * 4]; in tas2781_apply_calib()
113 l = j * (cali_data->cali_dat_sz_per_dev + 1); in tas2781_apply_calib()
114 if (k >= p->ndev || l > oft * 4) { in tas2781_apply_calib()
115 dev_err(p->dev, "%s: dev sum error\n", in tas2781_apply_calib()
117 cali_data->total_sz = 0; in tas2781_apply_calib()
121 data[l] = k; in tas2781_apply_calib()
123 cali_cnv(data, 4 * oft, l); in tas2781_apply_calib()
129 * Calibration data is in V1 format. in tas2781_apply_calib()
136 * int TimeStamp of Calibration (4 bytes) in tas2781_apply_calib()
140 crc = crc32(~0, data, 84) ^ ~0; in tas2781_apply_calib()
142 cali_data->total_sz = 0; in tas2781_apply_calib()
143 dev_err(p->dev, "%s: V1 CRC error\n", __func__); in tas2781_apply_calib()
147 for (j = p->ndev - 1; j >= 0; j--) { in tas2781_apply_calib()
148 l = j * (cali_data->cali_dat_sz_per_dev + 1); in tas2781_apply_calib()
149 cali_cnv(data, cali_data->cali_dat_sz_per_dev * j, l); in tas2781_apply_calib()
150 data[l] = j; in tas2781_apply_calib()
154 if (p->dspbin_typ == TASDEV_BASIC) { in tas2781_apply_calib()
155 r->r0_reg = cali_reg[0]; in tas2781_apply_calib()
156 r->invr0_reg = cali_reg[1]; in tas2781_apply_calib()
157 r->r0_low_reg = cali_reg[2]; in tas2781_apply_calib()
158 r->pow_reg = cali_reg[3]; in tas2781_apply_calib()
159 r->tlimit_reg = cali_reg[4]; in tas2781_apply_calib()
162 p->is_user_space_calidata = true; in tas2781_apply_calib()
163 cali_data->total_sz = p->ndev * (cali_data->cali_dat_sz_per_dev + 1); in tas2781_apply_calib()
167 * Update the calibration data, including speaker impedance, f0, etc,
168 * into algo. Calibrate data is done by manufacturer in the factory.
169 * The data is used by Algo for calculating the speaker temperature,
171 * Calibration data format in EFI is V2, since 2024.
176 * GUID was used for data access in BIOS, it was provided by board in tas2781_save_calibration()
181 * Some devices save the calibrated data into L"CALI_DATA", in tas2781_save_calibration()
188 struct tasdevice_priv *p = hda->priv; in tas2781_save_calibration()
189 struct calidata *cali_data = &p->cali_data; in tas2781_save_calibration()
192 unsigned char *data; in tas2781_save_calibration() local
197 dev_err(p->dev, "%s: NO EFI FOUND!\n", __func__); in tas2781_save_calibration()
198 return -EINVAL; in tas2781_save_calibration()
201 if (hda->catlog_id < LENOVO) in tas2781_save_calibration()
202 efi_guid = tasdev_fct_efi_guid[hda->catlog_id]; in tas2781_save_calibration()
204 cali_data->cali_dat_sz_per_dev = 20; in tas2781_save_calibration()
205 size = p->ndev * (cali_data->cali_dat_sz_per_dev + 1); in tas2781_save_calibration()
210 cali_data->total_sz = total_sz > size ? total_sz : size; in tas2781_save_calibration()
212 /* Allocate data buffer of data_size bytes */ in tas2781_save_calibration()
213 data = cali_data->data = devm_kzalloc(p->dev, in tas2781_save_calibration()
214 cali_data->total_sz, GFP_KERNEL); in tas2781_save_calibration()
215 if (!data) { in tas2781_save_calibration()
216 status = -ENOMEM; in tas2781_save_calibration()
221 &attr, &cali_data->total_sz, data); in tas2781_save_calibration()
223 /* Check whether get the calibrated data */ in tas2781_save_calibration()
229 cali_data->total_sz = 0; in tas2781_save_calibration()
244 component_del(tas_hda->dev, ops); in tas2781_hda_remove()
246 pm_runtime_get_sync(tas_hda->dev); in tas2781_hda_remove()
247 pm_runtime_disable(tas_hda->dev); in tas2781_hda_remove()
249 pm_runtime_put_noidle(tas_hda->dev); in tas2781_hda_remove()
251 tasdevice_remove(tas_hda->priv); in tas2781_hda_remove()
260 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in tasdevice_info_profile()
261 uinfo->count = 1; in tasdevice_info_profile()
262 uinfo->value.integer.min = 0; in tasdevice_info_profile()
263 uinfo->value.integer.max = tas_priv->rcabin.ncfgs - 1; in tasdevice_info_profile()
274 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in tasdevice_info_programs()
275 uinfo->count = 1; in tasdevice_info_programs()
276 uinfo->value.integer.min = 0; in tasdevice_info_programs()
277 uinfo->value.integer.max = tas_priv->fmw->nr_programs - 1; in tasdevice_info_programs()
287 struct tasdevice_fw *tas_fw = tas_priv->fmw; in tasdevice_info_config()
289 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in tasdevice_info_config()
290 uinfo->count = 1; in tasdevice_info_config()
291 uinfo->value.integer.min = 0; in tasdevice_info_config()
292 uinfo->value.integer.max = tas_fw->nr_configurations - 1; in tasdevice_info_config()
303 ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id; in tasdevice_get_profile_id()
305 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__, in tasdevice_get_profile_id()
306 kcontrol->id.name, tas_priv->rcabin.profile_cfg_id); in tasdevice_get_profile_id()
316 int profile_id = ucontrol->value.integer.value[0]; in tasdevice_set_profile_id()
317 int max = tas_priv->rcabin.ncfgs - 1; in tasdevice_set_profile_id()
322 guard(mutex)(&tas_priv->codec_lock); in tasdevice_set_profile_id()
324 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__, in tasdevice_set_profile_id()
325 kcontrol->id.name, tas_priv->rcabin.profile_cfg_id, val); in tasdevice_set_profile_id()
327 if (tas_priv->rcabin.profile_cfg_id != val) { in tasdevice_set_profile_id()
328 tas_priv->rcabin.profile_cfg_id = val; in tasdevice_set_profile_id()
341 ucontrol->value.integer.value[0] = tas_priv->cur_prog; in tasdevice_program_get()
343 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__, in tasdevice_program_get()
344 kcontrol->id.name, tas_priv->cur_prog); in tasdevice_program_get()
354 struct tasdevice_fw *tas_fw = tas_priv->fmw; in tasdevice_program_put()
355 int nr_program = ucontrol->value.integer.value[0]; in tasdevice_program_put()
356 int max = tas_fw->nr_programs - 1; in tasdevice_program_put()
361 guard(mutex)(&tas_priv->codec_lock); in tasdevice_program_put()
363 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__, in tasdevice_program_put()
364 kcontrol->id.name, tas_priv->cur_prog, val); in tasdevice_program_put()
366 if (tas_priv->cur_prog != val) { in tasdevice_program_put()
367 tas_priv->cur_prog = val; in tasdevice_program_put()
380 ucontrol->value.integer.value[0] = tas_priv->cur_conf; in tasdevice_config_get()
382 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__, in tasdevice_config_get()
383 kcontrol->id.name, tas_priv->cur_conf); in tasdevice_config_get()
393 struct tasdevice_fw *tas_fw = tas_priv->fmw; in tasdevice_config_put()
394 int nr_config = ucontrol->value.integer.value[0]; in tasdevice_config_put()
395 int max = tas_fw->nr_configurations - 1; in tasdevice_config_put()
400 guard(mutex)(&tas_priv->codec_lock); in tasdevice_config_put()
402 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__, in tasdevice_config_put()
403 kcontrol->id.name, tas_priv->cur_conf, val); in tasdevice_config_put()
405 if (tas_priv->cur_conf != val) { in tasdevice_config_put()
406 tas_priv->cur_conf = val; in tasdevice_config_put()
416 MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>");