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