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

Merge series "Cirrus Logic CS35L41 Amplifier" from David Rhodes <drhodes@opensource.cirrus.com>:

ASoC driver and devicetree documentation for a new
Cirrus Logic amplifier CS35L41

v7 changes:
Remove property 'classh-bst-max-limit'

David Rhodes (2):
ASoC: cs35l41: CS35L41 Boosted Smart Amplifier
ASoC: cs35l41: Add bindings for CS35L41

.../devicetree/bindings/sound/cs35l41.yaml | 151 ++
include/sound/cs35l41.h | 34 +
sound/soc/codecs/Kconfig | 12 +
sound/soc/codecs/Makefile | 4 +
sound/soc/codecs/cs35l41-i2c.c | 114 ++
sound/soc/codecs/cs35l41-spi.c | 143 ++
sound/soc/codecs/cs35l41-tables.c | 597 +++++++
sound/soc/codecs/cs35l41.c | 1545 +++++++++++++++++
sound/soc/codecs/cs35l41.h | 775 +++++++++
9 files changed, 3375 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/cs35l41.yaml
create mode 100644 include/sound/cs35l41.h
create mode 100644 sound/soc/codecs/cs35l41-i2c.c
create mode 100644 sound/soc/codecs/cs35l41-spi.c
create mode 100644 sound/soc/codecs/cs35l41-tables.c
create mode 100644 sound/soc/codecs/cs35l41.c
create mode 100644 sound/soc/codecs/cs35l41.h

--
2.25.1

