1285 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// aw88261.c -- AW88261 ALSA SoC Audio driver4//5// Copyright (c) 2023 awinic Technology CO., LTD6//7// Author: Jimmy Zhang <zhangjianming@awinic.com>8// Author: Weidong Wang <wangweidong.a@awinic.com>9//10 11#include <linux/i2c.h>12#include <linux/firmware.h>13#include <linux/regmap.h>14#include <sound/soc.h>15#include "aw88261.h"16#include "aw88395/aw88395_data_type.h"17#include "aw88395/aw88395_device.h"18 19static const struct regmap_config aw88261_remap_config = {20 .val_bits = 16,21 .reg_bits = 8,22 .max_register = AW88261_REG_MAX,23 .reg_format_endian = REGMAP_ENDIAN_LITTLE,24 .val_format_endian = REGMAP_ENDIAN_BIG,25};26 27static void aw88261_dev_set_volume(struct aw_device *aw_dev, unsigned int value)28{29 struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;30 unsigned int real_value, volume;31 unsigned int reg_value;32 33 volume = min((value + vol_desc->init_volume), (unsigned int)AW88261_MUTE_VOL);34 real_value = DB_TO_REG_VAL(volume);35 36 regmap_read(aw_dev->regmap, AW88261_SYSCTRL2_REG, ®_value);37 38 real_value = (real_value | (reg_value & AW88261_VOL_START_MASK));39 40 dev_dbg(aw_dev->dev, "value 0x%x , real_value:0x%x", value, real_value);41 42 regmap_write(aw_dev->regmap, AW88261_SYSCTRL2_REG, real_value);43}44 45static void aw88261_dev_fade_in(struct aw_device *aw_dev)46{47 struct aw_volume_desc *desc = &aw_dev->volume_desc;48 int fade_in_vol = desc->ctl_volume;49 int fade_step = aw_dev->fade_step;50 int i;51 52 if (fade_step == 0 || aw_dev->fade_in_time == 0) {53 aw88261_dev_set_volume(aw_dev, fade_in_vol);54 return;55 }56 57 for (i = AW88261_MUTE_VOL; i >= fade_in_vol; i -= fade_step) {58 aw88261_dev_set_volume(aw_dev, i);59 usleep_range(aw_dev->fade_in_time,60 aw_dev->fade_in_time + 10);61 }62 63 if (i != fade_in_vol)64 aw88261_dev_set_volume(aw_dev, fade_in_vol);65}66 67static void aw88261_dev_fade_out(struct aw_device *aw_dev)68{69 struct aw_volume_desc *desc = &aw_dev->volume_desc;70 int fade_step = aw_dev->fade_step;71 int i;72 73 if (fade_step == 0 || aw_dev->fade_out_time == 0) {74 aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL);75 return;76 }77 78 for (i = desc->ctl_volume; i <= AW88261_MUTE_VOL; i += fade_step) {79 aw88261_dev_set_volume(aw_dev, i);80 usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10);81 }82 83 if (i != AW88261_MUTE_VOL) {84 aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL);85 usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10);86 }87}88 89static void aw88261_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag)90{91 if (flag)92 regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG,93 ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_ENABLE_VALUE);94 else95 regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG,96 ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_DISABLE_VALUE);97}98 99static void aw88261_dev_pwd(struct aw_device *aw_dev, bool pwd)100{101 if (pwd)102 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,103 ~AW88261_PWDN_MASK, AW88261_PWDN_POWER_DOWN_VALUE);104 else105 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,106 ~AW88261_PWDN_MASK, AW88261_PWDN_WORKING_VALUE);107}108 109static void aw88261_dev_amppd(struct aw_device *aw_dev, bool amppd)110{111 if (amppd)112 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,113 ~AW88261_AMPPD_MASK, AW88261_AMPPD_POWER_DOWN_VALUE);114 else115 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,116 ~AW88261_AMPPD_MASK, AW88261_AMPPD_WORKING_VALUE);117}118 119static void aw88261_dev_mute(struct aw_device *aw_dev, bool is_mute)120{121 if (is_mute) {122 aw88261_dev_fade_out(aw_dev);123 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,124 ~AW88261_HMUTE_MASK, AW88261_HMUTE_ENABLE_VALUE);125 } else {126 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,127 ~AW88261_HMUTE_MASK, AW88261_HMUTE_DISABLE_VALUE);128 aw88261_dev_fade_in(aw_dev);129 }130}131 132static void aw88261_dev_clear_int_status(struct aw_device *aw_dev)133{134 unsigned int int_status;135 136 /* read int status and clear */137 regmap_read(aw_dev->regmap, AW88261_SYSINT_REG, &int_status);138 /* make sure int status is clear */139 regmap_read(aw_dev->regmap, AW88261_SYSINT_REG, &int_status);140 141 dev_dbg(aw_dev->dev, "read interrupt reg = 0x%04x", int_status);142}143 144static int aw88261_dev_get_iis_status(struct aw_device *aw_dev)145{146 unsigned int reg_val;147 int ret;148 149 ret = regmap_read(aw_dev->regmap, AW88261_SYSST_REG, ®_val);150 if (ret)151 return ret;152 if ((reg_val & AW88261_BIT_PLL_CHECK) != AW88261_BIT_PLL_CHECK) {153 dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val);154 return -EINVAL;155 }156 157 return ret;158}159 160static int aw88261_dev_check_mode1_pll(struct aw_device *aw_dev)161{162 int ret, i;163 164 for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {165 ret = aw88261_dev_get_iis_status(aw_dev);166 if (ret) {167 dev_err(aw_dev->dev, "mode1 iis signal check error");168 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);169 } else {170 return ret;171 }172 }173 174 return -EPERM;175}176 177static int aw88261_dev_check_mode2_pll(struct aw_device *aw_dev)178{179 unsigned int reg_val;180 int ret, i;181 182 ret = regmap_read(aw_dev->regmap, AW88261_PLLCTRL1_REG, ®_val);183 if (ret)184 return ret;185 186 reg_val &= (~AW88261_CCO_MUX_MASK);187 if (reg_val == AW88261_CCO_MUX_DIVIDED_VALUE) {188 dev_dbg(aw_dev->dev, "CCO_MUX is already divider");189 return -EPERM;190 }191 192 /* change mode2 */193 ret = regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG,194 ~AW88261_CCO_MUX_MASK, AW88261_CCO_MUX_DIVIDED_VALUE);195 if (ret)196 return ret;197 198 for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {199 ret = aw88261_dev_get_iis_status(aw_dev);200 if (ret) {201 dev_err(aw_dev->dev, "mode2 iis signal check error");202 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);203 } else {204 break;205 }206 }207 208 /* change mode1 */209 ret = regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG,210 ~AW88261_CCO_MUX_MASK, AW88261_CCO_MUX_BYPASS_VALUE);211 if (ret == 0) {212 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);213 for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {214 ret = aw88261_dev_check_mode1_pll(aw_dev);215 if (ret) {216 dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error");217 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);218 } else {219 break;220 }221 }222 }223 224 return ret;225}226 227static int aw88261_dev_check_syspll(struct aw_device *aw_dev)228{229 int ret;230 231 ret = aw88261_dev_check_mode1_pll(aw_dev);232 if (ret) {233 dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check");234 ret = aw88261_dev_check_mode2_pll(aw_dev);235 if (ret) {236 dev_err(aw_dev->dev, "mode2 check iis failed");237 return ret;238 }239 }240 241 return ret;242}243 244static int aw88261_dev_check_sysst(struct aw_device *aw_dev)245{246 unsigned int check_val;247 unsigned int reg_val;248 int ret, i;249 250 for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {251 ret = regmap_read(aw_dev->regmap, AW88261_SYSST_REG, ®_val);252 if (ret)253 return ret;254 255 check_val = reg_val & (~AW88261_BIT_SYSST_CHECK_MASK)256 & AW88261_BIT_SYSST_CHECK;257 if (check_val != AW88261_BIT_SYSST_CHECK) {258 dev_err(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",259 reg_val, AW88261_BIT_SYSST_CHECK);260 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);261 } else {262 return 0;263 }264 }265 266 return -EPERM;267}268 269static void aw88261_dev_uls_hmute(struct aw_device *aw_dev, bool uls_hmute)270{271 if (uls_hmute)272 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,273 ~AW88261_ULS_HMUTE_MASK,274 AW88261_ULS_HMUTE_ENABLE_VALUE);275 else276 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,277 ~AW88261_ULS_HMUTE_MASK,278 AW88261_ULS_HMUTE_DISABLE_VALUE);279}280 281static void aw88261_reg_force_set(struct aw88261 *aw88261)282{283 if (aw88261->frcset_en == AW88261_FRCSET_ENABLE) {284 /* set FORCE_PWM */285 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL3_REG,286 AW88261_FORCE_PWM_MASK, AW88261_FORCE_PWM_FORCEMINUS_PWM_VALUE);287 /* set BOOST_OS_WIDTH */288 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL5_REG,289 AW88261_BST_OS_WIDTH_MASK, AW88261_BST_OS_WIDTH_50NS_VALUE);290 /* set BURST_LOOPR */291 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL6_REG,292 AW88261_BST_LOOPR_MASK, AW88261_BST_LOOPR_340K_VALUE);293 /* set RSQN_DLY */294 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL7_REG,295 AW88261_RSQN_DLY_MASK, AW88261_RSQN_DLY_35NS_VALUE);296 /* set BURST_SSMODE */297 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL8_REG,298 AW88261_BURST_SSMODE_MASK, AW88261_BURST_SSMODE_FAST_VALUE);299 /* set BST_BURST */300 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL9_REG,301 AW88261_BST_BURST_MASK, AW88261_BST_BURST_30MA_VALUE);302 } else {303 dev_dbg(aw88261->aw_pa->dev, "needn't set reg value");304 }305}306 307static int aw88261_dev_get_icalk(struct aw_device *aw_dev, int16_t *icalk)308{309 u16 reg_icalk, reg_icalkl;310 unsigned int reg_val;311 int ret;312 313 ret = regmap_read(aw_dev->regmap, AW88261_EFRH4_REG, ®_val);314 if (ret)315 return ret;316 317 reg_icalk = reg_val & (~AW88261_EF_ISN_GESLP_H_MASK);318 319 ret = regmap_read(aw_dev->regmap, AW88261_EFRL4_REG, ®_val);320 if (ret)321 return ret;322 323 reg_icalkl = reg_val & (~AW88261_EF_ISN_GESLP_L_MASK);324 325 reg_icalk = (reg_icalk >> AW88261_ICALK_SHIFT) & (reg_icalkl >> AW88261_ICALKL_SHIFT);326 327 if (reg_icalk & (~AW88261_EF_ISN_GESLP_SIGN_MASK))328 reg_icalk = reg_icalk | ~AW88261_EF_ISN_GESLP_NEG;329 330 *icalk = (int16_t)reg_icalk;331 332 return ret;333}334 335static int aw88261_dev_get_vcalk(struct aw_device *aw_dev, int16_t *vcalk)336{337 u16 reg_vcalk, reg_vcalkl;338 unsigned int reg_val;339 int ret;340 341 ret = regmap_read(aw_dev->regmap, AW88261_EFRH3_REG, ®_val);342 if (ret)343 return ret;344 345 reg_vcalk = (u16)reg_val & (~AW88261_EF_VSN_GESLP_H_MASK);346 347 ret = regmap_read(aw_dev->regmap, AW88261_EFRL3_REG, ®_val);348 if (ret)349 return ret;350 351 reg_vcalkl = (u16)reg_val & (~AW88261_EF_VSN_GESLP_L_MASK);352 353 reg_vcalk = (reg_vcalk >> AW88261_VCALK_SHIFT) & (reg_vcalkl >> AW88261_VCALKL_SHIFT);354 355 if (reg_vcalk & AW88261_EF_VSN_GESLP_SIGN_MASK)356 reg_vcalk = reg_vcalk | (~AW88261_EF_VSN_GESLP_NEG);357 *vcalk = (int16_t)reg_vcalk;358 359 return ret;360}361 362static int aw88261_dev_set_vcalb(struct aw_device *aw_dev)363{364 int16_t icalk_val, vcalk_val;365 int icalk, vcalk, vcalb;366 u32 reg_val;367 int ret;368 369 ret = aw88261_dev_get_icalk(aw_dev, &icalk_val);370 if (ret)371 return ret;372 373 ret = aw88261_dev_get_vcalk(aw_dev, &vcalk_val);374 if (ret)375 return ret;376 377 icalk = AW88261_CABL_BASE_VALUE + AW88261_ICABLK_FACTOR * icalk_val;378 vcalk = AW88261_CABL_BASE_VALUE + AW88261_VCABLK_FACTOR * vcalk_val;379 if (!vcalk)380 return -EINVAL;381 382 vcalb = AW88261_VCAL_FACTOR * icalk / vcalk;383 reg_val = (unsigned int)vcalb;384 385 dev_dbg(aw_dev->dev, "icalk=%d, vcalk=%d, vcalb=%d, reg_val=0x%04x",386 icalk, vcalk, vcalb, reg_val);387 ret = regmap_write(aw_dev->regmap, AW88261_VSNTM1_REG, reg_val);388 389 return ret;390}391 392static int aw88261_dev_reg_update(struct aw88261 *aw88261,393 unsigned char *data, unsigned int len)394{395 struct aw_device *aw_dev = aw88261->aw_pa;396 struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;397 unsigned int read_val, efcheck_val, read_vol;398 int data_len, i, ret;399 int16_t *reg_data;400 u16 reg_val;401 u8 reg_addr;402 403 if (!len || !data) {404 dev_err(aw_dev->dev, "reg data is null or len is 0");405 return -EINVAL;406 }407 408 reg_data = (int16_t *)data;409 data_len = len >> 1;410 411 if (data_len & 0x1) {412 dev_err(aw_dev->dev, "data len:%d unsupported", data_len);413 return -EINVAL;414 }415 416 for (i = 0; i < data_len; i += 2) {417 reg_addr = reg_data[i];418 reg_val = reg_data[i + 1];419 420 if (reg_addr == AW88261_SYSCTRL_REG) {421 aw88261->amppd_st = reg_val & (~AW88261_AMPPD_MASK);422 ret = regmap_read(aw_dev->regmap, reg_addr, &read_val);423 if (ret)424 break;425 426 read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) |427 (~AW88261_HMUTE_MASK);428 reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK);429 reg_val |= read_val;430 431 /* enable uls hmute */432 reg_val &= AW88261_ULS_HMUTE_MASK;433 reg_val |= AW88261_ULS_HMUTE_ENABLE_VALUE;434 }435 436 if (reg_addr == AW88261_DBGCTRL_REG) {437 efcheck_val = reg_val & (~AW88261_EF_DBMD_MASK);438 if (efcheck_val == AW88261_OR_VALUE)439 aw88261->efuse_check = AW88261_EF_OR_CHECK;440 else441 aw88261->efuse_check = AW88261_EF_AND_CHECK;442 }443 444 /* i2stxen */445 if (reg_addr == AW88261_I2SCTRL3_REG) {446 /* close tx */447 reg_val &= AW88261_I2STXEN_MASK;448 reg_val |= AW88261_I2STXEN_DISABLE_VALUE;449 }450 451 if (reg_addr == AW88261_SYSCTRL2_REG) {452 read_vol = (reg_val & (~AW88261_VOL_MASK)) >>453 AW88261_VOL_START_BIT;454 aw_dev->volume_desc.init_volume =455 REG_VAL_TO_DB(read_vol);456 }457 458 if (reg_addr == AW88261_VSNTM1_REG)459 continue;460 461 ret = regmap_write(aw_dev->regmap, reg_addr, reg_val);462 if (ret)463 break;464 }465 466 ret = aw88261_dev_set_vcalb(aw_dev);467 if (ret)468 return ret;469 470 if (aw_dev->prof_cur != aw_dev->prof_index)471 vol_desc->ctl_volume = 0;472 473 /* keep min volume */474 aw88261_dev_set_volume(aw_dev, vol_desc->mute_volume);475 476 return ret;477}478 479static int aw88261_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name)480{481 struct aw_prof_info *prof_info = &aw_dev->prof_info;482 struct aw_prof_desc *prof_desc;483 484 if ((index >= aw_dev->prof_info.count) || (index < 0)) {485 dev_err(aw_dev->dev, "index[%d] overflow count[%d]",486 index, aw_dev->prof_info.count);487 return -EINVAL;488 }489 490 prof_desc = &aw_dev->prof_info.prof_desc[index];491 492 *prof_name = prof_info->prof_name_list[prof_desc->id];493 494 return 0;495}496 497static int aw88261_dev_get_prof_data(struct aw_device *aw_dev, int index,498 struct aw_prof_desc **prof_desc)499{500 if ((index >= aw_dev->prof_info.count) || (index < 0)) {501 dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n",502 __func__, index, aw_dev->prof_info.count);503 return -EINVAL;504 }505 506 *prof_desc = &aw_dev->prof_info.prof_desc[index];507 508 return 0;509}510 511static int aw88261_dev_fw_update(struct aw88261 *aw88261)512{513 struct aw_device *aw_dev = aw88261->aw_pa;514 struct aw_prof_desc *prof_index_desc;515 struct aw_sec_data_desc *sec_desc;516 char *prof_name;517 int ret;518 519 ret = aw88261_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name);520 if (ret) {521 dev_err(aw_dev->dev, "get prof name failed");522 return -EINVAL;523 }524 525 dev_dbg(aw_dev->dev, "start update %s", prof_name);526 527 ret = aw88261_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc);528 if (ret)529 return ret;530 531 /* update reg */532 sec_desc = prof_index_desc->sec_desc;533 ret = aw88261_dev_reg_update(aw88261, sec_desc[AW88395_DATA_TYPE_REG].data,534 sec_desc[AW88395_DATA_TYPE_REG].len);535 if (ret) {536 dev_err(aw_dev->dev, "update reg failed");537 return ret;538 }539 540 aw_dev->prof_cur = aw_dev->prof_index;541 542 return ret;543}544 545static int aw88261_dev_start(struct aw88261 *aw88261)546{547 struct aw_device *aw_dev = aw88261->aw_pa;548 int ret;549 550 if (aw_dev->status == AW88261_DEV_PW_ON) {551 dev_info(aw_dev->dev, "already power on");552 return 0;553 }554 555 /* power on */556 aw88261_dev_pwd(aw_dev, false);557 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);558 559 ret = aw88261_dev_check_syspll(aw_dev);560 if (ret) {561 dev_err(aw_dev->dev, "pll check failed cannot start");562 goto pll_check_fail;563 }564 565 /* amppd on */566 aw88261_dev_amppd(aw_dev, false);567 usleep_range(AW88261_1000_US, AW88261_1000_US + 50);568 569 /* check i2s status */570 ret = aw88261_dev_check_sysst(aw_dev);571 if (ret) {572 dev_err(aw_dev->dev, "sysst check failed");573 goto sysst_check_fail;574 }575 576 /* enable tx feedback */577 aw88261_dev_i2s_tx_enable(aw_dev, true);578 579 if (aw88261->amppd_st)580 aw88261_dev_amppd(aw_dev, true);581 582 aw88261_reg_force_set(aw88261);583 584 /* close uls mute */585 aw88261_dev_uls_hmute(aw_dev, false);586 587 /* close mute */588 if (!aw88261->mute_st)589 aw88261_dev_mute(aw_dev, false);590 591 /* clear inturrupt */592 aw88261_dev_clear_int_status(aw_dev);593 aw_dev->status = AW88261_DEV_PW_ON;594 595 return 0;596 597sysst_check_fail:598 aw88261_dev_i2s_tx_enable(aw_dev, false);599 aw88261_dev_clear_int_status(aw_dev);600 aw88261_dev_amppd(aw_dev, true);601pll_check_fail:602 aw88261_dev_pwd(aw_dev, true);603 aw_dev->status = AW88261_DEV_PW_OFF;604 605 return ret;606}607 608static int aw88261_dev_stop(struct aw_device *aw_dev)609{610 if (aw_dev->status == AW88261_DEV_PW_OFF) {611 dev_info(aw_dev->dev, "already power off");612 return 0;613 }614 615 aw_dev->status = AW88261_DEV_PW_OFF;616 617 /* clear inturrupt */618 aw88261_dev_clear_int_status(aw_dev);619 620 aw88261_dev_uls_hmute(aw_dev, true);621 /* set mute */622 aw88261_dev_mute(aw_dev, true);623 624 /* close tx feedback */625 aw88261_dev_i2s_tx_enable(aw_dev, false);626 usleep_range(AW88261_1000_US, AW88261_1000_US + 100);627 628 /* enable amppd */629 aw88261_dev_amppd(aw_dev, true);630 631 /* set power down */632 aw88261_dev_pwd(aw_dev, true);633 634 return 0;635}636 637static int aw88261_reg_update(struct aw88261 *aw88261, bool force)638{639 struct aw_device *aw_dev = aw88261->aw_pa;640 int ret;641 642 if (force) {643 ret = regmap_write(aw_dev->regmap,644 AW88261_ID_REG, AW88261_SOFT_RESET_VALUE);645 if (ret)646 return ret;647 648 ret = aw88261_dev_fw_update(aw88261);649 if (ret)650 return ret;651 } else {652 if (aw_dev->prof_cur != aw_dev->prof_index) {653 ret = aw88261_dev_fw_update(aw88261);654 if (ret)655 return ret;656 } else {657 ret = 0;658 }659 }660 661 aw_dev->prof_cur = aw_dev->prof_index;662 663 return ret;664}665 666static void aw88261_start_pa(struct aw88261 *aw88261)667{668 int ret, i;669 670 for (i = 0; i < AW88261_START_RETRIES; i++) {671 ret = aw88261_reg_update(aw88261, aw88261->phase_sync);672 if (ret) {673 dev_err(aw88261->aw_pa->dev, "fw update failed, cnt:%d\n", i);674 continue;675 }676 ret = aw88261_dev_start(aw88261);677 if (ret) {678 dev_err(aw88261->aw_pa->dev, "aw88261 device start failed. retry = %d", i);679 continue;680 } else {681 dev_info(aw88261->aw_pa->dev, "start success\n");682 break;683 }684 }685}686 687static void aw88261_startup_work(struct work_struct *work)688{689 struct aw88261 *aw88261 =690 container_of(work, struct aw88261, start_work.work);691 692 mutex_lock(&aw88261->lock);693 aw88261_start_pa(aw88261);694 mutex_unlock(&aw88261->lock);695}696 697static void aw88261_start(struct aw88261 *aw88261, bool sync_start)698{699 if (aw88261->aw_pa->fw_status != AW88261_DEV_FW_OK)700 return;701 702 if (aw88261->aw_pa->status == AW88261_DEV_PW_ON)703 return;704 705 if (sync_start == AW88261_SYNC_START)706 aw88261_start_pa(aw88261);707 else708 queue_delayed_work(system_wq,709 &aw88261->start_work,710 AW88261_START_WORK_DELAY_MS);711}712 713static struct snd_soc_dai_driver aw88261_dai[] = {714 {715 .name = "aw88261-aif",716 .id = 1,717 .playback = {718 .stream_name = "Speaker_Playback",719 .channels_min = 1,720 .channels_max = 2,721 .rates = AW88261_RATES,722 .formats = AW88261_FORMATS,723 },724 .capture = {725 .stream_name = "Speaker_Capture",726 .channels_min = 1,727 .channels_max = 2,728 .rates = AW88261_RATES,729 .formats = AW88261_FORMATS,730 },731 },732};733 734static int aw88261_get_fade_in_time(struct snd_kcontrol *kcontrol,735 struct snd_ctl_elem_value *ucontrol)736{737 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);738 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);739 struct aw_device *aw_dev = aw88261->aw_pa;740 741 ucontrol->value.integer.value[0] = aw_dev->fade_in_time;742 743 return 0;744}745 746static int aw88261_set_fade_in_time(struct snd_kcontrol *kcontrol,747 struct snd_ctl_elem_value *ucontrol)748{749 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);750 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);751 struct soc_mixer_control *mc =752 (struct soc_mixer_control *)kcontrol->private_value;753 struct aw_device *aw_dev = aw88261->aw_pa;754 int time;755 756 time = ucontrol->value.integer.value[0];757 758 if (time < mc->min || time > mc->max)759 return -EINVAL;760 761 if (time != aw_dev->fade_in_time) {762 aw_dev->fade_in_time = time;763 return 1;764 }765 766 return 0;767}768 769static int aw88261_get_fade_out_time(struct snd_kcontrol *kcontrol,770 struct snd_ctl_elem_value *ucontrol)771{772 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);773 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);774 struct aw_device *aw_dev = aw88261->aw_pa;775 776 ucontrol->value.integer.value[0] = aw_dev->fade_out_time;777 778 return 0;779}780 781static int aw88261_set_fade_out_time(struct snd_kcontrol *kcontrol,782 struct snd_ctl_elem_value *ucontrol)783{784 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);785 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);786 struct soc_mixer_control *mc =787 (struct soc_mixer_control *)kcontrol->private_value;788 struct aw_device *aw_dev = aw88261->aw_pa;789 int time;790 791 time = ucontrol->value.integer.value[0];792 if (time < mc->min || time > mc->max)793 return -EINVAL;794 795 if (time != aw_dev->fade_out_time) {796 aw_dev->fade_out_time = time;797 return 1;798 }799 800 return 0;801}802 803static int aw88261_dev_set_profile_index(struct aw_device *aw_dev, int index)804{805 /* check the index whether is valid */806 if ((index >= aw_dev->prof_info.count) || (index < 0))807 return -EINVAL;808 /* check the index whether change */809 if (aw_dev->prof_index == index)810 return -EPERM;811 812 aw_dev->prof_index = index;813 814 return 0;815}816 817static int aw88261_profile_info(struct snd_kcontrol *kcontrol,818 struct snd_ctl_elem_info *uinfo)819{820 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);821 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);822 char *prof_name, *name;823 int count, ret;824 825 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;826 uinfo->count = 1;827 828 count = aw88261->aw_pa->prof_info.count;829 if (count <= 0) {830 uinfo->value.enumerated.items = 0;831 return 0;832 }833 834 uinfo->value.enumerated.items = count;835 836 if (uinfo->value.enumerated.item >= count)837 uinfo->value.enumerated.item = count - 1;838 839 name = uinfo->value.enumerated.name;840 count = uinfo->value.enumerated.item;841 842 ret = aw88261_dev_get_prof_name(aw88261->aw_pa, count, &prof_name);843 if (ret) {844 strscpy(uinfo->value.enumerated.name, "null",845 strlen("null") + 1);846 return 0;847 }848 849 strscpy(name, prof_name, sizeof(uinfo->value.enumerated.name));850 851 return 0;852}853 854static int aw88261_profile_get(struct snd_kcontrol *kcontrol,855 struct snd_ctl_elem_value *ucontrol)856{857 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);858 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);859 860 ucontrol->value.integer.value[0] = aw88261->aw_pa->prof_index;861 862 return 0;863}864 865static int aw88261_profile_set(struct snd_kcontrol *kcontrol,866 struct snd_ctl_elem_value *ucontrol)867{868 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);869 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);870 int ret;871 872 /* pa stop or stopping just set profile */873 mutex_lock(&aw88261->lock);874 ret = aw88261_dev_set_profile_index(aw88261->aw_pa, ucontrol->value.integer.value[0]);875 if (ret) {876 dev_dbg(codec->dev, "profile index does not change");877 mutex_unlock(&aw88261->lock);878 return 0;879 }880 881 if (aw88261->aw_pa->status) {882 aw88261_dev_stop(aw88261->aw_pa);883 aw88261_start(aw88261, AW88261_SYNC_START);884 }885 886 mutex_unlock(&aw88261->lock);887 888 return 1;889}890 891static int aw88261_volume_get(struct snd_kcontrol *kcontrol,892 struct snd_ctl_elem_value *ucontrol)893{894 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);895 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);896 struct aw_volume_desc *vol_desc = &aw88261->aw_pa->volume_desc;897 898 ucontrol->value.integer.value[0] = vol_desc->ctl_volume;899 900 return 0;901}902 903static int aw88261_volume_set(struct snd_kcontrol *kcontrol,904 struct snd_ctl_elem_value *ucontrol)905{906 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);907 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);908 struct aw_volume_desc *vol_desc = &aw88261->aw_pa->volume_desc;909 struct soc_mixer_control *mc =910 (struct soc_mixer_control *)kcontrol->private_value;911 int value;912 913 value = ucontrol->value.integer.value[0];914 915 if (value < mc->min || value > mc->max)916 return -EINVAL;917 918 if (vol_desc->ctl_volume != value) {919 vol_desc->ctl_volume = value;920 aw88261_dev_set_volume(aw88261->aw_pa, vol_desc->ctl_volume);921 922 return 1;923 }924 925 return 0;926}927 928static int aw88261_get_fade_step(struct snd_kcontrol *kcontrol,929 struct snd_ctl_elem_value *ucontrol)930{931 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);932 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);933 934 ucontrol->value.integer.value[0] = aw88261->aw_pa->fade_step;935 936 return 0;937}938 939static int aw88261_set_fade_step(struct snd_kcontrol *kcontrol,940 struct snd_ctl_elem_value *ucontrol)941{942 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);943 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);944 struct soc_mixer_control *mc =945 (struct soc_mixer_control *)kcontrol->private_value;946 int value;947 948 value = ucontrol->value.integer.value[0];949 if (value < mc->min || value > mc->max)950 return -EINVAL;951 952 if (aw88261->aw_pa->fade_step != value) {953 aw88261->aw_pa->fade_step = value;954 return 1;955 }956 957 return 0;958}959 960static const struct snd_kcontrol_new aw88261_controls[] = {961 SOC_SINGLE_EXT("PCM Playback Volume", AW88261_SYSCTRL2_REG,962 6, AW88261_MUTE_VOL, 0, aw88261_volume_get,963 aw88261_volume_set),964 SOC_SINGLE_EXT("Fade Step", 0, 0, AW88261_MUTE_VOL, 0,965 aw88261_get_fade_step, aw88261_set_fade_step),966 SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN,967 aw88261_get_fade_in_time, aw88261_set_fade_in_time),968 SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN,969 aw88261_get_fade_out_time, aw88261_set_fade_out_time),970 AW88261_PROFILE_EXT("Profile Set", aw88261_profile_info,971 aw88261_profile_get, aw88261_profile_set),972};973 974static int aw88261_playback_event(struct snd_soc_dapm_widget *w,975 struct snd_kcontrol *k, int event)976{977 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);978 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);979 980 mutex_lock(&aw88261->lock);981 switch (event) {982 case SND_SOC_DAPM_PRE_PMU:983 aw88261_start(aw88261, AW88261_ASYNC_START);984 break;985 case SND_SOC_DAPM_POST_PMD:986 aw88261_dev_stop(aw88261->aw_pa);987 break;988 default:989 break;990 }991 mutex_unlock(&aw88261->lock);992 993 return 0;994}995 996static const struct snd_soc_dapm_widget aw88261_dapm_widgets[] = {997 /* playback */998 SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, 0, 0, 0,999 aw88261_playback_event,1000 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1001 SND_SOC_DAPM_OUTPUT("DAC Output"),1002 1003 /* capture */1004 SND_SOC_DAPM_AIF_OUT("AIF_TX", "Speaker_Capture", 0, SND_SOC_NOPM, 0, 0),1005 SND_SOC_DAPM_INPUT("ADC Input"),1006};1007 1008static const struct snd_soc_dapm_route aw88261_audio_map[] = {1009 {"DAC Output", NULL, "AIF_RX"},1010 {"AIF_TX", NULL, "ADC Input"},1011};1012 1013static int aw88261_frcset_check(struct aw88261 *aw88261)1014{1015 unsigned int reg_val;1016 u16 temh, teml, tem;1017 int ret;1018 1019 ret = regmap_read(aw88261->regmap, AW88261_EFRH3_REG, ®_val);1020 if (ret)1021 return ret;1022 temh = ((u16)reg_val & (~AW88261_TEMH_MASK));1023 1024 ret = regmap_read(aw88261->regmap, AW88261_EFRL3_REG, ®_val);1025 if (ret)1026 return ret;1027 teml = ((u16)reg_val & (~AW88261_TEML_MASK));1028 1029 if (aw88261->efuse_check == AW88261_EF_OR_CHECK)1030 tem = (temh | teml);1031 else1032 tem = (temh & teml);1033 1034 if (tem == AW88261_DEFAULT_CFG)1035 aw88261->frcset_en = AW88261_FRCSET_ENABLE;1036 else1037 aw88261->frcset_en = AW88261_FRCSET_DISABLE;1038 1039 dev_dbg(aw88261->aw_pa->dev, "tem is 0x%04x, frcset_en is %d",1040 tem, aw88261->frcset_en);1041 1042 return ret;1043}1044 1045static int aw88261_dev_init(struct aw88261 *aw88261, struct aw_container *aw_cfg)1046{1047 struct aw_device *aw_dev = aw88261->aw_pa;1048 int ret;1049 1050 ret = aw88395_dev_cfg_load(aw_dev, aw_cfg);1051 if (ret) {1052 dev_err(aw_dev->dev, "aw_dev acf parse failed");1053 return -EINVAL;1054 }1055 1056 ret = regmap_write(aw_dev->regmap, AW88261_ID_REG, AW88261_SOFT_RESET_VALUE);1057 if (ret)1058 return ret;1059 1060 aw_dev->fade_in_time = AW88261_500_US;1061 aw_dev->fade_out_time = AW88261_500_US;1062 aw_dev->prof_cur = AW88261_INIT_PROFILE;1063 aw_dev->prof_index = AW88261_INIT_PROFILE;1064 1065 ret = aw88261_dev_fw_update(aw88261);1066 if (ret) {1067 dev_err(aw_dev->dev, "fw update failed ret = %d\n", ret);1068 return ret;1069 }1070 1071 ret = aw88261_frcset_check(aw88261);1072 if (ret) {1073 dev_err(aw_dev->dev, "aw88261_frcset_check ret = %d\n", ret);1074 return ret;1075 }1076 1077 aw88261_dev_clear_int_status(aw_dev);1078 1079 aw88261_dev_uls_hmute(aw_dev, true);1080 1081 aw88261_dev_mute(aw_dev, true);1082 1083 aw88261_dev_i2s_tx_enable(aw_dev, false);1084 1085 usleep_range(AW88261_1000_US, AW88261_1000_US + 100);1086 1087 aw88261_dev_amppd(aw_dev, true);1088 1089 aw88261_dev_pwd(aw_dev, true);1090 1091 return 0;1092}1093 1094static int aw88261_request_firmware_file(struct aw88261 *aw88261)1095{1096 const struct firmware *cont = NULL;1097 int ret;1098 1099 aw88261->aw_pa->fw_status = AW88261_DEV_FW_FAILED;1100 1101 ret = request_firmware(&cont, AW88261_ACF_FILE, aw88261->aw_pa->dev);1102 if (ret)1103 return dev_err_probe(aw88261->aw_pa->dev, ret,1104 "load [%s] failed!", AW88261_ACF_FILE);1105 1106 dev_info(aw88261->aw_pa->dev, "loaded %s - size: %zu\n",1107 AW88261_ACF_FILE, cont ? cont->size : 0);1108 1109 aw88261->aw_cfg = devm_kzalloc(aw88261->aw_pa->dev, cont->size + sizeof(int), GFP_KERNEL);1110 if (!aw88261->aw_cfg) {1111 release_firmware(cont);1112 return -ENOMEM;1113 }1114 aw88261->aw_cfg->len = (int)cont->size;1115 memcpy(aw88261->aw_cfg->data, cont->data, cont->size);1116 release_firmware(cont);1117 1118 ret = aw88395_dev_load_acf_check(aw88261->aw_pa, aw88261->aw_cfg);1119 if (ret) {1120 dev_err(aw88261->aw_pa->dev, "load [%s] failed !", AW88261_ACF_FILE);1121 return ret;1122 }1123 1124 mutex_lock(&aw88261->lock);1125 /* aw device init */1126 ret = aw88261_dev_init(aw88261, aw88261->aw_cfg);1127 if (ret)1128 dev_err(aw88261->aw_pa->dev, "dev init failed");1129 mutex_unlock(&aw88261->lock);1130 1131 return ret;1132}1133 1134static int aw88261_codec_probe(struct snd_soc_component *component)1135{1136 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);1137 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);1138 int ret;1139 1140 INIT_DELAYED_WORK(&aw88261->start_work, aw88261_startup_work);1141 1142 ret = aw88261_request_firmware_file(aw88261);1143 if (ret)1144 return dev_err_probe(aw88261->aw_pa->dev, ret,1145 "aw88261_request_firmware_file failed\n");1146 1147 /* add widgets */1148 ret = snd_soc_dapm_new_controls(dapm, aw88261_dapm_widgets,1149 ARRAY_SIZE(aw88261_dapm_widgets));1150 if (ret)1151 return ret;1152 1153 /* add route */1154 ret = snd_soc_dapm_add_routes(dapm, aw88261_audio_map,1155 ARRAY_SIZE(aw88261_audio_map));1156 if (ret)1157 return ret;1158 1159 ret = snd_soc_add_component_controls(component, aw88261_controls,1160 ARRAY_SIZE(aw88261_controls));1161 1162 return ret;1163}1164 1165static void aw88261_codec_remove(struct snd_soc_component *aw_codec)1166{1167 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(aw_codec);1168 1169 cancel_delayed_work_sync(&aw88261->start_work);1170}1171 1172static const struct snd_soc_component_driver soc_codec_dev_aw88261 = {1173 .probe = aw88261_codec_probe,1174 .remove = aw88261_codec_remove,1175};1176 1177static void aw88261_parse_channel_dt(struct aw88261 *aw88261)1178{1179 struct aw_device *aw_dev = aw88261->aw_pa;1180 struct device_node *np = aw_dev->dev->of_node;1181 u32 channel_value = AW88261_DEV_DEFAULT_CH;1182 1183 of_property_read_u32(np, "awinic,audio-channel", &channel_value);1184 aw88261->phase_sync = of_property_read_bool(np, "awinic,sync-flag");1185 1186 aw_dev->channel = channel_value;1187}1188 1189static int aw88261_init(struct aw88261 **aw88261, struct i2c_client *i2c, struct regmap *regmap)1190{1191 struct aw_device *aw_dev;1192 unsigned int chip_id;1193 int ret;1194 1195 /* read chip id */1196 ret = regmap_read(regmap, AW88261_ID_REG, &chip_id);1197 if (ret) {1198 dev_err(&i2c->dev, "%s read chipid error. ret = %d", __func__, ret);1199 return ret;1200 }1201 if (chip_id != AW88261_CHIP_ID) {1202 dev_err(&i2c->dev, "unsupported device");1203 return -ENXIO;1204 }1205 1206 dev_info(&i2c->dev, "chip id = %x\n", chip_id);1207 1208 aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL);1209 if (!aw_dev)1210 return -ENOMEM;1211 1212 (*aw88261)->aw_pa = aw_dev;1213 aw_dev->i2c = i2c;1214 aw_dev->regmap = regmap;1215 aw_dev->dev = &i2c->dev;1216 aw_dev->chip_id = AW88261_CHIP_ID;1217 aw_dev->acf = NULL;1218 aw_dev->prof_info.prof_desc = NULL;1219 aw_dev->prof_info.count = 0;1220 aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID;1221 aw_dev->channel = 0;1222 aw_dev->fw_status = AW88261_DEV_FW_FAILED;1223 aw_dev->fade_step = AW88261_VOLUME_STEP_DB;1224 aw_dev->volume_desc.ctl_volume = AW88261_VOL_DEFAULT_VALUE;1225 aw_dev->volume_desc.mute_volume = AW88261_MUTE_VOL;1226 aw88261_parse_channel_dt(*aw88261);1227 1228 return ret;1229}1230 1231static int aw88261_i2c_probe(struct i2c_client *i2c)1232{1233 struct aw88261 *aw88261;1234 int ret;1235 1236 ret = i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C);1237 if (!ret)1238 return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed");1239 1240 aw88261 = devm_kzalloc(&i2c->dev, sizeof(*aw88261), GFP_KERNEL);1241 if (!aw88261)1242 return -ENOMEM;1243 1244 mutex_init(&aw88261->lock);1245 1246 i2c_set_clientdata(i2c, aw88261);1247 1248 aw88261->regmap = devm_regmap_init_i2c(i2c, &aw88261_remap_config);1249 if (IS_ERR(aw88261->regmap)) {1250 ret = PTR_ERR(aw88261->regmap);1251 return dev_err_probe(&i2c->dev, ret, "failed to init regmap: %d\n", ret);1252 }1253 1254 /* aw pa init */1255 ret = aw88261_init(&aw88261, i2c, aw88261->regmap);1256 if (ret)1257 return ret;1258 1259 ret = devm_snd_soc_register_component(&i2c->dev,1260 &soc_codec_dev_aw88261,1261 aw88261_dai, ARRAY_SIZE(aw88261_dai));1262 if (ret)1263 dev_err(&i2c->dev, "failed to register aw88261: %d", ret);1264 1265 return ret;1266}1267 1268static const struct i2c_device_id aw88261_i2c_id[] = {1269 { AW88261_I2C_NAME },1270 { }1271};1272MODULE_DEVICE_TABLE(i2c, aw88261_i2c_id);1273 1274static struct i2c_driver aw88261_i2c_driver = {1275 .driver = {1276 .name = AW88261_I2C_NAME,1277 },1278 .probe = aw88261_i2c_probe,1279 .id_table = aw88261_i2c_id,1280};1281module_i2c_driver(aw88261_i2c_driver);1282 1283MODULE_DESCRIPTION("ASoC AW88261 Smart PA Driver");1284MODULE_LICENSE("GPL v2");1285