* [PATCH] ARM: dts: imx6q-cm-fx6: enable S/PDIF support
From: christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg @ 2016-11-23 0:07 UTC (permalink / raw)
To: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linux-I+IVW8TIWO2tmTQ+vhA3Yw,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
grinberg-UTxiZqZC01RS1MOuV/RT9w, fabio.estevam-3arQi8VN3Tc,
christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg
From: Christopher Spinrath <christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org>
Enable the S/PDIF transceiver present on the cm-fx6 module.
Signed-off-by: Christopher Spinrath <christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org>
---
arch/arm/boot/dts/imx6q-cm-fx6.dts | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts
index cad1dc5..42b1031 100644
--- a/arch/arm/boot/dts/imx6q-cm-fx6.dts
+++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts
@@ -89,6 +89,14 @@
gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-out;
+ spdif-in;
+ };
};
&cpu0 {
@@ -222,6 +230,13 @@
>;
};
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0
+ MX6QDL_PAD_GPIO_19__SPDIF_OUT 0x1b0b0
+ >;
+ };
+
pinctrl_uart4: uart4grp {
fsl,pins = <
MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
@@ -259,6 +274,12 @@
status = "okay";
};
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ status = "okay";
+};
+
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart4>;
--
2.10.2
--
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 related
* Re: [PATCH v9 00/16] mmc: sdhci-msm: Add clk-rates, DDR, HS400 support
From: Ritesh Harjani @ 2016-11-23 0:05 UTC (permalink / raw)
To: Stephen Boyd, Ulf Hansson, Andy Gross
Cc: linux-mmc, Adrian Hunter, 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, Pramod Gurav, jeremymc
In-Reply-To: <20161121231138.GY25626@codeaurora.org>
On 11/22/2016 4:41 AM, Stephen Boyd wrote:
> On 11/21, Ritesh Harjani wrote:
>>
>>
>> On 11/21/2016 3:36 PM, 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?
>> Yes.
>>
>>>
>>> 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....
>> Ideal and preferable, would be that clk & mmc changes go in
>> together. But either ways should be fine.
>>
>
> There's only a runtime dependency where the clk rates will be
> wrong if clk tree isn't merged. I'd rather just apply the clk
> ones directly to clk tree and let all three trees come together
> in linux-next and work.
Ok great! So can we queue this patch series to next?
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v2] ARM: dts: da850: add the mstpri and ddrctl nodes
From: David Lechner @ 2016-11-22 22:23 UTC (permalink / raw)
To: Bartosz Golaszewski, Kevin Hilman, Michael Turquette, Sekhar Nori,
Rob Herring, Frank Rowand, Mark Rutland, Peter Ujfalusi,
Russell King
Cc: linux-devicetree, David Airlie, LKML, linux-drm, Tomi Valkeinen,
Jyri Sarha, arm-soc, Laurent Pinchart
In-Reply-To: <1479207611-18028-1-git-send-email-bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 11/15/2016 05:00 AM, Bartosz Golaszewski wrote:
> Add the nodes for the MSTPRI configuration and DDR2/mDDR memory
> controller drivers to da850.dtsi.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> v1 -> v2:
> - moved the priority controller node above the cfgchip node
> - renamed added nodes to better reflect their purpose
>
> arch/arm/boot/dts/da850.dtsi | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index 1bb1f6d..412eec6 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -210,6 +210,10 @@
> };
>
> };
> + prictrl: priority-controller@14110 {
> + compatible = "ti,da850-mstpri";
> + reg = <0x14110 0x0c>;
I think we should add status = "disabled"; here and let boards opt in.
> + };
> cfgchip: chip-controller@1417c {
> compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
> reg = <0x1417c 0x14>;
> @@ -451,4 +455,8 @@
> 1 0 0x68000000 0x00008000>;
> status = "disabled";
> };
> + memctrl: memory-controller@b0000000 {
> + compatible = "ti,da850-ddr-controller";
> + reg = <0xb0000000 0xe8>;
same here. status = "disabled";
> + };
> };
>
--
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 3/3] ARM64: dts: meson-gxbb: add the USB reset also to the second USB PHY
From: Martin Blumenstingl @ 2016-11-22 22:05 UTC (permalink / raw)
To: Kevin Hilman
Cc: p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, kishon-l0cyMroinI0,
carlo-KA+7E9HrN00dnm+yROfE0A, will.deacon-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <m2eg2437za.fsf-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On Mon, Nov 21, 2016 at 9:15 PM, Kevin Hilman <khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> wrote:
> Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> writes:
>
>> Hi Kevin,
>>
>> On Wed, Nov 16, 2016 at 10:35 PM, Kevin Hilman <khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> wrote:
>>> Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> writes:
>>>
>>>> When the USB PHY driver was introduced the reset framework did not
>>>> have support for triggering a reset pulse for shared resets. On GXBB
>>>> however there is only one reset line for both PHYs (meaning we have a
>>>> shared reset line). With the latest changes to the reset framework and
>>>> the corresponding updates to the phy-meson8b-usb2 driver we can now pass
>>>> the reset to the second PHY as well.
>>>>
>>>> Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>>>
>>> Applied.
>> Unfortunately I think I put crucial information only in the
>> cover-letter's description:
>> "the dts patch has a runtime-dependency on patch 1 and 2"
>
> I saw that, but also see that both of those have been queued, so should
> land in v4.10 also.
>
>> So please feel free to keep or drop the patch as it is. In case you
>> decide drop it I will re-send it for 4.11 (after all the 4.10 stuff is
>> done).
>
> IMO, it's fine to keep it. That means there may be some versions of
> linux-next that have the problem where the reset will get asserted
> twice, but since that is affecting very few people (probably only you),
> I think it's OK, since it will be fine once v4.10-rc1 is released.
fine with me, just wanted to let you know (so you're aware of it in
case someone runs into an issue with this)
> If you don't want that, let me know and I'll drop it for now.
let's keep it - this will mean that more users will test it :)
Martin
--
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 RFC] ARM: dts: add support for Turris Omnia
From: tomas.hlavacek @ 2016-11-22 21:59 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Mark Rutland, Andrew Lunn, marex, Jason Cooper, devicetree,
Rob Herring, Gregory Clement, linux-arm-kernel,
Sebastian Hesselbarth
In-Reply-To: <20161120203037.pd5mhqyjeotileve@perseus.defre.kleine-koenig.org>
Hi Uwe!
On Sun, Nov 20, 2016 at 9:30 PM, Uwe Kleine-König
<uwe@kleine-koenig.org> wrote:
> Hello Tomas,
>
> On Sat, Nov 19, 2016 at 09:09:07PM +0100, tomas.hlavacek@nic.cz wrote:
>> On Mon, Nov 14, 2016 at 9:28 PM, Andrew Lunn <andrew@lunn.ch> wrote:
>> > Interrupts don't seem to work very well with the nxp,pca9538.
>> Which
>> > is probably why it is disabled by default.
>>
>> I was thinking about this issue and I can remember that there was
>> an earlier
>> prototype that had a shared interrupt line from PHY (88E1514) and
>> from the
>> PCA9538. In this case we needed to specifically disable the
>> interrupt of the
>> PHY to release the interrupt line (which needed a hack into PHY
>> driver
>> code). The IRQ from PHY is connected as an ordinary input to
>> PCA9538 in
>> later board prototype. And the same holds for the production
>> version.
>
> That would explain why I see an "irq but nobody cared" message when
> booting the original system.
>
> This isn't the problem I meant though. When adding interrupt-parent =
> <&pcawan>; interrupts = <7 IRQ_TYPE_LEVEL_LOW>; to the phy node I get
> an
> error saying that there is no irq domain associated with this device.
>
>> Do you have CZ11NIC13 or older board revision?
>
> CZ11NIC12 is indicated on my board.
:-( Well, this board version has wrongly matched length of some
differential pairs, IRQ from 88E1514 is connected differently, there
are slight differences in power supplies and (if I am not mistaken)
something changed in RTC support circuitry. It looks like a huge
mistake on our side.
Anyway I took your patch and tried few things:
- clean up comments
- add pca9538 interrupt-controller
- remove rtc disable (WFM with CZ11NIC13, which is the production board)
- add MBUS mem regions for CESA
- add IRQ for 88E1514 PHY - and there is a problem:
It seems that libphy is probed before pca9538 and we end up with:
[ 4.217550] libphy: orion_mdio_bus: probed
[ 4.221777] irq: no irq domain found for
/soc/internal-regs/i2c@11000/i2cmux@70/i2c@7/gpio@71 !
Any clue where to look in order to defer probing libphy or at least
orion_mdio_bus?
I'll post my version of the patch without the PHY IRQ (therefore
polling will kick in).
Thanks,
Tomas
^ permalink raw reply
* Re: [PATCH v2 2/4] usb: dwc2: Add binding for AHB burst
From: Rob Herring @ 2016-11-22 21:46 UTC (permalink / raw)
To: Christian Lamparter
Cc: Stefan Wahren, Felipe Balbi, devicetree@vger.kernel.org,
linux-usb@vger.kernel.org, John Youn, Paul Mackerras,
Mark Rutland, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1495076.fZ1uLW9fli@debian64>
On Tue, Nov 22, 2016 at 2:51 PM, Christian Lamparter
<chunkeey@googlemail.com> wrote:
> On Monday, November 21, 2016 7:32:30 PM CET John Youn wrote:
>> On 11/21/2016 1:10 PM, Christian Lamparter wrote:
>> > On Monday, November 21, 2016 12:16:31 PM CET John Youn wrote:
>> >> On 11/18/2016 12:18 PM, Christian Lamparter wrote:
>> >>> On Friday, November 18, 2016 8:16:08 AM CET Rob Herring wrote:
>> >>>> Also, perhaps you should allow that the compatible string can define the
>> >>>> default.
>> >>>>
>> >>> I hoped you would say that :).
>> >>>
>> >>> I've attached a patch (on top of John Youn changes) [...]
>> >>> ---
>> >>> Subject: [PATCH] usb: dwc2: add a default ahb-burst setting for amcc,dwc-otg
>> >>> [...]
>> >>> @@ -1097,6 +1097,22 @@ static const char *const ahb_bursts[] = {
>> >>> +/* [...] */
>> >>> +static const struct of_device_id dwc2_compat_ahb_bursts[] = {
>> >>> + {
>> >>> + .compatible = "amcc,dwc-otg",
>> >>> + .data = (void *) GAHBCFG_HBSTLEN_INCR16,
>> >>> + },
>> >>> +};
>> [...]
>> > >>> @@ -1107,6 +1123,12 @@ static int dwc2_get_property_ahb_burst(struct dwc2_hsotg *hsotg)
>> >>> ret = device_property_read_string(hsotg->dev, "snps,ahb-burst", &str);
>> >>> if (ret < 0) {
>> >>> + const struct of_device_id *match;
>> >>> +
>> >>> + match = of_match_node(dwc2_compat_ahb_bursts, node);
>> >>> + if (match)
>> >>> + ret = (int)match->data;
>> >>> +
>> [...]
>> >> I'd prefer if you use the binding which requires no extra code in
>> >> dwc2.
>> > I'm fine with either option. However it think that this would require
>> > that either Mark or Rob would allow an exception to the "keep existing
>> > dts the way they are) and ack the following change to the canyonlands.dts.
>>
>> I don't know about that. Under what circumstance can the dts change?
> As far as I know, the justification for not changing the DTS is that a
> compiled DTB might be stored in an read-only ROM on a board. So it would
> be impossible to update it. Hence, the driver have work with the existing
> (and sometimes buggy or incomplete) information to stay compatible.
>
> (Note: Thankfully, the canyonlands dtb is stored in flash, it's possible
> to update it. But it is an extra step that's not done automatically
> with make install).
>
>> The canyonlands dts was binding to an external vendor driver. So it
>> wasn't documented nor expected to work with dwc2 until your recent
>> patch adding the compatible string.
>
> Oh, no that's not what happend. Let me explain why there was no "external
> vendor driver": AMCC/APM were planing to upstream their hole platform. And
> in fact, the devs tried very hard to include their driver back in 2011 [0].
> But this driver was denied inclusion back then due to:
>
> "[...]
> I would also like to point out that the same Synopsys USB controller
> is used in a number of other SoCs (especially ARM chips), and
> supported by other drivers, some of these even in mainline.
>
> See http://thread.gmane.org/gmane.linux.usb.general/61714/focus=62139
> for a related thread.
>
> Instead of trying to add a completely new driver to mainline (and one
> which has been repeatedly been rejected), I vote for focusing on the
> existing driver code that is already in mainline, and testing and
> improving this so we can use a single implementation of this driver
> code for all SoCs that use the same IP block." [1]
>
> Of course: The listed link goes the "USB Host driver for i.MX28" driver.
> And this is an ehci-hcd like driver... Which is as you are well aware not
> that similar to the dwc2 OTG. And as far as I can tell: AMCC abandoned
> the patch series right there.
>
> Note: AMCC did however succeed in pushing your employer's Synopsys
> DesignWare SATA and DMA drivers to the kernel back then. And I'm happy
> to report that both drivers are still around and working fine for the 460EX
> (sata_dwc_460ex.c[2] and the DW AHB DMA [3]). (The drivers also work for
> different platforms than the original PPC. I know that because I helped
> Andy Shevchenko with testing and pushing some fixes to it when he was
> adding support for the Intel Quark SoC, which uses the DWC SATA and DMA).
>
> So Please?
>> Systems that use the vendor driver will still work with the dts. If
>> you remove the vendor driver and configure it to use dwc2, it won't
>> work due to a quirk of the canyonlands hardware, for which you need to
>> add a dts property.
> Sadly, there is no up to date vendor driver. The canyonlands.dts binding
> is still in place and the hardware works fine. I'm interested in this
> platform since it is a cheap BigEndian system which is useful for usb
> driver development (carl9170 and rtl8192su)... and I would like to
> have out-of-the-box support.
>
>> I think this is reasonable. Rob or Mark, any feedback?
> I recall that Rob has already voiced his opinion about the ahb-burst setting:
> "Also, perhaps you should allow that the compatible string can define the default."
>
> And based on that, I made the "add a default ahb-burst setting for amcc,dwc-otg"
> patch above. Of course, it would be nice to have any feedback too. But unless I
> hear otherwise, I'll continue with posting patches to the dwc2 driver :).
And this is the correct thing to do. Requiring a dtb update is not.
Rob
^ permalink raw reply
* Re: [PATCH 1/2] of: base: add support to get machine model name
From: Rob Herring @ 2016-11-22 21:35 UTC (permalink / raw)
To: Frank Rowand
Cc: Sudeep Holla, linux-kernel@vger.kernel.org, Arnd Bergmann,
devicetree@vger.kernel.org
In-Reply-To: <5834921F.2020809@gmail.com>
On Tue, Nov 22, 2016 at 12:44 PM, Frank Rowand <frowand.list@gmail.com> wrote:
> Hi Rob,
>
> On 11/18/16 12:00, Frank Rowand wrote:
>> On 11/18/16 06:46, Rob Herring wrote:
>>> On Thu, Nov 17, 2016 at 03:32:54PM +0000, Sudeep Holla wrote:
>>>> Currently platforms/drivers needing to get the machine model name are
>>>> replicating the same snippet of code. In some case, the OF reference
>>>> counting is either missing or incorrect.
>>>>
>>>> This patch adds support to read the machine model name either using
>>>> the "model" or the "compatible" property in the device tree root node
>>>> to the core OF/DT code.
>>>>
>>>> This can be used to remove all the duplicate code snippets doing exactly
>>>> same thing later.
>>>>
>>>> Cc: Rob Herring <robh+dt@kernel.org>
>>>> Cc: Frank Rowand <frowand.list@gmail.com>
>>>> Cc: Arnd Bergmann <arnd@arndb.de>
>>>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
>>>> ---
>>>> drivers/of/base.c | 32 ++++++++++++++++++++++++++++++++
>>>> include/linux/of.h | 6 ++++++
>>>> 2 files changed, 38 insertions(+)
>>>>
>>>> Hi Rob,
>>>>
>>>> It would be good if we can target this for v4.10, so that we have no
>>>> dependencies to push PATCH 2/2 in v4.11
>>>
>>> Applied.
>>>
>>> Rob
>>>
>>
>> A little fast on the trigger Rob.
>>
>> -Frank
>
> This patch adds a function that leads to conflating the "model" property
> and the "compatible" property. This leads to opaque, confusing and unclear
> code where ever it is used. I think it is not good for the device tree
> framework to contribute to writing unclear code.
>
> Further, only two of the proposed users of this new function appear to
> be proper usage. I do not think that the small amount of reduced lines
> of code is a good trade off for the reduced code clarity and for the
> potential for future mis-use of this function.
>
> Can I convince you to revert this patch?
Yes, I will revert.
> If not, will you accept a patch to change the function name to more
> clearly indicate what it does? (One possible name would be
> of_model_or_1st_compatible().)
I took it as there's already the FDT equivalent function. I don't have
an issue with the name as the purpose is to get the best name string
for the machine which is model if present and most specific compatible
if not. However, any use of it beyond informational purpose is wrong.
For matching purposes, only compatible should be used.
Rob
^ permalink raw reply
* Re: [PATCH V2 1/2] regulator: pwm: DT: Add ramp delay for exponential voltage transition
From: Rob Herring @ 2016-11-22 21:13 UTC (permalink / raw)
To: Laxman Dewangan
Cc: Mark Brown, Mark Rutland,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Douglas Anderson, Aleksandr Frid
In-Reply-To: <583406CC.9080306-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
On Tue, Nov 22, 2016 at 2:50 AM, Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
>
> On Monday 21 November 2016 09:47 PM, Rob Herring wrote:
>>
>> On Fri, Nov 18, 2016 at 08:05:55PM +0530, Laxman Dewangan wrote:
>>>
>>> Some PWM regulator has the exponential transition in voltage change as
>>> opposite to fixed slew-rate linear transition on other regulators.
>>> For such PWM regulators, add the property to tell that voltage change
>>> is exponential and having fixed delay for any level of change.
>>>
>>> Signed-off-by: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>>> CC: Douglas Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
>>> CC: Aleksandr Frid <afrid-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>>>
>>> ---
>>> This patch is continuation of discussion on patch
>>> regulator: pwm: Fix regulator ramp delay for continuous mode
>>> https://patchwork.kernel.org/patch/9216857/
>>> where is it discussed to have separate property for PWM which has
>>> exponential voltage transition.
>>>
>>> Changes from V1:
>>> - Pass the flag to tell that voltage ramp is exponential instead of
>>> providing delay.
>>> ---
>>> .../devicetree/bindings/regulator/pwm-regulator.txt | 12
>>> ++++++++++++
>>> 1 file changed, 12 insertions(+)
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt
>>> b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt
>>> index 3aeba9f..2d9ef3a 100644
>>> --- a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt
>>> +++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt
>>> @@ -54,6 +54,18 @@ Optional properties:
>>> --------------------
>>> - enable-gpios: GPIO to use to enable/disable the
>>> regulator
>>> +- voltage-ramp-exponential: Boolean, Some of PWM regulator has the
>>> exponential
>>> + transition in voltage ramp as opposite to fixed
>>> + slew-rate linear transition on other regulators.
>>> + For such PWM regulator, presence of this property
>>> will
>>> + tell that value of the regulator ramp delay
>>> provided by
>>> + DT property "regulator-ramp-delay" is exponential
>>> and
>>> + fixed delay for any voltage level change.
>>> + If PWM regulator supports the fixed linear slew
>>> rate
>>> + then this property should be absent from DT node
>>> and
>>> + property "regulator-ramp-delay" is used as linear
>>> slew
>>> + rate.
>>
>> Sorry, but on further thought, I don't think we should mix different
>> units for the same property. Also, the fact that the ramp is exponential
>> is irrelevant. You just want an absolute delay time rather than a rate,
>> right? So instead, how about just "regulator-ramp-time-us". Roughly what
>> you had in v1, but not PWM specific.
>
>
> Can we say "regulator-settling-time-us" and make it generic i.e. part of the
> regulator core instead of PWM regulator specific?
Sure.
Rob
--
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 v2 01/13] devicetree/bindings: display: Document common panel properties
From: Rob Herring @ 2016-11-22 21:10 UTC (permalink / raw)
To: Thierry Reding
Cc: Laurent Pinchart, dri-devel,
open list:MEDIA DRIVERS FOR RENESAS - FCP, Tomi Valkeinen,
devicetree@vger.kernel.org
In-Reply-To: <20161122110548.GB22735@ulmo.ba.sec>
On Tue, Nov 22, 2016 at 5:05 AM, Thierry Reding
<thierry.reding@gmail.com> wrote:
> On Sat, Nov 19, 2016 at 05:28:01AM +0200, Laurent Pinchart wrote:
>> Document properties common to several display panels in a central
>> location that can be referenced by the panel device tree bindings.
>>
>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>> ---
>> .../bindings/display/panel/panel-common.txt | 91 ++++++++++++++++++++++
>> 1 file changed, 91 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/display/panel/panel-common.txt
>>
>> diff --git a/Documentation/devicetree/bindings/display/panel/panel-common.txt b/Documentation/devicetree/bindings/display/panel/panel-common.txt
>> new file mode 100644
>> index 000000000000..ec52c472c845
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/display/panel/panel-common.txt
>> @@ -0,0 +1,91 @@
>> +Common Properties for Display Panel
>> +===================================
>> +
>> +This document defines device tree properties common to several classes of
>> +display panels. It doesn't constitue a device tree binding specification by
>> +itself but is meant to be referenced by device tree bindings.
>> +
>> +When referenced from panel device tree bindings the properties defined in this
>> +document are defined as follows. The panel device tree bindings are
>> +responsible for defining whether each property is required or optional.
>> +
>> +
>> +Descriptive Properties
>> +----------------------
>> +
>> +- width-mm,
>> +- height-mm: The width-mm and height-mm specify the width and height of the
>> + physical area where images are displayed. These properties are expressed in
>> + millimeters and rounded to the closest unit.
>
> Erm... this is already implied by the compatible string. Having this in
> device tree is completely redundant.
>
>> +- label: The label property specifies a symbolic name for the panel as a
>> + string suitable for use by humans. It typically contains a name inscribed on
>> + the system (e.g. as an affixed label) or specified in the system's
>> + documentation (e.g. in the user's manual).
>> +
>> + If no such name exists, and unless the property is mandatory according to
>> + device tree bindings, it shall rather be omitted than constructed of
>> + non-descriptive information. For instance an LCD panel in a system that
>> + contains a single panel shall not be labelled "LCD" if that name is not
>> + inscribed on the system or used in a descriptive fashion in system
>> + documentation.
>> +
>> +
>> +Display Timings
>> +---------------
>> +
>> +- panel-timing: Most display panels are restricted to a single resolution and
>> + require specific display timings. The panel-timing subnode expresses those
>> + timings as specified in the timing subnode section of the display timing
>> + bindings defined in
>> + Documentation/devicetree/bindings/display/display-timing.txt.
>
> Why? That's also implied by the compatible string. Honestly, I thought
> by now we had been over this often enough...
While I completely agree we don't want *only* generic compatibles nor
generic gpio and power control, I think timing values in DT are fine.
They are just data copied out of datasheets and aren't tweaked per
platform. If the same data would make sense to put into a display
EDID, I think it also makes sense to put that data in DT.
Rob
^ permalink raw reply
* Re: [PATCH] dt-bindings: mfd: Improve readability for TPS65217 interrupt sources
From: Arnd Bergmann @ 2016-11-22 21:08 UTC (permalink / raw)
To: Lee Jones
Cc: Milo Kim, bcousson-rdvid1DuHRBWk0Htik3J/w, Tony Lindgren,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Robert Nelson
In-Reply-To: <20161122160013.GH10134-Re9dqnLqz4GzQB+pC5nmwQ@public.gmane.org>
On Tuesday, November 22, 2016 4:00:13 PM CET Lee Jones wrote:
> > > diff --git a/include/dt-bindings/mfd/tps65217.h b/include/dt-bindings/mfd/tps65217.h
> > > index cafb9e6..0293fdd 100644
> > > --- a/include/dt-bindings/mfd/tps65217.h
> > > +++ b/include/dt-bindings/mfd/tps65217.h
> > > @@ -19,8 +19,8 @@
> > > #ifndef __DT_BINDINGS_TPS65217_H__
> > > #define __DT_BINDINGS_TPS65217_H__
> > >
> > > -#define TPS65217_IRQ_USB 0
> > > -#define TPS65217_IRQ_AC 1
> > > -#define TPS65217_IRQ_PB 2
> > > +#define TPS65217_IRQ_USB_POWER 0 /* USB power state change */
> > > +#define TPS65217_IRQ_AC_POWER 1 /* AC power state change */
> > > +#define TPS65217_IRQ_PUSHBUTTON 2 /* Push button state change */
> >
> > This changes the ABI.
> >
> > It will require a DT Ack.
>
> Tell a lie. Sorry, I was getting false positives from my grep. It
> looks like you use the same scheme from within include/linux. I
> suggest that you probable don't want to do that.
Doing this change however would cause a bisection problem: you
can't rename just the constants in the header or just the driver
using those constants.
Arnd
--
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 v3 2/2] ARM: dts: add support for Turris Omnia
From: Uwe Kleine-König @ 2016-11-22 20:59 UTC (permalink / raw)
To: Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth
Cc: Tomas Hlavacek, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Bedřicha Košatu
In-Reply-To: <20161122205908.7297-1-uwe-rXY34ruvC2xidJT2blvkqNi2O/JbrIOy@public.gmane.org>
This machine is an open hardware router by cz.nic driven by a
Marvell Armada 385.
Signed-off-by: Uwe Kleine-König <uwe-rXY34ruvC2xidJT2blvkqNi2O/JbrIOy@public.gmane.org>
---
Changes since (implicit) v1:
- disable rtc
- change compatible to "cznic,turris-omnia"
Changes since v2:
- fix comment for usb@58000
- add gpio-expander that serves SPF and phy irq
I kept all three eth devices to keep the ethernet names when users upgrade.
Tomas said that he had problems with the emmc when operating it in DDR50
mode. I didn't see any I/O errors so far and didn't find a way to
limit the device to SDR50 via dt.
IMHO even with some peripherals still missing (SFP, switch, wlan) it
would be the right thing to take this patch as a base to get the
remaining bits sorted. Is it still possible to get it into 4.10?
Best regards
Uwe
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/armada-385-turris-omnia.dts | 282 ++++++++++++++++++++++++++
2 files changed, 283 insertions(+)
create mode 100644 arch/arm/boot/dts/armada-385-turris-omnia.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index befcd2619902..f1d3b9ff257e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -920,6 +920,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
armada-385-db-ap.dtb \
armada-385-linksys-caiman.dtb \
armada-385-linksys-cobra.dtb \
+ armada-385-turris-omnia.dtb \
armada-388-clearfog.dtb \
armada-388-db.dtb \
armada-388-gp.dtb \
diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
new file mode 100644
index 000000000000..a750fd8d8225
--- /dev/null
+++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
@@ -0,0 +1,282 @@
+/*
+ * Device Tree file for the Turris Omnia
+ * Schematic available at https://www.turris.cz/doc/_media/rtrom01-schema.pdf
+ *
+ * Copyright (C) 2016 Uwe Kleine-König <uwe-rXY34ruvC2xidJT2blvkqNi2O/JbrIOy@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "armada-385.dtsi"
+
+/ {
+ model = "Turris Omnia";
+ compatible = "cznic,turris-omnia", "marvell,armada385", "marvell,armada380";
+
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1024 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+
+ /* part of PCIe */
+ usb@58000 {
+ status = "okay";
+ };
+
+ rtc@a3800 {
+ /*
+ * There are several errata for this device
+ * still unimplemented. Without some love it only reports
+ * 2016-12-19 22:00:24. So disable for now.
+ */
+ status = "disabled";
+ };
+
+ sata@a8000 {
+ status = "okay";
+ };
+
+ sdhci@d8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+ status = "okay";
+
+ bus-width = <8>;
+ no-1-8-v;
+ non-removable;
+ };
+
+ usb3@f0000 {
+ status = "okay";
+ };
+
+ usb3@f8000 {
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@3,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+};
+
+ð0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ status = "okay";
+ phy-mode = "rgmii-id";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+ð1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ status = "okay";
+ phy-mode = "rgmii-id";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+/* WAN port */
+ð2 {
+ status = "okay";
+ phy-mode = "sgmii";
+ phy = <&phy1>;
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+
+ i2cmux@70 {
+ compatible = "nxp,pca9547";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+ status = "okay";
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "okay";
+
+ /* STM32F0 at address 0x2a */
+ /* leds device at address 0x2b */
+
+ eeprom@54 {
+ /* holds configuration about RAM, evaluated by bootloader */
+ compatible = "at,24c64";
+ reg = <0x54>;
+ };
+ };
+
+ i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ /* ATSHA204A at address 0x64 */
+ };
+
+ i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ /* exposed on pin header */
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+
+ pcawan: gpio@71 {
+ compatible = "nxp,pca9538";
+ reg = <0x71>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcawan_pins>;
+
+ interrupt-parent = <&gpio1>;
+ interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+ };
+};
+
+&mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+ status = "okay";
+
+ phy1: phy@1 {
+ status = "okay";
+ compatible = "ethernet-phy-id0141.0DD1", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+
+ /* There is a Switch (MV88E7176) at address 0x10 */
+};
+
+&pinctrl {
+ pcawan_pins: pcawan-pins {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+
+ spi0cs1_pins: spi0-pins-0cs1 {
+ marvell,pins = "mpp26";
+ marvell,function = "spi0";
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins &spi0cs1_pins>;
+ status = "okay";
+
+ spi-nor@0 {
+ compatible = "spansion,s25fl164k", "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ partition@0 {
+ reg = <0x0 0x00100000>;
+ label = "U-Boot";
+ };
+
+ partition@1 {
+ reg = <0x00100000 0x00700000>;
+ label = "Rescue system";
+ };
+ };
+
+ /* @1 is on pin header */
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+};
--
2.10.2
--
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 related
* [PATCH v3 1/2] devicetree: Add vendor prefix for CZ.NIC
From: Uwe Kleine-König @ 2016-11-22 20:59 UTC (permalink / raw)
To: Jason Cooper, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth
Cc: Tomas Hlavacek, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Bedřicha Košatu
Signed-off-by: Uwe Kleine-König <uwe-rXY34ruvC2xidJT2blvkqNi2O/JbrIOy@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
changes since v2:
- add ack by Rob Herring
Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index f0a48ea78659..ae9fce9fed03 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -67,6 +67,7 @@ creative Creative Technology Ltd
crystalfontz Crystalfontz America, Inc.
cubietech Cubietech, Ltd.
cypress Cypress Semiconductor Corporation
+cznic CZ.NIC, z.s.p.o.
dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc.
delta Delta Electronics, Inc.
--
2.10.2
--
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 related
* Re: [PATCH v3 0/7] mux controller abstraction and iio/i2c muxes
From: Lars-Peter Clausen @ 2016-11-22 20:58 UTC (permalink / raw)
To: Peter Rosin, linux-kernel
Cc: Wolfram Sang, Rob Herring, Mark Rutland, Jonathan Cameron,
Hartmut Knaack, Peter Meerwald-Stadler, Jonathan Corbet,
Arnd Bergmann, Greg Kroah-Hartman, linux-i2c, devicetree,
linux-iio, linux-doc
In-Reply-To: <1479734235-18837-1-git-send-email-peda@axentia.se>
On 11/21/2016 02:17 PM, Peter Rosin wrote:
[...]
> I have a piece of hardware that is using the same 3 GPIO pins
> to control four 8-way muxes. Three of them control ADC lines
> to an ADS1015 chip with an iio driver, and the last one
> controls the SDA line of an i2c bus. We have some deployed
> code to handle this, but you do not want to see it or ever
> hear about it. I'm not sure why I even mention it. Anyway,
> the situation has nagged me to no end for quite some time.
>
> So, after first getting more intimate with the i2c muxing code
> and later discovering the drivers/iio/inkern.c file and
> writing a couple of drivers making use of it, I came up with
> what I think is an acceptable solution; add a generic mux
> controller driver (and subsystem) that is shared between all
> instances, and combine that with an iio mux driver and a new
> generic i2c mux driver. The new i2c mux I called "simple"
> since it is only hooking the i2c muxing and the new mux
> controller (much like the alsa simple card driver does for ASoC).
While abstracting this properly is all nice and good and the way it should
be done, but it also adds a lot of complexity and the devicetree adds a lot
of restrictions on what can actually be represented.
There is a certain point where the fabric on a PCB becomes so complex that
it deserves to be a device on its own (like the audio fabric drivers).
Especially when the hardware is built with a certain application in mind and
the driver is supposed to impose policy which reflects this application. The
latter can often not properly be described with the primitives the
devicetree can offer.
And I think your setup is very borderline what can be done in a declarative
way only and it adds a lot of complexity over a more imperative solution in
form of a driver. I think it is worth investigating about having a driver
that is specific to your fabric and handles the interdependencies of the
discrete components.
^ permalink raw reply
* Re: [PATCH v2 2/4] usb: dwc2: Add binding for AHB burst
From: Christian Lamparter @ 2016-11-22 20:51 UTC (permalink / raw)
To: John Youn
Cc: Stefan Wahren, Rob Herring, devicetree@vger.kernel.org,
linux-usb@vger.kernel.org, Paul Mackerras, Christian Lamparter,
Mark Rutland, linuxppc-dev@lists.ozlabs.org, Felipe Balbi
In-Reply-To: <0677657e-043d-c6d4-783e-9b471d12afcb@synopsys.com>
On Monday, November 21, 2016 7:32:30 PM CET John Youn wrote:
> On 11/21/2016 1:10 PM, Christian Lamparter wrote:
> > On Monday, November 21, 2016 12:16:31 PM CET John Youn wrote:
> >> On 11/18/2016 12:18 PM, Christian Lamparter wrote:
> >>> On Friday, November 18, 2016 8:16:08 AM CET Rob Herring wrote:
> >>>> Also, perhaps you should allow that the compatible string can define the
> >>>> default.
> >>>>
> >>> I hoped you would say that :).
> >>>
> >>> I've attached a patch (on top of John Youn changes) [...]
> >>> ---
> >>> Subject: [PATCH] usb: dwc2: add a default ahb-burst setting for amcc,dwc-otg
> >>> [...]
> >>> @@ -1097,6 +1097,22 @@ static const char *const ahb_bursts[] = {
> >>> +/* [...] */
> >>> +static const struct of_device_id dwc2_compat_ahb_bursts[] = {
> >>> + {
> >>> + .compatible = "amcc,dwc-otg",
> >>> + .data = (void *) GAHBCFG_HBSTLEN_INCR16,
> >>> + },
> >>> +};
> [...]
> > >>> @@ -1107,6 +1123,12 @@ static int dwc2_get_property_ahb_burst(struct dwc2_hsotg *hsotg)
> >>> ret = device_property_read_string(hsotg->dev, "snps,ahb-burst", &str);
> >>> if (ret < 0) {
> >>> + const struct of_device_id *match;
> >>> +
> >>> + match = of_match_node(dwc2_compat_ahb_bursts, node);
> >>> + if (match)
> >>> + ret = (int)match->data;
> >>> +
> [...]
> >> I'd prefer if you use the binding which requires no extra code in
> >> dwc2.
> > I'm fine with either option. However it think that this would require
> > that either Mark or Rob would allow an exception to the "keep existing
> > dts the way they are) and ack the following change to the canyonlands.dts.
>
> I don't know about that. Under what circumstance can the dts change?
As far as I know, the justification for not changing the DTS is that a
compiled DTB might be stored in an read-only ROM on a board. So it would
be impossible to update it. Hence, the driver have work with the existing
(and sometimes buggy or incomplete) information to stay compatible.
(Note: Thankfully, the canyonlands dtb is stored in flash, it's possible
to update it. But it is an extra step that's not done automatically
with make install).
> The canyonlands dts was binding to an external vendor driver. So it
> wasn't documented nor expected to work with dwc2 until your recent
> patch adding the compatible string.
Oh, no that's not what happend. Let me explain why there was no "external
vendor driver": AMCC/APM were planing to upstream their hole platform. And
in fact, the devs tried very hard to include their driver back in 2011 [0].
But this driver was denied inclusion back then due to:
"[...]
I would also like to point out that the same Synopsys USB controller
is used in a number of other SoCs (especially ARM chips), and
supported by other drivers, some of these even in mainline.
See http://thread.gmane.org/gmane.linux.usb.general/61714/focus=62139
for a related thread.
Instead of trying to add a completely new driver to mainline (and one
which has been repeatedly been rejected), I vote for focusing on the
existing driver code that is already in mainline, and testing and
improving this so we can use a single implementation of this driver
code for all SoCs that use the same IP block." [1]
Of course: The listed link goes the "USB Host driver for i.MX28" driver.
And this is an ehci-hcd like driver... Which is as you are well aware not
that similar to the dwc2 OTG. And as far as I can tell: AMCC abandoned
the patch series right there.
Note: AMCC did however succeed in pushing your employer's Synopsys
DesignWare SATA and DMA drivers to the kernel back then. And I'm happy
to report that both drivers are still around and working fine for the 460EX
(sata_dwc_460ex.c[2] and the DW AHB DMA [3]). (The drivers also work for
different platforms than the original PPC. I know that because I helped
Andy Shevchenko with testing and pushing some fixes to it when he was
adding support for the Intel Quark SoC, which uses the DWC SATA and DMA).
So Please?
> Systems that use the vendor driver will still work with the dts. If
> you remove the vendor driver and configure it to use dwc2, it won't
> work due to a quirk of the canyonlands hardware, for which you need to
> add a dts property.
Sadly, there is no up to date vendor driver. The canyonlands.dts binding
is still in place and the hardware works fine. I'm interested in this
platform since it is a cheap BigEndian system which is useful for usb
driver development (carl9170 and rtl8192su)... and I would like to
have out-of-the-box support.
> I think this is reasonable. Rob or Mark, any feedback?
I recall that Rob has already voiced his opinion about the ahb-burst setting:
"Also, perhaps you should allow that the compatible string can define the default."
And based on that, I made the "add a default ahb-burst setting for amcc,dwc-otg"
patch above. Of course, it would be nice to have any feedback too. But unless I
hear otherwise, I'll continue with posting patches to the dwc2 driver :).
> One of the reasons I don't want to add the code in dwc2 is because I'm
> trying to make dwc2 a generic IP driver like dwc3.
I understand that. And let me say, that I also have a dwc3 in my IPQ4019.
And adding support for it was as simple as adding just one compatible
binding in dwc-of-simple [4].
Regards,
Christian
[0] <http://thread.gmane.org/gmane.linux.usb.general/53348/focus=53913>
[1] <https://lists.ozlabs.org/pipermail/linuxppc-dev/2012-May/097850.html>
[2] <http://lxr.free-electrons.com/source/drivers/ata/sata_dwc_460ex.c>
[3] <http://lxr.free-electrons.com/source/drivers/dma/dw/core.c>
[4] <https://github.com/chunkeey/LEDE-IPQ40XX/blob/staging/target/linux/ipq40xx/patches-4.8/830-usb-dwc3-register-qca-ipq4019-dwc3-in-dwc3-of-simple.patch>
^ permalink raw reply
* Applied "ASoC: sunxi: Add bindings for A23/A33/H3 codec's analog path controls" to the asoc tree
From: Mark Brown @ 2016-11-22 19:13 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Mark Rutland, alsa-devel, devicetree, Liam Girdwood, Rob Herring,
linux-kernel, Mark Brown, Maxime Ripard, Mylene Josserand,
Lee Jones, linux-arm-kernel
In-Reply-To: <20161112064648.26779-2-wens@csie.org>
The patch
ASoC: sunxi: Add bindings for A23/A33/H3 codec's analog path controls
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 837e71847aefd82c903ee0bb2ff2589e70b0808f Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Sat, 12 Nov 2016 14:46:39 +0800
Subject: [PATCH] ASoC: sunxi: Add bindings for A23/A33/H3 codec's analog path
controls
The internal codec on A23/A33/H3 is split into 2 parts. The
analog path controls are routed through an embedded custom register
bus accessed through the PRCM block.
The SoCs share a common set of inputs, outputs, and audio paths.
The following table lists the differences.
----------------------------------------
| Feature \ SoC | A23 | A33 | H3 |
----------------------------------------
| Headphone | v | v | |
----------------------------------------
| Line Out | | | v |
----------------------------------------
| Phone In/Out | v | v | |
----------------------------------------
Add a binding for this hardware.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
.../devicetree/bindings/sound/sun8i-codec-analog.txt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
new file mode 100644
index 000000000000..779b735781ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
@@ -0,0 +1,16 @@
+* Allwinner Codec Analog Controls
+
+Required properties:
+- compatible: must be one of the following compatibles:
+ - "allwinner,sun8i-a23-codec-analog"
+ - "allwinner,sun8i-h3-codec-analog"
+
+Required properties if not a sub-node of the PRCM node:
+- reg: must contain the registers location and length
+
+Example:
+prcm: prcm@01f01400 {
+ codec_analog: codec-analog {
+ compatible = "allwinner,sun8i-a23-codec-analog";
+ };
+};
--
2.10.2
^ permalink raw reply related
* Applied "ASoC: sunxi: Add support for A23/A33/H3 codec's analog path controls" to the asoc tree
From: Mark Brown @ 2016-11-22 19:13 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Mark Rutland, devicetree, alsa-devel, Liam Girdwood, Rob Herring,
linux-kernel, Mark Brown, Maxime Ripard, Mylene Josserand,
Lee Jones, linux-arm-kernel
In-Reply-To: <20161112064648.26779-3-wens@csie.org>
The patch
ASoC: sunxi: Add support for A23/A33/H3 codec's analog path controls
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From ba2ff3027b5ab4a96b9d2832822311c3ccbf3011 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Sat, 12 Nov 2016 14:46:40 +0800
Subject: [PATCH] ASoC: sunxi: Add support for A23/A33/H3 codec's analog path
controls
The internal codec on A23/A33/H3 is split into 2 parts. The
analog path controls are routed through an embedded custom register
bus accessed through the PRCM block.
The SoCs share a common set of inputs, outputs, and audio paths.
The following table lists the differences.
----------------------------------------
| Feature \ SoC | A23 | A33 | H3 |
----------------------------------------
| Headphone | v | v | |
----------------------------------------
| Line Out | | | v |
----------------------------------------
| Phone In/Out | v | v | |
----------------------------------------
Add an ASoC component driver for it. This should be tied to the codec
audio card as an auxiliary device. This patch adds the commont paths
and controls, and variant specific headphone out and line out.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/sunxi/Kconfig | 8 +
sound/soc/sunxi/Makefile | 1 +
sound/soc/sunxi/sun8i-codec-analog.c | 665 +++++++++++++++++++++++++++++++++++
3 files changed, 674 insertions(+)
create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index dd2368297fd3..6c344e16aca4 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -9,6 +9,14 @@ config SND_SUN4I_CODEC
Select Y or M to add support for the Codec embedded in the Allwinner
A10 and affiliated SoCs.
+config SND_SUN8I_CODEC_ANALOG
+ tristate "Allwinner sun8i Codec Analog Controls Support"
+ depends on MACH_SUN8I || COMPILE_TEST
+ select REGMAP
+ help
+ Say Y or M if you want to add support for the analog controls for
+ the codec embedded in newer Allwinner SoCs.
+
config SND_SUN4I_I2S
tristate "Allwinner A10 I2S Support"
select SND_SOC_GENERIC_DMAENGINE_PCM
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 604c7b842837..241c0df9ca0c 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
+obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
new file mode 100644
index 000000000000..222bbd440b1e
--- /dev/null
+++ b/sound/soc/sunxi/sun8i-codec-analog.c
@@ -0,0 +1,665 @@
+/*
+ * This driver supports the analog controls for the internal codec
+ * found in Allwinner's A31s, A23, A33 and H3 SoCs.
+ *
+ * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ *
+ * 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/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+/* Codec analog control register offsets and bit fields */
+#define SUN8I_ADDA_HP_VOLC 0x00
+#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE 7
+#define SUN8I_ADDA_HP_VOLC_HP_VOL 0
+#define SUN8I_ADDA_LOMIXSC 0x01
+#define SUN8I_ADDA_LOMIXSC_MIC1 6
+#define SUN8I_ADDA_LOMIXSC_MIC2 5
+#define SUN8I_ADDA_LOMIXSC_PHONE 4
+#define SUN8I_ADDA_LOMIXSC_PHONEN 3
+#define SUN8I_ADDA_LOMIXSC_LINEINL 2
+#define SUN8I_ADDA_LOMIXSC_DACL 1
+#define SUN8I_ADDA_LOMIXSC_DACR 0
+#define SUN8I_ADDA_ROMIXSC 0x02
+#define SUN8I_ADDA_ROMIXSC_MIC1 6
+#define SUN8I_ADDA_ROMIXSC_MIC2 5
+#define SUN8I_ADDA_ROMIXSC_PHONE 4
+#define SUN8I_ADDA_ROMIXSC_PHONEP 3
+#define SUN8I_ADDA_ROMIXSC_LINEINR 2
+#define SUN8I_ADDA_ROMIXSC_DACR 1
+#define SUN8I_ADDA_ROMIXSC_DACL 0
+#define SUN8I_ADDA_DAC_PA_SRC 0x03
+#define SUN8I_ADDA_DAC_PA_SRC_DACAREN 7
+#define SUN8I_ADDA_DAC_PA_SRC_DACALEN 6
+#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN 5
+#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN 4
+#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE 3
+#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE 2
+#define SUN8I_ADDA_DAC_PA_SRC_RHPIS 1
+#define SUN8I_ADDA_DAC_PA_SRC_LHPIS 0
+#define SUN8I_ADDA_PHONEIN_GCTRL 0x04
+#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG 4
+#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG 0
+#define SUN8I_ADDA_LINEIN_GCTRL 0x05
+#define SUN8I_ADDA_LINEIN_GCTRL_LINEING 4
+#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG 0
+#define SUN8I_ADDA_MICIN_GCTRL 0x06
+#define SUN8I_ADDA_MICIN_GCTRL_MIC1G 4
+#define SUN8I_ADDA_MICIN_GCTRL_MIC2G 0
+#define SUN8I_ADDA_PAEN_HP_CTRL 0x07
+#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN 7
+#define SUN8I_ADDA_PAEN_HP_CTRL_LINEOUTEN 7 /* H3 specific */
+#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC 5
+#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN 4
+#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL 2
+#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE 1
+#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE 0
+#define SUN8I_ADDA_PHONEOUT_CTRL 0x08
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG 5
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN 4
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUT_MIC1 3
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUT_MIC2 2
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUT_RMIX 1
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUT_LMIX 0
+#define SUN8I_ADDA_PHONE_GAIN_CTRL 0x09
+#define SUN8I_ADDA_PHONE_GAIN_CTRL_LINEOUT_VOL 3
+#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG 0
+#define SUN8I_ADDA_MIC2G_CTRL 0x0a
+#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN 7
+#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST 4
+#define SUN8I_ADDA_MIC2G_CTRL_LINEOUTLEN 3
+#define SUN8I_ADDA_MIC2G_CTRL_LINEOUTREN 2
+#define SUN8I_ADDA_MIC2G_CTRL_LINEOUTLSRC 1
+#define SUN8I_ADDA_MIC2G_CTRL_LINEOUTRSRC 0
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL 0x0b
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN 7
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN 6
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE 5
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN 3
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST 0
+#define SUN8I_ADDA_LADCMIXSC 0x0c
+#define SUN8I_ADDA_LADCMIXSC_MIC1 6
+#define SUN8I_ADDA_LADCMIXSC_MIC2 5
+#define SUN8I_ADDA_LADCMIXSC_PHONE 4
+#define SUN8I_ADDA_LADCMIXSC_PHONEN 3
+#define SUN8I_ADDA_LADCMIXSC_LINEINL 2
+#define SUN8I_ADDA_LADCMIXSC_OMIXRL 1
+#define SUN8I_ADDA_LADCMIXSC_OMIXRR 0
+#define SUN8I_ADDA_RADCMIXSC 0x0d
+#define SUN8I_ADDA_RADCMIXSC_MIC1 6
+#define SUN8I_ADDA_RADCMIXSC_MIC2 5
+#define SUN8I_ADDA_RADCMIXSC_PHONE 4
+#define SUN8I_ADDA_RADCMIXSC_PHONEP 3
+#define SUN8I_ADDA_RADCMIXSC_LINEINR 2
+#define SUN8I_ADDA_RADCMIXSC_OMIXR 1
+#define SUN8I_ADDA_RADCMIXSC_OMIXL 0
+#define SUN8I_ADDA_RES 0x0e
+#define SUN8I_ADDA_RES_MMICBIAS_SEL 4
+#define SUN8I_ADDA_RES_PA_ANTI_POP_CTRL 0
+#define SUN8I_ADDA_ADC_AP_EN 0x0f
+#define SUN8I_ADDA_ADC_AP_EN_ADCREN 7
+#define SUN8I_ADDA_ADC_AP_EN_ADCLEN 6
+#define SUN8I_ADDA_ADC_AP_EN_ADCG 0
+
+/* Analog control register access bits */
+#define ADDA_PR 0x0 /* PRCM base + 0x1c0 */
+#define ADDA_PR_RESET BIT(28)
+#define ADDA_PR_WRITE BIT(24)
+#define ADDA_PR_ADDR_SHIFT 16
+#define ADDA_PR_ADDR_MASK GENMASK(4, 0)
+#define ADDA_PR_DATA_IN_SHIFT 8
+#define ADDA_PR_DATA_IN_MASK GENMASK(7, 0)
+#define ADDA_PR_DATA_OUT_SHIFT 0
+#define ADDA_PR_DATA_OUT_MASK GENMASK(7, 0)
+
+/* regmap access bits */
+static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+ void __iomem *base = (void __iomem *)context;
+ u32 tmp;
+
+ /* De-assert reset */
+ writel(readl(base) | ADDA_PR_RESET, base);
+
+ /* Clear write bit */
+ writel(readl(base) & ~ADDA_PR_WRITE, base);
+
+ /* Set register address */
+ tmp = readl(base);
+ tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
+ tmp |= (reg & ADDA_PR_ADDR_MASK) << ADDA_PR_ADDR_SHIFT;
+ writel(tmp, base);
+
+ /* Read back value */
+ *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
+
+ return 0;
+}
+
+static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+ void __iomem *base = (void __iomem *)context;
+ u32 tmp;
+
+ /* De-assert reset */
+ writel(readl(base) | ADDA_PR_RESET, base);
+
+ /* Set register address */
+ tmp = readl(base);
+ tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
+ tmp |= (reg & ADDA_PR_ADDR_MASK) << ADDA_PR_ADDR_SHIFT;
+ writel(tmp, base);
+
+ /* Set data to write */
+ tmp = readl(base);
+ tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
+ tmp |= (val & ADDA_PR_DATA_IN_MASK) << ADDA_PR_DATA_IN_SHIFT;
+ writel(tmp, base);
+
+ /* Set write bit to signal a write */
+ writel(readl(base) | ADDA_PR_WRITE, base);
+
+ /* Clear write bit */
+ writel(readl(base) & ~ADDA_PR_WRITE, base);
+
+ return 0;
+}
+
+static const struct regmap_config adda_pr_regmap_cfg = {
+ .name = "adda-pr",
+ .reg_bits = 5,
+ .reg_stride = 1,
+ .val_bits = 8,
+ .reg_read = adda_reg_read,
+ .reg_write = adda_reg_write,
+ .fast_io = true,
+ .max_register = 24,
+};
+
+/* mixer controls */
+static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
+ SOC_DAPM_DOUBLE_R("DAC Playback Switch",
+ SUN8I_ADDA_LOMIXSC,
+ SUN8I_ADDA_ROMIXSC,
+ SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
+ SOC_DAPM_DOUBLE_R("DAC Reversed Playback Switch",
+ SUN8I_ADDA_LOMIXSC,
+ SUN8I_ADDA_ROMIXSC,
+ SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
+ SOC_DAPM_DOUBLE_R("Line In Playback Switch",
+ SUN8I_ADDA_LOMIXSC,
+ SUN8I_ADDA_ROMIXSC,
+ SUN8I_ADDA_LOMIXSC_LINEINL, 1, 0),
+ SOC_DAPM_DOUBLE_R("Mic1 Playback Switch",
+ SUN8I_ADDA_LOMIXSC,
+ SUN8I_ADDA_ROMIXSC,
+ SUN8I_ADDA_LOMIXSC_MIC1, 1, 0),
+ SOC_DAPM_DOUBLE_R("Mic2 Playback Switch",
+ SUN8I_ADDA_LOMIXSC,
+ SUN8I_ADDA_ROMIXSC,
+ SUN8I_ADDA_LOMIXSC_MIC2, 1, 0),
+};
+
+/* ADC mixer controls */
+static const struct snd_kcontrol_new sun8i_codec_adc_mixer_controls[] = {
+ SOC_DAPM_DOUBLE_R("Mixer Capture Switch",
+ SUN8I_ADDA_LADCMIXSC,
+ SUN8I_ADDA_RADCMIXSC,
+ SUN8I_ADDA_LADCMIXSC_OMIXRL, 1, 0),
+ SOC_DAPM_DOUBLE_R("Mixer Reversed Capture Switch",
+ SUN8I_ADDA_LADCMIXSC,
+ SUN8I_ADDA_RADCMIXSC,
+ SUN8I_ADDA_LADCMIXSC_OMIXRR, 1, 0),
+ SOC_DAPM_DOUBLE_R("Line In Capture Switch",
+ SUN8I_ADDA_LADCMIXSC,
+ SUN8I_ADDA_RADCMIXSC,
+ SUN8I_ADDA_LADCMIXSC_LINEINL, 1, 0),
+ SOC_DAPM_DOUBLE_R("Mic1 Capture Switch",
+ SUN8I_ADDA_LADCMIXSC,
+ SUN8I_ADDA_RADCMIXSC,
+ SUN8I_ADDA_LADCMIXSC_MIC1, 1, 0),
+ SOC_DAPM_DOUBLE_R("Mic2 Capture Switch",
+ SUN8I_ADDA_LADCMIXSC,
+ SUN8I_ADDA_RADCMIXSC,
+ SUN8I_ADDA_LADCMIXSC_MIC2, 1, 0),
+};
+
+/* volume / mute controls */
+static const DECLARE_TLV_DB_SCALE(sun8i_codec_out_mixer_pregain_scale,
+ -450, 150, 0);
+static const DECLARE_TLV_DB_RANGE(sun8i_codec_mic_gain_scale,
+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+ 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0),
+);
+
+static const struct snd_kcontrol_new sun8i_codec_common_controls[] = {
+ /* Mixer pre-gains */
+ SOC_SINGLE_TLV("Line In Playback Volume", SUN8I_ADDA_LINEIN_GCTRL,
+ SUN8I_ADDA_LINEIN_GCTRL_LINEING,
+ 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
+ SOC_SINGLE_TLV("Mic1 Playback Volume", SUN8I_ADDA_MICIN_GCTRL,
+ SUN8I_ADDA_MICIN_GCTRL_MIC1G,
+ 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
+ SOC_SINGLE_TLV("Mic2 Playback Volume",
+ SUN8I_ADDA_MICIN_GCTRL, SUN8I_ADDA_MICIN_GCTRL_MIC2G,
+ 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
+
+ /* Microphone Amp boost gains */
+ SOC_SINGLE_TLV("Mic1 Boost Volume", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
+ SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST, 0x7, 0,
+ sun8i_codec_mic_gain_scale),
+ SOC_SINGLE_TLV("Mic2 Boost Volume", SUN8I_ADDA_MIC2G_CTRL,
+ SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST, 0x7, 0,
+ sun8i_codec_mic_gain_scale),
+
+ /* ADC */
+ SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN8I_ADDA_ADC_AP_EN,
+ SUN8I_ADDA_ADC_AP_EN_ADCG, 0x7, 0,
+ sun8i_codec_out_mixer_pregain_scale),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
+ /* ADC */
+ SND_SOC_DAPM_ADC("Left ADC", NULL, SUN8I_ADDA_ADC_AP_EN,
+ SUN8I_ADDA_ADC_AP_EN_ADCLEN, 0),
+ SND_SOC_DAPM_ADC("Right ADC", NULL, SUN8I_ADDA_ADC_AP_EN,
+ SUN8I_ADDA_ADC_AP_EN_ADCREN, 0),
+
+ /* DAC */
+ SND_SOC_DAPM_DAC("Left DAC", NULL, SUN8I_ADDA_DAC_PA_SRC,
+ SUN8I_ADDA_DAC_PA_SRC_DACALEN, 0),
+ SND_SOC_DAPM_DAC("Right DAC", NULL, SUN8I_ADDA_DAC_PA_SRC,
+ SUN8I_ADDA_DAC_PA_SRC_DACAREN, 0),
+ /*
+ * Due to this component and the codec belonging to separate DAPM
+ * contexts, we need to manually link the above widgets to their
+ * stream widgets at the card level.
+ */
+
+ /* Line In */
+ SND_SOC_DAPM_INPUT("LINEIN"),
+
+ /* Microphone inputs */
+ SND_SOC_DAPM_INPUT("MIC1"),
+ SND_SOC_DAPM_INPUT("MIC2"),
+
+ /* Microphone Bias */
+ SND_SOC_DAPM_SUPPLY("MBIAS", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
+ SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN,
+ 0, NULL, 0),
+
+ /* Mic input path */
+ SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
+ SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN8I_ADDA_MIC2G_CTRL,
+ SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN, 0, NULL, 0),
+
+ /* Mixers */
+ SND_SOC_DAPM_MIXER("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
+ SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
+ sun8i_codec_mixer_controls,
+ ARRAY_SIZE(sun8i_codec_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
+ SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
+ sun8i_codec_mixer_controls,
+ ARRAY_SIZE(sun8i_codec_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Left ADC Mixer", SUN8I_ADDA_ADC_AP_EN,
+ SUN8I_ADDA_ADC_AP_EN_ADCLEN, 0,
+ sun8i_codec_adc_mixer_controls,
+ ARRAY_SIZE(sun8i_codec_adc_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Right ADC Mixer", SUN8I_ADDA_ADC_AP_EN,
+ SUN8I_ADDA_ADC_AP_EN_ADCREN, 0,
+ sun8i_codec_adc_mixer_controls,
+ ARRAY_SIZE(sun8i_codec_adc_mixer_controls)),
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_common_routes[] = {
+ /* Microphone Routes */
+ { "Mic1 Amplifier", NULL, "MIC1"},
+ { "Mic2 Amplifier", NULL, "MIC2"},
+
+ /* Left Mixer Routes */
+ { "Left Mixer", "DAC Playback Switch", "Left DAC" },
+ { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
+ { "Left Mixer", "Line In Playback Switch", "LINEIN" },
+ { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
+ { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
+
+ /* Right Mixer Routes */
+ { "Right Mixer", "DAC Playback Switch", "Right DAC" },
+ { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
+ { "Right Mixer", "Line In Playback Switch", "LINEIN" },
+ { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
+ { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
+
+ /* Left ADC Mixer Routes */
+ { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" },
+ { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" },
+ { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
+ { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
+ { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
+
+ /* Right ADC Mixer Routes */
+ { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" },
+ { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" },
+ { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
+ { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
+ { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
+
+ /* ADC Routes */
+ { "Left ADC", NULL, "Left ADC Mixer" },
+ { "Right ADC", NULL, "Right ADC Mixer" },
+};
+
+/* headphone specific controls, widgets, and routes */
+static const DECLARE_TLV_DB_SCALE(sun8i_codec_hp_vol_scale, -6300, 100, 1);
+static const struct snd_kcontrol_new sun8i_codec_headphone_controls[] = {
+ SOC_SINGLE_TLV("Headphone Playback Volume",
+ SUN8I_ADDA_HP_VOLC,
+ SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3f, 0,
+ sun8i_codec_hp_vol_scale),
+ SOC_DOUBLE("Headphone Playback Switch",
+ SUN8I_ADDA_DAC_PA_SRC,
+ SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
+ SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
+};
+
+static const char * const sun8i_codec_hp_src_enum_text[] = {
+ "DAC", "Mixer",
+};
+
+static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
+ SUN8I_ADDA_DAC_PA_SRC,
+ SUN8I_ADDA_DAC_PA_SRC_LHPIS,
+ SUN8I_ADDA_DAC_PA_SRC_RHPIS,
+ sun8i_codec_hp_src_enum_text);
+
+static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
+ SOC_DAPM_ENUM("Headphone Source Playback Route",
+ sun8i_codec_hp_src_enum),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_headphone_widgets[] = {
+ SND_SOC_DAPM_MUX("Headphone Source Playback Route",
+ SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
+ SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
+ SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("HPCOM Protection", SUN8I_ADDA_PAEN_HP_CTRL,
+ SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN, 0, NULL, 0),
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPCOM", SUN8I_ADDA_PAEN_HP_CTRL,
+ SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC, 0x3, 0x3, 0),
+ SND_SOC_DAPM_OUTPUT("HP"),
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_headphone_routes[] = {
+ { "Headphone Source Playback Route", "DAC", "Left DAC" },
+ { "Headphone Source Playback Route", "DAC", "Right DAC" },
+ { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
+ { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
+ { "Headphone Amp", NULL, "Headphone Source Playback Route" },
+ { "HPCOM", NULL, "HPCOM Protection" },
+ { "HP", NULL, "Headphone Amp" },
+};
+
+static int sun8i_codec_add_headphone(struct snd_soc_component *cmpnt)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
+ struct device *dev = cmpnt->dev;
+ int ret;
+
+ ret = snd_soc_add_component_controls(cmpnt,
+ sun8i_codec_headphone_controls,
+ ARRAY_SIZE(sun8i_codec_headphone_controls));
+ if (ret) {
+ dev_err(dev, "Failed to add Headphone controls: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_headphone_widgets,
+ ARRAY_SIZE(sun8i_codec_headphone_widgets));
+ if (ret) {
+ dev_err(dev, "Failed to add Headphone DAPM widgets: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_headphone_routes,
+ ARRAY_SIZE(sun8i_codec_headphone_routes));
+ if (ret) {
+ dev_err(dev, "Failed to add Headphone DAPM routes: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* hmic specific widget */
+static const struct snd_soc_dapm_widget sun8i_codec_hmic_widgets[] = {
+ SND_SOC_DAPM_SUPPLY("HBIAS", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
+ SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN,
+ 0, NULL, 0),
+};
+
+static int sun8i_codec_add_hmic(struct snd_soc_component *cmpnt)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
+ struct device *dev = cmpnt->dev;
+ int ret;
+
+ ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_hmic_widgets,
+ ARRAY_SIZE(sun8i_codec_hmic_widgets));
+ if (ret)
+ dev_err(dev, "Failed to add Mic3 DAPM widgets: %d\n", ret);
+
+ return ret;
+}
+
+/* line out specific controls, widgets and routes */
+static const DECLARE_TLV_DB_RANGE(sun8i_codec_lineout_vol_scale,
+ 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
+ 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
+);
+static const struct snd_kcontrol_new sun8i_codec_lineout_controls[] = {
+ SOC_SINGLE_TLV("Line Out Playback Volume",
+ SUN8I_ADDA_PHONE_GAIN_CTRL,
+ SUN8I_ADDA_PHONE_GAIN_CTRL_LINEOUT_VOL, 0x1f, 0,
+ sun8i_codec_lineout_vol_scale),
+ SOC_DOUBLE("Line Out Playback Switch",
+ SUN8I_ADDA_MIC2G_CTRL,
+ SUN8I_ADDA_MIC2G_CTRL_LINEOUTLEN,
+ SUN8I_ADDA_MIC2G_CTRL_LINEOUTREN, 1, 0),
+};
+
+static const char * const sun8i_codec_lineout_src_enum_text[] = {
+ "Stereo", "Mono Differential",
+};
+
+static SOC_ENUM_DOUBLE_DECL(sun8i_codec_lineout_src_enum,
+ SUN8I_ADDA_MIC2G_CTRL,
+ SUN8I_ADDA_MIC2G_CTRL_LINEOUTLSRC,
+ SUN8I_ADDA_MIC2G_CTRL_LINEOUTRSRC,
+ sun8i_codec_lineout_src_enum_text);
+
+static const struct snd_kcontrol_new sun8i_codec_lineout_src[] = {
+ SOC_DAPM_ENUM("Line Out Source Playback Route",
+ sun8i_codec_lineout_src_enum),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_lineout_widgets[] = {
+ SND_SOC_DAPM_MUX("Line Out Source Playback Route",
+ SND_SOC_NOPM, 0, 0, sun8i_codec_lineout_src),
+ /* It is unclear if this is a buffer or gate, model it as a supply */
+ SND_SOC_DAPM_SUPPLY("Line Out Enable", SUN8I_ADDA_PAEN_HP_CTRL,
+ SUN8I_ADDA_PAEN_HP_CTRL_LINEOUTEN, 0, NULL, 0),
+ SND_SOC_DAPM_OUTPUT("LINEOUT"),
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_lineout_routes[] = {
+ { "Line Out Source Playback Route", "Stereo", "Left Mixer" },
+ { "Line Out Source Playback Route", "Stereo", "Right Mixer" },
+ { "Line Out Source Playback Route", "Mono Differential", "Left Mixer" },
+ { "Line Out Source Playback Route", "Mono Differential", "Right Mixer" },
+ { "LINEOUT", NULL, "Line Out Source Playback Route" },
+ { "LINEOUT", NULL, "Line Out Enable", },
+};
+
+static int sun8i_codec_add_lineout(struct snd_soc_component *cmpnt)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
+ struct device *dev = cmpnt->dev;
+ int ret;
+
+ ret = snd_soc_add_component_controls(cmpnt,
+ sun8i_codec_lineout_controls,
+ ARRAY_SIZE(sun8i_codec_lineout_controls));
+ if (ret) {
+ dev_err(dev, "Failed to add Line Out controls: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_lineout_widgets,
+ ARRAY_SIZE(sun8i_codec_lineout_widgets));
+ if (ret) {
+ dev_err(dev, "Failed to add Line Out DAPM widgets: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_lineout_routes,
+ ARRAY_SIZE(sun8i_codec_lineout_routes));
+ if (ret) {
+ dev_err(dev, "Failed to add Line Out DAPM routes: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+struct sun8i_codec_analog_quirks {
+ bool has_headphone;
+ bool has_hmic;
+ bool has_lineout;
+};
+
+static const struct sun8i_codec_analog_quirks sun8i_a23_quirks = {
+ .has_headphone = true,
+ .has_hmic = true,
+};
+
+static const struct sun8i_codec_analog_quirks sun8i_h3_quirks = {
+ .has_lineout = true,
+};
+
+static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt)
+{
+ struct device *dev = cmpnt->dev;
+ const struct sun8i_codec_analog_quirks *quirks;
+ int ret;
+
+ /*
+ * This would never return NULL unless someone directly registers a
+ * platform device matching this driver's name, without specifying a
+ * device tree node.
+ */
+ quirks = of_device_get_match_data(dev);
+
+ /* Add controls, widgets, and routes for individual features */
+
+ if (quirks->has_headphone) {
+ ret = sun8i_codec_add_headphone(cmpnt);
+ if (ret)
+ return ret;
+ }
+
+ if (quirks->has_hmic) {
+ sun8i_codec_add_hmic(cmpnt);
+ if (ret)
+ return ret;
+ }
+
+ if (quirks->has_lineout) {
+ ret = sun8i_codec_add_lineout(cmpnt);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
+ .controls = sun8i_codec_common_controls,
+ .num_controls = ARRAY_SIZE(sun8i_codec_common_controls),
+ .dapm_widgets = sun8i_codec_common_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_common_widgets),
+ .dapm_routes = sun8i_codec_common_routes,
+ .num_dapm_routes = ARRAY_SIZE(sun8i_codec_common_routes),
+ .probe = sun8i_codec_analog_cmpnt_probe,
+};
+
+static const struct of_device_id sun8i_codec_analog_of_match[] = {
+ {
+ .compatible = "allwinner,sun8i-a23-codec-analog",
+ .data = &sun8i_a23_quirks,
+ },
+ {
+ .compatible = "allwinner,sun8i-h3-codec-analog",
+ .data = &sun8i_h3_quirks,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
+
+static int sun8i_codec_analog_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct regmap *regmap;
+ void __iomem *base;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base)) {
+ dev_err(&pdev->dev, "Failed to map the registers\n");
+ return PTR_ERR(base);
+ }
+
+ regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
+ if (IS_ERR(regmap)) {
+ dev_err(&pdev->dev, "Failed to create regmap\n");
+ return PTR_ERR(regmap);
+ }
+
+ return devm_snd_soc_register_component(&pdev->dev,
+ &sun8i_codec_analog_cmpnt_drv,
+ NULL, 0);
+}
+
+static struct platform_driver sun8i_codec_analog_driver = {
+ .driver = {
+ .name = "sun8i-codec-analog",
+ .of_match_table = sun8i_codec_analog_of_match,
+ },
+ .probe = sun8i_codec_analog_probe,
+};
+module_platform_driver(sun8i_codec_analog_driver);
+
+MODULE_DESCRIPTION("Allwinner internal codec analog controls driver");
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sun8i-codec-analog");
--
2.10.2
^ permalink raw reply related
* Re: [PATCH 0/2] serial: introduce DSR handling property
From: Uwe Kleine-König @ 2016-11-22 19:09 UTC (permalink / raw)
To: Christoph Fritz
Cc: Rob Herring, Mark Rutland, Greg Kroah-Hartman, Jiri Slaby,
Geert Uytterhoeven, Arnd Bergmann,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1479834851-32442-1-git-send-email-chf.fritz-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
On Tue, Nov 22, 2016 at 06:14:09PM +0100, Christoph Fritz wrote:
> This patchset introduces device-tree property "disable-dsr" including
> documentation and usage.
>
> Christoph Fritz (2):
> doc: DT: add generic serial property to disable DSR
I'd add the documentation for all handshaking lines, not only dsr. And
I'd call it disable-hw-dsr, otherwise
{
disable-dsr;
dsr-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
}
looks strange. (Not 100% sure this would make sense, but I think it
does.)
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
--
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 1/2] of: base: add support to get machine model name
From: Frank Rowand @ 2016-11-22 18:44 UTC (permalink / raw)
To: Rob Herring, Sudeep Holla
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <582F5DC0.4080804-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hi Rob,
On 11/18/16 12:00, Frank Rowand wrote:
> On 11/18/16 06:46, Rob Herring wrote:
>> On Thu, Nov 17, 2016 at 03:32:54PM +0000, Sudeep Holla wrote:
>>> Currently platforms/drivers needing to get the machine model name are
>>> replicating the same snippet of code. In some case, the OF reference
>>> counting is either missing or incorrect.
>>>
>>> This patch adds support to read the machine model name either using
>>> the "model" or the "compatible" property in the device tree root node
>>> to the core OF/DT code.
>>>
>>> This can be used to remove all the duplicate code snippets doing exactly
>>> same thing later.
>>>
>>> Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>> Cc: Frank Rowand <frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>> Cc: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
>>> Signed-off-by: Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org>
>>> ---
>>> drivers/of/base.c | 32 ++++++++++++++++++++++++++++++++
>>> include/linux/of.h | 6 ++++++
>>> 2 files changed, 38 insertions(+)
>>>
>>> Hi Rob,
>>>
>>> It would be good if we can target this for v4.10, so that we have no
>>> dependencies to push PATCH 2/2 in v4.11
>>
>> Applied.
>>
>> Rob
>>
>
> A little fast on the trigger Rob.
>
> -Frank
This patch adds a function that leads to conflating the "model" property
and the "compatible" property. This leads to opaque, confusing and unclear
code where ever it is used. I think it is not good for the device tree
framework to contribute to writing unclear code.
Further, only two of the proposed users of this new function appear to
be proper usage. I do not think that the small amount of reduced lines
of code is a good trade off for the reduced code clarity and for the
potential for future mis-use of this function.
Can I convince you to revert this patch?
If not, will you accept a patch to change the function name to more
clearly indicate what it does? (One possible name would be
of_model_or_1st_compatible().)
-Frank
--
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 1/2] PM / Domains: Introduce domain-performance-state binding
From: Vincent Guittot @ 2016-11-22 18:34 UTC (permalink / raw)
To: Kevin Hilman
Cc: Viresh Kumar, Rob Herring, Rafael Wysocki,
linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org,
linux-kernel, Mark Rutland, Ulf Hansson, Lina Iyer,
devicetree@vger.kernel.org, Stephen Boyd, Nayak Rajendra
In-Reply-To: <m260nfz8mr.fsf@baylibre.com>
On 22 November 2016 at 19:12, Kevin Hilman <khilman@baylibre.com> wrote:
> Viresh Kumar <viresh.kumar@linaro.org> writes:
>
>> On 21-11-16, 09:07, Rob Herring wrote:
>>> On Fri, Nov 18, 2016 at 02:53:12PM +0530, Viresh Kumar wrote:
>>> > Some platforms have the capability to configure the performance state of
>>> > their Power Domains. The performance levels are represented by positive
>>> > integer values, a lower value represents lower performance state.
>>> >
>>> > The power-domains until now were only concentrating on the idle state
>>> > management of the device and this needs to change in order to reuse the
>>> > infrastructure of power domains for active state management.
>>> >
>>> > This patch introduces a new optional property for the consumers of the
>>> > power-domains: domain-performance-state.
>>> >
>>> > If the consumers don't need the capability of switching to different
>>> > domain performance states at runtime, then they can simply define their
>>> > required domain performance state in their node directly. Otherwise the
>>> > consumers can define their requirements with help of other
>>> > infrastructure, for example the OPP table.
>>> >
>>> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>>> > ---
>>> > Documentation/devicetree/bindings/power/power_domain.txt | 6 ++++++
>>> > 1 file changed, 6 insertions(+)
>>> >
>>> > diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
>>> > index e1650364b296..db42eacf8b5c 100644
>>> > --- a/Documentation/devicetree/bindings/power/power_domain.txt
>>> > +++ b/Documentation/devicetree/bindings/power/power_domain.txt
>>> > @@ -106,6 +106,12 @@ domain provided by the 'parent' power controller.
>>> > - power-domains : A phandle and PM domain specifier as defined by bindings of
>>> > the power controller specified by phandle.
>>> >
>>> > +Optional properties:
>>> > +- domain-performance-state: A positive integer value representing the minimum
>>> > + performance level (of the parent domain) required by the consumer for its
>>> > + working. The integer value '1' represents the lowest performance level and the
>>> > + highest value represents the highest performance level.
>>>
>>> How does one come up with the range of values?
>>
>> Why would we need a range here? The value here represents the minimum 'state'
>> and the assumption is that everything above that level would be fine. So the
>> range is automatically: domain-performance-state -> MAX.
>>
>>> It seems like you are
>>> just making up numbers. Couldn't the domain performance level be an OPP
>>> in the sense that it is a collection of clock frequencies and voltage
>>> settings?
>>
>> The clock is going to be handled by the device itself (at least for the case we
>> have today) and the performance-state lies with the power-domain which is
>> configured separately. If the performance level includes both clk and voltage,
>> then why would we need to show the clock rates in the DT ? Wouldn't a
>> performance level be enough in such cases?
>
> I think the question is: what does the performance-level of a domain
> actually mean? Or, what are the units?
>
> 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. 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)
>
> 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.
>
> Kevin
>
>
>
>
>
>
>
>
^ permalink raw reply
* Re: [PATCH v4 1/2] i2c: aspeed: added driver for Aspeed I2C
From: Kachalov Anton @ 2016-11-22 18:23 UTC (permalink / raw)
To: Cédric Le Goater, Brendan Higgins,
wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
openbmc-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <28078e6d-f5e4-da59-e226-baa9a60a4b19-Bxea+6Xhats@public.gmane.org>
Hello.
I would like to add my five cents here. Do not limit the bus_clk with 400kHz (FM) while HighSpeed is above 1MHz (above FM+ devices). I've successfully tested FM+ (1Mhz) in a quite big i2c network (a number of pca9600, pca9675, pca9848) with at least eight AST2150 SoCs on the common bus.
BTW. Just a lame question. If the device isn't designed to work on the higher speed (like standard of FM) while the bus selected as FM+, would those kind of devices just unoperate or may have undefined behavior and disturb the SDA/SCL? Just wondering to dynamically slowdown down to 100Khz (if needed) for the specific slave, but keep high rate (FM+) at the normal operation.
--- source/drivers/i2c/busses/i2c-aspeed.c.orig 2016-11-18 19:17:41.000000000 +0300
+++ source/drivers/i2c/busses/i2c-aspeed.c 2016-11-18 19:17:49.682092658 +0300
@@ -310,7 +310,7 @@ static void ast_i2c_dev_init(struct ast_
bus->bus_clk, clk_get_rate(bus->pclk));
/* Set AC Timing */
- if(bus->bus_clk / 1000 > 400) {
+ if(bus->bus_clk / 1000 > 1000) {
ast_i2c_write(bus, ast_i2c_read(bus, I2C_FUN_CTRL_REG) |
AST_I2CD_M_HIGH_SPEED_EN |
AST_I2CD_M_SDA_DRIVE_1T_EN |
22.11.2016, 12:07, "Cédric Le Goater" <clg-Bxea+6Xhats@public.gmane.org>:
> Hello Brendan,
>
> A few comments below,
>
> On 11/05/2016 02:58 AM, Brendan Higgins wrote:
>> Added initial master and slave support for Aspeed I2C controller.
>> Supports fourteen busses present in ast24xx and ast25xx BMC SoCs by
>> Aspeed.
>>
>> Signed-off-by: Brendan Higgins <brendanhiggins-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
>> ---
>> Changes for v2:
>> - Added single module_init (multiple was breaking some builds).
>> Changes for v3:
>> - Removed "bus" device tree param; now extracted from bus address offset
>> Changes for v4:
>> - I2C adapter number is now generated dynamically unless specified in alias.
>> ---
>> drivers/i2c/busses/Kconfig | 10 +
>> drivers/i2c/busses/Makefile | 1 +
>> drivers/i2c/busses/i2c-aspeed.c | 807 ++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 818 insertions(+)
>> create mode 100644 drivers/i2c/busses/i2c-aspeed.c
>>
>> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
>> index d252276..b6caa5d 100644
>> --- a/drivers/i2c/busses/Kconfig
>> +++ b/drivers/i2c/busses/Kconfig
>> @@ -1009,6 +1009,16 @@ config I2C_RCAR
>> This driver can also be built as a module. If so, the module
>> will be called i2c-rcar.
>>
>> +config I2C_ASPEED
>> + tristate "Aspeed AST2xxx SoC I2C Controller"
>> + depends on ARCH_ASPEED
>> + help
>> + If you say yes to this option, support will be included for the
>> + Aspeed AST2xxx SoC I2C controller.
>> +
>> + This driver can also be built as a module. If so, the module
>> + will be called i2c-aspeed.
>> +
>> comment "External I2C/SMBus adapter drivers"
>>
>> config I2C_DIOLAN_U2C
>> diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
>> index 29764cc..826e780 100644
>> --- a/drivers/i2c/busses/Makefile
>> +++ b/drivers/i2c/busses/Makefile
>> @@ -99,6 +99,7 @@ obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
>> obj-$(CONFIG_I2C_XLR) += i2c-xlr.o
>> obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o
>> obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
>> +obj-$(CONFIG_I2C_ASPEED) += i2c-aspeed.o
>>
>> # External I2C/SMBus adapter drivers
>> obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o
>> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
>> new file mode 100644
>> index 0000000..88e078a
>> --- /dev/null
>> +++ b/drivers/i2c/busses/i2c-aspeed.c
>> @@ -0,0 +1,807 @@
>> +/*
>> + * I2C adapter for the ASPEED I2C bus.
>> + *
>> + * Copyright (C) 2012-2020 ASPEED Technology Inc.
>> + * Copyright 2016 IBM Corporation
>> + * Copyright 2016 Google, Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/i2c.h>
>> +#include <linux/irq.h>
>> +#include <linux/irqdomain.h>
>> +#include <linux/init.h>
>> +#include <linux/io.h>
>> +#include <linux/errno.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/completion.h>
>> +#include <linux/slab.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/err.h>
>> +#include <linux/clk.h>
>> +
>> +/* I2C Register */
>> +#define ASPEED_I2C_FUN_CTRL_REG 0x00
>> +#define ASPEED_I2C_AC_TIMING_REG1 0x04
>> +#define ASPEED_I2C_AC_TIMING_REG2 0x08
>> +#define ASPEED_I2C_INTR_CTRL_REG 0x0c
>> +#define ASPEED_I2C_INTR_STS_REG 0x10
>> +#define ASPEED_I2C_CMD_REG 0x14
>> +#define ASPEED_I2C_DEV_ADDR_REG 0x18
>> +#define ASPEED_I2C_BYTE_BUF_REG 0x20
>> +#define ASPEED_I2C_OFFSET_START 0x40
>> +#define ASPEED_I2C_OFFSET_INCREMENT 0x40
>> +
>> +#define ASPEED_I2C_NUM_BUS 14
>> +
>> +/* Global Register Definition */
>> +/* 0x00 : I2C Interrupt Status Register */
>> +/* 0x08 : I2C Interrupt Target Assignment */
>> +
>> +/* Device Register Definition */
>> +/* 0x00 : I2CD Function Control Register */
>> +#define ASPEED_I2CD_MULTI_MASTER_DIS BIT(15)
>> +#define ASPEED_I2CD_SDA_DRIVE_1T_EN BIT(8)
>> +#define ASPEED_I2CD_M_SDA_DRIVE_1T_EN BIT(7)
>> +#define ASPEED_I2CD_M_HIGH_SPEED_EN BIT(6)
>> +#define ASPEED_I2CD_SLAVE_EN BIT(1)
>> +#define ASPEED_I2CD_MASTER_EN BIT(0)
>> +
>> +/* 0x08 : I2CD Clock and AC Timing Control Register #2 */
>> +#define ASPEED_NO_TIMEOUT_CTRL 0
>> +
>> +
>> +/* 0x0c : I2CD Interrupt Control Register &
>> + * 0x10 : I2CD Interrupt Status Register
>> + *
>> + * These share bit definitions, so use the same values for the enable &
>> + * status bits.
>> + */
>> +#define ASPEED_I2CD_INTR_SDA_DL_TIMEOUT BIT(14)
>> +#define ASPEED_I2CD_INTR_BUS_RECOVER_DONE BIT(13)
>> +#define ASPEED_I2CD_INTR_SLAVE_MATCH BIT(7)
>> +#define ASPEED_I2CD_INTR_SCL_TIMEOUT BIT(6)
>> +#define ASPEED_I2CD_INTR_ABNORMAL BIT(5)
>> +#define ASPEED_I2CD_INTR_NORMAL_STOP BIT(4)
>> +#define ASPEED_I2CD_INTR_ARBIT_LOSS BIT(3)
>> +#define ASPEED_I2CD_INTR_RX_DONE BIT(2)
>> +#define ASPEED_I2CD_INTR_TX_NAK BIT(1)
>> +#define ASPEED_I2CD_INTR_TX_ACK BIT(0)
>> +
>> +/* 0x14 : I2CD Command/Status Register */
>> +#define ASPEED_I2CD_SCL_LINE_STS BIT(18)
>> +#define ASPEED_I2CD_SDA_LINE_STS BIT(17)
>> +#define ASPEED_I2CD_BUS_BUSY_STS BIT(16)
>> +#define ASPEED_I2CD_BUS_RECOVER_CMD BIT(11)
>> +
>> +/* Command Bit */
>> +#define ASPEED_I2CD_M_STOP_CMD BIT(5)
>> +#define ASPEED_I2CD_M_S_RX_CMD_LAST BIT(4)
>> +#define ASPEED_I2CD_M_RX_CMD BIT(3)
>> +#define ASPEED_I2CD_S_TX_CMD BIT(2)
>> +#define ASPEED_I2CD_M_TX_CMD BIT(1)
>> +#define ASPEED_I2CD_M_START_CMD BIT(0)
>> +
>> +/* 0x18 : I2CD Slave Device Address Register */
>> +#define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
>> +
>> +enum aspeed_i2c_slave_state {
>> + ASPEED_I2C_SLAVE_START,
>> + ASPEED_I2C_SLAVE_READ_REQUESTED,
>> + ASPEED_I2C_SLAVE_READ_PROCESSED,
>> + ASPEED_I2C_SLAVE_WRITE_REQUESTED,
>> + ASPEED_I2C_SLAVE_WRITE_RECEIVED,
>> + ASPEED_I2C_SLAVE_STOP,
>> +};
>> +
>> +struct aspeed_i2c_bus {
>> + struct i2c_adapter adap;
>> + struct device *dev;
>> + void __iomem *base;
>> + spinlock_t lock;
>> + struct completion cmd_complete;
>> + int irq;
>> + /* Transaction state. */
>> + struct i2c_msg *msg;
>> + int msg_pos;
>> + u32 cmd_err;
>> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
>> + struct i2c_client *slave;
>> + enum aspeed_i2c_slave_state slave_state;
>> +#endif
>> +};
>> +
>> +struct aspeed_i2c_controller {
>> + struct device *dev;
>> + void __iomem *base;
>> + int irq;
>> + struct irq_domain *irq_domain;
>> +};
>> +
>> +static inline void aspeed_i2c_write(struct aspeed_i2c_bus *bus, u32 val,
>> + u32 reg)
>> +{
>> + writel(val, bus->base + reg);
>> +}
>> +
>> +static inline u32 aspeed_i2c_read(struct aspeed_i2c_bus *bus, u32 reg)
>> +{
>> + return readl(bus->base + reg);
>> +}
>> +
>> +static u8 aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
>> +{
>> + u32 command;
>> + unsigned long time_left;
>> + unsigned long flags;
>> + int ret = 0;
>> +
>> + spin_lock_irqsave(&bus->lock, flags);
>> + command = aspeed_i2c_read(bus, ASPEED_I2C_CMD_REG);
>> + /* Bus is idle: no recovery needed. */
>> + if ((command & ASPEED_I2CD_SDA_LINE_STS) &&
>> + (command & ASPEED_I2CD_SCL_LINE_STS))
>> + goto out;
>> +
>> + dev_dbg(bus->dev, "bus hung (state %x), attempting recovery\n",
>> + command);
>> +
>> + /* Bus held: put bus in stop state. */
>> + if ((command & ASPEED_I2CD_SDA_LINE_STS) &&
>> + !(command & ASPEED_I2CD_SCL_LINE_STS)) {
>> + aspeed_i2c_write(bus, ASPEED_I2CD_M_STOP_CMD,
>> + ASPEED_I2C_CMD_REG);
>> + reinit_completion(&bus->cmd_complete);
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> +
>> + time_left = wait_for_completion_interruptible_timeout(
>> + &bus->cmd_complete, bus->adap.timeout * HZ);
>> +
>> + spin_lock_irqsave(&bus->lock, flags);
>> + if (time_left == 0)
>> + ret = -ETIMEDOUT;
>> + else if (bus->cmd_err)
>> + ret = -EIO;
>> + /* Bus error. */
>> + } else if (!(command & ASPEED_I2CD_SDA_LINE_STS)) {
>> + aspeed_i2c_write(bus, ASPEED_I2CD_BUS_RECOVER_CMD,
>> + ASPEED_I2C_CMD_REG);
>> + reinit_completion(&bus->cmd_complete);
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> +
>> + time_left = wait_for_completion_interruptible_timeout(
>> + &bus->cmd_complete, bus->adap.timeout * HZ);
>> +
>> + spin_lock_irqsave(&bus->lock, flags);
>> + if (time_left == 0)
>> + ret = -ETIMEDOUT;
>> + else if (bus->cmd_err)
>> + ret = -EIO;
>> + /* Recovery failed. */
>> + else if (!(aspeed_i2c_read(bus, ASPEED_I2C_CMD_REG) &
>> + ASPEED_I2CD_SDA_LINE_STS))
>> + ret = -EIO;
>> + }
>> +
>> +out:
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> + return ret;
>> +}
>> +
>> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
>> +static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
>> +{
>> + bool irq_handled = true;
>> + u32 command;
>> + u32 irq_status;
>> + u32 status_ack = 0;
>> + u8 value;
>> + struct i2c_client *slave = bus->slave;
>> +
>> + spin_lock(&bus->lock);
>> + if (!slave) {
>> + irq_handled = false;
>> + goto out;
>> + }
>> + command = aspeed_i2c_read(bus, ASPEED_I2C_CMD_REG);
>> + irq_status = aspeed_i2c_read(bus, ASPEED_I2C_INTR_STS_REG);
>> +
>> + /* Slave was requested, restart state machine. */
>> + if (irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH) {
>> + status_ack |= ASPEED_I2CD_INTR_SLAVE_MATCH;
>> + bus->slave_state = ASPEED_I2C_SLAVE_START;
>> + }
>> + /* Slave is not currently active, irq was for someone else. */
>> + if (bus->slave_state == ASPEED_I2C_SLAVE_STOP) {
>> + irq_handled = false;
>> + goto out;
>> + }
>> +
>> + dev_dbg(bus->dev, "slave irq status 0x%08x, cmd 0x%08x\n",
>> + irq_status, command);
>> +
>> + /* Slave was sent something. */
>> + if (irq_status & ASPEED_I2CD_INTR_RX_DONE) {
>> + value = aspeed_i2c_read(bus, ASPEED_I2C_BYTE_BUF_REG) >> 8;
>> + /* Handle address frame. */
>> + if (bus->slave_state == ASPEED_I2C_SLAVE_START) {
>> + if (value & 0x1)
>> + bus->slave_state =
>> + ASPEED_I2C_SLAVE_READ_REQUESTED;
>> + else
>> + bus->slave_state =
>> + ASPEED_I2C_SLAVE_WRITE_REQUESTED;
>> + }
>> + status_ack |= ASPEED_I2CD_INTR_RX_DONE;
>> + }
>> +
>> + /* Slave was asked to stop. */
>> + if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) {
>> + status_ack |= ASPEED_I2CD_INTR_NORMAL_STOP;
>> + bus->slave_state = ASPEED_I2C_SLAVE_STOP;
>> + }
>> + if (irq_status & ASPEED_I2CD_INTR_TX_NAK) {
>> + status_ack |= ASPEED_I2CD_INTR_TX_NAK;
>> + bus->slave_state = ASPEED_I2C_SLAVE_STOP;
>> + }
>> +
>> + if (bus->slave_state == ASPEED_I2C_SLAVE_READ_REQUESTED) {
>> + if (irq_status & ASPEED_I2CD_INTR_TX_ACK)
>> + dev_err(bus->dev, "Unexpected ACK on read request.\n");
>> + bus->slave_state = ASPEED_I2C_SLAVE_READ_PROCESSED;
>> +
>> + i2c_slave_event(slave, I2C_SLAVE_READ_REQUESTED, &value);
>> + aspeed_i2c_write(bus, value, ASPEED_I2C_BYTE_BUF_REG);
>> + aspeed_i2c_write(bus, ASPEED_I2CD_S_TX_CMD, ASPEED_I2C_CMD_REG);
>> + } else if (bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) {
>> + status_ack |= ASPEED_I2CD_INTR_TX_ACK;
>> + if (!(irq_status & ASPEED_I2CD_INTR_TX_ACK))
>> + dev_err(bus->dev,
>> + "Expected ACK after processed read.\n");
>> + i2c_slave_event(slave, I2C_SLAVE_READ_PROCESSED, &value);
>> + aspeed_i2c_write(bus, value, ASPEED_I2C_BYTE_BUF_REG);
>> + aspeed_i2c_write(bus, ASPEED_I2CD_S_TX_CMD, ASPEED_I2C_CMD_REG);
>> + } else if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_REQUESTED) {
>> + bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED;
>> + i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value);
>> + } else if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED) {
>> + i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value);
>> + } else if (bus->slave_state == ASPEED_I2C_SLAVE_STOP) {
>> + i2c_slave_event(slave, I2C_SLAVE_STOP, &value);
>> + }
>> +
>> + if (status_ack != irq_status)
>> + dev_err(bus->dev,
>> + "irq handled != irq. expected %x, but was %x\n",
>> + irq_status, status_ack);
>> + aspeed_i2c_write(bus, status_ack, ASPEED_I2C_INTR_STS_REG);
>> +
>> +out:
>> + spin_unlock(&bus->lock);
>> + return irq_handled;
>> +}
>> +#endif
>> +
>> +static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
>> +{
>> + const u32 errs = ASPEED_I2CD_INTR_ARBIT_LOSS |
>> + ASPEED_I2CD_INTR_ABNORMAL |
>> + ASPEED_I2CD_INTR_SCL_TIMEOUT |
>> + ASPEED_I2CD_INTR_SDA_DL_TIMEOUT |
>> + ASPEED_I2CD_INTR_TX_NAK;
>> + u32 irq_status;
>> +
>> + spin_lock(&bus->lock);
>> + irq_status = aspeed_i2c_read(bus, ASPEED_I2C_INTR_STS_REG);
>> + bus->cmd_err = irq_status & errs;
>> +
>> + dev_dbg(bus->dev, "master irq status 0x%08x\n", irq_status);
>> +
>> + /* No message to transfer. */
>> + if (bus->cmd_err ||
>> + (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) ||
>> + (irq_status & ASPEED_I2CD_INTR_BUS_RECOVER_DONE)) {
>> + complete(&bus->cmd_complete);
>> + goto out;
>> + } else if (!bus->msg || bus->msg_pos >= bus->msg->len)
>> + goto out;
>> +
>> + if ((bus->msg->flags & I2C_M_RD) &&
>> + (irq_status & ASPEED_I2CD_INTR_RX_DONE)) {
>> + bus->msg->buf[bus->msg_pos++] = aspeed_i2c_read(
>> + bus, ASPEED_I2C_BYTE_BUF_REG) >> 8;
>> + if (bus->msg_pos + 1 < bus->msg->len)
>> + aspeed_i2c_write(bus, ASPEED_I2CD_M_RX_CMD,
>> + ASPEED_I2C_CMD_REG);
>> + else if (bus->msg_pos < bus->msg->len)
>> + aspeed_i2c_write(bus, ASPEED_I2CD_M_RX_CMD |
>> + ASPEED_I2CD_M_S_RX_CMD_LAST,
>> + ASPEED_I2C_CMD_REG);
>> + } else if (!(bus->msg->flags & I2C_M_RD) &&
>> + (irq_status & ASPEED_I2CD_INTR_TX_ACK)) {
>> + aspeed_i2c_write(bus, bus->msg->buf[bus->msg_pos++],
>> + ASPEED_I2C_BYTE_BUF_REG);
>> + aspeed_i2c_write(bus, ASPEED_I2CD_M_TX_CMD, ASPEED_I2C_CMD_REG);
>> + }
>
> is it safe to start a new transaction when in a interrupt handler ?
>
>> + /* Transmission complete: notify caller. */
>> + if (bus->msg_pos >= bus->msg->len)
>> + complete(&bus->cmd_complete);
>> +out:
>> + aspeed_i2c_write(bus, irq_status, ASPEED_I2C_INTR_STS_REG);
>
> so this is clearing the interrupt status just after having started
> a new transaction on the bus. It looks unsafe to me as it could
> clear the status of the just started transaction.
>
>> + spin_unlock(&bus->lock);
>> + return true;
>> +}
>> +
>> +static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
>> +{
>> + struct aspeed_i2c_bus *bus = dev_id;
>> +
>> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
>> + if (aspeed_i2c_slave_irq(bus)) {
>> + dev_dbg(bus->dev, "irq handled by slave.\n");
>> + return IRQ_HANDLED;
>> + }
>> +#endif
>> + if (aspeed_i2c_master_irq(bus)) {
>> + dev_dbg(bus->dev, "irq handled by master.\n");
>> + return IRQ_HANDLED;
>> + }
>> + dev_err(bus->dev, "irq not handled properly!\n");
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static int aspeed_i2c_master_single_xfer(struct i2c_adapter *adap,
>> + struct i2c_msg *msg)
>> +{
>> + struct aspeed_i2c_bus *bus = adap->algo_data;
>> + unsigned long flags;
>> + u8 slave_addr;
>> + u32 command = ASPEED_I2CD_M_START_CMD | ASPEED_I2CD_M_TX_CMD;
>> + int ret = msg->len;
>> + unsigned long time_left;
>> +
>> + spin_lock_irqsave(&bus->lock, flags);
>> + bus->msg = msg;
>> + bus->msg_pos = 0;
>> + slave_addr = msg->addr << 1;
>> + if (msg->flags & I2C_M_RD) {
>> + slave_addr |= 1;
>> + command |= ASPEED_I2CD_M_RX_CMD;
>> + if (msg->len == 1)
>> + command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> + }
>> + aspeed_i2c_write(bus, slave_addr, ASPEED_I2C_BYTE_BUF_REG);
>> + aspeed_i2c_write(bus, command, ASPEED_I2C_CMD_REG);
>> + reinit_completion(&bus->cmd_complete);
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> +
>> + time_left = wait_for_completion_interruptible_timeout(
>> + &bus->cmd_complete, bus->adap.timeout * HZ * msg->len);
>
> Why do you multiply by * msg->len ?
>
>> + if (time_left == 0)
>> + return -ETIMEDOUT;
>> +
>> + spin_lock_irqsave(&bus->lock, flags);
>> + if (bus->cmd_err)
>> + ret = -EIO;
>> + bus->msg = NULL;
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> +
>> + return ret;
>> +}
>> +
>> +static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
>> + struct i2c_msg *msgs, int num)
>> +{
>> + struct aspeed_i2c_bus *bus = adap->algo_data;
>> + int ret;
>> + int i;
>> + unsigned long flags;
>> + unsigned long time_left;
>> +
>> + /* If bus is busy, attempt recovery. We assume a single master
>> + * environment.
>> + */
>> + if (aspeed_i2c_read(bus, ASPEED_I2C_CMD_REG) &
>> + ASPEED_I2CD_BUS_BUSY_STS) {
>> + ret = aspeed_i2c_recover_bus(bus);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + for (i = 0; i < num; i++) {
>> + ret = aspeed_i2c_master_single_xfer(adap, &msgs[i]);
>> + if (ret < 0)
>> + break;
>> + /* TODO: Support other forms of I2C protocol mangling. */
>> + if (msgs[i].flags & I2C_M_STOP) {
>> + spin_lock_irqsave(&bus->lock, flags);
>> + aspeed_i2c_write(bus, ASPEED_I2CD_M_STOP_CMD,
>> + ASPEED_I2C_CMD_REG);
>> + reinit_completion(&bus->cmd_complete);
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> +
>> + time_left = wait_for_completion_interruptible_timeout(
>> + &bus->cmd_complete,
>> + bus->adap.timeout * HZ);
>> + if (time_left == 0)
>> + return -ETIMEDOUT;
>> + }
>> + }
>> +
>> + spin_lock_irqsave(&bus->lock, flags);
>> + aspeed_i2c_write(bus, ASPEED_I2CD_M_STOP_CMD, ASPEED_I2C_CMD_REG);
>> + reinit_completion(&bus->cmd_complete);
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> +
>> + time_left = wait_for_completion_interruptible_timeout(
>> + &bus->cmd_complete, bus->adap.timeout * HZ);
>> + if (time_left == 0)
>> + return -ETIMEDOUT;
>> +
>> + /* If nothing went wrong, return number of messages transferred. */
>> + if (ret < 0)
>> + return ret;
>> + else
>> + return i;
>> +}
>> +
>> +static u32 aspeed_i2c_functionality(struct i2c_adapter *adap)
>> +{
>> + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA;
>> +}
>> +
>> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
>> +static int aspeed_i2c_reg_slave(struct i2c_client *client)
>> +{
>> + struct aspeed_i2c_bus *bus;
>> + unsigned long flags;
>> + u32 addr_reg_val;
>> + u32 func_ctrl_reg_val;
>> +
>> + bus = client->adapter->algo_data;
>> + spin_lock_irqsave(&bus->lock, flags);
>> + if (bus->slave) {
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> + return -EINVAL;
>> + }
>> +
>> + /* Set slave addr. */
>> + addr_reg_val = aspeed_i2c_read(bus, ASPEED_I2C_DEV_ADDR_REG);
>> + addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR_MASK;
>> + addr_reg_val |= client->addr & ASPEED_I2CD_DEV_ADDR_MASK;
>> + aspeed_i2c_write(bus, addr_reg_val, ASPEED_I2C_DEV_ADDR_REG);
>> +
>> + /* Switch from master mode to slave mode. */
>> + func_ctrl_reg_val = aspeed_i2c_read(bus, ASPEED_I2C_FUN_CTRL_REG);
>> + func_ctrl_reg_val &= ~ASPEED_I2CD_MASTER_EN;
>> + func_ctrl_reg_val |= ASPEED_I2CD_SLAVE_EN;
>> + aspeed_i2c_write(bus, func_ctrl_reg_val, ASPEED_I2C_FUN_CTRL_REG);
>> +
>> + bus->slave = client;
>> + bus->slave_state = ASPEED_I2C_SLAVE_STOP;
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> + return 0;
>> +}
>> +
>> +static int aspeed_i2c_unreg_slave(struct i2c_client *client)
>> +{
>> + struct aspeed_i2c_bus *bus = client->adapter->algo_data;
>> + unsigned long flags;
>> + u32 func_ctrl_reg_val;
>> +
>> + spin_lock_irqsave(&bus->lock, flags);
>> + if (!bus->slave) {
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> + return -EINVAL;
>> + }
>> +
>> + /* Switch from slave mode to master mode. */
>> + func_ctrl_reg_val = aspeed_i2c_read(bus, ASPEED_I2C_FUN_CTRL_REG);
>> + func_ctrl_reg_val &= ~ASPEED_I2CD_SLAVE_EN;
>> + func_ctrl_reg_val |= ASPEED_I2CD_MASTER_EN;
>> + aspeed_i2c_write(bus, func_ctrl_reg_val, ASPEED_I2C_FUN_CTRL_REG);
>> +
>> + bus->slave = NULL;
>> + spin_unlock_irqrestore(&bus->lock, flags);
>> + return 0;
>> +}
>> +#endif
>> +
>> +static const struct i2c_algorithm aspeed_i2c_algo = {
>> + .master_xfer = aspeed_i2c_master_xfer,
>> + .functionality = aspeed_i2c_functionality,
>> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
>> + .reg_slave = aspeed_i2c_reg_slave,
>> + .unreg_slave = aspeed_i2c_unreg_slave,
>> +#endif
>> +};
>> +
>> +static u32 aspeed_i2c_get_clk_reg_val(u32 divider_ratio)
>> +{
>> + unsigned int inc = 0, div;
>> + u32 scl_low, scl_high, data;
>> +
>> + for (div = 0; divider_ratio >= 16; div++) {
>> + inc |= (divider_ratio & 1);
>> + divider_ratio >>= 1;
>> + }
>> + divider_ratio += inc;
>> + scl_low = (divider_ratio >> 1) - 1;
>> + scl_high = divider_ratio - scl_low - 2;
>> + data = 0x77700300 | (scl_high << 16) | (scl_low << 12) | div;
>> + return data;
>> +}
>> +
>> +static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus,
>> + struct platform_device *pdev)
>> +{
>> + struct clk *pclk;
>> + u32 clk_freq;
>> + u32 divider_ratio;
>> + int ret;
>> +
>> + pclk = devm_clk_get(&pdev->dev, NULL);
>> + if (IS_ERR(pclk)) {
>> + dev_err(&pdev->dev, "clk_get failed\n");
>> + return PTR_ERR(pclk);
>> + }
>> + ret = of_property_read_u32(pdev->dev.of_node,
>> + "clock-frequency", &clk_freq);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev,
>> + "Could not read clock-frequency property\n");
>> + clk_freq = 100000;
>> + }
>> + divider_ratio = clk_get_rate(pclk) / clk_freq;
>> + /* We just need the clock rate, we don't actually use the clk object. */
>> + devm_clk_put(&pdev->dev, pclk);
>> +
>> + /* Set AC Timing */
>> + if (clk_freq / 1000 > 400) {
>> + aspeed_i2c_write(bus, aspeed_i2c_read(bus,
>> + ASPEED_I2C_FUN_CTRL_REG) |
>> + ASPEED_I2CD_M_HIGH_SPEED_EN |
>> + ASPEED_I2CD_M_SDA_DRIVE_1T_EN |
>> + ASPEED_I2CD_SDA_DRIVE_1T_EN,
>> + ASPEED_I2C_FUN_CTRL_REG);
>> +
>> + aspeed_i2c_write(bus, 0x3, ASPEED_I2C_AC_TIMING_REG2);
>> + aspeed_i2c_write(bus, aspeed_i2c_get_clk_reg_val(divider_ratio),
>> + ASPEED_I2C_AC_TIMING_REG1);
>> + } else {
>> + aspeed_i2c_write(bus, aspeed_i2c_get_clk_reg_val(divider_ratio),
>> + ASPEED_I2C_AC_TIMING_REG1);
>> + aspeed_i2c_write(bus, ASPEED_NO_TIMEOUT_CTRL,
>> + ASPEED_I2C_AC_TIMING_REG2);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static void noop(struct irq_data *data) { }
>> +
>> +static struct irq_chip aspeed_i2c_irqchip = {
>> + .name = "ast-i2c",
>> + .irq_unmask = noop,
>> + .irq_mask = noop,
>> +};
>> +
>> +static int aspeed_i2c_probe_bus(struct platform_device *pdev)
>> +{
>> + struct aspeed_i2c_bus *bus;
>> + struct aspeed_i2c_controller *controller =
>> + dev_get_drvdata(pdev->dev.parent);
>> + struct resource *res;
>> + int ret, irq;
>> + u32 hwirq;
>> +
>> + bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
>> + if (!bus)
>> + return -ENOMEM;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + bus->base = devm_ioremap_resource(&pdev->dev, res);
>> + if (IS_ERR(bus->base))
>> + return PTR_ERR(bus->base);
>> +
>> + bus->irq = platform_get_irq(pdev, 0);
>> + if (bus->irq < 0)
>> + return -ENXIO;
>> + ret = of_property_read_u32(pdev->dev.of_node, "interrupts", &hwirq);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "no I2C 'interrupts' property\n");
>> + return -ENXIO;
>> + }
>> + irq = irq_create_mapping(controller->irq_domain, hwirq);
>> + irq_set_chip_data(irq, controller);
>> + irq_set_chip_and_handler(irq, &aspeed_i2c_irqchip, handle_simple_irq);
>> + ret = devm_request_irq(&pdev->dev, bus->irq, aspeed_i2c_bus_irq,
>> + 0, dev_name(&pdev->dev), bus);
>> + if (ret) {
>> + dev_err(&pdev->dev, "failed to request interrupt\n");
>> + return -ENXIO;
>> + }
>> +
>> + /* Initialize the I2C adapter */
>> + spin_lock_init(&bus->lock);
>> + init_completion(&bus->cmd_complete);
>> + bus->adap.owner = THIS_MODULE;
>> + bus->adap.retries = 0;
>> + bus->adap.timeout = 5;
>> + bus->adap.algo = &aspeed_i2c_algo;
>> + bus->adap.algo_data = bus;
>> + bus->adap.dev.parent = &pdev->dev;
>> + bus->adap.dev.of_node = pdev->dev.of_node;
>> + snprintf(bus->adap.name, sizeof(bus->adap.name), "Aspeed i2c");
>> +
>> + bus->dev = &pdev->dev;
>> +
>> + /* reset device: disable master & slave functions */
>> + aspeed_i2c_write(bus, 0, ASPEED_I2C_FUN_CTRL_REG);
>> +
>> + ret = aspeed_i2c_init_clk(bus, pdev);
>> + if (ret < 0)
>> + return ret;
>> +
>> + /* Enable Master Mode */
>> + aspeed_i2c_write(bus, aspeed_i2c_read(bus, ASPEED_I2C_FUN_CTRL_REG) |
>> + ASPEED_I2CD_MASTER_EN |
>> + ASPEED_I2CD_MULTI_MASTER_DIS, ASPEED_I2C_FUN_CTRL_REG);
>> +
>> + /* Set interrupt generation of I2C controller */
>> + aspeed_i2c_write(bus, ASPEED_I2CD_INTR_SDA_DL_TIMEOUT |
>> + ASPEED_I2CD_INTR_BUS_RECOVER_DONE |
>> + ASPEED_I2CD_INTR_SCL_TIMEOUT |
>> + ASPEED_I2CD_INTR_ABNORMAL |
>> + ASPEED_I2CD_INTR_NORMAL_STOP |
>> + ASPEED_I2CD_INTR_ARBIT_LOSS |
>> + ASPEED_I2CD_INTR_RX_DONE |
>> + ASPEED_I2CD_INTR_TX_NAK |
>> + ASPEED_I2CD_INTR_TX_ACK,
>> + ASPEED_I2C_INTR_CTRL_REG);
>> +
>> + ret = i2c_add_adapter(&bus->adap);
>> + if (ret < 0)
>> + return -ENXIO;
>> +
>> + platform_set_drvdata(pdev, bus);
>> +
>> + dev_info(bus->dev, "i2c bus %d registered, irq %d\n",
>> + bus->adap.nr, bus->irq);
>> +
>> + return 0;
>> +}
>> +
>> +static int aspeed_i2c_remove_bus(struct platform_device *pdev)
>> +{
>> + struct aspeed_i2c_bus *bus = platform_get_drvdata(pdev);
>> +
>> + i2c_del_adapter(&bus->adap);
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id aspeed_i2c_bus_of_table[] = {
>> + { .compatible = "aspeed,ast2400-i2c-bus", },
>> + { .compatible = "aspeed,ast2500-i2c-bus", },
>> + { },
>> +};
>> +MODULE_DEVICE_TABLE(of, aspeed_i2c_bus_of_table);
>> +
>> +static struct platform_driver aspeed_i2c_bus_driver = {
>> + .probe = aspeed_i2c_probe_bus,
>> + .remove = aspeed_i2c_remove_bus,
>> + .driver = {
>> + .name = "ast-i2c-bus",
>> + .of_match_table = aspeed_i2c_bus_of_table,
>> + },
>> +};
>> +
>> +static void aspeed_i2c_controller_irq(struct irq_desc *desc)
>> +{
>> + struct aspeed_i2c_controller *c = irq_desc_get_handler_data(desc);
>> + unsigned long p, status;
>> + unsigned int bus_irq;
>> +
>> + status = readl(c->base);
>> + for_each_set_bit(p, &status, ASPEED_I2C_NUM_BUS) {
>> + bus_irq = irq_find_mapping(c->irq_domain, p);
>> + generic_handle_irq(bus_irq);
>> + }
>> +}
>> +
>> +static int aspeed_i2c_probe_controller(struct platform_device *pdev)
>> +{
>> + struct aspeed_i2c_controller *controller;
>> + struct device_node *np;
>> + struct resource *res;
>> +
>> + controller = kzalloc(sizeof(*controller), GFP_KERNEL);
>
> use devm_kzalloc() may be ?
>
> C.
>
>> + if (!controller)
>> + return -ENOMEM;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + controller->base = devm_ioremap_resource(&pdev->dev, res);
>> + if (IS_ERR(controller->base))
>> + return PTR_ERR(controller->base);
>> +
>> + controller->irq = platform_get_irq(pdev, 0);
>> + if (controller->irq < 0)
>> + return -ENXIO;
>> +
>> + controller->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
>> + ASPEED_I2C_NUM_BUS, &irq_domain_simple_ops, NULL);
>> + if (!controller->irq_domain)
>> + return -ENXIO;
>> + controller->irq_domain->name = "ast-i2c-domain";
>> +
>> + irq_set_chained_handler_and_data(controller->irq,
>> + aspeed_i2c_controller_irq, controller);
>> +
>> + controller->dev = &pdev->dev;
>> +
>> + platform_set_drvdata(pdev, controller);
>> +
>> + dev_info(controller->dev, "i2c controller registered, irq %d\n",
>> + controller->irq);
>> +
>> + for_each_child_of_node(pdev->dev.of_node, np) {
>> + of_platform_device_create(np, NULL, &pdev->dev);
>> + of_node_put(np);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int aspeed_i2c_remove_controller(struct platform_device *pdev)
>> +{
>> + struct aspeed_i2c_controller *controller = platform_get_drvdata(pdev);
>> +
>> + irq_domain_remove(controller->irq_domain);
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id aspeed_i2c_controller_of_table[] = {
>> + { .compatible = "aspeed,ast2400-i2c-controller", },
>> + { .compatible = "aspeed,ast2500-i2c-controller", },
>> + { },
>> +};
>> +MODULE_DEVICE_TABLE(of, aspeed_i2c_controller_of_table);
>> +
>> +static struct platform_driver aspeed_i2c_controller_driver = {
>> + .probe = aspeed_i2c_probe_controller,
>> + .remove = aspeed_i2c_remove_controller,
>> + .driver = {
>> + .name = "ast-i2c-controller",
>> + .of_match_table = aspeed_i2c_controller_of_table,
>> + },
>> +};
>> +
>> +static int __init aspeed_i2c_driver_init(void)
>> +{
>> + int ret;
>> +
>> + ret = platform_driver_register(&aspeed_i2c_controller_driver);
>> + if (ret < 0)
>> + return ret;
>> + return platform_driver_register(&aspeed_i2c_bus_driver);
>> +}
>> +module_init(aspeed_i2c_driver_init);
>> +
>> +static void __exit aspeed_i2c_driver_exit(void)
>> +{
>> + platform_driver_unregister(&aspeed_i2c_bus_driver);
>> + platform_driver_unregister(&aspeed_i2c_controller_driver);
>> +}
>> +module_exit(aspeed_i2c_driver_exit);
>> +
>> +MODULE_AUTHOR("Brendan Higgins <brendanhiggins-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>");
>> +MODULE_DESCRIPTION("Aspeed I2C Bus Driver");
>> +MODULE_LICENSE("GPL");
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
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 v2 1/5] ARM: memory: da8xx-ddrctl: new driver
From: Frank Rowand @ 2016-11-22 18:21 UTC (permalink / raw)
To: Sekhar Nori, Bartosz Golaszewski, Kevin Hilman, Michael Turquette,
Rob Herring, Mark Rutland, Peter Ujfalusi, Russell King
Cc: LKML, arm-soc, linux-drm, linux-devicetree, Jyri Sarha,
Tomi Valkeinen, David Airlie, Laurent Pinchart, Sudeep Holla
In-Reply-To: <800171a8-2e2c-2afb-f96d-800a17eaa17a-l0cyMroinI0@public.gmane.org>
On 11/21/16 22:25, Sekhar Nori wrote:
> Hi Frank,
>
> On Tuesday 22 November 2016 07:13 AM, Frank Rowand wrote:
>> On 11/21/16 08:33, Sekhar Nori wrote:
>>> On Monday 31 October 2016 08:15 PM, Bartosz Golaszewski wrote:
>>>> +static int da8xx_ddrctl_probe(struct platform_device *pdev)
>>>> +{
>>>> + const struct da8xx_ddrctl_config_knob *knob;
>>>> + const struct da8xx_ddrctl_setting *setting;
>>>> + struct device_node *node;
>>>> + struct resource *res;
>>>> + void __iomem *ddrctl;
>>>> + struct device *dev;
>>>> + u32 reg;
>>>> +
>>>> + dev = &pdev->dev;
>>>> + node = dev->of_node;
>>>> +
>>>> + setting = da8xx_ddrctl_get_board_settings();
>>>> + if (!setting) {
>>>> + dev_err(dev, "no settings for board '%s'\n",
>>>> + of_flat_dt_get_machine_name());
>>>> + return -EINVAL;
>>>> + }
>>>
>>> This causes a section mismatch because of_flat_dt_get_machine_name()
>>> has an __init annotation. I did not notice that before, sorry.
>>>
>>> It can be fixed with a patch like below:
>>>
>>> ---8<---
>>> diff --git a/drivers/memory/da8xx-ddrctl.c b/drivers/memory/da8xx-ddrctl.c
>>> index a20e7bbbcbe0..9ca5aab3ac54 100644
>>> --- a/drivers/memory/da8xx-ddrctl.c
>>> +++ b/drivers/memory/da8xx-ddrctl.c
>>> @@ -102,6 +102,18 @@ static const struct da8xx_ddrctl_setting *da8xx_ddrctl_get_board_settings(void)
>>> return NULL;
>>> }
>>>
>>> +static const char* da8xx_ddrctl_get_machine_name(void)
>>> +{
>>> + const char *str;
>>> + int ret;
>>> +
>>> + ret = of_property_read_string(of_root, "model", &str);
>>> + if (ret)
>>> + ret = of_property_read_string(of_root, "compatible", &str);
>>> +
>>> + return str;
>>> +}
>>> +
>>> static int da8xx_ddrctl_probe(struct platform_device *pdev)
>>> {
>>> const struct da8xx_ddrctl_config_knob *knob;
>>> @@ -118,7 +130,7 @@ static int da8xx_ddrctl_probe(struct platform_device *pdev)
>>> setting = da8xx_ddrctl_get_board_settings();
>>> if (!setting) {
>>> dev_err(dev, "no settings for board '%s'\n",
>>> - of_flat_dt_get_machine_name());
>>
>> da8xx_ddrctl_get_board_settings() tries to match based on the "compatible"
>> property in the root node. The "model" property in the root node has
>> nothing to do with the failure to match. So creating and then using
>> da8xx_ddrctl_get_machine_name() to potentially report model is not useful.
>>
>> It should be sufficient to simply report that no compatible matched.
>
> I agree with you on this. Even if model name is printed, you will have
> to go back and check the compatible anyway. But I think it will be
> useful to print the compatible instead of just reporting that nothing
> matched.
>
> Bartosz, if you agree too, could you send a fix patch just printing the
> compatible?
Please note that the compatible property might contain several strings, not just
a single string.
>
> Thanks,
> Sekhar
>
--
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 1/2] PM / Domains: Introduce domain-performance-state binding
From: Kevin Hilman @ 2016-11-22 18:12 UTC (permalink / raw)
To: Viresh Kumar
Cc: Rob Herring, Rafael Wysocki, linaro-kernel, linux-pm,
linux-kernel, Mark Rutland, Ulf Hansson, Vincent Guittot,
Lina Iyer, devicetree, Stephen Boyd, Nayak Rajendra
In-Reply-To: <20161122031717.GE10014@vireshk-i7>
Viresh Kumar <viresh.kumar@linaro.org> writes:
> On 21-11-16, 09:07, Rob Herring wrote:
>> On Fri, Nov 18, 2016 at 02:53:12PM +0530, Viresh Kumar wrote:
>> > Some platforms have the capability to configure the performance state of
>> > their Power Domains. The performance levels are represented by positive
>> > integer values, a lower value represents lower performance state.
>> >
>> > The power-domains until now were only concentrating on the idle state
>> > management of the device and this needs to change in order to reuse the
>> > infrastructure of power domains for active state management.
>> >
>> > This patch introduces a new optional property for the consumers of the
>> > power-domains: domain-performance-state.
>> >
>> > If the consumers don't need the capability of switching to different
>> > domain performance states at runtime, then they can simply define their
>> > required domain performance state in their node directly. Otherwise the
>> > consumers can define their requirements with help of other
>> > infrastructure, for example the OPP table.
>> >
>> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>> > ---
>> > Documentation/devicetree/bindings/power/power_domain.txt | 6 ++++++
>> > 1 file changed, 6 insertions(+)
>> >
>> > diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
>> > index e1650364b296..db42eacf8b5c 100644
>> > --- a/Documentation/devicetree/bindings/power/power_domain.txt
>> > +++ b/Documentation/devicetree/bindings/power/power_domain.txt
>> > @@ -106,6 +106,12 @@ domain provided by the 'parent' power controller.
>> > - power-domains : A phandle and PM domain specifier as defined by bindings of
>> > the power controller specified by phandle.
>> >
>> > +Optional properties:
>> > +- domain-performance-state: A positive integer value representing the minimum
>> > + performance level (of the parent domain) required by the consumer for its
>> > + working. The integer value '1' represents the lowest performance level and the
>> > + highest value represents the highest performance level.
>>
>> How does one come up with the range of values?
>
> Why would we need a range here? The value here represents the minimum 'state'
> and the assumption is that everything above that level would be fine. So the
> range is automatically: domain-performance-state -> MAX.
>
>> It seems like you are
>> just making up numbers. Couldn't the domain performance level be an OPP
>> in the sense that it is a collection of clock frequencies and voltage
>> settings?
>
> The clock is going to be handled by the device itself (at least for the case we
> have today) and the performance-state lies with the power-domain which is
> configured separately. If the performance level includes both clk and voltage,
> then why would we need to show the clock rates in the DT ? Wouldn't a
> performance level be enough in such cases?
I think the question is: what does the performance-level of a domain
actually mean? Or, what are the units?
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. 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.
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.
Kevin
^ permalink raw reply
* Re: [PATCH 5/10] dt: bindings: Add bindings for Marvell Xenon SD Host Controller
From: Gregory CLEMENT @ 2016-11-22 17:23 UTC (permalink / raw)
To: Rob Herring
Cc: Ziji Hu, Ulf Hansson, Adrian Hunter, linux-mmc, Jason Cooper,
Andrew Lunn, Sebastian Hesselbarth, devicetree, Thomas Petazzoni,
linux-arm-kernel, Jack(SH) Zhu, Jimmy Xu, Jisheng Zhang,
Nadav Haklai, Ryan Gao, Doug Jones, Shiwu Zhang, Victor Gu,
Wei(SOCP) Liu, Wilson Ding, Xueping Liu
In-Reply-To: <15b06a12-ed69-03a7-ccc7-0c133ce1ac1e@marvell.com>
Hi Rob,
On jeu., nov. 10 2016, Ziji Hu <huziji@marvell.com> wrote:
[...]
>>> +
>>> +- reg:
>>> + * For "marvell,xenon-sdhci", one register area for Xenon IP.
>>> +
>>> + * For "marvell,armada-3700-sdhci", two register areas.
>>> + The first one for Xenon IP register. The second one for the Armada 3700 SOC
>>> + PHY PAD Voltage Control register.
>>> + Please follow the examples with compatible "marvell,armada-3700-sdhci"
>>> + in below.
>>> + Please also check property marvell,pad-type in below.
>>> +
>>> +Optional Properties:
>>> +- marvell,xenon-slotno:
>>
>> Multiple slots should be represented as child nodes IMO. I think some
>> other bindings already do this.
>>
>
> All the slots are entirely independent.
> I prefer to consider it as multiple independent SDHCs placed in
> a single IP, instead of that a IP contains multiple child slots.
It was indeed what I tried to show in my answer for the 1st version:
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-October/461860.html
Maybe you missed it.
You also mentioned other bindings using child nodes, but for this one
we have one controller with only one set of register with multiple slots
(Atmel is an example). Here each slot have it own set of register.
Actually giving the fact that each slot is controlled by a different set
of register I wonder why the hardware can't also deduce the slot number
from the address register. For me it looks like an hardware bug but we
have to deal with it.
Do you still think we needchild node here?
>
> It is unlike the implementation which put multiple slots behind PCIe EP interface. sdhci-pci.c will handle each slot init one by one.
> If Xenon SDHC slots are represented as child nodes, there should also be a main entry in Xenon driver to init each child node one by one.
> In my very own opinion, it is inconvenient and unnecessary.
Gregory
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH 5/7] add bindings for stm32 IIO timer drivers
From: Lee Jones @ 2016-11-22 17:18 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: Lars-Peter Clausen, robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark Rutland,
alexandre.torgue-qxv4g6HH51o, devicetree-u79uwXL29TY76Z2rM5mHXA,
Linux Kernel Mailing List, Thierry Reding,
linux-pwm-u79uwXL29TY76Z2rM5mHXA, jic23-DgEjT+Ai2ygdnm+yROfE0A,
knaack.h-Mmb7MZpHnFY, Peter Meerwald-Stadler,
linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Fabrice Gasnier, Gerald Baeza, Arnaud Pouliquen, Linus Walleij,
Linaro Kernel Mailman List, Benjamin Gaignard
In-Reply-To: <CA+M3ks6ZoOND4VobU65OntEYU-f_XoNCV4wNZZ0_dYoOxy73+w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, 22 Nov 2016, Benjamin Gaignard wrote:
> [snip]
> >> + "st,stm32-iio-timer5"
> >> + "st,stm32-iio-timer6"
> >> + "st,stm32-iio-timer7"
> >> + "st,stm32-iio-timer8"
> >> + "st,stm32-iio-timer9"
> >> + "st,stm32-iio-timer10"
> >> + "st,stm32-iio-timer11"
> >> + "st,stm32-iio-timer12"
> >> + "st,stm32-iio-timer13"
> >> + "st,stm32-iio-timer14"
> >
> > We can't do this. This is a binding for a driver, not for the hardware.
> >
>
> Unfortunately each instance for the hardware IP have little
> differences like which triggers they could accept or size of the
> counter register,
> and I doesn't have value inside the hardware to distinguish them so
> the only way I found is to use compatible.
Can't you represent these as properties?
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 2/2] serial: imx: make DSR irq handling conditional
From: Christoph Fritz @ 2016-11-22 17:14 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Greg Kroah-Hartman, Jiri Slaby,
Geert Uytterhoeven, Arnd Bergmann
Cc: u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1479834851-32442-1-git-send-email-chf.fritz-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
This patch makes use of device-tree property disable-dsr. Disabling
DSR can be necessary on i.MX6SX to quirk buggy hardware, for more
info see commit 276b891e3879 ("ARM: dts: imx6sx: document SION
necessity of ENET1_REF_CLK1").
Signed-off-by: Christoph Fritz <chf.fritz-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
---
drivers/tty/serial/imx.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 0df2b1c..bd85a69a4 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -207,6 +207,7 @@ struct imx_port {
unsigned int dte_mode:1;
unsigned int irda_inv_rx:1;
unsigned int irda_inv_tx:1;
+ unsigned int dsr:1;
unsigned short trcv_delay; /* transceiver delay */
struct clk *clk_ipg;
struct clk *clk_per;
@@ -1219,7 +1220,8 @@ static int imx_startup(struct uart_port *port)
/*
* Finally, clear and enable interrupts
*/
- writel(USR1_RTSD | USR1_DTRD, sport->port.membase + USR1);
+ temp = USR1_RTSD | (sport->dsr ? USR1_DTRD : 0);
+ writel(temp, sport->port.membase + USR1);
writel(USR2_ORE, sport->port.membase + USR2);
if (sport->dma_is_inited && !sport->dma_is_enabled)
@@ -1259,7 +1261,7 @@ static int imx_startup(struct uart_port *port)
* now, too.
*/
temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP |
- UCR3_DTRDEN | UCR3_RI | UCR3_DCD;
+ (sport->dsr ? UCR3_DTRDEN : 0) | UCR3_RI | UCR3_DCD;
if (sport->dte_mode)
temp &= ~(UCR3_RI | UCR3_DCD);
@@ -1987,6 +1989,9 @@ static int serial_imx_probe_dt(struct imx_port *sport,
if (of_get_property(np, "fsl,dte-mode", NULL))
sport->dte_mode = 1;
+ if (!of_property_read_bool(np, "disable-dsr"))
+ sport->dsr = 1;
+
return 0;
}
#else
--
2.1.4
--
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 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