+3375
+151
Documentation/devicetree/bindings/sound/cs35l41.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/cs35l41.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Cirrus Logic CS35L41 Speaker Amplifier 8 + 9 + maintainers: 10 + - david.rhodes@cirrus.com 11 + 12 + description: | 13 + CS35L41 is a boosted mono Class D amplifier with DSP 14 + speaker protection and equalization 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - cirrus,cs35l40 20 + - cirrus,cs35l41 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + '#sound-dai-cells': 26 + description: 27 + The first cell indicating the audio interface. 28 + const: 1 29 + 30 + reset-gpios: 31 + maxItems: 1 32 + 33 + VA-supply: 34 + description: voltage regulator phandle for the VA supply 35 + 36 + VP-supply: 37 + description: voltage regulator phandle for the VP supply 38 + 39 + cirrus,boost-peak-milliamp: 40 + description: 41 + Boost-converter peak current limit in mA. 42 + Configures the peak current by monitoring the current through the boost FET. 43 + Range starts at 1600 mA and goes to a maximum of 4500 mA with increments 44 + of 50 mA. See section 4.3.6 of the datasheet for details. 45 + $ref: "/schemas/types.yaml#/definitions/uint32" 46 + minimum: 1600 47 + maximum: 4500 48 + default: 4500 49 + 50 + cirrus,boost-ind-nanohenry: 51 + description: 52 + Boost inductor value, expressed in nH. Valid 53 + values include 1000, 1200, 1500 and 2200. 54 + $ref: "/schemas/types.yaml#/definitions/uint32" 55 + minimum: 1000 56 + maximum: 2200 57 + 58 + cirrus,boost-cap-microfarad: 59 + description: 60 + Total equivalent boost capacitance on the VBST 61 + and VAMP pins, derated at 11 volts DC. The value must be rounded to the 62 + nearest integer and expressed in uF. 63 + $ref: "/schemas/types.yaml#/definitions/uint32" 64 + 65 + cirrus,asp-sdout-hiz: 66 + description: 67 + Audio serial port SDOUT Hi-Z control. Sets the Hi-Z 68 + configuration for SDOUT pin of amplifier. 69 + 0 = Logic 0 during unused slots, and while all transmit channels disabled 70 + 1 = Hi-Z during unused slots but logic 0 while all transmit channels disabled 71 + 2 = (Default) Logic 0 during unused slots, but Hi-Z while all transmit channels disabled 72 + 3 = Hi-Z during unused slots and while all transmit channels disabled 73 + $ref: "/schemas/types.yaml#/definitions/uint32" 74 + minimum: 0 75 + maximum: 3 76 + default: 2 77 + 78 + cirrus,gpio1-polarity-invert: 79 + description: 80 + Boolean which specifies whether the GPIO1 81 + level is inverted. If this property is not present the level is not inverted. 82 + type: boolean 83 + 84 + cirrus,gpio1-output-enable: 85 + description: 86 + Boolean which specifies whether the GPIO1 pin 87 + is configured as an output. If this property is not present the 88 + pin will be configured as an input. 89 + type: boolean 90 + 91 + cirrus,gpio1-src-select: 92 + description: 93 + Configures the function of the GPIO1 pin. 94 + Note that the options are different from the GPIO2 pin 95 + 0 = High Impedance (Default) 96 + 1 = GPIO 97 + 2 = Sync 98 + 3 = MCLK input 99 + $ref: "/schemas/types.yaml#/definitions/uint32" 100 + minimum: 0 101 + maximum: 3 102 + 103 + cirrus,gpio2-polarity-invert: 104 + description: 105 + Boolean which specifies whether the GPIO2 106 + level is inverted. If this property is not present the level is not inverted. 107 + type: boolean 108 + 109 + cirrus,gpio2-output-enable: 110 + description: 111 + Boolean which specifies whether the GPIO2 pin 112 + is configured as an output. If this property is not present the 113 + pin will be configured as an input. 114 + type: boolean 115 + 116 + cirrus,gpio2-src-select: 117 + description: 118 + Configures the function of the GPIO2 pin. 119 + Note that the options are different from the GPIO1 pin. 120 + 0 = High Impedance (Default) 121 + 1 = GPIO 122 + 2 = Open Drain INTB 123 + 3 = MCLK input 124 + 4 = Push-pull INTB (active low) 125 + 5 = Push-pull INT (active high) 126 + $ref: "/schemas/types.yaml#/definitions/uint32" 127 + minimum: 0 128 + maximum: 5 129 + 130 + required: 131 + - compatible 132 + - reg 133 + - "#sound-dai-cells" 134 + - cirrus,boost-peak-milliamp 135 + - cirrus,boost-ind-nanohenry 136 + - cirrus,boost-cap-microfarad 137 + 138 + unevaluatedProperties: false 139 + 140 + examples: 141 + - | 142 + cs35l41: cs35l41@2 { 143 + compatible = "cirrus,cs35l41"; 144 + reg = <2>; 145 + VA-supply = <&dummy_vreg>; 146 + VP-supply = <&dummy_vreg>; 147 + reset-gpios = <&gpio 110 0>; 148 + cirrus,boost-peak-milliamp = <4500>; 149 + cirrus,boost-ind-nanohenry = <1000>; 150 + cirrus,boost-cap-microfarad = <15>; 151 + };
+34
include/sound/cs35l41.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * linux/sound/cs35l41.h -- Platform data for CS35L41 4 + * 5 + * Copyright (c) 2017-2021 Cirrus Logic Inc. 6 + * 7 + * Author: David Rhodes <david.rhodes@cirrus.com> 8 + */ 9 + 10 + #ifndef __CS35L41_H 11 + #define __CS35L41_H 12 + 13 + enum cs35l41_clk_ids { 14 + CS35L41_CLKID_SCLK = 0, 15 + CS35L41_CLKID_LRCLK = 1, 16 + CS35L41_CLKID_MCLK = 4, 17 + }; 18 + 19 + struct cs35l41_irq_cfg { 20 + bool irq_pol_inv; 21 + bool irq_out_en; 22 + int irq_src_sel; 23 + }; 24 + 25 + struct cs35l41_platform_data { 26 + int bst_ind; 27 + int bst_ipk; 28 + int bst_cap; 29 + int dout_hiz; 30 + struct cs35l41_irq_cfg irq_config1; 31 + struct cs35l41_irq_cfg irq_config2; 32 + }; 33 + 34 + #endif /* __CS35L41_H */
+12
sound/soc/codecs/Kconfig
··· 61 61 imply SND_SOC_CS35L34 62 62 imply SND_SOC_CS35L35 63 63 imply SND_SOC_CS35L36 64 + imply SND_SOC_CS35L41_SPI 65 + imply SND_SOC_CS35L41_I2C 64 66 imply SND_SOC_CS42L42 65 67 imply SND_SOC_CS42L51_I2C 66 68 imply SND_SOC_CS42L52 ··· 604 602 config SND_SOC_CS35L36 605 603 tristate "Cirrus Logic CS35L36 CODEC" 606 604 depends on I2C 605 + 606 + config SND_SOC_CS35L41_SPI 607 + tristate "Cirrus Logic CS35L41 CODEC (SPI)" 608 + depends on SPI_MASTER 609 + select REGMAP_SPI 610 + 611 + config SND_SOC_CS35L41_I2C 612 + tristate "Cirrus Logic CS35L41 CODEC (I2C)" 613 + depends on I2C 614 + select REGMAP_I2C 607 615 608 616 config SND_SOC_CS42L42 609 617 tristate "Cirrus Logic CS42L42 CODEC"
+4
sound/soc/codecs/Makefile
··· 54 54 snd-soc-cs35l34-objs := cs35l34.o 55 55 snd-soc-cs35l35-objs := cs35l35.o 56 56 snd-soc-cs35l36-objs := cs35l36.o 57 + snd-soc-cs35l41-spi-objs := cs35l41-spi.o cs35l41.o cs35l41-tables.o 58 + snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o cs35l41.o cs35l41-tables.o 57 59 snd-soc-cs42l42-objs := cs42l42.o 58 60 snd-soc-cs42l51-objs := cs42l51.o 59 61 snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o ··· 388 386 obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o 389 387 obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o 390 388 obj-$(CONFIG_SND_SOC_CS35L36) += snd-soc-cs35l36.o 389 + obj-$(CONFIG_SND_SOC_CS35L41_SPI) += snd-soc-cs35l41-spi.o 390 + obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o 391 391 obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o 392 392 obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 393 393 obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
+114
sound/soc/codecs/cs35l41-i2c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // cs35l41-i2c.c -- CS35l41 I2C driver 4 + // 5 + // Copyright 2017-2021 Cirrus Logic, Inc. 6 + // 7 + // Author: David Rhodes <david.rhodes@cirrus.com> 8 + 9 + #include <linux/acpi.h> 10 + #include <linux/delay.h> 11 + #include <linux/i2c.h> 12 + #include <linux/init.h> 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/moduleparam.h> 16 + #include <linux/of_device.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/slab.h> 19 + 20 + #include <sound/cs35l41.h> 21 + #include "cs35l41.h" 22 + 23 + static struct regmap_config cs35l41_regmap_i2c = { 24 + .reg_bits = 32, 25 + .val_bits = 32, 26 + .reg_stride = CS35L41_REGSTRIDE, 27 + .reg_format_endian = REGMAP_ENDIAN_BIG, 28 + .val_format_endian = REGMAP_ENDIAN_BIG, 29 + .max_register = CS35L41_LASTREG, 30 + .reg_defaults = cs35l41_reg, 31 + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), 32 + .volatile_reg = cs35l41_volatile_reg, 33 + .readable_reg = cs35l41_readable_reg, 34 + .precious_reg = cs35l41_precious_reg, 35 + .cache_type = REGCACHE_RBTREE, 36 + }; 37 + 38 + static const struct i2c_device_id cs35l41_id_i2c[] = { 39 + { "cs35l40", 0 }, 40 + { "cs35l41", 0 }, 41 + {} 42 + }; 43 + 44 + MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); 45 + 46 + static int cs35l41_i2c_probe(struct i2c_client *client, 47 + const struct i2c_device_id *id) 48 + { 49 + struct cs35l41_private *cs35l41; 50 + struct device *dev = &client->dev; 51 + struct cs35l41_platform_data *pdata = dev_get_platdata(dev); 52 + const struct regmap_config *regmap_config = &cs35l41_regmap_i2c; 53 + int ret; 54 + 55 + cs35l41 = devm_kzalloc(dev, sizeof(struct cs35l41_private), GFP_KERNEL); 56 + 57 + if (!cs35l41) 58 + return -ENOMEM; 59 + 60 + cs35l41->dev = dev; 61 + cs35l41->irq = client->irq; 62 + 63 + i2c_set_clientdata(client, cs35l41); 64 + cs35l41->regmap = devm_regmap_init_i2c(client, regmap_config); 65 + if (IS_ERR(cs35l41->regmap)) { 66 + ret = PTR_ERR(cs35l41->regmap); 67 + dev_err(cs35l41->dev, "Failed to allocate register map: %d\n", 68 + ret); 69 + return ret; 70 + } 71 + 72 + return cs35l41_probe(cs35l41, pdata); 73 + } 74 + 75 + static int cs35l41_i2c_remove(struct i2c_client *client) 76 + { 77 + struct cs35l41_private *cs35l41 = i2c_get_clientdata(client); 78 + 79 + return cs35l41_remove(cs35l41); 80 + } 81 + 82 + #ifdef CONFIG_OF 83 + static const struct of_device_id cs35l41_of_match[] = { 84 + { .compatible = "cirrus,cs35l40" }, 85 + { .compatible = "cirrus,cs35l41" }, 86 + {}, 87 + }; 88 + MODULE_DEVICE_TABLE(of, cs35l41_of_match); 89 + #endif 90 + 91 + #ifdef CONFIG_ACPI 92 + static const struct acpi_device_id cs35l41_acpi_match[] = { 93 + { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ 94 + {}, 95 + }; 96 + MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); 97 + #endif 98 + 99 + static struct i2c_driver cs35l41_i2c_driver = { 100 + .driver = { 101 + .name = "cs35l41", 102 + .of_match_table = of_match_ptr(cs35l41_of_match), 103 + .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), 104 + }, 105 + .id_table = cs35l41_id_i2c, 106 + .probe = cs35l41_i2c_probe, 107 + .remove = cs35l41_i2c_remove, 108 + }; 109 + 110 + module_i2c_driver(cs35l41_i2c_driver); 111 + 112 + MODULE_DESCRIPTION("I2C CS35L41 driver"); 113 + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); 114 + MODULE_LICENSE("GPL");
+143
sound/soc/codecs/cs35l41-spi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // cs35l41-spi.c -- CS35l41 SPI driver 4 + // 5 + // Copyright 2017-2021 Cirrus Logic, Inc. 6 + // 7 + // Author: David Rhodes <david.rhodes@cirrus.com> 8 + 9 + #include <linux/acpi.h> 10 + #include <linux/delay.h> 11 + #include <linux/init.h> 12 + #include <linux/kernel.h> 13 + #include <linux/module.h> 14 + #include <linux/moduleparam.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/spi/spi.h> 17 + 18 + #include <sound/cs35l41.h> 19 + #include "cs35l41.h" 20 + 21 + static struct regmap_config cs35l41_regmap_spi = { 22 + .reg_bits = 32, 23 + .val_bits = 32, 24 + .pad_bits = 16, 25 + .reg_stride = CS35L41_REGSTRIDE, 26 + .reg_format_endian = REGMAP_ENDIAN_BIG, 27 + .val_format_endian = REGMAP_ENDIAN_BIG, 28 + .max_register = CS35L41_LASTREG, 29 + .reg_defaults = cs35l41_reg, 30 + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), 31 + .volatile_reg = cs35l41_volatile_reg, 32 + .readable_reg = cs35l41_readable_reg, 33 + .precious_reg = cs35l41_precious_reg, 34 + .cache_type = REGCACHE_RBTREE, 35 + }; 36 + 37 + static const struct spi_device_id cs35l41_id_spi[] = { 38 + { "cs35l40", 0 }, 39 + { "cs35l41", 0 }, 40 + {} 41 + }; 42 + 43 + MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); 44 + 45 + static void cs35l41_spi_otp_setup(struct cs35l41_private *cs35l41, 46 + bool is_pre_setup, unsigned int *freq) 47 + { 48 + struct spi_device *spi; 49 + u32 orig_spi_freq; 50 + 51 + spi = to_spi_device(cs35l41->dev); 52 + 53 + if (!spi) { 54 + dev_err(cs35l41->dev, "%s: No SPI device\n", __func__); 55 + return; 56 + } 57 + 58 + if (is_pre_setup) { 59 + orig_spi_freq = spi->max_speed_hz; 60 + if (orig_spi_freq > CS35L41_SPI_MAX_FREQ_OTP) { 61 + spi->max_speed_hz = CS35L41_SPI_MAX_FREQ_OTP; 62 + spi_setup(spi); 63 + } 64 + *freq = orig_spi_freq; 65 + } else { 66 + if (spi->max_speed_hz != *freq) { 67 + spi->max_speed_hz = *freq; 68 + spi_setup(spi); 69 + } 70 + } 71 + } 72 + 73 + static int cs35l41_spi_probe(struct spi_device *spi) 74 + { 75 + const struct regmap_config *regmap_config = &cs35l41_regmap_spi; 76 + struct cs35l41_platform_data *pdata = 77 + dev_get_platdata(&spi->dev); 78 + struct cs35l41_private *cs35l41; 79 + int ret; 80 + 81 + cs35l41 = devm_kzalloc(&spi->dev, 82 + sizeof(struct cs35l41_private), 83 + GFP_KERNEL); 84 + if (!cs35l41) 85 + return -ENOMEM; 86 + 87 + 88 + spi_set_drvdata(spi, cs35l41); 89 + cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); 90 + if (IS_ERR(cs35l41->regmap)) { 91 + ret = PTR_ERR(cs35l41->regmap); 92 + dev_err(&spi->dev, "Failed to allocate register map: %d\n", 93 + ret); 94 + return ret; 95 + } 96 + 97 + cs35l41->dev = &spi->dev; 98 + cs35l41->irq = spi->irq; 99 + cs35l41->otp_setup = cs35l41_spi_otp_setup; 100 + 101 + return cs35l41_probe(cs35l41, pdata); 102 + } 103 + 104 + static int cs35l41_spi_remove(struct spi_device *spi) 105 + { 106 + struct cs35l41_private *cs35l41 = spi_get_drvdata(spi); 107 + 108 + return cs35l41_remove(cs35l41); 109 + } 110 + 111 + #ifdef CONFIG_OF 112 + static const struct of_device_id cs35l41_of_match[] = { 113 + { .compatible = "cirrus,cs35l40" }, 114 + { .compatible = "cirrus,cs35l41" }, 115 + {}, 116 + }; 117 + MODULE_DEVICE_TABLE(of, cs35l41_of_match); 118 + #endif 119 + 120 + #ifdef CONFIG_ACPI 121 + static const struct acpi_device_id cs35l41_acpi_match[] = { 122 + { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ 123 + {}, 124 + }; 125 + MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); 126 + #endif 127 + 128 + static struct spi_driver cs35l41_spi_driver = { 129 + .driver = { 130 + .name = "cs35l41", 131 + .of_match_table = of_match_ptr(cs35l41_of_match), 132 + .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), 133 + }, 134 + .id_table = cs35l41_id_spi, 135 + .probe = cs35l41_spi_probe, 136 + .remove = cs35l41_spi_remove, 137 + }; 138 + 139 + module_spi_driver(cs35l41_spi_driver); 140 + 141 + MODULE_DESCRIPTION("SPI CS35L41 driver"); 142 + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); 143 + MODULE_LICENSE("GPL");
+597
sound/soc/codecs/cs35l41-tables.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // cs35l41-tables.c -- CS35L41 ALSA SoC audio driver 4 + // 5 + // Copyright 2017-2021 Cirrus Logic, Inc. 6 + // 7 + // Author: David Rhodes <david.rhodes@cirrus.com> 8 + 9 + #include "cs35l41.h" 10 + 11 + const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG] = { 12 + {CS35L41_PWR_CTRL1, 0x00000000}, 13 + {CS35L41_PWR_CTRL3, 0x01000010}, 14 + {CS35L41_GPIO_PAD_CONTROL, 0x00000000}, 15 + {CS35L41_SP_ENABLES, 0x00000000}, 16 + {CS35L41_SP_RATE_CTRL, 0x00000028}, 17 + {CS35L41_SP_FORMAT, 0x18180200}, 18 + {CS35L41_SP_HIZ_CTRL, 0x00000002}, 19 + {CS35L41_SP_FRAME_TX_SLOT, 0x03020100}, 20 + {CS35L41_SP_FRAME_RX_SLOT, 0x00000100}, 21 + {CS35L41_SP_TX_WL, 0x00000018}, 22 + {CS35L41_SP_RX_WL, 0x00000018}, 23 + {CS35L41_DAC_PCM1_SRC, 0x00000008}, 24 + {CS35L41_ASP_TX1_SRC, 0x00000018}, 25 + {CS35L41_ASP_TX2_SRC, 0x00000019}, 26 + {CS35L41_ASP_TX3_SRC, 0x00000020}, 27 + {CS35L41_ASP_TX4_SRC, 0x00000021}, 28 + {CS35L41_DSP1_RX1_SRC, 0x00000008}, 29 + {CS35L41_DSP1_RX2_SRC, 0x00000009}, 30 + {CS35L41_DSP1_RX3_SRC, 0x00000018}, 31 + {CS35L41_DSP1_RX4_SRC, 0x00000019}, 32 + {CS35L41_DSP1_RX5_SRC, 0x00000020}, 33 + {CS35L41_DSP1_RX6_SRC, 0x00000021}, 34 + {CS35L41_DSP1_RX7_SRC, 0x0000003A}, 35 + {CS35L41_DSP1_RX8_SRC, 0x00000001}, 36 + {CS35L41_NGATE1_SRC, 0x00000008}, 37 + {CS35L41_NGATE2_SRC, 0x00000009}, 38 + {CS35L41_AMP_DIG_VOL_CTRL, 0x00008000}, 39 + {CS35L41_CLASSH_CFG, 0x000B0405}, 40 + {CS35L41_WKFET_CFG, 0x00000111}, 41 + {CS35L41_NG_CFG, 0x00000033}, 42 + {CS35L41_AMP_GAIN_CTRL, 0x00000273}, 43 + {CS35L41_GPIO1_CTRL1, 0xE1000001}, 44 + {CS35L41_GPIO2_CTRL1, 0xE1000001}, 45 + {CS35L41_MIXER_NGATE_CFG, 0x00000000}, 46 + {CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303}, 47 + {CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303}, 48 + }; 49 + 50 + bool cs35l41_readable_reg(struct device *dev, unsigned int reg) 51 + { 52 + switch (reg) { 53 + case CS35L41_DEVID: 54 + case CS35L41_REVID: 55 + case CS35L41_FABID: 56 + case CS35L41_RELID: 57 + case CS35L41_OTPID: 58 + case CS35L41_TEST_KEY_CTL: 59 + case CS35L41_USER_KEY_CTL: 60 + case CS35L41_OTP_CTRL0: 61 + case CS35L41_OTP_CTRL3: 62 + case CS35L41_OTP_CTRL4: 63 + case CS35L41_OTP_CTRL5: 64 + case CS35L41_OTP_CTRL6: 65 + case CS35L41_OTP_CTRL7: 66 + case CS35L41_OTP_CTRL8: 67 + case CS35L41_PWR_CTRL1: 68 + case CS35L41_PWR_CTRL2: 69 + case CS35L41_PWR_CTRL3: 70 + case CS35L41_CTRL_OVRRIDE: 71 + case CS35L41_AMP_OUT_MUTE: 72 + case CS35L41_PROTECT_REL_ERR_IGN: 73 + case CS35L41_GPIO_PAD_CONTROL: 74 + case CS35L41_JTAG_CONTROL: 75 + case CS35L41_PLL_CLK_CTRL: 76 + case CS35L41_DSP_CLK_CTRL: 77 + case CS35L41_GLOBAL_CLK_CTRL: 78 + case CS35L41_DATA_FS_SEL: 79 + case CS35L41_MDSYNC_EN: 80 + case CS35L41_MDSYNC_TX_ID: 81 + case CS35L41_MDSYNC_PWR_CTRL: 82 + case CS35L41_MDSYNC_DATA_TX: 83 + case CS35L41_MDSYNC_TX_STATUS: 84 + case CS35L41_MDSYNC_DATA_RX: 85 + case CS35L41_MDSYNC_RX_STATUS: 86 + case CS35L41_MDSYNC_ERR_STATUS: 87 + case CS35L41_MDSYNC_SYNC_PTE2: 88 + case CS35L41_MDSYNC_SYNC_PTE3: 89 + case CS35L41_MDSYNC_SYNC_MSM_STATUS: 90 + case CS35L41_BSTCVRT_VCTRL1: 91 + case CS35L41_BSTCVRT_VCTRL2: 92 + case CS35L41_BSTCVRT_PEAK_CUR: 93 + case CS35L41_BSTCVRT_SFT_RAMP: 94 + case CS35L41_BSTCVRT_COEFF: 95 + case CS35L41_BSTCVRT_SLOPE_LBST: 96 + case CS35L41_BSTCVRT_SW_FREQ: 97 + case CS35L41_BSTCVRT_DCM_CTRL: 98 + case CS35L41_BSTCVRT_DCM_MODE_FORCE: 99 + case CS35L41_BSTCVRT_OVERVOLT_CTRL: 100 + case CS35L41_VI_VOL_POL: 101 + case CS35L41_DTEMP_WARN_THLD: 102 + case CS35L41_DTEMP_CFG: 103 + case CS35L41_DTEMP_EN: 104 + case CS35L41_VPVBST_FS_SEL: 105 + case CS35L41_SP_ENABLES: 106 + case CS35L41_SP_RATE_CTRL: 107 + case CS35L41_SP_FORMAT: 108 + case CS35L41_SP_HIZ_CTRL: 109 + case CS35L41_SP_FRAME_TX_SLOT: 110 + case CS35L41_SP_FRAME_RX_SLOT: 111 + case CS35L41_SP_TX_WL: 112 + case CS35L41_SP_RX_WL: 113 + case CS35L41_DAC_PCM1_SRC: 114 + case CS35L41_ASP_TX1_SRC: 115 + case CS35L41_ASP_TX2_SRC: 116 + case CS35L41_ASP_TX3_SRC: 117 + case CS35L41_ASP_TX4_SRC: 118 + case CS35L41_DSP1_RX1_SRC: 119 + case CS35L41_DSP1_RX2_SRC: 120 + case CS35L41_DSP1_RX3_SRC: 121 + case CS35L41_DSP1_RX4_SRC: 122 + case CS35L41_DSP1_RX5_SRC: 123 + case CS35L41_DSP1_RX6_SRC: 124 + case CS35L41_DSP1_RX7_SRC: 125 + case CS35L41_DSP1_RX8_SRC: 126 + case CS35L41_NGATE1_SRC: 127 + case CS35L41_NGATE2_SRC: 128 + case CS35L41_AMP_DIG_VOL_CTRL: 129 + case CS35L41_VPBR_CFG: 130 + case CS35L41_VBBR_CFG: 131 + case CS35L41_VPBR_STATUS: 132 + case CS35L41_VBBR_STATUS: 133 + case CS35L41_OVERTEMP_CFG: 134 + case CS35L41_AMP_ERR_VOL: 135 + case CS35L41_VOL_STATUS_TO_DSP: 136 + case CS35L41_CLASSH_CFG: 137 + case CS35L41_WKFET_CFG: 138 + case CS35L41_NG_CFG: 139 + case CS35L41_AMP_GAIN_CTRL: 140 + case CS35L41_DAC_MSM_CFG: 141 + case CS35L41_IRQ1_CFG: 142 + case CS35L41_IRQ1_STATUS: 143 + case CS35L41_IRQ1_STATUS1: 144 + case CS35L41_IRQ1_STATUS2: 145 + case CS35L41_IRQ1_STATUS3: 146 + case CS35L41_IRQ1_STATUS4: 147 + case CS35L41_IRQ1_RAW_STATUS1: 148 + case CS35L41_IRQ1_RAW_STATUS2: 149 + case CS35L41_IRQ1_RAW_STATUS3: 150 + case CS35L41_IRQ1_RAW_STATUS4: 151 + case CS35L41_IRQ1_MASK1: 152 + case CS35L41_IRQ1_MASK2: 153 + case CS35L41_IRQ1_MASK3: 154 + case CS35L41_IRQ1_MASK4: 155 + case CS35L41_IRQ1_FRC1: 156 + case CS35L41_IRQ1_FRC2: 157 + case CS35L41_IRQ1_FRC3: 158 + case CS35L41_IRQ1_FRC4: 159 + case CS35L41_IRQ1_EDGE1: 160 + case CS35L41_IRQ1_EDGE4: 161 + case CS35L41_IRQ1_POL1: 162 + case CS35L41_IRQ1_POL2: 163 + case CS35L41_IRQ1_POL3: 164 + case CS35L41_IRQ1_POL4: 165 + case CS35L41_IRQ1_DB3: 166 + case CS35L41_IRQ2_CFG: 167 + case CS35L41_IRQ2_STATUS: 168 + case CS35L41_IRQ2_STATUS1: 169 + case CS35L41_IRQ2_STATUS2: 170 + case CS35L41_IRQ2_STATUS3: 171 + case CS35L41_IRQ2_STATUS4: 172 + case CS35L41_IRQ2_RAW_STATUS1: 173 + case CS35L41_IRQ2_RAW_STATUS2: 174 + case CS35L41_IRQ2_RAW_STATUS3: 175 + case CS35L41_IRQ2_RAW_STATUS4: 176 + case CS35L41_IRQ2_MASK1: 177 + case CS35L41_IRQ2_MASK2: 178 + case CS35L41_IRQ2_MASK3: 179 + case CS35L41_IRQ2_MASK4: 180 + case CS35L41_IRQ2_FRC1: 181 + case CS35L41_IRQ2_FRC2: 182 + case CS35L41_IRQ2_FRC3: 183 + case CS35L41_IRQ2_FRC4: 184 + case CS35L41_IRQ2_EDGE1: 185 + case CS35L41_IRQ2_EDGE4: 186 + case CS35L41_IRQ2_POL1: 187 + case CS35L41_IRQ2_POL2: 188 + case CS35L41_IRQ2_POL3: 189 + case CS35L41_IRQ2_POL4: 190 + case CS35L41_IRQ2_DB3: 191 + case CS35L41_GPIO_STATUS1: 192 + case CS35L41_GPIO1_CTRL1: 193 + case CS35L41_GPIO2_CTRL1: 194 + case CS35L41_MIXER_NGATE_CFG: 195 + case CS35L41_MIXER_NGATE_CH1_CFG: 196 + case CS35L41_MIXER_NGATE_CH2_CFG: 197 + case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: 198 + case CS35L41_CLOCK_DETECT_1: 199 + case CS35L41_DIE_STS1: 200 + case CS35L41_DIE_STS2: 201 + case CS35L41_TEMP_CAL1: 202 + case CS35L41_TEMP_CAL2: 203 + case CS35L41_OTP_TRIM_1: 204 + case CS35L41_OTP_TRIM_2: 205 + case CS35L41_OTP_TRIM_3: 206 + case CS35L41_OTP_TRIM_4: 207 + case CS35L41_OTP_TRIM_5: 208 + case CS35L41_OTP_TRIM_6: 209 + case CS35L41_OTP_TRIM_7: 210 + case CS35L41_OTP_TRIM_8: 211 + case CS35L41_OTP_TRIM_9: 212 + case CS35L41_OTP_TRIM_10: 213 + case CS35L41_OTP_TRIM_11: 214 + case CS35L41_OTP_TRIM_12: 215 + case CS35L41_OTP_TRIM_13: 216 + case CS35L41_OTP_TRIM_14: 217 + case CS35L41_OTP_TRIM_15: 218 + case CS35L41_OTP_TRIM_16: 219 + case CS35L41_OTP_TRIM_17: 220 + case CS35L41_OTP_TRIM_18: 221 + case CS35L41_OTP_TRIM_19: 222 + case CS35L41_OTP_TRIM_20: 223 + case CS35L41_OTP_TRIM_21: 224 + case CS35L41_OTP_TRIM_22: 225 + case CS35L41_OTP_TRIM_23: 226 + case CS35L41_OTP_TRIM_24: 227 + case CS35L41_OTP_TRIM_25: 228 + case CS35L41_OTP_TRIM_26: 229 + case CS35L41_OTP_TRIM_27: 230 + case CS35L41_OTP_TRIM_28: 231 + case CS35L41_OTP_TRIM_29: 232 + case CS35L41_OTP_TRIM_30: 233 + case CS35L41_OTP_TRIM_31: 234 + case CS35L41_OTP_TRIM_32: 235 + case CS35L41_OTP_TRIM_33: 236 + case CS35L41_OTP_TRIM_34: 237 + case CS35L41_OTP_TRIM_35: 238 + case CS35L41_OTP_TRIM_36: 239 + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: 240 + /*test regs*/ 241 + case CS35L41_PLL_OVR: 242 + case CS35L41_BST_TEST_DUTY: 243 + case CS35L41_DIGPWM_IOCTRL: 244 + return true; 245 + default: 246 + return false; 247 + } 248 + } 249 + 250 + bool cs35l41_precious_reg(struct device *dev, unsigned int reg) 251 + { 252 + switch (reg) { 253 + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: 254 + return true; 255 + default: 256 + return false; 257 + } 258 + } 259 + 260 + bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) 261 + { 262 + switch (reg) { 263 + case CS35L41_DEVID: 264 + case CS35L41_SFT_RESET: 265 + case CS35L41_FABID: 266 + case CS35L41_REVID: 267 + case CS35L41_DTEMP_EN: 268 + case CS35L41_IRQ1_STATUS: 269 + case CS35L41_IRQ1_STATUS1: 270 + case CS35L41_IRQ1_STATUS2: 271 + case CS35L41_IRQ1_STATUS3: 272 + case CS35L41_IRQ1_STATUS4: 273 + case CS35L41_IRQ1_RAW_STATUS1: 274 + case CS35L41_IRQ1_RAW_STATUS2: 275 + case CS35L41_IRQ1_RAW_STATUS3: 276 + case CS35L41_IRQ1_RAW_STATUS4: 277 + case CS35L41_IRQ1_FRC1: 278 + case CS35L41_IRQ1_FRC2: 279 + case CS35L41_IRQ1_FRC3: 280 + case CS35L41_IRQ1_FRC4: 281 + case CS35L41_IRQ1_EDGE1: 282 + case CS35L41_IRQ1_EDGE4: 283 + case CS35L41_IRQ1_POL1: 284 + case CS35L41_IRQ1_POL2: 285 + case CS35L41_IRQ1_POL3: 286 + case CS35L41_IRQ1_POL4: 287 + case CS35L41_IRQ1_DB3: 288 + case CS35L41_IRQ2_STATUS: 289 + case CS35L41_IRQ2_STATUS1: 290 + case CS35L41_IRQ2_STATUS2: 291 + case CS35L41_IRQ2_STATUS3: 292 + case CS35L41_IRQ2_STATUS4: 293 + case CS35L41_IRQ2_RAW_STATUS1: 294 + case CS35L41_IRQ2_RAW_STATUS2: 295 + case CS35L41_IRQ2_RAW_STATUS3: 296 + case CS35L41_IRQ2_RAW_STATUS4: 297 + case CS35L41_IRQ2_FRC1: 298 + case CS35L41_IRQ2_FRC2: 299 + case CS35L41_IRQ2_FRC3: 300 + case CS35L41_IRQ2_FRC4: 301 + case CS35L41_IRQ2_EDGE1: 302 + case CS35L41_IRQ2_EDGE4: 303 + case CS35L41_IRQ2_POL1: 304 + case CS35L41_IRQ2_POL2: 305 + case CS35L41_IRQ2_POL3: 306 + case CS35L41_IRQ2_POL4: 307 + case CS35L41_IRQ2_DB3: 308 + case CS35L41_GPIO_STATUS1: 309 + case CS35L41_OTP_TRIM_1: 310 + case CS35L41_OTP_TRIM_2: 311 + case CS35L41_OTP_TRIM_3: 312 + case CS35L41_OTP_TRIM_4: 313 + case CS35L41_OTP_TRIM_5: 314 + case CS35L41_OTP_TRIM_6: 315 + case CS35L41_OTP_TRIM_7: 316 + case CS35L41_OTP_TRIM_8: 317 + case CS35L41_OTP_TRIM_9: 318 + case CS35L41_OTP_TRIM_10: 319 + case CS35L41_OTP_TRIM_11: 320 + case CS35L41_OTP_TRIM_12: 321 + case CS35L41_OTP_TRIM_13: 322 + case CS35L41_OTP_TRIM_14: 323 + case CS35L41_OTP_TRIM_15: 324 + case CS35L41_OTP_TRIM_16: 325 + case CS35L41_OTP_TRIM_17: 326 + case CS35L41_OTP_TRIM_18: 327 + case CS35L41_OTP_TRIM_19: 328 + case CS35L41_OTP_TRIM_20: 329 + case CS35L41_OTP_TRIM_21: 330 + case CS35L41_OTP_TRIM_22: 331 + case CS35L41_OTP_TRIM_23: 332 + case CS35L41_OTP_TRIM_24: 333 + case CS35L41_OTP_TRIM_25: 334 + case CS35L41_OTP_TRIM_26: 335 + case CS35L41_OTP_TRIM_27: 336 + case CS35L41_OTP_TRIM_28: 337 + case CS35L41_OTP_TRIM_29: 338 + case CS35L41_OTP_TRIM_30: 339 + case CS35L41_OTP_TRIM_31: 340 + case CS35L41_OTP_TRIM_32: 341 + case CS35L41_OTP_TRIM_33: 342 + case CS35L41_OTP_TRIM_34: 343 + case CS35L41_OTP_TRIM_35: 344 + case CS35L41_OTP_TRIM_36: 345 + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: 346 + return true; 347 + default: 348 + return false; 349 + } 350 + } 351 + 352 + static const struct cs35l41_otp_packed_element_t 353 + otp_map_1[CS35L41_NUM_OTP_ELEM] = { 354 + /* addr shift size */ 355 + {0x00002030, 0, 4}, /*TRIM_OSC_FREQ_TRIM*/ 356 + {0x00002030, 7, 1}, /*TRIM_OSC_TRIM_DONE*/ 357 + {0x0000208c, 24, 6}, /*TST_DIGREG_VREF_TRIM*/ 358 + {0x00002090, 14, 4}, /*TST_REF_TRIM*/ 359 + {0x00002090, 10, 4}, /*TST_REF_TEMPCO_TRIM*/ 360 + {0x0000300C, 11, 4}, /*PLL_LDOA_TST_VREF_TRIM*/ 361 + {0x0000394C, 23, 2}, /*BST_ATEST_CM_VOFF*/ 362 + {0x00003950, 0, 7}, /*BST_ATRIM_IADC_OFFSET*/ 363 + {0x00003950, 8, 7}, /*BST_ATRIM_IADC_GAIN1*/ 364 + {0x00003950, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET1*/ 365 + {0x00003950, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN1*/ 366 + {0x00003954, 0, 7}, /*BST_ATRIM_IADC_OFFSET2*/ 367 + {0x00003954, 8, 7}, /*BST_ATRIM_IADC_GAIN2*/ 368 + {0x00003954, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET2*/ 369 + {0x00003954, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN2*/ 370 + {0x00003958, 0, 7}, /*BST_ATRIM_IADC_OFFSET3*/ 371 + {0x00003958, 8, 7}, /*BST_ATRIM_IADC_GAIN3*/ 372 + {0x00003958, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET3*/ 373 + {0x00003958, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN3*/ 374 + {0x0000395C, 0, 7}, /*BST_ATRIM_IADC_OFFSET4*/ 375 + {0x0000395C, 8, 7}, /*BST_ATRIM_IADC_GAIN4*/ 376 + {0x0000395C, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET4*/ 377 + {0x0000395C, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN4*/ 378 + {0x0000416C, 0, 8}, /*VMON_GAIN_OTP_VAL*/ 379 + {0x00004160, 0, 7}, /*VMON_OFFSET_OTP_VAL*/ 380 + {0x0000416C, 8, 8}, /*IMON_GAIN_OTP_VAL*/ 381 + {0x00004160, 16, 10}, /*IMON_OFFSET_OTP_VAL*/ 382 + {0x0000416C, 16, 12}, /*VMON_CM_GAIN_OTP_VAL*/ 383 + {0x0000416C, 28, 1}, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ 384 + {0x00004170, 0, 6}, /*IMON_CAL_TEMPCO_OTP_VAL*/ 385 + {0x00004170, 6, 1}, /*IMON_CAL_TEMPCO_SIGN_OTP*/ 386 + {0x00004170, 8, 6}, /*IMON_CAL_TEMPCO2_OTP_VAL*/ 387 + {0x00004170, 14, 1}, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ 388 + {0x00004170, 16, 9}, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ 389 + {0x00004360, 0, 5}, /*TEMP_GAIN_OTP_VAL*/ 390 + {0x00004360, 6, 9}, /*TEMP_OFFSET_OTP_VAL*/ 391 + {0x00004448, 0, 8}, /*VP_SARADC_OFFSET*/ 392 + {0x00004448, 8, 8}, /*VP_GAIN_INDEX*/ 393 + {0x00004448, 16, 8}, /*VBST_SARADC_OFFSET*/ 394 + {0x00004448, 24, 8}, /*VBST_GAIN_INDEX*/ 395 + {0x0000444C, 0, 3}, /*ANA_SELINVREF*/ 396 + {0x00006E30, 0, 5}, /*GAIN_ERR_COEFF_0*/ 397 + {0x00006E30, 8, 5}, /*GAIN_ERR_COEFF_1*/ 398 + {0x00006E30, 16, 5}, /*GAIN_ERR_COEFF_2*/ 399 + {0x00006E30, 24, 5}, /*GAIN_ERR_COEFF_3*/ 400 + {0x00006E34, 0, 5}, /*GAIN_ERR_COEFF_4*/ 401 + {0x00006E34, 8, 5}, /*GAIN_ERR_COEFF_5*/ 402 + {0x00006E34, 16, 5}, /*GAIN_ERR_COEFF_6*/ 403 + {0x00006E34, 24, 5}, /*GAIN_ERR_COEFF_7*/ 404 + {0x00006E38, 0, 5}, /*GAIN_ERR_COEFF_8*/ 405 + {0x00006E38, 8, 5}, /*GAIN_ERR_COEFF_9*/ 406 + {0x00006E38, 16, 5}, /*GAIN_ERR_COEFF_10*/ 407 + {0x00006E38, 24, 5}, /*GAIN_ERR_COEFF_11*/ 408 + {0x00006E3C, 0, 5}, /*GAIN_ERR_COEFF_12*/ 409 + {0x00006E3C, 8, 5}, /*GAIN_ERR_COEFF_13*/ 410 + {0x00006E3C, 16, 5}, /*GAIN_ERR_COEFF_14*/ 411 + {0x00006E3C, 24, 5}, /*GAIN_ERR_COEFF_15*/ 412 + {0x00006E40, 0, 5}, /*GAIN_ERR_COEFF_16*/ 413 + {0x00006E40, 8, 5}, /*GAIN_ERR_COEFF_17*/ 414 + {0x00006E40, 16, 5}, /*GAIN_ERR_COEFF_18*/ 415 + {0x00006E40, 24, 5}, /*GAIN_ERR_COEFF_19*/ 416 + {0x00006E44, 0, 5}, /*GAIN_ERR_COEFF_20*/ 417 + {0x00006E48, 0, 10}, /*VOFF_GAIN_0*/ 418 + {0x00006E48, 10, 10}, /*VOFF_GAIN_1*/ 419 + {0x00006E48, 20, 10}, /*VOFF_GAIN_2*/ 420 + {0x00006E4C, 0, 10}, /*VOFF_GAIN_3*/ 421 + {0x00006E4C, 10, 10}, /*VOFF_GAIN_4*/ 422 + {0x00006E4C, 20, 10}, /*VOFF_GAIN_5*/ 423 + {0x00006E50, 0, 10}, /*VOFF_GAIN_6*/ 424 + {0x00006E50, 10, 10}, /*VOFF_GAIN_7*/ 425 + {0x00006E50, 20, 10}, /*VOFF_GAIN_8*/ 426 + {0x00006E54, 0, 10}, /*VOFF_GAIN_9*/ 427 + {0x00006E54, 10, 10}, /*VOFF_GAIN_10*/ 428 + {0x00006E54, 20, 10}, /*VOFF_GAIN_11*/ 429 + {0x00006E58, 0, 10}, /*VOFF_GAIN_12*/ 430 + {0x00006E58, 10, 10}, /*VOFF_GAIN_13*/ 431 + {0x00006E58, 20, 10}, /*VOFF_GAIN_14*/ 432 + {0x00006E5C, 0, 10}, /*VOFF_GAIN_15*/ 433 + {0x00006E5C, 10, 10}, /*VOFF_GAIN_16*/ 434 + {0x00006E5C, 20, 10}, /*VOFF_GAIN_17*/ 435 + {0x00006E60, 0, 10}, /*VOFF_GAIN_18*/ 436 + {0x00006E60, 10, 10}, /*VOFF_GAIN_19*/ 437 + {0x00006E60, 20, 10}, /*VOFF_GAIN_20*/ 438 + {0x00006E64, 0, 10}, /*VOFF_INT1*/ 439 + {0x00007418, 7, 5}, /*DS_SPK_INT1_CAP_TRIM*/ 440 + {0x0000741C, 0, 5}, /*DS_SPK_INT2_CAP_TRIM*/ 441 + {0x0000741C, 11, 4}, /*DS_SPK_LPF_CAP_TRIM*/ 442 + {0x0000741C, 19, 4}, /*DS_SPK_QUAN_CAP_TRIM*/ 443 + {0x00007434, 17, 1}, /*FORCE_CAL*/ 444 + {0x00007434, 18, 7}, /*CAL_OVERRIDE*/ 445 + {0x00007068, 0, 9}, /*MODIX*/ 446 + {0x0000410C, 7, 1}, /*VIMON_DLY_NOT_COMB*/ 447 + {0x0000400C, 0, 7}, /*VIMON_DLY*/ 448 + {0x00000000, 0, 1}, /*extra bit*/ 449 + {0x00017040, 0, 8}, /*X_COORDINATE*/ 450 + {0x00017040, 8, 8}, /*Y_COORDINATE*/ 451 + {0x00017040, 16, 8}, /*WAFER_ID*/ 452 + {0x00017040, 24, 8}, /*DVS*/ 453 + {0x00017044, 0, 24}, /*LOT_NUMBER*/ 454 + }; 455 + 456 + static const struct cs35l41_otp_packed_element_t 457 + otp_map_2[CS35L41_NUM_OTP_ELEM] = { 458 + /* addr shift size */ 459 + {0x00002030, 0, 4}, /*TRIM_OSC_FREQ_TRIM*/ 460 + {0x00002030, 7, 1}, /*TRIM_OSC_TRIM_DONE*/ 461 + {0x0000208c, 24, 6}, /*TST_DIGREG_VREF_TRIM*/ 462 + {0x00002090, 14, 4}, /*TST_REF_TRIM*/ 463 + {0x00002090, 10, 4}, /*TST_REF_TEMPCO_TRIM*/ 464 + {0x0000300C, 11, 4}, /*PLL_LDOA_TST_VREF_TRIM*/ 465 + {0x0000394C, 23, 2}, /*BST_ATEST_CM_VOFF*/ 466 + {0x00003950, 0, 7}, /*BST_ATRIM_IADC_OFFSET*/ 467 + {0x00003950, 8, 7}, /*BST_ATRIM_IADC_GAIN1*/ 468 + {0x00003950, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET1*/ 469 + {0x00003950, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN1*/ 470 + {0x00003954, 0, 7}, /*BST_ATRIM_IADC_OFFSET2*/ 471 + {0x00003954, 8, 7}, /*BST_ATRIM_IADC_GAIN2*/ 472 + {0x00003954, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET2*/ 473 + {0x00003954, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN2*/ 474 + {0x00003958, 0, 7}, /*BST_ATRIM_IADC_OFFSET3*/ 475 + {0x00003958, 8, 7}, /*BST_ATRIM_IADC_GAIN3*/ 476 + {0x00003958, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET3*/ 477 + {0x00003958, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN3*/ 478 + {0x0000395C, 0, 7}, /*BST_ATRIM_IADC_OFFSET4*/ 479 + {0x0000395C, 8, 7}, /*BST_ATRIM_IADC_GAIN4*/ 480 + {0x0000395C, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET4*/ 481 + {0x0000395C, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN4*/ 482 + {0x0000416C, 0, 8}, /*VMON_GAIN_OTP_VAL*/ 483 + {0x00004160, 0, 7}, /*VMON_OFFSET_OTP_VAL*/ 484 + {0x0000416C, 8, 8}, /*IMON_GAIN_OTP_VAL*/ 485 + {0x00004160, 16, 10}, /*IMON_OFFSET_OTP_VAL*/ 486 + {0x0000416C, 16, 12}, /*VMON_CM_GAIN_OTP_VAL*/ 487 + {0x0000416C, 28, 1}, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ 488 + {0x00004170, 0, 6}, /*IMON_CAL_TEMPCO_OTP_VAL*/ 489 + {0x00004170, 6, 1}, /*IMON_CAL_TEMPCO_SIGN_OTP*/ 490 + {0x00004170, 8, 6}, /*IMON_CAL_TEMPCO2_OTP_VAL*/ 491 + {0x00004170, 14, 1}, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ 492 + {0x00004170, 16, 9}, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ 493 + {0x00004360, 0, 5}, /*TEMP_GAIN_OTP_VAL*/ 494 + {0x00004360, 6, 9}, /*TEMP_OFFSET_OTP_VAL*/ 495 + {0x00004448, 0, 8}, /*VP_SARADC_OFFSET*/ 496 + {0x00004448, 8, 8}, /*VP_GAIN_INDEX*/ 497 + {0x00004448, 16, 8}, /*VBST_SARADC_OFFSET*/ 498 + {0x00004448, 24, 8}, /*VBST_GAIN_INDEX*/ 499 + {0x0000444C, 0, 3}, /*ANA_SELINVREF*/ 500 + {0x00006E30, 0, 5}, /*GAIN_ERR_COEFF_0*/ 501 + {0x00006E30, 8, 5}, /*GAIN_ERR_COEFF_1*/ 502 + {0x00006E30, 16, 5}, /*GAIN_ERR_COEFF_2*/ 503 + {0x00006E30, 24, 5}, /*GAIN_ERR_COEFF_3*/ 504 + {0x00006E34, 0, 5}, /*GAIN_ERR_COEFF_4*/ 505 + {0x00006E34, 8, 5}, /*GAIN_ERR_COEFF_5*/ 506 + {0x00006E34, 16, 5}, /*GAIN_ERR_COEFF_6*/ 507 + {0x00006E34, 24, 5}, /*GAIN_ERR_COEFF_7*/ 508 + {0x00006E38, 0, 5}, /*GAIN_ERR_COEFF_8*/ 509 + {0x00006E38, 8, 5}, /*GAIN_ERR_COEFF_9*/ 510 + {0x00006E38, 16, 5}, /*GAIN_ERR_COEFF_10*/ 511 + {0x00006E38, 24, 5}, /*GAIN_ERR_COEFF_11*/ 512 + {0x00006E3C, 0, 5}, /*GAIN_ERR_COEFF_12*/ 513 + {0x00006E3C, 8, 5}, /*GAIN_ERR_COEFF_13*/ 514 + {0x00006E3C, 16, 5}, /*GAIN_ERR_COEFF_14*/ 515 + {0x00006E3C, 24, 5}, /*GAIN_ERR_COEFF_15*/ 516 + {0x00006E40, 0, 5}, /*GAIN_ERR_COEFF_16*/ 517 + {0x00006E40, 8, 5}, /*GAIN_ERR_COEFF_17*/ 518 + {0x00006E40, 16, 5}, /*GAIN_ERR_COEFF_18*/ 519 + {0x00006E40, 24, 5}, /*GAIN_ERR_COEFF_19*/ 520 + {0x00006E44, 0, 5}, /*GAIN_ERR_COEFF_20*/ 521 + {0x00006E48, 0, 10}, /*VOFF_GAIN_0*/ 522 + {0x00006E48, 10, 10}, /*VOFF_GAIN_1*/ 523 + {0x00006E48, 20, 10}, /*VOFF_GAIN_2*/ 524 + {0x00006E4C, 0, 10}, /*VOFF_GAIN_3*/ 525 + {0x00006E4C, 10, 10}, /*VOFF_GAIN_4*/ 526 + {0x00006E4C, 20, 10}, /*VOFF_GAIN_5*/ 527 + {0x00006E50, 0, 10}, /*VOFF_GAIN_6*/ 528 + {0x00006E50, 10, 10}, /*VOFF_GAIN_7*/ 529 + {0x00006E50, 20, 10}, /*VOFF_GAIN_8*/ 530 + {0x00006E54, 0, 10}, /*VOFF_GAIN_9*/ 531 + {0x00006E54, 10, 10}, /*VOFF_GAIN_10*/ 532 + {0x00006E54, 20, 10}, /*VOFF_GAIN_11*/ 533 + {0x00006E58, 0, 10}, /*VOFF_GAIN_12*/ 534 + {0x00006E58, 10, 10}, /*VOFF_GAIN_13*/ 535 + {0x00006E58, 20, 10}, /*VOFF_GAIN_14*/ 536 + {0x00006E5C, 0, 10}, /*VOFF_GAIN_15*/ 537 + {0x00006E5C, 10, 10}, /*VOFF_GAIN_16*/ 538 + {0x00006E5C, 20, 10}, /*VOFF_GAIN_17*/ 539 + {0x00006E60, 0, 10}, /*VOFF_GAIN_18*/ 540 + {0x00006E60, 10, 10}, /*VOFF_GAIN_19*/ 541 + {0x00006E60, 20, 10}, /*VOFF_GAIN_20*/ 542 + {0x00006E64, 0, 10}, /*VOFF_INT1*/ 543 + {0x00007418, 7, 5}, /*DS_SPK_INT1_CAP_TRIM*/ 544 + {0x0000741C, 0, 5}, /*DS_SPK_INT2_CAP_TRIM*/ 545 + {0x0000741C, 11, 4}, /*DS_SPK_LPF_CAP_TRIM*/ 546 + {0x0000741C, 19, 4}, /*DS_SPK_QUAN_CAP_TRIM*/ 547 + {0x00007434, 17, 1}, /*FORCE_CAL*/ 548 + {0x00007434, 18, 7}, /*CAL_OVERRIDE*/ 549 + {0x00007068, 0, 9}, /*MODIX*/ 550 + {0x0000410C, 7, 1}, /*VIMON_DLY_NOT_COMB*/ 551 + {0x0000400C, 0, 7}, /*VIMON_DLY*/ 552 + {0x00004000, 11, 1}, /*VMON_POL*/ 553 + {0x00017040, 0, 8}, /*X_COORDINATE*/ 554 + {0x00017040, 8, 8}, /*Y_COORDINATE*/ 555 + {0x00017040, 16, 8}, /*WAFER_ID*/ 556 + {0x00017040, 24, 8}, /*DVS*/ 557 + {0x00017044, 0, 24}, /*LOT_NUMBER*/ 558 + }; 559 + 560 + const struct cs35l41_otp_map_element_t 561 + cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { 562 + { 563 + .id = 0x01, 564 + .map = otp_map_1, 565 + .num_elements = CS35L41_NUM_OTP_ELEM, 566 + .bit_offset = 16, 567 + .word_offset = 2, 568 + }, 569 + { 570 + .id = 0x02, 571 + .map = otp_map_2, 572 + .num_elements = CS35L41_NUM_OTP_ELEM, 573 + .bit_offset = 16, 574 + .word_offset = 2, 575 + }, 576 + { 577 + .id = 0x03, 578 + .map = otp_map_2, 579 + .num_elements = CS35L41_NUM_OTP_ELEM, 580 + .bit_offset = 16, 581 + .word_offset = 2, 582 + }, 583 + { 584 + .id = 0x06, 585 + .map = otp_map_2, 586 + .num_elements = CS35L41_NUM_OTP_ELEM, 587 + .bit_offset = 16, 588 + .word_offset = 2, 589 + }, 590 + { 591 + .id = 0x08, 592 + .map = otp_map_1, 593 + .num_elements = CS35L41_NUM_OTP_ELEM, 594 + .bit_offset = 16, 595 + .word_offset = 2, 596 + }, 597 + };
+1545
sound/soc/codecs/cs35l41.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // cs35l41.c -- CS35l41 ALSA SoC audio driver 4 + // 5 + // Copyright 2017-2021 Cirrus Logic, Inc. 6 + // 7 + // Author: David Rhodes <david.rhodes@cirrus.com> 8 + 9 + #include <linux/delay.h> 10 + #include <linux/err.h> 11 + #include <linux/init.h> 12 + #include <linux/kernel.h> 13 + #include <linux/module.h> 14 + #include <linux/moduleparam.h> 15 + #include <linux/of_device.h> 16 + #include <linux/property.h> 17 + #include <linux/slab.h> 18 + #include <sound/initval.h> 19 + #include <sound/pcm.h> 20 + #include <sound/pcm_params.h> 21 + #include <sound/soc.h> 22 + #include <sound/soc-dapm.h> 23 + #include <sound/tlv.h> 24 + 25 + #include "cs35l41.h" 26 + 27 + static const char * const cs35l41_supplies[CS35L41_NUM_SUPPLIES] = { 28 + "VA", 29 + "VP", 30 + }; 31 + 32 + struct cs35l41_pll_sysclk_config { 33 + int freq; 34 + int clk_cfg; 35 + }; 36 + 37 + static const struct cs35l41_pll_sysclk_config cs35l41_pll_sysclk[] = { 38 + { 32768, 0x00 }, 39 + { 8000, 0x01 }, 40 + { 11025, 0x02 }, 41 + { 12000, 0x03 }, 42 + { 16000, 0x04 }, 43 + { 22050, 0x05 }, 44 + { 24000, 0x06 }, 45 + { 32000, 0x07 }, 46 + { 44100, 0x08 }, 47 + { 48000, 0x09 }, 48 + { 88200, 0x0A }, 49 + { 96000, 0x0B }, 50 + { 128000, 0x0C }, 51 + { 176400, 0x0D }, 52 + { 192000, 0x0E }, 53 + { 256000, 0x0F }, 54 + { 352800, 0x10 }, 55 + { 384000, 0x11 }, 56 + { 512000, 0x12 }, 57 + { 705600, 0x13 }, 58 + { 750000, 0x14 }, 59 + { 768000, 0x15 }, 60 + { 1000000, 0x16 }, 61 + { 1024000, 0x17 }, 62 + { 1200000, 0x18 }, 63 + { 1411200, 0x19 }, 64 + { 1500000, 0x1A }, 65 + { 1536000, 0x1B }, 66 + { 2000000, 0x1C }, 67 + { 2048000, 0x1D }, 68 + { 2400000, 0x1E }, 69 + { 2822400, 0x1F }, 70 + { 3000000, 0x20 }, 71 + { 3072000, 0x21 }, 72 + { 3200000, 0x22 }, 73 + { 4000000, 0x23 }, 74 + { 4096000, 0x24 }, 75 + { 4800000, 0x25 }, 76 + { 5644800, 0x26 }, 77 + { 6000000, 0x27 }, 78 + { 6144000, 0x28 }, 79 + { 6250000, 0x29 }, 80 + { 6400000, 0x2A }, 81 + { 6500000, 0x2B }, 82 + { 6750000, 0x2C }, 83 + { 7526400, 0x2D }, 84 + { 8000000, 0x2E }, 85 + { 8192000, 0x2F }, 86 + { 9600000, 0x30 }, 87 + { 11289600, 0x31 }, 88 + { 12000000, 0x32 }, 89 + { 12288000, 0x33 }, 90 + { 12500000, 0x34 }, 91 + { 12800000, 0x35 }, 92 + { 13000000, 0x36 }, 93 + { 13500000, 0x37 }, 94 + { 19200000, 0x38 }, 95 + { 22579200, 0x39 }, 96 + { 24000000, 0x3A }, 97 + { 24576000, 0x3B }, 98 + { 25000000, 0x3C }, 99 + { 25600000, 0x3D }, 100 + { 26000000, 0x3E }, 101 + { 27000000, 0x3F }, 102 + }; 103 + 104 + struct cs35l41_fs_mon_config { 105 + int freq; 106 + unsigned int fs1; 107 + unsigned int fs2; 108 + }; 109 + 110 + static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = { 111 + { 32768, 2254, 3754 }, 112 + { 8000, 9220, 15364 }, 113 + { 11025, 6148, 10244 }, 114 + { 12000, 6148, 10244 }, 115 + { 16000, 4612, 7684 }, 116 + { 22050, 3076, 5124 }, 117 + { 24000, 3076, 5124 }, 118 + { 32000, 2308, 3844 }, 119 + { 44100, 1540, 2564 }, 120 + { 48000, 1540, 2564 }, 121 + { 88200, 772, 1284 }, 122 + { 96000, 772, 1284 }, 123 + { 128000, 580, 964 }, 124 + { 176400, 388, 644 }, 125 + { 192000, 388, 644 }, 126 + { 256000, 292, 484 }, 127 + { 352800, 196, 324 }, 128 + { 384000, 196, 324 }, 129 + { 512000, 148, 244 }, 130 + { 705600, 100, 164 }, 131 + { 750000, 100, 164 }, 132 + { 768000, 100, 164 }, 133 + { 1000000, 76, 124 }, 134 + { 1024000, 76, 124 }, 135 + { 1200000, 64, 104 }, 136 + { 1411200, 52, 84 }, 137 + { 1500000, 52, 84 }, 138 + { 1536000, 52, 84 }, 139 + { 2000000, 40, 64 }, 140 + { 2048000, 40, 64 }, 141 + { 2400000, 34, 54 }, 142 + { 2822400, 28, 44 }, 143 + { 3000000, 28, 44 }, 144 + { 3072000, 28, 44 }, 145 + { 3200000, 27, 42 }, 146 + { 4000000, 22, 34 }, 147 + { 4096000, 22, 34 }, 148 + { 4800000, 19, 29 }, 149 + { 5644800, 16, 24 }, 150 + { 6000000, 16, 24 }, 151 + { 6144000, 16, 24 }, 152 + }; 153 + 154 + static const unsigned char cs35l41_bst_k1_table[4][5] = { 155 + { 0x24, 0x32, 0x32, 0x4F, 0x57 }, 156 + { 0x24, 0x32, 0x32, 0x4F, 0x57 }, 157 + { 0x40, 0x32, 0x32, 0x4F, 0x57 }, 158 + { 0x40, 0x32, 0x32, 0x4F, 0x57 } 159 + }; 160 + 161 + static const unsigned char cs35l41_bst_k2_table[4][5] = { 162 + { 0x24, 0x49, 0x66, 0xA3, 0xEA }, 163 + { 0x24, 0x49, 0x66, 0xA3, 0xEA }, 164 + { 0x48, 0x49, 0x66, 0xA3, 0xEA }, 165 + { 0x48, 0x49, 0x66, 0xA3, 0xEA } 166 + }; 167 + 168 + static const unsigned char cs35l41_bst_slope_table[4] = { 169 + 0x75, 0x6B, 0x3B, 0x28}; 170 + 171 + static int cs35l41_get_fs_mon_config_index(int freq) 172 + { 173 + int i; 174 + 175 + for (i = 0; i < ARRAY_SIZE(cs35l41_fs_mon); i++) { 176 + if (cs35l41_fs_mon[i].freq == freq) 177 + return i; 178 + } 179 + 180 + return -EINVAL; 181 + } 182 + 183 + static const DECLARE_TLV_DB_RANGE(dig_vol_tlv, 184 + 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 185 + 1, 913, TLV_DB_MINMAX_ITEM(-10200, 1200)); 186 + static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1); 187 + 188 + static const struct snd_kcontrol_new dre_ctrl = 189 + SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0); 190 + 191 + static const char * const cs35l41_pcm_sftramp_text[] = { 192 + "Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"}; 193 + 194 + static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, 195 + CS35L41_AMP_DIG_VOL_CTRL, 0, 196 + cs35l41_pcm_sftramp_text); 197 + 198 + static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"}; 199 + static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32}; 200 + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum, 201 + CS35L41_DAC_PCM1_SRC, 202 + 0, CS35L41_ASP_SOURCE_MASK, 203 + cs35l41_pcm_source_texts, 204 + cs35l41_pcm_source_values); 205 + 206 + static const struct snd_kcontrol_new pcm_source_mux = 207 + SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum); 208 + 209 + static const char * const cs35l41_tx_input_texts[] = {"Zero", "ASPRX1", 210 + "ASPRX2", "VMON", 211 + "IMON", "VPMON", 212 + "VBSTMON", 213 + "DSPTX1", "DSPTX2"}; 214 + static const unsigned int cs35l41_tx_input_values[] = {0x00, 215 + CS35L41_INPUT_SRC_ASPRX1, 216 + CS35L41_INPUT_SRC_ASPRX2, 217 + CS35L41_INPUT_SRC_VMON, 218 + CS35L41_INPUT_SRC_IMON, 219 + CS35L41_INPUT_SRC_VPMON, 220 + CS35L41_INPUT_SRC_VBSTMON, 221 + CS35L41_INPUT_DSP_TX1, 222 + CS35L41_INPUT_DSP_TX2}; 223 + 224 + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum, 225 + CS35L41_ASP_TX1_SRC, 226 + 0, CS35L41_ASP_SOURCE_MASK, 227 + cs35l41_tx_input_texts, 228 + cs35l41_tx_input_values); 229 + 230 + static const struct snd_kcontrol_new asp_tx1_mux = 231 + SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum); 232 + 233 + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum, 234 + CS35L41_ASP_TX2_SRC, 235 + 0, CS35L41_ASP_SOURCE_MASK, 236 + cs35l41_tx_input_texts, 237 + cs35l41_tx_input_values); 238 + 239 + static const struct snd_kcontrol_new asp_tx2_mux = 240 + SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum); 241 + 242 + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum, 243 + CS35L41_ASP_TX3_SRC, 244 + 0, CS35L41_ASP_SOURCE_MASK, 245 + cs35l41_tx_input_texts, 246 + cs35l41_tx_input_values); 247 + 248 + static const struct snd_kcontrol_new asp_tx3_mux = 249 + SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum); 250 + 251 + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum, 252 + CS35L41_ASP_TX4_SRC, 253 + 0, CS35L41_ASP_SOURCE_MASK, 254 + cs35l41_tx_input_texts, 255 + cs35l41_tx_input_values); 256 + 257 + static const struct snd_kcontrol_new asp_tx4_mux = 258 + SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum); 259 + 260 + static const struct snd_kcontrol_new cs35l41_aud_controls[] = { 261 + SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL, 262 + 3, 0x4CF, 0x391, dig_vol_tlv), 263 + SOC_SINGLE_TLV("Analog PCM Volume", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0, 264 + amp_gain_tlv), 265 + SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp), 266 + SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0), 267 + SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0), 268 + SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0), 269 + SOC_SINGLE("Aux Noise Gate CH1 Enable", 270 + CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0), 271 + SOC_SINGLE("Aux Noise Gate CH1 Entry Delay", 272 + CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0), 273 + SOC_SINGLE("Aux Noise Gate CH1 Threshold", 274 + CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0), 275 + SOC_SINGLE("Aux Noise Gate CH2 Entry Delay", 276 + CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0), 277 + SOC_SINGLE("Aux Noise Gate CH2 Enable", 278 + CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0), 279 + SOC_SINGLE("Aux Noise Gate CH2 Threshold", 280 + CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0), 281 + SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), 282 + SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), 283 + SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL, 284 + CS35L41_AMP_INV_PCM_SHIFT, 1, 0), 285 + SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL, 286 + CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0), 287 + }; 288 + 289 + static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) 290 + { 291 + int i; 292 + 293 + for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) { 294 + if (cs35l41_otp_map_map[i].id == otp_id) 295 + return &cs35l41_otp_map_map[i]; 296 + } 297 + 298 + return NULL; 299 + } 300 + 301 + static int cs35l41_otp_unpack(void *data) 302 + { 303 + const struct cs35l41_otp_map_element_t *otp_map_match; 304 + const struct cs35l41_otp_packed_element_t *otp_map; 305 + struct cs35l41_private *cs35l41 = data; 306 + int bit_offset, word_offset, ret, i; 307 + unsigned int orig_spi_freq; 308 + unsigned int bit_sum = 8; 309 + u32 otp_val, otp_id_reg; 310 + u32 *otp_mem; 311 + 312 + otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), 313 + GFP_KERNEL); 314 + if (!otp_mem) 315 + return -ENOMEM; 316 + 317 + ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg); 318 + if (ret < 0) { 319 + dev_err(cs35l41->dev, "Read OTP ID failed\n"); 320 + ret = -EINVAL; 321 + goto err_otp_unpack; 322 + } 323 + 324 + otp_map_match = cs35l41_find_otp_map(otp_id_reg); 325 + 326 + if (!otp_map_match) { 327 + dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n", 328 + otp_id_reg); 329 + ret = -EINVAL; 330 + goto err_otp_unpack; 331 + } 332 + 333 + if (cs35l41->otp_setup) 334 + cs35l41->otp_setup(cs35l41, true, &orig_spi_freq); 335 + 336 + ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, 337 + CS35L41_OTP_SIZE_WORDS); 338 + if (ret < 0) { 339 + dev_err(cs35l41->dev, "Read OTP Mem failed\n"); 340 + ret = -EINVAL; 341 + goto err_otp_unpack; 342 + } 343 + 344 + if (cs35l41->otp_setup) 345 + cs35l41->otp_setup(cs35l41, false, &orig_spi_freq); 346 + 347 + otp_map = otp_map_match->map; 348 + 349 + bit_offset = otp_map_match->bit_offset; 350 + word_offset = otp_map_match->word_offset; 351 + 352 + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); 353 + if (ret < 0) { 354 + dev_err(cs35l41->dev, "Write Unlock key failed 1/2\n"); 355 + ret = -EINVAL; 356 + goto err_otp_unpack; 357 + } 358 + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); 359 + if (ret < 0) { 360 + dev_err(cs35l41->dev, "Write Unlock key failed 2/2\n"); 361 + ret = -EINVAL; 362 + goto err_otp_unpack; 363 + } 364 + 365 + for (i = 0; i < otp_map_match->num_elements; i++) { 366 + dev_dbg(cs35l41->dev, 367 + "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", 368 + bit_offset, word_offset, bit_sum % 32); 369 + if (bit_offset + otp_map[i].size - 1 >= 32) { 370 + otp_val = (otp_mem[word_offset] & 371 + GENMASK(31, bit_offset)) >> 372 + bit_offset; 373 + otp_val |= (otp_mem[++word_offset] & 374 + GENMASK(bit_offset + 375 + otp_map[i].size - 33, 0)) << 376 + (32 - bit_offset); 377 + bit_offset += otp_map[i].size - 32; 378 + } else { 379 + 380 + otp_val = (otp_mem[word_offset] & 381 + GENMASK(bit_offset + otp_map[i].size - 1, 382 + bit_offset)) >> bit_offset; 383 + bit_offset += otp_map[i].size; 384 + } 385 + bit_sum += otp_map[i].size; 386 + 387 + if (bit_offset == 32) { 388 + bit_offset = 0; 389 + word_offset++; 390 + } 391 + 392 + if (otp_map[i].reg != 0) { 393 + ret = regmap_update_bits(cs35l41->regmap, 394 + otp_map[i].reg, 395 + GENMASK(otp_map[i].shift + 396 + otp_map[i].size - 1, 397 + otp_map[i].shift), 398 + otp_val << otp_map[i].shift); 399 + if (ret < 0) { 400 + dev_err(cs35l41->dev, "Write OTP val failed\n"); 401 + ret = -EINVAL; 402 + goto err_otp_unpack; 403 + } 404 + } 405 + } 406 + 407 + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); 408 + if (ret < 0) { 409 + dev_err(cs35l41->dev, "Write Lock key failed 1/2\n"); 410 + ret = -EINVAL; 411 + goto err_otp_unpack; 412 + } 413 + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); 414 + if (ret < 0) { 415 + dev_err(cs35l41->dev, "Write Lock key failed 2/2\n"); 416 + ret = -EINVAL; 417 + goto err_otp_unpack; 418 + } 419 + ret = 0; 420 + 421 + err_otp_unpack: 422 + kfree(otp_mem); 423 + return ret; 424 + } 425 + 426 + static irqreturn_t cs35l41_irq(int irq, void *data) 427 + { 428 + struct cs35l41_private *cs35l41 = data; 429 + unsigned int status[4] = { 0, 0, 0, 0 }; 430 + unsigned int masks[4] = { 0, 0, 0, 0 }; 431 + int ret = IRQ_NONE; 432 + unsigned int i; 433 + 434 + for (i = 0; i < ARRAY_SIZE(status); i++) { 435 + regmap_read(cs35l41->regmap, 436 + CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE), 437 + &status[i]); 438 + regmap_read(cs35l41->regmap, 439 + CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE), 440 + &masks[i]); 441 + } 442 + 443 + /* Check to see if unmasked bits are active */ 444 + if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) && 445 + !(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) 446 + return IRQ_NONE; 447 + 448 + if (status[3] & CS35L41_OTP_BOOT_DONE) { 449 + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4, 450 + CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE); 451 + } 452 + 453 + /* 454 + * The following interrupts require a 455 + * protection release cycle to get the 456 + * speaker out of Safe-Mode. 457 + */ 458 + if (status[0] & CS35L41_AMP_SHORT_ERR) { 459 + dev_crit_ratelimited(cs35l41->dev, "Amp short error\n"); 460 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, 461 + CS35L41_AMP_SHORT_ERR); 462 + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); 463 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 464 + CS35L41_AMP_SHORT_ERR_RLS, 465 + CS35L41_AMP_SHORT_ERR_RLS); 466 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 467 + CS35L41_AMP_SHORT_ERR_RLS, 0); 468 + ret = IRQ_HANDLED; 469 + } 470 + 471 + if (status[0] & CS35L41_TEMP_WARN) { 472 + dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n"); 473 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, 474 + CS35L41_TEMP_WARN); 475 + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); 476 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 477 + CS35L41_TEMP_WARN_ERR_RLS, 478 + CS35L41_TEMP_WARN_ERR_RLS); 479 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 480 + CS35L41_TEMP_WARN_ERR_RLS, 0); 481 + ret = IRQ_HANDLED; 482 + } 483 + 484 + if (status[0] & CS35L41_TEMP_ERR) { 485 + dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n"); 486 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, 487 + CS35L41_TEMP_ERR); 488 + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); 489 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 490 + CS35L41_TEMP_ERR_RLS, 491 + CS35L41_TEMP_ERR_RLS); 492 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 493 + CS35L41_TEMP_ERR_RLS, 0); 494 + ret = IRQ_HANDLED; 495 + } 496 + 497 + if (status[0] & CS35L41_BST_OVP_ERR) { 498 + dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n"); 499 + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, 500 + CS35L41_BST_EN_MASK, 0); 501 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, 502 + CS35L41_BST_OVP_ERR); 503 + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); 504 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 505 + CS35L41_BST_OVP_ERR_RLS, 506 + CS35L41_BST_OVP_ERR_RLS); 507 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 508 + CS35L41_BST_OVP_ERR_RLS, 0); 509 + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, 510 + CS35L41_BST_EN_MASK, 511 + CS35L41_BST_EN_DEFAULT << 512 + CS35L41_BST_EN_SHIFT); 513 + ret = IRQ_HANDLED; 514 + } 515 + 516 + if (status[0] & CS35L41_BST_DCM_UVP_ERR) { 517 + dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n"); 518 + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, 519 + CS35L41_BST_EN_MASK, 0); 520 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, 521 + CS35L41_BST_DCM_UVP_ERR); 522 + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); 523 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 524 + CS35L41_BST_UVP_ERR_RLS, 525 + CS35L41_BST_UVP_ERR_RLS); 526 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 527 + CS35L41_BST_UVP_ERR_RLS, 0); 528 + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, 529 + CS35L41_BST_EN_MASK, 530 + CS35L41_BST_EN_DEFAULT << 531 + CS35L41_BST_EN_SHIFT); 532 + ret = IRQ_HANDLED; 533 + } 534 + 535 + if (status[0] & CS35L41_BST_SHORT_ERR) { 536 + dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n"); 537 + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, 538 + CS35L41_BST_EN_MASK, 0); 539 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, 540 + CS35L41_BST_SHORT_ERR); 541 + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); 542 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 543 + CS35L41_BST_SHORT_ERR_RLS, 544 + CS35L41_BST_SHORT_ERR_RLS); 545 + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 546 + CS35L41_BST_SHORT_ERR_RLS, 0); 547 + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, 548 + CS35L41_BST_EN_MASK, 549 + CS35L41_BST_EN_DEFAULT << 550 + CS35L41_BST_EN_SHIFT); 551 + ret = IRQ_HANDLED; 552 + } 553 + 554 + return ret; 555 + } 556 + 557 + static const struct reg_sequence cs35l41_pup_patch[] = { 558 + { 0x00000040, 0x00000055 }, 559 + { 0x00000040, 0x000000AA }, 560 + { 0x00002084, 0x002F1AA0 }, 561 + { 0x00000040, 0x000000CC }, 562 + { 0x00000040, 0x00000033 }, 563 + }; 564 + 565 + static const struct reg_sequence cs35l41_pdn_patch[] = { 566 + { 0x00000040, 0x00000055 }, 567 + { 0x00000040, 0x000000AA }, 568 + { 0x00002084, 0x002F1AA3 }, 569 + { 0x00000040, 0x000000CC }, 570 + { 0x00000040, 0x00000033 }, 571 + }; 572 + 573 + static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, 574 + struct snd_kcontrol *kcontrol, int event) 575 + { 576 + struct snd_soc_component *component = 577 + snd_soc_dapm_to_component(w->dapm); 578 + struct cs35l41_private *cs35l41 = 579 + snd_soc_component_get_drvdata(component); 580 + unsigned int val; 581 + int ret = 0; 582 + bool pdn; 583 + int i; 584 + 585 + switch (event) { 586 + case SND_SOC_DAPM_POST_PMU: 587 + regmap_multi_reg_write_bypassed(cs35l41->regmap, 588 + cs35l41_pup_patch, 589 + ARRAY_SIZE(cs35l41_pup_patch)); 590 + 591 + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, 592 + CS35L41_GLOBAL_EN_MASK, 593 + 1 << CS35L41_GLOBAL_EN_SHIFT); 594 + 595 + usleep_range(1000, 1100); 596 + break; 597 + case SND_SOC_DAPM_POST_PMD: 598 + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, 599 + CS35L41_GLOBAL_EN_MASK, 0); 600 + 601 + pdn = false; 602 + for (i = 0; i < 100; i++) { 603 + regmap_read(cs35l41->regmap, 604 + CS35L41_IRQ1_STATUS1, 605 + &val); 606 + if (val & CS35L41_PDN_DONE_MASK) { 607 + pdn = true; 608 + break; 609 + } 610 + usleep_range(1000, 1100); 611 + } 612 + 613 + if (!pdn) 614 + dev_warn(cs35l41->dev, "PDN failed\n"); 615 + 616 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, 617 + CS35L41_PDN_DONE_MASK); 618 + 619 + regmap_multi_reg_write_bypassed(cs35l41->regmap, 620 + cs35l41_pdn_patch, 621 + ARRAY_SIZE(cs35l41_pdn_patch)); 622 + break; 623 + default: 624 + dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event); 625 + ret = -EINVAL; 626 + } 627 + return ret; 628 + } 629 + 630 + static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { 631 + SND_SOC_DAPM_OUTPUT("SPK"), 632 + 633 + SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0), 634 + SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0), 635 + SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0), 636 + SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0), 637 + SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0), 638 + SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0), 639 + 640 + SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0), 641 + SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0), 642 + SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0), 643 + SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L41_PWR_CTRL2, 9, 0), 644 + SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, CS35L41_PWR_CTRL2, 10, 0), 645 + SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0), 646 + 647 + SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0, 648 + cs35l41_main_amp_event, 649 + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), 650 + 651 + SND_SOC_DAPM_INPUT("VP"), 652 + SND_SOC_DAPM_INPUT("VBST"), 653 + SND_SOC_DAPM_INPUT("ISENSE"), 654 + SND_SOC_DAPM_INPUT("VSENSE"), 655 + SND_SOC_DAPM_INPUT("TEMP"), 656 + 657 + SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux), 658 + SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux), 659 + SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux), 660 + SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux), 661 + SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux), 662 + SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl), 663 + }; 664 + 665 + static const struct snd_soc_dapm_route cs35l41_audio_map[] = { 666 + 667 + {"ASP TX1 Source", "VMON", "VMON ADC"}, 668 + {"ASP TX1 Source", "IMON", "IMON ADC"}, 669 + {"ASP TX1 Source", "VPMON", "VPMON ADC"}, 670 + {"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"}, 671 + {"ASP TX1 Source", "ASPRX1", "ASPRX1" }, 672 + {"ASP TX1 Source", "ASPRX2", "ASPRX2" }, 673 + {"ASP TX2 Source", "VMON", "VMON ADC"}, 674 + {"ASP TX2 Source", "IMON", "IMON ADC"}, 675 + {"ASP TX2 Source", "VPMON", "VPMON ADC"}, 676 + {"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"}, 677 + {"ASP TX2 Source", "ASPRX1", "ASPRX1" }, 678 + {"ASP TX2 Source", "ASPRX2", "ASPRX2" }, 679 + {"ASP TX3 Source", "VMON", "VMON ADC"}, 680 + {"ASP TX3 Source", "IMON", "IMON ADC"}, 681 + {"ASP TX3 Source", "VPMON", "VPMON ADC"}, 682 + {"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"}, 683 + {"ASP TX3 Source", "ASPRX1", "ASPRX1" }, 684 + {"ASP TX3 Source", "ASPRX2", "ASPRX2" }, 685 + {"ASP TX4 Source", "VMON", "VMON ADC"}, 686 + {"ASP TX4 Source", "IMON", "IMON ADC"}, 687 + {"ASP TX4 Source", "VPMON", "VPMON ADC"}, 688 + {"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"}, 689 + {"ASP TX4 Source", "ASPRX1", "ASPRX1" }, 690 + {"ASP TX4 Source", "ASPRX2", "ASPRX2" }, 691 + {"ASPTX1", NULL, "ASP TX1 Source"}, 692 + {"ASPTX2", NULL, "ASP TX2 Source"}, 693 + {"ASPTX3", NULL, "ASP TX3 Source"}, 694 + {"ASPTX4", NULL, "ASP TX4 Source"}, 695 + {"AMP Capture", NULL, "ASPTX1"}, 696 + {"AMP Capture", NULL, "ASPTX2"}, 697 + {"AMP Capture", NULL, "ASPTX3"}, 698 + {"AMP Capture", NULL, "ASPTX4"}, 699 + 700 + {"VMON ADC", NULL, "VSENSE"}, 701 + {"IMON ADC", NULL, "ISENSE"}, 702 + {"VPMON ADC", NULL, "VP"}, 703 + {"TEMPMON ADC", NULL, "TEMP"}, 704 + {"VBSTMON ADC", NULL, "VBST"}, 705 + 706 + {"ASPRX1", NULL, "AMP Playback"}, 707 + {"ASPRX2", NULL, "AMP Playback"}, 708 + {"DRE", "Switch", "CLASS H"}, 709 + {"Main AMP", NULL, "CLASS H"}, 710 + {"Main AMP", NULL, "DRE"}, 711 + {"SPK", NULL, "Main AMP"}, 712 + 713 + {"PCM Source", "ASP", "ASPRX1"}, 714 + {"CLASS H", NULL, "PCM Source"}, 715 + 716 + }; 717 + 718 + static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, 719 + unsigned int *tx_slot, unsigned int rx_num, 720 + unsigned int *rx_slot) 721 + { 722 + struct cs35l41_private *cs35l41 = 723 + snd_soc_component_get_drvdata(dai->component); 724 + int i; 725 + 726 + if (tx_num > 4 || rx_num > 2) 727 + return -EINVAL; 728 + 729 + for (i = 0; i < rx_num; i++) { 730 + dev_dbg(cs35l41->dev, "%s: rx slot %d position = %d\n", 731 + __func__, i, rx_slot[i]); 732 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, 733 + 0x3F << (i * 8), rx_slot[i] << (i * 8)); 734 + } 735 + 736 + for (i = 0; i < tx_num; i++) { 737 + dev_dbg(cs35l41->dev, "%s: tx slot %d position = %d\n", 738 + __func__, i, tx_slot[i]); 739 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, 740 + 0x3F << (i * 8), tx_slot[i] << (i * 8)); 741 + } 742 + 743 + return 0; 744 + } 745 + 746 + static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 747 + { 748 + struct cs35l41_private *cs35l41 = 749 + snd_soc_component_get_drvdata(codec_dai->component); 750 + unsigned int asp_fmt, lrclk_fmt, sclk_fmt, clock_provider; 751 + 752 + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 753 + case SND_SOC_DAIFMT_CBP_CFP: 754 + clock_provider = 1; 755 + break; 756 + case SND_SOC_DAIFMT_CBC_CFC: 757 + clock_provider = 0; 758 + break; 759 + default: 760 + dev_warn(cs35l41->dev, 761 + "%s: Mixed provider/consumer mode unsupported\n", 762 + __func__); 763 + return -EINVAL; 764 + } 765 + 766 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, 767 + CS35L41_SCLK_MSTR_MASK, 768 + clock_provider << CS35L41_SCLK_MSTR_SHIFT); 769 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, 770 + CS35L41_LRCLK_MSTR_MASK, 771 + clock_provider << CS35L41_LRCLK_MSTR_SHIFT); 772 + 773 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 774 + case SND_SOC_DAIFMT_DSP_A: 775 + asp_fmt = 0; 776 + break; 777 + case SND_SOC_DAIFMT_I2S: 778 + asp_fmt = 2; 779 + break; 780 + default: 781 + dev_warn(cs35l41->dev, 782 + "%s: Invalid or unsupported DAI format\n", __func__); 783 + return -EINVAL; 784 + } 785 + 786 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, 787 + CS35L41_ASP_FMT_MASK, 788 + asp_fmt << CS35L41_ASP_FMT_SHIFT); 789 + 790 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 791 + case SND_SOC_DAIFMT_NB_IF: 792 + lrclk_fmt = 1; 793 + sclk_fmt = 0; 794 + break; 795 + case SND_SOC_DAIFMT_IB_NF: 796 + lrclk_fmt = 0; 797 + sclk_fmt = 1; 798 + break; 799 + case SND_SOC_DAIFMT_IB_IF: 800 + lrclk_fmt = 1; 801 + sclk_fmt = 1; 802 + break; 803 + case SND_SOC_DAIFMT_NB_NF: 804 + lrclk_fmt = 0; 805 + sclk_fmt = 0; 806 + break; 807 + default: 808 + dev_warn(cs35l41->dev, 809 + "%s: Invalid DAI clock INV\n", __func__); 810 + return -EINVAL; 811 + } 812 + 813 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, 814 + CS35L41_LRCLK_INV_MASK, 815 + lrclk_fmt << CS35L41_LRCLK_INV_SHIFT); 816 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, 817 + CS35L41_SCLK_INV_MASK, 818 + sclk_fmt << CS35L41_SCLK_INV_SHIFT); 819 + 820 + return 0; 821 + } 822 + 823 + struct cs35l41_global_fs_config { 824 + int rate; 825 + int fs_cfg; 826 + }; 827 + 828 + static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = { 829 + { 12000, 0x01 }, 830 + { 24000, 0x02 }, 831 + { 48000, 0x03 }, 832 + { 96000, 0x04 }, 833 + { 192000, 0x05 }, 834 + { 11025, 0x09 }, 835 + { 22050, 0x0A }, 836 + { 44100, 0x0B }, 837 + { 88200, 0x0C }, 838 + { 176400, 0x0D }, 839 + { 8000, 0x11 }, 840 + { 16000, 0x12 }, 841 + { 32000, 0x13 }, 842 + }; 843 + 844 + static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream, 845 + struct snd_pcm_hw_params *params, 846 + struct snd_soc_dai *dai) 847 + { 848 + struct cs35l41_private *cs35l41 = 849 + snd_soc_component_get_drvdata(dai->component); 850 + unsigned int rate = params_rate(params); 851 + u8 asp_wl; 852 + int i; 853 + 854 + for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) { 855 + if (rate == cs35l41_fs_rates[i].rate) 856 + break; 857 + } 858 + 859 + if (i >= ARRAY_SIZE(cs35l41_fs_rates)) { 860 + dev_err(cs35l41->dev, "%s: Unsupported rate: %u\n", 861 + __func__, rate); 862 + return -EINVAL; 863 + } 864 + 865 + asp_wl = params_width(params); 866 + 867 + if (i < ARRAY_SIZE(cs35l41_fs_rates)) 868 + regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL, 869 + CS35L41_GLOBAL_FS_MASK, 870 + cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT); 871 + 872 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 873 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, 874 + CS35L41_ASP_WIDTH_RX_MASK, 875 + asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT); 876 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL, 877 + CS35L41_ASP_RX_WL_MASK, 878 + asp_wl << CS35L41_ASP_RX_WL_SHIFT); 879 + } else { 880 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, 881 + CS35L41_ASP_WIDTH_TX_MASK, 882 + asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT); 883 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL, 884 + CS35L41_ASP_TX_WL_MASK, 885 + asp_wl << CS35L41_ASP_TX_WL_SHIFT); 886 + } 887 + 888 + return 0; 889 + } 890 + 891 + static int cs35l41_get_clk_config(int freq) 892 + { 893 + int i; 894 + 895 + for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) { 896 + if (cs35l41_pll_sysclk[i].freq == freq) 897 + return cs35l41_pll_sysclk[i].clk_cfg; 898 + } 899 + 900 + return -EINVAL; 901 + } 902 + 903 + static const unsigned int cs35l41_src_rates[] = { 904 + 8000, 12000, 11025, 16000, 22050, 24000, 32000, 905 + 44100, 48000, 88200, 96000, 176400, 192000 906 + }; 907 + 908 + static const struct snd_pcm_hw_constraint_list cs35l41_constraints = { 909 + .count = ARRAY_SIZE(cs35l41_src_rates), 910 + .list = cs35l41_src_rates, 911 + }; 912 + 913 + static int cs35l41_pcm_startup(struct snd_pcm_substream *substream, 914 + struct snd_soc_dai *dai) 915 + { 916 + if (substream->runtime) 917 + return snd_pcm_hw_constraint_list(substream->runtime, 0, 918 + SNDRV_PCM_HW_PARAM_RATE, &cs35l41_constraints); 919 + return 0; 920 + } 921 + 922 + static int cs35l41_component_set_sysclk(struct snd_soc_component *component, 923 + int clk_id, int source, unsigned int freq, 924 + int dir) 925 + { 926 + struct cs35l41_private *cs35l41 = 927 + snd_soc_component_get_drvdata(component); 928 + int extclk_cfg, clksrc; 929 + 930 + switch (clk_id) { 931 + case CS35L41_CLKID_SCLK: 932 + clksrc = CS35L41_PLLSRC_SCLK; 933 + break; 934 + case CS35L41_CLKID_LRCLK: 935 + clksrc = CS35L41_PLLSRC_LRCLK; 936 + break; 937 + case CS35L41_CLKID_MCLK: 938 + clksrc = CS35L41_PLLSRC_MCLK; 939 + break; 940 + default: 941 + dev_err(cs35l41->dev, "Invalid CLK Config\n"); 942 + return -EINVAL; 943 + } 944 + 945 + extclk_cfg = cs35l41_get_clk_config(freq); 946 + 947 + if (extclk_cfg < 0) { 948 + dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n", 949 + extclk_cfg, freq); 950 + return -EINVAL; 951 + } 952 + 953 + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, 954 + CS35L41_PLL_OPENLOOP_MASK, 955 + 1 << CS35L41_PLL_OPENLOOP_SHIFT); 956 + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, 957 + CS35L41_REFCLK_FREQ_MASK, 958 + extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT); 959 + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, 960 + CS35L41_PLL_CLK_EN_MASK, 961 + 0 << CS35L41_PLL_CLK_EN_SHIFT); 962 + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, 963 + CS35L41_PLL_CLK_SEL_MASK, clksrc); 964 + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, 965 + CS35L41_PLL_OPENLOOP_MASK, 966 + 0 << CS35L41_PLL_OPENLOOP_SHIFT); 967 + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, 968 + CS35L41_PLL_CLK_EN_MASK, 969 + 1 << CS35L41_PLL_CLK_EN_SHIFT); 970 + 971 + return 0; 972 + } 973 + 974 + static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, 975 + int clk_id, unsigned int freq, int dir) 976 + { 977 + struct cs35l41_private *cs35l41 = 978 + snd_soc_component_get_drvdata(dai->component); 979 + unsigned int fs1_val; 980 + unsigned int fs2_val; 981 + unsigned int val; 982 + int fsIndex; 983 + 984 + fsIndex = cs35l41_get_fs_mon_config_index(freq); 985 + if (fsIndex < 0) { 986 + dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq); 987 + return -EINVAL; 988 + } 989 + 990 + dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq); 991 + if (freq <= 6144000) { 992 + /* Use the lookup table */ 993 + fs1_val = cs35l41_fs_mon[fsIndex].fs1; 994 + fs2_val = cs35l41_fs_mon[fsIndex].fs2; 995 + } else { 996 + /* Use hard-coded values */ 997 + fs1_val = 0x10; 998 + fs2_val = 0x24; 999 + } 1000 + 1001 + val = fs1_val; 1002 + val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK; 1003 + regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val); 1004 + 1005 + return 0; 1006 + } 1007 + 1008 + static int cs35l41_boost_config(struct cs35l41_private *cs35l41, 1009 + int boost_ind, int boost_cap, int boost_ipk) 1010 + { 1011 + unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; 1012 + struct regmap *regmap = cs35l41->regmap; 1013 + struct device *dev = cs35l41->dev; 1014 + int ret; 1015 + 1016 + switch (boost_ind) { 1017 + case 1000: /* 1.0 uH */ 1018 + bst_lbst_val = 0; 1019 + break; 1020 + case 1200: /* 1.2 uH */ 1021 + bst_lbst_val = 1; 1022 + break; 1023 + case 1500: /* 1.5 uH */ 1024 + bst_lbst_val = 2; 1025 + break; 1026 + case 2200: /* 2.2 uH */ 1027 + bst_lbst_val = 3; 1028 + break; 1029 + default: 1030 + dev_err(dev, "Invalid boost inductor value: %d nH\n", 1031 + boost_ind); 1032 + return -EINVAL; 1033 + } 1034 + 1035 + switch (boost_cap) { 1036 + case 0 ... 19: 1037 + bst_cbst_range = 0; 1038 + break; 1039 + case 20 ... 50: 1040 + bst_cbst_range = 1; 1041 + break; 1042 + case 51 ... 100: 1043 + bst_cbst_range = 2; 1044 + break; 1045 + case 101 ... 200: 1046 + bst_cbst_range = 3; 1047 + break; 1048 + default: /* 201 uF and greater */ 1049 + bst_cbst_range = 4; 1050 + } 1051 + 1052 + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, 1053 + CS35L41_BST_K1_MASK, 1054 + cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] 1055 + << CS35L41_BST_K1_SHIFT); 1056 + if (ret) { 1057 + dev_err(dev, "Failed to write boost K1 coefficient\n"); 1058 + return ret; 1059 + } 1060 + 1061 + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, 1062 + CS35L41_BST_K2_MASK, 1063 + cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] 1064 + << CS35L41_BST_K2_SHIFT); 1065 + if (ret) { 1066 + dev_err(dev, "Failed to write boost K2 coefficient\n"); 1067 + return ret; 1068 + } 1069 + 1070 + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, 1071 + CS35L41_BST_SLOPE_MASK, 1072 + cs35l41_bst_slope_table[bst_lbst_val] 1073 + << CS35L41_BST_SLOPE_SHIFT); 1074 + if (ret) { 1075 + dev_err(dev, "Failed to write boost slope coefficient\n"); 1076 + return ret; 1077 + } 1078 + 1079 + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, 1080 + CS35L41_BST_LBST_VAL_MASK, 1081 + bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); 1082 + if (ret) { 1083 + dev_err(dev, "Failed to write boost inductor value\n"); 1084 + return ret; 1085 + } 1086 + 1087 + if ((boost_ipk < 1600) || (boost_ipk > 4500)) { 1088 + dev_err(dev, "Invalid boost inductor peak current: %d mA\n", 1089 + boost_ipk); 1090 + return -EINVAL; 1091 + } 1092 + bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; 1093 + 1094 + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, 1095 + CS35L41_BST_IPK_MASK, 1096 + bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); 1097 + if (ret) { 1098 + dev_err(dev, "Failed to write boost inductor peak current\n"); 1099 + return ret; 1100 + } 1101 + 1102 + return 0; 1103 + } 1104 + 1105 + static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) 1106 + { 1107 + int ret; 1108 + 1109 + /* Set Platform Data */ 1110 + /* Required */ 1111 + if (cs35l41->pdata.bst_ipk && 1112 + cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) { 1113 + ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind, 1114 + cs35l41->pdata.bst_cap, 1115 + cs35l41->pdata.bst_ipk); 1116 + if (ret) { 1117 + dev_err(cs35l41->dev, "Error in Boost DT config\n"); 1118 + return ret; 1119 + } 1120 + } else { 1121 + dev_err(cs35l41->dev, "Incomplete Boost component DT config\n"); 1122 + return -EINVAL; 1123 + } 1124 + 1125 + /* Optional */ 1126 + if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && 1127 + cs35l41->pdata.dout_hiz >= 0) 1128 + regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, 1129 + CS35L41_ASP_DOUT_HIZ_MASK, 1130 + cs35l41->pdata.dout_hiz); 1131 + 1132 + return 0; 1133 + } 1134 + 1135 + static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) 1136 + { 1137 + struct cs35l41_irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1; 1138 + struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2; 1139 + int irq_pol = IRQF_TRIGGER_NONE; 1140 + 1141 + if (irq_gpio_cfg1->irq_pol_inv) 1142 + regmap_update_bits(cs35l41->regmap, 1143 + CS35L41_GPIO1_CTRL1, 1144 + CS35L41_GPIO_POL_MASK, 1145 + CS35L41_GPIO_POL_MASK); 1146 + if (irq_gpio_cfg1->irq_out_en) 1147 + regmap_update_bits(cs35l41->regmap, 1148 + CS35L41_GPIO1_CTRL1, 1149 + CS35L41_GPIO_DIR_MASK, 1150 + 0); 1151 + if (irq_gpio_cfg1->irq_src_sel) 1152 + regmap_update_bits(cs35l41->regmap, 1153 + CS35L41_GPIO_PAD_CONTROL, 1154 + CS35L41_GPIO1_CTRL_MASK, 1155 + irq_gpio_cfg1->irq_src_sel << 1156 + CS35L41_GPIO1_CTRL_SHIFT); 1157 + 1158 + if (irq_gpio_cfg2->irq_pol_inv) 1159 + regmap_update_bits(cs35l41->regmap, 1160 + CS35L41_GPIO2_CTRL1, 1161 + CS35L41_GPIO_POL_MASK, 1162 + CS35L41_GPIO_POL_MASK); 1163 + if (irq_gpio_cfg2->irq_out_en) 1164 + regmap_update_bits(cs35l41->regmap, 1165 + CS35L41_GPIO2_CTRL1, 1166 + CS35L41_GPIO_DIR_MASK, 1167 + 0); 1168 + if (irq_gpio_cfg2->irq_src_sel) 1169 + regmap_update_bits(cs35l41->regmap, 1170 + CS35L41_GPIO_PAD_CONTROL, 1171 + CS35L41_GPIO2_CTRL_MASK, 1172 + irq_gpio_cfg2->irq_src_sel << 1173 + CS35L41_GPIO2_CTRL_SHIFT); 1174 + 1175 + if ((irq_gpio_cfg2->irq_src_sel == 1176 + (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) || 1177 + (irq_gpio_cfg2->irq_src_sel == 1178 + (CS35L41_GPIO_CTRL_OPEN_INT | CS35L41_VALID_PDATA))) 1179 + irq_pol = IRQF_TRIGGER_LOW; 1180 + else if (irq_gpio_cfg2->irq_src_sel == 1181 + (CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA)) 1182 + irq_pol = IRQF_TRIGGER_HIGH; 1183 + 1184 + return irq_pol; 1185 + } 1186 + 1187 + static const struct snd_soc_dai_ops cs35l41_ops = { 1188 + .startup = cs35l41_pcm_startup, 1189 + .set_fmt = cs35l41_set_dai_fmt, 1190 + .hw_params = cs35l41_pcm_hw_params, 1191 + .set_sysclk = cs35l41_dai_set_sysclk, 1192 + .set_channel_map = cs35l41_set_channel_map, 1193 + }; 1194 + 1195 + static struct snd_soc_dai_driver cs35l41_dai[] = { 1196 + { 1197 + .name = "cs35l41-pcm", 1198 + .id = 0, 1199 + .playback = { 1200 + .stream_name = "AMP Playback", 1201 + .channels_min = 1, 1202 + .channels_max = 2, 1203 + .rates = SNDRV_PCM_RATE_KNOT, 1204 + .formats = CS35L41_RX_FORMATS, 1205 + }, 1206 + .capture = { 1207 + .stream_name = "AMP Capture", 1208 + .channels_min = 1, 1209 + .channels_max = 8, 1210 + .rates = SNDRV_PCM_RATE_KNOT, 1211 + .formats = CS35L41_TX_FORMATS, 1212 + }, 1213 + .ops = &cs35l41_ops, 1214 + .symmetric_rate = 1, 1215 + }, 1216 + }; 1217 + 1218 + static const struct snd_soc_component_driver soc_component_dev_cs35l41 = { 1219 + .name = "cs35l41-codec", 1220 + 1221 + .dapm_widgets = cs35l41_dapm_widgets, 1222 + .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets), 1223 + .dapm_routes = cs35l41_audio_map, 1224 + .num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map), 1225 + 1226 + .controls = cs35l41_aud_controls, 1227 + .num_controls = ARRAY_SIZE(cs35l41_aud_controls), 1228 + .set_sysclk = cs35l41_component_set_sysclk, 1229 + }; 1230 + 1231 + static int cs35l41_handle_pdata(struct device *dev, 1232 + struct cs35l41_platform_data *pdata, 1233 + struct cs35l41_private *cs35l41) 1234 + { 1235 + struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1; 1236 + struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2; 1237 + unsigned int val; 1238 + int ret; 1239 + 1240 + ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val); 1241 + if (ret >= 0) 1242 + pdata->bst_ipk = val; 1243 + 1244 + ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val); 1245 + if (ret >= 0) 1246 + pdata->bst_ind = val; 1247 + 1248 + ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val); 1249 + if (ret >= 0) 1250 + pdata->bst_cap = val; 1251 + 1252 + ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val); 1253 + if (ret >= 0) 1254 + pdata->dout_hiz = val; 1255 + else 1256 + pdata->dout_hiz = -1; 1257 + 1258 + /* GPIO1 Pin Config */ 1259 + irq_gpio1_config->irq_pol_inv = device_property_read_bool(dev, 1260 + "cirrus,gpio1-polarity-invert"); 1261 + irq_gpio1_config->irq_out_en = device_property_read_bool(dev, 1262 + "cirrus,gpio1-output-enable"); 1263 + ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", 1264 + &val); 1265 + if (ret >= 0) { 1266 + val |= CS35L41_VALID_PDATA; 1267 + irq_gpio1_config->irq_src_sel = val; 1268 + } 1269 + 1270 + /* GPIO2 Pin Config */ 1271 + irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev, 1272 + "cirrus,gpio2-polarity-invert"); 1273 + irq_gpio2_config->irq_out_en = device_property_read_bool(dev, 1274 + "cirrus,gpio2-output-enable"); 1275 + ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", 1276 + &val); 1277 + if (ret >= 0) { 1278 + val |= CS35L41_VALID_PDATA; 1279 + irq_gpio2_config->irq_src_sel = val; 1280 + } 1281 + 1282 + return 0; 1283 + } 1284 + 1285 + static const struct reg_sequence cs35l41_reva0_errata_patch[] = { 1286 + { 0x00000040, 0x00005555 }, 1287 + { 0x00000040, 0x0000AAAA }, 1288 + { 0x00003854, 0x05180240 }, 1289 + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, 1290 + { 0x00004310, 0x00000000 }, 1291 + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, 1292 + { CS35L41_OTP_TRIM_30, 0x9091A1C8 }, 1293 + { 0x00003014, 0x0200EE0E }, 1294 + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, 1295 + { 0x00000054, 0x00000004 }, 1296 + { CS35L41_IRQ1_DB3, 0x00000000 }, 1297 + { CS35L41_IRQ2_DB3, 0x00000000 }, 1298 + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, 1299 + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, 1300 + { 0x00000040, 0x0000CCCC }, 1301 + { 0x00000040, 0x00003333 }, 1302 + }; 1303 + 1304 + static const struct reg_sequence cs35l41_revb0_errata_patch[] = { 1305 + { 0x00000040, 0x00005555 }, 1306 + { 0x00000040, 0x0000AAAA }, 1307 + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, 1308 + { 0x00004310, 0x00000000 }, 1309 + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, 1310 + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, 1311 + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, 1312 + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, 1313 + { 0x00000040, 0x0000CCCC }, 1314 + { 0x00000040, 0x00003333 }, 1315 + }; 1316 + 1317 + static const struct reg_sequence cs35l41_revb2_errata_patch[] = { 1318 + { 0x00000040, 0x00005555 }, 1319 + { 0x00000040, 0x0000AAAA }, 1320 + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, 1321 + { 0x00004310, 0x00000000 }, 1322 + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, 1323 + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, 1324 + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, 1325 + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, 1326 + { 0x00000040, 0x0000CCCC }, 1327 + { 0x00000040, 0x00003333 }, 1328 + }; 1329 + 1330 + int cs35l41_probe(struct cs35l41_private *cs35l41, 1331 + struct cs35l41_platform_data *pdata) 1332 + { 1333 + u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; 1334 + int irq_pol = 0; 1335 + int timeout; 1336 + int ret; 1337 + 1338 + if (pdata) { 1339 + cs35l41->pdata = *pdata; 1340 + } else { 1341 + ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, 1342 + cs35l41); 1343 + if (ret != 0) 1344 + return ret; 1345 + } 1346 + 1347 + for (i = 0; i < CS35L41_NUM_SUPPLIES; i++) 1348 + cs35l41->supplies[i].supply = cs35l41_supplies[i]; 1349 + 1350 + ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES, 1351 + cs35l41->supplies); 1352 + if (ret != 0) { 1353 + dev_err(cs35l41->dev, 1354 + "Failed to request core supplies: %d\n", 1355 + ret); 1356 + return ret; 1357 + } 1358 + 1359 + ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); 1360 + if (ret != 0) { 1361 + dev_err(cs35l41->dev, 1362 + "Failed to enable core supplies: %d\n", ret); 1363 + return ret; 1364 + } 1365 + 1366 + /* returning NULL can be an option if in stereo mode */ 1367 + cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset", 1368 + GPIOD_OUT_LOW); 1369 + if (IS_ERR(cs35l41->reset_gpio)) { 1370 + ret = PTR_ERR(cs35l41->reset_gpio); 1371 + cs35l41->reset_gpio = NULL; 1372 + if (ret == -EBUSY) { 1373 + dev_info(cs35l41->dev, 1374 + "Reset line busy, assuming shared reset\n"); 1375 + } else { 1376 + dev_err(cs35l41->dev, 1377 + "Failed to get reset GPIO: %d\n", ret); 1378 + goto err; 1379 + } 1380 + } 1381 + if (cs35l41->reset_gpio) { 1382 + /* satisfy minimum reset pulse width spec */ 1383 + usleep_range(2000, 2100); 1384 + gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); 1385 + } 1386 + 1387 + usleep_range(2000, 2100); 1388 + 1389 + timeout = 100; 1390 + do { 1391 + if (timeout == 0) { 1392 + dev_err(cs35l41->dev, 1393 + "Timeout waiting for OTP_BOOT_DONE\n"); 1394 + ret = -EBUSY; 1395 + goto err; 1396 + } 1397 + usleep_range(1000, 1100); 1398 + regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS4, &int_status); 1399 + timeout--; 1400 + } while (!(int_status & CS35L41_OTP_BOOT_DONE)); 1401 + 1402 + regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status); 1403 + if (int_status & CS35L41_OTP_BOOT_ERR) { 1404 + dev_err(cs35l41->dev, "OTP Boot error\n"); 1405 + ret = -EINVAL; 1406 + goto err; 1407 + } 1408 + 1409 + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, &regid); 1410 + if (ret < 0) { 1411 + dev_err(cs35l41->dev, "Get Device ID failed\n"); 1412 + goto err; 1413 + } 1414 + 1415 + ret = regmap_read(cs35l41->regmap, CS35L41_REVID, &reg_revid); 1416 + if (ret < 0) { 1417 + dev_err(cs35l41->dev, "Get Revision ID failed\n"); 1418 + goto err; 1419 + } 1420 + 1421 + mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; 1422 + 1423 + /* CS35L41 will have even MTLREVID 1424 + * CS35L41R will have odd MTLREVID 1425 + */ 1426 + chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; 1427 + if (regid != chipid_match) { 1428 + dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n", 1429 + regid, chipid_match); 1430 + ret = -ENODEV; 1431 + goto err; 1432 + } 1433 + 1434 + switch (reg_revid) { 1435 + case CS35L41_REVID_A0: 1436 + ret = regmap_register_patch(cs35l41->regmap, 1437 + cs35l41_reva0_errata_patch, 1438 + ARRAY_SIZE(cs35l41_reva0_errata_patch)); 1439 + if (ret < 0) { 1440 + dev_err(cs35l41->dev, 1441 + "Failed to apply A0 errata patch %d\n", ret); 1442 + goto err; 1443 + } 1444 + break; 1445 + case CS35L41_REVID_B0: 1446 + ret = regmap_register_patch(cs35l41->regmap, 1447 + cs35l41_revb0_errata_patch, 1448 + ARRAY_SIZE(cs35l41_revb0_errata_patch)); 1449 + if (ret < 0) { 1450 + dev_err(cs35l41->dev, 1451 + "Failed to apply B0 errata patch %d\n", ret); 1452 + goto err; 1453 + } 1454 + break; 1455 + case CS35L41_REVID_B2: 1456 + ret = regmap_register_patch(cs35l41->regmap, 1457 + cs35l41_revb2_errata_patch, 1458 + ARRAY_SIZE(cs35l41_revb2_errata_patch)); 1459 + if (ret < 0) { 1460 + dev_err(cs35l41->dev, 1461 + "Failed to apply B2 errata patch %d\n", ret); 1462 + goto err; 1463 + } 1464 + break; 1465 + } 1466 + 1467 + irq_pol = cs35l41_irq_gpio_config(cs35l41); 1468 + 1469 + /* Set interrupt masks for critical errors */ 1470 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 1471 + CS35L41_INT1_MASK_DEFAULT); 1472 + 1473 + ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, 1474 + cs35l41_irq, IRQF_ONESHOT | IRQF_SHARED | irq_pol, 1475 + "cs35l41", cs35l41); 1476 + 1477 + /* CS35L41 needs INT for PDN_DONE */ 1478 + if (ret != 0) { 1479 + dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret); 1480 + ret = -ENODEV; 1481 + goto err; 1482 + } 1483 + 1484 + ret = cs35l41_otp_unpack(cs35l41); 1485 + if (ret < 0) { 1486 + dev_err(cs35l41->dev, "OTP Unpack failed\n"); 1487 + goto err; 1488 + } 1489 + 1490 + ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0); 1491 + if (ret < 0) { 1492 + dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed\n"); 1493 + goto err; 1494 + } 1495 + 1496 + ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, 1497 + CS35L41_AMP_EN_MASK, 0); 1498 + if (ret < 0) { 1499 + dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed\n"); 1500 + goto err; 1501 + } 1502 + 1503 + ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL, 1504 + CS35L41_AMP_GAIN_PCM_MASK, 0); 1505 + if (ret < 0) { 1506 + dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed\n"); 1507 + goto err; 1508 + } 1509 + 1510 + ret = cs35l41_set_pdata(cs35l41); 1511 + if (ret < 0) { 1512 + dev_err(cs35l41->dev, "%s: Set pdata failed\n", __func__); 1513 + goto err; 1514 + } 1515 + 1516 + ret = devm_snd_soc_register_component(cs35l41->dev, 1517 + &soc_component_dev_cs35l41, 1518 + cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); 1519 + if (ret < 0) { 1520 + dev_err(cs35l41->dev, "%s: Register codec failed\n", __func__); 1521 + goto err; 1522 + } 1523 + 1524 + dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", 1525 + regid, reg_revid); 1526 + 1527 + return 0; 1528 + 1529 + err: 1530 + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); 1531 + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); 1532 + return ret; 1533 + } 1534 + 1535 + int cs35l41_remove(struct cs35l41_private *cs35l41) 1536 + { 1537 + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); 1538 + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); 1539 + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); 1540 + return 0; 1541 + } 1542 + 1543 + MODULE_DESCRIPTION("ASoC CS35L41 driver"); 1544 + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); 1545 + MODULE_LICENSE("GPL");
+775
sound/soc/codecs/cs35l41.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * cs35l41.h -- CS35L41 ALSA SoC audio driver 4 + * 5 + * Copyright 2017-2021 Cirrus Logic, Inc. 6 + * 7 + * Author: David Rhodes <david.rhodes@cirrus.com> 8 + */ 9 + 10 + #ifndef __CS35L41_H__ 11 + #define __CS35L41_H__ 12 + 13 + #include <linux/gpio/consumer.h> 14 + #include <linux/regmap.h> 15 + #include <linux/regulator/consumer.h> 16 + #include <sound/core.h> 17 + #include <sound/cs35l41.h> 18 + 19 + #define CS35L41_FIRSTREG 0x00000000 20 + #define CS35L41_LASTREG 0x03804FE8 21 + #define CS35L41_DEVID 0x00000000 22 + #define CS35L41_REVID 0x00000004 23 + #define CS35L41_FABID 0x00000008 24 + #define CS35L41_RELID 0x0000000C 25 + #define CS35L41_OTPID 0x00000010 26 + #define CS35L41_SFT_RESET 0x00000020 27 + #define CS35L41_TEST_KEY_CTL 0x00000040 28 + #define CS35L41_USER_KEY_CTL 0x00000044 29 + #define CS35L41_OTP_MEM0 0x00000400 30 + #define CS35L41_OTP_MEM31 0x0000047C 31 + #define CS35L41_OTP_CTRL0 0x00000500 32 + #define CS35L41_OTP_CTRL1 0x00000504 33 + #define CS35L41_OTP_CTRL3 0x00000508 34 + #define CS35L41_OTP_CTRL4 0x0000050C 35 + #define CS35L41_OTP_CTRL5 0x00000510 36 + #define CS35L41_OTP_CTRL6 0x00000514 37 + #define CS35L41_OTP_CTRL7 0x00000518 38 + #define CS35L41_OTP_CTRL8 0x0000051C 39 + #define CS35L41_PWR_CTRL1 0x00002014 40 + #define CS35L41_PWR_CTRL2 0x00002018 41 + #define CS35L41_PWR_CTRL3 0x0000201C 42 + #define CS35L41_CTRL_OVRRIDE 0x00002020 43 + #define CS35L41_AMP_OUT_MUTE 0x00002024 44 + #define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 45 + #define CS35L41_GPIO_PAD_CONTROL 0x0000242C 46 + #define CS35L41_JTAG_CONTROL 0x00002438 47 + #define CS35L41_PLL_CLK_CTRL 0x00002C04 48 + #define CS35L41_DSP_CLK_CTRL 0x00002C08 49 + #define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C 50 + #define CS35L41_DATA_FS_SEL 0x00002C10 51 + #define CS35L41_TST_FS_MON0 0x00002D10 52 + #define CS35L41_MDSYNC_EN 0x00003400 53 + #define CS35L41_MDSYNC_TX_ID 0x00003408 54 + #define CS35L41_MDSYNC_PWR_CTRL 0x0000340C 55 + #define CS35L41_MDSYNC_DATA_TX 0x00003410 56 + #define CS35L41_MDSYNC_TX_STATUS 0x00003414 57 + #define CS35L41_MDSYNC_DATA_RX 0x0000341C 58 + #define CS35L41_MDSYNC_RX_STATUS 0x00003420 59 + #define CS35L41_MDSYNC_ERR_STATUS 0x00003424 60 + #define CS35L41_MDSYNC_SYNC_PTE2 0x00003528 61 + #define CS35L41_MDSYNC_SYNC_PTE3 0x0000352C 62 + #define CS35L41_MDSYNC_SYNC_MSM_STATUS 0x0000353C 63 + #define CS35L41_BSTCVRT_VCTRL1 0x00003800 64 + #define CS35L41_BSTCVRT_VCTRL2 0x00003804 65 + #define CS35L41_BSTCVRT_PEAK_CUR 0x00003808 66 + #define CS35L41_BSTCVRT_SFT_RAMP 0x0000380C 67 + #define CS35L41_BSTCVRT_COEFF 0x00003810 68 + #define CS35L41_BSTCVRT_SLOPE_LBST 0x00003814 69 + #define CS35L41_BSTCVRT_SW_FREQ 0x00003818 70 + #define CS35L41_BSTCVRT_DCM_CTRL 0x0000381C 71 + #define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820 72 + #define CS35L41_BSTCVRT_OVERVOLT_CTRL 0x00003830 73 + #define CS35L41_VI_VOL_POL 0x00004000 74 + #define CS35L41_VIMON_SPKMON_RESYNC 0x00004100 75 + #define CS35L41_DTEMP_WARN_THLD 0x00004220 76 + #define CS35L41_DTEMP_CFG 0x00004224 77 + #define CS35L41_DTEMP_EN 0x00004308 78 + #define CS35L41_VPVBST_FS_SEL 0x00004400 79 + #define CS35L41_SP_ENABLES 0x00004800 80 + #define CS35L41_SP_RATE_CTRL 0x00004804 81 + #define CS35L41_SP_FORMAT 0x00004808 82 + #define CS35L41_SP_HIZ_CTRL 0x0000480C 83 + #define CS35L41_SP_FRAME_TX_SLOT 0x00004810 84 + #define CS35L41_SP_FRAME_RX_SLOT 0x00004820 85 + #define CS35L41_SP_TX_WL 0x00004830 86 + #define CS35L41_SP_RX_WL 0x00004840 87 + #define CS35L41_ASP_CONTROL4 0x00004854 88 + #define CS35L41_DAC_PCM1_SRC 0x00004C00 89 + #define CS35L41_ASP_TX1_SRC 0x00004C20 90 + #define CS35L41_ASP_TX2_SRC 0x00004C24 91 + #define CS35L41_ASP_TX3_SRC 0x00004C28 92 + #define CS35L41_ASP_TX4_SRC 0x00004C2C 93 + #define CS35L41_DSP1_RX1_SRC 0x00004C40 94 + #define CS35L41_DSP1_RX2_SRC 0x00004C44 95 + #define CS35L41_DSP1_RX3_SRC 0x00004C48 96 + #define CS35L41_DSP1_RX4_SRC 0x00004C4C 97 + #define CS35L41_DSP1_RX5_SRC 0x00004C50 98 + #define CS35L41_DSP1_RX6_SRC 0x00004C54 99 + #define CS35L41_DSP1_RX7_SRC 0x00004C58 100 + #define CS35L41_DSP1_RX8_SRC 0x00004C5C 101 + #define CS35L41_NGATE1_SRC 0x00004C60 102 + #define CS35L41_NGATE2_SRC 0x00004C64 103 + #define CS35L41_AMP_DIG_VOL_CTRL 0x00006000 104 + #define CS35L41_VPBR_CFG 0x00006404 105 + #define CS35L41_VBBR_CFG 0x00006408 106 + #define CS35L41_VPBR_STATUS 0x0000640C 107 + #define CS35L41_VBBR_STATUS 0x00006410 108 + #define CS35L41_OVERTEMP_CFG 0x00006414 109 + #define CS35L41_AMP_ERR_VOL 0x00006418 110 + #define CS35L41_VOL_STATUS_TO_DSP 0x00006450 111 + #define CS35L41_CLASSH_CFG 0x00006800 112 + #define CS35L41_WKFET_CFG 0x00006804 113 + #define CS35L41_NG_CFG 0x00006808 114 + #define CS35L41_AMP_GAIN_CTRL 0x00006C04 115 + #define CS35L41_DAC_MSM_CFG 0x00007400 116 + #define CS35L41_IRQ1_CFG 0x00010000 117 + #define CS35L41_IRQ1_STATUS 0x00010004 118 + #define CS35L41_IRQ1_STATUS1 0x00010010 119 + #define CS35L41_IRQ1_STATUS2 0x00010014 120 + #define CS35L41_IRQ1_STATUS3 0x00010018 121 + #define CS35L41_IRQ1_STATUS4 0x0001001C 122 + #define CS35L41_IRQ1_RAW_STATUS1 0x00010090 123 + #define CS35L41_IRQ1_RAW_STATUS2 0x00010094 124 + #define CS35L41_IRQ1_RAW_STATUS3 0x00010098 125 + #define CS35L41_IRQ1_RAW_STATUS4 0x0001009C 126 + #define CS35L41_IRQ1_MASK1 0x00010110 127 + #define CS35L41_IRQ1_MASK2 0x00010114 128 + #define CS35L41_IRQ1_MASK3 0x00010118 129 + #define CS35L41_IRQ1_MASK4 0x0001011C 130 + #define CS35L41_IRQ1_FRC1 0x00010190 131 + #define CS35L41_IRQ1_FRC2 0x00010194 132 + #define CS35L41_IRQ1_FRC3 0x00010198 133 + #define CS35L41_IRQ1_FRC4 0x0001019C 134 + #define CS35L41_IRQ1_EDGE1 0x00010210 135 + #define CS35L41_IRQ1_EDGE4 0x0001021C 136 + #define CS35L41_IRQ1_POL1 0x00010290 137 + #define CS35L41_IRQ1_POL2 0x00010294 138 + #define CS35L41_IRQ1_POL3 0x00010298 139 + #define CS35L41_IRQ1_POL4 0x0001029C 140 + #define CS35L41_IRQ1_DB3 0x00010318 141 + #define CS35L41_IRQ2_CFG 0x00010800 142 + #define CS35L41_IRQ2_STATUS 0x00010804 143 + #define CS35L41_IRQ2_STATUS1 0x00010810 144 + #define CS35L41_IRQ2_STATUS2 0x00010814 145 + #define CS35L41_IRQ2_STATUS3 0x00010818 146 + #define CS35L41_IRQ2_STATUS4 0x0001081C 147 + #define CS35L41_IRQ2_RAW_STATUS1 0x00010890 148 + #define CS35L41_IRQ2_RAW_STATUS2 0x00010894 149 + #define CS35L41_IRQ2_RAW_STATUS3 0x00010898 150 + #define CS35L41_IRQ2_RAW_STATUS4 0x0001089C 151 + #define CS35L41_IRQ2_MASK1 0x00010910 152 + #define CS35L41_IRQ2_MASK2 0x00010914 153 + #define CS35L41_IRQ2_MASK3 0x00010918 154 + #define CS35L41_IRQ2_MASK4 0x0001091C 155 + #define CS35L41_IRQ2_FRC1 0x00010990 156 + #define CS35L41_IRQ2_FRC2 0x00010994 157 + #define CS35L41_IRQ2_FRC3 0x00010998 158 + #define CS35L41_IRQ2_FRC4 0x0001099C 159 + #define CS35L41_IRQ2_EDGE1 0x00010A10 160 + #define CS35L41_IRQ2_EDGE4 0x00010A1C 161 + #define CS35L41_IRQ2_POL1 0x00010A90 162 + #define CS35L41_IRQ2_POL2 0x00010A94 163 + #define CS35L41_IRQ2_POL3 0x00010A98 164 + #define CS35L41_IRQ2_POL4 0x00010A9C 165 + #define CS35L41_IRQ2_DB3 0x00010B18 166 + #define CS35L41_GPIO_STATUS1 0x00011000 167 + #define CS35L41_GPIO1_CTRL1 0x00011008 168 + #define CS35L41_GPIO2_CTRL1 0x0001100C 169 + #define CS35L41_MIXER_NGATE_CFG 0x00012000 170 + #define CS35L41_MIXER_NGATE_CH1_CFG 0x00012004 171 + #define CS35L41_MIXER_NGATE_CH2_CFG 0x00012008 172 + #define CS35L41_DSP_MBOX_1 0x00013000 173 + #define CS35L41_DSP_MBOX_2 0x00013004 174 + #define CS35L41_DSP_MBOX_3 0x00013008 175 + #define CS35L41_DSP_MBOX_4 0x0001300C 176 + #define CS35L41_DSP_MBOX_5 0x00013010 177 + #define CS35L41_DSP_MBOX_6 0x00013014 178 + #define CS35L41_DSP_MBOX_7 0x00013018 179 + #define CS35L41_DSP_MBOX_8 0x0001301C 180 + #define CS35L41_DSP_VIRT1_MBOX_1 0x00013020 181 + #define CS35L41_DSP_VIRT1_MBOX_2 0x00013024 182 + #define CS35L41_DSP_VIRT1_MBOX_3 0x00013028 183 + #define CS35L41_DSP_VIRT1_MBOX_4 0x0001302C 184 + #define CS35L41_DSP_VIRT1_MBOX_5 0x00013030 185 + #define CS35L41_DSP_VIRT1_MBOX_6 0x00013034 186 + #define CS35L41_DSP_VIRT1_MBOX_7 0x00013038 187 + #define CS35L41_DSP_VIRT1_MBOX_8 0x0001303C 188 + #define CS35L41_DSP_VIRT2_MBOX_1 0x00013040 189 + #define CS35L41_DSP_VIRT2_MBOX_2 0x00013044 190 + #define CS35L41_DSP_VIRT2_MBOX_3 0x00013048 191 + #define CS35L41_DSP_VIRT2_MBOX_4 0x0001304C 192 + #define CS35L41_DSP_VIRT2_MBOX_5 0x00013050 193 + #define CS35L41_DSP_VIRT2_MBOX_6 0x00013054 194 + #define CS35L41_DSP_VIRT2_MBOX_7 0x00013058 195 + #define CS35L41_DSP_VIRT2_MBOX_8 0x0001305C 196 + #define CS35L41_CLOCK_DETECT_1 0x00014000 197 + #define CS35L41_TIMER1_CONTROL 0x00015000 198 + #define CS35L41_TIMER1_COUNT_PRESET 0x00015004 199 + #define CS35L41_TIMER1_START_STOP 0x0001500C 200 + #define CS35L41_TIMER1_STATUS 0x00015010 201 + #define CS35L41_TIMER1_COUNT_READBACK 0x00015014 202 + #define CS35L41_TIMER1_DSP_CLK_CFG 0x00015018 203 + #define CS35L41_TIMER1_DSP_CLK_STATUS 0x0001501C 204 + #define CS35L41_TIMER2_CONTROL 0x00015100 205 + #define CS35L41_TIMER2_COUNT_PRESET 0x00015104 206 + #define CS35L41_TIMER2_START_STOP 0x0001510C 207 + #define CS35L41_TIMER2_STATUS 0x00015110 208 + #define CS35L41_TIMER2_COUNT_READBACK 0x00015114 209 + #define CS35L41_TIMER2_DSP_CLK_CFG 0x00015118 210 + #define CS35L41_TIMER2_DSP_CLK_STATUS 0x0001511C 211 + #define CS35L41_DFT_JTAG_CONTROL 0x00016000 212 + #define CS35L41_DIE_STS1 0x00017040 213 + #define CS35L41_DIE_STS2 0x00017044 214 + #define CS35L41_TEMP_CAL1 0x00017048 215 + #define CS35L41_TEMP_CAL2 0x0001704C 216 + #define CS35L41_DSP1_XMEM_PACK_0 0x02000000 217 + #define CS35L41_DSP1_XMEM_PACK_3068 0x02002FF0 218 + #define CS35L41_DSP1_XMEM_UNPACK32_0 0x02400000 219 + #define CS35L41_DSP1_XMEM_UNPACK32_2046 0x02401FF8 220 + #define CS35L41_DSP1_TIMESTAMP_COUNT 0x025C0800 221 + #define CS35L41_DSP1_SYS_ID 0x025E0000 222 + #define CS35L41_DSP1_SYS_VERSION 0x025E0004 223 + #define CS35L41_DSP1_SYS_CORE_ID 0x025E0008 224 + #define CS35L41_DSP1_SYS_AHB_ADDR 0x025E000C 225 + #define CS35L41_DSP1_SYS_XSRAM_SIZE 0x025E0010 226 + #define CS35L41_DSP1_SYS_YSRAM_SIZE 0x025E0018 227 + #define CS35L41_DSP1_SYS_PSRAM_SIZE 0x025E0020 228 + #define CS35L41_DSP1_SYS_PM_BOOT_SIZE 0x025E0028 229 + #define CS35L41_DSP1_SYS_FEATURES 0x025E002C 230 + #define CS35L41_DSP1_SYS_FIR_FILTERS 0x025E0030 231 + #define CS35L41_DSP1_SYS_LMS_FILTERS 0x025E0034 232 + #define CS35L41_DSP1_SYS_XM_BANK_SIZE 0x025E0038 233 + #define CS35L41_DSP1_SYS_YM_BANK_SIZE 0x025E003C 234 + #define CS35L41_DSP1_SYS_PM_BANK_SIZE 0x025E0040 235 + #define CS35L41_DSP1_AHBM_WIN0_CTRL0 0x025E2000 236 + #define CS35L41_DSP1_AHBM_WIN0_CTRL1 0x025E2004 237 + #define CS35L41_DSP1_AHBM_WIN1_CTRL0 0x025E2008 238 + #define CS35L41_DSP1_AHBM_WIN1_CTRL1 0x025E200C 239 + #define CS35L41_DSP1_AHBM_WIN2_CTRL0 0x025E2010 240 + #define CS35L41_DSP1_AHBM_WIN2_CTRL1 0x025E2014 241 + #define CS35L41_DSP1_AHBM_WIN3_CTRL0 0x025E2018 242 + #define CS35L41_DSP1_AHBM_WIN3_CTRL1 0x025E201C 243 + #define CS35L41_DSP1_AHBM_WIN4_CTRL0 0x025E2020 244 + #define CS35L41_DSP1_AHBM_WIN4_CTRL1 0x025E2024 245 + #define CS35L41_DSP1_AHBM_WIN5_CTRL0 0x025E2028 246 + #define CS35L41_DSP1_AHBM_WIN5_CTRL1 0x025E202C 247 + #define CS35L41_DSP1_AHBM_WIN6_CTRL0 0x025E2030 248 + #define CS35L41_DSP1_AHBM_WIN6_CTRL1 0x025E2034 249 + #define CS35L41_DSP1_AHBM_WIN7_CTRL0 0x025E2038 250 + #define CS35L41_DSP1_AHBM_WIN7_CTRL1 0x025E203C 251 + #define CS35L41_DSP1_AHBM_WIN_DBG_CTRL0 0x025E2040 252 + #define CS35L41_DSP1_AHBM_WIN_DBG_CTRL1 0x025E2044 253 + #define CS35L41_DSP1_XMEM_UNPACK24_0 0x02800000 254 + #define CS35L41_DSP1_XMEM_UNPACK24_4093 0x02803FF4 255 + #define CS35L41_DSP1_CTRL_BASE 0x02B80000 256 + #define CS35L41_DSP1_CORE_SOFT_RESET 0x02B80010 257 + #define CS35L41_DSP1_DEBUG 0x02B80040 258 + #define CS35L41_DSP1_TIMER_CTRL 0x02B80048 259 + #define CS35L41_DSP1_STREAM_ARB_CTRL 0x02B80050 260 + #define CS35L41_DSP1_RX1_RATE 0x02B80080 261 + #define CS35L41_DSP1_RX2_RATE 0x02B80088 262 + #define CS35L41_DSP1_RX3_RATE 0x02B80090 263 + #define CS35L41_DSP1_RX4_RATE 0x02B80098 264 + #define CS35L41_DSP1_RX5_RATE 0x02B800A0 265 + #define CS35L41_DSP1_RX6_RATE 0x02B800A8 266 + #define CS35L41_DSP1_RX7_RATE 0x02B800B0 267 + #define CS35L41_DSP1_RX8_RATE 0x02B800B8 268 + #define CS35L41_DSP1_TX1_RATE 0x02B80280 269 + #define CS35L41_DSP1_TX2_RATE 0x02B80288 270 + #define CS35L41_DSP1_TX3_RATE 0x02B80290 271 + #define CS35L41_DSP1_TX4_RATE 0x02B80298 272 + #define CS35L41_DSP1_TX5_RATE 0x02B802A0 273 + #define CS35L41_DSP1_TX6_RATE 0x02B802A8 274 + #define CS35L41_DSP1_TX7_RATE 0x02B802B0 275 + #define CS35L41_DSP1_TX8_RATE 0x02B802B8 276 + #define CS35L41_DSP1_NMI_CTRL1 0x02B80480 277 + #define CS35L41_DSP1_NMI_CTRL2 0x02B80488 278 + #define CS35L41_DSP1_NMI_CTRL3 0x02B80490 279 + #define CS35L41_DSP1_NMI_CTRL4 0x02B80498 280 + #define CS35L41_DSP1_NMI_CTRL5 0x02B804A0 281 + #define CS35L41_DSP1_NMI_CTRL6 0x02B804A8 282 + #define CS35L41_DSP1_NMI_CTRL7 0x02B804B0 283 + #define CS35L41_DSP1_NMI_CTRL8 0x02B804B8 284 + #define CS35L41_DSP1_RESUME_CTRL 0x02B80500 285 + #define CS35L41_DSP1_IRQ1_CTRL 0x02B80508 286 + #define CS35L41_DSP1_IRQ2_CTRL 0x02B80510 287 + #define CS35L41_DSP1_IRQ3_CTRL 0x02B80518 288 + #define CS35L41_DSP1_IRQ4_CTRL 0x02B80520 289 + #define CS35L41_DSP1_IRQ5_CTRL 0x02B80528 290 + #define CS35L41_DSP1_IRQ6_CTRL 0x02B80530 291 + #define CS35L41_DSP1_IRQ7_CTRL 0x02B80538 292 + #define CS35L41_DSP1_IRQ8_CTRL 0x02B80540 293 + #define CS35L41_DSP1_IRQ9_CTRL 0x02B80548 294 + #define CS35L41_DSP1_IRQ10_CTRL 0x02B80550 295 + #define CS35L41_DSP1_IRQ11_CTRL 0x02B80558 296 + #define CS35L41_DSP1_IRQ12_CTRL 0x02B80560 297 + #define CS35L41_DSP1_IRQ13_CTRL 0x02B80568 298 + #define CS35L41_DSP1_IRQ14_CTRL 0x02B80570 299 + #define CS35L41_DSP1_IRQ15_CTRL 0x02B80578 300 + #define CS35L41_DSP1_IRQ16_CTRL 0x02B80580 301 + #define CS35L41_DSP1_IRQ17_CTRL 0x02B80588 302 + #define CS35L41_DSP1_IRQ18_CTRL 0x02B80590 303 + #define CS35L41_DSP1_IRQ19_CTRL 0x02B80598 304 + #define CS35L41_DSP1_IRQ20_CTRL 0x02B805A0 305 + #define CS35L41_DSP1_IRQ21_CTRL 0x02B805A8 306 + #define CS35L41_DSP1_IRQ22_CTRL 0x02B805B0 307 + #define CS35L41_DSP1_IRQ23_CTRL 0x02B805B8 308 + #define CS35L41_DSP1_SCRATCH1 0x02B805C0 309 + #define CS35L41_DSP1_SCRATCH2 0x02B805C8 310 + #define CS35L41_DSP1_SCRATCH3 0x02B805D0 311 + #define CS35L41_DSP1_SCRATCH4 0x02B805D8 312 + #define CS35L41_DSP1_CCM_CORE_CTRL 0x02BC1000 313 + #define CS35L41_DSP1_CCM_CLK_OVERRIDE 0x02BC1008 314 + #define CS35L41_DSP1_XM_MSTR_EN 0x02BC2000 315 + #define CS35L41_DSP1_XM_CORE_PRI 0x02BC2008 316 + #define CS35L41_DSP1_XM_AHB_PACK_PL_PRI 0x02BC2010 317 + #define CS35L41_DSP1_XM_AHB_UP_PL_PRI 0x02BC2018 318 + #define CS35L41_DSP1_XM_ACCEL_PL0_PRI 0x02BC2020 319 + #define CS35L41_DSP1_XM_NPL0_PRI 0x02BC2078 320 + #define CS35L41_DSP1_YM_MSTR_EN 0x02BC20C0 321 + #define CS35L41_DSP1_YM_CORE_PRI 0x02BC20C8 322 + #define CS35L41_DSP1_YM_AHB_PACK_PL_PRI 0x02BC20D0 323 + #define CS35L41_DSP1_YM_AHB_UP_PL_PRI 0x02BC20D8 324 + #define CS35L41_DSP1_YM_ACCEL_PL0_PRI 0x02BC20E0 325 + #define CS35L41_DSP1_YM_NPL0_PRI 0x02BC2138 326 + #define CS35L41_DSP1_PM_MSTR_EN 0x02BC2180 327 + #define CS35L41_DSP1_PM_PATCH0_ADDR 0x02BC2188 328 + #define CS35L41_DSP1_PM_PATCH0_EN 0x02BC218C 329 + #define CS35L41_DSP1_PM_PATCH0_DATA_LO 0x02BC2190 330 + #define CS35L41_DSP1_PM_PATCH0_DATA_HI 0x02BC2194 331 + #define CS35L41_DSP1_PM_PATCH1_ADDR 0x02BC2198 332 + #define CS35L41_DSP1_PM_PATCH1_EN 0x02BC219C 333 + #define CS35L41_DSP1_PM_PATCH1_DATA_LO 0x02BC21A0 334 + #define CS35L41_DSP1_PM_PATCH1_DATA_HI 0x02BC21A4 335 + #define CS35L41_DSP1_PM_PATCH2_ADDR 0x02BC21A8 336 + #define CS35L41_DSP1_PM_PATCH2_EN 0x02BC21AC 337 + #define CS35L41_DSP1_PM_PATCH2_DATA_LO 0x02BC21B0 338 + #define CS35L41_DSP1_PM_PATCH2_DATA_HI 0x02BC21B4 339 + #define CS35L41_DSP1_PM_PATCH3_ADDR 0x02BC21B8 340 + #define CS35L41_DSP1_PM_PATCH3_EN 0x02BC21BC 341 + #define CS35L41_DSP1_PM_PATCH3_DATA_LO 0x02BC21C0 342 + #define CS35L41_DSP1_PM_PATCH3_DATA_HI 0x02BC21C4 343 + #define CS35L41_DSP1_PM_PATCH4_ADDR 0x02BC21C8 344 + #define CS35L41_DSP1_PM_PATCH4_EN 0x02BC21CC 345 + #define CS35L41_DSP1_PM_PATCH4_DATA_LO 0x02BC21D0 346 + #define CS35L41_DSP1_PM_PATCH4_DATA_HI 0x02BC21D4 347 + #define CS35L41_DSP1_PM_PATCH5_ADDR 0x02BC21D8 348 + #define CS35L41_DSP1_PM_PATCH5_EN 0x02BC21DC 349 + #define CS35L41_DSP1_PM_PATCH5_DATA_LO 0x02BC21E0 350 + #define CS35L41_DSP1_PM_PATCH5_DATA_HI 0x02BC21E4 351 + #define CS35L41_DSP1_PM_PATCH6_ADDR 0x02BC21E8 352 + #define CS35L41_DSP1_PM_PATCH6_EN 0x02BC21EC 353 + #define CS35L41_DSP1_PM_PATCH6_DATA_LO 0x02BC21F0 354 + #define CS35L41_DSP1_PM_PATCH6_DATA_HI 0x02BC21F4 355 + #define CS35L41_DSP1_PM_PATCH7_ADDR 0x02BC21F8 356 + #define CS35L41_DSP1_PM_PATCH7_EN 0x02BC21FC 357 + #define CS35L41_DSP1_PM_PATCH7_DATA_LO 0x02BC2200 358 + #define CS35L41_DSP1_PM_PATCH7_DATA_HI 0x02BC2204 359 + #define CS35L41_DSP1_MPU_XM_ACCESS0 0x02BC3000 360 + #define CS35L41_DSP1_MPU_YM_ACCESS0 0x02BC3004 361 + #define CS35L41_DSP1_MPU_WNDW_ACCESS0 0x02BC3008 362 + #define CS35L41_DSP1_MPU_XREG_ACCESS0 0x02BC300C 363 + #define CS35L41_DSP1_MPU_YREG_ACCESS0 0x02BC3014 364 + #define CS35L41_DSP1_MPU_XM_ACCESS1 0x02BC3018 365 + #define CS35L41_DSP1_MPU_YM_ACCESS1 0x02BC301C 366 + #define CS35L41_DSP1_MPU_WNDW_ACCESS1 0x02BC3020 367 + #define CS35L41_DSP1_MPU_XREG_ACCESS1 0x02BC3024 368 + #define CS35L41_DSP1_MPU_YREG_ACCESS1 0x02BC302C 369 + #define CS35L41_DSP1_MPU_XM_ACCESS2 0x02BC3030 370 + #define CS35L41_DSP1_MPU_YM_ACCESS2 0x02BC3034 371 + #define CS35L41_DSP1_MPU_WNDW_ACCESS2 0x02BC3038 372 + #define CS35L41_DSP1_MPU_XREG_ACCESS2 0x02BC303C 373 + #define CS35L41_DSP1_MPU_YREG_ACCESS2 0x02BC3044 374 + #define CS35L41_DSP1_MPU_XM_ACCESS3 0x02BC3048 375 + #define CS35L41_DSP1_MPU_YM_ACCESS3 0x02BC304C 376 + #define CS35L41_DSP1_MPU_WNDW_ACCESS3 0x02BC3050 377 + #define CS35L41_DSP1_MPU_XREG_ACCESS3 0x02BC3054 378 + #define CS35L41_DSP1_MPU_YREG_ACCESS3 0x02BC305C 379 + #define CS35L41_DSP1_MPU_XM_VIO_ADDR 0x02BC3100 380 + #define CS35L41_DSP1_MPU_XM_VIO_STATUS 0x02BC3104 381 + #define CS35L41_DSP1_MPU_YM_VIO_ADDR 0x02BC3108 382 + #define CS35L41_DSP1_MPU_YM_VIO_STATUS 0x02BC310C 383 + #define CS35L41_DSP1_MPU_PM_VIO_ADDR 0x02BC3110 384 + #define CS35L41_DSP1_MPU_PM_VIO_STATUS 0x02BC3114 385 + #define CS35L41_DSP1_MPU_LOCK_CONFIG 0x02BC3140 386 + #define CS35L41_DSP1_MPU_WDT_RST_CTRL 0x02BC3180 387 + #define CS35L41_DSP1_STRMARB_MSTR0_CFG0 0x02BC5000 388 + #define CS35L41_DSP1_STRMARB_MSTR0_CFG1 0x02BC5004 389 + #define CS35L41_DSP1_STRMARB_MSTR0_CFG2 0x02BC5008 390 + #define CS35L41_DSP1_STRMARB_MSTR1_CFG0 0x02BC5010 391 + #define CS35L41_DSP1_STRMARB_MSTR1_CFG1 0x02BC5014 392 + #define CS35L41_DSP1_STRMARB_MSTR1_CFG2 0x02BC5018 393 + #define CS35L41_DSP1_STRMARB_MSTR2_CFG0 0x02BC5020 394 + #define CS35L41_DSP1_STRMARB_MSTR2_CFG1 0x02BC5024 395 + #define CS35L41_DSP1_STRMARB_MSTR2_CFG2 0x02BC5028 396 + #define CS35L41_DSP1_STRMARB_MSTR3_CFG0 0x02BC5030 397 + #define CS35L41_DSP1_STRMARB_MSTR3_CFG1 0x02BC5034 398 + #define CS35L41_DSP1_STRMARB_MSTR3_CFG2 0x02BC5038 399 + #define CS35L41_DSP1_STRMARB_MSTR4_CFG0 0x02BC5040 400 + #define CS35L41_DSP1_STRMARB_MSTR4_CFG1 0x02BC5044 401 + #define CS35L41_DSP1_STRMARB_MSTR4_CFG2 0x02BC5048 402 + #define CS35L41_DSP1_STRMARB_MSTR5_CFG0 0x02BC5050 403 + #define CS35L41_DSP1_STRMARB_MSTR5_CFG1 0x02BC5054 404 + #define CS35L41_DSP1_STRMARB_MSTR5_CFG2 0x02BC5058 405 + #define CS35L41_DSP1_STRMARB_MSTR6_CFG0 0x02BC5060 406 + #define CS35L41_DSP1_STRMARB_MSTR6_CFG1 0x02BC5064 407 + #define CS35L41_DSP1_STRMARB_MSTR6_CFG2 0x02BC5068 408 + #define CS35L41_DSP1_STRMARB_MSTR7_CFG0 0x02BC5070 409 + #define CS35L41_DSP1_STRMARB_MSTR7_CFG1 0x02BC5074 410 + #define CS35L41_DSP1_STRMARB_MSTR7_CFG2 0x02BC5078 411 + #define CS35L41_DSP1_STRMARB_TX0_CFG0 0x02BC5200 412 + #define CS35L41_DSP1_STRMARB_TX0_CFG1 0x02BC5204 413 + #define CS35L41_DSP1_STRMARB_TX1_CFG0 0x02BC5208 414 + #define CS35L41_DSP1_STRMARB_TX1_CFG1 0x02BC520C 415 + #define CS35L41_DSP1_STRMARB_TX2_CFG0 0x02BC5210 416 + #define CS35L41_DSP1_STRMARB_TX2_CFG1 0x02BC5214 417 + #define CS35L41_DSP1_STRMARB_TX3_CFG0 0x02BC5218 418 + #define CS35L41_DSP1_STRMARB_TX3_CFG1 0x02BC521C 419 + #define CS35L41_DSP1_STRMARB_TX4_CFG0 0x02BC5220 420 + #define CS35L41_DSP1_STRMARB_TX4_CFG1 0x02BC5224 421 + #define CS35L41_DSP1_STRMARB_TX5_CFG0 0x02BC5228 422 + #define CS35L41_DSP1_STRMARB_TX5_CFG1 0x02BC522C 423 + #define CS35L41_DSP1_STRMARB_TX6_CFG0 0x02BC5230 424 + #define CS35L41_DSP1_STRMARB_TX6_CFG1 0x02BC5234 425 + #define CS35L41_DSP1_STRMARB_TX7_CFG0 0x02BC5238 426 + #define CS35L41_DSP1_STRMARB_TX7_CFG1 0x02BC523C 427 + #define CS35L41_DSP1_STRMARB_RX0_CFG0 0x02BC5400 428 + #define CS35L41_DSP1_STRMARB_RX0_CFG1 0x02BC5404 429 + #define CS35L41_DSP1_STRMARB_RX1_CFG0 0x02BC5408 430 + #define CS35L41_DSP1_STRMARB_RX1_CFG1 0x02BC540C 431 + #define CS35L41_DSP1_STRMARB_RX2_CFG0 0x02BC5410 432 + #define CS35L41_DSP1_STRMARB_RX2_CFG1 0x02BC5414 433 + #define CS35L41_DSP1_STRMARB_RX3_CFG0 0x02BC5418 434 + #define CS35L41_DSP1_STRMARB_RX3_CFG1 0x02BC541C 435 + #define CS35L41_DSP1_STRMARB_RX4_CFG0 0x02BC5420 436 + #define CS35L41_DSP1_STRMARB_RX4_CFG1 0x02BC5424 437 + #define CS35L41_DSP1_STRMARB_RX5_CFG0 0x02BC5428 438 + #define CS35L41_DSP1_STRMARB_RX5_CFG1 0x02BC542C 439 + #define CS35L41_DSP1_STRMARB_RX6_CFG0 0x02BC5430 440 + #define CS35L41_DSP1_STRMARB_RX6_CFG1 0x02BC5434 441 + #define CS35L41_DSP1_STRMARB_RX7_CFG0 0x02BC5438 442 + #define CS35L41_DSP1_STRMARB_RX7_CFG1 0x02BC543C 443 + #define CS35L41_DSP1_STRMARB_IRQ0_CFG0 0x02BC5600 444 + #define CS35L41_DSP1_STRMARB_IRQ0_CFG1 0x02BC5604 445 + #define CS35L41_DSP1_STRMARB_IRQ0_CFG2 0x02BC5608 446 + #define CS35L41_DSP1_STRMARB_IRQ1_CFG0 0x02BC5610 447 + #define CS35L41_DSP1_STRMARB_IRQ1_CFG1 0x02BC5614 448 + #define CS35L41_DSP1_STRMARB_IRQ1_CFG2 0x02BC5618 449 + #define CS35L41_DSP1_STRMARB_IRQ2_CFG0 0x02BC5620 450 + #define CS35L41_DSP1_STRMARB_IRQ2_CFG1 0x02BC5624 451 + #define CS35L41_DSP1_STRMARB_IRQ2_CFG2 0x02BC5628 452 + #define CS35L41_DSP1_STRMARB_IRQ3_CFG0 0x02BC5630 453 + #define CS35L41_DSP1_STRMARB_IRQ3_CFG1 0x02BC5634 454 + #define CS35L41_DSP1_STRMARB_IRQ3_CFG2 0x02BC5638 455 + #define CS35L41_DSP1_STRMARB_IRQ4_CFG0 0x02BC5640 456 + #define CS35L41_DSP1_STRMARB_IRQ4_CFG1 0x02BC5644 457 + #define CS35L41_DSP1_STRMARB_IRQ4_CFG2 0x02BC5648 458 + #define CS35L41_DSP1_STRMARB_IRQ5_CFG0 0x02BC5650 459 + #define CS35L41_DSP1_STRMARB_IRQ5_CFG1 0x02BC5654 460 + #define CS35L41_DSP1_STRMARB_IRQ5_CFG2 0x02BC5658 461 + #define CS35L41_DSP1_STRMARB_IRQ6_CFG0 0x02BC5660 462 + #define CS35L41_DSP1_STRMARB_IRQ6_CFG1 0x02BC5664 463 + #define CS35L41_DSP1_STRMARB_IRQ6_CFG2 0x02BC5668 464 + #define CS35L41_DSP1_STRMARB_IRQ7_CFG0 0x02BC5670 465 + #define CS35L41_DSP1_STRMARB_IRQ7_CFG1 0x02BC5674 466 + #define CS35L41_DSP1_STRMARB_IRQ7_CFG2 0x02BC5678 467 + #define CS35L41_DSP1_STRMARB_RESYNC_MSK 0x02BC5A00 468 + #define CS35L41_DSP1_STRMARB_ERR_STATUS 0x02BC5A08 469 + #define CS35L41_DSP1_INTPCTL_RES_STATIC 0x02BC6000 470 + #define CS35L41_DSP1_INTPCTL_RES_DYN 0x02BC6004 471 + #define CS35L41_DSP1_INTPCTL_NMI_CTRL 0x02BC6008 472 + #define CS35L41_DSP1_INTPCTL_IRQ_INV 0x02BC6010 473 + #define CS35L41_DSP1_INTPCTL_IRQ_MODE 0x02BC6014 474 + #define CS35L41_DSP1_INTPCTL_IRQ_EN 0x02BC6018 475 + #define CS35L41_DSP1_INTPCTL_IRQ_MSK 0x02BC601C 476 + #define CS35L41_DSP1_INTPCTL_IRQ_FLUSH 0x02BC6020 477 + #define CS35L41_DSP1_INTPCTL_IRQ_MSKCLR 0x02BC6024 478 + #define CS35L41_DSP1_INTPCTL_IRQ_FRC 0x02BC6028 479 + #define CS35L41_DSP1_INTPCTL_IRQ_MSKSET 0x02BC602C 480 + #define CS35L41_DSP1_INTPCTL_IRQ_ERR 0x02BC6030 481 + #define CS35L41_DSP1_INTPCTL_IRQ_PEND 0x02BC6034 482 + #define CS35L41_DSP1_INTPCTL_IRQ_GEN 0x02BC6038 483 + #define CS35L41_DSP1_INTPCTL_TESTBITS 0x02BC6040 484 + #define CS35L41_DSP1_WDT_CONTROL 0x02BC7000 485 + #define CS35L41_DSP1_WDT_STATUS 0x02BC7008 486 + #define CS35L41_DSP1_YMEM_PACK_0 0x02C00000 487 + #define CS35L41_DSP1_YMEM_PACK_1532 0x02C017F0 488 + #define CS35L41_DSP1_YMEM_UNPACK32_0 0x03000000 489 + #define CS35L41_DSP1_YMEM_UNPACK32_1022 0x03000FF8 490 + #define CS35L41_DSP1_YMEM_UNPACK24_0 0x03400000 491 + #define CS35L41_DSP1_YMEM_UNPACK24_2045 0x03401FF4 492 + #define CS35L41_DSP1_PMEM_0 0x03800000 493 + #define CS35L41_DSP1_PMEM_5114 0x03804FE8 494 + 495 + /*test regs for emulation bringup*/ 496 + #define CS35L41_PLL_OVR 0x00003018 497 + #define CS35L41_BST_TEST_DUTY 0x00003900 498 + #define CS35L41_DIGPWM_IOCTRL 0x0000706C 499 + 500 + /*registers populated by OTP*/ 501 + #define CS35L41_OTP_TRIM_1 0x0000208c 502 + #define CS35L41_OTP_TRIM_2 0x00002090 503 + #define CS35L41_OTP_TRIM_3 0x00003010 504 + #define CS35L41_OTP_TRIM_4 0x0000300C 505 + #define CS35L41_OTP_TRIM_5 0x0000394C 506 + #define CS35L41_OTP_TRIM_6 0x00003950 507 + #define CS35L41_OTP_TRIM_7 0x00003954 508 + #define CS35L41_OTP_TRIM_8 0x00003958 509 + #define CS35L41_OTP_TRIM_9 0x0000395C 510 + #define CS35L41_OTP_TRIM_10 0x0000416C 511 + #define CS35L41_OTP_TRIM_11 0x00004160 512 + #define CS35L41_OTP_TRIM_12 0x00004170 513 + #define CS35L41_OTP_TRIM_13 0x00004360 514 + #define CS35L41_OTP_TRIM_14 0x00004448 515 + #define CS35L41_OTP_TRIM_15 0x0000444C 516 + #define CS35L41_OTP_TRIM_16 0x00006E30 517 + #define CS35L41_OTP_TRIM_17 0x00006E34 518 + #define CS35L41_OTP_TRIM_18 0x00006E38 519 + #define CS35L41_OTP_TRIM_19 0x00006E3C 520 + #define CS35L41_OTP_TRIM_20 0x00006E40 521 + #define CS35L41_OTP_TRIM_21 0x00006E44 522 + #define CS35L41_OTP_TRIM_22 0x00006E48 523 + #define CS35L41_OTP_TRIM_23 0x00006E4C 524 + #define CS35L41_OTP_TRIM_24 0x00006E50 525 + #define CS35L41_OTP_TRIM_25 0x00006E54 526 + #define CS35L41_OTP_TRIM_26 0x00006E58 527 + #define CS35L41_OTP_TRIM_27 0x00006E5C 528 + #define CS35L41_OTP_TRIM_28 0x00006E60 529 + #define CS35L41_OTP_TRIM_29 0x00006E64 530 + #define CS35L41_OTP_TRIM_30 0x00007418 531 + #define CS35L41_OTP_TRIM_31 0x0000741C 532 + #define CS35L41_OTP_TRIM_32 0x00007434 533 + #define CS35L41_OTP_TRIM_33 0x00007068 534 + #define CS35L41_OTP_TRIM_34 0x0000410C 535 + #define CS35L41_OTP_TRIM_35 0x0000400C 536 + #define CS35L41_OTP_TRIM_36 0x00002030 537 + 538 + #define CS35L41_MAX_CACHE_REG 36 539 + #define CS35L41_OTP_SIZE_WORDS 32 540 + #define CS35L41_NUM_OTP_ELEM 100 541 + #define CS35L41_NUM_OTP_MAPS 5 542 + 543 + #define CS35L41_VALID_PDATA 0x80000000 544 + #define CS35L41_NUM_SUPPLIES 2 545 + 546 + #define CS35L41_SCLK_MSTR_MASK 0x10 547 + #define CS35L41_SCLK_MSTR_SHIFT 4 548 + #define CS35L41_LRCLK_MSTR_MASK 0x01 549 + #define CS35L41_LRCLK_MSTR_SHIFT 0 550 + #define CS35L41_SCLK_INV_MASK 0x40 551 + #define CS35L41_SCLK_INV_SHIFT 6 552 + #define CS35L41_LRCLK_INV_MASK 0x04 553 + #define CS35L41_LRCLK_INV_SHIFT 2 554 + #define CS35L41_SCLK_FRC_MASK 0x20 555 + #define CS35L41_SCLK_FRC_SHIFT 5 556 + #define CS35L41_LRCLK_FRC_MASK 0x02 557 + #define CS35L41_LRCLK_FRC_SHIFT 1 558 + 559 + #define CS35L41_AMP_GAIN_PCM_MASK 0x3E0 560 + #define CS35L41_AMP_GAIN_ZC_MASK 0x0400 561 + #define CS35L41_AMP_GAIN_ZC_SHIFT 10 562 + 563 + #define CS35L41_BST_CTL_MASK 0xFF 564 + #define CS35L41_BST_CTL_SEL_MASK 0x03 565 + #define CS35L41_BST_CTL_SEL_REG 0x00 566 + #define CS35L41_BST_CTL_SEL_CLASSH 0x01 567 + #define CS35L41_BST_IPK_MASK 0x7F 568 + #define CS35L41_BST_IPK_SHIFT 0 569 + #define CS35L41_BST_LIM_MASK 0x4 570 + #define CS35L41_BST_LIM_SHIFT 2 571 + #define CS35L41_BST_K1_MASK 0x000000FF 572 + #define CS35L41_BST_K1_SHIFT 0 573 + #define CS35L41_BST_K2_MASK 0x0000FF00 574 + #define CS35L41_BST_K2_SHIFT 8 575 + #define CS35L41_BST_SLOPE_MASK 0x0000FF00 576 + #define CS35L41_BST_SLOPE_SHIFT 8 577 + #define CS35L41_BST_LBST_VAL_MASK 0x00000003 578 + #define CS35L41_BST_LBST_VAL_SHIFT 0 579 + 580 + #define CS35L41_TEMP_THLD_MASK 0x03 581 + #define CS35L41_VMON_IMON_VOL_MASK 0x07FF07FF 582 + #define CS35L41_PDM_MODE_MASK 0x01 583 + #define CS35L41_PDM_MODE_SHIFT 0 584 + 585 + #define CS35L41_CH_MEM_DEPTH_MASK 0x07 586 + #define CS35L41_CH_MEM_DEPTH_SHIFT 0 587 + #define CS35L41_CH_HDRM_CTL_MASK 0x007F0000 588 + #define CS35L41_CH_HDRM_CTL_SHIFT 16 589 + #define CS35L41_CH_REL_RATE_MASK 0xFF00 590 + #define CS35L41_CH_REL_RATE_SHIFT 8 591 + #define CS35L41_CH_WKFET_DLY_MASK 0x001C 592 + #define CS35L41_CH_WKFET_DLY_SHIFT 2 593 + #define CS35L41_CH_WKFET_THLD_MASK 0x0F00 594 + #define CS35L41_CH_WKFET_THLD_SHIFT 8 595 + 596 + #define CS35L41_HW_NG_SEL_MASK 0x3F00 597 + #define CS35L41_HW_NG_SEL_SHIFT 8 598 + #define CS35L41_HW_NG_DLY_MASK 0x0070 599 + #define CS35L41_HW_NG_DLY_SHIFT 4 600 + #define CS35L41_HW_NG_THLD_MASK 0x0007 601 + #define CS35L41_HW_NG_THLD_SHIFT 0 602 + 603 + #define CS35L41_DSP_NG_ENABLE_MASK 0x00010000 604 + #define CS35L41_DSP_NG_ENABLE_SHIFT 16 605 + #define CS35L41_DSP_NG_THLD_MASK 0x7 606 + #define CS35L41_DSP_NG_THLD_SHIFT 0 607 + #define CS35L41_DSP_NG_DELAY_MASK 0x0F00 608 + #define CS35L41_DSP_NG_DELAY_SHIFT 8 609 + 610 + #define CS35L41_ASP_FMT_MASK 0x0700 611 + #define CS35L41_ASP_FMT_SHIFT 8 612 + #define CS35L41_ASP_DOUT_HIZ_MASK 0x03 613 + #define CS35L41_ASP_DOUT_HIZ_SHIFT 0 614 + #define CS35L41_ASP_WIDTH_16 0x10 615 + #define CS35L41_ASP_WIDTH_24 0x18 616 + #define CS35L41_ASP_WIDTH_32 0x20 617 + #define CS35L41_ASP_WIDTH_TX_MASK 0xFF0000 618 + #define CS35L41_ASP_WIDTH_TX_SHIFT 16 619 + #define CS35L41_ASP_WIDTH_RX_MASK 0xFF000000 620 + #define CS35L41_ASP_WIDTH_RX_SHIFT 24 621 + #define CS35L41_ASP_RX1_SLOT_MASK 0x3F 622 + #define CS35L41_ASP_RX1_SLOT_SHIFT 0 623 + #define CS35L41_ASP_RX2_SLOT_MASK 0x3F00 624 + #define CS35L41_ASP_RX2_SLOT_SHIFT 8 625 + #define CS35L41_ASP_RX_WL_MASK 0x3F 626 + #define CS35L41_ASP_TX_WL_MASK 0x3F 627 + #define CS35L41_ASP_RX_WL_SHIFT 0 628 + #define CS35L41_ASP_TX_WL_SHIFT 0 629 + #define CS35L41_ASP_SOURCE_MASK 0x7F 630 + 631 + #define CS35L41_INPUT_SRC_ASPRX1 0x08 632 + #define CS35L41_INPUT_SRC_ASPRX2 0x09 633 + #define CS35L41_INPUT_SRC_VMON 0x18 634 + #define CS35L41_INPUT_SRC_IMON 0x19 635 + #define CS35L41_INPUT_SRC_CLASSH 0x21 636 + #define CS35L41_INPUT_SRC_VPMON 0x28 637 + #define CS35L41_INPUT_SRC_VBSTMON 0x29 638 + #define CS35L41_INPUT_SRC_TEMPMON 0x3A 639 + #define CS35L41_INPUT_SRC_RSVD 0x3B 640 + #define CS35L41_INPUT_DSP_TX1 0x32 641 + #define CS35L41_INPUT_DSP_TX2 0x33 642 + 643 + #define CS35L41_PLL_CLK_SEL_MASK 0x07 644 + #define CS35L41_PLL_CLK_SEL_SHIFT 0 645 + #define CS35L41_PLL_CLK_EN_MASK 0x10 646 + #define CS35L41_PLL_CLK_EN_SHIFT 4 647 + #define CS35L41_PLL_OPENLOOP_MASK 0x0800 648 + #define CS35L41_PLL_OPENLOOP_SHIFT 11 649 + #define CS35L41_PLLSRC_SCLK 0 650 + #define CS35L41_PLLSRC_LRCLK 1 651 + #define CS35L41_PLLSRC_SELF 3 652 + #define CS35L41_PLLSRC_PDMCLK 4 653 + #define CS35L41_PLLSRC_MCLK 5 654 + #define CS35L41_PLLSRC_SWIRE 7 655 + #define CS35L41_REFCLK_FREQ_MASK 0x7E0 656 + #define CS35L41_REFCLK_FREQ_SHIFT 5 657 + 658 + #define CS35L41_GLOBAL_FS_MASK 0x1F 659 + #define CS35L41_GLOBAL_FS_SHIFT 0 660 + 661 + #define CS35L41_GLOBAL_EN_MASK 0x01 662 + #define CS35L41_GLOBAL_EN_SHIFT 0 663 + #define CS35L41_BST_EN_MASK 0x0030 664 + #define CS35L41_BST_EN_SHIFT 4 665 + #define CS35L41_BST_EN_DEFAULT 0x2 666 + #define CS35L41_AMP_EN_SHIFT 0 667 + #define CS35L41_AMP_EN_MASK 1 668 + 669 + #define CS35L41_PDN_DONE_MASK 0x00800000 670 + #define CS35L41_PDN_DONE_SHIFT 23 671 + #define CS35L41_PUP_DONE_MASK 0x01000000 672 + #define CS35L41_PUP_DONE_SHIFT 24 673 + 674 + #define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F 675 + #define CS35L36_PUP_DONE_IRQ_MASK 0xBF 676 + 677 + #define CS35L41_AMP_SHORT_ERR 0x80000000 678 + #define CS35L41_BST_SHORT_ERR 0x0100 679 + #define CS35L41_TEMP_WARN 0x8000 680 + #define CS35L41_TEMP_ERR 0x00020000 681 + #define CS35L41_BST_OVP_ERR 0x40 682 + #define CS35L41_BST_DCM_UVP_ERR 0x80 683 + #define CS35L41_OTP_BOOT_DONE 0x02 684 + #define CS35L41_PLL_UNLOCK 0x10 685 + #define CS35L41_OTP_BOOT_ERR 0x80000000 686 + 687 + #define CS35L41_AMP_SHORT_ERR_RLS 0x02 688 + #define CS35L41_BST_SHORT_ERR_RLS 0x04 689 + #define CS35L41_BST_OVP_ERR_RLS 0x08 690 + #define CS35L41_BST_UVP_ERR_RLS 0x10 691 + #define CS35L41_TEMP_WARN_ERR_RLS 0x20 692 + #define CS35L41_TEMP_ERR_RLS 0x40 693 + 694 + 695 + #define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F 696 + #define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF 697 + #define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF 698 + 699 + #define CS35L41_GPIO_DIR_MASK 0x80000000 700 + #define CS35L41_GPIO1_CTRL_MASK 0x00030000 701 + #define CS35L41_GPIO1_CTRL_SHIFT 16 702 + #define CS35L41_GPIO2_CTRL_MASK 0x07000000 703 + #define CS35L41_GPIO2_CTRL_SHIFT 24 704 + #define CS35L41_GPIO_CTRL_OPEN_INT 2 705 + #define CS35L41_GPIO_CTRL_ACTV_LO 4 706 + #define CS35L41_GPIO_CTRL_ACTV_HI 5 707 + #define CS35L41_GPIO_POL_MASK 0x1000 708 + #define CS35L41_GPIO_POL_SHIFT 12 709 + 710 + #define CS35L41_AMP_INV_PCM_SHIFT 14 711 + #define CS35L41_AMP_INV_PCM_MASK (1 << CS35L41_AMP_INV_PCM_SHIFT) 712 + #define CS35L41_AMP_PCM_VOL_SHIFT 3 713 + #define CS35L41_AMP_PCM_VOL_MASK (0x7FF << 3) 714 + #define CS35L41_AMP_PCM_VOL_MUTE 0x4CF 715 + 716 + #define CS35L41_CHIP_ID 0x35a40 717 + #define CS35L41R_CHIP_ID 0x35b40 718 + #define CS35L41_MTLREVID_MASK 0x0F 719 + #define CS35L41_REVID_A0 0xA0 720 + #define CS35L41_REVID_B0 0xB0 721 + #define CS35L41_REVID_B2 0xB2 722 + 723 + #define CS35L41_HALO_CORE_RESET 0x00000200 724 + 725 + #define CS35L41_FS1_WINDOW_MASK 0x000007FF 726 + #define CS35L41_FS2_WINDOW_MASK 0x00FFF800 727 + #define CS35L41_FS2_WINDOW_SHIFT 12 728 + 729 + #define CS35L41_SPI_MAX_FREQ_OTP 4000000 730 + 731 + #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 732 + #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 733 + 734 + bool cs35l41_readable_reg(struct device *dev, unsigned int reg); 735 + bool cs35l41_precious_reg(struct device *dev, unsigned int reg); 736 + bool cs35l41_volatile_reg(struct device *dev, unsigned int reg); 737 + 738 + struct cs35l41_otp_packed_element_t { 739 + u32 reg; 740 + u8 shift; 741 + u8 size; 742 + }; 743 + 744 + struct cs35l41_otp_map_element_t { 745 + u32 id; 746 + u32 num_elements; 747 + const struct cs35l41_otp_packed_element_t *map; 748 + u32 bit_offset; 749 + u32 word_offset; 750 + }; 751 + 752 + extern const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG]; 753 + extern const struct cs35l41_otp_map_element_t 754 + cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; 755 + 756 + #define CS35L41_REGSTRIDE 4 757 + 758 + struct cs35l41_private { 759 + struct snd_soc_codec *codec; 760 + struct cs35l41_platform_data pdata; 761 + struct device *dev; 762 + struct regmap *regmap; 763 + struct regulator_bulk_data supplies[CS35L41_NUM_SUPPLIES]; 764 + int irq; 765 + /* GPIO for /RST */ 766 + struct gpio_desc *reset_gpio; 767 + void (*otp_setup)(struct cs35l41_private *cs35l41, bool is_pre_setup, 768 + unsigned int *freq); 769 + }; 770 + 771 + int cs35l41_probe(struct cs35l41_private *cs35l41, 772 + struct cs35l41_platform_data *pdata); 773 + int cs35l41_remove(struct cs35l41_private *cs35l41); 774 + 775 + #endif /*__CS35L41_H__*/