Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 0/8] firmware: arm_scpi: add support for legacy SCPI protocol
From: Ryan Harkin @ 2016-11-21 15:04 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Sudeep Holla, Philippe Robin, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Neil Armstrong, lkml, Olof Johansson,
	linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <20161108174622.GW1041-l+eeeJia6m9URfEZ8mYm6t73F7V6hmMc@public.gmane.org>

On 8 November 2016 at 17:46, Russell King - ARM Linux
<linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org> wrote:
> On Tue, Nov 08, 2016 at 05:37:25PM +0000, Sudeep Holla wrote:
>>
>>
>> On 08/11/16 16:06, Russell King - ARM Linux wrote:
>> >On Tue, Nov 08, 2016 at 03:40:38PM +0000, Russell King - ARM Linux wrote:
>> >>As it contains a zero sized Image and .dtb files, I tried copying my
>> >>Image and .dtb over, and also copied my original config.txt (only
>> >>change is AUTORUN: FALSE).  It still doesn't appear to boot beyond
>> >>this point.
>> >
>> >Well, it seems that I can't even go back to my original set of firmware
>> >as UEFI has stopped working:
>> >
>> >NOTICE:  Booting Trusted Firmware
>> >NOTICE:  BL1: v1.0(release):14b6608
>> >NOTICE:  BL1: Built : 14:15:51, Sep  1 2014
>> >NOTICE:  BL1: Booting BL2
>> >NOTICE:  BL2: v1.0(release):14b6608
>> >NOTICE:  BL2: Built : 14:15:51, Sep  1 2014
>> >NOTICE:  BL1: Booting BL3-1
>> >NOTICE:  BL3-1: v1.0(release):14b6608
>> >NOTICE:  BL3-1: Built : 14:15:53, Sep  1 2014
>> >UEFI firmware (version v2.1 built at 14:41:56 on Oct 23 2014)
>> >Warning: Fail to load FDT file 'juno.dtb'.
>> >
>>
>> This again because of incompatibility of the configuration data saved in
>> NOR flash. The erase command I gave early is to erase that when you
>> switched between the UEFI binaries. It's really horrible mess UEFI
>> created in the initial days of Juno, and hopefully they have moved to
>> some standard format these days.
>
> Yea, what it means is I've no possibility to go back to what was
> originally working now, since I don't understand how to get UEFI to
> behave (Will set the machine up for me, I don't have any information
> on how it was originally configured other than what was on the uSD
> card, which appears incomplete.)
>
>> >and UEFI is the most unfriendly thing going - the "boot manager" thing
>> >doesn't let you view the configuration:
>> >
>>
>> I completely agree. I had real bad times in past dealing with such
>> things in UEFI.
>>
>> >[1] Linux from NOR Flash
>> >[2] Shell
>> >[3] Boot Manager
>> >Start: 3
>> >[1] Add Boot Device Entry
>> >[2] Update Boot Device Entry
>> >[3] Remove Boot Device Entry
>> >[4] Reorder Boot Device Entries
>> >[5] Update FDT path
>> >[6] Set Boot Timeout
>> >[7] Return to main menu
>> >Choice:
>> >
>> >and dropping into the shell... well, I've no idea how to get a listing
>> >of what it thinks is in the NOR device (or even how to refer to the
>> >NOR device.)  "devices" shows nothing that's even remotely English.
>> >

Using UEFI is painful enough on Juno.  Using a 2 year old version with
"that" menu system is even worse.

So I'll just pitch in here and recommend you switch to using u-boot.
Then you can see your config with "printenv" and you'll probably
understand it too.

The board will boot my prebuilt kernel/DTB using u-boot if you erase
the uSD card and unzip this firmware image to it:

http://releases.linaro.org/members/arm/platforms/16.10/juno-latest-oe-uboot.zip

Then you can copy over your own kernel & DTB for your own testing,
configure u-boot for TFTP, or whatever you like.

Switching to u-boot won't solve any thermal sensor calibration problems.


>>
>> I think startup.nsh needs some edits. Just replace it with something like:
>>
>> "norkern dtb=board.dtb console=ttyAMA0,115200n8 root=/dev/nfs rw
>> rootwait ip=dhcp systemd.log_target=null nfsroot=..." or something
>> alike. Currently it just echos and stops.
>>
>> Regarding the new firmware stopping abruptly, I have no clue, except
>> asking you to erase the flash completely when switching between the
>> firmware versions. That has worked for me for all UEFI related issues in
>> the past. It's really annoying I understand.
>>
>> flash> eraseall
>
> I've tried that, it still stops at the same point, after:
>
> FV2 Hob           0xFE07B000 - 0xFE8253BF
>
> and remains unresponsive.
>
> I do notice that the uSD card becomes visible through USB at this point
> though.
>
> Okay, well, I'm going to have to disable Juno from the nightly boots
> until we get some kind of resolution on this, as my Juno is now
> incapable of booting anything.
>
> --
> RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v5 2/2] drm/panel: simple: add support for Sharp LQ150X1LG11 panels
From: Peter Rosin @ 2016-11-21 15:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: Gustaf Lindström, Thierry Reding, David Airlie, Rob Herring,
	Mark Rutland, dri-devel, devicetree, Peter Rosin
In-Reply-To: <1479740449-20201-1-git-send-email-peda@axentia.se>

From: Gustaf Lindström <gl@axentia.se>

The Sharp 15" LQ150X1LG11 panel is an XGA TFT LCD panel.

The simple-panel driver is used to get support for essential
functionality of the panel.

Signed-off-by: Gustaf Lindström <gl@axentia.se>
Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/gpu/drm/panel/panel-simple.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 113db3c4a633..76f0ef7e5b7c 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1420,6 +1420,30 @@ static const struct panel_desc sharp_lq123p1jx31 = {
 	},
 };
 
+static const struct drm_display_mode sharp_lq150x1lg11_mode = {
+	.clock = 71100,
+	.hdisplay = 1024,
+	.hsync_start = 1024 + 168,
+	.hsync_end = 1024 + 168 + 64,
+	.htotal = 1024 + 168 + 64 + 88,
+	.vdisplay = 768,
+	.vsync_start = 768 + 37,
+	.vsync_end = 768 + 37 + 2,
+	.vtotal = 768 + 37 + 2 + 8,
+	.vrefresh = 60,
+};
+
+static const struct panel_desc sharp_lq150x1lg11 = {
+	.modes = &sharp_lq150x1lg11_mode,
+	.num_modes = 1,
+	.bpc = 6,
+	.size = {
+		.width = 304,
+		.height = 228,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB565_1X16,
+};
+
 static const struct drm_display_mode shelly_sca07010_bfn_lnn_mode = {
 	.clock = 33300,
 	.hdisplay = 800,
@@ -1683,6 +1707,9 @@ static const struct of_device_id platform_of_match[] = {
 		.compatible = "sharp,lq123p1jx31",
 		.data = &sharp_lq123p1jx31,
 	}, {
+		.compatible = "sharp,lq150x1lg11",
+		.data = &sharp_lq150x1lg11,
+	}, {
 		.compatible = "shelly,sca07010-bfn-lnn",
 		.data = &shelly_sca07010_bfn_lnn,
 	}, {
-- 
2.1.4

^ permalink raw reply related

* [PATCH v5 1/2] dt-bindings: display: Add Sharp LQ150X1LG11 panel binding
From: Peter Rosin @ 2016-11-21 15:00 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Peter Rosin, Thierry Reding, David Airlie, Rob Herring,
	Mark Rutland, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1479740449-20201-1-git-send-email-peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>

The Sharp 15" LQ150X1LG11 panel is an XGA TFT LCD panel.

Signed-off-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
---
 .../bindings/display/panel/sharp,lq150x1lg11.txt   | 36 ++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt

diff --git a/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt b/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt
new file mode 100644
index 000000000000..0f57c3143506
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt
@@ -0,0 +1,36 @@
+Sharp 15" LQ150X1LG11 XGA TFT LCD panel
+
+Required properties:
+- compatible: should be "sharp,lq150x1lg11"
+- power-supply: regulator to provide the VCC supply voltage (3.3 volts)
+
+Optional properties:
+- backlight: phandle of the backlight device
+- rlud-gpios: a single GPIO for the RL/UD (rotate 180 degrees) pin.
+- sellvds-gpios: a single GPIO for the SELLVDS pin.
+
+If rlud-gpios and/or sellvds-gpios are not specified, the RL/UD and/or SELLVDS
+pins are assumed to be handled appropriately by the hardware.
+
+Example:
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 100000>;                      /* VBR */
+
+		brightness-levels = <0 20 40 60 80 100>;
+		default-brightness-level = <2>;
+
+		power-supply = <&vdd_12v_reg>;               /* VDD */
+		enable-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;  /* XSTABY */
+	};
+
+	panel {
+		compatible = "sharp,lq150x1lg11";
+
+		power-supply = <&vcc_3v3_reg>;               /* VCC */
+
+		backlight = <&backlight>;
+		rlud-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;    /* RL/UD */
+		sellvds-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; /* SELLVDS */
+	};
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v5 0/2] drm/panel: simple: add support for Sharp LQ150X1LG11 panels
From: Peter Rosin @ 2016-11-21 15:00 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Peter Rosin, Thierry Reding, David Airlie, Rob Herring,
	Mark Rutland, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA

Hi!

This patch seems to have been forgotten? Thierry said that a
resend was not needed, but time is passing and the merge window
is nearing, so I'm resending anyway with the squashed .bpc-fix.

v4 -> v5 changes:
- change sharp_lq150x1lg11.bpc to 6 as noted by Thierry
- rebased onto v4.9-rc6

v3 -> v4 changes:
- addressed review comments from Rob (lvds -> sellvds and a couple of typos).

Cheers,
Peter

Gustaf Lindström (1):
  drm/panel: simple: add support for Sharp LQ150X1LG11 panels

Peter Rosin (1):
  dt-bindings: display: Add Sharp LQ150X1LG11 panel binding

 .../bindings/display/panel/sharp,lq150x1lg11.txt   | 36 ++++++++++++++++++++++
 drivers/gpu/drm/panel/panel-simple.c               | 27 ++++++++++++++++
 2 files changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt

-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v4 2/2] Add support for OV5647 sensor
From: Ramiro Oliveira @ 2016-11-21 15:00 UTC (permalink / raw)
  To: Pavel Machek, Ramiro Oliveira
  Cc: mchehab-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, devicetree-u79uwXL29TY76Z2rM5mHXA,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-0h96xk9xTtrk1uMJSBkQmQ, hverkuil-qWit8jRvyhVmR6Xm/wNWPw,
	dheitmueller-eb9eJ82Ua7k9XoPSrs7Ehg,
	slongerbeam-Re5JQEeQqe8AvxtiuMwx3w, lars-Qo5EllUWu/uELgA04lAiVw,
	robert.jarzmik-GANU6spQydw, pali.rohar-Re5JQEeQqe8AvxtiuMwx3w,
	sakari.ailus-VuQAYsv1563Yd54FQh9/CA, mark.rutland-5wv7dgnIgG8,
	CARLOS.PALMINHA-HKixBCOQz3hWk0Htik3J/w
In-Reply-To: <20161115121032.GB7018@amd>

Hi Pavel!

