ASoC: rt1321: Add RT1321 amplifier support

This patch supported RT1321 amplifier.

Signed-off-by: Shuming Fan <shumingf@realtek.com>
Link: https://patch.msgid.link/20250814092153.2733592-1-shumingf@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Shuming Fan 2025-08-14 17:21:53 +08:00 committed by Mark Brown
parent 0e62438e47
commit 7bf9e646af
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 343 additions and 47 deletions

View File

@ -255,6 +255,161 @@ static const struct reg_sequence rt1320_vc_blind_write[] = {
{ SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, { SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 },
}; };
static const struct reg_sequence rt1321_blind_write[] = {
{ 0x0000c003, 0xf0 },
{ 0x0000c01b, 0xfc },
{ 0x0000c5c3, 0xf2 },
{ 0x0000c5c2, 0x00 },
{ 0x0000c5c1, 0x10 },
{ 0x0000c5c0, 0x04 },
{ 0x0000c5c7, 0x03 },
{ 0x0000c5c6, 0x10 },
{ 0x0000c526, 0x47 },
{ 0x0000c5c4, 0x12 },
{ 0x0000c5c5, 0x60 },
{ 0x0000c520, 0x10 },
{ 0x0000c521, 0x32 },
{ 0x0000c5c7, 0x00 },
{ 0x0000c5c8, 0x03 },
{ 0x0000c5d3, 0x08 },
{ 0x0000c5d2, 0x0a },
{ 0x0000c5d1, 0x49 },
{ 0x0000c5d0, 0x0f },
{ 0x0000c580, 0x10 },
{ 0x0000c581, 0x32 },
{ 0x0000c582, 0x01 },
{ 0x0000cb00, 0x03 },
{ 0x0000cb02, 0x52 },
{ 0x0000cb04, 0x80 },
{ 0x0000cb0b, 0x01 },
{ 0x0000c682, 0x60 },
{ 0x0000c019, 0x10 },
{ 0x0000c5f0, 0x01 },
{ 0x0000c5f7, 0x22 },
{ 0x0000c5f6, 0x22 },
{ 0x0000c057, 0x51 },
{ 0x0000c054, 0x55 },
{ 0x0000c053, 0x55 },
{ 0x0000c052, 0x55 },
{ 0x0000c051, 0x01 },
{ 0x0000c050, 0x15 },
{ 0x0000c060, 0x99 },
{ 0x0000c030, 0x55 },
{ 0x0000c061, 0x55 },
{ 0x0000c063, 0x55 },
{ 0x0000c065, 0xa5 },
{ 0x0000c06b, 0x0a },
{ 0x0000ca05, 0xd6 },
{ 0x0000ca07, 0x07 },
{ 0x0000ca25, 0xd6 },
{ 0x0000ca27, 0x07 },
{ 0x0000cd00, 0x05 },
{ 0x0000c604, 0x40 },
{ 0x0000c609, 0x40 },
{ 0x0000c046, 0xf7 },
{ 0x0000c045, 0xff },
{ 0x0000c044, 0xff },
{ 0x0000c043, 0xff },
{ 0x0000c042, 0xff },
{ 0x0000c041, 0xff },
{ 0x0000c040, 0xff },
{ 0x0000c049, 0xff },
{ 0x0000c028, 0x3f },
{ 0x0000c020, 0x3f },
{ 0x0000c032, 0x13 },
{ 0x0000c033, 0x01 },
{ 0x0000cc10, 0x01 },
{ 0x0000dc20, 0x03 },
{ 0x0000de03, 0x05 },
{ 0x0000dc00, 0x00 },
{ 0x0000c700, 0xf0 },
{ 0x0000c701, 0x13 },
{ 0x0000c900, 0xc3 },
{ 0x0000c570, 0x08 },
{ 0x0000c086, 0x02 },
{ 0x0000c085, 0x7f },
{ 0x0000c084, 0x00 },
{ 0x0000c081, 0xff },
{ 0x0000f084, 0x0f },
{ 0x0000f083, 0xff },
{ 0x0000f082, 0xff },
{ 0x0000f081, 0xff },
{ 0x0000f080, 0xff },
{ 0x20003003, 0x3f },
{ 0x20005818, 0x81 },
{ 0x20009018, 0x81 },
{ 0x2000301c, 0x81 },
{ 0x0000c003, 0xc0 },
{ 0x0000c047, 0x80 },
{ 0x0000d541, 0x80 },
{ 0x0000d487, 0x0b },
{ 0x0000d487, 0x3b },
{ 0x0000d486, 0xc3 },
{ 0x0000d470, 0x89 },
{ 0x0000d471, 0x3a },
{ 0x0000d472, 0x1d },
{ 0x0000d478, 0xff },
{ 0x0000d479, 0x20 },
{ 0x0000d47a, 0x10 },
{ 0x0000d73c, 0xb7 },
{ 0x0000d73d, 0xd7 },
{ 0x0000d73e, 0x00 },
{ 0x0000d73f, 0x10 },
{ 0x3fc2dfc3, 0x00 },
{ 0x3fc2dfc2, 0x00 },
{ 0x3fc2dfc1, 0x00 },
{ 0x3fc2dfc0, 0x07 },
{ 0x3fc2dfc7, 0x00 },
{ 0x3fc2dfc6, 0x00 },
{ 0x3fc2dfc5, 0x00 },
{ 0x3fc2dfc4, 0x01 },
{ 0x3fc2df83, 0x00 },
{ 0x3fc2df82, 0x00 },
{ 0x3fc2df81, 0x00 },
{ 0x3fc2df80, 0x00 },
{ 0x0000d541, 0x40 },
{ 0x0000d486, 0x43 },
{ 0x1000db00, 0x03 },
{ 0x1000db01, 0x00 },
{ 0x1000db02, 0x10 },
{ 0x1000db03, 0x00 },
{ 0x1000db04, 0x00 },
{ 0x1000db05, 0x45 },
{ 0x1000db06, 0x12 },
{ 0x1000db07, 0x09 },
{ 0x1000db08, 0x00 },
{ 0x1000db09, 0x00 },
{ 0x1000db0a, 0x00 },
{ 0x1000db0b, 0x13 },
{ 0x1000db0c, 0x09 },
{ 0x1000db0d, 0x00 },
{ 0x1000db0e, 0x00 },
{ 0x1000db0f, 0x00 },
{ 0x0000d540, 0x21 },
{ 0x41000189, 0x00 },
{ 0x4100018a, 0x00 },
{ 0x41001988, 0x00 },
{ 0x41081400, 0x09 },
{ 0x40801508, 0x03 },
{ 0x40801588, 0x03 },
{ 0x40801809, 0x00 },
{ 0x4080180a, 0x00 },
{ 0x4080180b, 0x00 },
{ 0x4080180c, 0x00 },
{ 0x40801b09, 0x00 },
{ 0x40801b0a, 0x00 },
{ 0x40801b0b, 0x00 },
{ 0x40801b0c, 0x00 },
{ 0x0000d714, 0x17 },
{ 0x20009012, 0x00 },
{ 0x0000dd0b, 0x0d },
{ 0x0000dd0a, 0xff },
{ 0x0000dd09, 0x0d },
{ 0x0000dd08, 0xff },
{ 0x0000d172, 0x2a },
{ 0x41001988, 0x03 },
};
static const struct reg_default rt1320_reg_defaults[] = { static const struct reg_default rt1320_reg_defaults[] = {
{ SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, { SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 },
{ SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_MUTE, CH_01), 0x01 }, { SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_MUTE, CH_01), 0x01 },
@ -339,10 +494,19 @@ static bool rt1320_readable_register(struct device *dev, unsigned int reg)
case 0xf717 ... 0xf719: case 0xf717 ... 0xf719:
case 0xf720 ... 0xf723: case 0xf720 ... 0xf723:
case 0x1000cd91 ... 0x1000cd96: case 0x1000cd91 ... 0x1000cd96:
case RT1321_PATCH_MAIN_VER ... RT1321_PATCH_BETA_VER:
case 0x1000f008: case 0x1000f008:
case 0x1000f021: case 0x1000f021:
case 0x2000300f:
case 0x2000301c:
case 0x2000900f:
case 0x20009018:
case 0x3fc29d80 ... 0x3fc29d83:
case 0x3fe2e000 ... 0x3fe2e003: case 0x3fe2e000 ... 0x3fe2e003:
case 0x3fc2ab80 ... 0x3fc2abd4: case 0x3fc2ab80 ... 0x3fc2abd4:
case 0x3fc2bfc0 ... 0x3fc2bfc8:
case 0x3fc2d300 ... 0x3fc2d354:
case 0x3fc2dfc0 ... 0x3fc2dfc8:
/* 0x40801508/0x40801809/0x4080180a/0x40801909/0x4080190a */ /* 0x40801508/0x40801809/0x4080180a/0x40801909/0x4080190a */
case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_REQ_POWER_STATE, 0): case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_REQ_POWER_STATE, 0):
case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_MUTE, CH_01): case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_MUTE, CH_01):
@ -393,6 +557,7 @@ static bool rt1320_volatile_register(struct device *dev, unsigned int reg)
case 0xc560: case 0xc560:
case 0xc5b5 ... 0xc5b7: case 0xc5b5 ... 0xc5b7:
case 0xc5fc ... 0xc5ff: case 0xc5fc ... 0xc5ff:
case 0xc680 ... 0xc683:
case 0xc820: case 0xc820:
case 0xc900: case 0xc900:
case 0xc920: case 0xc920:
@ -411,7 +576,7 @@ static bool rt1320_volatile_register(struct device *dev, unsigned int reg)
case 0xd4e5 ... 0xd4e6: case 0xd4e5 ... 0xd4e6:
case 0xd4e8 ... 0xd4ff: case 0xd4e8 ... 0xd4ff:
case 0xd530: case 0xd530:
case 0xd540: case 0xd540 ... 0xd541:
case 0xd543: case 0xd543:
case 0xdb58 ... 0xdb5f: case 0xdb58 ... 0xdb5f:
case 0xdb60 ... 0xdb63: case 0xdb60 ... 0xdb63:
@ -428,13 +593,20 @@ static bool rt1320_volatile_register(struct device *dev, unsigned int reg)
case 0xf01e: case 0xf01e:
case 0xf717 ... 0xf719: case 0xf717 ... 0xf719:
case 0xf720 ... 0xf723: case 0xf720 ... 0xf723:
case 0x10000000 ... 0x10007fff: case 0x10000000 ... 0x10008fff:
case 0x1000c000 ... 0x1000dfff: case 0x1000c000 ... 0x1000dfff:
case 0x1000f008: case 0x1000f008:
case 0x1000f021: case 0x1000f021:
case 0x2000300f:
case 0x2000301c:
case 0x2000900f:
case 0x20009018:
case 0x3fc2ab80 ... 0x3fc2abd4: case 0x3fc2ab80 ... 0x3fc2abd4:
case 0x3fc2b780:
case 0x3fc2bf80 ... 0x3fc2bf83: case 0x3fc2bf80 ... 0x3fc2bf83:
case 0x3fc2bfc0 ... 0x3fc2bfc7: case 0x3fc2bfc0 ... 0x3fc2bfc8:
case 0x3fc2d300 ... 0x3fc2d354:
case 0x3fc2dfc0 ... 0x3fc2dfc8:
case 0x3fe2e000 ... 0x3fe2e003: case 0x3fe2e000 ... 0x3fe2e003:
case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_ACTUAL_POWER_STATE, 0): case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_ACTUAL_POWER_STATE, 0):
case SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT0, RT1320_SDCA_CTL_FUNC_STATUS, 0): case SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT0, RT1320_SDCA_CTL_FUNC_STATUS, 0):
@ -559,7 +731,7 @@ static int rt1320_read_prop(struct sdw_slave *slave)
static int rt1320_pde_transition_delay(struct rt1320_sdw_priv *rt1320, unsigned char func, static int rt1320_pde_transition_delay(struct rt1320_sdw_priv *rt1320, unsigned char func,
unsigned char entity, unsigned char ps) unsigned char entity, unsigned char ps)
{ {
unsigned int delay = 1000, val; unsigned int delay = 2000, val;
pm_runtime_mark_last_busy(&rt1320->sdw_slave->dev); pm_runtime_mark_last_busy(&rt1320->sdw_slave->dev);
@ -590,24 +762,44 @@ static void rt1320_load_mcu_patch(struct rt1320_sdw_priv *rt1320)
struct sdw_slave *slave = rt1320->sdw_slave; struct sdw_slave *slave = rt1320->sdw_slave;
const struct firmware *patch; const struct firmware *patch;
const char *filename; const char *filename;
unsigned int addr, val; unsigned int addr, val, min_addr, max_addr;
const unsigned char *ptr; const unsigned char *ptr;
int ret, i; int ret, i;
if (rt1320->version_id <= RT1320_VB) switch (rt1320->dev_id) {
filename = RT1320_VAB_MCU_PATCH; case RT1320_DEV_ID:
else if (rt1320->version_id <= RT1320_VB)
filename = RT1320_VC_MCU_PATCH; filename = RT1320_VAB_MCU_PATCH;
else
filename = RT1320_VC_MCU_PATCH;
min_addr = 0x10007000;
max_addr = 0x10007fff;
break;
case RT1321_DEV_ID:
filename = RT1321_VA_MCU_PATCH;
min_addr = 0x10008000;
max_addr = 0x10008fff;
break;
default:
dev_err(&slave->dev, "%s: Unknown device ID %d\n", __func__, rt1320->dev_id);
return;
}
/* load the patch code here */ /* load the patch code here */
ret = request_firmware(&patch, filename, &slave->dev); ret = request_firmware(&patch, filename, &slave->dev);
if (ret) { if (ret) {
dev_err(&slave->dev, "%s: Failed to load %s firmware", __func__, filename); dev_err(&slave->dev, "%s: Failed to load %s firmware", __func__, filename);
regmap_write(rt1320->regmap, 0xc598, 0x00); regmap_write(rt1320->regmap, 0xc598, 0x00);
regmap_write(rt1320->regmap, 0x10007000, 0x67); regmap_write(rt1320->regmap, min_addr, 0x67);
regmap_write(rt1320->regmap, 0x10007001, 0x80); regmap_write(rt1320->regmap, min_addr + 0x1, 0x80);
regmap_write(rt1320->regmap, 0x10007002, 0x00); regmap_write(rt1320->regmap, min_addr + 0x2, 0x00);
regmap_write(rt1320->regmap, 0x10007003, 0x00); regmap_write(rt1320->regmap, min_addr + 0x3, 0x00);
if (rt1320->dev_id == RT1321_DEV_ID) {
regmap_write(rt1320->regmap, 0xd73c, 0x67);
regmap_write(rt1320->regmap, 0xd73d, 0x80);
regmap_write(rt1320->regmap, 0xd73e, 0x00);
regmap_write(rt1320->regmap, 0xd73f, 0x00);
}
} else { } else {
ptr = (const unsigned char *)patch->data; ptr = (const unsigned char *)patch->data;
if ((patch->size % 8) == 0) { if ((patch->size % 8) == 0) {
@ -617,7 +809,7 @@ static void rt1320_load_mcu_patch(struct rt1320_sdw_priv *rt1320)
val = (ptr[i + 4] & 0xff) | (ptr[i + 5] & 0xff) << 8 | val = (ptr[i + 4] & 0xff) | (ptr[i + 5] & 0xff) << 8 |
(ptr[i + 6] & 0xff) << 16 | (ptr[i + 7] & 0xff) << 24; (ptr[i + 6] & 0xff) << 16 | (ptr[i + 7] & 0xff) << 24;
if (addr > 0x10007fff || addr < 0x10007000) { if (addr > max_addr || addr < min_addr) {
dev_err(&slave->dev, "%s: the address 0x%x is wrong", __func__, addr); dev_err(&slave->dev, "%s: the address 0x%x is wrong", __func__, addr);
goto _exit_; goto _exit_;
} }
@ -687,6 +879,28 @@ static void rt1320_vc_preset(struct rt1320_sdw_priv *rt1320)
} }
} }
static void rt1321_preset(struct rt1320_sdw_priv *rt1320)
{
unsigned int i, reg, val, delay;
for (i = 0; i < ARRAY_SIZE(rt1321_blind_write); i++) {
reg = rt1321_blind_write[i].reg;
val = rt1321_blind_write[i].def;
delay = rt1321_blind_write[i].delay_us;
if (reg == 0x3fc2dfc3)
rt1320_load_mcu_patch(rt1320);
regmap_write(rt1320->regmap, reg, val);
if (delay)
usleep_range(delay, delay + 1000);
if (reg == SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0))
rt1320_pde_transition_delay(rt1320, FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, val);
}
}
static int rt1320_io_init(struct device *dev, struct sdw_slave *slave) static int rt1320_io_init(struct device *dev, struct sdw_slave *slave)
{ {
struct rt1320_sdw_priv *rt1320 = dev_get_drvdata(dev); struct rt1320_sdw_priv *rt1320 = dev_get_drvdata(dev);
@ -713,6 +927,9 @@ static int rt1320_io_init(struct device *dev, struct sdw_slave *slave)
if (rt1320->version_id < 0) { if (rt1320->version_id < 0) {
regmap_read(rt1320->regmap, RT1320_DEV_VERSION_ID_1, &val); regmap_read(rt1320->regmap, RT1320_DEV_VERSION_ID_1, &val);
rt1320->version_id = val; rt1320->version_id = val;
regmap_read(rt1320->regmap, RT1320_DEV_ID_0, &val);
regmap_read(rt1320->regmap, RT1320_DEV_ID_1, &tmp);
rt1320->dev_id = (val << 8) | tmp;
} }
regmap_read(rt1320->regmap, regmap_read(rt1320->regmap,
@ -721,16 +938,25 @@ static int rt1320_io_init(struct device *dev, struct sdw_slave *slave)
/* initialization write */ /* initialization write */
if ((amp_func_status & FUNCTION_NEEDS_INITIALIZATION)) { if ((amp_func_status & FUNCTION_NEEDS_INITIALIZATION)) {
if (rt1320->version_id < RT1320_VC) switch (rt1320->dev_id) {
rt1320_vab_preset(rt1320); case RT1320_DEV_ID:
else if (rt1320->version_id < RT1320_VC)
rt1320_vc_preset(rt1320); rt1320_vab_preset(rt1320);
else
rt1320_vc_preset(rt1320);
break;
case RT1321_DEV_ID:
rt1321_preset(rt1320);
break;
default:
dev_err(dev, "%s: Unknown device ID %d\n", __func__, rt1320->dev_id);
}
regmap_write(rt1320->regmap, regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT0, RT1320_SDCA_CTL_FUNC_STATUS, 0), SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT0, RT1320_SDCA_CTL_FUNC_STATUS, 0),
FUNCTION_NEEDS_INITIALIZATION); FUNCTION_NEEDS_INITIALIZATION);
} }
if (!rt1320->first_hw_init && rt1320->version_id == RT1320_VA) { if (!rt1320->first_hw_init && rt1320->version_id == RT1320_VA && rt1320->dev_id == RT1320_DEV_ID) {
regmap_write(rt1320->regmap, SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, regmap_write(rt1320->regmap, SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23,
RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0); RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0);
regmap_read(rt1320->regmap, RT1320_HIFI_VER_0, &val); regmap_read(rt1320->regmap, RT1320_HIFI_VER_0, &val);
@ -750,7 +976,7 @@ static int rt1320_io_init(struct device *dev, struct sdw_slave *slave)
regmap_write(rt1320->regmap, SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, regmap_write(rt1320->regmap, SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23,
RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 3); RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 3);
} }
dev_dbg(dev, "%s version_id=%d\n", __func__, rt1320->version_id); dev_dbg(dev, "%s version_id=%d, dev_id=0x%x\n", __func__, rt1320->version_id, rt1320->dev_id);
if (rt1320->first_hw_init) { if (rt1320->first_hw_init) {
regcache_cache_bypass(rt1320->regmap, false); regcache_cache_bypass(rt1320->regmap, false);
@ -893,12 +1119,20 @@ _dmic_vol_:
/* check all channels */ /* check all channels */
for (i = 0; i < p->count; i++) { for (i = 0; i < p->count; i++) {
if (i < 2) { switch (rt1320->dev_id) {
case RT1320_DEV_ID:
if (i < 2) {
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue[i]);
} else {
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i - 2, &regvalue[i]);
}
break;
case RT1321_DEV_ID:
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01); reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue[i]); regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue[i]);
} else { break;
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i - 2, &regvalue[i]);
} }
gain_val[i] = ucontrol->value.integer.value[i]; gain_val[i] = ucontrol->value.integer.value[i];
@ -915,12 +1149,20 @@ _dmic_vol_:
return 0; return 0;
for (i = 0; i < p->count; i++) { for (i = 0; i < p->count; i++) {
if (i < 2) { switch (rt1320->dev_id) {
case RT1320_DEV_ID:
if (i < 2) {
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
err = regmap_write(rt1320->mbq_regmap, reg_base + i, gain_val[i]);
} else {
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
err = regmap_write(rt1320->mbq_regmap, reg_base + i - 2, gain_val[i]);
}
break;
case RT1321_DEV_ID:
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01); reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
err = regmap_write(rt1320->mbq_regmap, reg_base + i, gain_val[i]); err = regmap_write(rt1320->mbq_regmap, reg_base + i, gain_val[i]);
} else { break;
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
err = regmap_write(rt1320->mbq_regmap, reg_base + i - 2, gain_val[i]);
} }
if (err < 0) if (err < 0)
@ -965,12 +1207,20 @@ _dmic_vol_:
/* check all channels */ /* check all channels */
for (i = 0; i < p->count; i++) { for (i = 0; i < p->count; i++) {
if (i < 2) { switch (rt1320->dev_id) {
case RT1320_DEV_ID:
if (i < 2) {
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue);
} else {
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i - 2, &regvalue);
}
break;
case RT1321_DEV_ID:
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01); reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue); regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue);
} else { break;
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i - 2, &regvalue);
} }
ctl = p->max - (((0x1e00 - regvalue) & 0xffff) / interval_offset); ctl = p->max - (((0x1e00 - regvalue) & 0xffff) / interval_offset);
@ -988,14 +1238,26 @@ static int rt1320_set_fu_capture_ctl(struct rt1320_sdw_priv *rt1320)
for (i = 0; i < ARRAY_SIZE(rt1320->fu_mixer_mute); i++) { for (i = 0; i < ARRAY_SIZE(rt1320->fu_mixer_mute); i++) {
ch_mute = (rt1320->fu_dapm_mute || rt1320->fu_mixer_mute[i]) ? 0x01 : 0x00; ch_mute = (rt1320->fu_dapm_mute || rt1320->fu_mixer_mute[i]) ? 0x01 : 0x00;
if (i < 2) switch (rt1320->dev_id) {
case RT1320_DEV_ID:
if (i < 2)
err = regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113,
RT1320_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute);
else
err = regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14,
RT1320_SDCA_CTL_FU_MUTE, CH_01) + i - 2, ch_mute);
break;
case RT1321_DEV_ID:
err = regmap_write(rt1320->regmap, err = regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113,
RT1320_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute); RT1320_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute);
else break;
err = regmap_write(rt1320->regmap, default:
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, dev_err(&rt1320->sdw_slave->dev, "%s: Unknown device ID %d\n", __func__, rt1320->dev_id);
RT1320_SDCA_CTL_FU_MUTE, CH_01) + i - 2, ch_mute); return -EINVAL;
}
if (err < 0) if (err < 0)
return err; return err;
} }
@ -1216,10 +1478,20 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
if (dai->id == RT1320_AIF1) if (dai->id == RT1320_AIF1)
port_config.num = 4; port_config.num = 4;
else if (dai->id == RT1320_AIF2) { else if (dai->id == RT1320_AIF2) {
dmic_port_config[0].ch_mask = BIT(0) | BIT(1); switch (rt1320->dev_id) {
dmic_port_config[0].num = 8; case RT1320_DEV_ID:
dmic_port_config[1].ch_mask = BIT(0) | BIT(1); dmic_port_config[0].ch_mask = BIT(0) | BIT(1);
dmic_port_config[1].num = 10; dmic_port_config[0].num = 8;
dmic_port_config[1].ch_mask = BIT(0) | BIT(1);
dmic_port_config[1].num = 10;
break;
case RT1321_DEV_ID:
dmic_port_config[0].ch_mask = BIT(0) | BIT(1);
dmic_port_config[0].num = 8;
break;
default:
return -EINVAL;
}
} else } else
return -EINVAL; return -EINVAL;
} }
@ -1227,10 +1499,21 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
if (dai->id == RT1320_AIF1) if (dai->id == RT1320_AIF1)
retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config, retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config,
&port_config, 1, sdw_stream); &port_config, 1, sdw_stream);
else if (dai->id == RT1320_AIF2) else if (dai->id == RT1320_AIF2) {
retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config, switch (rt1320->dev_id) {
case RT1320_DEV_ID:
retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config,
dmic_port_config, 2, sdw_stream); dmic_port_config, 2, sdw_stream);
else break;
case RT1321_DEV_ID:
retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config,
dmic_port_config, 1, sdw_stream);
break;
default:
dev_err(dai->dev, "%s: Unknown device ID %d\n", __func__, rt1320->dev_id);
return -EINVAL;
}
} else
return -EINVAL; return -EINVAL;
if (retval) { if (retval) {
dev_err(dai->dev, "%s: Unable to configure port\n", __func__); dev_err(dai->dev, "%s: Unable to configure port\n", __func__);
@ -1272,9 +1555,11 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
regmap_write(rt1320->regmap, regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_CS113, RT1320_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_CS113, RT1320_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),
sampling_rate); sampling_rate);
regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_CS14, RT1320_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), if (rt1320->dev_id == RT1320_DEV_ID)
sampling_rate); regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_CS14, RT1320_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),
sampling_rate);
} }
return 0; return 0;
@ -1468,6 +1753,7 @@ static int rt1320_sdw_remove(struct sdw_slave *slave)
static const struct sdw_device_id rt1320_id[] = { static const struct sdw_device_id rt1320_id[] = {
SDW_SLAVE_ENTRY_EXT(0x025d, 0x1320, 0x3, 0x0, 0), SDW_SLAVE_ENTRY_EXT(0x025d, 0x1320, 0x3, 0x0, 0),
SDW_SLAVE_ENTRY_EXT(0x025d, 0x1320, 0x3, 0x1, 0), SDW_SLAVE_ENTRY_EXT(0x025d, 0x1320, 0x3, 0x1, 0),
SDW_SLAVE_ENTRY_EXT(0x025d, 0x1321, 0x3, 0x1, 0),
{}, {},
}; };
MODULE_DEVICE_TABLE(sdw, rt1320_id); MODULE_DEVICE_TABLE(sdw, rt1320_id);

