Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: codecs: Add aw88081 amplifier driver

Merge series from wangweidong.a@awinic.com:

Add the awinic,aw88081 property to support the aw88081 chip.

The driver is for amplifiers aw88081 of Awinic Technology
Corporation. The awinic AW88081 is an I2S/TDM input,
high efficiency digital Smart K audio amplifier

+1390 -1
+3 -1
Documentation/devicetree/bindings/sound/awinic,aw88395.yaml
··· 17 17 properties: 18 18 compatible: 19 19 enum: 20 - - awinic,aw88395 20 + - awinic,aw88081 21 21 - awinic,aw88261 22 + - awinic,aw88395 22 23 - awinic,aw88399 23 24 24 25 reg: ··· 57 56 compatible: 58 57 contains: 59 58 enum: 59 + - awinic,aw88081 60 60 - awinic,aw88261 61 61 then: 62 62 properties:
+12
sound/soc/codecs/Kconfig
··· 57 57 imply SND_SOC_AW8738 58 58 imply SND_SOC_AW87390 59 59 imply SND_SOC_AW88395 60 + imply SND_SOC_AW88081 60 61 imply SND_SOC_AW88261 61 62 imply SND_SOC_AW88399 62 63 imply SND_SOC_BT_SCO ··· 689 688 digital Smart K audio amplifier. The output voltage of 690 689 boost converter can be adjusted smartly according to 691 690 the input amplitude. 691 + 692 + config SND_SOC_AW88081 693 + tristate "Soc Audio for awinic aw88081" 694 + depends on I2C 695 + select REGMAP_I2C 696 + select SND_SOC_AW88395_LIB 697 + help 698 + This option enables support for aw88081 Smart PA. 699 + The awinic AW88081 is an I2S/TDM input, high efficiency 700 + digital Smart K audio amplifier. Due to its 9uV noise 701 + floor and ultra-low distortion, clean listening is guaranteed. 692 702 693 703 config SND_SOC_AW87390 694 704 tristate "Soc Audio for awinic aw87390"
+2
sound/soc/codecs/Makefile
··· 49 49 snd-soc-audio-iio-aux-y := audio-iio-aux.o 50 50 snd-soc-aw8738-y := aw8738.o 51 51 snd-soc-aw87390-y := aw87390.o 52 + snd-soc-aw88081-y := aw88081.o 52 53 snd-soc-aw88395-lib-y := aw88395/aw88395_lib.o 53 54 snd-soc-aw88395-y := aw88395/aw88395.o \ 54 55 aw88395/aw88395_device.o ··· 466 465 obj-$(CONFIG_SND_SOC_AUDIO_IIO_AUX) += snd-soc-audio-iio-aux.o 467 466 obj-$(CONFIG_SND_SOC_AW8738) += snd-soc-aw8738.o 468 467 obj-$(CONFIG_SND_SOC_AW87390) += snd-soc-aw87390.o 468 + obj-$(CONFIG_SND_SOC_AW88081) += snd-soc-aw88081.o 469 469 obj-$(CONFIG_SND_SOC_AW88395_LIB) += snd-soc-aw88395-lib.o 470 470 obj-$(CONFIG_SND_SOC_AW88395) +=snd-soc-aw88395.o 471 471 obj-$(CONFIG_SND_SOC_AW88261) +=snd-soc-aw88261.o
+1087
sound/soc/codecs/aw88081.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // aw88081.c -- AW88081 ALSA SoC Audio driver 4 + // 5 + // Copyright (c) 2024 awinic Technology CO., LTD 6 + // 7 + // Author: Weidong Wang <wangweidong.a@awinic.com> 8 + // 9 + 10 + #include <linux/firmware.h> 11 + #include <linux/i2c.h> 12 + #include <linux/regmap.h> 13 + #include <sound/soc.h> 14 + #include "aw88081.h" 15 + #include "aw88395/aw88395_device.h" 16 + 17 + struct aw88081 { 18 + struct aw_device *aw_pa; 19 + struct mutex lock; 20 + struct delayed_work start_work; 21 + struct regmap *regmap; 22 + struct aw_container *aw_cfg; 23 + 24 + bool phase_sync; 25 + }; 26 + 27 + static const struct regmap_config aw88081_regmap_config = { 28 + .val_bits = 16, 29 + .reg_bits = 8, 30 + .max_register = AW88081_REG_MAX, 31 + .reg_format_endian = REGMAP_ENDIAN_LITTLE, 32 + .val_format_endian = REGMAP_ENDIAN_BIG, 33 + }; 34 + 35 + static int aw88081_dev_get_iis_status(struct aw_device *aw_dev) 36 + { 37 + unsigned int reg_val; 38 + int ret; 39 + 40 + ret = regmap_read(aw_dev->regmap, AW88081_SYSST_REG, &reg_val); 41 + if (ret) 42 + return ret; 43 + if ((reg_val & AW88081_BIT_PLL_CHECK) != AW88081_BIT_PLL_CHECK) { 44 + dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val); 45 + return -EINVAL; 46 + } 47 + 48 + return 0; 49 + } 50 + 51 + static int aw88081_dev_check_mode1_pll(struct aw_device *aw_dev) 52 + { 53 + int ret, i; 54 + 55 + for (i = 0; i < AW88081_DEV_SYSST_CHECK_MAX; i++) { 56 + ret = aw88081_dev_get_iis_status(aw_dev); 57 + if (ret) { 58 + dev_err(aw_dev->dev, "mode1 iis signal check error"); 59 + usleep_range(AW88081_2000_US, AW88081_2000_US + 10); 60 + } else { 61 + return 0; 62 + } 63 + } 64 + 65 + return -EPERM; 66 + } 67 + 68 + static int aw88081_dev_check_mode2_pll(struct aw_device *aw_dev) 69 + { 70 + unsigned int reg_val; 71 + int ret, i; 72 + 73 + ret = regmap_read(aw_dev->regmap, AW88081_PLLCTRL1_REG, &reg_val); 74 + if (ret) 75 + return ret; 76 + 77 + reg_val &= (~AW88081_CCO_MUX_MASK); 78 + if (reg_val == AW88081_CCO_MUX_DIVIDED_VALUE) { 79 + dev_dbg(aw_dev->dev, "CCO_MUX is already divider"); 80 + return -EPERM; 81 + } 82 + 83 + /* change mode2 */ 84 + ret = regmap_update_bits(aw_dev->regmap, AW88081_PLLCTRL1_REG, 85 + ~AW88081_CCO_MUX_MASK, AW88081_CCO_MUX_DIVIDED_VALUE); 86 + if (ret) 87 + return ret; 88 + 89 + for (i = 0; i < AW88081_DEV_SYSST_CHECK_MAX; i++) { 90 + ret = aw88081_dev_get_iis_status(aw_dev); 91 + if (ret) { 92 + dev_err(aw_dev->dev, "mode2 iis check error"); 93 + usleep_range(AW88081_2000_US, AW88081_2000_US + 10); 94 + } else { 95 + break; 96 + } 97 + } 98 + 99 + /* change mode1 */ 100 + ret = regmap_update_bits(aw_dev->regmap, AW88081_PLLCTRL1_REG, 101 + ~AW88081_CCO_MUX_MASK, AW88081_CCO_MUX_BYPASS_VALUE); 102 + if (ret == 0) { 103 + usleep_range(AW88081_2000_US, AW88081_2000_US + 10); 104 + for (i = 0; i < AW88081_DEV_SYSST_CHECK_MAX; i++) { 105 + ret = aw88081_dev_check_mode1_pll(aw_dev); 106 + if (ret) { 107 + dev_err(aw_dev->dev, "mode2 switch to mode1, iis check error"); 108 + usleep_range(AW88081_2000_US, AW88081_2000_US + 10); 109 + } else { 110 + break; 111 + } 112 + } 113 + } 114 + 115 + return ret; 116 + } 117 + 118 + static int aw88081_dev_check_syspll(struct aw_device *aw_dev) 119 + { 120 + int ret; 121 + 122 + ret = aw88081_dev_check_mode1_pll(aw_dev); 123 + if (ret) { 124 + dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check"); 125 + ret = aw88081_dev_check_mode2_pll(aw_dev); 126 + if (ret) { 127 + dev_err(aw_dev->dev, "mode2 check iis failed"); 128 + return ret; 129 + } 130 + } 131 + 132 + return 0; 133 + } 134 + 135 + static int aw88081_dev_check_sysst(struct aw_device *aw_dev) 136 + { 137 + unsigned int check_val; 138 + unsigned int reg_val; 139 + unsigned int value; 140 + int ret, i; 141 + 142 + ret = regmap_read(aw_dev->regmap, AW88081_PWMCTRL4_REG, &reg_val); 143 + if (ret) 144 + return ret; 145 + 146 + if (reg_val & (~AW88081_NOISE_GATE_EN_MASK)) 147 + check_val = AW88081_NO_SWS_SYSST_CHECK; 148 + else 149 + check_val = AW88081_SWS_SYSST_CHECK; 150 + 151 + for (i = 0; i < AW88081_DEV_SYSST_CHECK_MAX; i++) { 152 + ret = regmap_read(aw_dev->regmap, AW88081_SYSST_REG, &reg_val); 153 + if (ret) 154 + return ret; 155 + 156 + value = reg_val & (~AW88081_BIT_SYSST_CHECK_MASK) & check_val; 157 + if (value != check_val) { 158 + dev_err(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x", 159 + reg_val, check_val); 160 + usleep_range(AW88081_2000_US, AW88081_2000_US + 10); 161 + } else { 162 + return 0; 163 + } 164 + } 165 + 166 + return -EPERM; 167 + } 168 + 169 + static void aw88081_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) 170 + { 171 + if (flag) 172 + regmap_update_bits(aw_dev->regmap, AW88081_I2SCTRL3_REG, 173 + ~AW88081_I2STXEN_MASK, AW88081_I2STXEN_ENABLE_VALUE); 174 + else 175 + regmap_update_bits(aw_dev->regmap, AW88081_I2SCTRL3_REG, 176 + ~AW88081_I2STXEN_MASK, AW88081_I2STXEN_DISABLE_VALUE); 177 + } 178 + 179 + static void aw88081_dev_pwd(struct aw_device *aw_dev, bool pwd) 180 + { 181 + if (pwd) 182 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, 183 + ~AW88081_PWDN_MASK, AW88081_PWDN_POWER_DOWN_VALUE); 184 + else 185 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, 186 + ~AW88081_PWDN_MASK, AW88081_PWDN_WORKING_VALUE); 187 + } 188 + 189 + static void aw88081_dev_amppd(struct aw_device *aw_dev, bool amppd) 190 + { 191 + if (amppd) 192 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, 193 + ~AW88081_EN_PA_MASK, AW88081_EN_PA_POWER_DOWN_VALUE); 194 + else 195 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, 196 + ~AW88081_EN_PA_MASK, AW88081_EN_PA_WORKING_VALUE); 197 + } 198 + 199 + static void aw88081_dev_clear_int_status(struct aw_device *aw_dev) 200 + { 201 + unsigned int int_status; 202 + 203 + /* read int status and clear */ 204 + regmap_read(aw_dev->regmap, AW88081_SYSINT_REG, &int_status); 205 + /* make sure int status is clear */ 206 + regmap_read(aw_dev->regmap, AW88081_SYSINT_REG, &int_status); 207 + 208 + dev_dbg(aw_dev->dev, "read interrupt reg = 0x%04x", int_status); 209 + } 210 + 211 + static void aw88081_dev_set_volume(struct aw_device *aw_dev, unsigned int value) 212 + { 213 + struct aw_volume_desc *vol_desc = &aw_dev->volume_desc; 214 + unsigned int volume; 215 + 216 + volume = min((value + vol_desc->init_volume), (unsigned int)AW88081_MUTE_VOL); 217 + 218 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL2_REG, ~AW88081_VOL_MASK, volume); 219 + } 220 + 221 + static void aw88081_dev_fade_in(struct aw_device *aw_dev) 222 + { 223 + struct aw_volume_desc *desc = &aw_dev->volume_desc; 224 + int fade_in_vol = desc->ctl_volume; 225 + int fade_step = aw_dev->fade_step; 226 + int i; 227 + 228 + if (fade_step == 0 || aw_dev->fade_in_time == 0) { 229 + aw88081_dev_set_volume(aw_dev, fade_in_vol); 230 + return; 231 + } 232 + 233 + for (i = AW88081_MUTE_VOL; i >= fade_in_vol; i -= fade_step) { 234 + aw88081_dev_set_volume(aw_dev, i); 235 + usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); 236 + } 237 + 238 + if (i != fade_in_vol) 239 + aw88081_dev_set_volume(aw_dev, fade_in_vol); 240 + } 241 + 242 + static void aw88081_dev_fade_out(struct aw_device *aw_dev) 243 + { 244 + struct aw_volume_desc *desc = &aw_dev->volume_desc; 245 + int fade_step = aw_dev->fade_step; 246 + int i; 247 + 248 + if (fade_step == 0 || aw_dev->fade_out_time == 0) { 249 + aw88081_dev_set_volume(aw_dev, AW88081_MUTE_VOL); 250 + return; 251 + } 252 + 253 + for (i = desc->ctl_volume; i <= AW88081_MUTE_VOL; i += fade_step) { 254 + aw88081_dev_set_volume(aw_dev, i); 255 + usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); 256 + } 257 + 258 + if (i != AW88081_MUTE_VOL) 259 + aw88081_dev_set_volume(aw_dev, AW88081_MUTE_VOL); 260 + } 261 + 262 + static void aw88081_dev_mute(struct aw_device *aw_dev, bool is_mute) 263 + { 264 + if (is_mute) { 265 + aw88081_dev_fade_out(aw_dev); 266 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, 267 + ~AW88081_HMUTE_MASK, AW88081_HMUTE_ENABLE_VALUE); 268 + } else { 269 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, 270 + ~AW88081_HMUTE_MASK, AW88081_HMUTE_DISABLE_VALUE); 271 + aw88081_dev_fade_in(aw_dev); 272 + } 273 + } 274 + 275 + static void aw88081_dev_uls_hmute(struct aw_device *aw_dev, bool uls_hmute) 276 + { 277 + if (uls_hmute) 278 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, 279 + ~AW88081_ULS_HMUTE_MASK, 280 + AW88081_ULS_HMUTE_ENABLE_VALUE); 281 + else 282 + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, 283 + ~AW88081_ULS_HMUTE_MASK, 284 + AW88081_ULS_HMUTE_DISABLE_VALUE); 285 + } 286 + 287 + static int aw88081_dev_reg_update(struct aw88081 *aw88081, 288 + unsigned char *data, unsigned int len) 289 + { 290 + struct aw_device *aw_dev = aw88081->aw_pa; 291 + struct aw_volume_desc *vol_desc = &aw_dev->volume_desc; 292 + unsigned int read_vol; 293 + int data_len, i, ret; 294 + int16_t *reg_data; 295 + u16 reg_val; 296 + u8 reg_addr; 297 + 298 + if (!len || !data) { 299 + dev_err(aw_dev->dev, "reg data is null or len is 0"); 300 + return -EINVAL; 301 + } 302 + 303 + reg_data = (int16_t *)data; 304 + data_len = len >> 1; 305 + 306 + if (data_len & 0x1) { 307 + dev_err(aw_dev->dev, "data len:%d unsupported", data_len); 308 + return -EINVAL; 309 + } 310 + 311 + for (i = 0; i < data_len; i += 2) { 312 + reg_addr = reg_data[i]; 313 + reg_val = reg_data[i + 1]; 314 + 315 + if (reg_addr == AW88081_SYSCTRL_REG) { 316 + reg_val &= ~(~AW88081_EN_PA_MASK | 317 + ~AW88081_PWDN_MASK | 318 + ~AW88081_HMUTE_MASK | 319 + ~AW88081_ULS_HMUTE_MASK); 320 + 321 + reg_val |= AW88081_EN_PA_POWER_DOWN_VALUE | 322 + AW88081_PWDN_POWER_DOWN_VALUE | 323 + AW88081_HMUTE_ENABLE_VALUE | 324 + AW88081_ULS_HMUTE_ENABLE_VALUE; 325 + } 326 + 327 + if (reg_addr == AW88081_SYSCTRL2_REG) { 328 + read_vol = (reg_val & (~AW88081_VOL_MASK)) >> 329 + AW88081_VOL_START_BIT; 330 + aw_dev->volume_desc.init_volume = read_vol; 331 + } 332 + 333 + /* i2stxen */ 334 + if (reg_addr == AW88081_I2SCTRL3_REG) { 335 + /* close tx */ 336 + reg_val &= AW88081_I2STXEN_MASK; 337 + reg_val |= AW88081_I2STXEN_DISABLE_VALUE; 338 + } 339 + 340 + ret = regmap_write(aw_dev->regmap, reg_addr, reg_val); 341 + if (ret) 342 + return ret; 343 + } 344 + 345 + if (aw_dev->prof_cur != aw_dev->prof_index) 346 + vol_desc->ctl_volume = 0; 347 + 348 + /* keep min volume */ 349 + aw88081_dev_set_volume(aw_dev, vol_desc->mute_volume); 350 + 351 + return 0; 352 + } 353 + 354 + static int aw88081_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name) 355 + { 356 + struct aw_prof_info *prof_info = &aw_dev->prof_info; 357 + struct aw_prof_desc *prof_desc; 358 + 359 + if ((index >= aw_dev->prof_info.count) || (index < 0)) { 360 + dev_err(aw_dev->dev, "index[%d] overflow count[%d]", 361 + index, aw_dev->prof_info.count); 362 + return -EINVAL; 363 + } 364 + 365 + prof_desc = &aw_dev->prof_info.prof_desc[index]; 366 + 367 + *prof_name = prof_info->prof_name_list[prof_desc->id]; 368 + 369 + return 0; 370 + } 371 + 372 + static int aw88081_dev_get_prof_data(struct aw_device *aw_dev, int index, 373 + struct aw_prof_desc **prof_desc) 374 + { 375 + if ((index >= aw_dev->prof_info.count) || (index < 0)) { 376 + dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", 377 + __func__, index, aw_dev->prof_info.count); 378 + return -EINVAL; 379 + } 380 + 381 + *prof_desc = &aw_dev->prof_info.prof_desc[index]; 382 + 383 + return 0; 384 + } 385 + 386 + static int aw88081_dev_fw_update(struct aw88081 *aw88081) 387 + { 388 + struct aw_device *aw_dev = aw88081->aw_pa; 389 + struct aw_prof_desc *prof_index_desc; 390 + struct aw_sec_data_desc *sec_desc; 391 + char *prof_name; 392 + int ret; 393 + 394 + ret = aw88081_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); 395 + if (ret) { 396 + dev_err(aw_dev->dev, "get prof name failed"); 397 + return -EINVAL; 398 + } 399 + 400 + dev_dbg(aw_dev->dev, "start update %s", prof_name); 401 + 402 + ret = aw88081_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc); 403 + if (ret) 404 + return ret; 405 + 406 + /* update reg */ 407 + sec_desc = prof_index_desc->sec_desc; 408 + ret = aw88081_dev_reg_update(aw88081, sec_desc[AW88395_DATA_TYPE_REG].data, 409 + sec_desc[AW88395_DATA_TYPE_REG].len); 410 + if (ret) { 411 + dev_err(aw_dev->dev, "update reg failed"); 412 + return ret; 413 + } 414 + 415 + aw_dev->prof_cur = aw_dev->prof_index; 416 + 417 + return 0; 418 + } 419 + 420 + static int aw88081_dev_start(struct aw88081 *aw88081) 421 + { 422 + struct aw_device *aw_dev = aw88081->aw_pa; 423 + int ret; 424 + 425 + if (aw_dev->status == AW88081_DEV_PW_ON) { 426 + dev_dbg(aw_dev->dev, "already power on"); 427 + return 0; 428 + } 429 + 430 + /* power on */ 431 + aw88081_dev_pwd(aw_dev, false); 432 + usleep_range(AW88081_2000_US, AW88081_2000_US + 10); 433 + 434 + ret = aw88081_dev_check_syspll(aw_dev); 435 + if (ret) { 436 + dev_err(aw_dev->dev, "pll check failed cannot start"); 437 + goto pll_check_fail; 438 + } 439 + 440 + /* amppd on */ 441 + aw88081_dev_amppd(aw_dev, false); 442 + usleep_range(AW88081_1000_US, AW88081_1000_US + 50); 443 + 444 + /* check i2s status */ 445 + ret = aw88081_dev_check_sysst(aw_dev); 446 + if (ret) { 447 + dev_err(aw_dev->dev, "sysst check failed"); 448 + goto sysst_check_fail; 449 + } 450 + 451 + /* enable tx feedback */ 452 + aw88081_dev_i2s_tx_enable(aw_dev, true); 453 + 454 + /* close uls mute */ 455 + aw88081_dev_uls_hmute(aw_dev, false); 456 + 457 + /* close mute */ 458 + aw88081_dev_mute(aw_dev, false); 459 + 460 + /* clear inturrupt */ 461 + aw88081_dev_clear_int_status(aw_dev); 462 + aw_dev->status = AW88081_DEV_PW_ON; 463 + 464 + return 0; 465 + 466 + sysst_check_fail: 467 + aw88081_dev_i2s_tx_enable(aw_dev, false); 468 + aw88081_dev_clear_int_status(aw_dev); 469 + aw88081_dev_amppd(aw_dev, true); 470 + pll_check_fail: 471 + aw88081_dev_pwd(aw_dev, true); 472 + aw_dev->status = AW88081_DEV_PW_OFF; 473 + 474 + return ret; 475 + } 476 + 477 + static int aw88081_dev_stop(struct aw_device *aw_dev) 478 + { 479 + if (aw_dev->status == AW88081_DEV_PW_OFF) { 480 + dev_dbg(aw_dev->dev, "already power off"); 481 + return 0; 482 + } 483 + 484 + aw_dev->status = AW88081_DEV_PW_OFF; 485 + 486 + /* clear inturrupt */ 487 + aw88081_dev_clear_int_status(aw_dev); 488 + 489 + aw88081_dev_uls_hmute(aw_dev, true); 490 + /* set mute */ 491 + aw88081_dev_mute(aw_dev, true); 492 + 493 + /* close tx feedback */ 494 + aw88081_dev_i2s_tx_enable(aw_dev, false); 495 + usleep_range(AW88081_1000_US, AW88081_1000_US + 100); 496 + 497 + /* enable amppd */ 498 + aw88081_dev_amppd(aw_dev, true); 499 + 500 + /* set power down */ 501 + aw88081_dev_pwd(aw_dev, true); 502 + 503 + return 0; 504 + } 505 + 506 + static int aw88081_reg_update(struct aw88081 *aw88081, bool force) 507 + { 508 + struct aw_device *aw_dev = aw88081->aw_pa; 509 + int ret; 510 + 511 + if (force) { 512 + ret = regmap_write(aw_dev->regmap, 513 + AW88081_ID_REG, AW88081_SOFT_RESET_VALUE); 514 + if (ret) 515 + return ret; 516 + 517 + ret = aw88081_dev_fw_update(aw88081); 518 + if (ret) 519 + return ret; 520 + } else { 521 + if (aw_dev->prof_cur != aw_dev->prof_index) { 522 + ret = aw88081_dev_fw_update(aw88081); 523 + if (ret) 524 + return ret; 525 + } 526 + } 527 + 528 + aw_dev->prof_cur = aw_dev->prof_index; 529 + 530 + return 0; 531 + } 532 + 533 + static void aw88081_start_pa(struct aw88081 *aw88081) 534 + { 535 + int ret, i; 536 + 537 + for (i = 0; i < AW88081_START_RETRIES; i++) { 538 + ret = aw88081_reg_update(aw88081, aw88081->phase_sync); 539 + if (ret) { 540 + dev_err(aw88081->aw_pa->dev, "fw update failed, cnt:%d\n", i); 541 + continue; 542 + } 543 + ret = aw88081_dev_start(aw88081); 544 + if (ret) { 545 + dev_err(aw88081->aw_pa->dev, "aw88081 device start failed. retry = %d", i); 546 + continue; 547 + } else { 548 + dev_dbg(aw88081->aw_pa->dev, "start success\n"); 549 + break; 550 + } 551 + } 552 + } 553 + 554 + static void aw88081_startup_work(struct work_struct *work) 555 + { 556 + struct aw88081 *aw88081 = 557 + container_of(work, struct aw88081, start_work.work); 558 + 559 + mutex_lock(&aw88081->lock); 560 + aw88081_start_pa(aw88081); 561 + mutex_unlock(&aw88081->lock); 562 + } 563 + 564 + static void aw88081_start(struct aw88081 *aw88081, bool sync_start) 565 + { 566 + if (aw88081->aw_pa->fw_status != AW88081_DEV_FW_OK) 567 + return; 568 + 569 + if (aw88081->aw_pa->status == AW88081_DEV_PW_ON) 570 + return; 571 + 572 + if (sync_start == AW88081_SYNC_START) 573 + aw88081_start_pa(aw88081); 574 + else 575 + queue_delayed_work(system_wq, 576 + &aw88081->start_work, 577 + AW88081_START_WORK_DELAY_MS); 578 + } 579 + 580 + static struct snd_soc_dai_driver aw88081_dai[] = { 581 + { 582 + .name = "aw88081-aif", 583 + .id = 1, 584 + .playback = { 585 + .stream_name = "Speaker_Playback", 586 + .channels_min = 1, 587 + .channels_max = 2, 588 + .rates = AW88081_RATES, 589 + .formats = AW88081_FORMATS, 590 + }, 591 + .capture = { 592 + .stream_name = "Speaker_Capture", 593 + .channels_min = 1, 594 + .channels_max = 2, 595 + .rates = AW88081_RATES, 596 + .formats = AW88081_FORMATS, 597 + }, 598 + }, 599 + }; 600 + 601 + static int aw88081_get_fade_in_time(struct snd_kcontrol *kcontrol, 602 + struct snd_ctl_elem_value *ucontrol) 603 + { 604 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 605 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(component); 606 + struct aw_device *aw_dev = aw88081->aw_pa; 607 + 608 + ucontrol->value.integer.value[0] = aw_dev->fade_in_time; 609 + 610 + return 0; 611 + } 612 + 613 + static int aw88081_set_fade_in_time(struct snd_kcontrol *kcontrol, 614 + struct snd_ctl_elem_value *ucontrol) 615 + { 616 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 617 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(component); 618 + struct soc_mixer_control *mc = 619 + (struct soc_mixer_control *)kcontrol->private_value; 620 + struct aw_device *aw_dev = aw88081->aw_pa; 621 + int time; 622 + 623 + time = ucontrol->value.integer.value[0]; 624 + 625 + if (time < mc->min || time > mc->max) 626 + return -EINVAL; 627 + 628 + if (time != aw_dev->fade_in_time) { 629 + aw_dev->fade_in_time = time; 630 + return 1; 631 + } 632 + 633 + return 0; 634 + } 635 + 636 + static int aw88081_get_fade_out_time(struct snd_kcontrol *kcontrol, 637 + struct snd_ctl_elem_value *ucontrol) 638 + { 639 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 640 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(component); 641 + struct aw_device *aw_dev = aw88081->aw_pa; 642 + 643 + ucontrol->value.integer.value[0] = aw_dev->fade_out_time; 644 + 645 + return 0; 646 + } 647 + 648 + static int aw88081_set_fade_out_time(struct snd_kcontrol *kcontrol, 649 + struct snd_ctl_elem_value *ucontrol) 650 + { 651 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 652 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(component); 653 + struct soc_mixer_control *mc = 654 + (struct soc_mixer_control *)kcontrol->private_value; 655 + struct aw_device *aw_dev = aw88081->aw_pa; 656 + int time; 657 + 658 + time = ucontrol->value.integer.value[0]; 659 + if (time < mc->min || time > mc->max) 660 + return -EINVAL; 661 + 662 + if (time != aw_dev->fade_out_time) { 663 + aw_dev->fade_out_time = time; 664 + return 1; 665 + } 666 + 667 + return 0; 668 + } 669 + 670 + static int aw88081_dev_set_profile_index(struct aw_device *aw_dev, int index) 671 + { 672 + /* check the index whether is valid */ 673 + if ((index >= aw_dev->prof_info.count) || (index < 0)) 674 + return -EINVAL; 675 + /* check the index whether change */ 676 + if (aw_dev->prof_index == index) 677 + return -EPERM; 678 + 679 + aw_dev->prof_index = index; 680 + 681 + return 0; 682 + } 683 + 684 + static int aw88081_profile_info(struct snd_kcontrol *kcontrol, 685 + struct snd_ctl_elem_info *uinfo) 686 + { 687 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 688 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(codec); 689 + char *prof_name; 690 + int count, ret; 691 + 692 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 693 + uinfo->count = 1; 694 + 695 + count = aw88081->aw_pa->prof_info.count; 696 + if (count <= 0) { 697 + uinfo->value.enumerated.items = 0; 698 + return 0; 699 + } 700 + 701 + uinfo->value.enumerated.items = count; 702 + 703 + if (uinfo->value.enumerated.item >= count) 704 + uinfo->value.enumerated.item = count - 1; 705 + 706 + count = uinfo->value.enumerated.item; 707 + 708 + ret = aw88081_dev_get_prof_name(aw88081->aw_pa, count, &prof_name); 709 + if (ret) { 710 + strscpy(uinfo->value.enumerated.name, "null", 711 + sizeof(uinfo->value.enumerated.name)); 712 + return 0; 713 + } 714 + 715 + strscpy(uinfo->value.enumerated.name, prof_name, sizeof(uinfo->value.enumerated.name)); 716 + 717 + return 0; 718 + } 719 + 720 + static int aw88081_profile_get(struct snd_kcontrol *kcontrol, 721 + struct snd_ctl_elem_value *ucontrol) 722 + { 723 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 724 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(codec); 725 + 726 + ucontrol->value.integer.value[0] = aw88081->aw_pa->prof_index; 727 + 728 + return 0; 729 + } 730 + 731 + static int aw88081_profile_set(struct snd_kcontrol *kcontrol, 732 + struct snd_ctl_elem_value *ucontrol) 733 + { 734 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 735 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(codec); 736 + int ret; 737 + 738 + /* pa stop or stopping just set profile */ 739 + mutex_lock(&aw88081->lock); 740 + ret = aw88081_dev_set_profile_index(aw88081->aw_pa, ucontrol->value.integer.value[0]); 741 + if (ret) { 742 + dev_dbg(codec->dev, "profile index does not change"); 743 + mutex_unlock(&aw88081->lock); 744 + return 0; 745 + } 746 + 747 + if (aw88081->aw_pa->status) { 748 + aw88081_dev_stop(aw88081->aw_pa); 749 + aw88081_start(aw88081, AW88081_SYNC_START); 750 + } 751 + 752 + mutex_unlock(&aw88081->lock); 753 + 754 + return 1; 755 + } 756 + 757 + static int aw88081_volume_get(struct snd_kcontrol *kcontrol, 758 + struct snd_ctl_elem_value *ucontrol) 759 + { 760 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 761 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(codec); 762 + struct aw_volume_desc *vol_desc = &aw88081->aw_pa->volume_desc; 763 + 764 + ucontrol->value.integer.value[0] = vol_desc->ctl_volume; 765 + 766 + return 0; 767 + } 768 + 769 + static int aw88081_volume_set(struct snd_kcontrol *kcontrol, 770 + struct snd_ctl_elem_value *ucontrol) 771 + { 772 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 773 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(codec); 774 + struct aw_volume_desc *vol_desc = &aw88081->aw_pa->volume_desc; 775 + struct soc_mixer_control *mc = 776 + (struct soc_mixer_control *)kcontrol->private_value; 777 + int value; 778 + 779 + value = ucontrol->value.integer.value[0]; 780 + 781 + if (value < mc->min || value > mc->max) 782 + return -EINVAL; 783 + 784 + if (vol_desc->ctl_volume != value) { 785 + vol_desc->ctl_volume = value; 786 + aw88081_dev_set_volume(aw88081->aw_pa, vol_desc->ctl_volume); 787 + return 1; 788 + } 789 + 790 + return 0; 791 + } 792 + 793 + static int aw88081_get_fade_step(struct snd_kcontrol *kcontrol, 794 + struct snd_ctl_elem_value *ucontrol) 795 + { 796 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 797 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(codec); 798 + 799 + ucontrol->value.integer.value[0] = aw88081->aw_pa->fade_step; 800 + 801 + return 0; 802 + } 803 + 804 + static int aw88081_set_fade_step(struct snd_kcontrol *kcontrol, 805 + struct snd_ctl_elem_value *ucontrol) 806 + { 807 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 808 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(codec); 809 + struct soc_mixer_control *mc = 810 + (struct soc_mixer_control *)kcontrol->private_value; 811 + int value; 812 + 813 + value = ucontrol->value.integer.value[0]; 814 + if (value < mc->min || value > mc->max) 815 + return -EINVAL; 816 + 817 + if (aw88081->aw_pa->fade_step != value) { 818 + aw88081->aw_pa->fade_step = value; 819 + return 1; 820 + } 821 + 822 + return 0; 823 + } 824 + 825 + static const struct snd_kcontrol_new aw88081_controls[] = { 826 + SOC_SINGLE_EXT("PCM Playback Volume", AW88081_SYSCTRL2_REG, 827 + 0, AW88081_MUTE_VOL, 0, aw88081_volume_get, 828 + aw88081_volume_set), 829 + SOC_SINGLE_EXT("Fade Step", 0, 0, AW88081_MUTE_VOL, 0, 830 + aw88081_get_fade_step, aw88081_set_fade_step), 831 + SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, 0, 832 + aw88081_get_fade_in_time, aw88081_set_fade_in_time), 833 + SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, 0, 834 + aw88081_get_fade_out_time, aw88081_set_fade_out_time), 835 + AW88081_PROFILE_EXT("Profile Set", aw88081_profile_info, 836 + aw88081_profile_get, aw88081_profile_set), 837 + }; 838 + 839 + static void aw88081_parse_channel_dt(struct aw88081 *aw88081) 840 + { 841 + struct aw_device *aw_dev = aw88081->aw_pa; 842 + struct device_node *np = aw_dev->dev->of_node; 843 + u32 channel_value = AW88081_DEV_DEFAULT_CH; 844 + 845 + of_property_read_u32(np, "awinic,audio-channel", &channel_value); 846 + aw88081->phase_sync = of_property_read_bool(np, "awinic,sync-flag"); 847 + 848 + aw_dev->channel = channel_value; 849 + } 850 + 851 + static int aw88081_init(struct aw88081 *aw88081, struct i2c_client *i2c, struct regmap *regmap) 852 + { 853 + struct aw_device *aw_dev; 854 + unsigned int chip_id; 855 + int ret; 856 + 857 + /* read chip id */ 858 + ret = regmap_read(regmap, AW88081_ID_REG, &chip_id); 859 + if (ret) { 860 + dev_err(&i2c->dev, "%s read chipid error. ret = %d", __func__, ret); 861 + return ret; 862 + } 863 + if (chip_id != AW88081_CHIP_ID) { 864 + dev_err(&i2c->dev, "unsupported device"); 865 + return -ENXIO; 866 + } 867 + 868 + dev_dbg(&i2c->dev, "chip id = %x\n", chip_id); 869 + 870 + aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL); 871 + if (!aw_dev) 872 + return -ENOMEM; 873 + 874 + aw88081->aw_pa = aw_dev; 875 + aw_dev->i2c = i2c; 876 + aw_dev->regmap = regmap; 877 + aw_dev->dev = &i2c->dev; 878 + aw_dev->chip_id = AW88081_CHIP_ID; 879 + aw_dev->acf = NULL; 880 + aw_dev->prof_info.prof_desc = NULL; 881 + aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID; 882 + aw_dev->fade_step = AW88081_VOLUME_STEP_DB; 883 + aw_dev->volume_desc.mute_volume = AW88081_MUTE_VOL; 884 + aw88081_parse_channel_dt(aw88081); 885 + 886 + return 0; 887 + } 888 + 889 + static int aw88081_dev_init(struct aw88081 *aw88081, struct aw_container *aw_cfg) 890 + { 891 + struct aw_device *aw_dev = aw88081->aw_pa; 892 + int ret; 893 + 894 + ret = aw88395_dev_cfg_load(aw_dev, aw_cfg); 895 + if (ret) { 896 + dev_err(aw_dev->dev, "aw_dev acf parse failed"); 897 + return -EINVAL; 898 + } 899 + 900 + ret = regmap_write(aw_dev->regmap, AW88081_ID_REG, AW88081_SOFT_RESET_VALUE); 901 + if (ret) 902 + return ret; 903 + 904 + aw_dev->fade_in_time = AW88081_500_US; 905 + aw_dev->fade_out_time = AW88081_500_US; 906 + aw_dev->prof_cur = AW88081_INIT_PROFILE; 907 + aw_dev->prof_index = AW88081_INIT_PROFILE; 908 + 909 + ret = aw88081_dev_fw_update(aw88081); 910 + if (ret) { 911 + dev_err(aw_dev->dev, "fw update failed ret = %d\n", ret); 912 + return ret; 913 + } 914 + 915 + aw88081_dev_clear_int_status(aw_dev); 916 + 917 + aw88081_dev_uls_hmute(aw_dev, true); 918 + 919 + aw88081_dev_mute(aw_dev, true); 920 + 921 + usleep_range(AW88081_5000_US, AW88081_5000_US + 10); 922 + 923 + aw88081_dev_i2s_tx_enable(aw_dev, false); 924 + 925 + usleep_range(AW88081_1000_US, AW88081_1000_US + 100); 926 + 927 + aw88081_dev_amppd(aw_dev, true); 928 + 929 + aw88081_dev_pwd(aw_dev, true); 930 + 931 + return 0; 932 + } 933 + 934 + static int aw88081_request_firmware_file(struct aw88081 *aw88081) 935 + { 936 + const struct firmware *cont = NULL; 937 + int ret; 938 + 939 + aw88081->aw_pa->fw_status = AW88081_DEV_FW_FAILED; 940 + 941 + ret = request_firmware(&cont, AW88081_ACF_FILE, aw88081->aw_pa->dev); 942 + if (ret) 943 + return ret; 944 + 945 + dev_dbg(aw88081->aw_pa->dev, "loaded %s - size: %zu\n", 946 + AW88081_ACF_FILE, cont ? cont->size : 0); 947 + 948 + aw88081->aw_cfg = devm_kzalloc(aw88081->aw_pa->dev, cont->size + sizeof(int), GFP_KERNEL); 949 + if (!aw88081->aw_cfg) { 950 + release_firmware(cont); 951 + return -ENOMEM; 952 + } 953 + aw88081->aw_cfg->len = (int)cont->size; 954 + memcpy(aw88081->aw_cfg->data, cont->data, cont->size); 955 + release_firmware(cont); 956 + 957 + ret = aw88395_dev_load_acf_check(aw88081->aw_pa, aw88081->aw_cfg); 958 + if (ret) 959 + return ret; 960 + 961 + mutex_lock(&aw88081->lock); 962 + ret = aw88081_dev_init(aw88081, aw88081->aw_cfg); 963 + mutex_unlock(&aw88081->lock); 964 + 965 + return ret; 966 + } 967 + 968 + static int aw88081_playback_event(struct snd_soc_dapm_widget *w, 969 + struct snd_kcontrol *k, int event) 970 + { 971 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 972 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(component); 973 + 974 + mutex_lock(&aw88081->lock); 975 + switch (event) { 976 + case SND_SOC_DAPM_PRE_PMU: 977 + aw88081_start(aw88081, AW88081_ASYNC_START); 978 + break; 979 + case SND_SOC_DAPM_POST_PMD: 980 + aw88081_dev_stop(aw88081->aw_pa); 981 + break; 982 + default: 983 + break; 984 + } 985 + mutex_unlock(&aw88081->lock); 986 + 987 + return 0; 988 + } 989 + 990 + static const struct snd_soc_dapm_widget aw88081_dapm_widgets[] = { 991 + /* playback */ 992 + SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, SND_SOC_NOPM, 0, 0, 993 + aw88081_playback_event, 994 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 995 + SND_SOC_DAPM_OUTPUT("DAC Output"), 996 + 997 + /* capture */ 998 + SND_SOC_DAPM_AIF_OUT("AIF_TX", "Speaker_Capture", 0, SND_SOC_NOPM, 0, 0), 999 + SND_SOC_DAPM_INPUT("ADC Input"), 1000 + }; 1001 + 1002 + static const struct snd_soc_dapm_route aw88081_audio_map[] = { 1003 + {"DAC Output", NULL, "AIF_RX"}, 1004 + {"AIF_TX", NULL, "ADC Input"}, 1005 + }; 1006 + 1007 + static int aw88081_codec_probe(struct snd_soc_component *component) 1008 + { 1009 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(component); 1010 + int ret; 1011 + 1012 + INIT_DELAYED_WORK(&aw88081->start_work, aw88081_startup_work); 1013 + 1014 + ret = aw88081_request_firmware_file(aw88081); 1015 + if (ret) 1016 + dev_err(aw88081->aw_pa->dev, "%s: request firmware failed\n", __func__); 1017 + 1018 + return ret; 1019 + } 1020 + 1021 + static void aw88081_codec_remove(struct snd_soc_component *aw_codec) 1022 + { 1023 + struct aw88081 *aw88081 = snd_soc_component_get_drvdata(aw_codec); 1024 + 1025 + cancel_delayed_work_sync(&aw88081->start_work); 1026 + } 1027 + 1028 + static const struct snd_soc_component_driver soc_codec_dev_aw88081 = { 1029 + .probe = aw88081_codec_probe, 1030 + .remove = aw88081_codec_remove, 1031 + .dapm_widgets = aw88081_dapm_widgets, 1032 + .num_dapm_widgets = ARRAY_SIZE(aw88081_dapm_widgets), 1033 + .dapm_routes = aw88081_audio_map, 1034 + .num_dapm_routes = ARRAY_SIZE(aw88081_audio_map), 1035 + .controls = aw88081_controls, 1036 + .num_controls = ARRAY_SIZE(aw88081_controls), 1037 + }; 1038 + 1039 + static int aw88081_i2c_probe(struct i2c_client *i2c) 1040 + { 1041 + struct aw88081 *aw88081; 1042 + int ret; 1043 + 1044 + ret = i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C); 1045 + if (!ret) 1046 + return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed"); 1047 + 1048 + aw88081 = devm_kzalloc(&i2c->dev, sizeof(*aw88081), GFP_KERNEL); 1049 + if (!aw88081) 1050 + return -ENOMEM; 1051 + 1052 + mutex_init(&aw88081->lock); 1053 + 1054 + i2c_set_clientdata(i2c, aw88081); 1055 + 1056 + aw88081->regmap = devm_regmap_init_i2c(i2c, &aw88081_regmap_config); 1057 + if (IS_ERR(aw88081->regmap)) 1058 + return dev_err_probe(&i2c->dev, PTR_ERR(aw88081->regmap), 1059 + "failed to init regmap\n"); 1060 + 1061 + /* aw pa init */ 1062 + ret = aw88081_init(aw88081, i2c, aw88081->regmap); 1063 + if (ret) 1064 + return ret; 1065 + 1066 + return devm_snd_soc_register_component(&i2c->dev, 1067 + &soc_codec_dev_aw88081, 1068 + aw88081_dai, ARRAY_SIZE(aw88081_dai)); 1069 + } 1070 + 1071 + static const struct i2c_device_id aw88081_i2c_id[] = { 1072 + { AW88081_I2C_NAME }, 1073 + { } 1074 + }; 1075 + MODULE_DEVICE_TABLE(i2c, aw88081_i2c_id); 1076 + 1077 + static struct i2c_driver aw88081_i2c_driver = { 1078 + .driver = { 1079 + .name = AW88081_I2C_NAME, 1080 + }, 1081 + .probe = aw88081_i2c_probe, 1082 + .id_table = aw88081_i2c_id, 1083 + }; 1084 + module_i2c_driver(aw88081_i2c_driver); 1085 + 1086 + MODULE_DESCRIPTION("ASoC AW88081 Smart PA Driver"); 1087 + MODULE_LICENSE("GPL v2");
+286
sound/soc/codecs/aw88081.h
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // aw88081.h -- AW88081 ALSA SoC Audio driver 4 + // 5 + // Copyright (c) 2024 awinic Technology CO., LTD 6 + // 7 + // Author: Weidong Wang <wangweidong.a@awinic.com> 8 + // 9 + 10 + #ifndef __AW88081_H__ 11 + #define __AW88081_H__ 12 + 13 + #define AW88081_ID_REG (0x00) 14 + #define AW88081_SYSST_REG (0x01) 15 + #define AW88081_SYSINT_REG (0x02) 16 + #define AW88081_SYSINTM_REG (0x03) 17 + #define AW88081_SYSCTRL_REG (0x04) 18 + #define AW88081_SYSCTRL2_REG (0x05) 19 + #define AW88081_I2SCTRL1_REG (0x06) 20 + #define AW88081_I2SCTRL2_REG (0x07) 21 + #define AW88081_I2SCTRL3_REG (0x08) 22 + #define AW88081_DACCFG1_REG (0x09) 23 + #define AW88081_DACCFG2_REG (0x0A) 24 + #define AW88081_DACCFG3_REG (0x0B) 25 + #define AW88081_DACCFG4_REG (0x0C) 26 + #define AW88081_DACCFG5_REG (0x0D) 27 + #define AW88081_DACCFG6_REG (0x0E) 28 + #define AW88081_DACCFG7_REG (0x11) 29 + #define AW88081_PWMCTRL1_REG (0x13) 30 + #define AW88081_PWMCTRL2_REG (0x14) 31 + #define AW88081_PWMCTRL3_REG (0x15) 32 + #define AW88081_PWMCTRL4_REG (0x16) 33 + #define AW88081_I2SCFG1_REG (0x17) 34 + #define AW88081_DBGCTRL_REG (0x18) 35 + #define AW88081_PDMCTRL_REG (0x19) 36 + #define AW88081_DACST_REG (0x20) 37 + #define AW88081_PATTERNST_REG (0x21) 38 + #define AW88081_I2SINT_REG (0x26) 39 + #define AW88081_I2SCAPCNT_REG (0x27) 40 + #define AW88081_ANASTA1_REG (0x28) 41 + #define AW88081_ANASTA2_REG (0x29) 42 + #define AW88081_ANASTA3_REG (0x2A) 43 + #define AW88081_VBAT_REG (0x21) 44 + #define AW88081_TEMP_REG (0x22) 45 + #define AW88081_PVDD_REG (0x23) 46 + #define AW88081_ISNDAT_REG (0x24) 47 + #define AW88081_VSNDAT_REG (0x25) 48 + #define AW88081_DSMCFG1_REG (0x30) 49 + #define AW88081_DSMCFG2_REG (0x31) 50 + #define AW88081_DSMCFG3_REG (0x32) 51 + #define AW88081_DSMCFG4_REG (0x33) 52 + #define AW88081_DSMCFG5_REG (0x34) 53 + #define AW88081_DSMCFG6_REG (0x35) 54 + #define AW88081_DSMCFG7_REG (0x36) 55 + #define AW88081_DSMCFG8_REG (0x37) 56 + #define AW88081_TESTIN_REG (0x38) 57 + #define AW88081_TESTOUT_REG (0x39) 58 + #define AW88081_BOPCTRL1_REG (0x40) 59 + #define AW88081_BOPCTRL2_REG (0x41) 60 + #define AW88081_BOPCTRL3_REG (0x42) 61 + #define AW88081_BOPSTA_REG (0x43) 62 + #define AW88081_PLLCTRL1_REG (0x54) 63 + #define AW88081_PLLCTRL2_REG (0x55) 64 + #define AW88081_PLLCTRL3_REG (0x56) 65 + #define AW88081_CDACTRL1_REG (0x57) 66 + #define AW88081_CDACTRL2_REG (0x58) 67 + #define AW88081_CDACTRL3_REG (0x59) 68 + #define AW88081_DITHERCFG1_REG (0x5A) 69 + #define AW88081_DITHERCFG2_REG (0x5B) 70 + #define AW88081_DITHERCFG3_REG (0x5C) 71 + #define AW88081_TM_REG (0x6E) 72 + #define AW88081_TM2_REG (0x6F) 73 + #define AW88081_TESTCTRL1_REG (0x70) 74 + #define AW88081_TESTCTRL2_REG (0x71) 75 + 76 + #define AW88081_REG_MAX (0x72) 77 + 78 + #define AW88081_UVLS_START_BIT (14) 79 + #define AW88081_UVLS_UVLO (1) 80 + #define AW88081_UVLS_UVLO_VALUE \ 81 + (AW88081_UVLS_UVLO << AW88081_UVLS_START_BIT) 82 + 83 + #define AW88081_SWS_START_BIT (8) 84 + #define AW88081_SWS_SWITCHING (1) 85 + #define AW88081_SWS_SWITCHING_VALUE \ 86 + (AW88081_SWS_SWITCHING << AW88081_SWS_START_BIT) 87 + 88 + #define AW88081_NOCLKS_START_BIT (5) 89 + #define AW88081_NOCLKS_NO_CLOCK (1) 90 + #define AW88081_NOCLKS_NO_CLOCK_VALUE \ 91 + (AW88081_NOCLKS_NO_CLOCK << AW88081_NOCLKS_START_BIT) 92 + 93 + #define AW88081_CLKS_START_BIT (4) 94 + #define AW88081_CLKS_STABLE (1) 95 + #define AW88081_CLKS_STABLE_VALUE \ 96 + (AW88081_CLKS_STABLE << AW88081_CLKS_START_BIT) 97 + 98 + #define AW88081_OCDS_START_BIT (3) 99 + #define AW88081_OCDS_OC (1) 100 + #define AW88081_OCDS_OC_VALUE \ 101 + (AW88081_OCDS_OC << AW88081_OCDS_START_BIT) 102 + 103 + #define AW88081_OTHS_START_BIT (1) 104 + #define AW88081_OTHS_OT (1) 105 + #define AW88081_OTHS_OT_VALUE \ 106 + (AW88081_OTHS_OT << AW88081_OTHS_START_BIT) 107 + 108 + #define AW88081_PLLS_START_BIT (0) 109 + #define AW88081_PLLS_LOCKED (1) 110 + #define AW88081_PLLS_LOCKED_VALUE \ 111 + (AW88081_PLLS_LOCKED << AW88081_PLLS_START_BIT) 112 + 113 + #define AW88081_BIT_PLL_CHECK \ 114 + (AW88081_CLKS_STABLE_VALUE | \ 115 + AW88081_PLLS_LOCKED_VALUE) 116 + 117 + #define AW88081_BIT_SYSST_CHECK_MASK \ 118 + (~(AW88081_UVLS_UVLO_VALUE | \ 119 + AW88081_SWS_SWITCHING_VALUE | \ 120 + AW88081_NOCLKS_NO_CLOCK_VALUE | \ 121 + AW88081_CLKS_STABLE_VALUE | \ 122 + AW88081_OCDS_OC_VALUE | \ 123 + AW88081_OTHS_OT_VALUE | \ 124 + AW88081_PLLS_LOCKED_VALUE)) 125 + 126 + #define AW88081_NO_SWS_SYSST_CHECK \ 127 + (AW88081_CLKS_STABLE_VALUE | \ 128 + AW88081_PLLS_LOCKED_VALUE) 129 + 130 + #define AW88081_SWS_SYSST_CHECK \ 131 + (AW88081_SWS_SWITCHING_VALUE | \ 132 + AW88081_CLKS_STABLE_VALUE | \ 133 + AW88081_PLLS_LOCKED_VALUE) 134 + 135 + #define AW88081_ULS_HMUTE_START_BIT (14) 136 + #define AW88081_ULS_HMUTE_BITS_LEN (1) 137 + #define AW88081_ULS_HMUTE_MASK \ 138 + (~(((1<<AW88081_ULS_HMUTE_BITS_LEN)-1) << AW88081_ULS_HMUTE_START_BIT)) 139 + 140 + #define AW88081_ULS_HMUTE_DISABLE (0) 141 + #define AW88081_ULS_HMUTE_DISABLE_VALUE \ 142 + (AW88081_ULS_HMUTE_DISABLE << AW88081_ULS_HMUTE_START_BIT) 143 + 144 + #define AW88081_ULS_HMUTE_ENABLE (1) 145 + #define AW88081_ULS_HMUTE_ENABLE_VALUE \ 146 + (AW88081_ULS_HMUTE_ENABLE << AW88081_ULS_HMUTE_START_BIT) 147 + 148 + #define AW88081_HMUTE_START_BIT (8) 149 + #define AW88081_HMUTE_BITS_LEN (1) 150 + #define AW88081_HMUTE_MASK \ 151 + (~(((1<<AW88081_HMUTE_BITS_LEN)-1) << AW88081_HMUTE_START_BIT)) 152 + 153 + #define AW88081_HMUTE_DISABLE (0) 154 + #define AW88081_HMUTE_DISABLE_VALUE \ 155 + (AW88081_HMUTE_DISABLE << AW88081_HMUTE_START_BIT) 156 + 157 + #define AW88081_HMUTE_ENABLE (1) 158 + #define AW88081_HMUTE_ENABLE_VALUE \ 159 + (AW88081_HMUTE_ENABLE << AW88081_HMUTE_START_BIT) 160 + 161 + #define AW88081_EN_PA_START_BIT (1) 162 + #define AW88081_EN_PA_BITS_LEN (1) 163 + #define AW88081_EN_PA_MASK \ 164 + (~(((1<<AW88081_EN_PA_BITS_LEN)-1) << AW88081_EN_PA_START_BIT)) 165 + 166 + #define AW88081_EN_PA_WORKING (1) 167 + #define AW88081_EN_PA_WORKING_VALUE \ 168 + (AW88081_EN_PA_WORKING << AW88081_EN_PA_START_BIT) 169 + 170 + #define AW88081_EN_PA_POWER_DOWN (0) 171 + #define AW88081_EN_PA_POWER_DOWN_VALUE \ 172 + (AW88081_EN_PA_POWER_DOWN << AW88081_EN_PA_START_BIT) 173 + 174 + #define AW88081_PWDN_START_BIT (0) 175 + #define AW88081_PWDN_BITS_LEN (1) 176 + #define AW88081_PWDN_MASK \ 177 + (~(((1<<AW88081_PWDN_BITS_LEN)-1) << AW88081_PWDN_START_BIT)) 178 + 179 + #define AW88081_PWDN_WORKING (0) 180 + #define AW88081_PWDN_WORKING_VALUE \ 181 + (AW88081_PWDN_WORKING << AW88081_PWDN_START_BIT) 182 + 183 + #define AW88081_PWDN_POWER_DOWN (1) 184 + #define AW88081_PWDN_POWER_DOWN_VALUE \ 185 + (AW88081_PWDN_POWER_DOWN << AW88081_PWDN_START_BIT) 186 + 187 + #define AW88081_VOL_START_BIT (0) 188 + #define AW88081_VOL_BITS_LEN (10) 189 + #define AW88081_VOL_MASK \ 190 + (~(((1<<AW88081_VOL_BITS_LEN)-1) << AW88081_VOL_START_BIT)) 191 + 192 + #define AW88081_VOLUME_STEP_DB (64) 193 + #define AW88081_MUTE_VOL (1023) 194 + 195 + #define AW88081_I2STXEN_START_BIT (6) 196 + #define AW88081_I2STXEN_BITS_LEN (1) 197 + #define AW88081_I2STXEN_MASK \ 198 + (~(((1<<AW88081_I2STXEN_BITS_LEN)-1) << AW88081_I2STXEN_START_BIT)) 199 + 200 + #define AW88081_I2STXEN_DISABLE (0) 201 + #define AW88081_I2STXEN_DISABLE_VALUE \ 202 + (AW88081_I2STXEN_DISABLE << AW88081_I2STXEN_START_BIT) 203 + 204 + #define AW88081_I2STXEN_ENABLE (1) 205 + #define AW88081_I2STXEN_ENABLE_VALUE \ 206 + (AW88081_I2STXEN_ENABLE << AW88081_I2STXEN_START_BIT) 207 + 208 + #define AW88081_NOISE_GATE_EN_START_BIT (13) 209 + #define AW88081_NOISE_GATE_EN_BITS_LEN (1) 210 + #define AW88081_NOISE_GATE_EN_MASK \ 211 + (~(((1<<AW88081_NOISE_GATE_EN_BITS_LEN)-1) << AW88081_NOISE_GATE_EN_START_BIT)) 212 + 213 + #define AW88081_NOISE_GATE_EN_DISABLE (0) 214 + #define AW88081_NOISE_GATE_EN_DISABLE_VALUE \ 215 + (AW88081_NOISE_GATE_EN_DISABLE << AW88081_NOISE_GATE_EN_START_BIT) 216 + 217 + #define AW88081_NOISE_GATE_EN_ENABLE (1) 218 + #define AW88081_NOISE_GATE_EN_ENABLE_VALUE \ 219 + (AW88081_NOISE_GATE_EN_ENABLE << AW88081_NOISE_GATE_EN_START_BIT) 220 + 221 + #define AW88081_CCO_MUX_START_BIT (13) 222 + #define AW88081_CCO_MUX_BITS_LEN (1) 223 + #define AW88081_CCO_MUX_MASK \ 224 + (~(((1<<AW88081_CCO_MUX_BITS_LEN)-1) << AW88081_CCO_MUX_START_BIT)) 225 + 226 + #define AW88081_CCO_MUX_DIVIDED (0) 227 + #define AW88081_CCO_MUX_DIVIDED_VALUE \ 228 + (AW88081_CCO_MUX_DIVIDED << AW88081_CCO_MUX_START_BIT) 229 + 230 + #define AW88081_CCO_MUX_BYPASS (1) 231 + #define AW88081_CCO_MUX_BYPASS_VALUE \ 232 + (AW88081_CCO_MUX_BYPASS << AW88081_CCO_MUX_START_BIT) 233 + 234 + #define AW88081_START_RETRIES (5) 235 + #define AW88081_START_WORK_DELAY_MS (0) 236 + 237 + #define AW88081_I2C_NAME "aw88081" 238 + #define AW88081_CHIP_ID 0x2116 239 + 240 + #define AW88081_RATES (SNDRV_PCM_RATE_8000_48000 | \ 241 + SNDRV_PCM_RATE_96000) 242 + #define AW88081_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 243 + SNDRV_PCM_FMTBIT_S24_LE | \ 244 + SNDRV_PCM_FMTBIT_S32_LE) 245 + 246 + #define FADE_TIME_MAX 100000 247 + 248 + #define AW88081_DEV_DEFAULT_CH (0) 249 + #define AW88081_ACF_FILE "aw88081_acf.bin" 250 + #define AW88081_DEV_SYSST_CHECK_MAX (10) 251 + #define AW88081_SOFT_RESET_VALUE (0x55aa) 252 + 253 + #define AW88081_INIT_PROFILE (0) 254 + 255 + #define AW88081_PROFILE_EXT(xname, profile_info, profile_get, profile_set) \ 256 + { \ 257 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 258 + .name = xname, \ 259 + .info = profile_info, \ 260 + .get = profile_get, \ 261 + .put = profile_set, \ 262 + } 263 + 264 + enum { 265 + AW88081_SYNC_START = 0, 266 + AW88081_ASYNC_START, 267 + }; 268 + 269 + enum { 270 + AW88081_500_US = 500, 271 + AW88081_1000_US = 1000, 272 + AW88081_2000_US = 2000, 273 + AW88081_5000_US = 5000, 274 + }; 275 + 276 + enum { 277 + AW88081_DEV_PW_OFF = 0, 278 + AW88081_DEV_PW_ON, 279 + }; 280 + 281 + enum { 282 + AW88081_DEV_FW_FAILED = 0, 283 + AW88081_DEV_FW_OK, 284 + }; 285 + 286 + #endif