On 11/15/2016 12:10 PM, Pavel Machek wrote:
> Hi!
> 
>> Add support for OV5647 sensor.
>>
> 
>> +static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
>> +{
>> +	int ret;
>> +	unsigned char data[3] = { reg >> 8, reg & 0xff, val};
>> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
>> +
>> +	ret = i2c_master_send(client, data, 3);
>> +	if (ret != 3) {
>> +		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
>> +				__func__, reg);
>> +		return ret < 0 ? ret : -EIO;
>> +	}
>> +	return 0;
>> +}
> 
> Sorry, this is wrong. It should something <0 any time error is detected.
> 
>> +static int ov5647_write_array(struct v4l2_subdev *sd,
>> +				struct regval_list *regs, int array_size)
>> +{
>> +	int i = 0;
>> +	int ret = 0;
>> +
>> +	if (!regs)
>> +		return -EINVAL;
>> +
>> +	while (i < array_size) {
>> +		ret = ov5647_write(sd, regs->addr, regs->data);
>> +		if (ret < 0)
>> +			return ret;
>> +		i++;
>> +		regs++;
>> +	}
>> +	return 0;
>> +}
> 
> For example this expects <0 on error.
> 
>> +static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
>> +{
>> +	int ret;
>> +	unsigned char rdval;
>> +
>> +	ret = ov5647_read(sd, 0x0100, &rdval);
>> +	if (ret != 0)
>> +		return ret;
>> +
>> +	if (standby)
>> +		ret = ov5647_write(sd, 0x0100, rdval&0xfe);
>> +	else
>> +		ret = ov5647_write(sd, 0x0100, rdval|0x01);
>> +
>> +	return ret;
> 
> if (standby)
>      rdval &= 0xfe;
> else
>      rdval |= 0x01;
> 
> ret = ov5647_write(sd, 0x0100, rdval);
> 
> ?
> 
> 
>> +/**
>> + * @short Store information about the video data format.
>> + */
>> +static struct sensor_format_struct {
>> +	__u8 *desc;
>> +	u32 mbus_code;
> 
> u8 is suitable here.
> 
> 
>> +	ov5647_read(sd, 0x0100, &resetval);
>> +		if (!resetval&0x01) {
> 
> add ()s here.
> 
>> +static int sensor_power(struct v4l2_subdev *sd, int on)
>> +{
>> +	int ret;
>> +	struct ov5647 *ov5647 = to_state(sd);
>> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
>> +
>> +	ret = 0;
>> +	mutex_lock(&ov5647->lock);
>> +
>> +	if (on)	{
>> +		dev_dbg(&client->dev, "OV5647 power on!\n");
>> +
>> +		ret = ov5647_write_array(sd, sensor_oe_enable_regs,
>> +				ARRAY_SIZE(sensor_oe_enable_regs));
>> +
>> +		ret = __sensor_init(sd);
>> +
>> +		if (ret < 0)
>> +			dev_err(&client->dev,
>> +				"Camera not available! Check Power!\n");
>> +	} else {
>> +		dev_dbg(&client->dev, "OV5647 power off!\n");
>> +
>> +		dev_dbg(&client->dev, "disable oe\n");
>> +		ret = ov5647_write_array(sd, sensor_oe_disable_regs,
>> +				ARRAY_SIZE(sensor_oe_disable_regs));
>> +
>> +		if (ret < 0)
>> +			dev_dbg(&client->dev, "disable oe failed!\n");
>> +
>> +		ret = set_sw_standby(sd, true);
>> +
>> +		if (ret < 0)
>> +			dev_dbg(&client->dev, "soft stby failed!\n");
> 
> dev_err for errors? Little less "!"s in the output?
> 
>> +static int sensor_get_register(struct v4l2_subdev *sd,
>> +				struct v4l2_dbg_register *reg)
>> +{
>> +	unsigned char val = 0;
>> +	int ret;
>> +
>> +	ret = ov5647_read(sd, reg->reg & 0xff, &val);
>> +	reg->val = val;
>> +	reg->size = 1;
>> +	return ret;
>> +}
> 
> Filling reg->* when read failed is strange.
> 
>> +static int sensor_set_register(struct v4l2_subdev *sd,
>> +				const struct v4l2_dbg_register *reg)
>> +{
>> +	ov5647_write(sd, reg->reg & 0xff, reg->val & 0xff);
>> +	return 0;
>> +}
> 
> error handling?
> 
> Best regards,
> 									Pavel
> 

Thanks for the feedback, I've corrected all the issues you pointed out, except
the one regarding the error handling in the ov5647_write function.

Best Regards,
Ramiro
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v3 2/3] drm/bridge: Add ti-tfp410 DVI transmitter driver
From: Rob Herring @ 2016-11-21 14:55 UTC (permalink / raw)
  To: Jyri Sarha
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	bcousson-rdvid1DuHRBWk0Htik3J/w, khilman-rdvid1DuHRBWk0Htik3J/w,
	bgolaszewski-rdvid1DuHRBWk0Htik3J/w, tomi.valkeinen-l0cyMroinI0,
	laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw
In-Reply-To: <6eaa1b5d467cd354f7d5dc5ff8da1b9bf732ff11.1479388871.git.jsarha-l0cyMroinI0@public.gmane.org>

On Thu, Nov 17, 2016 at 03:28:47PM +0200, Jyri Sarha wrote:
> Add very basic ti-ftp410 DVI transmitter driver. The only feature
> separating this from a completely dummy bridge is the EDID read
> support trough DDC I2C. Even that functionality should be in a
> separate generic connector driver. However, because of missing DRM
> infrastructure support the connector is implemented within the bridge
> driver. Some tfp410 HW specific features may be added later if needed,
> because there is a set of registers behind i2c if it is connected.
> 
> This implementation is tested against my new tilcdc bridge support
> and it works with BeagleBone DVI-D Cape Rev A3. A DT binding document
> is also added.
> 
> Signed-off-by: Jyri Sarha <jsarha-l0cyMroinI0@public.gmane.org>
> ---
>  .../bindings/display/bridge/ti,tfp410.txt          |  40 +++

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

>  drivers/gpu/drm/bridge/Kconfig                     |   7 +
>  drivers/gpu/drm/bridge/Makefile                    |   1 +
>  drivers/gpu/drm/bridge/ti-tfp410.c                 | 287 +++++++++++++++++++++
>  4 files changed, 335 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
>  create mode 100644 drivers/gpu/drm/bridge/ti-tfp410.c
--
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 0/3] Add Mediatek JPEG Decoder
From: Hans Verkuil @ 2016-11-21 14:53 UTC (permalink / raw)
  To: Rick Chang, Hans Verkuil, Laurent Pinchart, Mauro Carvalho Chehab,
	Matthias Brugger, Rob Herring
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Minghsiu Tsai
In-Reply-To: <1479353915-5043-1-git-send-email-rick.chang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

I'm missing a MAINTAINERS patch for this new driver.

Can you post a patch for that?

It's the only thing preventing this from being merged.

Regards,

	Hans

On 17/11/16 04:38, Rick Chang wrote:
> This series of patches provide a v4l2 driver to control Mediatek JPEG decoder
> for decoding JPEG image and Motion JPEG bitstream.
>
> changes since v5:
> - remove redundant name from struct mtk_jpeg_fmt
> - Set state of all buffers to VB2_BUF_STATE_QUEUED if fail in start streaming
> - Remove VB2_USERPTR
> - Add check for buffer index
>
> changes since v4:
> - Change file name of binding documentation
> - Revise DT binding documentation
> - Revise compatible string
>
> changes since v3:
> - Revise DT binding documentation
> - Revise compatible string
>
> changes since v2:
> - Revise DT binding documentation
>
> changes since v1:
> - Rebase for v4.9-rc1.
> - Update Compliance test version and result
> - Remove redundant path in Makefile
> - Fix potential build error without CONFIG_PM_RUNTIME and CONFIG_PM_SLEEP
> - Fix warnings from patch check and smatch check
>
> * Dependency
> The patch "arm: dts: mt2701: Add node for JPEG decoder" depends on:
>   CCF "Add clock support for Mediatek MT2701"[1]
>   iommu and smi "Add the dtsi node of iommu and smi for mt2701"[2]
>
> [1] http://lists.infradead.org/pipermail/linux-mediatek/2016-October/007271.html
> [2] https://patchwork.kernel.org/patch/9164013/
>
> * Compliance test
> v4l2-compliance SHA   : 4ad7174b908a36c4f315e3fe2efa7e2f8a6f375a
>
> Driver Info:
>         Driver name   : mtk-jpeg decode
>         Card type     : mtk-jpeg decoder
>         Bus info      : platform:15004000.jpegdec
>         Driver version: 4.9.0
>         Capabilities  : 0x84204000
>                 Video Memory-to-Memory Multiplanar
>                 Streaming
>                 Extended Pix Format
>                 Device Capabilities
>         Device Caps   : 0x04204000
>                 Video Memory-to-Memory Multiplanar
>                 Streaming
>                 Extended Pix Format
>
> Compliance test for device /dev/video3 (not using libv4l2):
>
> Required ioctls:
>         test VIDIOC_QUERYCAP: OK
>
> Allow for multiple opens:
>         test second video open: OK
>         test VIDIOC_QUERYCAP: OK
>         test VIDIOC_G/S_PRIORITY: OK
>         test for unlimited opens: OK
>
> Debug ioctls:
>         test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
>         test VIDIOC_LOG_STATUS: OK (Not Supported)
>
> Input ioctls:
>         test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
>         test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>         test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
>         test VIDIOC_ENUMAUDIO: OK (Not Supported)
>         test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
>         test VIDIOC_G/S_AUDIO: OK (Not Supported)
>         Inputs: 0 Audio Inputs: 0 Tuners: 0
>
> Output ioctls:
>         test VIDIOC_G/S_MODULATOR: OK (Not Supported)
>         test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>         test VIDIOC_ENUMAUDOUT: OK (Not Supported)
>         test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
>         test VIDIOC_G/S_AUDOUT: OK (Not Supported)
>         Outputs: 0 Audio Outputs: 0 Modulators: 0
>
> Input/Output configuration ioctls:
>         test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
>         test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
>         test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
>         test VIDIOC_G/S_EDID: OK (Not Supported)
>
>         Control ioctls:
>                 test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
>                 test VIDIOC_QUERYCTRL: OK (Not Supported)
>                 test VIDIOC_G/S_CTRL: OK (Not Supported)
>                 test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
>                 test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
>                 test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
>                 Standard Controls: 0 Private Controls: 0
>
>         Format ioctls:
>                 test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
>                 test VIDIOC_G/S_PARM: OK (Not Supported)
>                 test VIDIOC_G_FBUF: OK (Not Supported)
>                 test VIDIOC_G_FMT: OK
>                 test VIDIOC_TRY_FMT: OK
>                 test VIDIOC_S_FMT: OK
>                 test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
>                 test Cropping: OK (Not Supported)
>                 test Composing: OK
>                 test Scaling: OK
>
>         Codec ioctls:
>                 test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
>                 test VIDIOC_G_ENC_INDEX: OK (Not Supported)
>                 test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
>
>         Buffer ioctls:
>                 test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
>                 test VIDIOC_EXPBUF: OK
>
> Test input 0:
>
>
> Total: 43, Succeeded: 43, Failed: 0, Warnings: 0
>
> Rick Chang (3):
>   dt-bindings: mediatek: Add a binding for Mediatek JPEG Decoder
>   vcodec: mediatek: Add Mediatek JPEG Decoder Driver
>   arm: dts: mt2701: Add node for Mediatek JPEG Decoder
>
>  .../bindings/media/mediatek-jpeg-decoder.txt       |   37 +
>  arch/arm/boot/dts/mt2701.dtsi                      |   14 +
>  drivers/media/platform/Kconfig                     |   15 +
>  drivers/media/platform/Makefile                    |    2 +
>  drivers/media/platform/mtk-jpeg/Makefile           |    2 +
>  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c    | 1303 ++++++++++++++++++++
>  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h    |  139 +++
>  drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c      |  417 +++++++
>  drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h      |   91 ++
>  drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c   |  160 +++
>  drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h   |   25 +
>  drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h     |   58 +
>  12 files changed, 2263 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
>  create mode 100644 drivers/media/platform/mtk-jpeg/Makefile
>  create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
>  create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
>  create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c
>  create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h
>  create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
>  create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h
>  create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h
>
--
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 3/3] arm: dts: mt2701: Add node for Mediatek JPEG Decoder
From: Hans Verkuil @ 2016-11-21 14:51 UTC (permalink / raw)
  To: Rick Chang, Hans Verkuil, Laurent Pinchart, Mauro Carvalho Chehab,
	Matthias Brugger, Rob Herring
  Cc: linux-kernel, linux-media, srv_heupstream, linux-mediatek,
	linux-arm-kernel, devicetree, Minghsiu Tsai
In-Reply-To: <1479353915-5043-4-git-send-email-rick.chang@mediatek.com>

On 17/11/16 04:38, Rick Chang wrote:
> Signed-off-by: Rick Chang <rick.chang@mediatek.com>
> Signed-off-by: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
> ---
> This patch depends on:
>   CCF "Add clock support for Mediatek MT2701"[1]
>   iommu and smi "Add the dtsi node of iommu and smi for mt2701"[2]
>
> [1] http://lists.infradead.org/pipermail/linux-mediatek/2016-October/007271.html
> [2] https://patchwork.kernel.org/patch/9164013/

I assume that 1 & 2 will appear in 4.10? So this patch needs to go in 
after the
other two are merged in 4.10?

Regards,

	Hans

> ---
>  arch/arm/boot/dts/mt2701.dtsi | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index 8f13c70..4dd5048 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -298,6 +298,20 @@
>  		power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
>  	};
>
> +	jpegdec: jpegdec@15004000 {
> +		compatible = "mediatek,mt2701-jpgdec";
> +		reg = <0 0x15004000 0 0x1000>;
> +		interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>;
> +		clocks =  <&imgsys CLK_IMG_JPGDEC_SMI>,
> +			  <&imgsys CLK_IMG_JPGDEC>;
> +		clock-names = "jpgdec-smi",
> +			      "jpgdec";
> +		power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
> +		mediatek,larb = <&larb2>;
> +		iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
> +			 <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
> +	};
> +
>  	vdecsys: syscon@16000000 {
>  		compatible = "mediatek,mt2701-vdecsys", "syscon";
>  		reg = <0 0x16000000 0 0x1000>;
>

^ permalink raw reply

* Re: [PATCH 2/4] [media] davinci: vpif_capture: don't lock over s_stream
From: Hans Verkuil @ 2016-11-21 14:37 UTC (permalink / raw)
  To: Kevin Hilman, linux-media
  Cc: devicetree, Sekhar Nori, Axel Haslam, Bartosz Gołaszewski,
	Alexandre Bailon, David Lechner
In-Reply-To: <20161119003208.10550-2-khilman@baylibre.com>

On 19/11/16 01:32, Kevin Hilman wrote:
> Video capture subdevs may be over I2C and may sleep during xfer, so we
> cannot do IRQ-disabled locking when calling the subdev.
>
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
> ---
>  drivers/media/platform/davinci/vpif_capture.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
> index 79cef74e164f..becc3e63b472 100644
> --- a/drivers/media/platform/davinci/vpif_capture.c
> +++ b/drivers/media/platform/davinci/vpif_capture.c
> @@ -193,12 +193,16 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
>  		}
>  	}
>
> +	spin_unlock_irqrestore(&common->irqlock, flags);
> +
>  	ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
>  	if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
>  		vpif_dbg(1, debug, "stream on failed in subdev\n");
>  		goto err;
>  	}
>
> +	spin_lock_irqsave(&common->irqlock, flags);

