]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: cs35l56: Add struct to index firmware registers
authorStefan Binding <sbinding@opensource.cirrus.com>
Mon, 7 Apr 2025 15:16:41 +0000 (16:16 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 5 May 2025 23:49:18 +0000 (08:49 +0900)
Firmware based registers may be different addresses across different
device ids and revision ids. Create a structure to store and access
these addresses.

Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Reviewed-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20250407151842.143393-3-sbinding@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/cs35l56.h
sound/pci/hda/cs35l56_hda.c
sound/pci/hda/cs35l56_hda_i2c.c
sound/pci/hda/cs35l56_hda_spi.c
sound/soc/codecs/cs35l56-i2c.c
sound/soc/codecs/cs35l56-sdw.c
sound/soc/codecs/cs35l56-shared.c
sound/soc/codecs/cs35l56-spi.c
sound/soc/codecs/cs35l56.c

index 5d653a3491d07377d052190d08bd912384c9c981..d712cb79652b0934b3257ce8a59853e373370bde 100644 (file)
@@ -267,6 +267,14 @@ struct cs35l56_spi_payload {
 } __packed;
 static_assert(sizeof(struct cs35l56_spi_payload) == 10);
 
+struct cs35l56_fw_reg {
+       unsigned int fw_ver;
+       unsigned int halo_state;
+       unsigned int pm_cur_stat;
+       unsigned int prot_sts;
+       unsigned int transducer_actual_ps;
+};
+
 struct cs35l56_base {
        struct device *dev;
        struct regmap *regmap;
@@ -283,6 +291,7 @@ struct cs35l56_base {
        struct cirrus_amp_cal_data cal_data;
        struct gpio_desc *reset_gpio;
        struct cs35l56_spi_payload *spi_payload_buf;
+       const struct cs35l56_fw_reg *fw_reg;
 };
 
 static inline bool cs35l56_is_otp_register(unsigned int reg)
@@ -311,6 +320,8 @@ extern const struct regmap_config cs35l56_regmap_i2c;
 extern const struct regmap_config cs35l56_regmap_spi;
 extern const struct regmap_config cs35l56_regmap_sdw;
 
+extern const struct cs35l56_fw_reg cs35l56_fw_reg;
+
 extern const struct cirrus_amp_cal_controls cs35l56_calibration_controls;
 
 extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
index 235d22049aa9fa459efa18afd45b093e14cd962c..5660cf7087fece4843184ea91f8e8f7f4d6c382c 100644 (file)
@@ -68,7 +68,7 @@ static void cs35l56_hda_play(struct cs35l56_hda *cs35l56)
        if (ret == 0) {
                /* Wait for firmware to enter PS0 power state */
                ret = regmap_read_poll_timeout(cs35l56->base.regmap,
-                                              CS35L56_TRANSDUCER_ACTUAL_PS,
+                                              cs35l56->base.fw_reg->transducer_actual_ps,
                                               val, (val == CS35L56_PS0),
                                               CS35L56_PS0_POLL_US,
                                               CS35L56_PS0_TIMEOUT_US);
@@ -665,7 +665,8 @@ static void cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
 
        regcache_sync(cs35l56->base.regmap);
 
-       regmap_clear_bits(cs35l56->base.regmap, CS35L56_PROTECTION_STATUS,
+       regmap_clear_bits(cs35l56->base.regmap,
+                         cs35l56->base.fw_reg->prot_sts,
                          CS35L56_FIRMWARE_MISSING);
        cs35l56->base.fw_patched = true;
 
index c7b83661314984ad8a0f505bb0ecc7dba59c3543..d10209e4eddd5bddc97c2da8e239e0f4e9247bf5 100644 (file)
@@ -26,6 +26,9 @@ static int cs35l56_hda_i2c_probe(struct i2c_client *clt)
 #ifdef CS35L56_WAKE_HOLD_TIME_US
        cs35l56->base.can_hibernate = true;
 #endif
+
+       cs35l56->base.fw_reg = &cs35l56_fw_reg;
+
        cs35l56->base.regmap = devm_regmap_init_i2c(clt, &cs35l56_regmap_i2c);
        if (IS_ERR(cs35l56->base.regmap)) {
                ret = PTR_ERR(cs35l56->base.regmap);
index 90357846690537dc496cd6d622ee6674399053b0..f57533d3d728f5c31296e2d8a30da862d647ea7f 100644 (file)
@@ -29,6 +29,9 @@ static int cs35l56_hda_spi_probe(struct spi_device *spi)
 #ifdef CS35L56_WAKE_HOLD_TIME_US
        cs35l56->base.can_hibernate = true;
 #endif
+
+       cs35l56->base.fw_reg = &cs35l56_fw_reg;
+
        cs35l56->base.regmap = devm_regmap_init_spi(spi, &cs35l56_regmap_spi);
        if (IS_ERR(cs35l56->base.regmap)) {
                ret = PTR_ERR(cs35l56->base.regmap);
index 5962914e2180d5c20afd52f3ee5cd8c76039c706..38c391d11c785ad5af3bd6bfe7779826c179c227 100644 (file)
@@ -35,6 +35,7 @@ static int cs35l56_i2c_probe(struct i2c_client *client)
        switch (id) {
        case 0x3556:
                regmap_config = &cs35l56_regmap_i2c;
+               cs35l56->base.fw_reg = &cs35l56_fw_reg;
                break;
        default:
                return -ENODEV;
index d178357e1196a5992301ccdfc86dd188f5fb41ae..2e0422b41385a6b946da7d1119f8a8e50f835fa7 100644 (file)
@@ -526,6 +526,7 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi
        case 0x3556:
        case 0x3557:
                regmap_config = &cs35l56_regmap_sdw;
+               cs35l56->base.fw_reg = &cs35l56_fw_reg;
                break;
        default:
                return -ENODEV;
index e28bfefa72f33effe9d634b63aee0579d82ae349..bc8f9379bc74083524246cca449ce78a39e09c88 100644 (file)
@@ -253,7 +253,8 @@ int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base)
        if (ret)
                return ret;
 
-       ret = regmap_read_poll_timeout(cs35l56_base->regmap,  CS35L56_DSP1_PM_CUR_STATE,
+       ret = regmap_read_poll_timeout(cs35l56_base->regmap,
+                                      cs35l56_base->fw_reg->pm_cur_stat,
                                       val, (val == CS35L56_HALO_STATE_SHUTDOWN),
                                       CS35L56_HALO_STATE_POLL_US,
                                       CS35L56_HALO_STATE_TIMEOUT_US);
@@ -278,7 +279,9 @@ int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base)
                                     CS35L56_HALO_STATE_POLL_US,
                                     CS35L56_HALO_STATE_TIMEOUT_US,
                                     false,
-                                    cs35l56_base->regmap, CS35L56_DSP1_HALO_STATE, &val);
+                                    cs35l56_base->regmap,
+                                    cs35l56_base->fw_reg->halo_state,
+                                    &val);
 
        if (poll_ret) {
                dev_err(cs35l56_base->dev, "Firmware boot timed out(%d): HALO_STATE=%#x\n",
@@ -395,9 +398,17 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
                return;
        }
 
-       regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
-                                       cs35l56_system_reset_seq,
-                                       ARRAY_SIZE(cs35l56_system_reset_seq));
+       switch (cs35l56_base->type) {
+       case 0x54:
+       case 0x56:
+       case 0x57:
+               regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
+                                               cs35l56_system_reset_seq,
+                                               ARRAY_SIZE(cs35l56_system_reset_seq));
+               break;
+       default:
+               break;
+       }
 
        /* On SoundWire the registers won't be accessible until it re-enumerates. */
        if (is_soundwire)
@@ -514,7 +525,9 @@ int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base)
                return ret;
        }
 
-       ret = regmap_read(cs35l56_base->regmap, CS35L56_PROTECTION_STATUS, &val);
+       ret = regmap_read(cs35l56_base->regmap,
+                         cs35l56_base->fw_reg->prot_sts,
+                         &val);
        if (ret)
                dev_err(cs35l56_base->dev, "Failed to read PROTECTION_STATUS: %d\n", ret);
        else
@@ -562,7 +575,7 @@ int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base)
 
        /* Firmware must have entered a power-save state */
        ret = regmap_read_poll_timeout(cs35l56_base->regmap,
-                                      CS35L56_TRANSDUCER_ACTUAL_PS,
+                                      cs35l56_base->fw_reg->transducer_actual_ps,
                                       val, (val >= CS35L56_PS3),
                                       CS35L56_PS3_POLL_US,
                                       CS35L56_PS3_TIMEOUT_US);
