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

Configure Feed

Select the types of activity you want to include in your feed.

mfd: cs42l43: Add support for the B variant

Introducing CS42L43B codec, a variant of CS42L43 which can be driven by
the same driver.

Changes in CS42L43 driver specific for CS42L43B:
- Decimator 1 and 2 are dedicated to ADC, can't be selected for PDM
- Decimators 3 and 4 are connected to PDM1
- Added Decimator 5 and 6 for PDM2
- Supports SoundWire Clock Gearing
- Updated ROM requiring no patching
- Reduced RAM space
- Each ISRC has 4 decimators now

Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
Acked-by: Lee Jones <lee@kernel.org>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260306152829.3130530-4-mstrozek@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Maciej Strozek and committed by
Mark Brown
a6fe20d6 301db523

+166 -17
+5 -2
drivers/mfd/cs42l43-i2c.c
··· 47 47 cs42l43->irq = i2c->irq; 48 48 /* A device on an I2C is always attached by definition. */ 49 49 cs42l43->attached = true; 50 + cs42l43->variant_id = (long)device_get_match_data(cs42l43->dev); 50 51 51 52 cs42l43->regmap = devm_regmap_init_i2c(i2c, &cs42l43_i2c_regmap); 52 53 if (IS_ERR(cs42l43->regmap)) ··· 59 58 60 59 #if IS_ENABLED(CONFIG_OF) 61 60 static const struct of_device_id cs42l43_of_match[] = { 62 - { .compatible = "cirrus,cs42l43", }, 61 + { .compatible = "cirrus,cs42l43", .data = (void *)CS42L43_DEVID_VAL }, 62 + { .compatible = "cirrus,cs42l43b", .data = (void *)CS42L43B_DEVID_VAL }, 63 63 {} 64 64 }; 65 65 MODULE_DEVICE_TABLE(of, cs42l43_of_match); ··· 68 66 69 67 #if IS_ENABLED(CONFIG_ACPI) 70 68 static const struct acpi_device_id cs42l43_acpi_match[] = { 71 - { "CSC4243", 0 }, 69 + { "CSC4243", CS42L43_DEVID_VAL }, 70 + { "CSC2A3B", CS42L43B_DEVID_VAL }, 72 71 {} 73 72 }; 74 73 MODULE_DEVICE_TABLE(acpi, cs42l43_acpi_match);
+3 -1
drivers/mfd/cs42l43-sdw.c
··· 178 178 179 179 cs42l43->dev = dev; 180 180 cs42l43->sdw = sdw; 181 + cs42l43->variant_id = (long)id->driver_data; 181 182 182 183 cs42l43->regmap = devm_regmap_init_sdw(sdw, &cs42l43_sdw_regmap); 183 184 if (IS_ERR(cs42l43->regmap)) ··· 189 188 } 190 189 191 190 static const struct sdw_device_id cs42l43_sdw_id[] = { 192 - SDW_SLAVE_ENTRY(0x01FA, 0x4243, 0), 191 + SDW_SLAVE_ENTRY(0x01FA, 0x4243, (void *) CS42L43_DEVID_VAL), 192 + SDW_SLAVE_ENTRY(0x01FA, 0x2A3B, (void *) CS42L43B_DEVID_VAL), 193 193 {} 194 194 }; 195 195 MODULE_DEVICE_TABLE(sdw, cs42l43_sdw_id);
+80 -13
drivers/mfd/cs42l43.c
··· 115 115 { CS42L43_DECIM_HPF_WNF_CTRL2, 0x00000001 }, 116 116 { CS42L43_DECIM_HPF_WNF_CTRL3, 0x00000001 }, 117 117 { CS42L43_DECIM_HPF_WNF_CTRL4, 0x00000001 }, 118 + { CS42L43B_DECIM_HPF_WNF_CTRL5, 0x00000001 }, 119 + { CS42L43B_DECIM_HPF_WNF_CTRL6, 0x00000001 }, 118 120 { CS42L43_DMIC_PDM_CTRL, 0x00000000 }, 119 121 { CS42L43_DECIM_VOL_CTRL_CH1_CH2, 0x20122012 }, 120 122 { CS42L43_DECIM_VOL_CTRL_CH3_CH4, 0x20122012 }, 123 + { CS42L43B_DECIM_VOL_CTRL_CH1_CH2, 0x20122012 }, 124 + { CS42L43B_DECIM_VOL_CTRL_CH3_CH4, 0x20122012 }, 125 + { CS42L43B_DECIM_VOL_CTRL_CH5_CH6, 0x20122012 }, 121 126 { CS42L43_INTP_VOLUME_CTRL1, 0x00000180 }, 122 127 { CS42L43_INTP_VOLUME_CTRL2, 0x00000180 }, 123 128 { CS42L43_AMP1_2_VOL_RAMP, 0x00000022 }, ··· 160 155 { CS42L43_SWIRE_DP2_CH2_INPUT, 0x00000000 }, 161 156 { CS42L43_SWIRE_DP3_CH1_INPUT, 0x00000000 }, 162 157 { CS42L43_SWIRE_DP3_CH2_INPUT, 0x00000000 }, 158 + { CS42L43B_SWIRE_DP3_CH3_INPUT, 0x00000000 }, 159 + { CS42L43B_SWIRE_DP3_CH4_INPUT, 0x00000000 }, 163 160 { CS42L43_SWIRE_DP4_CH1_INPUT, 0x00000000 }, 164 161 { CS42L43_SWIRE_DP4_CH2_INPUT, 0x00000000 }, 162 + { CS42L43B_SWIRE_DP4_CH3_INPUT, 0x00000000 }, 163 + { CS42L43B_SWIRE_DP4_CH4_INPUT, 0x00000000 }, 165 164 { CS42L43_ASRC_INT1_INPUT1, 0x00000000 }, 166 165 { CS42L43_ASRC_INT2_INPUT1, 0x00000000 }, 167 166 { CS42L43_ASRC_INT3_INPUT1, 0x00000000 }, ··· 178 169 { CS42L43_ISRC1INT2_INPUT1, 0x00000000 }, 179 170 { CS42L43_ISRC1DEC1_INPUT1, 0x00000000 }, 180 171 { CS42L43_ISRC1DEC2_INPUT1, 0x00000000 }, 172 + { CS42L43B_ISRC1DEC3_INPUT1, 0x00000000 }, 173 + { CS42L43B_ISRC1DEC4_INPUT1, 0x00000000 }, 181 174 { CS42L43_ISRC2INT1_INPUT1, 0x00000000 }, 182 175 { CS42L43_ISRC2INT2_INPUT1, 0x00000000 }, 183 176 { CS42L43_ISRC2DEC1_INPUT1, 0x00000000 }, 184 177 { CS42L43_ISRC2DEC2_INPUT1, 0x00000000 }, 178 + { CS42L43B_ISRC2DEC3_INPUT1, 0x00000000 }, 179 + { CS42L43B_ISRC2DEC4_INPUT1, 0x00000000 }, 185 180 { CS42L43_EQ1MIX_INPUT1, 0x00800000 }, 186 181 { CS42L43_EQ1MIX_INPUT2, 0x00800000 }, 187 182 { CS42L43_EQ1MIX_INPUT3, 0x00800000 }, ··· 282 269 283 270 bool cs42l43_readable_register(struct device *dev, unsigned int reg) 284 271 { 272 + struct cs42l43 *cs42l43 = dev_get_drvdata(dev); 273 + 285 274 switch (reg) { 286 275 case CS42L43_DEVID: 287 276 case CS42L43_REVID: ··· 307 292 case CS42L43_ADC_B_CTRL1 ... CS42L43_ADC_B_CTRL2: 308 293 case CS42L43_DECIM_HPF_WNF_CTRL1 ... CS42L43_DECIM_HPF_WNF_CTRL4: 309 294 case CS42L43_DMIC_PDM_CTRL: 310 - case CS42L43_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43_DECIM_VOL_CTRL_CH3_CH4: 311 295 case CS42L43_INTP_VOLUME_CTRL1 ... CS42L43_INTP_VOLUME_CTRL2: 312 296 case CS42L43_AMP1_2_VOL_RAMP: 313 297 case CS42L43_ASP_CTRL: ··· 401 387 case CS42L43_BOOT_CONTROL: 402 388 case CS42L43_BLOCK_EN: 403 389 case CS42L43_SHUTTER_CONTROL: 404 - case CS42L43_MCU_SW_REV ... CS42L43_MCU_RAM_MAX: 405 - return true; 390 + case CS42L43B_MCU_SW_REV ... CS42L43B_MCU_RAM_MAX: 391 + return true; // registers present on all variants 392 + case CS42L43_MCU_SW_REV ... CS42L43B_MCU_SW_REV - 1: 393 + case CS42L43B_MCU_RAM_MAX + 1 ... CS42L43_MCU_RAM_MAX: 394 + case CS42L43_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43_DECIM_VOL_CTRL_CH3_CH4: 395 + return cs42l43->variant_id == CS42L43_DEVID_VAL; // regs only in CS42L43 variant 396 + case CS42L43B_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43B_DECIM_HPF_WNF_CTRL6: 397 + case CS42L43B_SWIRE_DP3_CH3_INPUT ... CS42L43B_SWIRE_DP4_CH4_INPUT: 398 + case CS42L43B_ISRC1DEC3_INPUT1 ... CS42L43B_ISRC2DEC4_INPUT1: 399 + return cs42l43->variant_id == CS42L43B_DEVID_VAL; // regs only in CS42L43B variant 406 400 default: 407 401 return false; 408 402 } ··· 619 597 static int cs42l43_mcu_stage_2_3(struct cs42l43 *cs42l43, bool shadow) 620 598 { 621 599 unsigned int need_reg = CS42L43_NEED_CONFIGS; 600 + unsigned int boot_reg; 622 601 unsigned int val; 623 602 int ret; 624 603 625 - if (shadow) 626 - need_reg = CS42L43_FW_SH_BOOT_CFG_NEED_CONFIGS; 604 + switch (cs42l43->variant_id) { 605 + case CS42L43_DEVID_VAL: 606 + if (shadow) 607 + need_reg = CS42L43_FW_SH_BOOT_CFG_NEED_CONFIGS; 608 + boot_reg = CS42L43_BOOT_STATUS; 609 + break; 610 + case CS42L43B_DEVID_VAL: 611 + need_reg = CS42L43B_NEED_CONFIGS; 612 + boot_reg = CS42L43B_BOOT_STATUS; 613 + break; 614 + default: 615 + return -EINVAL; 616 + } 627 617 628 618 regmap_write(cs42l43->regmap, need_reg, 0); 629 619 630 - ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_BOOT_STATUS, 620 + ret = regmap_read_poll_timeout(cs42l43->regmap, boot_reg, 631 621 val, (val == CS42L43_MCU_BOOT_STAGE3), 632 622 CS42L43_MCU_POLL_US, CS42L43_MCU_CMD_TIMEOUT_US); 633 623 if (ret) { ··· 678 644 */ 679 645 static int cs42l43_mcu_disable(struct cs42l43 *cs42l43) 680 646 { 681 - unsigned int val; 647 + unsigned int val, cfg_reg, ctrl_reg; 682 648 int ret; 683 649 684 - regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG, 685 - CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL); 686 - regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_MM_CTRL_SELECTION, 687 - CS42L43_FW_MM_CTRL_MCU_SEL_MASK); 650 + switch (cs42l43->variant_id) { 651 + case CS42L43_DEVID_VAL: 652 + cfg_reg = CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG; 653 + ctrl_reg = CS42L43_FW_MISSION_CTRL_MM_CTRL_SELECTION; 654 + break; 655 + case CS42L43B_DEVID_VAL: 656 + cfg_reg = CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG; 657 + ctrl_reg = CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION; 658 + break; 659 + default: 660 + return -EINVAL; 661 + } 662 + 663 + regmap_write(cs42l43->regmap, cfg_reg, CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL); 664 + regmap_write(cs42l43->regmap, ctrl_reg, CS42L43_FW_MM_CTRL_MCU_SEL_MASK); 665 + 688 666 regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, CS42L43_CONTROL_IND_MASK); 689 667 regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, 0); 690 668 ··· 786 740 { 787 741 unsigned int mcu_rev, bios_rev, boot_status, secure_cfg; 788 742 bool patched, shadow; 743 + int boot_status_reg, mcu_sw_rev_reg; 789 744 int ret; 745 + 746 + switch (cs42l43->variant_id) { 747 + case CS42L43_DEVID_VAL: 748 + boot_status_reg = CS42L43_BOOT_STATUS; 749 + mcu_sw_rev_reg = CS42L43_MCU_SW_REV; 750 + break; 751 + case CS42L43B_DEVID_VAL: 752 + boot_status_reg = CS42L43B_BOOT_STATUS; 753 + mcu_sw_rev_reg = CS42L43B_MCU_SW_REV; 754 + break; 755 + default: 756 + return -EINVAL; 757 + } 790 758 791 759 /* Clear any stale software interrupt bits. */ 792 760 regmap_read(cs42l43->regmap, CS42L43_SOFT_INT, &mcu_rev); 793 761 794 - ret = regmap_read(cs42l43->regmap, CS42L43_BOOT_STATUS, &boot_status); 762 + ret = regmap_read(cs42l43->regmap, boot_status_reg, &boot_status); 795 763 if (ret) { 796 764 dev_err(cs42l43->dev, "Failed to read boot status: %d\n", ret); 797 765 return ret; 798 766 } 799 767 800 - ret = regmap_read(cs42l43->regmap, CS42L43_MCU_SW_REV, &mcu_rev); 768 + ret = regmap_read(cs42l43->regmap, mcu_sw_rev_reg, &mcu_rev); 801 769 if (ret) { 802 770 dev_err(cs42l43->dev, "Failed to read firmware revision: %d\n", ret); 803 771 return ret; ··· 978 918 979 919 switch (devid) { 980 920 case CS42L43_DEVID_VAL: 921 + case CS42L43B_DEVID_VAL: 922 + if (devid != cs42l43->variant_id) { 923 + dev_err(cs42l43->dev, 924 + "Device ID (0x%06x) does not match variant ID (0x%06lx)\n", 925 + devid, cs42l43->variant_id); 926 + goto err; 927 + } 981 928 break; 982 929 default: 983 930 dev_err(cs42l43->dev, "Unrecognised devid: 0x%06x\n", devid);
+1 -1
drivers/mfd/cs42l43.h
··· 9 9 #ifndef CS42L43_CORE_INT_H 10 10 #define CS42L43_CORE_INT_H 11 11 12 - #define CS42L43_N_DEFAULTS 176 12 + #define CS42L43_N_DEFAULTS 189 13 13 14 14 struct dev_pm_ops; 15 15 struct device;
+76
include/linux/mfd/cs42l43-regs.h
··· 1181 1181 /* CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG */ 1182 1182 #define CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL 0xF05AA50F 1183 1183 1184 + /* CS42L43B VARIANT REGISTERS */ 1185 + #define CS42L43B_DEVID_VAL 0x0042A43B 1186 + 1187 + #define CS42L43B_DECIM_VOL_CTRL_CH1_CH2 0x00008280 1188 + #define CS42L43B_DECIM_VOL_CTRL_CH3_CH4 0x00008284 1189 + 1190 + #define CS42L43B_DECIM_VOL_CTRL_CH5_CH6 0x00008290 1191 + #define CS42L43B_DECIM_VOL_CTRL_UPDATE 0x0000829C 1192 + 1193 + #define CS42L43B_DECIM_HPF_WNF_CTRL5 0x000082A0 1194 + #define CS42L43B_DECIM_HPF_WNF_CTRL6 0x000082A4 1195 + 1196 + #define CS42L43B_SWIRE_DP3_CH3_INPUT 0x0000C320 1197 + #define CS42L43B_SWIRE_DP3_CH4_INPUT 0x0000C330 1198 + #define CS42L43B_SWIRE_DP4_CH3_INPUT 0x0000C340 1199 + #define CS42L43B_SWIRE_DP4_CH4_INPUT 0x0000C350 1200 + 1201 + #define CS42L43B_ISRC1DEC3_INPUT1 0x0000C780 1202 + #define CS42L43B_ISRC1DEC4_INPUT1 0x0000C790 1203 + #define CS42L43B_ISRC2DEC3_INPUT1 0x0000C7A0 1204 + #define CS42L43B_ISRC2DEC4_INPUT1 0x0000C7B0 1205 + 1206 + #define CS42L43B_FW_MISSION_CTRL_NEED_CONFIGS 0x00117E00 1207 + #define CS42L43B_FW_MISSION_CTRL_HAVE_CONFIGS 0x00117E04 1208 + #define CS42L43B_FW_MISSION_CTRL_PATCH_START_ADDR_REG 0x00117E08 1209 + #define CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION 0x00117E0C 1210 + #define CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG 0x00117E10 1211 + 1212 + #define CS42L43B_MCU_SW_REV 0x00117314 1213 + #define CS42L43B_PATCH_START_ADDR 0x00117318 1214 + #define CS42L43B_CONFIG_SELECTION 0x0011731C 1215 + #define CS42L43B_NEED_CONFIGS 0x00117320 1216 + #define CS42L43B_BOOT_STATUS 0x00117330 1217 + 1218 + #define CS42L43B_FW_MISSION_CTRL_NEED_CONFIGS 0x00117E00 1219 + #define CS42L43B_FW_MISSION_CTRL_HAVE_CONFIGS 0x00117E04 1220 + #define CS42L43B_FW_MISSION_CTRL_PATCH_START_ADDR_REG 0x00117E08 1221 + #define CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION 0x00117E0C 1222 + #define CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG 0x00117E10 1223 + 1224 + #define CS42L43B_MCU_RAM_MAX 0x00117FFF 1225 + 1226 + /* CS42L43B_DECIM_DECIM_VOL_CTRL_CH5_CH6 */ 1227 + #define CS42L43B_DECIM6_MUTE_MASK 0x80000000 1228 + #define CS42L43B_DECIM6_MUTE_SHIFT 31 1229 + #define CS42L43B_DECIM6_VOL_MASK 0x3FC00000 1230 + #define CS42L43B_DECIM6_VOL_SHIFT 22 1231 + #define CS42L43B_DECIM6_PATH1_VOL_FALL_RATE_MASK 0x00380000 1232 + #define CS42L43B_DECIM6_PATH1_VOL_FALL_RATE_SHIFT 19 1233 + #define CS42L43B_DECIM6_PATH1_VOL_RISE_RATE_MASK 0x00070000 1234 + #define CS42L43B_DECIM6_PATH1_VOL_RISE_RATE_SHIFT 16 1235 + #define CS42L43B_DECIM5_MUTE_MASK 0x00008000 1236 + #define CS42L43B_DECIM5_MUTE_SHIFT 15 1237 + #define CS42L43B_DECIM5_VOL_MASK 0x00003FC0 1238 + #define CS42L43B_DECIM5_VOL_SHIFT 6 1239 + #define CS42L43B_DECIM5_PATH1_VOL_FALL_RATE_MASK 0x00000038 1240 + #define CS42L43B_DECIM5_PATH1_VOL_FALL_RATE_SHIFT 3 1241 + #define CS42L43B_DECIM5_PATH1_VOL_RISE_RATE_MASK 0x00000007 1242 + #define CS42L43B_DECIM5_PATH1_VOL_RISE_RATE_SHIFT 0 1243 + 1244 + /* CS42L43B_DECIM_VOL_CTRL_UPDATE */ 1245 + #define CS42L43B_DECIM6_PATH1_VOL_TRIG_MASK 0x00000800 1246 + #define CS42L43B_DECIM6_PATH1_VOL_TRIG_SHIFT 11 1247 + #define CS42L43B_DECIM5_PATH1_VOL_TRIG_MASK 0x00000100 1248 + #define CS42L43B_DECIM5_PATH1_VOL_TRIG_SHIFT 8 1249 + #define CS42L43B_DECIM4_VOL_UPDATE_MASK 0x00000020 1250 + #define CS42L43B_DECIM4_VOL_UPDATE_SHIFT 5 1251 + 1252 + /* CS42L43_ISRC1_CTRL..CS42L43_ISRC2_CTRL */ 1253 + #define CS42L43B_ISRC_DEC4_EN_MASK 0x00000008 1254 + #define CS42L43B_ISRC_DEC4_EN_SHIFT 3 1255 + #define CS42L43B_ISRC_DEC4_EN_WIDTH 1 1256 + #define CS42L43B_ISRC_DEC3_EN_MASK 0x00000004 1257 + #define CS42L43B_ISRC_DEC3_EN_SHIFT 2 1258 + #define CS42L43B_ISRC_DEC3_EN_WIDTH 1 1259 + 1184 1260 #endif /* CS42L43_CORE_REGS_H */
+1
include/linux/mfd/cs42l43.h
··· 98 98 bool sdw_pll_active; 99 99 bool attached; 100 100 bool hw_lock; 101 + long variant_id; 101 102 }; 102 103 103 104 #endif /* CS42L43_CORE_EXT_H */