This needs to be moved to right after the v4l2_subdev_call, otherwise the
goto err above will not have the spinlock.

	Hans

> +
>  	/* Call vpif_set_params function to set the parameters and addresses */
>  	ret = vpif_set_video_params(vpif, ch->channel_id);
>  	if (ret < 0) {
>

^ permalink raw reply

* Re: [PATCH v3 5/7] iio: multiplexer: new iio category and iio-mux driver
From: kbuild test robot @ 2016-11-21 14:33 UTC (permalink / raw)
  Cc: kbuild-all, linux-kernel, Peter Rosin, Wolfram Sang, Rob Herring,
	Mark Rutland, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Jonathan Corbet,
	Arnd Bergmann, Greg Kroah-Hartman, linux-i2c, devicetree,
	linux-iio, linux-doc
In-Reply-To: <1479734235-18837-6-git-send-email-peda@axentia.se>

[-- Attachment #1: Type: text/plain, Size: 6412 bytes --]

Hi Peter,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.9-rc6]
[cannot apply to next-20161117]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Peter-Rosin/mux-controller-abstraction-and-iio-i2c-muxes/20161121-215311
config: x86_64-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/iio/multiplexer/iio-mux.c: In function 'mux_read_avail':
>> drivers/iio/multiplexer/iio-mux.c:134:9: error: implicit declaration of function 'iio_read_avail_channel_raw' [-Werror=implicit-function-declaration]
      ret = iio_read_avail_channel_raw(mux->parent, vals, length);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/multiplexer/iio-mux.c: At top level:
>> drivers/iio/multiplexer/iio-mux.c:174:2: error: unknown field 'read_avail' specified in initializer
     .read_avail = mux_read_avail,
     ^
>> drivers/iio/multiplexer/iio-mux.c:174:16: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .read_avail = mux_read_avail,
                   ^~~~~~~~~~~~~~
   drivers/iio/multiplexer/iio-mux.c:174:16: note: (near initialization for 'mux_info.read_raw_multi')
   drivers/iio/multiplexer/iio-mux.c: In function 'mux_configure_channel':
>> drivers/iio/multiplexer/iio-mux.c:267:6: error: implicit declaration of function 'iio_channel_has_available' [-Werror=implicit-function-declaration]
     if (iio_channel_has_available(pchan, IIO_CHAN_INFO_RAW))
         ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iio/multiplexer/iio-mux.c:268:7: error: 'struct iio_chan_spec' has no member named 'info_mask_separate_available'; did you mean 'info_mask_separate'?
      chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW);
          ^~
   cc1: some warnings being treated as errors

vim +/iio_read_avail_channel_raw +134 drivers/iio/multiplexer/iio-mux.c

   128		if (ret < 0)
   129			return ret;
   130	
   131		switch (mask) {
   132		case IIO_CHAN_INFO_RAW:
   133			*type = IIO_VAL_INT;
 > 134			ret = iio_read_avail_channel_raw(mux->parent, vals, length);
   135			break;
   136	
   137		default:
   138			ret = -EINVAL;
   139		}
   140	
   141		iio_mux_deselect(mux);
   142	
   143		return ret;
   144	}
   145	
   146	static int mux_write_raw(struct iio_dev *indio_dev,
   147				 struct iio_chan_spec const *chan,
   148				 int val, int val2, long mask)
   149	{
   150		struct mux *mux = iio_priv(indio_dev);
   151		int idx = chan - mux->chan;
   152		int ret;
   153	
   154		ret = iio_mux_select(mux, idx);
   155		if (ret < 0)
   156			return ret;
   157	
   158		switch (mask) {
   159		case IIO_CHAN_INFO_RAW:
   160			ret = iio_write_channel_raw(mux->parent, val);
   161			break;
   162	
   163		default:
   164			ret = -EINVAL;
   165		}
   166	
   167		iio_mux_deselect(mux);
   168	
   169		return ret;
   170	}
   171	
   172	static const struct iio_info mux_info = {
   173		.read_raw = mux_read_raw,
 > 174		.read_avail = mux_read_avail,
   175		.write_raw = mux_write_raw,
   176		.driver_module = THIS_MODULE,
   177	};
   178	
   179	static ssize_t mux_read_ext_info(struct iio_dev *indio_dev, uintptr_t private,
   180					 struct iio_chan_spec const *chan, char *buf)
   181	{
   182		struct mux *mux = iio_priv(indio_dev);
   183		int idx = chan - mux->chan;
   184		ssize_t ret;
   185	
   186		ret = iio_mux_select(mux, idx);
   187		if (ret < 0)
   188			return ret;
   189	
   190		ret = iio_read_channel_ext_info(mux->parent,
   191						mux->ext_info[private].name,
   192						buf);
   193	
   194		iio_mux_deselect(mux);
   195	
   196		return ret;
   197	}
   198	
   199	static ssize_t mux_write_ext_info(struct iio_dev *indio_dev, uintptr_t private,
   200					  struct iio_chan_spec const *chan,
   201					  const char *buf, size_t len)
   202	{
   203		struct device *dev = indio_dev->dev.parent;
   204		struct mux *mux = iio_priv(indio_dev);
   205		int idx = chan - mux->chan;
   206		char *new;
   207		ssize_t ret;
   208	
   209		ret = iio_mux_select(mux, idx);
   210		if (ret < 0)
   211			return ret;
   212	
   213		new = devm_kmemdup(dev, buf, len + 1, GFP_KERNEL);
   214		if (!new) {
   215			iio_mux_deselect(mux);
   216			return -ENOMEM;
   217		}
   218	
   219		new[len] = 0;
   220	
   221		ret = iio_write_channel_ext_info(mux->parent,
   222						 mux->ext_info[private].name,
   223						 buf, len);
   224		if (ret < 0) {
   225			iio_mux_deselect(mux);
   226			devm_kfree(dev, new);
   227			return ret;
   228		}
   229	
   230		devm_kfree(dev, mux->child[idx].ext_info_cache[private].data);
   231		mux->child[idx].ext_info_cache[private].data = new;
   232		mux->child[idx].ext_info_cache[private].size = len;
   233	
   234		iio_mux_deselect(mux);
   235	
   236		return ret;
   237	}
   238	
   239	static int mux_configure_channel(struct device *dev, struct mux *mux,
   240					 struct device_node *child_np, int idx)
   241	{
   242		struct mux_child *child = &mux->child[idx];
   243		struct iio_chan_spec *chan = &mux->chan[idx];
   244		struct iio_chan_spec const *pchan = mux->parent->channel;
   245		u32 state;
   246		char *page = NULL;
   247		int num_ext_info;
   248		int i;
   249		int ret;
   250	
   251		chan->indexed = 1;
   252		chan->output = pchan->output;
   253		chan->datasheet_name = child_np->name;
   254		chan->ext_info = mux->ext_info;
   255	
   256		ret = iio_get_channel_type(mux->parent, &chan->type);
   257		if (ret < 0) {
   258			dev_err(dev, "failed to get parent channel type\n");
   259			return ret;
   260		}
   261	
   262		if (iio_channel_has_info(pchan, IIO_CHAN_INFO_RAW))
   263			chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW);
   264		if (iio_channel_has_info(pchan, IIO_CHAN_INFO_SCALE))
   265			chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE);
   266	
 > 267		if (iio_channel_has_available(pchan, IIO_CHAN_INFO_RAW))
 > 268			chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW);
   269	
   270		ret = of_property_read_u32(child_np, "reg", &state);
   271		if (ret < 0) {

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 56692 bytes --]

^ permalink raw reply

* Re: [PATCH 4/4] [media] dt-bindings: add TI VPIF documentation
From: Arnd Bergmann @ 2016-11-21 14:15 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-media, Hans Verkuil, devicetree, Sekhar Nori, Axel Haslam,
	Bartosz Gołaszewski, Alexandre Bailon, David Lechner,
	Rob Herring
In-Reply-To: <20161119003208.10550-4-khilman@baylibre.com>

On Friday, November 18, 2016 4:32:08 PM CET Kevin Hilman wrote:
> +
> +Required properties:
> +- compatible: must be "ti,vpif-capture"
> +- reg: physical base address and length of the registers set for the device;
> +- interrupts: should contain IRQ line for the VPIF
> +
> 

Shouldn't this have a SoC specific identifier or a version number
in the compatible string? "vpif" seems rather generic, so it's
likely that TI made more than one variant of it.

	Arnd

^ permalink raw reply

* Re: [PATCH v3] ARM: at91/dt: add dts file for sama5d36ek CMP board
From: Alexandre Belloni @ 2016-11-21 14:02 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: Nicolas Ferre, Russell King, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Wenyou Yang,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1479705283-3052-1-git-send-email-wenyou.yang-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>

Hi,

I fixed it up this time but please use the proper subject prefix next
time (ARM: dts: at91:).

On 21/11/2016 at 13:14:42 +0800, Wenyou Yang wrote :
> The sama5d36ek CMP board is the variant of sama5d3xek board.
> It is equipped with the low-power DDR2 SDRAM, PMIC ACT8865 and
> some power rail. Its main purpose is used to measure the power
> consumption.
> The difference of the sama5d36ek CMP dts from sama5d36ek dts is
> listed as below.
>  1. The USB host nodes are removed, that is, the USB host is disabled.
>  2. The gpio_keys node is added to wake up from the sleep.
>  3. The LCD isn't supported due to the pins for LCD are conflicted
>     with gpio_keys.
>  4. The adc0 node support the pinctrl sleep state to fix the over
>     consumption on VDDANA.
> 
> As said in errata, "When the USB host ports are used in high speed
> mode (EHCI), it is not possible to suspend the ports if no device is
> attached on each port. This leads to increased power consumption even
> if the system is in a low power mode." That is why the the USB host
> is disabled.
> 
> Signed-off-by: Wenyou Yang <wenyou.yang-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
> ---
> 
> Changes in v3:
>  - Use a dual license scheme for DT files.
>  - Use the proper model name and the compatible string to reflect
>    the nature of this new "CMP" board.
>  - Change name of wakeup property to "wakeup-source".
>  - Remove unnecessary comments.
>  - Remove bootargs.
> 
> Changes in v2:
>  - Add the pinctrl sleep state for adc0 node to fix the over
>    consumption on VDDANA.
>  - Improve the commit log.
> 
>  arch/arm/boot/dts/sama5d36ek_cmp.dts  |  87 ++++++++++
>  arch/arm/boot/dts/sama5d3xcm_cmp.dtsi | 201 +++++++++++++++++++++++
>  arch/arm/boot/dts/sama5d3xmb_cmp.dtsi | 301 ++++++++++++++++++++++++++++++++++
>  3 files changed, 589 insertions(+)
>  create mode 100644 arch/arm/boot/dts/sama5d36ek_cmp.dts
>  create mode 100644 arch/arm/boot/dts/sama5d3xcm_cmp.dtsi
>  create mode 100644 arch/arm/boot/dts/sama5d3xmb_cmp.dtsi
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
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] ARM: dts: at91: sama5d3_uart: fix reg sizes to match documentation
From: Alexandre Belloni @ 2016-11-21 14:01 UTC (permalink / raw)
  To: Peter Rosin
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Nicolas Ferre,
	Jean-Christophe Plagniol-Villard, Rob Herring, Mark Rutland,
	Russell King, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1478764000-32233-1-git-send-email-peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>

