summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-11 02:48:58 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-11 02:48:58 +0000
commit8858f2e61d8d1cd234483dc6f6062a308f7d180a (patch)
tree413512dc27a725e52d7433b76178954912aa113f
parentaa2e3aafe2135d42222fd24d6c8271d07e71b141 (diff)
parent7974378b26c1faf35bc3b1db1b5564883e96ad85 (diff)
downloadamplifiers-android-gs-tangorpro-5.10-u-beta5.tar.gz
Change-Id: I0c520437da173f5573f16341b562876bbaa3ef5b
-rw-r--r--cs40l26/BUILD.bazel6
-rw-r--r--cs40l26/Kconfig33
-rw-r--r--cs40l26/Makefile20
-rw-r--r--cs40l26/cl_dsp-debugfs.c20
-rw-r--r--cs40l26/cl_dsp.c2
-rw-r--r--cs40l26/cs40l26-codec.c26
-rw-r--r--cs40l26/cs40l26-debugfs.c5
-rw-r--r--cs40l26/cs40l26-i2c.c10
-rw-r--r--cs40l26/cs40l26-spi.c10
-rw-r--r--cs40l26/cs40l26-tables.c17
-rw-r--r--cs40l26/cs40l26.c109
-rw-r--r--cs40l26/cs40l26.h13
12 files changed, 142 insertions, 129 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 = [
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/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, <fred.treven@cirrus.com>");
MODULE_LICENSE("GPL");
-MODULE_VERSION("3.2.0");
+MODULE_VERSION("4.0.1");
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..02ffdc3 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,7 +5147,14 @@ 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. <fred.treven@cirrus.com>");
MODULE_LICENSE("GPL");
-MODULE_VERSION("6.0.1");
+MODULE_VERSION("7.0.0");
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;