1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // TAS2781 HDA Shared Lib for I2C&SPI driver 4 // 5 // Copyright 2025 - 2026 Texas Instruments, Inc. 6 // 7 // Author: Shenghao Ding <shenghao-ding@ti.com> 8 9 #include <linux/component.h> 10 #include <linux/crc8.h> 11 #include <linux/crc32.h> 12 #include <linux/efi.h> 13 #include <linux/firmware.h> 14 #include <linux/i2c.h> 15 #include <linux/pm_runtime.h> 16 #include <sound/soc.h> 17 #include <sound/tas2781.h> 18 19 #include "tas2781_hda.h" 20 21 #define CALIBRATION_DATA_AREA_NUM 2 22 23 const efi_guid_t tasdev_fct_efi_guid[] = { 24 /* DELL */ 25 EFI_GUID(0xcc92382d, 0x6337, 0x41cb, 0xa8, 0x8b, 0x8e, 0xce, 0x74, 26 0x91, 0xea, 0x9f), 27 /* HP */ 28 EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, 0x5a, 29 0xa3, 0x5d, 0xb3), 30 /* LENOVO & OTHERS */ 31 EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc, 0x09, 0x43, 0xa3, 0xf4, 32 0x31, 0x0a, 0x92), 33 }; 34 EXPORT_SYMBOL_NS_GPL(tasdev_fct_efi_guid, "SND_HDA_SCODEC_TAS2781"); 35 36 /* 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 39 * writing function. 40 */ 41 static void cali_cnv(unsigned char *data, unsigned int base, int offset) 42 { 43 struct cali_reg reg_data; 44 45 memcpy(®_data, &data[base], sizeof(reg_data)); 46 /* the data order has to be swapped between r0_low_reg and inv0_reg */ 47 swap(reg_data.r0_low_reg, reg_data.invr0_reg); 48 49 cpu_to_be32_array((__force __be32 *)(data + offset + 1), 50 (u32 *)®_data, TASDEV_CALIB_N); 51 } 52 53 static void tas2781_apply_calib(struct tasdevice_priv *p) 54 { 55 struct calidata *cali_data = &p->cali_data; 56 struct cali_reg *r = &cali_data->cali_reg_array; 57 unsigned char *data = cali_data->data; 58 unsigned int *tmp_val = (unsigned int *)data; 59 unsigned int cali_reg[TASDEV_CALIB_N] = { 60 TASDEVICE_REG(0, 0x17, 0x74), 61 TASDEVICE_REG(0, 0x18, 0x0c), 62 TASDEVICE_REG(0, 0x18, 0x14), 63 TASDEVICE_REG(0, 0x13, 0x70), 64 TASDEVICE_REG(0, 0x18, 0x7c), 65 }; 66 unsigned int crc, oft, node_num; 67 unsigned char *buf; 68 int i, j, k, l; 69 70 if (tmp_val[0] == 2781) { 71 /* 72 * New features were added in calibrated Data V3: 73 * 1. Added calibration registers address define in 74 * a node, marked as Device id == 0x80. 75 * New features were added in calibrated Data V2: 76 * 1. Added some the fields to store the link_id and 77 * uniqie_id for multi-link solutions 78 * 2. Support flexible number of devices instead of 79 * fixed one in V1. 80 * Layout of calibrated data V2 in UEFI(total 256 bytes): 81 * ChipID (2781, 4 bytes) 82 * Data-Group-Sum (4 bytes) 83 * TimeStamp of Calibration (4 bytes) 84 * for (i = 0; i < Data-Group-Sum; i++) { 85 * if (Data type != 0x80) (4 bytes) 86 * Calibrated Data of Device #i (20 bytes) 87 * else 88 * Calibration registers address (5*4 = 20 bytes) 89 * # V2: No reg addr in data grp section. 90 * # V3: Normally the last grp is the reg addr. 91 * } 92 * CRC (4 bytes) 93 * Reserved (the rest) 94 */ 95 crc = crc32(~0, data, (3 + tmp_val[1] * 6) * 4) ^ ~0; 96 97 if (crc != tmp_val[3 + tmp_val[1] * 6]) { 98 cali_data->total_sz = 0; 99 dev_err(p->dev, "%s: CRC error\n", __func__); 100 return; 101 } 102 node_num = tmp_val[1]; 103 104 for (j = 0, k = 0; j < node_num; j++) { 105 oft = j * 6 + 3; 106 if (tmp_val[oft] == TASDEV_UEFI_CALI_REG_ADDR_FLG) { 107 for (i = 0; i < TASDEV_CALIB_N; i++) { 108 buf = &data[(oft + i + 1) * 4]; 109 cali_reg[i] = TASDEVICE_REG(buf[1], 110 buf[2], buf[3]); 111 } 112 } else { 113 l = j * (cali_data->cali_dat_sz_per_dev + 1); 114 if (k >= p->ndev || l > oft * 4) { 115 dev_err(p->dev, "%s: dev sum error\n", 116 __func__); 117 cali_data->total_sz = 0; 118 return; 119 } 120 121 data[l] = k; 122 oft++; 123 cali_cnv(data, 4 * oft, l); 124 k++; 125 } 126 } 127 } else { 128 /* 129 * Calibration data is in V1 format. 130 * struct cali_data { 131 * char cali_data[20]; 132 * } 133 * 134 * struct { 135 * struct cali_data cali_data[4]; 136 * int TimeStamp of Calibration (4 bytes) 137 * int CRC (4 bytes) 138 * } ueft; 139 */ 140 crc = crc32(~0, data, 84) ^ ~0; 141 if (crc != tmp_val[21]) { 142 cali_data->total_sz = 0; 143 dev_err(p->dev, "%s: V1 CRC error\n", __func__); 144 return; 145 } 146 147 for (j = p->ndev - 1; j >= 0; j--) { 148 l = j * (cali_data->cali_dat_sz_per_dev + 1); 149 cali_cnv(data, cali_data->cali_dat_sz_per_dev * j, l); 150 data[l] = j; 151 } 152 } 153 154 if (p->dspbin_typ == TASDEV_BASIC) { 155 r->r0_reg = cali_reg[0]; 156 r->invr0_reg = cali_reg[1]; 157 r->r0_low_reg = cali_reg[2]; 158 r->pow_reg = cali_reg[3]; 159 r->tlimit_reg = cali_reg[4]; 160 } 161 162 cali_data->total_sz = p->ndev * (cali_data->cali_dat_sz_per_dev + 1); 163 } 164 165 /* 166 * Update the calibration data, including speaker impedance, f0, etc, 167 * into algo. Calibrate data is done by manufacturer in the factory. 168 * The data is used by Algo for calculating the speaker temperature, 169 * speaker membrane excursion and f0 in real time during playback. 170 * Calibration data format in EFI is V2, since 2024. 171 */ 172 int tas2781_save_calibration(struct tas2781_hda *hda) 173 { 174 /* 175 * GUID was used for data access in BIOS, it was provided by board 176 * manufactory. 177 */ 178 efi_guid_t efi_guid = tasdev_fct_efi_guid[LENOVO]; 179 /* 180 * Some devices save the calibrated data into L"CALI_DATA", 181 * and others into L"SmartAmpCalibrationData". 182 */ 183 static efi_char16_t *efi_name[CALIBRATION_DATA_AREA_NUM] = { 184 L"CALI_DATA", 185 L"SmartAmpCalibrationData", 186 }; 187 struct tasdevice_priv *p = hda->priv; 188 struct calidata *cali_data = &p->cali_data; 189 unsigned long total_sz = 0; 190 unsigned int attr, size; 191 unsigned char *data; 192 efi_status_t status; 193 int i; 194 195 if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) { 196 dev_err(p->dev, "%s: NO EFI FOUND!\n", __func__); 197 return -EINVAL; 198 } 199 200 if (hda->catlog_id < LENOVO) 201 efi_guid = tasdev_fct_efi_guid[hda->catlog_id]; 202 203 cali_data->cali_dat_sz_per_dev = 20; 204 size = p->ndev * (cali_data->cali_dat_sz_per_dev + 1); 205 for (i = 0; i < CALIBRATION_DATA_AREA_NUM; i++) { 206 /* Get real size of UEFI variable */ 207 status = efi.get_variable(efi_name[i], &efi_guid, &attr, 208 &total_sz, NULL); 209 cali_data->total_sz = total_sz > size ? total_sz : size; 210 if (status == EFI_BUFFER_TOO_SMALL) { 211 /* Allocate data buffer of data_size bytes */ 212 data = cali_data->data = devm_kzalloc(p->dev, 213 cali_data->total_sz, GFP_KERNEL); 214 if (!data) { 215 status = -ENOMEM; 216 continue; 217 } 218 /* 219 * Set to an invalid value before the calibrated data 220 * is stored into it, for the default value is 0, which 221 * means the first device. 222 */ 223 data[0] = 0xff; 224 /* Get variable contents into buffer */ 225 status = efi.get_variable(efi_name[i], &efi_guid, 226 &attr, &cali_data->total_sz, data); 227 } 228 /* Check whether get the calibrated data */ 229 if (status == EFI_SUCCESS) 230 break; 231 } 232 233 if (status != EFI_SUCCESS) { 234 cali_data->total_sz = 0; 235 return status; 236 } 237 238 tas2781_apply_calib(p); 239 240 return 0; 241 } 242 EXPORT_SYMBOL_NS_GPL(tas2781_save_calibration, "SND_HDA_SCODEC_TAS2781"); 243 244 void tas2781_hda_remove(struct device *dev, 245 const struct component_ops *ops) 246 { 247 struct tas2781_hda *tas_hda = dev_get_drvdata(dev); 248 249 component_del(tas_hda->dev, ops); 250 251 pm_runtime_get_sync(tas_hda->dev); 252 pm_runtime_disable(tas_hda->dev); 253 254 pm_runtime_put_noidle(tas_hda->dev); 255 256 tasdevice_remove(tas_hda->priv); 257 } 258 EXPORT_SYMBOL_NS_GPL(tas2781_hda_remove, "SND_HDA_SCODEC_TAS2781"); 259 260 int tasdevice_info_profile(struct snd_kcontrol *kcontrol, 261 struct snd_ctl_elem_info *uinfo) 262 { 263 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 264 265 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 266 uinfo->count = 1; 267 uinfo->value.integer.min = 0; 268 uinfo->value.integer.max = tas_priv->rcabin.ncfgs - 1; 269 270 return 0; 271 } 272 EXPORT_SYMBOL_NS_GPL(tasdevice_info_profile, "SND_HDA_SCODEC_TAS2781"); 273 274 int tasdevice_info_programs(struct snd_kcontrol *kcontrol, 275 struct snd_ctl_elem_info *uinfo) 276 { 277 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 278 279 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 280 uinfo->count = 1; 281 uinfo->value.integer.min = 0; 282 uinfo->value.integer.max = tas_priv->fmw->nr_programs - 1; 283 284 return 0; 285 } 286 EXPORT_SYMBOL_NS_GPL(tasdevice_info_programs, "SND_HDA_SCODEC_TAS2781"); 287 288 int tasdevice_info_config(struct snd_kcontrol *kcontrol, 289 struct snd_ctl_elem_info *uinfo) 290 { 291 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 292 struct tasdevice_fw *tas_fw = tas_priv->fmw; 293 294 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 295 uinfo->count = 1; 296 uinfo->value.integer.min = 0; 297 uinfo->value.integer.max = tas_fw->nr_configurations - 1; 298 299 return 0; 300 } 301 EXPORT_SYMBOL_NS_GPL(tasdevice_info_config, "SND_HDA_SCODEC_TAS2781"); 302 303 int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol, 304 struct snd_ctl_elem_value *ucontrol) 305 { 306 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 307 308 ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id; 309 310 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__, 311 kcontrol->id.name, tas_priv->rcabin.profile_cfg_id); 312 313 return 0; 314 } 315 EXPORT_SYMBOL_NS_GPL(tasdevice_get_profile_id, "SND_HDA_SCODEC_TAS2781"); 316 317 int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol, 318 struct snd_ctl_elem_value *ucontrol) 319 { 320 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 321 int profile_id = ucontrol->value.integer.value[0]; 322 int max = tas_priv->rcabin.ncfgs - 1; 323 int val, ret = 0; 324 325 val = clamp(profile_id, 0, max); 326 327 guard(mutex)(&tas_priv->codec_lock); 328 329 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__, 330 kcontrol->id.name, tas_priv->rcabin.profile_cfg_id, val); 331 332 if (tas_priv->rcabin.profile_cfg_id != val) { 333 tas_priv->rcabin.profile_cfg_id = val; 334 ret = 1; 335 } 336 337 return ret; 338 } 339 EXPORT_SYMBOL_NS_GPL(tasdevice_set_profile_id, "SND_HDA_SCODEC_TAS2781"); 340 341 int tasdevice_program_get(struct snd_kcontrol *kcontrol, 342 struct snd_ctl_elem_value *ucontrol) 343 { 344 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 345 346 ucontrol->value.integer.value[0] = tas_priv->cur_prog; 347 348 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__, 349 kcontrol->id.name, tas_priv->cur_prog); 350 351 return 0; 352 } 353 EXPORT_SYMBOL_NS_GPL(tasdevice_program_get, "SND_HDA_SCODEC_TAS2781"); 354 355 int tasdevice_program_put(struct snd_kcontrol *kcontrol, 356 struct snd_ctl_elem_value *ucontrol) 357 { 358 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 359 struct tasdevice_fw *tas_fw = tas_priv->fmw; 360 int nr_program = ucontrol->value.integer.value[0]; 361 int max = tas_fw->nr_programs - 1; 362 int val, ret = 0; 363 364 val = clamp(nr_program, 0, max); 365 366 guard(mutex)(&tas_priv->codec_lock); 367 368 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__, 369 kcontrol->id.name, tas_priv->cur_prog, val); 370 371 if (tas_priv->cur_prog != val) { 372 tas_priv->cur_prog = val; 373 ret = 1; 374 } 375 376 return ret; 377 } 378 EXPORT_SYMBOL_NS_GPL(tasdevice_program_put, "SND_HDA_SCODEC_TAS2781"); 379 380 int tasdevice_config_get(struct snd_kcontrol *kcontrol, 381 struct snd_ctl_elem_value *ucontrol) 382 { 383 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 384 385 ucontrol->value.integer.value[0] = tas_priv->cur_conf; 386 387 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__, 388 kcontrol->id.name, tas_priv->cur_conf); 389 390 return 0; 391 } 392 EXPORT_SYMBOL_NS_GPL(tasdevice_config_get, "SND_HDA_SCODEC_TAS2781"); 393 394 int tasdevice_config_put(struct snd_kcontrol *kcontrol, 395 struct snd_ctl_elem_value *ucontrol) 396 { 397 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); 398 struct tasdevice_fw *tas_fw = tas_priv->fmw; 399 int nr_config = ucontrol->value.integer.value[0]; 400 int max = tas_fw->nr_configurations - 1; 401 int val, ret = 0; 402 403 val = clamp(nr_config, 0, max); 404 405 guard(mutex)(&tas_priv->codec_lock); 406 407 dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__, 408 kcontrol->id.name, tas_priv->cur_conf, val); 409 410 if (tas_priv->cur_conf != val) { 411 tas_priv->cur_conf = val; 412 ret = 1; 413 } 414 415 return ret; 416 } 417 EXPORT_SYMBOL_NS_GPL(tasdevice_config_put, "SND_HDA_SCODEC_TAS2781"); 418 419 MODULE_DESCRIPTION("TAS2781 HDA Driver"); 420 MODULE_LICENSE("GPL"); 421 MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>"); 422