From 77e97abf129c5028385dd72587eabab68db0d954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 28 May 2020 19:08:55 +0200 Subject: bcm27xx: update to latest patches from RPi foundation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also removes random module and switches to new bcm2711 thermal driver. Boot tested on RPi 4B v1.1 4G. Signed-off-by: Álvaro Fernández Rojas --- ...-for-merus-amp-soundcard-and-ma120x0p-cod.patch | 1589 ++++++++++++++++++++ 1 file changed, 1589 insertions(+) create mode 100644 target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch (limited to 'target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch') diff --git a/target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch b/target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch new file mode 100644 index 0000000000..8e66bccf6e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch @@ -0,0 +1,1589 @@ +From 76e0edf9676388c58bb5f0d7dda8eb8029926c6d Mon Sep 17 00:00:00 2001 +From: AMuszkat +Date: Mon, 24 Feb 2020 22:56:59 +0100 +Subject: [PATCH] Add support for merus-amp soundcard and ma120x0p + codec + +correct checkpatch warnings and errors + +Signed-off-by: AMuszkat +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 + + .../boot/dts/overlays/merus-amp-overlay.dts | 60 + + sound/soc/bcm/rpi-simple-soundcard.c | 28 + + sound/soc/codecs/Kconfig | 8 + + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/ma120x0p.c | 1384 +++++++++++++++++ + 7 files changed, 1489 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/merus-amp-overlay.dts + create mode 100644 sound/soc/codecs/ma120x0p.c + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -103,6 +103,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + mcp3202.dtbo \ + mcp342x.dtbo \ + media-center.dtbo \ ++ merus-amp.dtbo \ + midi-uart0.dtbo \ + midi-uart1.dtbo \ + miniuart-bt.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1662,6 +1662,12 @@ Params: speed Display + (default "off") + + ++Name: merus-amp ++Info: Configures the merus-amp audio card ++Load: dtoverlay=merus-amp ++Params: ++ ++ + Name: midi-uart0 + Info: Configures UART0 (ttyAMA0) so that a requested 38.4kbaud actually gets + 31.25kbaud, the frequency required for MIDI +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/merus-amp-overlay.dts +@@ -0,0 +1,60 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Definitions for Infineon Merus-Amp ++/dts-v1/; ++/plugin/; ++#include ++#include ++ ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ merus_amp_pins: merus_amp_pins { ++ brcm,pins = <23>; ++ brcm,function = <0>; /* in */ ++ brcm,pull = <2>; /* up */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ merus_amp: ma120x0p@20 { ++ #sound-dai-cells = <0>; ++ compatible = "ma,ma120x0p"; ++ reg = <0x20>; ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&merus_amp_pins>; ++ enable_gp-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>; ++ mute_gp-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>; ++ booster_gp-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; ++ error_gp-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "merus,merus-amp"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++}; +--- a/sound/soc/bcm/rpi-simple-soundcard.c ++++ b/sound/soc/bcm/rpi-simple-soundcard.c +@@ -16,6 +16,10 @@ + * adau1977-adc.c + * by Andrey Grodzovsky + * ++ * merus-amp.c ++ * by Ariel Muszkat ++ * Jorgen Kragh Jakobsen ++ * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. +@@ -229,6 +233,28 @@ static struct snd_rpi_simple_drvdata drv + .fixed_bclk_ratio = 64, + }; + ++SND_SOC_DAILINK_DEFS(merus_amp, ++ DAILINK_COMP_ARRAY(COMP_EMPTY()), ++ DAILINK_COMP_ARRAY(COMP_CODEC("ma120x0p-amp", "ma120x0p.1-0020")), ++ DAILINK_COMP_ARRAY(COMP_EMPTY())); ++ ++static struct snd_soc_dai_link snd_merus_amp_dai[] = { ++ { ++ .name = "MerusAmp", ++ .stream_name = "Merus Audio Amp", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ SND_SOC_DAILINK_REG(merus_amp), ++ }, ++}; ++ ++static struct snd_rpi_simple_drvdata drvdata_merus_amp = { ++ .card_name = "snd_rpi_merus_amp", ++ .dai = snd_merus_amp_dai, ++ .fixed_bclk_ratio = 64, ++}; ++ + static const struct of_device_id snd_rpi_simple_of_match[] = { + { .compatible = "adi,adau1977-adc", + .data = (void *) &drvdata_adau1977 }, +@@ -241,6 +267,8 @@ static const struct of_device_id snd_rpi + { .compatible = "hifiberry,hifiberry-dac", + .data = (void *) &drvdata_hifiberry_dac }, + { .compatible = "rpi,rpi-dac", &drvdata_rpi_dac}, ++ { .compatible = "merus,merus-amp", ++ .data = (void *) &drvdata_merus_amp }, + {}, + }; + +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -103,6 +103,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_LM4857 if I2C + select SND_SOC_LM49453 if I2C + select SND_SOC_LOCHNAGAR_SC if MFD_LOCHNAGAR ++ select SND_SOC_MA120X0P if I2C + select SND_SOC_MAX98088 if I2C + select SND_SOC_MAX98090 if I2C + select SND_SOC_MAX98095 if I2C +@@ -732,6 +733,13 @@ config SND_SOC_LOCHNAGAR_SC + This driver support the sound card functionality of the Cirrus + Logic Lochnagar audio development board. + ++config SND_SOC_MA120X0P ++ tristate "Infineon Merus(TM) MA120X0P Multilevel Class-D Audio amplifiers" ++ depends on I2C ++ help ++ Enable support for Infineon MA120X0P Multilevel Class-D audio power ++ amplifiers. ++ + config SND_SOC_MADERA + tristate + default y if SND_SOC_CS47L15=y +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -99,6 +99,7 @@ snd-soc-l3-objs := l3.o + snd-soc-lm4857-objs := lm4857.o + snd-soc-lm49453-objs := lm49453.o + snd-soc-lochnagar-sc-objs := lochnagar-sc.o ++snd-soc-ma120x0p-objs := ma120x0p.o + snd-soc-madera-objs := madera.o + snd-soc-max9759-objs := max9759.o + snd-soc-max9768-objs := max9768.o +@@ -386,6 +387,7 @@ obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o + obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o + obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o + obj-$(CONFIG_SND_SOC_LOCHNAGAR_SC) += snd-soc-lochnagar-sc.o ++obj-$(CONFIG_SND_SOC_MA120X0P) += snd-soc-ma120x0p.o + obj-$(CONFIG_SND_SOC_MADERA) += snd-soc-madera.o + obj-$(CONFIG_SND_SOC_MAX9759) += snd-soc-max9759.o + obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o +--- /dev/null ++++ b/sound/soc/codecs/ma120x0p.c +@@ -0,0 +1,1384 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * ASoC Driver for Infineon Merus(TM) ma120x0p multi-level class-D amplifier ++ * ++ * Authors: Ariel Muszkat ++ * Jorgen Kragh Jakobsen ++ * ++ * Copyright (C) 2019 Infineon Technologies AG ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#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 const 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, -5000, 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, 0x4a, 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 = 48000, ++ .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, ++ .non_legacy_dai_naming = 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, ++ const struct i2c_device_id *id) ++{ ++ 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(&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(&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 int 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); ++ ++ return 0; ++} ++ ++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"); -- cgit v1.2.3