* [PATCH 0/2] ASoC: codecs: Add Everest ES7202 support @ 2026-10-20 14:31 ` Jun Yan 0 siblings, 0 replies; 7+ messages in thread From: Jun Yan @ 2026-10-20 14:31 UTC (permalink / raw) To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai, heiko Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel, linux-rockchip, Jun Yan This series adds support for the Everest ES7202, a 2-channel PDM analog-to-digital converter controlled over I2C. Patch 1 adds the DT bindings and patch 2 the ASoC codec driver. The driver is based on the Rockchip BSP driver, reworked for mainline to use regmap and devm_ helpers, probe the device ID, and report the actual per-step PGA gain. Jun Yan (2): dt-bindings: sound: add Everest ES7202 ASoC: codecs: add support for Everest ES7202 PDM ADC .../bindings/sound/everest,es7202.yaml | 56 +++ sound/soc/codecs/Kconfig | 10 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/es7202.c | 372 ++++++++++++++++++ sound/soc/codecs/es7202.h | 133 +++++++ 5 files changed, 573 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/everest,es7202.yaml create mode 100644 sound/soc/codecs/es7202.c create mode 100644 sound/soc/codecs/es7202.h -- 2.56.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 0/2] ASoC: codecs: Add Everest ES7202 support @ 2026-10-20 14:31 ` Jun Yan 0 siblings, 0 replies; 7+ messages in thread From: Jun Yan @ 2026-10-20 14:31 UTC (permalink / raw) To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai, heiko Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel, linux-rockchip, Jun Yan This series adds support for the Everest ES7202, a 2-channel PDM analog-to-digital converter controlled over I2C. Patch 1 adds the DT bindings and patch 2 the ASoC codec driver. The driver is based on the Rockchip BSP driver, reworked for mainline to use regmap and devm_ helpers, probe the device ID, and report the actual per-step PGA gain. Jun Yan (2): dt-bindings: sound: add Everest ES7202 ASoC: codecs: add support for Everest ES7202 PDM ADC .../bindings/sound/everest,es7202.yaml | 56 +++ sound/soc/codecs/Kconfig | 10 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/es7202.c | 372 ++++++++++++++++++ sound/soc/codecs/es7202.h | 133 +++++++ 5 files changed, 573 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/everest,es7202.yaml create mode 100644 sound/soc/codecs/es7202.c create mode 100644 sound/soc/codecs/es7202.h -- 2.56.0 _______________________________________________ Linux-rockchip mailing list Linux-rockchip@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-rockchip ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] dt-bindings: sound: add Everest ES7202 2026-10-20 14:31 ` Jun Yan @ 2026-10-20 14:31 ` Jun Yan -1 siblings, 0 replies; 7+ messages in thread From: Jun Yan @ 2026-10-20 14:31 UTC (permalink / raw) To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai, heiko, Jun Yan Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel, linux-rockchip Add the device-tree bindings for the Everest ES7202, a 2-channel PDM analog-to-digital converter controlled over I2C. Signed-off-by: Jun Yan <jerrysteve1101@gmail.com> --- .../bindings/sound/everest,es7202.yaml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/everest,es7202.yaml diff --git a/Documentation/devicetree/bindings/sound/everest,es7202.yaml b/Documentation/devicetree/bindings/sound/everest,es7202.yaml new file mode 100644 index 000000000000..ce98d2d600d4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/everest,es7202.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/everest,es7202.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Everest ES7202 2 channel PDM analog to digital converter + +maintainers: + - Jun Yan <jerrysteve1101@gmail.com> + +properties: + compatible: + enum: + - everest,es7202 + + reg: + maxItems: 1 + + reset-gpios: + maxItems: 1 + description: GPIO connected to the reset pin (active low) + + vdd-supply: + description: Main power supply, 1.8 V or 3.3 V. Optional; defaults to 3.3 V + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - "#sound-dai-cells" + +allOf: + - $ref: dai-common.yaml# + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + es7202: codec@30 { + compatible = "everest,es7202"; + reg = <0x30>; + #sound-dai-cells = <0>; + reset-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + vdd-supply = <&vcc3v3_sys>; + }; + }; +... -- 2.56.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 1/2] dt-bindings: sound: add Everest ES7202 @ 2026-10-20 14:31 ` Jun Yan 0 siblings, 0 replies; 7+ messages in thread From: Jun Yan @ 2026-10-20 14:31 UTC (permalink / raw) To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai, heiko, Jun Yan Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel, linux-rockchip Add the device-tree bindings for the Everest ES7202, a 2-channel PDM analog-to-digital converter controlled over I2C. Signed-off-by: Jun Yan <jerrysteve1101@gmail.com> --- .../bindings/sound/everest,es7202.yaml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/everest,es7202.yaml diff --git a/Documentation/devicetree/bindings/sound/everest,es7202.yaml b/Documentation/devicetree/bindings/sound/everest,es7202.yaml new file mode 100644 index 000000000000..ce98d2d600d4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/everest,es7202.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/everest,es7202.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Everest ES7202 2 channel PDM analog to digital converter + +maintainers: + - Jun Yan <jerrysteve1101@gmail.com> + +properties: + compatible: + enum: + - everest,es7202 + + reg: + maxItems: 1 + + reset-gpios: + maxItems: 1 + description: GPIO connected to the reset pin (active low) + + vdd-supply: + description: Main power supply, 1.8 V or 3.3 V. Optional; defaults to 3.3 V + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - "#sound-dai-cells" + +allOf: + - $ref: dai-common.yaml# + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + es7202: codec@30 { + compatible = "everest,es7202"; + reg = <0x30>; + #sound-dai-cells = <0>; + reset-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + vdd-supply = <&vcc3v3_sys>; + }; + }; +... -- 2.56.0 _______________________________________________ Linux-rockchip mailing list Linux-rockchip@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-rockchip ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] ASoC: codecs: add support for Everest ES7202 PDM ADC 2026-10-20 14:31 ` Jun Yan @ 2026-10-20 14:31 ` Jun Yan -1 siblings, 0 replies; 7+ messages in thread From: Jun Yan @ 2026-10-20 14:31 UTC (permalink / raw) To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai, heiko Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel, linux-rockchip, Jun Yan Add support for the Everest ES7202, a 2-channel PDM analog-to-digital converter controlled over I2C. The device outputs PDM data to the SoC PDM controller and is configured through registers for supply voltage, analog front-end and per-channel PGA gain. Based on the Rockchip BSP driver[1] by Binyuan Lan <lby@rock-chips.com> (committed by Tao Huang <huangtao@rock-chips.com>), originally written by David Yang <yangxiaohua@everest-semi.com>. [1] https://github.com/rockchip-linux/kernel/blob/develop-6.1/sound/soc/codecs/es7202.c Link: https://archive.org/details/es-7202-ds Signed-off-by: Jun Yan <jerrysteve1101@gmail.com> --- sound/soc/codecs/Kconfig | 10 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/es7202.c | 372 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/es7202.h | 133 ++++++++++++++ 4 files changed, 517 insertions(+) create mode 100644 sound/soc/codecs/es7202.c create mode 100644 sound/soc/codecs/es7202.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ba59dabeeccd..c1eeebd12cf0 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1274,6 +1274,16 @@ config SND_SOC_HDMI_CODEC config SND_SOC_ES7134 tristate "Everest Semi ES7134 CODEC" +config SND_SOC_ES7202 + tristate "Everest Semi ES7202 CODEC" + depends on I2C + select REGMAP_I2C + help + Enable support for the Everest Semiconductor ES7202, a 2-channel + PDM analog-to-digital converter controlled over I2C. The device + outputs PDM data to a SoC PDM controller and is configured through + registers for supply voltage, analog front-end and PGA gain. + config SND_SOC_ES7241 tristate "Everest Semi ES7241 CODEC" diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3826f9e4fce8..2a56fad9073a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -129,6 +129,7 @@ snd-soc-da732x-y := da732x.o snd-soc-da9055-y := da9055.o snd-soc-dmic-y := dmic.o snd-soc-es7134-y := es7134.o +snd-soc-es7202-y := es7202.o snd-soc-es7241-y := es7241.o snd-soc-es83xx-dsm-common-y := es83xx-dsm-common.o snd-soc-es8311-y := es8311.o @@ -577,6 +578,7 @@ obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o obj-$(CONFIG_SND_SOC_ES7134) += snd-soc-es7134.o +obj-$(CONFIG_SND_SOC_ES7202) += snd-soc-es7202.o obj-$(CONFIG_SND_SOC_ES7241) += snd-soc-es7241.o obj-$(CONFIG_SND_SOC_ES83XX_DSM_COMMON) += snd-soc-es83xx-dsm-common.o obj-$(CONFIG_SND_SOC_ES8311) += snd-soc-es8311.o diff --git a/sound/soc/codecs/es7202.c b/sound/soc/codecs/es7202.c new file mode 100644 index 000000000000..c30b0123c91f --- /dev/null +++ b/sound/soc/codecs/es7202.c @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright Everest Semiconductor Co., Ltd. + * + * Author: David Yang <yangxiaohua@everest-semi.com> + * Author: Jun Yan <jerrysteve1101@gmail.com> + */ + +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/tlv.h> +#include "es7202.h" + +/* + * The main supply voltage selects the analog front-end configuration: + * below this threshold the device is configured for 1.8 V, otherwise 3.3 V. + */ +#define ES7202_SUPPLY_1V8_MAX_UV 1980000 +#define ES7202_SUPPLY_3V3_DEFAULT_UV 3300000 + +struct es7202_priv { + struct regmap *regmap; + struct regulator *supply; + struct gpio_desc *reset_gpio; + unsigned int supply_uv; +}; + +static bool es7202_volatile_reg(struct device *dev, unsigned int reg) +{ + /* status and device-id registers are read-only, never cached */ + return reg == ES7202_CHIP_STA || + reg == ES7202_DEV_ID1 || + reg == ES7202_DEV_ID0; +} + +static const struct reg_default es7202_reg_defaults[] = { + { ES7202_RESET, 0x10 }, + { ES7202_SOFT_MODE, 0x00 }, + { ES7202_CLK_DIV, 0x04 }, + { ES7202_CLK_EN, 0x00 }, + { ES7202_T1_VMID, 0x01 }, + { ES7202_T2_VMID, 0x18 }, + { ES7202_PDM_INF_CTL, 0x30 }, + { ES7202_MISC_CTL, 0x02 }, + { ES7202_ANALOG_EN, 0xff }, + { ES7202_BIAS_VMID, 0x0c }, + { ES7202_PGA1_BIAS, 0x55 }, + { ES7202_PGA2_BIAS, 0x55 }, + { ES7202_MOD1_BIAS, 0x8c }, + { ES7202_MOD2_BIAS, 0x33 }, + { ES7202_VREFP_BIAS, 0x33 }, + { ES7202_VMMOD_BIAS, 0x33 }, + { ES7202_MODS_BIAS, 0x44 }, + { ES7202_ANALOG_LP1, 0x00 }, + { ES7202_ANALOG_LP2, 0x00 }, + { ES7202_ANALOG_MISC1, 0x00 }, + { ES7202_ANALOG_MISC2, 0xf8 }, + { ES7202_PGA1, 0x18 }, + { ES7202_PGA2, 0x18 }, +}; + +static const struct regmap_config es7202_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = ES7202_DEV_ID0, + .reg_defaults = es7202_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(es7202_reg_defaults), + .volatile_reg = es7202_volatile_reg, + .cache_type = REGCACHE_MAPLE, +}; + +/* + * PGA gain per the datasheet: code 0 is 0 dB, codes 1..10 step +3 dB from + * 2.25 dB, and codes 11 and 12 are 30.75 dB and 32.25 dB respectively. As + * the steps are not uniform, a linear TLV (the vendor driver's + * DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 300, 0)) would misreport the gain, + * so use a piecewise range matching the datasheet instead. + */ +static const DECLARE_TLV_DB_RANGE(mic_boost_tlv, + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), + 1, 10, TLV_DB_SCALE_ITEM(225, 300, 0), + 11, 11, TLV_DB_SCALE_ITEM(3075, 0, 0), + 12, 12, TLV_DB_SCALE_ITEM(3225, 0, 0), +); + +static const struct snd_kcontrol_new es7202_controls[] = { + SOC_SINGLE_TLV("PGA1 Capture Volume", ES7202_PGA1, 0, 0x0c, 0, + mic_boost_tlv), + SOC_SINGLE_TLV("PGA2 Capture Volume", ES7202_PGA2, 0, 0x0c, 0, + mic_boost_tlv), +}; + +static const struct snd_soc_dapm_widget es7202_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("MIC1"), + SND_SOC_DAPM_INPUT("MIC2"), + SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_route es7202_dapm_routes[] = { + { "ADC", NULL, "MIC1" }, + { "ADC", NULL, "MIC2" }, +}; + +static int es7202_mute_pdm(struct es7202_priv *es7202, bool mute) +{ + return regmap_update_bits(es7202->regmap, ES7202_PDM_INF_CTL, + ES7202_PDM_INF_CTL_MUTE, + mute ? ES7202_PDM_INF_CTL_MUTE : 0); +} + +static int es7202_hw_init(struct es7202_priv *es7202) +{ + struct regmap *regmap = es7202->regmap; + bool is_1v8 = es7202->supply_uv > 0 && + es7202->supply_uv <= ES7202_SUPPLY_1V8_MAX_UV; + /* + * Power-up sequence from the vendor driver. + * The analog front-end is configured for the actual supply voltage + * (1.8 V vs 3.3 V) and the analog blocks are ramped out of + * power-down in stages. + */ + const struct reg_sequence init_seq[] = { + { ES7202_SOFT_MODE, ES7202_MODE_SOFT_MODE_SEL }, + { ES7202_ANALOG_MISC1, ES7202_ANALOG_MISC1_OFFSETSEL1 | + (is_1v8 ? 0 : ES7202_ANALOG_MISC1_SUPPLYSEL) }, + + /* 30.75 dB gain */ + { ES7202_PGA1, ES7202_PGA_SELMIC1 | + FIELD_PREP(ES7202_PGA_MIC1_GAIN, 11) }, + { ES7202_PGA2, ES7202_PGA_SELMIC2 | + FIELD_PREP(ES7202_PGA_MIC2_GAIN, 11) }, + + /* analog on, rest powered down */ + { ES7202_ANALOG_EN, ES7202_ANALOG_EN_PDN_ADCVREFGEN | + ES7202_ANALOG_EN_MODTOP1_RST | + ES7202_ANALOG_EN_MODTOP2_RST | + ES7202_ANALOG_EN_PDN_MOD1 | + ES7202_ANALOG_EN_PDN_MOD2 | + ES7202_ANALOG_EN_PDN_PGA1 | + ES7202_ANALOG_EN_PDN_PGA2 }, + + { ES7202_BIAS_VMID, FIELD_PREP(ES7202_BIAS_ADCBIAS_SWH1, 3) | + ES7202_BIAS_ENDITHER | + FIELD_PREP(ES7202_BIAS_VMIDSEL, 3) }, + + /* VREFGEN on; 3.3 V also drops MODTOP reset */ + { ES7202_ANALOG_EN, is_1v8 ? + (ES7202_ANALOG_EN_MODTOP1_RST | + ES7202_ANALOG_EN_MODTOP2_RST | + ES7202_ANALOG_EN_PDN_MOD1 | + ES7202_ANALOG_EN_PDN_MOD2 | + ES7202_ANALOG_EN_PDN_PGA1 | + ES7202_ANALOG_EN_PDN_PGA2) : + (ES7202_ANALOG_EN_PDN_MOD1 | + ES7202_ANALOG_EN_PDN_MOD2 | + ES7202_ANALOG_EN_PDN_PGA1 | + ES7202_ANALOG_EN_PDN_PGA2) }, + + { ES7202_ANALOG_EN, 0 }, + { ES7202_MOD1_BIAS, FIELD_PREP(ES7202_MOD1_BIAS_SW0, 5) | + FIELD_PREP(ES7202_MOD1_BIAS_SW1, 8) }, + { ES7202_CLK_DIV, FIELD_PREP(ES7202_CLK_DIV_MCLK_DIV, 1) }, + { ES7202_T2_VMID, 0x01 }, + { ES7202_MISC_CTL, ES7202_MISC_DSM_DITHER_ON }, + { ES7202_RESET, ES7202_RESET_CSM_ON }, + { ES7202_CLK_EN, ES7202_CLK_ANA_CLK_ON | ES7202_CLK_MCLK_ON }, + { ES7202_BIAS_VMID, FIELD_PREP(ES7202_BIAS_ADCBIAS_SWH1, 3) | + ES7202_BIAS_ENDITHER | + FIELD_PREP(ES7202_BIAS_VMIDSEL, 2) }, + }; + int ret; + + ret = regmap_multi_reg_write(regmap, init_seq, ARRAY_SIZE(init_seq)); + if (ret) + return ret; + + return es7202_mute_pdm(es7202, false); +} + +static int es7202_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_component *component = dai->component; + struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + return 0; + + return es7202_mute_pdm(es7202, mute); +} + +static const struct snd_soc_dai_ops es7202_dai_ops = { + .mute_stream = es7202_mute_stream, +}; + +static struct snd_soc_dai_driver es7202_dai = { + .name = "es7202-hifi", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &es7202_dai_ops, +}; + +static int es7202_suspend(struct snd_soc_component *component) +{ + struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component); + + return es7202_mute_pdm(es7202, true); +} + +static int es7202_resume(struct snd_soc_component *component) +{ + struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component); + int ret; + + regcache_mark_dirty(es7202->regmap); + ret = regcache_sync(es7202->regmap); + if (ret) + return ret; + + return es7202_mute_pdm(es7202, false); +} + +static const struct snd_soc_component_driver es7202_component_driver = { + .controls = es7202_controls, + .num_controls = ARRAY_SIZE(es7202_controls), + .dapm_widgets = es7202_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(es7202_dapm_widgets), + .dapm_routes = es7202_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(es7202_dapm_routes), + .suspend = es7202_suspend, + .resume = es7202_resume, + .idle_bias_on = 1, + .endianness = 1, +}; + +static void es7202_disable_supply(void *data) +{ + regulator_disable(data); +} + +static int es7202_i2c_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct es7202_priv *es7202; + unsigned int id1, id0, device_id; + int ret; + + es7202 = devm_kzalloc(dev, sizeof(*es7202), GFP_KERNEL); + if (!es7202) + return -ENOMEM; + + i2c_set_clientdata(i2c, es7202); + + es7202->regmap = devm_regmap_init_i2c(i2c, &es7202_regmap); + if (IS_ERR(es7202->regmap)) + return dev_err_probe(dev, PTR_ERR(es7202->regmap), + "failed to init regmap\n"); + + es7202->reset_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(es7202->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(es7202->reset_gpio), + "failed to get reset gpio\n"); + + es7202->supply = devm_regulator_get_optional(dev, "vdd"); + if (IS_ERR(es7202->supply)) { + if (PTR_ERR(es7202->supply) != -ENODEV) + return dev_err_probe(dev, PTR_ERR(es7202->supply), + "failed to get supply\n"); + + es7202->supply = NULL; + es7202->supply_uv = ES7202_SUPPLY_3V3_DEFAULT_UV; + } else { + ret = regulator_enable(es7202->supply); + if (ret) + return dev_err_probe(dev, ret, + "failed to enable supply\n"); + + ret = devm_add_action_or_reset(dev, es7202_disable_supply, + es7202->supply); + if (ret) + return dev_err_probe(dev, ret, + "failed to add supply disable action\n"); + + es7202->supply_uv = regulator_get_voltage(es7202->supply); + if (es7202->supply_uv < 0) + es7202->supply_uv = ES7202_SUPPLY_3V3_DEFAULT_UV; + } + + /* take the device out of reset */ + gpiod_set_value_cansleep(es7202->reset_gpio, 0); + usleep_range(1000, 2000); + + /* verify the chip is present by reading its device id */ + ret = regmap_read(es7202->regmap, ES7202_DEV_ID1, &id1); + if (ret) + return dev_err_probe(dev, ret, "failed to read device id\n"); + ret = regmap_read(es7202->regmap, ES7202_DEV_ID0, &id0); + if (ret) + return dev_err_probe(dev, ret, "failed to read device id\n"); + + device_id = (id1 << 8) | id0; + if (device_id != ES7202_DEVICE_ID) + return dev_err_probe(dev, -ENODEV, + "unexpected device id 0x%04x, expected 0x%04x\n", + device_id, ES7202_DEVICE_ID); + + ret = es7202_hw_init(es7202); + if (ret) + return dev_err_probe(dev, ret, "failed to init device\n"); + + return devm_snd_soc_register_component(dev, &es7202_component_driver, + &es7202_dai, 1); +} + +static void es7202_i2c_remove(struct i2c_client *i2c) +{ + struct es7202_priv *es7202 = i2c_get_clientdata(i2c); + + es7202_mute_pdm(es7202, true); +} + +static void es7202_i2c_shutdown(struct i2c_client *i2c) +{ + struct es7202_priv *es7202 = i2c_get_clientdata(i2c); + + es7202_mute_pdm(es7202, true); +} + +static const struct of_device_id es7202_of_match[] = { + { .compatible = "everest,es7202" }, + { } +}; +MODULE_DEVICE_TABLE(of, es7202_of_match); + +static const struct i2c_device_id es7202_i2c_id[] = { + { "es7202" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, es7202_i2c_id); + +static struct i2c_driver es7202_i2c_driver = { + .driver = { + .name = "es7202", + .of_match_table = of_match_ptr(es7202_of_match), + }, + .probe = es7202_i2c_probe, + .remove = es7202_i2c_remove, + .shutdown = es7202_i2c_shutdown, + .id_table = es7202_i2c_id, +}; +module_i2c_driver(es7202_i2c_driver); + +MODULE_DESCRIPTION("Everest Semi ES7202 PDM ADC ALSA SoC Codec Driver"); +MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>"); +MODULE_AUTHOR("Jun Yan <jerrysteve1101@gmail.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/es7202.h b/sound/soc/codecs/es7202.h new file mode 100644 index 000000000000..15811b73c20a --- /dev/null +++ b/sound/soc/codecs/es7202.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright Everest Semiconductor Co., Ltd. + * + * Author: David Yang <yangxiaohua@everest-semi.com> + * Author: Jun Yan <jerrysteve1101@gmail.com> + */ + +#ifndef _ES7202_H +#define _ES7202_H + +#include <linux/bits.h> + +/* Register addresses */ +#define ES7202_RESET 0x00 +#define ES7202_SOFT_MODE 0x01 +#define ES7202_CLK_DIV 0x02 +#define ES7202_CLK_EN 0x03 +#define ES7202_T1_VMID 0x04 +#define ES7202_T2_VMID 0x05 +#define ES7202_CHIP_STA 0x06 +#define ES7202_PDM_INF_CTL 0x07 +#define ES7202_MISC_CTL 0x08 +#define ES7202_ANALOG_EN 0x10 +#define ES7202_BIAS_VMID 0x11 +#define ES7202_PGA1_BIAS 0x12 +#define ES7202_PGA2_BIAS 0x13 +#define ES7202_MOD1_BIAS 0x14 +#define ES7202_MOD2_BIAS 0x15 +#define ES7202_VREFP_BIAS 0x16 +#define ES7202_VMMOD_BIAS 0x17 +#define ES7202_MODS_BIAS 0x18 +#define ES7202_ANALOG_LP1 0x19 +#define ES7202_ANALOG_LP2 0x1a +#define ES7202_ANALOG_MISC1 0x1b +#define ES7202_ANALOG_MISC2 0x1c +#define ES7202_PGA1 0x1d +#define ES7202_PGA2 0x1e +#define ES7202_DEV_ID1 0xfd +#define ES7202_DEV_ID0 0xfe + +#define ES7202_DEVICE_ID 0x7201 + +#define ES7202_RESET_RST_REGS BIT(5) +#define ES7202_RESET_RST_DIG BIT(4) +#define ES7202_RESET_SEQ_DIS BIT(1) +#define ES7202_RESET_CSM_ON BIT(0) + +#define ES7202_MODE_SOFT_MODE_SEL BIT(0) + +#define ES7202_CLK_DIV_MCLK_DIV GENMASK(3, 0) /* 0/1 = /16 ... 15 = /240 */ + +#define ES7202_CLK_MCLK_INVERT BIT(2) +#define ES7202_CLK_ANA_CLK_ON BIT(1) +#define ES7202_CLK_MCLK_ON BIT(0) + +#define ES7202_CHIP_STA_CSM_STATE GENMASK(5, 4) +#define ES7202_CHIP_STA_FORCE_CSM GENMASK(2, 0) + +#define ES7202_PDM_NEG_DATA_VALID BIT(5) +#define ES7202_PDM_POS_DATA_VALID BIT(4) +#define ES7202_PDM_CHN_CROSS BIT(3) +#define ES7202_PDM_IF_DLY BIT(2) +#define ES7202_PDM_DATA2_MUTE BIT(1) +#define ES7202_PDM_DATA1_MUTE BIT(0) +#define ES7202_PDM_INF_CTL_MUTE (ES7202_PDM_DATA2_MUTE | \ + ES7202_PDM_DATA1_MUTE) + +#define ES7202_MISC_CLKDET_RST_DIS BIT(2) +#define ES7202_MISC_DSM_DITHER_ON BIT(1) +#define ES7202_MISC_PDN_CLKDET BIT(0) + +#define ES7202_ANALOG_EN_PDN_ANA BIT(7) +#define ES7202_ANALOG_EN_PDN_ADCVREFGEN BIT(6) +#define ES7202_ANALOG_EN_MODTOP1_RST BIT(5) +#define ES7202_ANALOG_EN_MODTOP2_RST BIT(4) +#define ES7202_ANALOG_EN_PDN_MOD1 BIT(3) +#define ES7202_ANALOG_EN_PDN_MOD2 BIT(2) +#define ES7202_ANALOG_EN_PDN_PGA1 BIT(1) +#define ES7202_ANALOG_EN_PDN_PGA2 BIT(0) + +#define ES7202_BIAS_ADCBIAS_SWH0 GENMASK(7, 6) +#define ES7202_BIAS_ENDITHER BIT(5) +#define ES7202_BIAS_ADCBIAS_SWH1 GENMASK(3, 2) +#define ES7202_BIAS_VMIDSEL GENMASK(1, 0) /* 0 = off, 1 = 50k, 2 = 500k, 3 = 5k */ + +/* bias levels 0x12-0x18 (SW0 for 1.8 V, SW1 for 3.3 V) */ +#define ES7202_PGA1_BIAS_SW0 GENMASK(7, 4) +#define ES7202_PGA1_BIAS_SW1 GENMASK(3, 0) +#define ES7202_PGA2_BIAS_SW0 GENMASK(7, 4) +#define ES7202_PGA2_BIAS_SW1 GENMASK(3, 0) +#define ES7202_MOD1_BIAS_SW0 GENMASK(7, 4) +#define ES7202_MOD1_BIAS_SW1 GENMASK(3, 0) +#define ES7202_MOD2_BIAS_SW0 GENMASK(7, 4) +#define ES7202_MOD2_BIAS_SW1 GENMASK(3, 0) +#define ES7202_VREFP_BIAS_SW0 GENMASK(7, 4) +#define ES7202_VREFP_BIAS_SW1 GENMASK(3, 0) +#define ES7202_VMMOD_BIAS_SW0 GENMASK(7, 4) +#define ES7202_VMMOD_BIAS_SW1 GENMASK(3, 0) +#define ES7202_MODS_BIAS_SW0 GENMASK(7, 4) +#define ES7202_MODS_BIAS_SW1 GENMASK(3, 0) + +#define ES7202_LP1_LP_VRP BIT(7) +#define ES7202_LP1_LP_VRPOUT BIT(6) +#define ES7202_LP1_LP_VMMOD1 BIT(5) +#define ES7202_LP1_LP_VMMOD2 BIT(4) +#define ES7202_LP1_LP_MODS1 BIT(3) +#define ES7202_LP1_LP_MODS2 BIT(2) +#define ES7202_LP1_LP_MODI1 BIT(1) +#define ES7202_LP1_LP_MODI2 BIT(0) + +#define ES7202_LP2_LP_PGA1 BIT(5) +#define ES7202_LP2_LP_PGA2 BIT(4) +#define ES7202_LP2_PDN_DETCT BIT(3) + +#define ES7202_ANALOG_MISC1_OFFSETSEL1 BIT(6) +#define ES7202_ANALOG_MISC1_OFFSETSEL0 BIT(5) +#define ES7202_ANALOG_MISC1_SUPPLYSEL BIT(4) /* 0 = 1.8 V, 1 = 3.3 V */ +#define ES7202_ANALOG_MISC1_DITHERSEL GENMASK(2, 0) + +#define ES7202_ANALOG_MISC2_VX2OFF_SW0 BIT(7) +#define ES7202_ANALOG_MISC2_VX1SEL_SW0 BIT(6) +#define ES7202_ANALOG_MISC2_VMIDLOW_SW0 GENMASK(5, 4) +#define ES7202_ANALOG_MISC2_VX2OFF_SW1 BIT(3) +#define ES7202_ANALOG_MISC2_VX1SEL_SW1 BIT(2) +#define ES7202_ANALOG_MISC2_VMIDLOW_SW1 GENMASK(1, 0) + +#define ES7202_PGA_SELMIC1 BIT(4) +#define ES7202_PGA_MIC1_GAIN GENMASK(3, 0) +#define ES7202_PGA_SELMIC2 BIT(4) +#define ES7202_PGA_MIC2_GAIN GENMASK(3, 0) + +#endif -- 2.56.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] ASoC: codecs: add support for Everest ES7202 PDM ADC @ 2026-10-20 14:31 ` Jun Yan 0 siblings, 0 replies; 7+ messages in thread From: Jun Yan @ 2026-10-20 14:31 UTC (permalink / raw) To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai, heiko Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel, linux-rockchip, Jun Yan Add support for the Everest ES7202, a 2-channel PDM analog-to-digital converter controlled over I2C. The device outputs PDM data to the SoC PDM controller and is configured through registers for supply voltage, analog front-end and per-channel PGA gain. Based on the Rockchip BSP driver[1] by Binyuan Lan <lby@rock-chips.com> (committed by Tao Huang <huangtao@rock-chips.com>), originally written by David Yang <yangxiaohua@everest-semi.com>. [1] https://github.com/rockchip-linux/kernel/blob/develop-6.1/sound/soc/codecs/es7202.c Link: https://archive.org/details/es-7202-ds Signed-off-by: Jun Yan <jerrysteve1101@gmail.com> --- sound/soc/codecs/Kconfig | 10 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/es7202.c | 372 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/es7202.h | 133 ++++++++++++++ 4 files changed, 517 insertions(+) create mode 100644 sound/soc/codecs/es7202.c create mode 100644 sound/soc/codecs/es7202.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ba59dabeeccd..c1eeebd12cf0 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1274,6 +1274,16 @@ config SND_SOC_HDMI_CODEC config SND_SOC_ES7134 tristate "Everest Semi ES7134 CODEC" +config SND_SOC_ES7202 + tristate "Everest Semi ES7202 CODEC" + depends on I2C + select REGMAP_I2C + help + Enable support for the Everest Semiconductor ES7202, a 2-channel + PDM analog-to-digital converter controlled over I2C. The device + outputs PDM data to a SoC PDM controller and is configured through + registers for supply voltage, analog front-end and PGA gain. + config SND_SOC_ES7241 tristate "Everest Semi ES7241 CODEC" diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3826f9e4fce8..2a56fad9073a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -129,6 +129,7 @@ snd-soc-da732x-y := da732x.o snd-soc-da9055-y := da9055.o snd-soc-dmic-y := dmic.o snd-soc-es7134-y := es7134.o +snd-soc-es7202-y := es7202.o snd-soc-es7241-y := es7241.o snd-soc-es83xx-dsm-common-y := es83xx-dsm-common.o snd-soc-es8311-y := es8311.o @@ -577,6 +578,7 @@ obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o obj-$(CONFIG_SND_SOC_ES7134) += snd-soc-es7134.o +obj-$(CONFIG_SND_SOC_ES7202) += snd-soc-es7202.o obj-$(CONFIG_SND_SOC_ES7241) += snd-soc-es7241.o obj-$(CONFIG_SND_SOC_ES83XX_DSM_COMMON) += snd-soc-es83xx-dsm-common.o obj-$(CONFIG_SND_SOC_ES8311) += snd-soc-es8311.o diff --git a/sound/soc/codecs/es7202.c b/sound/soc/codecs/es7202.c new file mode 100644 index 000000000000..c30b0123c91f --- /dev/null +++ b/sound/soc/codecs/es7202.c @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright Everest Semiconductor Co., Ltd. + * + * Author: David Yang <yangxiaohua@everest-semi.com> + * Author: Jun Yan <jerrysteve1101@gmail.com> + */ + +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/tlv.h> +#include "es7202.h" + +/* + * The main supply voltage selects the analog front-end configuration: + * below this threshold the device is configured for 1.8 V, otherwise 3.3 V. + */ +#define ES7202_SUPPLY_1V8_MAX_UV 1980000 +#define ES7202_SUPPLY_3V3_DEFAULT_UV 3300000 + +struct es7202_priv { + struct regmap *regmap; + struct regulator *supply; + struct gpio_desc *reset_gpio; + unsigned int supply_uv; +}; + +static bool es7202_volatile_reg(struct device *dev, unsigned int reg) +{ + /* status and device-id registers are read-only, never cached */ + return reg == ES7202_CHIP_STA || + reg == ES7202_DEV_ID1 || + reg == ES7202_DEV_ID0; +} + +static const struct reg_default es7202_reg_defaults[] = { + { ES7202_RESET, 0x10 }, + { ES7202_SOFT_MODE, 0x00 }, + { ES7202_CLK_DIV, 0x04 }, + { ES7202_CLK_EN, 0x00 }, + { ES7202_T1_VMID, 0x01 }, + { ES7202_T2_VMID, 0x18 }, + { ES7202_PDM_INF_CTL, 0x30 }, + { ES7202_MISC_CTL, 0x02 }, + { ES7202_ANALOG_EN, 0xff }, + { ES7202_BIAS_VMID, 0x0c }, + { ES7202_PGA1_BIAS, 0x55 }, + { ES7202_PGA2_BIAS, 0x55 }, + { ES7202_MOD1_BIAS, 0x8c }, + { ES7202_MOD2_BIAS, 0x33 }, + { ES7202_VREFP_BIAS, 0x33 }, + { ES7202_VMMOD_BIAS, 0x33 }, + { ES7202_MODS_BIAS, 0x44 }, + { ES7202_ANALOG_LP1, 0x00 }, + { ES7202_ANALOG_LP2, 0x00 }, + { ES7202_ANALOG_MISC1, 0x00 }, + { ES7202_ANALOG_MISC2, 0xf8 }, + { ES7202_PGA1, 0x18 }, + { ES7202_PGA2, 0x18 }, +}; + +static const struct regmap_config es7202_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = ES7202_DEV_ID0, + .reg_defaults = es7202_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(es7202_reg_defaults), + .volatile_reg = es7202_volatile_reg, + .cache_type = REGCACHE_MAPLE, +}; + +/* + * PGA gain per the datasheet: code 0 is 0 dB, codes 1..10 step +3 dB from + * 2.25 dB, and codes 11 and 12 are 30.75 dB and 32.25 dB respectively. As + * the steps are not uniform, a linear TLV (the vendor driver's + * DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 300, 0)) would misreport the gain, + * so use a piecewise range matching the datasheet instead. + */ +static const DECLARE_TLV_DB_RANGE(mic_boost_tlv, + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), + 1, 10, TLV_DB_SCALE_ITEM(225, 300, 0), + 11, 11, TLV_DB_SCALE_ITEM(3075, 0, 0), + 12, 12, TLV_DB_SCALE_ITEM(3225, 0, 0), +); + +static const struct snd_kcontrol_new es7202_controls[] = { + SOC_SINGLE_TLV("PGA1 Capture Volume", ES7202_PGA1, 0, 0x0c, 0, + mic_boost_tlv), + SOC_SINGLE_TLV("PGA2 Capture Volume", ES7202_PGA2, 0, 0x0c, 0, + mic_boost_tlv), +}; + +static const struct snd_soc_dapm_widget es7202_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("MIC1"), + SND_SOC_DAPM_INPUT("MIC2"), + SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_route es7202_dapm_routes[] = { + { "ADC", NULL, "MIC1" }, + { "ADC", NULL, "MIC2" }, +}; + +static int es7202_mute_pdm(struct es7202_priv *es7202, bool mute) +{ + return regmap_update_bits(es7202->regmap, ES7202_PDM_INF_CTL, + ES7202_PDM_INF_CTL_MUTE, + mute ? ES7202_PDM_INF_CTL_MUTE : 0); +} + +static int es7202_hw_init(struct es7202_priv *es7202) +{ + struct regmap *regmap = es7202->regmap; + bool is_1v8 = es7202->supply_uv > 0 && + es7202->supply_uv <= ES7202_SUPPLY_1V8_MAX_UV; + /* + * Power-up sequence from the vendor driver. + * The analog front-end is configured for the actual supply voltage + * (1.8 V vs 3.3 V) and the analog blocks are ramped out of + * power-down in stages. + */ + const struct reg_sequence init_seq[] = { + { ES7202_SOFT_MODE, ES7202_MODE_SOFT_MODE_SEL }, + { ES7202_ANALOG_MISC1, ES7202_ANALOG_MISC1_OFFSETSEL1 | + (is_1v8 ? 0 : ES7202_ANALOG_MISC1_SUPPLYSEL) }, + + /* 30.75 dB gain */ + { ES7202_PGA1, ES7202_PGA_SELMIC1 | + FIELD_PREP(ES7202_PGA_MIC1_GAIN, 11) }, + { ES7202_PGA2, ES7202_PGA_SELMIC2 | + FIELD_PREP(ES7202_PGA_MIC2_GAIN, 11) }, + + /* analog on, rest powered down */ + { ES7202_ANALOG_EN, ES7202_ANALOG_EN_PDN_ADCVREFGEN | + ES7202_ANALOG_EN_MODTOP1_RST | + ES7202_ANALOG_EN_MODTOP2_RST | + ES7202_ANALOG_EN_PDN_MOD1 | + ES7202_ANALOG_EN_PDN_MOD2 | + ES7202_ANALOG_EN_PDN_PGA1 | + ES7202_ANALOG_EN_PDN_PGA2 }, + + { ES7202_BIAS_VMID, FIELD_PREP(ES7202_BIAS_ADCBIAS_SWH1, 3) | + ES7202_BIAS_ENDITHER | + FIELD_PREP(ES7202_BIAS_VMIDSEL, 3) }, + + /* VREFGEN on; 3.3 V also drops MODTOP reset */ + { ES7202_ANALOG_EN, is_1v8 ? + (ES7202_ANALOG_EN_MODTOP1_RST | + ES7202_ANALOG_EN_MODTOP2_RST | + ES7202_ANALOG_EN_PDN_MOD1 | + ES7202_ANALOG_EN_PDN_MOD2 | + ES7202_ANALOG_EN_PDN_PGA1 | + ES7202_ANALOG_EN_PDN_PGA2) : + (ES7202_ANALOG_EN_PDN_MOD1 | + ES7202_ANALOG_EN_PDN_MOD2 | + ES7202_ANALOG_EN_PDN_PGA1 | + ES7202_ANALOG_EN_PDN_PGA2) }, + + { ES7202_ANALOG_EN, 0 }, + { ES7202_MOD1_BIAS, FIELD_PREP(ES7202_MOD1_BIAS_SW0, 5) | + FIELD_PREP(ES7202_MOD1_BIAS_SW1, 8) }, + { ES7202_CLK_DIV, FIELD_PREP(ES7202_CLK_DIV_MCLK_DIV, 1) }, + { ES7202_T2_VMID, 0x01 }, + { ES7202_MISC_CTL, ES7202_MISC_DSM_DITHER_ON }, + { ES7202_RESET, ES7202_RESET_CSM_ON }, + { ES7202_CLK_EN, ES7202_CLK_ANA_CLK_ON | ES7202_CLK_MCLK_ON }, + { ES7202_BIAS_VMID, FIELD_PREP(ES7202_BIAS_ADCBIAS_SWH1, 3) | + ES7202_BIAS_ENDITHER | + FIELD_PREP(ES7202_BIAS_VMIDSEL, 2) }, + }; + int ret; + + ret = regmap_multi_reg_write(regmap, init_seq, ARRAY_SIZE(init_seq)); + if (ret) + return ret; + + return es7202_mute_pdm(es7202, false); +} + +static int es7202_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_component *component = dai->component; + struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + return 0; + + return es7202_mute_pdm(es7202, mute); +} + +static const struct snd_soc_dai_ops es7202_dai_ops = { + .mute_stream = es7202_mute_stream, +}; + +static struct snd_soc_dai_driver es7202_dai = { + .name = "es7202-hifi", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &es7202_dai_ops, +}; + +static int es7202_suspend(struct snd_soc_component *component) +{ + struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component); + + return es7202_mute_pdm(es7202, true); +} + +static int es7202_resume(struct snd_soc_component *component) +{ + struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component); + int ret; + + regcache_mark_dirty(es7202->regmap); + ret = regcache_sync(es7202->regmap); + if (ret) + return ret; + + return es7202_mute_pdm(es7202, false); +} + +static const struct snd_soc_component_driver es7202_component_driver = { + .controls = es7202_controls, + .num_controls = ARRAY_SIZE(es7202_controls), + .dapm_widgets = es7202_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(es7202_dapm_widgets), + .dapm_routes = es7202_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(es7202_dapm_routes), + .suspend = es7202_suspend, + .resume = es7202_resume, + .idle_bias_on = 1, + .endianness = 1, +}; + +static void es7202_disable_supply(void *data) +{ + regulator_disable(data); +} + +static int es7202_i2c_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct es7202_priv *es7202; + unsigned int id1, id0, device_id; + int ret; + + es7202 = devm_kzalloc(dev, sizeof(*es7202), GFP_KERNEL); + if (!es7202) + return -ENOMEM; + + i2c_set_clientdata(i2c, es7202); + + es7202->regmap = devm_regmap_init_i2c(i2c, &es7202_regmap); + if (IS_ERR(es7202->regmap)) + return dev_err_probe(dev, PTR_ERR(es7202->regmap), + "failed to init regmap\n"); + + es7202->reset_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(es7202->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(es7202->reset_gpio), + "failed to get reset gpio\n"); + + es7202->supply = devm_regulator_get_optional(dev, "vdd"); + if (IS_ERR(es7202->supply)) { + if (PTR_ERR(es7202->supply) != -ENODEV) + return dev_err_probe(dev, PTR_ERR(es7202->supply), + "failed to get supply\n"); + + es7202->supply = NULL; + es7202->supply_uv = ES7202_SUPPLY_3V3_DEFAULT_UV; + } else { + ret = regulator_enable(es7202->supply); + if (ret) + return dev_err_probe(dev, ret, + "failed to enable supply\n"); + + ret = devm_add_action_or_reset(dev, es7202_disable_supply, + es7202->supply); + if (ret) + return dev_err_probe(dev, ret, + "failed to add supply disable action\n"); + + es7202->supply_uv = regulator_get_voltage(es7202->supply); + if (es7202->supply_uv < 0) + es7202->supply_uv = ES7202_SUPPLY_3V3_DEFAULT_UV; + } + + /* take the device out of reset */ + gpiod_set_value_cansleep(es7202->reset_gpio, 0); + usleep_range(1000, 2000); + + /* verify the chip is present by reading its device id */ + ret = regmap_read(es7202->regmap, ES7202_DEV_ID1, &id1); + if (ret) + return dev_err_probe(dev, ret, "failed to read device id\n"); + ret = regmap_read(es7202->regmap, ES7202_DEV_ID0, &id0); + if (ret) + return dev_err_probe(dev, ret, "failed to read device id\n"); + + device_id = (id1 << 8) | id0; + if (device_id != ES7202_DEVICE_ID) + return dev_err_probe(dev, -ENODEV, + "unexpected device id 0x%04x, expected 0x%04x\n", + device_id, ES7202_DEVICE_ID); + + ret = es7202_hw_init(es7202); + if (ret) + return dev_err_probe(dev, ret, "failed to init device\n"); + + return devm_snd_soc_register_component(dev, &es7202_component_driver, + &es7202_dai, 1); +} + +static void es7202_i2c_remove(struct i2c_client *i2c) +{ + struct es7202_priv *es7202 = i2c_get_clientdata(i2c); + + es7202_mute_pdm(es7202, true); +} + +static void es7202_i2c_shutdown(struct i2c_client *i2c) +{ + struct es7202_priv *es7202 = i2c_get_clientdata(i2c); + + es7202_mute_pdm(es7202, true); +} + +static const struct of_device_id es7202_of_match[] = { + { .compatible = "everest,es7202" }, + { } +}; +MODULE_DEVICE_TABLE(of, es7202_of_match); + +static const struct i2c_device_id es7202_i2c_id[] = { + { "es7202" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, es7202_i2c_id); + +static struct i2c_driver es7202_i2c_driver = { + .driver = { + .name = "es7202", + .of_match_table = of_match_ptr(es7202_of_match), + }, + .probe = es7202_i2c_probe, + .remove = es7202_i2c_remove, + .shutdown = es7202_i2c_shutdown, + .id_table = es7202_i2c_id, +}; +module_i2c_driver(es7202_i2c_driver); + +MODULE_DESCRIPTION("Everest Semi ES7202 PDM ADC ALSA SoC Codec Driver"); +MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>"); +MODULE_AUTHOR("Jun Yan <jerrysteve1101@gmail.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/es7202.h b/sound/soc/codecs/es7202.h new file mode 100644 index 000000000000..15811b73c20a --- /dev/null +++ b/sound/soc/codecs/es7202.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright Everest Semiconductor Co., Ltd. + * + * Author: David Yang <yangxiaohua@everest-semi.com> + * Author: Jun Yan <jerrysteve1101@gmail.com> + */ + +#ifndef _ES7202_H +#define _ES7202_H + +#include <linux/bits.h> + +/* Register addresses */ +#define ES7202_RESET 0x00 +#define ES7202_SOFT_MODE 0x01 +#define ES7202_CLK_DIV 0x02 +#define ES7202_CLK_EN 0x03 +#define ES7202_T1_VMID 0x04 +#define ES7202_T2_VMID 0x05 +#define ES7202_CHIP_STA 0x06 +#define ES7202_PDM_INF_CTL 0x07 +#define ES7202_MISC_CTL 0x08 +#define ES7202_ANALOG_EN 0x10 +#define ES7202_BIAS_VMID 0x11 +#define ES7202_PGA1_BIAS 0x12 +#define ES7202_PGA2_BIAS 0x13 +#define ES7202_MOD1_BIAS 0x14 +#define ES7202_MOD2_BIAS 0x15 +#define ES7202_VREFP_BIAS 0x16 +#define ES7202_VMMOD_BIAS 0x17 +#define ES7202_MODS_BIAS 0x18 +#define ES7202_ANALOG_LP1 0x19 +#define ES7202_ANALOG_LP2 0x1a +#define ES7202_ANALOG_MISC1 0x1b +#define ES7202_ANALOG_MISC2 0x1c +#define ES7202_PGA1 0x1d +#define ES7202_PGA2 0x1e +#define ES7202_DEV_ID1 0xfd +#define ES7202_DEV_ID0 0xfe + +#define ES7202_DEVICE_ID 0x7201 + +#define ES7202_RESET_RST_REGS BIT(5) +#define ES7202_RESET_RST_DIG BIT(4) +#define ES7202_RESET_SEQ_DIS BIT(1) +#define ES7202_RESET_CSM_ON BIT(0) + +#define ES7202_MODE_SOFT_MODE_SEL BIT(0) + +#define ES7202_CLK_DIV_MCLK_DIV GENMASK(3, 0) /* 0/1 = /16 ... 15 = /240 */ + +#define ES7202_CLK_MCLK_INVERT BIT(2) +#define ES7202_CLK_ANA_CLK_ON BIT(1) +#define ES7202_CLK_MCLK_ON BIT(0) + +#define ES7202_CHIP_STA_CSM_STATE GENMASK(5, 4) +#define ES7202_CHIP_STA_FORCE_CSM GENMASK(2, 0) + +#define ES7202_PDM_NEG_DATA_VALID BIT(5) +#define ES7202_PDM_POS_DATA_VALID BIT(4) +#define ES7202_PDM_CHN_CROSS BIT(3) +#define ES7202_PDM_IF_DLY BIT(2) +#define ES7202_PDM_DATA2_MUTE BIT(1) +#define ES7202_PDM_DATA1_MUTE BIT(0) +#define ES7202_PDM_INF_CTL_MUTE (ES7202_PDM_DATA2_MUTE | \ + ES7202_PDM_DATA1_MUTE) + +#define ES7202_MISC_CLKDET_RST_DIS BIT(2) +#define ES7202_MISC_DSM_DITHER_ON BIT(1) +#define ES7202_MISC_PDN_CLKDET BIT(0) + +#define ES7202_ANALOG_EN_PDN_ANA BIT(7) +#define ES7202_ANALOG_EN_PDN_ADCVREFGEN BIT(6) +#define ES7202_ANALOG_EN_MODTOP1_RST BIT(5) +#define ES7202_ANALOG_EN_MODTOP2_RST BIT(4) +#define ES7202_ANALOG_EN_PDN_MOD1 BIT(3) +#define ES7202_ANALOG_EN_PDN_MOD2 BIT(2) +#define ES7202_ANALOG_EN_PDN_PGA1 BIT(1) +#define ES7202_ANALOG_EN_PDN_PGA2 BIT(0) + +#define ES7202_BIAS_ADCBIAS_SWH0 GENMASK(7, 6) +#define ES7202_BIAS_ENDITHER BIT(5) +#define ES7202_BIAS_ADCBIAS_SWH1 GENMASK(3, 2) +#define ES7202_BIAS_VMIDSEL GENMASK(1, 0) /* 0 = off, 1 = 50k, 2 = 500k, 3 = 5k */ + +/* bias levels 0x12-0x18 (SW0 for 1.8 V, SW1 for 3.3 V) */ +#define ES7202_PGA1_BIAS_SW0 GENMASK(7, 4) +#define ES7202_PGA1_BIAS_SW1 GENMASK(3, 0) +#define ES7202_PGA2_BIAS_SW0 GENMASK(7, 4) +#define ES7202_PGA2_BIAS_SW1 GENMASK(3, 0) +#define ES7202_MOD1_BIAS_SW0 GENMASK(7, 4) +#define ES7202_MOD1_BIAS_SW1 GENMASK(3, 0) +#define ES7202_MOD2_BIAS_SW0 GENMASK(7, 4) +#define ES7202_MOD2_BIAS_SW1 GENMASK(3, 0) +#define ES7202_VREFP_BIAS_SW0 GENMASK(7, 4) +#define ES7202_VREFP_BIAS_SW1 GENMASK(3, 0) +#define ES7202_VMMOD_BIAS_SW0 GENMASK(7, 4) +#define ES7202_VMMOD_BIAS_SW1 GENMASK(3, 0) +#define ES7202_MODS_BIAS_SW0 GENMASK(7, 4) +#define ES7202_MODS_BIAS_SW1 GENMASK(3, 0) + +#define ES7202_LP1_LP_VRP BIT(7) +#define ES7202_LP1_LP_VRPOUT BIT(6) +#define ES7202_LP1_LP_VMMOD1 BIT(5) +#define ES7202_LP1_LP_VMMOD2 BIT(4) +#define ES7202_LP1_LP_MODS1 BIT(3) +#define ES7202_LP1_LP_MODS2 BIT(2) +#define ES7202_LP1_LP_MODI1 BIT(1) +#define ES7202_LP1_LP_MODI2 BIT(0) + +#define ES7202_LP2_LP_PGA1 BIT(5) +#define ES7202_LP2_LP_PGA2 BIT(4) +#define ES7202_LP2_PDN_DETCT BIT(3) + +#define ES7202_ANALOG_MISC1_OFFSETSEL1 BIT(6) +#define ES7202_ANALOG_MISC1_OFFSETSEL0 BIT(5) +#define ES7202_ANALOG_MISC1_SUPPLYSEL BIT(4) /* 0 = 1.8 V, 1 = 3.3 V */ +#define ES7202_ANALOG_MISC1_DITHERSEL GENMASK(2, 0) + +#define ES7202_ANALOG_MISC2_VX2OFF_SW0 BIT(7) +#define ES7202_ANALOG_MISC2_VX1SEL_SW0 BIT(6) +#define ES7202_ANALOG_MISC2_VMIDLOW_SW0 GENMASK(5, 4) +#define ES7202_ANALOG_MISC2_VX2OFF_SW1 BIT(3) +#define ES7202_ANALOG_MISC2_VX1SEL_SW1 BIT(2) +#define ES7202_ANALOG_MISC2_VMIDLOW_SW1 GENMASK(1, 0) + +#define ES7202_PGA_SELMIC1 BIT(4) +#define ES7202_PGA_MIC1_GAIN GENMASK(3, 0) +#define ES7202_PGA_SELMIC2 BIT(4) +#define ES7202_PGA_MIC2_GAIN GENMASK(3, 0) + +#endif -- 2.56.0 _______________________________________________ Linux-rockchip mailing list Linux-rockchip@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-rockchip ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] ASoC: codecs: add support for Everest ES7202 PDM ADC 2026-10-20 14:31 ` Jun Yan (?) @ 2026-10-20 14:49 ` sashiko-bot -1 siblings, 0 replies; 7+ messages in thread From: sashiko-bot @ 2026-10-20 14:49 UTC (permalink / raw) To: Jun Yan; +Cc: devicetree, robh, conor+dt Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider: - [Medium] ASoC: es7202: unsigned supply_uv breaks regulator_get_voltage() error check - [Medium] ASoC: es7202: unmute in es7202_hw_init() skipped due to regmap cache default - [Medium] ASoC: es7202: broken power-up sequence and mute state in es7202_resume() - [Low] ASoC: es7202: unused es7202_of_match warning with of_match_ptr() when !CONFIG_OF -- commit 4a58517803f32764e08604ccc9d3e4df540a41cb Author: Jun Yan <jerrysteve1101@gmail.com> ASoC: codecs: add support for Everest ES7202 PDM ADC This commit adds an ASoC codec driver for the Everest Semiconductor ES7202 2-channel PDM analog-to-digital converter controlled over I2C. Link: https://archive.org/details/es-7202-ds > diff --git a/sound/soc/codecs/es7202.c b/sound/soc/codecs/es7202.c > new file mode 100644 > index 0000000000000..c30b0123c91f8 > --- /dev/null > +++ b/sound/soc/codecs/es7202.c > @@ -0,0 +1,372 @@ [ ... ] > +struct es7202_priv { > + struct regmap *regmap; > + struct regulator *supply; > + struct gpio_desc *reset_gpio; > + unsigned int supply_uv; > +}; > + > +static bool es7202_volatile_reg(struct device *dev, unsigned int reg) > +{ > + /* status and device-id registers are read-only, never cached */ > + return reg == ES7202_CHIP_STA || > + reg == ES7202_DEV_ID1 || > + reg == ES7202_DEV_ID0; > +} > + > +static const struct reg_default es7202_reg_defaults[] = { > + { ES7202_RESET, 0x10 }, > + { ES7202_SOFT_MODE, 0x00 }, > + { ES7202_CLK_DIV, 0x04 }, > + { ES7202_CLK_EN, 0x00 }, > + { ES7202_T1_VMID, 0x01 }, > + { ES7202_T2_VMID, 0x18 }, > + { ES7202_PDM_INF_CTL, 0x30 }, [ ... ] > +static int es7202_mute_pdm(struct es7202_priv *es7202, bool mute) > +{ > + return regmap_update_bits(es7202->regmap, ES7202_PDM_INF_CTL, > + ES7202_PDM_INF_CTL_MUTE, > + mute ? ES7202_PDM_INF_CTL_MUTE : 0); > +} > + > +static int es7202_hw_init(struct es7202_priv *es7202) > +{ > + struct regmap *regmap = es7202->regmap; > + bool is_1v8 = es7202->supply_uv > 0 && > + es7202->supply_uv <= ES7202_SUPPLY_1V8_MAX_UV; > + /* > + * Power-up sequence from the vendor driver. > + * The analog front-end is configured for the actual supply voltage > + * (1.8 V vs 3.3 V) and the analog blocks are ramped out of > + * power-down in stages. > + */ > + const struct reg_sequence init_seq[] = { > + { ES7202_SOFT_MODE, ES7202_MODE_SOFT_MODE_SEL }, > + { ES7202_ANALOG_MISC1, ES7202_ANALOG_MISC1_OFFSETSEL1 | > + (is_1v8 ? 0 : ES7202_ANALOG_MISC1_SUPPLYSEL) }, > + > + /* 30.75 dB gain */ > + { ES7202_PGA1, ES7202_PGA_SELMIC1 | > + FIELD_PREP(ES7202_PGA_MIC1_GAIN, 11) }, > + { ES7202_PGA2, ES7202_PGA_SELMIC2 | > + FIELD_PREP(ES7202_PGA_MIC2_GAIN, 11) }, > + > + /* analog on, rest powered down */ > + { ES7202_ANALOG_EN, ES7202_ANALOG_EN_PDN_ADCVREFGEN | > + ES7202_ANALOG_EN_MODTOP1_RST | > + ES7202_ANALOG_EN_MODTOP2_RST | > + ES7202_ANALOG_EN_PDN_MOD1 | > + ES7202_ANALOG_EN_PDN_MOD2 | > + ES7202_ANALOG_EN_PDN_PGA1 | > + ES7202_ANALOG_EN_PDN_PGA2 }, > + > + { ES7202_BIAS_VMID, FIELD_PREP(ES7202_BIAS_ADCBIAS_SWH1, 3) | > + ES7202_BIAS_ENDITHER | > + FIELD_PREP(ES7202_BIAS_VMIDSEL, 3) }, > + > + /* VREFGEN on; 3.3 V also drops MODTOP reset */ > + { ES7202_ANALOG_EN, is_1v8 ? > + (ES7202_ANALOG_EN_MODTOP1_RST | > + ES7202_ANALOG_EN_MODTOP2_RST | > + ES7202_ANALOG_EN_PDN_MOD1 | > + ES7202_ANALOG_EN_PDN_MOD2 | > + ES7202_ANALOG_EN_PDN_PGA1 | > + ES7202_ANALOG_EN_PDN_PGA2) : > + (ES7202_ANALOG_EN_PDN_MOD1 | > + ES7202_ANALOG_EN_PDN_MOD2 | > + ES7202_ANALOG_EN_PDN_PGA1 | > + ES7202_ANALOG_EN_PDN_PGA2) }, > + > + { ES7202_ANALOG_EN, 0 }, > + { ES7202_MOD1_BIAS, FIELD_PREP(ES7202_MOD1_BIAS_SW0, 5) | > + FIELD_PREP(ES7202_MOD1_BIAS_SW1, 8) }, > + { ES7202_CLK_DIV, FIELD_PREP(ES7202_CLK_DIV_MCLK_DIV, 1) }, > + { ES7202_T2_VMID, 0x01 }, > + { ES7202_MISC_CTL, ES7202_MISC_DSM_DITHER_ON }, > + { ES7202_RESET, ES7202_RESET_CSM_ON }, > + { ES7202_CLK_EN, ES7202_CLK_ANA_CLK_ON | ES7202_CLK_MCLK_ON }, > + { ES7202_BIAS_VMID, FIELD_PREP(ES7202_BIAS_ADCBIAS_SWH1, 3) | > + ES7202_BIAS_ENDITHER | > + FIELD_PREP(ES7202_BIAS_VMIDSEL, 2) }, > + }; > + int ret; > + > + ret = regmap_multi_reg_write(regmap, init_seq, ARRAY_SIZE(init_seq)); > + if (ret) > + return ret; > + > + return es7202_mute_pdm(es7202, false); > +} [Severity: Medium] Will es7202_mute_pdm(es7202, false) at the end of es7202_hw_init() ever write to the hardware? In es7202_reg_defaults[], ES7202_PDM_INF_CTL is initialized in the REGCACHE_MAPLE cache to 0x30, which already has the ES7202_PDM_INF_CTL_MUTE bits [1:0] cleared. Because init_seq does not touch ES7202_PDM_INF_CTL or reset the register file (ES7202_RESET_RST_REGS), regmap_update_bits() in es7202_mute_pdm(es7202, false) sees that the cached value is already 0x30 and skips the I2C write. If the driver was previously unbound via es7202_i2c_remove() or the system went through es7202_i2c_shutdown() (both of which write 0x33 to mute ES7202_PDM_INF_CTL in hardware) and is then rebound or warm-rebooted on a board without the optional reset-gpios or a switched vdd-supply, both es7202_hw_init() and the subsequent es7202_mute_stream() on capture startup will be skipped by the regmap cache, leaving the hardware muted. [ ... ] > +static int es7202_suspend(struct snd_soc_component *component) > +{ > + struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component); > + > + return es7202_mute_pdm(es7202, true); > +} > + > +static int es7202_resume(struct snd_soc_component *component) > +{ > + struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component); > + int ret; > + > + regcache_mark_dirty(es7202->regmap); > + ret = regcache_sync(es7202->regmap); > + if (ret) > + return ret; > + > + return es7202_mute_pdm(es7202, false); > +} [Severity: Medium] Does es7202_resume() properly restore the hardware state and mute status after system suspend? In es7202_hw_init(), the chip requires a staged power-up sequence that enables ES7202_SOFT_MODE, configures ES7202_ANALOG_MISC1 for the supply voltage, ramps ES7202_ANALOG_EN across three writes while fast-charging VMID with VMIDSEL=3 in ES7202_BIAS_VMID, and finally switches ES7202_BIAS_VMID to VMIDSEL=2. In es7202_resume(), regcache_sync() writes the final cached register values in ascending address order (0x00 to 0x1e). If the device lost power or was reset during suspend, this writes ES7202_RESET (0x00) before ES7202_SOFT_MODE (0x01) and powers on all analog blocks at once in ES7202_ANALOG_EN (0x10 = 0x00) before ES7202_ANALOG_MISC1 (0x1b) is configured for 3.3 V, skipping the analog ramp and VMID fast-charge stages. Additionally, es7202_suspend() calls es7202_mute_pdm(es7202, true), which updates the cached value of ES7202_PDM_INF_CTL to muted (0x33), and es7202_resume() then unconditionally calls es7202_mute_pdm(es7202, false), unmuting the PDM output even if no capture stream was active and the DAI was muted via es7202_mute_stream() prior to suspend. [ ... ] > +static int es7202_i2c_probe(struct i2c_client *i2c) > +{ > + struct device *dev = &i2c->dev; > + struct es7202_priv *es7202; > + unsigned int id1, id0, device_id; > + int ret; [ ... ] > + es7202->supply = devm_regulator_get_optional(dev, "vdd"); > + if (IS_ERR(es7202->supply)) { > + if (PTR_ERR(es7202->supply) != -ENODEV) > + return dev_err_probe(dev, PTR_ERR(es7202->supply), > + "failed to get supply\n"); > + > + es7202->supply = NULL; > + es7202->supply_uv = ES7202_SUPPLY_3V3_DEFAULT_UV; > + } else { > + ret = regulator_enable(es7202->supply); > + if (ret) > + return dev_err_probe(dev, ret, > + "failed to enable supply\n"); > + > + ret = devm_add_action_or_reset(dev, es7202_disable_supply, > + es7202->supply); > + if (ret) > + return dev_err_probe(dev, ret, > + "failed to add supply disable action\n"); > + > + es7202->supply_uv = regulator_get_voltage(es7202->supply); > + if (es7202->supply_uv < 0) > + es7202->supply_uv = ES7202_SUPPLY_3V3_DEFAULT_UV; > + } [Severity: Medium] Since es7202->supply_uv is declared as unsigned int in struct es7202_priv, won't the check: es7202->supply_uv = regulator_get_voltage(es7202->supply); if (es7202->supply_uv < 0) es7202->supply_uv = ES7202_SUPPLY_3V3_DEFAULT_UV; always evaluate to false? If regulator_get_voltage() returns a negative error code (such as -EINVAL when a regulator does not support voltage queries or when CONFIG_REGULATOR is disabled), storing it directly into unsigned int es7202->supply_uv wraps it to a large positive value and skips the fallback to ES7202_SUPPLY_3V3_DEFAULT_UV. [ ... ] > +static const struct of_device_id es7202_of_match[] = { > + { .compatible = "everest,es7202" }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, es7202_of_match); > + > +static const struct i2c_device_id es7202_i2c_id[] = { > + { "es7202" }, > + { } > +}; > +MODULE_DEVICE_TABLE(i2c, es7202_i2c_id); > + > +static struct i2c_driver es7202_i2c_driver = { > + .driver = { > + .name = "es7202", > + .of_match_table = of_match_ptr(es7202_of_match), > + }, [Severity: Low] When CONFIG_OF is disabled, of_match_ptr(es7202_of_match) expands to NULL while es7202_of_match is defined unconditionally without __maybe_unused. Could of_match_ptr() be dropped here to avoid an unused-const-variable warning when building with !CONFIG_OF? > + .probe = es7202_i2c_probe, > + .remove = es7202_i2c_remove, > + .shutdown = es7202_i2c_shutdown, > + .id_table = es7202_i2c_id, > +}; [ ... ] -- Sashiko AI review · https://sashiko.dev/#/patchset/20261020143135.623897-1-jerrysteve1101@gmail.com?part=2 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-20 14:49 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-20 14:31 [PATCH 0/2] ASoC: codecs: Add Everest ES7202 support Jun Yan 2026-10-20 14:31 ` Jun Yan 2026-10-20 14:31 ` [PATCH 1/2] dt-bindings: sound: add Everest ES7202 Jun Yan 2026-10-20 14:31 ` Jun Yan 2026-10-20 14:31 ` [PATCH 2/2] ASoC: codecs: add support for Everest ES7202 PDM ADC Jun Yan 2026-10-20 14:31 ` Jun Yan 2026-10-20 14:49 ` sashiko-bot
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.