On 10/11/2016 at 08:46:40 +0100, Peter Rosin wrote :
> The new size (0x100) also matches the size given in sama5d3.dtsi
> 
> Documentation reference: section 43.6 "Universal Asynchronous
> Receiver Transmitter (UART) User Interface", table 43-4 "Register
> Mapping" in [1].
> 
> [1] Atmel-11121F-ATARM-SAMA5D3-Series-Datasheet_02-Feb-16
> 
> Signed-off-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
> ---
>  arch/arm/boot/dts/sama5d3_uart.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
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 v3 2/2] DW DMAC: add multi-block property to device tree
From: Arnd Bergmann @ 2016-11-21 13:53 UTC (permalink / raw)
  To: Eugeniy Paltsev
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-snps-arc-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1479496356-27834-3-git-send-email-Eugeniy.Paltsev-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>

On Friday, November 18, 2016 10:12:36 PM CET Eugeniy Paltsev wrote:
> +- multi-block: Multi block transfers supported by hardware per AHB master.
> +  0 (default): not supported, 1: supported.

Please clarify that this is an array with one cell per master.
My first thought was "why is this not a boolean property", and
I'm sure others might misread it the same way.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v3 1/2] mfd: pm8xxx: add support to pm8821
From: Lee Jones @ 2016-11-21 13:48 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, Rob Herring, Andy Gross,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	linux-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1479211312-1431-1-git-send-email-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

On Tue, 15 Nov 2016, Srinivas Kandagatla wrote:

> This patch adds support to PM8821 PMIC and interrupt support.
> PM8821 is companion device that supplements primary PMIC PM8921 IC.
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> Changes since v2:
> 	- removed few empty lines spotted by Bjorn
> 	- rephrased some debug prints suggested by Bjorn
> 	
>  .../devicetree/bindings/mfd/qcom-pm8xxx.txt        |   1 +
>  drivers/mfd/qcom-pm8xxx.c                          | 231 ++++++++++++++++++++-
>  2 files changed, 222 insertions(+), 10 deletions(-)

Applied, thanks.

> diff --git a/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt b/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt
> index 37a088f..9e5eba4 100644
> --- a/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt
> +++ b/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt
> @@ -10,6 +10,7 @@ voltages and other various functionality to Qualcomm SoCs.
>  	Value type: <string>
>  	Definition: must be one of:
>  		    "qcom,pm8058"
> +		    "qcom,pm8821"
>  		    "qcom,pm8921"
>  
>  - #address-cells:
> diff --git a/drivers/mfd/qcom-pm8xxx.c b/drivers/mfd/qcom-pm8xxx.c
> index 7f9620e..f08758f 100644
> --- a/drivers/mfd/qcom-pm8xxx.c
> +++ b/drivers/mfd/qcom-pm8xxx.c
> @@ -39,6 +39,20 @@
>  #define	SSBI_REG_ADDR_IRQ_CONFIG	(SSBI_REG_ADDR_IRQ_BASE + 7)
>  #define	SSBI_REG_ADDR_IRQ_RT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 8)
>  
> +#define	PM8821_SSBI_REG_ADDR_IRQ_BASE	0x100
> +#define	PM8821_SSBI_REG_ADDR_IRQ_MASTER0 (PM8821_SSBI_REG_ADDR_IRQ_BASE + 0x30)
> +#define	PM8821_SSBI_REG_ADDR_IRQ_MASTER1 (PM8821_SSBI_REG_ADDR_IRQ_BASE + 0xb0)
> +#define	PM8821_SSBI_REG(m, b, offset) \
> +			((m == 0) ? \
> +			(PM8821_SSBI_REG_ADDR_IRQ_MASTER0 + b + offset) : \
> +			(PM8821_SSBI_REG_ADDR_IRQ_MASTER1 + b + offset))
> +#define	PM8821_SSBI_ADDR_IRQ_ROOT(m, b)		PM8821_SSBI_REG(m, b, 0x0)
> +#define	PM8821_SSBI_ADDR_IRQ_CLEAR(m, b)	PM8821_SSBI_REG(m, b, 0x01)
> +#define	PM8821_SSBI_ADDR_IRQ_MASK(m, b)		PM8821_SSBI_REG(m, b, 0x08)
> +#define	PM8821_SSBI_ADDR_IRQ_RT_STATUS(m, b)	PM8821_SSBI_REG(m, b, 0x0f)
> +
> +#define	PM8821_BLOCKS_PER_MASTER	7
> +
>  #define	PM_IRQF_LVL_SEL			0x01	/* level select */
>  #define	PM_IRQF_MASK_FE			0x02	/* mask falling edge */
>  #define	PM_IRQF_MASK_RE			0x04	/* mask rising edge */
> @@ -54,6 +68,7 @@
>  #define REG_HWREV_2		0x0E8  /* PMIC4 revision 2 */
>  
>  #define PM8XXX_NR_IRQS		256
> +#define PM8821_NR_IRQS		112
>  
>  struct pm_irq_chip {
>  	struct regmap		*regmap;
> @@ -65,6 +80,12 @@ struct pm_irq_chip {
>  	u8			config[0];
>  };
>  
> +struct pm_irq_data {
> +	int num_irqs;
> +	const struct irq_domain_ops  *irq_domain_ops;
> +	void (*irq_handler)(struct irq_desc *desc);
> +};
> +
>  static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
>  				 unsigned int *ip)
>  {
> @@ -182,6 +203,78 @@ static void pm8xxx_irq_handler(struct irq_desc *desc)
>  	chained_irq_exit(irq_chip, desc);
>  }
>  
> +static void pm8821_irq_block_handler(struct pm_irq_chip *chip,
> +				     int master, int block)
> +{
> +	int pmirq, irq, i, ret;
> +	unsigned int bits;
> +
> +	ret = regmap_read(chip->regmap,
> +			  PM8821_SSBI_ADDR_IRQ_ROOT(master, block), &bits);
> +	if (ret) {
> +		pr_err("Reading block %d failed ret=%d", block, ret);
> +		return;
> +	}
> +
> +	/* Convert block offset to global block number */
> +	block += (master * PM8821_BLOCKS_PER_MASTER) - 1;
> +
> +	/* Check IRQ bits */
> +	for (i = 0; i < 8; i++) {
> +		if (bits & BIT(i)) {
> +			pmirq = block * 8 + i;
> +			irq = irq_find_mapping(chip->irqdomain, pmirq);
> +			generic_handle_irq(irq);
> +		}
> +	}
> +}
> +
> +static inline void pm8821_irq_master_handler(struct pm_irq_chip *chip,
> +					     int master, u8 master_val)
> +{
> +	int block;
> +
> +	for (block = 1; block < 8; block++)
> +		if (master_val & BIT(block))
> +			pm8821_irq_block_handler(chip, master, block);
> +}
> +
> +static void pm8821_irq_handler(struct irq_desc *desc)
> +{
> +	struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
> +	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
> +	unsigned int master;
> +	int ret;
> +
> +	chained_irq_enter(irq_chip, desc);
> +	ret = regmap_read(chip->regmap,
> +			  PM8821_SSBI_REG_ADDR_IRQ_MASTER0, &master);
> +	if (ret) {
> +		pr_err("Failed to read master 0 ret=%d\n", ret);
> +		goto done;
> +	}
> +
> +	/* bits 1 through 7 marks the first 7 blocks in master 0 */
> +	if (master & GENMASK(7, 1))
> +		pm8821_irq_master_handler(chip, 0, master);
> +
> +	/* bit 0 marks if master 1 contains any bits */
> +	if (!(master & BIT(0)))
> +		goto done;
> +
> +	ret = regmap_read(chip->regmap,
> +			  PM8821_SSBI_REG_ADDR_IRQ_MASTER1, &master);
> +	if (ret) {
> +		pr_err("Failed to read master 1 ret=%d\n", ret);
> +		goto done;
> +	}
> +
> +	pm8821_irq_master_handler(chip, 1, master);
> +
> +done:
> +	chained_irq_exit(irq_chip, desc);
> +}
> +
>  static void pm8xxx_irq_mask_ack(struct irq_data *d)
>  {
>  	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
> @@ -299,6 +392,104 @@ static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
>  	.map = pm8xxx_irq_domain_map,
>  };
>  
> +static void pm8821_irq_mask_ack(struct irq_data *d)
> +{
> +	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
> +	unsigned int pmirq = irqd_to_hwirq(d);
> +	u8 block, master;
> +	int irq_bit, rc;
> +
> +	block = pmirq / 8;
> +	master = block / PM8821_BLOCKS_PER_MASTER;
> +	irq_bit = pmirq % 8;
> +	block %= PM8821_BLOCKS_PER_MASTER;
> +
> +	rc = regmap_update_bits(chip->regmap,
> +				PM8821_SSBI_ADDR_IRQ_MASK(master, block),
> +				BIT(irq_bit), BIT(irq_bit));
> +	if (rc) {
> +		pr_err("Failed to mask IRQ:%d rc=%d\n", pmirq, rc);
> +		return;
> +	}
> +
> +	rc = regmap_update_bits(chip->regmap,
> +				PM8821_SSBI_ADDR_IRQ_CLEAR(master, block),
> +				BIT(irq_bit), BIT(irq_bit));
> +	if (rc)
> +		pr_err("Failed to CLEAR IRQ:%d rc=%d\n", pmirq, rc);
> +}
> +
> +static void pm8821_irq_unmask(struct irq_data *d)
> +{
> +	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
> +	unsigned int pmirq = irqd_to_hwirq(d);
> +	int irq_bit, rc;
> +	u8 block, master;
> +
> +	block = pmirq / 8;
> +	master = block / PM8821_BLOCKS_PER_MASTER;
> +	irq_bit = pmirq % 8;
> +	block %= PM8821_BLOCKS_PER_MASTER;
> +
> +	rc = regmap_update_bits(chip->regmap,
> +				PM8821_SSBI_ADDR_IRQ_MASK(master, block),
> +				BIT(irq_bit), ~BIT(irq_bit));
> +	if (rc)
> +		pr_err("Failed to read/write unmask IRQ:%d rc=%d\n", pmirq, rc);
> +
> +}
> +
> +static int pm8821_irq_get_irqchip_state(struct irq_data *d,
> +					enum irqchip_irq_state which,
> +					bool *state)
> +{
> +	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
> +	int rc, pmirq = irqd_to_hwirq(d);
> +	u8 block, irq_bit, master;
> +	unsigned int bits;
> +
> +	block = pmirq / 8;
> +	master = block / PM8821_BLOCKS_PER_MASTER;
> +	irq_bit = pmirq % 8;
> +	block %= PM8821_BLOCKS_PER_MASTER;
> +
> +	rc = regmap_read(chip->regmap,
> +		PM8821_SSBI_ADDR_IRQ_RT_STATUS(master, block), &bits);
> +	if (rc) {
> +		pr_err("Reading Status of IRQ %d failed rc=%d\n", pmirq, rc);
> +		return rc;
> +	}
> +
> +	*state = !!(bits & BIT(irq_bit));
> +
> +	return rc;
> +}
> +
> +static struct irq_chip pm8821_irq_chip = {
> +	.name		= "pm8821",
> +	.irq_mask_ack	= pm8821_irq_mask_ack,
> +	.irq_unmask	= pm8821_irq_unmask,
> +	.irq_get_irqchip_state = pm8821_irq_get_irqchip_state,
> +	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
> +};
> +
> +static int pm8821_irq_domain_map(struct irq_domain *d, unsigned int irq,
> +				   irq_hw_number_t hwirq)
> +{
> +	struct pm_irq_chip *chip = d->host_data;
> +
> +	irq_set_chip_and_handler(irq, &pm8821_irq_chip, handle_level_irq);
> +	irq_set_chip_data(irq, chip);
> +	irq_set_noprobe(irq);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops pm8821_irq_domain_ops = {
> +	.xlate = irq_domain_xlate_twocell,
> +	.map = pm8821_irq_domain_map,
> +};
> +
>  static const struct regmap_config ssbi_regmap_config = {
>  	.reg_bits = 16,
>  	.val_bits = 8,
> @@ -308,22 +499,41 @@ static const struct regmap_config ssbi_regmap_config = {
>  	.reg_write = ssbi_reg_write
>  };
>  
> +static const struct pm_irq_data pm8xxx_data = {
> +	.num_irqs = PM8XXX_NR_IRQS,
> +	.irq_domain_ops = &pm8xxx_irq_domain_ops,
> +	.irq_handler = pm8xxx_irq_handler,
> +};
> +
> +static const struct pm_irq_data pm8821_data = {
> +	.num_irqs = PM8821_NR_IRQS,
> +	.irq_domain_ops = &pm8821_irq_domain_ops,
> +	.irq_handler = pm8821_irq_handler,
> +};
> +
>  static const struct of_device_id pm8xxx_id_table[] = {
> -	{ .compatible = "qcom,pm8018", },
> -	{ .compatible = "qcom,pm8058", },
> -	{ .compatible = "qcom,pm8921", },
> +	{ .compatible = "qcom,pm8018", .data = &pm8xxx_data},
> +	{ .compatible = "qcom,pm8058", .data = &pm8xxx_data},
> +	{ .compatible = "qcom,pm8821", .data = &pm8821_data},
> +	{ .compatible = "qcom,pm8921", .data = &pm8xxx_data},
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
>  
>  static int pm8xxx_probe(struct platform_device *pdev)
>  {
> +	const struct pm_irq_data *data;
>  	struct regmap *regmap;
>  	int irq, rc;
>  	unsigned int val;
>  	u32 rev;
>  	struct pm_irq_chip *chip;
> -	unsigned int nirqs = PM8XXX_NR_IRQS;
> +
> +	data = of_device_get_match_data(&pdev->dev);
> +	if (!data) {
> +		dev_err(&pdev->dev, "No matching driver data found\n");
> +		return -EINVAL;
> +	}
>  
>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0)
> @@ -354,25 +564,26 @@ static int pm8xxx_probe(struct platform_device *pdev)
>  	rev |= val << BITS_PER_BYTE;
>  
>  	chip = devm_kzalloc(&pdev->dev, sizeof(*chip) +
> -					sizeof(chip->config[0]) * nirqs,
> -					GFP_KERNEL);
> +			    sizeof(chip->config[0]) * data->num_irqs,
> +			    GFP_KERNEL);
>  	if (!chip)
>  		return -ENOMEM;
>  
>  	platform_set_drvdata(pdev, chip);
>  	chip->regmap = regmap;
> -	chip->num_irqs = nirqs;
> +	chip->num_irqs = data->num_irqs;
>  	chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
>  	chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
>  	spin_lock_init(&chip->pm_irq_lock);
>  
> -	chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, nirqs,
> -						&pm8xxx_irq_domain_ops,
> +	chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node,
> +						data->num_irqs,
> +						data->irq_domain_ops,
>  						chip);
>  	if (!chip->irqdomain)
>  		return -ENODEV;
>  
> -	irq_set_chained_handler_and_data(irq, pm8xxx_irq_handler, chip);
> +	irq_set_chained_handler_and_data(irq, data->irq_handler, chip);
>  	irq_set_irq_wake(irq, 1);
>  
>  	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v5 3/3] dt-bindings: i2c: pxa: Update the documentation for the Armada 3700
From: Romain Perier @ 2016-11-21 13:32 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Ian Campbell,
	Pawel Moll, Mark Rutland, Kumar Gala,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory Clement,
	Thomas Petazzoni, Nadav Haklai, Omri Itach, Shadi Ammouri,
	Yahuda Yitschak, Hanna Hawa, Neta Zur Hershkovits, Igal Liberman,
	Marcin Wojtas <mw>