@@ -752,7 +765,8 @@ int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
        unsigned int prot_status;
        int ret;
 
-       ret = regmap_read(cs35l56_base->regmap, CS35L56_PROTECTION_STATUS, &prot_status);
+       ret = regmap_read(cs35l56_base->regmap,
+                         cs35l56_base->fw_reg->prot_sts, &prot_status);
        if (ret) {
                dev_err(cs35l56_base->dev, "Get PROTECTION_STATUS failed: %d\n", ret);
                return ret;
@@ -760,7 +774,8 @@ int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
 
        *fw_missing = !!(prot_status & CS35L56_FIRMWARE_MISSING);
 
-       ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP1_FW_VER, fw_version);
+       ret = regmap_read(cs35l56_base->regmap,
+                         cs35l56_base->fw_reg->fw_ver, fw_version);
        if (ret) {
                dev_err(cs35l56_base->dev, "Get FW VER failed: %d\n", ret);
                return ret;
@@ -1045,6 +1060,15 @@ const struct regmap_config cs35l56_regmap_sdw = {
 };
 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, "SND_SOC_CS35L56_SHARED");
 
+const struct cs35l56_fw_reg cs35l56_fw_reg = {
+       .fw_ver = CS35L56_DSP1_FW_VER,
+       .halo_state = CS35L56_DSP1_HALO_STATE,
+       .pm_cur_stat = CS35L56_DSP1_PM_CUR_STATE,
+       .prot_sts = CS35L56_PROTECTION_STATUS,
+       .transducer_actual_ps = CS35L56_TRANSDUCER_ACTUAL_PS,
+};
+EXPORT_SYMBOL_NS_GPL(cs35l56_fw_reg, "SND_SOC_CS35L56_SHARED");
+
 MODULE_DESCRIPTION("ASoC CS35L56 Shared");
 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
 MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
