I've submitted this a couple of times, but the kernel test robot has come back with various remarks, so I've reworked it a bit more hopefully with positive results this time.
This is a codec driver for the TLV320ADC3001 and TLV320ADC3101 2 channel audio ADC chips from Texas Instruments.
Based on an old driver for these chips that I was referred to by Texas Instruments, but which apparently was never upstreamed, I've taken patches from various incarnations, ported them and augmented them with various new features in order to make a working driver.
There is currently no support for the on-chip "miniDSP".
Although the TLV320ADC3001 and TLV320ADC3101 have similarities with other TI codec chips for which there are existing drivers, upon closer inspection I decided the differences were too great to warrant attempting to modify an existing driver, especially without access to all supported chips and resources for testing them all.
There are certainly things that could be improved, among others in the area of PLL register value calculations, but it has been tested on the Axis ARTPEC-8 platform and has been found to work satisfactorily at least with a TLV320ADC3101 operating as an I2S slave at 48 kHz with 32 bit bit depth, 1 or 2 channels, both with the on-chip PLL enabled and disabled.
I have not tested this on a TLV320ADC3001 chip; in the original driver the only differences were related to the now-removed initialization code, so I've just retained the compatible strings for both chips.
Limitations: - GPIO pins on chip can only be set up as outputs. - Using BCLK as an input to clock chain is supported by the hw but not by driver.
Changes v5->v6:
- Added missing "depends on I2C" in the Kconfig (reported by lkp@intel.com). - Fold include file into source as it is not needed elsewhere. - Fix SPDX-License-Identifier which was using a deprecated license. - Clean up authorship information in file header, removing history. - Remove useless GPIOLIB ifdefs. - Use devm_gpiod_get for reset gpio rather than devm_gpio_request etc. - Handle EPROBE_DEFER properly for reset gpio request. - Use dev_err_probe rather than explicit EPROBE_DEFER checking. - Properly check value from DT parsing for mic bias and codec gpio pins.
No changes to the devicetree bindings.
Changes v4->v5:
Yet another fix based on kernel test robot (lkp@intel.com), this time a legitimate issue: the return value from of_get_named_gpio_flags() was crammed into an unsigned int so any potential negative error codes were lost.
No changes to the devicetree bindings.
Changes v3->v4:
More fixes reported by kernel test robot (lkp@intel.com). Don't know why these weren't reported the first time.
Changes v2->v3:
Fix a couple of issues reported by the kernel test robot (lkp@intel.com).
Changes v1->v2:
Large portions of the driver have been reworked from v1 based on remarks from Mark. More specifically:
- Remove an unneeded #ifdef and EXPORT_SYMBOL_GPL. - Add ADC3XXX_ prefix to all macro names to avoid namespace contention. - Clean up certain macro names with mixed lower case - upper case names. - Do away with the D0..D7 macros representing bit values. - Fix general formatting: spaces before and after {, }, replace multi spaces with tabs, maximum 2 blank lines anywhere, and other minor issues. - Page register does not need to be volatile. - Rather than use 0 / -6dB enum for input attenuator, use standard TLV. - The dither offset control contains reserved values so use VALUE_ENUM instead of straight ENUM. - Replace vector of SOC_ENUMs with individual variables. - Fix ALSA control names: - Use Volume at the end of all gain controls, and remove "Gain" where applicable. - Use "Switch" at the end of all switch controls, either adding it or changing "switch" into "Switch" as applicable. - Switches and Volumes related to capture should be set up as such, so add "Capture" to widget names where appropriate. This is mostly important for the PGA Capture and Switch widgets, not just for consistency, but also because amixer simple Switch controls expect different names (cap/nocap instead of on/off) for control values for capture. - Make widget names have capital first letters for all consitutent words. - When resuming, the registers will not have changed, so no need to call snd_soc_component_cache_sync(). - Move reset gpio init to I2C probe - Remove needless _priv at end of private struct name. - Make hex constants lower case - _CBM_CFM/_CBS_CFS -> _CBP_CFP/_CBC_CFC - Instead of using device specific ALSA controls to control the two GPIO pins, use GPIOLIB. GPIO pin functions still can be set up in the devicetree as the pins can be used for other functions which are not GPIO related. - Limitation: The GPIO pins can only be used as outputs, even though the hardware alternatively supports using them as inputs. - Handle GPIO configs in a vector rather than separately. - Use more appropriate module_i2c_driver instead of generic module_init/module_exit. - Remove useless initialization data. - As the ADC mute function had no control, add it. - Clean up GPIO initialization which was done both in the I2C probe and in the component probe. - Remove probe, remove, suspend and resume callbacks, which either do not do anything at all anymore, or uselessly just do set_bias_level. - The PLL should not be configured in the devicetree, so move the corresponding definitions to tlv320adc3xxx.h where they can be picked up by a machine driver if needed. - Default to PLL AUTO mode. - Use "reset-gpios" instead of too-generic "gpios" for dt property for configuring codec reset pin. - Use function for printing PLL mode rather than macro. - dev_info is too verbose for most of the printouts, change them to dev_dbg. - Add support for configuring micbias voltage in DT. - Remove ALSA control for mic bias. - Move PLL and NADC, MADC divisor enable to DAPM, including 10 ms post PLL start up delay via POST_PMU event. - ADC is powered on using DAPM, so needless to do it in set_bias_level, thus remove it. - Let DAPM handle BCLK divisor enable. With this, we can remove set_bias_level as it doesn't do anything anymore. - Fix incorrect argument order to a snd_soc_component_update_bits call. - Although the chip itself can operate using BCLK as the clock source, either directly to the divider chain or via the PLL, this is not yet supported in the driver, so require the clocks property for the MCLK for now. - Move PLL rate structure out of .h file where it does not belong.
/Ricard
Ricard Wanderlof (2): dt-bindings: sound: tlv320adc3xxx: New codec driver ASoC: codec: tlv320adc3xxx: New codec driver
.../bindings/sound/ti,tlv320adc3xxx.yaml | 137 ++ include/dt-bindings/sound/tlv320adc3xxx.h | 28 + sound/soc/codecs/Kconfig | 8 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/tlv320adc3xxx.c | 1311 +++++++++++++++++ 5 files changed, 1486 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ti,tlv320adc3xxx.yaml create mode 100644 include/dt-bindings/sound/tlv320adc3xxx.h create mode 100644 sound/soc/codecs/tlv320adc3xxx.c