In-Reply-To: <20161121133247.29889-1-romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

This commit documents the compatible string to have the compatibility for
the I2C unit found in the Armada 3700.

Signed-off-by: Romain Perier <romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---

Changes in v5:
 - Added the tag 'Acked-by', by Rob Herring

Changes in v2:
 - Fixed wrong compatible string, it should be "marvell,armada-3700-i2c"
   and not "marvell,armada-3700".

 Documentation/devicetree/bindings/i2c/i2c-pxa.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
index 12b78ac..d30f0b1 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
@@ -7,6 +7,7 @@ Required properties :
    compatible processor, e.g. pxa168, pxa910, mmp2, mmp3.
    For the pxa2xx/pxa3xx, an additional node "mrvl,pxa-i2c" is required
    as shown in the example below.
+   For the Armada 3700, the compatible should be "marvell,armada-3700-i2c".
 
 Recommended properties :
 
-- 
2.9.3

--
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 v5 2/3] arm64: dts: marvell: Add I2C definitions for the Armada 3700
From: Romain Perier @ 2016-11-21 13:32 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Ian Campbell,
	Pawel Moll, Mark Rutland, Kumar Gala,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory Clement,
	Thomas Petazzoni, Nadav Haklai, Omri Itach, Shadi Ammouri,
	Yahuda Yitschak, Hanna Hawa, Neta Zur Hershkovits, Igal Liberman,
	Marcin Wojtas <mw>
In-Reply-To: <20161121133247.29889-1-romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

The Armada 3700 has two i2c bus interface units, this commit adds the
definitions of the corresponding device nodes. It also enables the node
on the development board for this SoC.

