* [PATCH] arm/dts: ls1021a: Add dma-coherent property to usb3 node
From: Changming Huang @ 2016-11-23 7:15 UTC (permalink / raw)
To: robh+dt, mark.rutland, linux
Cc: devicetree, Rajesh Bhagat, linux-kernel, linux-arm-kernel,
Changming Huang
This sets dma ops as coherent for usb 3.0 platform device
Signed-off-by: Changming Huang <jerry.huang@nxp.com>
Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
---
arch/arm/boot/dts/ls1021a.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 368e219..81fb4d9 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -627,6 +627,7 @@
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
+ dma-coherent;
};
pcie@3400000 {
--
1.7.9.5
^ permalink raw reply related
* RE: [PATCH V3 1/2] powerpc/mpc85xx: Update TMU device tree node for T1040/T1042
From: Troy Jia @ 2016-11-23 7:14 UTC (permalink / raw)
To: Scott Wood, rui.zhang@intel.com, edubezval@gmail.com,
robh+dt@kernel.org, Scott Wood, shawnguo@kernel.org
Cc: devicetree@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <1479884833.21746.44.camel@buserror.net>
> -----Original Message-----
> From: Scott Wood [mailto:oss@buserror.net]
> Sent: Wednesday, November 23, 2016 3:07 PM
> To: Troy Jia <hongtao.jia@nxp.com>; rui.zhang@intel.com; edubezval@gmail.com;
> robh+dt@kernel.org; Scott Wood <scott.wood@nxp.com>; shawnguo@kernel.org
> Cc: devicetree@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; linux-
> kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH V3 1/2] powerpc/mpc85xx: Update TMU device tree node for
> T1040/T1042
>
> On Tue, 2016-10-25 at 10:15 +0800, Jia Hongtao wrote:
> > From: Hongtao Jia <hongtao.jia@nxp.com>
> >
> > Update #thermal-sensor-cells from 0 to 1 according to the new binding.
> > The sensor specifier added is the monitoring site ID, and represents
> > the "n" in TRITSRn and TRATSRn.
> >
> > Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
>
> Where can I find this new binding? As of the current linux-next I don't see anything
> in qoriq-thermal.txt about this.
Hi Rui Zhang,
As we discussed before. The time was inappropriate as merge window was about to close.
So do you have any plan for applying the binding file recently?
-Hongtao.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V3 1/2] powerpc/mpc85xx: Update TMU device tree node for T1040/T1042
From: Scott Wood @ 2016-11-23 7:07 UTC (permalink / raw)
To: Jia Hongtao, rui.zhang, edubezval, robh+dt, scott.wood, shawnguo
Cc: devicetree, linuxppc-dev, linux-kernel, linux-arm-kernel
In-Reply-To: <1477361742-589-1-git-send-email-hongtao.jia@nxp.com>
On Tue, 2016-10-25 at 10:15 +0800, Jia Hongtao wrote:
> From: Hongtao Jia <hongtao.jia@nxp.com>
>
> Update #thermal-sensor-cells from 0 to 1 according to the new binding. The
> sensor specifier added is the monitoring site ID, and represents the "n" in
> TRITSRn and TRATSRn.
>
> Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
Where can I find this new binding? As of the current linux-next I don't see
anything in qoriq-thermal.txt about this.
-Scott
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 1/5] ARM: memory: da8xx-ddrctl: new driver
From: Sekhar Nori @ 2016-11-23 5:55 UTC (permalink / raw)
To: Frank Rowand, Bartosz Golaszewski, Kevin Hilman,
Michael Turquette, Rob Herring, Mark Rutland, Peter Ujfalusi,
Russell King
Cc: linux-devicetree, David Airlie, LKML, linux-drm, Tomi Valkeinen,
Jyri Sarha, Sudeep Holla, arm-soc, Laurent Pinchart
In-Reply-To: <58348CB8.7050304@gmail.com>
On Tuesday 22 November 2016 11:51 PM, Frank Rowand wrote:
> Please note that the compatible property might contain several strings, not just
> a single string.
So I guess the best thing to do is to use
of_property_read_string_index() and print the sting at index 0.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH] arm/dts: ls1021a: Add dma-coherent property to usb3 node
From: Changming Huang @ 2016-11-23 5:49 UTC (permalink / raw)
To: linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: Changming Huang, Rajesh Bhagat
This sets dma ops as coherent for usb 3.0 platform device
Signed-off-by: Changming Huang <jerry.huang-3arQi8VN3Tc@public.gmane.org>
Signed-off-by: Rajesh Bhagat <rajesh.bhagat-3arQi8VN3Tc@public.gmane.org>
---
arch/arm/boot/dts/ls1021a.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 368e219..81fb4d9 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -627,6 +627,7 @@
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
+ dma-coherent;
};
pcie@3400000 {
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH 5/5] sdhci: Add quirk for delayed IRQ ACK
From: Jeremy McNicoll @ 2016-11-23 5:23 UTC (permalink / raw)
To: Jisheng Zhang
Cc: Jeremy McNicoll, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
andy.gross-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
robh-DgEjT+Ai2ygdnm+yROfE0A, arnd-r2nGTMty4D4,
bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
riteshh-sgV2jX0FEOL9JmXXK+q4OQ
In-Reply-To: <20161123121209.3623e14b@xhacker>
On 2016-11-22 8:12 PM, Jisheng Zhang wrote:
> On Tue, 22 Nov 2016 19:48:56 -0800 Jeremy McNicoll wrote:
>
>> On 2016-11-22 7:36 PM, Jisheng Zhang wrote:
>>> On Tue, 22 Nov 2016 17:09:48 -0800
>>> Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>>
>>>> On msm8992 it has been observed that IRQs were not getting
>>>> ACK'd correctly when clocked at speeds greater than 400KHz.
>>>>
>>>> Signed-off-by: Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>>> ---
>>>> drivers/mmc/host/sdhci-msm.c | 7 +++++++
>>>> drivers/mmc/host/sdhci.c | 12 ++++++++++--
>>>> drivers/mmc/host/sdhci.h | 2 ++
>>>> 3 files changed, 19 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
>>>> index 1fcda96..459003c 100644
>>>> --- a/drivers/mmc/host/sdhci-msm.c
>>>> +++ b/drivers/mmc/host/sdhci-msm.c
>>>> @@ -1303,6 +1303,13 @@ static int sdhci_msm_probe(struct platform_device *pdev)
>>>> CORE_VENDOR_SPEC_CAPABILITIES0);
>>>> }
>>>>
>>>> + /* Enable delayed IRQ handling workaround on 8992 */
>>>> + if (core_major == 1 && core_minor == 0x3e) {
>>>> + /* Add 40us delay in interrupt handler when operating
>>>> + * at initialization frequency of 400KHz. */
>>>> + host->quirks2 |= SDHCI_QUIRK2_SLOW_INT_CLR;
>>>> + }
>>>> +
>>>> /* Setup IRQ for handling power/voltage tasks with PMIC */
>>>> msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq");
>>>> if (msm_host->pwr_irq < 0) {
>>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>>> index 5911f98..c1aae22 100644
>>>> --- a/drivers/mmc/host/sdhci.c
>>>> +++ b/drivers/mmc/host/sdhci.c
>>>> @@ -2703,11 +2703,19 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
>>>> result = IRQ_WAKE_THREAD;
>>>> }
>>>>
>>>> - if (intmask & SDHCI_INT_CMD_MASK)
>>>> + if (intmask & SDHCI_INT_CMD_MASK) {
>>>> + if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
>>>> + udelay(40);
>>>> + }
>>>> sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
>>>> + }
>>>>
>>>> - if (intmask & SDHCI_INT_DATA_MASK)
>>>> + if (intmask & SDHCI_INT_DATA_MASK) {
>>>> + if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
>>>> + udelay(40);
>>>> + }
>>>> sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
>>>> + }
>>>>
>>>> if (intmask & SDHCI_INT_BUS_POWER)
>>>> pr_err("%s: Card is consuming too much power!\n",
>>>> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
>>>> index c055e24..5f8301e 100644
>>>> --- a/drivers/mmc/host/sdhci.h
>>>> +++ b/drivers/mmc/host/sdhci.h
>>>> @@ -24,6 +24,8 @@
>>>> * Controller registers
>>>> */
>>>>
>>>> +#define SDHCI_QUIRK2_SLOW_INT_CLR (1<<5)
>>>
>>> IIRC, new quirk isn't allowed now.
>>>
>>
>> Why not?
>
> IIRC, mmc subsystem will behave as a lib in the long run, so the community
> and developers call for no new quirk. For your case, we may need to handle
> the udelay in sdhci-msm.c, export sdhci_irq as a helper function?
>
Thanks for the details and suggestions. I am going to wait until the US
Thanksgiving (and cyber Monday) is over before I do any more.
-jeremy
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v9 00/16] mmc: sdhci-msm: Add clk-rates, DDR, HS400 support
From: Andy Gross @ 2016-11-23 5:00 UTC (permalink / raw)
To: Ulf Hansson
Cc: Ritesh Harjani, linux-mmc, Adrian Hunter, Stephen Boyd, Shawn Lin,
devicetree@vger.kernel.org, linux-clk, David Brown,
linux-arm-msm@vger.kernel.org, Georgi Djakov, Alex Lemberg,
Mateusz Nowak, Yuliy Izrailov, Asutosh Das, David Griego,
Sahitya Tummala, Venkat Gopalakrishnan, Rajendra Nayak
In-Reply-To: <CAPDyKFrRbf0+G5K=-jsaevAGbTqhTAss2zJv3QdiyCrv0BG-zA@mail.gmail.com>
On Mon, Nov 21, 2016 at 11:06:13AM +0100, Ulf Hansson wrote:
> On 21 November 2016 at 07:37, Ritesh Harjani <riteshh@codeaurora.org> wrote:
> > Hi,
> >
> > This is v9 version of the patch series which adds support for MSM8996.
> > Adds HS400 driver support as well.
> > These are tested on internal msm8996 & db410c HW.
> >
> > The patch series is ready. Do we think we can apply these
> > patches for next now?
>
> I guess the DTS changes can be picked up by Andy, so they can go via arm-soc?
Yeah I'll pick up the DTS change and the Documentation change.
>
> Then, does the mmc changes depend on the clock changes? If so, I can
> pick them as well, but then I need an ack from Stephen....
>
> Kind regards
> Uffe
Andy
^ permalink raw reply
* [PATCH] ALSA SoC MAX98927 driver - Initial release
From: Ryan Lee @ 2016-11-23 4:57 UTC (permalink / raw)
To: lgirdwood, broonie, robh+dt, mark.rutland, perex, tiwai, arnd,
michael, oder_chiou, yesanishhere, jacob, Damien.Horsley,
bardliao, kuninori.morimoto.gx, petr, lars, nh6z, ryans.lee,
alsa-devel, devicetree, linux-kernel
Cc: Ryan Lee
Signed-off-by: Ryan Lee <ryans.lee@maximintegrated.com>
---
.../devicetree/bindings/sound/max98927.txt | 32 +
sound/soc/codecs/Kconfig | 5 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/max98927.c | 954 +++++++++++++++
sound/soc/codecs/max98927.h | 1253 ++++++++++++++++++++
5 files changed, 2246 insertions(+)
create mode 100755 Documentation/devicetree/bindings/sound/max98927.txt
mode change 100644 => 100755 sound/soc/codecs/Kconfig
mode change 100644 => 100755 sound/soc/codecs/Makefile
create mode 100755 sound/soc/codecs/max98927.c
create mode 100755 sound/soc/codecs/max98927.h
diff --git a/Documentation/devicetree/bindings/sound/max98927.txt b/Documentation/devicetree/bindings/sound/max98927.txt
new file mode 100755
index 0000000..ddcd332
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/max98927.txt
@@ -0,0 +1,32 @@
+max98927 audio CODEC
+
+This device supports I2C.
+
+Required properties:
+
+ - compatible : "maxim,max98927"
+
+ - vmon-slot-no : slot number used to send voltage information
+ or in inteleave mode this will be used as
+ interleave slot.
+
+ - imon-slot-no : slot number used to send current information
+
+ - interleave-mode : When using two MAX98927 in a system it is
+ possible to create ADC data that that will
+ overflow the frame size. Digital Audio Interleave
+ mode provides a means to output VMON and IMON data
+ from two devices on a single DOUT line when running
+ smaller frames sizes such as 32 BCLKS per LRCLK or
+ 48 BCLKS per LRCLK.
+
+ - reg : the I2C address of the device for I2C
+
+Example:
+
+codec: max98927@3a {
+ compatible = "maxim,max98927";
+ vmon-slot-no = <1>;
+ imon-slot-no = <0>;
+ reg = <0x3a>;
+};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
old mode 100644
new mode 100755
index c67667b..45f21ca
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -86,6 +86,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9867 if I2C
select SND_SOC_MAX98925 if I2C
select SND_SOC_MAX98926 if I2C
+ select SND_SOC_MAX98927 if I2C
select SND_SOC_MAX9850 if I2C
select SND_SOC_MAX9860 if I2C
select SND_SOC_MAX9768 if I2C
@@ -573,6 +574,10 @@ config SND_SOC_MAX98925
config SND_SOC_MAX98926
tristate
+config SND_SOC_MAX98927
+ tristate "Maxim Integrated MAX98927 Speaker Amplifier"
+ depends on I2C
+
config SND_SOC_MAX9850
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
old mode 100644
new mode 100755
index 958cd49..1f5fe2c
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -82,6 +82,7 @@ snd-soc-max98371-objs := max98371.o
snd-soc-max9867-objs := max9867.o
snd-soc-max98925-objs := max98925.o
snd-soc-max98926-objs := max98926.o
+snd-soc-max98927-objs := max98927.o
snd-soc-max9850-objs := max9850.o
snd-soc-max9860-objs := max9860.o
snd-soc-mc13783-objs := mc13783.o
@@ -306,6 +307,7 @@ obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
+obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
new file mode 100755
index 0000000..d85c84f
--- /dev/null
+++ b/sound/soc/codecs/max98927.c
@@ -0,0 +1,954 @@
+/*
+ * max98927.c -- MAX98927 ALSA Soc Audio driver
+ *
+ * Copyright 2013-15 Maxim Integrated Products
+ * Author: Ryan Lee <ryans.lee@maximintegrated.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/cdev.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <sound/tlv.h>
+#include "max98927.h"
+
+static struct reg_default max98927_reg_map[] = {
+ {0x0014, 0x78},
+ {0x0015, 0xFF},
+ {0x0043, 0x04},
+ {0x0017, 0x55},
+ /* For mono driver we are just enabling one channel*/
+ {MAX98927_PCM_Rx_Enables_A, 0x03},
+ {MAX98927_PCM_Tx_HiZ_Control_A, 0xfc},
+ {MAX98927_PCM_Tx_HiZ_Control_B, 0xff},
+ {MAX98927_PCM_Tx_Channel_Sources_A, 0x01},
+ {MAX98927_PCM_Tx_Channel_Sources_B, 0x01},
+ {MAX98927_Measurement_DSP_Config, 0xf7},
+ {0x0025, 0x80},
+ {0x0026, 0x01},
+ {0x0035, 0x40},
+ {0x0036, 0x40},
+ {0x0037, 0x02},
+ {0x0039, 0x01},
+ {0x003c, 0x44},
+ {0x003d, 0x04},
+ {0x0040, 0x10},
+ {0x0042, 0x3f},
+ {0x0044, 0x00},
+ {0x0045, 0x24},
+ {0x007f, 0x06},
+ {0x0087, 0x1c},
+ {0x0089, 0x03},
+ {0x009f, 0x01},
+};
+
+void max98927_wrapper_write(struct max98927_priv *max98927,
+ unsigned int reg, unsigned int val)
+{
+ if (max98927->regmap)
+ regmap_write(max98927->regmap, reg, val);
+ if (max98927->sub_regmap)
+ regmap_write(max98927->sub_regmap, reg, val);
+}
+
+void max98927_wrap_update_bits(struct max98927_priv *max98927,
+ unsigned int reg, unsigned int mask, unsigned int val)
+{
+ if (max98927->regmap)
+ regmap_update_bits(max98927->regmap, reg, mask, val);
+ if (max98927->sub_regmap)
+ regmap_update_bits(max98927->sub_regmap, reg, mask, val);
+}
+
+static int max98927_reg_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol, unsigned int reg,
+ unsigned int mask, unsigned int shift)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ int data;
+
+ regmap_read(max98927->regmap, reg, &data);
+ ucontrol->value.integer.value[0] =
+ (data & mask) >> shift;
+ return 0;
+}
+
+static int max98927_reg_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol, unsigned int reg,
+ unsigned int mask, unsigned int shift)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ unsigned int sel = ucontrol->value.integer.value[0];
+
+ max98927_wrap_update_bits(max98927, reg, mask, sel << shift);
+ dev_dbg(codec->dev, "%s: register 0x%02X, value 0x%02X\n",
+ __func__, reg, sel);
+ return 0;
+}
+
+static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ unsigned int invert = 0;
+
+ dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode,
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask,
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_SLAVE);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ max98927->master = true;
+ max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode,
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask,
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_MASTER);
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode,
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask,
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_HYBRID);
+ default:
+ dev_err(codec->dev, "DAI clock mode unsupported");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ invert = MAX98927_PCM_Mode_Config_PCM_BCLKEDGE;
+ break;
+ default:
+ dev_err(codec->dev, "DAI invert mode unsupported");
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ max98927->iface |= SND_SOC_DAIFMT_I2S;
+ max98927_wrap_update_bits(max98927,
+ MAX98927_PCM_Mode_Config,
+ max98927->iface, max98927->iface);
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
+ max98927_wrap_update_bits(max98927,
+ MAX98927_PCM_Mode_Config,
+ max98927->iface, max98927->iface);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* pcm channel configuration */
+ if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
+ max98927_wrapper_write(max98927,
+ MAX98927_PCM_Rx_Enables_A,
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH0_EN|
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH1_EN);
+ max98927_wrapper_write(max98927,
+ MAX98927_PCM_Tx_Enables_A,
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH0_EN|
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH1_EN);
+ }
+ max98927_wrap_update_bits(max98927, MAX98927_PCM_Mode_Config,
+ MAX98927_PCM_Mode_Config_PCM_BCLKEDGE, invert);
+ return 0;
+}
+
+/* codec MCLK rate in master mode */
+static const int rate_table[] = {
+ 5644800, 6000000, 6144000, 6500000,
+ 9600000, 11289600, 12000000, 12288000,
+ 13000000, 19200000,
+};
+
+static int max98927_set_clock(struct max98927_priv *max98927,
+ struct snd_pcm_hw_params *params)
+{
+ /* BCLK/LRCLK ratio calculation */
+ int blr_clk_ratio = params_channels(params) * max98927->ch_size;
+ int reg = MAX98927_PCM_Clock_setup;
+ int mask = MAX98927_PCM_Clock_setup_PCM_BSEL_Mask;
+ int value;
+
+ if (max98927->master) {
+ int i;
+ /* match rate to closest value */
+ for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
+ if (rate_table[i] >= max98927->sysclk)
+ break;
+ }
+ if (i == ARRAY_SIZE(rate_table)) {
+ pr_err("%s couldn't get the MCLK to match codec\n",
+ __func__);
+ return -EINVAL;
+ }
+ max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode,
+ MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_Mask,
+ i << MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_SHIFT);
+ }
+
+ switch (blr_clk_ratio) {
+ case 32:
+ value = 2;
+ break;
+ case 48:
+ value = 3;
+ break;
+ case 64:
+ value = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+ max98927_wrap_update_bits(max98927,
+ reg, mask, value);
+ return 0;
+}
+
+static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ int sampling_rate = 0;
+
+ /* pcm mode configuration */
+ switch (snd_pcm_format_width(params_format(params))) {
+ case 16:
+ max98927_wrap_update_bits(max98927,
+ MAX98927_PCM_Mode_Config,
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_16,
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_16);
+ max98927->ch_size = 16;
+ break;
+ case 24:
+ max98927_wrap_update_bits(max98927,
+ MAX98927_PCM_Mode_Config,
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_24,
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_24);
+ max98927->ch_size = 24;
+ break;
+ case 32:
+ max98927_wrap_update_bits(max98927,
+ MAX98927_PCM_Mode_Config,
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_32,
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_32);
+ max98927->ch_size = 32;
+ break;
+ default:
+ pr_err("%s: format unsupported %d",
+ __func__, params_format(params));
+ goto err;
+ }
+ dev_dbg(codec->dev, "%s: format supported %d",
+ __func__, params_format(params));
+
+ /* sampling rate configuration */
+ switch (params_rate(params)) {
+ case 8000:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_8000;
+ break;
+ case 11025:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_11025;
+ break;
+ case 12000:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_12000;
+ break;
+ case 16000:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_16000;
+ break;
+ case 22050:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_22050;
+ break;
+ case 24000:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_24000;
+ break;
+ case 32000:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_32000;
+ break;
+ case 44100:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_44100;
+ break;
+ case 48000:
+ sampling_rate |=
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_48000;
+ break;
+ default:
+ pr_err("%s rate %d not supported\n",
+ __func__, params_rate(params));
+ goto err;
+ }
+ /* set DAI_SR to correct LRCLK frequency */
+ max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_1,
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_Mask, sampling_rate);
+ max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_2,
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_Mask, sampling_rate<<4);
+ max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_2,
+ MAX98927_PCM_Sample_rate_setup_2_IVADC_SR_Mask, sampling_rate);
+ return max98927_set_clock(max98927, params);
+err:
+ return -EINVAL;
+}
+
+#define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
+
+#define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+
+ max98927->sysclk = freq;
+ return 0;
+}
+
+static const struct snd_soc_dai_ops max98927_dai_ops = {
+ .set_sysclk = max98927_dai_set_sysclk,
+ .set_fmt = max98927_dai_set_fmt,
+ .hw_params = max98927_dai_hw_params,
+};
+
+static void max98927_handle_pdata(struct snd_soc_codec *codec)
+{
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ struct max98927_reg_default *regInfo;
+ int cfg_size = 0;
+ int x;
+
+ if (max98927->regcfg != NULL)
+ cfg_size = max98927->regcfg_sz / sizeof(uint32_t);
+
+ if (cfg_size <= 0) {
+ dev_dbg(codec->dev,
+ "Register configuration is not required.\n");
+ return;
+ }
+
+ /* direct configuration from device tree */
+ for (x = 0; x < cfg_size; x += 3) {
+ regInfo = (struct max98927_reg_default *)&max98927->regcfg[x];
+ dev_info(codec->dev, "CH:%d, reg:0x%02x, value:0x%02x\n",
+ be32_to_cpu(regInfo->ch),
+ be32_to_cpu(regInfo->reg),
+ be32_to_cpu(regInfo->def));
+ if (be32_to_cpu(regInfo->ch) == PRI_MAX98927
+ && max98927->regmap)
+ regmap_write(max98927->regmap,
+ be32_to_cpu(regInfo->reg),
+ be32_to_cpu(regInfo->def));
+ else if (be32_to_cpu(regInfo->ch) == SEC_MAX98927
+ && max98927->sub_regmap)
+ regmap_write(max98927->sub_regmap,
+ be32_to_cpu(regInfo->reg),
+ be32_to_cpu(regInfo->def));
+ }
+}
+
+static int max98927_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ max98927_wrap_update_bits(max98927,
+ MAX98927_AMP_enables, 1, 1);
+ /* enable the v and i for vi feedback */
+ max98927_wrap_update_bits(max98927,
+ MAX98927_Measurement_enables,
+ MAX98927_Measurement_enables_IVADC_V_EN,
+ MAX98927_Measurement_enables_IVADC_V_EN);
+ max98927_wrap_update_bits(max98927,
+ MAX98927_Measurement_enables,
+ MAX98927_Measurement_enables_IVADC_I_EN,
+ MAX98927_Measurement_enables_IVADC_I_EN);
+ max98927_wrap_update_bits(max98927,
+ MAX98927_Global_Enable, 1, 1);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ max98927_wrap_update_bits(max98927,
+ MAX98927_Global_Enable, 1, 0);
+ max98927_wrap_update_bits(max98927,
+ MAX98927_AMP_enables, 1, 0);
+ /* disable the v and i for vi feedback */
+ max98927_wrap_update_bits(max98927,
+ MAX98927_Measurement_enables,
+ MAX98927_Measurement_enables_IVADC_V_EN,
+ 0);
+ max98927_wrap_update_bits(max98927,
+ MAX98927_Measurement_enables,
+ MAX98927_Measurement_enables_IVADC_I_EN,
+ 0);
+ break;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_AMP_enables,
+ 0, 0, max98927_dac_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_OUTPUT("BE_OUT"),
+};
+
+static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
+static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
+
+static int max98927_spk_gain_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = max98927->spk_gain;
+ dev_dbg(codec->dev, "%s: spk_gain setting returned %d\n", __func__,
+ (int) ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int max98927_spk_gain_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ unsigned int sel = ucontrol->value.integer.value[0];
+
+ if (sel < ((1 << MAX98927_Speaker_Gain_Width) - 1)) {
+ max98927_wrap_update_bits(max98927, MAX98927_Speaker_Gain,
+ MAX98927_Speaker_Gain_SPK_PCM_GAIN_Mask, sel);
+ max98927->spk_gain = sel;
+ }
+ return 0;
+}
+
+static int max98927_digital_gain_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = max98927->digital_gain;
+ dev_dbg(codec->dev, "%s: spk_gain setting returned %d\n", __func__,
+ (int) ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int max98927_digital_gain_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ unsigned int sel = ucontrol->value.integer.value[0];
+
+ if (sel < ((1 << MAX98927_AMP_VOL_WIDTH) - 1)) {
+ max98927_wrap_update_bits(max98927, MAX98927_AMP_volume_control,
+ MAX98927_AMP_volume_control_AMP_VOL_Mask, sel);
+ max98927->digital_gain = sel;
+ }
+ return 0;
+}
+
+static int max98927_boost_voltage_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_get(kcontrol, ucontrol, MAX98927_Boost_Control_0,
+ MAX98927_Boost_Control_0_BST_VOUT_Mask, 0);
+}
+
+static int max98927_boost_voltage_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_put(kcontrol, ucontrol, MAX98927_Boost_Control_0,
+ MAX98927_Boost_Control_0_BST_VOUT_Mask, 0);
+}
+
+static int max98927_amp_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_get(kcontrol, ucontrol, MAX98927_Boost_Control_0,
+ MAX98927_Boost_Control_0_BST_VOUT_Mask,
+ MAX98927_AMP_VOL_LOCATION_SHIFT);
+}
+
+static int max98927_amp_dsp_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_put(kcontrol, ucontrol, MAX98927_Brownout_enables,
+ MAX98927_Brownout_enables_AMP_DSP_EN, MAX98927_BDE_DSP_SHIFT);
+}
+
+static int max98927_amp_dsp_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_get(kcontrol, ucontrol, MAX98927_Brownout_enables,
+ MAX98927_Brownout_enables_AMP_DSP_EN, MAX98927_BDE_DSP_SHIFT);
+}
+
+static int max98927_ramp_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_put(kcontrol, ucontrol, MAX98927_AMP_DSP_Config,
+ MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS,
+ MAX98927_SPK_RMP_EN_SHIFT);
+}
+static int max98927_ramp_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_get(kcontrol, ucontrol, MAX98927_AMP_DSP_Config,
+ MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS,
+ MAX98927_SPK_RMP_EN_SHIFT);
+}
+
+static int max98927_dre_en_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_put(kcontrol, ucontrol, MAX98927_DRE_Control,
+ MAX98927_DRE_Control_DRE_EN, 0);
+}
+static int max98927_dre_en_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_get(kcontrol, ucontrol, MAX98927_DRE_Control,
+ MAX98927_DRE_Control_DRE_EN, 0);
+}
+static int max98927_amp_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_put(kcontrol, ucontrol,
+ MAX98927_AMP_volume_control,
+ MAX98927_AMP_volume_control_AMP_VOL_SEL,
+ MAX98927_AMP_VOL_LOCATION_SHIFT);
+}
+static int max98927_spk_src_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_get(kcontrol, ucontrol,
+ MAX98927_Speaker_source_select,
+ MAX98927_Speaker_source_select_SPK_SOURCE_Mask, 0);
+}
+
+static int max98927_spk_src_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_put(kcontrol, ucontrol,
+ MAX98927_Speaker_source_select,
+ MAX98927_Speaker_source_select_SPK_SOURCE_Mask, 0);
+}
+
+static int max98927_mono_out_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_get(kcontrol, ucontrol,
+ MAX98927_PCM_to_speaker_monomix_A,
+ MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask,
+ MAX98927_PCM_to_speaker_monomix_A_SHIFT);
+}
+
+static int max98927_mono_out_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return max98927_reg_put(kcontrol, ucontrol,
+ MAX98927_PCM_to_speaker_monomix_A,
+ MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask,
+ MAX98927_PCM_to_speaker_monomix_A_SHIFT);
+}
+
+static bool max98927_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case 0x0001 ... 0x0028:
+ case 0x002B ... 0x004E:
+ case 0x0051 ... 0x0055:
+ case 0x005A ... 0x0061:
+ case 0x0072 ... 0x0087:
+ case 0x00FF:
+ case 0x0100:
+ case 0x01FF:
+ return true;
+ }
+ return false;
+};
+
+static const char * const max98927_boost_voltage_text[] = {
+ "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
+ "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
+ "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
+ "9.5V", "9.625V", "9.75V", "9.875V", "10V"
+};
+
+static const char * const max98927_speaker_source_text[] = {
+ "i2s", "reserved", "tone", "pdm"
+};
+
+static const char * const max98927_monomix_output_text[] = {
+ "ch_0", "ch_1", "ch_1_2_div"
+};
+
+static const struct soc_enum max98927_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_monomix_output_text),
+ max98927_monomix_output_text),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_speaker_source_text),
+ max98927_speaker_source_text),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_boost_voltage_text),
+ max98927_boost_voltage_text),
+};
+
+static const struct snd_kcontrol_new max98927_snd_controls[] = {
+ SOC_SINGLE_EXT_TLV("Speaker Volume", MAX98927_Speaker_Gain,
+ 0, (1<<MAX98927_Speaker_Gain_Width)-1, 0,
+ max98927_spk_gain_get, max98927_spk_gain_put,
+ max98927_spk_tlv),
+ SOC_SINGLE_EXT_TLV("Digital Gain", MAX98927_AMP_volume_control,
+ 0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
+ max98927_digital_gain_get, max98927_digital_gain_put,
+ max98927_digital_tlv),
+ SOC_SINGLE_EXT("Amp DSP Enable", MAX98927_Brownout_enables,
+ MAX98927_BDE_DSP_SHIFT, 1, 0,
+ max98927_amp_dsp_get, max98927_amp_dsp_put),
+ SOC_SINGLE_EXT("Ramp Switch", MAX98927_AMP_DSP_Config,
+ MAX98927_SPK_RMP_EN_SHIFT, 1, 1,
+ max98927_ramp_switch_get, max98927_ramp_switch_put),
+ SOC_SINGLE_EXT("DRE EN", MAX98927_DRE_Control,
+ MAX98927_DRE_Control_DRE_SHIFT, 1, 0,
+ max98927_dre_en_get, max98927_dre_en_put),
+ SOC_SINGLE_EXT("Amp Volume Location", MAX98927_AMP_volume_control,
+ MAX98927_AMP_VOL_LOCATION_SHIFT, 1, 0,
+ max98927_amp_vol_get, max98927_amp_vol_put),
+
+ SOC_ENUM_EXT("Boost Output Voltage", max98927_enum[2],
+ max98927_boost_voltage_get, max98927_boost_voltage_put),
+ SOC_ENUM_EXT("Speaker Source", max98927_enum[1],
+ max98927_spk_src_get, max98927_spk_src_put),
+ SOC_ENUM_EXT("Monomix Output", max98927_enum[0],
+ max98927_mono_out_get, max98927_mono_out_put),
+};
+
+static const struct snd_soc_dapm_route max98927_audio_map[] = {
+ {"BE_OUT", NULL, "Amp Enable"},
+};
+
+static struct snd_soc_dai_driver max98927_dai[] = {
+ {
+ .name = "max98927-aif1",
+ .playback = {
+ .stream_name = "HiFi Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MAX98927_RATES,
+ .formats = MAX98927_FORMATS,
+ },
+ .capture = {
+ .stream_name = "HiFi Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MAX98927_RATES,
+ .formats = MAX98927_FORMATS,
+ },
+ .ops = &max98927_dai_ops,
+ }
+};
+
+static int max98927_probe(struct snd_soc_codec *codec)
+{
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0, reg = 0, i;
+
+ max98927->codec = codec;
+ codec->control_data = max98927->regmap;
+ codec->cache_bypass = 1;
+
+ /* Software Reset */
+ max98927_wrapper_write(max98927,
+ MAX98927_Software_Reset, MAX98927_Software_Reset_RST);
+
+ /* Check Revision ID for the primary MAX98927*/
+ ret = regmap_read(max98927->regmap, MAX98927_REV_ID, ®);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "Failed to read: 0x%02X\n", MAX98927_REV_ID);
+ else
+ dev_info(codec->dev,
+ "MAX98927 revisionID: 0x%02X\n", reg);
+
+ /* Check Revision ID for the secondary MAX98927*/
+ if (max98927->sub_regmap) {
+ ret = regmap_read(max98927->sub_regmap, MAX98927_REV_ID, ®);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "Failed to read: 0x%02X from secodnary device\n"
+ , MAX98927_REV_ID);
+ else
+ dev_info(codec->dev,
+ "Secondary device revisionID: 0x%02X\n", reg);
+ }
+
+ /* Register initialization */
+ for (i = 0; i < sizeof(max98927_reg_map)/
+ sizeof(max98927_reg_map[0]); i++)
+ max98927_wrapper_write(max98927,
+ max98927_reg_map[i].reg,
+ max98927_reg_map[i].def);
+
+ if (max98927->regmap)
+ regmap_write(max98927->regmap,
+ MAX98927_PCM_Tx_Channel_Sources_A,
+ (max98927->i_l_slot
+ <<MAX98927_PCM_Tx_Ch_Sources_A_I_SHIFT|
+ max98927->v_l_slot)&0xFF);
+ if (max98927->sub_regmap)
+ regmap_write(max98927->sub_regmap,
+ MAX98927_PCM_Tx_Channel_Sources_A,
+ (max98927->i_r_slot
+ <<MAX98927_PCM_Tx_Ch_Sources_A_I_SHIFT|
+ max98927->v_r_slot)&0xFF);
+
+ /* Set interleave mode */
+ if (max98927->interleave_mode)
+ max98927_wrap_update_bits(max98927,
+ MAX98927_PCM_Tx_Channel_Sources_B,
+ MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask,
+ MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask);
+
+ max98927_handle_pdata(codec);
+
+ return ret;
+}
+
+static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
+ .probe = max98927_probe,
+ .dapm_routes = max98927_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
+ .dapm_widgets = max98927_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
+ .controls = max98927_snd_controls,
+ .num_controls = ARRAY_SIZE(max98927_snd_controls),
+};
+
+static const struct regmap_config max98927_regmap = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = MAX98927_REV_ID,
+ .reg_defaults = max98927_reg_map,
+ .num_reg_defaults = ARRAY_SIZE(max98927_reg_map),
+ .readable_reg = max98927_readable_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static struct i2c_board_info max98927_i2c_sub_board[] = {
+ {
+ I2C_BOARD_INFO("max98927_sub", 0x39),
+ }
+};
+
+static struct i2c_driver max98927_i2c_sub_driver = {
+ .driver = {
+ .name = "max98927_sub",
+ .owner = THIS_MODULE,
+ },
+};
+
+struct i2c_client *max98927_add_sub_device(int bus_id, int slave_addr)
+{
+ struct i2c_client *i2c = NULL;
+ struct i2c_adapter *adapter;
+
+ max98927_i2c_sub_board[0].addr = slave_addr;
+
+ adapter = i2c_get_adapter(bus_id);
+ if (adapter) {
+ i2c = i2c_new_device(adapter, max98927_i2c_sub_board);
+ if (i2c)
+ i2c->dev.driver = &max98927_i2c_sub_driver.driver;
+ }
+
+ return i2c;
+}
+
+int probe_common(struct i2c_client *i2c, struct max98927_priv *max98927)
+{
+ int ret = 0, value;
+
+ if (!of_property_read_u32(i2c->dev.of_node, "vmon-l-slot", &value))
+ max98927->v_l_slot = value & 0xF;
+ else
+ max98927->v_l_slot = 0;
+ if (!of_property_read_u32(i2c->dev.of_node, "imon-l-slot", &value))
+ max98927->i_l_slot = value & 0xF;
+ else
+ max98927->i_l_slot = 1;
+ if (!of_property_read_u32(i2c->dev.of_node, "vmon-r-slot", &value))
+ max98927->v_r_slot = value & 0xF;
+ else
+ max98927->v_r_slot = 2;
+ if (!of_property_read_u32(i2c->dev.of_node, "imon-r-slot", &value))
+ max98927->i_r_slot = value & 0xF;
+ else
+ max98927->i_r_slot = 3;
+
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
+ max98927_dai, ARRAY_SIZE(max98927_dai));
+ if (ret < 0)
+ dev_err(&i2c->dev,
+ "Failed to register codec: %d\n", ret);
+ return ret;
+}
+
+static int max98927_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+
+ int ret = 0, value;
+ struct max98927_priv *max98927 = NULL;
+
+ max98927 = devm_kzalloc(&i2c->dev,
+ sizeof(*max98927), GFP_KERNEL);
+
+ if (!max98927) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ i2c_set_clientdata(i2c, max98927);
+
+ /* update interleave mode info */
+ if (!of_property_read_u32(i2c->dev.of_node,
+ "interleave_mode", &value)) {
+ if (value > 0)
+ max98927->interleave_mode = 1;
+ else
+ max98927->interleave_mode = 0;
+ } else
+ max98927->interleave_mode = 0;
+
+ /* update direct configuration info */
+ max98927->regcfg = of_get_property(i2c->dev.of_node,
+ "maxim,regcfg", &max98927->regcfg_sz);
+
+ /* check for secondary MAX98927 */
+ ret = of_property_read_u32(i2c->dev.of_node,
+ "maxim,sub_reg", &max98927->sub_reg);
+ if (ret) {
+ dev_err(&i2c->dev, "Sub-device slave address was not found.\n");
+ max98927->sub_reg = -1;
+ }
+ ret = of_property_read_u32(i2c->dev.of_node,
+ "maxim,sub_bus", &max98927->sub_bus);
+ if (ret) {
+ dev_err(&i2c->dev, "Sub-device bus information was not found.\n");
+ max98927->sub_bus = i2c->adapter->nr;
+ }
+
+ /* regmap initialization for primary device */
+ max98927->regmap
+ = devm_regmap_init_i2c(i2c, &max98927_regmap);
+ if (IS_ERR(max98927->regmap)) {
+ ret = PTR_ERR(max98927->regmap);
+ dev_err(&i2c->dev,
+ "Failed to allocate regmap: %d\n", ret);
+ goto err;
+ }
+
+ /* regmap initialization for secondary device */
+ if (max98927->sub_reg > 0) {
+ max98927->sub_i2c = max98927_add_sub_device(max98927->sub_bus,
+ max98927->sub_reg);
+ if (IS_ERR(max98927->sub_i2c)) {
+ dev_err(&max98927->sub_i2c->dev,
+ "Second MAX98927 was not found\n");
+ ret = PTR_ERR(max98927->regmap);
+ goto err;
+ } else {
+ max98927->sub_regmap = regmap_init_i2c(
+ max98927->sub_i2c, &max98927_regmap);
+ if (IS_ERR(max98927->sub_regmap)) {
+ ret = PTR_ERR(max98927->sub_regmap);
+ dev_err(&max98927->sub_i2c->dev,
+ "Failed to allocate sub_regmap: %d\n",
+ ret);
+ goto err;
+ }
+ }
+ }
+
+ /* codec registeration */
+ ret = probe_common(i2c, max98927);
+
+ return ret;
+
+err:
+ if (max98927)
+ devm_kfree(&i2c->dev, max98927);
+ return ret;
+}
+
+static int max98927_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ return 0;
+}
+
+static const struct i2c_device_id max98927_i2c_id[] = {
+ { "max98927", 0},
+ { },
+};
+
+MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
+
+static const struct of_device_id max98927_of_match[] = {
+ { .compatible = "maxim,max98927", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max98927_of_match);
+
+static struct i2c_driver max98927_i2c_driver = {
+ .driver = {
+ .name = "max98927",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(max98927_of_match),
+ .pm = NULL,
+ },
+ .probe = max98927_i2c_probe,
+ .remove = max98927_i2c_remove,
+ .id_table = max98927_i2c_id,
+};
+
+module_i2c_driver(max98927_i2c_driver)
+
+MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
+MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
new file mode 100755
index 0000000..2305185
--- /dev/null
+++ b/sound/soc/codecs/max98927.h
@@ -0,0 +1,1253 @@
+/*
+ * max98927.c -- MAX98927 ALSA Soc Audio driver
+ *
+ * Copyright 2008-11 Wolfson Microelectronics PLC.
+ * Author: Ryan Lee <ryans.lee@maximintegrated.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef __MAX98927_REGISTERDEFS_H
+#define __MAX98927_REGISTERDEFS_H
+#ifdef CONFIG_SND_SOC_MAXIM_DSM
+#include <sound/maxim_dsm.h>
+#endif /* CONFIG_SND_SOC_MAXIM_DSM */
+
+enum {
+ PRI_MAX98927 = 0,
+ SEC_MAX98927 = 1,
+ MAX_DEV_ID_MAX98927,
+} MAX98927deviceID;
+
+enum {
+ /*Interrupt Raw 1 (Address 0x0001)*/
+ MAX98927_Interrupt_Raw_1 = 0x0001,
+ MAX98927_Interrupt_Raw_1_BDE_ACTIVE_END_RAW = (0x1 << 0),
+ MAX98927_Interrupt_Raw_1_BDE_ACTIVE_BGN_RAW = (0x1 << 1),
+ MAX98927_Interrupt_Raw_1_BDE_LEVEL_CHANGE_RAW = (0x1 << 2),
+ MAX98927_Interrupt_Raw_1_BDE_L8_RAW = (0x1 << 3),
+ MAX98927_Interrupt_Raw_1_THERMWARN_END_RAW = (0x1 << 4),
+ MAX98927_Interrupt_Raw_1_THERMWARN_START_RAW = (0x1 << 5),
+ MAX98927_Interrupt_Raw_1_THERMSHDN_END_RAW = (0x1 << 6),
+ MAX98927_Interrupt_Raw_1_THERMSHDN_START_RAW = (0x1 << 7),
+
+ /* Interrupt Raw 2 (Address 0x0002)*/
+ MAX98927_Interrupt_Raw_2 = 0x0002,
+ MAX98927_Interrupt_Raw_2_WATCHDOGWARN_RAW = (0x1 << 0),
+ MAX98927_Interrupt_Raw_2_WATCHDOGFAIL_RAW = (0x1 << 1),
+ MAX98927_Interrupt_Raw_2_BOOSTCURRLIM_RAW = (0x1 << 2),
+ MAX98927_Interrupt_Raw_2_CLKSTOP_RAW = (0x1 << 3),
+ MAX98927_Interrupt_Raw_2_CLKSTART_RAW = (0x1 << 4),
+ MAX98927_Interrupt_Raw_2_MEASADC_END_RAW = (0x1 << 5),
+ MAX98927_Interrupt_Raw_2_PWRDN_DONE_RAW = (0x1 << 6),
+ MAX98927_Interrupt_Raw_2_PWRUP_DONE_RAW = (0x1 << 7),
+
+ /* Interrupt Raw 3 (Address 0x0003)*/
+ MAX98927_Interrupt_Raw_3 = 0x0003,
+ MAX98927_Interrupt_Raw_3_PWRUP_FAIL_RAW = (0x1 << 0),
+ MAX98927_Interrupt_Raw_3_AUTH_DONE_RAW = (0x1 << 1),
+ MAX98927_Interrupt_Raw_3_SPK_OVC_RAW = (0x1 << 2),
+ MAX98927_Interrupt_Raw_3_BST_UVLO_RAW = (0x1 << 3),
+
+ /* Interrupt State 1 (Address 0x0004)*/
+ MAX98927_Interrupt_State_1 = 0x0004,
+ MAX98927_Interrupt_State_1_BDE_ACTIVE_END_STATE = (0x1 << 0),
+ MAX98927_Interrupt_State_1_BDE_ACTIVE_BGN_STATE = (0x1 << 1),
+ MAX98927_Interrupt_State_1_BDE_LEVEL_CHANGE_STATE = (0x1 << 2),
+ MAX98927_Interrupt_State_1_BDE_L8_STATE = (0x1 << 3),
+ MAX98927_Interrupt_State_1_THERMWARN_END_STATE = (0x1 << 4),
+ MAX98927_Interrupt_State_1_THERMWARN_START_STATE = (0x1 << 5),
+ MAX98927_Interrupt_State_1_THERMSHDN_END_STATE = (0x1 << 6),
+ MAX98927_Interrupt_State_1_THERMSHDN_START_STATE = (0x1 << 7),
+
+ /* Interrupt State 2 (Address 0x0005)*/
+ MAX98927_Interrupt_State_2 = 0x0005,
+ MAX98927_Interrupt_State_2_WATCHDOGWARN_STATE = (0x1 << 0),
+ MAX98927_Interrupt_State_2_WATCHDOGFAIL_STATE = (0x1 << 1),
+ MAX98927_Interrupt_State_2_BOOSTCURRLIM_STATE = (0x1 << 2),
+ MAX98927_Interrupt_State_2_CLKSTOP_STATE = (0x1 << 3),
+ MAX98927_Interrupt_State_2_CLKSTART_STATE = (0x1 << 4),
+ MAX98927_Interrupt_State_2_MEASADC_END_STATE = (0x1 << 5),
+ MAX98927_Interrupt_State_2_PWRDN_DONE_STATE = (0x1 << 6),
+ MAX98927_Interrupt_State_2_PWRUP_DONE_STATE = (0x1 << 7),
+
+ /* Interrupt State 3 (Address 0x0006)*/
+ MAX98927_Interrupt_State_3 = 0x0006,
+ MAX98927_Interrupt_State_3_PWRUP_FAIL_STATE = (0x1 << 0),
+ MAX98927_Interrupt_State_3_AUTH_DONE_STATE = (0x1 << 1),
+ MAX98927_Interrupt_State_3_SPK_OVC_STATE = (0x1 << 2),
+ MAX98927_Interrupt_State_3_BST_UVLO_STATE = (0x1 << 3),
+
+ /* Interrupt Flag 1 (Address 0x0007)*/
+ MAX98927_Interrupt_Flag_1 = 0x0007,
+ MAX98927_Interrupt_Flag_1_BDE_ACTIVE_END_FLAG = (0x1 << 0),
+ MAX98927_Interrupt_Flag_1_BDE_ACTIVE_BGN_FLAG = (0x1 << 1),
+ MAX98927_Interrupt_Flag_1_BDE_LEVEL_CHANGE_FLAG = (0x1 << 2),
+ MAX98927_Interrupt_Flag_1_BDE_L8_FLAG = (0x1 << 3),
+ MAX98927_Interrupt_Flag_1_THERMWARN_END_FLAG = (0x1 << 4),
+ MAX98927_Interrupt_Flag_1_THERMWARN_START_FLAG = (0x1 << 5),
+ MAX98927_Interrupt_Flag_1_THERMSHDN_END_FLAG = (0x1 << 6),
+ MAX98927_Interrupt_Flag_1_THERMSHDN_START_FLAG = (0x1 << 7),
+
+ /* Interrupt Flag 2 (Address 0x0008)*/
+ MAX98927_Interrupt_Flag_2 = 0x0008,
+ MAX98927_Interrupt_Flag_2_WATCHDOGWARN_FLAG = (0x1 << 0),
+ MAX98927_Interrupt_Flag_2_WATCHDOGFAIL_FLAG = (0x1 << 1),
+ MAX98927_Interrupt_Flag_2_BOOSTCURRLIM_FLAG = (0x1 << 2),
+ MAX98927_Interrupt_Flag_2_CLKSTOP_FLAG = (0x1 << 3),
+ MAX98927_Interrupt_Flag_2_CLKSTART_FLAG = (0x1 << 4),
+ MAX98927_Interrupt_Flag_2_MEASADC_END_FLAG = (0x1 << 5),
+ MAX98927_Interrupt_Flag_2_PWRDN_DONE_FLAG = (0x1 << 6),
+ MAX98927_Interrupt_Flag_2_PWRUP_DONE_FLAG = (0x1 << 7),
+
+ /* Interrupt Flag 3 (Address 0x0009)*/
+ MAX98927_Interrupt_Flag_3 = 0x0009,
+ MAX98927_Interrupt_Flag_3_PWRUP_FAIL_FLAG = (0x1 << 0),
+ MAX98927_Interrupt_Flag_3_AUTH_DONE_FLAG = (0x1 << 1),
+ MAX98927_Interrupt_Flag_3_SPK_OVC_FLAG = (0x1 << 2),
+ MAX98927_Interrupt_Flag_3_BST_UVLO_FLAG = (0x1 << 3),
+
+ /* Interrupt Enable 1 (Address 0x000a)*/
+ MAX98927_Interrupt_Enable_1 = 0x000a,
+ MAX98927_Interrupt_Enable_1_BDE_ACTIVE_END_EN = (0x1 << 0),
+ MAX98927_Interrupt_Enable_1_BDE_ACTIVE_BGN_EN = (0x1 << 1),
+ MAX98927_Interrupt_Enable_1_BDE_LEVEL_CHANGE_EN = (0x1 << 2),
+ MAX98927_Interrupt_Enable_1_BDE_L8_EN = (0x1 << 3),
+ MAX98927_Interrupt_Enable_1_THERMWARN_END_EN = (0x1 << 4),
+ MAX98927_Interrupt_Enable_1_THERMWARN_START_EN = (0x1 << 5),
+ MAX98927_Interrupt_Enable_1_THERMSHDN_END_EN = (0x1 << 6),
+ MAX98927_Interrupt_Enable_1_THERMSHDN_START_EN = (0x1 << 7),
+
+ /* Interrupt Enable 2 (Address 0x000b)*/
+ MAX98927_Interrupt_Enable_2 = 0x000b,
+ MAX98927_Interrupt_Enable_2_WATCHDOGWARN_EN = (0x1 << 0),
+ MAX98927_Interrupt_Enable_2_WATCHDOGFAIL_EN = (0x1 << 1),
+ MAX98927_Interrupt_Enable_2_BOOSTCURRLIM_EN = (0x1 << 2),
+ MAX98927_Interrupt_Enable_2_CLKSTOP_EN = (0x1 << 3),
+ MAX98927_Interrupt_Enable_2_CLKSTART_EN = (0x1 << 4),
+ MAX98927_Interrupt_Enable_2_MEASADC_END_EN = (0x1 << 5),
+ MAX98927_Interrupt_Enable_2_PWRDN_DONE_EN = (0x1 << 6),
+ MAX98927_Interrupt_Enable_2_PWRUP_DONE_EN = (0x1 << 7),
+
+ /* Interrupt Enable 3 (Address 0x000c)*/
+ MAX98927_Interrupt_Enable_3 = 0x000c,
+ MAX98927_Interrupt_Enable_3_PWRUP_FAIL_EN = (0x1 << 0),
+ MAX98927_Interrupt_Enable_3_AUTH_DONE_EN = (0x1 << 1),
+ MAX98927_Interrupt_Enable_3_SPK_OVC_EN = (0x1 << 2),
+ MAX98927_Interrupt_Enable_3_BST_UVLO_EN = (0x1 << 3),
+
+ /* Interrupt Flag Clear 1 (Address 0x000d)*/
+ MAX98927_Interrupt_Flag_Clear_1 = 0x000d,
+ MAX98927_Interrupt_Flag_Clear_1_BDE_ACTIVE_END_CLR = (0x1 << 0),
+ MAX98927_Interrupt_Flag_Clear_1_BDE_ACTIVE_BGN_CLR = (0x1 << 1),
+ MAX98927_Interrupt_Flag_Clear_1_BDE_LEVEL_CHANGE_CLR = (0x1 << 2),
+ MAX98927_Interrupt_Flag_Clear_1_BDE_L8_CLR = (0x1 << 3),
+ MAX98927_Interrupt_Flag_Clear_1_THERMWARN_END_CLR = (0x1 << 4),
+ MAX98927_Interrupt_Flag_Clear_1_THERMWARN_START_CLR = (0x1 << 5),
+ MAX98927_Interrupt_Flag_Clear_1_THERMSHDN_END_CLR = (0x1 << 6),
+ MAX98927_Interrupt_Flag_Clear_1_THERMSHDN_START_CLR = (0x1 << 7),
+
+ /* Interrupt Flag Clear 2 (Address 0x000e)*/
+ MAX98927_Interrupt_Flag_Clear_2 = 0x000e,
+ MAX98927_Interrupt_Flag_Clear_2_WATCHDOGWARN_CLR = (0x1 << 0),
+ MAX98927_Interrupt_Flag_Clear_2_WATCHDOGFAIL_CLR = (0x1 << 1),
+ MAX98927_Interrupt_Flag_Clear_2_BOOSTCURRLIM_CLR = (0x1 << 2),
+ MAX98927_Interrupt_Flag_Clear_2_CLKSTOP_CLR = (0x1 << 3),
+ MAX98927_Interrupt_Flag_Clear_2_CLKSTART_CLR = (0x1 << 4),
+ MAX98927_Interrupt_Flag_Clear_2_MEASADC_END_CLR = (0x1 << 5),
+ MAX98927_Interrupt_Flag_Clear_2_PWRDN_DONE_CLR = (0x1 << 6),
+ MAX98927_Interrupt_Flag_Clear_2_PWRUP_DONE_CLR = (0x1 << 7),
+
+ /* Interrupt Flag Clear 3 (Address 0x000f)*/
+ MAX98927_Interrupt_Flag_Clear_3 = 0x000f,
+ MAX98927_Interrupt_Flag_Clear_3_PWRUP_FAIL_CLR = (0x1 << 0),
+ MAX98927_Interrupt_Flag_Clear_3_AUTH_DONE_CLR = (0x1 << 1),
+ MAX98927_Interrupt_Flag_Clear_3_SPK_OVC_CLR = (0x1 << 2),
+ MAX98927_Interrupt_Flag_Clear_3_BST_UVLO_CLR = (0x1 << 3),
+
+ /* IRQ Control (Address 0x0010)*/
+ MAX98927_IRQ_Control = 0x0010,
+ MAX98927_IRQ_Control_IRQ_EN = (0x1 << 0),
+ MAX98927_IRQ_Control_IRQ_POL = (0x1 << 1),
+ MAX98927_IRQ_Control_IRQ_MODE = (0x1 << 2),
+
+ /* Clock monitor enable (Address 0x0011)*/
+ MAX98927_Clock_monitor_enable = 0x0011,
+ MAX98927_Clock_monitor_enable_CMON_ENA = (0x1 << 0),
+ MAX98927_Clock_monitor_enable_CMON_AUTORESTART_ENA = (0x1 << 1),
+
+ /* Watchdog Control (Address 0x0012)*/
+ MAX98927_Watchdog_Control = 0x0012,
+ MAX98927_Watchdog_Control_WDT_ENA = (0x1 << 0),
+ MAX98927_Watchdog_Control_WDT_MODE = (0x1 << 1),
+ MAX98927_Watchdog_Control_WDT_TO_SEL_Mask = (0x3 << 2),
+ MAX98927_Watchdog_Control_WDT_TO_SEL_5 = (0x0 << 2),
+ MAX98927_Watchdog_Control_WDT_TO_SEL_10 = (0x1 << 2),
+ MAX98927_Watchdog_Control_WDT_TO_SEL_35 = (0x2 << 2),
+ MAX98927_Watchdog_Control_WDT_TO_SEL_50 = (0x3 << 2),
+ MAX98927_Watchdog_Control_WDT_HW_SOURCE = (0x1 << 4),
+
+ /* Watchdog SW Reset (Address 0x0013)*/
+ MAX98927_Watchdog_SW_Reset = 0x0013,
+ MAX98927_Watchdog_SW_Reset_WDT_SW_RST_Mask = (0xff << 0),
+
+ /* Meas ADC Thermal Warning Threshhold (Address 0x0014)*/
+ MAX98927_Meas_ADC_TW_Threshhold = 0x0014,
+ MAX98927_Meas_ADC_TW_Threshhold_MEAS_ADC_WARN_THRESH_Mask
+ = (0xff << 0),
+
+ /* Meas ADC Thermal Shutdown Threshhold (Address 0x0015)*/
+ MAX98927_Meas_ADC_TS_Threshhold = 0x0015,
+ MAX98927_Meas_ADC_TS_Threshhold_MEAS_ADC_SHDN_THRESH_Mask
+ = (0xff << 0),
+
+ /* Meas ADC Thermal Hysteresis (Address 0x0016)*/
+ MAX98927_Meas_ADC_Thermal_Hysteresis = 0x0016,
+ MAX98927_Meas_ADC_TH_MEAS_ADC_THERM_HYST_Mask = (0x1f << 0),
+
+ /* Pin Config (Address 0x0017)*/
+ MAX98927_Pin_Config = 0x0017,
+ MAX98927_Pin_Config_DOUT_DRV_Mask = (0x3 << 0),
+ MAX98927_Pin_Config_DOUT_DRV_01 = (0x0 << 0),
+ MAX98927_Pin_Config_DOUT_DRV_11 = (0x2 << 0),
+ MAX98927_Pin_Config_BCLK_DRV_Mask = (0x3 << 2),
+ MAX98927_Pin_Config_BCLK_DRV_01 = (0x0 << 2),
+ MAX98927_Pin_Config_BCLK_DRV_11 = (0x2 << 2),
+ MAX98927_Pin_Config_LRCLK_DRV_Mask = (0x3 << 4),
+ MAX98927_Pin_Config_LRCLK_DRV_01 = (0x0 << 4),
+ MAX98927_Pin_Config_LRCLK_DRV_11 = (0x2 << 4),
+ MAX98927_Pin_Config_ICC_DRV_Mask = (0x3 << 6),
+ MAX98927_Pin_Config_ICC_DRV_01 = (0x0 << 6),
+ MAX98927_Pin_Config_ICC_DRV_11 = (0x2 << 6),
+
+ /* PCM Rx Enables A (Address 0x0018)*/
+ MAX98927_PCM_Rx_Enables_A = 0x0018,
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH0_EN = (0x1 << 0),
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH1_EN = (0x1 << 1),
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH2_EN = (0x1 << 2),
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH3_EN = (0x1 << 3),
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH4_EN = (0x1 << 4),
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH5_EN = (0x1 << 5),
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH6_EN = (0x1 << 6),
+ MAX98927_PCM_Rx_Enables_A_PCM_RX_CH7_EN = (0x1 << 7),
+
+ /* PCM Rx Enables B (Address 0x0019)*/
+ MAX98927_PCM_Rx_Enables_B = 0x0019,
+ MAX98927_PCM_Rx_Enables_B_PCM_RX_CH8_EN = (0x1 << 0),
+ MAX98927_PCM_Rx_Enables_B_PCM_RX_CH9_EN = (0x1 << 1),
+ MAX98927_PCM_Rx_Enables_B_PCM_RX_CH10_EN = (0x1 << 2),
+ MAX98927_PCM_Rx_Enables_B_PCM_RX_CH11_EN = (0x1 << 3),
+ MAX98927_PCM_Rx_Enables_B_PCM_RX_CH12_EN = (0x1 << 4),
+ MAX98927_PCM_Rx_Enables_B_PCM_RX_CH13_EN = (0x1 << 5),
+ MAX98927_PCM_Rx_Enables_B_PCM_RX_CH14_EN = (0x1 << 6),
+ MAX98927_PCM_Rx_Enables_B_PCM_RX_CH15_EN = (0x1 << 7),
+
+ /* PCM Tx Enables A (Address 0x001a)*/
+ MAX98927_PCM_Tx_Enables_A = 0x001a,
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH0_EN = (0x1 << 0),
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH1_EN = (0x1 << 1),
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH2_EN = (0x1 << 2),
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH3_EN = (0x1 << 3),
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH4_EN = (0x1 << 4),
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH5_EN = (0x1 << 5),
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH6_EN = (0x1 << 6),
+ MAX98927_PCM_Tx_Enables_A_PCM_TX_CH7_EN = (0x1 << 7),
+
+ /* PCM Tx Enables B (Address 0x001b)*/
+ MAX98927_PCM_Tx_Enables_B = 0x001b,
+ MAX98927_PCM_Tx_Enables_B_PCM_TX_CH8_EN = (0x1 << 0),
+ MAX98927_PCM_Tx_Enables_B_PCM_TX_CH9_EN = (0x1 << 1),
+ MAX98927_PCM_Tx_Enables_B_PCM_TX_CH10_EN = (0x1 << 2),
+ MAX98927_PCM_Tx_Enables_B_PCM_TX_CH11_EN = (0x1 << 3),
+ MAX98927_PCM_Tx_Enables_B_PCM_TX_CH12_EN = (0x1 << 4),
+ MAX98927_PCM_Tx_Enables_B_PCM_TX_CH13_EN = (0x1 << 5),
+ MAX98927_PCM_Tx_Enables_B_PCM_TX_CH14_EN = (0x1 << 6),
+ MAX98927_PCM_Tx_Enables_B_PCM_TX_CH15_EN = (0x1 << 7),
+
+ /* PCM Tx HiZ Control A (Address 0x001c)*/
+ MAX98927_PCM_Tx_HiZ_Control_A = 0x001c,
+ MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH0_HIZ = (0x1 << 0),
+ MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH1_HIZ = (0x1 << 1),
+ MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH2_HIZ = (0x1 << 2),
+ MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH3_HIZ = (0x1 << 3),
+ MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH4_HIZ = (0x1 << 4),
+ MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH5_HIZ = (0x1 << 5),
+ MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH6_HIZ = (0x1 << 6),
+ MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH7_HIZ = (0x1 << 7),
+
+ /* PCM Tx HiZ Control B (Address 0x001d)*/
+ MAX98927_PCM_Tx_HiZ_Control_B = 0x001d,
+ MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH8_HIZ = (0x1 << 0),
+ MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH9_HIZ = (0x1 << 1),
+ MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH10_HIZ = (0x1 << 2),
+ MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH11_HIZ = (0x1 << 3),
+ MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH12_HIZ = (0x1 << 4),
+ MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH13_HIZ = (0x1 << 5),
+ MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH14_HIZ = (0x1 << 6),
+ MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH15_HIZ = (0x1 << 7),
+
+ /* PCM Tx Channel Sources A (Address 0x001e)*/
+ MAX98927_PCM_Tx_Channel_Sources_A = 0x001e,
+ MAX98927_PCM_Tx_Channel_Sources_A_PCM_IVADC_V_DEST_Mask = (0xf << 0),
+ MAX98927_PCM_Tx_Channel_Sources_A_PCM_IVADC_I_DEST_Mask = (0xf << 4),
+
+ /* PCM Tx Channel Sources B (Address 0x001f)*/
+ MAX98927_PCM_Tx_Channel_Sources_B = 0x001f,
+ MAX98927_PCM_Tx_Channel_Sources_B_PCM_AMP_DSP_DEST_Mask = (0xf << 0),
+ MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask = (0x1 << 5),
+
+ /* PCM Mode Config (Address 0x0020)*/
+ MAX98927_PCM_Mode_Config = 0x0020,
+ MAX98927_PCM_Mode_Config_PCM_TX_EXTRA_HIZ = (0x1 << 0),
+ MAX98927_PCM_Mode_Config_PCM_CHANSEL = (0x1 << 1),
+ MAX98927_PCM_Mode_Config_PCM_BCLKEDGE = (0x1 << 2),
+ MAX98927_PCM_Mode_Config_PCM_FORMAT_Mask = (0x7 << 3),
+ MAX98927_PCM_Mode_Config_PCM_FORMAT_I2S = (0x0 << 3),
+ MAX98927_PCM_Mode_Config_PCM_FORMAT_LEFT = (0x1 << 3),
+ MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_0 = (0x3 << 3),
+ MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_1 = (0x4 << 3),
+ MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_2 = (0x5 << 3),
+ MAX98927_PCM_Mode_Config_PCM_FORMAT_ = (0x6 << 3),
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_Mask = (0x3 << 6),
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_16 = (0x1 << 6),
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_24 = (0x2 << 6),
+ MAX98927_PCM_Mode_Config_PCM_CHANSZ_32 = (0x3 << 6),
+
+ /* PCM Master Mode (Address 0x0021)*/
+ MAX98927_PCM_Master_Mode = 0x0021,
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask = (0x3 << 0),
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_SLAVE = (0x0 << 0),
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_MASTER = (0x3 << 0),
+ MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_HYBRID = (0x1 << 0),
+ MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_Mask = (0xf << 2),
+ MAX98927_PCM_Master_Mode_PCM_CLK_SOURCE = (0x1 << 6),
+
+ /* PCM Clock setup (Address 0x0022)*/
+ MAX98927_PCM_Clock_setup = 0x0022,
+ MAX98927_PCM_Clock_setup_PCM_BSEL_Mask = (0xf << 0),
+ MAX98927_PCM_Clock_setup_PCM_MSEL_Mask = (0xf << 4),
+
+ /* PCM Sample rate setup 1 (Address 0x0023)*/
+ MAX98927_PCM_Sample_rate_setup_1 = 0x0023,
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_Mask = (0xf << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_8000 = (0x0 << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_11025 = (0x1 << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_12000 = (0x2 << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_16000 = (0x3 << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_22050 = (0x4 << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_24000 = (0x5 << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_32000 = (0x6 << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_44100 = (0x7 << 0),
+ MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_48000 = (0x8 << 0),
+
+ /* PCM Sample rate setup 1 (Address 0x0024)*/
+ MAX98927_PCM_Sample_rate_setup_2 = 0x0024,
+ MAX98927_PCM_Sample_rate_setup_2_IVADC_SR_Mask = (0xf << 0),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_Mask = (0xf << 4),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0001 = (0x0 << 4),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0011 = (0x2 << 4),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0101 = (0x4 << 4),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0111 = (0x6 << 4),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1001 = (0x8 << 4),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1011 = (0xa << 4),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1101 = (0xc << 4),
+ MAX98927_PCM_Sample_rate_setup_2_SPK_SR_ = (0xf << 4),
+
+ /* PCM to speaker monomix A (Address 0x0025)*/
+ MAX98927_PCM_to_speaker_monomix_A = 0x0025,
+ MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CH0_SOURCE_Mask = (0xf << 0),
+ MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask = (0x3 << 6),
+ MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_1 = (0x0 << 6),
+ MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_3 = (0x0 << 6),
+
+ /* PCM to speaker monomix B (Address 0x0026)*/
+ MAX98927_PCM_to_spkmonomix_B = 0x0026,
+ MAX98927_PCM_to_spkmonomix_B_DMONOMIX_CH1_SOURCE_Mask = (0xf << 0),
+
+ /* ICC RX Enables A (Address 0x0027)*/
+ MAX98927_ICC_RX_Enables_A = 0x0027,
+ MAX98927_ICC_RX_Enables_A_ICC_RX_CH0_EN = (0x1 << 0),
+ MAX98927_ICC_RX_Enables_A_ICC_RX_CH1_EN = (0x1 << 1),
+ MAX98927_ICC_RX_Enables_A_ICC_RX_CH2_EN = (0x1 << 2),
+ MAX98927_ICC_RX_Enables_A_ICC_RX_CH3_EN = (0x1 << 3),
+ MAX98927_ICC_RX_Enables_A_ICC_RX_CH4_EN = (0x1 << 4),
+ MAX98927_ICC_RX_Enables_A_ICC_RX_CH5_EN = (0x1 << 5),
+ MAX98927_ICC_RX_Enables_A_ICC_RX_CH6_EN = (0x1 << 6),
+ MAX98927_ICC_RX_Enables_A_ICC_RX_CH7_EN = (0x1 << 7),
+
+ /* ICC RX Enables B (Address 0x0028)*/
+ MAX98927_ICC_RX_Enables_B = 0x0028,
+ MAX98927_ICC_RX_Enables_B_ICC_RX_CH8_EN = (0x1 << 0),
+ MAX98927_ICC_RX_Enables_B_ICC_RX_CH9_EN = (0x1 << 1),
+ MAX98927_ICC_RX_Enables_B_ICC_RX_CH10_EN = (0x1 << 2),
+ MAX98927_ICC_RX_Enables_B_ICC_RX_CH11_EN = (0x1 << 3),
+ MAX98927_ICC_RX_Enables_B_ICC_RX_CH12_EN = (0x1 << 4),
+ MAX98927_ICC_RX_Enables_B_ICC_RX_CH13_EN = (0x1 << 5),
+ MAX98927_ICC_RX_Enables_B_ICC_RX_CH14_EN = (0x1 << 6),
+ MAX98927_ICC_RX_Enables_B_ICC_RX_CH15_EN = (0x1 << 7),
+
+ /* ICC TX Enables A (Address 0x002b)*/
+ MAX98927_ICC_TX_Enables_A = 0x002b,
+ MAX98927_ICC_TX_Enables_A_ICC_TX_CH0_EN = (0x1 << 0),
+ MAX98927_ICC_TX_Enables_A_ICC_TX_CH1_EN = (0x1 << 1),
+ MAX98927_ICC_TX_Enables_A_ICC_TX_CH2_EN = (0x1 << 2),
+ MAX98927_ICC_TX_Enables_A_ICC_TX_CH3_EN = (0x1 << 3),
+ MAX98927_ICC_TX_Enables_A_ICC_TX_CH4_EN = (0x1 << 4),
+ MAX98927_ICC_TX_Enables_A_ICC_TX_CH5_EN = (0x1 << 5),
+ MAX98927_ICC_TX_Enables_A_ICC_TX_CH6_EN = (0x1 << 6),
+ MAX98927_ICC_TX_Enables_A_ICC_TX_CH7_EN = (0x1 << 7),
+
+ /* ICC TX Enables B (Address 0x002c)*/
+ MAX98927_ICC_TX_Enables_B = 0x002c,
+ MAX98927_ICC_TX_Enables_B_ICC_TX_CH8_EN = (0x1 << 0),
+ MAX98927_ICC_TX_Enables_B_ICC_TX_CH9_EN = (0x1 << 1),
+ MAX98927_ICC_TX_Enables_B_ICC_TX_CH10_EN = (0x1 << 2),
+ MAX98927_ICC_TX_Enables_B_ICC_TX_CH11_EN = (0x1 << 3),
+ MAX98927_ICC_TX_Enables_B_ICC_TX_CH12_EN = (0x1 << 4),
+ MAX98927_ICC_TX_Enables_B_ICC_TX_CH13_EN = (0x1 << 5),
+ MAX98927_ICC_TX_Enables_B_ICC_TX_CH14_EN = (0x1 << 6),
+ MAX98927_ICC_TX_Enables_B_ICC_TX_CH15_EN = (0x1 << 7),
+
+ /* ICC Data Order Select (Address 0x002d)*/
+ MAX98927_ICC_Data_Order_Select = 0x002d,
+ MAX98927_ICC_Data_Order_Select_ICC_DRIVE_MODE = (0x1 << 3),
+
+ /* ICC HiZ Manual Mode (Address 0x002e)*/
+ MAX98927_ICC_HiZ_Manual_Mode = 0x002e,
+ MAX98927_ICC_HiZ_Manual_Mode_ICC_TX_HIZ_MANUAL = (0x1 << 0),
+ MAX98927_ICC_HiZ_Manual_Mode_ICC_TX_EXTRA_HIZ = (0x1 << 1),
+
+ /* ICC TX HiZ Enables A (Address 0x002f)*/
+ MAX98927_ICC_TX_HiZ_Enables_A = 0x002f,
+ MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH0_HIZ = (0x1 << 0),
+ MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH1_HIZ = (0x1 << 1),
+ MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH2_HIZ = (0x1 << 2),
+ MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH3_HIZ = (0x1 << 3),
+ MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH4_HIZ = (0x1 << 4),
+ MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH5_HIZ = (0x1 << 5),
+ MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH6_HIZ = (0x1 << 6),
+ MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH7_HIZ = (0x1 << 7),
+
+ /* ICC TX HiZ Enables B (Address 0x0030)*/
+ MAX98927_ICC_TX_HiZ_Enables_B = 0x0030,
+ MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH8_HIZ = (0x1 << 0),
+ MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH9_HIZ = (0x1 << 1),
+ MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH10_HIZ = (0x1 << 2),
+ MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH11_HIZ = (0x1 << 3),
+ MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH12_HIZ = (0x1 << 4),
+ MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH13_HIZ = (0x1 << 5),
+ MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH14_HIZ = (0x1 << 6),
+ MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH15_HIZ = (0x1 << 7),
+
+ /* ICC Link Enables (Address 0x0031)*/
+ MAX98927_ICC_Link_Enables = 0x0031,
+ MAX98927_ICC_Link_Enables_ICC_LINK_EN = (0x1 << 1),
+
+ /* PDM Tx Enables (Address 0x0032)*/
+ MAX98927_PDM_Tx_Enables = 0x0032,
+ MAX98927_PDM_Tx_Enables_PDM_TX_EN = (0x1 << 0),
+ MAX98927_PDM_Tx_Enables_PDM_TX_CLK_DIV2 = (0x1 << 1),
+
+ /* PDM Tx HiZ Control (Address 0x0033)*/
+ MAX98927_PDM_Tx_HiZ_Control = 0x0033,
+ MAX98927_PDM_Tx_HiZ_Control_PDM_TX_HIZ = (0x1 << 0),
+
+ /* PDM Tx Control (Address 0x0034)*/
+ MAX98927_PDM_Tx_Control = 0x0034,
+ MAX98927_PDM_Tx_Control_PDM_TX_CH0_SOURCE = (0x1 << 0),
+ MAX98927_PDM_Tx_Control_PDM_TX_CH1_SOURCE = (0x1 << 1),
+
+ /* PDM Rx Enable (Address 0x0034)*/
+ MAX98927_PDM_Rx_Enable = 0x0035,
+ MAX98927_PDM_Rx_Enable_PDM_RX_EN = (0x1 << 0),
+ MAX98927_PDM_Rx_Enable_PDM_DSP_EN = (0x1 << 1),
+ MAX98927_PDM_Rx_Enable_PDM_DITH_EN = (0x1 << 2),
+ MAX98927_PDM_Rx_Enable_PDM_RX_CH_SEL = (0x1 << 3),
+ MAX98927_PDM_Rx_Enable_PDM_FIFO_RDY_LVL_Mask = (0xf << 4),
+
+ /* AMP volume control (Address 0x0036)*/
+ MAX98927_AMP_volume_control = 0x0036,
+ MAX98927_AMP_volume_control_AMP_VOL_Mask = (0x7f << 0),
+ MAX98927_AMP_volume_control_AMP_VOL_SEL = (0x1 << 7),
+
+ /* AMP DSP Config (Address 0x0037)*/
+ MAX98927_AMP_DSP_Config = 0x0037,
+ MAX98927_AMP_DSP_Config_AMP_DCBLK_EN = (0x1 << 0),
+ MAX98927_AMP_DSP_Config_AMP_DITH_EN = (0x1 << 1),
+ MAX98927_AMP_DSP_Config_DAC_HALF_REF_CURRENT = (0x1 << 2),
+ MAX98927_AMP_DSP_Config_DAC_DOUBLE_RFB = (0x1 << 3),
+ MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS = (0x1 << 4),
+ MAX98927_AMP_DSP_Config_DAC_INVERT = (0x1 << 5),
+
+ /* Tone Generator and DC Config (Address 0x0038)*/
+ MAX98927_Tone_Generator_and_DC_Config = 0x0038,
+ MAX98927_Tone_Generator_and_DC_Config_TONE_CONFIG_Mask = (0xf << 0),
+
+ /* DRE Control (Address 0x0039)*/
+ MAX98927_DRE_Control = 0x0039,
+ MAX98927_DRE_Control_DRE_EN = (0x1 << 0),
+
+ /* AMP enables (Address 0x003a)*/
+ MAX98927_AMP_enables = 0x003a,
+ MAX98927_AMP_enables_SPK_EN = (0x1 << 0),
+
+ /* Speaker source select (Address 0x003b)*/
+ MAX98927_Speaker_source_select = 0x003b,
+ MAX98927_Speaker_source_select_SPK_SOURCE_Mask = (0x3 << 0),
+ MAX98927_Speaker_source_select_SPK_SOURCE_01 = (0x0 << 0),
+ MAX98927_Speaker_source_select_SPK_SOURCE_11 = (0x2 << 0),
+
+ /* Speaker Gain (Address 0x003c)*/
+ MAX98927_Speaker_Gain = 0x003c,
+ MAX98927_Speaker_Gain_SPK_PCM_GAIN_Mask = (0x7 << 0),
+ MAX98927_Speaker_Gain_SPK_PCM_GAIN_001 = (0x0 << 0),
+ MAX98927_Speaker_Gain_SPK_PCM_GAIN_011 = (0x2 << 0),
+ MAX98927_Speaker_Gain_SPK_PCM_GAIN_101 = (0x4 << 0),
+ MAX98927_Speaker_Gain_SPK_PCM_GAIN_111 = (0x6 << 0),
+ MAX98927_Speaker_Gain_SPK_PDM_GAIN_Mask = (0x7 << 4),
+ MAX98927_Speaker_Gain_SPK_PDM_GAIN_001 = (0x0 << 4),
+ MAX98927_Speaker_Gain_SPK_PDM_GAIN_011 = (0x2 << 4),
+ MAX98927_Speaker_Gain_SPK_PDM_GAIN_101 = (0x4 << 4),
+ MAX98927_Speaker_Gain_SPK_PDM_GAIN_111 = (0x6 << 4),
+
+ /* SSM Configuration (Address 0x003d)*/
+ MAX98927_SSM_Configuration = 0x003d,
+ MAX98927_SSM_Configuration_SSM_MOD_INDEX_Mask = (0x7 << 0),
+ MAX98927_SSM_Configuration_SSM_MOD_INDEX_001 = (0x0 << 0),
+ MAX98927_SSM_Configuration_SSM_MOD_INDEX_011 = (0x2 << 0),
+ MAX98927_SSM_Configuration_SSM_MOD_INDEX_101 = (0x4 << 0),
+ MAX98927_SSM_Configuration_SSM_MOD_INDEX_ = (0x6 << 0),
+ MAX98927_SSM_Configuration_SPK_FSW_SEL = (0x1 << 3),
+ MAX98927_SSM_Configuration_SSM_ENA = (0x1 << 7),
+
+ /* Measurement enables (Address 0x003e)*/
+ MAX98927_Measurement_enables = 0x003e,
+ MAX98927_Measurement_enables_IVADC_V_EN = (0x1 << 0),
+ MAX98927_Measurement_enables_IVADC_I_EN = (0x1 << 1),
+
+ /* Measurement DSP Config (Address 0x003f)*/
+ MAX98927_Measurement_DSP_Config = 0x003f,
+ MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_EN = (0x1 << 0),
+ MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_EN = (0x1 << 1),
+ MAX98927_Measurement_DSP_Config_MEAS_DITH_EN = (0x1 << 2),
+ MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_Mask = (0x3 << 4),
+ MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_01 = (0x0 << 4),
+ MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_11 = (0x2 << 4),
+ MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_Mask = (0x3 << 6),
+ MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_01 = (0x0 << 6),
+ MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_11 = (0x2 << 6),
+
+ /* Boost Control 0 (Address 0x0040)*/
+ MAX98927_Boost_Control_0 = 0x0040,
+ MAX98927_Boost_Control_0_BST_VOUT_Mask = (0x1f << 0),
+ MAX98927_Boost_Control_0_EXT_PVDD_EN = (0x1 << 7),
+
+ /* Boost Control 3 (Address 0x0041)*/
+ MAX98927_Boost_Control_3 = 0x0041,
+ MAX98927_Boost_Control_3_BST_SKIPLOAD_Mask = (0x3 << 0),
+ MAX98927_Boost_Control_3_BST_SKIPLOAD_01 = (0x0 << 0),
+ MAX98927_Boost_Control_3_BST_SKIPLOAD_11 = (0x2 << 0),
+ MAX98927_Boost_Control_3_BST_PHASE_Mask = (0x7 << 2),
+ MAX98927_Boost_Control_3_BST_PHASE_001 = (0x0 << 2),
+ MAX98927_Boost_Control_3_BST_PHASE_011 = (0x2 << 2),
+ MAX98927_Boost_Control_3_BST_PHASE_ = (0x1 << 2),
+ MAX98927_Boost_Control_3_BST_SLOWSTART = (0x1 << 5),
+
+ /* Boost Control 1 (Address 0x0042)*/
+ MAX98927_Boost_Control_1 = 0x0042,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Boost_Control_1_BST_ILIM_Mask = (0x3f << 0),
+
+ /* Meas ADC Config (Address 0x0043)*/
+ MAX98927_Meas_ADC_Config = 0x0043,
+ MAX98927_Meas_ADC_Config_MEAS_ADC_CH0_EN = (0x1 << 0),
+ MAX98927_Meas_ADC_Config_MEAS_ADC_CH1_EN = (0x1 << 1),
+ MAX98927_Meas_ADC_Config_MEAS_ADC_CH2_EN = (0x1 << 2),
+
+ /* Meas ADC Base Divide MSByte (Address 0x0044)*/
+ MAX98927_Meas_ADC_Base_Divide_MSByte = 0x0044,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Meas_ADC_Base_Divide_MSByte_MEAS_ADC_BASE_DIV_Mask
+ = (0xff << 0),
+
+ /* Meas ADC Base Divide LSByte (Address 0x0045)*/
+ MAX98927_Meas_ADC_Base_Divide_LSByte = 0x0045,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Meas_ADC_Base_Divide_LSByte_MEAS_ADC_BASE_DIV_Mask
+ = (0xff << 0),
+
+ /* Meas ADC Chan 0 Divide (Address 0x0046)*/
+ MAX98927_Meas_ADC_Chan_0_Divide = 0x0046,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Meas_ADC_Chan_0_Divide_MEAS_ADC_CH0_DIV_Mask = (0xff << 0),
+
+ /* Meas ADC Chan 1 Divide (Address 0x0047)*/
+ MAX98927_Meas_ADC_Chan_1_Divide = 0x0047,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Meas_ADC_Chan_1_Divide_MEAS_ADC_CH1_DIV_Mask = (0xff << 0),
+
+ /* Meas ADC Chan 2 Divide (Address 0x0048)*/
+ MAX98927_Meas_ADC_Chan_2_Divide = 0x0048,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Meas_ADC_Chan_2_Divide_MEAS_ADC_CH2_DIV_Mask = (0xff << 0),
+
+ /* Meas ADC Chan 0 Filt Config (Address 0x0049)*/
+ MAX98927_Meas_ADC_Chan_0_Filt_Config = 0x0049,
+ MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_Mask
+ = (0x7 << 0),
+ MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_001
+ = (0x0 << 0),
+ MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_011
+ = (0x2 << 0),
+ MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_101
+ = (0x4 << 0),
+ MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_EN
+ = (0x1 << 3),
+
+ /* Meas ADC Chan 1 Filt Config (Address 0x004a)*/
+ MAX98927_Meas_ADC_Chan_1_Filt_Config = 0x004a,
+ MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_Mask
+ = (0x7 << 0),
+ MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_001
+ = (0x0 << 0),
+ MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_011
+ = (0x2 << 0),
+ MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_101
+ = (0x4 << 0),
+ MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_EN
+ = (0x1 << 3),
+
+ /* Meas ADC Chan 2 Filt Config (Address 0x004b)*/
+ MAX98927_Meas_ADC_Chan_2_Filt_Config = 0x004b,
+ MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_Mask
+ = (0x7 << 0),
+ MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_001
+ = (0x0 << 0),
+ MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_011
+ = (0x2 << 0),
+ MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_101
+ = (0x4 << 0),
+ MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_EN
+ = (0x1 << 3),
+
+ /* Meas ADC Chan 0 Readback (Address 0x004c)*/
+ MAX98927_Meas_ADC_Chan_0_Readback = 0x004c,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Meas_ADC_Chan_0_Readback_MEAS_ADC_CH0_DATA_Mask
+ = (0xff << 0),
+
+ /* Meas ADC Chan 1 Readback (Address 0x004d)*/
+ MAX98927_Meas_ADC_Chan_1_Readback = 0x004d,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Meas_ADC_Chan_1_Readback_MEAS_ADC_CH1_DATA_Mask
+ = (0xff << 0),
+
+ /* Meas ADC Chan 2 Readback (Address 0x004e)*/
+ MAX98927_Meas_ADC_Chan_2_Readback = 0x004e,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Meas_ADC_Chan_2_Readback_MEAS_ADC_CH2_DATA_Mask
+ = (0xff << 0),
+
+ /* Brownout status (Address 0x0051)*/
+ MAX98927_Brownout_status = 0x0051,
+ MAX98927_Brownout_status_BDE_STATE_Mask = (0xf << 0),
+
+ /* Brownout enables (Address 0x0052)*/
+ MAX98927_Brownout_enables = 0x0052,
+ MAX98927_Brownout_enables_BDE_EN = (0x1 << 0),
+ MAX98927_Brownout_enables_BDE_AMP_EN = (0x1 << 1),
+ MAX98927_Brownout_enables_AMP_DSP_EN = (0x1 << 2),
+
+ /* Brownout level infinite hold (Address 0x0053)*/
+ MAX98927_Brownout_level_infinite_hold = 0x0053,
+ MAX98927_Brownout_level_infinite_hold_BDE_L8_INF_HLD = (0x1 << 1),
+
+ /* Brownout level infinite hold clear (Address 0x0054)*/
+ MAX98927_Brownout_level_infinite_hold_clear = 0x0054,
+ MAX98927_Brownout_level_infinite_hold_clear_BDE_L8_HLD_RLS
+ = (0x1 << 1),
+
+ /* Brownout level hold (Address 0x0055)*/
+ MAX98927_Brownout_level_hold = 0x0055,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout_level_hold_BDE_HLD_Mask = (0xff << 0),
+
+ /* Brownout level 1 threshold (Address 0x0056)*/
+ MAX98927_Brownout__level_1_threshold = 0x0056,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_1_threshold_BDE_L1_VTHRESH_Mask = (0xff << 0),
+
+ /* Brownout level 2 threshold (Address 0x0057)*/
+ MAX98927_Brownout__level_2_threshold = 0x0057,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_2_threshold_BDE_L2_VTHRESH_Mask = (0xff << 0),
+
+ /* Brownout level 3 threshold (Address 0x0058)*/
+ MAX98927_Brownout__level_3_threshold = 0x0058,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_3_threshold_BDE_L3_VTHRESH_Mask = (0xff << 0),
+
+ /* Brownout level 4 threshold (Address 0x0059)*/
+ MAX98927_Brownout__level_4_threshold = 0x0059,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_4_threshold_BDE_L4_VTHRESH_Mask = (0xff << 0),
+
+ /* Brownout level 5 threshold (Address 0x005a)*/
+ MAX98927_Brownout__level_5_threshold = 0x005a,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_5_threshold_BDE_L5_VTHRESH_Mask = (0xff << 0),
+
+ /* Brownout level 6 threshold (Address 0x005b)*/
+ MAX98927_Brownout__level_6_threshold = 0x005b,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_6_threshold_BDE_L6_VTHRESH_Mask = (0xff << 0),
+
+ /* Brownout level 7 threshold (Address 0x005c)*/
+ MAX98927_Brownout__level_7_threshold = 0x005c,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_7_threshold_BDE_L7_VTHRESH_Mask = (0xff << 0),
+
+ /* Brownout level 8 threshold (Address 0x005d)*/
+ MAX98927_Brownout__level_8_threshold = 0x005d,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_8_threshold_BDE_L8_VTHRESH_Mask = (0xff << 0),
+
+ /* Brownout threshold hysterysis (Address 0x005e)*/
+ MAX98927_Brownout_threshold_hysterysis = 0x005e,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout_threshold_hysterysis_BDE_VTHRESH_HYST_Mask
+ = (0xff << 0),
+ /* Brownout AMP limiter attack/release (Address 0x005f)*/
+ MAX98927_Brownout_AMP_limiter_attack_release = 0x005f,
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_Mask
+ = (0xf << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0001
+ = (0x0 << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0011
+ = (0x2 << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0101
+ = (0x4 << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0111
+ = (0x6 << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1001
+ = (0x8 << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1011
+ = (0xa << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1101
+ = (0xc << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1111
+ = (0xe << 0),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_Mask
+ = (0xf << 4),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0001
+ = (0x0 << 4),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0011
+ = (0x2 << 4),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0101
+ = (0x4 << 4),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0111
+ = (0x6 << 4),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1001
+ = (0x8 << 4),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1011
+ = (0xa << 4),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1101
+ = (0xc << 4),
+ MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1111
+ = (0xe << 4),
+
+ /* Brownout AMP gain attack/release (Address 0x0060)*/
+ MAX98927_Brownout_AMP_gain_attack_release = 0x0060,
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_Mask
+ = (0xf << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0001
+ = (0x0 << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0011
+ = (0x2 << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0101
+ = (0x4 << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0111
+ = (0x6 << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1001
+ = (0x8 << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1011
+ = (0xa << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1101
+ = (0xc << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1111
+ = (0xe << 0),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_Mask
+ = (0xf << 4),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0001
+ = (0x0 << 4),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0011
+ = (0x2 << 4),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0101
+ = (0x4 << 4),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0111
+ = (0x6 << 4),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1001
+ = (0x8 << 4),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1011
+ = (0xa << 4),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1101
+ = (0xc << 4),
+ MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1111
+ = (0xe << 4),
+
+ /* Brownout AMP1 clip mode (Address 0x0061)*/
+ MAX98927_Brownout_AMP1_clip_mode = 0x0061,
+ MAX98927_Brownout_AMP1_clip_mode_AMP_CLIP_MODE = (0x1 << 0),
+
+ /* Brownout level 1 current limit (Address 0x0062)*/
+ MAX98927_Brownout__level_1_current_limit = 0x0062,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_1_current_limit_BDE_L1_ILIM_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 1 amp 1 control 1 (Address 0x0063)*/
+ MAX98927_Brownout__level_1_amp_1_control_1 = 0x0063,
+ MAX98927_Brownout__level_1_amp_1_control_1_BDE_L1_AMP1_LIM_Mask
+ = (0xf << 0),
+
+ /* Brownout level 1 amp 1 control 2 (Address 0x0064)*/
+ MAX98927_Brownout__level_1_amp_1_control_2 = 0x0064,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_1_amp_1_control_2_BDE_L1_AMP1_CLIP_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 1 amp 1 control 3 (Address 0x0065)*/
+ MAX98927_Brownout__level_1_amp_1_control_3 = 0x0065,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_1_amp_1_control_3_BDE_L1_AMP1_GAIN_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 2 current limit (Address 0x0066)*/
+ MAX98927_Brownout__level_2_current_limit = 0x0066,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_2_current_limit_BDE_L2_ILIM_Mask = (0x3f << 0),
+
+ /* Brownout level 2 amp 1 control 1 (Address 0x0067)*/
+ MAX98927_Brownout__level_2_amp_1_control_1 = 0x0067,
+ MAX98927_Brownout__level_2_amp_1_control_1_BDE_L2_AMP1_LIM_Mask
+ = (0xf << 0),
+
+ /* Brownout level 2 amp 1 control 2 (Address 0x0068)*/
+ MAX98927_Brownout__level_2_amp_1_control_2 = 0x0068,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_2_amp_1_control_2_BDE_L2_AMP1_CLIP_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 2 amp 1 control 3 (Address 0x0069)*/
+ MAX98927_Brownout__level_2_amp_1_control_3 = 0x0069,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_2_amp_1_control_3_BDE_L2_AMP1_GAIN_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 3 current limit (Address 0x006a)*/
+ MAX98927_Brownout__level_3_current_limit = 0x006a,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_3_current_limit_BDE_L3_ILIM_Mask = (0x3f << 0),
+
+ /* Brownout level 3 amp 1 control 1 (Address 0x006b)*/
+ MAX98927_Brownout__level_3_amp_1_control_1 = 0x006b,
+ MAX98927_Brownout__level_3_amp_1_control_1_BDE_L3_AMP1_LIM_Mask
+ = (0xf << 0),
+
+ /* Brownout level 3 amp 1 control 2 (Address 0x006c)*/
+ MAX98927_Brownout__level_3_amp_1_control_2 = 0x006c,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_3_amp_1_control_2_BDE_L3_AMP1_CLIP_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 3 amp 1 control 3 (Address 0x006d)*/
+ MAX98927_Brownout__level_3_amp_1_control_3 = 0x006d,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_3_amp_1_control_3_BDE_L3_AMP1_GAIN_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 4 current limit (Address 0x006e)*/
+ MAX98927_Brownout__level_4_current_limit = 0x006e,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_4_current_limit_BDE_L4_ILIM_Mask = (0x3f << 0),
+
+ /* Brownout level 4 amp 1 control 1 (Address 0x006f)*/
+ MAX98927_Brownout__level_4_amp_1_control_1 = 0x006f,
+ MAX98927_Brownout__level_4_amp_1_control_1_BDE_L4_AMP1_LIM_Mask
+ = (0xf << 0),
+
+ /* Brownout level 4 amp 1 control 2 (Address 0x0070)*/
+ MAX98927_Brownout__level_4_amp_1_control_2 = 0x0070,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_4_amp_1_control_2_BDE_L4_AMP1_CLIP_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 4 amp 1 control 3 (Address 0x0071)*/
+ MAX98927_Brownout__level_4_amp_1_control_3 = 0x0071,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_4_amp_1_control_3_BDE_L4_AMP1_GAIN_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 5 current limit (Address 0x0072)*/
+ MAX98927_Brownout__level_5_current_limit = 0x0072,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_5_current_limit_BDE_L5_ILIM_Mask = (0x3f << 0),
+
+ /* Brownout level 5 amp 1 control 1 (Address 0x0073)*/
+ MAX98927_Brownout__level_5_amp_1_control_1 = 0x0073,
+ MAX98927_Brownout__level_5_amp_1_control_1_BDE_L5_AMP1_LIM_Mask
+ = (0xf << 0),
+
+ /* Brownout level 5 amp 1 control 2 (Address 0x0074)*/
+ MAX98927_Brownout__level_5_amp_1_control_2 = 0x0074,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_5_amp_1_control_2_BDE_L5_AMP1_CLIP_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 5 amp 1 control 3 (Address 0x0075)*/
+ MAX98927_Brownout__level_5_amp_1_control_3 = 0x0075,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_5_amp_1_control_3_BDE_L5_AMP1_GAIN_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 6 current limit (Address 0x0076)*/
+ MAX98927_Brownout__level_6_current_limit = 0x0076,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_6_current_limit_BDE_L6_ILIM_Mask = (0x3f << 0),
+
+ /* Brownout level 6 amp 1 control 1 (Address 0x0077)*/
+ MAX98927_Brownout__level_6_amp_1_control_1 = 0x0077,
+ MAX98927_Brownout__level_6_amp_1_control_1_BDE_L6_AMP1_LIM_Mask
+ = (0xf << 0),
+
+ /* Brownout level 6 amp 1 control 2 (Address 0x0078)*/
+ MAX98927_Brownout__level_6_amp_1_control_2 = 0x0078,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_6_amp_1_control_2_BDE_L6_AMP1_CLIP_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 6 amp 1 control 3 (Address 0x0079)*/
+ MAX98927_Brownout__level_6_amp_1_control_3 = 0x0079,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_6_amp_1_control_3_BDE_L6_AMP1_GAIN_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 7 current limit (Address 0x007a)*/
+ MAX98927_Brownout__level_7_current_limit = 0x007a,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_7_current_limit_BDE_L7_ILIM_Mask = (0x3f << 0),
+
+ /* Brownout level 7 amp 1 control 1 (Address 0x007b)*/
+ MAX98927_Brownout__level_7_amp_1_control_1 = 0x007b,
+ MAX98927_Brownout__level_7_amp_1_control_1_BDE_L7_AMP1_LIM_Mask
+ = (0xf << 0),
+
+ /* Brownout level 7 amp 1 control 2 (Address 0x007c)*/
+ MAX98927_Brownout__level_7_amp_1_control_2 = 0x007c,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_7_amp_1_control_2_BDE_L7_AMP1_CLIP_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 7 amp 1 control 3 (Address 0x007d)*/
+ MAX98927_Brownout__level_7_amp_1_control_3 = 0x007d,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_7_amp_1_control_3_BDE_L7_AMP1_GAIN_Mask
+ = (0x3f << 0),
+
+ /* Brownout level 8 current limit (Address 0x007e)*/
+ MAX98927_Brownout__level_8_current_limit = 0x007e,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_8_current_limit_BDE_L8_ILIM_Mask = (0x3f << 0),
+
+ /* Brownout level 8 amp 1 control 1 (Address 0x007f)*/
+ MAX98927_Brownout__level_8_amp_1_control_1 = 0x007f,
+ MAX98927_Brownout__level_8_amp_1_control_1_BDE_L8_AMP1_LIM_Mask
+ = (0xf << 0),
+
+ /* Brownout level 8 amp 1 control 2 (Address 0x0080)*/
+ MAX98927_Brownout__lvl_8_amp_1_control_2 = 0x0080,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__lvl_8_amp_1_control_2_BDE_L8_AMP1_CLIP_Mask
+ = (0x3f << 0),
+ MAX98927_Brownout__lvl_8_amp_1_control_2_BDE_L8_AMP1_MUTE
+ = (0x1 << 7),
+
+ /* Brownout level 8 amp 1 control 3 (Address 0x0081)*/
+ MAX98927_Brownout__level_8_amp_1_control_3 = 0x0081,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Brownout__level_8_amp_1_control_3_BDE_L8_AMP1_GAIN_Mask
+ = (0x3f << 0),
+
+ /* Env Tracker Vout Headroom (Address 0x0082)*/
+ MAX98927_Env_Tracker_Vout_Headroom = 0x0082,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Env_Tracker_Vout_Head_ENV_TRACKER_BST_VOUT_HEADROOM_Mask
+ = (0x1f << 0),
+
+ /* Env Tracker Boost Vout Delay (Address 0x0083)*/
+ MAX98927_Env_Tracker_Boost_Vout_Delay = 0x0083,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Env_Tracker_Boost_V_Delay_ENV_TRACKER_BST_VOUT_DELAY_Mask
+ = (0x1f << 0),
+ MAX98927_Env_Tracker_Boost_Vout_Delay_ENV_TRACKER_BDE_MODE
+ = (0x1 << 7),
+
+ /* Env Tracker Release Rate (Address 0x0084)*/
+ MAX98927_Env_Tracker_Release_Rate = 0x0084,
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_Mask
+ = (0x7 << 0),
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_001
+ = (0x0 << 0),
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_011
+ = (0x2 << 0),
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_101
+ = (0x4 << 0),
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_111
+ = (0x6 << 0),
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_PEAK_DET_LPF_BYP_EN
+ = (0x1 << 3),
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_Mask
+ = (0x3 << 4),
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_01
+ = (0x0 << 4),
+ MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_11
+ = (0x2 << 4),
+
+ /* Env Tracker Hold Rate (Address 0x0085)*/
+ MAX98927_Env_Tracker_Hold_Rate = 0x0085,
+ MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_Mask
+ = (0x7 << 0),
+ MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_001
+ = (0x0 << 0),
+ MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_011
+ = (0x2 << 0),
+ MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_101
+ = (0x4 << 0),
+ MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_111
+ = (0x6 << 0),
+
+ /* Env Tracker Control (Address 0x0086)*/
+ MAX98927_Env_Tracker_Control = 0x0086,
+ MAX98927_Env_Tracker_Control_ENV_TRACKER_EN = (0x1 << 0),
+
+ /* Env Tracker Boost Vout ReadBack (Address 0x0087)*/
+ MAX98927_Env_Tracker__Boost_Vout_ReadBack = 0x0087,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Env_Tracker__Boost_Vout_RB_ENV_TRACKER_BST_VOUT_RD_Mask
+ = (0x1f << 0),
+
+ /* Advanced Settings (Address 0x0089)*/
+ MAX98927_Advanced_Settings = 0x0089,
+ MAX98927_Advanced_Settings_DAC_HALF_FIR = (0x1 << 0),
+ MAX98927_Advanced_Settings_PDM_MOD_SEL = (0x1 << 1),
+ MAX98927_Advanced_Settings_ISOCH_EN = (0x1 << 2),
+
+ /* DAC Test 1 (Address 0x009f)*/
+ MAX98927_DAC_Test_1 = 0x009f,
+ MAX98927_DAC_Test_1_DAC_PCM_TIMING = (0x1 << 0),
+ MAX98927_DAC_Test_1_DAC_HALFI_AMP = (0x1 << 1),
+ MAX98927_DAC_Test_1_DAC_LONG_HOLD = (0x1 << 3),
+ MAX98927_DAC_Test_1_DAC_DISABLE_CHOP = (0x1 << 4),
+ MAX98927_DAC_Test_1_DAC_TM = (0x1 << 5),
+ MAX98927_DAC_Test_1_DAC_INVERT_DACCLK = (0x1 << 6),
+
+ /* Authentication key 0 (Address 0x00ea)*/
+ MAX98927_Authentication_key_0 = 0x00ea,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_key_0_AUTH_KEY_Mask = (0xff << 0),
+
+ /* Authentication key 1 (Address 0x00eb)*/
+ MAX98927_Authentication_key_1 = 0x00eb,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_key_1_AUTH_KEY_Mask = (0xff << 0),
+
+ /* Authentication key 2 (Address 0x00ec)*/
+ MAX98927_Authentication_key_2 = 0x00ec,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_key_2_AUTH_KEY_Mask = (0xff << 0),
+
+ /* Authentication key 3 (Address 0x00ed)*/
+ MAX98927_Authentication_key_3 = 0x00ed,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_key_3_AUTH_KEY_Mask = (0xff << 0),
+
+ /* Authentication enable (Address 0x00ee)*/
+ MAX98927_Authentication_enable = 0x00ee,
+ MAX98927_Authentication_enable_AUTH_EN = (0x1 << 0),
+
+ /* Authentication result 0 (Address 0x00ef)*/
+ MAX98927_Authentication_result_0 = 0x00ef,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_0_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 1 (Address 0x00f0)*/
+ MAX98927_Authentication_result_1 = 0x00f0,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_1_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 2 (Address 0x00f1)*/
+ MAX98927_Authentication_result_2 = 0x00f1,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_2_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 3 (Address 0x00f2)*/
+ MAX98927_Authentication_result_3 = 0x00f2,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_3_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 4 (Address 0x00f3)*/
+ MAX98927_Authentication_result_4 = 0x00f3,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_4_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 5 (Address 0x00f4)*/
+ MAX98927_Authentication_result_5 = 0x00f4,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_5_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 6 (Address 0x00f5)*/
+ MAX98927_Authentication_result_6 = 0x00f5,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_6_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 7 (Address 0x00f6)*/
+ MAX98927_Authentication_result_7 = 0x00f6,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_7_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 8 (Address 0x00f7)*/
+ MAX98927_Authentication_result_8 = 0x00f7,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_8_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 9 (Address 0x00f8)*/
+ MAX98927_Authentication_result_9 = 0x00f8,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_9_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 10 (Address 0x00f9)*/
+ MAX98927_Authentication_result_10 = 0x00f9,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_10_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 11 (Address 0x00fa)*/
+ MAX98927_Authentication_result_11 = 0x00fa,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_11_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 12 (Address 0x00fb)*/
+ MAX98927_Authentication_result_12 = 0x00fb,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_12_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 13 (Address 0x00fc)*/
+ MAX98927_Authentication_result_13 = 0x00fc,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_13_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 14 (Address 0x00fd)*/
+ MAX98927_Authentication_result_14 = 0x00fd,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_14_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Authentication result 15 (Address 0x00fe)*/
+ MAX98927_Authentication_result_15 = 0x00fe,
+ /*#BYHAND width >= 5:*/
+ MAX98927_Authentication_result_15_AUTH_RESULT_Mask = (0xff << 0),
+
+ /* Global Enable (Address 0x00ff)*/
+ MAX98927_Global_Enable = 0x00ff,
+ MAX98927_Global_Enable_EN = (0x1 << 0),
+ /* Software Reset (Address 0x0100)*/
+ MAX98927_Software_Reset = 0x0100,
+ MAX98927_Software_Reset_RST = (0x1 << 0),
+
+ /* REV ID (Address 0x01ff)*/
+ MAX98927_REV_ID = 0x01ff,
+ /*#BYHAND width >= 5:*/
+ MAX98927_REV_ID_REV_ID_Mask = (0xff << 0),
+} MAX98927Registers;
+
+struct max98927_reg_default {
+ unsigned int ch;
+ unsigned int reg;
+ unsigned int def;
+};
+struct max98927_priv {
+ struct regmap *regmap;
+ struct regmap *sub_regmap;
+ struct snd_soc_codec *codec;
+ struct max98927_pdata *pdata;
+ const uint32_t *regcfg;
+ uint32_t regcfg_sz;
+ unsigned int spk_gain;
+ unsigned int sysclk;
+ unsigned int v_l_slot;
+ unsigned int i_l_slot;
+ unsigned int v_r_slot;
+ unsigned int i_r_slot;
+ bool interleave_mode;
+ unsigned int ch_size;
+ unsigned int rate;
+ unsigned int iface;
+ unsigned int master;
+ unsigned int thres_hyste;
+ unsigned int level5_hold;
+ unsigned int level6_hold;
+ unsigned int level7_hold;
+ unsigned int level8_hold;
+ unsigned int amp_limit;
+ unsigned int amp_limit_rel;
+ unsigned int amp1_level;
+ unsigned int amp2_level;
+ unsigned int amp3_level;
+ unsigned int amp1_level8;
+ unsigned int amp2_level8;
+ unsigned int amp3_level8;
+ unsigned int amp1_level7;
+ unsigned int amp2_level7;
+ unsigned int amp3_level7;
+ unsigned int amp1_level6;
+ unsigned int amp2_level6;
+ unsigned int amp3_level6;
+ unsigned int amp1_level5;
+ unsigned int amp2_level5;
+ unsigned int amp3_level5;
+ unsigned int digital_gain;
+ unsigned int pdm_gain;
+ unsigned int level_hold;
+ struct i2c_client *sub_i2c;
+ int sub_reg;
+ int sub_bus;
+};
+
+#define MAX98927_GLOBAL_SHIFT 0
+#define M98927_DAI_MSEL_SHIFT 4
+#define M98927_DAI_BSEL_SHIFT 0
+#define M98927_DAI_BSEL_32 (2 << M98927_DAI_BSEL_SHIFT)
+#define M98927_DAI_BSEL_48 (3 << M98927_DAI_BSEL_SHIFT)
+#define M98927_DAI_BSEL_64 (4 << M98927_DAI_BSEL_SHIFT)
+#define M98927_DAI_MSEL_32 (2 << M98927_DAI_MSEL_SHIFT)
+#define M98927_DAI_MSEL_48 (3 << M98927_DAI_MSEL_SHIFT)
+#define M98927_DAI_MSEL_64 (4 << M98927_DAI_MSEL_SHIFT)
+#define MAX98927_Speaker_Gain_Width 3
+#define MAX98927_SPK_RMP_EN_SHIFT 4
+#define MAX98927_PDM_GAIN_SHIFT 4
+#define MAX98927_pdm_Gain_Width 3
+#define MAX98927_AMP_VOL_WIDTH 7
+#define MAX98927_AMP_VOL_LOCATION_SHIFT 7
+#define MAX98927_PDM_Rx_Enable_PDM_CH_SHIFT 3
+#define MAX98927_PCM_to_speaker_monomix_A_SHIFT 6
+#define MAX98927_PCM_Sample_rate_setup_2_DIG_IF_SR_48000 (0x8 << 4)
+#define MAX98927_PCM_FORMAT_DSP_A (0x3 << 3)
+#define MAX98927_DRE_Control_DRE_SHIFT 0x1
+#define MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_SHIFT (2)
+#define MAX98927_Brownout_AMP_limiter_attack_release_shift 4
+#define MAX98927_BDE_DSP_SHIFT 2
+#define MAX98927_Speaker_Gain_SPK_PDM_GAIN_SHIFT (4)
+#define MAX98927_BDE_AMP_SHIFT (1)
+#define MAX98927_PCM_Tx_Ch_Sources_A_I_SHIFT (4)
+#endif
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v3 2/2] DW DMAC: add multi-block property to device tree
From: Vinod Koul @ 2016-11-23 4:15 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Eugeniy Paltsev, devicetree, robh+dt, mark.rutland, linux-kernel,
dmaengine, linux-snps-arc
In-Reply-To: <1479497593.22212.45.camel@linux.intel.com>
On Fri, Nov 18, 2016 at 09:33:13PM +0200, Andy Shevchenko wrote:
> > @@ -1569,7 +1569,7 @@ int dw_dma_probe(struct dw_dma_chip *chip)
> > (dwc_params >> DWC_PARAMS_MBLK_EN &
> > 0x1) == 0;
> > } else {
> > dwc->block_size = pdata->block_size;
> > - dwc->nollp = pdata->is_nollp;
> > + dwc->nollp = pdata->multi_block[i];
>
> You missed the point. You assign positive value to negative variable.
> It's a bug. Have you tested this? How?
>
> In case of positive property you have to update DTS. By the way, I'm
> pretty sure that spare13xx boards has auto configuration enabled, though
> it has to be checked with vendor (I assume you may have fast response
> from them).
Yeah why are we not using auto configuration here would be the first
question..
--
~Vinod
^ permalink raw reply
* Re: [PATCH v4 3/3] dmaengine: sun6i: share the dma driver with sun50i
From: Vinod Koul @ 2016-11-23 4:12 UTC (permalink / raw)
To: Hao Zhang
Cc: mark.rutland, devicetree, catalin.marinas, will.deacon,
linux-kernel, wens, robh+dt, dmaengine, maxime.ripard,
dan.j.williams, linux-arm-kernel
In-Reply-To: <1479638740-20520-4-git-send-email-hao5781286@gmail.com>
On Sun, Nov 20, 2016 at 06:45:40PM +0800, Hao Zhang wrote:
> Changes the limited buswith to 8 bytes,and add
> the test in sun6i_dma_config function
>
> Accroding to sun6i dma driver, i think ,if the client
^^^^^^^^
typo and other grammatical mistakes here..
> doesn't configure the address width with dmaengine_slave_config
> function, it would use the default width. So we can add the test
> in sun6i_dma_config function called by dmaengine_slave_config,
> and test the configuration whether is support for the device.
>
> Signed-off-by: Hao Zhang <hao5781286@gmail.com>
> ---
> drivers/dma/sun6i-dma.c | 33 ++++++++++++++++++++++++++++++++-
> 1 file changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index a235878..f7c90b6 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -250,7 +250,7 @@ static inline s8 convert_burst(u32 maxburst)
> static inline s8 convert_buswidth(enum dma_slave_buswidth addr_width)
> {
> if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) ||
> - (addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
> + (addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES))
> return -EINVAL;
>
> return addr_width >> 1;
> @@ -758,6 +758,18 @@ static int sun6i_dma_config(struct dma_chan *chan,
> {
> struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
>
> + if ((BIT(config->src_addr_width) | chan->device->src_addr_widths) !=
> + chan->device->src_addr_widths) {
First I dont like coding style here
Second, this is not driver specific, should be move to core..
--
~Vinod
^ permalink raw reply
* Re: [PATCH 5/5] sdhci: Add quirk for delayed IRQ ACK
From: Jisheng Zhang @ 2016-11-23 4:12 UTC (permalink / raw)
To: Jeremy McNicoll
Cc: Jeremy McNicoll, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
andy.gross-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
robh-DgEjT+Ai2ygdnm+yROfE0A, arnd-r2nGTMty4D4,
bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
riteshh-sgV2jX0FEOL9JmXXK+q4OQ
In-Reply-To: <ecacec51-4b06-49cd-c756-489128729499-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Tue, 22 Nov 2016 19:48:56 -0800 Jeremy McNicoll wrote:
> On 2016-11-22 7:36 PM, Jisheng Zhang wrote:
> > On Tue, 22 Nov 2016 17:09:48 -0800
> > Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> >
> >> On msm8992 it has been observed that IRQs were not getting
> >> ACK'd correctly when clocked at speeds greater than 400KHz.
> >>
> >> Signed-off-by: Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> >> ---
> >> drivers/mmc/host/sdhci-msm.c | 7 +++++++
> >> drivers/mmc/host/sdhci.c | 12 ++++++++++--
> >> drivers/mmc/host/sdhci.h | 2 ++
> >> 3 files changed, 19 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> >> index 1fcda96..459003c 100644
> >> --- a/drivers/mmc/host/sdhci-msm.c
> >> +++ b/drivers/mmc/host/sdhci-msm.c
> >> @@ -1303,6 +1303,13 @@ static int sdhci_msm_probe(struct platform_device *pdev)
> >> CORE_VENDOR_SPEC_CAPABILITIES0);
> >> }
> >>
> >> + /* Enable delayed IRQ handling workaround on 8992 */
> >> + if (core_major == 1 && core_minor == 0x3e) {
> >> + /* Add 40us delay in interrupt handler when operating
> >> + * at initialization frequency of 400KHz. */
> >> + host->quirks2 |= SDHCI_QUIRK2_SLOW_INT_CLR;
> >> + }
> >> +
> >> /* Setup IRQ for handling power/voltage tasks with PMIC */
> >> msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq");
> >> if (msm_host->pwr_irq < 0) {
> >> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> >> index 5911f98..c1aae22 100644
> >> --- a/drivers/mmc/host/sdhci.c
> >> +++ b/drivers/mmc/host/sdhci.c
> >> @@ -2703,11 +2703,19 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
> >> result = IRQ_WAKE_THREAD;
> >> }
> >>
> >> - if (intmask & SDHCI_INT_CMD_MASK)
> >> + if (intmask & SDHCI_INT_CMD_MASK) {
> >> + if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
> >> + udelay(40);
> >> + }
> >> sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
> >> + }
> >>
> >> - if (intmask & SDHCI_INT_DATA_MASK)
> >> + if (intmask & SDHCI_INT_DATA_MASK) {
> >> + if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
> >> + udelay(40);
> >> + }
> >> sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
> >> + }
> >>
> >> if (intmask & SDHCI_INT_BUS_POWER)
> >> pr_err("%s: Card is consuming too much power!\n",
> >> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> >> index c055e24..5f8301e 100644
> >> --- a/drivers/mmc/host/sdhci.h
> >> +++ b/drivers/mmc/host/sdhci.h
> >> @@ -24,6 +24,8 @@
> >> * Controller registers
> >> */
> >>
> >> +#define SDHCI_QUIRK2_SLOW_INT_CLR (1<<5)
> >
> > IIRC, new quirk isn't allowed now.
> >
>
> Why not?
IIRC, mmc subsystem will behave as a lib in the long run, so the community
and developers call for no new quirk. For your case, we may need to handle
the udelay in sdhci-msm.c, export sdhci_irq as a helper function?
Thanks
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 0/2] DW DMAC: update device tree
From: Vinod Koul @ 2016-11-23 4:06 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Alexey Brodkin,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Eugeniy.Paltsev-HKixBCOQz3hWk0Htik3J/w@public.gmane.org,
linux-snps-arc-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
dmaengine-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1479724626.22212.50.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
On Mon, Nov 21, 2016 at 12:37:06PM +0200, Andy Shevchenko wrote:
> On Mon, 2016-11-21 at 10:02 +0000, Alexey Brodkin wrote:
> > Hi Andy,
> >
> > On Fri, 2016-11-18 at 21:26 +0200, Andy Shevchenko wrote:
> > > On Fri, 2016-11-18 at 22:12 +0300, Eugeniy Paltsev wrote:
> > > >
> > > > It wasn't possible to enable some features like
> > > > memory-to-memory transfers or multi block transfers via DT.
> > > > It is fixed by these patches.
> > >
> > > First of all, please, give time to reviewers to comment the patches.
> > > Usually it should be at least 24h (for the series that has been sent
> > > first time 1 week approximately).
> >
> > I'm not really sure a lot of people get disturbed by this series
> > and given this all has been discussed for months now I'd really like
> > to see changes required for our HW to work to land in upstream ASAP.
>
> I understand your concern, I'm often in the same position in many areas,
> including this driver (I'm not a maintainer of slave DMA subsystem).
>
> Though let's face the issues we have with the series:
> - stuff regarding to style and alike (would be fixed in a day)
> - DTS naming and conventions, this is apparently a big area, where I
> might share opinion, but can't decide for
> - last word by the subsystem maintainer
>
> > Too bad we're late for 4.9 (which is supposed to be the next LTS) but
> > > we need to make sure this series hits 4.10 for sure.
>
> Vinod, is it possible to get in for this series (if we get Ack from DT
> people)?
We still have a week or so... But holding race agaisnt upstream is a bad
idea... Doesnt work that way.
--
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 5/5] sdhci: Add quirk for delayed IRQ ACK
From: Jeremy McNicoll @ 2016-11-23 3:48 UTC (permalink / raw)
To: Jisheng Zhang, Jeremy McNicoll
Cc: linux-arm-msm, linux-soc, devicetree, linux-mmc, andy.gross,
sboyd, robh, arnd, bjorn.andersson, riteshh
In-Reply-To: <20161123113647.0b3deac0@xhacker>
On 2016-11-22 7:36 PM, Jisheng Zhang wrote:
> On Tue, 22 Nov 2016 17:09:48 -0800
> Jeremy McNicoll <jeremymc@redhat.com> wrote:
>
>> On msm8992 it has been observed that IRQs were not getting
>> ACK'd correctly when clocked at speeds greater than 400KHz.
>>
>> Signed-off-by: Jeremy McNicoll <jeremymc@redhat.com>
>> ---
>> drivers/mmc/host/sdhci-msm.c | 7 +++++++
>> drivers/mmc/host/sdhci.c | 12 ++++++++++--
>> drivers/mmc/host/sdhci.h | 2 ++
>> 3 files changed, 19 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
>> index 1fcda96..459003c 100644
>> --- a/drivers/mmc/host/sdhci-msm.c
>> +++ b/drivers/mmc/host/sdhci-msm.c
>> @@ -1303,6 +1303,13 @@ static int sdhci_msm_probe(struct platform_device *pdev)
>> CORE_VENDOR_SPEC_CAPABILITIES0);
>> }
>>
>> + /* Enable delayed IRQ handling workaround on 8992 */
>> + if (core_major == 1 && core_minor == 0x3e) {
>> + /* Add 40us delay in interrupt handler when operating
>> + * at initialization frequency of 400KHz. */
>> + host->quirks2 |= SDHCI_QUIRK2_SLOW_INT_CLR;
>> + }
>> +
>> /* Setup IRQ for handling power/voltage tasks with PMIC */
>> msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq");
>> if (msm_host->pwr_irq < 0) {
>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>> index 5911f98..c1aae22 100644
>> --- a/drivers/mmc/host/sdhci.c
>> +++ b/drivers/mmc/host/sdhci.c
>> @@ -2703,11 +2703,19 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
>> result = IRQ_WAKE_THREAD;
>> }
>>
>> - if (intmask & SDHCI_INT_CMD_MASK)
>> + if (intmask & SDHCI_INT_CMD_MASK) {
>> + if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
>> + udelay(40);
>> + }
>> sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
>> + }
>>
>> - if (intmask & SDHCI_INT_DATA_MASK)
>> + if (intmask & SDHCI_INT_DATA_MASK) {
>> + if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
>> + udelay(40);
>> + }
>> sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
>> + }
>>
>> if (intmask & SDHCI_INT_BUS_POWER)
>> pr_err("%s: Card is consuming too much power!\n",
>> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
>> index c055e24..5f8301e 100644
>> --- a/drivers/mmc/host/sdhci.h
>> +++ b/drivers/mmc/host/sdhci.h
>> @@ -24,6 +24,8 @@
>> * Controller registers
>> */
>>
>> +#define SDHCI_QUIRK2_SLOW_INT_CLR (1<<5)
>
> IIRC, new quirk isn't allowed now.
>
Why not?
-jeremy
> Thanks,
> Jisheng
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH 5/5] sdhci: Add quirk for delayed IRQ ACK
From: Jisheng Zhang @ 2016-11-23 3:36 UTC (permalink / raw)
To: Jeremy McNicoll
Cc: linux-arm-msm, linux-soc, devicetree, linux-mmc, andy.gross,
sboyd, robh, arnd, bjorn.andersson, riteshh
In-Reply-To: <1479863388-23678-6-git-send-email-jeremymc@redhat.com>
On Tue, 22 Nov 2016 17:09:48 -0800
Jeremy McNicoll <jeremymc@redhat.com> wrote:
> On msm8992 it has been observed that IRQs were not getting
> ACK'd correctly when clocked at speeds greater than 400KHz.
>
> Signed-off-by: Jeremy McNicoll <jeremymc@redhat.com>
> ---
> drivers/mmc/host/sdhci-msm.c | 7 +++++++
> drivers/mmc/host/sdhci.c | 12 ++++++++++--
> drivers/mmc/host/sdhci.h | 2 ++
> 3 files changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index 1fcda96..459003c 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -1303,6 +1303,13 @@ static int sdhci_msm_probe(struct platform_device *pdev)
> CORE_VENDOR_SPEC_CAPABILITIES0);
> }
>
> + /* Enable delayed IRQ handling workaround on 8992 */
> + if (core_major == 1 && core_minor == 0x3e) {
> + /* Add 40us delay in interrupt handler when operating
> + * at initialization frequency of 400KHz. */
> + host->quirks2 |= SDHCI_QUIRK2_SLOW_INT_CLR;
> + }
> +
> /* Setup IRQ for handling power/voltage tasks with PMIC */
> msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq");
> if (msm_host->pwr_irq < 0) {
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 5911f98..c1aae22 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -2703,11 +2703,19 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
> result = IRQ_WAKE_THREAD;
> }
>
> - if (intmask & SDHCI_INT_CMD_MASK)
> + if (intmask & SDHCI_INT_CMD_MASK) {
> + if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
> + udelay(40);
> + }
> sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
> + }
>
> - if (intmask & SDHCI_INT_DATA_MASK)
> + if (intmask & SDHCI_INT_DATA_MASK) {
> + if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
> + udelay(40);
> + }
> sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
> + }
>
> if (intmask & SDHCI_INT_BUS_POWER)
> pr_err("%s: Card is consuming too much power!\n",
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index c055e24..5f8301e 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -24,6 +24,8 @@
> * Controller registers
> */
>
> +#define SDHCI_QUIRK2_SLOW_INT_CLR (1<<5)
IIRC, new quirk isn't allowed now.
Thanks,
Jisheng
^ permalink raw reply
* Re: [PATCH v2 4/5] arm: dts: am57xx-beagle-x15-common: Add overide powerhold property
From: Keerthy @ 2016-11-23 3:35 UTC (permalink / raw)
To: Tony Lindgren, lee.jones-QSEj5FYQhm4dnm+yROfE0A
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-gpio-u79uwXL29TY76Z2rM5mHXA, nm-l0cyMroinI0,
t-kristo-l0cyMroinI0
In-Reply-To: <20161115000849.GD4082-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
On Tuesday 15 November 2016 05:38 AM, Tony Lindgren wrote:
> * Keerthy <j-keerthy-l0cyMroinI0@public.gmane.org> [161109 21:10]:
>> The PMICs have POWERHOLD set by default which prevents PMIC shutdown
>> even on DEV_CTRL On bit set to 0 as the Powerhold has higher priority.
>> So to enable pmic power off this property lets one over ride the default
>> value and enable pmic power off.
>
> This should not cause merge conflicts so probably best to merge along
> with the driver changes:
>
> Acked-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
>
> If you guys want me to pick up this separately let me know.
Hi Lee Jones,
Are you planning to pull DT and Documentation patches as well?
Regards,
Keerthy
>
> Regards,
>
> Tony
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 3/3] ARM: dts: da850: Add node for pullup/pulldown pinconf
From: David Lechner @ 2016-11-23 3:29 UTC (permalink / raw)
To: Linus Walleij, Rob Herring, Mark Rutland, Sekhar Nori,
Kevin Hilman
Cc: David Lechner, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel, Axel Haslam, Alexandre Bailon,
Bartosz Gołaszewski
In-Reply-To: <1479871767-20160-1-git-send-email-david@lechnology.com>
This SoC has a separate pin controller for configuring pullup/pulldown
bias on groups of pins.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/boot/dts/da850.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 8945815..1c0224c 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -210,6 +210,11 @@
};
};
+ pinconf: pin-controller@22c00c {
+ compatible = "ti,da850-pupd";
+ reg = <0x22c00c 0x8>;
+ status = "disabled";
+ };
prictrl: priority-controller@14110 {
compatible = "ti,da850-mstpri";
reg = <0x14110 0x0c>;
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3] pinctrl: New driver for TI DA8XX/OMAP-L138/AM18XX pinconf
From: David Lechner @ 2016-11-23 3:29 UTC (permalink / raw)
To: Linus Walleij, Rob Herring, Mark Rutland, Sekhar Nori,
Kevin Hilman
Cc: David Lechner, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel, Axel Haslam, Alexandre Bailon,
Bartosz Gołaszewski
In-Reply-To: <1479871767-20160-1-git-send-email-david@lechnology.com>
This adds a new driver for pinconf on TI DA8XX/OMAP-L138/AM18XX. These
SoCs have a separate controller for controlling pullup/pulldown groups.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/pinctrl/Kconfig | 9 ++
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-da850-pupd.c | 210 +++++++++++++++++++++++++++++++++++
3 files changed, 220 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-da850-pupd.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 5f40ad6..54044a8 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -93,6 +93,15 @@ config PINCTRL_AMD
Requires ACPI/FDT device enumeration code to set up a platform
device.
+config PINCTRL_DA850_PUPD
+ tristate "TI DA850/OMAP-L138/AM18XX pullup/pulldown groups"
+ depends on OF && (ARCH_DAVINCI_DA850 || COMPILE_TEST)
+ select PINCONF
+ select GENERIC_PINCONF
+ help
+ Driver for TI DA850/OMAP-L138/AM18XX pinconf. Used to control
+ pullup/pulldown pin groups.
+
config PINCTRL_DIGICOLOR
bool
depends on OF && (ARCH_DIGICOLOR || COMPILE_TEST)
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 3b8e6f7..25d50a8 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
+obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o
diff --git a/drivers/pinctrl/pinctrl-da850-pupd.c b/drivers/pinctrl/pinctrl-da850-pupd.c
new file mode 100644
index 0000000..0446df7
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-da850-pupd.c
@@ -0,0 +1,210 @@
+/*
+ * Pinconf driver for TI DA850/OMAP-L138/AM18XX pullup/pulldown groups
+ *
+ * Copyright (C) 2016 David Lechner
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+
+#define DA850_PUPD_ENA 0x00
+#define DA850_PUPD_SEL 0x04
+
+struct da850_pupd_data {
+ void __iomem *base;
+ struct pinctrl_desc desc;
+ struct pinctrl_dev *pinctrl;
+};
+
+static const char * const da850_pupd_group_names[] = {
+ "cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7",
+ "cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15",
+ "cp16", "cp17", "cp18", "cp19", "cp20", "cp21", "cp22", "cp23",
+ "cp24", "cp25", "cp26", "cp27", "cp28", "cp29", "cp30", "cp31",
+};
+
+static int da850_pupd_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ return ARRAY_SIZE(da850_pupd_group_names);
+}
+
+static const char *da850_pupd_get_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ return da850_pupd_group_names[selector];
+}
+
+static int da850_pupd_get_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+{
+ *num_pins = 0;
+
+ return 0;
+}
+
+static const struct pinctrl_ops da850_pupd_pctlops = {
+ .get_groups_count = da850_pupd_get_groups_count,
+ .get_group_name = da850_pupd_get_get_group_name,
+ .get_group_pins = da850_pupd_get_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
+ .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int da850_pupd_pin_config_group_get(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *config)
+{
+ struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 val;
+ u16 arg;
+
+ val = readl(data->base + DA850_PUPD_ENA);
+ arg = !!(~val & BIT(selector));
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg) {
+ /* bias is disabled */
+ arg = 0;
+ break;
+ }
+ val = readl(data->base + DA850_PUPD_SEL);
+ if (param == PIN_CONFIG_BIAS_PULL_DOWN)
+ val = ~val;
+ arg = !!(val & BIT(selector));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int da850_pupd_pin_config_group_set(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
+ u32 ena, sel;
+ enum pin_config_param param;
+ u16 arg;
+ int i;
+
+ ena = readl(data->base + DA850_PUPD_ENA);
+ sel = readl(data->base + DA850_PUPD_SEL);
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ ena &= ~BIT(selector);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ ena |= BIT(selector);
+ sel |= BIT(selector);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ ena |= BIT(selector);
+ sel &= ~BIT(selector);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ writel(sel, data->base + DA850_PUPD_SEL);
+ writel(ena, data->base + DA850_PUPD_ENA);
+
+ return 0;
+}
+
+static const struct pinconf_ops da850_pupd_confops = {
+ .is_generic = true,
+ .pin_config_group_get = da850_pupd_pin_config_group_get,
+ .pin_config_group_set = da850_pupd_pin_config_group_set,
+};
+
+static int da850_pupd_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct da850_pupd_data *data;
+ struct resource *res;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ data->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(data->base)) {
+ dev_err(dev, "Could not map resource\n");
+ return PTR_ERR(data->base);
+ }
+
+ data->desc.name = dev_name(dev);
+ data->desc.pctlops = &da850_pupd_pctlops;
+ data->desc.confops = &da850_pupd_confops;
+ data->desc.owner = THIS_MODULE;
+
+ data->pinctrl = devm_pinctrl_register(dev, &data->desc, data);
+ if (IS_ERR(data->pinctrl)) {
+ dev_err(dev, "Failed to register pinctrl\n");
+ return PTR_ERR(data->pinctrl);
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int da850_pupd_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct of_device_id da850_pupd_of_match[] = {
+ { .compatible = "ti,da850-pupd" },
+ { }
+};
+
+static struct platform_driver da850_pupd_driver = {
+ .driver = {
+ .name = "ti-da850-pupd",
+ .of_match_table = da850_pupd_of_match,
+ },
+ .probe = da850_pupd_probe,
+ .remove = da850_pupd_remove,
+};
+module_platform_driver(da850_pupd_driver);
+
+MODULE_AUTHOR("David Lechner <david@lechnology.com>");
+MODULE_DESCRIPTION("TI DA850/OMAP-L138/AM18XX pullup/pulldown configuration");
+MODULE_LICENSE("GPL");
--
2.7.4
^ permalink raw reply related
* [PATCH 1/3] devicetree: bindings: pinctrl: Add binding for ti,da850-pupd
From: David Lechner @ 2016-11-23 3:29 UTC (permalink / raw)
To: Linus Walleij, Rob Herring, Mark Rutland, Sekhar Nori,
Kevin Hilman
Cc: David Lechner, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel, Axel Haslam, Alexandre Bailon,
Bartosz Gołaszewski
In-Reply-To: <1479871767-20160-1-git-send-email-david@lechnology.com>
Device-tree bindings for TI DA8XX/OMAP-L138/AM18XX pullup/pulldown
pinconf controller.
Signed-off-by: David Lechner <david@lechnology.com>
---
.../devicetree/bindings/pinctrl/ti,da850-pupd.txt | 55 ++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
diff --git a/Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt b/Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
new file mode 100644
index 0000000..7f29805
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
@@ -0,0 +1,55 @@
+* Pin configuration for TI DA850/OMAP-L138/AM18x
+
+These SoCs have a separate controller for setting bias (internal pullup/down).
+Bias can only be selected for groups rather than individual pins.
+
+Required Properties:
+
+ - compatible: Must be "ti,da850-pupd"
+ - reg: Base address and length of the memory resource used by the pullup/down
+ controller hardware module.
+
+The controller node also acts as a container for pin group configuration nodes.
+The names of these groups are ignored.
+
+Pin Group Node Properties:
+
+- groups: An array of strings, each string containing the name of a pin group.
+ Valid names are "cp0".."cp31".
+
+The pin configuration parameters use the generic pinconf bindings defined in
+pinctrl-bindings.txt in this directory. The supported parameters are
+bias-disable, bias-pull-up, bias-pull-down.
+
+
+Example
+-------
+
+In common dtsi file:
+
+ pinconf: pin-controller@22c00c {
+ compatible = "ti,da850-pupd";
+ reg = <0x22c00c 0x8>;
+ };
+
+In board-specific file:
+
+ &pinconf {
+ pinctrl-0 = <&pinconf_bias_groups>;
+ pinctrl-names = "default";
+
+ pinconf_bias_groups: bias-groups {
+ pull-up {
+ groups = "cp30", "cp31";
+ bias-pull-up;
+ };
+ pull-down {
+ groups = "cp29", "cp28";
+ bias-pull-down;
+ };
+ disable {
+ groups = "cp27", "cp26";
+ bias-disable;
+ };
+ };
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH 0/3] TI DA850/OMAP-L138/AM18x pinconf
From: David Lechner @ 2016-11-23 3:29 UTC (permalink / raw)
To: Linus Walleij, Rob Herring, Mark Rutland, Sekhar Nori,
Kevin Hilman
Cc: David Lechner, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel, Axel Haslam, Alexandre Bailon,
Bartosz Gołaszewski
This series adds a new driver and DT bindings for TI DA850/OMAP-L138/AM18x
pinconf (bias pullup/pulldown).
The motivation for this series is LEGO MINDSTORMS EV3 support. It needs most,
if not all, internal pullup/down resistors disabled in order to work correctly.
David Lechner (3):
devicetree: bindings: pinctrl: Add binding for ti,da850-pupd
pinctrl: New driver for TI DA8XX/OMAP-L138/AM18XX pinconf
ARM: dts: da850: Add node for pullup/pulldown pinconf
.../devicetree/bindings/pinctrl/ti,da850-pupd.txt | 55 ++++++
arch/arm/boot/dts/da850.dtsi | 5 +
drivers/pinctrl/Kconfig | 9 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-da850-pupd.c | 210 +++++++++++++++++++++
5 files changed, 280 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/ti,da850-pupd.txt
create mode 100644 drivers/pinctrl/pinctrl-da850-pupd.c
--
2.7.4
^ permalink raw reply
* Re: [PATCH 1/2] PM / Domains: Introduce domain-performance-state binding
From: Viresh Kumar @ 2016-11-23 3:22 UTC (permalink / raw)
To: Vincent Guittot
Cc: Kevin Hilman, Rob Herring, Rafael Wysocki,
linaro-kernel-cunTk1MwBs8s++Sfvej+rw@public.gmane.org,
linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel,
Mark Rutland, Ulf Hansson, Lina Iyer,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Stephen Boyd,
Nayak Rajendra
In-Reply-To: <CAKfTPtDR6Y5UgaqJ+D5T0yBeFRSYWm6OT1+r4ZABrtqtvF2D0w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Thanks for explaining on my behalf Vincent :)
On 22-11-16, 19:34, Vincent Guittot wrote:
> On 22 November 2016 at 19:12, Kevin Hilman <khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> wrote:
> > I think the question is: what does the performance-level of a domain
> > actually mean? Or, what are the units?
There is no unit. If we have units like Hz and volts etc, then we can actually
use the existing clk/regulator frameworks straight away.
The whole problem here is that the regulator (and maybe the clock on a different
platform) for a power domain are hidden from the kernel and handled by a black
box (An M3 core in my case). All we can ask is for a performance state, a simple
positive integer value.
> > Depending on the SoC, there's probably a few things this could mean. It
> > might mean is that an underlying bus/interconnect can be configured to
> > guarantee a specific bandwidth or throughput.
We are talking in terms of power domains here and so if the bus/interconnect has
a power domain for itself, then yes we can very much have that situation. But if
the kernel have the capability of configuring clk and voltages directly, then we
don't need this new infrastructure at all.
> > That in turn might mean
> > that that bus/interconnect might have to be set at a specific
> > frequency/voltage.
> >
> > In your case, IIUC, you're just passing some magic value to some
> > firmware running on a micro-controller, but under the hood that uC is
> > probably configuring a frequency/voltage someplace.
>
> In the case described by Viresh, it's only about setting the voltage
> of a power domain that is shared between different devices. these
> devices wants to run at different frequency (set by the devices) but
> we have to select a Volateg value that will match with the constraint
> of all devices (in this case the highest voltage)
That's right.
> > So, if we're going to have a generic DT binding for this, it needs to be
> > something that's useful on platforms that are not using magic numbers
> > managed by a uC as well.
What suggestions do you have for this and I am not sure what all cases we want
to solve by this ?
--
viresh
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC] Documentation: media, leds: move IR LED remote controllers from media to LED
From: Andi Shyti @ 2016-11-23 2:28 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Rob Herring, Jacek Anaszewski, linux-leds, linux-media,
devicetree
In-Reply-To: <20161122121440.627f1c16@vento.lan>
Hi Mauro,
> > this is purely a request for comments after a discussion had with
> > Rob and Jacek [*] about where to place the ir leds binding. Rob wants
> > the binding to be under led, while Jacek wants it in media...
> > "Ubi maior minor cessat": it goes to LED and they can be organized
> > in a subdirectory.
> >
> > Standing to Rob "Bindings are grouped by types of h/w and IR LEDs
> > are a type of LED": all remote controllers have an IR LED as core
> > device, even though the framework is under drivers/media/rc/, thus
> > they naturally belong to the LED binding group.
> >
> > Please, let me know if this is the right approach.
>
> IMHO, this is wrong.
>
> Ok, if you look at just the diode, the physics of an IR Light-emitting Diode
> (LED) is identical to the one for a visible light LED, just like the physics
> of the LED diodes inside a display. Btw, the physics of an IR detector
> diode is almost identical to the physics of a LED.
>
> Yet, the hardware where those diodes are connected are very different,
> and so their purpose.
>
> The same way I don't think it would make sense to represent a LED
> display using the same approach as a flash light, I don't think we
> should to it for IR LEDs.
>
> A visible light LED is used either to work as a flash light for a camera
> or as a way to indicate a status. No machine2machine protocol there.
> The circuitry for them is usually just a gatway that will turn it on
> or off.
>
> With regards to the IR hardware, an IR LED is used for machine2machine
> signaling. It is part of a modulator circuit that uses a carrier of about
> 40kHz to modulate 16 or 32 bits words.
>
> The IR device hardware usually also have another diode (the IR detector)
> that receives IR rays. Visually, they look identical.
>
> IMHO, it makes much more sense to keep both IR detector and light-emitting
> diodes described together, as they are part of the same circuitry and
> have a way more similarities than a flash light or a LED display.
thanks for the reply, I agree with you, that's why I first put
the ir-spi of tm2 in the media directory where all the ir leds
devices are. That's what Jacek recommended and what you are
recommending (that's also why this is an RFC and not a patch).
Rob, if I place the tm2 ir-spi in the led bindings in a
sub-directory it will be the only device there for the time
being. But the ir-spi it's not unique in its kind, there are many
others and they are all under the media directory. My opinion is
that all the ir-leds devices should be in the same place.
Would, then, make sense to split the ir-leds devices in two
different locations?
Would it be a valid alternative to create instead an 'rc'
directory for the ir-leds bindings that can either be under
media or in the higher directory?
Thanks,
Andi
^ permalink raw reply
* Re: [PATCH v6 3/3] arm: dts: mt2701: Add node for Mediatek JPEG Decoder
From: Rick Chang @ 2016-11-23 1:54 UTC (permalink / raw)
To: Hans Verkuil
Cc: Hans Verkuil, Laurent Pinchart, Mauro Carvalho Chehab,
Matthias Brugger, Rob Herring, linux-kernel, linux-media,
srv_heupstream, linux-mediatek, linux-arm-kernel, devicetree,
Minghsiu Tsai
In-Reply-To: <badf8125-27ed-9c5b-fbc0-75716ffdfb0e@xs4all.nl>
Hi Hans,
On Tue, 2016-11-22 at 13:43 +0100, Hans Verkuil wrote:
> On 22/11/16 04:21, Rick Chang wrote:
> > Hi Hans,
> >
> > On Mon, 2016-11-21 at 15:51 +0100, Hans Verkuil wrote:
> >> On 17/11/16 04:38, Rick Chang wrote:
> >>> Signed-off-by: Rick Chang <rick.chang@mediatek.com>
> >>> Signed-off-by: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
> >>> ---
> >>> This patch depends on:
> >>> CCF "Add clock support for Mediatek MT2701"[1]
> >>> iommu and smi "Add the dtsi node of iommu and smi for mt2701"[2]
> >>>
> >>> [1] http://lists.infradead.org/pipermail/linux-mediatek/2016-October/007271.html
> >>> [2] https://patchwork.kernel.org/patch/9164013/
> >>
> >> I assume that 1 & 2 will appear in 4.10? So this patch needs to go in
> >> after the
> >> other two are merged in 4.10?
> >>
> >> Regards,
> >>
> >> Hans
> >
> > [1] will appear in 4.10, but [2] will appear latter than 4.10.So this
> > patch needs to go in after [1] & [2] will be merged in 4.11.
>
> So what should I do? Merge the driver for 4.11 and wait with this patch
> until [2] is merged in 4.11? Does that sound reasonable?
>
> Regards,
>
> Hans
What do you think about this? You merge the driver first and I send this
patch again after [1] & [2] is merged.
^ permalink raw reply
* Re: [PATCH RFC] ARM: dts: add support for Turris Omnia
From: Andrew Lunn @ 2016-11-23 1:39 UTC (permalink / raw)
To: tomas.hlavacek-x+rMaJPWets
Cc: Uwe Kleine-König, Mark Rutland, marex-ynQEQJNshbs,
Jason Cooper, devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
Gregory Clement,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Sebastian Hesselbarth
In-Reply-To: <1479860851.10840.11-TAvD023jEQEN+BqQ9rBEUg@public.gmane.org>
On Wed, Nov 23, 2016 at 01:27:31AM +0100, tomas.hlavacek-x+rMaJPWets@public.gmane.org wrote:
> Hi Uwe!
>
> On Tue, Nov 22, 2016 at 10:59 PM, tomas.hlavacek-x+rMaJPWets@public.gmane.org wrote:
> >Anyway I took your patch and tried few things:
> >- add pca9538 interrupt-controller
> >- add IRQ for 88E1514 PHY - and there is a problem:
> ...
>
> I thought it over and if I am not mistaken this is not going to work
> anyway, because pca9538 driver causes the GPIO driver to set
> IRQ_NESTED_THREAD, so we can not simply use one of the GPIO expander
> pins as IRQ source for 88E1514, because request_irq() on it will
> fail ultimately.
Actually, the phylib now does uses threaded IRQs, since i implemented
interrupt support for the mv88e6xxx driver. Its interrupts require
MDIO transactions, so have to be threaded.
However, i don't think using interrupts on the pca9538 are
reliable. Interrupt support is compile time optional for that
driver. It is not clear to me if distributions do compile the driver
with interrupts enabled. So it could be the probe fails with OpenWRT,
Debian, etc...
Andrew
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 5/5] sdhci: Add quirk for delayed IRQ ACK
From: Jeremy McNicoll @ 2016-11-23 1:09 UTC (permalink / raw)
To: linux-arm-msm, linux-soc, devicetree, linux-mmc
Cc: andy.gross, sboyd, robh, arnd, bjorn.andersson, riteshh, jeremymc
In-Reply-To: <1479863388-23678-1-git-send-email-jeremymc@redhat.com>
On msm8992 it has been observed that IRQs were not getting
ACK'd correctly when clocked at speeds greater than 400KHz.
Signed-off-by: Jeremy McNicoll <jeremymc@redhat.com>
---
drivers/mmc/host/sdhci-msm.c | 7 +++++++
drivers/mmc/host/sdhci.c | 12 ++++++++++--
drivers/mmc/host/sdhci.h | 2 ++
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 1fcda96..459003c 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1303,6 +1303,13 @@ static int sdhci_msm_probe(struct platform_device *pdev)
CORE_VENDOR_SPEC_CAPABILITIES0);
}
+ /* Enable delayed IRQ handling workaround on 8992 */
+ if (core_major == 1 && core_minor == 0x3e) {
+ /* Add 40us delay in interrupt handler when operating
+ * at initialization frequency of 400KHz. */
+ host->quirks2 |= SDHCI_QUIRK2_SLOW_INT_CLR;
+ }
+
/* Setup IRQ for handling power/voltage tasks with PMIC */
msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq");
if (msm_host->pwr_irq < 0) {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5911f98..c1aae22 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2703,11 +2703,19 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
result = IRQ_WAKE_THREAD;
}
- if (intmask & SDHCI_INT_CMD_MASK)
+ if (intmask & SDHCI_INT_CMD_MASK) {
+ if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
+ udelay(40);
+ }
sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
+ }
- if (intmask & SDHCI_INT_DATA_MASK)
+ if (intmask & SDHCI_INT_DATA_MASK) {
+ if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
+ udelay(40);
+ }
sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
+ }
if (intmask & SDHCI_INT_BUS_POWER)
pr_err("%s: Card is consuming too much power!\n",
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index c055e24..5f8301e 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -24,6 +24,8 @@
* Controller registers
*/
+#define SDHCI_QUIRK2_SLOW_INT_CLR (1<<5)
+
#define SDHCI_DMA_ADDRESS 0x00
#define SDHCI_ARGUMENT2 SDHCI_DMA_ADDRESS
--
2.6.1
^ permalink raw reply related
* [PATCH 4/5] sdhci: dump vendor state and regs
From: Jeremy McNicoll @ 2016-11-23 1:09 UTC (permalink / raw)
To: linux-arm-msm, linux-soc, devicetree, linux-mmc
Cc: andy.gross, sboyd, robh, arnd, bjorn.andersson, riteshh, jeremymc
In-Reply-To: <1479863388-23678-1-git-send-email-jeremymc@redhat.com>
This has proven very useful in debugging SDHCI RPM interaction
issues.
Signed-off-by: Jeremy McNicoll <jeremymc@redhat.com>
---
drivers/mmc/host/sdhci-msm.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
drivers/mmc/host/sdhci.c | 25 ++++++++++++++
drivers/mmc/host/sdhci.h | 1 +
3 files changed, 105 insertions(+)
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index ee01d95..1fcda96 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -678,6 +678,84 @@ static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host)
return ret;
}
+
+
+#define MAX_TEST_BUS 20
+#define CORE_MCI_DATA_CNT 0x30
+#define CORE_MCI_FIFO_CNT 0x44
+#define CORE_MCI_STATUS 0x34
+#define CORE_VENDOR_SPEC_ADMA_ERR_ADDR0 0x114
+#define CORE_VENDOR_SPEC_ADMA_ERR_ADDR1 0x118
+#define CORE_TESTBUS_SEL2_BIT 4
+#define CORE_TESTBUS_SEL2 (1 << CORE_TESTBUS_SEL2_BIT)
+
+#define CORE_TESTBUS_ENA (1 << 3)
+
+#define CORE_TESTBUS_CONFIG 0x0CC
+
+#define CORE_SDCC_DEBUG_REG 0x124
+
+void sdhci_msm_dump_vendor_regs(struct sdhci_host *host)
+{
+
+ int tbsel, tbsel2;
+ int i, index = 0;
+ u32 test_bus_val = 0;
+ u32 debug_reg[MAX_TEST_BUS] = {0};
+ struct sdhci_pltfm_host *pltfm_host;
+ struct sdhci_msm_host *msm_host;
+
+ pltfm_host = sdhci_priv(host);
+ msm_host = sdhci_pltfm_priv(pltfm_host);
+
+ pr_info("----------- VENDOR REGISTER DUMP -----------\n");
+ pr_info("Data cnt: 0x%08x | Fifo cnt: 0x%08x | Int sts: 0x%08x\n",
+ readl_relaxed(msm_host->core_mem + CORE_MCI_DATA_CNT),
+ readl_relaxed(msm_host->core_mem + CORE_MCI_FIFO_CNT),
+ readl_relaxed(msm_host->core_mem + CORE_MCI_STATUS));
+ pr_info("DLL cfg: 0x%08x | DLL sts: 0x%08x | SDCC ver: 0x%08x\n",
+ readl_relaxed(host->ioaddr + CORE_DLL_CONFIG),
+ readl_relaxed(host->ioaddr + CORE_DLL_STATUS),
+ readl_relaxed(msm_host->core_mem + CORE_MCI_VERSION));
+ pr_info("Vndr func: 0x%08x | Vndr adma err : addr0: 0x%08x addr1: 0x%08x\n",
+ readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC),
+ readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_ADMA_ERR_ADDR0),
+ readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_ADMA_ERR_ADDR1));
+
+ /*
+ * tbsel indicates [2:0] bits and tbsel2 indicates [7:4] bits
+ * of CORE_TESTBUS_CONFIG register.
+ *
+ * To select test bus 0 to 7 use tbsel and to select any test bus
+ * above 7 use (tbsel2 | tbsel) to get the test bus number. For eg,
+ * to select test bus 14, write 0x1E to CORE_TESTBUS_CONFIG register
+ * i.e., tbsel2[7:4] = 0001, tbsel[2:0] = 110.
+ */
+ for (tbsel2 = 0; tbsel2 < 3; tbsel2++) {
+ for (tbsel = 0; tbsel < 8; tbsel++) {
+ if (index >= MAX_TEST_BUS)
+ break;
+ test_bus_val = (tbsel2 << CORE_TESTBUS_SEL2_BIT) |
+ tbsel | CORE_TESTBUS_ENA;
+ writel_relaxed(test_bus_val,
+ msm_host->core_mem + CORE_TESTBUS_CONFIG);
+ debug_reg[index++] = readl_relaxed(msm_host->core_mem +
+ CORE_SDCC_DEBUG_REG);
+ }
+ }
+
+ for (i = 0; i < MAX_TEST_BUS; i = i + 4)
+ pr_info(" Test bus[%d to %d]: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ i, i + 3, debug_reg[i], debug_reg[i+1],
+ debug_reg[i+2], debug_reg[i+3]);
+ /* Disable test bus */
+ writel_relaxed(~CORE_TESTBUS_ENA, msm_host->core_mem +
+ CORE_TESTBUS_CONFIG);
+}
+
+
+
+
static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
{
int tuning_seq_cnt = 3;
@@ -1081,6 +1159,7 @@ static const struct sdhci_ops sdhci_msm_ops = {
.set_bus_width = sdhci_set_bus_width,
.set_uhs_signaling = sdhci_msm_set_uhs_signaling,
.voltage_switch = sdhci_msm_voltage_switch,
+ .dump_vendor_regs = sdhci_msm_dump_vendor_regs,
};
static const struct sdhci_pltfm_data sdhci_msm_pdata = {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 71654b9..5911f98 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -47,6 +47,27 @@ static void sdhci_finish_data(struct sdhci_host *);
static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
+static void sdhci_dump_rpm_info(struct sdhci_host *host)
+{
+ struct mmc_host *mmc = host->mmc;
+
+ pr_info("%s: rpmstatus[pltfm](runtime-suspend:usage_count:disable_depth)(%d:%d:%d)\n",
+ mmc_hostname(mmc), mmc->parent->power.runtime_status,
+ atomic_read(&mmc->parent->power.usage_count),
+ mmc->parent->power.disable_depth);
+}
+
+
+static void sdhci_dump_state(struct sdhci_host *host)
+{
+ struct mmc_host *mmc = host->mmc;
+
+ pr_info("%s: clk: %d claimer: %s pwr: %d\n",
+ mmc_hostname(mmc), host->clock,
+ mmc->claimer->comm, host->pwr);
+ sdhci_dump_rpm_info(host);
+}
+
static void sdhci_dumpregs(struct sdhci_host *host)
{
pr_err(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
@@ -100,6 +121,10 @@ static void sdhci_dumpregs(struct sdhci_host *host)
readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
}
+ if (host->ops->dump_vendor_regs)
+ host->ops->dump_vendor_regs(host);
+
+ sdhci_dump_state(host);
pr_err(DRIVER_NAME ": ===========================================\n");
}
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 766df17..c055e24 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -563,6 +563,7 @@ struct sdhci_ops {
struct mmc_card *card,
unsigned int max_dtr, int host_drv,
int card_drv, int *drv_type);
+ void (*dump_vendor_regs)(struct sdhci_host *host);
};
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
--
2.6.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox