// SPDX-License-Identifier: GPL-2.0-only
//
// aw88081.c -- AW88081 ALSA SoC Audio driver
//
// Copyright (c) 2024 awinic Technology CO., LTD
//
// Author: Weidong Wang <wangweidong.a@awinic.com>
//
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include "aw88081.h"
#include "aw88395/aw88395_device.h"
enum aw8808x_type {
AW88081,
AW88083,
};
struct aw88081 {
struct aw_device *aw_pa;
struct mutex lock;
struct delayed_work start_work;
struct regmap *regmap;
struct aw_container *aw_cfg;
enum aw8808x_type devtype;
bool phase_sync;
};
static const struct regmap_config aw88081_regmap_config = {
.val_bits = 16,
.reg_bits = 8,
.max_register = AW88081_REG_MAX,
.reg_format_endian = REGMAP_ENDIAN_LITTLE,
.val_format_endian = REGMAP_ENDIAN_BIG,
};
static const struct regmap_config aw88083_regmap_config = {
.val_bits = 16,
.reg_bits = 8,
.max_register = AW88083_REG_MAX,
.reg_format_endian = REGMAP_ENDIAN_LITTLE,
.val_format_endian = REGMAP_ENDIAN_BIG,
};
static int aw88081_dev_get_iis_status(struct aw_device *aw_dev)
{
unsigned int reg_val;
int ret;
ret = regmap_read(aw_dev->regmap, AW88081_SYSST_REG, ®_val);
if (ret)
return ret;
if ((reg_val & AW88081_BIT_PLL_CHECK) != AW88081_BIT_PLL_CHECK) {
dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val);
return -EINVAL;
}
return 0;
}
static int aw88081_dev_check_mode1_pll(struct aw_device *aw_dev)
{
int ret, i;
for (i = 0; i < AW88081_DEV_SYSST_CHECK_MAX; i++) {
ret = aw88081_dev_get_iis_status(aw_dev);
if (ret) {
dev_err(aw_dev->dev, "mode1 iis signal check error");
usleep_range(AW88081_2000_US, AW88081_2000_US + 10);
} else {
return 0;
}
}
return -EPERM;
}
static int aw88081_dev_check_mode2_pll(struct aw_device *aw_dev)
{
unsigned int reg_val;
int ret, i;
ret = regmap_read(aw_dev->regmap, AW88081_PLLCTRL1_REG, ®_val);
if (ret)
return ret;
reg_val &= (~AW88081_CCO_MUX_MASK);
if (reg_val == AW88081_CCO_MUX_DIVIDED_VALUE) {
dev_dbg(aw_dev->dev, "CCO_MUX is already divider");
return -EPERM;
}
/* change mode2 */
ret = regmap_update_bits(aw_dev->regmap, AW88081_PLLCTRL1_REG,
~AW88081_CCO_MUX_MASK, AW88081_CCO_MUX_DIVIDED_VALUE);
if (ret)
return ret;
for (i = 0; i < AW88081_DEV_SYSST_CHECK_MAX; i++) {
ret = aw88081_dev_get_iis_status(aw