Signed-off-by: Romain Perier <romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Acked-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 arch/arm64/boot/dts/marvell/armada-3720-db.dts |  4 ++++
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi   | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index 1372e9a6..16d84af 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -62,6 +62,10 @@
 	};
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 /* CON3 */
 &sata {
 	status = "okay";
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index e9bd587..1b0fd21 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -98,6 +98,24 @@
 			/* 32M internal register @ 0xd000_0000 */
 			ranges = <0x0 0x0 0xd0000000 0x2000000>;
 
+			i2c0: i2c@11000 {
+				compatible = "marvell,armada-3700-i2c";
+				reg = <0x11000 0x24>;
+				clocks = <&nb_periph_clk 10>;
+				interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+				mrvl,i2c-fast-mode;
+				status = "disabled";
+			};
+
+			i2c1: i2c@11080 {
+				compatible = "marvell,armada-3700-i2c";
+				reg = <0x11080 0x24>;
+				clocks = <&nb_periph_clk 9>;
+				interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+				mrvl,i2c-fast-mode;
+				status = "disabled";
+			};
+
 			uart0: serial@12000 {
 				compatible = "marvell,armada-3700-uart";
 				reg = <0x12000 0x400>;
-- 
2.9.3

--
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 v5 1/3] i2c: pxa: Add support for the I2C units found in Armada 3700
From: Romain Perier @ 2016-11-21 13:32 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Ian Campbell,
	Pawel Moll, Mark Rutland, Kumar Gala,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory Clement,
	Thomas Petazzoni, Nadav Haklai, Omri Itach, Shadi Ammouri,
	Yahuda Yitschak, Hanna Hawa, Neta Zur Hershkovits, Igal Liberman,
	Marcin Wojtas <mw>
In-Reply-To: <20161121133247.29889-1-romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

The Armada 3700 has two I2C controllers that is compliant with the I2C
Bus Specificiation 2.1, supports multi-master and different bus speed:
Standard mode (up to 100 KHz), Fast mode (up to 400 KHz),
High speed mode (up to 3.4 Mhz).

This IP block has a lot of similarity with the PXA, except some register
offsets and bitfield. This commits adds a basic support for this I2C
unit.

Signed-off-by: Romain Perier <romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Tested-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---

Changes in v5:
 - Don't define registers for armada-3700, we can re-use the ones
   for PXA3XX.
 - Define registers mask when OF is not used, in probe_pdata. 

Changes in v4:
 - Replaced the type of hs_mask and fm_mask by u32, instead of
   unsigned int, As writel() take an u32 as first argument...

Changes in v3:
 - Replaced the type of hs_mask and fm_mask by unsigned int,
   instead of unsigned long.

 drivers/i2c/busses/Kconfig   |  2 +-
 drivers/i2c/busses/i2c-pxa.c | 24 ++++++++++++++++++++++--
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index d252276..2f56a26 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -763,7 +763,7 @@ config I2C_PUV3
 
 config I2C_PXA
 	tristate "Intel PXA2XX I2C adapter"
-	depends on ARCH_PXA || ARCH_MMP || (X86_32 && PCI && OF)
+	depends on ARCH_PXA || ARCH_MMP || ARCH_MVEBU || (X86_32 && PCI && OF)
 	help
 	  If you have devices in the PXA I2C bus, say yes to this option.
 	  This driver can also be built as a module.  If so, the module
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index e28b825..374d17c 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -98,6 +98,7 @@ static const struct platform_device_id i2c_pxa_id_table[] = {
 	{ "pxa3xx-pwri2c",	REGS_PXA3XX },
 	{ "ce4100-i2c",		REGS_CE4100 },
 	{ "pxa910-i2c",		REGS_PXA910 },
+	{ "armada-3700-i2c",	REGS_PXA3XX  },
 	{ },
 };
 MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
@@ -122,7 +123,9 @@ MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
 #define ICR_SADIE	(1 << 13)	   /* slave address detected int enable */
 #define ICR_UR		(1 << 14)	   /* unit reset */
 #define ICR_FM		(1 << 15)	   /* fast mode */
+#define ICR_BUSMODE_FM	(1 << 16)	   /* shifted fast mode for armada-3700 */
 #define ICR_HS		(1 << 16)	   /* High Speed mode */
+#define ICR_BUSMODE_HS	(1 << 17)	   /* shifted high speed mode for armada-3700 */
 #define ICR_GPIOEN	(1 << 19)	   /* enable GPIO mode for SCL in HS */
 
 #define ISR_RWM		(1 << 0)	   /* read/write mode */
@@ -193,6 +196,8 @@ struct pxa_i2c {
 	unsigned char		master_code;
 	unsigned long		rate;
 	bool			highmode_enter;
+	u32			fm_mask;
+	u32			hs_mask;
 };
 
 #define _IBMR(i2c)	((i2c)->reg_ibmr)
@@ -503,8 +508,8 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
 		writel(i2c->slave_addr, _ISAR(i2c));
 
 	/* set control register values */
-	writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
-	writel(readl(_ICR(i2c)) | (i2c->high_mode ? ICR_HS : 0), _ICR(i2c));
+	writel(I2C_ICR_INIT | (i2c->fast_mode ? i2c->fm_mask : 0), _ICR(i2c));
+	writel(readl(_ICR(i2c)) | (i2c->high_mode ? i2c->hs_mask : 0), _ICR(i2c));
 
 #ifdef CONFIG_I2C_PXA_SLAVE
 	dev_info(&i2c->adap.dev, "Enabling slave mode\n");
@@ -1137,6 +1142,7 @@ static const struct of_device_id i2c_pxa_dt_ids[] = {
 	{ .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
 	{ .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
 	{ .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
+	{ .compatible = "marvell,armada-3700-i2c", .data = (void *)REGS_PXA3XX },
 	{}
 };
 MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
@@ -1158,6 +1164,13 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
 		i2c->use_pio = 1;
 	if (of_get_property(np, "mrvl,i2c-fast-mode", NULL))
 		i2c->fast_mode = 1;
+	if (of_device_is_compatible(np, "marvell,armada-3700-i2c")) {
+		i2c->fm_mask = ICR_BUSMODE_FM;
+		i2c->hs_mask = ICR_BUSMODE_HS;
+	} else {
+		i2c->fm_mask = ICR_FM;
+		i2c->hs_mask = ICR_HS;
+	}
 
 	*i2c_types = (enum pxa_i2c_types)(of_id->data);
 
@@ -1181,6 +1194,13 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev,
 			i2c->master_code = 0xe;
 		i2c->rate = plat->rate;
 	}
+	if (!strcmp(id->name, "armada-3700-i2c")) {
+		i2c->fm_mask = ICR_BUSMODE_FM;
+		i2c->hs_mask = ICR_BUSMODE_HS;
+	} else {
+		i2c->fm_mask = ICR_FM;
+		i2c->hs_mask = ICR_HS;
+	}
 	return 0;
 }
 
-- 
2.9.3

--
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 v5 0/3] Add basic support for the I2C units of the Armada 3700
From: Romain Perier @ 2016-11-21 13:32 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c
  Cc: devicetree, Rob Herring, Ian Campbell, Pawel Moll, Mark Rutland,
	Kumar Gala, linux-arm-kernel, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Gregory Clement, Thomas Petazzoni,
	Nadav Haklai, Omri Itach, Shadi Ammouri, Yahuda Yitschak,
	Hanna Hawa, Neta Zur Hershkovits, Igal Liberman,
	Marcin Wojtas <mw>

This series add basic support for the I2C bus interface units present
in the Armada 3700 to the pxa-i2c driver. It also add the definitions of
the device nodes to the devicetree at the SoC level and for its official
development board: the Armada 3720 DB.

Romain Perier (3):
  i2c: pxa: Add support for the I2C units found in Armada 3700
  arm64: dts: marvell: Add I2C definitions for the Armada 3700
  dt-bindings: i2c: pxa: Update the documentation for the Armada 3700

 Documentation/devicetree/bindings/i2c/i2c-pxa.txt |  1 +
 arch/arm64/boot/dts/marvell/armada-3720-db.dts    |  4 ++++
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi      | 18 +++++++++++++++++
 drivers/i2c/busses/Kconfig                        |  2 +-
 drivers/i2c/busses/i2c-pxa.c                      | 24 +++++++++++++++++++++--
 5 files changed, 46 insertions(+), 3 deletions(-)

-- 
2.9.3

^ permalink raw reply

* Re: [PATCH] PM / Domains: Fix compatible for domain idle state
From: Ulf Hansson @ 2016-11-21 13:27 UTC (permalink / raw)
  To: Lina Iyer
  Cc: devicetree@vger.kernel.org, Lorenzo Pieralisi, Juri Lelli,
	linux-pm@vger.kernel.org, Rafael J. Wysocki, Kevin Hilman,
	Stephen Boyd, Sudeep Holla, Brendan Jackman,
	linux-arm-msm@vger.kernel.org, Andy Gross,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <1478210075-92045-2-git-send-email-lina.iyer@linaro.org>

On 3 November 2016 at 22:54, Lina Iyer <lina.iyer@linaro.org> wrote:
> Re-using idle state definition provided by arm,idle-state for domain
> idle states creates a lot of confusion and limits further evolution of
> the domain idle definition. To keep things clear and simple, define a
> idle states for domain using a new compatible "domain-idle-state".
>
> Fix existing PM domains code to look for the newly defined compatible.
>
> Cc: <devicetree@vger.kernel.org>
> Cc: Rob Herring <robh@kernel.org>
> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

Kind regards
Uffe

> ---
>  .../bindings/power/domain-idle-state.txt           | 33 ++++++++++++++++++++++
>  .../devicetree/bindings/power/power_domain.txt     |  8 +++---
>  drivers/base/power/domain.c                        |  2 +-
>  3 files changed, 38 insertions(+), 5 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/power/domain-idle-state.txt
>
> diff --git a/Documentation/devicetree/bindings/power/domain-idle-state.txt b/Documentation/devicetree/bindings/power/domain-idle-state.txt
> new file mode 100644
> index 0000000..eefc7ed
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/domain-idle-state.txt
> @@ -0,0 +1,33 @@
> +PM Domain Idle State Node:
> +
> +A domain idle state node represents the state parameters that will be used to
> +select the state when there are no active components in the domain.
> +
> +The state node has the following parameters -
> +
> +- compatible:
> +       Usage: Required
> +       Value type: <string>
> +       Definition: Must be "domain-idle-state".
> +
> +- entry-latency-us
> +       Usage: Required
> +       Value type: <prop-encoded-array>
> +       Definition: u32 value representing worst case latency in
> +                   microseconds required to enter the idle state.
> +                   The exit-latency-us duration may be guaranteed
> +                   only after entry-latency-us has passed.
> +
> +- exit-latency-us
> +       Usage: Required
> +       Value type: <prop-encoded-array>
> +       Definition: u32 value representing worst case latency
> +                   in microseconds required to exit the idle state.
> +
> +- min-residency-us
> +       Usage: Required
> +       Value type: <prop-encoded-array>
> +       Definition: u32 value representing minimum residency duration
> +                   in microseconds after which the idle state will yield
> +                   power benefits after overcoming the overhead in entering
> +i                  the idle state.
> diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
> index e165036..723e1ad 100644
> --- a/Documentation/devicetree/bindings/power/power_domain.txt
> +++ b/Documentation/devicetree/bindings/power/power_domain.txt
> @@ -31,7 +31,7 @@ Optional properties:
>
>  - domain-idle-states : A phandle of an idle-state that shall be soaked into a
>                  generic domain power state. The idle state definitions are
> -                compatible with arm,idle-state specified in [1].
> +                compatible with domain-idle-state specified in [1].
>    The domain-idle-state property reflects the idle state of this PM domain and
>    not the idle states of the devices or sub-domains in the PM domain. Devices
>    and sub-domains have their own idle-states independent of the parent
> @@ -85,7 +85,7 @@ Example 3:
>         };
>
>         DOMAIN_RET: state@0 {
> -               compatible = "arm,idle-state";
> +               compatible = "domain-idle-state";
>                 reg = <0x0>;
>                 entry-latency-us = <1000>;
>                 exit-latency-us = <2000>;
> @@ -93,7 +93,7 @@ Example 3:
>         };
>
>         DOMAIN_PWR_DN: state@1 {
> -               compatible = "arm,idle-state";
> +               compatible = "domain-idle-state";
>                 reg = <0x1>;
>                 entry-latency-us = <5000>;
>                 exit-latency-us = <8000>;
> @@ -118,4 +118,4 @@ The node above defines a typical PM domain consumer device, which is located
>  inside a PM domain with index 0 of a power controller represented by a node
>  with the label "power".
>
> -[1]. Documentation/devicetree/bindings/arm/idle-states.txt
> +[1]. Documentation/devicetree/bindings/power/domain-idle-state.txt
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index 661737c..f0bc672 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -2048,7 +2048,7 @@ int genpd_dev_pm_attach(struct device *dev)
>  EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
>
>  static const struct of_device_id idle_state_match[] = {
> -       { .compatible = "arm,idle-state", },
> +       { .compatible = "domain-idle-state", },
>         { }
>  };
>
> --
> 2.7.4
>

^ permalink raw reply

* Re: [PATCH 03/10] mfd: sun6i-prcm: Add codec analog controls sub-device for Allwinner A23
From: Lee Jones @ 2016-11-21 13:23 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Liam Girdwood, Mark Brown, Maxime Ripard, Rob Herring,
	Mark Rutland, alsa-devel, linux-arm-kernel, linux-kernel,
	devicetree, Mylene Josserand
In-Reply-To: <20161112064648.26779-4-wens@csie.org>

On Sat, 12 Nov 2016, Chen-Yu Tsai wrote:

> The PRCM block on the A23 contains a message box like interface to
> the registers for the analog path controls of the internal codec.
> 
> Add a sub-device for it.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  drivers/mfd/sun6i-prcm.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
> index 011fcc555945..4abbf2ede944 100644
> --- a/drivers/mfd/sun6i-prcm.c
> +++ b/drivers/mfd/sun6i-prcm.c
> @@ -12,6 +12,9 @@
>  #include <linux/init.h>
>  #include <linux/of.h>
>  
> +#define SUN8I_CODEC_ANALOG_BASE	0x1c0
> +#define SUN8I_CODEC_ANALOG_END	(SUN8I_CODEC_ANALOG_BASE + 0x4 - 1)
> +
>  struct prcm_data {
>  	int nsubdevs;
>  	const struct mfd_cell *subdevs;
> @@ -57,6 +60,14 @@ static const struct resource sun6i_a31_apb0_rstc_res[] = {
>  	},
>  };
>  
> +static const struct resource sun8i_codec_analog_res[] = {
> +	{
> +		.start	= SUN8I_CODEC_ANALOG_BASE,
> +		.end	= SUN8I_CODEC_ANALOG_END,
> +		.flags	= IORESOURCE_MEM,
> +	},
> +};

Use the DEVICE_RES_* macros.

>  static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
>  	{
>  		.name = "sun6i-a31-ar100-clk",
> @@ -109,6 +120,12 @@ static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {
>  		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
>  		.resources = sun6i_a31_apb0_rstc_res,
>  	},
> +	{
> +		.name		= "sun8i-codec-analog",
> +		.of_compatible	= "allwinner,sun8i-a23-codec-analog",
> +		.num_resources	= ARRAY_SIZE(sun8i_codec_analog_res),
> +		.resources	= sun8i_codec_analog_res,
> +	},
>  };
>  
>  static const struct prcm_data sun6i_a31_prcm_data = {

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v3 7/7] i2c: i2c-mux-simple: new driver
From: Peter Rosin @ 2016-11-21 13:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Peter Rosin, Wolfram Sang, Rob Herring, Mark Rutland,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jonathan Corbet, Arnd Bergmann,
	Greg Kroah-Hartman, linux-i2c, devicetree, linux-iio, linux-doc
In-Reply-To: <1479734235-18837-1-git-send-email-peda@axentia.se>

This is a generic simple i2c mux that uses the generic multiplexer
subsystem to do the muxing.

The user can select if the mux is to be mux-locked and parent-locked
as described in Documentation/i2c/i2c-topology.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 drivers/i2c/muxes/Kconfig          |  13 +++
 drivers/i2c/muxes/Makefile         |   1 +
 drivers/i2c/muxes/i2c-mux-simple.c | 177 +++++++++++++++++++++++++++++++++++++
 3 files changed, 191 insertions(+)
 create mode 100644 drivers/i2c/muxes/i2c-mux-simple.c

diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index 96de9ce5669b..fb4f587d822a 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -73,6 +73,19 @@ config I2C_MUX_REG
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-mux-reg.
 
+config I2C_MUX_SIMPLE
+	tristate "Simple I2C multiplexer"
+	select MULTIPLEXER
+	depends on OF
+	help
+	  If you say yes to this option, support will be included for a
+	  simple generic I2C multiplexer. This driver provides access to
+	  I2C busses connected through a MUX, which is controlled
+	  by a generic MUX controller.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-mux-simple.
+
 config I2C_DEMUX_PINCTRL
 	tristate "pinctrl-based I2C demultiplexer"
 	depends on PINCTRL && OF
diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile
index 7c267c29b191..eea1fb9e6466 100644
--- a/drivers/i2c/muxes/Makefile
+++ b/drivers/i2c/muxes/Makefile
@@ -10,5 +10,6 @@ obj-$(CONFIG_I2C_MUX_PCA9541)	+= i2c-mux-pca9541.o
 obj-$(CONFIG_I2C_MUX_PCA954x)	+= i2c-mux-pca954x.o
 obj-$(CONFIG_I2C_MUX_PINCTRL)	+= i2c-mux-pinctrl.o
 obj-$(CONFIG_I2C_MUX_REG)	+= i2c-mux-reg.o
+obj-$(CONFIG_I2C_MUX_SIMPLE)	+= i2c-mux-simple.o
 
 ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
diff --git a/drivers/i2c/muxes/i2c-mux-simple.c b/drivers/i2c/muxes/i2c-mux-simple.c
new file mode 100644
index 000000000000..a2f1dc8a3295
--- /dev/null
+++ b/drivers/i2c/muxes/i2c-mux-simple.c
@@ -0,0 +1,177 @@
+/*
+ * Generic simple I2C multiplexer
+ *
+ * Peter Rosin <peda@axentia.se>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/module.h>
+#include <linux/mux.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+struct mux {
+	struct mux_control *control;
+
+	bool do_not_deselect;
+};
+
+static int i2c_mux_select(struct i2c_mux_core *muxc, u32 chan)
+{
+	struct mux *mux = i2c_mux_priv(muxc);
+	int ret;
+
+	ret = mux_control_select(mux->control, chan);
+	mux->do_not_deselect = ret < 0;
+
+	return ret;
+}
+
+static int i2c_mux_deselect(struct i2c_mux_core *muxc, u32 chan)
+{
+	struct mux *mux = i2c_mux_priv(muxc);
+
+	if (mux->do_not_deselect)
+		return 0;
+
+	return mux_control_deselect(mux->control);
+}
+
+static struct i2c_adapter *mux_parent_adapter(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct device_node *parent_np;
+	struct i2c_adapter *parent;
+
+	parent_np = of_parse_phandle(np, "i2c-parent", 0);
+	if (!parent_np) {
+		dev_err(dev, "Cannot parse i2c-parent\n");
+		return ERR_PTR(-ENODEV);
+	}
+	parent = of_find_i2c_adapter_by_node(parent_np);
+	of_node_put(parent_np);
+	if (!parent)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return parent;
+}
+
+static const struct of_device_id i2c_mux_of_match[] = {
+	{ .compatible = "i2c-mux-simple,parent-locked",
+	  .data = (void *)0, },
+	{ .compatible = "i2c-mux-simple,mux-locked",
+	  .data = (void *)1, },
+	{},
+};
+MODULE_DEVICE_TABLE(of, i2c_mux_of_match);
+
+static int i2c_mux_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *child;
+	const struct of_device_id *match;
+	struct i2c_mux_core *muxc;
+	struct mux *mux;
+	struct i2c_adapter *parent;
+	int children;
+	int ret;
+
+	if (!np)
+		return -ENODEV;
+
+	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return -ENOMEM;
+
+	mux->control = devm_mux_control_get(dev);
+	if (IS_ERR(mux->control)) {
+		if (PTR_ERR(mux->control) != -EPROBE_DEFER)
+			dev_err(dev, "failed to get control-mux\n");
+		return PTR_ERR(mux->control);
+	}
+
+	parent = mux_parent_adapter(dev);
+	if (IS_ERR(parent)) {
+		if (PTR_ERR(parent) != -EPROBE_DEFER)
+			dev_err(dev, "failed to get i2c-parent adapter\n");
+		return PTR_ERR(parent);
+	}
+
+	children = of_get_child_count(np);
+
+	muxc = i2c_mux_alloc(parent, dev, children, 0, 0,
+			     i2c_mux_select, i2c_mux_deselect);
+	if (!muxc) {
+		ret = -ENOMEM;
+		goto err_parent;
+	}
+	muxc->priv = mux;
+
+	platform_set_drvdata(pdev, muxc);
+
+	match = of_match_device(of_match_ptr(i2c_mux_of_match), dev);
+	if (match)
+		muxc->mux_locked = !!of_device_get_match_data(dev);
+
+	for_each_child_of_node(np, child) {
+		u32 chan;
+
+		ret = of_property_read_u32(child, "reg", &chan);
+		if (ret < 0) {
+			dev_err(dev, "no reg property for node '%s'\n",
+				child->name);
+			goto err_children;
+		}
+
+		if (chan >= mux->control->states) {
+			dev_err(dev, "invalid reg %u\n", chan);
+			ret = -EINVAL;
+			goto err_children;
+		}
+
+		ret = i2c_mux_add_adapter(muxc, 0, chan, 0);
+		if (ret)
+			goto err_children;
+	}
+
+	dev_info(dev, "%d-port mux on %s adapter\n", children, parent->name);
+
+	return 0;
+
+err_children:
+	i2c_mux_del_adapters(muxc);
+err_parent:
+	i2c_put_adapter(parent);
+
+	return ret;
+}
+
+static int i2c_mux_remove(struct platform_device *pdev)
+{
+	struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+	i2c_mux_del_adapters(muxc);
+	i2c_put_adapter(muxc->parent);
+
+	return 0;
+}
+
+static struct platform_driver i2c_mux_driver = {
+	.probe	= i2c_mux_probe,
+	.remove	= i2c_mux_remove,
+	.driver	= {
+		.name	= "i2c-mux-simple",
+		.of_match_table = i2c_mux_of_match,
+	},
+};
+module_platform_driver(i2c_mux_driver);
+
+MODULE_DESCRIPTION("Simple I2C multiplexer driver");
+MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
+MODULE_LICENSE("GPL v2");
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 6/7] dt-bindings: i2c: i2c-mux-simple: document i2c-mux-simple bindings
From: Peter Rosin @ 2016-11-21 13:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Peter Rosin, Wolfram Sang, Rob Herring, Mark Rutland,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jonathan Corbet, Arnd Bergmann,
	Greg Kroah-Hartman, linux-i2c, devicetree, linux-iio, linux-doc
In-Reply-To: <1479734235-18837-1-git-send-email-peda@axentia.se>

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 .../devicetree/bindings/i2c/i2c-mux-simple.txt     | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux-simple.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-simple.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-simple.txt
new file mode 100644
index 000000000000..decfd742b297
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-simple.txt
@@ -0,0 +1,76 @@
+Simple I2C Bus Mux
+
+This binding describes an I2C bus multiplexer that uses a mux controller
+from the mux subsystem to route the I2C signals.
+
+                                  .-----.  .-----.
+                                  | dev |  | dev |
+    .------------.                '-----'  '-----'
+    | SoC        |                   |        |
+    |            |          .--------+--------'
+    |   .------. |  .------+    child bus A, on MUX value set to 0
+    |   | I2C  |-|--| Mux  |
+    |   '------' |  '--+---+    child bus B, on MUX value set to 1
+    |   .------. |     |    '----------+--------+--------.
+    |   | MUX- | |     |               |        |        |
+    |   | Ctrl |-|-----+            .-----.  .-----.  .-----.
+    |   '------' |                  | dev |  | dev |  | dev |
+    '------------'                  '-----'  '-----'  '-----'
+
+Required properties:
+- compatible: i2c-mux-simple,mux-locked or i2c-mux-simple,parent-locked
+- i2c-parent: The phandle of the I2C bus that this multiplexer's master-side
+  port is connected to.
+* Standard I2C mux properties. See i2c-mux.txt in this directory.
+* I2C child bus nodes. See i2c-mux.txt in this directory. The sub-bus number
+  is also the mux-controller state described in ../misc/mux-controller.txt
+
+For each i2c child node, an I2C child bus will be created. They will
+be numbered based on their order in the device tree.
+
+Whenever an access is made to a device on a child bus, the value set
+in the relevant node's reg property will be set as the state in the
+mux controller.
+
+Example:
+	mux {
+		compatible = "mux-gpio";
+
+		mux-gpios = <&pioA 0 GPIO_ACTIVE_HIGH>,
+			    <&pioA 1 GPIO_ACTIVE_HIGH>;
+
+		i2c-mux {
+			compatible = "i2c-mux-simple,mux-locked";
+			i2c-parent = <&i2c1>;
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			i2c@1 {
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ssd1307: oled@3c {
+					compatible = "solomon,ssd1307fb-i2c";
+					reg = <0x3c>;
+					pwms = <&pwm 4 3000>;
+					reset-gpios = <&gpio2 7 1>;
+					reset-active-low;
+				};
+			};
+
+			i2c@3 {
+				reg = <3>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				pca9555: pca9555@20 {
+					compatible = "nxp,pca9555";
+					gpio-controller;
+					#gpio-cells = <2>;
+					reg = <0x20>;
+				};
+			};
+		};
+	};
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 5/7] iio: multiplexer: new iio category and iio-mux driver
From: Peter Rosin @ 2016-11-21 13:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Peter Rosin, Wolfram Sang, Rob Herring, Mark Rutland,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jonathan Corbet, Arnd Bergmann,
	Greg Kroah-Hartman, linux-i2c, devicetree, linux-iio, linux-doc
In-Reply-To: <1479734235-18837-1-git-send-email-peda@axentia.se>

When a multiplexer changes how an iio device behaves (for example
by feeding different signals to an ADC), this driver can be used
create one virtual iio channel for each multiplexer state.

Depends on the generic multiplexer subsystem.

Cache any ext_info values from the parent iio channel, creating a private
copy of the ext_info attributes for each multiplexer state/channel.

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 MAINTAINERS                       |   1 +
 drivers/iio/Kconfig               |   1 +
 drivers/iio/Makefile              |   1 +
 drivers/iio/multiplexer/Kconfig   |  18 ++
 drivers/iio/multiplexer/Makefile  |   6 +
 drivers/iio/multiplexer/iio-mux.c | 450 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 477 insertions(+)
 create mode 100644 drivers/iio/multiplexer/Kconfig
 create mode 100644 drivers/iio/multiplexer/Makefile
 create mode 100644 drivers/iio/multiplexer/iio-mux.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3fc0dbbc04ea..02d9072aae16 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6129,6 +6129,7 @@ M:	Peter Rosin <peda@axentia.se>
 L:	linux-iio@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt
+F:	drivers/iio/multiplexer/iio-mux.c
 
 IIO SUBSYSTEM AND DRIVERS
 M:	Jonathan Cameron <jic23@kernel.org>
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 6743b18194fb..dcb541d0d70e 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -82,6 +82,7 @@ source "drivers/iio/humidity/Kconfig"
 source "drivers/iio/imu/Kconfig"
 source "drivers/iio/light/Kconfig"
 source "drivers/iio/magnetometer/Kconfig"
+source "drivers/iio/multiplexer/Kconfig"
 source "drivers/iio/orientation/Kconfig"
 if IIO_TRIGGER
    source "drivers/iio/trigger/Kconfig"
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index 87e4c4369e2f..f9879c29cf6f 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -27,6 +27,7 @@ obj-y += humidity/
 obj-y += imu/
 obj-y += light/
 obj-y += magnetometer/
+obj-y += multiplexer/
 obj-y += orientation/
 obj-y += potentiometer/
 obj-y += pressure/
diff --git a/drivers/iio/multiplexer/Kconfig b/drivers/iio/multiplexer/Kconfig
new file mode 100644
index 000000000000..70a044510686
--- /dev/null
+++ b/drivers/iio/multiplexer/Kconfig
@@ -0,0 +1,18 @@
+#
+# Multiplexer drivers
+#
+# When adding new entries keep the list in alphabetical order
+
+menu "Multiplexers"
+
+config IIO_MUX
+	tristate "IIO multiplexer driver"
+	select MULTIPLEXER
+	depends on OF
+	help
+	  Say yes here to build support for the IIO multiplexer.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iio-mux.
+
+endmenu
diff --git a/drivers/iio/multiplexer/Makefile b/drivers/iio/multiplexer/Makefile
new file mode 100644
index 000000000000..68be3c4abd07
--- /dev/null
+++ b/drivers/iio/multiplexer/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for industrial I/O multiplexer drivers
+#
+
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_IIO_MUX) += iio-mux.o
diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c
new file mode 100644
index 000000000000..0b9d04914241
--- /dev/null
+++ b/drivers/iio/multiplexer/iio-mux.c
@@ -0,0 +1,450 @@
+/*
+ * IIO multiplexer driver
+ *
+ * Copyright (C) 2016 Axentia Technologies AB
+ *
+ * Author: Peter Rosin <peda@axentia.se>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/iio/consumer.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/mux.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+struct mux_ext_info_cache {
+	char *data;
+	size_t size;
+};
+
+struct mux_child {
+	struct mux_ext_info_cache *ext_info_cache;
+};
+
+struct mux {
+	int cached_state;
+	struct mux_control *control;
+	struct iio_channel *parent;
+	struct iio_dev *indio_dev;
+	struct iio_chan_spec *chan;
+	struct iio_chan_spec_ext_info *ext_info;
+	struct mux_child *child;
+};
+
+static int iio_mux_select(struct mux *mux, int idx)
+{
+	struct mux_child *child = &mux->child[idx];
+	struct iio_chan_spec const *chan = &mux->chan[idx];
+	int ret;
+	int i;
+
+	ret = mux_control_select(mux->control, chan->channel);
+	if (ret < 0) {
+		mux->cached_state = -1;
+		return ret;
+	}
+
+	if (mux->cached_state == chan->channel)
+		return 0;
+
+	if (chan->ext_info) {
+		for (i = 0; chan->ext_info[i].name; ++i) {
+			const char *attr = chan->ext_info[i].name;
+			struct mux_ext_info_cache *cache;
+
+			cache = &child->ext_info_cache[i];
+
+			if (cache->size < 0)
+				continue;
+
+			ret = iio_write_channel_ext_info(mux->parent, attr,
+							 cache->data,
+							 cache->size);
+
+			if (ret < 0) {
+				mux_control_deselect(mux->control);
+				mux->cached_state = -1;
+				return ret;
+			}
+		}
+	}
+	mux->cached_state = chan->channel;
+
+	return 0;
+}
+
+static void iio_mux_deselect(struct mux *mux)
+{
+	mux_control_deselect(mux->control);
+}
+
+static int mux_read_raw(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int *val, int *val2, long mask)
+{
+	struct mux *mux = iio_priv(indio_dev);
+	int idx = chan - mux->chan;
+	int ret;
+
+	ret = iio_mux_select(mux, idx);
+	if (ret < 0)
+		return ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = iio_read_channel_raw(mux->parent, val);
+		break;
+
+	case IIO_CHAN_INFO_SCALE:
+		ret = iio_read_channel_scale(mux->parent, val, val2);
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	iio_mux_deselect(mux);
+
+	return ret;
+}
+
+static int mux_read_avail(struct iio_dev *indio_dev,
+			  struct iio_chan_spec const *chan,
+			  const int **vals, int *type, int *length,
+			  long mask)
+{
+	struct mux *mux = iio_priv(indio_dev);
+	int idx = chan - mux->chan;
+	int ret;
+
+	ret = iio_mux_select(mux, idx);
+	if (ret < 0)
+		return ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		*type = IIO_VAL_INT;
+		ret = iio_read_avail_channel_raw(mux->parent, vals, length);
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	iio_mux_deselect(mux);
+
+	return ret;
+}
+
+static int mux_write_raw(struct iio_dev *indio_dev,
+			 struct iio_chan_spec const *chan,
+			 int val, int val2, long mask)
+{
+	struct mux *mux = iio_priv(indio_dev);
+	int idx = chan - mux->chan;
+	int ret;
+
+	ret = iio_mux_select(mux, idx);
+	if (ret < 0)
+		return ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = iio_write_channel_raw(mux->parent, val);
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	iio_mux_deselect(mux);
+
+	return ret;
+}
+
+static const struct iio_info mux_info = {
+	.read_raw = mux_read_raw,
+	.read_avail = mux_read_avail,
+	.write_raw = mux_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static ssize_t mux_read_ext_info(struct iio_dev *indio_dev, uintptr_t private,
+				 struct iio_chan_spec const *chan, char *buf)
+{
+	struct mux *mux = iio_priv(indio_dev);
+	int idx = chan - mux->chan;
+	ssize_t ret;
+
+	ret = iio_mux_select(mux, idx);
+	if (ret < 0)
+		return ret;
+
+	ret = iio_read_channel_ext_info(mux->parent,
+					mux->ext_info[private].name,
+					buf);
+
+	iio_mux_deselect(mux);
+
+	return ret;
+}
+
+static ssize_t mux_write_ext_info(struct iio_dev *indio_dev, uintptr_t private,
+				  struct iio_chan_spec const *chan,
+				  const char *buf, size_t len)
+{
+	struct device *dev = indio_dev->dev.parent;
+	struct mux *mux = iio_priv(indio_dev);
+	int idx = chan - mux->chan;
+	char *new;
+	ssize_t ret;
+
+	ret = iio_mux_select(mux, idx);
+	if (ret < 0)
+		return ret;
+
+	new = devm_kmemdup(dev, buf, len + 1, GFP_KERNEL);
+	if (!new) {
+		iio_mux_deselect(mux);
+		return -ENOMEM;
+	}
+
+	new[len] = 0;
+
+	ret = iio_write_channel_ext_info(mux->parent,
+					 mux->ext_info[private].name,
+					 buf, len);
+	if (ret < 0) {
+		iio_mux_deselect(mux);
+		devm_kfree(dev, new);
+		return ret;
+	}
+
+	devm_kfree(dev, mux->child[idx].ext_info_cache[private].data);
+	mux->child[idx].ext_info_cache[private].data = new;
+	mux->child[idx].ext_info_cache[private].size = len;
+
+	iio_mux_deselect(mux);
+
+	return ret;
+}
+
+static int mux_configure_channel(struct device *dev, struct mux *mux,
+				 struct device_node *child_np, int idx)
+{
+	struct mux_child *child = &mux->child[idx];
+	struct iio_chan_spec *chan = &mux->chan[idx];
+	struct iio_chan_spec const *pchan = mux->parent->channel;
+	u32 state;
+	char *page = NULL;
+	int num_ext_info;
+	int i;
+	int ret;
+
+	chan->indexed = 1;
+	chan->output = pchan->output;
+	chan->datasheet_name = child_np->name;
+	chan->ext_info = mux->ext_info;
+
+	ret = iio_get_channel_type(mux->parent, &chan->type);
+	if (ret < 0) {
+		dev_err(dev, "failed to get parent channel type\n");
+		return ret;
+	}
+
+	if (iio_channel_has_info(pchan, IIO_CHAN_INFO_RAW))
+		chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW);
+	if (iio_channel_has_info(pchan, IIO_CHAN_INFO_SCALE))
+		chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE);
+
+	if (iio_channel_has_available(pchan, IIO_CHAN_INFO_RAW))
+		chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW);
+
+	ret = of_property_read_u32(child_np, "reg", &state);
+	if (ret < 0) {
+		dev_err(dev, "no reg property for node '%s'\n", child_np->name);
+		return ret;
+	}
+
+	if (state >= mux->control->states) {
+		dev_err(dev, "invalid reg %u\n", state);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < idx; ++i) {
+		if (mux->chan[i].channel == state) {
+			dev_err(dev, "double use of reg %u\n", state);
+			return -EINVAL;
+		}
+	}
+
+	chan->channel = state;
+
+	num_ext_info = iio_get_channel_ext_info_count(mux->parent);
+	if (num_ext_info) {
+		page = devm_kzalloc(dev, PAGE_SIZE, GFP_KERNEL);
+		if (!page)
+			return -ENOMEM;
+	}
+	child->ext_info_cache = devm_kzalloc(dev,
+					     sizeof(*child->ext_info_cache) *
+					     num_ext_info, GFP_KERNEL);
+	for (i = 0; i < num_ext_info; ++i) {
+		child->ext_info_cache[i].size = -1;
+
+		if (!pchan->ext_info[i].write)
+			continue;
+		if (!pchan->ext_info[i].read)
+			continue;
+
+		ret = iio_read_channel_ext_info(mux->parent,
+						mux->ext_info[i].name,
+						page);
+		if (ret < 0) {
+			dev_err(dev, "failed to get ext_info '%s'\n",
+				pchan->ext_info[i].name);
+			return ret;
+		}
+		if (ret >= PAGE_SIZE) {
+			dev_err(dev, "too large ext_info '%s'\n",
+				pchan->ext_info[i].name);
+			return -EINVAL;
+		}
+
+		child->ext_info_cache[i].data = devm_kmemdup(dev, page, ret + 1,
+							     GFP_KERNEL);
+		child->ext_info_cache[i].data[ret] = 0;
+		child->ext_info_cache[i].size = ret;
+	}
+
+	if (page)
+		devm_kfree(dev, page);
+
+	return 0;
+}
+
+static int mux_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child_np;
+	struct iio_dev *indio_dev;
+	struct iio_channel *parent;
+	struct mux *mux;
+	int sizeof_ext_info;
+	int children;
+	int sizeof_priv;
+	int i;
+	int ret;
+
+	if (!np)
+		return -ENODEV;
+
+	parent = devm_iio_channel_get(dev, "parent");
+	if (IS_ERR(parent)) {
+		if (PTR_ERR(parent) != -EPROBE_DEFER)
+			dev_err(dev, "failed to get parent channel\n");
+		return PTR_ERR(parent);
+	}
+
+	sizeof_ext_info = iio_get_channel_ext_info_count(parent);
+	if (sizeof_ext_info) {
+		sizeof_ext_info += 1; /* one extra entry for the sentinel */
+		sizeof_ext_info *= sizeof(*mux->ext_info);
+	}
+
+	children = of_get_child_count(np);
+	if (children <= 0) {
+		dev_err(dev, "not even a single child\n");
+		return -EINVAL;
+	}
+
+	sizeof_priv = sizeof(*mux);
+	sizeof_priv += sizeof(*mux->child) * children;
+	sizeof_priv += sizeof(*mux->chan) * children;
+	sizeof_priv += sizeof_ext_info;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof_priv);
+	if (!indio_dev)
+		return -ENOMEM;
+
+	mux = iio_priv(indio_dev);
+	mux->child = (struct mux_child *)(mux + 1);
+	mux->chan = (struct iio_chan_spec *)(mux->child + children);
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	mux->parent = parent;
+	mux->cached_state = -1;
+
+	indio_dev->name = dev_name(dev);
+	indio_dev->dev.parent = dev;
+	indio_dev->info = &mux_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = mux->chan;
+	indio_dev->num_channels = children;
+	if (sizeof_ext_info) {
+		mux->ext_info = devm_kmemdup(dev,
+					     parent->channel->ext_info,
+					     sizeof_ext_info, GFP_KERNEL);
+		if (!mux->ext_info)
+			return -ENOMEM;
+
+		for (i = 0; mux->ext_info[i].name; ++i) {
+			if (parent->channel->ext_info[i].read)
+				mux->ext_info[i].read = mux_read_ext_info;
+			if (parent->channel->ext_info[i].write)
+				mux->ext_info[i].write = mux_write_ext_info;
+			mux->ext_info[i].private = i;
+		}
+	}
+
+	mux->control = devm_mux_control_get(dev);
+	if (IS_ERR(mux->control)) {
+		if (PTR_ERR(mux->control) != -EPROBE_DEFER)
+			dev_err(dev, "failed to get control-mux\n");
+		return PTR_ERR(mux->control);
+	}
+
+	i = 0;
+	for_each_child_of_node(np, child_np) {
+		ret = mux_configure_channel(dev, mux, child_np, i);
+		if (ret < 0)
+			return ret;
+		i++;
+	}
+
+	ret = devm_iio_device_register(dev, indio_dev);
+	if (ret) {
+		dev_err(dev, "failed to register iio device\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id mux_match[] = {
+	{ .compatible = "iio-mux" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mux_match);
+
+static struct platform_driver mux_driver = {
+	.probe = mux_probe,
+	.driver = {
+		.name = "iio-mux",
+		.of_match_table = mux_match,
+	},
+};
+module_platform_driver(mux_driver);
+
+MODULE_DESCRIPTION("IIO multiplexer driver");
+MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
+MODULE_LICENSE("GPL v2");
-- 
2.1.4


^ permalink raw reply related

* [PATCH v3 4/7] dt-bindings: iio: iio-mux: document iio-mux bindings
From: Peter Rosin @ 2016-11-21 13:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Peter Rosin, Wolfram Sang, Rob Herring, Mark Rutland,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jonathan Corbet, Arnd Bergmann,
	Greg Kroah-Hartman, linux-i2c, devicetree, linux-iio, linux-doc
In-Reply-To: <1479734235-18837-1-git-send-email-peda@axentia.se>

Signed-off-by: Peter Rosin <peda@axentia.se>
---
 .../bindings/iio/multiplexer/iio-mux.txt           | 47 ++++++++++++++++++++++
 MAINTAINERS                                        |  6 +++
 2 files changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt

diff --git a/Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt b/Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt
new file mode 100644
index 000000000000..2807333ccc86
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt
@@ -0,0 +1,47 @@
+IIO multiplexer bindings
+
+If a multiplexer is used to select which hardware signal is fed to
+e.g. an ADC channel, these bindings describe that situation.
+
+Required properties:
+- compatible : "iio-mux"
+- io-channels : Channel node of the parent channel that has multiplexed
+		input.
+- io-channel-names : Should be "parent".
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Required properties for iio-mux child nodes:
+- reg : The multiplexer state as described in ../misc/mux-controller.txt
+
+For each iio-mux child, an iio channel will be created whose number will
+match the mux controller state.
+
+Example:
+	mux {
+		compatible = "mux-gpio";
+
+		mux-gpios = <&pioA 0 GPIO_ACTIVE_HIGH>,
+			    <&pioA 1 GPIO_ACTIVE_HIGH>;
+
+		adc {
+			compatible = "iio-mux";
+			io-channels = <&adc 0>;
+			io-channel-names = "parent";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			sync@0 {
+				reg = <0>;
+			};
+
+			in@1 {
+				reg = <1>;
+			};
+
+			system-regulator@2 {
+				reg = <2>;
+			};
+		};
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 37974aeee750..3fc0dbbc04ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6124,6 +6124,12 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 F:	drivers/media/rc/iguanair.c
 
+IIO MULTIPLEXER
+M:	Peter Rosin <peda@axentia.se>
+L:	linux-iio@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iio/multiplexer/iio-mux.txt
+
 IIO SUBSYSTEM AND DRIVERS
 M:	Jonathan Cameron <jic23@kernel.org>
 R:	Hartmut Knaack <knaack.h@gmx.de>
-- 
2.1.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox