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