* Re: [PATCH/RFT v2 17/17] ARM: dts: da850: add usb device node
From: David Lechner @ 2016-10-25 0:48 UTC (permalink / raw)
To: ahaslam-rdvid1DuHRBWk0Htik3J/w,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
johan-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
nsekhar-l0cyMroinI0, stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
khilman-rdvid1DuHRBWk0Htik3J/w, sshtylyov-hkdhdckH98+B+jHODAdFcQ,
manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A,
broonie-DgEjT+Ai2ygdnm+yROfE0A, abailon-rdvid1DuHRBWk0Htik3J/w
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161024164634.4330-18-ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 10/24/2016 11:46 AM, ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org wrote:
> From: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>
> This adds the usb (ohci) device node for the da850 soc.
> Also it enables it for the lcdk board
>
> Signed-off-by: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> arch/arm/boot/dts/da850-lcdk.dts | 8 ++++++++
> arch/arm/boot/dts/da850.dtsi | 8 ++++++++
> 2 files changed, 16 insertions(+)
>
> diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
> index 7b8ab21..fa91339 100644
> --- a/arch/arm/boot/dts/da850-lcdk.dts
> +++ b/arch/arm/boot/dts/da850-lcdk.dts
> @@ -86,6 +86,14 @@
> };
> };
>
> +&usb_phy {
> + status = "okay";
> +};
> +
> +&usb {
> + status = "okay";
Don't you need to specify a regulator here using the vbus-supply property?
> +};
> +
> &serial2 {
> pinctrl-names = "default";
> pinctrl-0 = <&serial2_rxtx_pins>;
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index 33fcdce..ec2cec3 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -381,6 +381,14 @@
> #phy-cells = <1>;
> status = "disabled";
> };
> + usb: usb@0225000 {
Don't need the leading 0 on usb@225000
The alias (usb:) might need to be more specific since there is a second
usb device that will be added later for musb. (The comments in the
previous review only referred to the "usb" in "usb@", not the alias.)
> + compatible = "ti,da830-ohci";
> + reg = <0x225000 0x1000>;
> + interrupts = <59>;
> + phys = <&usb_phy 1>;
> + phy-names = "usb-phy";
> + status = "disabled";
> + };
> gpio: gpio@226000 {
> compatible = "ti,dm6441-gpio";
> gpio-controller;
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH/RFT v2 16/17] USB: ohci-da8xx: Allow probing from DT
From: David Lechner @ 2016-10-25 0:53 UTC (permalink / raw)
To: ahaslam-rdvid1DuHRBWk0Htik3J/w,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
johan-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
nsekhar-l0cyMroinI0, stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
khilman-rdvid1DuHRBWk0Htik3J/w, sshtylyov-hkdhdckH98+B+jHODAdFcQ,
broonie-DgEjT+Ai2ygdnm+yROfE0A, abailon-rdvid1DuHRBWk0Htik3J/w
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161024164634.4330-17-ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 10/24/2016 11:46 AM, ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org wrote:
> From: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>
> This adds the compatible string to the ohci driver
> to be able to probe from DT
>
> Signed-off-by: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> drivers/usb/host/ohci-da8xx.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
> index bebc3f0..1a8db25 100644
> --- a/drivers/usb/host/ohci-da8xx.c
> +++ b/drivers/usb/host/ohci-da8xx.c
> @@ -273,6 +273,13 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> }
>
> /*-------------------------------------------------------------------------*/
> +#ifdef CONFIG_OF
#ifdef CONFIG_OF is probably not needed here...
> +static const struct of_device_id da8xx_ohci_ids[] = {
> + { .compatible = "ti,da830-ohci" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, da8xx_ohci_ids);
> +#endif
>
> static int ohci_da8xx_probe(struct platform_device *pdev)
> {
> @@ -421,6 +428,7 @@ static int ohci_da8xx_resume(struct platform_device *dev)
> #endif
> .driver = {
> .name = "ohci",
> + .of_match_table = da8xx_ohci_ids,
...otherwise, da8xx_ohci_ids will not be defined here
> },
> };
>
>
--
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/RFT v2 15/17] usb: host: ohci-da8xx: Add devicetree bindings documentation
From: David Lechner @ 2016-10-25 1:02 UTC (permalink / raw)
To: ahaslam-rdvid1DuHRBWk0Htik3J/w,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
johan-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
nsekhar-l0cyMroinI0, stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
khilman-rdvid1DuHRBWk0Htik3J/w, sshtylyov-hkdhdckH98+B+jHODAdFcQ,
broonie-DgEjT+Ai2ygdnm+yROfE0A, abailon-rdvid1DuHRBWk0Htik3J/w
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161024164634.4330-16-ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 10/24/2016 11:46 AM, ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org wrote:
> From: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>
> This patch documents the device tree bindings required for
> the ohci controller found in TI da8xx family of SoC's
>
> Signed-off-by: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> .../devicetree/bindings/usb/ohci-da8xx.txt | 39 ++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/usb/ohci-da8xx.txt
>
> diff --git a/Documentation/devicetree/bindings/usb/ohci-da8xx.txt b/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
> new file mode 100644
> index 0000000..4251c84
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
> @@ -0,0 +1,39 @@
> +DA8XX USB OHCI controller
> +
> +Required properties:
> +
> + - compatible: Should be "ti,da830-ohci"
> + - reg: Should contain one register range i.e. start and length
> + - interrupts: Description of the interrupt line
> + - phys: Phandle for the PHY device
> + - phy-names: Should be "usb-phy"
> +
> +Optional properties:
> + - vbus-supply: Regulator that controls vbus power
Isn't vbus-supply property required?
If it is really supposed to be optional, the ohci driver needs to use
devm_regulator_get_optional() and handle the case when there is no
regulator.
I don't see a problem with making it required though since one can just
use a dummy supply if there is not a real one.
> +
> +Example for omap138-lck:
> +
> +vbus_fixed: fixed-regulator-vbus {
> + compatible = "regulator-fixed";
> + gpio = <&gpio 109 0>;
> + oc-gpio = <&gpio 36 0>;
> + regulator-boot-on;
> + enable-active-high;
> + regulator-name = "vbus";
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> +};
> +
> +usb_phy: usb-phy {
> + compatible = "ti,da830-usb-phy";
> + #phy-cells = <1>;
> + status = "disabled";
why disabled?
> +};
> +usb: usb@0225000 {
> + compatible = "ti,da830-ohci";
> + reg = <0x225000 0x1000>;
> + interrupts = <59>;
> + phys = <&usb_phy 1>;
> + phy-names = "usb-phy";
missing vbus-supply property
> + status = "disabled";
why disabled?
> +};
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH/RFT v2 13/17] USB: da8xx: use ohci priv data instead of globals
From: David Lechner @ 2016-10-25 1:12 UTC (permalink / raw)
To: ahaslam-rdvid1DuHRBWk0Htik3J/w,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
johan-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
nsekhar-l0cyMroinI0, stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
khilman-rdvid1DuHRBWk0Htik3J/w, sshtylyov-hkdhdckH98+B+jHODAdFcQ,
broonie-DgEjT+Ai2ygdnm+yROfE0A, abailon-rdvid1DuHRBWk0Htik3J/w
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161024164634.4330-14-ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 10/24/2016 11:46 AM, ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org wrote:
> From: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > static const struct ohci_driver_overrides da8xx_overrides __initconst = {
> - .reset = ohci_da8xx_reset
> + .reset = ohci_da8xx_reset,
> + .extra_priv_size = sizeof(struct da8xx_ohci_hcd),
nit: since you are changing both lines anyway, you might as well make
the ='s line up.
> };
>
> /*
>
--
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 v5 02/23] of: device: Export of_device_{get_modalias, uvent_modalias} to modules
From: Peter Chen @ 2016-10-25 1:16 UTC (permalink / raw)
To: Stephen Boyd, robh
Cc: Chen-Yu Tsai, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
linux-arm-msm, linux-usb, linux-kernel, Bjorn Andersson,
devicetree, Peter Chen, Andy Gross, linux-arm-kernel
In-Reply-To: <147733850401.29612.2343965740004706258@sboyd-linaro>
On Mon, Oct 24, 2016 at 12:48:24PM -0700, Stephen Boyd wrote:
> Quoting Chen-Yu Tsai (2016-10-24 05:19:05)
> > Hi,
> >
> > On Tue, Oct 18, 2016 at 9:56 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> > > The ULPI bus can be built as a module, and it will soon be
> > > calling these functions when it supports probing devices from DT.
> > > Export them so they can be used by the ULPI module.
> > >
> > > Acked-by: Rob Herring <robh@kernel.org>
> > > Cc: <devicetree@vger.kernel.org>
> > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > ---
> > > drivers/of/device.c | 2 ++
> > > 1 file changed, 2 insertions(+)
> > >
> > > diff --git a/drivers/of/device.c b/drivers/of/device.c
> > > index 8a22a253a830..6719ab35b62e 100644
> > > --- a/drivers/of/device.c
> > > +++ b/drivers/of/device.c
> > > @@ -225,6 +225,7 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
> > >
> > > return tsize;
> > > }
> > > +EXPORT_SYMBOL_GPL(of_device_get_modalias);
> > >
> > > int of_device_request_module(struct device *dev)
> > > {
> > > @@ -290,6 +291,7 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
> > > }
> > > mutex_unlock(&of_mutex);
> > > }
> > > +EXPORT_SYMBOL_GPL(of_device_uevent_modalias);
> >
> > This is trailing the wrong function.
> >
>
> Good catch. Must have been some bad rebase.
>
> Peter, can you fix it while applying or should I resend this patch?
>
But, this is device tree patch. I can only get chipidea part and other
USB patches if Greg agrees.
--
Best Regards,
Peter Chen
^ permalink raw reply
* Re: [PATCH v9 1/2] usb: dwc2: assert phy reset when waking up in rk3288 platform
From: John Youn @ 2016-10-25 1:30 UTC (permalink / raw)
To: ayaka, John Youn, linux-usb@vger.kernel.org, kishon@ti.com
Cc: felipe.balbi@linux.intel.com, mark.rutland@arm.com,
devicetree@vger.kernel.org, heiko@sntech.de,
gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
robh+dt@kernel.org, randy.li@rock-chips.com
In-Reply-To: <922d7f12-a520-7c07-bc4c-887321177c6d@soulik.info>
On 10/23/2016 2:33 AM, ayaka wrote:
>
>
> On 10/22/2016 03:27 AM, John Youn wrote:
>> On 10/20/2016 11:38 AM, Randy Li wrote:
>>> On the rk3288 USB host-only port (the one that's not the OTG-enabled
>>> port) the PHY can get into a bad state when a wakeup is asserted (not
>>> just a wakeup from full system suspend but also a wakeup from
>>> autosuspend).
>>>
>>> We can get the PHY out of its bad state by asserting its "port reset",
>>> but unfortunately that seems to assert a reset onto the USB bus so it
>>> could confuse things if we don't actually deenumerate / reenumerate the
>>> device.
>>>
>>> We can also get the PHY out of its bad state by fully resetting it using
>>> the reset from the CRU (clock reset unit) in chip, which does a more full
>>> reset. The CRU-based reset appears to actually cause devices on the bus
>>> to be removed and reinserted, which fixes the problem (albeit in a hacky
>>> way).
>>>
>>> It's unfortunate that we need to do a full re-enumeration of devices at
>>> wakeup time, but this is better than alternative of letting the bus get
>>> wedged.
>>>
>>> Signed-off-by: Randy Li <ayaka@soulik.info>
>>> ---
>>> drivers/usb/dwc2/core.h | 1 +
>>> drivers/usb/dwc2/core_intr.c | 11 +++++++++++
>>> drivers/usb/dwc2/platform.c | 9 +++++++++
>>> 3 files changed, 21 insertions(+)
>>>
>>> diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
>>> index 2a21a04..e91ddbc 100644
>>> --- a/drivers/usb/dwc2/core.h
>>> +++ b/drivers/usb/dwc2/core.h
>>> @@ -859,6 +859,7 @@ struct dwc2_hsotg {
>>> unsigned int ll_hw_enabled:1;
>>>
>>> struct phy *phy;
>>> + struct work_struct phy_rst_work;
>>> struct usb_phy *uphy;
>>> struct dwc2_hsotg_plat *plat;
>>> struct regulator_bulk_data supplies[ARRAY_SIZE(dwc2_hsotg_supply_names)];
>>> diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
>>> index d85c5c9..c3d2168 100644
>>> --- a/drivers/usb/dwc2/core_intr.c
>>> +++ b/drivers/usb/dwc2/core_intr.c
>>> @@ -345,6 +345,7 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
>>> static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
>>> {
>>> int ret;
>>> + struct device_node *np = hsotg->dev->of_node;
>>>
>>> /* Clear interrupt */
>>> dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
>>> @@ -379,6 +380,16 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
>>> /* Restart the Phy Clock */
>>> pcgcctl &= ~PCGCTL_STOPPCLK;
>>> dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
>>> +
>>> + /*
>>> + * It is a quirk in Rockchip RK3288, causing by
>>> + * a hardware bug. This will propagate out and
>>> + * eventually we'll re-enumerate the device.
>>> + * Not great but the best we can do
>>> + */
>>> + if (of_device_is_compatible(np, "rockchip,rk3288-usb"))
>>> + schedule_work(&hsotg->phy_rst_work);
>>> +
>>> mod_timer(&hsotg->wkp_timer,
>>> jiffies + msecs_to_jiffies(71));
>>> } else {
>>> diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
>>> index 8e1728b..65953cf 100644
>>> --- a/drivers/usb/dwc2/platform.c
>>> +++ b/drivers/usb/dwc2/platform.c
>>> @@ -366,6 +366,14 @@ int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
>>> return ret;
>>> }
>>>
>>> +/* Only used to reset usb phy at interrupter runtime */
>>> +static void dwc2_reset_phy_work(struct work_struct *data)
>>> +{
>>> + struct dwc2_hsotg *hsotg = container_of(data, struct dwc2_hsotg,
>>> + phy_rst_work);
>>> + phy_reset(hsotg->phy);
>>> +}
>>> +
>>> static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
>>> {
>>> int i, ret;
>>> @@ -410,6 +418,7 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
>>> return ret;
>>> }
>>> }
>>> + INIT_WORK(&hsotg->phy_rst_work, dwc2_reset_phy_work);
>>>
>>> if (!hsotg->phy) {
>>> hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
>>>
>> Hi Randy,
>>
>> This fails compile if CONFIG_GENERIC_PHY is disabled. I think you need
>> to make a fix to your phy_reset patch first.
> In the last time, cac18ecb6f44b11bc303d7afbae3887b27938fa4 have not been
> merged, I though the
> [PATCH v8 1/3] phy: Add reset callback for not generic phy have been
> merged before that. when the rebase abandon it.
> Should re-send that patch? As the mainline have not been affected, could
> you arrange a squash for it?
Hi Randy,
Can you resend the fix to Kishon?
The phy_reset patch landed in 4.9-rc so I think he should take the fix
for the next -rc. After that we can send the dwc2 change through
Felipe.
Regards,
John
^ permalink raw reply
* [PATCH V1] mfd: pv88080: Expand driver for GPIO function support.
From: Eric Jeong @ 2016-10-25 1:37 UTC (permalink / raw)
To: Alexandre Courbot, DEVICETREE, LINUX-GPIO, LINUX-KERNEL,
Lee Jones, Liam Girdwood, Linus Walleij, Mark Brown, Mark Rutland,
Rob Herring
Cc: Support Opensource
From: Eric Jeong <eric.jeong.opensource@diasemi.com>
This patch adds support for the PV88080 PMIC.
This pathch is done as part of the existing PV88080 regulator driver
by expanding the driver for GPIO function support.
The MFD core driver provides communication through the I2C interface.
and contains the following components:
- Regulators
- Configurable GPIOs
Kconfig and Makefile are updated to reflect support for PV88080 PMIC.
Signed-off-by: Eric Jeong <eric.jeong.opensource@diasemi.com>
---
This patch applies against linux-next and next-20161024
Hi,
This change is made as a single patch. Because, to ensure that
kernel builds and runs properly after this patch.
The regulator device driver for PV88080 IC is submitted to Linux kernel.
And now, GPIO function is required. In order to add GPIO driver,
MFD driver is also required.
Changes
- Add MFD driver.
- Add GPIO driver.
- Update regulator driver to reflect the support.
- Delete pv88080-regulator.h file.
- Move binding document to mfd directory.
Regards,
Eric Jeong, Dialog Semiconductor Ltd.
Documentation/devicetree/bindings/mfd/pv88080.txt | 63 +++++
.../devicetree/bindings/regulator/pv88080.txt | 62 -----
drivers/gpio/Kconfig | 11 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-pv88080.c | 195 ++++++++++++++
drivers/mfd/Kconfig | 12 +
drivers/mfd/Makefile | 2 +
drivers/mfd/pv88080-core.c | 270 ++++++++++++++++++++
drivers/mfd/pv88080-i2c.c | 99 +++++++
drivers/regulator/Kconfig | 5 +-
drivers/regulator/pv88080-regulator.c | 202 ++++++---------
drivers/regulator/pv88080-regulator.h | 118 ---------
include/linux/mfd/pv88080.h | 236 +++++++++++++++++
13 files changed, 970 insertions(+), 306 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/pv88080.txt
delete mode 100644 Documentation/devicetree/bindings/regulator/pv88080.txt
create mode 100644 drivers/gpio/gpio-pv88080.c
create mode 100644 drivers/mfd/pv88080-core.c
create mode 100644 drivers/mfd/pv88080-i2c.c
delete mode 100644 drivers/regulator/pv88080-regulator.h
create mode 100644 include/linux/mfd/pv88080.h
diff --git a/Documentation/devicetree/bindings/mfd/pv88080.txt b/Documentation/devicetree/bindings/mfd/pv88080.txt
new file mode 100644
index 0000000..7b556b1
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/pv88080.txt
@@ -0,0 +1,63 @@
+* Powerventure Semiconductor PV88080 PMIC
+
+Required properties:
+- compatible: Must be one of the following, depending on the
+ silicon version:
+ - "pvs,pv88080" (DEPRECATED)
+
+ - "pvs,pv88080-aa" for PV88080 AA or AB silicon
+ - "pvs,pv88080-ba" for PV88080 BA or BB silicon
+ NOTE: The use of the compatibles with no silicon version is deprecated.
+- reg: I2C slave address, usually 0x49
+- interrupts: the interrupt outputs of the controller
+- regulators: A node that houses a sub-node for each regulator within the
+ device. Each sub-node is identified using the node's name, with valid
+ values listed below. The content of each sub-node is defined by the
+ standard binding for regulators; see regulator.txt.
+ BUCK1, BUCK2, BUCK3 and HVBUCK.
+
+Optional properties:
+- Any optional property defined in regulator.txt
+ and gpio.txt for more information.
+
+Example:
+
+ pmic: pv88080@49 {
+ compatible = "pvs,pv88080-ba";
+ reg = <0x49>;
+ interrupt-parent = <&gpio>;
+ interrupts = <24 24>;
+
+ regulators {
+ BUCK1 {
+ regulator-name = "buck1";
+ regulator-min-microvolt = < 600000>;
+ regulator-max-microvolt = <1393750>;
+ regulator-min-microamp = < 220000>;
+ regulator-max-microamp = <7040000>;
+ };
+
+ BUCK2 {
+ regulator-name = "buck2";
+ regulator-min-microvolt = < 600000>;
+ regulator-max-microvolt = <1393750>;
+ regulator-min-microamp = <1496000>;
+ regulator-max-microamp = <4189000>;
+ };
+
+ BUCK3 {
+ regulator-name = "buck3";
+ regulator-min-microvolt = <1400000>;
+ regulator-max-microvolt = <2193750>;
+ regulator-min-microamp = <1496000>;
+ regulator-max-microamp = <4189000>;
+ };
+
+ HVBUCK {
+ regulator-name = "hvbuck";
+ regulator-min-microvolt = < 5000>;
+ regulator-max-microvolt = <1275000>;
+ };
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/regulator/pv88080.txt b/Documentation/devicetree/bindings/regulator/pv88080.txt
deleted file mode 100644
index e6e4b9c8..0000000
--- a/Documentation/devicetree/bindings/regulator/pv88080.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-* Powerventure Semiconductor PV88080 Voltage Regulator
-
-Required properties:
-- compatible: Must be one of the following, depending on the
- silicon version:
- - "pvs,pv88080" (DEPRECATED)
-
- - "pvs,pv88080-aa" for PV88080 AA or AB silicon
- - "pvs,pv88080-ba" for PV88080 BA or BB silicon
- NOTE: The use of the compatibles with no silicon version is deprecated.
-- reg: I2C slave address, usually 0x49
-- interrupts: the interrupt outputs of the controller
-- regulators: A node that houses a sub-node for each regulator within the
- device. Each sub-node is identified using the node's name, with valid
- values listed below. The content of each sub-node is defined by the
- standard binding for regulators; see regulator.txt.
- BUCK1, BUCK2, BUCK3 and HVBUCK.
-
-Optional properties:
-- Any optional property defined in regulator.txt
-
-Example:
-
- pmic: pv88080@49 {
- compatible = "pvs,pv88080-ba";
- reg = <0x49>;
- interrupt-parent = <&gpio>;
- interrupts = <24 24>;
-
- regulators {
- BUCK1 {
- regulator-name = "buck1";
- regulator-min-microvolt = < 600000>;
- regulator-max-microvolt = <1393750>;
- regulator-min-microamp = < 220000>;
- regulator-max-microamp = <7040000>;
- };
-
- BUCK2 {
- regulator-name = "buck2";
- regulator-min-microvolt = < 600000>;
- regulator-max-microvolt = <1393750>;
- regulator-min-microamp = <1496000>;
- regulator-max-microamp = <4189000>;
- };
-
- BUCK3 {
- regulator-name = "buck3";
- regulator-min-microvolt = <1400000>;
- regulator-max-microvolt = <2193750>;
- regulator-min-microamp = <1496000>;
- regulator-max-microamp = <4189000>;
- };
-
- HVBUCK {
- regulator-name = "hvbuck";
- regulator-min-microvolt = < 5000>;
- regulator-max-microvolt = <1275000>;
- };
- };
- };
-
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 9f0f4b6..0381ffd 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -952,6 +952,17 @@ config GPIO_PALMAS
Select this option to enable GPIO driver for the TI PALMAS
series chip family.
+config GPIO_PV88080
+ bool "Powerventure Semiconductor PV88080 GPIO"
+ depends on MFD_PV88080
+ help
+ Support for GPIO pins on PV88080 PMIC.
+
+ Say yes here to enable the GPIO driver for the PV88080 chip.
+
+ The Powerventure PMIC chip has 2 GPIO pins that can be
+ controlled by this driver.
+
config GPIO_RC5T583
bool "RICOH RC5T583 GPIO"
depends on MFD_RC5T583
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 145847a4d..503aed5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
+obj-$(CONFIG_GPIO_PV88080) += gpio-pv88080.o
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
diff --git a/drivers/gpio/gpio-pv88080.c b/drivers/gpio/gpio-pv88080.c
new file mode 100644
index 0000000..0e2eb49
--- /dev/null
+++ b/drivers/gpio/gpio-pv88080.c
@@ -0,0 +1,195 @@
+/*
+ * gpio-pv88080.c - GPIO device driver for PV88080
+ * Copyright (C) 2016 Powerventure Semiconductor Ltd.
+ *
+ * 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/gpio.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/pv88080.h>
+
+#define DEFAULT_PIN_NUMBER 2
+
+#define PV88080_PORT_DIRECTION_INPUT 0
+#define PV88080_PORT_DIRECTION_OUTPUT 1
+
+struct pv88080_gpio {
+ struct pv88080 *chip;
+ struct gpio_chip gpio_chip;
+ unsigned int input_reg;
+ unsigned int gpio_base_reg;
+};
+
+static int pv88080_gpio_get_direction(struct gpio_chip *gc,
+ unsigned int offset)
+{
+ struct pv88080_gpio *priv = gpiochip_get_data(gc);
+ struct pv88080 *chip = priv->chip;
+ unsigned int reg;
+ int ret;
+
+ ret = regmap_read(chip->regmap, priv->gpio_base_reg + offset, ®);
+ if (ret)
+ return ret;
+
+ reg = reg & PV88080_GPIO_DIRECTION_MASK;
+
+ return !reg;
+}
+
+static int pv88080_gpio_direction_input(struct gpio_chip *gc,
+ unsigned int offset)
+{
+ struct pv88080_gpio *priv = gpiochip_get_data(gc);
+ struct pv88080 *chip = priv->chip;
+ int ret;
+
+ /* Set the initial value */
+ ret = regmap_update_bits(chip->regmap, priv->gpio_base_reg + offset,
+ PV88080_GPIO_OUTPUT_MASK, 0);
+ if (ret)
+ return ret;
+
+ return regmap_update_bits(chip->regmap, priv->gpio_base_reg + offset,
+ PV88080_GPIO_DIRECTION_MASK, 0);
+}
+
+static int pv88080_gpio_direction_output(struct gpio_chip *gc,
+ unsigned int offset, int value)
+{
+ struct pv88080_gpio *priv = gpiochip_get_data(gc);
+ struct pv88080 *chip = priv->chip;
+ int ret;
+
+ ret = regmap_update_bits(chip->regmap, priv->gpio_base_reg + offset,
+ PV88080_GPIO_DIRECTION_MASK,
+ PV88080_GPIO_DIRECTION_MASK);
+
+ return ret;
+}
+
+static int pv88080_gpio_get(struct gpio_chip *gc, unsigned int offset)
+{
+ struct pv88080_gpio *priv = gpiochip_get_data(gc);
+ struct pv88080 *chip = priv->chip;
+ unsigned int reg = 0, direction;
+ int ret;
+
+ ret = regmap_read(chip->regmap, priv->gpio_base_reg + offset, ®);
+ if (ret)
+ return ret;
+
+ direction = (reg & PV88080_GPIO_DIRECTION_MASK);
+ if (direction == PV88080_PORT_DIRECTION_OUTPUT) {
+ if (reg & PV88080_GPIO_OUTPUT_EN)
+ return 1;
+ ret = 0;
+ } else {
+ ret = regmap_read(chip->regmap, priv->input_reg, ®);
+ if (ret < 0)
+ return ret;
+ ret = (reg & (PV88080_GPIO_INPUT_MASK << offset)) >> offset;
+ }
+
+ return ret;
+}
+
+static void pv88080_gpio_set(struct gpio_chip *gc, unsigned int offset,
+ int value)
+{
+ struct pv88080_gpio *priv = gpiochip_get_data(gc);
+ struct pv88080 *chip = priv->chip;
+
+ if (value)
+ regmap_update_bits(chip->regmap, priv->gpio_base_reg + offset,
+ PV88080_GPIO_OUTPUT_MASK,
+ PV88080_GPIO_OUTPUT_EN);
+ else
+ regmap_update_bits(chip->regmap, priv->gpio_base_reg + offset,
+ PV88080_GPIO_OUTPUT_MASK,
+ PV88080_GPIO_OUTPUT_DIS);
+}
+
+static const struct gpio_chip template_gpio = {
+ .label = "pv88080-gpio",
+ .owner = THIS_MODULE,
+ .get_direction = pv88080_gpio_get_direction,
+ .direction_input = pv88080_gpio_direction_input,
+ .direction_output = pv88080_gpio_direction_output,
+ .get = pv88080_gpio_get,
+ .set = pv88080_gpio_set,
+ .base = -1,
+ .ngpio = DEFAULT_PIN_NUMBER,
+};
+
+static int pv88080_gpio_probe(struct platform_device *pdev)
+{
+ struct pv88080 *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pv88080_pdata *pdata = dev_get_platdata(chip->dev);
+ struct pv88080_gpio *priv;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev,
+ sizeof(struct pv88080_gpio), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->chip = chip;
+ priv->gpio_chip = template_gpio;
+ priv->gpio_chip.parent = chip->dev;
+ if (pdata && pdata->gpio_base)
+ priv->gpio_chip.base = pdata->gpio_base;
+
+ switch (chip->type) {
+ case TYPE_PV88080_AA:
+ priv->input_reg = PV88080AA_REG_GPIO_INPUT;
+ priv->gpio_base_reg = PV88080AA_REG_GPIO_GPIO0;
+ break;
+ case TYPE_PV88080_BA:
+ priv->input_reg = PV88080BA_REG_GPIO_INPUT;
+ priv->gpio_base_reg = PV88080BA_REG_GPIO_GPIO0;
+ break;
+ }
+
+ ret = devm_gpiochip_add_data(&pdev->dev, &priv->gpio_chip, priv);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Unable to register gpiochip\n");
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, priv);
+
+ return 0;
+}
+
+static const struct platform_device_id pv88080_gpio_id_table[] = {
+ { "pv88080-gpio", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, pv88080_gpio_id_table);
+
+static struct platform_driver pv88080_gpio_driver = {
+ .driver = {
+ .name = "pv88080-gpio",
+ },
+ .probe = pv88080_gpio_probe,
+ .id_table = pv88080_gpio_id_table,
+};
+module_platform_driver(pv88080_gpio_driver);
+
+MODULE_AUTHOR("Eric Jeong <eric.jeong.opensource@diasemi.com>");
+MODULE_DESCRIPTION("GPIO device driver for Powerventure PV88080");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c6df644..d69edf4 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -775,6 +775,18 @@ config MFD_PM8921_CORE
Say M here if you want to include support for PM8921 chip as a module.
This will build a module called "pm8921-core".
+config MFD_PV88080
+ bool "Powerventure Semiconductor PV88080 PMIC Support"
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ depends on I2C
+ help
+ Say yes here for support for the Powerventure Semiconductor PV88080 PMIC.
+ This includes the I2C driver and core APIs.
+ Additional drivers must be enabled in order to use the functionality
+ of the device.
+
config MFD_QCOM_RPM
tristate "Qualcomm Resource Power Manager (RPM)"
depends on ARCH_QCOM && OF
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 9834e66..6248e0b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -173,6 +173,8 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o
obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o
+pv88080-objs := pv88080-core.o pv88080-i2c.o
+obj-$(CONFIG_MFD_PV88080) += pv88080.o
obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o
obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
diff --git a/drivers/mfd/pv88080-core.c b/drivers/mfd/pv88080-core.c
new file mode 100644
index 0000000..b858f06
--- /dev/null
+++ b/drivers/mfd/pv88080-core.c
@@ -0,0 +1,270 @@
+/*
+ * pv88080-core.c - Device access for PV88080
+ *
+ * Copyright (C) 2016 Powerventure Semiconductor Ltd.
+ *
+ * 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/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+
+#include <linux/mfd/pv88080.h>
+
+#define PV88080_REG_EVENT_A_OFFSET 0
+#define PV88080_REG_EVENT_B_OFFSET 1
+#define PV88080_REG_EVENT_C_OFFSET 2
+
+static const struct resource regulators_aa_resources[] = {
+ {
+ .name = "regulator-irq",
+ .start = PV88080_AA_IRQ_VDD_FLT,
+ .end = PV88080_AA_IRQ_OVER_TEMP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct resource regulators_ba_resources[] = {
+ {
+ .name = "regulator-irq",
+ .start = PV88080_BA_IRQ_VDD_FLT,
+ .end = PV88080_BA_IRQ_OVER_TEMP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell pv88080_cells[] = {
+ {
+ .name = "pv88080-regulator",
+ },
+ {
+ .name = "pv88080-gpio",
+ },
+};
+
+static const struct regmap_irq pv88080_aa_irqs[] = {
+ /* PV88080 event A register for AA/AB silicon */
+ [PV88080_AA_IRQ_VDD_FLT] = {
+ .reg_offset = PV88080_REG_EVENT_A_OFFSET,
+ .mask = PV88080_M_VDD_FLT,
+ },
+ [PV88080_AA_IRQ_OVER_TEMP] = {
+ .reg_offset = PV88080_REG_EVENT_A_OFFSET,
+ .mask = PV88080_M_OVER_TEMP,
+ },
+ [PV88080_AA_IRQ_SEQ_RDY] = {
+ .reg_offset = PV88080_REG_EVENT_A_OFFSET,
+ .mask = PV88080_M_SEQ_RDY,
+ },
+ /* PV88080 event B register for AA/AB silicon */
+ [PV88080_AA_IRQ_HVBUCK_OV] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_HVBUCK_OV,
+ },
+ [PV88080_AA_IRQ_HVBUCK_UV] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_HVBUCK_UV,
+ },
+ [PV88080_AA_IRQ_HVBUCK_SCP] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_HVBUCK_SCP,
+ },
+ [PV88080_AA_IRQ_BUCK1_SCP] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_BUCK1_SCP,
+ },
+ [PV88080_AA_IRQ_BUCK2_SCP] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_BUCK2_SCP,
+ },
+ [PV88080_AA_IRQ_BUCK3_SCP] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_BUCK3_SCP,
+ },
+ /* PV88080 event C register for AA/AB silicon */
+ [PV88080_AA_IRQ_GPIO_FLAG0] = {
+ .reg_offset = PV88080_REG_EVENT_C_OFFSET,
+ .mask = PV88080_M_GPIO_FLAG0,
+ },
+ [PV88080_AA_IRQ_GPIO_FLAG1] = {
+ .reg_offset = PV88080_REG_EVENT_C_OFFSET,
+ .mask = PV88080_M_GPIO_FLAG1,
+ },
+};
+
+static const struct regmap_irq pv88080_ba_irqs[] = {
+ /* PV88080 event A register for BA/BB silicon */
+ [PV88080_BA_IRQ_VDD_FLT] = {
+ .reg_offset = PV88080_REG_EVENT_A_OFFSET,
+ .mask = PV88080_M_VDD_FLT,
+ },
+ [PV88080_BA_IRQ_OVER_TEMP] = {
+ .reg_offset = PV88080_REG_EVENT_A_OFFSET,
+ .mask = PV88080_M_OVER_TEMP,
+ },
+ [PV88080_BA_IRQ_SEQ_RDY] = {
+ .reg_offset = PV88080_REG_EVENT_A_OFFSET,
+ .mask = PV88080_M_SEQ_RDY,
+ },
+ [PV88080_BA_IRQ_EXT_OT] = {
+ .reg_offset = PV88080_REG_EVENT_A_OFFSET,
+ .mask = PV88080_M_EXT_OT,
+ },
+ /* PV88080 event B register for BA/BB silicon */
+ [PV88080_BA_IRQ_HVBUCK_OV] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_HVBUCK_OV,
+ },
+ [PV88080_BA_IRQ_HVBUCK_UV] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_HVBUCK_UV,
+ },
+ [PV88080_BA_IRQ_HVBUCK_SCP] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_HVBUCK_SCP,
+ },
+ [PV88080_BA_IRQ_BUCK1_SCP] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_BUCK1_SCP,
+ },
+ [PV88080_BA_IRQ_BUCK2_SCP] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_BUCK2_SCP,
+ },
+ [PV88080_BA_IRQ_BUCK3_SCP] = {
+ .reg_offset = PV88080_REG_EVENT_B_OFFSET,
+ .mask = PV88080_M_BUCK3_SCP,
+ },
+ /* PV88080 event C register for BA/BB silicon */
+ [PV88080_BA_IRQ_GPIO_FLAG0] = {
+ .reg_offset = PV88080_REG_EVENT_C_OFFSET,
+ .mask = PV88080_M_GPIO_FLAG0,
+ },
+ [PV88080_BA_IRQ_GPIO_FLAG1] = {
+ .reg_offset = PV88080_REG_EVENT_C_OFFSET,
+ .mask = PV88080_M_GPIO_FLAG1,
+ },
+ [PV88080_BA_IRQ_BUCK1_DROP_TIMEOUT] = {
+ .reg_offset = PV88080_REG_EVENT_C_OFFSET,
+ .mask = PV88080_M_BUCK1_DROP_TIMEOUT,
+ },
+ [PV88080_BA_IRQ_BUCK2_DROP_TIMEOUT] = {
+ .reg_offset = PV88080_REG_EVENT_C_OFFSET,
+ .mask = PV88080_M_BUCK2_DROP_TIMEOUT,
+ },
+ [PB88080_BA_IRQ_BUCK3_DROP_TIMEOUT] = {
+ .reg_offset = PV88080_REG_EVENT_C_OFFSET,
+ .mask = PV88080_M_BUCk3_DROP_TIMEOUT,
+ },
+};
+
+static struct regmap_irq_chip pv88080_irq_chip = {
+ .name = "pv88080-irq",
+ .num_regs = 3,
+ .status_base = PV88080_REG_EVENT_A,
+ .mask_base = PV88080_REG_MASK_A,
+ .ack_base = PV88080_REG_EVENT_A,
+ .init_ack_masked = true,
+};
+
+int pv88080_device_init(struct pv88080 *chip, unsigned int irq)
+{
+ struct pv88080_pdata *pdata = dev_get_platdata(chip->dev);
+ int ret;
+
+ if (pdata)
+ chip->irq_base = pdata->irq_base;
+ else
+ chip->irq_base = 0;
+ chip->irq = irq;
+
+ if (pdata && pdata->init != NULL) {
+ ret = pdata->init(chip);
+ if (ret != 0) {
+ dev_err(chip->dev, "Platform initialization failed\n");
+ return ret;
+ }
+ }
+
+ ret = regmap_write(chip->regmap, PV88080_REG_MASK_A, 0xFF);
+ if (ret < 0) {
+ dev_err(chip->dev,
+ "Failed to mask A reg: %d\n", ret);
+ return ret;
+ }
+ ret = regmap_write(chip->regmap, PV88080_REG_MASK_B, 0xFF);
+ if (ret < 0) {
+ dev_err(chip->dev,
+ "Failed to mask B reg: %d\n", ret);
+ return ret;
+ }
+ ret = regmap_write(chip->regmap, PV88080_REG_MASK_C, 0xFF);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to mask C reg: %d\n", ret);
+ return ret;
+ }
+
+ switch (chip->type) {
+ case TYPE_PV88080_AA:
+ pv88080_irq_chip.irqs = pv88080_aa_irqs;
+ pv88080_irq_chip.num_irqs = ARRAY_SIZE(pv88080_aa_irqs);
+
+ pv88080_cells[0].num_resources
+ = ARRAY_SIZE(regulators_aa_resources);
+ pv88080_cells[0].resources = regulators_aa_resources;
+ break;
+ case TYPE_PV88080_BA:
+ pv88080_irq_chip.irqs = pv88080_ba_irqs;
+ pv88080_irq_chip.num_irqs = ARRAY_SIZE(pv88080_ba_irqs);
+
+ pv88080_cells[0].num_resources
+ = ARRAY_SIZE(regulators_ba_resources);
+ pv88080_cells[0].resources = regulators_ba_resources;
+ break;
+ }
+
+ ret = regmap_add_irq_chip(chip->regmap, chip->irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ chip->irq_base, &pv88080_irq_chip,
+ &chip->irq_data);
+ if (ret) {
+ dev_err(chip->dev, "Failed to reguest IRQ %d: %d\n",
+ chip->irq, ret);
+ return ret;
+ }
+
+ ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE,
+ pv88080_cells, ARRAY_SIZE(pv88080_cells),
+ NULL, chip->irq_base, NULL);
+ if (ret) {
+ dev_err(chip->dev, "Cannot add MFD cells\n");
+ regmap_del_irq_chip(chip->irq, chip->irq_data);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pv88080_device_init);
+
+int pv88080_device_exit(struct pv88080 *chip)
+{
+ mfd_remove_devices(chip->dev);
+ regmap_del_irq_chip(chip->irq, chip->irq_data);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pv88080_device_exit);
+
+MODULE_AUTHOR("Eric Jeong <eric.jeong.opensource@diasemi.com>");
+MODULE_DESCRIPTION("MFD driver for Powerventure PV88080");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mfd/pv88080-i2c.c b/drivers/mfd/pv88080-i2c.c
new file mode 100644
index 0000000..a90cd40
--- /dev/null
+++ b/drivers/mfd/pv88080-i2c.c
@@ -0,0 +1,99 @@
+/*
+ * pv88080-i2c.c - I2C access driver for PV88080
+ *
+ * Copyright (C) 2016 Powerventure Semiconductor Ltd.
+ *
+ * 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/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/pv88080.h>
+
+static const struct regmap_config pv88080_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static const struct of_device_id pv88080_of_match_table[] = {
+ { .compatible = "pvs,pv88080", .data = (void *)TYPE_PV88080_AA },
+ { .compatible = "pvs,pv88080-aa", .data = (void *)TYPE_PV88080_AA },
+ { .compatible = "pvs,pv88080-ba", .data = (void *)TYPE_PV88080_BA },
+ { },
+};
+MODULE_DEVICE_TABLE(of, pv88080_of_match_table);
+
+static int pv88080_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *ids)
+{
+ struct pv88080 *chip;
+ const struct of_device_id *match;
+
+ chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ if (client->dev.of_node) {
+ match = of_match_node(pv88080_of_match_table,
+ client->dev.of_node);
+ if (!match) {
+ dev_err(&client->dev, "Failed to get of_match_node\n");
+ return -EINVAL;
+ }
+ chip->type = (unsigned long)match->data;
+ } else {
+ chip->type = ids->driver_data;
+ }
+
+ i2c_set_clientdata(client, chip);
+
+ chip->dev = &client->dev;
+ chip->regmap = devm_regmap_init_i2c(client, &pv88080_regmap_config);
+ if (IS_ERR(chip->regmap)) {
+ dev_err(chip->dev, "Failed to initialize register map\n");
+ return PTR_ERR(chip->regmap);
+ }
+
+ return pv88080_device_init(chip, client->irq);
+}
+
+static int pv88080_i2c_remove(struct i2c_client *client)
+{
+ struct pv88080 *chip = i2c_get_clientdata(client);
+
+ return pv88080_device_exit(chip);
+}
+
+static const struct i2c_device_id pv88080_i2c_id[] = {
+ { "pv88080", TYPE_PV88080_AA },
+ { "pv88080-aa", TYPE_PV88080_AA },
+ { "pv88080-ba", TYPE_PV88080_BA },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id);
+
+static struct i2c_driver pv88080_i2c_driver = {
+ .driver = {
+ .name = "pv88080",
+ .of_match_table = of_match_ptr(pv88080_of_match_table),
+ },
+ .probe = pv88080_i2c_probe,
+ .remove = pv88080_i2c_remove,
+ .id_table = pv88080_i2c_id,
+};
+module_i2c_driver(pv88080_i2c_driver);
+
+MODULE_AUTHOR("Eric Jeong <eric.jeong.opensource@diasemi.com>");
+MODULE_DESCRIPTION("I2C driver for Powerventure PV88080");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 936f7cc..217d568 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -576,9 +576,8 @@ config REGULATOR_PV88060
PV88060
config REGULATOR_PV88080
- tristate "Powerventure Semiconductor PV88080 regulator"
- depends on I2C
- select REGMAP_I2C
+ bool "Powerventure Semiconductor PV88080 regulator"
+ depends on MFD_PV88080
help
Say y here to support the buck convertors on PV88080
diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c
index 954a20e..6dfccee 100644
--- a/drivers/regulator/pv88080-regulator.c
+++ b/drivers/regulator/pv88080-regulator.c
@@ -14,8 +14,8 @@
*/
#include <linux/err.h>
-#include <linux/i2c.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -25,9 +25,8 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/regulator/of_regulator.h>
-#include "pv88080-regulator.h"
-#define PV88080_MAX_REGULATORS 4
+#include <linux/mfd/pv88080.h>
/* PV88080 REGULATOR IDs */
enum {
@@ -38,11 +37,6 @@ enum {
PV88080_ID_HVBUCK,
};
-enum pv88080_types {
- TYPE_PV88080_AA,
- TYPE_PV88080_BA,
-};
-
struct pv88080_regulator {
struct regulator_desc desc;
/* Current limiting */
@@ -55,14 +49,6 @@ struct pv88080_regulator {
unsigned int conf5;
};
-struct pv88080 {
- struct device *dev;
- struct regmap *regmap;
- struct regulator_dev *rdev[PV88080_MAX_REGULATORS];
- unsigned long type;
- const struct pv88080_compatible_regmap *regmap_config;
-};
-
struct pv88080_buck_voltage {
int min_uV;
int max_uV;
@@ -93,11 +79,14 @@ struct pv88080_compatible_regmap {
int hvbuck_vsel_mask;
};
-static const struct regmap_config pv88080_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
+struct pv88080_regulators {
+ int virq;
+ struct pv88080 *pv88080;
+ struct regulator_dev *rdev[PV88080_MAX_REGULATORS];
+ const struct pv88080_compatible_regmap *regmap_config;
};
+
/* Current limits array (in uA) for BUCK1, BUCK2, BUCK3.
* Entry indexes corresponds to register values.
*/
@@ -211,16 +200,6 @@ struct pv88080_compatible_regmap {
.hvbuck_vsel_mask = PV88080_VHVBUCK_MASK,
};
-#ifdef CONFIG_OF
-static const struct of_device_id pv88080_dt_ids[] = {
- { .compatible = "pvs,pv88080", .data = (void *)TYPE_PV88080_AA },
- { .compatible = "pvs,pv88080-aa", .data = (void *)TYPE_PV88080_AA },
- { .compatible = "pvs,pv88080-ba", .data = (void *)TYPE_PV88080_BA },
- {},
-};
-MODULE_DEVICE_TABLE(of, pv88080_dt_ids);
-#endif
-
static unsigned int pv88080_buck_get_mode(struct regulator_dev *rdev)
{
struct pv88080_regulator *info = rdev_get_drvdata(rdev);
@@ -374,7 +353,8 @@ static int pv88080_get_current_limit(struct regulator_dev *rdev)
static irqreturn_t pv88080_irq_handler(int irq, void *data)
{
- struct pv88080 *chip = data;
+ struct pv88080_regulators *regulators = data;
+ struct pv88080 *chip = regulators->pv88080;
int i, reg_val, err, ret = IRQ_NONE;
err = regmap_read(chip->regmap, PV88080_REG_EVENT_A, ®_val);
@@ -383,8 +363,9 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data)
if (reg_val & PV88080_E_VDD_FLT) {
for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
- if (chip->rdev[i] != NULL) {
- regulator_notifier_call_chain(chip->rdev[i],
+ if (regulators->rdev[i] != NULL) {
+ regulator_notifier_call_chain(
+ regulators->rdev[i],
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
}
@@ -400,8 +381,9 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data)
if (reg_val & PV88080_E_OVER_TEMP) {
for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
- if (chip->rdev[i] != NULL) {
- regulator_notifier_call_chain(chip->rdev[i],
+ if (regulators->rdev[i] != NULL) {
+ regulator_notifier_call_chain(
+ regulators->rdev[i],
REGULATOR_EVENT_OVER_TEMP,
NULL);
}
@@ -425,101 +407,67 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data)
/*
* I2C driver interface functions
*/
-static int pv88080_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int pv88080_regulator_probe(struct platform_device *pdev)
{
- struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
- struct pv88080 *chip;
+ struct pv88080 *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pv88080_pdata *pdata = dev_get_platdata(chip->dev);
+ struct pv88080_regulators *regulators;
const struct pv88080_compatible_regmap *regmap_config;
- const struct of_device_id *match;
struct regulator_config config = { };
- int i, error, ret;
+ int i, ret, irq;
unsigned int conf2, conf5;
- chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88080), GFP_KERNEL);
- if (!chip)
+ regulators = devm_kzalloc(&pdev->dev,
+ sizeof(struct pv88080_regulators), GFP_KERNEL);
+ if (!regulators)
return -ENOMEM;
- chip->dev = &i2c->dev;
- chip->regmap = devm_regmap_init_i2c(i2c, &pv88080_regmap_config);
- if (IS_ERR(chip->regmap)) {
- error = PTR_ERR(chip->regmap);
- dev_err(chip->dev, "Failed to allocate register map: %d\n",
- error);
- return error;
- }
+ platform_set_drvdata(pdev, regulators);
- if (i2c->dev.of_node) {
- match = of_match_node(pv88080_dt_ids, i2c->dev.of_node);
- if (!match) {
- dev_err(chip->dev, "Failed to get of_match_node\n");
- return -EINVAL;
- }
- chip->type = (unsigned long)match->data;
- } else {
- chip->type = id->driver_data;
+ irq = platform_get_irq_byname(pdev, "regulator-irq");
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Failed to get IRQ.\n");
+ return irq;
}
- i2c_set_clientdata(i2c, chip);
-
- if (i2c->irq != 0) {
- ret = regmap_write(chip->regmap, PV88080_REG_MASK_A, 0xFF);
- if (ret < 0) {
- dev_err(chip->dev,
- "Failed to mask A reg: %d\n", ret);
- return ret;
- }
- ret = regmap_write(chip->regmap, PV88080_REG_MASK_B, 0xFF);
- if (ret < 0) {
- dev_err(chip->dev,
- "Failed to mask B reg: %d\n", ret);
- return ret;
- }
- ret = regmap_write(chip->regmap, PV88080_REG_MASK_C, 0xFF);
- if (ret < 0) {
- dev_err(chip->dev,
- "Failed to mask C reg: %d\n", ret);
- return ret;
- }
-
- ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
- pv88080_irq_handler,
- IRQF_TRIGGER_LOW|IRQF_ONESHOT,
- "pv88080", chip);
- if (ret != 0) {
- dev_err(chip->dev, "Failed to request IRQ: %d\n",
- i2c->irq);
+ regulators->virq = regmap_irq_get_virq(chip->irq_data, irq);
+ if (regulators->virq >= 0) {
+ ret = devm_request_threaded_irq(&pdev->dev,
+ regulators->virq, NULL,
+ pv88080_irq_handler,
+ IRQF_TRIGGER_LOW|IRQF_ONESHOT,
+ "regulator-irq", regulators);
+ if (ret) {
+ dev_err(chip->dev, "Failed to request IRQ: %d\n", irq);
return ret;
}
+ }
- ret = regmap_update_bits(chip->regmap, PV88080_REG_MASK_A,
- PV88080_M_VDD_FLT | PV88080_M_OVER_TEMP, 0);
- if (ret < 0) {
- dev_err(chip->dev,
- "Failed to update mask reg: %d\n", ret);
- return ret;
- }
- } else {
- dev_warn(chip->dev, "No IRQ configured\n");
+ ret = regmap_update_bits(chip->regmap, PV88080_REG_MASK_A,
+ PV88080_M_VDD_FLT | PV88080_M_OVER_TEMP, 0);
+ if (ret < 0) {
+ dev_err(chip->dev,
+ "Failed to update mask reg: %d\n", ret);
+ return ret;
}
switch (chip->type) {
case TYPE_PV88080_AA:
- chip->regmap_config = &pv88080_aa_regs;
+ regulators->regmap_config = &pv88080_aa_regs;
break;
case TYPE_PV88080_BA:
- chip->regmap_config = &pv88080_ba_regs;
+ regulators->regmap_config = &pv88080_ba_regs;
break;
}
- regmap_config = chip->regmap_config;
+ regmap_config = regulators->regmap_config;
config.dev = chip->dev;
config.regmap = chip->regmap;
/* Registeration for BUCK1, 2, 3 */
for (i = 0; i < PV88080_MAX_REGULATORS-1; i++) {
- if (init_data)
- config.init_data = &init_data[i];
+ if (pdata && pdata->regulators)
+ config.init_data = pdata->regulators[i];
pv88080_regulator_info[i].limit_reg
= regmap_config->buck_regmap[i].buck_limit_reg;
@@ -564,12 +512,12 @@ static int pv88080_i2c_probe(struct i2c_client *i2c,
/(pv88080_regulator_info[i].desc.uV_step) + 1;
config.driver_data = (void *)&pv88080_regulator_info[i];
- chip->rdev[i] = devm_regulator_register(chip->dev,
+ regulators->rdev[i] = devm_regulator_register(chip->dev,
&pv88080_regulator_info[i].desc, &config);
- if (IS_ERR(chip->rdev[i])) {
+ if (IS_ERR(regulators->rdev[i])) {
dev_err(chip->dev,
"Failed to register PV88080 regulator\n");
- return PTR_ERR(chip->rdev[i]);
+ return PTR_ERR(regulators->rdev[i]);
}
}
@@ -583,39 +531,47 @@ static int pv88080_i2c_probe(struct i2c_client *i2c,
= regmap_config->hvbuck_vsel_mask;
/* Registeration for HVBUCK */
- if (init_data)
- config.init_data = &init_data[PV88080_ID_HVBUCK];
+ if (pdata && pdata->regulators)
+ config.init_data = pdata->regulators[PV88080_ID_HVBUCK];
config.driver_data = (void *)&pv88080_regulator_info[PV88080_ID_HVBUCK];
- chip->rdev[PV88080_ID_HVBUCK] = devm_regulator_register(chip->dev,
+ regulators->rdev[PV88080_ID_HVBUCK] = devm_regulator_register(chip->dev,
&pv88080_regulator_info[PV88080_ID_HVBUCK].desc, &config);
- if (IS_ERR(chip->rdev[PV88080_ID_HVBUCK])) {
+ if (IS_ERR(regulators->rdev[PV88080_ID_HVBUCK])) {
dev_err(chip->dev, "Failed to register PV88080 regulator\n");
- return PTR_ERR(chip->rdev[PV88080_ID_HVBUCK]);
+ return PTR_ERR(regulators->rdev[PV88080_ID_HVBUCK]);
}
return 0;
}
-static const struct i2c_device_id pv88080_i2c_id[] = {
- { "pv88080", TYPE_PV88080_AA },
- { "pv88080-aa", TYPE_PV88080_AA },
- { "pv88080-ba", TYPE_PV88080_BA },
- {},
+static const struct platform_device_id pv88080_regulator_id_table[] = {
+ { "pv88080-regulator", },
+ { /* sentinel */ }
};
-MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id);
+MODULE_DEVICE_TABLE(platform, pv88080_regulator_id_table);
-static struct i2c_driver pv88080_regulator_driver = {
+static struct platform_driver pv88080_regulator_driver = {
.driver = {
- .name = "pv88080",
- .of_match_table = of_match_ptr(pv88080_dt_ids),
+ .name = "pv88080-regulator",
},
- .probe = pv88080_i2c_probe,
- .id_table = pv88080_i2c_id,
+ .probe = pv88080_regulator_probe,
+ .id_table = pv88080_regulator_id_table,
};
-module_i2c_driver(pv88080_regulator_driver);
+static int __init pv88080_regulator_init(void)
+{
+ return platform_driver_register(&pv88080_regulator_driver);
+}
+subsys_initcall(pv88080_regulator_init);
+
+static void __exit pv88080_regulator_exit(void)
+{
+ platform_driver_unregister(&pv88080_regulator_driver);
+}
+module_exit(pv88080_regulator_exit);
-MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
+MODULE_AUTHOR("Eric Jeong <eric.jeong.opensource@diasemi.com>");
MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88080");
MODULE_LICENSE("GPL");
+
diff --git a/drivers/regulator/pv88080-regulator.h b/drivers/regulator/pv88080-regulator.h
deleted file mode 100644
index ae25ff3..0000000
--- a/drivers/regulator/pv88080-regulator.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * pv88080-regulator.h - Regulator definitions for PV88080
- * Copyright (C) 2016 Powerventure Semiconductor Ltd.
- *
- * 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.
- */
-
-#ifndef __PV88080_REGISTERS_H__
-#define __PV88080_REGISTERS_H__
-
-/* System Control and Event Registers */
-#define PV88080_REG_EVENT_A 0x04
-#define PV88080_REG_MASK_A 0x09
-#define PV88080_REG_MASK_B 0x0A
-#define PV88080_REG_MASK_C 0x0B
-
-/* Regulator Registers - rev. AA */
-#define PV88080AA_REG_HVBUCK_CONF1 0x2D
-#define PV88080AA_REG_HVBUCK_CONF2 0x2E
-#define PV88080AA_REG_BUCK1_CONF0 0x27
-#define PV88080AA_REG_BUCK1_CONF1 0x28
-#define PV88080AA_REG_BUCK1_CONF2 0x59
-#define PV88080AA_REG_BUCK1_CONF5 0x5C
-#define PV88080AA_REG_BUCK2_CONF0 0x29
-#define PV88080AA_REG_BUCK2_CONF1 0x2A
-#define PV88080AA_REG_BUCK2_CONF2 0x61
-#define PV88080AA_REG_BUCK2_CONF5 0x64
-#define PV88080AA_REG_BUCK3_CONF0 0x2B
-#define PV88080AA_REG_BUCK3_CONF1 0x2C
-#define PV88080AA_REG_BUCK3_CONF2 0x69
-#define PV88080AA_REG_BUCK3_CONF5 0x6C
-
-/* Regulator Registers - rev. BA */
-#define PV88080BA_REG_HVBUCK_CONF1 0x33
-#define PV88080BA_REG_HVBUCK_CONF2 0x34
-#define PV88080BA_REG_BUCK1_CONF0 0x2A
-#define PV88080BA_REG_BUCK1_CONF1 0x2C
-#define PV88080BA_REG_BUCK1_CONF2 0x5A
-#define PV88080BA_REG_BUCK1_CONF5 0x5D
-#define PV88080BA_REG_BUCK2_CONF0 0x2D
-#define PV88080BA_REG_BUCK2_CONF1 0x2F
-#define PV88080BA_REG_BUCK2_CONF2 0x63
-#define PV88080BA_REG_BUCK2_CONF5 0x66
-#define PV88080BA_REG_BUCK3_CONF0 0x30
-#define PV88080BA_REG_BUCK3_CONF1 0x32
-#define PV88080BA_REG_BUCK3_CONF2 0x6C
-#define PV88080BA_REG_BUCK3_CONF5 0x6F
-
-/* PV88080_REG_EVENT_A (addr=0x04) */
-#define PV88080_E_VDD_FLT 0x01
-#define PV88080_E_OVER_TEMP 0x02
-
-/* PV88080_REG_MASK_A (addr=0x09) */
-#define PV88080_M_VDD_FLT 0x01
-#define PV88080_M_OVER_TEMP 0x02
-
-/* PV88080_REG_BUCK1_CONF0 (addr=0x27|0x2A) */
-#define PV88080_BUCK1_EN 0x80
-#define PV88080_VBUCK1_MASK 0x7F
-
-/* PV88080_REG_BUCK2_CONF0 (addr=0x29|0x2D) */
-#define PV88080_BUCK2_EN 0x80
-#define PV88080_VBUCK2_MASK 0x7F
-
-/* PV88080_REG_BUCK3_CONF0 (addr=0x2B|0x30) */
-#define PV88080_BUCK3_EN 0x80
-#define PV88080_VBUCK3_MASK 0x7F
-
-/* PV88080_REG_BUCK1_CONF1 (addr=0x28|0x2C) */
-#define PV88080_BUCK1_ILIM_SHIFT 2
-#define PV88080_BUCK1_ILIM_MASK 0x0C
-#define PV88080_BUCK1_MODE_MASK 0x03
-
-/* PV88080_REG_BUCK2_CONF1 (addr=0x2A|0x2F) */
-#define PV88080_BUCK2_ILIM_SHIFT 2
-#define PV88080_BUCK2_ILIM_MASK 0x0C
-#define PV88080_BUCK2_MODE_MASK 0x03
-
-/* PV88080_REG_BUCK3_CONF1 (addr=0x2C|0x32) */
-#define PV88080_BUCK3_ILIM_SHIFT 2
-#define PV88080_BUCK3_ILIM_MASK 0x0C
-#define PV88080_BUCK3_MODE_MASK 0x03
-
-#define PV88080_BUCK_MODE_SLEEP 0x00
-#define PV88080_BUCK_MODE_AUTO 0x01
-#define PV88080_BUCK_MODE_SYNC 0x02
-
-/* PV88080_REG_HVBUCK_CONF1 (addr=0x2D|0x33) */
-#define PV88080_VHVBUCK_MASK 0xFF
-
-/* PV88080_REG_HVBUCK_CONF1 (addr=0x2E|0x34) */
-#define PV88080_HVBUCK_EN 0x01
-
-/* PV88080_REG_BUCK2_CONF2 (addr=0x61|0x63) */
-/* PV88080_REG_BUCK3_CONF2 (addr=0x69|0x6C) */
-#define PV88080_BUCK_VDAC_RANGE_SHIFT 7
-#define PV88080_BUCK_VDAC_RANGE_MASK 0x01
-
-#define PV88080_BUCK_VDAC_RANGE_1 0x00
-#define PV88080_BUCK_VDAC_RANGE_2 0x01
-
-/* PV88080_REG_BUCK2_CONF5 (addr=0x64|0x66) */
-/* PV88080_REG_BUCK3_CONF5 (addr=0x6C|0x6F) */
-#define PV88080_BUCK_VRANGE_GAIN_SHIFT 0
-#define PV88080_BUCK_VRANGE_GAIN_MASK 0x01
-
-#define PV88080_BUCK_VRANGE_GAIN_1 0x00
-#define PV88080_BUCK_VRANGE_GAIN_2 0x01
-
-#endif /* __PV88080_REGISTERS_H__ */
diff --git a/include/linux/mfd/pv88080.h b/include/linux/mfd/pv88080.h
new file mode 100644
index 0000000..479b3eb
--- /dev/null
+++ b/include/linux/mfd/pv88080.h
@@ -0,0 +1,236 @@
+/*
+ * pv88080.h - Declarations for PV88080.
+ * Copyright (C) 2016 Powerventure Semiconductor Ltd.
+ *
+ * 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.
+ */
+
+#ifndef __PV88080_H__
+#define __PV88080_H__
+
+#include <linux/regulator/machine.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+/* System Control and Event Registers */
+#define PV88080_REG_STATUS_A 0x01
+#define PV88080_REG_EVENT_A 0x04
+#define PV88080_REG_MASK_A 0x09
+#define PV88080_REG_MASK_B 0x0A
+#define PV88080_REG_MASK_C 0x0B
+
+/* GPIO Registers - rev. AA */
+#define PV88080AA_REG_GPIO_INPUT 0x18
+#define PV88080AA_REG_GPIO_GPIO0 0x1A
+
+/* Regulator Registers - rev. AA */
+#define PV88080AA_REG_HVBUCK_CONF1 0x2D
+#define PV88080AA_REG_HVBUCK_CONF2 0x2E
+#define PV88080AA_REG_BUCK1_CONF0 0x27
+#define PV88080AA_REG_BUCK1_CONF1 0x28
+#define PV88080AA_REG_BUCK1_CONF2 0x59
+#define PV88080AA_REG_BUCK1_CONF5 0x5C
+#define PV88080AA_REG_BUCK2_CONF0 0x29
+#define PV88080AA_REG_BUCK2_CONF1 0x2A
+#define PV88080AA_REG_BUCK2_CONF2 0x61
+#define PV88080AA_REG_BUCK2_CONF5 0x64
+#define PV88080AA_REG_BUCK3_CONF0 0x2B
+#define PV88080AA_REG_BUCK3_CONF1 0x2C
+#define PV88080AA_REG_BUCK3_CONF2 0x69
+#define PV88080AA_REG_BUCK3_CONF5 0x6C
+
+/* GPIO Registers - rev. AA */
+#define PV88080BA_REG_GPIO_INPUT 0x17
+#define PV88080BA_REG_GPIO_GPIO0 0x19
+
+/* Regulator Registers - rev. BA */
+#define PV88080BA_REG_HVBUCK_CONF1 0x33
+#define PV88080BA_REG_HVBUCK_CONF2 0x34
+#define PV88080BA_REG_BUCK1_CONF0 0x2A
+#define PV88080BA_REG_BUCK1_CONF1 0x2C
+#define PV88080BA_REG_BUCK1_CONF2 0x5A
+#define PV88080BA_REG_BUCK1_CONF5 0x5D
+#define PV88080BA_REG_BUCK2_CONF0 0x2D
+#define PV88080BA_REG_BUCK2_CONF1 0x2F
+#define PV88080BA_REG_BUCK2_CONF2 0x63
+#define PV88080BA_REG_BUCK2_CONF5 0x66
+#define PV88080BA_REG_BUCK3_CONF0 0x30
+#define PV88080BA_REG_BUCK3_CONF1 0x32
+#define PV88080BA_REG_BUCK3_CONF2 0x6C
+#define PV88080BA_REG_BUCK3_CONF5 0x6F
+
+/* PV88080_REG_EVENT_A (addr=0x04) */
+#define PV88080_E_VDD_FLT 0x01
+#define PV88080_E_OVER_TEMP 0x02
+#define PV88080_E_SEQ_RDY 0x04
+#define PV88080_E_EXT_OT 0x08
+
+/* PV88080_REG_MASK_A (addr=0x09) */
+#define PV88080_M_VDD_FLT 0x01
+#define PV88080_M_OVER_TEMP 0x02
+#define PV88080_M_SEQ_RDY 0x04
+#define PV88080_M_EXT_OT 0x08
+
+/* PV88080_REG_EVENT_B (addr=0x05) */
+#define PV88080_E_HVBUCK_OV 0x01
+#define PV88080_E_HVBUCK_UV 0x02
+#define PV88080_E_HVBUCK_SCP 0x04
+#define PV88080_E_BUCK1_SCP 0x08
+#define PV88080_E_BUCK2_SCP 0x10
+#define PV88080_E_BUCK3_SCP 0x20
+
+/* PV88080_REG_MASK_B (addr=0x0A) */
+#define PV88080_M_HVBUCK_OV 0x01
+#define PV88080_M_HVBUCK_UV 0x02
+#define PV88080_M_HVBUCK_SCP 0x04
+#define PV88080_M_BUCK1_SCP 0x08
+#define PV88080_M_BUCK2_SCP 0x10
+#define PV88080_M_BUCK3_SCP 0x20
+
+/* PV88080_REG_EVENT_C (addr=0x06) */
+#define PV88080_E_GPIO_FLAG0 0x01
+#define PV88080_E_GPIO_FLAG1 0x02
+#define PV88080_E_BUCK1_DROP_TIMEOUT 0x08
+#define PV88080_E_BUCK2_DROP_TIMEOUT 0x10
+#define PV88080_E_BUCk3_DROP_TIMEOUT 0x20
+
+/* PV88080_REG_MASK_C (addr=0x0B) */
+#define PV88080_M_GPIO_FLAG0 0x01
+#define PV88080_M_GPIO_FLAG1 0x02
+#define PV88080_M_BUCK1_DROP_TIMEOUT 0x08
+#define PV88080_M_BUCK2_DROP_TIMEOUT 0x10
+#define PV88080_M_BUCk3_DROP_TIMEOUT 0x20
+
+/* PV88080xx_REG_GPIO_INPUT (addr=0x18|0x17) */
+#define PV88080_GPIO_INPUT_MASK 0x01
+
+/* PV88080xx_REG_GPIO_GPIO0 (addr=0x1A|0x19) */
+#define PV88080_GPIO_DIRECTION_MASK 0x01
+#define PV88080_GPIO_OUTPUT_MASK 0x0C
+#define PV88080_GPIO_OUTPUT_EN 0x04
+#define PV88080_GPIO_OUTPUT_DIS 0x08
+
+/* PV88080_REG_BUCK1_CONF0 (addr=0x27|0x2A) */
+#define PV88080_BUCK1_EN 0x80
+#define PV88080_VBUCK1_MASK 0x7F
+
+/* PV88080_REG_BUCK2_CONF0 (addr=0x29|0x2D) */
+#define PV88080_BUCK2_EN 0x80
+#define PV88080_VBUCK2_MASK 0x7F
+
+/* PV88080_REG_BUCK3_CONF0 (addr=0x2B|0x30) */
+#define PV88080_BUCK3_EN 0x80
+#define PV88080_VBUCK3_MASK 0x7F
+
+/* PV88080_REG_BUCK1_CONF1 (addr=0x28|0x2C) */
+#define PV88080_BUCK1_ILIM_SHIFT 2
+#define PV88080_BUCK1_ILIM_MASK 0x0C
+#define PV88080_BUCK1_MODE_MASK 0x03
+
+/* PV88080_REG_BUCK2_CONF1 (addr=0x2A|0x2F) */
+#define PV88080_BUCK2_ILIM_SHIFT 2
+#define PV88080_BUCK2_ILIM_MASK 0x0C
+#define PV88080_BUCK2_MODE_MASK 0x03
+
+/* PV88080_REG_BUCK3_CONF1 (addr=0x2C|0x32) */
+#define PV88080_BUCK3_ILIM_SHIFT 2
+#define PV88080_BUCK3_ILIM_MASK 0x0C
+#define PV88080_BUCK3_MODE_MASK 0x03
+
+#define PV88080_BUCK_MODE_SLEEP 0x00
+#define PV88080_BUCK_MODE_AUTO 0x01
+#define PV88080_BUCK_MODE_SYNC 0x02
+
+/* PV88080_REG_HVBUCK_CONF1 (addr=0x2D|0x33) */
+#define PV88080_VHVBUCK_MASK 0xFF
+
+/* PV88080_REG_HVBUCK_CONF1 (addr=0x2E|0x34) */
+#define PV88080_HVBUCK_EN 0x01
+
+/* PV88080_REG_BUCK2_CONF2 (addr=0x61|0x63) */
+/* PV88080_REG_BUCK3_CONF2 (addr=0x69|0x6C) */
+#define PV88080_BUCK_VDAC_RANGE_SHIFT 7
+#define PV88080_BUCK_VDAC_RANGE_MASK 0x01
+
+#define PV88080_BUCK_VDAC_RANGE_1 0x00
+#define PV88080_BUCK_VDAC_RANGE_2 0x01
+
+/* PV88080_REG_BUCK2_CONF5 (addr=0x64|0x66) */
+/* PV88080_REG_BUCK3_CONF5 (addr=0x6C|0x6F) */
+#define PV88080_BUCK_VRANGE_GAIN_SHIFT 0
+#define PV88080_BUCK_VRANGE_GAIN_MASK 0x01
+
+#define PV88080_BUCK_VRANGE_GAIN_1 0x00
+#define PV88080_BUCK_VRANGE_GAIN_2 0x01
+
+#define PV88080_MAX_REGULATORS 4
+
+enum pv88080_types {
+ TYPE_PV88080_AA,
+ TYPE_PV88080_BA,
+};
+
+/* Interrupts */
+enum pv88080_aa_irqs {
+ PV88080_AA_IRQ_VDD_FLT,
+ PV88080_AA_IRQ_OVER_TEMP,
+ PV88080_AA_IRQ_SEQ_RDY,
+ PV88080_AA_IRQ_HVBUCK_OV,
+ PV88080_AA_IRQ_HVBUCK_UV,
+ PV88080_AA_IRQ_HVBUCK_SCP,
+ PV88080_AA_IRQ_BUCK1_SCP,
+ PV88080_AA_IRQ_BUCK2_SCP,
+ PV88080_AA_IRQ_BUCK3_SCP,
+ PV88080_AA_IRQ_GPIO_FLAG0,
+ PV88080_AA_IRQ_GPIO_FLAG1,
+};
+
+enum pv88080_ba_irqs {
+ PV88080_BA_IRQ_VDD_FLT,
+ PV88080_BA_IRQ_OVER_TEMP,
+ PV88080_BA_IRQ_SEQ_RDY,
+ PV88080_BA_IRQ_EXT_OT,
+ PV88080_BA_IRQ_HVBUCK_OV,
+ PV88080_BA_IRQ_HVBUCK_UV,
+ PV88080_BA_IRQ_HVBUCK_SCP,
+ PV88080_BA_IRQ_BUCK1_SCP,
+ PV88080_BA_IRQ_BUCK2_SCP,
+ PV88080_BA_IRQ_BUCK3_SCP,
+ PV88080_BA_IRQ_GPIO_FLAG0,
+ PV88080_BA_IRQ_GPIO_FLAG1,
+ PV88080_BA_IRQ_BUCK1_DROP_TIMEOUT,
+ PV88080_BA_IRQ_BUCK2_DROP_TIMEOUT,
+ PB88080_BA_IRQ_BUCK3_DROP_TIMEOUT,
+};
+
+struct pv88080 {
+ struct device *dev;
+ struct regmap *regmap;
+ unsigned long type;
+
+ /* IRQ Data */
+ int irq;
+ int irq_base;
+ struct regmap_irq_chip_data *irq_data;
+};
+
+struct pv88080_pdata {
+ int (*init)(struct pv88080 *pv88080);
+ int irq_base;
+ int gpio_base;
+ struct regulator_init_data *regulators[PV88080_MAX_REGULATORS];
+};
+
+int pv88080_device_init(struct pv88080 *chip, unsigned int irq);
+int pv88080_device_exit(struct pv88080 *chip);
+
+#endif /* __PV88080_H__ */
+
--
end-of-patch for PATCH V1
^ permalink raw reply related
* Re: [PATCH/RFT v2 12/17] USB: ochi-da8xx: Use a regulator for vbus/overcurrent
From: David Lechner @ 2016-10-25 1:39 UTC (permalink / raw)
To: ahaslam-rdvid1DuHRBWk0Htik3J/w,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
johan-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
nsekhar-l0cyMroinI0, stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
khilman-rdvid1DuHRBWk0Htik3J/w, sshtylyov-hkdhdckH98+B+jHODAdFcQ,
broonie-DgEjT+Ai2ygdnm+yROfE0A, abailon-rdvid1DuHRBWk0Htik3J/w
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161024164634.4330-13-ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 10/24/2016 11:46 AM, ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org wrote:
> From: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>
> Currently, the da8xx ohci driver uses a set of gpios and callbacks in
> board files to handle vbus and overcurrent irqs form the power supply.
> However, this does not play nice when moving to a DT based boot were
> we wont have board files.
>
> Instead of requesting and handling the gpio, use the regulator framework
> to take care of enabling and disabling vbus power.
> This has the benefit
> that we dont need to pass any more platform data to the driver:
>
> These will be handled by the regulator framework:
> set_power -> regulator_enable/regulator_disable
> get_power -> regulator_is_enabled
> get_oci -> regulator_get_mode
> ocic_notify -> regulator notification
>
> We can keep the default potpgt and use the regulator start delay instead:
> potpgt -> regulator startup delay time
>
> The hawk board does not have a GPIO/OVERCURRENT gpio to control vbus,
> (they should not have been decleared/reserved) so, just remove those
> definitions from the hwk board file.
>
> Signed-off-by: Axel Haslam <ahaslam-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
How do you recover after an overcurrent event?
I have configured a fixed-regulator using device-tree, but similar to
the configuration in the board files here. However, when I shorted out
the VBUS and caused an overcurrent event, I see nothing in the kernel
log saying that there was an overcurrent event and after I remove the
short, the regulator is never turned back on.
> @@ -163,7 +198,6 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> u16 wIndex, char *buf, u16 wLength)
> {
> struct device *dev = hcd->self.controller;
> - struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
nit: unnecessary whitespace change
> int temp;
>
> switch (typeReq) {
--
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 1/2] powerpc/mpc85xx: Update TMU device tree node for T1040/T1042
From: Jia Hongtao @ 2016-10-25 2:15 UTC (permalink / raw)
To: rui.zhang-ral2JQCrhuEAvxtiuMwx3w,
edubezval-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
scott.wood-3arQi8VN3Tc, shawnguo-DgEjT+Ai2ygdnm+yROfE0A
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
hongtao.jia-3arQi8VN3Tc
From: Hongtao Jia <hongtao.jia-3arQi8VN3Tc@public.gmane.org>
Update #thermal-sensor-cells from 0 to 1 according to the new binding. The
sensor specifier added is the monitoring site ID, and represents the "n" in
TRITSRn and TRATSRn.
Signed-off-by: Jia Hongtao <hongtao.jia-3arQi8VN3Tc@public.gmane.org>
---
Changes for V3:
* Update the commit log to a better description.
Changes for V2:
* Rebase on latest linux-next tree (next-20161006).
arch/powerpc/boot/dts/fsl/t1040si-post.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 44e399b..145c7f4 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -526,7 +526,7 @@
0x00030000 0x00000012
0x00030001 0x0000001d>;
- #thermal-sensor-cells = <0>;
+ #thermal-sensor-cells = <1>;
};
thermal-zones {
@@ -534,7 +534,7 @@
polling-delay-passive = <1000>;
polling-delay = <5000>;
- thermal-sensors = <&tmu>;
+ thermal-sensors = <&tmu 2>;
trips {
cpu_alert: cpu-alert {
--
2.1.0.27.g96db324
--
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 2/2] powerpc/mpc85xx: Update TMU device tree node for T1023/T1024
From: Jia Hongtao @ 2016-10-25 2:15 UTC (permalink / raw)
To: rui.zhang-ral2JQCrhuEAvxtiuMwx3w,
edubezval-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
scott.wood-3arQi8VN3Tc, shawnguo-DgEjT+Ai2ygdnm+yROfE0A
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
hongtao.jia-3arQi8VN3Tc
In-Reply-To: <1477361742-589-1-git-send-email-hongtao.jia-3arQi8VN3Tc@public.gmane.org>
From: Hongtao Jia <hongtao.jia-3arQi8VN3Tc@public.gmane.org>
Update #thermal-sensor-cells from 0 to 1 according to the new binding. The
sensor specifier added is the monitoring site ID, and represents the "n" in
TRITSRn and TRATSRn.
Signed-off-by: Jia Hongtao <hongtao.jia-3arQi8VN3Tc@public.gmane.org>
---
Changes for V3:
* Update the commit log to a better description.
Changes for V2:
* Rebase on latest linux-next tree (next-20161006).
arch/powerpc/boot/dts/fsl/t1023si-post.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
index 6e0b489..bce762a 100644
--- a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
@@ -321,7 +321,7 @@
0x00030001 0x0000000d
0x00030002 0x00000019
0x00030003 0x00000024>;
- #thermal-sensor-cells = <0>;
+ #thermal-sensor-cells = <1>;
};
thermal-zones {
@@ -329,7 +329,7 @@
polling-delay-passive = <1000>;
polling-delay = <5000>;
- thermal-sensors = <&tmu>;
+ thermal-sensors = <&tmu 0>;
trips {
cpu_alert: cpu-alert {
--
2.1.0.27.g96db324
--
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 V2 1/5] powerpc/mpc85xx: Update TMU device tree node for T1040/T1042
From: Troy Jia @ 2016-10-25 2:29 UTC (permalink / raw)
To: Shawn Guo
Cc: rui.zhang@intel.com, edubezval@gmail.com, robh+dt@kernel.org,
Scott Wood, devicetree@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20161024083654.GB30578@tiger>
> -----Original Message-----
> From: Shawn Guo [mailto:shawnguo@kernel.org]
> Sent: Monday, October 24, 2016 4:37 PM
> To: Troy Jia <hongtao.jia@nxp.com>
> Cc: rui.zhang@intel.com; edubezval@gmail.com; robh+dt@kernel.org; Scott Wood
> <scott.wood@nxp.com>; devicetree@vger.kernel.org; linuxppc-
> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org
> Subject: Re: [PATCH V2 1/5] powerpc/mpc85xx: Update TMU device tree node for
> T1040/T1042
>
> On Sun, Oct 09, 2016 at 02:47:02PM +0800, Jia Hongtao wrote:
> > From: Hongtao Jia <hongtao.jia@nxp.com>
> >
> > SoC compatible string and endianness property are added according to
> > the new bindings.
>
> The commit log doesn't seem to match the actual changes. Same for patch 2/5.
Right. I just revise the log and sent a new version. Please help to review.
Thanks.
-Hongtao.
>
> >
> > Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
> > ---
> > Changes for V2:
> > * Rebase on latest linux-next tree (next-20161006).
> >
> > arch/powerpc/boot/dts/fsl/t1040si-post.dtsi | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
> > b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
> > index 44e399b..145c7f4 100644
> > --- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
> > +++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
> > @@ -526,7 +526,7 @@
> >
> > 0x00030000 0x00000012
> > 0x00030001 0x0000001d>;
> > - #thermal-sensor-cells = <0>;
> > + #thermal-sensor-cells = <1>;
> > };
> >
> > thermal-zones {
> > @@ -534,7 +534,7 @@
> > polling-delay-passive = <1000>;
> > polling-delay = <5000>;
> >
> > - thermal-sensors = <&tmu>;
> > + thermal-sensors = <&tmu 2>;
> >
> > trips {
> > cpu_alert: cpu-alert {
> > --
> > 2.1.0.27.g96db324
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V7 2/6] thermal: bcm2835: add thermal driver for bcm2835 soc
From: Zhang Rui @ 2016-10-25 2:47 UTC (permalink / raw)
To: Stefan Wahren, kernel-TqfNSX0MhmxHKSADF0wUEw, Eric Anholt
Cc: Will Deacon, Lee Jones, Pawel Moll, Rob Herring,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-pm-u79uwXL29TY76Z2rM5mHXA, Eduardo Valentin, Russell King,
Catalin Marinas, Stephen Warren, Mark Rutland, Florian Fainelli,
linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1190898538.120930.02d69662-0b1a-447d-9c29-782aec7a1189.open-xchange-7tX72C7vayboQLBSYMtkGA@public.gmane.org>
On Mon, 2016-10-24 at 20:25 +0200, Stefan Wahren wrote:
> >
> > Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org> hat am 24. Oktober 2016 um 18:38
> > geschrieben:
> >
> >
> > Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org> writes:
> >
> > >
> > > Hi Martin,
> > >
> > > Am 28.09.2016 um 23:10 schrieb Eric Anholt:
> > > >
> > > > kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org writes:
> > > >
> > > > >
> > > > > From: Martin Sperl <kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
> > > > >
> > > > > Add basic thermal driver for bcm2835 SOC.
> > > > >
> > > > > This driver currently relies on the firmware setting up the
> > > > > tsense HW block and does not set it up itself.
> > > > >
> > > > > Signed-off-by: Martin Sperl <kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
> > > > > Acked-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
> > > > > Acked-by: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
> > > > What's the status of merging this one? I'd like to merge the
> > > > other
> > > > patches.
> > > i think it's necessary to rebase the whole series. Maybe we could
> > > get it
> > > into 4.10.
> > Why would it need to be rebased? The status, as far as I know, is
> > that
> > we're still waiting for the subsystem maintainer to respond.
> Since at least this patch won't apply anymore, but feedback from
> maintainer is
> still good :-)
>
> Sorry for this impatience, but i'm afraid that we possibly miss 4.10.
Eduardo,
any comments on this patchset?
thanks,
rui
--
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/RFT v2 07/17] ARM: davinci: da8xx: Enable the usb20 "per" clk on phy_clk_enable
From: David Lechner @ 2016-10-25 2:53 UTC (permalink / raw)
To: ahaslam, gregkh, johan, robh+dt, nsekhar, stern, khilman,
sshtylyov, manjunath.goudar, broonie, abailon
Cc: linux-usb, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <20161024164634.4330-8-ahaslam@baylibre.com>
On 10/24/2016 11:46 AM, ahaslam@baylibre.com wrote:
> From: Axel Haslam <ahaslam@baylibre.com>
>
> While probing ochi phy with usb20 phy as a parent clock for usb11_phy,
> the usb20_phy clock enable would time out. This is because the usb20
> module clock needs to enabled while trying to lock the usb20_phy PLL.
>
> Call clk enable and get for the usb20 peripheral before trying to
> enable the phy PLL.
>
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
> ---
This patch can be combined with "ARM: davinci: da8xx: add usb phy
clocks" since that patch has not been merged yet.
If you like, I can resubmit my patches from this series along with the
changes from this patch.
^ permalink raw reply
* Re: [PATCH 5/5] ARM: dts: Add LEGO MINDSTORTMS EV3 dts
From: David Lechner @ 2016-10-25 2:56 UTC (permalink / raw)
To: Sekhar Nori, Kevin Hilman
Cc: Mark Rutland, devicetree, Russell King, linux-kernel, Rob Herring,
linux-arm-kernel
In-Reply-To: <1593441f-d147-4c91-8aab-8622dd8ced19@lechnology.com>
On 10/24/2016 10:50 AM, David Lechner wrote:
> On 10/24/2016 06:58 AM, Sekhar Nori wrote:
>> On Saturday 22 October 2016 12:06 AM, David Lechner wrote:
>>> +};
>>> +
>>> +&spi1 {
>>> + status = "okay";
>>> + pinctrl-names = "default";
>>> + pinctrl-0 = <&spi1_pins>, <&spi1_cs0_pin>;
>>> +
>>> + /* TODO: LCD Display goes here */
>>
>> Add this node when you actually have display working.
>
> What if we set this up as a spidev node instead? This way the display
> could be used from userspace without a driver.
>
To answer my own question, it seems that specifying "spidev" in
devicetree is frowned upon since it does not "describe the hardware".
^ permalink raw reply
* Re: [RESEND][PATCH] crypto: caam: add support for iMX6UL
From: Herbert Xu @ 2016-10-25 3:39 UTC (permalink / raw)
To: Marcus Folkesson
Cc: David S . Miller, Rob Herring, Mark Rutland, Horia Geanta,
Arnd Bergmann, Alex Porosanu, Srinivas Kandagatla, Baoyou Xie,
Russell King, linux-crypto-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1476703680-22676-1-git-send-email-marcus.folkesson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Mon, Oct 17, 2016 at 01:28:00PM +0200, Marcus Folkesson wrote:
> i.MX6UL does only require three clocks to enable CAAM module.
>
> Signed-off-by: Marcus Folkesson <marcus.folkesson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Reviewed-by: Horia Geantă <horia.geanta-3arQi8VN3Tc@public.gmane.org>
Patch applied. Thanks.
--
Email: Herbert Xu <herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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] ARM64: dts: bcm2835: Fix bcm2837 compatible string
From: Eric Anholt @ 2016-10-25 3:59 UTC (permalink / raw)
To: linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Andreas Färber, Stephen Warren, Rob Herring, Mark Rutland,
Catalin Marinas, Will Deacon, Florian Fainelli, Ray Jui,
Scott Branden, bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1477321791-7896-1-git-send-email-afaerber-l3A5Bk7waGM@public.gmane.org>
e<#secure method=pgpmime mode=sign>
Andreas Färber <afaerber-l3A5Bk7waGM@public.gmane.org> writes:
> bcm2837-rpi-3-b.dts, its only in-tree user, was overriding it as
> "brcm,bcm2837" already.
Pulled to bcm2835-dt-64-next. Thanks!
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH RESEND 1/2] dt: bindings: add allwinner,otg-routed property for phy-sun4i-usb
From: Icenowy Zheng @ 2016-10-25 4:11 UTC (permalink / raw)
To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I,
Hans de Goede
Cc: Mark Rutland, Reinder de Haan, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
On some newer Allwinner SoCs (H3 or A64), the PHY0 can be either routed to
the MUSB controller (which is an OTG controller) or the OHCI/EHCI pair
(which is a Host-only controller, but more stable and easy to implement).
This property marks whether on a certain board which controller should be
attached to the PHY.
Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
index 287150d..a63c766 100644
--- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
@@ -36,6 +36,12 @@ Optional properties:
- usb1_vbus-supply : regulator phandle for controller usb1 vbus
- usb2_vbus-supply : regulator phandle for controller usb2 vbus
+Optional properties for H3 or A64 SoCs:
+- allwinner,otg-routed : USB0 (OTG) PHY is routed to OHCI/EHCI pair rather than
+ MUSB. (boolean, if this property is set, the OHCI/EHCI
+ controllers at PHY0 should be enabled and the MUSB
+ controller must *NOT* be enabled)
+
Example:
usbphy: phy@0x01c13400 {
#phy-cells = <1>;
--
2.10.1
^ permalink raw reply related
* [PATCH RESEND 2/2] phy-sun4i-usb: add support for host mode of phy0 on A64 SoC
From: Icenowy Zheng @ 2016-10-25 4:11 UTC (permalink / raw)
To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I,
Hans de Goede
Cc: Mark Rutland, Reinder de Haan, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20161025041139.46454-1-icenowy-ymACFijhrKM@public.gmane.org>
The OTG phy of A64 can be put into the host mode with an OHCI/EHCI pair,
just like the H3 SoC.
Some A64 boards (such as Pine64 series) use the USB OTG port as a generic
USB-A port, and thus can be fully support by the driver now.
The register's name is changed to PHY_OTG_CFG, as it's described in the
A64 downstream BSP kernel source, at drivers/usb/host/sunxi_hci.h .
Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
drivers/phy/phy-sun4i-usb.c | 46 +++++++++++++++++++++++++++++++++------------
1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index a4db658..9287247 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -47,7 +47,7 @@
#define REG_PHYBIST 0x08
#define REG_PHYTUNE 0x0c
#define REG_PHYCTL_A33 0x10
-#define REG_PHY_UNK_H3 0x20
+#define REG_PHY_OTG_CFG 0x20
#define REG_PMU_UNK1 0x10
@@ -107,6 +107,7 @@ struct sun4i_usb_phy_cfg {
u8 phyctl_offset;
bool dedicated_clocks;
bool enable_pmu_unk1;
+ bool route_otg;
};
struct sun4i_usb_phy_data {
@@ -135,6 +136,7 @@ struct sun4i_usb_phy_data {
int id_det;
int vbus_det;
struct delayed_work detect;
+ bool otg_routed;
};
#define to_sun4i_usb_phy_data(phy) \
@@ -263,10 +265,11 @@ static int sun4i_usb_phy_init(struct phy *_phy)
writel(val & ~2, phy->pmu + REG_PMU_UNK1);
}
- if (data->cfg->type == sun8i_h3_phy) {
- if (phy->index == 0) {
- val = readl(data->base + REG_PHY_UNK_H3);
- writel(val & ~1, data->base + REG_PHY_UNK_H3);
+ if (data->cfg->route_otg) {
+ if (phy->index == 0 && data->otg_routed) {
+ /* Route the OTG PHY to HCI */
+ val = readl(data->base + REG_PHY_OTG_CFG);
+ writel(val & ~1, data->base + REG_PHY_OTG_CFG);
}
} else {
/* Enable USB 45 Ohm resistor calibration */
@@ -283,7 +286,7 @@ static int sun4i_usb_phy_init(struct phy *_phy)
sun4i_usb_phy_passby(phy, 1);
- if (phy->index == 0) {
+ if (phy->index == 0 && !data->otg_routed) {
data->phy0_init = true;
/* Enable pull-ups */
@@ -310,7 +313,7 @@ static int sun4i_usb_phy_exit(struct phy *_phy)
struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
- if (phy->index == 0) {
+ if (phy->index == 0 && !data->otg_routed) {
/* Disable pull-ups */
sun4i_usb_phy0_update_iscr(_phy, ISCR_DPDM_PULLUP_EN, 0);
sun4i_usb_phy0_update_iscr(_phy, ISCR_ID_PULLUP_EN, 0);
@@ -377,7 +380,7 @@ static int sun4i_usb_phy_power_on(struct phy *_phy)
/* For phy0 only turn on Vbus if we don't have an ext. Vbus */
if (phy->index == 0 && sun4i_usb_phy0_have_vbus_det(data) &&
- data->vbus_det)
+ data->vbus_det && !data->otg_routed)
return 0;
ret = regulator_enable(phy->vbus);
@@ -387,7 +390,7 @@ static int sun4i_usb_phy_power_on(struct phy *_phy)
phy->regulator_on = true;
/* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */
- if (phy->index == 0 && sun4i_usb_phy0_poll(data))
+ if (phy->index == 0 && sun4i_usb_phy0_poll(data) && !data->otg_routed)
mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
return 0;
@@ -408,7 +411,7 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
* phy0 vbus typically slowly discharges, sometimes this causes the
* Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan.
*/
- if (phy->index == 0 && !sun4i_usb_phy0_poll(data))
+ if (phy->index == 0 && !sun4i_usb_phy0_poll(data) && !data->otg_routed)
mod_delayed_work(system_wq, &data->detect, POLL_TIME);
return 0;
@@ -567,7 +570,17 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return -ENOMEM;
mutex_init(&data->mutex);
- INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan);
+ if (device_property_read_bool(dev, "allwinner,otg-routed")) {
+ /*
+ * PHY0 is routed to HCI rather than OTG Controller.
+ * In this situation, the port can only be used as a host port.
+ */
+ data->otg_routed = true;
+ } else {
+ /* ID/Vbus detection is only meaningful when it's really OTG */
+ INIT_DELAYED_WORK(&data->detect,
+ sun4i_usb_phy0_id_vbus_det_scan);
+ }
dev_set_drvdata(dev, data);
data->cfg = of_device_get_match_data(dev);
if (!data->cfg)
@@ -647,7 +660,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy->reset);
}
- if (i) { /* No pmu for usbc0 */
+ /* PMU is only valid on PHYs in HCI mode */
+ if (i || data->otg_routed) {
snprintf(name, sizeof(name), "pmu%d", i);
res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, name);
@@ -719,6 +733,7 @@ static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = false,
.enable_pmu_unk1 = false,
+ .route_otg = false,
};
static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
@@ -728,6 +743,7 @@ static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = false,
.enable_pmu_unk1 = false,
+ .route_otg = false,
};
static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
@@ -737,6 +753,7 @@ static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = true,
.enable_pmu_unk1 = false,
+ .route_otg = false,
};
static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
@@ -746,6 +763,7 @@ static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = false,
.enable_pmu_unk1 = false,
+ .route_otg = false,
};
static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
@@ -755,6 +773,7 @@ static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
.phyctl_offset = REG_PHYCTL_A10,
.dedicated_clocks = true,
.enable_pmu_unk1 = false,
+ .route_otg = false,
};
static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
@@ -764,6 +783,7 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
.enable_pmu_unk1 = false,
+ .route_otg = false,
};
static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
@@ -772,6 +792,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
.disc_thresh = 3,
.dedicated_clocks = true,
.enable_pmu_unk1 = true,
+ .route_otg = true,
};
static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
@@ -781,6 +802,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
.enable_pmu_unk1 = true,
+ .route_otg = true,
};
static const struct of_device_id sun4i_usb_phy_of_match[] = {
--
2.10.1
^ permalink raw reply related
* Re: [v2 2/2] fpga: Add support for Lattice iCE40 FPGAs
From: Joel Holdsworth @ 2016-10-25 4:51 UTC (permalink / raw)
To: Moritz Fischer, atull
Cc: ijc+devicetree, galak, mark.rutland, pawel.moll, robh+dt,
devicetree, linux-kernel
In-Reply-To: <20161024222805.GA5754@live.com>
On 10/24/2016 04:28 PM, Moritz Fischer wrote:
> Hi Joel,
>
> Ha, finally someone beat me to submitting my driver,
> I had an ugly hack to bitbang the SPI since I couldn't figure
> out a good way to assert the creset after the CS.
>
> Thanks!
>
Hi Moritz - yeah I figured someone might have a driver in the works.
I think my set_cs() function is ok-ish. It's copied from spi_set_cs() in
drivers/spi/spi.c . This function is a static internal helper, so I
copy/pasted the function into the ice40 driver. Given that it's only
4-lines of code, it didn't seem too bad - though I'm not exactly sure
why spi_set_cs() isn't a public API. It seems like quite a common-place
thing to need to do with certain devices.
However, perhaps the function is internal because the authors of the SPI
framework foresaw how easy it would be to screw up a shared bus with
that function. I had to take care to make sure the SPI bus was locked
throughout.
Do you agree that it's the right thing to copy the function in? Or do
you think it would be better to ask for spi_set_cs to be exposed publicly?
Best Regards
Joel
^ permalink raw reply
* Re: [v2 2/2] fpga: Add support for Lattice iCE40 FPGAs
From: Joel Holdsworth @ 2016-10-25 5:05 UTC (permalink / raw)
To: atull
Cc: ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, mark.rutland-5wv7dgnIgG8,
moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w, pawel.moll-5wv7dgnIgG8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <alpine.DEB.2.02.1610241615280.14525@linuxheads99>
> Hi Joel,
>
> Thanks for submitting your driver!
>
> I didn't see any huge problems, just minor things below...
>
> Alan
>
Hi Alan, Thanks for your feedback. I've implemented all your suggestions
and I'll resubmit.
I had a question about the status of the fpga-manager framework. Is
there active work going on? I was wondering if there were any patches
for specifying a firmware file from device-tree? and/or if there were
any patches for loading firmware from userspace - something like this:
"cat firmware.bin > /dev/fpga0"?
Only being able to load firmware from kernel C-code is rather a
limitation - though I suppose the framework is quite early in development.
Thanks
Joel
--
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 1/2] of: Add vendor prefix for Lattice Semiconductor
From: Joel Holdsworth @ 2016-10-25 5:05 UTC (permalink / raw)
To: atull-yzvPICuk2ABMcg4IHK0kFoH6Mc4MB0Vx,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, mark.rutland-5wv7dgnIgG8,
moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w, pawel.moll-5wv7dgnIgG8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Joel Holdsworth
---
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 1992aa9..d64a835 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -146,6 +146,7 @@ kosagi Sutajio Ko-Usagi PTE Ltd.
kyo Kyocera Corporation
lacie LaCie
lantiq Lantiq Semiconductor
+lattice Lattice Semiconductor
lenovo Lenovo Group Ltd.
lg LG Corporation
linux Linux-specific binding
--
2.7.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
* [PATCH v3 2/2] fpga: Add support for Lattice iCE40 FPGAs
From: Joel Holdsworth @ 2016-10-25 5:05 UTC (permalink / raw)
To: atull-yzvPICuk2ABMcg4IHK0kFoH6Mc4MB0Vx,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, mark.rutland-5wv7dgnIgG8,
moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w, pawel.moll-5wv7dgnIgG8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Joel Holdsworth
In-Reply-To: <1477371948-12780-1-git-send-email-joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org>
The Lattice iCE40 is a family of FPGAs with a minimalistic architecture
and very regular structure, designed for low-cost, high-volume consumer
and system applications.
This patch adds support to the FPGA manager for configuring the SRAM of
iCE40LM, iCE40LP, iCE40HX, iCE40 Ultra, iCE40 UltraLite and iCE40
UltraPlus devices, through slave SPI.
The iCE40 family is notable because it is the first FPGA family to have
complete reverse engineered bit-stream documentation for the iCE40LP and
iCE40HX devices. Furthermore, there is now a Free Software Verilog
synthesis tool-chain: the "IceStorm" tool-chain.
This project is the work of Clifford Wolf, who is the maintainer of
Yosys Verilog RTL synthesis framework, and Mathias Lasser, with notable
contributions from "Cotton Seed", the main author of "arachne-pnr"; a
place-and-route tool for iCE40 FPGAs.
Having a Free Software synthesis tool-chain offers interesting
opportunities for embedded devices that are able reconfigure themselves
with open firmware that is generated on the device itself. For example
a mobile device might have an application processor with an iCE40 FPGA
attached, which implements slave devices, or through which the processor
communicates with other devices through the FPGA fabric.
A kernel driver for the iCE40 is useful, because in some cases, the FPGA
may need to be configured before other devices can be accessed.
An example of such a device is the icoBoard; a RaspberryPI HAT which
features an iCE40HX8K with a 1 or 8 MBit SRAM and ports for
Digilent-compatible PMOD modules. A PMOD module may contain a device
with which the kernel communicates, via the FPGA.
---
.../bindings/fpga/lattice-ice40-fpga-mgr.txt | 23 +++
drivers/fpga/Kconfig | 6 +
drivers/fpga/Makefile | 1 +
drivers/fpga/ice40-spi.c | 219 +++++++++++++++++++++
4 files changed, 249 insertions(+)
create mode 100644 Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
create mode 100644 drivers/fpga/ice40-spi.c
diff --git a/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
new file mode 100644
index 0000000..3d2917c
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
@@ -0,0 +1,23 @@
+Lattice iCE40 FPGA Manager
+
+Required properties:
+- compatible: should contain "lattice,ice40-fpga-mgr"
+- reg: SPI chip select
+- spi-max-frequency: Maximum SPI frequency (>=1000000, <=25000000)
+- cdone-gpio: GPIO connected to CDONE pin
+- creset_b-gpio: GPIO connected to CRESET_B pin. Note that CRESET_B is
+ treated as an active-low output because the signal is
+ treated as an enable signal, rather than a reset. This
+ is necessary because the FPGA will enter Master SPI
+ mode and drive SCK with a clock signal, potentially
+ jamming other devices on the bus, unless CRESET_B is
+ held high until the firmware is loaded.
+
+Example:
+ ice40: ice40@0 {
+ compatible = "lattice,ice40-fpga-mgr";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ cdone-gpio = <&gpio 24 GPIO_ACTIVE_HIGH>;
+ creset_b-gpio = <&gpio 22 GPIO_ACTIVE_LOW>;
+ };
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index d614102..85ff429 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -13,6 +13,12 @@ config FPGA
if FPGA
+config FPGA_MGR_ICE40_SPI
+ tristate "Lattice iCE40 SPI"
+ depends on SPI
+ help
+ FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
+
config FPGA_MGR_SOCFPGA
tristate "Altera SOCFPGA FPGA Manager"
depends on ARCH_SOCFPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8d83fc6..adb5811 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -6,5 +6,6 @@
obj-$(CONFIG_FPGA) += fpga-mgr.o
# FPGA Manager Drivers
+obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o
obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o
diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c
new file mode 100644
index 0000000..2e430ff
--- /dev/null
+++ b/drivers/fpga/ice40-spi.c
@@ -0,0 +1,219 @@
+/*
+ * FPGA Manager Driver for Lattice iCE40.
+ *
+ * Copyright (c) 2016 Joel Holdsworth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This driver adds support to the FPGA manager for configuring the SRAM of
+ * Lattice iCE40 FPGAs through slave SPI.
+ */
+
+#include <linux/delay.h>
+#include <linux/fpga/fpga-mgr.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_gpio.h>
+#include <linux/spi/spi.h>
+
+#define ICE40_SPI_FPGAMGR_RESET_DELAY 1 /* us (>200ns) */
+#define ICE40_SPI_FPGAMGR_HOUSEKEEPING_DELAY 1200 /* us */
+
+#define ICE40_SPI_FPGAMGR_NUM_ACTIVATION_BITS 49 /* bits */
+
+struct ice40_fpga_priv {
+ struct spi_device *dev;
+ struct gpio_desc *creset_b;
+ struct gpio_desc *cdone;
+};
+
+static enum fpga_mgr_states ice40_fpga_ops_state(struct fpga_manager *mgr)
+{
+ struct ice40_fpga_priv *priv = mgr->priv;
+ return gpiod_get_value(priv->cdone) ? FPGA_MGR_STATE_OPERATING :
+ FPGA_MGR_STATE_UNKNOWN;
+}
+
+static void set_cs(struct spi_device *spi, bool enable)
+{
+ if (gpio_is_valid(spi->cs_gpio))
+ gpio_set_value(spi->cs_gpio, !enable);
+ else if (spi->master->set_cs)
+ spi->master->set_cs(spi, !enable);
+}
+
+static int ice40_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
+ const char *buf, size_t count)
+{
+ struct ice40_fpga_priv *priv = mgr->priv;
+ struct spi_device *dev = priv->dev;
+ int ret;
+
+ if ((flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ dev_err(&dev->dev,
+ "Partial reconfiguration is not supported\n");
+ return -ENOTSUPP;
+ }
+
+ /* Lock the bus, assert SS_B and CRESET_B */
+ ret = spi_bus_lock(dev->master);
+ if (ret) {
+ dev_err(&dev->dev, "Failed to lock SPI bus, ret: %d\n", ret);
+ return ret;
+ }
+
+ set_cs(dev, 1);
+ gpiod_set_value(priv->creset_b, 1);
+
+ /* Delay for >200ns */
+ udelay(ICE40_SPI_FPGAMGR_RESET_DELAY);
+
+ /* Come out of reset */
+ gpiod_set_value(priv->creset_b, 0);
+
+ /* Check CDONE is de-asserted i.e. the FPGA is reset */
+ if (gpiod_get_value(priv->cdone)) {
+ dev_err(&dev->dev, "Device reset failed, CDONE is asserted\n");
+ ret = -EIO;
+ }
+
+ /* Wait for the housekeeping to complete */
+ if (!ret)
+ udelay(ICE40_SPI_FPGAMGR_HOUSEKEEPING_DELAY);
+
+ /* Release the SS_B */
+ set_cs(dev, 0);
+ spi_bus_unlock(dev->master);
+
+ return ret;
+}
+
+static int ice40_fpga_ops_write(struct fpga_manager *mgr,
+ const char *buf, size_t count)
+{
+ struct ice40_fpga_priv *priv = mgr->priv;
+ struct spi_device *dev = priv->dev;
+ int ret;
+
+ ret = spi_write(dev, buf, count);
+ if (ret)
+ dev_err(&dev->dev, "Error sending SPI data, ret: %d\n", ret);
+
+ return ret;
+}
+
+static int ice40_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags)
+{
+ struct ice40_fpga_priv *priv = mgr->priv;
+ struct spi_device *dev = priv->dev;
+ int ret = 0;
+
+ /* Check CDONE is asserted */
+ if (!gpiod_get_value(priv->cdone)) {
+ dev_err(&dev->dev,
+ "CDONE was not asserted after firmware transfer\n");
+ return -EIO;
+ }
+
+ /* Send of zero-padding to activate the firmware */
+ ret = spi_write(dev, NULL, (ICE40_SPI_FPGAMGR_NUM_ACTIVATION_BITS +
+ dev->bits_per_word - 1) / dev->bits_per_word);
+ if (ret) {
+ dev_err(&dev->dev, "Error sending zero padding, ret: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* Success */
+ return 0;
+}
+
+static const struct fpga_manager_ops ice40_fpga_ops = {
+ .state = ice40_fpga_ops_state,
+ .write_init = ice40_fpga_ops_write_init,
+ .write = ice40_fpga_ops_write,
+ .write_complete = ice40_fpga_ops_write_complete,
+};
+
+static int ice40_fpga_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct device_node *np = spi->dev.of_node;
+ struct ice40_fpga_priv *priv;
+ int ret;
+
+ if (!np) {
+ dev_err(dev, "No Device Tree entry\n");
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = spi;
+
+ /* Check board setup data. */
+ if (spi->max_speed_hz > 25000000) {
+ dev_err(dev, "speed is too high\n");
+ return -EINVAL;
+ } else if (spi->mode & SPI_CPHA) {
+ dev_err(dev, "bad mode\n");
+ return -EINVAL;
+ }
+
+ /* Set up the GPIOs */
+ priv->cdone = devm_gpiod_get(dev, "cdone", GPIOD_IN);
+ if (IS_ERR(priv->cdone)) {
+ dev_err(dev, "Failed to get CDONE GPIO: %ld\n",
+ PTR_ERR(priv->cdone));
+ return ret;
+ }
+
+ priv->creset_b = devm_gpiod_get(dev, "creset_b", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->creset_b)) {
+ dev_err(dev, "Failed to get CRESET_B GPIO: %ld\n",
+ PTR_ERR(priv->creset_b));
+ return ret;
+ }
+
+ /* Register with the FPGA manager */
+ ret = fpga_mgr_register(dev, "Lattice iCE40 FPGA Manager",
+ &ice40_fpga_ops, priv);
+ if (ret) {
+ dev_err(dev, "unable to register FPGA manager");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ice40_fpga_remove(struct spi_device *spi)
+{
+ fpga_mgr_unregister(&spi->dev);
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ice40_fpga_of_match[] = {
+ { .compatible = "lattice,ice40-fpga-mgr", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ice40_fpga_of_match);
+#endif
+
+static struct spi_driver ice40_fpga_driver = {
+ .probe = ice40_fpga_probe,
+ .remove = ice40_fpga_remove,
+ .driver = {
+ .name = "ice40spi",
+ .of_match_table = of_match_ptr(ice40_fpga_of_match),
+ },
+};
+
+module_spi_driver(ice40_fpga_driver);
+
+MODULE_AUTHOR("Joel Holdsworth <joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org>");
+MODULE_DESCRIPTION("Lattice iCE40 FPGA Manager");
+MODULE_LICENSE("GPL v2");
--
2.7.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
* [PATCH v2] drm/mediatek: fixed the calc method of data rate per lane
From: Jitao Shi @ 2016-10-25 5:40 UTC (permalink / raw)
To: Philipp Zabel, ck.hu-NuS5LvNUpcJWk0Htik3J/w, Matthias Brugger
Cc: Mark Rutland, stonea168-9Onoh4P/yGk,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Andy Yan, Ajay Kumar,
Vincent Palatin, cawa.cheng-NuS5LvNUpcJWk0Htik3J/w,
bibby.hsieh-NuS5LvNUpcJWk0Htik3J/w, Russell King,
devicetree-u79uwXL29TY76Z2rM5mHXA, Jitao Shi, Pawel Moll,
Ian Campbell, Inki Dae, Rob Herring,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w,
eddie.huang-NuS5LvNUpcJWk0Htik3J/w,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rahul Sharma,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Sascha Hauer, Kumar Gala,
Sean Paul
Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e. Tlpx,
Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP mode, this
signal will cause h-time larger than normal and reduce FPS.
Need to multiply a coefficient to offset the extra signal's effect.
coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+Ths_trail+
Ths_exit)/(htotal*bpp/lane_number))
Signed-off-by: Jitao Shi <jitao.shi-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
Change since v1:
- phy_timing2 and phy_timing3 refer clock cycle time.
- define values of LPX HS_PRPR HS_ZERO HS_TRAIL TA_GO TA_SURE TA_GET DA_HS_EXIT
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 103 +++++++++++++++++++++++-------------
1 file changed, 67 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 28b2044..ade6f46 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -85,16 +85,16 @@
#define LD0_WAKEUP_EN BIT(2)
#define DSI_PHY_TIMECON0 0x110
-#define LPX (0xff << 0)
-#define HS_PRPR (0xff << 8)
-#define HS_ZERO (0xff << 16)
-#define HS_TRAIL (0xff << 24)
+#define LPX (5 << 0)
+#define HS_PRPR (6 << 8)
+#define HS_ZERO (10 << 16)
+#define HS_TRAIL (8 << 24)
#define DSI_PHY_TIMECON1 0x114
-#define TA_GO (0xff << 0)
-#define TA_SURE (0xff << 8)
-#define TA_GET (0xff << 16)
-#define DA_HS_EXIT (0xff << 24)
+#define TA_GO (20 << 0)
+#define TA_SURE (7 << 8)
+#define TA_GET (25 << 16)
+#define DA_HS_EXIT (7 << 24)
#define DSI_PHY_TIMECON2 0x118
#define CONT_DET (0xff << 0)
@@ -158,28 +158,14 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, u32 mask, u32 data)
writel((temp & ~mask) | (data & mask), dsi->regs + offset);
}
-static void dsi_phy_timconfig(struct mtk_dsi *dsi)
+static void dsi_phy_timconfig(struct mtk_dsi *dsi, u32 phy_timing0,
+ u32 phy_timing1, u32 phy_timing2,
+ u32 phy_timing3)
{
- u32 timcon0, timcon1, timcon2, timcon3;
- unsigned int ui, cycle_time;
- unsigned int lpx;
-
- ui = 1000 / dsi->data_rate + 0x01;
- cycle_time = 8000 / dsi->data_rate + 0x01;
- lpx = 5;
-
- timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
- timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
- (4 * lpx);
- timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
- (NS_TO_CYCLE(0x150, cycle_time) << 16);
- timcon3 = (2 * lpx) << 16 | NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8 |
- NS_TO_CYCLE(0x40, cycle_time);
-
- writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
- writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
- writel(timcon2, dsi->regs + DSI_PHY_TIMECON2);
- writel(timcon3, dsi->regs + DSI_PHY_TIMECON3);
+ writel(phy_timing0, dsi->regs + DSI_PHY_TIMECON0);
+ writel(phy_timing1, dsi->regs + DSI_PHY_TIMECON1);
+ writel(phy_timing2, dsi->regs + DSI_PHY_TIMECON2);
+ writel(phy_timing3, dsi->regs + DSI_PHY_TIMECON3);
}
static void mtk_dsi_enable(struct mtk_dsi *dsi)
@@ -202,19 +188,51 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
{
struct device *dev = dsi->dev;
int ret;
+ u64 bit_clock, total_bits;
+ u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
+ u32 phy_timing0, phy_timing1, phy_timing2, phy_timing3;
+ u32 ui, cycle_time;
if (++dsi->refcount != 1)
return 0;
+ switch (dsi->format) {
+ case MIPI_DSI_FMT_RGB565:
+ bit_per_pixel = 16;
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ bit_per_pixel = 18;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+ case MIPI_DSI_FMT_RGB888:
+ default:
+ bit_per_pixel = 24;
+ break;
+ }
+ /**
+ * data_rate = (pixel_clock) * bit_per_pixel * mipi_ratio / lane_num;
+ * vm.pixelclock is Khz, data_rata unit is Hz, so need to multiply 1000
+ * mipi_ratio is (htotal * byte_per_pixel / lane_num + Tlpx + Ths_prep
+ * + Thstrail + Ths_exit + Ths_zero) /
+ * (htotal * byte_per_pixel /lane_number)
+ */
+ bit_clock = dsi->vm.pixelclock * 1000 * bit_per_pixel;
+ htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
+ dsi->vm.hsync_len;
+ htotal_bits = htotal * bit_per_pixel;
+
/**
- * data_rate = (pixel_clock / 1000) * pixel_dipth * mipi_ratio;
- * pixel_clock unit is Khz, data_rata unit is MHz, so need divide 1000.
- * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
- * we set mipi_ratio is 1.05.
+ * overhead = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
*/
- dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
+ overhead_cycles = LPX + (HS_PRPR >> 8) + (HS_ZERO >> 16) +
+ (HS_TRAIL >> 24) + (DA_HS_EXIT >> 24);
+ overhead_bits = overhead_cycles * dsi->lanes * 8;
+ total_bits = htotal_bits + overhead_bits;
- ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 1000000);
+ dsi->data_rate = DIV_ROUND_UP_ULL(bit_clock * total_bits,
+ htotal_bits * dsi->lanes);
+
+ ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
if (ret < 0) {
dev_err(dev, "Failed to set data rate: %d\n", ret);
goto err_refcount;
@@ -236,7 +254,20 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
mtk_dsi_enable(dsi);
mtk_dsi_reset(dsi);
- dsi_phy_timconfig(dsi);
+
+ ui = 1000 / dsi->data_rate + 0x01;
+ cycle_time = 8000 / dsi->data_rate + 0x01;
+
+ phy_timing0 = LPX | HS_PRPR | HS_ZERO | HS_TRAIL;
+ phy_timing1 = TA_GO | TA_SURE | TA_GET | DA_HS_EXIT;
+ phy_timing2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
+ (NS_TO_CYCLE(0x150, cycle_time) << 16);
+ phy_timing3 = (2 * LPX) << 16 |
+ NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8 |
+ NS_TO_CYCLE(0x40, cycle_time);
+
+ dsi_phy_timconfig(dsi, phy_timing0, phy_timing1, phy_timing2,
+ phy_timing3);
return 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v1] ARM: at91/dt: add dts file for sama5d36ek CMP board
From: Wenyou Yang @ 2016-10-25 6:08 UTC (permalink / raw)
To: Nicolas Ferre, Alexandre Belloni, Russell King, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala
Cc: linux-kernel, Wenyou Yang, devicetree, linux-arm-kernel,
Wenyou Yang
The difference between sama5d36ek_cmp.dts and sama5d36ek.dts
is listed as below.
1. The USB host nodes are removed, that is, the USB host is disabled.
2. The gpio_keys node is added to wake up from the sleep.
3. The sama5d3xdm.dtsi isn't included, because the pins for LCD are
conflicted with one for gpio_keys.
As said in errata, "When the USB host ports are used in high speed
mode (EHCI), it is not possible to suspend the ports if no device is
attached on each port. This leads to increased power consumption even
if the system is in a low power mode." That is why the the USB host
isn't enabled.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
arch/arm/boot/dts/sama5d36ek_cmp.dts | 51 ++++++++
arch/arm/boot/dts/sama5d3xcm_cmp.dtsi | 166 ++++++++++++++++++++++++
arch/arm/boot/dts/sama5d3xmb_cmp.dtsi | 230 ++++++++++++++++++++++++++++++++++
3 files changed, 447 insertions(+)
create mode 100644 arch/arm/boot/dts/sama5d36ek_cmp.dts
create mode 100644 arch/arm/boot/dts/sama5d3xcm_cmp.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3xmb_cmp.dtsi
diff --git a/arch/arm/boot/dts/sama5d36ek_cmp.dts b/arch/arm/boot/dts/sama5d36ek_cmp.dts
new file mode 100644
index 0000000..fd6bcd6
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d36ek_cmp.dts
@@ -0,0 +1,51 @@
+/*
+ * sama5d36ek_cmp.dts - Device Tree file for SAMA5D36-EK CMP board
+ *
+ * Copyright (C) 2016 Atmel,
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d36.dtsi"
+#include "sama5d3xmb_cmp.dtsi"
+
+/ {
+ model = "Atmel SAMA5D36-EK";
+ compatible = "atmel,sama5d36ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ status = "okay";
+ };
+
+ ssc0: ssc@f0008000 {
+ status = "okay";
+ };
+
+ can0: can@f000c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@f0014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f0018000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@f0028000 {
+ status = "okay";
+ };
+
+ macb1: ethernet@f802c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ sound {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi b/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi
new file mode 100644
index 0000000..77638c3
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi
@@ -0,0 +1,166 @@
+/*
+ * sama5d3xcm_cmp.dtsi - Device Tree Include file for SAMA5D36 CMP CPU Module
+ *
+ * Copyright (C) 2016 Atmel,
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/ {
+ compatible = "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
+
+ chosen {
+ bootargs = "rootfstype=ubifs ubi.mtd=5 root=ubi0:rootfs";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0x20000000 0x20000000>;
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ spi0: spi@f0004000 {
+ cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
+ };
+
+ macb0: ethernet@f0028000 {
+ phy-mode = "rgmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-phy@1 {
+ reg = <0x1>;
+ interrupt-parent = <&pioB>;
+ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+ txen-skew-ps = <800>;
+ txc-skew-ps = <3000>;
+ rxdv-skew-ps = <400>;
+ rxc-skew-ps = <3000>;
+ rxd0-skew-ps = <400>;
+ rxd1-skew-ps = <400>;
+ rxd2-skew-ps = <400>;
+ rxd3-skew-ps = <400>;
+ };
+
+ ethernet-phy@7 {
+ reg = <0x7>;
+ interrupt-parent = <&pioB>;
+ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+ txen-skew-ps = <800>;
+ txc-skew-ps = <3000>;
+ rxdv-skew-ps = <400>;
+ rxc-skew-ps = <3000>;
+ rxd0-skew-ps = <400>;
+ rxd1-skew-ps = <400>;
+ rxd2-skew-ps = <400>;
+ rxd3-skew-ps = <400>;
+ };
+ };
+
+ i2c1: i2c@f0018000 {
+ pmic: act8865@5b {
+ compatible = "active-semi,act8865";
+ reg = <0x5b>;
+ status = "disabled";
+
+ regulators {
+ vcc_1v8_reg: DCDC_REG1 {
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc_1v2_reg: DCDC_REG2 {
+ regulator-name = "VCC_1V2";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ };
+
+ vcc_3v3_reg: DCDC_REG3 {
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vddana_reg: LDO_REG1 {
+ regulator-name = "VDDANA";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vddfuse_reg: LDO_REG2 {
+ regulator-name = "FUSE_2V5";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+ };
+ };
+ };
+ };
+
+ nand0: nand@60000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc;
+ atmel,pmecc-cap = <4>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv@c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb@180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ d2 {
+ label = "d2";
+ gpios = <&pioE 25 GPIO_ACTIVE_LOW>; /* PE25, conflicts with A25, RXD2 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3xmb_cmp.dtsi b/arch/arm/boot/dts/sama5d3xmb_cmp.dtsi
new file mode 100644
index 0000000..3ec78867
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3xmb_cmp.dtsi
@@ -0,0 +1,230 @@
+/*
+ * sama5d3xmb_cmp.dts - Device Tree file for SAMA5D3x CMP mother board
+ *
+ * Copyright (C) 2016 Atmel,
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3xcm_cmp.dtsi"
+
+/ {
+ compatible = "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ mmc0: mmc@f0000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_cd>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ spi0: spi@f0004000 {
+ dmas = <0>, <0>; /* Do not use DMA for spi0 */
+
+ m25p80@0 {
+ compatible = "atmel,at25df321a";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ ssc0: ssc@f0008000 {
+ atmel,clk-from-rk-pin;
+ };
+
+ /*
+ * i2c0 conflicts with ISI:
+ * disable it to allow the use of ISI
+ * can not enable audio when i2c0 disabled
+ */
+ i2c0: i2c@f0014000 {
+ wm8904: wm8904@1a {
+ compatible = "wlf,wm8904";
+ reg = <0x1a>;
+ clocks = <&pck0>;
+ clock-names = "mclk";
+ };
+ };
+
+ i2c1: i2c@f0018000 {
+ ov2640: camera@0x30 {
+ compatible = "ovti,ov2640";
+ reg = <0x30>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>;
+ resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>;
+ pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>;
+ /* use pck1 for the master clock of ov2640 */
+ clocks = <&pck1>;
+ clock-names = "xvclk";
+ assigned-clocks = <&pck1>;
+ assigned-clock-rates = <25000000>;
+
+ port {
+ ov2640_0: endpoint {
+ remote-endpoint = <&isi_0>;
+ bus-width = <8>;
+ };
+ };
+ };
+ };
+
+ usart1: serial@f0020000 {
+ dmas = <0>, <0>; /* Do not use DMA for usart1 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
+ status = "okay";
+ };
+
+ isi: isi@f0034000 {
+ port {
+ isi_0: endpoint {
+ remote-endpoint = <&ov2640_0>;
+ bus-width = <8>;
+ vsync-active = <1>;
+ hsync-active = <1>;
+ };
+ };
+ };
+
+ mmc1: mmc@f8000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ adc0: adc@f8018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_adc0_adtrg
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ >;
+ status = "okay";
+ };
+
+ macb1: ethernet@f802c000 {
+ phy-mode = "rmii";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy@1 {
+ /*interrupt-parent = <&pioE>;*/
+ /*interrupts = <30 IRQ_TYPE_EDGE_FALLING>;*/
+ reg = <1>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ board {
+ pinctrl_gpio_keys: gpio_keys {
+ atmel,pins =
+ <AT91_PIOE 27 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+ };
+
+ pinctrl_mmc0_cd: mmc0_cd {
+ atmel,pins =
+ <AT91_PIOD 17 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD17 GPIO with pullup deglitch */
+ };
+
+ pinctrl_mmc1_cd: mmc1_cd {
+ atmel,pins =
+ <AT91_PIOD 18 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD18 GPIO with pullup deglitch */
+ };
+
+ pinctrl_pck0_as_audio_mck: pck0_as_audio_mck {
+ atmel,pins =
+ <AT91_PIOD 30 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD30 periph B */
+ };
+
+ pinctrl_pck1_as_isi_mck: pck1_as_isi_mck-0 {
+ atmel,pins =
+ <AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD31 periph B ISI_MCK */
+ };
+
+ pinctrl_sensor_reset: sensor_reset-0 {
+ atmel,pins =
+ <AT91_PIOE 24 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE24 gpio */
+ };
+
+ pinctrl_sensor_power: sensor_power-0 {
+ atmel,pins =
+ <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE29 gpio */
+ };
+
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOD 29 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PD29 GPIO with deglitch */
+ };
+ };
+ };
+
+ dbgu: serial@ffffee00 {
+ dmas = <0>, <0>; /* Do not use DMA for dbgu */
+ status = "okay";
+ };
+
+ watchdog@fffffe40 {
+ status = "okay";
+ };
+ };
+
+ usb0: gadget@00500000 {
+ atmel,vbus-gpio = <&pioD 29 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "okay";
+ };
+ };
+
+ sound {
+ compatible = "atmel,asoc-wm8904";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck0_as_audio_mck>;
+
+ atmel,model = "wm8904 @ SAMA5D3EK";
+ atmel,audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN2L", "Line In Jack",
+ "IN2R", "Line In Jack",
+ "Mic", "MICBIAS",
+ "IN1L", "Mic";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8904>;
+
+ status = "disabled";
+ };
+
+ /* Conflict with LCD pins */
+ gpio_keys {
+ compatible = "gpio-keys";
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ pb_user1 {
+ label = "pb_user1";
+ gpios = <&pioE 27 GPIO_ACTIVE_HIGH>;
+ linux,code = <0x100>;
+ gpio-key,wakeup;
+ };
+ };
+};
--
2.7.4
^ permalink raw reply related
* Re: [PATCH V1] mfd: pv88080: Expand driver for GPIO function support.
From: Lee Jones @ 2016-10-25 6:40 UTC (permalink / raw)
To: Eric Jeong
Cc: Alexandre Courbot, DEVICETREE, LINUX-GPIO, LINUX-KERNEL,
Liam Girdwood, Linus Walleij, Mark Brown, Mark Rutland,
Rob Herring, Support Opensource
In-Reply-To: <20161025014148.7DF655FA17@krsrvapps-01.diasemi.com>
On Tue, 25 Oct 2016, Eric Jeong wrote:
>
> From: Eric Jeong <eric.jeong.opensource@diasemi.com>
>
> This patch adds support for the PV88080 PMIC.
>
> This pathch is done as part of the existing PV88080 regulator driver
> by expanding the driver for GPIO function support.
>
> The MFD core driver provides communication through the I2C interface.
> and contains the following components:
>
> - Regulators
> - Configurable GPIOs
>
> Kconfig and Makefile are updated to reflect support for PV88080 PMIC.
>
> Signed-off-by: Eric Jeong <eric.jeong.opensource@diasemi.com>
>
> ---
> This patch applies against linux-next and next-20161024
>
> Hi,
>
> This change is made as a single patch. Because, to ensure that
> kernel builds and runs properly after this patch.
>
> The regulator device driver for PV88080 IC is submitted to Linux kernel.
> And now, GPIO function is required. In order to add GPIO driver,
> MFD driver is also required.
>
> Changes
> - Add MFD driver.
> - Add GPIO driver.
> - Update regulator driver to reflect the support.
> - Delete pv88080-regulator.h file.
> - Move binding document to mfd directory.
>
> Regards,
> Eric Jeong, Dialog Semiconductor Ltd.
>
>
> Documentation/devicetree/bindings/mfd/pv88080.txt | 63 +++++
> .../devicetree/bindings/regulator/pv88080.txt | 62 -----
> drivers/gpio/Kconfig | 11 +
> drivers/gpio/Makefile | 1 +
> drivers/gpio/gpio-pv88080.c | 195 ++++++++++++++
> drivers/mfd/Kconfig | 12 +
> drivers/mfd/Makefile | 2 +
> drivers/mfd/pv88080-core.c | 270 ++++++++++++++++++++
> drivers/mfd/pv88080-i2c.c | 99 +++++++
> drivers/regulator/Kconfig | 5 +-
> drivers/regulator/pv88080-regulator.c | 202 ++++++---------
> drivers/regulator/pv88080-regulator.h | 118 ---------
> include/linux/mfd/pv88080.h | 236 +++++++++++++++++
> 13 files changed, 970 insertions(+), 306 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/mfd/pv88080.txt
> delete mode 100644 Documentation/devicetree/bindings/regulator/pv88080.txt
> create mode 100644 drivers/gpio/gpio-pv88080.c
> create mode 100644 drivers/mfd/pv88080-core.c
> create mode 100644 drivers/mfd/pv88080-i2c.c
> delete mode 100644 drivers/regulator/pv88080-regulator.h
> create mode 100644 include/linux/mfd/pv88080.h
You're going to need to split this patch up as much as possible.
No one is going to want to review a 1200 line patch.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
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