mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
ASoC: Add support for Rpi-DAC ASoC: Add prompt for ICS43432 codec Without a prompt string, a config setting can't be included in a defconfig. Give CONFIG_SND_SOC_ICS43432 a prompt so that Pi soundcards can use the driver. Signed-off-by: Phil Elwell <phil@raspberrypi.org> Add IQaudIO Sound Card support for Raspberry Pi Set a limit of 0dB on Digital Volume Control The main volume control in the PCM512x DAC has a range up to +24dB. This is dangerously loud and can potentially cause massive clipping in the output stages. Therefore this sets a sensible limit of 0dB for this control. Allow up to 24dB digital gain to be applied when using IQAudIO DAC+ 24db_digital_gain DT param can be used to specify that PCM512x codec "Digital" volume control should not be limited to 0dB gain, and if specified will allow the full 24dB gain. Modify IQAudIO DAC+ ASoC driver to set card/dai config from dt Add the ability to set the card name, dai name and dai stream name, from dt config. Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk> IQaudIO: auto-mute for AMP+ and DigiAMP+ IQAudIO amplifier mute via GPIO22. Add dt params for "one-shot" unmute and auto mute. Revision 2, auto mute implementing HiassofT suggestion to mute/unmute using set_bias_level, rather than startup/shutdown.... "By default DAPM waits 5 seconds (pmdown_time) before shutting down playback streams so a close/stop immediately followed by open/start doesn't trigger an amp mute+unmute." Tested on both AMP+ (via DAC+) and DigiAMP+, with both options... dtoverlay=iqaudio-dacplus,unmute_amp "one-shot" unmute when kernel module loads. dtoverlay=iqaudio-dacplus,auto_mute_amp Unmute amp when ALSA device opened by a client. Mute, with 5 second delay when ALSA device closed. (Re-opening the device within the 5 second close window, will cancel mute.) Revision 4, using gpiod. Revision 5, clean-up formatting before adding mute code. - Convert tab plus 4 space formatting to 2x tab - Remove '// NOT USED' commented code Revision 6, don't attempt to "one-shot" unmute amp, unless card is successfully registered. Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk> ASoC: iqaudio-dac: fix S24_LE format Remove set_bclk_ratio call so 24-bit data is transmitted in 24 bclk cycles. Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: iqaudio-dac: use modern dai_link style Signed-off-by: Matthias Reichl <hias@horus.com> Added support for HiFiBerry DAC+ The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses a different codec chip (PCM5122), therefore a new driver is necessary. Add support for the HiFiBerry DAC+ Pro. The HiFiBerry DAC+ and DAC+ Pro products both use the existing bcm sound driver with the DAC+ Pro having a special clock device driver representing the two high precision oscillators. An addition bug fix is included for the PCM512x codec where by the physical size of the sample frame is used in the calculation of the LRCK divisor as it was found to be wrong when using 24-bit depth sample contained in a little endian 4-byte sample frame. Limit PCM512x "Digital" gain to 0dB by default with HiFiBerry DAC+ 24db_digital_gain DT param can be used to specify that PCM512x codec "Digital" volume control should not be limited to 0dB gain, and if specified will allow the full 24dB gain. Add dt param to force HiFiBerry DAC+ Pro into slave mode "dtoverlay=hifiberry-dacplus,slave" Add 'slave' param to use HiFiBerry DAC+ Pro in slave mode, with Pi as master for bit and frame clock. Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk> Fixed a bug when using 352.8kHz sample rate Signed-off-by: Daniel Matuschek <daniel@hifiberry.com> ASoC: pcm512x: revert downstream changes This partially reverts commit185ea05465which was added by https://github.com/raspberrypi/linux/pull/1152 The downstream pcm512x changes caused a regression, it broke normal use of the 24bit format with the codec, eg when using simple-audio-card. The actual bug with 24bit playback is the incorrect usage of physical_width in various drivers in the downstream tree which causes 24bit data to be transmitted with 32 clock cycles. So it's not the pcm512x that needs fixing, it's the soundcard drivers. Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: hifiberry_dacplus: fix S24_LE format Remove set_bclk_ratio call so 24-bit data is transmitted in 24 bclk cycles. Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: hifiberry_dacplus: transmit S24_LE with 64 BCLK cycles Signed-off-by: Matthias Reichl <hias@horus.com> hifiberry_dacplus: switch to snd_soc_dai_set_bclk_ratio Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: hifiberry_dacplus: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Add driver for rpi-proto Forward port of 3.10.x driver from https://github.com/koalo We are using a custom board and would like to use rpi 3.18.x kernel. Patch works fine for our embedded system. URL to the audio chip: http://www.mikroe.com/add-on-boards/audio-voice/audio-codec-proto/ Playback tested with devicetree enabled. Signed-off-by: Waldemar Brodkorb <wbrodkorb@conet.de> ASoC: rpi-proto: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Add Support for JustBoom Audio boards justboom-dac: Adjust for ALSA API change As of 4.4, snd_soc_limit_volume now takes a struct snd_soc_card * rather than a struct snd_soc_codec *. Signed-off-by: Phil Elwell <phil@raspberrypi.org> ASoC: justboom-dac: fix S24_LE format Remove set_bclk_ratio call so 24-bit data is transmitted in 24 bclk cycles. Also remove hw_params as it's no longer needed. Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: justboom-dac: use modern dai_link style Signed-off-by: Matthias Reichl <hias@horus.com> New AudioInjector.net Pi soundcard with low jitter audio in and out. Contains the sound/soc/bcm ALSA machine driver and necessary alterations to the Kconfig and Makefile. Adds the dts overlay and updates the Makefile and README. Updates the relevant defconfig files to enable building for the Raspberry Pi. Thanks to Phil Elwell (pelwell) for the review, simple-card concepts and discussion. Thanks to Clive Messer for overlay naming suggestions. Added support for headphones, microphone and bclk_ratio settings. This patch adds headphone and microphone capability to the Audio Injector sound card. The patch also sets the bit clock ratio for use in the bcm2835-i2s driver. The bcm2835-i2s can't handle an 8 kHz sample rate when the bit clock is at 12 MHz because its register is only 10 bits wide which can't represent the ch2 offset of 1508. For that reason, the rate constraint is added. ASoC: audioinjector-pi-soundcard: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> New driver for RRA DigiDAC1 soundcard using WM8741 + WM8804 ASoC: digidac1-soundcard: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Add support for Dion Audio LOCO DAC-AMP HAT Using dedicated machine driver and pcm5102a codec driver. Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk> ASoC: dionaudio_loco: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Allo Piano DAC boards: Initial 2 channel (stereo) support (#1645) Add initial 2 channel (stereo) support for Allo Piano DAC (2.0/2.1) boards, using allo-piano-dac-pcm512x-audio overlay and allo-piano-dac ALSA ASoC machine driver. NB. The initial support is 2 channel (stereo) ONLY! (The Piano DAC 2.1 will only support 2 channel (stereo) left/right output, pending an update to the upstream pcm512x codec driver, which will have to be submitted via upstream. With the initial downstream support, provided by this patch, the Piano DAC 2.1 subwoofer outputs will not function.) Signed-off-by: Baswaraj K <jaikumar@cem-solutions.net> Signed-off-by: Clive Messer <clive.messer@digitaldreamtime.co.uk> Tested-by: Clive Messer <clive.messer@digitaldreamtime.co.uk> ASoC: allo-piano-dac: fix S24_LE format Remove set_bclk_ratio call so 24-bit data is transmitted in 24 bclk cycles. Also remove hw_params and ops as they are no longer needed. Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: allo-piano-dac: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Add support for Allo Piano DAC 2.1 plus add-on board for Raspberry Pi. The Piano DAC 2.1 has support for 4 channels with subwoofer. Signed-off-by: Baswaraj K <jaikumar@cem-solutions.net> Reviewed-by: Vijay Kumar B. <vijaykumar@zilogic.com> Reviewed-by: Raashid Muhammed <raashidmuhammed@zilogic.com> Add clock changes and mute gpios (#1938) Also improve code style and adhere to ALSA coding conventions. Signed-off-by: Baswaraj K <jaikumar@cem-solutions.net> Reviewed-by: Vijay Kumar B. <vijaykumar@zilogic.com> Reviewed-by: Raashid Muhammed <raashidmuhammed@zilogic.com> PianoPlus: Dual Mono & Dual Stereo features added (#2069) allo-piano-dac-plus: Master volume added + fixes Master volume added, which controls both DACs volumes. See: https://github.com/raspberrypi/linux/pull/2149 Also fix initial max volume, default mode value, and unmute. Signed-off-by: allocom <sparky-dev@allo.com> ASoC: allo-piano-dac-plus: fix S24_LE format Remove set_bclk_ratio call so 24-bit data is transmitted in 24 bclk cycles. Signed-off-by: Matthias Reichl <hias@horus.com> sound: bcm: Fix memset dereference warning This warning appears with GCC 6.4.0 from toolchains.bootlin.com: ../sound/soc/bcm/allo-piano-dac-plus.c: In function ‘snd_allo_piano_dac_init’: ../sound/soc/bcm/allo-piano-dac-plus.c:711:30: warning: argument to ‘sizeof’ in ‘memset’ call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess] memset(glb_ptr, 0x00, sizeof(glb_ptr)); ^ Suggested-by: Phil Elwell <phil@raspberrypi.org> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> ASoC: allo-piano-dac-plus: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Add support for Allo Boss DAC add-on board for Raspberry Pi. (#1924) Signed-off-by: Baswaraj K <jaikumar@cem-solutions.net> Reviewed-by: Deepak <deepak@zilogic.com> Reviewed-by: BabuSubashChandar <babusubashchandar@zilogic.com> Add support for new clock rate and mute gpios. Signed-off-by: Baswaraj K <jaikumar@cem-solutions.net> Reviewed-by: Deepak <deepak@zilogic.com> Reviewed-by: BabuSubashChandar <babusubashchandar@zilogic.com> ASoC: allo-boss-dac: fix S24_LE format Remove set_bclk_ratio call so 24-bit data is transmitted in 24 bclk cycles. Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: allo-boss-dac: transmit S24_LE with 64 BCLK cycles Signed-off-by: Matthias Reichl <hias@horus.com> allo-boss-dac: switch to snd_soc_dai_set_bclk_ratio Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: allo-boss-dac: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Support for Blokas Labs pisound board Pisound dynamic overlay (#1760) Restructuring pisound-overlay.dts, so it can be loaded and unloaded dynamically using dtoverlay. Print a logline when the kernel module is removed. pisound improvements: * Added a writable sysfs object to enable scripts / user space software to blink MIDI activity LEDs for variable duration. * Improved hw_param constraints setting. * Added compatibility with S16_LE sample format. * Exposed some simple placeholder volume controls, so the card appears in volumealsa widget. Add missing SND_PISOUND selects dependency to SND_RAWMIDI Without it the Pisound module fails to compile. See https://github.com/raspberrypi/linux/issues/2366 Updates for Pisound module code: * Merged 'Fix a warning in DEBUG builds' (1c8b82b). * Updating some strings and copyright information. * Fix for handling high load of MIDI input and output. * Use dual rate oversampling ratio for 96kHz instead of single rate one. Signed-off-by: Giedrius Trainavicius <giedrius@blokas.io> Fixing memset call in pisound.c Signed-off-by: Giedrius Trainavicius <giedrius@blokas.io> Fix for Pisound's MIDI Input getting blocked for a while in rare cases. There was a possible race condition which could lead to Input's FIFO queue to be underflown, causing high amount of processing in the worker thread for some period of time. Signed-off-by: Giedrius Trainavicius <giedrius@blokas.io> Fix for Pisound kernel module in Real Time kernel configuration. When handler of data_available interrupt is fired, queue_work ends up getting called and it can block on a spin lock which is not allowed in interrupt context. The fix was to run the handler from a thread context instead. Pisound: Remove spinlock usage around spi_sync ASoC: pisound: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> ASoC: pisound: fix the parameter for spi_device_match Signed-off-by: Hui Wang <hui.wang@canonical.com> ASoC: Add driver for Cirrus Logic Audio Card Note: due to problems with deferred probing of regulators the following softdep should be added to a modprobe.d file softdep arizona-spi pre: arizona-ldo1 Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: rpi-cirrus: use modern dai_link style Signed-off-by: Matthias Reichl <hias@horus.com> sound: Support for Dion Audio LOCO-V2 DAC-AMP HAT Signed-off-by: Miquel Blauw <info@dionaudio.nl> ASoC: dionaudio_loco-v2: fix S24_LE format Remove set_bclk_ratio call so 24-bit data is transmitted in 24 bclk cycles. Also remove hw_params and ops as they are no longer needed. Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: dionaudio_loco-v2: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Add support for Fe-Pi audio sound card. (#1867) Fe-Pi Audio Sound Card is based on NXP SGTL5000 codec. Mechanical specification of the board is the same the Raspberry Pi Zero. 3.5mm jacks for Headphone/Mic, Line In, and Line Out. Signed-off-by: Henry Kupis <fe-pi@cox.net> ASoC: fe-pi-audio: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Add support for the AudioInjector.net Octo sound card AudioInjector Octo: sample rates, regulators, reset This patch adds new sample rates to the Audioinjector Octo sound card. The new supported rates are (in kHz) : 96, 48, 32, 24, 16, 8, 88.2, 44.1, 29.4, 22.05, 14.7 Reference the bcm270x DT regulators in the overlay. This patch adds a reset GPIO for the AudioInjector.net octo sound card. Audioinjector octo : Make the playback and capture symmetric This patch ensures that the sample rate and channel count of the audioinjector octo sound card are symmetric. audioinjector-octo: Add continuous clock feature By user request, add a switch to prevent the clocks being stopped when the stream is paused, stopped or shutdown. Provide access to the switch by adding a 'non-stop-clocks' parameter to the audioinjector-addons overlay. See: https://github.com/raspberrypi/linux/issues/2409 Signed-off-by: Phil Elwell <phil@raspberrypi.org> sound: Fixes for audioinjector-octo under 4.19 1. Move the DT alias declaration to the I2C shim in the cases where the shim is enabled. This works around a problem caused by a 4.19 commit [1] that generates DT/OF uevents for I2C drivers. 2. Fix the diagnostics in an error path of the soundcard driver to correctly identify the reason for the failure to load. 3. Move the declaration of the clock node in the overlay outside the I2C node to avoid warnings. 4. Sort the overlay nodes so that dependencies are only to earlier fragments, in an attempt to get runtime dtoverlay application to work (it still doesn't...) See: https://github.com/Audio-Injector/Octo/issues/14 Signed-off-by: Phil Elwell <phil@raspberrypi.org> [1]af503716ac("i2c: core: report OF style module alias for devices registered via OF") ASoC: audioinjector-octo-soundcard: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Driver support for Google voiceHAT soundcard. ASoC: googlevoicehat-codec: Use correct device when grabbing GPIO The fixup for the VoiceHAT in 4.18 incorrectly tried to find the sdmode GPIO pin under the card device, not the codec device. This failed, and therefore caused the device probe to fail. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> ASoC: googlevoicehat-codec: Reformat for kernel coding standards Fix all whitespace, indentation, and bracing errors. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> ASoC: googlevoicehat-codec: Make driver function structure const Make voicehat_component_driver a const structure. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> ASoC: googlevoicehat-codec: Only convert from ms to jiffies once Minor optimisation and allows to become checkpatch clean. A msec value is read out of DT or from a define, and convert once to jiffies, rather than every time that it is used. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> Driver and overlay for Allo Katana DAC Allo Katana DAC: Updated default values Signed-off-by: Jaikumar <jaikumar@cem-solutions.com> Added mute stream func Signed-off-by: Jaikumar <jaikumar@cem-solutions.net> codecs: Correct Katana minimum volume Update Katana minimum volume to get the exact 0.5 dB value in each step. Signed-off-by: Sudeep Kumar <sudeepkumar@cem-solutions.net> ASoC: Add generic RPI driver for simple soundcards. The RPI simple sound card driver provides a generic ALSA SOC card driver supporting a variety of Pi HAT soundcards. The intention is to avoid the duplication of code for cards that can't be fully supported by the soc simple/graph cards but are otherwise almost identical. This initial commit adds support for the ADAU1977 ADC, Google VoiceHat, HifiBerry AMP, HifiBerry DAC and RPI DAC. Signed-off-by: Tim Gover <tim.gover@raspberrypi.org> ASoC: Use correct card name in rpi-simple driver Use the specific card name from drvdata instead of the snd_rpi_simple rpi-simple-soundcard: Use nicer driver name "RPi-simple" Rename the driver from "RPI simple soundcard" to "RPi-simple" so that the driver name won't be mangled allowing to be used unaltered as the card conf filename. ASoC: rpi-simple-soundcard: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> ASoC: Add Kconfig and Makefile for sound/soc/bcm Signed-off-by: popcornmix <popcornmix@gmail.com> ASoC: Create a generic Pi Hat WM8804 driver Reduce the amount of duplicated code by creating a generic driver for Pi Hat digi cards using the WM8804 codec. This replaces the Allo DigiOne, Hifiberry Digi/Pro, JustBoom Digi and IQAudIO Digi dedicate soundcard drivers with a generic driver. There are no significant changes to the runtime behavior of the drivers and end users should not have to change any configuration settings after upgrading. Minor changes * Check the return value of snd_soc_component_update_bits * Added some pr_debug tracing * Various checkpatch tidyups * Updated allodigi-one to use use 128FS at > 96 Khz. This appears to be an omission in the original driver code so followed the Hifiberry DAC driver approach. ASoC: rpi-wm8804-soundcard: use modern dai_link style Signed-off-by: Matthias Reichl <hias@horus.com> rpi-wm8804-soundcard: drop PWRDN register writes Since kernel 4.0 the PWRDN register bits are under DAPM control from the wm8804 driver. Drop code that modifies that register to avoid interfering with DAPM. Signed-off-by: Matthias Reichl <hias@horus.com> rpi-wm8804-soundcard: configure wm8804 clocks only on rate change This should avoid clicks when stopping and immediately afterwards starting a stream with the same samplerate as before. Signed-off-by: Matthias Reichl <hias@horus.com> rpi-wm8804-soundcard: Fixed MCLKDIV for Allo Digione The Allo Digione board wants a fixed MCLKDIV of 256. See: https://github.com/raspberrypi/linux/issues/3296 Signed-off-by: Phil Elwell <phil@raspberrypi.org> ASoC: Add support for AudioSense-Pi add-on soundcard AudioSense-Pi is a RPi HAT based on a TI's TLV320AIC32x4 stereo codec This hardware provides multiple audio I/O capabilities to the RPi. The codec connects to the RPi's SoC through the I2S Bus. The following devices can be connected through a 3.5mm jack 1. Line-In: Plain old audio in from mobile phones, PCs, etc., 2. Mic-In: Connect a microphone 3. Line-Out: Connect the output to a speaker 4. Headphones: Connect a Headphone w or w/o microphones Multiple Inputs: It supports the following combinations 1. Two stereo Line-Inputs and a microphone 2. One stereo Line-Input and two microphones 3. Two stereo Line-Inputs, a microphone and one mono line-input (with h/w hack) 4. One stereo Line-Input, two microphones and one mono line-input (with h/w hack) Multiple Outputs: Audio output can be routed to the headphones or speakers (with additional hardware) Signed-off-by: b-ak <anur.bhargav@gmail.com> ASoC: audiosense-pi: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Added driver for the HiFiBerry DAC+ ADC (#2694) Signed-off-by: Daniel Matuschek <daniel@hifiberry.com> hifiberry_dacplusadc: switch to snd_soc_dai_set_bclk_ratio Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: hifiberry_dacplusadc: fix DAI link setup The driver only defines a single DAI link and the code that tries to setup the second (non-existent) DAI link looks wrong - using dmic as a CPU/platform driver doesn't make any sense. The DT overlay doesn't define a dmic property, so the code was never executed (otherwise it would have resulted in a memory corruption). So drop the offending code to prevent issues if a dmic property should be added to the DT overlay. Signed-off-by: Matthias Reichl <hias@horus.com> ASoC: hifiberry_dacplusadc: use modern dai_link style Signed-off-by: Matthias Reichl <hias@horus.com> Audiophonics I-Sabre 9038Q2M DAC driver Signed-off-by: Audiophonics <contact@audiophonics.fr> ASoC: i-sabre-q2m: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> Added IQaudIO Pi-Codec board support (#2969) Add support for the IQaudIO Pi-Codec board. Signed-off-by: Gordon <gordon@iqaudio.com> Fixed 48k timing issue ASoC: iqaudio-codec: use modern dai_link style Signed-off-by: Hui Wang <hui.wang@canonical.com> adds the Hifiberry DAC+ADC PRO version This adds the driver for the DAC+ADC PRO version of the Hifiberry soundcard with software controlled PCM1863 ADC Signed-off-by: Joerg Schambacher joerg@i2audio.com Add Hifiberry DAC+DSP soundcard driver (#3224) Adds the driver for the Hifiberry DAC+DSP. It supports capture and playback depending on the DSP firmware. Signed-off-by: Joerg Schambacher <joerg@i2audio.com> Allow simultaneous use of JustBoom DAC and Digi Signed-off-by: Johannes Krude <johannes@krude.de> Pisound: MIDI communication fixes for scaled down CPU. * Increased maximum SPI communication speed to avoid running too slow when the CPU is scaled down and losing MIDI data. * Keep track of buffer usage in millibytes for higher precision. Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io> sound: Add the HiFiBerry DAC+HD version This adds the driver for the DAC+HD version supporting HiFiBerry's PCM179x based DACs. It also adds PLL control for clock generation. Signed-off-by: Joerg Schambacher <joerg@i2audio.com> Fix master mode settings of HiFiBerry DAC+ADC PRO card (#3424) This patch fixes the board DAI setting when in master-mode. Wrong setting could have caused random pop noise. Signed-off-by: Joerg Schambacher <joerg@i2audio.com> adds LED OFF feature to HiFiBerry DAC+ADC PRO sound card This adds a DT overlay parameter 'leds_off' which allows to switch off the onboard activity LEDs at all times which has been requested by some users. Signed-off-by: Joerg Schambacher <joerg@i2audio.com> adds LED OFF feature to HiFiBerry DAC+ADC sound card This adds a DT overlay parameter 'leds_off' which allows to switch off the onboard activity LEDs at all times which has been requested by some users. Signed-off-by: Joerg Schambacher <joerg@i2audio.com> adds LED OFF feature to HiFiBerry DAC+/DAC+PRO sound cards This adds a DT overlay parameter 'leds_off' which allows to switch off the onboard activity LEDs at all times which has been requested by some users. Signed-off-by: Joerg Schambacher <joerg@i2audio.com> pisound: Added reading Pisound board hardware revision and exposing it (#3425) pisound: Added reading Pisound board hardware revision and exposing it in kernel log and sysfs file: /sys/kernel/pisound/hw_version Signed-off-by: Giedrius <giedrius@blokas.io> Added driver for HiFiBerry Amp amplifier add-on board The driver contains a low-level hardware driver for the TAS5713 and the drivers for the Raspberry Pi I2S subsystem. TAS5713: return error if initialisation fails Existing TAS5713 driver logs errors during initialisation, but does not return an error code. Therefore even if initialisation fails, the driver will still be loaded, but won't work. This patch fixes this. I2C communication error will now reported correctly by a non-zero return code. HiFiBerry Amp: fix device-tree problems Some code to load the driver based on device-tree-overlays was missing. This is added by this patch. According to 5713 pdf doc CLOCK_CTRL is a readonly status register, and it behaves so. Remove useless setting sound: pcm512x-codec: Adding 352.8kHz samplerate support sound/soc: only first codec is master in multicodec setup When using multiple codecs, at most one codec should generate the master clock. All codecs except the first are therefore configured for slave mode. Signed-off-by: Johannes Krude <johannes@krude.de> ASoC: Fix snd_soc_get_pcm_runtime usage Commit [1] changed the snd_soc_get_pcm_runtime to take a dai_link pointer instead of a string. Patch up the downstream drivers to use the modified API. Signed-off-by: Phil Elwell <phil@raspberrypi.com> [1]4468189ff3("ASoC: soc-core: find rtd via dai_link pointer at snd_soc_get_pcm_runtime()") Add support for the AudioInjector.net Isolated sound card This patch adds support for the Audio Injector Isolated sound card. Signed-off-by: Matt Flax <flatmax@flatmax.org> Add support for merus-amp soundcard and ma120x0p codec Add 96KHz rate support to MA120X0P codec and make enable and mute gpio pins optional. Signed-off-by: AMuszkat <ariel.muszkat@gmail.com> Fixes a problem with clock settings of HiFiBerry DAC+ADC PRO (#3545) This patch fixes a problem of the re-calculation of i2s-clock and -parameter settings when only the ADC is activated. Signed-off-by: Joerg Schambacher <joerg@i2audio.com> configs: Enable the AD193x codecs See: https://github.com/raspberrypi/linux/issues/2850 Signed-off-by: Phil Elwell <phil@raspberrypi.org> Switch to snd_soc_dai_set_bclk_ratio Replaces obsolete function snd_soc_dai_set_tdm_slot Signed-off-by: Joerg Schambacher <joerg@i2audio.com> Enhances the DAC+ driver to control the optional headphone amplifier Probes on the I2C bus for TPA6130A2, if successful, it sets DT-parameter 'status' from 'disabled' to 'okay' using change_sets to enable the headphone control. Signed-off-by: Joerg Schambacher joerg@i2audio.com Update Allo Piano Dac Driver Add unique names to the individual dac coded drivers Remove some of the codec controls that are not used. Signed-off-by: Paul Hermann <paul@picoreplayer.org> Fixes an onboard clock detection problem of the PRO versions Increasing the sleep time after clock selection to 3-4ms allows the correct detection of all combinations of DAC+ Pro and DAC+ADC Pro sound cards and the various PI revisions. Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> ASoC:ma120x0p: Increase maximum sample rate to 192KHz Change the maximum sample rate for the amplifier to 192KHz as given in the Infineon specification. Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> ASoC: ma120x0p: Remove unnecessary const specifier Clang warns: sound/soc/codecs/ma120x0p.c:891:14: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier] static const SOC_VALUE_ENUM_SINGLE_DECL(pwr_mode_ctrl, ^ ./include/sound/soc.h:362:2: note: expanded from macro 'SOC_VALUE_ENUM_SINGLE_DECL' SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues) ^ ./include/sound/soc.h:359:2: note: expanded from macro 'SOC_VALUE_ENUM_DOUBLE_DECL' const struct soc_enum name = SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, \ ^ 1 warning generated. SOC_VALUE_ENUM_DOUBLE_DECL already has a const specifier. Remove the duplicate const to clean up the warning. Fixes:42444979e7("Add support for all the downstream rpi sound card drivers") Signed-off-by: Nathan Chancellor <nathan@kernel.org> ASoC: bcm: allo-piano-dac-plus: Remove unnecessary const specifiers Clang warns: sound/soc/bcm/allo-piano-dac-plus.c:66:14: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier] static const SOC_ENUM_SINGLE_DECL(allo_piano_mode_enum, ^ ./include/sound/soc.h:355:2: note: expanded from macro 'SOC_ENUM_SINGLE_DECL' SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts) ^ ./include/sound/soc.h:352:2: note: expanded from macro 'SOC_ENUM_DOUBLE_DECL' const struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \ ^ sound/soc/bcm/allo-piano-dac-plus.c:75:14: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier] static const SOC_ENUM_SINGLE_DECL(allo_piano_dual_mode_enum, ^ ./include/sound/soc.h:355:2: note: expanded from macro 'SOC_ENUM_SINGLE_DECL' SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts) ^ ./include/sound/soc.h:352:2: note: expanded from macro 'SOC_ENUM_DOUBLE_DECL' const struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \ ^ sound/soc/bcm/allo-piano-dac-plus.c:96:14: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier] static const SOC_ENUM_SINGLE_DECL(allo_piano_enum, ^ ./include/sound/soc.h:355:2: note: expanded from macro 'SOC_ENUM_SINGLE_DECL' SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts) ^ ./include/sound/soc.h:352:2: note: expanded from macro 'SOC_ENUM_DOUBLE_DECL' const struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \ ^ 3 warnings generated. SOC_VALUE_ENUM_DOUBLE_DECL already has a const specifier. Remove the duplicate const specifiers to clean up the warnings. Fixes:42444979e7("Add support for all the downstream rpi sound card drivers") Signed-off-by: Nathan Chancellor <nathan@kernel.org> rpi-simple-soundcard: Add Dion Audio KIWI streamer Signed-off-by: Miquel Blauw <miquelblauw@hotmail.com> rpi-simple-soundcard: adds definitions for the HiFiBerry AMP3 card Uses Infineon MA120x0 amplifier and supports full sample rate of 192ksps. Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> sound: soc: bcm: Added Sound card driver for Dacberry400 Audio card for Raspberry Pi 400 Added Sound card driver for DACberry400 Audio card. Signed-off-by: Ashish Vara <ashishhvara@gmail.com> ASoC:ma120x0p: Corrects the volume level display Fixes the wrongly changed 'limiter volume' display back to -50dB minimum and sets the correct minimum volume level to -144dB to be aligned with the controls and display in alsamixer etc. Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> ASoC: bcm: Fix Rpi-PROTO and audioinjector.net Pi As of kernel 5.19 the WM8731 driver has separate I2C and SPI support modules. Change the Kconfig definitions for the audioinjector.net Pi and Rpi-PROTO soundcards to select SND_SOC_WM8731_I2C. See: https://github.com/raspberrypi/linux/issues/5364 Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: adau1977: Add correct compatible strings Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: bcm2835-i2s: Use phys addresses for DAI DMA Contrary to what struct snd_dmaengine_dai_dma_data suggests, the configuration of addresses of DMA slave interfaces should be done in CPU physical addresses. Signed-off-by: Phil Elwell <phil@raspberrypi.com> rpi sound cards: Fix Codec Zero rate switching The Raspberry Pi Codec Zero (and IQaudIO Codec) don't notify the DA7213 codec when it needs to change PLL frequencies. As a result, audio can be played at the wrong rate - play a 48kHz sound immediately after a 44.1kHz sound to see the effect, but in some configurations the codec can lock into the wrong state and always get some rates wrong. Add the necessary notification to fix the issue. Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: dwc: Support set_bclk_ratio Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: dwc: Add DMACR handling Add control of the DMACR register, which is required for paced DMA (i.e. DREQ) support. Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASOC: dwc: Improve DMA shutdown Disabling the I2S interface with outstanding transfers prevents the DMAC from shutting down, so keep it partially active after a stop. Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASOC: dwc: Fix 16-bit audio handling IMO the Synopsys datasheet could be clearer in this area, but it seems that the DMA data ports (DMATX and DMARX) expect left and right samples in alternate writes; if a stereo pair is pushed in a single 32-bit write, the upper half is ignored, leading to double speed audio with a confused stereo image. Make sure the necessary changes happen by updating the DMA configuration data in the hw_params method. The set_bclk_ratio change was made at a time when it looked like it could be causing an error, but I think the division of responsibilities is clearer this way (and the kernel log clearer without the info-level message). Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: bcm: Remove dependency on BCM2835 I2S These soundcard drivers don't rely on a specific I2S interface, so remove the dependency declarations. See: https://github.com/raspberrypi/linux-2712/issues/111 Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: bcm: audioinjector_octo: Add soundcard "owner" See: https://github.com/raspberrypi/linux/issues/5697 Signed-off-by: Phil Elwell <phil@raspberrypi.com> Pisound: Don't export the button GPIO via sysfs GPIO class. Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io> Pisound: Read out the SPI speed to use from the Device Tree. Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io> ASoC: DACplus - fix 16bit sample support in clock consumer mode The former code did not adjust the physical sample width when in clock consumer mode and has taken the fixed 32 bit default. This has caused the audio to be played at half its frequency due to the fixed bclk_ratio of 64. Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> ASoC: adds support for AMP4 Pro to the DAC Plus driver The AMP4 Pro is a I2S master mode capable amplifier with clean onboard clock generators. We can share the card driver between TAS575x amplifiers and the PCM512x DACs as they are SW compatible. From a HW perspective though we need to limit the sample rates to the standard audio rates to avoid running the onboard clocks through the PLL. Using the PLL would require even a different HW. DAI/stream name are also set accordingly to allow the user a convenient identification of the soundcard Needs the pcm512x driver with TAS575x support (already in upstream kernel). Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> ASoC: DACplusADCPro - fix 16bit sample support in clock consumer mode The former code did not adjust the physical sample width when in clock consumer mode and has taken the fixed 32 bit default. This has caused the audio to be played at half its frequency due to the fixed bclk_ratio of 64. Problem appears only on PI5 as on the former PIs the I2S module did simply run at fixed 64x rate. Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> Impliment driver support for Interlude Audio Digital Hat Implementing driver support for Interlude audio's WM8805 based digital hat by leveraging existing drivers ASOc: Add HiFiBerry DAC8X to the simple card driver Defines the settings for the 8 channel version of the standard DAC by overwriting the number of channels in the DAI defs. It can run in 8ch mode only on PI5 using the 4 lane data output of the designware I2S0 module. Signed-off-by: j-schambacher <joerg@hifiberry.com> ASoC: bcm: Use the correct sample width value ALSA's concept of the physical width of a sample is how much memory it occupies, including any padding. This not the same as the count of bits of actual sample content. In particular, S24_LE has a width of 24 bits but a physical width of 32 bits because there is a byte of padding with each sample. When calculating bclk_ratio, etc., it is width that matters, not physical width. Correct the error that has been replicated across the drivers for many Raspberry Pi-compatible soundcards. Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: dwc: Correct channel count reporting The DWC I2S driver treats the channel count register values as if they encode a power of two (2, 4, 8, 16), but they actually encode a multiple of 2 (2, 4, 6, 8). Also improve the error message when asked for an unsupported number of channels. Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: Fix 16bit sample support for Hifiberry DACplusADC Same issue as #5919. 'width' needs to be set independent of clocking mode. Signed-off-by: j-schambacher <joerg@hifiberry.com> allo-boss-dac mute output when changing parameters Since I noticed that sometimes changing sample rates causes some digital quirks and noises, I've changed the function to mute the output before performing the changes and then unmute it when an error occurs or the parameters got set. Signed-off-by: Alessandro Marcon <marconalessandro04@gmail.com> ASoC: bcm: Use power-of-2 bclk_ratios The soundcard drivers originally used snd_pcm_format_physical_width, but a later commit changed that to snd_pcm_format_width because the in-memory sample storage width should not be a factor in determining the bclk_ratio. However, the physical width rounds the sample bits up to the nearest power of 2, which makes it easier to find integer clock divisors. Restore the old behaviour, but with an implementation that makes it clear what is going on. See: https://github.com/raspberrypi/linux/issues/6104 Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: bcm: Add "owner" info for more soundcards See: https://github.com/raspberrypi/linux/issues/5697 Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: da7213: Add a set_bclk_ratio method Following [1], it becomes harder for the CPU DAI to know the correct BCLK ratio. We can either bake the same knowledge into the sound card driver, or implement and use set_bclk_ratio on the codec. This commit does the latter. [1] commitc89e652e84("ASoC: da7213: Add support for mono, set frame width to 32 when possible") Signed-off-by: Phil Elwell <phil@raspberrypi.com> iqaudio-codec: Use the codec's new set_bclk_ratio To ensure that the CPU DAI and codec agree over the BCLK ratio, impose a fixed value of 64 on both of them. Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: add driver for new HiFiBerry ADC only board(s) Adds the driver for the soon to be released first ADC only board. It includes the same ADC controls as used by the DAC+ADC Pro driver. Signed-off-by: j-schambacher <joerg@hifiberry.com> ASoC: add HiFiBerry ADC8x 8-channel ADC to simple-card-driver Definitions for the 8 channel ADC card. The card uses only HW-controlled devices which allows the uses of the 'dummy-dai'. It will run only on a PI5 as it requires the designware I2S0 module. The necessary output lanes I2S0_DI[0..3] are claimed from within the DT overlay. Signed-off-by: j-schambacher <joerg@hifiberry.com> sound/soc: dwc-i2s: choose FIFO thresholds based on DMA burst constraints Valid ranges for the I2S peripheral's FIFO configuration include a depth of 16 - unconditionally setting the burst length to 16 with a fifo threshold of size/2 will cause under/overflows. For DMA engines with restricted capabilities the requested burst length and FIFO thresholds need to be adjusted downward accordingly. Both the RX and TX FIFOs operate on "less-than" thresholds. Setting the TX threshold to fifo_size minus burst means the FIFO is kept nearly-full. Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com> ASoC: allo-piano-dac-plus: Fix volume limit locking Calling snd_soc_limit_volume from within a kcontrol put handler seems to cause a deadlock as it attempts to claim a write lock that is already held. Call snd_soc_limit_volume from the main initialisation code instead, to avoid the recursive locking. See: https://github.com/raspberrypi/linux/issues/6527 Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: allo-piano-dac-plus: Suppress -517 errors Use dev_err_probe to simplify the code and suppress EPROBE_DEFER errors. Signed-off-by: Phil Elwell <phil@raspberrypi.com> soc: pcm3168a: Add DT binding to force clock consumer mode ASoC cannot configure the codec correctly when the ADC and DAC share clock lines and one of them is the clock producer. Add a DT binding that overrides ASoC and forces the component into clock consumer mode. Signed-off-by: Stephen Gordon <gordoste@iinet.net.au> ASoC: pcm512x: Demote "No SCLK" to debug level Designing a PCM512X-based soundcard with no external SCLK is a valid choice supported by the driver. Don't alarm users with messages that say "No SCLK, using BCLK: -2" - reclassify them as debug information. Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: allo-piano-dac-plus: Fix volume limiting Controls which only exist when snd_soc_register_card returns can't be modified before then. Move the setting of volume limits to just before the end of the probe function. Link: https://github.com/raspberrypi/linux/issues/6527 Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: allo-piano-dac-plus: Remove pointless code The codec control Digital Playback Volume is one of the controls deleted by the allo-piano-dac-plus driver. It is effectively replaced by the soundcard controls Master Playback Volume and Subwoofer Playback Volume. Delete the code that sets the volume limit on those codec controls - the limits on the soundcard volume controls are sufficient. Signed-off-by: Phil Elwell <phil@raspberrypi.com> ASoC: adds ADC8x support to the Hifiberry DAC8x The driver probes for the ADC8x which can be stacked on top of the DAC8x. It enables a symmetric 8 channel capture using the dummy-dai. Signed-off-by: j-schambacher <joerg@hifiberry.com> sound: soc: raspberrypi: RP1 Audio Out driver as an ASOC DAI Only 48000Hz stereo 16-bit output is currently supported. It requires some additional OF plumbing to connect it to a "dummy" codec and generic sound card. Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com> Adding Pimidi kernel module. Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io> Adding Pisound Micro kernel module Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io> Pisound Micro: Fix for MIDI output under full load. This fixes MIDI output of Pisound Micro after running for a while under full load and increases timing stability. Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io> ALSA: korg1212: replace del_timer with timer_delete pisound-micro: Added pin_pull and pin_b_pull sysfs attributes for Pisound Micro. These attributes are available only for GPIO input and Encoder elements. Signed-off-by: Giedrius <giedrius@blokas.io> Pisound Micro: Workaround for snd_soc_dai_set_tdm_slot with slots=0 Even though it's documented that specifying slots=0 can be used to disable the TDM mode, error checking introduced in 6.12.31 version broke this, therefore, for the time being, a workaround is to provide a xlate_tdm_slot_mask operation implementation to return 0 instead of -EINVAL as it does in case slots argument is 0. Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io>
1381 lines
47 KiB
C
1381 lines
47 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* ASoC Driver for Infineon Merus(TM) ma120x0p multi-level class-D amplifier
|
|
*
|
|
* Authors: Ariel Muszkat <ariel.muszkat@gmail.com>
|
|
* Jorgen Kragh Jakobsen <jorgen.kraghjakobsen@infineon.com>
|
|
*
|
|
* Copyright (C) 2019 Infineon Technologies AG
|
|
*
|
|
*/
|
|
#include <linux/module.h>
|
|
#include <linux/moduleparam.h>
|
|
#include <linux/init.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/of_device.h>
|
|
#include <linux/spi/spi.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/gpio/consumer.h>
|
|
#include <linux/gpio.h>
|
|
#include <sound/core.h>
|
|
#include <sound/pcm.h>
|
|
#include <sound/pcm_params.h>
|
|
#include <sound/soc.h>
|
|
#include <sound/soc-dapm.h>
|
|
#include <sound/initval.h>
|
|
#include <sound/tlv.h>
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/string.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
#ifndef _MA120X0P_
|
|
#define _MA120X0P_
|
|
//------------------------------------------------------------------manualPM---
|
|
// Select Manual PowerMode control
|
|
#define ma_manualpm__a 0
|
|
#define ma_manualpm__len 1
|
|
#define ma_manualpm__mask 0x40
|
|
#define ma_manualpm__shift 0x06
|
|
#define ma_manualpm__reset 0x00
|
|
//--------------------------------------------------------------------pm_man---
|
|
// manual selected power mode
|
|
#define ma_pm_man__a 0
|
|
#define ma_pm_man__len 2
|
|
#define ma_pm_man__mask 0x30
|
|
#define ma_pm_man__shift 0x04
|
|
#define ma_pm_man__reset 0x03
|
|
//------------------------------------------ ----------------------mthr_1to2---
|
|
// mod. index threshold value for pm1=>pm2 change.
|
|
#define ma_mthr_1to2__a 1
|
|
#define ma_mthr_1to2__len 8
|
|
#define ma_mthr_1to2__mask 0xff
|
|
#define ma_mthr_1to2__shift 0x00
|
|
#define ma_mthr_1to2__reset 0x3c
|
|
//-----------------------------------------------------------------mthr_2to1---
|
|
// mod. index threshold value for pm2=>pm1 change.
|
|
#define ma_mthr_2to1__a 2
|
|
#define ma_mthr_2to1__len 8
|
|
#define ma_mthr_2to1__mask 0xff
|
|
#define ma_mthr_2to1__shift 0x00
|
|
#define ma_mthr_2to1__reset 0x32
|
|
//-----------------------------------------------------------------mthr_2to3---
|
|
// mod. index threshold value for pm2=>pm3 change.
|
|
#define ma_mthr_2to3__a 3
|
|
#define ma_mthr_2to3__len 8
|
|
#define ma_mthr_2to3__mask 0xff
|
|
#define ma_mthr_2to3__shift 0x00
|
|
#define ma_mthr_2to3__reset 0x5a
|
|
//-----------------------------------------------------------------mthr_3to2---
|
|
// mod. index threshold value for pm3=>pm2 change.
|
|
#define ma_mthr_3to2__a 4
|
|
#define ma_mthr_3to2__len 8
|
|
#define ma_mthr_3to2__mask 0xff
|
|
#define ma_mthr_3to2__shift 0x00
|
|
#define ma_mthr_3to2__reset 0x50
|
|
//-------------------------------------------------------------pwmclkdiv_nom---
|
|
// pwm default clock divider value
|
|
#define ma_pwmclkdiv_nom__a 8
|
|
#define ma_pwmclkdiv_nom__len 8
|
|
#define ma_pwmclkdiv_nom__mask 0xff
|
|
#define ma_pwmclkdiv_nom__shift 0x00
|
|
#define ma_pwmclkdiv_nom__reset 0x26
|
|
//--------- ----------------------------------------------------ocp_latch_en---
|
|
// high to use permanently latching level-2 ocp
|
|
#define ma_ocp_latch_en__a 10
|
|
#define ma_ocp_latch_en__len 1
|
|
#define ma_ocp_latch_en__mask 0x02
|
|
#define ma_ocp_latch_en__shift 0x01
|
|
#define ma_ocp_latch_en__reset 0x00
|
|
//---------------------------------------------------------------lf_clamp_en---
|
|
// high (default) to enable lf int2+3 clamping on clip
|
|
#define ma_lf_clamp_en__a 10
|
|
#define ma_lf_clamp_en__len 1
|
|
#define ma_lf_clamp_en__mask 0x80
|
|
#define ma_lf_clamp_en__shift 0x07
|
|
#define ma_lf_clamp_en__reset 0x00
|
|
//-------------------------------------------------------pmcfg_btl_b.modtype---
|
|
//
|
|
#define ma_pmcfg_btl_b__modtype__a 18
|
|
#define ma_pmcfg_btl_b__modtype__len 2
|
|
#define ma_pmcfg_btl_b__modtype__mask 0x18
|
|
#define ma_pmcfg_btl_b__modtype__shift 0x03
|
|
#define ma_pmcfg_btl_b__modtype__reset 0x02
|
|
//-------------------------------------------------------pmcfg_btl_b.freqdiv---
|
|
#define ma_pmcfg_btl_b__freqdiv__a 18
|
|
#define ma_pmcfg_btl_b__freqdiv__len 2
|
|
#define ma_pmcfg_btl_b__freqdiv__mask 0x06
|
|
#define ma_pmcfg_btl_b__freqdiv__shift 0x01
|
|
#define ma_pmcfg_btl_b__freqdiv__reset 0x01
|
|
//----------------------------------------------------pmcfg_btl_b.lf_gain_ol---
|
|
//
|
|
#define ma_pmcfg_btl_b__lf_gain_ol__a 18
|
|
#define ma_pmcfg_btl_b__lf_gain_ol__len 1
|
|
#define ma_pmcfg_btl_b__lf_gain_ol__mask 0x01
|
|
#define ma_pmcfg_btl_b__lf_gain_ol__shift 0x00
|
|
#define ma_pmcfg_btl_b__lf_gain_ol__reset 0x01
|
|
//-------------------------------------------------------pmcfg_btl_c.freqdiv---
|
|
//
|
|
#define ma_pmcfg_btl_c__freqdiv__a 19
|
|
#define ma_pmcfg_btl_c__freqdiv__len 2
|
|
#define ma_pmcfg_btl_c__freqdiv__mask 0x06
|
|
#define ma_pmcfg_btl_c__freqdiv__shift 0x01
|
|
#define ma_pmcfg_btl_c__freqdiv__reset 0x01
|
|
//-------------------------------------------------------pmcfg_btl_c.modtype---
|
|
//
|
|
#define ma_pmcfg_btl_c__modtype__a 19
|
|
#define ma_pmcfg_btl_c__modtype__len 2
|
|
#define ma_pmcfg_btl_c__modtype__mask 0x18
|
|
#define ma_pmcfg_btl_c__modtype__shift 0x03
|
|
#define ma_pmcfg_btl_c__modtype__reset 0x01
|
|
//----------------------------------------------------pmcfg_btl_c.lf_gain_ol---
|
|
//
|
|
#define ma_pmcfg_btl_c__lf_gain_ol__a 19
|
|
#define ma_pmcfg_btl_c__lf_gain_ol__len 1
|
|
#define ma_pmcfg_btl_c__lf_gain_ol__mask 0x01
|
|
#define ma_pmcfg_btl_c__lf_gain_ol__shift 0x00
|
|
#define ma_pmcfg_btl_c__lf_gain_ol__reset 0x00
|
|
//-------------------------------------------------------pmcfg_btl_d.modtype---
|
|
//
|
|
#define ma_pmcfg_btl_d__modtype__a 20
|
|
#define ma_pmcfg_btl_d__modtype__len 2
|
|
#define ma_pmcfg_btl_d__modtype__mask 0x18
|
|
#define ma_pmcfg_btl_d__modtype__shift 0x03
|
|
#define ma_pmcfg_btl_d__modtype__reset 0x02
|
|
//-------------------------------------------------------pmcfg_btl_d.freqdiv---
|
|
//
|
|
#define ma_pmcfg_btl_d__freqdiv__a 20
|
|
#define ma_pmcfg_btl_d__freqdiv__len 2
|
|
#define ma_pmcfg_btl_d__freqdiv__mask 0x06
|
|
#define ma_pmcfg_btl_d__freqdiv__shift 0x01
|
|
#define ma_pmcfg_btl_d__freqdiv__reset 0x02
|
|
//----------------------------------------------------pmcfg_btl_d.lf_gain_ol---
|
|
//
|
|
#define ma_pmcfg_btl_d__lf_gain_ol__a 20
|
|
#define ma_pmcfg_btl_d__lf_gain_ol__len 1
|
|
#define ma_pmcfg_btl_d__lf_gain_ol__mask 0x01
|
|
#define ma_pmcfg_btl_d__lf_gain_ol__shift 0x00
|
|
#define ma_pmcfg_btl_d__lf_gain_ol__reset 0x00
|
|
//------------ -------------------------------------------pmcfg_se_a.modtype---
|
|
//
|
|
#define ma_pmcfg_se_a__modtype__a 21
|
|
#define ma_pmcfg_se_a__modtype__len 2
|
|
#define ma_pmcfg_se_a__modtype__mask 0x18
|
|
#define ma_pmcfg_se_a__modtype__shift 0x03
|
|
#define ma_pmcfg_se_a__modtype__reset 0x01
|
|
//--------------------------------------------------------pmcfg_se_a.freqdiv---
|
|
//
|
|
#define ma_pmcfg_se_a__freqdiv__a 21
|
|
#define ma_pmcfg_se_a__freqdiv__len 2
|
|
#define ma_pmcfg_se_a__freqdiv__mask 0x06
|
|
#define ma_pmcfg_se_a__freqdiv__shift 0x01
|
|
#define ma_pmcfg_se_a__freqdiv__reset 0x00
|
|
//-----------------------------------------------------pmcfg_se_a.lf_gain_ol---
|
|
//
|
|
#define ma_pmcfg_se_a__lf_gain_ol__a 21
|
|
#define ma_pmcfg_se_a__lf_gain_ol__len 1
|
|
#define ma_pmcfg_se_a__lf_gain_ol__mask 0x01
|
|
#define ma_pmcfg_se_a__lf_gain_ol__shift 0x00
|
|
#define ma_pmcfg_se_a__lf_gain_ol__reset 0x01
|
|
//-----------------------------------------------------pmcfg_se_b.lf_gain_ol---
|
|
//
|
|
#define ma_pmcfg_se_b__lf_gain_ol__a 22
|
|
#define ma_pmcfg_se_b__lf_gain_ol__len 1
|
|
#define ma_pmcfg_se_b__lf_gain_ol__mask 0x01
|
|
#define ma_pmcfg_se_b__lf_gain_ol__shift 0x00
|
|
#define ma_pmcfg_se_b__lf_gain_ol__reset 0x00
|
|
//--------------------------------------------------------pmcfg_se_b.freqdiv---
|
|
//
|
|
#define ma_pmcfg_se_b__freqdiv__a 22
|
|
#define ma_pmcfg_se_b__freqdiv__len 2
|
|
#define ma_pmcfg_se_b__freqdiv__mask 0x06
|
|
#define ma_pmcfg_se_b__freqdiv__shift 0x01
|
|
#define ma_pmcfg_se_b__freqdiv__reset 0x01
|
|
//--------------------------------------------------------pmcfg_se_b.modtype---
|
|
//
|
|
#define ma_pmcfg_se_b__modtype__a 22
|
|
#define ma_pmcfg_se_b__modtype__len 2
|
|
#define ma_pmcfg_se_b__modtype__mask 0x18
|
|
#define ma_pmcfg_se_b__modtype__shift 0x03
|
|
#define ma_pmcfg_se_b__modtype__reset 0x01
|
|
//----------------------------------------------------------balwaitcount_pm1---
|
|
// pm1 balancing period.
|
|
#define ma_balwaitcount_pm1__a 23
|
|
#define ma_balwaitcount_pm1__len 8
|
|
#define ma_balwaitcount_pm1__mask 0xff
|
|
#define ma_balwaitcount_pm1__shift 0x00
|
|
#define ma_balwaitcount_pm1__reset 0x14
|
|
//----------------------------------------------------------balwaitcount_pm2---
|
|
// pm2 balancing period.
|
|
#define ma_balwaitcount_pm2__a 24
|
|
#define ma_balwaitcount_pm2__len 8
|
|
#define ma_balwaitcount_pm2__mask 0xff
|
|
#define ma_balwaitcount_pm2__shift 0x00
|
|
#define ma_balwaitcount_pm2__reset 0x14
|
|
//----------------------------------------------------------balwaitcount_pm3---
|
|
// pm3 balancing period.
|
|
#define ma_balwaitcount_pm3__a 25
|
|
#define ma_balwaitcount_pm3__len 8
|
|
#define ma_balwaitcount_pm3__mask 0xff
|
|
#define ma_balwaitcount_pm3__shift 0x00
|
|
#define ma_balwaitcount_pm3__reset 0x1a
|
|
//-------------------------------------------------------------usespread_pm1---
|
|
// pm1 pwm spread-spectrum mode on/off.
|
|
#define ma_usespread_pm1__a 26
|
|
#define ma_usespread_pm1__len 1
|
|
#define ma_usespread_pm1__mask 0x40
|
|
#define ma_usespread_pm1__shift 0x06
|
|
#define ma_usespread_pm1__reset 0x00
|
|
//---------------------------------------------------------------dtsteps_pm1---
|
|
// pm1 dead time setting [10ns steps].
|
|
#define ma_dtsteps_pm1__a 26
|
|
#define ma_dtsteps_pm1__len 3
|
|
#define ma_dtsteps_pm1__mask 0x38
|
|
#define ma_dtsteps_pm1__shift 0x03
|
|
#define ma_dtsteps_pm1__reset 0x04
|
|
//---------------------------------------------------------------baltype_pm1---
|
|
// pm1 balancing sensor scheme.
|
|
#define ma_baltype_pm1__a 26
|
|
#define ma_baltype_pm1__len 3
|
|
#define ma_baltype_pm1__mask 0x07
|
|
#define ma_baltype_pm1__shift 0x00
|
|
#define ma_baltype_pm1__reset 0x00
|
|
//-------------------------------------------------------------usespread_pm2---
|
|
// pm2 pwm spread-spectrum mode on/off.
|
|
#define ma_usespread_pm2__a 27
|
|
#define ma_usespread_pm2__len 1
|
|
#define ma_usespread_pm2__mask 0x40
|
|
#define ma_usespread_pm2__shift 0x06
|
|
#define ma_usespread_pm2__reset 0x00
|
|
//---------------------------------------------------------------dtsteps_pm2---
|
|
// pm2 dead time setting [10ns steps].
|
|
#define ma_dtsteps_pm2__a 27
|
|
#define ma_dtsteps_pm2__len 3
|
|
#define ma_dtsteps_pm2__mask 0x38
|
|
#define ma_dtsteps_pm2__shift 0x03
|
|
#define ma_dtsteps_pm2__reset 0x03
|
|
//---------------------------------------------------------------baltype_pm2---
|
|
// pm2 balancing sensor scheme.
|
|
#define ma_baltype_pm2__a 27
|
|
#define ma_baltype_pm2__len 3
|
|
#define ma_baltype_pm2__mask 0x07
|
|
#define ma_baltype_pm2__shift 0x00
|
|
#define ma_baltype_pm2__reset 0x01
|
|
//-------------------------------------------------------------usespread_pm3---
|
|
// pm3 pwm spread-spectrum mode on/off.
|
|
#define ma_usespread_pm3__a 28
|
|
#define ma_usespread_pm3__len 1
|
|
#define ma_usespread_pm3__mask 0x40
|
|
#define ma_usespread_pm3__shift 0x06
|
|
#define ma_usespread_pm3__reset 0x00
|
|
//---------------------------------------------------------------dtsteps_pm3---
|
|
// pm3 dead time setting [10ns steps].
|
|
#define ma_dtsteps_pm3__a 28
|
|
#define ma_dtsteps_pm3__len 3
|
|
#define ma_dtsteps_pm3__mask 0x38
|
|
#define ma_dtsteps_pm3__shift 0x03
|
|
#define ma_dtsteps_pm3__reset 0x01
|
|
//---------------------------------------------------------------baltype_pm3---
|
|
// pm3 balancing sensor scheme.
|
|
#define ma_baltype_pm3__a 28
|
|
#define ma_baltype_pm3__len 3
|
|
#define ma_baltype_pm3__mask 0x07
|
|
#define ma_baltype_pm3__shift 0x00
|
|
#define ma_baltype_pm3__reset 0x03
|
|
//-----------------------------------------------------------------pmprofile---
|
|
// pm profile select. valid presets: 0-1-2-3-4. 5=> custom profile.
|
|
#define ma_pmprofile__a 29
|
|
#define ma_pmprofile__len 3
|
|
#define ma_pmprofile__mask 0x07
|
|
#define ma_pmprofile__shift 0x00
|
|
#define ma_pmprofile__reset 0x00
|
|
//-------------------------------------------------------------------pm3_man---
|
|
// custom profile pm3 contents. 0=>a, 1=>b, 2=>c, 3=>d
|
|
#define ma_pm3_man__a 30
|
|
#define ma_pm3_man__len 2
|
|
#define ma_pm3_man__mask 0x30
|
|
#define ma_pm3_man__shift 0x04
|
|
#define ma_pm3_man__reset 0x02
|
|
//-------------------------------------------------------------------pm2_man---
|
|
// custom profile pm2 contents. 0=>a, 1=>b, 2=>c, 3=>d
|
|
#define ma_pm2_man__a 30
|
|
#define ma_pm2_man__len 2
|
|
#define ma_pm2_man__mask 0x0c
|
|
#define ma_pm2_man__shift 0x02
|
|
#define ma_pm2_man__reset 0x03
|
|
//-------------------------------------------------------------------pm1_man---
|
|
// custom profile pm1 contents. 0=>a, 1=>b, 2=>c, 3=>d
|
|
#define ma_pm1_man__a 30
|
|
#define ma_pm1_man__len 2
|
|
#define ma_pm1_man__mask 0x03
|
|
#define ma_pm1_man__shift 0x00
|
|
#define ma_pm1_man__reset 0x03
|
|
//-----------------------------------------------------------ocp_latch_clear---
|
|
// low-high clears current ocp latched condition.
|
|
#define ma_ocp_latch_clear__a 32
|
|
#define ma_ocp_latch_clear__len 1
|
|
#define ma_ocp_latch_clear__mask 0x80
|
|
#define ma_ocp_latch_clear__shift 0x07
|
|
#define ma_ocp_latch_clear__reset 0x00
|
|
//-------------------------------------------------------------audio_in_mode---
|
|
// audio input mode; 0-1-2-3-4-5
|
|
#define ma_audio_in_mode__a 37
|
|
#define ma_audio_in_mode__len 3
|
|
#define ma_audio_in_mode__mask 0xe0
|
|
#define ma_audio_in_mode__shift 0x05
|
|
#define ma_audio_in_mode__reset 0x00
|
|
//-----------------------------------------------------------------eh_dcshdn---
|
|
// high to enable dc protection
|
|
#define ma_eh_dcshdn__a 38
|
|
#define ma_eh_dcshdn__len 1
|
|
#define ma_eh_dcshdn__mask 0x04
|
|
#define ma_eh_dcshdn__shift 0x02
|
|
#define ma_eh_dcshdn__reset 0x01
|
|
//---------------------------------------------------------audio_in_mode_ext---
|
|
// if set, audio_in_mode is controlled from audio_in_mode register. if not set
|
|
//audio_in_mode is set from fuse bank setting
|
|
#define ma_audio_in_mode_ext__a 39
|
|
#define ma_audio_in_mode_ext__len 1
|
|
#define ma_audio_in_mode_ext__mask 0x20
|
|
#define ma_audio_in_mode_ext__shift 0x05
|
|
#define ma_audio_in_mode_ext__reset 0x00
|
|
//------------------------------------------------------------------eh_clear---
|
|
// flip to clear error registers
|
|
#define ma_eh_clear__a 45
|
|
#define ma_eh_clear__len 1
|
|
#define ma_eh_clear__mask 0x04
|
|
#define ma_eh_clear__shift 0x02
|
|
#define ma_eh_clear__reset 0x00
|
|
//----------------------------------------------------------thermal_compr_en---
|
|
// enable otw-contr. input compression?
|
|
#define ma_thermal_compr_en__a 45
|
|
#define ma_thermal_compr_en__len 1
|
|
#define ma_thermal_compr_en__mask 0x20
|
|
#define ma_thermal_compr_en__shift 0x05
|
|
#define ma_thermal_compr_en__reset 0x01
|
|
//---------------------------------------------------------------system_mute---
|
|
// 1 = mute system, 0 = normal operation
|
|
#define ma_system_mute__a 45
|
|
#define ma_system_mute__len 1
|
|
#define ma_system_mute__mask 0x40
|
|
#define ma_system_mute__shift 0x06
|
|
#define ma_system_mute__reset 0x00
|
|
//------------------------------------------------------thermal_compr_max_db---
|
|
// audio limiter max thermal reduction
|
|
#define ma_thermal_compr_max_db__a 46
|
|
#define ma_thermal_compr_max_db__len 3
|
|
#define ma_thermal_compr_max_db__mask 0x07
|
|
#define ma_thermal_compr_max_db__shift 0x00
|
|
#define ma_thermal_compr_max_db__reset 0x04
|
|
//---------------------------------------------------------audio_proc_enable---
|
|
// enable audio proc, bypass if not enabled
|
|
#define ma_audio_proc_enable__a 53
|
|
#define ma_audio_proc_enable__len 1
|
|
#define ma_audio_proc_enable__mask 0x08
|
|
#define ma_audio_proc_enable__shift 0x03
|
|
#define ma_audio_proc_enable__reset 0x00
|
|
//--------------------------------------------------------audio_proc_release---
|
|
// 00:slow, 01:normal, 10:fast
|
|
#define ma_audio_proc_release__a 53
|
|
#define ma_audio_proc_release__len 2
|
|
#define ma_audio_proc_release__mask 0x30
|
|
#define ma_audio_proc_release__shift 0x04
|
|
#define ma_audio_proc_release__reset 0x00
|
|
//---------------------------------------------------------audio_proc_attack---
|
|
// 00:slow, 01:normal, 10:fast
|
|
#define ma_audio_proc_attack__a 53
|
|
#define ma_audio_proc_attack__len 2
|
|
#define ma_audio_proc_attack__mask 0xc0
|
|
#define ma_audio_proc_attack__shift 0x06
|
|
#define ma_audio_proc_attack__reset 0x00
|
|
//----------------------------------------------------------------i2s_format---
|
|
// i2s basic data format, 000 = std. i2s, 001 = left justified (default)
|
|
#define ma_i2s_format__a 53
|
|
#define ma_i2s_format__len 3
|
|
#define ma_i2s_format__mask 0x07
|
|
#define ma_i2s_format__shift 0x00
|
|
#define ma_i2s_format__reset 0x01
|
|
//--------------------------------------------------audio_proc_limiterenable---
|
|
// 1: enable limiter, 0: disable limiter
|
|
#define ma_audio_proc_limiterenable__a 54
|
|
#define ma_audio_proc_limiterenable__len 1
|
|
#define ma_audio_proc_limiterenable__mask 0x40
|
|
#define ma_audio_proc_limiterenable__shift 0x06
|
|
#define ma_audio_proc_limiterenable__reset 0x00
|
|
//-----------------------------------------------------------audio_proc_mute---
|
|
// 1: mute, 0: unmute
|
|
#define ma_audio_proc_mute__a 54
|
|
#define ma_audio_proc_mute__len 1
|
|
#define ma_audio_proc_mute__mask 0x80
|
|
#define ma_audio_proc_mute__shift 0x07
|
|
#define ma_audio_proc_mute__reset 0x00
|
|
//---------------------------------------------------------------i2s_sck_pol---
|
|
// i2s sck polarity cfg. 0 = rising edge data change
|
|
#define ma_i2s_sck_pol__a 54
|
|
#define ma_i2s_sck_pol__len 1
|
|
#define ma_i2s_sck_pol__mask 0x01
|
|
#define ma_i2s_sck_pol__shift 0x00
|
|
#define ma_i2s_sck_pol__reset 0x01
|
|
//-------------------------------------------------------------i2s_framesize---
|
|
// i2s word length. 00 = 32bit, 01 = 24bit
|
|
#define ma_i2s_framesize__a 54
|
|
#define ma_i2s_framesize__len 2
|
|
#define ma_i2s_framesize__mask 0x18
|
|
#define ma_i2s_framesize__shift 0x03
|
|
#define ma_i2s_framesize__reset 0x00
|
|
//----------------------------------------------------------------i2s_ws_pol---
|
|
// i2s ws polarity. 0 = low first
|
|
#define ma_i2s_ws_pol__a 54
|
|
#define ma_i2s_ws_pol__len 1
|
|
#define ma_i2s_ws_pol__mask 0x02
|
|
#define ma_i2s_ws_pol__shift 0x01
|
|
#define ma_i2s_ws_pol__reset 0x00
|
|
//-----------------------------------------------------------------i2s_order---
|
|
// i2s word bit order. 0 = msb first
|
|
#define ma_i2s_order__a 54
|
|
#define ma_i2s_order__len 1
|
|
#define ma_i2s_order__mask 0x04
|
|
#define ma_i2s_order__shift 0x02
|
|
#define ma_i2s_order__reset 0x00
|
|
//------------------------------------------------------------i2s_rightfirst---
|
|
// i2s l/r word order; 0 = left first
|
|
#define ma_i2s_rightfirst__a 54
|
|
#define ma_i2s_rightfirst__len 1
|
|
#define ma_i2s_rightfirst__mask 0x20
|
|
#define ma_i2s_rightfirst__shift 0x05
|
|
#define ma_i2s_rightfirst__reset 0x00
|
|
//-------------------------------------------------------------vol_db_master---
|
|
// master volume db
|
|
#define ma_vol_db_master__a 64
|
|
#define ma_vol_db_master__len 8
|
|
#define ma_vol_db_master__mask 0xff
|
|
#define ma_vol_db_master__shift 0x00
|
|
#define ma_vol_db_master__reset 0x18
|
|
//------------------------------------------------------------vol_lsb_master---
|
|
// master volume lsb 1/4 steps
|
|
#define ma_vol_lsb_master__a 65
|
|
#define ma_vol_lsb_master__len 2
|
|
#define ma_vol_lsb_master__mask 0x03
|
|
#define ma_vol_lsb_master__shift 0x00
|
|
#define ma_vol_lsb_master__reset 0x00
|
|
//----------------------------------------------------------------vol_db_ch0---
|
|
// volume channel 0
|
|
#define ma_vol_db_ch0__a 66
|
|
#define ma_vol_db_ch0__len 8
|
|
#define ma_vol_db_ch0__mask 0xff
|
|
#define ma_vol_db_ch0__shift 0x00
|
|
#define ma_vol_db_ch0__reset 0x18
|
|
//----------------------------------------------------------------vol_db_ch1---
|
|
// volume channel 1
|
|
#define ma_vol_db_ch1__a 67
|
|
#define ma_vol_db_ch1__len 8
|
|
#define ma_vol_db_ch1__mask 0xff
|
|
#define ma_vol_db_ch1__shift 0x00
|
|
#define ma_vol_db_ch1__reset 0x18
|
|
//----------------------------------------------------------------vol_db_ch2---
|
|
// volume channel 2
|
|
#define ma_vol_db_ch2__a 68
|
|
#define ma_vol_db_ch2__len 8
|
|
#define ma_vol_db_ch2__mask 0xff
|
|
#define ma_vol_db_ch2__shift 0x00
|
|
#define ma_vol_db_ch2__reset 0x18
|
|
//----------------------------------------------------------------vol_db_ch3---
|
|
// volume channel 3
|
|
#define ma_vol_db_ch3__a 69
|
|
#define ma_vol_db_ch3__len 8
|
|
#define ma_vol_db_ch3__mask 0xff
|
|
#define ma_vol_db_ch3__shift 0x00
|
|
#define ma_vol_db_ch3__reset 0x18
|
|
//---------------------------------------------------------------vol_lsb_ch0---
|
|
// volume channel 1 - 1/4 steps
|
|
#define ma_vol_lsb_ch0__a 70
|
|
#define ma_vol_lsb_ch0__len 2
|
|
#define ma_vol_lsb_ch0__mask 0x03
|
|
#define ma_vol_lsb_ch0__shift 0x00
|
|
#define ma_vol_lsb_ch0__reset 0x00
|
|
//---------------------------------------------------------------vol_lsb_ch1---
|
|
// volume channel 3 - 1/4 steps
|
|
#define ma_vol_lsb_ch1__a 70
|
|
#define ma_vol_lsb_ch1__len 2
|
|
#define ma_vol_lsb_ch1__mask 0x0c
|
|
#define ma_vol_lsb_ch1__shift 0x02
|
|
#define ma_vol_lsb_ch1__reset 0x00
|
|
//---------------------------------------------------------------vol_lsb_ch2---
|
|
// volume channel 2 - 1/4 steps
|
|
#define ma_vol_lsb_ch2__a 70
|
|
#define ma_vol_lsb_ch2__len 2
|
|
#define ma_vol_lsb_ch2__mask 0x30
|
|
#define ma_vol_lsb_ch2__shift 0x04
|
|
#define ma_vol_lsb_ch2__reset 0x00
|
|
//---------------------------------------------------------------vol_lsb_ch3---
|
|
// volume channel 3 - 1/4 steps
|
|
#define ma_vol_lsb_ch3__a 70
|
|
#define ma_vol_lsb_ch3__len 2
|
|
#define ma_vol_lsb_ch3__mask 0xc0
|
|
#define ma_vol_lsb_ch3__shift 0x06
|
|
#define ma_vol_lsb_ch3__reset 0x00
|
|
//----------------------------------------------------------------thr_db_ch0---
|
|
// thr_db channel 0
|
|
#define ma_thr_db_ch0__a 71
|
|
#define ma_thr_db_ch0__len 8
|
|
#define ma_thr_db_ch0__mask 0xff
|
|
#define ma_thr_db_ch0__shift 0x00
|
|
#define ma_thr_db_ch0__reset 0x18
|
|
//----------------------------------------------------------------thr_db_ch1---
|
|
// thr db ch1
|
|
#define ma_thr_db_ch1__a 72
|
|
#define ma_thr_db_ch1__len 8
|
|
#define ma_thr_db_ch1__mask 0xff
|
|
#define ma_thr_db_ch1__shift 0x00
|
|
#define ma_thr_db_ch1__reset 0x18
|
|
//----------------------------------------------------------------thr_db_ch2---
|
|
// thr db ch2
|
|
#define ma_thr_db_ch2__a 73
|
|
#define ma_thr_db_ch2__len 8
|
|
#define ma_thr_db_ch2__mask 0xff
|
|
#define ma_thr_db_ch2__shift 0x00
|
|
#define ma_thr_db_ch2__reset 0x18
|
|
//----------------------------------------------------------------thr_db_ch3---
|
|
// threshold db ch3
|
|
#define ma_thr_db_ch3__a 74
|
|
#define ma_thr_db_ch3__len 8
|
|
#define ma_thr_db_ch3__mask 0xff
|
|
#define ma_thr_db_ch3__shift 0x00
|
|
#define ma_thr_db_ch3__reset 0x18
|
|
//---------------------------------------------------------------thr_lsb_ch0---
|
|
// thr lsb ch0
|
|
#define ma_thr_lsb_ch0__a 75
|
|
#define ma_thr_lsb_ch0__len 2
|
|
#define ma_thr_lsb_ch0__mask 0x03
|
|
#define ma_thr_lsb_ch0__shift 0x00
|
|
#define ma_thr_lsb_ch0__reset 0x00
|
|
//---------------------------------------------------------------thr_lsb_ch1---
|
|
// thr lsb ch1
|
|
#define ma_thr_lsb_ch1__a 75
|
|
#define ma_thr_lsb_ch1__len 2
|
|
#define ma_thr_lsb_ch1__mask 0x0c
|
|
#define ma_thr_lsb_ch1__shift 0x02
|
|
#define ma_thr_lsb_ch1__reset 0x00
|
|
//---------------------------------------------------------------thr_lsb_ch2---
|
|
// thr lsb ch2 1/4 db step
|
|
#define ma_thr_lsb_ch2__a 75
|
|
#define ma_thr_lsb_ch2__len 2
|
|
#define ma_thr_lsb_ch2__mask 0x30
|
|
#define ma_thr_lsb_ch2__shift 0x04
|
|
#define ma_thr_lsb_ch2__reset 0x00
|
|
//---------------------------------------------------------------thr_lsb_ch3---
|
|
// threshold lsb ch3
|
|
#define ma_thr_lsb_ch3__a 75
|
|
#define ma_thr_lsb_ch3__len 2
|
|
#define ma_thr_lsb_ch3__mask 0xc0
|
|
#define ma_thr_lsb_ch3__shift 0x06
|
|
#define ma_thr_lsb_ch3__reset 0x00
|
|
//-----------------------------------------------------------dcu_mon0.pm_mon---
|
|
// power mode monitor channel 0
|
|
#define ma_dcu_mon0__pm_mon__a 96
|
|
#define ma_dcu_mon0__pm_mon__len 2
|
|
#define ma_dcu_mon0__pm_mon__mask 0x03
|
|
#define ma_dcu_mon0__pm_mon__shift 0x00
|
|
#define ma_dcu_mon0__pm_mon__reset 0x00
|
|
//-----------------------------------------------------dcu_mon0.freqmode_mon---
|
|
// frequence mode monitor channel 0
|
|
#define ma_dcu_mon0__freqmode_mon__a 96
|
|
#define ma_dcu_mon0__freqmode_mon__len 3
|
|
#define ma_dcu_mon0__freqmode_mon__mask 0x70
|
|
#define ma_dcu_mon0__freqmode_mon__shift 0x04
|
|
#define ma_dcu_mon0__freqmode_mon__reset 0x00
|
|
//-------------------------------------------------------dcu_mon0.pps_passed---
|
|
// dcu0 pps completion indicator
|
|
#define ma_dcu_mon0__pps_passed__a 96
|
|
#define ma_dcu_mon0__pps_passed__len 1
|
|
#define ma_dcu_mon0__pps_passed__mask 0x80
|
|
#define ma_dcu_mon0__pps_passed__shift 0x07
|
|
#define ma_dcu_mon0__pps_passed__reset 0x00
|
|
//----------------------------------------------------------dcu_mon0.ocp_mon---
|
|
// ocp monitor channel 0
|
|
#define ma_dcu_mon0__ocp_mon__a 97
|
|
#define ma_dcu_mon0__ocp_mon__len 1
|
|
#define ma_dcu_mon0__ocp_mon__mask 0x01
|
|
#define ma_dcu_mon0__ocp_mon__shift 0x00
|
|
#define ma_dcu_mon0__ocp_mon__reset 0x00
|
|
//--------------------------------------------------------dcu_mon0.vcfly1_ok---
|
|
// cfly1 protection monitor channel 0.
|
|
#define ma_dcu_mon0__vcfly1_ok__a 97
|
|
#define ma_dcu_mon0__vcfly1_ok__len 1
|
|
#define ma_dcu_mon0__vcfly1_ok__mask 0x02
|
|
#define ma_dcu_mon0__vcfly1_ok__shift 0x01
|
|
#define ma_dcu_mon0__vcfly1_ok__reset 0x00
|
|
//--------------------------------------------------------dcu_mon0.vcfly2_ok---
|
|
// cfly2 protection monitor channel 0.
|
|
#define ma_dcu_mon0__vcfly2_ok__a 97
|
|
#define ma_dcu_mon0__vcfly2_ok__len 1
|
|
#define ma_dcu_mon0__vcfly2_ok__mask 0x04
|
|
#define ma_dcu_mon0__vcfly2_ok__shift 0x02
|
|
#define ma_dcu_mon0__vcfly2_ok__reset 0x00
|
|
//----------------------------------------------------------dcu_mon0.pvdd_ok---
|
|
// dcu0 pvdd monitor
|
|
#define ma_dcu_mon0__pvdd_ok__a 97
|
|
#define ma_dcu_mon0__pvdd_ok__len 1
|
|
#define ma_dcu_mon0__pvdd_ok__mask 0x08
|
|
#define ma_dcu_mon0__pvdd_ok__shift 0x03
|
|
#define ma_dcu_mon0__pvdd_ok__reset 0x00
|
|
//-----------------------------------------------------------dcu_mon0.vdd_ok---
|
|
// dcu0 vdd monitor
|
|
#define ma_dcu_mon0__vdd_ok__a 97
|
|
#define ma_dcu_mon0__vdd_ok__len 1
|
|
#define ma_dcu_mon0__vdd_ok__mask 0x10
|
|
#define ma_dcu_mon0__vdd_ok__shift 0x04
|
|
#define ma_dcu_mon0__vdd_ok__reset 0x00
|
|
//-------------------------------------------------------------dcu_mon0.mute---
|
|
// dcu0 mute monitor
|
|
#define ma_dcu_mon0__mute__a 97
|
|
#define ma_dcu_mon0__mute__len 1
|
|
#define ma_dcu_mon0__mute__mask 0x20
|
|
#define ma_dcu_mon0__mute__shift 0x05
|
|
#define ma_dcu_mon0__mute__reset 0x00
|
|
//------------------------------------------------------------dcu_mon0.m_mon---
|
|
// m sense monitor channel 0
|
|
#define ma_dcu_mon0__m_mon__a 98
|
|
#define ma_dcu_mon0__m_mon__len 8
|
|
#define ma_dcu_mon0__m_mon__mask 0xff
|
|
#define ma_dcu_mon0__m_mon__shift 0x00
|
|
#define ma_dcu_mon0__m_mon__reset 0x00
|
|
//-----------------------------------------------------------dcu_mon1.pm_mon---
|
|
// power mode monitor channel 1
|
|
#define ma_dcu_mon1__pm_mon__a 100
|
|
#define ma_dcu_mon1__pm_mon__len 2
|
|
#define ma_dcu_mon1__pm_mon__mask 0x03
|
|
#define ma_dcu_mon1__pm_mon__shift 0x00
|
|
#define ma_dcu_mon1__pm_mon__reset 0x00
|
|
//-----------------------------------------------------dcu_mon1.freqmode_mon---
|
|
// frequence mode monitor channel 1
|
|
#define ma_dcu_mon1__freqmode_mon__a 100
|
|
#define ma_dcu_mon1__freqmode_mon__len 3
|
|
#define ma_dcu_mon1__freqmode_mon__mask 0x70
|
|
#define ma_dcu_mon1__freqmode_mon__shift 0x04
|
|
#define ma_dcu_mon1__freqmode_mon__reset 0x00
|
|
//-------------------------------------------------------dcu_mon1.pps_passed---
|
|
// dcu1 pps completion indicator
|
|
#define ma_dcu_mon1__pps_passed__a 100
|
|
#define ma_dcu_mon1__pps_passed__len 1
|
|
#define ma_dcu_mon1__pps_passed__mask 0x80
|
|
#define ma_dcu_mon1__pps_passed__shift 0x07
|
|
#define ma_dcu_mon1__pps_passed__reset 0x00
|
|
//----------------------------------------------------------dcu_mon1.ocp_mon---
|
|
// ocp monitor channel 1
|
|
#define ma_dcu_mon1__ocp_mon__a 101
|
|
#define ma_dcu_mon1__ocp_mon__len 1
|
|
#define ma_dcu_mon1__ocp_mon__mask 0x01
|
|
#define ma_dcu_mon1__ocp_mon__shift 0x00
|
|
#define ma_dcu_mon1__ocp_mon__reset 0x00
|
|
//--------------------------------------------------------dcu_mon1.vcfly1_ok---
|
|
// cfly1 protcetion monitor channel 1
|
|
#define ma_dcu_mon1__vcfly1_ok__a 101
|
|
#define ma_dcu_mon1__vcfly1_ok__len 1
|
|
#define ma_dcu_mon1__vcfly1_ok__mask 0x02
|
|
#define ma_dcu_mon1__vcfly1_ok__shift 0x01
|
|
#define ma_dcu_mon1__vcfly1_ok__reset 0x00
|
|
//--------------------------------------------------------dcu_mon1.vcfly2_ok---
|
|
// cfly2 protection monitor channel 1
|
|
#define ma_dcu_mon1__vcfly2_ok__a 101
|
|
#define ma_dcu_mon1__vcfly2_ok__len 1
|
|
#define ma_dcu_mon1__vcfly2_ok__mask 0x04
|
|
#define ma_dcu_mon1__vcfly2_ok__shift 0x02
|
|
#define ma_dcu_mon1__vcfly2_ok__reset 0x00
|
|
//----------------------------------------------------------dcu_mon1.pvdd_ok---
|
|
// dcu1 pvdd monitor
|
|
#define ma_dcu_mon1__pvdd_ok__a 101
|
|
#define ma_dcu_mon1__pvdd_ok__len 1
|
|
#define ma_dcu_mon1__pvdd_ok__mask 0x08
|
|
#define ma_dcu_mon1__pvdd_ok__shift 0x03
|
|
#define ma_dcu_mon1__pvdd_ok__reset 0x00
|
|
//-----------------------------------------------------------dcu_mon1.vdd_ok---
|
|
// dcu1 vdd monitor
|
|
#define ma_dcu_mon1__vdd_ok__a 101
|
|
#define ma_dcu_mon1__vdd_ok__len 1
|
|
#define ma_dcu_mon1__vdd_ok__mask 0x10
|
|
#define ma_dcu_mon1__vdd_ok__shift 0x04
|
|
#define ma_dcu_mon1__vdd_ok__reset 0x00
|
|
//-------------------------------------------------------------dcu_mon1.mute---
|
|
// dcu1 mute monitor
|
|
#define ma_dcu_mon1__mute__a 101
|
|
#define ma_dcu_mon1__mute__len 1
|
|
#define ma_dcu_mon1__mute__mask 0x20
|
|
#define ma_dcu_mon1__mute__shift 0x05
|
|
#define ma_dcu_mon1__mute__reset 0x00
|
|
//------------------------------------------------------------dcu_mon1.m_mon---
|
|
// m sense monitor channel 1
|
|
#define ma_dcu_mon1__m_mon__a 102
|
|
#define ma_dcu_mon1__m_mon__len 8
|
|
#define ma_dcu_mon1__m_mon__mask 0xff
|
|
#define ma_dcu_mon1__m_mon__shift 0x00
|
|
#define ma_dcu_mon1__m_mon__reset 0x00
|
|
//--------------------------------------------------------dcu_mon0.sw_enable---
|
|
// dcu0 switch enable monitor
|
|
#define ma_dcu_mon0__sw_enable__a 104
|
|
#define ma_dcu_mon0__sw_enable__len 1
|
|
#define ma_dcu_mon0__sw_enable__mask 0x40
|
|
#define ma_dcu_mon0__sw_enable__shift 0x06
|
|
#define ma_dcu_mon0__sw_enable__reset 0x00
|
|
//--------------------------------------------------------dcu_mon1.sw_enable---
|
|
// dcu1 switch enable monitor
|
|
#define ma_dcu_mon1__sw_enable__a 104
|
|
#define ma_dcu_mon1__sw_enable__len 1
|
|
#define ma_dcu_mon1__sw_enable__mask 0x80
|
|
#define ma_dcu_mon1__sw_enable__shift 0x07
|
|
#define ma_dcu_mon1__sw_enable__reset 0x00
|
|
//------------------------------------------------------------hvboot0_ok_mon---
|
|
// hvboot0_ok for test/debug
|
|
#define ma_hvboot0_ok_mon__a 105
|
|
#define ma_hvboot0_ok_mon__len 1
|
|
#define ma_hvboot0_ok_mon__mask 0x40
|
|
#define ma_hvboot0_ok_mon__shift 0x06
|
|
#define ma_hvboot0_ok_mon__reset 0x00
|
|
//------------------------------------------------------------hvboot1_ok_mon---
|
|
// hvboot1_ok for test/debug
|
|
#define ma_hvboot1_ok_mon__a 105
|
|
#define ma_hvboot1_ok_mon__len 1
|
|
#define ma_hvboot1_ok_mon__mask 0x80
|
|
#define ma_hvboot1_ok_mon__shift 0x07
|
|
#define ma_hvboot1_ok_mon__reset 0x00
|
|
//-----------------------------------------------------------------error_acc---
|
|
// accumulated errors, at and after triggering
|
|
#define ma_error_acc__a 109
|
|
#define ma_error_acc__len 8
|
|
#define ma_error_acc__mask 0xff
|
|
#define ma_error_acc__shift 0x00
|
|
#define ma_error_acc__reset 0x00
|
|
//-------------------------------------------------------------i2s_data_rate---
|
|
// detected i2s data rate: 00/01/10 = x1/x2/x4
|
|
#define ma_i2s_data_rate__a 116
|
|
#define ma_i2s_data_rate__len 2
|
|
#define ma_i2s_data_rate__mask 0x03
|
|
#define ma_i2s_data_rate__shift 0x00
|
|
#define ma_i2s_data_rate__reset 0x00
|
|
//---------------------------------------------------------audio_in_mode_mon---
|
|
// audio input mode monitor
|
|
#define ma_audio_in_mode_mon__a 116
|
|
#define ma_audio_in_mode_mon__len 3
|
|
#define ma_audio_in_mode_mon__mask 0x1c
|
|
#define ma_audio_in_mode_mon__shift 0x02
|
|
#define ma_audio_in_mode_mon__reset 0x00
|
|
//------------------------------------------------------------------msel_mon---
|
|
// msel[2:0] monitor register
|
|
#define ma_msel_mon__a 117
|
|
#define ma_msel_mon__len 3
|
|
#define ma_msel_mon__mask 0x07
|
|
#define ma_msel_mon__shift 0x00
|
|
#define ma_msel_mon__reset 0x00
|
|
//---------------------------------------------------------------------error---
|
|
// current error flag monitor reg - for app. ctrl.
|
|
#define ma_error__a 124
|
|
#define ma_error__len 8
|
|
#define ma_error__mask 0xff
|
|
#define ma_error__shift 0x00
|
|
#define ma_error__reset 0x00
|
|
//----------------------------------------------------audio_proc_limiter_mon---
|
|
// b7-b4: channel 3-0 limiter active
|
|
#define ma_audio_proc_limiter_mon__a 126
|
|
#define ma_audio_proc_limiter_mon__len 4
|
|
#define ma_audio_proc_limiter_mon__mask 0xf0
|
|
#define ma_audio_proc_limiter_mon__shift 0x04
|
|
#define ma_audio_proc_limiter_mon__reset 0x00
|
|
//-------------------------------------------------------audio_proc_clip_mon---
|
|
// b3-b0: channel 3-0 clipping monitor
|
|
#define ma_audio_proc_clip_mon__a 126
|
|
#define ma_audio_proc_clip_mon__len 4
|
|
#define ma_audio_proc_clip_mon__mask 0x0f
|
|
#define ma_audio_proc_clip_mon__shift 0x00
|
|
#define ma_audio_proc_clip_mon__reset 0x00
|
|
#endif
|
|
|
|
#define SOC_ENUM_ERR(xname, xenum)\
|
|
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
|
.access = SNDRV_CTL_ELEM_ACCESS_READ,\
|
|
.info = snd_soc_info_enum_double,\
|
|
.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double,\
|
|
.private_value = (unsigned long)&(xenum) }
|
|
|
|
static struct i2c_client *i2c;
|
|
|
|
struct ma120x0p_priv {
|
|
struct regmap *regmap;
|
|
int mclk_div;
|
|
struct snd_soc_component *component;
|
|
struct gpio_desc *enable_gpio;
|
|
struct gpio_desc *mute_gpio;
|
|
struct gpio_desc *booster_gpio;
|
|
struct gpio_desc *error_gpio;
|
|
};
|
|
|
|
static struct ma120x0p_priv *priv_data;
|
|
|
|
//Used to share the IRQ number within this file
|
|
static unsigned int irqNumber;
|
|
|
|
// Function prototype for the custom IRQ handler function
|
|
static irqreturn_t ma120x0p_irq_handler(int irq, void *data);
|
|
|
|
//Alsa Controls
|
|
static const char * const limenable_text[] = {"Bypassed", "Enabled"};
|
|
static const char * const limatack_text[] = {"Slow", "Normal", "Fast"};
|
|
static const char * const limrelease_text[] = {"Slow", "Normal", "Fast"};
|
|
|
|
static const char * const err_flycap_text[] = {"Ok", "Error"};
|
|
static const char * const err_overcurr_text[] = {"Ok", "Error"};
|
|
static const char * const err_pllerr_text[] = {"Ok", "Error"};
|
|
static const char * const err_pvddunder_text[] = {"Ok", "Error"};
|
|
static const char * const err_overtempw_text[] = {"Ok", "Error"};
|
|
static const char * const err_overtempe_text[] = {"Ok", "Error"};
|
|
static const char * const err_pinlowimp_text[] = {"Ok", "Error"};
|
|
static const char * const err_dcprot_text[] = {"Ok", "Error"};
|
|
|
|
static const char * const pwr_mode_prof_text[] = {"PMF0", "PMF1", "PMF2",
|
|
"PMF3", "PMF4"};
|
|
|
|
static const struct soc_enum lim_enable_ctrl =
|
|
SOC_ENUM_SINGLE(ma_audio_proc_limiterenable__a,
|
|
ma_audio_proc_limiterenable__shift,
|
|
ma_audio_proc_limiterenable__len + 1,
|
|
limenable_text);
|
|
static const struct soc_enum limatack_ctrl =
|
|
SOC_ENUM_SINGLE(ma_audio_proc_attack__a,
|
|
ma_audio_proc_attack__shift,
|
|
ma_audio_proc_attack__len + 1,
|
|
limatack_text);
|
|
static const struct soc_enum limrelease_ctrl =
|
|
SOC_ENUM_SINGLE(ma_audio_proc_release__a,
|
|
ma_audio_proc_release__shift,
|
|
ma_audio_proc_release__len + 1,
|
|
limrelease_text);
|
|
static const struct soc_enum err_flycap_ctrl =
|
|
SOC_ENUM_SINGLE(ma_error__a, 0, 3, err_flycap_text);
|
|
static const struct soc_enum err_overcurr_ctrl =
|
|
SOC_ENUM_SINGLE(ma_error__a, 1, 3, err_overcurr_text);
|
|
static const struct soc_enum err_pllerr_ctrl =
|
|
SOC_ENUM_SINGLE(ma_error__a, 2, 3, err_pllerr_text);
|
|
static const struct soc_enum err_pvddunder_ctrl =
|
|
SOC_ENUM_SINGLE(ma_error__a, 3, 3, err_pvddunder_text);
|
|
static const struct soc_enum err_overtempw_ctrl =
|
|
SOC_ENUM_SINGLE(ma_error__a, 4, 3, err_overtempw_text);
|
|
static const struct soc_enum err_overtempe_ctrl =
|
|
SOC_ENUM_SINGLE(ma_error__a, 5, 3, err_overtempe_text);
|
|
static const struct soc_enum err_pinlowimp_ctrl =
|
|
SOC_ENUM_SINGLE(ma_error__a, 6, 3, err_pinlowimp_text);
|
|
static const struct soc_enum err_dcprot_ctrl =
|
|
SOC_ENUM_SINGLE(ma_error__a, 7, 3, err_dcprot_text);
|
|
static const struct soc_enum pwr_mode_prof_ctrl =
|
|
SOC_ENUM_SINGLE(ma_pmprofile__a, ma_pmprofile__shift, 5,
|
|
pwr_mode_prof_text);
|
|
|
|
static const char * const pwr_mode_texts[] = {
|
|
"Dynamic power mode",
|
|
"Power mode 1",
|
|
"Power mode 2",
|
|
"Power mode 3",
|
|
};
|
|
|
|
static const int pwr_mode_values[] = {
|
|
0x10,
|
|
0x50,
|
|
0x60,
|
|
0x70,
|
|
};
|
|
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(pwr_mode_ctrl,
|
|
ma_pm_man__a, 0, 0x70,
|
|
pwr_mode_texts,
|
|
pwr_mode_values);
|
|
|
|
static const DECLARE_TLV_DB_SCALE(ma120x0p_vol_tlv, -14400, 100, 0);
|
|
static const DECLARE_TLV_DB_SCALE(ma120x0p_lim_tlv, -5000, 100, 0);
|
|
static const DECLARE_TLV_DB_SCALE(ma120x0p_lr_tlv, -5000, 100, 0);
|
|
|
|
static const struct snd_kcontrol_new ma120x0p_snd_controls[] = {
|
|
//Master Volume
|
|
SOC_SINGLE_RANGE_TLV("A.Mstr Vol Volume",
|
|
ma_vol_db_master__a, 0, 0x18, 0xa8, 1, ma120x0p_vol_tlv),
|
|
|
|
//L-R Volume ch0
|
|
SOC_SINGLE_RANGE_TLV("B.L Vol Volume",
|
|
ma_vol_db_ch0__a, 0, 0x18, 0x4a, 1, ma120x0p_lr_tlv),
|
|
SOC_SINGLE_RANGE_TLV("C.R Vol Volume",
|
|
ma_vol_db_ch1__a, 0, 0x18, 0x4a, 1, ma120x0p_lr_tlv),
|
|
|
|
//L-R Limiter Threshold ch0-ch1
|
|
SOC_DOUBLE_R_RANGE_TLV("D.Lim thresh Volume",
|
|
ma_thr_db_ch0__a, ma_thr_db_ch1__a, 0, 0x0e, 0x4a, 1,
|
|
ma120x0p_lim_tlv),
|
|
|
|
//Enum Switches/Selectors
|
|
//SOC_ENUM("E.AudioProc Mute", audioproc_mute_ctrl),
|
|
SOC_ENUM("F.Limiter Enable", lim_enable_ctrl),
|
|
SOC_ENUM("G.Limiter Attck", limatack_ctrl),
|
|
SOC_ENUM("H.Limiter Rls", limrelease_ctrl),
|
|
|
|
//Enum Error Monitor (read-only)
|
|
SOC_ENUM_ERR("I.Err flycap", err_flycap_ctrl),
|
|
SOC_ENUM_ERR("J.Err overcurr", err_overcurr_ctrl),
|
|
SOC_ENUM_ERR("K.Err pllerr", err_pllerr_ctrl),
|
|
SOC_ENUM_ERR("L.Err pvddunder", err_pvddunder_ctrl),
|
|
SOC_ENUM_ERR("M.Err overtempw", err_overtempw_ctrl),
|
|
SOC_ENUM_ERR("N.Err overtempe", err_overtempe_ctrl),
|
|
SOC_ENUM_ERR("O.Err pinlowimp", err_pinlowimp_ctrl),
|
|
SOC_ENUM_ERR("P.Err dcprot", err_dcprot_ctrl),
|
|
|
|
//Power modes profiles
|
|
SOC_ENUM("Q.PM Prof", pwr_mode_prof_ctrl),
|
|
|
|
// Power mode selection (Dynamic,1,2,3)
|
|
SOC_ENUM("R.Power Mode", pwr_mode_ctrl),
|
|
};
|
|
|
|
//Machine Driver
|
|
static int ma120x0p_hw_params(struct snd_pcm_substream *substream,
|
|
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
|
|
{
|
|
u16 blen = 0x00;
|
|
|
|
struct snd_soc_component *component = dai->component;
|
|
|
|
priv_data->component = component;
|
|
|
|
switch (params_format(params)) {
|
|
case SNDRV_PCM_FORMAT_S16_LE:
|
|
blen = 0x10;
|
|
break;
|
|
case SNDRV_PCM_FORMAT_S24_LE:
|
|
blen = 0x00;
|
|
break;
|
|
case SNDRV_PCM_FORMAT_S32_LE:
|
|
blen = 0x00;
|
|
break;
|
|
default:
|
|
dev_err(dai->dev, "Unsupported word length: %u\n",
|
|
params_format(params));
|
|
return -EINVAL;
|
|
}
|
|
|
|
// set word length
|
|
snd_soc_component_update_bits(component, ma_i2s_framesize__a,
|
|
ma_i2s_framesize__mask, blen);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ma120x0p_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
|
|
{
|
|
int val = 0;
|
|
|
|
struct ma120x0p_priv *ma120x0p;
|
|
|
|
struct snd_soc_component *component = dai->component;
|
|
|
|
ma120x0p = snd_soc_component_get_drvdata(component);
|
|
|
|
if (mute)
|
|
val = 0;
|
|
else
|
|
val = 1;
|
|
|
|
gpiod_set_value_cansleep(priv_data->mute_gpio, val);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct snd_soc_dai_ops ma120x0p_dai_ops = {
|
|
.hw_params = ma120x0p_hw_params,
|
|
.mute_stream = ma120x0p_mute_stream,
|
|
};
|
|
|
|
static struct snd_soc_dai_driver ma120x0p_dai = {
|
|
.name = "ma120x0p-amp",
|
|
.playback = {
|
|
.stream_name = "Playback",
|
|
.channels_min = 2,
|
|
.channels_max = 2,
|
|
.rates = SNDRV_PCM_RATE_CONTINUOUS,
|
|
.rate_min = 44100,
|
|
.rate_max = 192000,
|
|
.formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE
|
|
},
|
|
.ops = &ma120x0p_dai_ops,
|
|
};
|
|
|
|
//Codec Driver
|
|
static int ma120x0p_clear_err(struct snd_soc_component *component)
|
|
{
|
|
int ret = 0;
|
|
|
|
struct ma120x0p_priv *ma120x0p;
|
|
|
|
ma120x0p = snd_soc_component_get_drvdata(component);
|
|
|
|
ret = snd_soc_component_update_bits(component,
|
|
ma_eh_clear__a, ma_eh_clear__mask, 0x00);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = snd_soc_component_update_bits(component,
|
|
ma_eh_clear__a, ma_eh_clear__mask, 0x04);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = snd_soc_component_update_bits(component,
|
|
ma_eh_clear__a, ma_eh_clear__mask, 0x00);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void ma120x0p_remove(struct snd_soc_component *component)
|
|
{
|
|
struct ma120x0p_priv *ma120x0p;
|
|
|
|
ma120x0p = snd_soc_component_get_drvdata(component);
|
|
}
|
|
|
|
static int ma120x0p_probe(struct snd_soc_component *component)
|
|
{
|
|
struct ma120x0p_priv *ma120x0p;
|
|
|
|
int ret = 0;
|
|
|
|
i2c = container_of(component->dev, struct i2c_client, dev);
|
|
|
|
ma120x0p = snd_soc_component_get_drvdata(component);
|
|
|
|
//Reset error
|
|
ma120x0p_clear_err(component);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
// set serial audio format I2S and enable audio processor
|
|
ret = snd_soc_component_write(component, ma_i2s_format__a, 0x08);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
// Enable audio limiter
|
|
ret = snd_soc_component_update_bits(component,
|
|
ma_audio_proc_limiterenable__a,
|
|
ma_audio_proc_limiterenable__mask, 0x40);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
// Set lim attack to fast
|
|
ret = snd_soc_component_update_bits(component,
|
|
ma_audio_proc_attack__a, ma_audio_proc_attack__mask, 0x80);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
// Set lim attack to low
|
|
ret = snd_soc_component_update_bits(component,
|
|
ma_audio_proc_release__a, ma_audio_proc_release__mask, 0x00);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
// set volume to 0dB
|
|
ret = snd_soc_component_write(component, ma_vol_db_master__a, 0x18);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
// set ch0 lim thresh to -15dB
|
|
ret = snd_soc_component_write(component, ma_thr_db_ch0__a, 0x27);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
// set ch1 lim thresh to -15dB
|
|
ret = snd_soc_component_write(component, ma_thr_db_ch1__a, 0x27);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
//Check for errors
|
|
ret = snd_soc_component_test_bits(component, ma_error_acc__a, 0x00, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
ret = snd_soc_component_test_bits(component, ma_error_acc__a, 0x01, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
ret = snd_soc_component_test_bits(component, ma_error_acc__a, 0x02, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
ret = snd_soc_component_test_bits(component, ma_error_acc__a, 0x08, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
ret = snd_soc_component_test_bits(component, ma_error_acc__a, 0x10, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
ret = snd_soc_component_test_bits(component, ma_error_acc__a, 0x20, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
ret = snd_soc_component_test_bits(component, ma_error_acc__a, 0x40, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
ret = snd_soc_component_test_bits(component, ma_error_acc__a, 0x80, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ma120x0p_set_bias_level(struct snd_soc_component *component,
|
|
enum snd_soc_bias_level level)
|
|
{
|
|
int ret = 0;
|
|
|
|
struct ma120x0p_priv *ma120x0p;
|
|
|
|
ma120x0p = snd_soc_component_get_drvdata(component);
|
|
|
|
switch (level) {
|
|
case SND_SOC_BIAS_ON:
|
|
break;
|
|
|
|
case SND_SOC_BIAS_PREPARE:
|
|
break;
|
|
|
|
case SND_SOC_BIAS_STANDBY:
|
|
ret = gpiod_get_value_cansleep(priv_data->enable_gpio);
|
|
if (ret != 0) {
|
|
dev_err(component->dev, "Device ma120x0p disabled in STANDBY BIAS: %d\n",
|
|
ret);
|
|
return ret;
|
|
}
|
|
break;
|
|
|
|
case SND_SOC_BIAS_OFF:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct snd_soc_dapm_widget ma120x0p_dapm_widgets[] = {
|
|
SND_SOC_DAPM_OUTPUT("OUT_A"),
|
|
SND_SOC_DAPM_OUTPUT("OUT_B"),
|
|
};
|
|
|
|
static const struct snd_soc_dapm_route ma120x0p_dapm_routes[] = {
|
|
{ "OUT_B", NULL, "Playback" },
|
|
{ "OUT_A", NULL, "Playback" },
|
|
};
|
|
|
|
static const struct snd_soc_component_driver ma120x0p_component_driver = {
|
|
.probe = ma120x0p_probe,
|
|
.remove = ma120x0p_remove,
|
|
.set_bias_level = ma120x0p_set_bias_level,
|
|
.dapm_widgets = ma120x0p_dapm_widgets,
|
|
.num_dapm_widgets = ARRAY_SIZE(ma120x0p_dapm_widgets),
|
|
.dapm_routes = ma120x0p_dapm_routes,
|
|
.num_dapm_routes = ARRAY_SIZE(ma120x0p_dapm_routes),
|
|
.controls = ma120x0p_snd_controls,
|
|
.num_controls = ARRAY_SIZE(ma120x0p_snd_controls),
|
|
.use_pmdown_time = 1,
|
|
.endianness = 1,
|
|
};
|
|
|
|
//I2C Driver
|
|
static const struct reg_default ma120x0p_reg_defaults[] = {
|
|
{ 0x01, 0x3c },
|
|
};
|
|
|
|
static bool ma120x0p_reg_volatile(struct device *dev, unsigned int reg)
|
|
{
|
|
switch (reg) {
|
|
case ma_error__a:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static const struct of_device_id ma120x0p_of_match[] = {
|
|
{ .compatible = "ma,ma120x0p", },
|
|
{ }
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(of, ma120x0p_of_match);
|
|
|
|
static struct regmap_config ma120x0p_regmap_config = {
|
|
.reg_bits = 8,
|
|
.val_bits = 8,
|
|
|
|
.max_register = 255,
|
|
.volatile_reg = ma120x0p_reg_volatile,
|
|
|
|
.cache_type = REGCACHE_RBTREE,
|
|
.reg_defaults = ma120x0p_reg_defaults,
|
|
.num_reg_defaults = ARRAY_SIZE(ma120x0p_reg_defaults),
|
|
};
|
|
|
|
static int ma120x0p_i2c_probe(struct i2c_client *i2c)
|
|
{
|
|
int ret;
|
|
|
|
priv_data = devm_kzalloc(&i2c->dev, sizeof(*priv_data), GFP_KERNEL);
|
|
if (!priv_data)
|
|
return -ENOMEM;
|
|
i2c_set_clientdata(i2c, priv_data);
|
|
|
|
priv_data->regmap = devm_regmap_init_i2c(i2c, &ma120x0p_regmap_config);
|
|
if (IS_ERR(priv_data->regmap)) {
|
|
ret = PTR_ERR(priv_data->regmap);
|
|
return ret;
|
|
}
|
|
|
|
//Startup sequence
|
|
|
|
//Make sure the device is muted
|
|
priv_data->mute_gpio = devm_gpiod_get_optional(&i2c->dev, "mute_gp",
|
|
GPIOD_OUT_LOW);
|
|
if (IS_ERR(priv_data->mute_gpio)) {
|
|
ret = PTR_ERR(priv_data->mute_gpio);
|
|
dev_err(&i2c->dev, "Failed to get mute gpio line: %d\n", ret);
|
|
return ret;
|
|
}
|
|
msleep(50);
|
|
|
|
// MA120xx0P devices are usually powered by an integrated boost converter.
|
|
// An option GPIO control line is provided to enable the booster properly and
|
|
// in sync with the enable and mute GPIO lines.
|
|
priv_data->booster_gpio = devm_gpiod_get_optional(&i2c->dev,
|
|
"booster_gp", GPIOD_OUT_LOW);
|
|
if (IS_ERR(priv_data->booster_gpio)) {
|
|
ret = PTR_ERR(priv_data->booster_gpio);
|
|
dev_err(&i2c->dev,
|
|
"Failed to get booster enable gpio line: %d\n", ret);
|
|
return ret;
|
|
}
|
|
msleep(50);
|
|
|
|
//Enable booster and wait 200ms until stable PVDD
|
|
gpiod_set_value_cansleep(priv_data->booster_gpio, 1);
|
|
msleep(200);
|
|
|
|
//Enable ma120x0pp
|
|
priv_data->enable_gpio = devm_gpiod_get_optional(&i2c->dev,
|
|
"enable_gp", GPIOD_OUT_LOW);
|
|
if (IS_ERR(priv_data->enable_gpio)) {
|
|
ret = PTR_ERR(priv_data->enable_gpio);
|
|
dev_err(&i2c->dev,
|
|
"Failed to get ma120x0p enable gpio line: %d\n", ret);
|
|
return ret;
|
|
}
|
|
msleep(50);
|
|
|
|
//Optional use of ma120x0pp error line as an interrupt trigger to
|
|
//platform GPIO.
|
|
//Get error input gpio ma120x0p
|
|
priv_data->error_gpio = devm_gpiod_get_optional(&i2c->dev,
|
|
"error_gp", GPIOD_IN);
|
|
if (IS_ERR(priv_data->error_gpio)) {
|
|
ret = PTR_ERR(priv_data->error_gpio);
|
|
dev_err(&i2c->dev,
|
|
"Failed to get ma120x0p error gpio line: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
if (priv_data->error_gpio != NULL) {
|
|
irqNumber = gpiod_to_irq(priv_data->error_gpio);
|
|
|
|
ret = devm_request_threaded_irq(&i2c->dev,
|
|
irqNumber, ma120x0p_irq_handler,
|
|
NULL, IRQF_TRIGGER_FALLING,
|
|
"ma120x0p", priv_data);
|
|
if (ret != 0)
|
|
dev_warn(&i2c->dev, "Failed to request IRQ: %d\n",
|
|
ret);
|
|
}
|
|
|
|
ret = devm_snd_soc_register_component(&i2c->dev,
|
|
&ma120x0p_component_driver, &ma120x0p_dai, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static irqreturn_t ma120x0p_irq_handler(int irq, void *data)
|
|
{
|
|
gpiod_set_value_cansleep(priv_data->mute_gpio, 0);
|
|
gpiod_set_value_cansleep(priv_data->enable_gpio, 1);
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
static void ma120x0p_i2c_remove(struct i2c_client *i2c)
|
|
{
|
|
snd_soc_unregister_component(&i2c->dev);
|
|
i2c_set_clientdata(i2c, NULL);
|
|
|
|
gpiod_set_value_cansleep(priv_data->mute_gpio, 0);
|
|
msleep(30);
|
|
gpiod_set_value_cansleep(priv_data->enable_gpio, 1);
|
|
msleep(200);
|
|
gpiod_set_value_cansleep(priv_data->booster_gpio, 0);
|
|
msleep(200);
|
|
|
|
kfree(priv_data);
|
|
}
|
|
|
|
static void ma120x0p_i2c_shutdown(struct i2c_client *i2c)
|
|
{
|
|
snd_soc_unregister_component(&i2c->dev);
|
|
i2c_set_clientdata(i2c, NULL);
|
|
|
|
gpiod_set_value_cansleep(priv_data->mute_gpio, 0);
|
|
msleep(30);
|
|
gpiod_set_value_cansleep(priv_data->enable_gpio, 1);
|
|
msleep(200);
|
|
gpiod_set_value_cansleep(priv_data->booster_gpio, 0);
|
|
msleep(200);
|
|
|
|
kfree(priv_data);
|
|
}
|
|
|
|
static const struct i2c_device_id ma120x0p_i2c_id[] = {
|
|
{ "ma120x0p", 0 },
|
|
{ }
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(i2c, ma120x0p_i2c_id);
|
|
|
|
static struct i2c_driver ma120x0p_i2c_driver = {
|
|
.driver = {
|
|
.name = "ma120x0p",
|
|
.owner = THIS_MODULE,
|
|
.of_match_table = ma120x0p_of_match,
|
|
},
|
|
.probe = ma120x0p_i2c_probe,
|
|
.remove = ma120x0p_i2c_remove,
|
|
.shutdown = ma120x0p_i2c_shutdown,
|
|
.id_table = ma120x0p_i2c_id
|
|
};
|
|
|
|
static int __init ma120x0p_modinit(void)
|
|
{
|
|
int ret = 0;
|
|
|
|
ret = i2c_add_driver(&ma120x0p_i2c_driver);
|
|
if (ret != 0) {
|
|
pr_err("Failed to register MA120X0P I2C driver: %d\n", ret);
|
|
return ret;
|
|
}
|
|
return ret;
|
|
}
|
|
module_init(ma120x0p_modinit);
|
|
|
|
static void __exit ma120x0p_exit(void)
|
|
{
|
|
i2c_del_driver(&ma120x0p_i2c_driver);
|
|
}
|
|
module_exit(ma120x0p_exit);
|
|
|
|
MODULE_AUTHOR("Ariel Muszkat ariel.muszkat@gmail.com>");
|
|
MODULE_DESCRIPTION("ASoC driver for ma120x0p");
|
|
MODULE_LICENSE("GPL v2");
|