* Re: Re: [PATCH v3 04/11] drm/sun4i: abstract the layer type
From: icenowy-h8G6r0blFSE @ 2017-04-05 17:14 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: devicetree, Jernej Skrabec, linux-sunxi, linux-kernel, dri-devel,
Rob Herring, Sean Paul, Maxime Ripard, linux-clk,
linux-arm-kernel
In-Reply-To: <CAGb2v66vxP0c3qMTAUCseTCbpJ6gxnKfNGNcC41jPHA_Ye4ggw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
在 2017-04-05 10:27,Chen-Yu Tsai 写道:
> On Wed, Apr 5, 2017 at 3:53 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
>>
>>
>> 在 2017年04月05日 03:28, Sean Paul 写道:
>>>
>>> On Thu, Mar 30, 2017 at 03:46:06AM +0800, Icenowy Zheng wrote:
>>>>
>>>> As we are going to add support for the Allwinner DE2 Mixer in
>>>> sun4i-drm
>>>> driver, we will finally have two types of layer.
>>>>
>>>> Abstract the layer type to void * and a ops struct, which contains
>>>> the
>>>> only function used by crtc -- get the drm_plane struct of the layer.
>>>>
>>>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>>>> ---
>>>> Refactored patch in v3.
>>>>
>>>> drivers/gpu/drm/sun4i/sun4i_crtc.c | 19 +++++++++++--------
>>>> drivers/gpu/drm/sun4i/sun4i_crtc.h | 3 ++-
>>>> drivers/gpu/drm/sun4i/sun4i_layer.c | 19 ++++++++++++++++++-
>>>> drivers/gpu/drm/sun4i/sun4i_layer.h | 2 +-
>>>> drivers/gpu/drm/sun4i/sunxi_layer.h | 17 +++++++++++++++++
>>>> 5 files changed, 49 insertions(+), 11 deletions(-)
>>>> create mode 100644 drivers/gpu/drm/sun4i/sunxi_layer.h
>>>>
>>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c
>>>> b/drivers/gpu/drm/sun4i/sun4i_crtc.c
>>>> index 3c876c3a356a..33854ee7f636 100644
>>>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
>>>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
>>>> @@ -29,6 +29,7 @@
>>>> #include "sun4i_crtc.h"
>>>> #include "sun4i_drv.h"
>>>> #include "sun4i_layer.h"
>>>> +#include "sunxi_layer.h"
>>>> #include "sun4i_tcon.h"
>>>>
>>>> static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc,
>>>> @@ -149,7 +150,7 @@ struct sun4i_crtc *sun4i_crtc_init(struct
>>>> drm_device
>>>> *drm,
>>>> scrtc->tcon = tcon;
>>>>
>>>> /* Create our layers */
>>>> - scrtc->layers = sun4i_layers_init(drm, scrtc->backend);
>>>> + scrtc->layers = (void **)sun4i_layers_init(drm, scrtc);
>>>> if (IS_ERR(scrtc->layers)) {
>>>> dev_err(drm->dev, "Couldn't create the planes\n");
>>>> return NULL;
>>>> @@ -157,14 +158,15 @@ struct sun4i_crtc *sun4i_crtc_init(struct
>>>> drm_device *drm,
>>>>
>>>> /* find primary and cursor planes for
>>>> drm_crtc_init_with_planes
>>>> */
>>>> for (i = 0; scrtc->layers[i]; i++) {
>>>> - struct sun4i_layer *layer = scrtc->layers[i];
>>>> + void *layer = scrtc->layers[i];
>>>> + struct drm_plane *plane =
>>>> scrtc->layer_ops->get_plane(layer);
>>>>
>>>> - switch (layer->plane.type) {
>>>> + switch (plane->type) {
>>>> case DRM_PLANE_TYPE_PRIMARY:
>>>> - primary = &layer->plane;
>>>> + primary = plane;
>>>> break;
>>>> case DRM_PLANE_TYPE_CURSOR:
>>>> - cursor = &layer->plane;
>>>> + cursor = plane;
>>>> break;
>>>> default:
>>>> break;
>>>> @@ -190,10 +192,11 @@ struct sun4i_crtc *sun4i_crtc_init(struct
>>>> drm_device *drm,
>>>> /* Set possible_crtcs to this crtc for overlay planes */
>>>> for (i = 0; scrtc->layers[i]; i++) {
>>>> uint32_t possible_crtcs =
>>>> BIT(drm_crtc_index(&scrtc->crtc));
>>>> - struct sun4i_layer *layer = scrtc->layers[i];
>>>> + void *layer = scrtc->layers[i];
>>>> + struct drm_plane *plane =
>>>> scrtc->layer_ops->get_plane(layer);
>>>>
>>>> - if (layer->plane.type == DRM_PLANE_TYPE_OVERLAY)
>>>> - layer->plane.possible_crtcs =
>>>> possible_crtcs;
>>>> + if (plane->type == DRM_PLANE_TYPE_OVERLAY)
>>>> + plane->possible_crtcs = possible_crtcs;
>>>> }
>>>>
>>>> return scrtc;
>>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.h
>>>> b/drivers/gpu/drm/sun4i/sun4i_crtc.h
>>>> index 230cb8f0d601..a4036ee44cf8 100644
>>>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.h
>>>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.h
>>>> @@ -19,7 +19,8 @@ struct sun4i_crtc {
>>>>
>>>> struct sun4i_backend *backend;
>>>> struct sun4i_tcon *tcon;
>>>> - struct sun4i_layer **layers;
>>>> + void **layers;
>>>> + const struct sunxi_layer_ops *layer_ops;
>>>
>>>
>>> I think you should probably take a different approach to abstract the
>>> layer
>>> type. How about creating
>>>
>>> struct sunxi_layer {
>>> struct drm_plane plane;
>>> }
>>>
>>> base and then subclassing that for sun4i and sun8i? By doing this you
>>> can
>>> avoid
>>> the nasty casting and you can also get rid of the get_plane() hook
>>> and
>>> layer_ops.
>>
>>
>> For the situation that using ** things are easily to get weird.
>
> That code could be reworked, by initializing the layers directly within
> the crtc init code. If you look at rockchip's drm driver, you'll see
> they do this. There is a good reason to do it this way, as you need
> to first create the primary and cursor layers, pass them in when you
> create the crtc, then initialize any additional layers with the
> possible_crtcs bitmap.
I feel that it's still more proper to offload plane creation code
to *_layers_init function, as:
1. We cannot assume the cursor layer's
existance. In fact currently no code in sun4i-drm (including this
patchset) create a cursor layer.
2. The format of planes heavily depend on the engine type (
sun4i-backend or sun8i-mixer).
3. We should create planes according to the type of engine.
Currently the *_layers_init function is part of engine code (See my
Makefile change).
4. If we do so we will have two codes for plane creating -- one for
primary in sun4i_crtc_init, another for overlays in *_layers_init.
>
> In our driver we are currently initializing all layers, then going
> back and filling in possible_crtcs for the extra layers.
>
> And as Maxime and I mentioned in the other thread, we don't really
> need to keep a reference to **layers.
It's correct, layers doesn't need to be kept.
And the struct sunxi_layer refactor also makes sense.
>
> Regards
> ChenYu
>
>>
>>>
>>> Sean
>>>
>>>
>>>
>>>> };
>>>>
>>>> static inline struct sun4i_crtc *drm_crtc_to_sun4i_crtc(struct
>>>> drm_crtc
>>>> *crtc)
>>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c
>>>> b/drivers/gpu/drm/sun4i/sun4i_layer.c
>>>> index f26bde5b9117..bc4a70d6968b 100644
>>>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
>>>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
>>>> @@ -16,7 +16,9 @@
>>>> #include <drm/drmP.h>
>>>>
>>>> #include "sun4i_backend.h"
>>>> +#include "sun4i_crtc.h"
>>>> #include "sun4i_layer.h"
>>>> +#include "sunxi_layer.h"
>>>>
>>>> struct sun4i_plane_desc {
>>>> enum drm_plane_type type;
>>>> @@ -100,6 +102,17 @@ static const struct sun4i_plane_desc
>>>> sun4i_backend_planes[] = {
>>>> },
>>>> };
>>>>
>>>> +static struct drm_plane *sun4i_layer_get_plane(void *layer)
>>>> +{
>>>> + struct sun4i_layer *sun4i_layer = layer;
>>>> +
>>>> + return &sun4i_layer->plane;
>>>> +}
>>>> +
>>>> +static const struct sunxi_layer_ops layer_ops = {
>>>> + .get_plane = sun4i_layer_get_plane,
>>>> +};
>>>> +
>>>> static struct sun4i_layer *sun4i_layer_init_one(struct drm_device
>>>> *drm,
>>>> struct sun4i_backend
>>>> *backend,
>>>> const struct
>>>> sun4i_plane_desc *plane)
>>>> @@ -129,9 +142,10 @@ static struct sun4i_layer
>>>> *sun4i_layer_init_one(struct drm_device *drm,
>>>> }
>>>>
>>>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
>>>> - struct sun4i_backend
>>>> *backend)
>>>> + struct sun4i_crtc *crtc)
>>>> {
>>>> struct sun4i_layer **layers;
>>>> + struct sun4i_backend *backend = crtc->backend;
>>>> int i;
>>>>
>>>> layers = devm_kcalloc(drm->dev,
>>>> ARRAY_SIZE(sun4i_backend_planes)
>>>> + 1,
>>>> @@ -181,5 +195,8 @@ struct sun4i_layer **sun4i_layers_init(struct
>>>> drm_device *drm,
>>>> layers[i] = layer;
>>>> };
>>>>
>>>> + /* Assign layer ops to the CRTC */
>>>> + crtc->layer_ops = &layer_ops;
>>>> +
>>>> return layers;
>>>> }
>>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h
>>>> b/drivers/gpu/drm/sun4i/sun4i_layer.h
>>>> index 4be1f0919df2..425eea7b9e3b 100644
>>>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.h
>>>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.h
>>>> @@ -27,6 +27,6 @@ plane_to_sun4i_layer(struct drm_plane *plane)
>>>> }
>>>>
>>>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
>>>> - struct sun4i_backend
>>>> *backend);
>>>> + struct sun4i_crtc *crtc);
>>>>
>>>> #endif /* _SUN4I_LAYER_H_ */
>>>> diff --git a/drivers/gpu/drm/sun4i/sunxi_layer.h
>>>> b/drivers/gpu/drm/sun4i/sunxi_layer.h
>>>> new file mode 100644
>>>> index 000000000000..d8838ec39299
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/sun4i/sunxi_layer.h
>>>> @@ -0,0 +1,17 @@
>>>> +/*
>>>> + * Copyright (C) 2017 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or
>>>> + * modify it under the terms of the GNU General Public License as
>>>> + * published by the Free Software Foundation; either version 2 of
>>>> + * the License, or (at your option) any later version.
>>>> + */
>>>> +
>>>> +#ifndef _SUNXI_LAYER_H_
>>>> +#define _SUNXI_LAYER_H_
>>>> +
>>>> +struct sunxi_layer_ops {
>>>> + struct drm_plane *(*get_plane)(void *layer);
>>>> +};
>>>> +
>>>> +#endif /* _SUNXI_LAYER_H_ */
>>>> --
>>>> 2.12.0
>>>>
>>>>
>>>> _______________________________________________
>>>> linux-arm-kernel mailing list
>>>> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>
>>>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups
>> "linux-sunxi" group.
>> To unsubscribe from this group and stop receiving emails from it, send
>> an
>> email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
>> For more options, visit https://groups.google.com/d/optout.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [RFC] [media] imx: assume MEDIA_ENT_F_ATV_DECODER entities output video on pad 1
From: Devin Heitmueller @ 2017-04-05 17:02 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Philipp Zabel, Russell King - ARM Linux, Mauro Carvalho Chehab,
Steve Longerbeam, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, fabio.estevam-3arQi8VN3Tc,
Hans Verkuil, nick-gcszYUEDH4VrovVCs/uTlw,
markus.heiser-m1Uo1GnMJf0b1SvskN2V4Q,
laurent.pinchart+renesas-ryLnwIuWjnjg/C1BVhZhaw,
bparrot-l0cyMroinI0, geert-Td1EMuHUCqxL1ZNQvxDV9g, Arnd Bergmann,
sudipm.mukherjee-Re5JQEeQqe8AvxtiuMwx3w,
minghsiu.tsai-NuS5LvNUpcJWk0Htik3J/w,
tiffany.lin-NuS5LvNUpcJWk0Htik3J/w,
jean-christophe.trotin-qxv4g6HH51o,
horms+renesas-/R6kz+dDXgpPR4JQBCEnsQ,
niklas.soderlund+renesas-1zkq55x86MTxsAP9Fp7wbw,
robert.jarzmik-GANU6spQydw, songjun.wu-UWL1GkI3JZL3oGB3hsPCZA,
andrew-ct.chen-NuS5LvNUpcJWk0Htik3J/w, Greg Kroah-Hartman
In-Reply-To: <20170405131725.22c13a1d-ch4gOOMV7nf/PtFMR13I2A@public.gmane.org>
>> For what it's worth, I doubt most of the em28xx designs have the
>> tvp5150 interrupt request line connected in any way.
>
> True. But, on embedded hardware, such line may be connected into the
> SoC. Actually, from the IGEPv3 expansion diagram:
>
> https://www.isee.biz/support/downloads/item/igepv2-expansion-rc-schematics
>
> The INT line is connected to CAM_IRQ. That's connected to GPIO_154 pin
> at OMAP3.
>
> So, on a first glance, it seems possible to use it, instead of polling.
To be clear, I wasn't suggesting that the IRQ request line on the
tvp5150 couldn't be supported in general (for example, for those
embedded targets which have it wired up to a host processor). I'm
just saying you shouldn't expect it to work on most (perhaps all)
em28xx designs which have the tvp5150. In fact on some em28xx designs
the pin is used as a GPIO output tied to a mux to control input
selection. Hence blindly enabling the interrupt request line by
default would do all sorts of bad things.
>> You would likely
>> have to poll the FIFO status register via I2C,
>
> Yes, I considered this option when I wrote the driver. It could work,
> although it would likely have some performance drawback, as the driver
> would need to poll it at least 60 times per second.
>
>> or use the feature to
>> embed the sliced data into as VANC data in the 656 output (as
>> described in sec 3.9 of the tvp5150am1 spec).
>
> True, but the bridge driver would need to handle such data.
Correct.
> I remember I looked on this when I wrote the driver, but I was
> unable to find a way for em28xx to parse (or forward) such
> data packets.
I'm pretty sure it's possible, but I haven't looked at the datasheets
in a number of years and don't recall the details.
Hardware VBI splicing is supported by a number of decoders but it's
rarely used on commodity PCs (the Conexant and NXP decoders support it
as well). That said, I won't argue there might be some value on
really low end platforms. All I would ask is that if you do introduce
any such functionality into the tvp5150 driver for some embedded
application that you please not break support for devices such as the
em28xx.
Thanks,
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
--
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 v6 01/23] PCI: endpoint: Add EP core layer to enable EP controller and EP functions
From: Bjorn Helgaas @ 2017-04-05 16:52 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: devicetree, Joao Pinto, linux-doc, linux-pci, nsekhar,
linux-kernel, hch, Bjorn Helgaas, linux-omap, linux-arm-kernel
In-Reply-To: <20170405085243.18123-2-kishon@ti.com>
On Wed, Apr 05, 2017 at 02:22:21PM +0530, Kishon Vijay Abraham I wrote:
> Introduce a new EP core layer in order to support endpoint functions in
> linux kernel. This comprises the EPC library (Endpoint Controller Library)
> and EPF library (Endpoint Function Library). EPC library implements
> functions specific to an endpoint controller and EPF library implements
> functions specific to an endpoint function.
> ...
> +/**
> + * pci_epf_linkup() - Notify the function driver that EPC device has
> + * established a connection with the Root Complex.
> + * @epf: the EPF device bound to the EPC device which has established
> + * the connection with the host
> + *
> + * Invoke to notify the function driver that EPC device has established
> + * a connection with the Root Complex.
> + */
> +void pci_epf_linkup(struct pci_epf *epf)
> +{
> + if (!epf->driver)
> + dev_WARN(&epf->dev, "epf device not bound to driver\n");
> +
> + epf->driver->ops->linkup(epf);
I don't understand what's going on here. We warn if epf->driver is
NULL, but the next thing we do is dereference it.
For NULL pointers that are symptoms of Linux defects, I usually prefer
not to check at all so that a dereference generates an oops and we can
debug the problem. For NULL pointers caused by user error, we would
generally return an error that percolates up to the user.
I haven't competely wrapped my head around this endpoint support, but
I assume a NULL pointer here would be caused by user error, not
necessarily a Linux defect. So why would we dereference a NULL
pointer? And what happens when we do? Is this just going to oops an
embedded Linux running inside the endpoint? Is that the correct
behavior?
Bjorn
^ permalink raw reply
* Re: [PATCH 4/4] iio: dac: stm32: add support for waveform generator
From: Fabrice Gasnier @ 2017-04-05 16:46 UTC (permalink / raw)
To: Jonathan Cameron, linux, robh+dt, linux-arm-kernel, devicetree,
linux-kernel
Cc: mark.rutland, benjamin.gaignard, lars, alexandre.torgue,
Hennerich, Michael, linux-iio, pmeerw, amelie.delaunay,
mcoquelin.stm32, knaack.h, linus.walleij, benjamin.gaignard
In-Reply-To: <e6a02296-fa72-50e8-d5e8-25bb5d496085@kernel.org>
JonathanOn 04/02/2017 02:19 PM, Jonathan Cameron wrote:
> On 31/03/17 12:45, Fabrice Gasnier wrote:
>> STM32 DAC has built-in noise or triangle waveform generator.
>> Waveform generator requires trigger to be configured.
>> - "wave" extended attribute selects noise or triangle.
>> - "mamp" extended attribute selects either LFSR (linear feedback
>> shift register) mask for noise waveform, OR triangle amplitude.
>>
>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>
> Looks like AN3126 is the relevant doc.
> (a quick note from this relevant to earlier patches- doc says
> 1-3 channels - perhaps build that from the start with that
> possibility in mind).
Hi Jonathan,
Just to clarify this, some products like STM32F334xx have 3 channels,
yes. Several STM32 DAC IPs (& so registers) are instantiated: DAC1 have
two outputs (dac1_out1 & dac1_out2), DAC2 have one output (e.g.
dac2_out1). Driver can be instantiated several times. Is it ok ?
>
> As you probably know, this wanders into a large chunk of 'poorly'
> defined ABI within IIO as it stands.
>
> Note there are a number of waveform generators still in staging.
> Not a lot of movement on getting them out of staging unfortunately
> (so far!)
>
> However, let us keep those drivers in mind as we work on ABI and
> I definitely want some input from someone at Analog.
> Lars, who is best for this? I see at least some of these were
> originally Michael's work.
>
> They do have partial docs under
> drivers/staging/iio/Documentation/sysfs-bus-iio-dds
> I'll highlight thoughts from there as I look through this...
Thanks for pointing this out.
>
>
>> ---
>> Documentation/ABI/testing/sysfs-bus-iio-dac-stm32 | 32 ++++++
>> drivers/iio/dac/stm32-dac.c | 124 ++++++++++++++++++++++
>> 2 files changed, 156 insertions(+)
>> create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
>>
>> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
>> new file mode 100644
>> index 0000000..c2432e1
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
>> @@ -0,0 +1,32 @@
>> +What: /sys/bus/iio/devices/iio:deviceX/wave
>> +What: /sys/bus/iio/devices/iio:deviceX/wave_available
> Needs to be channel associated. Whilst in your case you have basically
> a pair of single channel devices, in more general case, it's not usual
> to have multiple parallel waveform generators clocked together.
>
> Old ABI is:
> What: /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype etc
>
I'll rework this in V2.
>
>> +KernelVersion: 4.12
>> +Contact: fabrice.gasnier@st.com
>> +Description:
>> + List and/or select waveform generation provided by STM32 DAC:
>> + - "none": (default) means normal DAC operations
> none kind of hints at nothing coming out. Perhaps 'flat' would be closer?
> i.e. only changes when someone tells it to.
>
>> + - "noise": select noise waveform
>> + - "triangle": select triangle waveform
>> + Note: when waveform generator is used, writing _raw sysfs entry
>> + adds a DC offset to generated waveform. Reading it reports
>> + current output value.
> Interesting. This gets fiddly but one option would be to describe the whole
> device as a dds.
>
> Then we have flat type above, combined with an _offset.
I'll update from 'none' to 'flat' in V2, and use _offset.
>
>> +
>> +What: /sys/bus/iio/devices/iio:deviceX/mamp
>> +What: /sys/bus/iio/devices/iio:deviceX/mamp_available
>> +KernelVersion: 4.12
>> +Contact: fabrice.gasnier@st.com
>> +Description:
>> + List and select mask/amplitude used for noise/triangle waveform
>> + generator, which are:
>> + - "0": unmask bit 0 of LFSR / triangle amplitude equal to 1
>> + - "1": unmask bit [1:0] of LFSR / triangle amplitude equal to 3
>> + - "2": unmask bit [2:0] of LFSR / triangle amplitude equal to 7
>> + - "3": unmask bit [3:0] of LFSR / triangle amplitude equal to 15
>> + - "4": unmask bit [4:0] of LFSR / triangle amplitude equal to 31
>> + - "5": unmask bit [5:0] of LFSR / triangle amplitude equal to 63
>> + - "6": unmask bit [6:0] of LFSR / triangle amplitude equal to 127
>> + - "7": unmask bit [7:0] of LFSR / triangle amplitude equal to 255
>> + - "8": unmask bit [8:0] of LFSR / triangle amplitude equal to 511
>> + - "9": unmask bit [9:0] of LFSR / triangle amplitude equal to 1023
>> + - "10": unmask bit [10:0] of LFSR / triangle amplitude equal to 2047
>> + - "11": unmask bit [11:0] of LFSR / triangle amplitude equal to 4095
> I don't fully understand what is going on here - so I'm guessing somewhat.
Sorry for this, this is basically amplitude.
I think best is to rename above to something like 'amplitude' and
'amplitude_available'.
I'll rework this in V2.
>
>
> Let us try describing these generically. If we define standard 'forms' of each
> waveform type. Say a 0 to 1 V peak to peak, then we could use _scale to control
> this nicely.
>
>> diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c
>> index 62e43e9..d7dda78 100644
>> --- a/drivers/iio/dac/stm32-dac.c
>> +++ b/drivers/iio/dac/stm32-dac.c
>> @@ -41,10 +41,14 @@
>> /**
>> * struct stm32_dac - private data of DAC driver
>> * @common: reference to DAC common data
>> + * @wave: waveform generator
>> + * @mamp: waveform mask/amplitude
>> * @swtrig: Using software trigger
>> */
>> struct stm32_dac {
>> struct stm32_dac_common *common;
>> + u32 wave;
>> + u32 mamp;
>> bool swtrig;
>> };
>>
>> @@ -157,6 +161,24 @@ static int stm32_dac_is_enabled(struct stm32_dac *dac, int channel)
>> return !!en;
>> }
>>
>> +static int stm32_dac_wavegen(struct stm32_dac *dac, int channel)
>> +{
>> + struct regmap *regmap = dac->common->regmap;
>> + u32 mask, val;
>> +
>> + if (channel == STM32_DAC_CHANNEL_1) {
>> + val = FIELD_PREP(STM32_DAC_CR_WAVE1, dac->wave) |
>> + FIELD_PREP(STM32_DAC_CR_MAMP1, dac->mamp);
>> + mask = STM32_DAC_CR_WAVE1 | STM32_DAC_CR_MAMP1;
>> + } else {
>> + val = FIELD_PREP(STM32_DAC_CR_WAVE2, dac->wave) |
>> + FIELD_PREP(STM32_DAC_CR_MAMP2, dac->mamp);
>> + mask = STM32_DAC_CR_WAVE2 | STM32_DAC_CR_MAMP2;
>> + }
>> +
>> + return regmap_update_bits(regmap, STM32_DAC_CR, mask, val);
>> +}
>> +
>> static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
>> {
>> struct stm32_dac *dac = iio_priv(indio_dev);
>> @@ -164,6 +186,17 @@ static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
>> STM32_DAC_CR_EN1 : STM32_DAC_CR_EN2;
>> int ret;
>>
>> + if (dac->wave && !indio_dev->trig) {
>> + dev_err(&indio_dev->dev, "Wavegen requires a trigger\n");
>> + return -EINVAL;
>> + }
>> +
>> + ret = stm32_dac_wavegen(dac, channel);
>> + if (ret < 0) {
>> + dev_err(&indio_dev->dev, "Wavegen setup failed\n");
>> + return ret;
>> + }
>> +
>> ret = stm32_dac_set_trig(dac, indio_dev->trig, channel);
>> if (ret < 0) {
>> dev_err(&indio_dev->dev, "Trigger setup failed\n");
>> @@ -291,6 +324,96 @@ static int stm32_dac_debugfs_reg_access(struct iio_dev *indio_dev,
>> .driver_module = THIS_MODULE,
>> };
>>
>> +/* waveform generator wave selection */
>> +static const char * const stm32_dac_wave_desc[] = {
>> + "none",
>> + "noise",
>> + "triangle",
>> +};
>> +
>> +static int stm32_dac_set_wave(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan,
>> + unsigned int type)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + if (stm32_dac_is_enabled(dac, chan->channel))
>> + return -EBUSY;
>> + dac->wave = type;
>> +
>> + return 0;
>> +}
>> +
>> +static int stm32_dac_get_wave(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + return dac->wave;
>> +}
>> +
>> +static const struct iio_enum stm32_dac_wave_enum = {
>> + .items = stm32_dac_wave_desc,
>> + .num_items = ARRAY_SIZE(stm32_dac_wave_desc),
>> + .get = stm32_dac_get_wave,
>> + .set = stm32_dac_set_wave,
>> +};
>> +
>> +/*
>> + * waveform generator mask/amplitude selection:
>> + * - noise: LFSR mask (linear feedback shift register, umasks bit 0, [1:0]...)
>> + * - triangle: amplitude (equal to 1, 3, 5, 7... 4095)
>> + */
>> +static const char * const stm32_dac_mamp_desc[] = {
>> + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
>> +};
>> +
>> +static int stm32_dac_set_mamp(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan,
>> + unsigned int type)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + if (stm32_dac_is_enabled(dac, chan->channel))
>> + return -EBUSY;
>> + dac->mamp = type;
>> +
>> + return 0;
>> +}
>> +
>> +static int stm32_dac_get_mamp(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + return dac->mamp;
>> +}
>> +
>> +static const struct iio_enum stm32_dac_mamp_enum = {
>> + .items = stm32_dac_mamp_desc,
>> + .num_items = ARRAY_SIZE(stm32_dac_mamp_desc),
>> + .get = stm32_dac_get_mamp,
>> + .set = stm32_dac_set_mamp,
>> +};
>> +
>> +static const struct iio_chan_spec_ext_info stm32_dac_ext_info[] = {
>> + IIO_ENUM("wave", IIO_SHARED_BY_ALL, &stm32_dac_wave_enum),
>> + {
>> + .name = "wave_available",
>> + .shared = IIO_SHARED_BY_ALL,
>> + .read = iio_enum_available_read,
>> + .private = (uintptr_t)&stm32_dac_wave_enum,
>> + },
>> + IIO_ENUM("mamp", IIO_SHARED_BY_ALL, &stm32_dac_mamp_enum),
>> + {
>> + .name = "mamp_available",
>> + .shared = IIO_SHARED_BY_ALL,
>> + .read = iio_enum_available_read,
>> + .private = (uintptr_t)&stm32_dac_mamp_enum,
>> + },
>> + {},
>> +};
>> +
>> #define STM32_DAC_CHANNEL(chan, name) { \
>> .type = IIO_VOLTAGE, \
>> .indexed = 1, \
>> @@ -306,6 +429,7 @@ static int stm32_dac_debugfs_reg_access(struct iio_dev *indio_dev,
>> .storagebits = 16, \
>> }, \
>> .datasheet_name = name, \
>> + .ext_info = stm32_dac_ext_info \
>> }
>>
>> static const struct iio_chan_spec stm32_dac_channels[] = {
>>
>
^ permalink raw reply
* Re: [PATCH 3/4] iio: dac: stm32: add support for trigger events
From: Fabrice Gasnier @ 2017-04-05 16:44 UTC (permalink / raw)
To: Jonathan Cameron, linux, robh+dt, linux-arm-kernel, devicetree,
linux-kernel
Cc: mark.rutland, benjamin.gaignard, lars, alexandre.torgue,
linux-iio, pmeerw, amelie.delaunay, mcoquelin.stm32, knaack.h,
linus.walleij, benjamin.gaignard
In-Reply-To: <7dba5b17-5f82-e68d-3c06-afe4a4e478e7@kernel.org>
On 04/02/2017 02:21 PM, Jonathan Cameron wrote:
> On 02/04/17 12:45, Jonathan Cameron wrote:
>> On 31/03/17 12:45, Fabrice Gasnier wrote:
>>> STM32 DAC supports triggers to synchronize conversions. When trigger
>>> occurs, data is transferred from DHR (data holding register) to DOR
>>> (data output register) so output voltage is updated.
>>> Both hardware and software triggers are supported.
>>>
>>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>> Hmm. This is a somewhat different use of triggered event from normal...
>>
Waveform generator in STM32 DAC requires a trigger to increment /
decrement internal counter in case of triangle generator. Noise
generator is a bit different, but same trigger usage applies. I agree
this is unusual.
Is it acceptable to use event trigger for this use ?
>> What you have here is rather closer to the output buffers stuff that Analog
>> have in their tree which hasn't made it upstream yet.
>> To that end I'll want Lars to have a look at this... I've completely
>> lost track of where they are with this.
>> Perhaps Lars can give us a quick update?
>>
>> If that was in place (or what I have in my head was true anyway),
>> it would look like the reverse of the triggered buffer input devices.
>> You'd be able to write to a software buffer and it would clock them
>> out as the trigger fires (here I think it would have to keep updating
>> the DHR whenever the trigger occurs).
Hmm.. for waveform generator mode, there is no need for data buffer. DAC
generate samples itself, using trigger. But, i agree it would be nice
for playing data samples (write DHR registers, or dma), yes.
>>
>> Even if it's not there, we aren't necessarily looking at terribly big job
>> to implement it in the core and that would make this handling a lot more
>> 'standard' and consistent.
>
> Having tracked down some limited docs (AN3126 - Audio and waveform
> generation using the DAC in STM32 microcontrollers) the fact this
> can also be driven by DMA definitely argues in favour of working with
> Analog on getting the output buffers support upstream.
>
> *crosses fingers people have the time!*
Hopefully this can happen.
For the time being, I'll propose a similar patch in V2. I found out this
patch is missing a clear path to (re-)assign trigger, once set by
userland. Also, driver never gets informed in case trigger gets changed
or removed, without re-enabling it:
e.g. like echo "" > trigger/current_trigger
I'll propose a small change. Hope you agree with this approach.
Thanks,
Fabrice
>>
>> Jonathan
>>
>>> ---
>>> drivers/iio/dac/Kconfig | 3 +
>>> drivers/iio/dac/stm32-dac-core.h | 12 ++++
>>> drivers/iio/dac/stm32-dac.c | 124 ++++++++++++++++++++++++++++++++++++++-
>>> 3 files changed, 136 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
>>> index 7198648..786c38b 100644
>>> --- a/drivers/iio/dac/Kconfig
>>> +++ b/drivers/iio/dac/Kconfig
>>> @@ -278,6 +278,9 @@ config STM32_DAC
>>> tristate "STMicroelectronics STM32 DAC"
>>> depends on (ARCH_STM32 && OF) || COMPILE_TEST
>>> depends on REGULATOR
>>> + select IIO_TRIGGERED_EVENT
>>> + select IIO_STM32_TIMER_TRIGGER
>>> + select MFD_STM32_TIMERS
>>> select STM32_DAC_CORE
>>> help
>>> Say yes here to build support for STMicroelectronics STM32 Digital
>>> diff --git a/drivers/iio/dac/stm32-dac-core.h b/drivers/iio/dac/stm32-dac-core.h
>>> index d3099f7..3bf211c 100644
>>> --- a/drivers/iio/dac/stm32-dac-core.h
>>> +++ b/drivers/iio/dac/stm32-dac-core.h
>>> @@ -26,6 +26,7 @@
>>>
>>> /* STM32 DAC registers */
>>> #define STM32_DAC_CR 0x00
>>> +#define STM32_DAC_SWTRIGR 0x04
>>> #define STM32_DAC_DHR12R1 0x08
>>> #define STM32_DAC_DHR12R2 0x14
>>> #define STM32_DAC_DOR1 0x2C
>>> @@ -33,8 +34,19 @@
>>>
>>> /* STM32_DAC_CR bit fields */
>>> #define STM32_DAC_CR_EN1 BIT(0)
>>> +#define STM32H7_DAC_CR_TEN1 BIT(1)
>>> +#define STM32H7_DAC_CR_TSEL1_SHIFT 2
>>> +#define STM32H7_DAC_CR_TSEL1 GENMASK(5, 2)
>>> +#define STM32_DAC_CR_WAVE1 GENMASK(7, 6)
>>> +#define STM32_DAC_CR_MAMP1 GENMASK(11, 8)
>>> #define STM32H7_DAC_CR_HFSEL BIT(15)
>>> #define STM32_DAC_CR_EN2 BIT(16)
>>> +#define STM32_DAC_CR_WAVE2 GENMASK(23, 22)
>>> +#define STM32_DAC_CR_MAMP2 GENMASK(27, 24)
>>> +
>>> +/* STM32_DAC_SWTRIGR bit fields */
>>> +#define STM32_DAC_SWTRIGR_SWTRIG1 BIT(0)
>>> +#define STM32_DAC_SWTRIGR_SWTRIG2 BIT(1)
>>>
>>> /**
>>> * struct stm32_dac_common - stm32 DAC driver common data (for all instances)
>>> diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c
>>> index ee9711d..62e43e9 100644
>>> --- a/drivers/iio/dac/stm32-dac.c
>>> +++ b/drivers/iio/dac/stm32-dac.c
>>> @@ -23,6 +23,10 @@
>>> #include <linux/bitfield.h>
>>> #include <linux/delay.h>
>>> #include <linux/iio/iio.h>
>>> +#include <linux/iio/timer/stm32-timer-trigger.h>
>>> +#include <linux/iio/trigger.h>
>>> +#include <linux/iio/trigger_consumer.h>
>>> +#include <linux/iio/triggered_event.h>
>>> #include <linux/kernel.h>
>>> #include <linux/module.h>
>>> #include <linux/platform_device.h>
>>> @@ -31,15 +35,112 @@
>>>
>>> #define STM32_DAC_CHANNEL_1 1
>>> #define STM32_DAC_CHANNEL_2 2
>>> +/* channel2 shift */
>>> +#define STM32_DAC_CHAN2_SHIFT 16
>>>
>>> /**
>>> * struct stm32_dac - private data of DAC driver
>>> * @common: reference to DAC common data
>>> + * @swtrig: Using software trigger
>>> */
>>> struct stm32_dac {
>>> struct stm32_dac_common *common;
>>> + bool swtrig;
>>> };
>>>
>>> +/**
>>> + * struct stm32_dac_trig_info - DAC trigger info
>>> + * @name: name of the trigger, corresponding to its source
>>> + * @tsel: trigger selection, value to be configured in DAC_CR.TSELx
>>> + */
>>> +struct stm32_dac_trig_info {
>>> + const char *name;
>>> + u32 tsel;
>>> +};
>>> +
>>> +static const struct stm32_dac_trig_info stm32h7_dac_trinfo[] = {
>>> + { "swtrig", 0 },
>>> + { TIM1_TRGO, 1 },
>>> + { TIM2_TRGO, 2 },
>>> + { TIM4_TRGO, 3 },
>>> + { TIM5_TRGO, 4 },
>>> + { TIM6_TRGO, 5 },
>>> + { TIM7_TRGO, 6 },
>>> + { TIM8_TRGO, 7 },
>>> + {},
>>> +};
>>> +
>>> +static irqreturn_t stm32_dac_trigger_handler(int irq, void *p)
>>> +{
>>> + struct iio_poll_func *pf = p;
>>> + struct iio_dev *indio_dev = pf->indio_dev;
>>> + struct stm32_dac *dac = iio_priv(indio_dev);
>>> + int channel = indio_dev->channels[0].channel;
>>> +
>>> + /* Using software trigger? Then, trigger it now */
>>> + if (dac->swtrig) {
>>> + u32 swtrig;
>>> +
>>> + if (channel == STM32_DAC_CHANNEL_1)
>>> + swtrig = STM32_DAC_SWTRIGR_SWTRIG1;
>>> + else
>>> + swtrig = STM32_DAC_SWTRIGR_SWTRIG2;
>>> + regmap_update_bits(dac->common->regmap, STM32_DAC_SWTRIGR,
>>> + swtrig, swtrig);
>>> + }
>>> +
>>> + iio_trigger_notify_done(indio_dev->trig);
>>> +
>>> + return IRQ_HANDLED;
>>> +}
>>> +
>>> +static unsigned int stm32_dac_get_trig_tsel(struct stm32_dac *dac,
>>> + struct iio_trigger *trig)
>>> +{
>>> + unsigned int i;
>>> +
>>> + /* skip 1st trigger that should be swtrig */
>>> + for (i = 1; stm32h7_dac_trinfo[i].name; i++) {
>>> + /*
>>> + * Checking both stm32 timer trigger type and trig name
>>> + * should be safe against arbitrary trigger names.
>>> + */
>>> + if (is_stm32_timer_trigger(trig) &&
>>> + !strcmp(stm32h7_dac_trinfo[i].name, trig->name)) {
>>> + return stm32h7_dac_trinfo[i].tsel;
>>> + }
>>> + }
>>> +
>>> + /* When no trigger has been found, default to software trigger */
>>> + dac->swtrig = true;
>>> +
>>> + return stm32h7_dac_trinfo[0].tsel;
>>> +}
>>> +
>>> +static int stm32_dac_set_trig(struct stm32_dac *dac, struct iio_trigger *trig,
>>> + int channel)
>>> +{
>>> + struct iio_dev *indio_dev = iio_priv_to_dev(dac);
>>> + u32 shift = channel == STM32_DAC_CHANNEL_1 ? 0 : STM32_DAC_CHAN2_SHIFT;
>>> + u32 val = 0, tsel;
>>> + u32 msk = (STM32H7_DAC_CR_TEN1 | STM32H7_DAC_CR_TSEL1) << shift;
>>> +
>>> + dac->swtrig = false;
>>> + if (trig) {
>>> + /* select & enable trigger (tsel / ten) */
>>> + tsel = stm32_dac_get_trig_tsel(dac, trig);
>>> + val = tsel << STM32H7_DAC_CR_TSEL1_SHIFT;
>>> + val = (val | STM32H7_DAC_CR_TEN1) << shift;
>>> + }
>>> +
>>> + if (trig)
>>> + dev_dbg(&indio_dev->dev, "enable trigger: %s\n", trig->name);
>>> + else
>>> + dev_dbg(&indio_dev->dev, "disable trigger\n");
>>> +
>>> + return regmap_update_bits(dac->common->regmap, STM32_DAC_CR, msk, val);
>>> +}
>>> +
>>> static int stm32_dac_is_enabled(struct stm32_dac *dac, int channel)
>>> {
>>> u32 en, val;
>>> @@ -63,9 +164,16 @@ static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
>>> STM32_DAC_CR_EN1 : STM32_DAC_CR_EN2;
>>> int ret;
>>>
>>> + ret = stm32_dac_set_trig(dac, indio_dev->trig, channel);
>>> + if (ret < 0) {
>>> + dev_err(&indio_dev->dev, "Trigger setup failed\n");
>>> + return ret;
>>> + }
>>> +
>>> ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, en, en);
>>> if (ret < 0) {
>>> dev_err(&indio_dev->dev, "Enable failed\n");
>>> + stm32_dac_set_trig(dac, NULL, channel);
>>> return ret;
>>> }
>>>
>>> @@ -88,10 +196,12 @@ static int stm32_dac_disable(struct iio_dev *indio_dev, int channel)
>>> int ret;
>>>
>>> ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, en, 0);
>>> - if (ret)
>>> + if (ret) {
>>> dev_err(&indio_dev->dev, "Disable failed\n");
>>> + return ret;
>>> + }
>>>
>>> - return ret;
>>> + return stm32_dac_set_trig(dac, NULL, channel);
>>> }
>>>
>>> static int stm32_dac_get_value(struct stm32_dac *dac, int channel, int *val)
>>> @@ -258,10 +368,17 @@ static int stm32_dac_probe(struct platform_device *pdev)
>>> if (ret < 0)
>>> return ret;
>>>
>>> - ret = iio_device_register(indio_dev);
>>> + ret = iio_triggered_event_setup(indio_dev, NULL,
>>> + stm32_dac_trigger_handler);
>>> if (ret)
>>> return ret;
>>>
>>> + ret = iio_device_register(indio_dev);
>>> + if (ret) {
>>> + iio_triggered_event_cleanup(indio_dev);
>>> + return ret;
>>> + }
>>> +
>>> return 0;
>>> }
>>>
>>> @@ -269,6 +386,7 @@ static int stm32_dac_remove(struct platform_device *pdev)
>>> {
>>> struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>>>
>>> + iio_triggered_event_cleanup(indio_dev);
>>> iio_device_unregister(indio_dev);
>>>
>>> return 0;
>>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
^ permalink raw reply
* Re: [PATCH v5 22/23] drivers/fsi: Add hub master support
From: Randy Dunlap @ 2017-04-05 16:36 UTC (permalink / raw)
To: Christopher Bostic, robh+dt, mark.rutland, linux, rostedt, mingo,
gregkh, devicetree, linux-arm-kernel
Cc: andrew, alistair, linux-kernel, joel, benh, Jeremy Kerr
In-Reply-To: <20170405020607.79939-23-cbostic@linux.vnet.ibm.com>
On 04/04/17 19:06, Christopher Bostic wrote:
> From: Chris Bostic <cbostic@linux.vnet.ibm.com>
>
> Add an engine driver to expose a "hub" FSI master - which has a set of
> control registers in the engine address space, and uses a chunk of the
> slave address space for actual FSI communication.
>
> Additional changes from Jeremy Kerr <jk@ozlabs.org>.
>
> Signed-off-by: Chris Bostic <cbostic@linux.vnet.ibm.com>
> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/fsi/Kconfig | 9 ++
> drivers/fsi/Makefile | 1 +
> drivers/fsi/fsi-master-hub.c | 327 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 337 insertions(+)
> create mode 100644 drivers/fsi/fsi-master-hub.c
>
> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
> index 0fa265c..e1156b4 100644
> --- a/drivers/fsi/Kconfig
> +++ b/drivers/fsi/Kconfig
> @@ -18,6 +18,15 @@ config FSI_MASTER_GPIO
> ---help---
> This option enables a FSI master driver using GPIO lines.
>
> +config FSI_MASTER_HUB
> + tristate "FSI hub master"
> + depends on FSI
redundant again.
> + ---help---
> + This option enables a FSI hub master driver. Hub is a type of FSI
> + master that is connected to the upstream master via a slave. Hubs
> + allow chaining of FSI links to an arbitrary depth. This allows for
> + a high target device fanout.
> +
> config FSI_SCOM
> tristate "SCOM FSI client device driver"
> depends on FSI
--
~Randy
^ permalink raw reply
* Re: [PATCH v5 21/23] drivers/fsi: Add SCOM FSI client device driver
From: Randy Dunlap @ 2017-04-05 16:35 UTC (permalink / raw)
To: Christopher Bostic, robh+dt, mark.rutland, linux, rostedt, mingo,
gregkh, devicetree, linux-arm-kernel
Cc: andrew, alistair, linux-kernel, joel, Edward A . James, benh,
Jeremy Kerr
In-Reply-To: <20170405020607.79939-22-cbostic@linux.vnet.ibm.com>
On 04/04/17 19:06, Christopher Bostic wrote:
> From: Chris Bostic <cbostic@linux.vnet.ibm.com>
>
> Create a simple SCOM engine device driver that reads and writes
> its control registers via an FSI bus.
>
> Includes changes from Edward A. James <eajames@us.ibm.com>.
>
> Signed-off-by: Chris Bostic <cbostic@linux.vnet.ibm.com>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> Signed-off-by: Edward A. James <eajames@us.ibm.com>
> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
> ---
> drivers/fsi/Kconfig | 6 ++
> drivers/fsi/Makefile | 1 +
> drivers/fsi/fsi-scom.c | 263 +++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 270 insertions(+)
> create mode 100644 drivers/fsi/fsi-scom.c
>
> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
> index 9cf8345..0fa265c 100644
> --- a/drivers/fsi/Kconfig
> +++ b/drivers/fsi/Kconfig
> @@ -18,6 +18,12 @@ config FSI_MASTER_GPIO
> ---help---
> This option enables a FSI master driver using GPIO lines.
>
> +config FSI_SCOM
> + tristate "SCOM FSI client device driver"
> + depends on FSI
depends on FSI is redundant.
> + ---help---
> + This option enables an FSI based SCOM device driver.
> +
> endif
>
--
~Randy
^ permalink raw reply
* Re: [PATCH v5 19/23] drivers/fsi: Add GPIO based FSI master
From: Randy Dunlap @ 2017-04-05 16:35 UTC (permalink / raw)
To: Christopher Bostic, robh+dt, mark.rutland, linux, rostedt, mingo,
gregkh, devicetree, linux-arm-kernel
Cc: andrew, alistair, linux-kernel, joel, Edward A . James, benh,
Jeremy Kerr
In-Reply-To: <20170405020607.79939-20-cbostic@linux.vnet.ibm.com>
On 04/04/17 19:06, Christopher Bostic wrote:
> From: Chris Bostic <cbostic@linux.vnet.ibm.com>
>
> Implement a FSI master using GPIO. Will generate FSI protocol for
> read and write commands to particular addresses. Sends master command
> and waits for and decodes a slave response.
>
> Includes changes from Edward A. James <eajames@us.ibm.com> and Jeremy
> Kerr <jk@ozlabs.org>.
>
> Signed-off-by: Edward A. James <eajames@us.ibm.com>
> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
> Signed-off-by: Chris Bostic <cbostic@linux.vnet.ibm.com>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/fsi/Kconfig | 11 +
> drivers/fsi/Makefile | 1 +
> drivers/fsi/fsi-master-gpio.c | 610 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 622 insertions(+)
> create mode 100644 drivers/fsi/fsi-master-gpio.c
>
> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
> index 04c1a0e..9cf8345 100644
> --- a/drivers/fsi/Kconfig
> +++ b/drivers/fsi/Kconfig
> @@ -9,4 +9,15 @@ config FSI
> ---help---
> FSI - the FRU Support Interface - is a simple bus for low-level
> access to POWER-based hardware.
> +
> +if FSI
> +
> +config FSI_MASTER_GPIO
> + tristate "GPIO-based FSI master"
> + depends on FSI && GPIOLIB
depends on FSI is redundant since "if FSI" does the same thing.
> + ---help---
> + This option enables a FSI master driver using GPIO lines.
> +
> +endif
> +
--
~Randy
^ permalink raw reply
* Re: [PATCH 0/2] mtd: spi-nor: add stm32 qspi driver
From: Ludovic BARRE @ 2017-04-05 16:20 UTC (permalink / raw)
To: Marek Vasut, Cyrille Pitchen, Cyrille Pitchen
Cc: Boris Brezillon, Alexandre Torgue, devicetree, Richard Weinberger,
linux-kernel, Rob Herring, linux-mtd, Brian Norris,
David Woodhouse
In-Reply-To: <e04fa293-63d4-7a7e-a998-37aab31167e5@gmail.com>
hi Cyrille, Marek
I've re-based and tested my patchset onto
"mtd: spi-nor: introduce more SPI protocols and the Dual Transfer Mode"
So I can deliver my patchset before or after Cyrille patchset
How do you wish process? what version do you want for the v3?
BR
Ludo
On 03/30/2017 12:15 PM, Marek Vasut wrote:
> On 03/30/2017 09:31 AM, Ludovic BARRE wrote:
>> hi Cyrille
>>
>> I see your patch series
>>
>> [PATCH v5 0/6] mtd: spi-nor: parse SFDP tables to setup (Q)SPI memories
>>
>> No problem, I rebase my V2 onto your patch
> I still didn't review that, so it might take a bit until it hits
> mainline. I think the stm32 stuff looks pretty OK, so we can take that
> before the SFDP stuff, no?
>
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
* Re: [RFC] [media] imx: assume MEDIA_ENT_F_ATV_DECODER entities output video on pad 1
From: Mauro Carvalho Chehab @ 2017-04-05 16:17 UTC (permalink / raw)
To: Devin Heitmueller
Cc: mark.rutland, andrew-ct.chen, minghsiu.tsai,
sakari.ailus@linux.intel.com, nick, songjun.wu, Hans Verkuil,
Steve Longerbeam, Pavel Machek, robert.jarzmik, devel,
markus.heiser, laurent.pinchart+renesas, shuah,
Russell King - ARM Linux, geert, Steve Longerbeam,
Linux Media Mailing List, devicetree, Philipp Zabel,
Arnd Bergmann, Mauro Carvalho Chehab, bparrot, robh+dt,
horms+renesas, tiffany.lin, linux-arm-kernel
In-Reply-To: <CAGoCfizXdDV_Eo1NSOAb+-wrC7F47iFQKyP8-wiJMpb-nsYArA@mail.gmail.com>
Em Wed, 5 Apr 2017 11:39:06 -0400
Devin Heitmueller <dheitmueller@kernellabs.com> escreveu:
> > Currently, the driver doesn't support (2), because, at the time
> > I wrote the driver, I didn't find a way to read the interrupts generated
> > by tvp5150 at em28xx[1], due to the lack of em28xx documentation,
> > but adding support for it shoudn't be hard. I may eventually do it
> > when I have some time to play with my ISEE hardware.
>
> For what it's worth, I doubt most of the em28xx designs have the
> tvp5150 interrupt request line connected in any way.
True. But, on embedded hardware, such line may be connected into the
SoC. Actually, from the IGEPv3 expansion diagram:
https://www.isee.biz/support/downloads/item/igepv2-expansion-rc-schematics
The INT line is connected to CAM_IRQ. That's connected to GPIO_154 pin
at OMAP3.
So, on a first glance, it seems possible to use it, instead of polling.
> You would likely
> have to poll the FIFO status register via I2C,
Yes, I considered this option when I wrote the driver. It could work,
although it would likely have some performance drawback, as the driver
would need to poll it at least 60 times per second.
> or use the feature to
> embed the sliced data into as VANC data in the 656 output (as
> described in sec 3.9 of the tvp5150am1 spec).
True, but the bridge driver would need to handle such data.
I remember I looked on this when I wrote the driver, but I was
unable to find a way for em28xx to parse (or forward) such
data packets.
Thanks,
Mauro
^ permalink raw reply
* Re: [PATCH 1/3] dt: bindings: add pmu0 regs for USB PHYs on Allwinner H3/V3s/A64
From: Chen-Yu Tsai @ 2017-04-05 16:13 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Icenowy Zheng, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
devicetree, linux-arm-kernel, linux-kernel, linux-sunxi,
Icenowy Zheng
In-Reply-To: <1524732c-b72f-61ce-8ae7-1d764f85c903-l0cyMroinI0@public.gmane.org>
On Wed, Apr 5, 2017 at 8:58 PM, Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org> wrote:
>
>
> On Wednesday 05 April 2017 06:20 PM, Icenowy Zheng wrote:
>> From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
>>
>> Allwinner H3/V3s/A64 SoCs have a special USB PHY0 that can route to two
>> controllers: one is MUSB and the other is a EHCI/OHCI pair.
>>
>> When it's routed to EHCI/OHCI pair, it will needs a "pmu0" regs to
>> tweak, like other EHCI/OHCI pairs in Allwinner SoCs.
>>
>> Add this to the binding of USB PHYs on Allwinner H3/V3s/A64.
>>
>> Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
>> Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>> Signed-off-by: Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org>
>> ---
>>
>> Kishon, could you push this to 4.11?
>
> Is this for the patch titled "phy: sun4i-usb: add support for V3s USB PHY" that
> was added during the last merge window.
Yes. In fact, as the description suggests, this also applies retroactively to
H3 and A64, which were added in the following commits:
4.9 732e35da7b4a ("dt: bindings: add bindings for Allwinner A64 usb phy")
4.5 626a630e003c ("phy-sun4i-usb: Add support for the host usb-phys found
on the H3 SoC")
Though this was missed at the time the binding was added.
ChenYu
> this patch looks simpler enough to be merged in this -rc cycle. However it
> depends on Greg KH.
>
> Thanks
> Kishon
>
>>
>> Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
>> index e42334258185..005bc22938ff 100644
>> --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
>> @@ -15,6 +15,7 @@ Required properties:
>> - reg : a list of offset + length pairs
>> - reg-names :
>> * "phy_ctrl"
>> + * "pmu0" for H3, V3s and A64
>> * "pmu1"
>> * "pmu2" for sun4i, sun6i or sun7i
>> - #phy-cells : from the generic phy bindings, must be 1
>>
^ permalink raw reply
* Re: [PATCH 1/1] ARM: dts: armada-xp-linksys-mamba: use wan instead of internet for DSA port
From: Ralph Sennhauser @ 2017-04-05 16:08 UTC (permalink / raw)
To: Andrew Lunn
Cc: Mark Rutland, devicetree, Jason Cooper, linux-kernel,
Russell King, Rob Herring, Gregory Clement, linux-arm-kernel,
Sebastian Hesselbarth
In-Reply-To: <20170405155032.GL13449@lunn.ch>
Hi Andrew,
On Wed, 5 Apr 2017 17:50:32 +0200
Andrew Lunn <andrew@lunn.ch> wrote:
> > In fact "internet" label on the case is uppercase, would this matter
> > for you for new bindings, or would you still use the lowercase
> > version?
>
> I would use lower case, just to fix with the general convention that
> interface names are lower case.
Thanks
>
> > > I would say, this is now too late. Changing an interface name will
> > > break configuration scripts. We are stuck with it.
> > >
> >
> > If it weren't for commit cb4f71c42988 that would have been obvious
> > for me as well.
>
> Yes, that was not nice. But it was also very earlier in the life of
> 38x, so it just affected a few developers with reference boards, not
> real products out in the wild, as far as i remember.
>
> Andrew
The mentioned commit bit me amongst others, see
https://lkml.org/lkml/2016/8/21/62
In fact I expect the impact to be much lower this time around, before
4.10 DSA was no contender for swconfig (out of tree switch driver as
used by OpenWrt and others). On Mamba ~200Mbit was top speed. Now they
perform roughly the same.
Thanks
Ralph
^ permalink raw reply
* Re: [PATCH v2] clk/axs10x: introduce AXS10X pll driver
From: Vlad Zakharov @ 2017-04-05 16:06 UTC (permalink / raw)
To: sboyd@codeaurora.org
Cc: mark.rutland@arm.com, linux-kernel@vger.kernel.org,
Jose.Abreu@synopsys.com, mturquette@baylibre.com,
devicetree@vger.kernel.org, linux-clk@vger.kernel.org,
linux-snps-arc@lists.infradead.org
In-Reply-To: <20170405013525.GJ18246@codeaurora.org>
Hi Stephen,
On Tue, 2017-04-04 at 18:35 -0700, Stephen Boyd wrote:
> > + .pll_table = (struct pll_of_table []){
> > + {
> > + .prate = 27000000,
>
> Can this be another clk in the framework instead of hardcoding
> the parent rate?
In fact there is another clk in the framework that represents this parent clock. But this field is needed to get
appropriate pll_cfg_table as it depends on parent clock frequency. Below in pll_cfg_get function we are searching for
the correct table comparing .parent_node field with real hardware parent clock frequency:
---------------------------------->8------------------------------------
for (i = 0; pll_table[i].prate != 0; i++)
if (pll_table[i].prate == prate)
return pll_table[i].pll_cfg_table;
---------------------------------->8------------------------------------
>
> > + .pll_cfg_table = (struct pll_cfg []){
> > + { 25200000, 1, 84, 90 },
> > + { 50000000, 1, 100, 54 },
> > + { 74250000, 1, 44, 16 },
> > + { },
> > + },
> > + },
> > + /* Used as list limiter */
> > + { },
>
> There's only ever one, so I'm confused why we're making a list.
By this patch we only add support of core arc pll and pgu pll and today they are clocked by the only parent clocks
introduced here. But other plls on axs10x may be driven by different or configurable clocks, so in such cases we will
have more than one entry in this list. And we are going to add more supported plls to this driver in the nearest future.
> > +
> > + clk = clk_register(NULL, &pll_clk->hw);
> > + if (IS_ERR(clk)) {
> > + pr_err("failed to register %s clock (%ld)\n",
> > + node->name, PTR_ERR(clk));
> > + kfree(pll_clk);
> > + return;
> > + }
> > +
> > + of_clk_add_provider(node, of_clk_src_simple_get, clk);
>
> Can you please use the clk_hw based provider and clk registration
> functions?
Sure. Could you be so kind to explain what is the difference between hw and non-hw based provider and clk registration
functions please? In which cases they are preferred?
>
> > +}
> > +
> > +CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock", of_pll_clk_setup);
>
> Does this need to be CLK_OF_DECLARE_DRIVER? I mean does the
> driver need to probe and also have this of declare happen? Is the
> PLL special and needs to be used for the timers?
It is special and is used for the timers, so we have to CLK_OF_DECLARE it. On the other hand similar pll is used to
drive PGU clock frequency and other subsystems and so we add usual probe func.
--
Best regards,
Vlad Zakharov <vzakhar@synopsys.com>
^ permalink raw reply
* Re: [PATCH v4 5/7] pinctrl: aramda-37xx: Add irqchip support
From: Gregory CLEMENT @ 2017-04-05 16:03 UTC (permalink / raw)
To: Linus Walleij
Cc: Thomas Petazzoni, Andrew Lunn, Jason Cooper, devicetree,
linux-kernel, Nadav Haklai, linux-gpio, Rob Herring,
Neta Zur Hershkovits, Victor Gu, Hua Jing, Marcin Wojtas,
Wilson Ding, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <70ffe3343c13d01737bf74e5de4898d0c0be07a0.1491405475.git-series.gregory.clement@free-electrons.com>
Argh, I sill have the typo in the title of this patch! :(
If you are going to apply it could you fix it, else it will be fixed in
the next version.
Sorry,
Gregory
On mer., avril 05 2017, Gregory CLEMENT <gregory.clement@free-electrons.com> wrote:
> The Armada 37xx SoCs can handle interrupt through GPIO. However it can
> only manage the edge ones.
>
> The way the interrupt are managed are classical so we can use the generic
> interrupt chip model.
>
> The only unusual "feature" is that many interrupts are connected to the
> parent interrupt controller. But we do not take advantage of this and use
> the chained irq with all of them.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 221 +++++++++++++++++++++-
> 1 file changed, 221 insertions(+)
>
> diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
> index 5c96f5558310..7356516e0921 100644
> --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
> +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
> @@ -13,7 +13,9 @@
> #include <linux/gpio/driver.h>
> #include <linux/mfd/syscon.h>
> #include <linux/of.h>
> +#include <linux/of_address.h>
> #include <linux/of_device.h>
> +#include <linux/of_irq.h>
> #include <linux/pinctrl/pinconf-generic.h>
> #include <linux/pinctrl/pinconf.h>
> #include <linux/pinctrl/pinctrl.h>
> @@ -30,6 +32,11 @@
> #define OUTPUT_CTL 0x20
> #define SELECTION 0x30
>
> +#define IRQ_EN 0x0
> +#define IRQ_POL 0x08
> +#define IRQ_STATUS 0x10
> +#define IRQ_WKUP 0x18
> +
> #define NB_FUNCS 2
> #define GPIO_PER_REG 32
>
> @@ -75,9 +82,12 @@ struct armada_37xx_pmx_func {
>
> struct armada_37xx_pinctrl {
> struct regmap *regmap;
> + void __iomem *base;
> const struct armada_37xx_pin_data *data;
> struct device *dev;
> struct gpio_chip gpio_chip;
> + struct irq_chip irq_chip;
> + spinlock_t irq_lock;
> struct pinctrl_desc pctl;
> struct pinctrl_dev *pctl_dev;
> struct armada_37xx_pin_group *groups;
> @@ -346,6 +356,14 @@ static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev,
> return armada_37xx_pmx_set_by_name(pctldev, name, grp);
> }
>
> +static inline void armada_37xx_irq_update_reg(unsigned int *reg,
> + struct irq_data *d)
> +{
> + int offset = irqd_to_hwirq(d);
> +
> + armada_37xx_update_reg(reg, offset);
> +}
> +
> static int armada_37xx_gpio_direction_input(struct gpio_chip *chip,
> unsigned int offset)
> {
> @@ -468,6 +486,206 @@ static const struct gpio_chip armada_37xx_gpiolib_chip = {
> .owner = THIS_MODULE,
> };
>
> +void armada_37xx_irq_ack(struct irq_data *d)
> +{
> + struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
> + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
> + u32 reg = IRQ_STATUS, mask = d->mask;
> + unsigned long flags;
> +
> + armada_37xx_irq_update_reg(®, d);
> + spin_lock_irqsave(&info->irq_lock, flags);
> + writel(mask, info->base + reg);
> + spin_unlock_irqrestore(&info->irq_lock, flags);
> +}
> +
> +void armada_37xx_irq_mask(struct irq_data *d)
> +{
> + struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
> + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
> + u32 val, reg = IRQ_EN, mask = d->mask;
> + unsigned long flags;
> +
> + armada_37xx_irq_update_reg(®, d);
> + spin_lock_irqsave(&info->irq_lock, flags);
> + val = readl(info->base + reg);
> + writel(val & ~mask, info->base + reg);
> + spin_unlock_irqrestore(&info->irq_lock, flags);
> +}
> +
> +void armada_37xx_irq_unmask(struct irq_data *d)
> +{
> + struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
> + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
> + u32 val, reg = IRQ_EN, mask = d->mask;
> + unsigned long flags;
> +
> + armada_37xx_irq_update_reg(®, d);
> + spin_lock_irqsave(&info->irq_lock, flags);
> + val = readl(info->base + reg);
> + writel(val | mask, info->base + reg);
> + spin_unlock_irqrestore(&info->irq_lock, flags);
> +}
> +
> +static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
> +{
> + struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
> + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
> + u32 val, reg = IRQ_WKUP, mask = d->mask;
> + unsigned long flags;
> +
> + armada_37xx_irq_update_reg(®, d);
> + spin_lock_irqsave(&info->irq_lock, flags);
> + val = readl(info->base + reg);
> + if (on)
> + val |= mask;
> + else
> + val &= ~mask;
> + writel(val, info->base + reg);
> + spin_unlock_irqrestore(&info->irq_lock, flags);
> +
> + return 0;
> +}
> +
> +static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
> +{
> + struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
> + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
> + u32 val, reg = IRQ_POL, mask = d->mask;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&info->irq_lock, flags);
> + armada_37xx_irq_update_reg(®, d);
> + val = readl(info->base + reg);
> + switch (type) {
> + case IRQ_TYPE_EDGE_RISING:
> + val &= ~mask;
> + break;
> + case IRQ_TYPE_EDGE_FALLING:
> + val |= mask;
> + break;
> + default:
> + spin_unlock_irqrestore(&info->irq_lock, flags);
> + return -EINVAL;
> + }
> + writel(val, info->base + reg);
> + spin_unlock_irqrestore(&info->irq_lock, flags);
> +
> + return 0;
> +}
> +
> +
> +static void armada_37xx_irq_handler(struct irq_desc *desc)
> +{
> + struct gpio_chip *gc = irq_desc_get_handler_data(desc);
> + struct irq_chip *chip = irq_desc_get_chip(desc);
> + struct armada_37xx_pinctrl *info = gpiochip_get_data(gc);
> + struct irq_domain *d = gc->irqdomain;
> + int i;
> +
> + chained_irq_enter(chip, desc);
> + for (i = 0; i <= d->revmap_size / GPIO_PER_REG; i++) {
> + u32 status;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&info->irq_lock, flags);
> + status = readl_relaxed(info->base + IRQ_STATUS + 4 * i);
> + /* Manage only the interrupt that was enabled */
> + status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
> + spin_unlock_irqrestore(&info->irq_lock, flags);
> + while (status) {
> + u32 hwirq = ffs(status) - 1;
> + u32 virq = irq_find_mapping(d, hwirq +
> + i * GPIO_PER_REG);
> +
> + generic_handle_irq(virq);
> + status &= ~BIT(hwirq);
> + }
> + }
> + chained_irq_exit(chip, desc);
> +}
> +
> +static int armada_37xx_irqchip_register(struct platform_device *pdev,
> + struct armada_37xx_pinctrl *info)
> +{
> + struct device_node *np = info->dev->of_node;
> + int nrirqs = info->data->nr_pins;
> + struct gpio_chip *gc = &info->gpio_chip;
> + struct irq_chip *irqchip = &info->irq_chip;
> + struct resource res;
> + int ret = -ENODEV, i, nr_irq_parent;
> +
> + for_each_child_of_node(info->dev->of_node, np) {
> + if (of_find_property(np, "gpio-controller", NULL)) {
> + ret = 0;
> + break;
> + }
> + };
> + if (ret)
> + return ret;
> +
> + nr_irq_parent = of_irq_count(np);
> + spin_lock_init(&info->irq_lock);
> +
> + if (!nr_irq_parent) {
> + dev_err(&pdev->dev, "Invalid or no IRQ\n");
> + return 0;
> + }
> +
> + if (of_address_to_resource(info->dev->of_node, 1, &res)) {
> + dev_err(info->dev, "cannot find IO resource\n");
> + return -ENOENT;
> + }
> +
> + info->base = devm_ioremap_resource(info->dev, &res);
> + if (IS_ERR(info->base))
> + return PTR_ERR(info->base);
> +
> + irqchip->irq_ack = armada_37xx_irq_ack;
> + irqchip->irq_mask = armada_37xx_irq_mask;
> + irqchip->irq_unmask = armada_37xx_irq_unmask;
> + irqchip->irq_set_wake = armada_37xx_irq_set_wake;
> + irqchip->irq_set_type = armada_37xx_irq_set_type;
> + irqchip->name = info->data->name;
> +
> + ret = gpiochip_irqchip_add(gc, irqchip, 0,
> + handle_edge_irq, IRQ_TYPE_NONE);
> + if (ret) {
> + dev_info(&pdev->dev, "could not add irqchip\n");
> + return ret;
> + }
> +
> + /*
> + * Many interrupts are connected to the parent interrupt
> + * controller. But we do not take advantage of this and use
> + * the chained irq with all of them.
> + */
> + for (i = 0; i < nrirqs; i++) {
> + struct irq_data *d = irq_get_irq_data(gc->irq_base + i);
> +
> + /*
> + * The mask field is a "precomputed bitmask for
> + * accessing the chip registers" which was introduced
> + * for the generic irqchip framework. As we don't use
> + * this framework, we can reuse this field for our own
> + * usage.
> + */
> + d->mask = BIT(i % GPIO_PER_REG);
> + }
> +
> + for (i = 0; i < nr_irq_parent; i++) {
> + int irq = irq_of_parse_and_map(np, i);
> +
> + if (irq < 0)
> + continue;
> +
> + gpiochip_set_chained_irqchip(gc, irqchip, irq,
> + armada_37xx_irq_handler);
> + }
> +
> + return 0;
> +}
> +
> static int armada_37xx_gpiochip_register(struct platform_device *pdev,
> struct armada_37xx_pinctrl *info)
> {
> @@ -496,6 +714,9 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
> ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
> if (ret)
> return ret;
> + ret = armada_37xx_irqchip_register(pdev, info);
> + if (ret)
> + return ret;
>
> return 0;
> }
> --
> git-series 0.9.1
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH 07/11] regulator: axp20x-regulator: add support for AXP803
From: Chen-Yu Tsai @ 2017-04-05 16:01 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Lee Jones, Rob Herring, Chen-Yu Tsai, Maxime Ripard,
Liam Girdwood, devicetree, linux-sunxi, linux-kernel,
linux-arm-kernel
In-Reply-To: <20170404180145.12897-8-icenowy-h8G6r0blFSE@public.gmane.org>
Hi,
On Wed, Apr 5, 2017 at 2:01 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
> AXP803 PMIC also have a series of regulators (DCDCs and LDOs)
> controllable via I2C/RSB bus.
>
> Add support for them.
>
> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> ---
> drivers/regulator/axp20x-regulator.c | 135 +++++++++++++++++++++++++++++++----
> include/linux/mfd/axp20x.h | 37 ++++++++++
> 2 files changed, 158 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
> index 0b9d4e3e52c7..219a731df392 100644
> --- a/drivers/regulator/axp20x-regulator.c
> +++ b/drivers/regulator/axp20x-regulator.c
> @@ -355,6 +355,81 @@ static const struct regulator_desc axp809_regulators[] = {
> AXP_DESC_SW(AXP809, SW, "sw", "swin", AXP22X_PWR_OUT_CTRL2, BIT(6)),
> };
>
> +static const struct regulator_linear_range axp803_dcdc234_ranges[] = {
> + REGULATOR_LINEAR_RANGE(500000, 0x0, 0x46, 10000),
> + REGULATOR_LINEAR_RANGE(1200000, 0x47, 0x4b, 20000),
> +};
Can you keep the ranges the datasheet uses? It makes it easier to compare.
> +
> +static const struct regulator_linear_range axp803_dcdc5_ranges[] = {
> + REGULATOR_LINEAR_RANGE(800000, 0x0, 0x20, 10000),
> + REGULATOR_LINEAR_RANGE(1140000, 0x21, 0x43, 20000),
1.14 ~ 1.84 / 0.02 = 36 steps. This would end at 0x44.
> +};
> +
> +static const struct regulator_linear_range axp803_dcdc6_ranges[] = {
> + REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000),
> + REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000),
> +};
> +
> +static const struct regulator_linear_range axp803_dldo2_ranges[] = {
> + REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000),
> + REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000),
> +};
This is the same as axp806_cldo2_ranges. To keep the variants sorted
in ascending order, you could keep this version but replace references
to axp806_cldo2_ranges with this one.
> +
> +static const struct regulator_desc axp803_regulators[] = {
> + AXP_DESC(AXP803, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
> + AXP803_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(0)),
> + AXP_DESC_RANGES(AXP803, DCDC2, "dcdc2", "vin2", axp803_dcdc234_ranges,
> + 76, AXP803_DCDC2_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
> + BIT(1)),
> + AXP_DESC_RANGES(AXP803, DCDC3, "dcdc3", "vin3", axp803_dcdc234_ranges,
> + 76, AXP803_DCDC3_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
> + BIT(2)),
> + AXP_DESC_RANGES(AXP803, DCDC4, "dcdc4", "vin4", axp803_dcdc234_ranges,
> + 76, AXP803_DCDC4_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
> + BIT(3)),
> + AXP_DESC_RANGES(AXP803, DCDC5, "dcdc5", "vin5", axp803_dcdc5_ranges,
> + 68, AXP803_DCDC5_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
> + BIT(4)),
> + AXP_DESC_RANGES(AXP803, DCDC6, "dcdc6", "vin6", axp803_dcdc6_ranges,
> + 72, AXP803_DCDC6_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
> + BIT(5)),
> + /* secondary switchable output of DCDC1 */
> + AXP_DESC_SW(AXP803, DC1SW, "dc1sw", NULL, AXP22X_PWR_OUT_CTRL2,
> + BIT(7)),
> + AXP_DESC(AXP803, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
> + AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(5)),
> + AXP_DESC(AXP803, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
> + AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(6)),
> + AXP_DESC(AXP803, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
> + AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(7)),
> + AXP_DESC(AXP803, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
> + AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(3)),
> + AXP_DESC_RANGES(AXP803, DLDO2, "dldo2", "dldoin", axp803_dldo2_ranges,
> + 32, AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2,
> + BIT(4)),
> + AXP_DESC(AXP803, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
> + AXP22X_DLDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(5)),
> + AXP_DESC(AXP803, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
> + AXP22X_DLDO4_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(6)),
dldo3 and dldo4 are controlled from AXP22X_PWR_OUT_CTRL2.
> + AXP_DESC(AXP803, ELDO1, "eldo1", "eldoin", 700, 1900, 50,
> + AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
> + AXP_DESC(AXP803, ELDO2, "eldo2", "eldoin", 700, 1900, 50,
> + AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
> + AXP_DESC(AXP803, ELDO3, "eldo3", "eldoin", 700, 1900, 50,
> + AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
> + AXP_DESC(AXP803, FLDO1, "fldo1", "fldoin", 700, 1450, 50,
> + AXP803_FLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(2)),
> + AXP_DESC(AXP803, FLDO2, "fldo2", "fldoin", 700, 1450, 50,
> + AXP803_FLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(3)),
The fields for fldo* are only four bits wide.
> + AXP_DESC_IO(AXP803, LDO_IO0, "ldo_io0", "ips", 700, 3300, 100,
> + AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
> + AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
> + AXP_DESC_IO(AXP803, LDO_IO1, "ldo_io1", "ips", 700, 3300, 100,
> + AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
> + AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
> + AXP_DESC_FIXED(AXP803, RTC_LDO, "rtc_ldo", "ips", 3000),
> +};
> +
> static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
> {
> struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> @@ -377,6 +452,13 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
> * (See include/linux/mfd/axp20x.h)
> */
> reg = AXP806_DCDC_FREQ_CTRL;
> + case AXP803_ID:
AXP803 should come before AXP806.
> + /*
> + * AXP803 also have DCDC work frequency setting register at a
> + * different position.
> + */
> + if (axp20x->variant == AXP803_ID)
> + reg = AXP803_DCDC_FREQ_CTRL;
> case AXP221_ID:
> case AXP223_ID:
> case AXP809_ID:
> @@ -474,7 +556,13 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
> mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP22X_DCDC1);
> workmode <<= id - AXP22X_DCDC1;
> break;
> + case AXP803_ID:
Same here. Also this switch block has empty lines separating each case.
> + if (id < AXP803_DCDC1 || id > AXP803_DCDC6)
> + return -EINVAL;
>
> + mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP803_DCDC1);
> + workmode <<= id - AXP803_DCDC1;
> + break;
> default:
> /* should not happen */
> WARN_ON(1);
> @@ -492,20 +580,34 @@ static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
> {
> u32 reg = 0;
>
> - /* Only AXP806 has poly-phase outputs */
> - if (axp20x->variant != AXP806_ID)
> + /*
> + * Currently in our supported AXP variants, only AXP806 and AXP803
> + * have polyphase regulators.
> + */
> + switch (axp20x->variant) {
> + case AXP806_ID:
> + regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, ®);
> +
> + switch (id) {
> + case AXP806_DCDCB:
> + return (((reg & GENMASK(7, 6)) == BIT(6)) ||
> + ((reg & GENMASK(7, 6)) == BIT(7)));
> + case AXP806_DCDCC:
> + return ((reg & GENMASK(7, 6)) == BIT(7));
> + case AXP806_DCDCE:
> + return !!(reg & BIT(5));
> + }
> + case AXP803_ID:
803 before 806.
> + regmap_read(axp20x->regmap, AXP803_POLYPHASE_CTRL, ®);
> +
> + switch (id) {
> + case AXP803_DCDC3:
> + return !!(reg & BIT(6));
> + case AXP803_DCDC6:
> + return !!(reg & BIT(7));
> + }
> + default:
> return false;
> -
> - regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, ®);
> -
> - switch (id) {
> - case AXP806_DCDCB:
> - return (((reg & GENMASK(7, 6)) == BIT(6)) ||
> - ((reg & GENMASK(7, 6)) == BIT(7)));
> - case AXP806_DCDCC:
> - return ((reg & GENMASK(7, 6)) == BIT(7));
> - case AXP806_DCDCE:
> - return !!(reg & BIT(5));
> }
>
> return false;
> @@ -548,6 +650,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
> regulators = axp809_regulators;
> nregulators = AXP809_REG_ID_MAX;
> break;
> + case AXP803_ID:
> + regulators = axp803_regulators;
> + nregulators = AXP803_REG_ID_MAX;
> + break;
Ascending order.
> default:
> dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
> axp20x->variant);
> @@ -579,7 +685,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
> * name.
> */
> if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
> - (regulators == axp809_regulators && i == AXP809_DC1SW)) {
> + (regulators == axp809_regulators && i == AXP809_DC1SW) ||
> + (regulators == axp803_regulators && i == AXP803_DC1SW)) {
803 before 809.
So, mostly ordering issues, and a few minor errors.
Regards
ChenYu
> new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
> GFP_KERNEL);
> *new_desc = regulators[i];
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index b3220ef374d3..858d5b1b43b9 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -119,6 +119,17 @@ enum axp20x_variants {
> #define AXP806_BUS_ADDR_EXT 0xfe
> #define AXP806_REG_ADDR_EXT 0xff
>
> +#define AXP803_POLYPHASE_CTRL 0x14
> +#define AXP803_FLDO1_V_OUT 0x1c
> +#define AXP803_FLDO2_V_OUT 0x1d
> +#define AXP803_DCDC1_V_OUT 0x20
> +#define AXP803_DCDC2_V_OUT 0x21
> +#define AXP803_DCDC3_V_OUT 0x22
> +#define AXP803_DCDC4_V_OUT 0x23
> +#define AXP803_DCDC5_V_OUT 0x24
> +#define AXP803_DCDC6_V_OUT 0x25
> +#define AXP803_DCDC_FREQ_CTRL 0x3b
> +
> /* Interrupt */
> #define AXP152_IRQ1_EN 0x40
> #define AXP152_IRQ2_EN 0x41
> @@ -350,6 +361,32 @@ enum {
> AXP809_REG_ID_MAX,
> };
>
> +enum {
> + AXP803_DCDC1 = 0,
> + AXP803_DCDC2,
> + AXP803_DCDC3,
> + AXP803_DCDC4,
> + AXP803_DCDC5,
> + AXP803_DCDC6,
> + AXP803_DC1SW,
> + AXP803_ALDO1,
> + AXP803_ALDO2,
> + AXP803_ALDO3,
> + AXP803_DLDO1,
> + AXP803_DLDO2,
> + AXP803_DLDO3,
> + AXP803_DLDO4,
> + AXP803_ELDO1,
> + AXP803_ELDO2,
> + AXP803_ELDO3,
> + AXP803_FLDO1,
> + AXP803_FLDO2,
> + AXP803_RTC_LDO,
> + AXP803_LDO_IO0,
> + AXP803_LDO_IO1,
> + AXP803_REG_ID_MAX,
> +};
> +
> /* IRQs */
> enum {
> AXP152_IRQ_LDO0IN_CONNECT = 1,
> --
> 2.12.2
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
> For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: Document the STM32 QSPI bindings
From: Ludovic BARRE @ 2017-04-05 16:00 UTC (permalink / raw)
To: Rob Herring
Cc: Cyrille Pitchen, Marek Vasut, David Woodhouse, Brian Norris,
Boris Brezillon, Richard Weinberger, Alexandre Torgue,
linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org
In-Reply-To: <CAL_JsqK5mZojW1fVRrg=TfO3sXd7Eqa6gS9NS9aDjXwn4_26_w@mail.gmail.com>
On 04/04/2017 02:20 PM, Rob Herring wrote:
> On Tue, Apr 4, 2017 at 2:28 AM, Ludovic BARRE <ludovic.barre@st.com> wrote:
>> Hi Rob
>>
>> thanks for review
>> my comments below
>>
>> br
>> Ludo
>>
>> On 04/03/2017 06:57 PM, Rob Herring wrote:
>>> On Fri, Mar 31, 2017 at 07:02:03PM +0200, Ludovic Barre wrote:
>>>> From: Ludovic Barre <ludovic.barre@st.com>
>>>>
>>>> This patch adds documentation of device tree bindings for the STM32
>>>> QSPI controller.
>>>>
>>>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>>>> ---
>>>> .../devicetree/bindings/mtd/stm32-quadspi.txt | 45
>>>> ++++++++++++++++++++++
>>>> 1 file changed, 45 insertions(+)
>>>> create mode 100644
>>>> Documentation/devicetree/bindings/mtd/stm32-quadspi.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mtd/stm32-quadspi.txt
>>>> b/Documentation/devicetree/bindings/mtd/stm32-quadspi.txt
>>>> new file mode 100644
>>>> index 0000000..95a8ebd
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mtd/stm32-quadspi.txt
>>>> @@ -0,0 +1,45 @@
>>>> +* STMicroelectronics Quad Serial Peripheral Interface(QuadSPI)
>>>> +
>>>> +Required properties:
>>>> +- compatible: should be "st,stm32f469-qspi"
>>>> +- reg: contains the register location and length.
>>>> + (optional) the memory mapping address and length
>>> Why optional? Either the h/w has it or doesn't. If some chips don't,
>>> they should have a different compatible string.
>> in fact, the stm32 qspi controller can operate in any of the following
>> modes:
>> -indirect mode: all the operations are performed using the qspi registers
>> with read/write.
>> -read memory-mapped mode: the external Flash memory is mapped to the
>> microcontroller address space and is seen by the system as if it was
>> an internal memory (use memcpy_fromio). this mode improve read throughput
>>
>> if qspi_mm is defined the qspi controller use read memory-mapped mode
>> else the controller transfers in indirect mode.
> You should always have the memory region defined because that's what
> the h/w has. If you want another property to select the mode, then
> perhaps that's fine. But why? Can't the OS figure out which to use?
> Why would you ever not use memory mapped mode unless the driver
> doesn't yet support it?
ok, I always map the memory region (qspi_mm is now required).
if the nor-flash is more bigger than "qspi memory region", I force to use
the indirect mode.
> Rob
^ permalink raw reply
* Re: [PATCH 2/3] of/fdt: introduce of_scan_flat_dt_subnodes and of_get_flat_dt_phandle
From: Rob Herring @ 2017-04-05 15:58 UTC (permalink / raw)
To: Nicholas Piggin
Cc: Michael Ellerman,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linuxppc-dev,
Benjamin Herrenschmidt, Frank Rowand
In-Reply-To: <20170406003251.533e2845-a5aMA/AkCkgK5Ils6ZIQy0EOCMrvLtNR@public.gmane.org>
On Wed, Apr 5, 2017 at 9:32 AM, Nicholas Piggin <npiggin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Wed, 5 Apr 2017 08:35:06 -0500
> Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>
>> On Wed, Apr 5, 2017 at 7:37 AM, Nicholas Piggin <npiggin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> > Introduce primitives for FDT parsing. These will be used for powerpc
>> > cpufeatures node scanning, which has quite complex structure but should
>> > be processed early.
>>
>> Have you looked at unflattening the FDT earlier?
>
> Hi, thanks for taking a look. Did you mean to trim the cc list?
Ugg, no. I've added everyone back.
> It may be possible but I'd like to avoid it if we can. There might
> turn out to be some errata or feature that requires early setup. And
> the current cpu feature parsing code does it with flat dt.
Well, I'd like to avoid expanding usage of flat DT parsing in the
kernel. But you could just put this function into arch/powerpc and I'd
never see it, but I like that even less. Mainly, I just wanted to
raise the point.
Your argument works until you need that setup in assembly code, then
you are in the situation that you need to either handle the setup in
bootloader/firmware or have an simple way to determine that condition.
Rob
>
>> > Signed-off-by: Nicholas Piggin <npiggin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> > ---
>> > drivers/of/fdt.c | 39 +++++++++++++++++++++++++++++++++++++++
>> > include/linux/of_fdt.h | 6 ++++++
>> > 2 files changed, 45 insertions(+)
>> >
>> > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
>> > index e5ce4b59e162..a45854fe5156 100644
>> > --- a/drivers/of/fdt.c
>> > +++ b/drivers/of/fdt.c
>> > @@ -754,6 +754,37 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
>> > }
>> >
>> > /**
>> > + * of_scan_flat_dt_subnodes - scan sub-nodes of a node call callback on each.
>> > + * @it: callback function
>> > + * @data: context data pointer
>> > + *
>> > + * This function is used to scan sub-nodes of a node.
>> > + */
>> > +int __init of_scan_flat_dt_subnodes(unsigned long node,
>> > + int (*it)(unsigned long node,
>> > + const char *uname,
>> > + void *data),
>> > + void *data)
>> > +{
>> > + const void *blob = initial_boot_params;
>> > + const char *pathp;
>> > + int offset, rc = 0;
>> > +
>> > + offset = node;
>> > + for (offset = fdt_first_subnode(blob, offset);
>> > + offset >= 0 && !rc;
>> > + offset = fdt_next_subnode(blob, offset)) {
>>
>> fdt_for_each_subnode()
>
> Got it.
>
>>
>> > +
>> > + pathp = fdt_get_name(blob, offset, NULL);
>> > + if (*pathp == '/')
>> > + pathp = kbasename(pathp);
>>
>> Seems a bit odd that you parse the name in this function. Perhaps the
>> caller should do that, or if you want subnodes matching a certain
>> name, then do the matching here. But you didn't copy me on the rest of
>> the series, so I don't know how you are using this.
>
> Hmm, it was a while since writing that part. I guess I just copied
> of_scan_flat_dt interface.
>
> Caller is in this patch:
>
> https://patchwork.ozlabs.org/patch/747262/
>
> I'll include you in subsequent post if you prefer.
>
> Thanks,
> Nick
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/1] ARM: dts: armada-xp-linksys-mamba: use wan instead of internet for DSA port
From: Andrew Lunn @ 2017-04-05 15:50 UTC (permalink / raw)
To: Ralph Sennhauser
Cc: Mark Rutland, devicetree, Jason Cooper, linux-kernel,
Russell King, Rob Herring, Gregory Clement, linux-arm-kernel,
Sebastian Hesselbarth
In-Reply-To: <20170405172224.38c1f9fb@gmail.com>
> In fact "internet" label on the case is uppercase, would this matter
> for you for new bindings, or would you still use the lowercase version?
I would use lower case, just to fix with the general convention that
interface names are lower case.
> > I would say, this is now too late. Changing an interface name will
> > break configuration scripts. We are stuck with it.
> >
>
> If it weren't for commit cb4f71c42988 that would have been obvious for
> me as well.
Yes, that was not nice. But it was also very earlier in the life of
38x, so it just affected a few developers with reference boards, not
real products out in the wild, as far as i remember.
Andrew
^ permalink raw reply
* Re: [PATCH] ARM: dts: armada-38x: label USB and SATA nodes
From: Gregory CLEMENT @ 2017-04-05 15:49 UTC (permalink / raw)
To: Andrew Lunn
Cc: Ralph Sennhauser,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Jason Cooper,
Sebastian Hesselbarth, Rob Herring, Mark Rutland, Russell King,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170331182111.GJ22609-g2DYL2Zd6BY@public.gmane.org>
Hi Andrew,
On ven., mars 31 2017, Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> wrote:
> On Fri, Mar 31, 2017 at 07:39:20PM +0200, Ralph Sennhauser wrote:
>> On Fri, 31 Mar 2017 18:50:15 +0200
>> Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> wrote:
>>
>> > > - sata@a8000 {
>> > > + satac0: sata@a8000 {
>> >
>> > Hi Ralph
>> >
>> > Why the c in satac0?
>>
>> For controller and to not conflict with a use case of sata0 for a port,
>> similarly to pciec and pcie1. See armada-385-synology-ds116.dts.
>
> :~/linux/arch/arm/boot/dts$ ls *ds116*
> ls: cannot access '*ds116*': No such file or directory
>
> But anyway, a few boards seem to solve this by calling the controller
> node ahci0: and the port sata0:
>
>> > > - usb3@f0000 {
>> > > + usb3_0: usb3@f0000 {
>> > > compatible =
>> > > "marvell,armada-380-xhci"; reg = <0xf0000 0x4000>,<0xf4000 0x4000>;
>> > > interrupts = <GIC_SPI 16
>> > > IRQ_TYPE_LEVEL_HIGH>; @@ -598,7 +598,7 @@
>> > > status = "disabled";
>> > > };
>> > >
>> > > - usb3@f8000 {
>> > > + usb3_1: usb3@f8000 {
>> > > compatible =
>> > > "marvell,armada-380-xhci"; reg = <0xf8000 0x4000>,<0xfc000 0x4000>;
>> > > interrupts = <GIC_SPI 17
>> > > IRQ_TYPE_LEVEL_HIGH>;
>> >
>> > I can understand what you are saying. But does anybody else care? Are
>> > there other .dtsi files differentiating between USB 1.1, 2 and 3?
>>
>> It's handled differently where ever I looked, some do some don't. A
>> case for distinguishing USB 2.0 and USB 3.0 like this is
>> armada-388-gp.dts.
Actually I care and I found confusing calling usb2 the second usb port if
it is controlled by an USB3 controller.
>
> Humm...
>
> /* CON4 */
> usb@58000 {
> vcc-supply = <®_usb2_0_vbus>;
> status = "okay";
> };
>
>
> /* CON5 */
> usb3@f0000 {
> usb-phy = <&usb2_1_phy>;
> status = "okay";
> };
>
> /* CON7 */
> usb3@f8000 {
> usb-phy = <&usb3_phy>;
> status = "okay";
> };
>
> Is this clear? Is CON5 a USB 3 host, but has a USB 2 PHY connected to
> it? CON7 is the only true USB 3 port? I think some comments written in
I can answer it: CON5 is indeed an USB3 host with a USB2 PHY connected
to it so we can use it only as an USB2. And indeed CON7 is the only true
USB3 port.
> schwiizerdütsch would be clearre.:-)
Actually all your assumption were correct so maybe it is not as
confusing as it looks! :) But I can add a comment if needed.
Gregory
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
--
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 2/4] iio: dac: add support for stm32 DAC
From: Fabrice Gasnier @ 2017-04-05 15:48 UTC (permalink / raw)
To: Jonathan Cameron, linux, robh+dt, linux-arm-kernel, devicetree,
linux-kernel
Cc: mark.rutland, benjamin.gaignard, lars, alexandre.torgue,
linux-iio, pmeerw, amelie.delaunay, mcoquelin.stm32, knaack.h,
linus.walleij, benjamin.gaignard
In-Reply-To: <fd46ba6c-98f3-8dc9-5f71-9a09d60acf8e@kernel.org>
On 04/02/2017 01:32 PM, Jonathan Cameron wrote:
> On 31/03/17 12:45, Fabrice Gasnier wrote:
>> Add support for STMicroelectronics STM32 DAC. It's a 12-bit, voltage
>> output digital-to-analog converter. It has two output channels, each
>> with its own converter.
>> It supports 8 bits or 12bits left/right aligned data format. Only
>> 12bits right-aligned is used here. It has built-in noise or
>> triangle waveform generator, and supports external triggers for
>> conversions.
>> Each channel can be used independently, with separate trigger, then
>> separate IIO devices are used to handle this. Core driver is intended
>> to share common resources such as clock, reset, reference voltage and
>> registers.
>>
>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> Annoyingly my laptop just crashed mid way through reviewing this..
>
Hi Jonathan,
I hope I have nothing to do with this ;-)
> Ah well, hopefully I'll remember everything (there wasn't much).
>
> For DACs the 'enable' attribute is not normally used. Rather we
> use the powerdown one. The reasoning being that we care about what
> the state is when it is powered down. Even if that isn't controllable
> I would expect to see it exported as powerdown_mode with a fixed value.
>
Ok, I'll try to use powerdown_mode in V2 as other DACs do. For now,
basically, I'll remap same functionality as 'enable' of this patch.
What do you mean by 'fixed value' ?
But, this also raise me one question:
Current patch use 'enable' to set EN bits in control register. Then, DAC
output goes from Hi-Z to buffered output.
There is also other power modes available. One of them is 'unbuffered':
output buffer can be disabled/bypassed.
This typically can save power, but it only makes sense to use it
depending on output load impedance (This is explained in AN3126 as you
pointed out in later patch).
Current patch uses buffered output (which suits all needs regarding
output load impedance). And the question is...
Should I expose this power modes to userland by using 'powerdown_mode' ?
OR... I'd rather rely on a dt property like st,dac-output-mode to manage
this, because buffered/unbuffered output modes depends on HW output load
impedance. Do you agree with this approach to use:
- powerdown_mode as Hi-Z / enable switch, with dedicated dt property to
set output power mode ?
Please let me know your opinion.
But, I think this can be part of another patchset...
> Other than that - looks pretty good to me.
>
> Jonathan
>
>> ---
>> drivers/iio/dac/Kconfig | 15 ++
>> drivers/iio/dac/Makefile | 2 +
>> drivers/iio/dac/stm32-dac-core.c | 180 ++++++++++++++++++++++++
>> drivers/iio/dac/stm32-dac-core.h | 51 +++++++
>> drivers/iio/dac/stm32-dac.c | 296 +++++++++++++++++++++++++++++++++++++++
>> 5 files changed, 544 insertions(+)
>> create mode 100644 drivers/iio/dac/stm32-dac-core.c
>> create mode 100644 drivers/iio/dac/stm32-dac-core.h
>> create mode 100644 drivers/iio/dac/stm32-dac.c
>>
>> diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
>> index d3084028..7198648 100644
>> --- a/drivers/iio/dac/Kconfig
>> +++ b/drivers/iio/dac/Kconfig
>> @@ -274,6 +274,21 @@ config MCP4922
>> To compile this driver as a module, choose M here: the module
>> will be called mcp4922.
>>
>> +config STM32_DAC
>> + tristate "STMicroelectronics STM32 DAC"
>> + depends on (ARCH_STM32 && OF) || COMPILE_TEST
>> + depends on REGULATOR
>> + select STM32_DAC_CORE
>> + help
>> + Say yes here to build support for STMicroelectronics STM32 Digital
>> + to Analog Converter (DAC).
>> +
>> + This driver can also be built as a module. If so, the module
>> + will be called stm32-dac.
>> +
>> +config STM32_DAC_CORE
>> + tristate
>> +
>> config VF610_DAC
>> tristate "Vybrid vf610 DAC driver"
>> depends on OF
>> diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
>> index f01bf4a..afe8ae7 100644
>> --- a/drivers/iio/dac/Makefile
>> +++ b/drivers/iio/dac/Makefile
>> @@ -29,4 +29,6 @@ obj-$(CONFIG_MAX517) += max517.o
>> obj-$(CONFIG_MAX5821) += max5821.o
>> obj-$(CONFIG_MCP4725) += mcp4725.o
>> obj-$(CONFIG_MCP4922) += mcp4922.o
>> +obj-$(CONFIG_STM32_DAC_CORE) += stm32-dac-core.o
>> +obj-$(CONFIG_STM32_DAC) += stm32-dac.o
>> obj-$(CONFIG_VF610_DAC) += vf610_dac.o
>> diff --git a/drivers/iio/dac/stm32-dac-core.c b/drivers/iio/dac/stm32-dac-core.c
>> new file mode 100644
>> index 0000000..75e4878
>> --- /dev/null
>> +++ b/drivers/iio/dac/stm32-dac-core.c
>> @@ -0,0 +1,180 @@
>> +/*
>> + * This file is part of STM32 DAC driver
>> + *
>> + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
>> + * Author: Fabrice Gasnier <fabrice.gasnier@st.com>.
>> + *
>> + * License type: GPLv2
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published by
>> + * the Free Software Foundation.
>> + *
>> + * 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.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/module.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/reset.h>
>> +
>> +#include "stm32-dac-core.h"
>> +
>> +/**
>> + * struct stm32_dac_priv - stm32 DAC core private data
>> + * @pclk: peripheral clock common for all DACs
>> + * @rst: peripheral reset control
>> + * @vref: regulator reference
>> + * @common: Common data for all DAC instances
>> + */
>> +struct stm32_dac_priv {
>> + struct clk *pclk;
>> + struct reset_control *rst;
>> + struct regulator *vref;
>> + struct stm32_dac_common common;
>> +};
>> +
>> +static struct stm32_dac_priv *to_stm32_dac_priv(struct stm32_dac_common *com)
>> +{
>> + return container_of(com, struct stm32_dac_priv, common);
>> +}
>> +
>> +static const struct regmap_config stm32_dac_regmap_cfg = {
>> + .reg_bits = 32,
>> + .val_bits = 32,
>> + .reg_stride = sizeof(u32),
>> + .max_register = 0x3fc,
>> +};
>> +
>> +static int stm32_dac_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct stm32_dac_priv *priv;
>> + struct regmap *regmap;
>> + struct resource *res;
>> + void __iomem *mmio;
>> + int ret;
>> +
>> + if (!dev->of_node)
>> + return -ENODEV;
>> +
>> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>> + if (!priv)
>> + return -ENOMEM;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + mmio = devm_ioremap_resource(dev, res);
>> + if (IS_ERR(mmio))
>> + return PTR_ERR(mmio);
>> +
>> + regmap = devm_regmap_init_mmio(dev, mmio, &stm32_dac_regmap_cfg);
>> + if (IS_ERR(regmap))
>> + return PTR_ERR(regmap);
>> + priv->common.regmap = regmap;
>> +
>> + priv->vref = devm_regulator_get(dev, "vref");
>> + if (IS_ERR(priv->vref)) {
>> + ret = PTR_ERR(priv->vref);
>> + dev_err(dev, "vref get failed, %d\n", ret);
>> + return ret;
>> + }
>> +
>> + ret = regulator_enable(priv->vref);
>> + if (ret < 0) {
>> + dev_err(dev, "vref enable failed\n");
>> + return ret;
>> + }
>> +
>> + ret = regulator_get_voltage(priv->vref);
>> + if (ret < 0) {
>> + dev_err(dev, "vref get voltage failed, %d\n", ret);
>> + goto err_vref;
>> + }
>> + priv->common.vref_mv = ret / 1000;
>> + dev_dbg(dev, "vref+=%dmV\n", priv->common.vref_mv);
>> +
>> + priv->pclk = devm_clk_get(dev, "pclk");
>> + if (IS_ERR(priv->pclk)) {
>> + ret = PTR_ERR(priv->pclk);
>> + dev_err(dev, "pclk get failed\n");
>> + goto err_vref;
>> + }
>> +
>> + ret = clk_prepare_enable(priv->pclk);
>> + if (ret < 0) {
>> + dev_err(dev, "pclk enable failed\n");
>> + goto err_vref;
>> + }
>> +
>> + priv->rst = devm_reset_control_get(dev, NULL);
>> + if (!IS_ERR(priv->rst)) {
>> + reset_control_assert(priv->rst);
>> + udelay(2);
>> + reset_control_deassert(priv->rst);
>> + }
>> +
>> + /* When clock speed is higher than 80MHz, set HFSEL */
>> + priv->common.hfsel = (clk_get_rate(priv->pclk) > 80000000UL);
>> + ret = regmap_update_bits(regmap, STM32_DAC_CR, STM32H7_DAC_CR_HFSEL,
>> + priv->common.hfsel ? STM32H7_DAC_CR_HFSEL : 0);
>> + if (ret)
>> + goto err_pclk;
>> +
>> + platform_set_drvdata(pdev, &priv->common);
>> +
>> + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev);
>> + if (ret < 0) {
>> + dev_err(dev, "failed to populate DT children\n");
>> + goto err_pclk;
>> + }
>> +
>> + return 0;
>> +
>> +err_pclk:
>> + clk_disable_unprepare(priv->pclk);
>> +err_vref:
>> + regulator_disable(priv->vref);
>> +
>> + return ret;
>> +}
>> +
>> +static int stm32_dac_remove(struct platform_device *pdev)
>> +{
>> + struct stm32_dac_common *common = platform_get_drvdata(pdev);
>> + struct stm32_dac_priv *priv = to_stm32_dac_priv(common);
>> +
>> + of_platform_depopulate(&pdev->dev);
>> + clk_disable_unprepare(priv->pclk);
>> + regulator_disable(priv->vref);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id stm32_dac_of_match[] = {
>> + { .compatible = "st,stm32h7-dac-core", },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, stm32_dac_of_match);
>> +
>> +static struct platform_driver stm32_dac_driver = {
>> + .probe = stm32_dac_probe,
>> + .remove = stm32_dac_remove,
>> + .driver = {
>> + .name = "stm32-dac-core",
>> + .of_match_table = stm32_dac_of_match,
>> + },
>> +};
>> +module_platform_driver(stm32_dac_driver);
>> +
>> +MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
>> +MODULE_DESCRIPTION("STMicroelectronics STM32 DAC core driver");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_ALIAS("platform:stm32-dac-core");
>> diff --git a/drivers/iio/dac/stm32-dac-core.h b/drivers/iio/dac/stm32-dac-core.h
>> new file mode 100644
>> index 0000000..d3099f7
>> --- /dev/null
>> +++ b/drivers/iio/dac/stm32-dac-core.h
>> @@ -0,0 +1,51 @@
>> +/*
>> + * This file is part of STM32 DAC driver
>> + *
>> + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
>> + * Author: Fabrice Gasnier <fabrice.gasnier@st.com>.
>> + *
>> + * License type: GPLv2
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published by
>> + * the Free Software Foundation.
>> + *
>> + * 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.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#ifndef __STM32_DAC_CORE_H
>> +#define __STM32_DAC_CORE_H
>> +
>> +#include <linux/regmap.h>
>> +
>> +/* STM32 DAC registers */
>> +#define STM32_DAC_CR 0x00
>> +#define STM32_DAC_DHR12R1 0x08
>> +#define STM32_DAC_DHR12R2 0x14
>> +#define STM32_DAC_DOR1 0x2C
>> +#define STM32_DAC_DOR2 0x30
>> +
>> +/* STM32_DAC_CR bit fields */
>> +#define STM32_DAC_CR_EN1 BIT(0)
>> +#define STM32H7_DAC_CR_HFSEL BIT(15)
>> +#define STM32_DAC_CR_EN2 BIT(16)
>> +
>> +/**
>> + * struct stm32_dac_common - stm32 DAC driver common data (for all instances)
>> + * @regmap: DAC registers shared via regmap
>> + * @vref_mv: reference voltage (mv)
>> + * @hfsel: high speed bus clock
>> + */
>> +struct stm32_dac_common {
>> + struct regmap *regmap;
>> + int vref_mv;
>> + bool hfsel;
>> +};
>> +
>> +#endif
>> diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c
>> new file mode 100644
>> index 0000000..ee9711d
>> --- /dev/null
>> +++ b/drivers/iio/dac/stm32-dac.c
>> @@ -0,0 +1,296 @@
>> +/*
>> + * This file is part of STM32 DAC driver
>> + *
>> + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
>> + * Authors: Amelie Delaunay <amelie.delaunay@st.com>
>> + * Fabrice Gasnier <fabrice.gasnier@st.com>
>> + *
>> + * License type: GPLv2
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published by
>> + * the Free Software Foundation.
>> + *
>> + * 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.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/bitfield.h>
>> +#include <linux/delay.h>
>> +#include <linux/iio/iio.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +
>> +#include "stm32-dac-core.h"
>> +
>> +#define STM32_DAC_CHANNEL_1 1
>> +#define STM32_DAC_CHANNEL_2 2
>> +
>> +/**
>> + * struct stm32_dac - private data of DAC driver
>> + * @common: reference to DAC common data
>> + */
>> +struct stm32_dac {
>> + struct stm32_dac_common *common;
>> +};
>> +
>> +static int stm32_dac_is_enabled(struct stm32_dac *dac, int channel)
>> +{
>> + u32 en, val;
>> + int ret;
>> +
>> + ret = regmap_read(dac->common->regmap, STM32_DAC_CR, &val);
>> + if (ret < 0)
>> + return ret;
>> + if (channel == STM32_DAC_CHANNEL_1)
>> + en = FIELD_GET(STM32_DAC_CR_EN1, val);
>> + else
>> + en = FIELD_GET(STM32_DAC_CR_EN2, val);
>> +
>> + return !!en;
>> +}
>> +
>> +static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> + u32 en = (channel == STM32_DAC_CHANNEL_1) ?
>> + STM32_DAC_CR_EN1 : STM32_DAC_CR_EN2;
>> + int ret;
>> +
>> + ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, en, en);
>> + if (ret < 0) {
>> + dev_err(&indio_dev->dev, "Enable failed\n");
>> + return ret;
>> + }
>> +
>> + /*
>> + * When HFSEL is set, it is not allowed to write the DHRx register
>> + * during 8 clock cycles after the ENx bit is set. It is not allowed
>> + * to make software/hardware trigger during this period neither.
>> + */
>> + if (dac->common->hfsel)
>> + udelay(1);
>> +
>> + return 0;
>> +}
>> +
>> +static int stm32_dac_disable(struct iio_dev *indio_dev, int channel)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> + u32 en = (channel == STM32_DAC_CHANNEL_1) ?
>> + STM32_DAC_CR_EN1 : STM32_DAC_CR_EN2;
>> + int ret;
>> +
>> + ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, en, 0);
>> + if (ret)
>> + dev_err(&indio_dev->dev, "Disable failed\n");
>> +
>> + return ret;
>> +}
>> +
>> +static int stm32_dac_get_value(struct stm32_dac *dac, int channel, int *val)
>> +{
>> + int ret;
>> +
>> + if (channel == STM32_DAC_CHANNEL_1)
>> + ret = regmap_read(dac->common->regmap, STM32_DAC_DOR1, val);
>> + else
>> + ret = regmap_read(dac->common->regmap, STM32_DAC_DOR2, val);
>> +
>> + return ret ? ret : IIO_VAL_INT;
>> +}
>> +
>> +static int stm32_dac_set_value(struct stm32_dac *dac, int channel, int val)
>> +{
>> + int ret;
>> +
>> + if (channel == STM32_DAC_CHANNEL_1)
>> + ret = regmap_write(dac->common->regmap, STM32_DAC_DHR12R1, val);
>> + else
>> + ret = regmap_write(dac->common->regmap, STM32_DAC_DHR12R2, val);
>> +
>> + return ret;
>> +}
>> +
>> +static int stm32_dac_read_raw(struct iio_dev *indio_dev,
>> + struct iio_chan_spec const *chan,
>> + int *val, int *val2, long mask)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> + int ret;
>> +
>> + switch (mask) {
>> + case IIO_CHAN_INFO_RAW:
>> + return stm32_dac_get_value(dac, chan->channel, val);
>> + case IIO_CHAN_INFO_SCALE:
>> + *val = dac->common->vref_mv;
>> + *val2 = chan->scan_type.realbits;
>> + return IIO_VAL_FRACTIONAL_LOG2;
>> + case IIO_CHAN_INFO_ENABLE:
>> + ret = stm32_dac_is_enabled(dac, chan->channel);
>> + if (ret < 0)
>> + return ret;
>> + *val = ret;
>> + return IIO_VAL_INT;
>> + default:
>> + return -EINVAL;
>> + }
>> +}
>> +
>> +static int stm32_dac_write_raw(struct iio_dev *indio_dev,
>> + struct iio_chan_spec const *chan,
>> + int val, int val2, long mask)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + switch (mask) {
>> + case IIO_CHAN_INFO_RAW:
>> + return stm32_dac_set_value(dac, chan->channel, val);
>> + case IIO_CHAN_INFO_ENABLE:
>> + if (!!val)
>> + return stm32_dac_enable(indio_dev, chan->channel);
>> + else
>> + return stm32_dac_disable(indio_dev, chan->channel);
>> + default:
>> + return -EINVAL;
>> + }
>> +}
>> +
>> +static int stm32_dac_debugfs_reg_access(struct iio_dev *indio_dev,
>> + unsigned reg, unsigned writeval,
>> + unsigned *readval)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + if (!readval)
>> + return regmap_write(dac->common->regmap, reg, writeval);
>> + else
>> + return regmap_read(dac->common->regmap, reg, readval);
>> +}
>> +
>> +static const struct iio_info stm32_dac_iio_info = {
>> + .read_raw = &stm32_dac_read_raw,
>> + .write_raw = &stm32_dac_write_raw,
>> + .debugfs_reg_access = &stm32_dac_debugfs_reg_access,
>> + .driver_module = THIS_MODULE,
>> +};
>> +
>> +#define STM32_DAC_CHANNEL(chan, name) { \
>> + .type = IIO_VOLTAGE, \
>> + .indexed = 1, \
>> + .output = 1, \
>> + .channel = chan, \
>> + .info_mask_separate = \
>> + BIT(IIO_CHAN_INFO_RAW) | \
>> + BIT(IIO_CHAN_INFO_ENABLE) | \
>> + BIT(IIO_CHAN_INFO_SCALE), \
>> + .scan_type = { \
>> + .sign = 'u', \
>> + .realbits = 12, \
>> + .storagebits = 16, \
>> + }, \
>> + .datasheet_name = name, \
>> +}
>> +
>> +static const struct iio_chan_spec stm32_dac_channels[] = {
>> + STM32_DAC_CHANNEL(STM32_DAC_CHANNEL_1, "out1"),
>> + STM32_DAC_CHANNEL(STM32_DAC_CHANNEL_2, "out2"),
>> +};
>> +
>> +static int stm32_dac_chan_of_init(struct iio_dev *indio_dev)
>> +{
>> + struct device_node *np = indio_dev->dev.of_node;
>> + unsigned int i;
>> + u32 channel;
>> + int ret;
>> +
>> + ret = of_property_read_u32(np, "st,dac-channel", &channel);
>> + if (ret) {
>> + dev_err(&indio_dev->dev, "Failed to read st,dac-channel\n");
>> + return ret;
>> + }
>> +
>> + for (i = 0; i < ARRAY_SIZE(stm32_dac_channels); i++) {
>> + if (stm32_dac_channels[i].channel == channel)
>> + break;
>> + }
>> + if (i >= ARRAY_SIZE(stm32_dac_channels)) {
>> + dev_err(&indio_dev->dev, "Invalid st,dac-channel\n");
>> + return -EINVAL;
>> + }
>> +
>> + indio_dev->channels = &stm32_dac_channels[i];
>> + indio_dev->num_channels = 1;
>> +
>> + return 0;
>> +};
>> +
>> +static int stm32_dac_probe(struct platform_device *pdev)
>> +{
>> + struct device_node *np = pdev->dev.of_node;
>> + struct iio_dev *indio_dev;
>> + struct stm32_dac *dac;
>> + int ret;
>> +
>> + if (!np)
>> + return -ENODEV;
>> +
>> + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*dac));
>> + if (!indio_dev)
>> + return -ENOMEM;
>> + platform_set_drvdata(pdev, indio_dev);
>> +
>> + dac = iio_priv(indio_dev);
>> + dac->common = dev_get_drvdata(pdev->dev.parent);
>> + indio_dev->name = dev_name(&pdev->dev);
>> + indio_dev->dev.parent = &pdev->dev;
>> + indio_dev->dev.of_node = pdev->dev.of_node;
>> + indio_dev->info = &stm32_dac_iio_info;
>> + indio_dev->modes = INDIO_DIRECT_MODE;
>> +
>> + ret = stm32_dac_chan_of_init(indio_dev);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = iio_device_register(indio_dev);
>> + if (ret)
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> +static int stm32_dac_remove(struct platform_device *pdev)
>> +{
>> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>> +
>> + iio_device_unregister(indio_dev);
> use devm_iio_device_register and drop the remove entirely
> (I guess this may make no sense once I've looked at later
> patches however!)
Good guess ;-)
But okay, I'll use devm_ anyway, regardless of other patches.
Thanks & Regards,
Fabrice
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id stm32_dac_of_match[] = {
>> + { .compatible = "st,stm32-dac", },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, stm32_dac_of_match);
>> +
>> +static struct platform_driver stm32_dac_driver = {
>> + .probe = stm32_dac_probe,
>> + .remove = stm32_dac_remove,
>> + .driver = {
>> + .name = "stm32-dac",
>> + .of_match_table = stm32_dac_of_match,
>> + },
>> +};
>> +module_platform_driver(stm32_dac_driver);
>> +
>> +MODULE_ALIAS("platform:stm32-dac");
>> +MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay@st.com>");
>> +MODULE_DESCRIPTION("STMicroelectronics STM32 DAC driver");
>> +MODULE_LICENSE("GPL v2");
>>
>
^ permalink raw reply
* Re: [RFC] [media] imx: assume MEDIA_ENT_F_ATV_DECODER entities output video on pad 1
From: Devin Heitmueller @ 2017-04-05 15:39 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: mark.rutland, andrew-ct.chen, minghsiu.tsai,
sakari.ailus@linux.intel.com, nick, songjun.wu, Hans Verkuil,
Steve Longerbeam, Pavel Machek, robert.jarzmik, devel,
markus.heiser, laurent.pinchart+renesas, shuah,
Russell King - ARM Linux, geert, Steve Longerbeam,
Linux Media Mailing List, devicetree, Philipp Zabel,
Arnd Bergmann, Mauro Carvalho Chehab, bparrot, robh+dt,
horms+renesas, tiffany.lin, linux-arm-kernel
In-Reply-To: <20170405115336.7135e542@vento.lan>
> Currently, the driver doesn't support (2), because, at the time
> I wrote the driver, I didn't find a way to read the interrupts generated
> by tvp5150 at em28xx[1], due to the lack of em28xx documentation,
> but adding support for it shoudn't be hard. I may eventually do it
> when I have some time to play with my ISEE hardware.
For what it's worth, I doubt most of the em28xx designs have the
tvp5150 interrupt request line connected in any way. You would likely
have to poll the FIFO status register via I2C, or use the feature to
embed the sliced data into as VANC data in the 656 output (as
described in sec 3.9 of the tvp5150am1 spec).
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply
* Re: [PATCH] ARM: dts: armada-385-linksys: disk-activity trigger for all
From: Gregory CLEMENT @ 2017-04-05 15:27 UTC (permalink / raw)
To: Ralph Sennhauser
Cc: Andrew Lunn, linux-arm-kernel, Jason Cooper,
Sebastian Hesselbarth, Rob Herring, Mark Rutland, Russell King,
devicetree, linux-kernel
In-Reply-To: <20170331153549.GA12814@lunn.ch>
Hi Ralph,
On ven., mars 31 2017, Andrew Lunn <andrew@lunn.ch> wrote:
> On Thu, Mar 30, 2017 at 06:54:04PM +0200, Ralph Sennhauser wrote:
>> Commit a4ee7e18d808 ("ARM: dts: armada: Add default trigger for sata
>> led") adds the default trigger to individual boards, move it to
>> armada-385-linksys.dtsi which effectively enables the definition for
>> the WRT1900ACS (Shelby) as well as for future boards.
>>
>> Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
>
> Centralising this makes sense.
>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Applied on mvebu/dt
Thanks,
Gregory
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH V7 0/4] phy: USB and PCIe phy drivers for Qcom chipsets
From: Vivek Gautam @ 2017-04-05 15:24 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: robh+dt, linux-arm-kernel@lists.infradead.org, linux-arm-msm,
linux-kernel@vger.kernel.org, Linux USB Mailing List,
devicetree@vger.kernel.org, Mark Rutland, Stephen Boyd,
Bjorn Andersson, Srinivas Kandagatla
In-Reply-To: <a59d6776-5855-9d04-a5be-de03456b8d2e@ti.com>
Hi Kishon,
On Wed, Apr 5, 2017 at 7:08 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Hi Vivek,
>
> On Wednesday 05 April 2017 06:02 PM, Vivek Gautam wrote:
>> This patch series adds couple of PHY drivers for Qualcomm chipsets.
>> a) qcom-qusb2 phy driver: that provides High Speed USB functionality.
>> b) qcom-qmp phy driver: that is a combo phy providing support for
>> USB3, PCIe, UFS and few other controllers.
>>
>> The patches are based on next branch of linux-phy tree.
>>
>> These patches have been tested on Dragon board db820c hardware with
>> required set of dt patches and the patches to get rpm up on msm8996.
>> Couple of other patches [1, 2] fixing DMA config for XHCI are also
>> pulled in for testing.
>> A branch based on torvald's master is available in github [3].
>
> I get a bunch of checkpatch errors/warnings when I run checkpatch with --strict
> option. Those look simple enough to be fixed. Can you respin your series fixing
> those?
Sure, I am on it.
Thanks for pointing out.
Regards
Vivek
>
> Thanks
> Kishon
>
>>
>> Changes since v6:
>> - Rebased on phy/next and *not* including phy grouping series[4].
>> - qusb2-phy: addressed Stephen's comment.
>> - Dropped pm8994_s2 corner regulator from QUSB2 phy bindings.
>> - qmp-phy: none on functionality side.
>>
>> Changes since v5:
>> - Addressed review comments from Bjorn:
>> - Removed instances of readl/wirtel_relaxed calls from the drivers.
>> Instead, using simple readl/writel. Inserting a readl after a writel
>> to ensure the write is through to the device.
>> - Replaced regulator handling with regulator_bulk_** apis. This helps
>> in cutting down a lot of regulator handling code.
>> - Fixed minor return statements.
>>
>> Changes since v4:
>> - Addressed comment to add child nodes for qmp phy driver. Each phy lane
>> now has a separate child node under the main qmp node.
>> - Modified the clock and reset initialization and enable methods.
>> Different phys - pcie, usb and later ufs, have varying number of clocks
>> and resets that are mandatory. So adding provision for clocks and reset
>> lists helps in requesting all mandatory resources for individual phys
>> and handle their failure cases accordingly.
>>
>> Changes since v3:
>> - Addressed review comments given by Rob and Stephen for qusb2 phy
>> and qmp phy bindings respectively.
>> - Addressed review comments given by Stephen and Bjorn for qmp phy driver.
>>
>> Changes since v2:
>> - Addressed review comments given by Rob and Stephen for bindings.
>> - Addressed the review comments given by Stephen for the qusb2 and qmp
>> phy drivers.
>>
>> Changes since v1:
>> - Moved device tree binding documentation to separate patches, as suggested
>> by Rob.
>> - Addressed review comment regarding qfprom accesses by qusb2 phy driver,
>> given by Rob.
>> - Addressed review comments from Kishon.
>> - Addressed review comments from Srinivas for QMP phy driver.
>> - Addressed kbuild warning.
>>
>> Please see individual patches for detailed changelogs.
>>
>> [1] https://patchwork.kernel.org/patch/9567767/
>> [2] https://patchwork.kernel.org/patch/9567779/
>> [3] https://github.com/vivekgautam1/linux/tree/linux-v4.11-rc5-qmp-phy-db820c
>> [4] https://lkml.org/lkml/2017/3/20/407
>>
>> Vivek Gautam (4):
>> dt-bindings: phy: Add support for QUSB2 phy
>> phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips
>> dt-bindings: phy: Add support for QMP phy
>> phy: qcom-qmp: new qmp phy driver for qcom-chipsets
>>
>> .../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 ++
>> .../devicetree/bindings/phy/qcom-qusb2-phy.txt | 43 +
>> drivers/phy/Kconfig | 18 +
>> drivers/phy/Makefile | 2 +
>> drivers/phy/phy-qcom-qmp.c | 1153 ++++++++++++++++++++
>> drivers/phy/phy-qcom-qusb2.c | 491 +++++++++
>> 6 files changed, 1813 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
>> create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> create mode 100644 drivers/phy/phy-qcom-qmp.c
>> create mode 100644 drivers/phy/phy-qcom-qusb2.c
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH 1/1] ARM: dts: armada-xp-linksys-mamba: use wan instead of internet for DSA port
From: Ralph Sennhauser @ 2017-04-05 15:22 UTC (permalink / raw)
To: Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
Jason Cooper, devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Gregory Clement, Rob Herring,
Sebastian Hesselbarth
In-Reply-To: <20170405142824.GB13449-g2DYL2Zd6BY@public.gmane.org>
On Wed, 5 Apr 2017 16:28:24 +0200
Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> wrote:
> On Wed, Apr 05, 2017 at 07:28:46AM +0200, Ralph Sennhauser wrote:
> > The LEDs for the "wan" port are already labeled "mamba:amber:wan"
> > resp. "mamba:white:wan". So besides being an outlier with regard to
> > the rest of the product line (see table below) changing the label
> > fixes an internal inconsistency as well.
> >
> > This will be visible in user space. Given commit cb4f71c42988 ("ARM:
> > dts: armada-38x: change order of ethernet DT nodes on Armada 38x")
> > it's expected to happen anyway. Commit 499400c9ac20 ("ARM: dts:
> > armada-xp-linksys-mamba: Utilize new DSA binding") switches to the
> > new bindings, use this opportunity to do it now rather than later.
> >
> > |-----------------------------------------------------------------|
> > | Labels used for the case and those used for the DSA ports |
> > |-----------------------------------------------------------------|
> > | case labels | armada-385-linksys-* |
> > armada-xp-linksys-mamba |
> > |---------------|-----------------------|-------------------------|
> > | internet | wan |
> > internet | | 1 |
> > lan1 | lan1 | |
> > 2 | lan2 |
> > lan2 | | 3 |
> > lan3 | lan3 | |
> > 4 | lan4 |
> > lan4 |
> > |-----------------------------------------------------------------|
>
> Hi Ralph
>
> I always encourage people to use the case labels as interface names.
> So if i was going to make a change, it would be wan->internet for the
> armada-385-linksys-*.
Glad Imre used lan1 instead of 1 ;)
The reverse I have appended to this mail so people know what it would
look like.
In fact "internet" label on the case is uppercase, would this matter
for you for new bindings, or would you still use the lowercase version?
It's not relevant here, just wondering.
>
> > I underestimated the urge of people to make all the same before.
> > While I do not particularly like this sort of change I see it
> > coming anyway. So this patch is meant to make it a deliberate
> > decision so it no longer is an item lurking in the shadows. Whether
> > this patch gets taken or rejected my goal is reached.
>
> I would say, this is now too late. Changing an interface name will
> break configuration scripts. We are stuck with it.
>
If it weren't for commit cb4f71c42988 that would have been obvious for
me as well.
Thanks
Ralph
The inverse (following trough all the way) would look the following,
same changes applies to Rango which is not yet supported by vanilla
kernel.
diff --git a/arch/arm/boot/dts/armada-385-linksys-caiman.dts b/arch/arm/boot/dts/armada-385-linksys-caiman.dts
index a1b6e68..3efceda 100644
--- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts
+++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts
@@ -53,13 +53,13 @@
#address-cells = <1>;
#size-cells = <0>;
- wan_amber@0 {
- label = "caiman:amber:wan";
+ internet_amber@0 {
+ label = "caiman:amber:internet";
reg = <0x0>;
};
- wan_white@1 {
- label = "caiman:white:wan";
+ internet_white@1 {
+ label = "caiman:white:internet";
reg = <0x1>;
};
diff --git a/arch/arm/boot/dts/armada-385-linksys-cobra.dts b/arch/arm/boot/dts/armada-385-linksys-cobra.dts
index a1a75af..4f2e7f6 100644
--- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts
+++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts
@@ -53,13 +53,13 @@
#address-cells = <1>;
#size-cells = <0>;
- wan_amber@0 {
- label = "cobra:amber:wan";
+ internet_amber@0 {
+ label = "cobra:amber:internet";
reg = <0x0>;
};
- wan_white@1 {
- label = "cobra:white:wan";
+ internet_white@1 {
+ label = "cobra:white:internet";
reg = <0x1>;
};
diff --git a/arch/arm/boot/dts/armada-385-linksys-shelby.dts b/arch/arm/boot/dts/armada-385-linksys-shelby.dts
index c7a8ddd..a7b47f7 100644
--- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts
+++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts
@@ -53,13 +53,13 @@
#address-cells = <1>;
#size-cells = <0>;
- wan_amber@0 {
- label = "shelby:amber:wan";
+ internet_amber@0 {
+ label = "shelby:amber:internet";
reg = <0x0>;
};
- wan_white@1 {
- label = "shelby:white:wan";
+ internet_white@1 {
+ label = "shelby:white:internet";
reg = <0x1>;
};
diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi
index aa0d225..8460066 100644
--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
@@ -145,7 +145,7 @@
port@4 {
reg = <4>;
- label = "wan";
+ label = "internet";
};
port@5 {
@@ -360,7 +360,7 @@
port@4 {
reg = <4>;
- label = "wan";
+ label = "internet";
};
port@5 {
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
index 9efcf59..ed2fe8f 100644
--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -140,13 +140,13 @@
compatible = "ti,tlc59116";
reg = <0x68>;
- wan_amber@0 {
- label = "mamba:amber:wan";
+ internet_amber@0 {
+ label = "mamba:amber:internet";
reg = <0x0>;
};
- wan_white@1 {
- label = "mamba:white:wan";
+ internet_white@1 {
+ label = "mamba:white:internet";
reg = <0x1>;
};
--
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 v4 7/7] ARM64: dts: marvell: armada37xx: add pinctrl definition
From: Gregory CLEMENT @ 2017-04-05 15:18 UTC (permalink / raw)
To: Linus Walleij, linux-gpio
Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT,
Thomas Petazzoni, linux-arm-kernel, Rob Herring, devicetree,
linux-kernel, Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding,
Hua Jing, Neta Zur Hershkovits
In-Reply-To: <cover.65d0e6796fecf1fe6c5d07b981160b54dc9b4acd.1491405475.git-series.gregory.clement@free-electrons.com>
Start to populate the device tree of the Armada 37xx with the pincontrol
configuration used on the board providing a dts.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-3720-db.dts | 8 +++++-
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 31 +++++++++++++++++++-
2 files changed, 39 insertions(+)
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index 86602c907a61..e749c5727490 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -63,6 +63,8 @@
};
&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
status = "okay";
};
@@ -73,6 +75,8 @@
&spi0 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_quad_pins>;
m25p80@0 {
compatible = "jedec,spi-nor";
@@ -103,6 +107,8 @@
/* Exported on the micro USB connector CON32 through an FTDI */
&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
status = "okay";
};
@@ -128,6 +134,8 @@
};
ð0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
phy-mode = "rgmii-id";
phy = <&phy0>;
status = "okay";
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index c02b13479458..2ac25f54d01d 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -186,6 +186,31 @@
clock-output-names = "xtal";
#clock-cells = <0>;
};
+
+ spi_quad_pins: spi-quad-pins {
+ groups = "spi_quad";
+ function = "spi";
+ };
+
+ i2c1_pins: i2c1-pins {
+ groups = "i2c1";
+ function = "i2c";
+ };
+
+ i2c2_pins: i2c2-pins {
+ groups = "i2c2";
+ function = "i2c";
+ };
+
+ uart1_pins: uart1-pins {
+ groups = "uart1";
+ function = "uart";
+ };
+
+ uart2_pins: uart2-pins {
+ groups = "uart2";
+ function = "uart";
+ };
};
pinctrl_sb: pinctrl-sb@18800 {
@@ -203,6 +228,12 @@
<GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
};
+
+ rgmii_pins: mii-pins {
+ groups = "rgmii";
+ function = "mii";
+ };
+
};
eth0: ethernet@30000 {
--
git-series 0.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox