[PATCH 0/4] ASoC: add ESS Technology ES9039Q2M codec driver
Karl Asseily <[email protected]>
| Newsgroups | gmane.linux.drivers.devicetree,gmane.linux.sound,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
This series adds support for the ESS Technology ES9039Q2M, a 32-bit two-channel audio DAC with an asynchronous sample rate converter, controlled over I2C. The part has two control personalities selected by its MODE pin: hardware mode, strapped by HW0/HW1/HW2 with no bus at all, and software mode over I2C or SPI. This driver implements software mode over I2C, which MODE = GND selects. Three properties of the part shape the driver: - The ASRC in front of the DAC means MCLK need not be synchronous with BCLK or LRCK. A board can feed it a fixed oscillator and never touch the clock again. In that asynchronous mode the part requires MCLK >= 130 x Fs, so the driver installs a startup constraint deriving the maximum rate from the MCLK it was given rather than advertising rates the hardware cannot honour. - Selecting an input format is two registers, not one. Register 57 INPUT_SEL chooses which port to listen to; register 1 SYS MODE CONFIG enables the corresponding decoder, and at reset only ENABLE_TDM_DECODE is set. Selecting DoP without also enabling ENABLE_DOP_DECODE leaves the part hunting for a marker with the marker decoder switched off; it finds no valid DoP and mutes. The driver sets both. - Several registers have non-zero reserved defaults - register 88 reads 0xb8 at reset - so every write is read-modify-write. Everything the driver exposes has been verified against the silicon on hardware rather than against the driver's own read-back: each control is written through ALSA and the chip's register is then read over raw I2C. That covers the eight filter shapes, the modulator bandwidth, the IIR bandwidth, the four signed 16-bit THD compensation coefficients at both extremes of their range, and the automute enable, time, level and off-level fields including the neighbouring MUTE_RAMP_TO_GND bit that shares a register with the 11-bit time field. Two limitations are deliberate and worth stating up front, because both look like omissions: - The programmable FIR coefficient controls are write-only. The part has a PROG_COEFF_OUT register described as "Programmable FIR coefficient readback", but it is not a RAM read port: it returns the last coefficient written, whatever address is selected in PROG_COEFF_ADDR. Measured by writing two different coefficients to addresses 0 and 1 and reading them back with five different sequences - plain, with a settle delay, with PROG_COEFF_EN set, with the address written twice, and with a write-enable pulse after the address. All ten reads returned the value written to address 1. A get() built on that register would return something with the shape of data and none of its meaning, so there is none. - Coefficient uploads pulse PROG_COEFF_WE per coefficient, as the datasheet's sequence specifies. Holding it high across the whole upload also works on this silicon, but that is not what the documentation says. DSD, DoP and S/PDIF input are all implemented. DoP is detected by the part rather than announced by the host: AUTO_INPUT_SEL is enabled and both the TDM and DoP decoders run, so a player can simply send DoP-encoded PCM, which is the only way DoP works in practice. An earlier revision of this driver required userspace to select DoP through a kcontrol first; no player can do that, and the result was that DoP-encoded material rendered as the near- silent hiss the DoP marker design deliberately degrades to. The datasheet attaches a "data must be provided on the DATA2 pin" condition to automatic detection; that applies to identifying DSD, whose channels arrive on separate data lines, and DoP detects correctly on a two-channel I2S link without it. DoP was verified end to end by generating a DSD64 test tone, carrying it as 32-bit PCM at 176400 Hz with nothing selected by hand, and confirming the part's own DOP_VALID flag and INPUT_SELECT_OVERRIDE readback while it played. ESS Technology has no bindings in the tree today, so the series also introduces the vendor prefix. Karl Asseily (4): dt-bindings: vendor-prefixes: add ESS Technology ASoC: dt-bindings: add ESS Technology ES9039Q2M ASoC: es9039q2m: add ESS Technology ES9039Q2M codec driver MAINTAINERS: add entry for the ES9039Q2M codec driver .../bindings/sound/ess,es9039q2m.yaml | 61 + .../devicetree/bindings/vendor-prefixes.yaml | 2 + MAINTAINERS | 7 + sound/soc/codecs/Kconfig | 14 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/es9039q2m.c | 1259 +++++++++++++++++ 6 files changed, 1345 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ess,es9039q2m.yaml create mode 100644 sound/soc/codecs/es9039q2m.c -- 2.34.1