View File

@ -14,8 +14,16 @@
#include <linux/soundwire/sdw_registers.h> #include <linux/soundwire/sdw_registers.h>
#include <sound/soc.h> #include <sound/soc.h>
#define RT1320_DEV_ID 0x6981
#define RT1321_DEV_ID 0x7045
/* imp-defined registers */ /* imp-defined registers */
#define RT1320_DEV_VERSION_ID_1 0xc404 #define RT1320_DEV_VERSION_ID_1 0xc404
#define RT1320_DEV_ID_1 0xc405
#define RT1320_DEV_ID_0 0xc406
#define RT1321_PATCH_MAIN_VER 0x1000cffe
#define RT1321_PATCH_BETA_VER 0x1000cfff
#define RT1320_KR0_STATUS_CNT 0x1000f008 #define RT1320_KR0_STATUS_CNT 0x1000f008
#define RT1320_KR0_INT_READY 0x1000f021 #define RT1320_KR0_INT_READY 0x1000f021
@ -86,6 +94,7 @@ enum rt1320_version_id {
#define RT1320_VER_B_ID 0x07392238 #define RT1320_VER_B_ID 0x07392238
#define RT1320_VAB_MCU_PATCH "realtek/rt1320/rt1320-patch-code-vab.bin" #define RT1320_VAB_MCU_PATCH "realtek/rt1320/rt1320-patch-code-vab.bin"
#define RT1320_VC_MCU_PATCH "realtek/rt1320/rt1320-patch-code-vc.bin" #define RT1320_VC_MCU_PATCH "realtek/rt1320/rt1320-patch-code-vc.bin"
#define RT1321_VA_MCU_PATCH "realtek/rt1320/rt1321-patch-code-va.bin"
struct rt1320_sdw_priv { struct rt1320_sdw_priv {
struct snd_soc_component *component; struct snd_soc_component *component;
@ -96,6 +105,7 @@ struct rt1320_sdw_priv {
bool hw_init; bool hw_init;
bool first_hw_init; bool first_hw_init;
int version_id; int version_id;
unsigned int dev_id;
bool fu_dapm_mute; bool fu_dapm_mute;
bool fu_mixer_mute[4]; bool fu_mixer_mute[4];
}; };