index ca6c03a8766d3817ec022f03e54ec19e01be2bef..c2ddee22cd231ba5099b7f5276d2199a5a98e5ac 100644 (file)
@@ -25,6 +25,9 @@ static int cs35l56_spi_probe(struct spi_device *spi)
                return -ENOMEM;
 
        spi_set_drvdata(spi, cs35l56);
+
+       cs35l56->base.fw_reg = &cs35l56_fw_reg;
+
        cs35l56->base.regmap = devm_regmap_init_spi(spi, regmap_config);
        if (IS_ERR(cs35l56->base.regmap)) {
                ret = PTR_ERR(cs35l56->base.regmap);
index b3158a84b87afec87ab528e90cde84f44d3278cb..c1d8bfb803b9ec958fdfa94dfee6915163f5da5f 100644 (file)
@@ -174,7 +174,7 @@ static int cs35l56_play_event(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_POST_PMU:
                /* Wait for firmware to enter PS0 power state */
                ret = regmap_read_poll_timeout(cs35l56->base.regmap,
-                                              CS35L56_TRANSDUCER_ACTUAL_PS,
+                                              cs35l56->base.fw_reg->transducer_actual_ps,
                                               val, (val == CS35L56_PS0),
                                               CS35L56_PS0_POLL_US,
                                               CS35L56_PS0_TIMEOUT_US);
@@ -760,7 +760,8 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing
                goto err_unlock;
        }
 
-       regmap_clear_bits(cs35l56->base.regmap, CS35L56_PROTECTION_STATUS,
+       regmap_clear_bits(cs35l56->base.regmap,
+                         cs35l56->base.fw_reg->prot_sts,
                          CS35L56_FIRMWARE_MISSING);
        cs35l56->base.fw_patched = true;