From 598989c4b0ced330b0d7541be331b62eb0709dc4 Mon Sep 17 00:00:00 2001 From: Tai Kuo Date: Wed, 10 May 2023 17:04:22 +0800 Subject: cs40l26: merge cs40l26 v6.0.2, 6.1.1, 7.0.0 and dsp v4.0.0, 4.0.1 Merge Cirrus kernel driver (tag cs40l26 v6.0.2, 6.1.1, 7.0.0 and dsp v4.0.0, 4.0.1) and manually update the Kconfig and Makefile. Branches: v5.15-cirrus-dsp-fw and v5.15-cs40l26 Tags: cirrus-dsp-fw-v4.0.0_5.15, cl-dsp-fw-v4.0.1_5.15, cs40l26-v6.0.2_5.15, cs40l26-v6.1.1_5.15 and cs40l26-v7.0.0_5.15. Files: Documentation/devicetree/bindings/input/cs40l26.yaml (No changes) drivers/firmware/cirrus/cl_dsp-debugfs.c drivers/firmware/cirrus/cl_dsp.c (No changes) include/linux/firmware/cirrus/cl_dsp.h (No changes) drivers/input/misc/cs40l26-debugfs.c drivers/input/misc/cs40l26-i2c.c drivers/input/misc/cs40l26-spi.c drivers/input/misc/cs40l26-sysfs.c (No changes) drivers/input/misc/cs40l26-tables.c drivers/input/misc/cs40l26.c include/linux/mfd/cs40l26.h sound/soc/codecs/cs40l26.c -> cs40l26-codec.c ... Tag: cirrus-dsp-fw-v4.0.0_5.15: Cirrus DSP Firmware Driver v4.0.0 New Features: - Change the build method and module name for the cl_dsp code Commits: a9da515 firmware: cirrus: Change CL_DSP build method Tag: cl-dsp-fw-v4.0.1_5.15: Cirrus DSP Firmware Driver v4.0.1 Bug Fixes: - Wait until reinitialization process to reset EVENT_LOGGER to avoid potential race condition in debugfs_destroy(). Commits: 3e1294c firmware: cirrus: Reset EVENT_LOGGER during initialization Tag: cs40l26-v6.0.2_5.15 - Prevent invalid option of 0 for mixer control "A2H Level" - Various build warnings fixed Commits: 919d495 input: cs40l26: Remove unused functions 84feb83 ASoC: cs40l26: Prohibit setting VOLUMELEVEL to 0 9965618 input: cs40l26: Use string literal in snprintf 8c7e2b1 input: cs40l26: Avoid undefined function warning Tag: cs40l26-v6.1.1_5.15 - Fix composites with repeats Commits: 7054f8b ASoC: cs40l26: Change name of ALSA mixer control and its options 8821e02 input: cs40l26: Fix PWLE header serialization 1010409 input: cs40l26: Load Live F0 Tracking tuning file 3f0d182 input: cs40l26: Fix delay field present bit Tag: cs40l26-v7.0.0_5.15 - Add support for silicon revision B1 - Do not attempt to load the event logger if it is not preset in the FW - Change build configuration to match precedent in the kernel Commits: 2249a92 input: cs40l26: Improve build configuration d8a7a15 input: cs40l26: Don't initialize CL DSP debugfs if not supported firmware 35ef42e input: cs40l26: Add support for revision B1 Bug: 278018625 Test: Build and probe. Test: Copy texts and adjust alarm Test: NFC, dumpstate, keyboard vibration Test: idlcli commands Test: Switch firmware continuous Test: Switch firmware and check the first tick effect Test: atest PtsVibratorHalTestSuite \ PtsHapticsTestCases \ VibratorHalCs40l26TestSuite \ VtsHalVibratorManagerTargetTest \ VtsHalVibratorTargetTest \ android.os.cts.VibratorTest \ android.os.cts.VibratorManagerTest \ android.os.cts.VibrationEffectTest \ android.os.cts.VibrationAttributesTest \ android.os.cts.CombinedVibrationTest Change-Id: I0a0da4726fa14c7e61be48d8dd7e51ecb1e0a2d9 Signed-off-by: Tai Kuo --- cs40l26/Kconfig | 33 ++++++++------ cs40l26/Makefile | 20 ++++----- cs40l26/cl_dsp-debugfs.c | 20 ++++----- cs40l26/cs40l26-codec.c | 26 +++++------ cs40l26/cs40l26-debugfs.c | 5 ++- cs40l26/cs40l26-i2c.c | 10 ++++- cs40l26/cs40l26-spi.c | 10 ++++- cs40l26/cs40l26-tables.c | 17 +------- cs40l26/cs40l26.c | 107 +++++++++++++++++++++++----------------------- cs40l26/cs40l26.h | 13 +++--- 10 files changed, 136 insertions(+), 125 deletions(-) diff --git a/cs40l26/Kconfig b/cs40l26/Kconfig index c4e0510..0c45b31 100644 --- a/cs40l26/Kconfig +++ b/cs40l26/Kconfig @@ -3,29 +3,36 @@ # Cirrus Logic haptic driver configuration # +config INPUT_CS40L26 + tristate "Cirrus Logic CS40L26 haptic amplifier support" + select CL_DSP + help + Say Y here to enable support for CS40L26 boosted haptic amplifier. + + To compile the driver as a module choose M here: the module will + be called cs40l26_core. + config INPUT_CS40L26_I2C - tristate "Cirrus Logic CS40L26 Haptic Driver (I2C)" - depends on I2C + tristate "Support I2C bus connection" + depends on INPUT_CS40L26 && I2C select REGMAP_I2C help - Say Y here to enable support for CS40L26 boosted - haptic amplifier with I2C control port. + Say Y if you have CS40L26 hooked to an I2C bus. - To complie the driver as a module choose M here: the - module will be called input_cs40l26_i2c. + To compile the driver as a module choose M here: the + module will be called cs40l26_i2c. config INPUT_CS40L26_SPI - tristate "Cirrus Logic CS40L26 Haptic Driver (SPI)" - depends on SPI_MASTER + tristate "Support SPI bus connection" + depends on INPUT_CS40L26 && SPI_MASTER select REGMAP_SPI help - Say Y here to enable support for CS40L26 boosted - haptic amplifier with SPI control port. + Say Y if you have CS40L26 hooked to a SPI bus. - To compile the driver as a module choose M here: the - module will be called input_cs40l26_spi. + To compile the driver as a module choose M here: the + module will be called cs40l26_spi. -config CIRRUS_FIRMWARE_CL_DSP +config CL_DSP tristate "Cirrus Logic Haptics DSP driver" help This driver is used to handle firmware loading diff --git a/cs40l26/Makefile b/cs40l26/Makefile index 979b83a..836691e 100644 --- a/cs40l26/Makefile +++ b/cs40l26/Makefile @@ -3,22 +3,22 @@ # Makefile for Cirrus Logic haptic driver. # -input-cs40l26-i2c-objs := cs40l26.o cs40l26-tables.o cs40l26-sysfs.o \ - cs40l26-i2c.o cs40l26-debugfs.o cl_dsp-debugfs.o -input-cs40l26-spi-objs := cs40l26.o cs40l26-tables.o cs40l26-sysfs.o \ - cs40l26-spi.o cs40l26-debugfs.o cl_dsp-debugfs.o +cl_dsp-core-objs := cl_dsp.o cl_dsp-debugfs.o +cs40l26-core-objs := cs40l26.o cs40l26-tables.o cs40l26-sysfs.o cs40l26-debugfs.o snd-soc-cs40l26-objs := cs40l26-codec.o -obj-$(CONFIG_INPUT_CS40L26_I2C) += input-cs40l26-i2c.o -obj-$(CONFIG_INPUT_CS40L26_SPI) += input-cs40l26-spi.o -obj-$(CONFIG_CIRRUS_FIRMWARE_CL_DSP) += cl_dsp.o -obj-$(CONFIG_SND_SOC_CS40L26) += snd-soc-cs40l26.o +obj-$(CONFIG_CL_DSP) += cl_dsp-core.o +obj-$(CONFIG_INPUT_CS40L26) += cs40l26-core.o +obj-$(CONFIG_INPUT_CS40L26_I2C) += cs40l26-i2c.o +obj-$(CONFIG_INPUT_CS40L26_SPI) += cs40l26-spi.o +obj-$(CONFIG_SND_SOC_CS40L26) += snd-soc-cs40l26.o KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build M ?= $(shell pwd) -KBUILD_OPTIONS += CONFIG_INPUT_CS40L26_I2C=m \ - CONFIG_CIRRUS_FIRMWARE_CL_DSP=m \ +KBUILD_OPTIONS += CONFIG_CL_DSP=m \ + CONFIG_INPUT_CS40L26=m \ + CONFIG_INPUT_CS40L26_I2C=m \ CONFIG_SND_SOC_CS40L26=m EXTRA_CFLAGS += -DDYNAMIC_DEBUG_MODULE diff --git a/cs40l26/cl_dsp-debugfs.c b/cs40l26/cl_dsp-debugfs.c index 498b8ff..1c8aec9 100644 --- a/cs40l26/cl_dsp-debugfs.c +++ b/cs40l26/cl_dsp-debugfs.c @@ -448,6 +448,15 @@ static int cl_dsp_logger_init(struct cl_dsp_debugfs *db) ret = cl_dsp_host_buffer_field_read(db, HOST_BUFFER_FIELD(high_water_mark), &db->dl.high_watermark); + if (ret) + return ret; + + /* Set next_read_index to -1 to reset logger */ + ret = cl_dsp_host_buffer_field_write(db, + HOST_BUFFER_FIELD(next_read_index), + CL_DSP_HOST_BUFFER_READ_INDEX_RESET); + if (ret) + dev_err(db->core->dev, "Failed to reset event logger\n"); return ret; } @@ -504,18 +513,9 @@ EXPORT_SYMBOL(cl_dsp_debugfs_create); void cl_dsp_debugfs_destroy(struct cl_dsp_debugfs *db) { - int ret; - - if (!db || IS_ERR(db)) + if (IS_ERR_OR_NULL(db)) return; - /* Set next_read_index to -1 to reset logger */ - ret = cl_dsp_host_buffer_field_write(db, - HOST_BUFFER_FIELD(next_read_index), - CL_DSP_HOST_BUFFER_READ_INDEX_RESET); - if (ret) - dev_err(db->core->dev, "Failed to reset event logger\n"); - debugfs_remove_recursive(db->debugfs_node); kfree(db); } diff --git a/cs40l26/cs40l26-codec.c b/cs40l26/cs40l26-codec.c index 48b63a2..24a10b1 100644 --- a/cs40l26/cs40l26-codec.c +++ b/cs40l26/cs40l26-codec.c @@ -601,8 +601,8 @@ static int cs40l26_a2h_level_put(struct snd_kcontrol *kcontrol, if (ucontrol->value.integer.value[0] > CS40L26_A2H_LEVEL_MAX) val = CS40L26_A2H_LEVEL_MAX; - else if (ucontrol->value.integer.value[0] < 0) - val = 0; + else if (ucontrol->value.integer.value[0] < CS40L26_A2H_LEVEL_MIN) + val = CS40L26_A2H_LEVEL_MIN; else val = ucontrol->value.integer.value[0]; @@ -749,10 +749,10 @@ static const struct snd_kcontrol_new cs40l26_controls[] = { #endif }; -static const char * const cs40l26_out_mux_texts[] = { "None", "ASP Rx", "DSP Tx" }; +static const char * const cs40l26_out_mux_texts[] = { "Off", "PCM", "A2H" }; static SOC_ENUM_SINGLE_VIRT_DECL(cs40l26_out_mux_enum, cs40l26_out_mux_texts); static const struct snd_kcontrol_new cs40l26_out_mux = - SOC_DAPM_ENUM("Haptics Streaming Source", cs40l26_out_mux_enum); + SOC_DAPM_ENUM("Haptics Source", cs40l26_out_mux_enum); static const struct snd_soc_dapm_widget cs40l26_dapm_widgets[] = { @@ -761,12 +761,12 @@ static const struct snd_soc_dapm_widget SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_PGA_E("ASP Rx", SND_SOC_NOPM, 0, 0, NULL, 0, cs40l26_asp_rx, + SND_SOC_DAPM_PGA_E("PCM", SND_SOC_NOPM, 0, 0, NULL, 0, cs40l26_asp_rx, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_MIXER_E("DSP Tx", SND_SOC_NOPM, 0, 0, NULL, 0, cs40l26_dsp_tx, + SND_SOC_DAPM_MIXER_E("A2H", SND_SOC_NOPM, 0, 0, NULL, 0, cs40l26_dsp_tx, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_MUX("Haptics Streaming Source", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MUX("Haptics Source", SND_SOC_NOPM, 0, 0, &cs40l26_out_mux), SND_SOC_DAPM_OUTPUT("OUT"), }; @@ -777,13 +777,13 @@ static const struct snd_soc_dapm_route { "ASPRX1", NULL, "ASP Playback" }, { "ASPRX2", NULL, "ASP Playback" }, - { "ASP Rx", NULL, "ASPRX1" }, - { "ASP Rx", NULL, "ASPRX2" }, - { "DSP Tx", NULL, "ASP Rx" }, + { "PCM", NULL, "ASPRX1" }, + { "PCM", NULL, "ASPRX2" }, + { "A2H", NULL, "PCM" }, - { "Haptics Streaming Source", "ASP Rx", "ASP Rx" }, - { "Haptics Streaming Source", "DSP Tx", "DSP Tx" }, - { "OUT", NULL, "Haptics Streaming Source" }, + { "Haptics Source", "PCM", "PCM" }, + { "Haptics Source", "A2H", "A2H" }, + { "OUT", NULL, "Haptics Source" }, }; static int cs40l26_component_set_sysclk(struct snd_soc_component *component, diff --git a/cs40l26/cs40l26-debugfs.c b/cs40l26/cs40l26-debugfs.c index 5341d7d..59369ba 100644 --- a/cs40l26/cs40l26-debugfs.c +++ b/cs40l26/cs40l26-debugfs.c @@ -144,7 +144,7 @@ static ssize_t cs40l26_fw_ctrl_val_read(struct file *file, goto err_mutex; } - snprintf(input, strlen(cs40l26->dbg_fw_ctrl_name), + snprintf(input, strlen(cs40l26->dbg_fw_ctrl_name), "%s", cs40l26->dbg_fw_ctrl_name); ret = cl_dsp_get_reg(cs40l26->dsp, input, mem_type, @@ -232,7 +232,8 @@ void cs40l26_debugfs_init(struct cs40l26_private *cs40l26) cs40l26->dbg_fw_algo_id = CS40L26_VIBEGEN_ALGO_ID; cs40l26->debugfs_root = root; - if (cs40l26->fw_id == CS40L26_FW_ID) { + if (cs40l26->fw_id == CS40L26_FW_ID && + cl_dsp_algo_is_present(cs40l26->dsp, CS40L26_EVENT_LOGGER_ALGO_ID)) { cs40l26->cl_dsp_db = cl_dsp_debugfs_create(cs40l26->dsp, cs40l26->debugfs_root, (u32) CS40L26_EVENT_LOGGER_ALGO_ID); diff --git a/cs40l26/cs40l26-i2c.c b/cs40l26/cs40l26-i2c.c index f07e812..b638c84 100644 --- a/cs40l26/cs40l26-i2c.c +++ b/cs40l26/cs40l26-i2c.c @@ -19,9 +19,17 @@ static const struct i2c_device_id cs40l26_id_i2c[] = { {"cs40l27b", 3}, {} }; - MODULE_DEVICE_TABLE(i2c, cs40l26_id_i2c); +static const struct of_device_id cs40l26_of_match[CS40L26_NUM_DEVS + 1] = { + { .compatible = "cirrus,cs40l26a" }, + { .compatible = "cirrus,cs40l26b" }, + { .compatible = "cirrus,cs40l27a" }, + { .compatible = "cirrus,cs40l27b" }, + {} +}; +MODULE_DEVICE_TABLE(of, cs40l26_of_match); + static int cs40l26_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { diff --git a/cs40l26/cs40l26-spi.c b/cs40l26/cs40l26-spi.c index 7d0f021..db1e0ac 100644 --- a/cs40l26/cs40l26-spi.c +++ b/cs40l26/cs40l26-spi.c @@ -19,9 +19,17 @@ static const struct spi_device_id cs40l26_id_spi[] = { {"cs40l27b", 3}, {} }; - MODULE_DEVICE_TABLE(spi, cs40l26_id_spi); +static const struct of_device_id cs40l26_of_match[CS40L26_NUM_DEVS + 1] = { + { .compatible = "cirrus,cs40l26a" }, + { .compatible = "cirrus,cs40l26b" }, + { .compatible = "cirrus,cs40l27a" }, + { .compatible = "cirrus,cs40l27b" }, + {} +}; +MODULE_DEVICE_TABLE(of, cs40l26_of_match); + static int cs40l26_spi_probe(struct spi_device *spi) { int ret; diff --git a/cs40l26/cs40l26-tables.c b/cs40l26/cs40l26-tables.c index a217f9a..f8bf336 100644 --- a/cs40l26/cs40l26-tables.c +++ b/cs40l26/cs40l26-tables.c @@ -13,15 +13,6 @@ #include "cs40l26.h" -const struct of_device_id cs40l26_of_match[CS40L26_NUM_DEVS + 1] = { - { .compatible = "cirrus,cs40l26a" }, - { .compatible = "cirrus,cs40l26b" }, - { .compatible = "cirrus,cs40l27a" }, - { .compatible = "cirrus,cs40l27b" }, - { } -}; -MODULE_DEVICE_TABLE(of, cs40l26_of_match); - const struct regmap_config cs40l26_regmap = { .reg_bits = 32, .val_bits = 32, @@ -35,6 +26,7 @@ const struct regmap_config cs40l26_regmap = { .volatile_reg = cs40l26_volatile_reg, .cache_type = REGCACHE_NONE, }; +EXPORT_SYMBOL_GPL(cs40l26_regmap); const char * const cs40l26_dbc_names[CS40L26_DBC_NUM_CONTROLS] = { CS40L26_DBC_ENV_REL_COEF_NAME, @@ -51,13 +43,6 @@ const struct reg_sequence cs40l26_a1_errata[CS40L26_ERRATA_A1_NUM_WRITES] = { {CS40L26_TEST_LBST, CS40L26_DISABLE_EXPL_MODE}, }; -const struct dev_pm_ops cs40l26_pm_ops = { - SET_RUNTIME_PM_OPS(cs40l26_suspend, cs40l26_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(cs40l26_sys_suspend, cs40l26_sys_resume) - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cs40l26_sys_suspend_noirq, - cs40l26_sys_resume_noirq) -}; - const u8 cs40l26_pseq_op_sizes[CS40L26_PSEQ_NUM_OPS][2] = { { CS40L26_PSEQ_OP_WRITE_FULL, CS40L26_PSEQ_OP_WRITE_FULL_WORDS}, diff --git a/cs40l26/cs40l26.c b/cs40l26/cs40l26.c index 31c03a2..acdc371 100644 --- a/cs40l26/cs40l26.c +++ b/cs40l26/cs40l26.c @@ -705,11 +705,11 @@ static int cs40l26_handle_mbox_buffer(struct cs40l26_private *cs40l26) if ((val & CS40L26_DSP_MBOX_CMD_INDEX_MASK) == CS40L26_DSP_MBOX_WATERMARK) { dev_dbg(dev, "Mailbox: WATERMARK\n"); - +#ifdef CONFIG_DEBUG_FS ret = cl_dsp_logger_update(cs40l26->cl_dsp_db); if (ret) return ret; - +#endif continue; } @@ -2483,9 +2483,8 @@ static int cs40l26_owt_comp_data_size(struct cs40l26_private *cs40l26, return size; } -static int cs40l26_refactor_owt(struct cs40l26_private *cs40l26, s16 *in_data, - u32 in_data_nibbles, bool pwle, bool svc_waveform, - u8 **out_data) +static int cs40l26_refactor_owt_composite(struct cs40l26_private *cs40l26, s16 *in_data, + u32 in_data_nibbles, u8 **out_data) { u8 nsections, global_rep, out_nsections = 0; int ret = 0, pos_byte = 0, in_pos_nib = 2; @@ -2501,34 +2500,6 @@ static int cs40l26_refactor_owt(struct cs40l26_private *cs40l26, s16 *in_data, u32 ncw_bytes, wlen; int i; - if (pwle) { - out_data_bytes = CS40L26_WT_HEADER_PWLE_SIZE + in_data_bytes; - *out_data = kcalloc(out_data_bytes, sizeof(u8), GFP_KERNEL); - if (!*out_data) { - dev_err(dev, "No space for refactored data\n"); - return -ENOMEM; - } - - out_ch = cl_dsp_memchunk_create((void *) *out_data, - out_data_bytes); - cl_dsp_memchunk_write(&out_ch, 16, - CS40L26_WT_HEADER_DEFAULT_FLAGS | - (svc_waveform ? - CS40L26_OWT_SVC_METADATA : 0)); - cl_dsp_memchunk_write(&out_ch, 8, WT_TYPE_V6_PWLE); - cl_dsp_memchunk_write(&out_ch, 24, CS40L26_WT_HEADER_OFFSET + - (svc_waveform ? - CS40L26_WT_METADATA_OFFSET : 0)); - cl_dsp_memchunk_write(&out_ch, 24, (in_data_bytes / 4) - - (svc_waveform ? - CS40L26_WT_METADATA_OFFSET : 0)); - - - memcpy(*out_data + out_ch.bytes, in_data, in_data_bytes); - - return out_data_bytes; - } - ch = cl_dsp_memchunk_create((void *) in_data, in_data_bytes); /* Skip padding */ ret = cl_dsp_memchunk_read(cs40l26->dsp, &ch, 8, NULL); @@ -2687,8 +2658,10 @@ static int cs40l26_refactor_owt(struct cs40l26_private *cs40l26, s16 *in_data, ret = cs40l26_owt_calculate_wlength(cs40l26, out_nsections, global_rep, data, data_bytes, &wlen); - if (ret) + if (ret) { + kfree(out_data); goto data_err_free; + } cl_dsp_memchunk_write(&out_ch, 24, wlen); cl_dsp_memchunk_write(&out_ch, 8, 0x00); /* Pad */ @@ -2771,9 +2744,6 @@ static int cs40l26_custom_upload(struct cs40l26_private *cs40l26, struct ff_effect *effect, struct cs40l26_uploaded_effect *ueffect) { - s16 first = cs40l26->raw_custom_data[0]; - bool is_pwle = (first != CS40L26_WT_TYPE10_COMP_BUFFER); - bool is_svc = (first == CS40L26_SVC_ID); struct device *dev = cs40l26->dev; u32 nwaves, min_index, max_index, trigger_index; int ret, data_len, refactored_data_len; @@ -2783,16 +2753,25 @@ static int cs40l26_custom_upload(struct cs40l26_private *cs40l26, data_len = effect->u.periodic.custom_len; if (data_len > CS40L26_CUSTOM_DATA_SIZE) { - refactored_data_len = cs40l26_refactor_owt(cs40l26, - cs40l26->raw_custom_data, data_len, is_pwle, - is_svc, &refactored_data); - if (refactored_data_len <= 0) { - dev_err(cs40l26->dev, "Failed to refactor OWT\n"); - return -ENOMEM; + if (cs40l26->raw_custom_data[1] == CS40L26_WT_TYPE12_IDENTIFIER) { + refactored_data_len = cs40l26->raw_custom_data_len * 2; + refactored_data = kcalloc(refactored_data_len, sizeof(u8), GFP_KERNEL); + if (!refactored_data) { + dev_err(dev, "Failed to allocate space for PWLE\n"); + return -ENOMEM; + } + + memcpy(refactored_data, cs40l26->raw_custom_data, refactored_data_len); + } else { + refactored_data_len = cs40l26_refactor_owt_composite(cs40l26, + cs40l26->raw_custom_data, data_len, &refactored_data); + if (refactored_data_len <= 0) { + dev_err(dev, "Failed to refactor OWT\n"); + return -ENOMEM; + } } - ret = cs40l26_owt_upload(cs40l26, refactored_data, - refactored_data_len); + ret = cs40l26_owt_upload(cs40l26, refactored_data, refactored_data_len); kfree(refactored_data); if (ret) return ret; @@ -2800,7 +2779,7 @@ static int cs40l26_custom_upload(struct cs40l26_private *cs40l26, bank = (u16) CS40L26_OWT_BANK_ID; index = (u16) cs40l26->num_owt_effects; } else { - bank = (u16) first; + bank = (u16) cs40l26->raw_custom_data[0]; index = (u16) (cs40l26->raw_custom_data[1] & CS40L26_MAX_INDEX_MASK); } @@ -3249,9 +3228,14 @@ static int cs40l26_part_num_resolve(struct cs40l26_private *cs40l26) } val &= CS40L26_REVID_MASK; - if (val == CS40L26_REVID_A1 || val == CS40L26_REVID_B0) { + + switch (val) { + case CS40L26_REVID_A1: + case CS40L26_REVID_B0: + case CS40L26_REVID_B1: cs40l26->revid = val; - } else { + break; + default: dev_err(dev, "Invalid device revision: 0x%02X\n", val); return -EINVAL; } @@ -4220,6 +4204,10 @@ static char **cs40l26_get_tuning_names(struct cs40l26_private *cs40l26, CS40L26_SVC_TUNING_FILE_NAME, CS40L26_TUNING_FILE_NAME_MAX_LEN); } + if (cl_dsp_algo_is_present(cs40l26->dsp, CS40L26_LF0T_ALGO_ID)) + strscpy(coeff_files[file_count++], + CS40L26_LF0T_FILE_NAME, + CS40L26_TUNING_FILE_NAME_MAX_LEN); if (cl_dsp_algo_is_present(cs40l26->dsp, CS40L26_DVL_ALGO_ID)) strscpy(coeff_files[file_count++], @@ -4483,18 +4471,22 @@ int cs40l26_fw_swap(struct cs40l26_private *cs40l26, const u32 id) bool re_enable = false; int ret = 0; - if (cs40l26->revid != CS40L26_REVID_A1 && - cs40l26->revid != CS40L26_REVID_B0) { - dev_err(dev, "pseq unrecognized revid: %d\n", cs40l26->revid); - return -EINVAL; - } - if (cs40l26->fw_loaded) { disable_irq(cs40l26->irq); cs40l26_pm_runtime_teardown(cs40l26); re_enable = true; } + switch (cs40l26->revid) { + case CS40L26_REVID_A1: + case CS40L26_REVID_B0: + case CS40L26_REVID_B1: + break; + default: + dev_err(dev, "pseq unrecognized revid: %d\n", cs40l26->revid); + return -EINVAL; + } + /* reset pseq END_OF_SCRIPT to location from ROM */ ret = cs40l26_dsp_write(cs40l26, CS40L26_PSEQ_ROM_END_OF_SCRIPT, CS40L26_PSEQ_OP_END << CS40L26_PSEQ_OP_SHIFT); @@ -5155,6 +5147,13 @@ int cs40l26_sys_resume_noirq(struct device *dev) } EXPORT_SYMBOL(cs40l26_sys_resume_noirq); +const struct dev_pm_ops cs40l26_pm_ops = { + SET_RUNTIME_PM_OPS(cs40l26_suspend, cs40l26_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(cs40l26_sys_suspend, cs40l26_sys_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cs40l26_sys_suspend_noirq, cs40l26_sys_resume_noirq) +}; +EXPORT_SYMBOL_GPL(cs40l26_pm_ops); + MODULE_DESCRIPTION("CS40L26 Boosted Mono Class D Amplifier for Haptics"); MODULE_AUTHOR("Fred Treven, Cirrus Logic Inc. "); MODULE_LICENSE("GPL"); diff --git a/cs40l26/cs40l26.h b/cs40l26/cs40l26.h index 765bd28..05f0458 100644 --- a/cs40l26/cs40l26.h +++ b/cs40l26/cs40l26.h @@ -646,6 +646,7 @@ #define CS40L26_REVID_A1 0xA1 #define CS40L26_REVID_B0 0xB0 +#define CS40L26_REVID_B1 0xB1 #define CS40L26_REVID_MASK GENMASK(7, 0) #define CS40L26_GLOBAL_EN_MASK BIT(0) @@ -711,6 +712,7 @@ #define CS40L26_EVENT_LOGGER_ALGO_ID 0x0004F222 #define CS40L26_EXT_ALGO_ID 0x0004013C #define CS40L26_DVL_ALGO_ID 0x00040140 +#define CS40L26_LF0T_ALGO_ID 0x00040143 /* DebugFS */ #define CS40L26_ALGO_ID_MAX_STR_LEN 12 @@ -847,7 +849,7 @@ #define CS40L26_FW_FILE_NAME "cs40l26.wmfw" #define CS40L26_FW_CALIB_NAME "cs40l26-calib.wmfw" -#define CS40L26_MAX_TUNING_FILES 5 +#define CS40L26_MAX_TUNING_FILES 6 #define CS40L26_WT_FILE_NAME "cs40l26.bin" #define CS40L26_WT_FILE_PREFIX "cs40l26-wt" @@ -861,6 +863,7 @@ #define CS40L26_TUNING_FILE_SUFFIX_LEN 4 #define CS40L26_DVL_FILE_NAME "cs40l26-dvl.bin" #define CS40L26_CALIB_BIN_FILE_NAME "cs40l26-calib.bin" +#define CS40L26_LF0T_FILE_NAME "cs40l26-lf0t.bin" #define CS40L26_SVC_LE_EST_TIME_US 8000 #define CS40L26_SVC_LE_MAX_ATTEMPTS 2 @@ -1184,6 +1187,7 @@ #define CS40L26_A2H_MAX_TUNINGS 5 #define CS40L26_A2H_LEVEL_MAX 0x7FFFFF +#define CS40L26_A2H_LEVEL_MIN 0x000001 #define CS40L26_A2H_DELAY_MAX 0x190 @@ -1209,15 +1213,15 @@ #define CS40L26_WT_HEADER_DEFAULT_FLAGS 0x0000 #define CS40L26_WT_HEADER_PWLE_SIZE 12 #define CS40L26_WT_HEADER_COMP_SIZE 20 -#define CS40L26_OWT_SVC_METADATA BIT(10) -#define CS40L26_SVC_ID 0x100 +#define CS40L26_WT_SVC_METADATA BIT(10) +#define CS40L26_WT_TYPE12_IDENTIFIER 0xC00 #define CS40L26_WT_TYPE10_SECTION_BYTES_MIN 8 #define CS40L26_WT_TYPE10_SECTION_BYTES_MAX 12 #define CS40L26_WT_TYPE10_WAVELEN_MAX 0x3FFFFF #define CS40L26_WT_TYPE10_WAVELEN_INDEF 0x400000 #define CS40L26_WT_TYPE10_WAVELEN_CALCULATED 0x800000 -#define CS40L26_WT_TYPE10_COMP_DURATION_FLAG 0x8 +#define CS40L26_WT_TYPE10_COMP_DURATION_FLAG 0x80 #define CS40L26_WT_TYPE10_COMP_BUFFER 0x0000 /* F0 Offset represented as Q10.14 format */ @@ -1633,7 +1637,6 @@ int cs40l26_pseq_write(struct cs40l26_private *cs40l26, u32 addr, int cs40l26_copy_f0_est_to_dvl(struct cs40l26_private *cs40l26); /* external tables */ -extern const struct of_device_id cs40l26_of_match[CS40L26_NUM_DEVS + 1]; extern struct regulator_bulk_data cs40l26_supplies[CS40L26_NUM_SUPPLIES]; extern const struct dev_pm_ops cs40l26_pm_ops; -- cgit v1.2.3 From 3d8ac1914b489a5102843f4be80e97c0a6277c5c Mon Sep 17 00:00:00 2001 From: Tai Kuo Date: Thu, 11 May 2023 14:33:15 +0800 Subject: cs40l26: update modules in BUILD.bazel Bug: 278018625 Test: Kernel modules were built. Change-Id: Id699f6b47a3f0dee2630cc192ae33fc16c243f58 Signed-off-by: Tai Kuo --- cs40l26/BUILD.bazel | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cs40l26/BUILD.bazel b/cs40l26/BUILD.bazel index 87e63ba..436521d 100644 --- a/cs40l26/BUILD.bazel +++ b/cs40l26/BUILD.bazel @@ -11,8 +11,10 @@ load("//build/kleaf:kernel.bzl", "kernel_module") kernel_module( name = "cs40l26.cloudripper", outs = [ - "cl_dsp.ko", - "input-cs40l26-i2c.ko", + "cl_dsp-core.ko", + "cs40l26-core.ko", + "cs40l26-i2c.ko", + "snd-soc-cs40l26.ko", ], kernel_build = "//private/gs-google:cloudripper", visibility = [ -- cgit v1.2.3 From 7974378b26c1faf35bc3b1db1b5564883e96ad85 Mon Sep 17 00:00:00 2001 From: Tai Kuo Date: Thu, 11 May 2023 16:35:53 +0800 Subject: cs40l26: version tag: cs40l26 v7.0.0 and cl_dsp v4.0.1 Bug: 278018625 Test: Build pass. Change-Id: Ib5ab826bb3c308f10cd309aca376ca1f3e9e2934 Signed-off-by: Tai Kuo --- cs40l26/cl_dsp.c | 2 +- cs40l26/cs40l26.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cs40l26/cl_dsp.c b/cs40l26/cl_dsp.c index 9255d6b..c283c5a 100644 --- a/cs40l26/cl_dsp.c +++ b/cs40l26/cl_dsp.c @@ -1170,4 +1170,4 @@ EXPORT_SYMBOL(cl_dsp_destroy); MODULE_DESCRIPTION("Cirrus Logic DSP Firmware Driver"); MODULE_AUTHOR("Fred Treven, Cirrus Logic Inc, "); MODULE_LICENSE("GPL"); -MODULE_VERSION("3.2.0"); +MODULE_VERSION("4.0.1"); diff --git a/cs40l26/cs40l26.c b/cs40l26/cs40l26.c index acdc371..02ffdc3 100644 --- a/cs40l26/cs40l26.c +++ b/cs40l26/cs40l26.c @@ -5157,4 +5157,4 @@ EXPORT_SYMBOL_GPL(cs40l26_pm_ops); MODULE_DESCRIPTION("CS40L26 Boosted Mono Class D Amplifier for Haptics"); MODULE_AUTHOR("Fred Treven, Cirrus Logic Inc. "); MODULE_LICENSE("GPL"); -MODULE_VERSION("6.0.1"); +MODULE_VERSION("7.0.0"); -- cgit v1.2.3