1911 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// aw88399.c -- ALSA SoC AW88399 codec support4//5// Copyright (c) 2023 AWINIC Technology CO., LTD6//7// Author: Weidong Wang <wangweidong.a@awinic.com>8//9 10#include <linux/crc32.h>11#include <linux/gpio/consumer.h>12#include <linux/i2c.h>13#include <linux/firmware.h>14#include <linux/regmap.h>15#include <sound/soc.h>16#include "aw88399.h"17#include "aw88395/aw88395_device.h"18 19static const struct regmap_config aw88399_remap_config = {20 .val_bits = 16,21 .reg_bits = 8,22 .max_register = AW88399_REG_MAX,23 .reg_format_endian = REGMAP_ENDIAN_LITTLE,24 .val_format_endian = REGMAP_ENDIAN_BIG,25};26 27static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev,28 unsigned short dsp_addr, unsigned int dsp_data)29{30 int ret;31 32 ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr);33 if (ret) {34 dev_err(aw_dev->dev, "%s write addr error, ret=%d", __func__, ret);35 return ret;36 }37 38 ret = regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, (u16)dsp_data);39 if (ret) {40 dev_err(aw_dev->dev, "%s write data error, ret=%d", __func__, ret);41 return ret;42 }43 44 return 0;45}46 47static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev,48 unsigned short dsp_addr, unsigned int *dsp_data)49{50 unsigned int temp_data;51 int ret;52 53 ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr);54 if (ret) {55 dev_err(aw_dev->dev, "%s write error, ret=%d", __func__, ret);56 return ret;57 }58 59 ret = regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data);60 if (ret) {61 dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret);62 return ret;63 }64 *dsp_data = temp_data;65 66 return 0;67}68 69static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev,70 unsigned short dsp_addr, unsigned int *dsp_data)71{72 unsigned int temp_data;73 int ret;74 75 ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr);76 if (ret) {77 dev_err(aw_dev->dev, "%s write error, ret=%d", __func__, ret);78 return ret;79 }80 81 ret = regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data);82 if (ret) {83 dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret);84 return ret;85 }86 *dsp_data = temp_data;87 88 ret = regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data);89 if (ret) {90 dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret);91 return ret;92 }93 *dsp_data |= (temp_data << 16);94 95 return 0;96}97 98static int aw_dev_dsp_read(struct aw_device *aw_dev,99 unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type)100{101 u32 reg_value;102 int ret;103 104 mutex_lock(&aw_dev->dsp_lock);105 switch (data_type) {106 case AW88399_DSP_16_DATA:107 ret = aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data);108 if (ret)109 dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed",110 (u32)dsp_addr, *dsp_data);111 break;112 case AW88399_DSP_32_DATA:113 ret = aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data);114 if (ret)115 dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32r-bit dsp_data[0x%x] failed",116 (u32)dsp_addr, *dsp_data);117 break;118 default:119 dev_err(aw_dev->dev, "data type[%d] unsupported", data_type);120 ret = -EINVAL;121 break;122 }123 124 /* clear dsp chip select state */125 if (regmap_read(aw_dev->regmap, AW88399_ID_REG, ®_value))126 dev_err(aw_dev->dev, "%s fail to clear chip state. ret=%d\n", __func__, ret);127 mutex_unlock(&aw_dev->dsp_lock);128 129 return ret;130}131 132static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd)133{134 int ret;135 136 if (pwd)137 ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG,138 ~AW88399_PWDN_MASK, AW88399_PWDN_POWER_DOWN_VALUE);139 else140 ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG,141 ~AW88399_PWDN_MASK, AW88399_PWDN_WORKING_VALUE);142 143 if (ret)144 dev_dbg(aw_dev->dev, "%s failed", __func__);145}146 147static void aw_dev_get_int_status(struct aw_device *aw_dev, unsigned short *int_status)148{149 unsigned int reg_val;150 int ret;151 152 ret = regmap_read(aw_dev->regmap, AW88399_SYSINT_REG, ®_val);153 if (ret)154 dev_err(aw_dev->dev, "read interrupt reg fail, ret=%d", ret);155 else156 *int_status = reg_val;157 158 dev_dbg(aw_dev->dev, "read interrupt reg=0x%04x", *int_status);159}160 161static void aw_dev_clear_int_status(struct aw_device *aw_dev)162{163 u16 int_status;164 165 /* read int status and clear */166 aw_dev_get_int_status(aw_dev, &int_status);167 /* make sure int status is clear */168 aw_dev_get_int_status(aw_dev, &int_status);169 if (int_status)170 dev_dbg(aw_dev->dev, "int status(%d) is not cleaned.\n", int_status);171}172 173static int aw_dev_get_iis_status(struct aw_device *aw_dev)174{175 unsigned int reg_val;176 int ret;177 178 ret = regmap_read(aw_dev->regmap, AW88399_SYSST_REG, ®_val);179 if (ret)180 return ret;181 if ((reg_val & AW88399_BIT_PLL_CHECK) != AW88399_BIT_PLL_CHECK) {182 dev_err(aw_dev->dev, "check pll lock fail, reg_val:0x%04x", reg_val);183 return -EINVAL;184 }185 186 return 0;187}188 189static int aw_dev_check_mode1_pll(struct aw_device *aw_dev)190{191 int ret, i;192 193 for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) {194 ret = aw_dev_get_iis_status(aw_dev);195 if (ret) {196 dev_err(aw_dev->dev, "mode1 iis signal check error");197 usleep_range(AW88399_2000_US, AW88399_2000_US + 10);198 } else {199 return 0;200 }201 }202 203 return -EPERM;204}205 206static int aw_dev_check_mode2_pll(struct aw_device *aw_dev)207{208 unsigned int reg_val;209 int ret, i;210 211 ret = regmap_read(aw_dev->regmap, AW88399_PLLCTRL2_REG, ®_val);212 if (ret)213 return ret;214 215 reg_val &= (~AW88399_CCO_MUX_MASK);216 if (reg_val == AW88399_CCO_MUX_DIVIDED_VALUE) {217 dev_dbg(aw_dev->dev, "CCO_MUX is already divider");218 return -EPERM;219 }220 221 /* change mode2 */222 ret = regmap_update_bits(aw_dev->regmap, AW88399_PLLCTRL2_REG,223 ~AW88399_CCO_MUX_MASK, AW88399_CCO_MUX_DIVIDED_VALUE);224 if (ret)225 return ret;226 227 for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) {228 ret = aw_dev_get_iis_status(aw_dev);229 if (ret) {230 dev_err(aw_dev->dev, "mode2 iis signal check error");231 usleep_range(AW88399_2000_US, AW88399_2000_US + 10);232 } else {233 break;234 }235 }236 237 /* change mode1 */238 regmap_update_bits(aw_dev->regmap, AW88399_PLLCTRL2_REG,239 ~AW88399_CCO_MUX_MASK, AW88399_CCO_MUX_BYPASS_VALUE);240 if (ret == 0) {241 usleep_range(AW88399_2000_US, AW88399_2000_US + 10);242 for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) {243 ret = aw_dev_get_iis_status(aw_dev);244 if (ret) {245 dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error");246 usleep_range(AW88399_2000_US, AW88399_2000_US + 10);247 } else {248 break;249 }250 }251 }252 253 return ret;254}255 256static int aw_dev_check_syspll(struct aw_device *aw_dev)257{258 int ret;259 260 ret = aw_dev_check_mode1_pll(aw_dev);261 if (ret) {262 dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check");263 ret = aw_dev_check_mode2_pll(aw_dev);264 if (ret) {265 dev_err(aw_dev->dev, "mode2 check iis failed");266 return ret;267 }268 }269 270 return 0;271}272 273static int aw_dev_check_sysst(struct aw_device *aw_dev)274{275 unsigned int check_val;276 unsigned int reg_val;277 int ret, i;278 279 ret = regmap_read(aw_dev->regmap, AW88399_PWMCTRL3_REG, ®_val);280 if (ret)281 return ret;282 283 if (reg_val & (~AW88399_NOISE_GATE_EN_MASK))284 check_val = AW88399_BIT_SYSST_NOSWS_CHECK;285 else286 check_val = AW88399_BIT_SYSST_SWS_CHECK;287 288 for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) {289 ret = regmap_read(aw_dev->regmap, AW88399_SYSST_REG, ®_val);290 if (ret)291 return ret;292 293 if ((reg_val & (~AW88399_BIT_SYSST_CHECK_MASK) & check_val) != check_val) {294 dev_err(aw_dev->dev, "check sysst fail, cnt=%d, reg_val=0x%04x, check:0x%x",295 i, reg_val, AW88399_BIT_SYSST_NOSWS_CHECK);296 usleep_range(AW88399_2000_US, AW88399_2000_US + 10);297 } else {298 return 0;299 }300 }301 302 return -EPERM;303}304 305static void aw_dev_amppd(struct aw_device *aw_dev, bool amppd)306{307 int ret;308 309 if (amppd)310 ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG,311 ~AW88399_AMPPD_MASK, AW88399_AMPPD_POWER_DOWN_VALUE);312 else313 ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG,314 ~AW88399_AMPPD_MASK, AW88399_AMPPD_WORKING_VALUE);315 316 if (ret)317 dev_dbg(aw_dev->dev, "%s failed", __func__);318}319 320static void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable)321{322 int ret;323 324 if (is_enable)325 ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG,326 ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE);327 else328 ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG,329 ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE);330 331 if (ret)332 dev_dbg(aw_dev->dev, "%s failed\n", __func__);333}334 335static int aw88399_dev_get_icalk(struct aw88399 *aw88399, int16_t *icalk)336{337 uint16_t icalkh_val, icalkl_val, icalk_val;338 struct aw_device *aw_dev = aw88399->aw_pa;339 unsigned int reg_val;340 int ret;341 342 ret = regmap_read(aw_dev->regmap, AW88399_EFRH4_REG, ®_val);343 if (ret)344 return ret;345 icalkh_val = reg_val & (~AW88399_EF_ISN_GESLP_H_MASK);346 347 ret = regmap_read(aw_dev->regmap, AW88399_EFRL4_REG, ®_val);348 if (ret)349 return ret;350 icalkl_val = reg_val & (~AW88399_EF_ISN_GESLP_L_MASK);351 352 if (aw88399->check_val == AW_EF_AND_CHECK)353 icalk_val = icalkh_val & icalkl_val;354 else355 icalk_val = icalkh_val | icalkl_val;356 357 if (icalk_val & (~AW88399_EF_ISN_GESLP_SIGN_MASK))358 icalk_val = icalk_val | AW88399_EF_ISN_GESLP_SIGN_NEG;359 *icalk = (int16_t)icalk_val;360 361 return 0;362}363 364static int aw88399_dev_get_vcalk(struct aw88399 *aw88399, int16_t *vcalk)365{366 uint16_t vcalkh_val, vcalkl_val, vcalk_val;367 struct aw_device *aw_dev = aw88399->aw_pa;368 unsigned int reg_val;369 int ret;370 371 ret = regmap_read(aw_dev->regmap, AW88399_EFRH3_REG, ®_val);372 if (ret)373 return ret;374 375 vcalkh_val = reg_val & (~AW88399_EF_VSN_GESLP_H_MASK);376 377 ret = regmap_read(aw_dev->regmap, AW88399_EFRL3_REG, ®_val);378 if (ret)379 return ret;380 381 vcalkl_val = reg_val & (~AW88399_EF_VSN_GESLP_L_MASK);382 383 if (aw88399->check_val == AW_EF_AND_CHECK)384 vcalk_val = vcalkh_val & vcalkl_val;385 else386 vcalk_val = vcalkh_val | vcalkl_val;387 388 if (vcalk_val & AW88399_EF_VSN_GESLP_SIGN_MASK)389 vcalk_val = vcalk_val | AW88399_EF_VSN_GESLP_SIGN_NEG;390 *vcalk = (int16_t)vcalk_val;391 392 return 0;393}394 395static int aw88399_dev_get_internal_vcalk(struct aw88399 *aw88399, int16_t *vcalk)396{397 uint16_t vcalkh_val, vcalkl_val, vcalk_val;398 struct aw_device *aw_dev = aw88399->aw_pa;399 unsigned int reg_val;400 int ret;401 402 ret = regmap_read(aw_dev->regmap, AW88399_EFRH2_REG, ®_val);403 if (ret)404 return ret;405 vcalkh_val = reg_val & (~AW88399_INTERNAL_VSN_TRIM_H_MASK);406 407 ret = regmap_read(aw_dev->regmap, AW88399_EFRL2_REG, ®_val);408 if (ret)409 return ret;410 vcalkl_val = reg_val & (~AW88399_INTERNAL_VSN_TRIM_L_MASK);411 412 if (aw88399->check_val == AW_EF_AND_CHECK)413 vcalk_val = (vcalkh_val >> AW88399_INTERNAL_VSN_TRIM_H_START_BIT) &414 (vcalkl_val >> AW88399_INTERNAL_VSN_TRIM_L_START_BIT);415 else416 vcalk_val = (vcalkh_val >> AW88399_INTERNAL_VSN_TRIM_H_START_BIT) |417 (vcalkl_val >> AW88399_INTERNAL_VSN_TRIM_L_START_BIT);418 419 if (vcalk_val & (~AW88399_TEM4_SIGN_MASK))420 vcalk_val = vcalk_val | AW88399_TEM4_SIGN_NEG;421 422 *vcalk = (int16_t)vcalk_val;423 424 return 0;425}426 427static int aw_dev_set_vcalb(struct aw88399 *aw88399)428{429 struct aw_device *aw_dev = aw88399->aw_pa;430 unsigned int vsense_select, vsense_value;431 int32_t ical_k, vcal_k, vcalb;432 int16_t icalk, vcalk;433 uint16_t reg_val;434 int ret;435 436 ret = regmap_read(aw_dev->regmap, AW88399_VSNCTRL1_REG, &vsense_value);437 if (ret)438 return ret;439 440 vsense_select = vsense_value & (~AW88399_VDSEL_MASK);441 442 ret = aw88399_dev_get_icalk(aw88399, &icalk);443 if (ret) {444 dev_err(aw_dev->dev, "get icalk failed\n");445 return ret;446 }447 448 ical_k = icalk * AW88399_ICABLK_FACTOR + AW88399_CABL_BASE_VALUE;449 450 switch (vsense_select) {451 case AW88399_DEV_VDSEL_VSENSE:452 ret = aw88399_dev_get_vcalk(aw88399, &vcalk);453 vcal_k = vcalk * AW88399_VCABLK_FACTOR + AW88399_CABL_BASE_VALUE;454 vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_FACTOR / AW88399_ISCAL_FACTOR /455 ical_k / vcal_k * aw88399->vcalb_init_val;456 break;457 case AW88399_DEV_VDSEL_DAC:458 ret = aw88399_dev_get_internal_vcalk(aw88399, &vcalk);459 vcal_k = vcalk * AW88399_VCABLK_DAC_FACTOR + AW88399_CABL_BASE_VALUE;460 vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_DAC_FACTOR /461 AW88399_ISCAL_DAC_FACTOR / ical_k /462 vcal_k * aw88399->vcalb_init_val;463 break;464 default:465 dev_err(aw_dev->dev, "%s: unsupport vsense\n", __func__);466 ret = -EINVAL;467 break;468 }469 if (ret)470 return ret;471 472 vcalb = vcalb >> AW88399_VCALB_ADJ_FACTOR;473 reg_val = (uint32_t)vcalb;474 475 regmap_write(aw_dev->regmap, AW88399_DSPVCALB_REG, reg_val);476 477 return 0;478}479 480static int aw_dev_update_cali_re(struct aw_cali_desc *cali_desc)481{482 struct aw_device *aw_dev =483 container_of(cali_desc, struct aw_device, cali_desc);484 uint16_t re_lbits, re_hbits;485 u32 cali_re;486 int ret;487 488 if ((aw_dev->cali_desc.cali_re >= AW88399_CALI_RE_MAX) ||489 (aw_dev->cali_desc.cali_re <= AW88399_CALI_RE_MIN))490 return -EINVAL;491 492 cali_re = AW88399_SHOW_RE_TO_DSP_RE((aw_dev->cali_desc.cali_re +493 aw_dev->cali_desc.ra), AW88399_DSP_RE_SHIFT);494 495 re_hbits = (cali_re & (~AW88399_CALI_RE_HBITS_MASK)) >> AW88399_CALI_RE_HBITS_SHIFT;496 re_lbits = (cali_re & (~AW88399_CALI_RE_LBITS_MASK)) >> AW88399_CALI_RE_LBITS_SHIFT;497 498 ret = regmap_write(aw_dev->regmap, AW88399_ACR1_REG, re_hbits);499 if (ret) {500 dev_err(aw_dev->dev, "set cali re error");501 return ret;502 }503 504 ret = regmap_write(aw_dev->regmap, AW88399_ACR2_REG, re_lbits);505 if (ret)506 dev_err(aw_dev->dev, "set cali re error");507 508 return ret;509}510 511static int aw_dev_fw_crc_check(struct aw_device *aw_dev)512{513 uint16_t check_val, fw_len_val;514 unsigned int reg_val;515 int ret;516 517 /* calculate fw_end_addr */518 fw_len_val = ((aw_dev->dsp_fw_len / AW_FW_ADDR_LEN) - 1) + AW88399_CRC_FW_BASE_ADDR;519 520 /* write fw_end_addr to crc_end_addr */521 ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG,522 ~AW88399_CRC_END_ADDR_MASK, fw_len_val);523 if (ret)524 return ret;525 /* enable fw crc check */526 ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG,527 ~AW88399_CRC_CODE_EN_MASK, AW88399_CRC_CODE_EN_ENABLE_VALUE);528 529 usleep_range(AW88399_2000_US, AW88399_2000_US + 10);530 531 /* read crc check result */532 regmap_read(aw_dev->regmap, AW88399_HAGCST_REG, ®_val);533 if (ret)534 return ret;535 536 check_val = (reg_val & (~AW88399_CRC_CHECK_BITS_MASK)) >> AW88399_CRC_CHECK_START_BIT;537 538 /* disable fw crc check */539 ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG,540 ~AW88399_CRC_CODE_EN_MASK, AW88399_CRC_CODE_EN_DISABLE_VALUE);541 if (ret)542 return ret;543 544 if (check_val != AW88399_CRC_CHECK_PASS_VAL) {545 dev_err(aw_dev->dev, "%s failed, check_val 0x%x != 0x%x",546 __func__, check_val, AW88399_CRC_CHECK_PASS_VAL);547 ret = -EINVAL;548 }549 550 return ret;551}552 553static int aw_dev_cfg_crc_check(struct aw_device *aw_dev)554{555 uint16_t check_val, cfg_len_val;556 unsigned int reg_val;557 int ret;558 559 /* calculate cfg end addr */560 cfg_len_val = ((aw_dev->dsp_cfg_len / AW_FW_ADDR_LEN) - 1) + AW88399_CRC_CFG_BASE_ADDR;561 562 /* write cfg_end_addr to crc_end_addr */563 ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG,564 ~AW88399_CRC_END_ADDR_MASK, cfg_len_val);565 if (ret)566 return ret;567 568 /* enable cfg crc check */569 ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG,570 ~AW88399_CRC_CFG_EN_MASK, AW88399_CRC_CFG_EN_ENABLE_VALUE);571 if (ret)572 return ret;573 574 usleep_range(AW88399_1000_US, AW88399_1000_US + 10);575 576 /* read crc check result */577 ret = regmap_read(aw_dev->regmap, AW88399_HAGCST_REG, ®_val);578 if (ret)579 return ret;580 581 check_val = (reg_val & (~AW88399_CRC_CHECK_BITS_MASK)) >> AW88399_CRC_CHECK_START_BIT;582 583 /* disable cfg crc check */584 ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG,585 ~AW88399_CRC_CFG_EN_MASK, AW88399_CRC_CFG_EN_DISABLE_VALUE);586 if (ret)587 return ret;588 589 if (check_val != AW88399_CRC_CHECK_PASS_VAL) {590 dev_err(aw_dev->dev, "crc_check failed, check val 0x%x != 0x%x",591 check_val, AW88399_CRC_CHECK_PASS_VAL);592 ret = -EINVAL;593 }594 595 return ret;596}597 598static int aw_dev_hw_crc_check(struct aw88399 *aw88399)599{600 struct aw_device *aw_dev = aw88399->aw_pa;601 int ret;602 603 ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG,604 ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_BYPASS_VALUE);605 if (ret)606 return ret;607 608 ret = aw_dev_fw_crc_check(aw_dev);609 if (ret) {610 dev_err(aw_dev->dev, "fw_crc_check failed\n");611 goto crc_check_failed;612 }613 614 ret = aw_dev_cfg_crc_check(aw_dev);615 if (ret) {616 dev_err(aw_dev->dev, "cfg_crc_check failed\n");617 goto crc_check_failed;618 }619 620 ret = regmap_write(aw_dev->regmap, AW88399_CRCCTRL_REG, aw88399->crc_init_val);621 if (ret)622 return ret;623 624 ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG,625 ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_WORK_VALUE);626 627 return ret;628 629crc_check_failed:630 regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG,631 ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_WORK_VALUE);632 return ret;633}634 635static void aw_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag)636{637 int ret;638 639 if (flag)640 ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCTRL3_REG,641 ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_ENABLE_VALUE);642 else643 ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG,644 ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_DISABLE_VALUE);645 646 if (ret)647 dev_dbg(aw_dev->dev, "%s failed", __func__);648}649 650static int aw_dev_get_dsp_status(struct aw_device *aw_dev)651{652 unsigned int reg_val;653 int ret;654 655 ret = regmap_read(aw_dev->regmap, AW88399_WDT_REG, ®_val);656 if (ret)657 return ret;658 if (!(reg_val & (~AW88399_WDT_CNT_MASK)))659 return -EPERM;660 661 return 0;662}663 664static int aw_dev_dsp_check(struct aw_device *aw_dev)665{666 int ret, i;667 668 switch (aw_dev->dsp_cfg) {669 case AW88399_DEV_DSP_BYPASS:670 dev_dbg(aw_dev->dev, "dsp bypass");671 ret = 0;672 break;673 case AW88399_DEV_DSP_WORK:674 aw_dev_dsp_enable(aw_dev, false);675 aw_dev_dsp_enable(aw_dev, true);676 usleep_range(AW88399_1000_US, AW88399_1000_US + 10);677 for (i = 0; i < AW88399_DEV_DSP_CHECK_MAX; i++) {678 ret = aw_dev_get_dsp_status(aw_dev);679 if (ret) {680 dev_err(aw_dev->dev, "dsp wdt status error=%d", ret);681 usleep_range(AW88399_2000_US, AW88399_2000_US + 10);682 }683 }684 break;685 default:686 dev_err(aw_dev->dev, "unknown dsp cfg=%d", aw_dev->dsp_cfg);687 ret = -EINVAL;688 break;689 }690 691 return ret;692}693 694static int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value)695{696 struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;697 unsigned int reg_value;698 u16 real_value;699 int ret;700 701 real_value = min((value + vol_desc->init_volume), (unsigned int)AW88399_MUTE_VOL);702 703 ret = regmap_read(aw_dev->regmap, AW88399_SYSCTRL2_REG, ®_value);704 if (ret)705 return ret;706 707 dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value);708 709 real_value = (real_value << AW88399_VOL_START_BIT) | (reg_value & AW88399_VOL_MASK);710 711 ret = regmap_write(aw_dev->regmap, AW88399_SYSCTRL2_REG, real_value);712 713 return ret;714}715 716static void aw_dev_fade_in(struct aw_device *aw_dev)717{718 struct aw_volume_desc *desc = &aw_dev->volume_desc;719 u16 fade_in_vol = desc->ctl_volume;720 int fade_step = aw_dev->fade_step;721 int i;722 723 if (fade_step == 0 || aw_dev->fade_in_time == 0) {724 aw_dev_set_volume(aw_dev, fade_in_vol);725 return;726 }727 728 for (i = AW88399_MUTE_VOL; i >= fade_in_vol; i -= fade_step) {729 aw_dev_set_volume(aw_dev, i);730 usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10);731 }732 733 if (i != fade_in_vol)734 aw_dev_set_volume(aw_dev, fade_in_vol);735}736 737static void aw_dev_fade_out(struct aw_device *aw_dev)738{739 struct aw_volume_desc *desc = &aw_dev->volume_desc;740 int fade_step = aw_dev->fade_step;741 int i;742 743 if (fade_step == 0 || aw_dev->fade_out_time == 0) {744 aw_dev_set_volume(aw_dev, AW88399_MUTE_VOL);745 return;746 }747 748 for (i = desc->ctl_volume; i <= AW88399_MUTE_VOL; i += fade_step) {749 aw_dev_set_volume(aw_dev, i);750 usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10);751 }752 753 if (i != AW88399_MUTE_VOL) {754 aw_dev_set_volume(aw_dev, AW88399_MUTE_VOL);755 usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10);756 }757}758 759static void aw88399_dev_mute(struct aw_device *aw_dev, bool is_mute)760{761 if (is_mute) {762 aw_dev_fade_out(aw_dev);763 regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG,764 ~AW88399_HMUTE_MASK, AW88399_HMUTE_ENABLE_VALUE);765 } else {766 regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG,767 ~AW88399_HMUTE_MASK, AW88399_HMUTE_DISABLE_VALUE);768 aw_dev_fade_in(aw_dev);769 }770}771 772static void aw88399_dev_set_dither(struct aw88399 *aw88399, bool dither)773{774 struct aw_device *aw_dev = aw88399->aw_pa;775 776 if (dither)777 regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG,778 ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_ENABLE_VALUE);779 else780 regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG,781 ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_DISABLE_VALUE);782}783 784static int aw88399_dev_start(struct aw88399 *aw88399)785{786 struct aw_device *aw_dev = aw88399->aw_pa;787 int ret;788 789 if (aw_dev->status == AW88399_DEV_PW_ON) {790 dev_dbg(aw_dev->dev, "already power on");791 return 0;792 }793 794 aw88399_dev_set_dither(aw88399, false);795 796 /* power on */797 aw_dev_pwd(aw_dev, false);798 usleep_range(AW88399_2000_US, AW88399_2000_US + 10);799 800 ret = aw_dev_check_syspll(aw_dev);801 if (ret) {802 dev_err(aw_dev->dev, "pll check failed cannot start");803 goto pll_check_fail;804 }805 806 /* amppd on */807 aw_dev_amppd(aw_dev, false);808 usleep_range(AW88399_1000_US, AW88399_1000_US + 50);809 810 /* check i2s status */811 ret = aw_dev_check_sysst(aw_dev);812 if (ret) {813 dev_err(aw_dev->dev, "sysst check failed");814 goto sysst_check_fail;815 }816 817 if (aw_dev->dsp_cfg == AW88399_DEV_DSP_WORK) {818 ret = aw_dev_hw_crc_check(aw88399);819 if (ret) {820 dev_err(aw_dev->dev, "dsp crc check failed");821 goto crc_check_fail;822 }823 aw_dev_dsp_enable(aw_dev, false);824 aw_dev_set_vcalb(aw88399);825 aw_dev_update_cali_re(&aw_dev->cali_desc);826 827 ret = aw_dev_dsp_check(aw_dev);828 if (ret) {829 dev_err(aw_dev->dev, "dsp status check failed");830 goto dsp_check_fail;831 }832 } else {833 dev_dbg(aw_dev->dev, "start pa with dsp bypass");834 }835 836 /* enable tx feedback */837 aw_dev_i2s_tx_enable(aw_dev, true);838 839 if (aw88399->dither_st == AW88399_DITHER_EN_ENABLE_VALUE)840 aw88399_dev_set_dither(aw88399, true);841 842 /* close mute */843 aw88399_dev_mute(aw_dev, false);844 /* clear inturrupt */845 aw_dev_clear_int_status(aw_dev);846 aw_dev->status = AW88399_DEV_PW_ON;847 848 return 0;849 850dsp_check_fail:851crc_check_fail:852 aw_dev_dsp_enable(aw_dev, false);853sysst_check_fail:854 aw_dev_clear_int_status(aw_dev);855 aw_dev_amppd(aw_dev, true);856pll_check_fail:857 aw_dev_pwd(aw_dev, true);858 aw_dev->status = AW88399_DEV_PW_OFF;859 860 return ret;861}862 863static int aw_dev_dsp_update_container(struct aw_device *aw_dev,864 unsigned char *data, unsigned int len, unsigned short base)865{866 u32 tmp_len;867 int i, ret;868 869 mutex_lock(&aw_dev->dsp_lock);870 ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, base);871 if (ret)872 goto error_operation;873 874 for (i = 0; i < len; i += AW88399_MAX_RAM_WRITE_BYTE_SIZE) {875 if ((len - i) < AW88399_MAX_RAM_WRITE_BYTE_SIZE)876 tmp_len = len - i;877 else878 tmp_len = AW88399_MAX_RAM_WRITE_BYTE_SIZE;879 880 ret = regmap_raw_write(aw_dev->regmap, AW88399_DSPMDAT_REG,881 &data[i], tmp_len);882 if (ret)883 goto error_operation;884 }885 mutex_unlock(&aw_dev->dsp_lock);886 887 return 0;888 889error_operation:890 mutex_unlock(&aw_dev->dsp_lock);891 return ret;892}893 894static int aw_dev_get_ra(struct aw_cali_desc *cali_desc)895{896 struct aw_device *aw_dev =897 container_of(cali_desc, struct aw_device, cali_desc);898 u32 dsp_ra;899 int ret;900 901 ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_ADPZ_RA,902 &dsp_ra, AW88399_DSP_32_DATA);903 if (ret) {904 dev_err(aw_dev->dev, "read ra error");905 return ret;906 }907 908 cali_desc->ra = AW88399_DSP_RE_TO_SHOW_RE(dsp_ra,909 AW88399_DSP_RE_SHIFT);910 911 return 0;912}913 914static int aw_dev_dsp_update_cfg(struct aw_device *aw_dev,915 unsigned char *data, unsigned int len)916{917 int ret;918 919 dev_dbg(aw_dev->dev, "dsp config len:%d", len);920 921 if (!len || !data) {922 dev_err(aw_dev->dev, "dsp config data is null or len is 0");923 return -EINVAL;924 }925 926 ret = aw_dev_dsp_update_container(aw_dev, data, len, AW88399_DSP_CFG_ADDR);927 if (ret)928 return ret;929 930 aw_dev->dsp_cfg_len = len;931 932 ret = aw_dev_get_ra(&aw_dev->cali_desc);933 934 return ret;935}936 937static int aw_dev_dsp_update_fw(struct aw_device *aw_dev,938 unsigned char *data, unsigned int len)939{940 int ret;941 942 dev_dbg(aw_dev->dev, "dsp firmware len:%d", len);943 944 if (!len || !data) {945 dev_err(aw_dev->dev, "dsp firmware data is null or len is 0");946 return -EINVAL;947 }948 949 aw_dev->dsp_fw_len = len;950 ret = aw_dev_dsp_update_container(aw_dev, data, len, AW88399_DSP_FW_ADDR);951 952 return ret;953}954 955static int aw_dev_check_sram(struct aw_device *aw_dev)956{957 unsigned int reg_val;958 959 mutex_lock(&aw_dev->dsp_lock);960 /* read dsp_rom_check_reg */961 aw_dev_dsp_read_16bit(aw_dev, AW88399_DSP_ROM_CHECK_ADDR, ®_val);962 if (reg_val != AW88399_DSP_ROM_CHECK_DATA) {963 dev_err(aw_dev->dev, "check dsp rom failed, read[0x%x] != check[0x%x]",964 reg_val, AW88399_DSP_ROM_CHECK_DATA);965 goto error;966 }967 968 /* check dsp_cfg_base_addr */969 aw_dev_dsp_write_16bit(aw_dev, AW88399_DSP_CFG_ADDR, AW88399_DSP_ODD_NUM_BIT_TEST);970 aw_dev_dsp_read_16bit(aw_dev, AW88399_DSP_CFG_ADDR, ®_val);971 if (reg_val != AW88399_DSP_ODD_NUM_BIT_TEST) {972 dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] != write[0x%x]",973 reg_val, AW88399_DSP_ODD_NUM_BIT_TEST);974 goto error;975 }976 mutex_unlock(&aw_dev->dsp_lock);977 978 return 0;979error:980 mutex_unlock(&aw_dev->dsp_lock);981 return -EPERM;982}983 984static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char flag)985{986 int ret;987 988 switch (flag) {989 case AW88399_DEV_MEMCLK_PLL:990 ret = regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG,991 ~AW88399_MEM_CLKSEL_MASK,992 AW88399_MEM_CLKSEL_DAPHCLK_VALUE);993 if (ret)994 dev_err(aw_dev->dev, "memclk select pll failed");995 break;996 case AW88399_DEV_MEMCLK_OSC:997 ret = regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG,998 ~AW88399_MEM_CLKSEL_MASK,999 AW88399_MEM_CLKSEL_OSCCLK_VALUE);1000 if (ret)1001 dev_err(aw_dev->dev, "memclk select OSC failed");1002 break;1003 default:1004 dev_err(aw_dev->dev, "unknown memclk config, flag=0x%x", flag);1005 break;1006 }1007}1008 1009static void aw_dev_get_cur_mode_st(struct aw_device *aw_dev)1010{1011 struct aw_profctrl_desc *profctrl_desc = &aw_dev->profctrl_desc;1012 unsigned int reg_val;1013 int ret;1014 1015 ret = regmap_read(aw_dev->regmap, AW88399_SYSCTRL_REG, ®_val);1016 if (ret) {1017 dev_dbg(aw_dev->dev, "%s failed", __func__);1018 return;1019 }1020 if ((reg_val & (~AW88399_RCV_MODE_MASK)) == AW88399_RCV_MODE_RECEIVER_VALUE)1021 profctrl_desc->cur_mode = AW88399_RCV_MODE;1022 else1023 profctrl_desc->cur_mode = AW88399_NOT_RCV_MODE;1024}1025 1026static int aw_dev_update_reg_container(struct aw88399 *aw88399,1027 unsigned char *data, unsigned int len)1028{1029 struct aw_device *aw_dev = aw88399->aw_pa;1030 struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;1031 u16 read_vol, reg_val;1032 int data_len, i, ret;1033 int16_t *reg_data;1034 u8 reg_addr;1035 1036 reg_data = (int16_t *)data;1037 data_len = len >> 1;1038 1039 if (data_len & 0x1) {1040 dev_err(aw_dev->dev, "data len:%d unsupported", data_len);1041 return -EINVAL;1042 }1043 1044 for (i = 0; i < data_len; i += 2) {1045 reg_addr = reg_data[i];1046 reg_val = reg_data[i + 1];1047 1048 if (reg_addr == AW88399_DSPVCALB_REG) {1049 aw88399->vcalb_init_val = reg_val;1050 continue;1051 }1052 1053 if (reg_addr == AW88399_SYSCTRL_REG) {1054 if (reg_val & (~AW88399_DSPBY_MASK))1055 aw_dev->dsp_cfg = AW88399_DEV_DSP_BYPASS;1056 else1057 aw_dev->dsp_cfg = AW88399_DEV_DSP_WORK;1058 1059 reg_val &= (AW88399_HMUTE_MASK | AW88399_PWDN_MASK |1060 AW88399_DSPBY_MASK);1061 reg_val |= (AW88399_HMUTE_ENABLE_VALUE | AW88399_PWDN_POWER_DOWN_VALUE |1062 AW88399_DSPBY_BYPASS_VALUE);1063 }1064 1065 if (reg_addr == AW88399_I2SCTRL3_REG) {1066 reg_val &= AW88399_I2STXEN_MASK;1067 reg_val |= AW88399_I2STXEN_DISABLE_VALUE;1068 }1069 1070 if (reg_addr == AW88399_SYSCTRL2_REG) {1071 read_vol = (reg_val & (~AW88399_VOL_MASK)) >>1072 AW88399_VOL_START_BIT;1073 aw_dev->volume_desc.init_volume = read_vol;1074 }1075 1076 if (reg_addr == AW88399_DBGCTRL_REG) {1077 if ((reg_val & (~AW88399_EF_DBMD_MASK)) == AW88399_EF_DBMD_OR_VALUE)1078 aw88399->check_val = AW_EF_OR_CHECK;1079 else1080 aw88399->check_val = AW_EF_AND_CHECK;1081 1082 aw88399->dither_st = reg_val & (~AW88399_DITHER_EN_MASK);1083 }1084 1085 if (reg_addr == AW88399_CRCCTRL_REG)1086 aw88399->crc_init_val = reg_val;1087 1088 ret = regmap_write(aw_dev->regmap, reg_addr, reg_val);1089 if (ret)1090 return ret;1091 }1092 1093 aw_dev_pwd(aw_dev, false);1094 usleep_range(AW88399_1000_US, AW88399_1000_US + 10);1095 1096 aw_dev_get_cur_mode_st(aw_dev);1097 1098 if (aw_dev->prof_cur != aw_dev->prof_index)1099 vol_desc->ctl_volume = 0;1100 else1101 aw_dev_set_volume(aw_dev, vol_desc->ctl_volume);1102 1103 return 0;1104}1105 1106static int aw_dev_reg_update(struct aw88399 *aw88399,1107 unsigned char *data, unsigned int len)1108{1109 int ret;1110 1111 if (!len || !data) {1112 dev_err(aw88399->aw_pa->dev, "reg data is null or len is 0");1113 return -EINVAL;1114 }1115 1116 ret = aw_dev_update_reg_container(aw88399, data, len);1117 if (ret)1118 dev_err(aw88399->aw_pa->dev, "reg update failed");1119 1120 return ret;1121}1122 1123static int aw88399_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name)1124{1125 struct aw_prof_info *prof_info = &aw_dev->prof_info;1126 struct aw_prof_desc *prof_desc;1127 1128 if ((index >= aw_dev->prof_info.count) || (index < 0)) {1129 dev_err(aw_dev->dev, "index[%d] overflow count[%d]",1130 index, aw_dev->prof_info.count);1131 return -EINVAL;1132 }1133 1134 prof_desc = &aw_dev->prof_info.prof_desc[index];1135 1136 *prof_name = prof_info->prof_name_list[prof_desc->id];1137 1138 return 0;1139}1140 1141static int aw88399_dev_get_prof_data(struct aw_device *aw_dev, int index,1142 struct aw_prof_desc **prof_desc)1143{1144 if ((index >= aw_dev->prof_info.count) || (index < 0)) {1145 dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n",1146 __func__, index, aw_dev->prof_info.count);1147 return -EINVAL;1148 }1149 1150 *prof_desc = &aw_dev->prof_info.prof_desc[index];1151 1152 return 0;1153}1154 1155static int aw88399_dev_fw_update(struct aw88399 *aw88399, bool up_dsp_fw_en, bool force_up_en)1156{1157 struct aw_device *aw_dev = aw88399->aw_pa;1158 struct aw_prof_desc *prof_index_desc;1159 struct aw_sec_data_desc *sec_desc;1160 char *prof_name;1161 int ret;1162 1163 if ((aw_dev->prof_cur == aw_dev->prof_index) &&1164 (force_up_en == AW88399_FORCE_UPDATE_OFF)) {1165 dev_dbg(aw_dev->dev, "scene no change, not update");1166 return 0;1167 }1168 1169 if (aw_dev->fw_status == AW88399_DEV_FW_FAILED) {1170 dev_err(aw_dev->dev, "fw status[%d] error", aw_dev->fw_status);1171 return -EPERM;1172 }1173 1174 ret = aw88399_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name);1175 if (ret)1176 return ret;1177 1178 dev_dbg(aw_dev->dev, "start update %s", prof_name);1179 1180 ret = aw88399_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc);1181 if (ret)1182 return ret;1183 1184 /* update reg */1185 sec_desc = prof_index_desc->sec_desc;1186 ret = aw_dev_reg_update(aw88399, sec_desc[AW88395_DATA_TYPE_REG].data,1187 sec_desc[AW88395_DATA_TYPE_REG].len);1188 if (ret) {1189 dev_err(aw_dev->dev, "update reg failed");1190 return ret;1191 }1192 1193 aw88399_dev_mute(aw_dev, true);1194 1195 if (aw_dev->dsp_cfg == AW88399_DEV_DSP_WORK)1196 aw_dev_dsp_enable(aw_dev, false);1197 1198 aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_OSC);1199 1200 ret = aw_dev_check_sram(aw_dev);1201 if (ret) {1202 dev_err(aw_dev->dev, "check sram failed");1203 goto error;1204 }1205 1206 if (up_dsp_fw_en) {1207 dev_dbg(aw_dev->dev, "fw_ver: [%x]", prof_index_desc->fw_ver);1208 ret = aw_dev_dsp_update_fw(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_FW].data,1209 sec_desc[AW88395_DATA_TYPE_DSP_FW].len);1210 if (ret) {1211 dev_err(aw_dev->dev, "update dsp fw failed");1212 goto error;1213 }1214 }1215 1216 /* update dsp config */1217 ret = aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_CFG].data,1218 sec_desc[AW88395_DATA_TYPE_DSP_CFG].len);1219 if (ret) {1220 dev_err(aw_dev->dev, "update dsp cfg failed");1221 goto error;1222 }1223 1224 aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL);1225 1226 aw_dev->prof_cur = aw_dev->prof_index;1227 1228 return 0;1229 1230error:1231 aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL);1232 return ret;1233}1234 1235static void aw88399_start_pa(struct aw88399 *aw88399)1236{1237 int ret, i;1238 1239 for (i = 0; i < AW88399_START_RETRIES; i++) {1240 ret = aw88399_dev_start(aw88399);1241 if (ret) {1242 dev_err(aw88399->aw_pa->dev, "aw88399 device start failed. retry = %d", i);1243 ret = aw88399_dev_fw_update(aw88399, AW88399_DSP_FW_UPDATE_ON, true);1244 if (ret) {1245 dev_err(aw88399->aw_pa->dev, "fw update failed");1246 continue;1247 }1248 } else {1249 dev_dbg(aw88399->aw_pa->dev, "start success\n");1250 break;1251 }1252 }1253}1254 1255static void aw88399_startup_work(struct work_struct *work)1256{1257 struct aw88399 *aw88399 =1258 container_of(work, struct aw88399, start_work.work);1259 1260 mutex_lock(&aw88399->lock);1261 aw88399_start_pa(aw88399);1262 mutex_unlock(&aw88399->lock);1263}1264 1265static void aw88399_start(struct aw88399 *aw88399, bool sync_start)1266{1267 int ret;1268 1269 if (aw88399->aw_pa->fw_status != AW88399_DEV_FW_OK)1270 return;1271 1272 if (aw88399->aw_pa->status == AW88399_DEV_PW_ON)1273 return;1274 1275 ret = aw88399_dev_fw_update(aw88399, AW88399_DSP_FW_UPDATE_OFF, true);1276 if (ret) {1277 dev_err(aw88399->aw_pa->dev, "fw update failed.");1278 return;1279 }1280 1281 if (sync_start == AW88399_SYNC_START)1282 aw88399_start_pa(aw88399);1283 else1284 queue_delayed_work(system_wq,1285 &aw88399->start_work,1286 AW88399_START_WORK_DELAY_MS);1287}1288 1289static int aw_dev_check_sysint(struct aw_device *aw_dev)1290{1291 u16 reg_val;1292 1293 aw_dev_get_int_status(aw_dev, ®_val);1294 if (reg_val & AW88399_BIT_SYSINT_CHECK) {1295 dev_err(aw_dev->dev, "pa stop check fail:0x%04x", reg_val);1296 return -EINVAL;1297 }1298 1299 return 0;1300}1301 1302static int aw88399_stop(struct aw_device *aw_dev)1303{1304 struct aw_sec_data_desc *dsp_cfg =1305 &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYPE_DSP_CFG];1306 struct aw_sec_data_desc *dsp_fw =1307 &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYPE_DSP_FW];1308 int int_st;1309 1310 if (aw_dev->status == AW88399_DEV_PW_OFF) {1311 dev_dbg(aw_dev->dev, "already power off");1312 return 0;1313 }1314 1315 aw_dev->status = AW88399_DEV_PW_OFF;1316 1317 aw88399_dev_mute(aw_dev, true);1318 usleep_range(AW88399_4000_US, AW88399_4000_US + 100);1319 1320 aw_dev_i2s_tx_enable(aw_dev, false);1321 usleep_range(AW88399_1000_US, AW88399_1000_US + 100);1322 1323 int_st = aw_dev_check_sysint(aw_dev);1324 1325 aw_dev_dsp_enable(aw_dev, false);1326 1327 aw_dev_amppd(aw_dev, true);1328 1329 if (int_st) {1330 aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_OSC);1331 aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len);1332 aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len);1333 aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL);1334 }1335 1336 aw_dev_pwd(aw_dev, true);1337 1338 return 0;1339}1340 1341static struct snd_soc_dai_driver aw88399_dai[] = {1342 {1343 .name = "aw88399-aif",1344 .id = 1,1345 .playback = {1346 .stream_name = "Speaker_Playback",1347 .channels_min = 1,1348 .channels_max = 2,1349 .rates = AW88399_RATES,1350 .formats = AW88399_FORMATS,1351 },1352 .capture = {1353 .stream_name = "Speaker_Capture",1354 .channels_min = 1,1355 .channels_max = 2,1356 .rates = AW88399_RATES,1357 .formats = AW88399_FORMATS,1358 },1359 },1360};1361 1362static int aw88399_get_fade_in_time(struct snd_kcontrol *kcontrol,1363 struct snd_ctl_elem_value *ucontrol)1364{1365 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1366 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(component);1367 struct aw_device *aw_dev = aw88399->aw_pa;1368 1369 ucontrol->value.integer.value[0] = aw_dev->fade_in_time;1370 1371 return 0;1372}1373 1374static int aw88399_set_fade_in_time(struct snd_kcontrol *kcontrol,1375 struct snd_ctl_elem_value *ucontrol)1376{1377 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1378 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(component);1379 struct soc_mixer_control *mc =1380 (struct soc_mixer_control *)kcontrol->private_value;1381 struct aw_device *aw_dev = aw88399->aw_pa;1382 int time;1383 1384 time = ucontrol->value.integer.value[0];1385 1386 if (time < mc->min || time > mc->max)1387 return -EINVAL;1388 1389 if (time != aw_dev->fade_in_time) {1390 aw_dev->fade_in_time = time;1391 return 1;1392 }1393 1394 return 0;1395}1396 1397static int aw88399_get_fade_out_time(struct snd_kcontrol *kcontrol,1398 struct snd_ctl_elem_value *ucontrol)1399{1400 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1401 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(component);1402 struct aw_device *aw_dev = aw88399->aw_pa;1403 1404 ucontrol->value.integer.value[0] = aw_dev->fade_out_time;1405 1406 return 0;1407}1408 1409static int aw88399_set_fade_out_time(struct snd_kcontrol *kcontrol,1410 struct snd_ctl_elem_value *ucontrol)1411{1412 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1413 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(component);1414 struct soc_mixer_control *mc =1415 (struct soc_mixer_control *)kcontrol->private_value;1416 struct aw_device *aw_dev = aw88399->aw_pa;1417 int time;1418 1419 time = ucontrol->value.integer.value[0];1420 if (time < mc->min || time > mc->max)1421 return -EINVAL;1422 1423 if (time != aw_dev->fade_out_time) {1424 aw_dev->fade_out_time = time;1425 return 1;1426 }1427 1428 return 0;1429}1430 1431static int aw88399_dev_set_profile_index(struct aw_device *aw_dev, int index)1432{1433 /* check the index whether is valid */1434 if ((index >= aw_dev->prof_info.count) || (index < 0))1435 return -EINVAL;1436 /* check the index whether change */1437 if (aw_dev->prof_index == index)1438 return -EINVAL;1439 1440 aw_dev->prof_index = index;1441 dev_dbg(aw_dev->dev, "set prof[%s]",1442 aw_dev->prof_info.prof_name_list[aw_dev->prof_info.prof_desc[index].id]);1443 1444 return 0;1445}1446 1447static int aw88399_profile_info(struct snd_kcontrol *kcontrol,1448 struct snd_ctl_elem_info *uinfo)1449{1450 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1451 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1452 char *prof_name, *name;1453 int count, ret;1454 1455 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;1456 uinfo->count = 1;1457 1458 count = aw88399->aw_pa->prof_info.count;1459 if (count <= 0) {1460 uinfo->value.enumerated.items = 0;1461 return 0;1462 }1463 1464 uinfo->value.enumerated.items = count;1465 1466 if (uinfo->value.enumerated.item >= count)1467 uinfo->value.enumerated.item = count - 1;1468 1469 name = uinfo->value.enumerated.name;1470 count = uinfo->value.enumerated.item;1471 1472 ret = aw88399_dev_get_prof_name(aw88399->aw_pa, count, &prof_name);1473 if (ret) {1474 strscpy(uinfo->value.enumerated.name, "null",1475 strlen("null") + 1);1476 return 0;1477 }1478 1479 strscpy(name, prof_name, sizeof(uinfo->value.enumerated.name));1480 1481 return 0;1482}1483 1484static int aw88399_profile_get(struct snd_kcontrol *kcontrol,1485 struct snd_ctl_elem_value *ucontrol)1486{1487 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1488 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1489 1490 ucontrol->value.integer.value[0] = aw88399->aw_pa->prof_index;1491 1492 return 0;1493}1494 1495static int aw88399_profile_set(struct snd_kcontrol *kcontrol,1496 struct snd_ctl_elem_value *ucontrol)1497{1498 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1499 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1500 int ret;1501 1502 mutex_lock(&aw88399->lock);1503 ret = aw88399_dev_set_profile_index(aw88399->aw_pa, ucontrol->value.integer.value[0]);1504 if (ret) {1505 dev_dbg(codec->dev, "profile index does not change");1506 mutex_unlock(&aw88399->lock);1507 return 0;1508 }1509 1510 if (aw88399->aw_pa->status) {1511 aw88399_stop(aw88399->aw_pa);1512 aw88399_start(aw88399, AW88399_SYNC_START);1513 }1514 1515 mutex_unlock(&aw88399->lock);1516 1517 return 1;1518}1519 1520static int aw88399_volume_get(struct snd_kcontrol *kcontrol,1521 struct snd_ctl_elem_value *ucontrol)1522{1523 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1524 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1525 struct aw_volume_desc *vol_desc = &aw88399->aw_pa->volume_desc;1526 1527 ucontrol->value.integer.value[0] = vol_desc->ctl_volume;1528 1529 return 0;1530}1531 1532static int aw88399_volume_set(struct snd_kcontrol *kcontrol,1533 struct snd_ctl_elem_value *ucontrol)1534{1535 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1536 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1537 struct aw_volume_desc *vol_desc = &aw88399->aw_pa->volume_desc;1538 struct soc_mixer_control *mc =1539 (struct soc_mixer_control *)kcontrol->private_value;1540 int value;1541 1542 value = ucontrol->value.integer.value[0];1543 if (value < mc->min || value > mc->max)1544 return -EINVAL;1545 1546 if (vol_desc->ctl_volume != value) {1547 vol_desc->ctl_volume = value;1548 aw_dev_set_volume(aw88399->aw_pa, vol_desc->ctl_volume);1549 1550 return 1;1551 }1552 1553 return 0;1554}1555 1556static int aw88399_get_fade_step(struct snd_kcontrol *kcontrol,1557 struct snd_ctl_elem_value *ucontrol)1558{1559 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1560 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1561 1562 ucontrol->value.integer.value[0] = aw88399->aw_pa->fade_step;1563 1564 return 0;1565}1566 1567static int aw88399_set_fade_step(struct snd_kcontrol *kcontrol,1568 struct snd_ctl_elem_value *ucontrol)1569{1570 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1571 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1572 struct soc_mixer_control *mc =1573 (struct soc_mixer_control *)kcontrol->private_value;1574 int value;1575 1576 value = ucontrol->value.integer.value[0];1577 if (value < mc->min || value > mc->max)1578 return -EINVAL;1579 1580 if (aw88399->aw_pa->fade_step != value) {1581 aw88399->aw_pa->fade_step = value;1582 return 1;1583 }1584 1585 return 0;1586}1587 1588static int aw88399_re_get(struct snd_kcontrol *kcontrol,1589 struct snd_ctl_elem_value *ucontrol)1590{1591 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1592 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1593 struct aw_device *aw_dev = aw88399->aw_pa;1594 1595 ucontrol->value.integer.value[0] = aw_dev->cali_desc.cali_re;1596 1597 return 0;1598}1599 1600static int aw88399_re_set(struct snd_kcontrol *kcontrol,1601 struct snd_ctl_elem_value *ucontrol)1602{1603 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);1604 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec);1605 struct soc_mixer_control *mc =1606 (struct soc_mixer_control *)kcontrol->private_value;1607 struct aw_device *aw_dev = aw88399->aw_pa;1608 int value;1609 1610 value = ucontrol->value.integer.value[0];1611 if (value < mc->min || value > mc->max)1612 return -EINVAL;1613 1614 if (aw_dev->cali_desc.cali_re != value) {1615 aw_dev->cali_desc.cali_re = value;1616 return 1;1617 }1618 1619 return 0;1620}1621 1622static int aw88399_dev_init(struct aw88399 *aw88399, struct aw_container *aw_cfg)1623{1624 struct aw_device *aw_dev = aw88399->aw_pa;1625 int ret;1626 1627 ret = aw88395_dev_cfg_load(aw_dev, aw_cfg);1628 if (ret) {1629 dev_err(aw_dev->dev, "aw_dev acf parse failed");1630 return -EINVAL;1631 }1632 aw_dev->fade_in_time = AW88399_1000_US / 10;1633 aw_dev->fade_out_time = AW88399_1000_US >> 1;1634 aw_dev->prof_cur = aw_dev->prof_info.prof_desc[0].id;1635 aw_dev->prof_index = aw_dev->prof_info.prof_desc[0].id;1636 1637 ret = aw88399_dev_fw_update(aw88399, AW88399_FORCE_UPDATE_ON, AW88399_DSP_FW_UPDATE_ON);1638 if (ret) {1639 dev_err(aw_dev->dev, "fw update failed ret = %d\n", ret);1640 return ret;1641 }1642 1643 aw88399_dev_mute(aw_dev, true);1644 1645 /* close tx feedback */1646 aw_dev_i2s_tx_enable(aw_dev, false);1647 usleep_range(AW88399_1000_US, AW88399_1000_US + 100);1648 1649 /* enable amppd */1650 aw_dev_amppd(aw_dev, true);1651 1652 /* close dsp */1653 aw_dev_dsp_enable(aw_dev, false);1654 /* set power down */1655 aw_dev_pwd(aw_dev, true);1656 1657 return 0;1658}1659 1660static int aw88399_request_firmware_file(struct aw88399 *aw88399)1661{1662 const struct firmware *cont = NULL;1663 int ret;1664 1665 aw88399->aw_pa->fw_status = AW88399_DEV_FW_FAILED;1666 1667 ret = request_firmware(&cont, AW88399_ACF_FILE, aw88399->aw_pa->dev);1668 if (ret) {1669 dev_err(aw88399->aw_pa->dev, "request [%s] failed!", AW88399_ACF_FILE);1670 return ret;1671 }1672 1673 dev_dbg(aw88399->aw_pa->dev, "loaded %s - size: %zu\n",1674 AW88399_ACF_FILE, cont ? cont->size : 0);1675 1676 aw88399->aw_cfg = devm_kzalloc(aw88399->aw_pa->dev,1677 struct_size(aw88399->aw_cfg, data, cont->size), GFP_KERNEL);1678 if (!aw88399->aw_cfg) {1679 release_firmware(cont);1680 return -ENOMEM;1681 }1682 aw88399->aw_cfg->len = (int)cont->size;1683 memcpy(aw88399->aw_cfg->data, cont->data, cont->size);1684 release_firmware(cont);1685 1686 ret = aw88395_dev_load_acf_check(aw88399->aw_pa, aw88399->aw_cfg);1687 if (ret) {1688 dev_err(aw88399->aw_pa->dev, "load [%s] failed!", AW88399_ACF_FILE);1689 return ret;1690 }1691 1692 mutex_lock(&aw88399->lock);1693 /* aw device init */1694 ret = aw88399_dev_init(aw88399, aw88399->aw_cfg);1695 if (ret)1696 dev_err(aw88399->aw_pa->dev, "dev init failed");1697 mutex_unlock(&aw88399->lock);1698 1699 return ret;1700}1701 1702static const struct snd_kcontrol_new aw88399_controls[] = {1703 SOC_SINGLE_EXT("PCM Playback Volume", AW88399_SYSCTRL2_REG,1704 6, AW88399_MUTE_VOL, 0, aw88399_volume_get,1705 aw88399_volume_set),1706 SOC_SINGLE_EXT("Fade Step", 0, 0, AW88399_MUTE_VOL, 0,1707 aw88399_get_fade_step, aw88399_set_fade_step),1708 SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN,1709 aw88399_get_fade_in_time, aw88399_set_fade_in_time),1710 SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN,1711 aw88399_get_fade_out_time, aw88399_set_fade_out_time),1712 SOC_SINGLE_EXT("Calib", 0, 0, AW88399_CALI_RE_MAX, 0,1713 aw88399_re_get, aw88399_re_set),1714 AW88399_PROFILE_EXT("AW88399 Profile Set", aw88399_profile_info,1715 aw88399_profile_get, aw88399_profile_set),1716};1717 1718static int aw88399_playback_event(struct snd_soc_dapm_widget *w,1719 struct snd_kcontrol *k, int event)1720{1721 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1722 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(component);1723 1724 mutex_lock(&aw88399->lock);1725 switch (event) {1726 case SND_SOC_DAPM_PRE_PMU:1727 aw88399_start(aw88399, AW88399_ASYNC_START);1728 break;1729 case SND_SOC_DAPM_POST_PMD:1730 aw88399_stop(aw88399->aw_pa);1731 break;1732 default:1733 break;1734 }1735 mutex_unlock(&aw88399->lock);1736 1737 return 0;1738}1739 1740static const struct snd_soc_dapm_widget aw88399_dapm_widgets[] = {1741 /* playback */1742 SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, 0, 0, 0,1743 aw88399_playback_event,1744 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1745 SND_SOC_DAPM_OUTPUT("DAC Output"),1746 1747 /* capture */1748 SND_SOC_DAPM_AIF_OUT("AIF_TX", "Speaker_Capture", 0, SND_SOC_NOPM, 0, 0),1749 SND_SOC_DAPM_INPUT("ADC Input"),1750};1751 1752static const struct snd_soc_dapm_route aw88399_audio_map[] = {1753 {"DAC Output", NULL, "AIF_RX"},1754 {"AIF_TX", NULL, "ADC Input"},1755};1756 1757static int aw88399_codec_probe(struct snd_soc_component *component)1758{1759 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(component);1760 int ret;1761 1762 INIT_DELAYED_WORK(&aw88399->start_work, aw88399_startup_work);1763 1764 ret = aw88399_request_firmware_file(aw88399);1765 if (ret)1766 dev_err(aw88399->aw_pa->dev, "%s failed\n", __func__);1767 1768 return ret;1769}1770 1771static void aw88399_codec_remove(struct snd_soc_component *aw_codec)1772{1773 struct aw88399 *aw88399 = snd_soc_component_get_drvdata(aw_codec);1774 1775 cancel_delayed_work_sync(&aw88399->start_work);1776}1777 1778static const struct snd_soc_component_driver soc_codec_dev_aw88399 = {1779 .probe = aw88399_codec_probe,1780 .remove = aw88399_codec_remove,1781 .dapm_widgets = aw88399_dapm_widgets,1782 .num_dapm_widgets = ARRAY_SIZE(aw88399_dapm_widgets),1783 .dapm_routes = aw88399_audio_map,1784 .num_dapm_routes = ARRAY_SIZE(aw88399_audio_map),1785 .controls = aw88399_controls,1786 .num_controls = ARRAY_SIZE(aw88399_controls),1787};1788 1789static void aw88399_hw_reset(struct aw88399 *aw88399)1790{1791 if (aw88399->reset_gpio) {1792 gpiod_set_value_cansleep(aw88399->reset_gpio, 1);1793 usleep_range(AW88399_1000_US, AW88399_1000_US + 10);1794 gpiod_set_value_cansleep(aw88399->reset_gpio, 0);1795 usleep_range(AW88399_1000_US, AW88399_1000_US + 10);1796 gpiod_set_value_cansleep(aw88399->reset_gpio, 1);1797 usleep_range(AW88399_1000_US, AW88399_1000_US + 10);1798 }1799}1800 1801static void aw88399_parse_channel_dt(struct aw_device *aw_dev)1802{1803 struct device_node *np = aw_dev->dev->of_node;1804 u32 channel_value;1805 1806 of_property_read_u32(np, "awinic,audio-channel", &channel_value);1807 aw_dev->channel = channel_value;1808}1809 1810static int aw88399_init(struct aw88399 *aw88399, struct i2c_client *i2c, struct regmap *regmap)1811{1812 struct aw_device *aw_dev;1813 unsigned int chip_id;1814 int ret;1815 1816 ret = regmap_read(regmap, AW88399_ID_REG, &chip_id);1817 if (ret) {1818 dev_err(&i2c->dev, "%s read chipid error. ret = %d", __func__, ret);1819 return ret;1820 }1821 if (chip_id != AW88399_CHIP_ID) {1822 dev_err(&i2c->dev, "unsupported device");1823 return -ENXIO;1824 }1825 dev_dbg(&i2c->dev, "chip id = %x\n", chip_id);1826 1827 aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL);1828 if (!aw_dev)1829 return -ENOMEM;1830 aw88399->aw_pa = aw_dev;1831 1832 aw_dev->i2c = i2c;1833 aw_dev->dev = &i2c->dev;1834 aw_dev->regmap = regmap;1835 mutex_init(&aw_dev->dsp_lock);1836 1837 aw_dev->chip_id = chip_id;1838 aw_dev->acf = NULL;1839 aw_dev->prof_info.prof_desc = NULL;1840 aw_dev->prof_info.count = 0;1841 aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID;1842 aw_dev->channel = AW88399_DEV_DEFAULT_CH;1843 aw_dev->fw_status = AW88399_DEV_FW_FAILED;1844 1845 aw_dev->fade_step = AW88399_VOLUME_STEP_DB;1846 aw_dev->volume_desc.ctl_volume = AW88399_VOL_DEFAULT_VALUE;1847 1848 aw88399_parse_channel_dt(aw_dev);1849 1850 return 0;1851}1852 1853static int aw88399_i2c_probe(struct i2c_client *i2c)1854{1855 struct aw88399 *aw88399;1856 int ret;1857 1858 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))1859 return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed");1860 1861 aw88399 = devm_kzalloc(&i2c->dev, sizeof(*aw88399), GFP_KERNEL);1862 if (!aw88399)1863 return -ENOMEM;1864 1865 mutex_init(&aw88399->lock);1866 1867 i2c_set_clientdata(i2c, aw88399);1868 1869 aw88399->reset_gpio = devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD_OUT_LOW);1870 if (IS_ERR(aw88399->reset_gpio))1871 return dev_err_probe(&i2c->dev, PTR_ERR(aw88399->reset_gpio),1872 "reset gpio not defined\n");1873 aw88399_hw_reset(aw88399);1874 1875 aw88399->regmap = devm_regmap_init_i2c(i2c, &aw88399_remap_config);1876 if (IS_ERR(aw88399->regmap))1877 return dev_err_probe(&i2c->dev, PTR_ERR(aw88399->regmap),1878 "failed to init regmap\n");1879 1880 /* aw pa init */1881 ret = aw88399_init(aw88399, i2c, aw88399->regmap);1882 if (ret)1883 return ret;1884 1885 ret = devm_snd_soc_register_component(&i2c->dev,1886 &soc_codec_dev_aw88399,1887 aw88399_dai, ARRAY_SIZE(aw88399_dai));1888 if (ret)1889 dev_err(&i2c->dev, "failed to register aw88399: %d", ret);1890 1891 return ret;1892}1893 1894static const struct i2c_device_id aw88399_i2c_id[] = {1895 { AW88399_I2C_NAME },1896 { }1897};1898MODULE_DEVICE_TABLE(i2c, aw88399_i2c_id);1899 1900static struct i2c_driver aw88399_i2c_driver = {1901 .driver = {1902 .name = AW88399_I2C_NAME,1903 },1904 .probe = aw88399_i2c_probe,1905 .id_table = aw88399_i2c_id,1906};1907module_i2c_driver(aw88399_i2c_driver);1908 1909MODULE_DESCRIPTION("ASoC AW88399 Smart PA Driver");1910MODULE_LICENSE("GPL v2");1911