LKML Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs
@ 2018-10-08 21:11 Vladimir Zapolskiy
  2018-10-08 21:11 ` [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description " Vladimir Zapolskiy
                   ` (7 more replies)
  0 siblings, 8 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-08 21:11 UTC (permalink / raw)
  To: Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel

The published drivers describe the essential and generic parts of
TI DS90Ux9xx series of ICs, which allow to transfer video, audio and
control signals between FPD-Link III serializers and deserializers.

The placement of TI DS90Ux9xx I2C client driver was selected to be
drivers/mfd as the most natural location of a true MFD driver,
apparently drivers/media/i2c is for another type of device drivers,
also DS90Ux9xx I2C bridge subcontroller driver is placed nearby,
because drivers/i2c for it would be an inappropriate destination
as well. Informally the TI DS90Ux9xx ICs serve a similar function
to SMSC/Microchip MOST, and its drivers are in drivers/staging/most,
the final destination is unknown to me. Please feel free to advise
a better location for the published drivers, at the moment the core
drivers are in drivers/mfd, but I select linux-media as a mailing list.

The published drivers instantly give a chance to test video bridge
functionality to a TI DS90Ux9xx deserializer equipped display panel
with the aide of Laurent's "lvds-encoder" driver by misusing it
as a generic and transparent drm bridge with no particular LVDS
specifics in it, for that it should be sufficient just to add the
corresponding device node and input/output ports as children of
a serializer connected to an application controller.

While the selected scheme of IC description by a list of subdevices,
where each one described in its own device node, works pretty well,
it might lead to unnecessary overcomplicated description of connections
between subdevices on serializer and deserializer sides, i.e. for
proper description of links/connections video serializer should
be linked to video deserializer, audio serializer should be linked
to audio deserializer and so on, however formally there is just one
FPD-III Link connection between two ICs.

The series of patches is rebased on top of linux-next, and there are
more changes in the queue to provide better support of TI DS90Ux9xx ICs.

The introduction to the ICs and drivers can be found in my presentation
https://schd.ws/hosted_files/ossalsjp18/8a/vzapolskiy_als2018.pdf

Sandeep Jain (1):
  dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs

Vladimir Zapolskiy (6):
  dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge
  dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
  pinctrl: ds90ux9xx: add TI DS90Ux9xx pinmux and GPIO controller driver
  MAINTAINERS: add entry for TI DS90Ux9xx FPD-Link III drivers

 .../bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt  |  61 ++
 .../devicetree/bindings/mfd/ti,ds90ux9xx.txt  |  66 ++
 .../bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt |  83 ++
 MAINTAINERS                                   |  10 +
 drivers/mfd/Kconfig                           |  22 +
 drivers/mfd/Makefile                          |   2 +
 drivers/mfd/ds90ux9xx-core.c                  | 879 ++++++++++++++++
 drivers/mfd/ds90ux9xx-i2c-bridge.c            | 764 ++++++++++++++
 drivers/pinctrl/Kconfig                       |  11 +
 drivers/pinctrl/Makefile                      |   1 +
 drivers/pinctrl/pinctrl-ds90ux9xx.c           | 970 ++++++++++++++++++
 include/linux/mfd/ds90ux9xx.h                 |  42 +
 12 files changed, 2911 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
 create mode 100644 drivers/mfd/ds90ux9xx-core.c
 create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c
 create mode 100644 drivers/pinctrl/pinctrl-ds90ux9xx.c
 create mode 100644 include/linux/mfd/ds90ux9xx.h

-- 
2.17.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
@ 2018-10-08 21:11 ` " Vladimir Zapolskiy
  2018-10-09  0:13   ` Marek Vasut
                     ` (3 more replies)
  2018-10-08 21:12 ` [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge Vladimir Zapolskiy
                   ` (6 subsequent siblings)
  7 siblings, 4 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-08 21:11 UTC (permalink / raw)
  To: Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel, Sandeep Jain,
	Vladimir Zapolskiy

From: Sandeep Jain <Sandeep_Jain@mentor.com>

The change adds device tree binding description of TI DS90Ux9xx
series of serializer and deserializer controllers which support video,
audio and control data transmission over FPD-III Link connection.

Signed-off-by: Sandeep Jain <Sandeep_Jain@mentor.com>
[vzapolskiy: various updates and corrections of secondary importance]
Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
 .../devicetree/bindings/mfd/ti,ds90ux9xx.txt  | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt

diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
new file mode 100644
index 000000000000..0733da88f7ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
@@ -0,0 +1,66 @@
+Texas Instruments DS90Ux9xx de-/serializer controllers
+
+Required properties:
+- compatible: Must contain a generic "ti,ds90ux9xx" value and
+	may contain one more specific value from the list:
+	"ti,ds90ub925q",
+	"ti,ds90uh925q",
+	"ti,ds90ub927q",
+	"ti,ds90uh927q",
+	"ti,ds90ub926q",
+	"ti,ds90uh926q",
+	"ti,ds90ub928q",
+	"ti,ds90uh928q",
+	"ti,ds90ub940q",
+	"ti,ds90uh940q".
+
+Optional properties:
+- reg : Specifies the I2C slave address of a local de-/serializer.
+- power-gpios : GPIO line to control supplied power to the device.
+- ti,backward-compatible-mode : Overrides backward compatibility mode.
+	Possible values are "<1>" or "<0>".
+	If "ti,backward-compatible-mode" is not mentioned, the backward
+	compatibility mode is not touched and given by hardware pin strapping.
+- ti,low-frequency-mode : Overrides low frequency mode.
+	Possible values are "<1>" or "<0>".
+	If "ti,low-frequency-mode" is not mentioned, the low frequency mode
+	is not touched and given by hardware pin strapping.
+- ti,video-map-select-msb: Sets video bridge pins to MSB mode, if it is set
+	MAPSEL pin value is ignored.
+- ti,video-map-select-lsb: Sets video bridge pins to LSB mode, if it is set
+	MAPSEL pin value is ignored.
+- ti,pixel-clock-edge : Selects Pixel Clock Edge.
+	Possible values are "<1>" or "<0>".
+	If "ti,pixel-clock-edge" is High <1>, output data is strobed on the
+	Rising edge of the PCLK. If ti,pixel-clock-edge is Low <0>, data is
+	strobed on the Falling edge of the PCLK.
+	If "ti,pixel-clock-edge" is not mentioned, the pixel clock edge
+	value is not touched and given by hardware pin strapping.
+- ti,spread-spectrum-clock-generation : Spread Sprectrum Clock Generation.
+	Possible values are from "<0>" to "<7>". The same value will be
+	written to SSC register. If "ti,spread-spectrum-clock-gen" is not
+	found, then SSCG will be disabled.
+
+TI DS90Ux9xx serializers and deserializer device nodes may contain a number
+of children device nodes to describe and enable particular subcomponents
+found on ICs.
+
+Example:
+
+serializer: serializer@c {
+	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
+	reg = <0xc>;
+	power-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
+	ti,backward-compatible-mode = <0>;
+	ti,low-frequency-mode = <0>;
+	ti,pixel-clock-edge = <0>;
+	...
+}
+
+deserializer: deserializer@3c {
+	compatible = "ti,ds90ub940q", "ti,ds90ux9xx";
+	reg = <0x3c>;
+	power-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
+	...
+}
+
-- 
2.17.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge
  2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
  2018-10-08 21:11 ` [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description " Vladimir Zapolskiy
@ 2018-10-08 21:12 ` Vladimir Zapolskiy
  2018-10-12 11:54   ` Laurent Pinchart
  2018-10-30 16:43   ` Luca Ceresoli
  2018-10-08 21:12 ` [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux Vladimir Zapolskiy
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-08 21:12 UTC (permalink / raw)
  To: Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel, Vladimir Zapolskiy

From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>

TI DS90Ux9xx de-/serializers are capable to route I2C messages to
I2C slave devices connected to a remote de-/serializer in a pair,
the change adds description of device tree bindings of the subcontroller
to configure and enable this functionality.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
 .../bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt  | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt

diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
new file mode 100644
index 000000000000..4169e382073a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
@@ -0,0 +1,61 @@
+TI DS90Ux9xx de-/serializer I2C bridge subcontroller
+
+Required properties:
+- compatible: Must contain a generic "ti,ds90ux9xx-i2c-bridge" value and
+	may contain one more specific value from the list:
+	"ti,ds90ux925-i2c-bridge",
+	"ti,ds90ux926-i2c-bridge",
+	"ti,ds90ux927-i2c-bridge",
+	"ti,ds90ux928-i2c-bridge",
+	"ti,ds90ux940-i2c-bridge".
+
+Required properties of a de-/serializer device connected to a local I2C bus:
+- ti,i2c-bridges: List of phandles to remote de-/serializer devices with
+	two arguments: id of a local de-/serializer FPD link and an assigned
+	I2C address of a remote de-/serializer to be accessed on a local
+	I2C bus.
+
+Optional properties of a de-/serializer device connected to a local I2C bus:
+- ti,i2c-bridge-maps: List of 3-cell values:
+	- the first argument is id of a local de-/serializer FPD link,
+	- the second argument is an I2C address of a device connected to
+	  a remote de-/serializer IC,
+	- the third argument is an I2C address of the remote I2C device
+	  for access on a local I2C bus.
+- ti,i2c-bridge-auto-ack: Enables AUTO ACK mode.
+- ti,i2c-bridge-pass-all: Enables PASS ALL mode, remote I2C slave devices
+	are accessible on a local (host) I2C bus without I2C address
+	remappings.
+
+Remote de-/serializer device may contain a list of device nodes, each
+one represents an I2C device connected to that remote de-/serializer IC.
+
+Example (remote device is a deserializer with Atmel MXT touchscreen):
+
+serializer: serializer@c {
+	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
+	reg = <0xc>;
+
+	i2c-bridge {
+		compatible = "ti,ds90ux927-i2c-bridge",
+			     "ti,ds90ux9xx-i2c-bridge";
+		ti,i2c-bridges = <&deserializer 0 0x3b>;
+		ti,i2c-bridge-maps = <0 0x4b 0x64>;
+	};
+};
+
+deserializer: deserializer {
+	compatible = "ti,ds90ub928q", "ti,ds90ux9xx";
+
+	i2c-bridge {
+		compatible = "ti,ds90ux928-i2c-bridge",
+			     "ti,ds90ux9xx-i2c-bridge";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		touchscreen@4b {
+			compatible = "atmel,maxtouch";
+			reg = <0x4b>;
+		};
+	};
+};
-- 
2.17.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
  2018-10-08 21:11 ` [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description " Vladimir Zapolskiy
  2018-10-08 21:12 ` [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge Vladimir Zapolskiy
@ 2018-10-08 21:12 ` Vladimir Zapolskiy
  2018-10-10  8:45   ` Linus Walleij
  2018-10-12 12:01   ` Laurent Pinchart
  2018-10-08 21:12 ` [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver Vladimir Zapolskiy
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-08 21:12 UTC (permalink / raw)
  To: Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel, Vladimir Zapolskiy

From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>

TI DS90Ux9xx de-/serializers have a capability to multiplex pin functions,
in particular a pin may have selectable functions of GPIO, GPIO line
transmitter, one of I2S lines, one of RGB24 video signal lines and so on.

The change adds a description of DS90Ux9xx pin multiplexers and GPIO
controllers.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
 .../bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt | 83 +++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
new file mode 100644
index 000000000000..fbfa1a3cdf9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
@@ -0,0 +1,83 @@
+TI DS90Ux9xx de-/serializer pinmux and GPIO subcontroller
+
+Required properties:
+- compatible: Must contain a generic "ti,ds90ux9xx-pinctrl" value and
+	may contain one more specific value from the list:
+	"ti,ds90ux925-pinctrl",
+	"ti,ds90ux926-pinctrl",
+	"ti,ds90ux927-pinctrl",
+	"ti,ds90ux928-pinctrl",
+	"ti,ds90ux940-pinctrl".
+
+- gpio-controller: Marks the device node as a GPIO controller.
+
+- #gpio-cells: Must be set to 2,
+	- the first cell is the GPIO offset number within the controller,
+	- the second cell is used to specify the GPIO line polarity.
+
+- gpio-ranges: Mapping to pin controller pins (as described in
+	Documentation/devicetree/bindings/gpio/gpio.txt)
+
+Optional properties:
+- ti,video-depth-18bit: Sets video bridge pins to RGB 18-bit mode.
+
+Available pins, groups and functions (reference to device datasheets):
+
+function: "gpio" ("gpio4" is on DS90Ux925 and DS90Ux926 only,
+		  "gpio9" is on DS90Ux940 only)
+ - pins: "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6",
+	 "gpio7", "gpio8", "gpio9"
+
+function: "gpio-remote"
+ - pins: "gpio0", "gpio1", "gpio2", "gpio3"
+
+function: "pass" (DS90Ux940 specific only)
+ - pins: "gpio0", "gpio3"
+
+function: "i2s-1"
+ - group: "i2s-1"
+
+function: "i2s-2"
+ - group: "i2s-2"
+
+function: "i2s-3" (DS90Ux927, DS90Ux928 and DS90Ux940 specific only)
+ - group: "i2s-3"
+
+function: "i2s-4" (DS90Ux927, DS90Ux928 and DS90Ux940 specific only)
+ - group: "i2s-4"
+
+function: "i2s-m" (DS90Ux928 and DS90Ux940 specific only)
+ - group: "i2s-m"
+
+function: "parallel" (DS90Ux925 and DS90Ux926 specific only)
+ - group: "parallel"
+
+Example (deserializer with pins GPIO[3:0] set to bridged output
+	 function and pin GPIO4 in standard hogged GPIO function):
+
+deserializer {
+	compatible = "ti,ds90ub928q", "ti,ds90ux9xx";
+
+	ds90ux928_pctrl: pin-controller {
+		compatible = "ti,ds90ux928-pinctrl", "ti,ds90ux9xx-pinctrl";
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-ranges = <&ds90ux928_pctrl 0 0 8>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&ds90ux928_pins>;
+
+		ds90ux928_pins: pinmux {
+			gpio-remote {
+				pins = "gpio0", "gpio1", "gpio2", "gpio3";
+				function = "gpio-remote";
+			};
+		};
+
+		rst {
+			gpio-hog;
+			gpios = <4 GPIO_ACTIVE_HIGH>;
+			output-high;
+		};
+	};
+};
-- 
2.17.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
                   ` (2 preceding siblings ...)
  2018-10-08 21:12 ` [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux Vladimir Zapolskiy
@ 2018-10-08 21:12 ` Vladimir Zapolskiy
  2018-10-09  4:08   ` kbuild test robot
  2018-10-12  6:03   ` Lee Jones
  2018-10-08 21:12 ` [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver Vladimir Zapolskiy
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-08 21:12 UTC (permalink / raw)
  To: Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel, Vladimir Zapolskiy

From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>

The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
support of subdevice controllers is done in separate drivers, because
not all IC functionality may be needed in particular situations, and
this can be fine grained controlled in device tree.

The development of the driver was a collaborative work, the
contribution done by Balasubramani Vivekanandan includes:
* original implementation of the driver based on a reference driver,
* regmap powered interrupt controller support on serializers,
* support of implicitly or improperly specified in device tree ICs,
* support of device properties and attributes: backward compatible
  mode, low frequency operation mode, spread spectrum clock generator.

Contribution by Steve Longerbeam:
* added ds90ux9xx_read_indirect() function,
* moved number of links property and added ds90ux9xx_num_fpd_links(),
* moved and updated ds90ux9xx_get_link_status() function to core driver,
* added fpd_link_show device attribute.

Sandeep Jain added support of pixel clock edge configuration.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
 drivers/mfd/Kconfig           |  14 +
 drivers/mfd/Makefile          |   1 +
 drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
 include/linux/mfd/ds90ux9xx.h |  42 ++
 4 files changed, 936 insertions(+)
 create mode 100644 drivers/mfd/ds90ux9xx-core.c
 create mode 100644 include/linux/mfd/ds90ux9xx.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8c5dfdce4326..a969fa123f64 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
 	  boards.  MSP430 firmware manages resets and power sequencing,
 	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
 
+config MFD_DS90UX9XX
+	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
+	depends on I2C && OF
+	select MFD_CORE
+	select REGMAP_I2C
+	help
+	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
+
+	  This driver provides basic support for setting up the de-/serializer
+	  chips. Additional functionalities like connection handling to
+	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
+	  controller and so on are provided by separate drivers and should
+	  enabled individually.
+
 config MFD_LP3943
 	tristate "TI/National Semiconductor LP3943 MFD Driver"
 	depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 12980a4ad460..cc92bf5394b7 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -224,6 +224,7 @@ obj-$(CONFIG_MFD_HI655X_PMIC)   += hi655x-pmic.o
 obj-$(CONFIG_MFD_DLN2)		+= dln2.o
 obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
 obj-$(CONFIG_MFD_SKY81452)	+= sky81452.o
+obj-$(CONFIG_MFD_DS90UX9XX)	+= ds90ux9xx-core.o
 
 intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
diff --git a/drivers/mfd/ds90ux9xx-core.c b/drivers/mfd/ds90ux9xx-core.c
new file mode 100644
index 000000000000..ad96c109a451
--- /dev/null
+++ b/drivers/mfd/ds90ux9xx-core.c
@@ -0,0 +1,879 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * TI DS90Ux9xx MFD driver
+ *
+ * Copyright (c) 2017-2018 Mentor Graphics Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds90ux9xx.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+
+/* Serializer Registers */
+#define SER_REG_MODE_SELECT		0x04
+#define SER_REG_GEN_STATUS		0x0C
+#define SER_REG_CTRL_STATUS		0x13
+
+/* Deserializer Registers */
+#define DES_REG_GEN_CONFIG0		0x02
+#define DES_REG_GEN_STATUS		0x1C
+#define DES_REG_MODE_STATUS		0x23
+#define DES_REG_SSCG_CTRL		0x2C
+#define DES_REG_DUAL_RX_CTRL		0x34
+#define DES_REG_MAPSEL			0x49
+#define DES_REG_INDIRECT_ADDR		0x6C
+#define DES_REG_INDIRECT_DATA		0x6D
+
+#define DES_FPD_MODE_MASK		(BIT(4) | BIT(3))
+#define DES_FPD_HW_MODE_AUTO		0x0
+#define DES_FPD_HW_MODE_PRIMARY		BIT(4)
+#define DES_FPD_HW_MODE_SECONDARY	(BIT(4) | BIT(3))
+
+#define SSCG_REG_MASK			0x0F
+#define SSCG_MAX_VALUE			0x7
+#define SSCG_ENABLE			BIT(3)
+
+/* Common Registers and bitfields */
+#define SER_DES_REG_CONFIG		0x03
+
+#define SER_DE_GATE_RGB			BIT(4)
+#define DES_DE_GATE_RGB			BIT(1)
+
+#define PIXEL_CLK_EDGE_RISING		BIT(0)
+
+#define MAPSEL_MASK			(BIT(6) | BIT(5))
+#define MAPSEL_SET			BIT(6)
+#define MAPSEL_MSB			BIT(5)
+
+#define BKWD_MODE_OVERRIDE		BIT(3)
+#define BKWD_MODE_ENABLED		BIT(2)
+#define LF_MODE_OVERRIDE		BIT(1)
+#define LF_MODE_ENABLED			BIT(0)
+
+#define LF_MODE_PIN_STATUS		BIT(3)
+#define BKWD_MODE_PIN_STATUS		BIT(1)
+
+#define GEN_STATUS_LOCK			BIT(0)
+
+#define SER_DES_DEVICE_ID_REG		0xF0
+#define DEVICE_ID_LEN			6
+
+enum ds90ux9xx_capability {
+	DS90UX9XX_CAP_SERIALIZER,
+	DS90UX9XX_CAP_HDCP,
+	DS90UX9XX_CAP_MODES,
+	DS90UX9XX_CAP_SSCG,
+	DS90UX9XX_CAP_PIXEL_CLK_EDGE,
+	DS90UX9XX_CAP_MAPSEL,
+	DS90UX9XX_CAP_DE_GATE,
+};
+
+struct ds90ux9xx_device_property {
+	const char id[DEVICE_ID_LEN];
+	unsigned int num_links;
+	const u32 caps;
+};
+
+struct ds90ux9xx {
+	struct device *dev;
+	struct regmap *regmap;
+	struct mutex indirect;	/* serializes access to indirect registers */
+	struct gpio_desc *power_gpio;
+	enum ds90ux9xx_device_id dev_id;
+	const struct ds90ux9xx_device_property *property;
+};
+
+#define TO_CAP(_cap, _enabled)	(_enabled ? BIT(DS90UX9XX_CAP_ ## _cap) : 0x0)
+
+#define DS90UX9XX_DEVICE(_id, _links, _ser, _hdcp, _modes, _sscg,	\
+			 _pixel, _mapsel, _de_gate)			\
+	[TI_DS90 ## _id] = {						\
+		.id = "_" __stringify(_id),				\
+		.num_links = _links,					\
+		.caps =							\
+			TO_CAP(SERIALIZER, _ser)	|		\
+			TO_CAP(HDCP, _hdcp)		|		\
+			TO_CAP(MODES, _modes)		|		\
+			TO_CAP(SSCG, _sscg)		|		\
+			TO_CAP(PIXEL_CLK_EDGE, _pixel)	|		\
+			TO_CAP(MAPSEL, _mapsel)		|		\
+			TO_CAP(DE_GATE, _de_gate)			\
+	}
+
+static const struct ds90ux9xx_device_property ds90ux9xx_devices[] =  {
+	/*
+	 * List of TI DS90Ux9xx properties:
+	 *      # FPD-links, serializer, HDCP, BW/LF modes, SSCG,
+	 *      pixel clock edge, mapsel, RGB DE Gate
+	 */
+	DS90UX9XX_DEVICE(UB925, 1, 1, 0, 1, 0, 1, 0, 1),
+	DS90UX9XX_DEVICE(UH925, 1, 1, 1, 1, 0, 1, 0, 1),
+	DS90UX9XX_DEVICE(UB927, 1, 1, 0, 1, 0, 0, 1, 1),
+	DS90UX9XX_DEVICE(UH927, 1, 1, 1, 1, 0, 0, 1, 1),
+	DS90UX9XX_DEVICE(UB926, 1, 0, 0, 1, 1, 1, 0, 0),
+	DS90UX9XX_DEVICE(UH926, 1, 0, 1, 1, 1, 1, 0, 0),
+	DS90UX9XX_DEVICE(UB928, 1, 0, 0, 1, 0, 0, 1, 0),
+	DS90UX9XX_DEVICE(UH928, 1, 0, 1, 1, 0, 0, 1, 0),
+	DS90UX9XX_DEVICE(UB940, 2, 0, 0, 0, 0, 0, 0, 1),
+	DS90UX9XX_DEVICE(UH940, 2, 0, 1, 0, 0, 0, 0, 1),
+};
+
+static const struct regmap_config ds90ux9xx_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0xFF,
+	.cache_type = REGCACHE_NONE,
+};
+
+static bool ds90ux9xx_has_capability(struct ds90ux9xx *ds90ux9xx,
+				     enum ds90ux9xx_capability cap)
+{
+	return ds90ux9xx->property->caps & BIT(cap);
+}
+
+bool ds90ux9xx_is_serializer(struct device *dev)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+
+	return ds90ux9xx_has_capability(ds90ux9xx, DS90UX9XX_CAP_SERIALIZER);
+}
+EXPORT_SYMBOL_GPL(ds90ux9xx_is_serializer);
+
+unsigned int ds90ux9xx_num_fpd_links(struct device *dev)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+
+	return ds90ux9xx->property->num_links;
+}
+EXPORT_SYMBOL_GPL(ds90ux9xx_num_fpd_links);
+
+int ds90ux9xx_update_bits_indirect(struct device *dev, u8 reg, u8 mask, u8 val)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	int ret;
+
+	mutex_lock(&ds90ux9xx->indirect);
+
+	ret = regmap_write(ds90ux9xx->regmap, DES_REG_INDIRECT_ADDR, reg);
+	if (ret) {
+		mutex_unlock(&ds90ux9xx->indirect);
+		return ret;
+	}
+
+	ret = regmap_update_bits(ds90ux9xx->regmap, DES_REG_INDIRECT_DATA,
+				 mask, val);
+
+	mutex_unlock(&ds90ux9xx->indirect);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ds90ux9xx_update_bits_indirect);
+
+int ds90ux9xx_write_indirect(struct device *dev, u8 reg, u8 val)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	int ret;
+
+	mutex_lock(&ds90ux9xx->indirect);
+
+	ret = regmap_write(ds90ux9xx->regmap, DES_REG_INDIRECT_ADDR, reg);
+	if (ret) {
+		mutex_unlock(&ds90ux9xx->indirect);
+		return ret;
+	}
+
+	ret = regmap_write(ds90ux9xx->regmap, DES_REG_INDIRECT_DATA, val);
+
+	mutex_unlock(&ds90ux9xx->indirect);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ds90ux9xx_write_indirect);
+
+int ds90ux9xx_read_indirect(struct device *dev, u8 reg, u8 *val)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	unsigned int data;
+	int ret;
+
+	mutex_lock(&ds90ux9xx->indirect);
+
+	ret = regmap_write(ds90ux9xx->regmap, DES_REG_INDIRECT_ADDR, reg);
+	if (ret) {
+		mutex_unlock(&ds90ux9xx->indirect);
+		return ret;
+	}
+
+	ret = regmap_read(ds90ux9xx->regmap, DES_REG_INDIRECT_DATA, &data);
+
+	mutex_unlock(&ds90ux9xx->indirect);
+
+	if (!ret)
+		*val = data;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ds90ux9xx_read_indirect);
+
+static int ds90ux9xx_read_active_link(struct ds90ux9xx *ds90ux9xx,
+				      unsigned int *link)
+{
+	unsigned int val;
+	int ret;
+
+	if (ds90ux9xx->property->num_links == 1) {
+		*link = 0;
+		return 0;
+	}
+
+	ret = regmap_read(ds90ux9xx->regmap, DES_REG_DUAL_RX_CTRL, &val);
+	if (ret) {
+		dev_err(ds90ux9xx->dev, "Failed to read FPD mode\n");
+		return ret;
+	}
+
+	switch (val & DES_FPD_MODE_MASK) {
+	case DES_FPD_HW_MODE_AUTO:
+	case DES_FPD_HW_MODE_PRIMARY:
+		*link = 0;
+		break;
+	case DES_FPD_HW_MODE_SECONDARY:
+		*link = 1;
+		break;
+	default:
+		dev_err(ds90ux9xx->dev, "Unhandled FPD mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Note that lock status is reported if video pattern generator is enabled */
+int ds90ux9xx_get_link_status(struct device *dev, unsigned int *link,
+			      bool *locked)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	unsigned int reg, status;
+	int ret;
+
+	ret = ds90ux9xx_read_active_link(ds90ux9xx, link);
+	if (ret)
+		return ret;
+
+	if (ds90ux9xx_is_serializer(dev))
+		reg = SER_REG_GEN_STATUS;
+	else
+		reg = DES_REG_GEN_STATUS;
+
+	ret = regmap_read(ds90ux9xx->regmap, reg, &status);
+	if (ret) {
+		dev_err(dev, "Unable to get lock status\n");
+		return ret;
+	}
+
+	*locked = status & GEN_STATUS_LOCK ? true : false;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ds90ux9xx_get_link_status);
+
+enum ds90ux9xx_device_id ds90ux9xx_get_ic_type(struct device *dev)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+
+	return ds90ux9xx->dev_id;
+}
+EXPORT_SYMBOL_GPL(ds90ux9xx_get_ic_type);
+
+static int ds90ux9xx_set_de_gate(struct ds90ux9xx *ds90ux9xx, bool enable)
+{
+	unsigned int reg, val;
+
+	if (!ds90ux9xx_has_capability(ds90ux9xx, DS90UX9XX_CAP_DE_GATE))
+		return 0;
+
+	if (ds90ux9xx_is_serializer(ds90ux9xx->dev)) {
+		reg = SER_REG_MODE_SELECT;
+		val = SER_DE_GATE_RGB;
+	} else {
+		reg = SER_DES_REG_CONFIG;
+		val = DES_DE_GATE_RGB;
+	}
+
+	return regmap_update_bits(ds90ux9xx->regmap, reg, val,
+				  enable ? val : 0x0);
+}
+
+static int ds90ux9xx_set_bcmode(struct ds90ux9xx *ds90ux9xx, bool enable)
+{
+	unsigned int reg, val;
+	int ret;
+
+	if (ds90ux9xx_is_serializer(ds90ux9xx->dev))
+		reg = SER_REG_MODE_SELECT;
+	else
+		reg = DES_REG_GEN_CONFIG0;
+
+	val = BKWD_MODE_OVERRIDE;
+	if (enable)
+		val |= BKWD_MODE_ENABLED;
+
+	ret = regmap_update_bits(ds90ux9xx->regmap, reg,
+				 BKWD_MODE_OVERRIDE | BKWD_MODE_ENABLED, val);
+	if (ret)
+		return ret;
+
+	return ds90ux9xx_set_de_gate(ds90ux9xx, !enable);
+}
+
+static int ds90ux9xx_set_lfmode(struct ds90ux9xx *ds90ux9xx, bool enable)
+{
+	unsigned int reg, val;
+
+	if (ds90ux9xx_is_serializer(ds90ux9xx->dev))
+		reg = SER_REG_MODE_SELECT;
+	else
+		reg = DES_REG_GEN_CONFIG0;
+
+	val = LF_MODE_OVERRIDE;
+	if (enable)
+		val |= LF_MODE_ENABLED;
+
+	return regmap_update_bits(ds90ux9xx->regmap, reg,
+				  LF_MODE_OVERRIDE | LF_MODE_ENABLED, val);
+}
+
+static int ds90ux9xx_set_sscg(struct ds90ux9xx *ds90ux9xx, unsigned int val)
+{
+	if ((val & ~SSCG_ENABLE) > SSCG_MAX_VALUE) {
+		dev_err(ds90ux9xx->dev, "Invalid SSCG value: %#x", val);
+		return -EINVAL;
+	}
+
+	return regmap_write(ds90ux9xx->regmap, DES_REG_SSCG_CTRL, val);
+}
+
+static int ds90ux9xx_set_pixel_clk_edge(struct ds90ux9xx *ds90ux9xx,
+					bool rising)
+{
+	return regmap_update_bits(ds90ux9xx->regmap, SER_DES_REG_CONFIG,
+				  PIXEL_CLK_EDGE_RISING,
+				  rising ? PIXEL_CLK_EDGE_RISING : 0x0);
+}
+
+static ssize_t backward_compatible_mode_show(struct device *dev,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	unsigned int cfg_reg, sts_reg, val;
+	int ret, bcmode;
+
+	if (ds90ux9xx_is_serializer(ds90ux9xx->dev)) {
+		cfg_reg = SER_REG_MODE_SELECT;
+		sts_reg = SER_REG_CTRL_STATUS;
+	} else {
+		cfg_reg = DES_REG_GEN_CONFIG0;
+		sts_reg = DES_REG_MODE_STATUS;
+	}
+
+	ret = regmap_read(ds90ux9xx->regmap, cfg_reg, &val);
+	if (ret)
+		return ret;
+
+	if (val & BKWD_MODE_OVERRIDE) {
+		bcmode = val & BKWD_MODE_ENABLED;
+	} else {
+		/* Read mode from pin status */
+		ret = regmap_read(ds90ux9xx->regmap, sts_reg, &val);
+		if (ret)
+			return ret;
+
+		bcmode = val & BKWD_MODE_PIN_STATUS;
+	}
+
+	return sprintf(buf, "%d\n", bcmode ? 1 : 0);
+}
+
+static ssize_t backward_compatible_mode_store(struct device *dev,
+					      struct device_attribute *attr,
+					      const char *buf, size_t count)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	ret = ds90ux9xx_set_bcmode(ds90ux9xx, val);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static DEVICE_ATTR_RW(backward_compatible_mode);
+
+static ssize_t low_frequency_mode_show(struct device *dev,
+				       struct device_attribute *attr, char *buf)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	unsigned int cfg_reg, sts_reg, val;
+	int ret, lfmode;
+
+	if (ds90ux9xx_is_serializer(ds90ux9xx->dev)) {
+		cfg_reg = SER_REG_MODE_SELECT;
+		sts_reg = SER_REG_CTRL_STATUS;
+	} else {
+		cfg_reg = DES_REG_GEN_CONFIG0;
+		sts_reg = DES_REG_MODE_STATUS;
+	}
+
+	ret = regmap_read(ds90ux9xx->regmap, cfg_reg, &val);
+	if (ret)
+		return ret;
+
+	if (val & LF_MODE_OVERRIDE) {
+		lfmode = val & LF_MODE_ENABLED;
+	} else {
+		/* Read mode from pin status */
+		ret = regmap_read(ds90ux9xx->regmap, sts_reg, &val);
+		if (ret)
+			return ret;
+
+		lfmode = val & LF_MODE_PIN_STATUS;
+	}
+
+	return sprintf(buf, "%d\n", lfmode ? 1 : 0);
+}
+
+static ssize_t low_frequency_mode_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	ret = ds90ux9xx_set_lfmode(ds90ux9xx, val);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static DEVICE_ATTR_RW(low_frequency_mode);
+
+static ssize_t sscg_show(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(ds90ux9xx->regmap, DES_REG_SSCG_CTRL, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d\n", val & SSCG_REG_MASK);
+}
+
+static ssize_t sscg_store(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	int ret, val;
+
+	ret = kstrtoint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	ret = ds90ux9xx_set_sscg(ds90ux9xx, val);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static DEVICE_ATTR_RW(sscg);
+
+static ssize_t pixel_clock_edge_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(ds90ux9xx->regmap, SER_DES_REG_CONFIG, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%s\n",
+		       (val & PIXEL_CLK_EDGE_RISING) ? "rising" : "falling");
+}
+
+static ssize_t pixel_clock_edge_store(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	bool rising;
+	int ret;
+
+	if (sysfs_streq(buf, "rising") || sysfs_streq(buf, "1"))
+		rising = true;
+	else if (sysfs_streq(buf, "falling") || sysfs_streq(buf, "0"))
+		rising = false;
+	else
+		return -EINVAL;
+
+	ret = ds90ux9xx_set_pixel_clk_edge(ds90ux9xx, rising);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static DEVICE_ATTR_RW(pixel_clock_edge);
+
+static ssize_t link_show(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	unsigned int link;
+	bool locked;
+	int ret;
+
+	ret = ds90ux9xx_get_link_status(dev, &link, &locked);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u: %s\n", link, locked ? "locked" : "unlocked");
+}
+static DEVICE_ATTR_RO(link);
+
+static struct attribute *ds90ux9xx_attributes[] = {
+	&dev_attr_backward_compatible_mode.attr,
+	&dev_attr_low_frequency_mode.attr,
+	&dev_attr_sscg.attr,
+	&dev_attr_pixel_clock_edge.attr,
+	&dev_attr_link.attr,
+	NULL,
+};
+
+static umode_t ds90ux9xx_attr_is_visible(struct kobject *kobj,
+					 struct attribute *attr, int index)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct ds90ux9xx *ds90ux9xx = dev_get_drvdata(dev);
+	enum ds90ux9xx_capability cap;
+
+	/* Attribute indices match the ds90ux9xx_attributes[] array indices */
+	switch (index) {
+	case 0:	/* Backward compatible mode */
+	case 1:	/* Low frequency mode */
+		cap = DS90UX9XX_CAP_MODES;
+		break;
+	case 2:	/* Spread spectrum clock generator */
+		cap = DS90UX9XX_CAP_SSCG;
+		break;
+	case 3:	/* Pixel clock edge */
+		cap = DS90UX9XX_CAP_PIXEL_CLK_EDGE;
+		break;
+	case 4: /* FPD-III link lock status - visible for all chips */
+		return attr->mode;
+	default:
+		return 0;
+	}
+
+	return ds90ux9xx_has_capability(ds90ux9xx, cap) ? attr->mode : 0;
+}
+
+static const struct attribute_group ds90ux9xx_attr_group = {
+	.attrs = ds90ux9xx_attributes,
+	.is_visible = ds90ux9xx_attr_is_visible,
+};
+__ATTRIBUTE_GROUPS(ds90ux9xx_attr);
+
+static int ds90ux9xx_config_modes(struct ds90ux9xx *ds90ux9xx)
+{
+	struct device_node *np = ds90ux9xx->dev->of_node;
+	u32 mode;
+	int ret;
+
+	if (!ds90ux9xx_has_capability(ds90ux9xx, DS90UX9XX_CAP_MODES))
+		return 0;
+
+	ret = of_property_read_u32(np, "ti,backward-compatible-mode", &mode);
+	if (!ret) {
+		ret = ds90ux9xx_set_bcmode(ds90ux9xx, mode);
+		if (ret)
+			return ret;
+	} else {
+		ret = ds90ux9xx_set_de_gate(ds90ux9xx, true);
+		if (ret)
+			return ret;
+	}
+
+	ret = of_property_read_u32(np, "ti,low-frequency-mode", &mode);
+	if (!ret) {
+		ret = ds90ux9xx_set_lfmode(ds90ux9xx, mode);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int ds90ux9xx_config_sscg(struct ds90ux9xx *ds90ux9xx)
+{
+	struct device_node *np = ds90ux9xx->dev->of_node;
+	u32 sscg;
+	int ret;
+
+	if (!ds90ux9xx_has_capability(ds90ux9xx, DS90UX9XX_CAP_SSCG))
+		return 0;
+
+	ret = of_property_read_u32(np, "ti,spread-spectrum-clock-generation",
+				   &sscg);
+	if (ret)
+		return 0;
+
+	return ds90ux9xx_set_sscg(ds90ux9xx, sscg);
+}
+
+static int ds90ux9xx_config_pixel_clk_edge(struct ds90ux9xx *ds90ux9xx)
+{
+	struct device_node *np = ds90ux9xx->dev->of_node;
+	const char *pixel;
+	bool rising;
+
+	if (!ds90ux9xx_has_capability(ds90ux9xx, DS90UX9XX_CAP_PIXEL_CLK_EDGE))
+		return 0;
+
+	if (of_property_read_string(np, "ti,pixel-clock-edge", &pixel))
+		return 0;
+
+	if (!strcmp(pixel, "rising"))
+		rising = true;
+	else if (!strcmp(pixel, "falling"))
+		rising = false;
+	else
+		return -EINVAL;
+
+	return ds90ux9xx_set_pixel_clk_edge(ds90ux9xx, rising);
+}
+
+static int ds90ux9xx_config_map_select(struct ds90ux9xx *ds90ux9xx)
+{
+	struct device_node *np = ds90ux9xx->dev->of_node;
+	unsigned int reg, val;
+
+	if (!ds90ux9xx_has_capability(ds90ux9xx, DS90UX9XX_CAP_MAPSEL))
+		return 0;
+
+	if (ds90ux9xx_is_serializer(ds90ux9xx->dev))
+		reg = SER_REG_CTRL_STATUS;
+	else
+		reg = DES_REG_MAPSEL;
+
+	if (of_property_read_bool(np, "ti,video-map-select-msb"))
+		val = MAPSEL_SET | MAPSEL_MSB;
+	else if (of_property_read_bool(np, "ti,video-map-select-lsb"))
+		val = MAPSEL_SET;
+	else
+		val = 0;
+
+	return regmap_update_bits(ds90ux9xx->regmap, reg, MAPSEL_MASK, val);
+}
+
+static int ds90ux9xx_config_properties(struct ds90ux9xx *ds90ux9xx)
+{
+	int ret;
+
+	ret = ds90ux9xx_config_modes(ds90ux9xx);
+	if (ret)
+		return ret;
+
+	ret = ds90ux9xx_config_sscg(ds90ux9xx);
+	if (ret)
+		return ret;
+
+	ret = ds90ux9xx_config_pixel_clk_edge(ds90ux9xx);
+	if (ret)
+		return ret;
+
+	return ds90ux9xx_config_map_select(ds90ux9xx);
+}
+
+static const struct i2c_device_id ds90ux9xx_ids[] = {
+	/* Supported serializers */
+	{ "ds90ub925q", TI_DS90UB925 },
+	{ "ds90uh925q", TI_DS90UH925 },
+	{ "ds90ub927q", TI_DS90UB927 },
+	{ "ds90uh927q", TI_DS90UH927 },
+
+	/* Supported deserializers */
+	{ "ds90ub926q", TI_DS90UB926 },
+	{ "ds90uh926q", TI_DS90UH926 },
+	{ "ds90ub928q", TI_DS90UB928 },
+	{ "ds90uh928q", TI_DS90UH928 },
+	{ "ds90ub940q", TI_DS90UB940 },
+	{ "ds90uh940q", TI_DS90UH940 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, ds90ux9xx_ids);
+
+static const struct of_device_id ds90ux9xx_dt_ids[] = {
+	{ .compatible = "ti,ds90ux9xx",  },
+	{ .compatible = "ti,ds90ub925q", },
+	{ .compatible = "ti,ds90uh925q", },
+	{ .compatible = "ti,ds90ub927q", },
+	{ .compatible = "ti,ds90uh927q", },
+	{ .compatible = "ti,ds90ub926q", },
+	{ .compatible = "ti,ds90uh926q", },
+	{ .compatible = "ti,ds90ub928q", },
+	{ .compatible = "ti,ds90uh928q", },
+	{ .compatible = "ti,ds90ub940q", },
+	{ .compatible = "ti,ds90uh940q", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ds90ux9xx_dt_ids);
+
+static int ds90ux9xx_read_ic_type(struct i2c_client *client,
+				  struct ds90ux9xx *ds90ux9xx)
+{
+	u8 device_id[DEVICE_ID_LEN + 1] = { 0 };
+	const struct i2c_device_id *id;
+	const char *id_code;
+	unsigned int i;
+	int ret;
+
+	ret = regmap_raw_read(ds90ux9xx->regmap, SER_DES_DEVICE_ID_REG,
+			      device_id, DEVICE_ID_LEN);
+	if (ret < 0) {
+		dev_err(ds90ux9xx->dev, "Failed to read device id: %d\n", ret);
+		return ret;
+	}
+
+	id = i2c_match_id(ds90ux9xx_ids, client);
+	if (id) {
+		id_code = ds90ux9xx_devices[id->driver_data].id;
+		if (!strncmp(device_id, id_code, DEVICE_ID_LEN)) {
+			ds90ux9xx->dev_id = id->driver_data;
+			return 0;
+		}
+	}
+
+	/* DS90UH925 device quirk */
+	if (!memcmp(device_id, "\0\0\0\0\0\0", DEVICE_ID_LEN)) {
+		if (id && id->driver_data != TI_DS90UH925)
+			dev_err(ds90ux9xx->dev,
+				"Device ID returned all zeroes, assuming device is DS90UH925\n");
+		ds90ux9xx->dev_id = TI_DS90UH925;
+		return 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ds90ux9xx_devices); i++) {
+		if (strncmp(device_id, ds90ux9xx_devices[i].id, DEVICE_ID_LEN))
+			continue;
+
+		if (id)
+			dev_err(ds90ux9xx->dev,
+				"Mismatch between probed device ID [%s] and HW device ID [%s]\n",
+				id_code, device_id);
+
+		ds90ux9xx->dev_id = i;
+		return 0;
+	}
+
+	dev_err(ds90ux9xx->dev, "Device ID [%s] is not supported\n", device_id);
+
+	return -ENODEV;
+}
+
+static int ds90ux9xx_probe(struct i2c_client *client)
+{
+	struct ds90ux9xx *ds90ux9xx;
+	int ret;
+
+	ds90ux9xx = devm_kzalloc(&client->dev, sizeof(*ds90ux9xx), GFP_KERNEL);
+	if (!ds90ux9xx)
+		return -ENOMEM;
+
+	/* Get optional GPIO connected to PDB pin */
+	ds90ux9xx->power_gpio = devm_gpiod_get_optional(&client->dev, "power",
+							GPIOD_OUT_HIGH);
+	if (IS_ERR(ds90ux9xx->power_gpio))
+		return PTR_ERR(ds90ux9xx->power_gpio);
+
+	/* Give time to the controller to initialize itself after power-up */
+	if (ds90ux9xx->power_gpio)
+		usleep_range(2000, 2500);
+
+	ds90ux9xx->dev = &client->dev;
+	ds90ux9xx->regmap = devm_regmap_init_i2c(client,
+						 &ds90ux9xx_regmap_config);
+	if (IS_ERR(ds90ux9xx->regmap))
+		return PTR_ERR(ds90ux9xx->regmap);
+
+	mutex_init(&ds90ux9xx->indirect);
+
+	ret = ds90ux9xx_read_ic_type(client, ds90ux9xx);
+	if (ret)
+		return ret;
+
+	ds90ux9xx->property = &ds90ux9xx_devices[ds90ux9xx->dev_id];
+
+	i2c_set_clientdata(client, ds90ux9xx);
+
+	ret = ds90ux9xx_config_properties(ds90ux9xx);
+	if (ret)
+		return ret;
+
+	ret = sysfs_create_groups(&ds90ux9xx->dev->kobj, ds90ux9xx_attr_groups);
+	if (ret)
+		return ret;
+
+	ret = devm_of_platform_populate(ds90ux9xx->dev);
+	if (ret)
+		sysfs_remove_groups(&ds90ux9xx->dev->kobj,
+				    ds90ux9xx_attr_groups);
+
+	return ret;
+}
+
+static int ds90ux9xx_remove(struct i2c_client *client)
+{
+	struct ds90ux9xx *ds90ux9xx = i2c_get_clientdata(client);
+
+	sysfs_remove_groups(&ds90ux9xx->dev->kobj, ds90ux9xx_attr_groups);
+
+	if (ds90ux9xx->power_gpio)
+		gpiod_set_value_cansleep(ds90ux9xx->power_gpio, 0);
+
+	return 0;
+}
+
+static struct i2c_driver ds90ux9xx_driver = {
+	.driver = {
+		.name = "ds90ux9xx",
+		.of_match_table = ds90ux9xx_dt_ids,
+	},
+	.probe_new = ds90ux9xx_probe,
+	.remove = ds90ux9xx_remove,
+	.id_table = ds90ux9xx_ids,
+};
+module_i2c_driver(ds90ux9xx_driver);
+
+MODULE_AUTHOR("Balasubramani Vivekanandan <balasubramani_vivekanandan@mentor.com>");
+MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>");
+MODULE_DESCRIPTION("TI DS90Ux9xx MFD driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/ds90ux9xx.h b/include/linux/mfd/ds90ux9xx.h
new file mode 100644
index 000000000000..72a5928b6ad1
--- /dev/null
+++ b/include/linux/mfd/ds90ux9xx.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * TI DS90Ux9xx MFD driver
+ *
+ * Copyright (c) 2017-2018 Mentor Graphics Inc.
+ */
+
+#ifndef __LINUX_MFD_DS90UX9XX_H
+#define __LINUX_MFD_DS90UX9XX_H
+
+#include <linux/types.h>
+
+enum ds90ux9xx_device_id {
+	/* Supported serializers */
+	TI_DS90UB925,
+	TI_DS90UH925,
+	TI_DS90UB927,
+	TI_DS90UH927,
+
+	/* Supported deserializers */
+	TI_DS90UB926,
+	TI_DS90UH926,
+	TI_DS90UB928,
+	TI_DS90UH928,
+	TI_DS90UB940,
+	TI_DS90UH940,
+};
+
+struct device;
+
+bool ds90ux9xx_is_serializer(struct device *dev);
+enum ds90ux9xx_device_id ds90ux9xx_get_ic_type(struct device *dev);
+unsigned int ds90ux9xx_num_fpd_links(struct device *dev);
+
+int ds90ux9xx_get_link_status(struct device *dev, unsigned int *link,
+			      bool *locked);
+
+int ds90ux9xx_update_bits_indirect(struct device *dev, u8 reg, u8 mask, u8 val);
+int ds90ux9xx_write_indirect(struct device *dev, unsigned char reg, u8 val);
+int ds90ux9xx_read_indirect(struct device *dev, u8 reg, u8 *val);
+
+#endif /*__LINUX_MFD_DS90UX9XX_H */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
  2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
                   ` (3 preceding siblings ...)
  2018-10-08 21:12 ` [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver Vladimir Zapolskiy
@ 2018-10-08 21:12 ` Vladimir Zapolskiy
  2018-10-12  6:04   ` Lee Jones
  2018-10-08 21:12 ` [PATCH 6/7] pinctrl: ds90ux9xx: add TI DS90Ux9xx pinmux and GPIO controller driver Vladimir Zapolskiy
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-08 21:12 UTC (permalink / raw)
  To: Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel, Vladimir Zapolskiy

From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>

The change adds TI DS90Ux9xx I2C bridge/alias subdevice driver and
FPD Link connection handling mechanism.

Access to I2C devices connected to a remote de-/serializer is done in
a transparent way, on established link detection event such devices
are registered on an I2C bus, which serves a local de-/serializer IC.

The development of the driver was a collaborative work, the
contribution done by Balasubramani Vivekanandan includes:
* original simplistic implementation of the driver,
* support of implicitly specified devices in device tree,
* support of multiple FPD links for TI DS90Ux9xx,
* other kind of valuable review comments, clean-ups and fixes.

Also Steve Longerbeam made the following changes:
* clear address maps after linked device removal,
* disable pass-through in disconnection,
* qualify locked status with non-zero remote address.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
 drivers/mfd/Kconfig                |   8 +
 drivers/mfd/Makefile               |   1 +
 drivers/mfd/ds90ux9xx-i2c-bridge.c | 764 +++++++++++++++++++++++++++++
 3 files changed, 773 insertions(+)
 create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a969fa123f64..d97f652046d9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1294,6 +1294,14 @@ config MFD_DS90UX9XX
 	  controller and so on are provided by separate drivers and should
 	  enabled individually.
 
+config MFD_DS90UX9XX_I2C
+	tristate "TI DS90Ux9xx I2C bridge/alias driver"
+	default MFD_DS90UX9XX
+	depends on MFD_DS90UX9XX
+	help
+	  Select this option to enable I2C bridge/alias and link connection
+	  handling driver for the TI DS90Ux9xx FPD Link de-/serializer ICs.
+
 config MFD_LP3943
 	tristate "TI/National Semiconductor LP3943 MFD Driver"
 	depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index cc92bf5394b7..5414d0cc0898 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -225,6 +225,7 @@ obj-$(CONFIG_MFD_DLN2)		+= dln2.o
 obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
 obj-$(CONFIG_MFD_SKY81452)	+= sky81452.o
 obj-$(CONFIG_MFD_DS90UX9XX)	+= ds90ux9xx-core.o
+obj-$(CONFIG_MFD_DS90UX9XX_I2C)	+= ds90ux9xx-i2c-bridge.o
 
 intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
diff --git a/drivers/mfd/ds90ux9xx-i2c-bridge.c b/drivers/mfd/ds90ux9xx-i2c-bridge.c
new file mode 100644
index 000000000000..f35af0f238c8
--- /dev/null
+++ b/drivers/mfd/ds90ux9xx-i2c-bridge.c
@@ -0,0 +1,764 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * TI DS90Ux9xx I2C bridge/alias controller driver
+ *
+ * Copyright (c) 2017-2018 Mentor Graphics Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/kthread.h>
+#include <linux/mfd/ds90ux9xx.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+/* Serializer Registers */
+#define SER_REG_REMOTE_ID		0x06
+#define SER_REG_I2C_CTRL		0x17
+
+/* Deserializer Registers */
+#define DES_REG_I2C_CTRL		0x05
+#define DES_REG_REMOTE_ID		0x07
+
+/* Common Register address */
+#define SER_DES_REG_DEVICE_ID		0x00
+#define DEVICE_ID_OVERRIDE		BIT(0)
+
+#define SER_DES_REG_CONFIG		0x03
+#define SER_CONFIG_I2C_AUTO_ACK		BIT(5)
+#define CONFIG_I2C_PASS_THROUGH		BIT(3)
+#define DES_CONFIG_I2C_AUTO_ACK	BIT(2)
+
+#define I2C_CTRL_PASS_ALL		BIT(7)
+
+#define DS90UX9XX_MAX_LINKED_DEVICES	2
+#define DS90UX9XX_MAX_SLAVE_DEVICES	8
+
+/* Chosen link connection timings */
+#define CONN_MIN_TIME_MSEC		400U
+#define CONN_STEP_TIME_MSEC		50U
+#define CONN_MAX_TIME_MSEC		1000U
+
+struct ds90ux9xx_i2c_data {
+	const u8 slave_reg[DS90UX9XX_MAX_SLAVE_DEVICES];
+	const u8 alias_reg[DS90UX9XX_MAX_SLAVE_DEVICES];
+	const unsigned int num_slaves;
+};
+
+static const struct ds90ux9xx_i2c_data ds90ux925_i2c = {
+	.slave_reg = { 0x07, },
+	.alias_reg = { 0x08, },
+	.num_slaves = 1,
+};
+
+static const struct ds90ux9xx_i2c_data ds90ux926_i2c = {
+	.slave_reg = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, },
+	.alias_reg = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, },
+	.num_slaves = 8,
+};
+
+static const struct ds90ux9xx_i2c_data ds90ux927_i2c = {
+	.slave_reg = { 0x07, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, },
+	.alias_reg = { 0x08, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, },
+	.num_slaves = 8,
+};
+
+struct ds90ux9xx_i2c_bridged {
+	struct device_node *np;
+	struct i2c_client *i2c;
+	u8 addr;
+};
+
+struct ds90ux9xx_i2c_map {
+	u8 real_addr;
+	u8 alias_addr;
+};
+
+struct ds90ux9xx_i2c_linked {
+	struct ds90ux9xx_i2c_bridged remote;
+	struct ds90ux9xx_i2c_bridged slave[DS90UX9XX_MAX_SLAVE_DEVICES];
+	struct ds90ux9xx_i2c_map map[DS90UX9XX_MAX_SLAVE_DEVICES];
+	unsigned int num_slaves;
+	unsigned int num_maps;
+	bool is_bridged;
+};
+
+struct ds90ux9xx_i2c {
+	struct device *dev;
+	struct regmap *regmap;
+	struct i2c_adapter *adapter;
+	const struct ds90ux9xx_i2c_data *i2c_data;
+	bool remote;
+	struct task_struct *conn_monitor;
+	struct ds90ux9xx_i2c_linked linked[DS90UX9XX_MAX_LINKED_DEVICES];
+	unsigned int link;
+	bool pass_all;
+};
+
+static int ds90ux9xx_setup_i2c_pass_through(struct ds90ux9xx_i2c *i2c_bridge,
+					    bool enable)
+{
+	int ret;
+
+	ret = regmap_update_bits(i2c_bridge->regmap, SER_DES_REG_CONFIG,
+				 CONFIG_I2C_PASS_THROUGH,
+				 enable ? CONFIG_I2C_PASS_THROUGH : 0x0);
+	if (ret)
+		dev_err(i2c_bridge->dev, "Failed to setup pass through\n");
+
+	return ret;
+}
+
+static int ds90ux9xx_setup_i2c_pass_all(struct ds90ux9xx_i2c *i2c_bridge,
+					bool enable)
+{
+	unsigned int reg;
+	int ret;
+
+	if (ds90ux9xx_is_serializer(i2c_bridge->dev->parent))
+		reg = SER_REG_I2C_CTRL;
+	else
+		reg = DES_REG_I2C_CTRL;
+
+	ret = regmap_update_bits(i2c_bridge->regmap, reg, I2C_CTRL_PASS_ALL,
+				 enable ? I2C_CTRL_PASS_ALL : 0x0);
+	if (ret)
+		dev_err(i2c_bridge->dev, "Failed to setup pass all mode\n");
+
+	return ret;
+}
+
+static int ds90ux9xx_setup_auto_ack(struct ds90ux9xx_i2c *i2c_bridge,
+				    bool enable)
+{
+	unsigned int val;
+	int ret;
+
+	if (ds90ux9xx_is_serializer(i2c_bridge->dev->parent))
+		val = SER_CONFIG_I2C_AUTO_ACK;
+	else
+		val = DES_CONFIG_I2C_AUTO_ACK;
+
+	ret = regmap_update_bits(i2c_bridge->regmap, SER_DES_REG_CONFIG, val,
+				 enable ? val : 0x0);
+	if (ret)
+		dev_err(i2c_bridge->dev, "Failed to setup auto ack mode\n");
+
+	return ret;
+}
+
+static int ds90ux9xx_setup_address_mapping(struct ds90ux9xx_i2c *i2c_bridge,
+					   unsigned int i, u8 slave, u8 alias)
+{
+	const struct ds90ux9xx_i2c_data *i2c_data = i2c_bridge->i2c_data;
+	int ret;
+
+	if (i >= i2c_data->num_slaves)
+		return -EINVAL;
+
+	ret = regmap_write(i2c_bridge->regmap, i2c_data->slave_reg[i],
+			   slave << 1);
+	if (ret)
+		return ret;
+
+	return regmap_write(i2c_bridge->regmap, i2c_data->alias_reg[i],
+			    alias << 1);
+}
+
+static void ds90ux9xx_clear_address_mappings(struct ds90ux9xx_i2c *i2c_bridge)
+{
+	unsigned int i;
+
+	for (i = 0; i < i2c_bridge->i2c_data->num_slaves; i++)
+		ds90ux9xx_setup_address_mapping(i2c_bridge, i, 0, 0);
+}
+
+static int ds90ux9xx_setup_address_mappings(struct ds90ux9xx_i2c *i2c_bridge,
+					    struct ds90ux9xx_i2c_linked *linked)
+{
+	struct ds90ux9xx_i2c_map *map;
+	unsigned int i;
+	int ret;
+
+	/* To avoid address collisions disable the remaining slave/aliases */
+	for (i = 0; i < i2c_bridge->i2c_data->num_slaves; i++) {
+		map = &linked->map[i];
+
+		if (i < linked->num_maps)
+			dev_dbg(i2c_bridge->dev, "Mapping remote slave %#x to %#x\n",
+				map->real_addr, map->alias_addr);
+
+		ret = ds90ux9xx_setup_address_mapping(i2c_bridge, i,
+						      map->real_addr,
+						      map->alias_addr);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int ds90ux9xx_get_remote_addr(struct ds90ux9xx_i2c *i2c_bridge, u8 *addr)
+{
+	unsigned int reg, val;
+	int ret;
+
+	if (ds90ux9xx_is_serializer(i2c_bridge->dev->parent))
+		reg = SER_REG_REMOTE_ID;
+	else
+		reg = DES_REG_REMOTE_ID;
+
+	ret = regmap_read(i2c_bridge->regmap, reg, &val);
+	if (ret)
+		dev_err(i2c_bridge->dev, "Failed to get remote addr: %d\n",
+			ret);
+	else
+		*addr = val >> 1;
+
+	return ret;
+}
+
+static int ds90ux9xx_set_remote_addr(struct ds90ux9xx_i2c *i2c_bridge, u8 addr)
+{
+	u8 remote_addr, data[2] = { SER_DES_REG_DEVICE_ID,
+				    (addr << 1) | DEVICE_ID_OVERRIDE };
+	struct i2c_msg msg = {
+		.addr	= addr,
+		.flags	= 0x00,
+		.len	= 2,
+		.buf	= data,
+	};
+	int ret;
+
+	ret = ds90ux9xx_get_remote_addr(i2c_bridge, &remote_addr);
+	if (ret)
+		return ret;
+
+	if (remote_addr == addr)
+		return 0;
+
+	ret = ds90ux9xx_setup_address_mapping(i2c_bridge, 0, remote_addr, addr);
+	if (ret)
+		return ret;
+
+	ret = i2c_transfer(i2c_bridge->adapter, &msg, 1);
+	if (ret != 1)
+		return ret ? ret : -EIO;
+
+	dev_dbg(i2c_bridge->dev, "New address set for remote %#x\n", addr);
+
+	return 0;
+}
+
+static void ds90ux9xx_remove_slave_devices(struct ds90ux9xx_i2c_linked *linked,
+					   bool drop_reference)
+{
+	struct ds90ux9xx_i2c_bridged *slave;
+	unsigned int i;
+
+	if (!linked->is_bridged)
+		return;
+
+	for (i = 0; i < linked->num_slaves; i++) {
+		slave = &linked->slave[i];
+
+		if (slave->i2c) {
+			i2c_unregister_device(slave->i2c);
+			slave->i2c = NULL;
+		}
+
+		if (drop_reference && slave->np) {
+			of_node_put(slave->np);
+			slave->np = NULL;
+		}
+	}
+}
+
+static void ds90ux9xx_remove_linked_device(struct ds90ux9xx_i2c *i2c_bridge,
+					   struct ds90ux9xx_i2c_linked *linked,
+					   bool drop_reference)
+{
+	struct ds90ux9xx_i2c_bridged *remote = &linked->remote;
+
+	ds90ux9xx_remove_slave_devices(linked, drop_reference);
+
+	if (remote->i2c) {
+		if (linked->is_bridged)
+			i2c_unregister_device(remote->i2c);
+		else
+			put_device(&remote->i2c->dev);
+
+		remote->i2c = NULL;
+	}
+
+	if (drop_reference && remote->np) {
+		of_node_put(remote->np);
+		remote->np = NULL;
+	}
+
+	ds90ux9xx_clear_address_mappings(i2c_bridge);
+}
+
+static void ds90ux9xx_remove_linked_devices(struct ds90ux9xx_i2c *i2c_bridge)
+{
+	struct ds90ux9xx_i2c_linked *linked;
+	unsigned int i;
+
+	for (i = 0; i < ds90ux9xx_num_fpd_links(i2c_bridge->dev->parent); i++) {
+		linked = &i2c_bridge->linked[i];
+		ds90ux9xx_remove_linked_device(i2c_bridge, linked, true);
+	}
+}
+
+static void ds90ux9xx_add_bridged_device(struct ds90ux9xx_i2c *i2c_bridge,
+					 struct ds90ux9xx_i2c_bridged *bridged)
+{
+	struct i2c_board_info info = {};
+	int ret;
+
+	dev_dbg(i2c_bridge->dev, "Add I2C device '%s'\n", bridged->np->name);
+
+	info.addr = bridged->addr;
+	info.of_node = bridged->np;
+
+	/* Non-critical, in case of the problem report it and fallback */
+	ret = of_modalias_node(bridged->np, info.type, sizeof(info.type));
+	if (ret)
+		dev_err(i2c_bridge->dev, "Cannot get module alias for '%s'\n",
+			bridged->np->full_name);
+
+	bridged->i2c = i2c_new_device(i2c_bridge->adapter, &info);
+	if (!bridged->i2c)
+		dev_err(i2c_bridge->dev, "Cannot add new I2C device\n");
+}
+
+static int ds90ux9xx_configure_remote_devices(struct ds90ux9xx_i2c *i2c_bridge,
+					struct ds90ux9xx_i2c_linked *linked)
+{
+	struct ds90ux9xx_i2c_bridged *remote = &linked->remote, *slave;
+	unsigned int i;
+	int ret;
+
+	ret = ds90ux9xx_setup_address_mappings(i2c_bridge, linked);
+	if (ret)
+		return ret;
+
+	ds90ux9xx_add_bridged_device(i2c_bridge, remote);
+	if (!remote->i2c)
+		return -ENODEV;
+
+	for (i = 0; i < linked->num_slaves; i++) {
+		slave = &linked->slave[i];
+
+		ds90ux9xx_add_bridged_device(i2c_bridge, slave);
+		if (!slave->i2c) {
+			ds90ux9xx_remove_linked_device(i2c_bridge,
+						       linked, false);
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+
+static void ds90ux9xx_disconnect_remotes(struct ds90ux9xx_i2c *i2c_bridge)
+{
+	unsigned int link = i2c_bridge->link;
+
+	dev_dbg(i2c_bridge->dev, "Link %d is disconnected\n", link);
+
+	ds90ux9xx_remove_linked_device(i2c_bridge,
+				       &i2c_bridge->linked[link], false);
+
+	ds90ux9xx_setup_i2c_pass_through(i2c_bridge, false);
+}
+
+static int ds90ux9xx_connect_remotes(struct ds90ux9xx_i2c *i2c_bridge,
+				     unsigned int link)
+{
+	struct ds90ux9xx_i2c_linked *linked = &i2c_bridge->linked[link];
+	struct ds90ux9xx_i2c_bridged *remote = &linked->remote;
+	int ret;
+
+	dev_dbg(i2c_bridge->dev, "Link %d is connected\n", link);
+
+	i2c_bridge->link = link;
+
+	ret = ds90ux9xx_setup_i2c_pass_through(i2c_bridge, linked->is_bridged);
+	if (ret)
+		return ret;
+
+	if (!linked->is_bridged) {
+		remote->i2c = of_find_i2c_device_by_node(remote->np);
+		return remote->i2c ? 0 : -ENODEV;
+	}
+
+	ret = ds90ux9xx_set_remote_addr(i2c_bridge, remote->addr);
+	if (ret)
+		return ret;
+
+	return ds90ux9xx_configure_remote_devices(i2c_bridge, linked);
+}
+
+static int ds90ux9xx_conn_monitor(void *data)
+{
+	unsigned int link, sleep_time = CONN_MIN_TIME_MSEC;
+	struct ds90ux9xx_i2c *i2c_bridge = data;
+	struct ds90ux9xx_i2c_bridged *remote;
+	struct ds90ux9xx_i2c_linked *linked;
+	bool lock;
+	u8 addr;
+	int ret;
+
+	while (!kthread_should_stop()) {
+		ret = ds90ux9xx_get_link_status(i2c_bridge->dev->parent,
+						&link, &lock);
+		if (ret)
+			goto sleep;
+
+		linked = &i2c_bridge->linked[i2c_bridge->link];
+		remote = &linked->remote;
+
+		ret = ds90ux9xx_get_remote_addr(i2c_bridge, &addr);
+		if (ret < 0)
+			goto sleep;
+
+		lock = lock && (addr != 0);
+
+		if (lock)
+			sleep_time = CONN_MAX_TIME_MSEC;
+		else if (remote->i2c)
+			sleep_time = CONN_MIN_TIME_MSEC;
+		else
+			sleep_time = min_t(unsigned int, CONN_MAX_TIME_MSEC,
+					   sleep_time + CONN_STEP_TIME_MSEC);
+
+		if (remote->i2c && lock && i2c_bridge->link == link) {
+			if (!linked->is_bridged)
+				goto sleep;
+
+			if (remote->addr == addr)
+				goto sleep;
+		}
+
+		if (remote->i2c)
+			ds90ux9xx_disconnect_remotes(i2c_bridge);
+
+		if (!remote->i2c && lock) {
+			ret = ds90ux9xx_connect_remotes(i2c_bridge, link);
+			if (ret < 0)
+				dev_err(i2c_bridge->dev,
+					"Can't establish connection\n");
+		}
+sleep:
+		msleep(sleep_time);
+	}
+
+	return 0;
+}
+
+static int ds90ux9xx_parse_address_mappings(struct ds90ux9xx_i2c *i2c_bridge)
+{
+	const struct ds90ux9xx_i2c_data *i2c_data = i2c_bridge->i2c_data;
+	struct ds90ux9xx_i2c_linked *remote;
+	u32 link, real_addr, alias_addr;
+	unsigned int size, i;
+	const __be32 *list;
+
+	list = of_get_property(i2c_bridge->dev->of_node, "ti,i2c-bridge-maps",
+			       &size);
+	if (!list)
+		return 0;
+
+	if (!size || size % 12) {
+		dev_err(i2c_bridge->dev, "Failed to get valid alias maps\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < size / 12; i++) {
+		link = be32_to_cpu(*list++);
+		real_addr = be32_to_cpu(*list++);
+		alias_addr = be32_to_cpu(*list++);
+
+		if (link >= ds90ux9xx_num_fpd_links(i2c_bridge->dev->parent)) {
+			dev_info(i2c_bridge->dev, "Invalid link id %d\n", i);
+			continue;
+		}
+
+		remote = &i2c_bridge->linked[link];
+		if (remote->num_maps >= i2c_data->num_slaves) {
+			dev_info(i2c_bridge->dev, "Too many aliases\n");
+			break;
+		}
+
+		remote->map[remote->num_maps].real_addr = real_addr;
+		remote->map[remote->num_maps].alias_addr = alias_addr;
+		remote->num_maps++;
+	}
+
+	return 0;
+}
+
+static u8 ds90ux9xx_get_mapped_address(struct ds90ux9xx_i2c_linked *linked,
+				       u8 remote_addr)
+{
+	unsigned int i;
+
+	for (i = 0; i < linked->num_maps; i++) {
+		if (linked->map[i].real_addr == remote_addr)
+			return linked->map[i].alias_addr;
+	}
+
+	/* Fallback to preset address, remote device may be inaccessible */
+	return remote_addr;
+}
+
+static int ds90ux9xx_parse_remote_slaves(struct ds90ux9xx_i2c *i2c_bridge,
+					 struct ds90ux9xx_i2c_linked *linked)
+{
+	struct ds90ux9xx_i2c_bridged *slave;
+	struct device_node *child, *np;
+	u32 addr;
+
+	np = of_get_child_by_name(linked->remote.np, "i2c-bridge");
+	if (!np) {
+		dev_info(i2c_bridge->dev, "I2C bridge device node not found\n");
+		return 0;
+	}
+
+	if (of_get_child_count(np) > DS90UX9XX_MAX_SLAVE_DEVICES) {
+		dev_err(i2c_bridge->dev, "Too many aliased I2C devices\n");
+		of_node_put(np);
+		return -EINVAL;
+	}
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_u32(child, "reg", &addr)) {
+			dev_err(i2c_bridge->dev, "No I2C device address '%s'\n",
+				child->full_name);
+			/* Try the next one */
+			continue;
+		}
+
+		slave = &linked->slave[linked->num_slaves];
+		slave->np = of_node_get(child);
+		if (i2c_bridge->pass_all)
+			slave->addr = addr;
+		else
+			slave->addr = ds90ux9xx_get_mapped_address(linked,
+								   addr);
+
+		linked->num_slaves++;
+	}
+
+	of_node_put(np);
+
+	return 0;
+}
+
+static int ds90ux9xx_configure_link(struct ds90ux9xx_i2c *i2c_bridge)
+{
+	struct device_node *np = i2c_bridge->dev->parent->of_node;
+	struct i2c_client *client;
+	int ret;
+
+	/* The link value is updated when established connection is detected */
+	i2c_bridge->link = 0;
+
+	client = of_find_i2c_device_by_node(np);
+	if (!client || !client->adapter)
+		return -ENODEV;
+
+	i2c_bridge->adapter = client->adapter;
+	put_device(&client->dev);
+
+	ret = ds90ux9xx_setup_i2c_pass_all(i2c_bridge, i2c_bridge->pass_all);
+	if (ret)
+		return ret;
+
+	i2c_bridge->conn_monitor = kthread_run(ds90ux9xx_conn_monitor,
+					       i2c_bridge,
+					       "ds90ux9xx_conn_monitor");
+	if (IS_ERR(i2c_bridge->conn_monitor))
+		return PTR_ERR(i2c_bridge->conn_monitor);
+
+	return 0;
+}
+
+static int ds90ux9xx_set_link_attributes(struct ds90ux9xx_i2c *i2c_bridge)
+{
+	struct device_node *np = i2c_bridge->dev->of_node;
+	struct ds90ux9xx_i2c_linked *linked;
+	struct of_phandle_args remote;
+	unsigned int link, num_links, i;
+	bool auto_ack;
+	int ret;
+
+	if (of_property_read_bool(np, "ti,i2c-bridge-pass-all"))
+		i2c_bridge->pass_all = true;
+
+	auto_ack = of_property_read_bool(np, "ti,i2c-bridge-auto-ack");
+	ret = ds90ux9xx_setup_auto_ack(i2c_bridge, auto_ack);
+	if (ret)
+		return ret;
+
+	ret = ds90ux9xx_parse_address_mappings(i2c_bridge);
+	if (ret)
+		return ret;
+
+	num_links = ds90ux9xx_num_fpd_links(i2c_bridge->dev->parent);
+
+	for (i = 0; i < num_links; i++) {
+		ret = of_parse_phandle_with_fixed_args(np, "ti,i2c-bridges",
+						       2, i, &remote);
+		if (ret) {
+			if (ret == -ENOENT)
+				break;
+			goto drop_nodes;
+		}
+
+		link = remote.args[0];
+		if (link >= num_links) {
+			ret = -EINVAL;
+			goto drop_nodes;
+		}
+
+		linked = &i2c_bridge->linked[link];
+		if (linked->remote.np) {
+			ret = -EINVAL;
+			goto drop_nodes;
+		}
+
+		linked->remote.np = remote.np;
+		linked->remote.addr = remote.args[1];
+
+		/*
+		 * Don't open I2C access over the FPD-link bidirectional channel
+		 * to the remote's slave devices, if the remote is an I2C slave
+		 * attached to a local bus, because the remote's slaves would
+		 * also necessarily have to hang off the same local bus.
+		 * Enabling pass-through in this case will cause I2C collisions
+		 * due to multiple routes to the same device.
+		 */
+		if (of_property_read_bool(linked->remote.np, "reg")) {
+			linked->is_bridged = false;
+			continue;
+		}
+
+		linked->is_bridged = true;
+
+		ret = ds90ux9xx_parse_remote_slaves(i2c_bridge, linked);
+		if (ret)
+			goto drop_nodes;
+	}
+
+	ret = ds90ux9xx_configure_link(i2c_bridge);
+	if (ret)
+		goto drop_nodes;
+
+	return 0;
+
+drop_nodes:
+	ds90ux9xx_remove_linked_devices(i2c_bridge);
+
+	return ret;
+}
+
+static void ds90ux9xx_get_i2c_data(struct ds90ux9xx_i2c *i2c_bridge)
+{
+	enum ds90ux9xx_device_id id =
+		ds90ux9xx_get_ic_type(i2c_bridge->dev->parent);
+
+	switch (id) {
+	case TI_DS90UB925:
+	case TI_DS90UH925:
+		i2c_bridge->i2c_data = &ds90ux925_i2c;
+		break;
+	case TI_DS90UB927:
+	case TI_DS90UH927:
+		i2c_bridge->i2c_data = &ds90ux927_i2c;
+		break;
+	case TI_DS90UB926:
+	case TI_DS90UH926:
+	case TI_DS90UB928:
+	case TI_DS90UH928:
+	case TI_DS90UB940:
+	case TI_DS90UH940:
+		i2c_bridge->i2c_data = &ds90ux926_i2c;
+		break;
+	default:
+		dev_err(i2c_bridge->dev, "Not supported hardware: [%d]\n", id);
+	}
+}
+
+static int ds90ux9xx_i2c_bridge_probe(struct platform_device *pdev)
+{
+	struct ds90ux9xx_i2c *i2c_bridge;
+	struct device *dev = &pdev->dev;
+
+	i2c_bridge = devm_kzalloc(dev, sizeof(*i2c_bridge), GFP_KERNEL);
+	if (!i2c_bridge)
+		return -ENOMEM;
+
+	i2c_bridge->dev = dev;
+	i2c_bridge->regmap = dev_get_regmap(dev->parent, NULL);
+	if (!i2c_bridge->regmap)
+		return -ENODEV;
+
+	i2c_bridge->i2c_data = of_device_get_match_data(dev);
+	if (!i2c_bridge->i2c_data)
+		ds90ux9xx_get_i2c_data(i2c_bridge);
+
+	if (!i2c_bridge->i2c_data)
+		return -ENODEV;
+
+	platform_set_drvdata(pdev, i2c_bridge);
+
+	if (of_property_read_bool(dev->of_node, "ti,i2c-bridges"))
+		return ds90ux9xx_set_link_attributes(i2c_bridge);
+
+	i2c_bridge->remote = true;
+
+	return ds90ux9xx_setup_i2c_pass_through(i2c_bridge, false);
+}
+
+static int ds90ux9xx_i2c_bridge_remove(struct platform_device *pdev)
+{
+	struct ds90ux9xx_i2c *i2c_bridge = platform_get_drvdata(pdev);
+
+	if (i2c_bridge->remote)
+		return 0;
+
+	kthread_stop(i2c_bridge->conn_monitor);
+	ds90ux9xx_remove_linked_devices(i2c_bridge);
+
+	return 0;
+}
+
+static const struct of_device_id ds90ux9xx_i2c_dt_ids[] = {
+	{ .compatible = "ti,ds90ux9xx-i2c-bridge", },
+	{ .compatible = "ti,ds90ux925-i2c-bridge", .data = &ds90ux925_i2c, },
+	{ .compatible = "ti,ds90ux926-i2c-bridge", .data = &ds90ux926_i2c, },
+	{ .compatible = "ti,ds90ux927-i2c-bridge", .data = &ds90ux927_i2c, },
+	{ .compatible = "ti,ds90ux928-i2c-bridge", .data = &ds90ux926_i2c, },
+	{ .compatible = "ti,ds90ux940-i2c-bridge", .data = &ds90ux926_i2c, },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ds90ux9xx_i2c_dt_ids);
+
+static struct platform_driver ds90ux9xx_i2c_bridge_driver = {
+	.probe = ds90ux9xx_i2c_bridge_probe,
+	.remove = ds90ux9xx_i2c_bridge_remove,
+	.driver = {
+		.name = "ds90ux9xx-i2c-bridge",
+		.of_match_table = ds90ux9xx_i2c_dt_ids,
+	},
+};
+module_platform_driver(ds90ux9xx_i2c_bridge_driver);
+
+MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>");
+MODULE_AUTHOR("Balasubramani Vivekanandan <balasubramani_vivekanandan@mentor.com>");
+MODULE_DESCRIPTION("TI DS90Ux9xx I2C bridge/alias controller driver");
+MODULE_LICENSE("GPL");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH 6/7] pinctrl: ds90ux9xx: add TI DS90Ux9xx pinmux and GPIO controller driver
  2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
                   ` (4 preceding siblings ...)
  2018-10-08 21:12 ` [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver Vladimir Zapolskiy
@ 2018-10-08 21:12 ` Vladimir Zapolskiy
  2018-10-10  9:04   ` Linus Walleij
  2018-10-08 21:12 ` [PATCH 7/7] MAINTAINERS: add entry for TI DS90Ux9xx FPD-Link III drivers Vladimir Zapolskiy
  2018-10-12 11:34 ` [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Laurent Pinchart
  7 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-08 21:12 UTC (permalink / raw)
  To: Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel, Vladimir Zapolskiy

From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>

The change adds an MFD cell driver for managing pin functions on
TI DS90Ux9xx de-/serializers.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
 drivers/pinctrl/Kconfig             |  11 +
 drivers/pinctrl/Makefile            |   1 +
 drivers/pinctrl/pinctrl-ds90ux9xx.c | 970 ++++++++++++++++++++++++++++
 3 files changed, 982 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-ds90ux9xx.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 978b2ed4d014..9350263cac4b 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -123,6 +123,17 @@ config PINCTRL_DIGICOLOR
 	select PINMUX
 	select GENERIC_PINCONF
 
+config PINCTRL_DS90UX9XX
+	tristate "TI DS90Ux9xx pin multiplexer and GPIO driver"
+	depends on MFD_DS90UX9XX
+	default MFD_DS90UX9XX
+	select GPIOLIB
+	select PINMUX
+	select GENERIC_PINCONF
+	help
+	  Select this option to enable pinmux and GPIO bridge/controller
+	  driver for the TI DS90Ux9xx de-/serializer chip family.
+
 config PINCTRL_LANTIQ
 	bool
 	depends on LANTIQ
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 8e127bd8610f..34fc2dbfb9c1 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_AT91PIO4)	+= pinctrl-at91-pio4.o
 obj-$(CONFIG_PINCTRL_AMD)	+= pinctrl-amd.o
 obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
 obj-$(CONFIG_PINCTRL_DIGICOLOR)	+= pinctrl-digicolor.o
+obj-$(CONFIG_PINCTRL_DS90UX9XX)	+= pinctrl-ds90ux9xx.o
 obj-$(CONFIG_PINCTRL_FALCON)	+= pinctrl-falcon.o
 obj-$(CONFIG_PINCTRL_GEMINI)	+= pinctrl-gemini.o
 obj-$(CONFIG_PINCTRL_MAX77620)	+= pinctrl-max77620.o
diff --git a/drivers/pinctrl/pinctrl-ds90ux9xx.c b/drivers/pinctrl/pinctrl-ds90ux9xx.c
new file mode 100644
index 000000000000..7fdb5c15743a
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ds90ux9xx.c
@@ -0,0 +1,970 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Pinmux and GPIO controller driver for TI DS90Ux9xx De-/Serializer hardware
+ *
+ * Copyright (c) 2017-2018 Mentor Graphics Inc.
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/mfd/ds90ux9xx.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/sysfs.h>
+
+#include "pinctrl-utils.h"
+
+#define SER_REG_PIN_CTRL		0x12
+#define PIN_CTRL_RGB18			BIT(2)
+#define PIN_CTRL_I2S_DATA_ISLAND	BIT(1)
+#define PIN_CTRL_I2S_CHANNEL_B		(BIT(0) | BIT(3))
+
+#define SER_REG_I2S_SURROUND		0x1A
+#define PIN_CTRL_I2S_SURR_BIT		BIT(0)
+
+#define DES_REG_INDIRECT_PASS		0x16
+
+#define OUTPUT_HIGH			BIT(3)
+#define REMOTE_CONTROL			BIT(2)
+#define DIR_INPUT			BIT(1)
+#define ENABLE_GPIO			BIT(0)
+
+#define GPIO_AS_INPUT			(ENABLE_GPIO | DIR_INPUT)
+#define GPIO_AS_OUTPUT			ENABLE_GPIO
+#define GPIO_OUTPUT_HIGH		(GPIO_AS_OUTPUT | OUTPUT_HIGH)
+#define GPIO_OUTPUT_LOW			GPIO_AS_OUTPUT
+#define GPIO_OUTPUT_REMOTE		(GPIO_AS_OUTPUT | REMOTE_CONTROL)
+
+#define DS90UX9XX_MAX_GROUP_PINS	6
+
+struct ds90ux9xx_gpio {
+	const u8 cfg_reg;
+	const u8 cfg_mask;
+	const u8 stat_reg;
+	const u8 stat_bit;
+	const bool input;
+};
+
+#define DS90UX9XX_PIN_GPIO_SIMPLE(_cfg, _high, _input)		\
+	{							\
+		.cfg_reg	= _cfg,				\
+		.cfg_mask	= _high ? 0xf0 : 0x0f,		\
+		.stat_reg	= 0x0,				\
+		.stat_bit	= 0x0,				\
+		.input		= _input ? true : false,	\
+	}
+
+#define DS90UX9XX_PIN_GPIO(_cfg, _high, _stat, _bit)		\
+	{							\
+		.cfg_reg	= _cfg,				\
+		.cfg_mask	= _high ? 0xf0 : 0x0f,		\
+		.stat_reg	= _stat,			\
+		.stat_bit	= BIT(_bit),			\
+		.input		= true,				\
+	}
+
+enum ds90ux9xx_function {
+	DS90UX9XX_FUNC_NONE,
+	DS90UX9XX_FUNC_GPIO,
+	DS90UX9XX_FUNC_REMOTE,
+	DS90UX9XX_FUNC_PASS,
+	DS90UX9XX_FUNC_I2S_1,
+	DS90UX9XX_FUNC_I2S_2,
+	DS90UX9XX_FUNC_I2S_3,
+	DS90UX9XX_FUNC_I2S_4,
+	DS90UX9XX_FUNC_I2S_M,
+	DS90UX9XX_FUNC_PARALLEL,
+};
+
+struct ds90ux9xx_pin {
+	const unsigned int id;
+	const char *name;
+	const u32 func_mask;
+	const u8 pass_bit;
+	const struct ds90ux9xx_gpio gpio;
+};
+
+#define TO_BIT(_f)	(DS90UX9XX_FUNC_##_f ? BIT(DS90UX9XX_FUNC_##_f) : 0)
+#define DS90UX9XX_GPIO(_pin, _name, _f1, _f2, _f3)			\
+	[_pin] = {							\
+		.id = _pin,						\
+		.name = _name,						\
+		.func_mask = TO_BIT(GPIO) | TO_BIT(_f2) | TO_BIT(_f3),	\
+		.gpio = DS90UX9XX_PIN_##_f1,				\
+	}
+
+#define DS90UX940_GPIO(_pin, _name, _f1, _f2, _f3, _pass)		\
+	[_pin] = {							\
+		.id = _pin,						\
+		.name = _name,						\
+		.func_mask = TO_BIT(GPIO) | TO_BIT(PASS) |		\
+			     TO_BIT(_f2) | TO_BIT(_f3),			\
+		.pass_bit = BIT(_pass),					\
+		.gpio = DS90UX9XX_PIN_##_f1,				\
+	}
+
+struct ds90ux9xx_pinctrl_data {
+	const char *name;
+	const struct ds90ux9xx_pin *pins;
+	const struct pinctrl_pin_desc *pins_desc;
+	const unsigned int npins;
+	const enum ds90ux9xx_function *functions;
+	const unsigned int nfunctions;
+};
+
+static const struct pinctrl_pin_desc ds90ux925_926_pins_desc[] = {
+	PINCTRL_PIN(0, "gpio0"),	/* DS90Ux925 pin 25, DS90Ux926 pin 41 */
+	PINCTRL_PIN(1, "gpio1"),	/* DS90Ux925 pin 26, DS90Ux926 pin 40 */
+	PINCTRL_PIN(2, "gpio2"),	/* DS90Ux925 pin 35, DS90Ux926 pin 28 */
+	PINCTRL_PIN(3, "gpio3"),	/* DS90Ux925 pin 36, DS90Ux926 pin 27 */
+	PINCTRL_PIN(4, "gpio4"),	/* DS90Ux925 pin 43, DS90Ux926 pin 19 */
+	PINCTRL_PIN(5, "gpio5"),	/* DS90Ux925 pin 44, DS90Ux926 pin 18 */
+	PINCTRL_PIN(6, "gpio6"),	/* DS90Ux925 pin 11, DS90Ux926 pin 45 */
+	PINCTRL_PIN(7, "gpio7"),	/* DS90Ux925 pin 12, DS90Ux926 pin 30 */
+	PINCTRL_PIN(8, "gpio8"),	/* DS90Ux925 pin 13, DS90Ux926 pin  1 */
+};
+
+static const struct pinctrl_pin_desc ds90ux927_928_pins_desc[] = {
+	PINCTRL_PIN(0, "gpio0"),	/* DS90Ux927 pin 39, DS90Ux928 pin 14 */
+	PINCTRL_PIN(1, "gpio1"),	/* DS90Ux927 pin 40, DS90Ux928 pin 13 */
+	PINCTRL_PIN(2, "gpio2"),	/* DS90Ux927 pin  5, DS90Ux928 pin 37 */
+	PINCTRL_PIN(3, "gpio3"),	/* DS90Ux927 pin  6, DS90Ux928 pin 36 */
+	PINCTRL_PIN(4, "gpio5"),	/* DS90Ux927 pin  4, DS90Ux928 pin  3 */
+	PINCTRL_PIN(5, "gpio6"),	/* DS90Ux927 pin  3, DS90Ux928 pin  7 */
+	PINCTRL_PIN(6, "gpio7"),	/* DS90Ux927 pin  2, DS90Ux928 pin 10 */
+	PINCTRL_PIN(7, "gpio8"),	/* DS90Ux927 pin  1, DS90Ux928 pin  8 */
+};
+
+static const struct pinctrl_pin_desc ds90ux940_pins_desc[] = {
+	PINCTRL_PIN(0, "gpio0"),	/* DS90Ux940 pin  7 */
+	PINCTRL_PIN(1, "gpio1"),	/* DS90Ux940 pin  8 */
+	PINCTRL_PIN(2, "gpio2"),	/* DS90Ux940 pin 10 */
+	PINCTRL_PIN(3, "gpio3"),	/* DS90Ux940 pin  9 */
+	PINCTRL_PIN(4, "gpio5"),	/* DS90Ux940 pin 11 */
+	PINCTRL_PIN(5, "gpio6"),	/* DS90Ux940 pin 12 */
+	PINCTRL_PIN(6, "gpio7"),	/* DS90Ux940 pin 14 */
+	PINCTRL_PIN(7, "gpio8"),	/* DS90Ux940 pin 13 */
+	PINCTRL_PIN(8, "gpio9"),	/* DS90Ux940 pin 15 */
+};
+
+static const struct ds90ux9xx_pin ds90ux925_pins[] = {
+	DS90UX9XX_GPIO(0, "gpio0", GPIO_SIMPLE(0x0d, 0, 1), REMOTE, PARALLEL),
+	DS90UX9XX_GPIO(1, "gpio1", GPIO_SIMPLE(0x0e, 0, 1), REMOTE, PARALLEL),
+	DS90UX9XX_GPIO(2, "gpio2", GPIO_SIMPLE(0x0e, 1, 1), REMOTE, PARALLEL),
+	DS90UX9XX_GPIO(3, "gpio3", GPIO_SIMPLE(0x0f, 0, 1), REMOTE, PARALLEL),
+	DS90UX9XX_GPIO(4, "gpio4", GPIO_SIMPLE(0x0f, 1, 0),   NONE, PARALLEL),
+	DS90UX9XX_GPIO(5, "gpio5", GPIO_SIMPLE(0x10, 0, 0),  I2S_2, PARALLEL),
+	DS90UX9XX_GPIO(6, "gpio6", GPIO_SIMPLE(0x10, 1, 0),  I2S_1,     NONE),
+	DS90UX9XX_GPIO(7, "gpio7", GPIO_SIMPLE(0x11, 0, 0),  I2S_1,     NONE),
+	DS90UX9XX_GPIO(8, "gpio8", GPIO_SIMPLE(0x11, 1, 0),  I2S_1,     NONE),
+};
+
+static const struct ds90ux9xx_pin ds90ux926_pins[] = {
+	DS90UX9XX_GPIO(0, "gpio0", GPIO_SIMPLE(0x1d, 0, 1), REMOTE, PARALLEL),
+	DS90UX9XX_GPIO(1, "gpio1", GPIO_SIMPLE(0x1e, 0, 1), REMOTE, PARALLEL),
+	DS90UX9XX_GPIO(2, "gpio2", GPIO_SIMPLE(0x1e, 1, 1), REMOTE, PARALLEL),
+	DS90UX9XX_GPIO(3, "gpio3", GPIO_SIMPLE(0x1f, 0, 1), REMOTE, PARALLEL),
+	DS90UX9XX_GPIO(4, "gpio4", GPIO_SIMPLE(0x1f, 1, 0),   NONE, PARALLEL),
+	DS90UX9XX_GPIO(5, "gpio5", GPIO_SIMPLE(0x20, 0, 0),  I2S_2, PARALLEL),
+	DS90UX9XX_GPIO(6, "gpio6", GPIO_SIMPLE(0x20, 1, 0),  I2S_1,     NONE),
+	DS90UX9XX_GPIO(7, "gpio7", GPIO_SIMPLE(0x21, 0, 0),  I2S_1,     NONE),
+	DS90UX9XX_GPIO(8, "gpio8", GPIO_SIMPLE(0x21, 1, 0),  I2S_1,     NONE),
+};
+
+static const struct ds90ux9xx_pin ds90ux927_pins[] = {
+	DS90UX9XX_GPIO(0, "gpio0", GPIO(0x0d, 0, 0x1c, 0), REMOTE,  NONE),
+	DS90UX9XX_GPIO(1, "gpio1", GPIO(0x0e, 0, 0x1c, 1), REMOTE,  NONE),
+	DS90UX9XX_GPIO(2, "gpio2", GPIO(0x0e, 1, 0x1c, 2), REMOTE, I2S_3),
+	DS90UX9XX_GPIO(3, "gpio3", GPIO(0x0f, 0, 0x1c, 3), REMOTE, I2S_4),
+	DS90UX9XX_GPIO(4, "gpio5", GPIO(0x10, 0, 0x1c, 5),   NONE, I2S_2),
+	DS90UX9XX_GPIO(5, "gpio6", GPIO(0x10, 1, 0x1c, 6),   NONE, I2S_1),
+	DS90UX9XX_GPIO(6, "gpio7", GPIO(0x11, 0, 0x1c, 7),   NONE, I2S_1),
+	DS90UX9XX_GPIO(7, "gpio8", GPIO(0x11, 1, 0x1d, 0),   NONE, I2S_1),
+};
+
+static const struct ds90ux9xx_pin ds90ux928_pins[] = {
+	DS90UX9XX_GPIO(0, "gpio0", GPIO(0x1d, 0, 0x6e, 0), REMOTE, I2S_M),
+	DS90UX9XX_GPIO(1, "gpio1", GPIO(0x1e, 0, 0x6e, 1), REMOTE, I2S_M),
+	DS90UX9XX_GPIO(2, "gpio2", GPIO(0x1e, 1, 0x6e, 2), REMOTE, I2S_3),
+	DS90UX9XX_GPIO(3, "gpio3", GPIO(0x1f, 0, 0x6e, 3), REMOTE, I2S_4),
+	DS90UX9XX_GPIO(4, "gpio5", GPIO(0x20, 0, 0x6e, 5),   NONE, I2S_2),
+	DS90UX9XX_GPIO(5, "gpio6", GPIO(0x20, 1, 0x6e, 6),   NONE, I2S_1),
+	DS90UX9XX_GPIO(6, "gpio7", GPIO(0x21, 0, 0x6e, 7),   NONE, I2S_1),
+	DS90UX9XX_GPIO(7, "gpio8", GPIO(0x21, 1, 0x6f, 0),   NONE, I2S_1),
+};
+
+static const struct ds90ux9xx_pin ds90ux940_pins[] = {
+	DS90UX940_GPIO(0, "gpio0", GPIO(0x1d, 0, 0x6e, 0), REMOTE, I2S_M, 1),
+	DS90UX9XX_GPIO(1, "gpio1", GPIO(0x1e, 0, 0x6e, 1), REMOTE, I2S_M),
+	DS90UX9XX_GPIO(2, "gpio2", GPIO(0x1e, 1, 0x6e, 2), REMOTE, I2S_3),
+	DS90UX940_GPIO(3, "gpio3", GPIO(0x1f, 0, 0x6e, 3), REMOTE, I2S_4, 2),
+	DS90UX9XX_GPIO(4, "gpio5", GPIO(0x20, 0, 0x6e, 5),   NONE, I2S_2),
+	DS90UX9XX_GPIO(5, "gpio6", GPIO(0x20, 1, 0x6e, 6),   NONE, I2S_1),
+	DS90UX9XX_GPIO(6, "gpio7", GPIO(0x21, 0, 0x6e, 7),   NONE, I2S_1),
+	DS90UX9XX_GPIO(7, "gpio8", GPIO(0x21, 1, 0x6f, 0),   NONE, I2S_1),
+	DS90UX9XX_GPIO(8, "gpio9", GPIO_SIMPLE(0x1a, 0, 1),  NONE, I2S_M),
+};
+
+static const enum ds90ux9xx_function ds90ux925_926_pin_functions[] = {
+	DS90UX9XX_FUNC_GPIO,
+	DS90UX9XX_FUNC_REMOTE,
+	DS90UX9XX_FUNC_I2S_1,
+	DS90UX9XX_FUNC_I2S_2,
+	DS90UX9XX_FUNC_PARALLEL,
+};
+
+static const enum ds90ux9xx_function ds90ux927_pin_functions[] = {
+	DS90UX9XX_FUNC_GPIO,
+	DS90UX9XX_FUNC_REMOTE,
+	DS90UX9XX_FUNC_I2S_1,
+	DS90UX9XX_FUNC_I2S_2,
+	DS90UX9XX_FUNC_I2S_3,
+	DS90UX9XX_FUNC_I2S_4,
+};
+
+static const enum ds90ux9xx_function ds90ux928_pin_functions[] = {
+	DS90UX9XX_FUNC_GPIO,
+	DS90UX9XX_FUNC_REMOTE,
+	DS90UX9XX_FUNC_I2S_1,
+	DS90UX9XX_FUNC_I2S_2,
+	DS90UX9XX_FUNC_I2S_3,
+	DS90UX9XX_FUNC_I2S_4,
+	DS90UX9XX_FUNC_I2S_M,
+};
+
+static const enum ds90ux9xx_function ds90ux940_pin_functions[] = {
+	DS90UX9XX_FUNC_GPIO,
+	DS90UX9XX_FUNC_REMOTE,
+	DS90UX9XX_FUNC_PASS,
+	DS90UX9XX_FUNC_I2S_1,
+	DS90UX9XX_FUNC_I2S_2,
+	DS90UX9XX_FUNC_I2S_3,
+	DS90UX9XX_FUNC_I2S_4,
+	DS90UX9XX_FUNC_I2S_M,
+};
+
+static const struct ds90ux9xx_pinctrl_data ds90ux925_pinctrl = {
+	.name = "ds90ux925",
+	.pins_desc = ds90ux925_926_pins_desc,
+	.pins = ds90ux925_pins,
+	.npins = ARRAY_SIZE(ds90ux925_pins),
+	.functions = ds90ux925_926_pin_functions,
+	.nfunctions = ARRAY_SIZE(ds90ux925_926_pin_functions),
+};
+
+static const struct ds90ux9xx_pinctrl_data ds90ux926_pinctrl = {
+	.name = "ds90ux926",
+	.pins_desc = ds90ux925_926_pins_desc,
+	.pins = ds90ux926_pins,
+	.npins = ARRAY_SIZE(ds90ux926_pins),
+	.functions = ds90ux925_926_pin_functions,
+	.nfunctions = ARRAY_SIZE(ds90ux925_926_pin_functions),
+};
+
+static const struct ds90ux9xx_pinctrl_data ds90ux927_pinctrl = {
+	.name = "ds90ux927",
+	.pins_desc = ds90ux927_928_pins_desc,
+	.pins = ds90ux927_pins,
+	.npins = ARRAY_SIZE(ds90ux927_pins),
+	.functions = ds90ux927_pin_functions,
+	.nfunctions = ARRAY_SIZE(ds90ux927_pin_functions),
+};
+
+static const struct ds90ux9xx_pinctrl_data ds90ux928_pinctrl = {
+	.name = "ds90ux928",
+	.pins_desc = ds90ux927_928_pins_desc,
+	.pins = ds90ux928_pins,
+	.npins = ARRAY_SIZE(ds90ux928_pins),
+	.functions = ds90ux928_pin_functions,
+	.nfunctions = ARRAY_SIZE(ds90ux928_pin_functions),
+};
+
+static const struct ds90ux9xx_pinctrl_data ds90ux940_pinctrl = {
+	.name = "ds90ux940",
+	.pins_desc = ds90ux940_pins_desc,
+	.pins = ds90ux940_pins,
+	.npins = ARRAY_SIZE(ds90ux940_pins),
+	.functions = ds90ux940_pin_functions,
+	.nfunctions = ARRAY_SIZE(ds90ux940_pin_functions),
+};
+
+struct ds90ux9xx_pin_function {
+	enum ds90ux9xx_function id;
+	const char **groups;
+	unsigned int ngroups;
+};
+
+struct ds90ux9xx_pin_group {
+	const char *name;
+	unsigned int pins[DS90UX9XX_MAX_GROUP_PINS];
+	unsigned int npins;
+};
+
+struct ds90ux9xx_pinctrl {
+	struct device *dev;
+	struct regmap *regmap;
+
+	struct pinctrl_dev *pctrl;
+	struct pinctrl_desc desc;
+
+	struct ds90ux9xx_pin_function *functions;
+	unsigned int nfunctions;
+
+	struct ds90ux9xx_pin_group *groups;
+	unsigned int ngroups;
+
+	const struct ds90ux9xx_pin *pins;
+	unsigned int npins;
+
+	struct gpio_chip gpiochip;
+	unsigned int ngpios;
+};
+
+static const char *const ds90ux9xx_func_names[] = {
+	[DS90UX9XX_FUNC_NONE]		= "none",
+	[DS90UX9XX_FUNC_GPIO]		= "gpio",
+	[DS90UX9XX_FUNC_REMOTE]		= "gpio-remote",
+	[DS90UX9XX_FUNC_PASS]		= "pass",
+	[DS90UX9XX_FUNC_I2S_1]		= "i2s-1",
+	[DS90UX9XX_FUNC_I2S_2]		= "i2s-2",
+	[DS90UX9XX_FUNC_I2S_3]		= "i2s-3",
+	[DS90UX9XX_FUNC_I2S_4]		= "i2s-4",
+	[DS90UX9XX_FUNC_I2S_M]		= "i2s-m",
+	[DS90UX9XX_FUNC_PARALLEL]	= "parallel",
+};
+
+static bool ds90ux9xx_func_in_group(u32 func_mask, enum ds90ux9xx_function id)
+{
+	u32 mask = BIT(id);
+
+	if (id == DS90UX9XX_FUNC_I2S_4) {
+		mask |= BIT(DS90UX9XX_FUNC_I2S_3);
+		id = DS90UX9XX_FUNC_I2S_3;
+	}
+
+	if (id == DS90UX9XX_FUNC_I2S_3) {
+		mask |= BIT(DS90UX9XX_FUNC_I2S_2);
+		id = DS90UX9XX_FUNC_I2S_2;
+	}
+
+	if (id == DS90UX9XX_FUNC_I2S_2)
+		mask |= BIT(DS90UX9XX_FUNC_I2S_1);
+
+	return func_mask & mask;
+}
+
+static bool ds90ux9xx_pin_function(enum ds90ux9xx_function id)
+{
+	if (id == DS90UX9XX_FUNC_GPIO || id == DS90UX9XX_FUNC_REMOTE ||
+	    id == DS90UX9XX_FUNC_PASS)
+		return true;
+
+	return false;
+}
+
+static int ds90ux9xx_populate_groups(struct ds90ux9xx_pinctrl *pctrl,
+				     const struct ds90ux9xx_pinctrl_data *cfg)
+{
+	struct ds90ux9xx_pin_function *func;
+	struct ds90ux9xx_pin_group *group;
+	enum ds90ux9xx_function func_id;
+	unsigned int i, j, n;
+
+	pctrl->pins = cfg->pins;
+	pctrl->npins = cfg->npins;
+
+	/* Assert that only GPIO pins are muxed, it may be changed in future */
+	for (j = 0; j < pctrl->npins; j++)
+		if (!(pctrl->pins[j].func_mask & BIT(DS90UX9XX_FUNC_GPIO)))
+			return -EINVAL;
+
+	pctrl->ngpios = pctrl->npins;
+
+	pctrl->nfunctions = cfg->nfunctions;
+	pctrl->functions = devm_kcalloc(pctrl->dev, pctrl->nfunctions,
+					sizeof(*pctrl->functions), GFP_KERNEL);
+	if (!pctrl->functions)
+		return -ENOMEM;
+
+	for (i = 0; i < pctrl->nfunctions; i++) {
+		func = &pctrl->functions[i];
+		func->id = cfg->functions[i];
+
+		/*
+		 * Number of pin groups is a sum of pins and pin group functions
+		 */
+		if (ds90ux9xx_pin_function(func->id)) {
+			for (j = 0; j < pctrl->npins; j++) {
+				if (func->id == DS90UX9XX_FUNC_GPIO)
+					pctrl->ngroups++;
+
+				if (pctrl->pins[j].func_mask & BIT(func->id))
+					func->ngroups++;
+			}
+		} else {
+			pctrl->ngroups++;
+			func->ngroups = 1;
+		}
+
+		func->groups = devm_kcalloc(pctrl->dev, func->ngroups,
+					    sizeof(*func->groups), GFP_KERNEL);
+		if (!func->groups)
+			return -ENOMEM;
+
+		if (ds90ux9xx_pin_function(func->id)) {
+			n = 0;
+			for (j = 0; j < pctrl->npins; j++)
+				if (pctrl->pins[j].func_mask & BIT(func->id))
+					func->groups[n++] = pctrl->pins[j].name;
+		} else {
+			/* Group name matches function name */
+			func->groups[0] = ds90ux9xx_func_names[func->id];
+		}
+	}
+
+	pctrl->groups = devm_kcalloc(pctrl->dev, pctrl->ngroups,
+				     sizeof(*pctrl->groups), GFP_KERNEL);
+	if (!pctrl->groups)
+		return -ENOMEM;
+
+	/* Firstly scan for GPIOs as individual pin groups */
+	group = pctrl->groups;
+	for (i = 0; i < pctrl->npins; i++) {
+		group->name = pctrl->pins[i].name;
+		group->pins[0] = pctrl->pins[i].id;
+		group->npins = 1;
+		group++;
+	}
+
+	/* Now scan for the rest of pin groups, which has own functions */
+	for (i = 0; i < pctrl->nfunctions; i++) {
+		func_id = pctrl->functions[i].id;
+
+		/* Those pin groups were accounted above as pin functions */
+		if (ds90ux9xx_pin_function(func_id))
+			continue;
+
+		group->name = ds90ux9xx_func_names[func_id];
+		for (j = 0; j < pctrl->npins; j++) {
+			if (ds90ux9xx_func_in_group(pctrl->pins[j].func_mask,
+						    func_id)) {
+				group->pins[group->npins] = pctrl->pins[j].id;
+				group->npins++;
+			}
+		}
+
+		group++;
+	}
+
+	return 0;
+}
+
+static int ds90ux9xx_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct ds90ux9xx_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->ngroups;
+}
+
+static const char *ds90ux9xx_get_group_name(struct pinctrl_dev *pctldev,
+					    unsigned int group)
+{
+	struct ds90ux9xx_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->groups[group].name;
+}
+
+static int ds90ux9xx_get_group_pins(struct pinctrl_dev *pctldev,
+				    unsigned int group,
+				    const unsigned int **pins,
+				    unsigned int *num_pins)
+{
+	struct ds90ux9xx_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = pctrl->groups[group].pins;
+	*num_pins = pctrl->groups[group].npins;
+
+	return 0;
+}
+
+static const struct pinctrl_ops ds90ux9xx_pinctrl_ops = {
+	.get_groups_count	= ds90ux9xx_get_groups_count,
+	.get_group_name		= ds90ux9xx_get_group_name,
+	.get_group_pins		= ds90ux9xx_get_group_pins,
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_all,
+	.dt_free_map		= pinctrl_utils_free_map,
+};
+
+static int ds90ux9xx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct ds90ux9xx_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctrl->nfunctions;
+}
+
+static const char *ds90ux9xx_get_func_name(struct pinctrl_dev *pctldev,
+					   unsigned int function)
+{
+	struct ds90ux9xx_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return ds90ux9xx_func_names[pctrl->functions[function].id];
+}
+
+static int ds90ux9xx_get_func_groups(struct pinctrl_dev *pctldev,
+				     unsigned int function,
+				     const char * const **groups,
+				     unsigned int * const num_groups)
+{
+	struct ds90ux9xx_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = pctrl->functions[function].groups;
+	*num_groups = pctrl->functions[function].ngroups;
+
+	return 0;
+}
+
+static int ds90ux9xx_gpio_read(struct ds90ux9xx_pinctrl *pctrl,
+			       unsigned int offset, u8 *value)
+{
+	const struct ds90ux9xx_gpio *gpio;
+	unsigned int val;
+	int ret;
+
+	gpio = &pctrl->pins[offset].gpio;
+
+	ret = regmap_read(pctrl->regmap, gpio->cfg_reg, &val);
+	if (ret) {
+		dev_err(pctrl->dev, "Failed to read register %#x, gpio %d\n",
+			gpio->cfg_reg, offset);
+		return ret;
+	}
+
+	*value = val & gpio->cfg_mask;
+	if (gpio->cfg_mask == 0xf0)
+		*value >>= 4;
+
+	return 0;
+}
+
+static int ds90ux9xx_gpio_read_stat(struct ds90ux9xx_pinctrl *pctrl,
+				    unsigned int offset, u8 *value)
+{
+	const struct ds90ux9xx_gpio *gpio;
+	unsigned int val;
+	int ret;
+
+	gpio = &pctrl->pins[offset].gpio;
+
+	if (!gpio->stat_bit)
+		return -EINVAL;
+
+	ret = regmap_read(pctrl->regmap, gpio->stat_reg, &val);
+	if (ret) {
+		dev_err(pctrl->dev, "Failed to read register %#x, gpio %d\n",
+			gpio->stat_reg, offset);
+		return ret;
+	}
+
+	*value = val & gpio->stat_bit;
+
+	return 0;
+}
+
+static int ds90ux9xx_gpio_write(struct ds90ux9xx_pinctrl *pctrl,
+				unsigned int offset, u8 value)
+{
+	const struct ds90ux9xx_gpio *gpio;
+	int ret;
+
+	gpio = &pctrl->pins[offset].gpio;
+
+	if (value & DIR_INPUT && !gpio->input)
+		return -EINVAL;
+
+	if (gpio->cfg_mask == 0xf0)
+		value <<= 4;
+
+	ret = regmap_update_bits(pctrl->regmap, gpio->cfg_reg,
+				 gpio->cfg_mask, value);
+	if (ret)
+		dev_err(pctrl->dev, "Failed to modify register %#x, gpio %d\n",
+			gpio->cfg_reg, offset);
+
+	return ret;
+}
+
+static int ds90ux940_set_pass(struct ds90ux9xx_pinctrl *pctrl,
+			      unsigned int pin, bool enable)
+{
+	u8 bit = pctrl->pins[pin].pass_bit;
+
+	return ds90ux9xx_update_bits_indirect(pctrl->dev->parent,
+			DES_REG_INDIRECT_PASS, bit, enable ? bit : 0x0);
+}
+
+static int ds90ux9xx_pinctrl_group_disable(struct ds90ux9xx_pinctrl *pctrl,
+					   enum ds90ux9xx_function function,
+					   unsigned int pin)
+{
+	int ret;
+
+	switch (function) {
+	case DS90UX9XX_FUNC_GPIO:
+	case DS90UX9XX_FUNC_REMOTE:
+		return ds90ux9xx_gpio_write(pctrl, pin, 0x0);
+	case DS90UX9XX_FUNC_PASS:
+		return ds90ux940_set_pass(pctrl, pin, false);
+	default:
+		break;
+	}
+
+	if (!ds90ux9xx_is_serializer(pctrl->dev->parent))
+		return 0;
+
+	switch (function) {
+	case DS90UX9XX_FUNC_PARALLEL:
+		return regmap_update_bits(pctrl->regmap, SER_REG_PIN_CTRL,
+					  PIN_CTRL_RGB18, PIN_CTRL_RGB18);
+	case DS90UX9XX_FUNC_I2S_4:
+	case DS90UX9XX_FUNC_I2S_3:
+		ret = regmap_update_bits(pctrl->regmap, SER_REG_I2S_SURROUND,
+					 PIN_CTRL_I2S_SURR_BIT, 0x0);
+		if (ret)
+			return ret;
+		/* Fall through */
+	case DS90UX9XX_FUNC_I2S_2:
+		return regmap_update_bits(pctrl->regmap, SER_REG_PIN_CTRL,
+					  PIN_CTRL_I2S_CHANNEL_B, 0x0);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int ds90ux9xx_pinctrl_group_enable(struct ds90ux9xx_pinctrl *pctrl,
+					  enum ds90ux9xx_function function,
+					  struct ds90ux9xx_pin_group *group)
+{
+	unsigned int pin = group->pins[0];
+	int ret;
+
+	switch (function) {
+	case DS90UX9XX_FUNC_GPIO:
+		/* Not all GPIOs can be set to input, fallback to output low */
+		ret = ds90ux9xx_gpio_write(pctrl, pin, GPIO_AS_INPUT);
+		if (ret < 0)
+			ret = ds90ux9xx_gpio_write(pctrl, pin, GPIO_OUTPUT_LOW);
+		return ret;
+	case DS90UX9XX_FUNC_REMOTE:
+		return ds90ux9xx_gpio_write(pctrl, pin, GPIO_OUTPUT_REMOTE);
+	case DS90UX9XX_FUNC_PASS:
+		return ds90ux940_set_pass(pctrl, pin, true);
+	default:
+		break;
+	}
+
+	if (!ds90ux9xx_is_serializer(pctrl->dev->parent))
+		return 0;
+
+	switch (function) {
+	case DS90UX9XX_FUNC_PARALLEL:
+		return regmap_update_bits(pctrl->regmap, SER_REG_PIN_CTRL,
+					  PIN_CTRL_RGB18, 0x0);
+	case DS90UX9XX_FUNC_I2S_4:
+	case DS90UX9XX_FUNC_I2S_3:
+		ret = regmap_update_bits(pctrl->regmap, SER_REG_I2S_SURROUND,
+					 PIN_CTRL_I2S_SURR_BIT,
+					 PIN_CTRL_I2S_SURR_BIT);
+		if (ret)
+			return ret;
+		/* Fall through */
+	case DS90UX9XX_FUNC_I2S_2:
+		return regmap_update_bits(pctrl->regmap, SER_REG_PIN_CTRL,
+			PIN_CTRL_I2S_CHANNEL_B | PIN_CTRL_I2S_DATA_ISLAND,
+					  PIN_CTRL_I2S_CHANNEL_B);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int ds90ux9xx_pinctrl_func_enable(struct ds90ux9xx_pinctrl *pctrl,
+					 enum ds90ux9xx_function function,
+					 struct ds90ux9xx_pin_group *group)
+{
+	enum ds90ux9xx_function func;
+	unsigned int i, pin;
+	u32 func_mask;
+	int ret;
+
+	/* Disable probably enabled pin functions with pin resource conflicts */
+	for (i = 0; i < group->npins; i++) {
+		pin = group->pins[i];
+
+		func_mask = pctrl->pins[pin].func_mask & ~BIT(function);
+
+		/* Abandon remote GPIOs which are covered by GPIO function */
+		if (function == DS90UX9XX_FUNC_REMOTE)
+			func_mask &= ~BIT(DS90UX9XX_FUNC_GPIO);
+		else
+			func_mask &= ~BIT(DS90UX9XX_FUNC_REMOTE);
+
+		/* Zero to three possible conflicting pin functions */
+		while (func_mask) {
+			func = __ffs(func_mask);
+			func_mask &= ~BIT(func);
+			ret = ds90ux9xx_pinctrl_group_disable(pctrl, func, pin);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ds90ux9xx_pinctrl_group_enable(pctrl, function, group);
+}
+
+static int ds90ux9xx_set_mux(struct pinctrl_dev *pctldev,
+			     unsigned int function, unsigned int group)
+{
+	struct ds90ux9xx_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	enum ds90ux9xx_function func = pctrl->functions[function].id;
+	struct ds90ux9xx_pin_group *grp = &pctrl->groups[group];
+
+	return ds90ux9xx_pinctrl_func_enable(pctrl, func, grp);
+}
+
+static int ds90ux9xx_gpio_request_enable(struct pinctrl_dev *pctldev,
+					 struct pinctrl_gpio_range *range,
+					 unsigned int offset)
+{
+	struct ds90ux9xx_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return ds90ux9xx_pinctrl_func_enable(pctrl, DS90UX9XX_FUNC_GPIO,
+					     &pctrl->groups[offset]);
+}
+
+static const struct pinmux_ops ds90ux9xx_pinmux_ops = {
+	.get_functions_count	= ds90ux9xx_get_funcs_count,
+	.get_function_name	= ds90ux9xx_get_func_name,
+	.get_function_groups	= ds90ux9xx_get_func_groups,
+	.set_mux		= ds90ux9xx_set_mux,
+	.gpio_request_enable	= ds90ux9xx_gpio_request_enable,
+	.strict = true,
+};
+
+static const struct pinctrl_desc ds90ux9xx_pinctrl_desc = {
+	.pctlops	= &ds90ux9xx_pinctrl_ops,
+	.pmxops		= &ds90ux9xx_pinmux_ops,
+};
+
+static int ds90ux9xx_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct ds90ux9xx_pinctrl *pctrl = gpiochip_get_data(chip);
+	int ret;
+	u8 val;
+
+	ret = ds90ux9xx_gpio_read(pctrl, offset, &val);
+	if (ret)
+		return ret;
+
+	if (!(val & DIR_INPUT))
+		return !!(val & OUTPUT_HIGH);
+
+	ret = ds90ux9xx_gpio_read_stat(pctrl, offset, &val);
+	if (ret)
+		return ret;
+
+	return !!val;
+}
+
+static void ds90ux9xx_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			       int value)
+{
+	struct ds90ux9xx_pinctrl *pctrl = gpiochip_get_data(chip);
+	u8 val = value ? GPIO_OUTPUT_HIGH : GPIO_OUTPUT_LOW;
+
+	ds90ux9xx_gpio_write(pctrl, offset, val);
+}
+
+static int ds90ux9xx_gpio_get_direction(struct gpio_chip *chip,
+					unsigned int offset)
+{
+	struct ds90ux9xx_pinctrl *pctrl = gpiochip_get_data(chip);
+	int ret;
+	u8 val;
+
+	ret = ds90ux9xx_gpio_read(pctrl, offset, &val);
+	if (ret)
+		return ret;
+
+	return !!(val & DIR_INPUT);
+}
+
+static int ds90ux9xx_gpio_direction_input(struct gpio_chip *chip,
+					  unsigned int offset)
+{
+	struct ds90ux9xx_pinctrl *pctrl = gpiochip_get_data(chip);
+
+	return ds90ux9xx_gpio_write(pctrl, offset, GPIO_AS_INPUT);
+}
+
+static int ds90ux9xx_gpio_direction_output(struct gpio_chip *chip,
+					   unsigned int offset, int value)
+{
+	struct ds90ux9xx_pinctrl *pctrl = gpiochip_get_data(chip);
+	u8 val = value ? GPIO_OUTPUT_HIGH : GPIO_OUTPUT_LOW;
+
+	return ds90ux9xx_gpio_write(pctrl, offset, val);
+}
+
+static const struct gpio_chip ds90ux9xx_gpio_chip = {
+	.owner			= THIS_MODULE,
+	.get			= ds90ux9xx_gpio_get,
+	.set			= ds90ux9xx_gpio_set,
+	.get_direction		= ds90ux9xx_gpio_get_direction,
+	.direction_input	= ds90ux9xx_gpio_direction_input,
+	.direction_output	= ds90ux9xx_gpio_direction_output,
+	.base			= -1,
+	.can_sleep		= 1,
+	.of_gpio_n_cells	= 2,
+	.of_xlate		= of_gpio_simple_xlate,
+};
+
+static int ds90ux9xx_parse_dt_properties(struct ds90ux9xx_pinctrl *pctrl)
+{
+	struct device_node *np = pctrl->dev->of_node;
+	unsigned int val;
+
+	if (!ds90ux9xx_is_serializer(pctrl->dev->parent))
+		return 0;
+
+	/*
+	 * Optionally set "Video Color Depth Mode" to RGB18 mode, it may be
+	 * needed if DS90Ux927 serializer is paired with DS90Ux926 deserializer
+	 * or if there is no pins conflicting with the "parallel" pin group
+	 * to disable RGB24 mode implicitly.
+	 */
+	if (of_property_read_bool(np, "ti,video-depth-18bit"))
+		val = PIN_CTRL_RGB18;
+	else
+		val = 0;
+
+	return regmap_update_bits(pctrl->regmap, SER_REG_PIN_CTRL,
+				  PIN_CTRL_RGB18, val);
+}
+
+static void ds90ux9xx_get_data(struct ds90ux9xx_pinctrl *pctrl,
+			       const struct ds90ux9xx_pinctrl_data **pctrl_data)
+{
+	enum ds90ux9xx_device_id id = ds90ux9xx_get_ic_type(pctrl->dev->parent);
+
+	switch (id) {
+	case TI_DS90UB925:
+	case TI_DS90UH925:
+		*pctrl_data = &ds90ux925_pinctrl;
+		break;
+	case TI_DS90UB927:
+	case TI_DS90UH927:
+		*pctrl_data = &ds90ux927_pinctrl;
+		break;
+	case TI_DS90UB926:
+	case TI_DS90UH926:
+		*pctrl_data = &ds90ux926_pinctrl;
+		break;
+	case TI_DS90UB928:
+	case TI_DS90UH928:
+		*pctrl_data = &ds90ux928_pinctrl;
+		break;
+	case TI_DS90UB940:
+	case TI_DS90UH940:
+		*pctrl_data = &ds90ux940_pinctrl;
+		break;
+	default:
+		dev_err(pctrl->dev, "Unsupported hardware id %d\n", id);
+	}
+}
+
+static int ds90ux9xx_pinctrl_probe(struct platform_device *pdev)
+{
+	const struct ds90ux9xx_pinctrl_data *pctrl_data;
+	struct ds90ux9xx_pinctrl *pctrl;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
+	if (!pctrl)
+		return -ENOMEM;
+
+	pctrl->dev = dev;
+	pctrl->regmap = dev_get_regmap(dev->parent, NULL);
+	if (!pctrl->regmap)
+		return -ENODEV;
+
+	pctrl_data = of_device_get_match_data(dev);
+	if (!pctrl_data)
+		ds90ux9xx_get_data(pctrl, &pctrl_data);
+
+	if (!pctrl_data)
+		return -ENODEV;
+
+	ret = ds90ux9xx_populate_groups(pctrl, pctrl_data);
+	if (ret)
+		return ret;
+
+	ret = ds90ux9xx_parse_dt_properties(pctrl);
+	if (ret)
+		return ret;
+
+	pctrl->desc = ds90ux9xx_pinctrl_desc;
+	pctrl->desc.name = pctrl_data->name;
+	pctrl->desc.pins = pctrl_data->pins_desc;
+	pctrl->desc.npins = pctrl_data->npins;
+
+	pctrl->pctrl = devm_pinctrl_register(dev, &pctrl->desc, pctrl);
+	if (IS_ERR(pctrl->pctrl))
+		return PTR_ERR(pctrl->pctrl);
+
+	platform_set_drvdata(pdev, pctrl);
+
+	pctrl->gpiochip = ds90ux9xx_gpio_chip;
+	pctrl->gpiochip.parent = dev;
+	pctrl->gpiochip.label = pctrl_data->name;
+	pctrl->gpiochip.ngpio = pctrl->ngpios;
+
+	if (of_property_read_bool(dev->of_node, "gpio-ranges")) {
+		pctrl->gpiochip.request = gpiochip_generic_request;
+		pctrl->gpiochip.free = gpiochip_generic_free;
+	}
+
+	return devm_gpiochip_add_data(dev, &pctrl->gpiochip, pctrl);
+}
+
+static const struct of_device_id ds90ux9xx_pinctrl_dt_ids[] = {
+	{ .compatible = "ti,ds90ux9xx-pinctrl", },
+	{ .compatible = "ti,ds90ux925-pinctrl", .data = &ds90ux925_pinctrl, },
+	{ .compatible = "ti,ds90ux926-pinctrl", .data = &ds90ux926_pinctrl, },
+	{ .compatible = "ti,ds90ux927-pinctrl", .data = &ds90ux927_pinctrl, },
+	{ .compatible = "ti,ds90ux928-pinctrl", .data = &ds90ux928_pinctrl, },
+	{ .compatible = "ti,ds90ux940-pinctrl", .data = &ds90ux940_pinctrl, },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ds90ux9xx_pinctrl_dt_ids);
+
+static struct platform_driver ds90ux9xx_pinctrl_driver = {
+	.probe = ds90ux9xx_pinctrl_probe,
+	.driver = {
+		.name = "ds90ux9xx-pinctrl",
+		.of_match_table = ds90ux9xx_pinctrl_dt_ids,
+	},
+};
+module_platform_driver(ds90ux9xx_pinctrl_driver);
+
+MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>");
+MODULE_DESCRIPTION("TI DS90Ux9xx pinmux and GPIO controller driver");
+MODULE_LICENSE("GPL");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH 7/7] MAINTAINERS: add entry for TI DS90Ux9xx FPD-Link III drivers
  2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
                   ` (5 preceding siblings ...)
  2018-10-08 21:12 ` [PATCH 6/7] pinctrl: ds90ux9xx: add TI DS90Ux9xx pinmux and GPIO controller driver Vladimir Zapolskiy
@ 2018-10-08 21:12 ` Vladimir Zapolskiy
  2018-10-12 11:34 ` [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Laurent Pinchart
  7 siblings, 0 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-08 21:12 UTC (permalink / raw)
  To: Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel

Record TI DS90Ux9xx series of serializer and deserializer ICs
and IC subcontrollers as maintained.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 29c08106bd22..3952035b6b71 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14762,6 +14762,16 @@ S:	Maintained
 F:	drivers/media/platform/davinci/
 F:	include/media/davinci/
 
+TI DS90UX9XX FPD-LINK III SERDES DRIVERS
+M:	Vladimir Zapolskiy <vz@mleia.com>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+F:	drivers/mfd/ds90ux9xx-core.c
+F:	drivers/mfd/ds90ux9xx-i2c-bridge.c
+F:	drivers/pinctrl/pinctrl-ds90ux9xx.c
+F:	include/linux/mfd/ds90ux9xx.h
+N:	ds90u[bhx]9*
+
 TI ETHERNET SWITCH DRIVER (CPSW)
 R:	Grygorii Strashko <grygorii.strashko@ti.com>
 L:	linux-omap@vger.kernel.org
-- 
2.17.1


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-08 21:11 ` [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description " Vladimir Zapolskiy
@ 2018-10-09  0:13   ` Marek Vasut
  2018-10-09 11:11     ` Vladimir Zapolskiy
  2018-10-10  8:41   ` Linus Walleij
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 62+ messages in thread
From: Marek Vasut @ 2018-10-09  0:13 UTC (permalink / raw)
  To: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring
  Cc: Laurent Pinchart, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel, Sandeep Jain, Vladimir Zapolskiy

On 10/08/2018 11:11 PM, Vladimir Zapolskiy wrote:
> From: Sandeep Jain <Sandeep_Jain@mentor.com>
> 
> The change adds device tree binding description of TI DS90Ux9xx
> series of serializer and deserializer controllers which support video,
> audio and control data transmission over FPD-III Link connection.
> 
> Signed-off-by: Sandeep Jain <Sandeep_Jain@mentor.com>
> [vzapolskiy: various updates and corrections of secondary importance]
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> ---
>  .../devicetree/bindings/mfd/ti,ds90ux9xx.txt  | 66 +++++++++++++++++++
>  1 file changed, 66 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> new file mode 100644
> index 000000000000..0733da88f7ef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> @@ -0,0 +1,66 @@
> +Texas Instruments DS90Ux9xx de-/serializer controllers
> +
> +Required properties:
> +- compatible: Must contain a generic "ti,ds90ux9xx" value and
> +	may contain one more specific value from the list:
> +	"ti,ds90ub925q",
> +	"ti,ds90uh925q",
> +	"ti,ds90ub927q",
> +	"ti,ds90uh927q",
> +	"ti,ds90ub926q",
> +	"ti,ds90uh926q",

Keep the list sorted.

> +	"ti,ds90ub928q",
> +	"ti,ds90uh928q",
> +	"ti,ds90ub940q",
> +	"ti,ds90uh940q".
> +
> +Optional properties:
> +- reg : Specifies the I2C slave address of a local de-/serializer.
> +- power-gpios : GPIO line to control supplied power to the device.

Shouldn't this be regulator phandle ?

> +- ti,backward-compatible-mode : Overrides backward compatibility mode.
> +	Possible values are "<1>" or "<0>".

Make this bool , ie. present or not.

> +	If "ti,backward-compatible-mode" is not mentioned, the backward
> +	compatibility mode is not touched and given by hardware pin strapping.
> +- ti,low-frequency-mode : Overrides low frequency mode.
> +	Possible values are "<1>" or "<0>".
> +	If "ti,low-frequency-mode" is not mentioned, the low frequency mode
> +	is not touched and given by hardware pin strapping.
> +- ti,video-map-select-msb: Sets video bridge pins to MSB mode, if it is set
> +	MAPSEL pin value is ignored.
> +- ti,video-map-select-lsb: Sets video bridge pins to LSB mode, if it is set
> +	MAPSEL pin value is ignored.

This needs some additional explanation, what's this about ?

> +- ti,pixel-clock-edge : Selects Pixel Clock Edge.
> +	Possible values are "<1>" or "<0>".
> +	If "ti,pixel-clock-edge" is High <1>, output data is strobed on the
> +	Rising edge of the PCLK. If ti,pixel-clock-edge is Low <0>, data is
> +	strobed on the Falling edge of the PCLK.
> +	If "ti,pixel-clock-edge" is not mentioned, the pixel clock edge
> +	value is not touched and given by hardware pin strapping.
> +- ti,spread-spectrum-clock-generation : Spread Sprectrum Clock Generation.
> +	Possible values are from "<0>" to "<7>". The same value will be
> +	written to SSC register. If "ti,spread-spectrum-clock-gen" is not
> +	found, then SSCG will be disabled.
> +
> +TI DS90Ux9xx serializers and deserializer device nodes may contain a number
> +of children device nodes to describe and enable particular subcomponents
> +found on ICs.
> +
> +Example:
> +
> +serializer: serializer@c {
> +	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
> +	reg = <0xc>;
> +	power-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
> +	ti,backward-compatible-mode = <0>;
> +	ti,low-frequency-mode = <0>;
> +	ti,pixel-clock-edge = <0>;
> +	...
> +}
> +
> +deserializer: deserializer@3c {
> +	compatible = "ti,ds90ub940q", "ti,ds90ux9xx";
> +	reg = <0x3c>;
> +	power-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
> +	...
> +}
> +
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-08 21:12 ` [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver Vladimir Zapolskiy
@ 2018-10-09  4:08   ` kbuild test robot
  2018-10-09 11:14     ` Vladimir Zapolskiy
  2018-10-12  6:03   ` Lee Jones
  1 sibling, 1 reply; 62+ messages in thread
From: kbuild test robot @ 2018-10-09  4:08 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: kbuild-all, Lee Jones, Linus Walleij, Rob Herring, Marek Vasut,
	Laurent Pinchart, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel, Vladimir Zapolskiy

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

Hi Vladimir,

I love your patch! Perhaps something to improve:

[auto build test WARNING on ljones-mfd/for-mfd-next]
[also build test WARNING on v4.19-rc7 next-20181008]
[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/Vladimir-Zapolskiy/mfd-pinctrl-add-initial-support-of-TI-DS90Ux9xx-ICs/20181009-090135
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers/mfd/ds90ux9xx-core.c: In function 'ds90ux9xx_probe':
>> drivers/mfd/ds90ux9xx-core.c:789:4: warning: 'id_code' may be used uninitialized in this function [-Wmaybe-uninitialized]
       dev_err(ds90ux9xx->dev,
       ^~~~~~~~~~~~~~~~~~~~~~~                                                                                       
   drivers/mfd/ds90ux9xx-core.c:755:14: note: 'id_code' was declared here
     const char *id_code;
                 ^~~~~~~

vim +/id_code +789 drivers/mfd/ds90ux9xx-core.c

   749	
   750	static int ds90ux9xx_read_ic_type(struct i2c_client *client,
   751					  struct ds90ux9xx *ds90ux9xx)
   752	{
   753		u8 device_id[DEVICE_ID_LEN + 1] = { 0 };
   754		const struct i2c_device_id *id;
   755		const char *id_code;
   756		unsigned int i;
   757		int ret;
   758	
   759		ret = regmap_raw_read(ds90ux9xx->regmap, SER_DES_DEVICE_ID_REG,
   760				      device_id, DEVICE_ID_LEN);
   761		if (ret < 0) {
   762			dev_err(ds90ux9xx->dev, "Failed to read device id: %d\n", ret);
   763			return ret;
   764		}
   765	
   766		id = i2c_match_id(ds90ux9xx_ids, client);
   767		if (id) {
   768			id_code = ds90ux9xx_devices[id->driver_data].id;
   769			if (!strncmp(device_id, id_code, DEVICE_ID_LEN)) {
   770				ds90ux9xx->dev_id = id->driver_data;
   771				return 0;
   772			}
   773		}
   774	
   775		/* DS90UH925 device quirk */
   776		if (!memcmp(device_id, "\0\0\0\0\0\0", DEVICE_ID_LEN)) {
   777			if (id && id->driver_data != TI_DS90UH925)
   778				dev_err(ds90ux9xx->dev,
   779					"Device ID returned all zeroes, assuming device is DS90UH925\n");
   780			ds90ux9xx->dev_id = TI_DS90UH925;
   781			return 0;
   782		}
   783	
   784		for (i = 0; i < ARRAY_SIZE(ds90ux9xx_devices); i++) {
   785			if (strncmp(device_id, ds90ux9xx_devices[i].id, DEVICE_ID_LEN))
   786				continue;
   787	
   788			if (id)
 > 789				dev_err(ds90ux9xx->dev,
   790					"Mismatch between probed device ID [%s] and HW device ID [%s]\n",
   791					id_code, device_id);
   792	
   793			ds90ux9xx->dev_id = i;
   794			return 0;
   795		}
   796	
   797		dev_err(ds90ux9xx->dev, "Device ID [%s] is not supported\n", device_id);
   798	
   799		return -ENODEV;
   800	}
   801	

---
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: 64458 bytes --]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-09  0:13   ` Marek Vasut
@ 2018-10-09 11:11     ` Vladimir Zapolskiy
  2018-10-09 20:55       ` Vladimir Zapolskiy
  0 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-09 11:11 UTC (permalink / raw)
  To: Marek Vasut, Lee Jones, Linus Walleij, Rob Herring
  Cc: Laurent Pinchart, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel, Sandeep Jain, Vladimir Zapolskiy

Hi Marek,

On 10/09/2018 03:13 AM, Marek Vasut wrote:
> On 10/08/2018 11:11 PM, Vladimir Zapolskiy wrote:
>> From: Sandeep Jain <Sandeep_Jain@mentor.com>
>>
>> The change adds device tree binding description of TI DS90Ux9xx
>> series of serializer and deserializer controllers which support video,
>> audio and control data transmission over FPD-III Link connection.
>>
>> Signed-off-by: Sandeep Jain <Sandeep_Jain@mentor.com>
>> [vzapolskiy: various updates and corrections of secondary importance]
>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>> ---
>>  .../devicetree/bindings/mfd/ti,ds90ux9xx.txt  | 66 +++++++++++++++++++
>>  1 file changed, 66 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
>> new file mode 100644
>> index 000000000000..0733da88f7ef
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
>> @@ -0,0 +1,66 @@
>> +Texas Instruments DS90Ux9xx de-/serializer controllers
>> +
>> +Required properties:
>> +- compatible: Must contain a generic "ti,ds90ux9xx" value and
>> +	may contain one more specific value from the list:
>> +	"ti,ds90ub925q",
>> +	"ti,ds90uh925q",
>> +	"ti,ds90ub927q",
>> +	"ti,ds90uh927q",
>> +	"ti,ds90ub926q",
>> +	"ti,ds90uh926q",
> 
> Keep the list sorted.
> 

actually the list is a concatenation of two sorted lists, one for
serializers, another for deserializers.

Perhaps it makes sense to keep the list as it is done now and just
mention the selected order, but then it will complicate the formal
description.

>> +	"ti,ds90ub928q",
>> +	"ti,ds90uh928q",
>> +	"ti,ds90ub940q",
>> +	"ti,ds90uh940q".
>> +
>> +Optional properties:
>> +- reg : Specifies the I2C slave address of a local de-/serializer.
>> +- power-gpios : GPIO line to control supplied power to the device.
> 
> Shouldn't this be regulator phandle ?

It could be, right. I'll ponder upon it.

>> +- ti,backward-compatible-mode : Overrides backward compatibility mode.
>> +	Possible values are "<1>" or "<0>".
> 
> Make this bool , ie. present or not.
> 

It is a real tristate property which is represented by non-present, 0, 1.
It shall not be bool IMHO.

>> +	If "ti,backward-compatible-mode" is not mentioned, the backward
>> +	compatibility mode is not touched and given by hardware pin strapping.
>> +- ti,low-frequency-mode : Overrides low frequency mode.
>> +	Possible values are "<1>" or "<0>".
>> +	If "ti,low-frequency-mode" is not mentioned, the low frequency mode
>> +	is not touched and given by hardware pin strapping.
>> +- ti,video-map-select-msb: Sets video bridge pins to MSB mode, if it is set
>> +	MAPSEL pin value is ignored.
>> +- ti,video-map-select-lsb: Sets video bridge pins to LSB mode, if it is set
>> +	MAPSEL pin value is ignored.
> 
> This needs some additional explanation, what's this about ?
> 

Please reference to datasheet, for instance search for MAPSEL pin description
and overriding I2C commands in http://www.ti.com/lit/ds/symlink/ds90ub927q-q1.pdf

I believe it makes little sense to copy excessive information from an open
datasheet into bindings documentation.

>> +- ti,pixel-clock-edge : Selects Pixel Clock Edge.
>> +	Possible values are "<1>" or "<0>".
>> +	If "ti,pixel-clock-edge" is High <1>, output data is strobed on the
>> +	Rising edge of the PCLK. If ti,pixel-clock-edge is Low <0>, data is
>> +	strobed on the Falling edge of the PCLK.
>> +	If "ti,pixel-clock-edge" is not mentioned, the pixel clock edge
>> +	value is not touched and given by hardware pin strapping.
>> +- ti,spread-spectrum-clock-generation : Spread Sprectrum Clock Generation.
>> +	Possible values are from "<0>" to "<7>". The same value will be
>> +	written to SSC register. If "ti,spread-spectrum-clock-gen" is not
>> +	found, then SSCG will be disabled.
>> +
>> +TI DS90Ux9xx serializers and deserializer device nodes may contain a number
>> +of children device nodes to describe and enable particular subcomponents
>> +found on ICs.
>> +
>> +Example:
>> +
>> +serializer: serializer@c {
>> +	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
>> +	reg = <0xc>;
>> +	power-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
>> +	ti,backward-compatible-mode = <0>;
>> +	ti,low-frequency-mode = <0>;
>> +	ti,pixel-clock-edge = <0>;
>> +	...
>> +}
>> +
>> +deserializer: deserializer@3c {
>> +	compatible = "ti,ds90ub940q", "ti,ds90ux9xx";
>> +	reg = <0x3c>;
>> +	power-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
>> +	...
>> +}
>> +
>>
> 

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-09  4:08   ` kbuild test robot
@ 2018-10-09 11:14     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-09 11:14 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Lee Jones, Linus Walleij, Rob Herring, Marek Vasut,
	Laurent Pinchart, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

On 10/09/2018 07:08 AM, kbuild test robot wrote:
> Hi Vladimir,
> 
> I love your patch! Perhaps something to improve:
> 
> [auto build test WARNING on ljones-mfd/for-mfd-next]
> [also build test WARNING on v4.19-rc7 next-20181008]
> [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/Vladimir-Zapolskiy/mfd-pinctrl-add-initial-support-of-TI-DS90Ux9xx-ICs/20181009-090135
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
> config: i386-allyesconfig (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386 
> 
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
> 

And it is a false positive.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-09 11:11     ` Vladimir Zapolskiy
@ 2018-10-09 20:55       ` Vladimir Zapolskiy
  2018-10-09 21:03         ` Marek Vasut
  0 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-09 20:55 UTC (permalink / raw)
  To: Marek Vasut, Lee Jones, Linus Walleij, Rob Herring
  Cc: Laurent Pinchart, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel, Sandeep Jain, Vladimir Zapolskiy

On 10/09/2018 02:11 PM, Vladimir Zapolskiy wrote:
> Hi Marek,
> 
> On 10/09/2018 03:13 AM, Marek Vasut wrote:
>> On 10/08/2018 11:11 PM, Vladimir Zapolskiy wrote:
>>> From: Sandeep Jain <Sandeep_Jain@mentor.com>
>>>
>>> The change adds device tree binding description of TI DS90Ux9xx
>>> series of serializer and deserializer controllers which support video,
>>> audio and control data transmission over FPD-III Link connection.
>>>

[snip]

>>> +Optional properties:
>>> +- reg : Specifies the I2C slave address of a local de-/serializer.
>>> +- power-gpios : GPIO line to control supplied power to the device.
>>
>> Shouldn't this be regulator phandle ?
> 
> It could be, right. I'll ponder upon it.
> 

No, it can not.

The property describes PDB "Power-down Mode Input Pin", it is a control
pin with the predefined voltage, so regulator phandle is not applicable
here.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-09 20:55       ` Vladimir Zapolskiy
@ 2018-10-09 21:03         ` Marek Vasut
  0 siblings, 0 replies; 62+ messages in thread
From: Marek Vasut @ 2018-10-09 21:03 UTC (permalink / raw)
  To: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring
  Cc: Laurent Pinchart, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel, Sandeep Jain, Vladimir Zapolskiy

On 10/09/2018 10:55 PM, Vladimir Zapolskiy wrote:
> On 10/09/2018 02:11 PM, Vladimir Zapolskiy wrote:
>> Hi Marek,
>>
>> On 10/09/2018 03:13 AM, Marek Vasut wrote:
>>> On 10/08/2018 11:11 PM, Vladimir Zapolskiy wrote:
>>>> From: Sandeep Jain <Sandeep_Jain@mentor.com>
>>>>
>>>> The change adds device tree binding description of TI DS90Ux9xx
>>>> series of serializer and deserializer controllers which support video,
>>>> audio and control data transmission over FPD-III Link connection.
>>>>
> 
> [snip]
> 
>>>> +Optional properties:
>>>> +- reg : Specifies the I2C slave address of a local de-/serializer.
>>>> +- power-gpios : GPIO line to control supplied power to the device.
>>>
>>> Shouldn't this be regulator phandle ?
>>
>> It could be, right. I'll ponder upon it.
>>
> 
> No, it can not.
> 
> The property describes PDB "Power-down Mode Input Pin", it is a control
> pin with the predefined voltage, so regulator phandle is not applicable
> here.

Then the DT binding document needs updating, because this is completely
unclear and confusing.

-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-08 21:11 ` [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description " Vladimir Zapolskiy
  2018-10-09  0:13   ` Marek Vasut
@ 2018-10-10  8:41   ` Linus Walleij
  2018-10-12 11:44   ` Laurent Pinchart
  2018-10-30 16:43   ` Luca Ceresoli
  3 siblings, 0 replies; 62+ messages in thread
From: Linus Walleij @ 2018-10-10  8:41 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Rob Herring, Mark Vasut, Laurent Pinchart,
	Wolfram Sang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:GPIO SUBSYSTEM, linux-media, linux-kernel,
	Sandeep_Jain, Vladimir Zapolskiy, open list:DRM PANEL DRIVERS

 On Mon, Oct 8, 2018 at 11:12 PM Vladimir Zapolskiy <vz@mleia.com> wrote:
> From: Sandeep Jain <Sandeep_Jain@mentor.com>
(...)
> +- ti,pixel-clock-edge : Selects Pixel Clock Edge.
> +       Possible values are "<1>" or "<0>".
> +       If "ti,pixel-clock-edge" is High <1>, output data is strobed on the
> +       Rising edge of the PCLK. If ti,pixel-clock-edge is Low <0>, data is
> +       strobed on the Falling edge of the PCLK.
> +       If "ti,pixel-clock-edge" is not mentioned, the pixel clock edge
> +       value is not touched and given by hardware pin strapping.

Please use the existing binding in
Documentation/devicetree/bindings/display/panel/display-timing.txt
for this: pixelclk-active = [<0>|<1>];

Please reference the above document in your binding.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  2018-10-08 21:12 ` [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux Vladimir Zapolskiy
@ 2018-10-10  8:45   ` Linus Walleij
  2018-10-17 15:02     ` Rob Herring
  2018-10-12 12:01   ` Laurent Pinchart
  1 sibling, 1 reply; 62+ messages in thread
From: Linus Walleij @ 2018-10-10  8:45 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Rob Herring, Mark Vasut, Laurent Pinchart,
	Wolfram Sang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:GPIO SUBSYSTEM, linux-media, linux-kernel,
	Vladimir Zapolskiy

Hi Vladimir,

thanks for your patch!

Can we change the subject to something like "add DT bindings" rather than
"add description" as it is more specific and makes it easier for me as
maintainer.

On Mon, Oct 8, 2018 at 11:12 PM Vladimir Zapolskiy <vz@mleia.com> wrote:

> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>
> TI DS90Ux9xx de-/serializers have a capability to multiplex pin functions,
> in particular a pin may have selectable functions of GPIO, GPIO line
> transmitter, one of I2S lines, one of RGB24 video signal lines and so on.
>
> The change adds a description of DS90Ux9xx pin multiplexers and GPIO
> controllers.
>
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
(...)
> +- gpio-ranges: Mapping to pin controller pins (as described in
> +       Documentation/devicetree/bindings/gpio/gpio.txt)
> +
> +Optional properties:
> +- ti,video-depth-18bit: Sets video bridge pins to RGB 18-bit mode.
> +
> +Available pins, groups and functions (reference to device datasheets):

Please reference the generic binding you're using here:
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

Apart from these small nitpicks it looks very standard and good.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 6/7] pinctrl: ds90ux9xx: add TI DS90Ux9xx pinmux and GPIO controller driver
  2018-10-08 21:12 ` [PATCH 6/7] pinctrl: ds90ux9xx: add TI DS90Ux9xx pinmux and GPIO controller driver Vladimir Zapolskiy
@ 2018-10-10  9:04   ` Linus Walleij
  0 siblings, 0 replies; 62+ messages in thread
From: Linus Walleij @ 2018-10-10  9:04 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Rob Herring, Mark Vasut, Laurent Pinchart,
	Wolfram Sang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:GPIO SUBSYSTEM, linux-media, linux-kernel,
	Vladimir Zapolskiy

Hi Vladimir,

thanks for your patch! Some review comments:

On Mon, Oct 8, 2018 at 11:12 PM Vladimir Zapolskiy <vz@mleia.com> wrote:

> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>
> The change adds an MFD cell driver for managing pin functions on
> TI DS90Ux9xx de-/serializers.
>
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>

Please mention in the commit that you are also adding a GPIO
chip driver.

> +// SPDX-License-Identifier: GPL-2.0-or-later

I prefer the simple "GPL-2.0+" here.

> +#include <linux/of_gpio.h>

You should not need this include. If you do, something is wrong.

> +#define SER_REG_PIN_CTRL               0x12
> +#define PIN_CTRL_RGB18                 BIT(2)
> +#define PIN_CTRL_I2S_DATA_ISLAND       BIT(1)
> +#define PIN_CTRL_I2S_CHANNEL_B         (BIT(0) | BIT(3))
> +
> +#define SER_REG_I2S_SURROUND           0x1A
> +#define PIN_CTRL_I2S_SURR_BIT          BIT(0)
> +
> +#define DES_REG_INDIRECT_PASS          0x16
> +
> +#define OUTPUT_HIGH                    BIT(3)
> +#define REMOTE_CONTROL                 BIT(2)
> +#define DIR_INPUT                      BIT(1)
> +#define ENABLE_GPIO                    BIT(0)
> +
> +#define GPIO_AS_INPUT                  (ENABLE_GPIO | DIR_INPUT)
> +#define GPIO_AS_OUTPUT                 ENABLE_GPIO
> +#define GPIO_OUTPUT_HIGH               (GPIO_AS_OUTPUT | OUTPUT_HIGH)
> +#define GPIO_OUTPUT_LOW                        GPIO_AS_OUTPUT
> +#define GPIO_OUTPUT_REMOTE             (GPIO_AS_OUTPUT | REMOTE_CONTROL)

These have a creepily generic look, like they hit the global GPIO
namespace without really clashing. It gets confusing when reading
the code.

Do you think you could prefix them with DS90_* or something
so it is clear that these defines belong in this driver?

> +static const struct gpio_chip ds90ux9xx_gpio_chip = {
> +       .owner                  = THIS_MODULE,
> +       .get                    = ds90ux9xx_gpio_get,
> +       .set                    = ds90ux9xx_gpio_set,
> +       .get_direction          = ds90ux9xx_gpio_get_direction,
> +       .direction_input        = ds90ux9xx_gpio_direction_input,
> +       .direction_output       = ds90ux9xx_gpio_direction_output,
> +       .base                   = -1,
> +       .can_sleep              = 1,

This is bool so set it = true;

Overall it's a very nice driver. It is pretty complex but pin control
is complex so that's a fact of life.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-08 21:12 ` [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver Vladimir Zapolskiy
  2018-10-09  4:08   ` kbuild test robot
@ 2018-10-12  6:03   ` Lee Jones
  2018-10-12  7:41     ` Vladimir Zapolskiy
  1 sibling, 1 reply; 62+ messages in thread
From: Lee Jones @ 2018-10-12  6:03 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Linus Walleij, Rob Herring, Marek Vasut, Laurent Pinchart,
	Wolfram Sang, devicetree, linux-gpio, linux-media, linux-kernel,
	Vladimir Zapolskiy

On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:

> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> 
> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
> support of subdevice controllers is done in separate drivers, because
> not all IC functionality may be needed in particular situations, and
> this can be fine grained controlled in device tree.
> 
> The development of the driver was a collaborative work, the
> contribution done by Balasubramani Vivekanandan includes:
> * original implementation of the driver based on a reference driver,
> * regmap powered interrupt controller support on serializers,
> * support of implicitly or improperly specified in device tree ICs,
> * support of device properties and attributes: backward compatible
>   mode, low frequency operation mode, spread spectrum clock generator.
> 
> Contribution by Steve Longerbeam:
> * added ds90ux9xx_read_indirect() function,
> * moved number of links property and added ds90ux9xx_num_fpd_links(),
> * moved and updated ds90ux9xx_get_link_status() function to core driver,
> * added fpd_link_show device attribute.
> 
> Sandeep Jain added support of pixel clock edge configuration.
> 
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> ---
>  drivers/mfd/Kconfig           |  14 +
>  drivers/mfd/Makefile          |   1 +
>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
>  include/linux/mfd/ds90ux9xx.h |  42 ++
>  4 files changed, 936 insertions(+)
>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>  create mode 100644 include/linux/mfd/ds90ux9xx.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 8c5dfdce4326..a969fa123f64 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>  	  boards.  MSP430 firmware manages resets and power sequencing,
>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>  
> +config MFD_DS90UX9XX
> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
> +	depends on I2C && OF
> +	select MFD_CORE
> +	select REGMAP_I2C
> +	help
> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
> +
> +	  This driver provides basic support for setting up the de-/serializer
> +	  chips. Additional functionalities like connection handling to
> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
> +	  controller and so on are provided by separate drivers and should
> +	  enabled individually.

This is not an MFD driver.

After a 30 second Google of what this device actually does, perhaps
drivers/media might be a better fit?

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
  2018-10-08 21:12 ` [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver Vladimir Zapolskiy
@ 2018-10-12  6:04   ` Lee Jones
  2018-10-12  7:32     ` Vladimir Zapolskiy
  0 siblings, 1 reply; 62+ messages in thread
From: Lee Jones @ 2018-10-12  6:04 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Linus Walleij, Rob Herring, Marek Vasut, Laurent Pinchart,
	Wolfram Sang, devicetree, linux-gpio, linux-media, linux-kernel,
	Vladimir Zapolskiy

On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:

> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> 
> The change adds TI DS90Ux9xx I2C bridge/alias subdevice driver and
> FPD Link connection handling mechanism.
> 
> Access to I2C devices connected to a remote de-/serializer is done in
> a transparent way, on established link detection event such devices
> are registered on an I2C bus, which serves a local de-/serializer IC.
> 
> The development of the driver was a collaborative work, the
> contribution done by Balasubramani Vivekanandan includes:
> * original simplistic implementation of the driver,
> * support of implicitly specified devices in device tree,
> * support of multiple FPD links for TI DS90Ux9xx,
> * other kind of valuable review comments, clean-ups and fixes.
> 
> Also Steve Longerbeam made the following changes:
> * clear address maps after linked device removal,
> * disable pass-through in disconnection,
> * qualify locked status with non-zero remote address.
> 
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> ---
>  drivers/mfd/Kconfig                |   8 +
>  drivers/mfd/Makefile               |   1 +
>  drivers/mfd/ds90ux9xx-i2c-bridge.c | 764 +++++++++++++++++++++++++++++
>  3 files changed, 773 insertions(+)
>  create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c

Shouldn't this live in drivers/i2c?

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
  2018-10-12  6:04   ` Lee Jones
@ 2018-10-12  7:32     ` Vladimir Zapolskiy
  2018-10-12  9:03       ` Lee Jones
  2018-10-12 13:12       ` Laurent Pinchart
  0 siblings, 2 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-12  7:32 UTC (permalink / raw)
  To: Lee Jones
  Cc: Vladimir Zapolskiy, Linus Walleij, Rob Herring, Marek Vasut,
	Laurent Pinchart, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

Hi Lee,

On 10/12/2018 09:04 AM, Lee Jones wrote:
> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> 
>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>
>> The change adds TI DS90Ux9xx I2C bridge/alias subdevice driver and
>> FPD Link connection handling mechanism.
>>
>> Access to I2C devices connected to a remote de-/serializer is done in
>> a transparent way, on established link detection event such devices
>> are registered on an I2C bus, which serves a local de-/serializer IC.
>>
>> The development of the driver was a collaborative work, the
>> contribution done by Balasubramani Vivekanandan includes:
>> * original simplistic implementation of the driver,
>> * support of implicitly specified devices in device tree,
>> * support of multiple FPD links for TI DS90Ux9xx,
>> * other kind of valuable review comments, clean-ups and fixes.
>>
>> Also Steve Longerbeam made the following changes:
>> * clear address maps after linked device removal,
>> * disable pass-through in disconnection,
>> * qualify locked status with non-zero remote address.
>>
>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>> ---
>>  drivers/mfd/Kconfig                |   8 +
>>  drivers/mfd/Makefile               |   1 +
>>  drivers/mfd/ds90ux9xx-i2c-bridge.c | 764 +++++++++++++++++++++++++++++
>>  3 files changed, 773 insertions(+)
>>  create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c
> 
> Shouldn't this live in drivers/i2c?

no, the driver is not for an I2C controller of any kind, and the driver does
not register itself in the I2C subsystem by calling i2c_add_adapter() or
i2c_add_numbered_adapter() or i2c_mux_add_adapter() etc, this topic was
discussed with Wolfram also.

Formally the driver converts the managed IC into a multi-address I2C
slave device, I understand that it does not sound like a well suited driver
for MFD, but ds90ux9xx-core.c and ds90ux9xx-i2c-bridge.c drivers are quite
tightly coupled.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12  6:03   ` Lee Jones
@ 2018-10-12  7:41     ` Vladimir Zapolskiy
  2018-10-12  8:39       ` Lee Jones
  0 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-12  7:41 UTC (permalink / raw)
  To: Lee Jones, Laurent Pinchart
  Cc: Vladimir Zapolskiy, Linus Walleij, Rob Herring, Marek Vasut,
	Wolfram Sang, devicetree, linux-gpio, linux-media, linux-kernel

Hi Lee,

On 10/12/2018 09:03 AM, Lee Jones wrote:
> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> 
>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>
>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
>> support of subdevice controllers is done in separate drivers, because
>> not all IC functionality may be needed in particular situations, and
>> this can be fine grained controlled in device tree.
>>
>> The development of the driver was a collaborative work, the
>> contribution done by Balasubramani Vivekanandan includes:
>> * original implementation of the driver based on a reference driver,
>> * regmap powered interrupt controller support on serializers,
>> * support of implicitly or improperly specified in device tree ICs,
>> * support of device properties and attributes: backward compatible
>>   mode, low frequency operation mode, spread spectrum clock generator.
>>
>> Contribution by Steve Longerbeam:
>> * added ds90ux9xx_read_indirect() function,
>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
>> * added fpd_link_show device attribute.
>>
>> Sandeep Jain added support of pixel clock edge configuration.
>>
>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>> ---
>>  drivers/mfd/Kconfig           |  14 +
>>  drivers/mfd/Makefile          |   1 +
>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
>>  include/linux/mfd/ds90ux9xx.h |  42 ++
>>  4 files changed, 936 insertions(+)
>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
>>
>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>> index 8c5dfdce4326..a969fa123f64 100644
>> --- a/drivers/mfd/Kconfig
>> +++ b/drivers/mfd/Kconfig
>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>>  	  boards.  MSP430 firmware manages resets and power sequencing,
>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>>  
>> +config MFD_DS90UX9XX
>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
>> +	depends on I2C && OF
>> +	select MFD_CORE
>> +	select REGMAP_I2C
>> +	help
>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
>> +
>> +	  This driver provides basic support for setting up the de-/serializer
>> +	  chips. Additional functionalities like connection handling to
>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
>> +	  controller and so on are provided by separate drivers and should
>> +	  enabled individually.
> 
> This is not an MFD driver.

Why do you think so? The representation of the ICs into device tree format
of hardware description shows that this is a truly MFD driver with multiple
IP subcomponents naturally mapped into MFD cells.

Basically it is possible to replace explicit of_platform_populate() by
adding a "simple-mfd" compatible, if it is desired.

> After a 30 second Google of what this device actually does, perhaps
> drivers/media might be a better fit?
> 

I assume it would be quite unusual to add a driver with NO media functions
and controls into drivers/media.

Laurent, can you please share your opinion?

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12  7:41     ` Vladimir Zapolskiy
@ 2018-10-12  8:39       ` Lee Jones
  2018-10-12  9:20         ` Kieran Bingham
  2018-10-12 11:24         ` Vladimir Zapolskiy
  0 siblings, 2 replies; 62+ messages in thread
From: Lee Jones @ 2018-10-12  8:39 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Laurent Pinchart, Vladimir Zapolskiy, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> On 10/12/2018 09:03 AM, Lee Jones wrote:
> > On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> > 
> >> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>
> >> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
> >> support of subdevice controllers is done in separate drivers, because
> >> not all IC functionality may be needed in particular situations, and
> >> this can be fine grained controlled in device tree.
> >>
> >> The development of the driver was a collaborative work, the
> >> contribution done by Balasubramani Vivekanandan includes:
> >> * original implementation of the driver based on a reference driver,
> >> * regmap powered interrupt controller support on serializers,
> >> * support of implicitly or improperly specified in device tree ICs,
> >> * support of device properties and attributes: backward compatible
> >>   mode, low frequency operation mode, spread spectrum clock generator.
> >>
> >> Contribution by Steve Longerbeam:
> >> * added ds90ux9xx_read_indirect() function,
> >> * moved number of links property and added ds90ux9xx_num_fpd_links(),
> >> * moved and updated ds90ux9xx_get_link_status() function to core driver,
> >> * added fpd_link_show device attribute.
> >>
> >> Sandeep Jain added support of pixel clock edge configuration.
> >>
> >> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >> ---
> >>  drivers/mfd/Kconfig           |  14 +
> >>  drivers/mfd/Makefile          |   1 +
> >>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
> >>  include/linux/mfd/ds90ux9xx.h |  42 ++
> >>  4 files changed, 936 insertions(+)
> >>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
> >>  create mode 100644 include/linux/mfd/ds90ux9xx.h
> >>
> >> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> >> index 8c5dfdce4326..a969fa123f64 100644
> >> --- a/drivers/mfd/Kconfig
> >> +++ b/drivers/mfd/Kconfig
> >> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
> >>  	  boards.  MSP430 firmware manages resets and power sequencing,
> >>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
> >>  
> >> +config MFD_DS90UX9XX
> >> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
> >> +	depends on I2C && OF
> >> +	select MFD_CORE
> >> +	select REGMAP_I2C
> >> +	help
> >> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
> >> +
> >> +	  This driver provides basic support for setting up the de-/serializer
> >> +	  chips. Additional functionalities like connection handling to
> >> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
> >> +	  controller and so on are provided by separate drivers and should
> >> +	  enabled individually.
> > 
> > This is not an MFD driver.
> 
> Why do you think so? The representation of the ICs into device tree format
> of hardware description shows that this is a truly MFD driver with multiple
> IP subcomponents naturally mapped into MFD cells.

This driver does too much real work ('stuff') to be an MFD driver.
MFD drivers should not need to care of; links, gates, modes, pixels,
frequencies maps or properties.  Nor should they contain elaborate
sysfs structures to control the aforementioned 'stuff'.

Granted, there may be some code in there which could be appropriate
for an MFD driver.  However most of it needs moving out into a
function driver (or two).

> Basically it is possible to replace explicit of_platform_populate() by
> adding a "simple-mfd" compatible, if it is desired.
> 
> > After a 30 second Google of what this device actually does, perhaps
> > drivers/media might be a better fit?
> 
> I assume it would be quite unusual to add a driver with NO media functions
> and controls into drivers/media.

drivers/media may very well not be the correct place for this.  In my
30 second Google, I saw that this device has a lot to do with cameras,
hence my media association.

If *all* else fails, there is always drivers/misc, but this should be
avoided if at all possible.

> Laurent, can you please share your opinion?

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
  2018-10-12  7:32     ` Vladimir Zapolskiy
@ 2018-10-12  9:03       ` Lee Jones
  2018-10-12 13:12       ` Laurent Pinchart
  1 sibling, 0 replies; 62+ messages in thread
From: Lee Jones @ 2018-10-12  9:03 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Vladimir Zapolskiy, Linus Walleij, Rob Herring, Marek Vasut,
	Laurent Pinchart, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> On 10/12/2018 09:04 AM, Lee Jones wrote:
> > On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> > 
> >> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>
> >> The change adds TI DS90Ux9xx I2C bridge/alias subdevice driver and
> >> FPD Link connection handling mechanism.
> >>
> >> Access to I2C devices connected to a remote de-/serializer is done in
> >> a transparent way, on established link detection event such devices
> >> are registered on an I2C bus, which serves a local de-/serializer IC.
> >>
> >> The development of the driver was a collaborative work, the
> >> contribution done by Balasubramani Vivekanandan includes:
> >> * original simplistic implementation of the driver,
> >> * support of implicitly specified devices in device tree,
> >> * support of multiple FPD links for TI DS90Ux9xx,
> >> * other kind of valuable review comments, clean-ups and fixes.
> >>
> >> Also Steve Longerbeam made the following changes:
> >> * clear address maps after linked device removal,
> >> * disable pass-through in disconnection,
> >> * qualify locked status with non-zero remote address.
> >>
> >> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >> ---
> >>  drivers/mfd/Kconfig                |   8 +
> >>  drivers/mfd/Makefile               |   1 +
> >>  drivers/mfd/ds90ux9xx-i2c-bridge.c | 764 +++++++++++++++++++++++++++++
> >>  3 files changed, 773 insertions(+)
> >>  create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c
> > 
> > Shouldn't this live in drivers/i2c?
> 
> no, the driver is not for an I2C controller of any kind, and the driver does
> not register itself in the I2C subsystem by calling i2c_add_adapter() or
> i2c_add_numbered_adapter() or i2c_mux_add_adapter() etc, this topic was
> discussed with Wolfram also.
> 
> Formally the driver converts the managed IC into a multi-address I2C
> slave device, I understand that it does not sound like a well suited driver
> for MFD, but ds90ux9xx-core.c and ds90ux9xx-i2c-bridge.c drivers are quite
> tightly coupled.

Using MFD as the default dumping ground for anything which does more
than one thing has also been discussed before. :)

You need to figure out what function this device provides and
re-locate it into the subsystem which it best fits.

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12  8:39       ` Lee Jones
@ 2018-10-12  9:20         ` Kieran Bingham
  2018-10-12 10:58           ` Vladimir Zapolskiy
  2018-10-12 11:24         ` Vladimir Zapolskiy
  1 sibling, 1 reply; 62+ messages in thread
From: Kieran Bingham @ 2018-10-12  9:20 UTC (permalink / raw)
  To: Lee Jones, Vladimir Zapolskiy, Laurent Pinchart
  Cc: Vladimir Zapolskiy, Linus Walleij, Rob Herring, Marek Vasut,
	Wolfram Sang, devicetree, linux-gpio, linux-media, linux-kernel

Hi Vladimir,

On 12/10/18 09:39, Lee Jones wrote:
> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
>> On 10/12/2018 09:03 AM, Lee Jones wrote:
>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
>>>
>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>
>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
>>>> support of subdevice controllers is done in separate drivers, because
>>>> not all IC functionality may be needed in particular situations, and
>>>> this can be fine grained controlled in device tree.
>>>>
>>>> The development of the driver was a collaborative work, the
>>>> contribution done by Balasubramani Vivekanandan includes:
>>>> * original implementation of the driver based on a reference driver,
>>>> * regmap powered interrupt controller support on serializers,
>>>> * support of implicitly or improperly specified in device tree ICs,
>>>> * support of device properties and attributes: backward compatible
>>>>   mode, low frequency operation mode, spread spectrum clock generator.
>>>>
>>>> Contribution by Steve Longerbeam:
>>>> * added ds90ux9xx_read_indirect() function,
>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
>>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
>>>> * added fpd_link_show device attribute.
>>>>
>>>> Sandeep Jain added support of pixel clock edge configuration.
>>>>
>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>> ---
>>>>  drivers/mfd/Kconfig           |  14 +
>>>>  drivers/mfd/Makefile          |   1 +
>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
>>>>  4 files changed, 936 insertions(+)
>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
>>>>
>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>>> index 8c5dfdce4326..a969fa123f64 100644
>>>> --- a/drivers/mfd/Kconfig
>>>> +++ b/drivers/mfd/Kconfig
>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>>>>  
>>>> +config MFD_DS90UX9XX
>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
>>>> +	depends on I2C && OF
>>>> +	select MFD_CORE
>>>> +	select REGMAP_I2C
>>>> +	help
>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
>>>> +
>>>> +	  This driver provides basic support for setting up the de-/serializer
>>>> +	  chips. Additional functionalities like connection handling to
>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
>>>> +	  controller and so on are provided by separate drivers and should
>>>> +	  enabled individually.
>>>
>>> This is not an MFD driver.
>>
>> Why do you think so? The representation of the ICs into device tree format
>> of hardware description shows that this is a truly MFD driver with multiple
>> IP subcomponents naturally mapped into MFD cells.
> 
> This driver does too much real work ('stuff') to be an MFD driver.
> MFD drivers should not need to care of; links, gates, modes, pixels,
> frequencies maps or properties.  Nor should they contain elaborate
> sysfs structures to control the aforementioned 'stuff'.
> 
> Granted, there may be some code in there which could be appropriate
> for an MFD driver.  However most of it needs moving out into a
> function driver (or two).
> 
>> Basically it is possible to replace explicit of_platform_populate() by
>> adding a "simple-mfd" compatible, if it is desired.
>>
>>> After a 30 second Google of what this device actually does, perhaps
>>> drivers/media might be a better fit?
>>
>> I assume it would be quite unusual to add a driver with NO media functions
>> and controls into drivers/media.
> 
> drivers/media may very well not be the correct place for this.  In my
> 30 second Google, I saw that this device has a lot to do with cameras,
> hence my media association.
> 
> If *all* else fails, there is always drivers/misc, but this should be
> avoided if at all possible.


The device as a whole is FPD Link for camera devices I believe, but it
certainly has different functions which are broken out in this
implementation.

I think it might be quite awkward having the i2c components in
drivers/i2c and the media components in drivers/media/i2c, so what about
creating drivers/media/i2c/fpd-link (or such) as a container?

Our GMSL implementation is also a complex camera(s) device - but does
not yet use the MFD framework, perhaps that's something to add to my
todo list.

We currently keep all of the complexity within the max9286.c driver, but
I could foresee that being split further if more devices add to the
complexity of managing the bus. At which point we might want an
equivalent drivers/media/i2c/gmsl/ perhaps?

--
Regards

Kieran


>> Laurent, can you please share your opinion?

-- 
Regards
--
Kieran

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12  9:20         ` Kieran Bingham
@ 2018-10-12 10:58           ` Vladimir Zapolskiy
  2018-10-12 11:34             ` Lee Jones
  2018-10-12 11:47             ` Kieran Bingham
  0 siblings, 2 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-12 10:58 UTC (permalink / raw)
  To: kieran.bingham, Lee Jones, Laurent Pinchart
  Cc: Vladimir Zapolskiy, Linus Walleij, Rob Herring, Marek Vasut,
	Wolfram Sang, devicetree, linux-gpio, linux-media, linux-kernel

Hi Kieran,

On 10/12/2018 12:20 PM, Kieran Bingham wrote:
> Hi Vladimir,
> 
> On 12/10/18 09:39, Lee Jones wrote:
>> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
>>> On 10/12/2018 09:03 AM, Lee Jones wrote:
>>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
>>>>
>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>
>>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
>>>>> support of subdevice controllers is done in separate drivers, because
>>>>> not all IC functionality may be needed in particular situations, and
>>>>> this can be fine grained controlled in device tree.
>>>>>
>>>>> The development of the driver was a collaborative work, the
>>>>> contribution done by Balasubramani Vivekanandan includes:
>>>>> * original implementation of the driver based on a reference driver,
>>>>> * regmap powered interrupt controller support on serializers,
>>>>> * support of implicitly or improperly specified in device tree ICs,
>>>>> * support of device properties and attributes: backward compatible
>>>>>   mode, low frequency operation mode, spread spectrum clock generator.
>>>>>
>>>>> Contribution by Steve Longerbeam:
>>>>> * added ds90ux9xx_read_indirect() function,
>>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
>>>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
>>>>> * added fpd_link_show device attribute.
>>>>>
>>>>> Sandeep Jain added support of pixel clock edge configuration.
>>>>>
>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>> ---
>>>>>  drivers/mfd/Kconfig           |  14 +
>>>>>  drivers/mfd/Makefile          |   1 +
>>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
>>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
>>>>>  4 files changed, 936 insertions(+)
>>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
>>>>>
>>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>>>> index 8c5dfdce4326..a969fa123f64 100644
>>>>> --- a/drivers/mfd/Kconfig
>>>>> +++ b/drivers/mfd/Kconfig
>>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
>>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>>>>>  
>>>>> +config MFD_DS90UX9XX
>>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
>>>>> +	depends on I2C && OF
>>>>> +	select MFD_CORE
>>>>> +	select REGMAP_I2C
>>>>> +	help
>>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
>>>>> +
>>>>> +	  This driver provides basic support for setting up the de-/serializer
>>>>> +	  chips. Additional functionalities like connection handling to
>>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
>>>>> +	  controller and so on are provided by separate drivers and should
>>>>> +	  enabled individually.
>>>>
>>>> This is not an MFD driver.
>>>
>>> Why do you think so? The representation of the ICs into device tree format
>>> of hardware description shows that this is a truly MFD driver with multiple
>>> IP subcomponents naturally mapped into MFD cells.
>>
>> This driver does too much real work ('stuff') to be an MFD driver.
>> MFD drivers should not need to care of; links, gates, modes, pixels,
>> frequencies maps or properties.  Nor should they contain elaborate
>> sysfs structures to control the aforementioned 'stuff'.
>>
>> Granted, there may be some code in there which could be appropriate
>> for an MFD driver.  However most of it needs moving out into a
>> function driver (or two).
>>
>>> Basically it is possible to replace explicit of_platform_populate() by
>>> adding a "simple-mfd" compatible, if it is desired.
>>>
>>>> After a 30 second Google of what this device actually does, perhaps
>>>> drivers/media might be a better fit?
>>>
>>> I assume it would be quite unusual to add a driver with NO media functions
>>> and controls into drivers/media.
>>
>> drivers/media may very well not be the correct place for this.  In my
>> 30 second Google, I saw that this device has a lot to do with cameras,
>> hence my media association.
>>
>> If *all* else fails, there is always drivers/misc, but this should be
>> avoided if at all possible.
> 
> The device as a whole is FPD Link for camera devices I believe, but it

I still don't understand (I could be biased though) why there is such
a strong emphasis on cameras and media stuff in the discussion.

No, "the device as a whole is FPD Link for camera devices" is a wrong
statement. On hand I have a number of boards with serializers/deserializers
from the TI DS90Ux9xx IC series and sensors are NOT connected to them.

> certainly has different functions which are broken out in this
> implementation.

No, there is absolutely nothing broken out from the presented MFD drivers,
the drivers are completely integral and basically I don't expect any.

If you are concerned about media functionality, the correspondent MFD
*cell* drivers will be added into drivers/media, drivers/gpu/drm or
whatever is to be a proper place.

> I think it might be quite awkward having the i2c components in
> drivers/i2c and the media components in drivers/media/i2c, so what about
> creating drivers/media/i2c/fpd-link (or such) as a container?

I open drivers/media/i2c/Kconfig and all entries with no exception are
under from 'if VIDEO_V4L2'. The MFD drivers do NOT require on depend on
VIDEO_V4L2 or any other multimedia frameworks, nor the MFD drivers export
any multimedia controls.

> Our GMSL implementation is also a complex camera(s) device - but does
> not yet use the MFD framework, perhaps that's something to add to my
> todo list.
> 

Okay, but the TI DS90Ux9xx is NOT a camera device, and it is NOT a multimedia
device, but it is a pure MFD device so the argument is not applicable.

> We currently keep all of the complexity within the max9286.c driver, but
> I could foresee that being split further if more devices add to the
> complexity of managing the bus. At which point we might want an
> equivalent drivers/media/i2c/gmsl/ perhaps?
> 

--
Best wishes,
Vladimir

>>> Laurent, can you please share your opinion?
> 

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12  8:39       ` Lee Jones
  2018-10-12  9:20         ` Kieran Bingham
@ 2018-10-12 11:24         ` Vladimir Zapolskiy
  2018-10-12 11:43           ` Lee Jones
  2018-10-12 13:07           ` Laurent Pinchart
  1 sibling, 2 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-12 11:24 UTC (permalink / raw)
  To: Lee Jones
  Cc: Laurent Pinchart, Vladimir Zapolskiy, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

On 10/12/2018 11:39 AM, Lee Jones wrote:
> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
>> On 10/12/2018 09:03 AM, Lee Jones wrote:
>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
>>>
>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>
>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
>>>> support of subdevice controllers is done in separate drivers, because
>>>> not all IC functionality may be needed in particular situations, and
>>>> this can be fine grained controlled in device tree.
>>>>
>>>> The development of the driver was a collaborative work, the
>>>> contribution done by Balasubramani Vivekanandan includes:
>>>> * original implementation of the driver based on a reference driver,
>>>> * regmap powered interrupt controller support on serializers,
>>>> * support of implicitly or improperly specified in device tree ICs,
>>>> * support of device properties and attributes: backward compatible
>>>>   mode, low frequency operation mode, spread spectrum clock generator.
>>>>
>>>> Contribution by Steve Longerbeam:
>>>> * added ds90ux9xx_read_indirect() function,
>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
>>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
>>>> * added fpd_link_show device attribute.
>>>>
>>>> Sandeep Jain added support of pixel clock edge configuration.
>>>>
>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>> ---
>>>>  drivers/mfd/Kconfig           |  14 +
>>>>  drivers/mfd/Makefile          |   1 +
>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
>>>>  4 files changed, 936 insertions(+)
>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
>>>>
>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>>> index 8c5dfdce4326..a969fa123f64 100644
>>>> --- a/drivers/mfd/Kconfig
>>>> +++ b/drivers/mfd/Kconfig
>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>>>>  
>>>> +config MFD_DS90UX9XX
>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
>>>> +	depends on I2C && OF
>>>> +	select MFD_CORE
>>>> +	select REGMAP_I2C
>>>> +	help
>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
>>>> +
>>>> +	  This driver provides basic support for setting up the de-/serializer
>>>> +	  chips. Additional functionalities like connection handling to
>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
>>>> +	  controller and so on are provided by separate drivers and should
>>>> +	  enabled individually.
>>>
>>> This is not an MFD driver.
>>
>> Why do you think so? The representation of the ICs into device tree format
>> of hardware description shows that this is a truly MFD driver with multiple
>> IP subcomponents naturally mapped into MFD cells.
> 
> This driver does too much real work ('stuff') to be an MFD driver.
> MFD drivers should not need to care of; links, gates, modes, pixels,
> frequencies maps or properties.  Nor should they contain elaborate
> sysfs structures to control the aforementioned 'stuff'.
> 

What is the reason why device drivers for sort of multimedia ICs like
WL1273, WM8994 and other numerous codecs are found in drivers/mfd?

If the same reason can not be applied to this DS90Ux9xx driver, why?

> Granted, there may be some code in there which could be appropriate
> for an MFD driver.  However most of it needs moving out into a
> function driver (or two).
> 
>> Basically it is possible to replace explicit of_platform_populate() by
>> adding a "simple-mfd" compatible, if it is desired.
>>
>>> After a 30 second Google of what this device actually does, perhaps
>>> drivers/media might be a better fit?
>>
>> I assume it would be quite unusual to add a driver with NO media functions
>> and controls into drivers/media.
> 
> drivers/media may very well not be the correct place for this.  In my
> 30 second Google, I saw that this device has a lot to do with cameras,
> hence my media association.

Well, the argument is similar to the statement that Google says that
camera sensors *can* be connected to NXP i.MX6 SoC, thus arch/arm/mach-imx
contents should be placed into drivers/media

A few TI DS90Ux9xx *cell* drivers may be added to drivers/media, but it is
out of the scope of the current series, which is completely integral per se,
and actually the cover letter says that the series of drivers immediately
allows to output video over DRM to panels, but the discussion is around
sensors by some reason. But I hope it won't be seen as a misleading
reason to consider to add the MFD driver into drivers/gpu/drm

> If *all* else fails, there is always drivers/misc, but this should be
> avoided if at all possible.

drivers/misc does not sound like a proper place for the MFD driver...

>> Laurent, can you please share your opinion?
> 

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 10:58           ` Vladimir Zapolskiy
@ 2018-10-12 11:34             ` Lee Jones
  2018-10-12 14:13               ` Vladimir Zapolskiy
  2018-10-12 11:47             ` Kieran Bingham
  1 sibling, 1 reply; 62+ messages in thread
From: Lee Jones @ 2018-10-12 11:34 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: kieran.bingham, Laurent Pinchart, Vladimir Zapolskiy,
	Linus Walleij, Rob Herring, Marek Vasut, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel

On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> On 10/12/2018 12:20 PM, Kieran Bingham wrote:
> > Hi Vladimir,
> > On 12/10/18 09:39, Lee Jones wrote:
> >> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> >>> On 10/12/2018 09:03 AM, Lee Jones wrote:
> >>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> >>>>
> >>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>>
> >>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
> >>>>> support of subdevice controllers is done in separate drivers, because
> >>>>> not all IC functionality may be needed in particular situations, and
> >>>>> this can be fine grained controlled in device tree.
> >>>>>
> >>>>> The development of the driver was a collaborative work, the
> >>>>> contribution done by Balasubramani Vivekanandan includes:
> >>>>> * original implementation of the driver based on a reference driver,
> >>>>> * regmap powered interrupt controller support on serializers,
> >>>>> * support of implicitly or improperly specified in device tree ICs,
> >>>>> * support of device properties and attributes: backward compatible
> >>>>>   mode, low frequency operation mode, spread spectrum clock generator.
> >>>>>
> >>>>> Contribution by Steve Longerbeam:
> >>>>> * added ds90ux9xx_read_indirect() function,
> >>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
> >>>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
> >>>>> * added fpd_link_show device attribute.
> >>>>>
> >>>>> Sandeep Jain added support of pixel clock edge configuration.
> >>>>>
> >>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>> ---
> >>>>>  drivers/mfd/Kconfig           |  14 +
> >>>>>  drivers/mfd/Makefile          |   1 +
> >>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
> >>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
> >>>>>  4 files changed, 936 insertions(+)
> >>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
> >>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
> >>>>>
> >>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> >>>>> index 8c5dfdce4326..a969fa123f64 100644
> >>>>> --- a/drivers/mfd/Kconfig
> >>>>> +++ b/drivers/mfd/Kconfig
> >>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
> >>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
> >>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
> >>>>>  
> >>>>> +config MFD_DS90UX9XX
> >>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
> >>>>> +	depends on I2C && OF
> >>>>> +	select MFD_CORE
> >>>>> +	select REGMAP_I2C
> >>>>> +	help
> >>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
> >>>>> +
> >>>>> +	  This driver provides basic support for setting up the de-/serializer
> >>>>> +	  chips. Additional functionalities like connection handling to
> >>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
> >>>>> +	  controller and so on are provided by separate drivers and should
> >>>>> +	  enabled individually.
> >>>>
> >>>> This is not an MFD driver.
> >>>
> >>> Why do you think so? The representation of the ICs into device tree format
> >>> of hardware description shows that this is a truly MFD driver with multiple
> >>> IP subcomponents naturally mapped into MFD cells.
> >>
> >> This driver does too much real work ('stuff') to be an MFD driver.
> >> MFD drivers should not need to care of; links, gates, modes, pixels,
> >> frequencies maps or properties.  Nor should they contain elaborate
> >> sysfs structures to control the aforementioned 'stuff'.
> >>
> >> Granted, there may be some code in there which could be appropriate
> >> for an MFD driver.  However most of it needs moving out into a
> >> function driver (or two).
> >>
> >>> Basically it is possible to replace explicit of_platform_populate() by
> >>> adding a "simple-mfd" compatible, if it is desired.
> >>>
> >>>> After a 30 second Google of what this device actually does, perhaps
> >>>> drivers/media might be a better fit?
> >>>
> >>> I assume it would be quite unusual to add a driver with NO media functions
> >>> and controls into drivers/media.
> >>
> >> drivers/media may very well not be the correct place for this.  In my
> >> 30 second Google, I saw that this device has a lot to do with cameras,
> >> hence my media association.
> >>
> >> If *all* else fails, there is always drivers/misc, but this should be
> >> avoided if at all possible.
> > 
> > The device as a whole is FPD Link for camera devices I believe, but it
> 
> I still don't understand (I could be biased though) why there is such
> a strong emphasis on cameras and media stuff in the discussion.
> 
> No, "the device as a whole is FPD Link for camera devices" is a wrong
> statement. On hand I have a number of boards with serializers/deserializers
> from the TI DS90Ux9xx IC series and sensors are NOT connected to them.
> 
> > certainly has different functions which are broken out in this
> > implementation.
> 
> No, there is absolutely nothing broken out from the presented MFD drivers,
> the drivers are completely integral and basically I don't expect any.
> 
> If you are concerned about media functionality, the correspondent MFD
> *cell* drivers will be added into drivers/media, drivers/gpu/drm or
> whatever is to be a proper place.
> 
> > I think it might be quite awkward having the i2c components in
> > drivers/i2c and the media components in drivers/media/i2c, so what about
> > creating drivers/media/i2c/fpd-link (or such) as a container?
> 
> I open drivers/media/i2c/Kconfig and all entries with no exception are
> under from 'if VIDEO_V4L2'. The MFD drivers do NOT require on depend on
> VIDEO_V4L2 or any other multimedia frameworks, nor the MFD drivers export
> any multimedia controls.
> 
> > Our GMSL implementation is also a complex camera(s) device - but does
> > not yet use the MFD framework, perhaps that's something to add to my
> > todo list.
> > 
> 
> Okay, but the TI DS90Ux9xx is NOT a camera device, and it is NOT a multimedia
> device, but it is a pure MFD device so the argument is not applicable.

You keep saying that "this is an MFD device" without any obvious
comprehension of what an MFD is.  Just saying that it is one
over-and-over does not make it so.

An MFD should be little more than parent to other functional devices.
Their role is to register children which in turn conduct operations
on the hardware in a useful way.  Some MFDs also house common functions
to save repetition of code in each of the child devices.  They do not
tend to offer any useful functionality (stuff) in their own right. 

As I already mentioned, you need to figure out what this device is
and move all of the functionality into the appropriate subsystem.
Since an MFD isn't a real thing/device (it's a Linuxy-shim which 
only serves to register sub-devices and (sometimes) provide a space
for common functionality to be located), drivers/mfd is not the
subsystem which you seek. 

> > We currently keep all of the complexity within the max9286.c driver, but
> > I could foresee that being split further if more devices add to the
> > complexity of managing the bus. At which point we might want an
> > equivalent drivers/media/i2c/gmsl/ perhaps?

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs
  2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
                   ` (6 preceding siblings ...)
  2018-10-08 21:12 ` [PATCH 7/7] MAINTAINERS: add entry for TI DS90Ux9xx FPD-Link III drivers Vladimir Zapolskiy
@ 2018-10-12 11:34 ` Laurent Pinchart
  7 siblings, 0 replies; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-12 11:34 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Linus Walleij, Rob Herring, Marek Vasut, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel

Hi Vladimir,

Thank you for the patches.

On Tuesday, 9 October 2018 00:11:58 EEST Vladimir Zapolskiy wrote:
> The published drivers describe the essential and generic parts of
> TI DS90Ux9xx series of ICs, which allow to transfer video, audio and
> control signals between FPD-Link III serializers and deserializers.
> 
> The placement of TI DS90Ux9xx I2C client driver was selected to be
> drivers/mfd as the most natural location of a true MFD driver,

Why does this have to be an MFD driver ? It's not uncommon for random devices 
to expose a few GPIOs or clocks to the outside world, to support their main 
feature (video transmission in this case). HDMI cables transport I2C on the 
DDC pins, and HDMI encoders usually have an I2C master controller to read 
EDID, and a GPIO pin to connect to the HPD signal. We don't model them as MFD 
drivers. You can register an I2C adapter and a GPIO controller from within any 
driver without a need to involve the MFD framework. I think it's completely 
overkill in this case.

> apparently drivers/media/i2c is for another type of device drivers,
> also DS90Ux9xx I2C bridge subcontroller driver is placed nearby,
> because drivers/i2c for it would be an inappropriate destination
> as well. Informally the TI DS90Ux9xx ICs serve a similar function
> to SMSC/Microchip MOST, and its drivers are in drivers/staging/most,
> the final destination is unknown to me. Please feel free to advise
> a better location for the published drivers, at the moment the core
> drivers are in drivers/mfd, but I select linux-media as a mailing list.
> 
> The published drivers instantly give a chance to test video bridge
> functionality to a TI DS90Ux9xx deserializer equipped display panel
> with the aide of Laurent's "lvds-encoder" driver by misusing it
> as a generic and transparent drm bridge with no particular LVDS
> specifics in it, for that it should be sufficient just to add the
> corresponding device node and input/output ports as children of
> a serializer connected to an application controller.
> 
> While the selected scheme of IC description by a list of subdevices,
> where each one described in its own device node, works pretty well,
> it might lead to unnecessary overcomplicated description of connections
> between subdevices on serializer and deserializer sides, i.e. for
> proper description of links/connections video serializer should
> be linked to video deserializer, audio serializer should be linked
> to audio deserializer and so on, however formally there is just one
> FPD-III Link connection between two ICs.

Could you please provide a complete DT example ? The series is titled "initial 
support", but it's hard to ascertain that it's taking the right direction 
without seeing where you want to go. In particular, I want to see how devices 
on both sides of the serializer and deserializer will be modeled.

> The series of patches is rebased on top of linux-next, and there are
> more changes in the queue to provide better support of TI DS90Ux9xx ICs.
> 
> The introduction to the ICs and drivers can be found in my presentation
> https://schd.ws/hosted_files/ossalsjp18/8a/vzapolskiy_als2018.pdf
> 
> Sandeep Jain (1):
>   dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
> 
> Vladimir Zapolskiy (6):
>   dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge
>   dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
>   mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
>   mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
>   pinctrl: ds90ux9xx: add TI DS90Ux9xx pinmux and GPIO controller driver
>   MAINTAINERS: add entry for TI DS90Ux9xx FPD-Link III drivers
> 
>  .../bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt  |  61 ++
>  .../devicetree/bindings/mfd/ti,ds90ux9xx.txt  |  66 ++
>  .../bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt |  83 ++
>  MAINTAINERS                                   |  10 +
>  drivers/mfd/Kconfig                           |  22 +
>  drivers/mfd/Makefile                          |   2 +
>  drivers/mfd/ds90ux9xx-core.c                  | 879 ++++++++++++++++
>  drivers/mfd/ds90ux9xx-i2c-bridge.c            | 764 ++++++++++++++
>  drivers/pinctrl/Kconfig                       |  11 +
>  drivers/pinctrl/Makefile                      |   1 +
>  drivers/pinctrl/pinctrl-ds90ux9xx.c           | 970 ++++++++++++++++++
>  include/linux/mfd/ds90ux9xx.h                 |  42 +
>  12 files changed, 2911 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt create
> mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt create
> mode 100644
> Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt create
> mode 100644 drivers/mfd/ds90ux9xx-core.c
>  create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c
>  create mode 100644 drivers/pinctrl/pinctrl-ds90ux9xx.c
>  create mode 100644 include/linux/mfd/ds90ux9xx.h

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 11:24         ` Vladimir Zapolskiy
@ 2018-10-12 11:43           ` Lee Jones
  2018-10-12 14:23             ` Vladimir Zapolskiy
  2018-10-12 13:07           ` Laurent Pinchart
  1 sibling, 1 reply; 62+ messages in thread
From: Lee Jones @ 2018-10-12 11:43 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Laurent Pinchart, Vladimir Zapolskiy, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:

> On 10/12/2018 11:39 AM, Lee Jones wrote:
> > On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> >> On 10/12/2018 09:03 AM, Lee Jones wrote:
> >>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> >>>
> >>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>
> >>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
> >>>> support of subdevice controllers is done in separate drivers, because
> >>>> not all IC functionality may be needed in particular situations, and
> >>>> this can be fine grained controlled in device tree.
> >>>>
> >>>> The development of the driver was a collaborative work, the
> >>>> contribution done by Balasubramani Vivekanandan includes:
> >>>> * original implementation of the driver based on a reference driver,
> >>>> * regmap powered interrupt controller support on serializers,
> >>>> * support of implicitly or improperly specified in device tree ICs,
> >>>> * support of device properties and attributes: backward compatible
> >>>>   mode, low frequency operation mode, spread spectrum clock generator.
> >>>>
> >>>> Contribution by Steve Longerbeam:
> >>>> * added ds90ux9xx_read_indirect() function,
> >>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
> >>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
> >>>> * added fpd_link_show device attribute.
> >>>>
> >>>> Sandeep Jain added support of pixel clock edge configuration.
> >>>>
> >>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>> ---
> >>>>  drivers/mfd/Kconfig           |  14 +
> >>>>  drivers/mfd/Makefile          |   1 +
> >>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
> >>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
> >>>>  4 files changed, 936 insertions(+)
> >>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
> >>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
> >>>>
> >>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> >>>> index 8c5dfdce4326..a969fa123f64 100644
> >>>> --- a/drivers/mfd/Kconfig
> >>>> +++ b/drivers/mfd/Kconfig
> >>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
> >>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
> >>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
> >>>>  
> >>>> +config MFD_DS90UX9XX
> >>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
> >>>> +	depends on I2C && OF
> >>>> +	select MFD_CORE
> >>>> +	select REGMAP_I2C
> >>>> +	help
> >>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
> >>>> +
> >>>> +	  This driver provides basic support for setting up the de-/serializer
> >>>> +	  chips. Additional functionalities like connection handling to
> >>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
> >>>> +	  controller and so on are provided by separate drivers and should
> >>>> +	  enabled individually.
> >>>
> >>> This is not an MFD driver.
> >>
> >> Why do you think so? The representation of the ICs into device tree format
> >> of hardware description shows that this is a truly MFD driver with multiple
> >> IP subcomponents naturally mapped into MFD cells.
> > 
> > This driver does too much real work ('stuff') to be an MFD driver.
> > MFD drivers should not need to care of; links, gates, modes, pixels,
> > frequencies maps or properties.  Nor should they contain elaborate
> > sysfs structures to control the aforementioned 'stuff'.
> > 
> 
> What is the reason why device drivers for sort of multimedia ICs like
> WL1273, WM8994 and other numerous codecs are found in drivers/mfd?
> 
> If the same reason can not be applied to this DS90Ux9xx driver, why?
> 
> > Granted, there may be some code in there which could be appropriate
> > for an MFD driver.  However most of it needs moving out into a
> > function driver (or two).
> > 
> >> Basically it is possible to replace explicit of_platform_populate() by
> >> adding a "simple-mfd" compatible, if it is desired.
> >>
> >>> After a 30 second Google of what this device actually does, perhaps
> >>> drivers/media might be a better fit?
> >>
> >> I assume it would be quite unusual to add a driver with NO media functions
> >> and controls into drivers/media.
> > 
> > drivers/media may very well not be the correct place for this.  In my
> > 30 second Google, I saw that this device has a lot to do with cameras,
> > hence my media association.
> 
> Well, the argument is similar to the statement that Google says that
> camera sensors *can* be connected to NXP i.MX6 SoC, thus arch/arm/mach-imx
> contents should be placed into drivers/media
> 
> A few TI DS90Ux9xx *cell* drivers may be added to drivers/media, but it is
> out of the scope of the current series, which is completely integral per se,
> and actually the cover letter says that the series of drivers immediately
> allows to output video over DRM to panels, but the discussion is around
> sensors by some reason. But I hope it won't be seen as a misleading
> reason to consider to add the MFD driver into drivers/gpu/drm

This discussion isn't about not adding enough child devices.  It's
about there being too much functional work being done in an MFD
driver, where it doesn't belong.

> > If *all* else fails, there is always drivers/misc, but this should be
> > avoided if at all possible.
> 
> drivers/misc does not sound like a proper place for the MFD driver...

I'd agree with you if this were an MFD driver.

As I mentioned before, there may well be an argument for and MFD
driver to be part of this driver-set.  However it needs to be
significantly reduced with any functional code removed and placed
where it belongs.

> >> Laurent, can you please share your opinion?

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-08 21:11 ` [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description " Vladimir Zapolskiy
  2018-10-09  0:13   ` Marek Vasut
  2018-10-10  8:41   ` Linus Walleij
@ 2018-10-12 11:44   ` Laurent Pinchart
  2018-10-13 14:28     ` Vladimir Zapolskiy
  2018-10-30 16:43   ` Luca Ceresoli
  3 siblings, 1 reply; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-12 11:44 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Linus Walleij, Rob Herring, Marek Vasut, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel, Sandeep Jain,
	Vladimir Zapolskiy

Hi Vladimir,

Thank you for the patch.

On Tuesday, 9 October 2018 00:11:59 EEST Vladimir Zapolskiy wrote:
> From: Sandeep Jain <Sandeep_Jain@mentor.com>
> 
> The change adds device tree binding description of TI DS90Ux9xx
> series of serializer and deserializer controllers which support video,
> audio and control data transmission over FPD-III Link connection.
> 
> Signed-off-by: Sandeep Jain <Sandeep_Jain@mentor.com>
> [vzapolskiy: various updates and corrections of secondary importance]
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> ---
>  .../devicetree/bindings/mfd/ti,ds90ux9xx.txt  | 66 +++++++++++++++++++
>  1 file changed, 66 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt new file mode
> 100644
> index 000000000000..0733da88f7ef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> @@ -0,0 +1,66 @@
> +Texas Instruments DS90Ux9xx de-/serializer controllers
> +
> +Required properties:
> +- compatible: Must contain a generic "ti,ds90ux9xx" value and
> +	may contain one more specific value from the list:

If it "may" contain one more specific value, when should that value be 
present, and when can it be absent ?

> +	"ti,ds90ub925q",
> +	"ti,ds90uh925q",
> +	"ti,ds90ub927q",
> +	"ti,ds90uh927q",
> +	"ti,ds90ub926q",
> +	"ti,ds90uh926q",
> +	"ti,ds90ub928q",
> +	"ti,ds90uh928q",
> +	"ti,ds90ub940q",
> +	"ti,ds90uh940q".
> +
> +Optional properties:
> +- reg : Specifies the I2C slave address of a local de-/serializer.

You should explain when the reg property is required and when it isn't. This 
will in my opinion require a more detailed explanation of the DT model for 
this device.

> +- power-gpios : GPIO line to control supplied power to the device.

As Marek mentioned, a regulator would be better. I would make it a mandatory 
property, as the device always needs to be powered.

> +- ti,backward-compatible-mode : Overrides backward compatibility mode.
> +	Possible values are "<1>" or "<0>".
> +	If "ti,backward-compatible-mode" is not mentioned, the backward
> +	compatibility mode is not touched and given by hardware pin strapping.

This doesn't seem to be a device description to me, it's a software 
configuration. You should handle it in drivers.

> +- ti,low-frequency-mode : Overrides low frequency mode.
> +	Possible values are "<1>" or "<0>".
> +	If "ti,low-frequency-mode" is not mentioned, the low frequency mode
> +	is not touched and given by hardware pin strapping.

This sounds the same. How about giving a real life example of a case where you 
need to set these two properties to override the pin strapping, for the 
purpose of discussing the DT bindings ?

> +- ti,video-map-select-msb: Sets video bridge pins to MSB mode, if it is set
> +	MAPSEL pin value is ignored.
> +- ti,video-map-select-lsb: Sets video bridge pins to LSB mode, if it is set
> +	MAPSEL pin value is ignored.

I assume those two are mutually exclusive, this should be documented, or you 
could merge the two properties into one. Same comment as above though, why do 
you need an override in DT ?

> +- ti,pixel-clock-edge : Selects Pixel Clock Edge.
> +	Possible values are "<1>" or "<0>".
> +	If "ti,pixel-clock-edge" is High <1>, output data is strobed on the
> +	Rising edge of the PCLK. If ti,pixel-clock-edge is Low <0>, data is
> +	strobed on the Falling edge of the PCLK.
> +	If "ti,pixel-clock-edge" is not mentioned, the pixel clock edge
> +	value is not touched and given by hardware pin strapping.

We have a standard property in Documentation/devicetree/bindings/media/video-
interfaces.txt for this, please use it.

> +- ti,spread-spectrum-clock-generation : Spread Sprectrum Clock Generation.
> +	Possible values are from "<0>" to "<7>". The same value will be
> +	written to SSC register. If "ti,spread-spectrum-clock-gen" is not
> +	found, then SSCG will be disabled.

This makes sense in DT in my opinion, as EMC is a system property. I wonder 
however if exposing the hardware register directly is the best option. Could 
you elaborate on how a system designer will select which value to use, in 
order to find the best DT description ?

> +TI DS90Ux9xx serializers and deserializer device nodes may contain a number
> +of children device nodes to describe and enable particular subcomponents
> +found on ICs.

As mentioned in my review of the cover letter I don't think this is necessary. 
You can make the serializer and deserializer I2C controllers without subnodes. 
Same goes for GPIO control.

> +Example:
> +
> +serializer: serializer@c {
> +	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
> +	reg = <0xc>;
> +	power-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
> +	ti,backward-compatible-mode = <0>;
> +	ti,low-frequency-mode = <0>;
> +	ti,pixel-clock-edge = <0>;
> +	...
> +}
> +
> +deserializer: deserializer@3c {
> +	compatible = "ti,ds90ub940q", "ti,ds90ux9xx";
> +	reg = <0x3c>;
> +	power-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
> +	...
> +}
> +

Extra blank line ?

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 10:58           ` Vladimir Zapolskiy
  2018-10-12 11:34             ` Lee Jones
@ 2018-10-12 11:47             ` Kieran Bingham
  2018-10-12 13:01               ` Laurent Pinchart
  2018-10-13 12:33               ` Vladimir Zapolskiy
  1 sibling, 2 replies; 62+ messages in thread
From: Kieran Bingham @ 2018-10-12 11:47 UTC (permalink / raw)
  To: Vladimir Zapolskiy, Lee Jones, Laurent Pinchart
  Cc: Vladimir Zapolskiy, Linus Walleij, Rob Herring, Marek Vasut,
	Wolfram Sang, devicetree, linux-gpio, linux-media, linux-kernel

Hi Vladimir,

On 12/10/18 11:58, Vladimir Zapolskiy wrote:
> Hi Kieran,
> 
> On 10/12/2018 12:20 PM, Kieran Bingham wrote:
>> Hi Vladimir,
>>
>> On 12/10/18 09:39, Lee Jones wrote:
>>> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
>>>> On 10/12/2018 09:03 AM, Lee Jones wrote:
>>>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
>>>>>
>>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>>
>>>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
>>>>>> support of subdevice controllers is done in separate drivers, because
>>>>>> not all IC functionality may be needed in particular situations, and
>>>>>> this can be fine grained controlled in device tree.
>>>>>>
>>>>>> The development of the driver was a collaborative work, the
>>>>>> contribution done by Balasubramani Vivekanandan includes:
>>>>>> * original implementation of the driver based on a reference driver,
>>>>>> * regmap powered interrupt controller support on serializers,
>>>>>> * support of implicitly or improperly specified in device tree ICs,
>>>>>> * support of device properties and attributes: backward compatible
>>>>>>   mode, low frequency operation mode, spread spectrum clock generator.
>>>>>>
>>>>>> Contribution by Steve Longerbeam:
>>>>>> * added ds90ux9xx_read_indirect() function,
>>>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
>>>>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
>>>>>> * added fpd_link_show device attribute.
>>>>>>
>>>>>> Sandeep Jain added support of pixel clock edge configuration.
>>>>>>
>>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>> ---
>>>>>>  drivers/mfd/Kconfig           |  14 +
>>>>>>  drivers/mfd/Makefile          |   1 +
>>>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
>>>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
>>>>>>  4 files changed, 936 insertions(+)
>>>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>>>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
>>>>>>
>>>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>>>>> index 8c5dfdce4326..a969fa123f64 100644
>>>>>> --- a/drivers/mfd/Kconfig
>>>>>> +++ b/drivers/mfd/Kconfig
>>>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>>>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
>>>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>>>>>>  
>>>>>> +config MFD_DS90UX9XX
>>>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
>>>>>> +	depends on I2C && OF
>>>>>> +	select MFD_CORE
>>>>>> +	select REGMAP_I2C
>>>>>> +	help
>>>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
>>>>>> +
>>>>>> +	  This driver provides basic support for setting up the de-/serializer
>>>>>> +	  chips. Additional functionalities like connection handling to
>>>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
>>>>>> +	  controller and so on are provided by separate drivers and should
>>>>>> +	  enabled individually.
>>>>>
>>>>> This is not an MFD driver.
>>>>
>>>> Why do you think so? The representation of the ICs into device tree format
>>>> of hardware description shows that this is a truly MFD driver with multiple
>>>> IP subcomponents naturally mapped into MFD cells.
>>>
>>> This driver does too much real work ('stuff') to be an MFD driver.
>>> MFD drivers should not need to care of; links, gates, modes, pixels,
>>> frequencies maps or properties.  Nor should they contain elaborate
>>> sysfs structures to control the aforementioned 'stuff'.
>>>
>>> Granted, there may be some code in there which could be appropriate
>>> for an MFD driver.  However most of it needs moving out into a
>>> function driver (or two).
>>>
>>>> Basically it is possible to replace explicit of_platform_populate() by
>>>> adding a "simple-mfd" compatible, if it is desired.
>>>>
>>>>> After a 30 second Google of what this device actually does, perhaps
>>>>> drivers/media might be a better fit?
>>>>
>>>> I assume it would be quite unusual to add a driver with NO media functions
>>>> and controls into drivers/media.
>>>
>>> drivers/media may very well not be the correct place for this.  In my
>>> 30 second Google, I saw that this device has a lot to do with cameras,
>>> hence my media association.
>>>
>>> If *all* else fails, there is always drivers/misc, but this should be
>>> avoided if at all possible.
>>
>> The device as a whole is FPD Link for camera devices I believe, but it
> 
> I still don't understand (I could be biased though) why there is such
> a strong emphasis on cameras and media stuff in the discussion.
> 
> No, "the device as a whole is FPD Link for camera devices" is a wrong
> statement. On hand I have a number of boards with serializers/deserializers
> from the TI DS90Ux9xx IC series and sensors are NOT connected to them.


Yes - My apologies, this is a good point.

Especially as the clue is in the name "Flat Panel Display".
I have been stuck with my GMSL hat on for too long.

Even GMSL is in the same boat. It's just that 'we' are using GMSL for
cameras, but it can be used equally for displays and data.

These devices are serialiser-deserialiser pairs with power and control
paths.

Essentially they are multi purpose buses - which do not yet have a home.
We have used media as a home because of our use case.

The use case whether they transfer frames from a camera or to a display
are of course closely related, but ultimately covered by two separate
subsystems at the pixel level (DRM vs V4L, or other for other data)

Perhaps as they are buses - on a level with USB or I2C (except they can
of course carry I2C or Serial as well as 'bi-directional video' etc ),
they are looking for their own subsystem.

Except I don't think we don't want to add a new subsystem for just one
(or two) devices...

--
Kieran




>> certainly has different functions which are broken out in this
>> implementation.
> 
> No, there is absolutely nothing broken out from the presented MFD drivers,
> the drivers are completely integral and basically I don't expect any.
> 
> If you are concerned about media functionality, the correspondent MFD
> *cell* drivers will be added into drivers/media, drivers/gpu/drm or
> whatever is to be a proper place.
> 
>> I think it might be quite awkward having the i2c components in
>> drivers/i2c and the media components in drivers/media/i2c, so what about
>> creating drivers/media/i2c/fpd-link (or such) as a container?
> 
> I open drivers/media/i2c/Kconfig and all entries with no exception are
> under from 'if VIDEO_V4L2'. The MFD drivers do NOT require on depend on
> VIDEO_V4L2 or any other multimedia frameworks, nor the MFD drivers export
> any multimedia controls.
> 
>> Our GMSL implementation is also a complex camera(s) device - but does
>> not yet use the MFD framework, perhaps that's something to add to my
>> todo list.
>>
> 
> Okay, but the TI DS90Ux9xx is NOT a camera device, and it is NOT a multimedia
> device, but it is a pure MFD device so the argument is not applicable.
> 
>> We currently keep all of the complexity within the max9286.c driver, but
>> I could foresee that being split further if more devices add to the
>> complexity of managing the bus. At which point we might want an
>> equivalent drivers/media/i2c/gmsl/ perhaps?
>>
> 
> --
> Best wishes,
> Vladimir
> 
>>>> Laurent, can you please share your opinion?
>>

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge
  2018-10-08 21:12 ` [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge Vladimir Zapolskiy
@ 2018-10-12 11:54   ` Laurent Pinchart
  2018-10-30 16:43   ` Luca Ceresoli
  1 sibling, 0 replies; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-12 11:54 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Linus Walleij, Rob Herring, Marek Vasut, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel,
	Vladimir Zapolskiy

Hi Vladimir,

Thank you for the patch.

On Tuesday, 9 October 2018 00:12:00 EEST Vladimir Zapolskiy wrote:
> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> 
> TI DS90Ux9xx de-/serializers are capable to route I2C messages to
> I2C slave devices connected to a remote de-/serializer in a pair,
> the change adds description of device tree bindings of the subcontroller
> to configure and enable this functionality.
> 
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> ---
>  .../bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt  | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
> 
> diff --git
> a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
> b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt new
> file mode 100644
> index 000000000000..4169e382073a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
> @@ -0,0 +1,61 @@
> +TI DS90Ux9xx de-/serializer I2C bridge subcontroller
> +
> +Required properties:
> +- compatible: Must contain a generic "ti,ds90ux9xx-i2c-bridge" value and
> +	may contain one more specific value from the list:
> +	"ti,ds90ux925-i2c-bridge",
> +	"ti,ds90ux926-i2c-bridge",
> +	"ti,ds90ux927-i2c-bridge",
> +	"ti,ds90ux928-i2c-bridge",
> +	"ti,ds90ux940-i2c-bridge".

I still don't think the I2C bridge should be modeled with a separate 
compatible string, as explained in my comments to the cover letter and patch 
1/7.

> +Required properties of a de-/serializer device connected to a local I2C
> bus:
> +- ti,i2c-bridges: List of phandles to remote de-/serializer devices with
> +	two arguments: id of a local de-/serializer FPD link and an assigned
> +	I2C address of a remote de-/serializer to be accessed on a local
> +	I2C bus.

Please don't. Just make the deserializer a child of the serializer. This is 
how DT works, devices are organized in a tree based on the main control bus. 
When the deserializer is controlled from the serializer through the FPD link, 
it should be a child of the serializer.

> +Optional properties of a de-/serializer device connected to a local I2C
> bus:
> +- ti,i2c-bridge-maps: List of 3-cell values:
> +	- the first argument is id of a local de-/serializer FPD link,
> +	- the second argument is an I2C address of a device connected to
> +	  a remote de-/serializer IC,
> +	- the third argument is an I2C address of the remote I2C device
> +	  for access on a local I2C bus.
> +- ti,i2c-bridge-auto-ack: Enables AUTO ACK mode.

From my experience with GMSL this isn't something you can just enable or 
disable unconditionally, it needs to be handled at runtime, and doesn't belong 
to DT anyway.

> +- ti,i2c-bridge-pass-all: Enables PASS ALL mode, remote I2C slave devices
> +	are accessible on a local (host) I2C bus without I2C address
> +	remappings.

This property also doesn't seem like a hardware description. Please try to 
focus on what DT describes, not what the effect of the properties are. 
Bindings need to describe the model of the device, and that description then 
leads to effects. It shouldn't be the other way around.

> +Remote de-/serializer device may contain a list of device nodes, each
> +one represents an I2C device connected to that remote de-/serializer IC.
> +
> +Example (remote device is a deserializer with Atmel MXT touchscreen):
> +
> +serializer: serializer@c {
> +	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
> +	reg = <0xc>;
> +
> +	i2c-bridge {
> +		compatible = "ti,ds90ux927-i2c-bridge",
> +			     "ti,ds90ux9xx-i2c-bridge";
> +		ti,i2c-bridges = <&deserializer 0 0x3b>;
> +		ti,i2c-bridge-maps = <0 0x4b 0x64>;
> +	};
> +};
> +
> +deserializer: deserializer {
> +	compatible = "ti,ds90ub928q", "ti,ds90ux9xx";
> +
> +	i2c-bridge {
> +		compatible = "ti,ds90ux928-i2c-bridge",
> +			     "ti,ds90ux9xx-i2c-bridge";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		touchscreen@4b {
> +			compatible = "atmel,maxtouch";
> +			reg = <0x4b>;
> +		};
> +	};
> +};

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  2018-10-08 21:12 ` [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux Vladimir Zapolskiy
  2018-10-10  8:45   ` Linus Walleij
@ 2018-10-12 12:01   ` Laurent Pinchart
  2018-10-13 13:47     ` Vladimir Zapolskiy
  1 sibling, 1 reply; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-12 12:01 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Linus Walleij, Rob Herring, Marek Vasut, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel,
	Vladimir Zapolskiy

Hi Vladimir,

Thank you for the patch.

On Tuesday, 9 October 2018 00:12:01 EEST Vladimir Zapolskiy wrote:
> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> 
> TI DS90Ux9xx de-/serializers have a capability to multiplex pin functions,
> in particular a pin may have selectable functions of GPIO, GPIO line
> transmitter, one of I2S lines, one of RGB24 video signal lines and so on.
> 
> The change adds a description of DS90Ux9xx pin multiplexers and GPIO
> controllers.
> 
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> ---
>  .../bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt | 83 +++++++++++++++++++
>  1 file changed, 83 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
> 
> diff --git
> a/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
> b/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt new
> file mode 100644
> index 000000000000..fbfa1a3cdf9f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
> @@ -0,0 +1,83 @@
> +TI DS90Ux9xx de-/serializer pinmux and GPIO subcontroller
> +
> +Required properties:
> +- compatible: Must contain a generic "ti,ds90ux9xx-pinctrl" value and
> +	may contain one more specific value from the list:
> +	"ti,ds90ux925-pinctrl",
> +	"ti,ds90ux926-pinctrl",
> +	"ti,ds90ux927-pinctrl",
> +	"ti,ds90ux928-pinctrl",
> +	"ti,ds90ux940-pinctrl".

No need for a subnode, you can mark the main DT node with gpio-controller 
directly.

> +- gpio-controller: Marks the device node as a GPIO controller.
> +
> +- #gpio-cells: Must be set to 2,
> +	- the first cell is the GPIO offset number within the controller,
> +	- the second cell is used to specify the GPIO line polarity.
> +
> +- gpio-ranges: Mapping to pin controller pins (as described in
> +	Documentation/devicetree/bindings/gpio/gpio.txt)
> +
> +Optional properties:
> +- ti,video-depth-18bit: Sets video bridge pins to RGB 18-bit mode.

Please use standard properties to configure bus width. There is one defined in 
Documentation/devicetree/bindings/media/video-interfaces.txt.

> +Available pins, groups and functions (reference to device datasheets):
> +
> +function: "gpio" ("gpio4" is on DS90Ux925 and DS90Ux926 only,
> +		  "gpio9" is on DS90Ux940 only)
> + - pins: "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6",
> +	 "gpio7", "gpio8", "gpio9"
> +
> +function: "gpio-remote"
> + - pins: "gpio0", "gpio1", "gpio2", "gpio3"
> +
> +function: "pass" (DS90Ux940 specific only)
> + - pins: "gpio0", "gpio3"

What do those functions mean ?

> +function: "i2s-1"
> + - group: "i2s-1"
> +
> +function: "i2s-2"
> + - group: "i2s-2"
> +
> +function: "i2s-3" (DS90Ux927, DS90Ux928 and DS90Ux940 specific only)
> + - group: "i2s-3"
> +
> +function: "i2s-4" (DS90Ux927, DS90Ux928 and DS90Ux940 specific only)
> + - group: "i2s-4"
> +
> +function: "i2s-m" (DS90Ux928 and DS90Ux940 specific only)
> + - group: "i2s-m"

Do we really need all this ? I think a better model would be to describe the 
audio interfaces explicitly, and configure pinmuxing automatically based on 
which audio interfaces are in use.

> +function: "parallel" (DS90Ux925 and DS90Ux926 specific only)
> + - group: "parallel"
> +
> +Example (deserializer with pins GPIO[3:0] set to bridged output
> +	 function and pin GPIO4 in standard hogged GPIO function):
> +
> +deserializer {
> +	compatible = "ti,ds90ub928q", "ti,ds90ux9xx";
> +
> +	ds90ux928_pctrl: pin-controller {
> +		compatible = "ti,ds90ux928-pinctrl", "ti,ds90ux9xx-pinctrl";
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		gpio-ranges = <&ds90ux928_pctrl 0 0 8>;
> +
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&ds90ux928_pins>;
> +
> +		ds90ux928_pins: pinmux {
> +			gpio-remote {
> +				pins = "gpio0", "gpio1", "gpio2", "gpio3";
> +				function = "gpio-remote";
> +			};
> +		};
> +
> +		rst {
> +			gpio-hog;
> +			gpios = <4 GPIO_ACTIVE_HIGH>;
> +			output-high;
> +		};
> +	};
> +};

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 11:47             ` Kieran Bingham
@ 2018-10-12 13:01               ` Laurent Pinchart
  2018-10-12 13:59                 ` Vladimir Zapolskiy
  2018-10-13 15:10                 ` Vladimir Zapolskiy
  2018-10-13 12:33               ` Vladimir Zapolskiy
  1 sibling, 2 replies; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-12 13:01 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: kieran.bingham, Lee Jones, Vladimir Zapolskiy, Linus Walleij,
	Rob Herring, Marek Vasut, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

Hello Vladimir,

On Friday, 12 October 2018 14:47:52 EEST Kieran Bingham wrote:
> On 12/10/18 11:58, Vladimir Zapolskiy wrote:
> > On 10/12/2018 12:20 PM, Kieran Bingham wrote:
> >> On 12/10/18 09:39, Lee Jones wrote:
> >>> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> >>>> On 10/12/2018 09:03 AM, Lee Jones wrote:
> >>>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> >>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>>> 
> >>>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
> >>>>>> support of subdevice controllers is done in separate drivers, because
> >>>>>> not all IC functionality may be needed in particular situations, and
> >>>>>> this can be fine grained controlled in device tree.
> >>>>>> 
> >>>>>> The development of the driver was a collaborative work, the
> >>>>>> contribution done by Balasubramani Vivekanandan includes:
> >>>>>> * original implementation of the driver based on a reference driver,
> >>>>>> * regmap powered interrupt controller support on serializers,
> >>>>>> * support of implicitly or improperly specified in device tree ICs,
> >>>>>> * support of device properties and attributes: backward compatible
> >>>>>> 
> >>>>>>   mode, low frequency operation mode, spread spectrum clock
> >>>>>>   generator.
> >>>>>> 
> >>>>>> Contribution by Steve Longerbeam:
> >>>>>> * added ds90ux9xx_read_indirect() function,
> >>>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
> >>>>>> * moved and updated ds90ux9xx_get_link_status() function to core
> >>>>>> driver,
> >>>>>> * added fpd_link_show device attribute.
> >>>>>> 
> >>>>>> Sandeep Jain added support of pixel clock edge configuration.
> >>>>>> 
> >>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>>> ---
> >>>>>> 
> >>>>>>  drivers/mfd/Kconfig           |  14 +
> >>>>>>  drivers/mfd/Makefile          |   1 +
> >>>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++
> >>>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
> >>>>>>  4 files changed, 936 insertions(+)
> >>>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
> >>>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
> >>>>>> 
> >>>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> >>>>>> index 8c5dfdce4326..a969fa123f64 100644
> >>>>>> --- a/drivers/mfd/Kconfig
> >>>>>> +++ b/drivers/mfd/Kconfig
> >>>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
> >>>>>> 
> >>>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
> >>>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
> >>>>>> 
> >>>>>> +config MFD_DS90UX9XX
> >>>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
> >>>>>> +	depends on I2C && OF
> >>>>>> +	select MFD_CORE
> >>>>>> +	select REGMAP_I2C
> >>>>>> +	help
> >>>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer
> >>>>>> ICs.
> >>>>>> +
> >>>>>> +	  This driver provides basic support for setting up the
> >>>>>> de-/serializer
> >>>>>> +	  chips. Additional functionalities like connection handling to
> >>>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
> >>>>>> +	  controller and so on are provided by separate drivers and should
> >>>>>> +	  enabled individually.
> >>>>> 
> >>>>> This is not an MFD driver.
> >>>> 
> >>>> Why do you think so? The representation of the ICs into device tree
> >>>> format of hardware description shows that this is a truly MFD driver
> >>>> with multiple IP subcomponents naturally mapped into MFD cells.
> >>> 
> >>> This driver does too much real work ('stuff') to be an MFD driver.
> >>> MFD drivers should not need to care of; links, gates, modes, pixels,
> >>> frequencies maps or properties.  Nor should they contain elaborate
> >>> sysfs structures to control the aforementioned 'stuff'.
> >>> 
> >>> Granted, there may be some code in there which could be appropriate
> >>> for an MFD driver.  However most of it needs moving out into a
> >>> function driver (or two).
> >>> 
> >>>> Basically it is possible to replace explicit of_platform_populate() by
> >>>> adding a "simple-mfd" compatible, if it is desired.
> >>>> 
> >>>>> After a 30 second Google of what this device actually does, perhaps
> >>>>> drivers/media might be a better fit?
> >>>> 
> >>>> I assume it would be quite unusual to add a driver with NO media
> >>>> functions and controls into drivers/media.
> >>> 
> >>> drivers/media may very well not be the correct place for this.  In my
> >>> 30 second Google, I saw that this device has a lot to do with cameras,
> >>> hence my media association.
> >>> 
> >>> If *all* else fails, there is always drivers/misc, but this should be
> >>> avoided if at all possible.
> >> 
> >> The device as a whole is FPD Link for camera devices I believe, but it
> > 
> > I still don't understand (I could be biased though) why there is such
> > a strong emphasis on cameras and media stuff in the discussion.
> > 
> > No, "the device as a whole is FPD Link for camera devices" is a wrong
> > statement. On hand I have a number of boards with
> > serializers/deserializers from the TI DS90Ux9xx IC series and sensors are
> > NOT connected to them.

I understand what is not connected to them, but could you tell us what is 
connected then ? :-)

> Yes - My apologies, this is a good point.
> 
> Especially as the clue is in the name "Flat Panel Display".
> I have been stuck with my GMSL hat on for too long.
> 
> Even GMSL is in the same boat. It's just that 'we' are using GMSL for
> cameras, but it can be used equally for displays and data.
> 
> These devices are serialiser-deserialiser pairs with power and control
> paths.

And data paths, that are designed to transport video (and audio in this case). 
The devices are thus media-focussed, although in a broader sense than drivers/
media/

> Essentially they are multi purpose buses - which do not yet have a home.
> We have used media as a home because of our use case.
> 
> The use case whether they transfer frames from a camera or to a display
> are of course closely related, but ultimately covered by two separate
> subsystems at the pixel level (DRM vs V4L, or other for other data)
> 
> Perhaps as they are buses - on a level with USB or I2C (except they can
> of course carry I2C or Serial as well as 'bi-directional video' etc ),
> they are looking for their own subsystem.
> 
> Except I don't think we don't want to add a new subsystem for just one
> (or two) devices...

I'm not sure a new subsystem is needed. As you've noted there's an overlap 
between drivers/media/ and drivers/gpu/drm/ in terms of supported hardware. We 
even have a devices supported by two drivers, one in drivers/media/ and one in 
drivers/gpu/drm/ (I'm thinking about the adv7511 in particular). This is a 
well known issue, and so far nothing has been done in mainline to try and 
solve it.

Trying to find another home in drivers/mfd/ to escape from the problem isn't a 
good solution in my opinion. The best option from a Linux point of view would 
be to unify V4L2 and DRM/KMS when it comes to bridge support, but that's a 
long way down the road (I won't complain if you want to give it a go though 
:-)). As your use cases are display, focused, I would propose to start with 
drivers/gpu/drm/bridge/, and leave the problem of camera support for first 
person who will have such a use case.

> >> certainly has different functions which are broken out in this
> >> implementation.
> > 
> > No, there is absolutely nothing broken out from the presented MFD drivers,
> > the drivers are completely integral and basically I don't expect any.
> > 
> > If you are concerned about media functionality, the correspondent MFD
> > *cell* drivers will be added into drivers/media, drivers/gpu/drm or
> > whatever is to be a proper place.
> > 
> >> I think it might be quite awkward having the i2c components in
> >> drivers/i2c and the media components in drivers/media/i2c, so what about
> >> creating drivers/media/i2c/fpd-link (or such) as a container?
> > 
> > I open drivers/media/i2c/Kconfig and all entries with no exception are
> > under from 'if VIDEO_V4L2'. The MFD drivers do NOT require on depend on
> > VIDEO_V4L2 or any other multimedia frameworks, nor the MFD drivers export
> > any multimedia controls.
> > 
> >> Our GMSL implementation is also a complex camera(s) device - but does
> >> not yet use the MFD framework, perhaps that's something to add to my
> >> todo list.

Nope, please don't :-) The GMSL (de)serializers are no MFD devices either.

> > Okay, but the TI DS90Ux9xx is NOT a camera device, and it is NOT a
> > multimedia device, but it is a pure MFD device so the argument is not
> > applicable.

For the reasons pointed out in the review of other patches, and also pointed 
out by Lee in his review of this patch, I disagree with that. This isn't an 
MFD device.

> >> We currently keep all of the complexity within the max9286.c driver, but
> >> I could foresee that being split further if more devices add to the
> >> complexity of managing the bus. At which point we might want an
> >> equivalent drivers/media/i2c/gmsl/ perhaps?
> >> 
> >>>> Laurent, can you please share your opinion?

Done :-)

I'd like to mention that I would prefer focusing on the DT bindings first, and 
then move to the driver side. In that area I would like to have a full example 
of a system using these chips, as the "initial support" is too limited for a 
proper review. This won't come as a surprise, but I will expect the OF graph 
bindings to be used to model data connections.

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 11:24         ` Vladimir Zapolskiy
  2018-10-12 11:43           ` Lee Jones
@ 2018-10-12 13:07           ` Laurent Pinchart
  1 sibling, 0 replies; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-12 13:07 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Vladimir Zapolskiy, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Vladimir,

On Friday, 12 October 2018 14:24:08 EEST Vladimir Zapolskiy wrote:
> On 10/12/2018 11:39 AM, Lee Jones wrote:
> > On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> >> On 10/12/2018 09:03 AM, Lee Jones wrote:
> >>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> >>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>> 
> >>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
> >>>> support of subdevice controllers is done in separate drivers, because
> >>>> not all IC functionality may be needed in particular situations, and
> >>>> this can be fine grained controlled in device tree.
> >>>> 
> >>>> The development of the driver was a collaborative work, the
> >>>> contribution done by Balasubramani Vivekanandan includes:
> >>>> * original implementation of the driver based on a reference driver,
> >>>> * regmap powered interrupt controller support on serializers,
> >>>> * support of implicitly or improperly specified in device tree ICs,
> >>>> * support of device properties and attributes: backward compatible
> >>>> 
> >>>>   mode, low frequency operation mode, spread spectrum clock generator.
> >>>> 
> >>>> Contribution by Steve Longerbeam:
> >>>> * added ds90ux9xx_read_indirect() function,
> >>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
> >>>> * moved and updated ds90ux9xx_get_link_status() function to core
> >>>> driver,
> >>>> * added fpd_link_show device attribute.
> >>>> 
> >>>> Sandeep Jain added support of pixel clock edge configuration.
> >>>> 
> >>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>> ---
> >>>> 
> >>>>  drivers/mfd/Kconfig           |  14 +
> >>>>  drivers/mfd/Makefile          |   1 +
> >>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
> >>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
> >>>>  4 files changed, 936 insertions(+)
> >>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
> >>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
> >>>> 
> >>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> >>>> index 8c5dfdce4326..a969fa123f64 100644
> >>>> --- a/drivers/mfd/Kconfig
> >>>> +++ b/drivers/mfd/Kconfig
> >>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
> >>>> 
> >>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
> >>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
> >>>> 
> >>>> +config MFD_DS90UX9XX
> >>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
> >>>> +	depends on I2C && OF
> >>>> +	select MFD_CORE
> >>>> +	select REGMAP_I2C
> >>>> +	help
> >>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer 
ICs.
> >>>> +
> >>>> +	  This driver provides basic support for setting up the
> >>>> de-/serializer
> >>>> +	  chips. Additional functionalities like connection handling to
> >>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
> >>>> +	  controller and so on are provided by separate drivers and should
> >>>> +	  enabled individually.
> >>> 
> >>> This is not an MFD driver.
> >> 
> >> Why do you think so? The representation of the ICs into device tree
> >> format of hardware description shows that this is a truly MFD driver with
> >> multiple IP subcomponents naturally mapped into MFD cells.
> > 
> > This driver does too much real work ('stuff') to be an MFD driver.
> > MFD drivers should not need to care of; links, gates, modes, pixels,
> > frequencies maps or properties.  Nor should they contain elaborate
> > sysfs structures to control the aforementioned 'stuff'.
> 
> What is the reason why device drivers for sort of multimedia ICs like
> WL1273, WM8994 and other numerous codecs are found in drivers/mfd?

I won't comment on those because I don't know them (Lee might have a better 
knowledge in this area), but let's not rule out historical mistakes, that we 
may not want to repeat.

> If the same reason can not be applied to this DS90Ux9xx driver, why?
> 
> > Granted, there may be some code in there which could be appropriate
> > for an MFD driver.  However most of it needs moving out into a
> > function driver (or two).
> > 
> >> Basically it is possible to replace explicit of_platform_populate() by
> >> adding a "simple-mfd" compatible, if it is desired.
> >> 
> >>> After a 30 second Google of what this device actually does, perhaps
> >>> drivers/media might be a better fit?
> >> 
> >> I assume it would be quite unusual to add a driver with NO media
> >> functions and controls into drivers/media.
> > 
> > drivers/media may very well not be the correct place for this.  In my
> > 30 second Google, I saw that this device has a lot to do with cameras,
> > hence my media association.
> 
> Well, the argument is similar to the statement that Google says that
> camera sensors *can* be connected to NXP i.MX6 SoC, thus arch/arm/mach-imx
> contents should be placed into drivers/media

If there are any camera drivers in arch/arm/mach-imx, they should certainly be 
moved.

> A few TI DS90Ux9xx *cell* drivers may be added to drivers/media, but it is
> out of the scope of the current series, which is completely integral per se,
> and actually the cover letter says that the series of drivers immediately
> allows to output video over DRM to panels, but the discussion is around
> sensors by some reason.

Possibly because a quick search for more information about the device returned 
camera use cases. Let's not focus on that.

> But I hope it won't be seen as a misleading reason to consider to add the
> MFD driver into drivers/gpu/drm

Not a misleading one, a very good one :-) This should go in drivers/gpu/drm/
bridge/.

> > If *all* else fails, there is always drivers/misc, but this should be
> > avoided if at all possible.
> 
> drivers/misc does not sound like a proper place for the MFD driver...

drivers/misc/ isn't right either.

> >> Laurent, can you please share your opinion?

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
  2018-10-12  7:32     ` Vladimir Zapolskiy
  2018-10-12  9:03       ` Lee Jones
@ 2018-10-12 13:12       ` Laurent Pinchart
  2018-10-12 14:36         ` Vladimir Zapolskiy
  1 sibling, 1 reply; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-12 13:12 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Lee Jones, Vladimir Zapolskiy, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel, wsa

Hi Vladimir,

(CC'ing Wolfram)

On Friday, 12 October 2018 10:32:32 EEST Vladimir Zapolskiy wrote:
> On 10/12/2018 09:04 AM, Lee Jones wrote:
> > On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> >> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >> 
> >> The change adds TI DS90Ux9xx I2C bridge/alias subdevice driver and
> >> FPD Link connection handling mechanism.
> >> 
> >> Access to I2C devices connected to a remote de-/serializer is done in
> >> a transparent way, on established link detection event such devices
> >> are registered on an I2C bus, which serves a local de-/serializer IC.
> >> 
> >> The development of the driver was a collaborative work, the
> >> contribution done by Balasubramani Vivekanandan includes:
> >> * original simplistic implementation of the driver,
> >> * support of implicitly specified devices in device tree,
> >> * support of multiple FPD links for TI DS90Ux9xx,
> >> * other kind of valuable review comments, clean-ups and fixes.
> >> 
> >> Also Steve Longerbeam made the following changes:
> >> * clear address maps after linked device removal,
> >> * disable pass-through in disconnection,
> >> * qualify locked status with non-zero remote address.
> >> 
> >> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >> ---
> >> 
> >>  drivers/mfd/Kconfig                |   8 +
> >>  drivers/mfd/Makefile               |   1 +
> >>  drivers/mfd/ds90ux9xx-i2c-bridge.c | 764 +++++++++++++++++++++++++++++
> >>  3 files changed, 773 insertions(+)
> >>  create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c
> > 
> > Shouldn't this live in drivers/i2c?
> 
> no, the driver is not for an I2C controller of any kind, and the driver does
> not register itself in the I2C subsystem by calling i2c_add_adapter() or
> i2c_add_numbered_adapter() or i2c_mux_add_adapter() etc, this topic was
> discussed with Wolfram also.

(Who is now on CC)

> Formally the driver converts the managed IC into a multi-address I2C
> slave device, I understand that it does not sound like a well suited driver
> for MFD, but ds90ux9xx-core.c and ds90ux9xx-i2c-bridge.c drivers are quite
> tightly coupled.

As mentioned in other e-mails in this thread I don't think this should be 
split out to a separate driver, I would move the functionality to the 
ds90ux9xx driver. You may want to register an I2C mux, but as you have a 
single port, that could be overkill. I haven't studied in details how to best 
support this chip using the existing I2C subsystems APIs (which we may want to 
extend if it needed), but I believe that (in your use cases) the deserializer 
should be a child of the serializer, and modeled as an I2C device.

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 13:01               ` Laurent Pinchart
@ 2018-10-12 13:59                 ` Vladimir Zapolskiy
  2018-10-16 13:08                   ` Laurent Pinchart
  2018-10-23  8:16                   ` Vladimir Zapolskiy
  2018-10-13 15:10                 ` Vladimir Zapolskiy
  1 sibling, 2 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-12 13:59 UTC (permalink / raw)
  To: Laurent Pinchart, Vladimir Zapolskiy
  Cc: kieran.bingham, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hello Laurent.

On 10/12/2018 04:01 PM, Laurent Pinchart wrote:
> Hello Vladimir,
> 
> On Friday, 12 October 2018 14:47:52 EEST Kieran Bingham wrote:
>> On 12/10/18 11:58, Vladimir Zapolskiy wrote:
>>> On 10/12/2018 12:20 PM, Kieran Bingham wrote:
>>>> On 12/10/18 09:39, Lee Jones wrote:
>>>>> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
>>>>>> On 10/12/2018 09:03 AM, Lee Jones wrote:
>>>>>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
>>>>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>>>>
>>>>>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
>>>>>>>> support of subdevice controllers is done in separate drivers, because
>>>>>>>> not all IC functionality may be needed in particular situations, and
>>>>>>>> this can be fine grained controlled in device tree.
>>>>>>>>
>>>>>>>> The development of the driver was a collaborative work, the
>>>>>>>> contribution done by Balasubramani Vivekanandan includes:
>>>>>>>> * original implementation of the driver based on a reference driver,
>>>>>>>> * regmap powered interrupt controller support on serializers,
>>>>>>>> * support of implicitly or improperly specified in device tree ICs,
>>>>>>>> * support of device properties and attributes: backward compatible
>>>>>>>>
>>>>>>>>   mode, low frequency operation mode, spread spectrum clock
>>>>>>>>   generator.
>>>>>>>>
>>>>>>>> Contribution by Steve Longerbeam:
>>>>>>>> * added ds90ux9xx_read_indirect() function,
>>>>>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
>>>>>>>> * moved and updated ds90ux9xx_get_link_status() function to core
>>>>>>>> driver,
>>>>>>>> * added fpd_link_show device attribute.
>>>>>>>>
>>>>>>>> Sandeep Jain added support of pixel clock edge configuration.
>>>>>>>>
>>>>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>>>> ---
>>>>>>>>
>>>>>>>>  drivers/mfd/Kconfig           |  14 +
>>>>>>>>  drivers/mfd/Makefile          |   1 +
>>>>>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++
>>>>>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
>>>>>>>>  4 files changed, 936 insertions(+)
>>>>>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>>>>>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
>>>>>>>>
>>>>>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>>>>>>> index 8c5dfdce4326..a969fa123f64 100644
>>>>>>>> --- a/drivers/mfd/Kconfig
>>>>>>>> +++ b/drivers/mfd/Kconfig
>>>>>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>>>>>>>>
>>>>>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
>>>>>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>>>>>>>>
>>>>>>>> +config MFD_DS90UX9XX
>>>>>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
>>>>>>>> +	depends on I2C && OF
>>>>>>>> +	select MFD_CORE
>>>>>>>> +	select REGMAP_I2C
>>>>>>>> +	help
>>>>>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer
>>>>>>>> ICs.
>>>>>>>> +
>>>>>>>> +	  This driver provides basic support for setting up the
>>>>>>>> de-/serializer
>>>>>>>> +	  chips. Additional functionalities like connection handling to
>>>>>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
>>>>>>>> +	  controller and so on are provided by separate drivers and should
>>>>>>>> +	  enabled individually.
>>>>>>>
>>>>>>> This is not an MFD driver.
>>>>>>
>>>>>> Why do you think so? The representation of the ICs into device tree
>>>>>> format of hardware description shows that this is a truly MFD driver
>>>>>> with multiple IP subcomponents naturally mapped into MFD cells.
>>>>>
>>>>> This driver does too much real work ('stuff') to be an MFD driver.
>>>>> MFD drivers should not need to care of; links, gates, modes, pixels,
>>>>> frequencies maps or properties.  Nor should they contain elaborate
>>>>> sysfs structures to control the aforementioned 'stuff'.
>>>>>
>>>>> Granted, there may be some code in there which could be appropriate
>>>>> for an MFD driver.  However most of it needs moving out into a
>>>>> function driver (or two).
>>>>>
>>>>>> Basically it is possible to replace explicit of_platform_populate() by
>>>>>> adding a "simple-mfd" compatible, if it is desired.
>>>>>>
>>>>>>> After a 30 second Google of what this device actually does, perhaps
>>>>>>> drivers/media might be a better fit?
>>>>>>
>>>>>> I assume it would be quite unusual to add a driver with NO media
>>>>>> functions and controls into drivers/media.
>>>>>
>>>>> drivers/media may very well not be the correct place for this.  In my
>>>>> 30 second Google, I saw that this device has a lot to do with cameras,
>>>>> hence my media association.
>>>>>
>>>>> If *all* else fails, there is always drivers/misc, but this should be
>>>>> avoided if at all possible.
>>>>
>>>> The device as a whole is FPD Link for camera devices I believe, but it
>>>
>>> I still don't understand (I could be biased though) why there is such
>>> a strong emphasis on cameras and media stuff in the discussion.
>>>
>>> No, "the device as a whole is FPD Link for camera devices" is a wrong
>>> statement. On hand I have a number of boards with
>>> serializers/deserializers from the TI DS90Ux9xx IC series and sensors are
>>> NOT connected to them.
> 
> I understand what is not connected to them, but could you tell us what is 
> connected then ? :-)

You got it right, the most two common ways of using the ICs:

1) SoC -> serializer ("local") -> deserializer ("remote") -> panel,
2) sensor -> serializer ("remote") -> deserializer ("local") -> SoC.

The point is that the published drivers naturally support both data chains
and even more of them, e.g. transferring audio data only or just setting
GPIO line signals on a "remote" PCB.

>> Yes - My apologies, this is a good point.
>>
>> Especially as the clue is in the name "Flat Panel Display".
>> I have been stuck with my GMSL hat on for too long.
>>
>> Even GMSL is in the same boat. It's just that 'we' are using GMSL for
>> cameras, but it can be used equally for displays and data.
>>
>> These devices are serialiser-deserialiser pairs with power and control
>> paths.
> 
> And data paths, that are designed to transport video (and audio in this case). 
> The devices are thus media-focussed, although in a broader sense than drivers/
> media/

The devices are media-focused only in the sense that media functionality
casts a shadow onto inalienable GPIO or I2C bridging functionality.

Anyway MFD driver representation of the ICs allows to keep pinmuxing, V4L2,
DRM, audio bridging, interrupt controller and all other subcontroller
functions separately, configure them separately, store under separate
driver frameworks etc. That's a perfect flexibility on drivers level
as I can see it.

>> Essentially they are multi purpose buses - which do not yet have a home.
>> We have used media as a home because of our use case.
>>
>> The use case whether they transfer frames from a camera or to a display
>> are of course closely related, but ultimately covered by two separate
>> subsystems at the pixel level (DRM vs V4L, or other for other data)
>>
>> Perhaps as they are buses - on a level with USB or I2C (except they can
>> of course carry I2C or Serial as well as 'bi-directional video' etc ),
>> they are looking for their own subsystem.
>>
>> Except I don't think we don't want to add a new subsystem for just one
>> (or two) devices...
> 
> I'm not sure a new subsystem is needed. As you've noted there's an overlap 
> between drivers/media/ and drivers/gpu/drm/ in terms of supported hardware. We 
> even have a devices supported by two drivers, one in drivers/media/ and one in 
> drivers/gpu/drm/ (I'm thinking about the adv7511 in particular). This is a 
> well known issue, and so far nothing has been done in mainline to try and 
> solve it.

Right, presumably this IC series would have *cell* drivers in both drivers/media
and drivers/gpu/drm/ and other folders like drivers/pinctrl/ or sound/.

The interesting thing is that the published drivers do NOT require any new
cell drivers (at least non-trivial ones with >200 LoC) in drivers/media/
or drivers/gpu/drm/ to get the expected operation of DS90Ux925/926/927/928
ICs (any ser-des connection combination), and we have a DS90Ux940 cell driver
targeted to drivers/media/

> Trying to find another home in drivers/mfd/ to escape from the problem isn't a 
> good solution in my opinion. The best option from a Linux point of view would 
> be to unify V4L2 and DRM/KMS when it comes to bridge support, but that's a 
> long way down the road (I won't complain if you want to give it a go though 
> :-)). As your use cases are display, focused, I would propose to start with 
> drivers/gpu/drm/bridge/, and leave the problem of camera support for first 
> person who will have such a use case.

Well, what should I do with pinctrl or audio bridging device drivers?

Stick all drivers together into an unmaintainable clod of tangled code?

Let's better exploit the excellent opportunity for code modularity given
by the MFD framework.

>>>> certainly has different functions which are broken out in this
>>>> implementation.
>>>
>>> No, there is absolutely nothing broken out from the presented MFD drivers,
>>> the drivers are completely integral and basically I don't expect any.
>>>
>>> If you are concerned about media functionality, the correspondent MFD
>>> *cell* drivers will be added into drivers/media, drivers/gpu/drm or
>>> whatever is to be a proper place.
>>>
>>>> I think it might be quite awkward having the i2c components in
>>>> drivers/i2c and the media components in drivers/media/i2c, so what about
>>>> creating drivers/media/i2c/fpd-link (or such) as a container?
>>>
>>> I open drivers/media/i2c/Kconfig and all entries with no exception are
>>> under from 'if VIDEO_V4L2'. The MFD drivers do NOT require on depend on
>>> VIDEO_V4L2 or any other multimedia frameworks, nor the MFD drivers export
>>> any multimedia controls.
>>>
>>>> Our GMSL implementation is also a complex camera(s) device - but does
>>>> not yet use the MFD framework, perhaps that's something to add to my
>>>> todo list.
> 
> Nope, please don't :-) The GMSL (de)serializers are no MFD devices either.
> 
>>> Okay, but the TI DS90Ux9xx is NOT a camera device, and it is NOT a
>>> multimedia device, but it is a pure MFD device so the argument is not
>>> applicable.
> 
> For the reasons pointed out in the review of other patches, and also pointed 
> out by Lee in his review of this patch, I disagree with that. This isn't an 
> MFD device.

Eh, it is an MFD device. Just probably drivers/mfd is really not the best
place to store this particular MFD device driver...

>>>> We currently keep all of the complexity within the max9286.c driver, but
>>>> I could foresee that being split further if more devices add to the
>>>> complexity of managing the bus. At which point we might want an
>>>> equivalent drivers/media/i2c/gmsl/ perhaps?
>>>>
>>>>>> Laurent, can you please share your opinion?
> 
> Done :-)
> 
> I'd like to mention that I would prefer focusing on the DT bindings first, and 

Sure, thank you for your comments :)

> then move to the driver side. In that area I would like to have a full example 
> of a system using these chips, as the "initial support" is too limited for a 
> proper review. This won't come as a surprise, but I will expect the OF graph 
> bindings to be used to model data connections.
> 

The leverage of "the initial support" to "the complete support" requires:
* audio bridge cell driver -- trivial, just one mute/unmute control,
* interrupt controller cell driver -- trivial, but for sake of perfection
  it requires some minimal changes in drivers/base/regmap/regmap-irq.c
* DS90Ux940 MIPI CSI-2 -- non-trivial one, but we have it ready, I just
  don't want to add it to the pile at the moment, otherwise we'll continue
  discussing cameras, and I'd like to postpone it :)

No more than that is needed to get absolutely complete support of 5 claimed
DS90UB9xx ICs, really. 5 other DS90UH9xx will require HDCP support in addition.

I'll try to roll out an example of DTS snippet soon.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 11:34             ` Lee Jones
@ 2018-10-12 14:13               ` Vladimir Zapolskiy
  2018-10-12 14:25                 ` Lee Jones
  0 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-12 14:13 UTC (permalink / raw)
  To: Lee Jones, Vladimir Zapolskiy
  Cc: kieran.bingham, Laurent Pinchart, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Lee,

On 10/12/2018 02:34 PM, Lee Jones wrote:
> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
>> On 10/12/2018 12:20 PM, Kieran Bingham wrote:
>>> Hi Vladimir,
>>> On 12/10/18 09:39, Lee Jones wrote:
>>>> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
>>>>> On 10/12/2018 09:03 AM, Lee Jones wrote:
>>>>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
>>>>>>
>>>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>>>
>>>>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
>>>>>>> support of subdevice controllers is done in separate drivers, because
>>>>>>> not all IC functionality may be needed in particular situations, and
>>>>>>> this can be fine grained controlled in device tree.
>>>>>>>
>>>>>>> The development of the driver was a collaborative work, the
>>>>>>> contribution done by Balasubramani Vivekanandan includes:
>>>>>>> * original implementation of the driver based on a reference driver,
>>>>>>> * regmap powered interrupt controller support on serializers,
>>>>>>> * support of implicitly or improperly specified in device tree ICs,
>>>>>>> * support of device properties and attributes: backward compatible
>>>>>>>   mode, low frequency operation mode, spread spectrum clock generator.
>>>>>>>
>>>>>>> Contribution by Steve Longerbeam:
>>>>>>> * added ds90ux9xx_read_indirect() function,
>>>>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
>>>>>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
>>>>>>> * added fpd_link_show device attribute.
>>>>>>>
>>>>>>> Sandeep Jain added support of pixel clock edge configuration.
>>>>>>>
>>>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>>> ---
>>>>>>>  drivers/mfd/Kconfig           |  14 +
>>>>>>>  drivers/mfd/Makefile          |   1 +
>>>>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
>>>>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
>>>>>>>  4 files changed, 936 insertions(+)
>>>>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>>>>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
>>>>>>>
>>>>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>>>>>> index 8c5dfdce4326..a969fa123f64 100644
>>>>>>> --- a/drivers/mfd/Kconfig
>>>>>>> +++ b/drivers/mfd/Kconfig
>>>>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>>>>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
>>>>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>>>>>>>  
>>>>>>> +config MFD_DS90UX9XX
>>>>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
>>>>>>> +	depends on I2C && OF
>>>>>>> +	select MFD_CORE
>>>>>>> +	select REGMAP_I2C
>>>>>>> +	help
>>>>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
>>>>>>> +
>>>>>>> +	  This driver provides basic support for setting up the de-/serializer
>>>>>>> +	  chips. Additional functionalities like connection handling to
>>>>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
>>>>>>> +	  controller and so on are provided by separate drivers and should
>>>>>>> +	  enabled individually.
>>>>>>
>>>>>> This is not an MFD driver.
>>>>>
>>>>> Why do you think so? The representation of the ICs into device tree format
>>>>> of hardware description shows that this is a truly MFD driver with multiple
>>>>> IP subcomponents naturally mapped into MFD cells.
>>>>
>>>> This driver does too much real work ('stuff') to be an MFD driver.
>>>> MFD drivers should not need to care of; links, gates, modes, pixels,
>>>> frequencies maps or properties.  Nor should they contain elaborate
>>>> sysfs structures to control the aforementioned 'stuff'.
>>>>
>>>> Granted, there may be some code in there which could be appropriate
>>>> for an MFD driver.  However most of it needs moving out into a
>>>> function driver (or two).
>>>>
>>>>> Basically it is possible to replace explicit of_platform_populate() by
>>>>> adding a "simple-mfd" compatible, if it is desired.
>>>>>
>>>>>> After a 30 second Google of what this device actually does, perhaps
>>>>>> drivers/media might be a better fit?
>>>>>
>>>>> I assume it would be quite unusual to add a driver with NO media functions
>>>>> and controls into drivers/media.
>>>>
>>>> drivers/media may very well not be the correct place for this.  In my
>>>> 30 second Google, I saw that this device has a lot to do with cameras,
>>>> hence my media association.
>>>>
>>>> If *all* else fails, there is always drivers/misc, but this should be
>>>> avoided if at all possible.
>>>
>>> The device as a whole is FPD Link for camera devices I believe, but it
>>
>> I still don't understand (I could be biased though) why there is such
>> a strong emphasis on cameras and media stuff in the discussion.
>>
>> No, "the device as a whole is FPD Link for camera devices" is a wrong
>> statement. On hand I have a number of boards with serializers/deserializers
>> from the TI DS90Ux9xx IC series and sensors are NOT connected to them.
>>
>>> certainly has different functions which are broken out in this
>>> implementation.
>>
>> No, there is absolutely nothing broken out from the presented MFD drivers,
>> the drivers are completely integral and basically I don't expect any.
>>
>> If you are concerned about media functionality, the correspondent MFD
>> *cell* drivers will be added into drivers/media, drivers/gpu/drm or
>> whatever is to be a proper place.
>>
>>> I think it might be quite awkward having the i2c components in
>>> drivers/i2c and the media components in drivers/media/i2c, so what about
>>> creating drivers/media/i2c/fpd-link (or such) as a container?
>>
>> I open drivers/media/i2c/Kconfig and all entries with no exception are
>> under from 'if VIDEO_V4L2'. The MFD drivers do NOT require on depend on
>> VIDEO_V4L2 or any other multimedia frameworks, nor the MFD drivers export
>> any multimedia controls.
>>
>>> Our GMSL implementation is also a complex camera(s) device - but does
>>> not yet use the MFD framework, perhaps that's something to add to my
>>> todo list.
>>>
>>
>> Okay, but the TI DS90Ux9xx is NOT a camera device, and it is NOT a multimedia
>> device, but it is a pure MFD device so the argument is not applicable.
> 
> You keep saying that "this is an MFD device" without any obvious
> comprehension of what an MFD is.  Just saying that it is one
> over-and-over does not make it so.
> An MFD should be little more than parent to other functional devices.
> Their role is to register children which in turn conduct operations
> on the hardware in a useful way.  Some MFDs also house common functions
> to save repetition of code in each of the child devices.  They do not
> tend to offer any useful functionality (stuff) in their own right. 

This describes the presented MFD driver quite closely, if I remove
a few OF controls from ds90ux9xx-core.c:
* ti,video-map-select-*,
* ti,pixel-clock-edge,
* ti,spread-spectrum-clock-generation

Then the MFD device driver will not have any useful functionality
apart of what you've listed above, please feel free to recheck.

Should I just go ahead and do the change with the assumption that
the modified MFD driver suits MFD framework?

> As I already mentioned, you need to figure out what this device is
> and move all of the functionality into the appropriate subsystem.

By definition as I comprehend it only MFD cell device drivers should
be relocated into the correspondent subsystems, but ds90ux9xx-core
remains in drivers/mfd, no?

Probably ds90ux9xx-i2c-bridge cell driver could enter drivers/misc.

> Since an MFD isn't a real thing/device (it's a Linuxy-shim which 
> only serves to register sub-devices and (sometimes) provide a space
> for common functionality to be located), drivers/mfd is not the
> subsystem which you seek. 

Oh, that's exactly the case with DS90Ux9xx driver 'ds90ux9xx-core.c',
it's just a common place to store the shared boilerplate code
snippets for all cell device drivers and various flavours of ICs
from the series.

>>> We currently keep all of the complexity within the max9286.c driver, but
>>> I could foresee that being split further if more devices add to the
>>> complexity of managing the bus. At which point we might want an
>>> equivalent drivers/media/i2c/gmsl/ perhaps?
> 

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 11:43           ` Lee Jones
@ 2018-10-12 14:23             ` Vladimir Zapolskiy
  0 siblings, 0 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-12 14:23 UTC (permalink / raw)
  To: Lee Jones, Vladimir Zapolskiy
  Cc: Laurent Pinchart, Linus Walleij, Rob Herring, Marek Vasut,
	Wolfram Sang, devicetree, linux-gpio, linux-media, linux-kernel

On 10/12/2018 02:43 PM, Lee Jones wrote:
> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> 
>> On 10/12/2018 11:39 AM, Lee Jones wrote:
>>> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
>>>> On 10/12/2018 09:03 AM, Lee Jones wrote:
>>>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
>>>>>
>>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>>
>>>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
>>>>>> support of subdevice controllers is done in separate drivers, because
>>>>>> not all IC functionality may be needed in particular situations, and
>>>>>> this can be fine grained controlled in device tree.
>>>>>>
>>>>>> The development of the driver was a collaborative work, the
>>>>>> contribution done by Balasubramani Vivekanandan includes:
>>>>>> * original implementation of the driver based on a reference driver,
>>>>>> * regmap powered interrupt controller support on serializers,
>>>>>> * support of implicitly or improperly specified in device tree ICs,
>>>>>> * support of device properties and attributes: backward compatible
>>>>>>   mode, low frequency operation mode, spread spectrum clock generator.
>>>>>>
>>>>>> Contribution by Steve Longerbeam:
>>>>>> * added ds90ux9xx_read_indirect() function,
>>>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
>>>>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
>>>>>> * added fpd_link_show device attribute.
>>>>>>
>>>>>> Sandeep Jain added support of pixel clock edge configuration.
>>>>>>
>>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>> ---
>>>>>>  drivers/mfd/Kconfig           |  14 +
>>>>>>  drivers/mfd/Makefile          |   1 +
>>>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
>>>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
>>>>>>  4 files changed, 936 insertions(+)
>>>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
>>>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
>>>>>>
>>>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>>>>> index 8c5dfdce4326..a969fa123f64 100644
>>>>>> --- a/drivers/mfd/Kconfig
>>>>>> +++ b/drivers/mfd/Kconfig
>>>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
>>>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
>>>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
>>>>>>  
>>>>>> +config MFD_DS90UX9XX
>>>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
>>>>>> +	depends on I2C && OF
>>>>>> +	select MFD_CORE
>>>>>> +	select REGMAP_I2C
>>>>>> +	help
>>>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
>>>>>> +
>>>>>> +	  This driver provides basic support for setting up the de-/serializer
>>>>>> +	  chips. Additional functionalities like connection handling to
>>>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
>>>>>> +	  controller and so on are provided by separate drivers and should
>>>>>> +	  enabled individually.
>>>>>
>>>>> This is not an MFD driver.
>>>>
>>>> Why do you think so? The representation of the ICs into device tree format
>>>> of hardware description shows that this is a truly MFD driver with multiple
>>>> IP subcomponents naturally mapped into MFD cells.
>>>
>>> This driver does too much real work ('stuff') to be an MFD driver.
>>> MFD drivers should not need to care of; links, gates, modes, pixels,
>>> frequencies maps or properties.  Nor should they contain elaborate
>>> sysfs structures to control the aforementioned 'stuff'.
>>>
>>
>> What is the reason why device drivers for sort of multimedia ICs like
>> WL1273, WM8994 and other numerous codecs are found in drivers/mfd?
>>
>> If the same reason can not be applied to this DS90Ux9xx driver, why?
>>
>>> Granted, there may be some code in there which could be appropriate
>>> for an MFD driver.  However most of it needs moving out into a
>>> function driver (or two).
>>>
>>>> Basically it is possible to replace explicit of_platform_populate() by
>>>> adding a "simple-mfd" compatible, if it is desired.
>>>>
>>>>> After a 30 second Google of what this device actually does, perhaps
>>>>> drivers/media might be a better fit?
>>>>
>>>> I assume it would be quite unusual to add a driver with NO media functions
>>>> and controls into drivers/media.
>>>
>>> drivers/media may very well not be the correct place for this.  In my
>>> 30 second Google, I saw that this device has a lot to do with cameras,
>>> hence my media association.
>>
>> Well, the argument is similar to the statement that Google says that
>> camera sensors *can* be connected to NXP i.MX6 SoC, thus arch/arm/mach-imx
>> contents should be placed into drivers/media
>>
>> A few TI DS90Ux9xx *cell* drivers may be added to drivers/media, but it is
>> out of the scope of the current series, which is completely integral per se,
>> and actually the cover letter says that the series of drivers immediately
>> allows to output video over DRM to panels, but the discussion is around
>> sensors by some reason. But I hope it won't be seen as a misleading
>> reason to consider to add the MFD driver into drivers/gpu/drm
> 
> This discussion isn't about not adding enough child devices.  It's
> about there being too much functional work being done in an MFD
> driver, where it doesn't belong.

Please can you elaborate what is "too much functional work" here
more precisely?

>>> If *all* else fails, there is always drivers/misc, but this should be
>>> avoided if at all possible.
>>
>> drivers/misc does not sound like a proper place for the MFD driver...
> 
> I'd agree with you if this were an MFD driver.
> 
> As I mentioned before, there may well be an argument for and MFD
> driver to be part of this driver-set.  However it needs to be
> significantly reduced with any functional code removed and placed
> where it belongs.
> 

I can name just settings of a few bitfields from OF and sysfs to be
moved to another location (media or DRM, Laurent?), and some of them
like "backward compatible mode" (used to connect ICs of different
generations) setting should remain in the core driver.

Clearly I'd like to know what exactly should be changed in the
ds90ux9xx-core.c code to get it accepted as an MFD device driver,
probably you can comment on the code about anything to remove/relocate?

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 14:13               ` Vladimir Zapolskiy
@ 2018-10-12 14:25                 ` Lee Jones
  0 siblings, 0 replies; 62+ messages in thread
From: Lee Jones @ 2018-10-12 14:25 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Vladimir Zapolskiy, kieran.bingham, Laurent Pinchart,
	Linus Walleij, Rob Herring, Marek Vasut, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel

On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:

> Hi Lee,
> 
> On 10/12/2018 02:34 PM, Lee Jones wrote:
> > On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> >> On 10/12/2018 12:20 PM, Kieran Bingham wrote:
> >>> Hi Vladimir,
> >>> On 12/10/18 09:39, Lee Jones wrote:
> >>>> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> >>>>> On 10/12/2018 09:03 AM, Lee Jones wrote:
> >>>>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> >>>>>>
> >>>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>>>>
> >>>>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
> >>>>>>> support of subdevice controllers is done in separate drivers, because
> >>>>>>> not all IC functionality may be needed in particular situations, and
> >>>>>>> this can be fine grained controlled in device tree.
> >>>>>>>
> >>>>>>> The development of the driver was a collaborative work, the
> >>>>>>> contribution done by Balasubramani Vivekanandan includes:
> >>>>>>> * original implementation of the driver based on a reference driver,
> >>>>>>> * regmap powered interrupt controller support on serializers,
> >>>>>>> * support of implicitly or improperly specified in device tree ICs,
> >>>>>>> * support of device properties and attributes: backward compatible
> >>>>>>>   mode, low frequency operation mode, spread spectrum clock generator.
> >>>>>>>
> >>>>>>> Contribution by Steve Longerbeam:
> >>>>>>> * added ds90ux9xx_read_indirect() function,
> >>>>>>> * moved number of links property and added ds90ux9xx_num_fpd_links(),
> >>>>>>> * moved and updated ds90ux9xx_get_link_status() function to core driver,
> >>>>>>> * added fpd_link_show device attribute.
> >>>>>>>
> >>>>>>> Sandeep Jain added support of pixel clock edge configuration.
> >>>>>>>
> >>>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>>>> ---
> >>>>>>>  drivers/mfd/Kconfig           |  14 +
> >>>>>>>  drivers/mfd/Makefile          |   1 +
> >>>>>>>  drivers/mfd/ds90ux9xx-core.c  | 879 ++++++++++++++++++++++++++++++++++
> >>>>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
> >>>>>>>  4 files changed, 936 insertions(+)
> >>>>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
> >>>>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
> >>>>>>>
> >>>>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> >>>>>>> index 8c5dfdce4326..a969fa123f64 100644
> >>>>>>> --- a/drivers/mfd/Kconfig
> >>>>>>> +++ b/drivers/mfd/Kconfig
> >>>>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
> >>>>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
> >>>>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
> >>>>>>>  
> >>>>>>> +config MFD_DS90UX9XX
> >>>>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
> >>>>>>> +	depends on I2C && OF
> >>>>>>> +	select MFD_CORE
> >>>>>>> +	select REGMAP_I2C
> >>>>>>> +	help
> >>>>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer ICs.
> >>>>>>> +
> >>>>>>> +	  This driver provides basic support for setting up the de-/serializer
> >>>>>>> +	  chips. Additional functionalities like connection handling to
> >>>>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
> >>>>>>> +	  controller and so on are provided by separate drivers and should
> >>>>>>> +	  enabled individually.
> >>>>>>
> >>>>>> This is not an MFD driver.
> >>>>>
> >>>>> Why do you think so? The representation of the ICs into device tree format
> >>>>> of hardware description shows that this is a truly MFD driver with multiple
> >>>>> IP subcomponents naturally mapped into MFD cells.
> >>>>
> >>>> This driver does too much real work ('stuff') to be an MFD driver.
> >>>> MFD drivers should not need to care of; links, gates, modes, pixels,
> >>>> frequencies maps or properties.  Nor should they contain elaborate
> >>>> sysfs structures to control the aforementioned 'stuff'.
> >>>>
> >>>> Granted, there may be some code in there which could be appropriate
> >>>> for an MFD driver.  However most of it needs moving out into a
> >>>> function driver (or two).
> >>>>
> >>>>> Basically it is possible to replace explicit of_platform_populate() by
> >>>>> adding a "simple-mfd" compatible, if it is desired.
> >>>>>
> >>>>>> After a 30 second Google of what this device actually does, perhaps
> >>>>>> drivers/media might be a better fit?
> >>>>>
> >>>>> I assume it would be quite unusual to add a driver with NO media functions
> >>>>> and controls into drivers/media.
> >>>>
> >>>> drivers/media may very well not be the correct place for this.  In my
> >>>> 30 second Google, I saw that this device has a lot to do with cameras,
> >>>> hence my media association.
> >>>>
> >>>> If *all* else fails, there is always drivers/misc, but this should be
> >>>> avoided if at all possible.
> >>>
> >>> The device as a whole is FPD Link for camera devices I believe, but it
> >>
> >> I still don't understand (I could be biased though) why there is such
> >> a strong emphasis on cameras and media stuff in the discussion.
> >>
> >> No, "the device as a whole is FPD Link for camera devices" is a wrong
> >> statement. On hand I have a number of boards with serializers/deserializers
> >> from the TI DS90Ux9xx IC series and sensors are NOT connected to them.
> >>
> >>> certainly has different functions which are broken out in this
> >>> implementation.
> >>
> >> No, there is absolutely nothing broken out from the presented MFD drivers,
> >> the drivers are completely integral and basically I don't expect any.
> >>
> >> If you are concerned about media functionality, the correspondent MFD
> >> *cell* drivers will be added into drivers/media, drivers/gpu/drm or
> >> whatever is to be a proper place.
> >>
> >>> I think it might be quite awkward having the i2c components in
> >>> drivers/i2c and the media components in drivers/media/i2c, so what about
> >>> creating drivers/media/i2c/fpd-link (or such) as a container?
> >>
> >> I open drivers/media/i2c/Kconfig and all entries with no exception are
> >> under from 'if VIDEO_V4L2'. The MFD drivers do NOT require on depend on
> >> VIDEO_V4L2 or any other multimedia frameworks, nor the MFD drivers export
> >> any multimedia controls.
> >>
> >>> Our GMSL implementation is also a complex camera(s) device - but does
> >>> not yet use the MFD framework, perhaps that's something to add to my
> >>> todo list.
> >>>
> >>
> >> Okay, but the TI DS90Ux9xx is NOT a camera device, and it is NOT a multimedia
> >> device, but it is a pure MFD device so the argument is not applicable.
> > 
> > You keep saying that "this is an MFD device" without any obvious
> > comprehension of what an MFD is.  Just saying that it is one
> > over-and-over does not make it so.
> > An MFD should be little more than parent to other functional devices.
> > Their role is to register children which in turn conduct operations
> > on the hardware in a useful way.  Some MFDs also house common functions
> > to save repetition of code in each of the child devices.  They do not
> > tend to offer any useful functionality (stuff) in their own right. 
> 
> This describes the presented MFD driver quite closely, if I remove
> a few OF controls from ds90ux9xx-core.c:
> * ti,video-map-select-*,
> * ti,pixel-clock-edge,
> * ti,spread-spectrum-clock-generation
> 
> Then the MFD device driver will not have any useful functionality
> apart of what you've listed above, please feel free to recheck.
> 
> Should I just go ahead and do the change with the assumption that
> the modified MFD driver suits MFD framework?

Since this device seems to be truly multi-function, I have no qualms
with it being represented by a parent MFD driver.  Providing any
useful functionality (code that actually does stuff) is removed and
placed in a more suitable location, it sounds like a reasonably good
fit for MFD.

> > As I already mentioned, you need to figure out what this device is
> > and move all of the functionality into the appropriate subsystem.
> 
> By definition as I comprehend it only MFD cell device drivers should
> be relocated into the correspondent subsystems, but ds90ux9xx-core
> remains in drivers/mfd, no?

Sounds about right.

> Probably ds90ux9xx-i2c-bridge cell driver could enter drivers/misc.

Let's see what Wolfram has to say WRT Laurent's suggestion.

> > Since an MFD isn't a real thing/device (it's a Linuxy-shim which 
> > only serves to register sub-devices and (sometimes) provide a space
> > for common functionality to be located), drivers/mfd is not the
> > subsystem which you seek. 
> 
> Oh, that's exactly the case with DS90Ux9xx driver 'ds90ux9xx-core.c',
> it's just a common place to store the shared boilerplate code
> snippets for all cell device drivers and various flavours of ICs
> from the series.

What you're using it for now is out-of-scope of an MFD driver.  Which
if the functions are called from more than 1 call-site?  Those have a
chance of residing - we'll discuss those on an ad-hoc basis.  Anything
else needs relocating to the relevant subsystem.

We should also speak to Mark Brown about the indirect Regmap stuff.
Perhaps this would better suit a header file.

> >>> We currently keep all of the complexity within the max9286.c driver, but
> >>> I could foresee that being split further if more devices add to the
> >>> complexity of managing the bus. At which point we might want an
> >>> equivalent drivers/media/i2c/gmsl/ perhaps?

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
  2018-10-12 13:12       ` Laurent Pinchart
@ 2018-10-12 14:36         ` Vladimir Zapolskiy
  2018-10-16 14:06           ` Laurent Pinchart
  0 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-12 14:36 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Laurent

On 10/12/2018 04:12 PM, Laurent Pinchart wrote:
> Hi Vladimir,
> 
> (CC'ing Wolfram)
> 
> On Friday, 12 October 2018 10:32:32 EEST Vladimir Zapolskiy wrote:
>> On 10/12/2018 09:04 AM, Lee Jones wrote:
>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>
>>>> The change adds TI DS90Ux9xx I2C bridge/alias subdevice driver and
>>>> FPD Link connection handling mechanism.
>>>>
>>>> Access to I2C devices connected to a remote de-/serializer is done in
>>>> a transparent way, on established link detection event such devices
>>>> are registered on an I2C bus, which serves a local de-/serializer IC.
>>>>
>>>> The development of the driver was a collaborative work, the
>>>> contribution done by Balasubramani Vivekanandan includes:
>>>> * original simplistic implementation of the driver,
>>>> * support of implicitly specified devices in device tree,
>>>> * support of multiple FPD links for TI DS90Ux9xx,
>>>> * other kind of valuable review comments, clean-ups and fixes.
>>>>
>>>> Also Steve Longerbeam made the following changes:
>>>> * clear address maps after linked device removal,
>>>> * disable pass-through in disconnection,
>>>> * qualify locked status with non-zero remote address.
>>>>
>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>> ---
>>>>
>>>>  drivers/mfd/Kconfig                |   8 +
>>>>  drivers/mfd/Makefile               |   1 +
>>>>  drivers/mfd/ds90ux9xx-i2c-bridge.c | 764 +++++++++++++++++++++++++++++
>>>>  3 files changed, 773 insertions(+)
>>>>  create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c
>>>
>>> Shouldn't this live in drivers/i2c?
>>
>> no, the driver is not for an I2C controller of any kind, and the driver does
>> not register itself in the I2C subsystem by calling i2c_add_adapter() or
>> i2c_add_numbered_adapter() or i2c_mux_add_adapter() etc, this topic was
>> discussed with Wolfram also.
> 
> (Who is now on CC)
> 

Wolfram has copies of the drivers and discussion right from the beginning,
hopefully he won't get two copies ;)

>> Formally the driver converts the managed IC into a multi-address I2C
>> slave device, I understand that it does not sound like a well suited driver
>> for MFD, but ds90ux9xx-core.c and ds90ux9xx-i2c-bridge.c drivers are quite
>> tightly coupled.
> 
> As mentioned in other e-mails in this thread I don't think this should be 
> split out to a separate driver,> I would move the functionality to the 
> ds90ux9xx driver.

The proposal may have the grounds, but the I2C bridging functionality of ICs
is quite detached from all other ones, thus it found its place in the cell
driver per se.

> You may want to register an I2C mux, but as you have a single port, that
> could be overkill. I haven't studied in details how to best support this
> chip using the existing I2C subsystems APIs (which we may want to extend
> if it needed), but I believe that (in your use cases) the deserializer
> should be a child of the serializer, and modeled as an I2C device.
> 

Formally in OF terms to define a link between devices by a phandle should
be sufficient, panels are not the children of LVDS controllers under OF graph
constraints in DT representation, the panels become secondary in runtime
only, I'd like to reuse the concept. Also it adds a better sense of symmetry
of deserializer <-> serializer connections relatively to a SoC/data source.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 11:47             ` Kieran Bingham
  2018-10-12 13:01               ` Laurent Pinchart
@ 2018-10-13 12:33               ` Vladimir Zapolskiy
  1 sibling, 0 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-13 12:33 UTC (permalink / raw)
  To: kieran.bingham, Laurent Pinchart
  Cc: Lee Jones, Vladimir Zapolskiy, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Kieran,

On 10/12/2018 02:47 PM, Kieran Bingham wrote:
> Hi Vladimir,
> 

[snip]

> 
> Essentially they are multi purpose buses - which do not yet have a home.
> We have used media as a home because of our use case.
> 
> The use case whether they transfer frames from a camera or to a display
> are of course closely related, but ultimately covered by two separate
> subsystems at the pixel level (DRM vs V4L, or other for other data)
> 
> Perhaps as they are buses - on a level with USB or I2C (except they can
> of course carry I2C or Serial as well as 'bi-directional video' etc ),
> they are looking for their own subsystem.
> 
> Except I don't think we don't want to add a new subsystem for just one
> (or two) devices...
> 

I suppose that the incomplete list includes Maxim GMSL, TI FPD-Link III,
SMSC/Microchip MOST (drivers/staging/most -- what's the destination after
exiting staging?) an Inova APIX.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  2018-10-12 12:01   ` Laurent Pinchart
@ 2018-10-13 13:47     ` Vladimir Zapolskiy
  2018-10-16 12:48       ` Laurent Pinchart
  0 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-13 13:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Laurent,

thank you for review, please find my comments below.

On 10/12/2018 03:01 PM, Laurent Pinchart wrote:
> Hi Vladimir,
> 
> Thank you for the patch.
> 
> On Tuesday, 9 October 2018 00:12:01 EEST Vladimir Zapolskiy wrote:
>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>
>> TI DS90Ux9xx de-/serializers have a capability to multiplex pin functions,
>> in particular a pin may have selectable functions of GPIO, GPIO line
>> transmitter, one of I2S lines, one of RGB24 video signal lines and so on.
>>
>> The change adds a description of DS90Ux9xx pin multiplexers and GPIO
>> controllers.
>>
>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>> ---
>>  .../bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt | 83 +++++++++++++++++++
>>  1 file changed, 83 insertions(+)
>>  create mode 100644
>> Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
>>
>> diff --git
>> a/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
>> b/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt new
>> file mode 100644
>> index 000000000000..fbfa1a3cdf9f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
>> @@ -0,0 +1,83 @@
>> +TI DS90Ux9xx de-/serializer pinmux and GPIO subcontroller
>> +
>> +Required properties:
>> +- compatible: Must contain a generic "ti,ds90ux9xx-pinctrl" value and
>> +	may contain one more specific value from the list:
>> +	"ti,ds90ux925-pinctrl",
>> +	"ti,ds90ux926-pinctrl",
>> +	"ti,ds90ux927-pinctrl",
>> +	"ti,ds90ux928-pinctrl",
>> +	"ti,ds90ux940-pinctrl".
> 
> No need for a subnode, you can mark the main DT node with gpio-controller 
> directly.

If the IC is seen as an MFD, and you guess I highly prefer it and I object
the "overkill" argument, then the subnode is requred.

Also the more complicated part of the subcontroller and its device driver
is to provide pinmuxing function to consumers rather than to allow GPIO
line configuration.

The pinctrl/GPIO driver can not be alloyed with the base driver's code
to sustain maintainability, so it will reside in drivers/pinctrl as
a separate cell driver, and by the way that is the reason why it earns
its own very non-trivial DT binding description documentation.

>> +- gpio-controller: Marks the device node as a GPIO controller.
>> +
>> +- #gpio-cells: Must be set to 2,
>> +	- the first cell is the GPIO offset number within the controller,
>> +	- the second cell is used to specify the GPIO line polarity.
>> +
>> +- gpio-ranges: Mapping to pin controller pins (as described in
>> +	Documentation/devicetree/bindings/gpio/gpio.txt)
>> +
>> +Optional properties:
>> +- ti,video-depth-18bit: Sets video bridge pins to RGB 18-bit mode.
> 
> Please use standard properties to configure bus width. There is one defined in 
> Documentation/devicetree/bindings/media/video-interfaces.txt.

Here it is not a bus width description or property, but rather it is a custom
pinmux control.

It could make sense to reduce the scope of the property to "parallel" pin
function only though, like in

	ds90ux927_0_pins: pinmux {
		parallel {
			groups = "parallel";
			function = "parallel";
			ti,video-depth-18bit;
		};
	};

Alternatively the removal of the property would be almost loseless, it is
needed just in one very specific case, please reference to the driver code
for details, there you'll find a comment in ds90ux9xx_parse_dt_properties()
function.

>> +Available pins, groups and functions (reference to device datasheets):
>> +
>> +function: "gpio" ("gpio4" is on DS90Ux925 and DS90Ux926 only,
>> +		  "gpio9" is on DS90Ux940 only)
>> + - pins: "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6",
>> +	 "gpio7", "gpio8", "gpio9"
>> +
>> +function: "gpio-remote"
>> + - pins: "gpio0", "gpio1", "gpio2", "gpio3"
>> +
>> +function: "pass" (DS90Ux940 specific only)
>> + - pins: "gpio0", "gpio3"
> 
> What do those functions mean ?
> 

"gpio" function should be already familiar to you.

"gpio-remote" function is the pin function for a GPIO line bridging.

"pass" function sets a pin to a status pin function for detecting
display timing issues, namely DE or Vsync length value mismatch.

>> +function: "i2s-1"
>> + - group: "i2s-1"
>> +
>> +function: "i2s-2"
>> + - group: "i2s-2"
>> +
>> +function: "i2s-3" (DS90Ux927, DS90Ux928 and DS90Ux940 specific only)
>> + - group: "i2s-3"
>> +
>> +function: "i2s-4" (DS90Ux927, DS90Ux928 and DS90Ux940 specific only)
>> + - group: "i2s-4"
>> +
>> +function: "i2s-m" (DS90Ux928 and DS90Ux940 specific only)
>> + - group: "i2s-m"
> 
> Do we really need all this ? I think a better model would be to describe the 
> audio interfaces explicitly, and configure pinmuxing automatically based on 
> which audio interfaces are in use.

Yes, all the pin functions are needed, because they are transparent pinmux
controls.

I really don't want to copy a part of gpio and pinctrl frameworks to
the driver to hunt out why a user configured audio bridging and a GPIO
line, and then something goes funny due to a pin conflict. To forget
about such very possible pin and pin function conflicts I'm happy to
shift the task to the neat Linus' frameworks.

>> +function: "parallel" (DS90Ux925 and DS90Ux926 specific only)
>> + - group: "parallel"
>> +
>> +Example (deserializer with pins GPIO[3:0] set to bridged output
>> +	 function and pin GPIO4 in standard hogged GPIO function):
>> +
>> +deserializer {
>> +	compatible = "ti,ds90ub928q", "ti,ds90ux9xx";
>> +
>> +	ds90ux928_pctrl: pin-controller {
>> +		compatible = "ti,ds90ux928-pinctrl", "ti,ds90ux9xx-pinctrl";
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +		gpio-ranges = <&ds90ux928_pctrl 0 0 8>;
>> +
>> +		pinctrl-names = "default";
>> +		pinctrl-0 = <&ds90ux928_pins>;
>> +
>> +		ds90ux928_pins: pinmux {
>> +			gpio-remote {
>> +				pins = "gpio0", "gpio1", "gpio2", "gpio3";
>> +				function = "gpio-remote";
>> +			};
>> +		};
>> +
>> +		rst {
>> +			gpio-hog;
>> +			gpios = <4 GPIO_ACTIVE_HIGH>;
>> +			output-high;
>> +		};
>> +	};
>> +};
> 

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-12 11:44   ` Laurent Pinchart
@ 2018-10-13 14:28     ` Vladimir Zapolskiy
  2018-10-16 12:30       ` Laurent Pinchart
  0 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-13 14:28 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel, Sandeep Jain

Hi Laurent,

thank you for review, please find my comments below.

On 10/12/2018 02:44 PM, Laurent Pinchart wrote:
> Hi Vladimir,
> 
> Thank you for the patch.
> 
> On Tuesday, 9 October 2018 00:11:59 EEST Vladimir Zapolskiy wrote:
>> From: Sandeep Jain <Sandeep_Jain@mentor.com>
>>
>> The change adds device tree binding description of TI DS90Ux9xx
>> series of serializer and deserializer controllers which support video,
>> audio and control data transmission over FPD-III Link connection.
>>
>> Signed-off-by: Sandeep Jain <Sandeep_Jain@mentor.com>
>> [vzapolskiy: various updates and corrections of secondary importance]
>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>> ---
>>  .../devicetree/bindings/mfd/ti,ds90ux9xx.txt  | 66 +++++++++++++++++++
>>  1 file changed, 66 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
>> b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt new file mode
>> 100644
>> index 000000000000..0733da88f7ef
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
>> @@ -0,0 +1,66 @@
>> +Texas Instruments DS90Ux9xx de-/serializer controllers
>> +
>> +Required properties:
>> +- compatible: Must contain a generic "ti,ds90ux9xx" value and
>> +	may contain one more specific value from the list:
> 
> If it "may" contain one more specific value, when should that value be 
> present, and when can it be absent ?

Practically you can always omit a specific compatible, because (with a number
of minor exceptions like DS90UH925Q case, see a quirk in the code) it is
possible to read out the IC type in runtime.

Nevertheless I prefer to have a complete list of all specific compatibles
to avoid problems with maintenance in future, recently I had a long discussion
with Jassi Brar about iMX* mailbox compatibles on the DT mailing list,
the arguments remain the same, but I don't feel enough internal power to start
another such an exhaustive discussion right at the moment.

>> +	"ti,ds90ub925q",
>> +	"ti,ds90uh925q",
>> +	"ti,ds90ub927q",
>> +	"ti,ds90uh927q",
>> +	"ti,ds90ub926q",
>> +	"ti,ds90uh926q",
>> +	"ti,ds90ub928q",
>> +	"ti,ds90uh928q",
>> +	"ti,ds90ub940q",
>> +	"ti,ds90uh940q".
>> +
>> +Optional properties:
>> +- reg : Specifies the I2C slave address of a local de-/serializer.
> 
> You should explain when the reg property is required and when it isn't. This

Talking about TI DS90Ux9xx IC series, ideally I'd like to shift from
serializer/deserializer concept and promote "remote" and "local" IC, by the
way, and if I'm not mistaken, MOST ICs are truly identical on both ends.

So, here "reg" property is need only if the IC (serializer or deserializer,
it does not matter) is on the "local" side, i.e. it is a slave I2C device
discovered on an I2C bus, which is under control by an application processor.

If IC is on the "remote" side, in other words separated by the serial link
from the "local" IC, then "reg" property is not needed.

> will in my opinion require a more detailed explanation of the DT model for 
> this device.
> 
>> +- power-gpios : GPIO line to control supplied power to the device.
> 
> As Marek mentioned, a regulator would be better. I would make it a mandatory 
> property, as the device always needs to be powered.
> 

I get a memory flashback. Did we discuss recently a right property name to
control panel power by a GPIO or was it something else?

There are quite many properties of exactly the same functionality:
* powerdown-gpios
* pd-gpios
* pdn-gpios
* power-gpios
* powerdn-gpio
* power-down-gpios
* ...

Probably device tree maintainers should unify the names, but my point is that
your argument should be applicable to all such device tree nodes / property
descriptions and usages. Do I understand you correctly?

I would prefer to reference to a regulator while dealing with the power
rails, and reference to a GPIO in case of power control only like in the
case above.

>> +- ti,backward-compatible-mode : Overrides backward compatibility mode.
>> +	Possible values are "<1>" or "<0>".
>> +	If "ti,backward-compatible-mode" is not mentioned, the backward
>> +	compatibility mode is not touched and given by hardware pin strapping.
> 
> This doesn't seem to be a device description to me, it's a software 
> configuration. You should handle it in drivers.
> 

No, it is a hardware description which allows to connect/discover ICs of
different series, please reference to the datasheet for examples of its
usage.

>> +- ti,low-frequency-mode : Overrides low frequency mode.
>> +	Possible values are "<1>" or "<0>".
>> +	If "ti,low-frequency-mode" is not mentioned, the low frequency mode
>> +	is not touched and given by hardware pin strapping.
> 
> This sounds the same. How about giving a real life example of a case where you 
> need to set these two properties to override the pin strapping, for the 
> purpose of discussing the DT bindings ?

I have to ask, what do you mean by "a software configuration"?

Both properties are IC controls (= hardware configuration in my language),
and these hardware properties shall be set (if needed of course) on a "local" IC
*before* a discovery of some "remote" IC, thus the property are in the DT.

>> +- ti,video-map-select-msb: Sets video bridge pins to MSB mode, if it is set
>> +	MAPSEL pin value is ignored.
>> +- ti,video-map-select-lsb: Sets video bridge pins to LSB mode, if it is set
>> +	MAPSEL pin value is ignored.
> 
> I assume those two are mutually exclusive, this should be documented, or you 
> could merge the two properties into one. Same comment as above though, why do 
> you need an override in DT ?
> 

The property are mutually exclusive, but it is a tristate property, please
see my answer to a similar question from Marek.

>> +- ti,pixel-clock-edge : Selects Pixel Clock Edge.
>> +	Possible values are "<1>" or "<0>".
>> +	If "ti,pixel-clock-edge" is High <1>, output data is strobed on the
>> +	Rising edge of the PCLK. If ti,pixel-clock-edge is Low <0>, data is
>> +	strobed on the Falling edge of the PCLK.
>> +	If "ti,pixel-clock-edge" is not mentioned, the pixel clock edge
>> +	value is not touched and given by hardware pin strapping.
> 
> We have a standard property in Documentation/devicetree/bindings/media/video-
> interfaces.txt for this, please use it.
> 

Okay, thank you for the link.

>> +- ti,spread-spectrum-clock-generation : Spread Sprectrum Clock Generation.
>> +	Possible values are from "<0>" to "<7>". The same value will be
>> +	written to SSC register. If "ti,spread-spectrum-clock-gen" is not
>> +	found, then SSCG will be disabled.
> 
> This makes sense in DT in my opinion, as EMC is a system property. I wonder 
> however if exposing the hardware register directly is the best option. Could 
> you elaborate on how a system designer will select which value to use, in 
> order to find the best DT description ?
> 

Hm, I suppose IC datasheets should serve as a better source of information.

>> +TI DS90Ux9xx serializers and deserializer device nodes may contain a number
>> +of children device nodes to describe and enable particular subcomponents
>> +found on ICs.
> 
> As mentioned in my review of the cover letter I don't think this is necessary. 

It is, in my humble opinion if an IC can be described as "a _pinmux_ + loads
of other functions" it makes it an MFD.

> You can make the serializer and deserializer I2C controllers without subnodes. 
> Same goes for GPIO control.
> 

I have to define pinmuxes, one of the complicated and essential parts of IC
configuration is unfairly excluded from the consideration.

>> +Example:
>> +
>> +serializer: serializer@c {
>> +	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
>> +	reg = <0xc>;
>> +	power-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
>> +	ti,backward-compatible-mode = <0>;
>> +	ti,low-frequency-mode = <0>;
>> +	ti,pixel-clock-edge = <0>;
>> +	...
>> +}
>> +
>> +deserializer: deserializer@3c {
>> +	compatible = "ti,ds90ub940q", "ti,ds90ux9xx";
>> +	reg = <0x3c>;
>> +	power-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
>> +	...
>> +}
>> +
> 
> Extra blank line ?
> 

Right, thank you for comments.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 13:01               ` Laurent Pinchart
  2018-10-12 13:59                 ` Vladimir Zapolskiy
@ 2018-10-13 15:10                 ` Vladimir Zapolskiy
  2018-10-16 13:12                   ` Laurent Pinchart
  1 sibling, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-13 15:10 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: kieran.bingham, Lee Jones, Vladimir Zapolskiy, Linus Walleij,
	Rob Herring, Marek Vasut, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

Hi Laurent,

On 10/12/2018 04:01 PM, Laurent Pinchart wrote:
> Hello Vladimir,
> 
> On Friday, 12 October 2018 14:47:52 EEST Kieran Bingham wrote:
>> On 12/10/18 11:58, Vladimir Zapolskiy wrote:

[snip]

>> Essentially they are multi purpose buses - which do not yet have a home.
>> We have used media as a home because of our use case.
>>
>> The use case whether they transfer frames from a camera or to a display
>> are of course closely related, but ultimately covered by two separate
>> subsystems at the pixel level (DRM vs V4L, or other for other data)
>>
>> Perhaps as they are buses - on a level with USB or I2C (except they can
>> of course carry I2C or Serial as well as 'bi-directional video' etc ),
>> they are looking for their own subsystem.
>>
>> Except I don't think we don't want to add a new subsystem for just one
>> (or two) devices...
> 
> I'm not sure a new subsystem is needed. As you've noted there's an overlap 
> between drivers/media/ and drivers/gpu/drm/ in terms of supported hardware.
> We even have a devices supported by two drivers, one in drivers/media/ and
> one in drivers/gpu/drm/ (I'm thinking about the adv7511 in particular).
> This is a well known issue, and so far nothing has been done in mainline
> to try and solve it.

I agree that there's an overlap between drivers/media/ and drivers/gpu/drm/,
formally a hypothetical (sic!) DS90Ux9xx video bridge cell driver should be
added into both subsystems also, and the actual driver of two should be
selected in runtime. I call such a driver 'hypothetical', because in fact
I don't have it, and I'm not so sure that its existence is justified, but
that's only because DS90Ux9xx video bridge functionality is _transparent_,
it does not have any controls literally, but it is a pure luck eventually.

So, as I've stated in my cover letter, I can misuse yours 'lvds-encoder'
driver only for the purpose of establishing a mediated link between 
an LVDS controller and a panel over a serializer-deserializer pair.

> Trying to find another home in drivers/mfd/ to escape from the problem isn't a 
> good solution in my opinion. The best option from a Linux point of view would 
> be to unify V4L2 and DRM/KMS when it comes to bridge support, but that's a 
> long way down the road (I won't complain if you want to give it a go though 
> :-)).

I return you a wider smile :)

> As your use cases are display, focused, I would propose to start with 
> drivers/gpu/drm/bridge/, and leave the problem of camera support for first 
> person who will have such a use case.

Frankly speaking I would like to start from copy-pasting your 'lvds-encoder'
driver into an 'absolutely-transparent-video-bridge' driver with no LVDS
or 'encoder' specifics, adding just a new compatible may suffice, if the
driver is renamed/redefined.

PS, I remember I owe you a reference OF snippet of data path to a panel.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-13 14:28     ` Vladimir Zapolskiy
@ 2018-10-16 12:30       ` Laurent Pinchart
  0 siblings, 0 replies; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-16 12:30 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel, Sandeep Jain

Hi Vladimir,

On Saturday, 13 October 2018 17:28:30 EEST Vladimir Zapolskiy wrote:
> On 10/12/2018 02:44 PM, Laurent Pinchart wrote:
> > On Tuesday, 9 October 2018 00:11:59 EEST Vladimir Zapolskiy wrote:
> >> From: Sandeep Jain <Sandeep_Jain@mentor.com>
> >> 
> >> The change adds device tree binding description of TI DS90Ux9xx
> >> series of serializer and deserializer controllers which support video,
> >> audio and control data transmission over FPD-III Link connection.
> >> 
> >> Signed-off-by: Sandeep Jain <Sandeep_Jain@mentor.com>
> >> [vzapolskiy: various updates and corrections of secondary importance]
> >> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >> ---
> >> 
> >>  .../devicetree/bindings/mfd/ti,ds90ux9xx.txt  | 66 +++++++++++++++++++
> >>  1 file changed, 66 insertions(+)
> >>  create mode 100644
> >>  Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> >> 
> >> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> >> b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt new file mode
> >> 100644
> >> index 000000000000..0733da88f7ef
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx.txt
> >> @@ -0,0 +1,66 @@
> >> +Texas Instruments DS90Ux9xx de-/serializer controllers
> >> +
> >> +Required properties:
> >> +- compatible: Must contain a generic "ti,ds90ux9xx" value and
> > 
> >> +	may contain one more specific value from the list:
> > If it "may" contain one more specific value, when should that value be
> > present, and when can it be absent ?
> 
> Practically you can always omit a specific compatible, because (with a
> number of minor exceptions like DS90UH925Q case, see a quirk in the code)
> it is possible to read out the IC type in runtime.
> 
> Nevertheless I prefer to have a complete list of all specific compatibles
> to avoid problems with maintenance in future,

I agree with you. Let's thus word this as

Shall contain exactly one value from the list below, and the generic 
"ti,ds90ux9xx" value, in that order.

> recently I had a long
> discussion with Jassi Brar about iMX* mailbox compatibles on the DT mailing
> list, the arguments remain the same, but I don't feel enough internal power
> to start another such an exhaustive discussion right at the moment.
> 
> >> +	"ti,ds90ub925q",
> >> +	"ti,ds90uh925q",
> >> +	"ti,ds90ub927q",
> >> +	"ti,ds90uh927q",
> >> +	"ti,ds90ub926q",
> >> +	"ti,ds90uh926q",
> >> +	"ti,ds90ub928q",
> >> +	"ti,ds90uh928q",
> >> +	"ti,ds90ub940q",
> >> +	"ti,ds90uh940q".
> >> +
> >> +Optional properties:
> >> +- reg : Specifies the I2C slave address of a local de-/serializer.
> > 
> > You should explain when the reg property is required and when it isn't.
> > This
> 
> Talking about TI DS90Ux9xx IC series, ideally I'd like to shift from
> serializer/deserializer concept and promote "remote" and "local" IC, by the
> way, and if I'm not mistaken, MOST ICs are truly identical on both ends.
> 
> So, here "reg" property is need only if the IC (serializer or deserializer,
> it does not matter) is on the "local" side, i.e. it is a slave I2C device
> discovered on an I2C bus, which is under control by an application
> processor.
> 
> If IC is on the "remote" side, in other words separated by the serial link
> from the "local" IC, then "reg" property is not needed.

Let's document this then. Please make sure to document the local and remote 
concepts in the introduction first.

> > will in my opinion require a more detailed explanation of the DT model for
> > this device.
> > 
> >> +- power-gpios : GPIO line to control supplied power to the device.
> > 
> > As Marek mentioned, a regulator would be better. I would make it a
> > mandatory property, as the device always needs to be powered.
> 
> I get a memory flashback. Did we discuss recently a right property name to
> control panel power by a GPIO or was it something else?
> 
> There are quite many properties of exactly the same functionality:
> * powerdown-gpios
> * pd-gpios
> * pdn-gpios
> * power-gpios
> * powerdn-gpio
> * power-down-gpios
> * ...
> 
> Probably device tree maintainers should unify the names, but my point is
> that your argument should be applicable to all such device tree nodes /
> property descriptions and usages. Do I understand you correctly?

The general agreement is that we should try to standardize the naming of 
GPIOs. As powerdown is the inverse of enable, it has been proposed to use 
enable-gpios instead.

> I would prefer to reference to a regulator while dealing with the power
> rails, and reference to a GPIO in case of power control only like in the
> case above.

The patch made me think that the GPIO controls a regulator, which is why I 
advised using regulators. If that's not the case, if the GPIO is connected to 
a pin of the device, you should document which pin, and rephrase the 
description to remove the ambiguity.

> >> +- ti,backward-compatible-mode : Overrides backward compatibility mode.
> >> +	Possible values are "<1>" or "<0>".
> >> +	If "ti,backward-compatible-mode" is not mentioned, the backward
> >> +	compatibility mode is not touched and given by hardware pin strapping.
> > 
> > This doesn't seem to be a device description to me, it's a software
> > configuration. You should handle it in drivers.
> 
> No, it is a hardware description which allows to connect/discover ICs of
> different series, please reference to the datasheet for examples of its
> usage.

Could you please point us to the right section of the right document ?

> >> +- ti,low-frequency-mode : Overrides low frequency mode.
> >> +	Possible values are "<1>" or "<0>".
> >> +	If "ti,low-frequency-mode" is not mentioned, the low frequency mode
> >> +	is not touched and given by hardware pin strapping.
> > 
> > This sounds the same. How about giving a real life example of a case where
> > you need to set these two properties to override the pin strapping, for
> > the purpose of discussing the DT bindings ?
> 
> I have to ask, what do you mean by "a software configuration"?
> 
> Both properties are IC controls (= hardware configuration in my language),
> and these hardware properties shall be set (if needed of course) on a
> "local" IC *before* a discovery of some "remote" IC, thus the property are
> in the DT.

Software configuration refers to configuration parameters that are modified in 
software based on a policy that can be established by the software. If you can 
provide real examples that show why and how pin strapping needs to be 
overridden, that would help discussing the DT bindings.

> >> +- ti,video-map-select-msb: Sets video bridge pins to MSB mode, if it is
> >> set +	MAPSEL pin value is ignored.
> >> +- ti,video-map-select-lsb: Sets video bridge pins to LSB mode, if it is
> >> set +	MAPSEL pin value is ignored.
> > 
> > I assume those two are mutually exclusive, this should be documented, or
> > you could merge the two properties into one. Same comment as above
> > though, why do you need an override in DT ?
> 
> The property are mutually exclusive, but it is a tristate property, please
> see my answer to a similar question from Marek.

You can implement a tristate property with 0, 1 and absent (or "lsb", "msb" or 
absent, or something similar), you don't need two properties.

> >> +- ti,pixel-clock-edge : Selects Pixel Clock Edge.
> >> +	Possible values are "<1>" or "<0>".
> >> +	If "ti,pixel-clock-edge" is High <1>, output data is strobed on the
> >> +	Rising edge of the PCLK. If ti,pixel-clock-edge is Low <0>, data is
> >> +	strobed on the Falling edge of the PCLK.
> >> +	If "ti,pixel-clock-edge" is not mentioned, the pixel clock edge
> >> +	value is not touched and given by hardware pin strapping.
> > 
> > We have a standard property in
> > Documentation/devicetree/bindings/media/video-interfaces.txt for this,
> > please use it.
> 
> Okay, thank you for the link.
> 
> >> +- ti,spread-spectrum-clock-generation : Spread Sprectrum Clock
> >> Generation.
> >> +	Possible values are from "<0>" to "<7>". The same value will be
> >> +	written to SSC register. If "ti,spread-spectrum-clock-gen" is not
> >> +	found, then SSCG will be disabled.
> > 
> > This makes sense in DT in my opinion, as EMC is a system property. I
> > wonder however if exposing the hardware register directly is the best
> > option. Could you elaborate on how a system designer will select which
> > value to use, in order to find the best DT description ?
> 
> Hm, I suppose IC datasheets should serve as a better source of information.

Could you please point us to the right section(s) of the right datasheet(s) ?

> >> +TI DS90Ux9xx serializers and deserializer device nodes may contain a
> >> number +of children device nodes to describe and enable particular
> >> subcomponents +found on ICs.
> > 
> > As mentioned in my review of the cover letter I don't think this is
> > necessary.
> 
> It is, in my humble opinion if an IC can be described as "a _pinmux_ + loads
> of other functions" it makes it an MFD.

We do disagree :-)

> > You can make the serializer and deserializer I2C controllers without
> > subnodes. Same goes for GPIO control.
> 
> I have to define pinmuxes, one of the complicated and essential parts of IC
> configuration is unfairly excluded from the consideration.
> 
> >> +Example:
> >> +
> >> +serializer: serializer@c {
> >> +	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
> >> +	reg = <0xc>;
> >> +	power-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
> >> +	ti,backward-compatible-mode = <0>;
> >> +	ti,low-frequency-mode = <0>;
> >> +	ti,pixel-clock-edge = <0>;
> >> +	...
> >> +}
> >> +
> >> +deserializer: deserializer@3c {
> >> +	compatible = "ti,ds90ub940q", "ti,ds90ux9xx";
> >> +	reg = <0x3c>;
> >> +	power-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
> >> +	...
> >> +}
> >> +
> > 
> > Extra blank line ?
> 
> Right, thank you for comments.

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  2018-10-13 13:47     ` Vladimir Zapolskiy
@ 2018-10-16 12:48       ` Laurent Pinchart
  2018-10-30 16:44         ` Luca Ceresoli
  0 siblings, 1 reply; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-16 12:48 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Vladimir,

On Saturday, 13 October 2018 16:47:48 EEST Vladimir Zapolskiy wrote:
> On 10/12/2018 03:01 PM, Laurent Pinchart wrote:
> > On Tuesday, 9 October 2018 00:12:01 EEST Vladimir Zapolskiy wrote:
> >> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >> 
> >> TI DS90Ux9xx de-/serializers have a capability to multiplex pin
> >> functions, in particular a pin may have selectable functions of GPIO,
> >> GPIO line transmitter, one of I2S lines, one of RGB24 video signal lines
> >> and so on.
> >> 
> >> The change adds a description of DS90Ux9xx pin multiplexers and GPIO
> >> controllers.
> >> 
> >> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >> ---
> >> 
> >>  .../bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt | 83 +++++++++++++++++++
> >>  1 file changed, 83 insertions(+)
> >>  create mode 100644
> >> 
> >> Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
> >> 
> >> diff --git
> >> a/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
> >> b/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt new
> >> file mode 100644
> >> index 000000000000..fbfa1a3cdf9f
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/pinctrl/ti,ds90ux9xx-pinctrl.txt
> >> @@ -0,0 +1,83 @@
> >> +TI DS90Ux9xx de-/serializer pinmux and GPIO subcontroller
> >> +
> >> +Required properties:
> >> +- compatible: Must contain a generic "ti,ds90ux9xx-pinctrl" value and
> >> +	may contain one more specific value from the list:
> >> +	"ti,ds90ux925-pinctrl",
> >> +	"ti,ds90ux926-pinctrl",
> >> +	"ti,ds90ux927-pinctrl",
> >> +	"ti,ds90ux928-pinctrl",
> >> +	"ti,ds90ux940-pinctrl".
> > 
> > No need for a subnode, you can mark the main DT node with gpio-controller
> > directly.
> 
> If the IC is seen as an MFD, and you guess I highly prefer it and I object
> the "overkill" argument, then the subnode is requred.
> 
> Also the more complicated part of the subcontroller and its device driver
> is to provide pinmuxing function to consumers rather than to allow GPIO
> line configuration.
> 
> The pinctrl/GPIO driver can not be alloyed with the base driver's code
> to sustain maintainability, so it will reside in drivers/pinctrl as
> a separate cell driver, and by the way that is the reason why it earns
> its own very non-trivial DT binding description documentation.
> 
> >> +- gpio-controller: Marks the device node as a GPIO controller.
> >> +
> >> +- #gpio-cells: Must be set to 2,
> >> +	- the first cell is the GPIO offset number within the controller,
> >> +	- the second cell is used to specify the GPIO line polarity.
> >> +
> >> +- gpio-ranges: Mapping to pin controller pins (as described in
> >> +	Documentation/devicetree/bindings/gpio/gpio.txt)
> >> +
> >> +Optional properties:
> >> +- ti,video-depth-18bit: Sets video bridge pins to RGB 18-bit mode.
> > 
> > Please use standard properties to configure bus width. There is one
> > defined in Documentation/devicetree/bindings/media/video-interfaces.txt.
> 
> Here it is not a bus width description or property, but rather it is a
> custom pinmux control.
> 
> It could make sense to reduce the scope of the property to "parallel" pin
> function only though, like in
> 
> 	ds90ux927_0_pins: pinmux {
> 		parallel {
> 			groups = "parallel";
> 			function = "parallel";
> 			ti,video-depth-18bit;
> 		};
> 	};
> 
> Alternatively the removal of the property would be almost loseless, it is
> needed just in one very specific case, please reference to the driver code
> for details, there you'll find a comment in ds90ux9xx_parse_dt_properties()
> function.

Based on the information I gathered from the DS90UH92[567] datasheets, the 
restriction on GPIO usage related to 18-bit mode is due to the signals being 
multiplexed on the same pins on DS90UH925. It could also be that the FPD-Link 
protocol itself can't carry both GPIO and the extra 6 colour bits.

In any case, I don't think the property belongs here. The bus width should be 
specified in the DT bindings for the video ports, and the drivers should then 
use that information to configure other parameters, possibly GPIO-specific, if 
needed.

> >> +Available pins, groups and functions (reference to device datasheets):
> >> +
> >> +function: "gpio" ("gpio4" is on DS90Ux925 and DS90Ux926 only,
> >> +		  "gpio9" is on DS90Ux940 only)
> >> + - pins: "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6",
> >> +	 "gpio7", "gpio8", "gpio9"
> >> +
> >> +function: "gpio-remote"
> >> + - pins: "gpio0", "gpio1", "gpio2", "gpio3"
> >> +
> >> +function: "pass" (DS90Ux940 specific only)
> >> + - pins: "gpio0", "gpio3"
> > 
> > What do those functions mean ?
> 
> "gpio" function should be already familiar to you.

I assume this function is only available for the local device, not the remote 
one ?

> "gpio-remote" function is the pin function for a GPIO line bridging.
> 
> "pass" function sets a pin to a status pin function for detecting
> display timing issues, namely DE or Vsync length value mismatch.

All this is not clear at all from the proposed DT bindings, it should be 
properly documented.

> >> +function: "i2s-1"
> >> + - group: "i2s-1"
> >> +
> >> +function: "i2s-2"
> >> + - group: "i2s-2"
> >> +
> >> +function: "i2s-3" (DS90Ux927, DS90Ux928 and DS90Ux940 specific only)
> >> + - group: "i2s-3"
> >> +
> >> +function: "i2s-4" (DS90Ux927, DS90Ux928 and DS90Ux940 specific only)
> >> + - group: "i2s-4"
> >> +
> >> +function: "i2s-m" (DS90Ux928 and DS90Ux940 specific only)
> >> + - group: "i2s-m"
> > 
> > Do we really need all this ? I think a better model would be to describe
> > the audio interfaces explicitly, and configure pinmuxing automatically
> > based on which audio interfaces are in use.
> 
> Yes, all the pin functions are needed, because they are transparent pinmux
> controls.
> 
> I really don't want to copy a part of gpio and pinctrl frameworks to
> the driver to hunt out why a user configured audio bridging and a GPIO
> line, and then something goes funny due to a pin conflict. To forget
> about such very possible pin and pin function conflicts I'm happy to
> shift the task to the neat Linus' frameworks.

And I still believe this is overkill and confusing, and disagrees that this is 
an MFD device.

> >> +function: "parallel" (DS90Ux925 and DS90Ux926 specific only)
> >> + - group: "parallel"
> >> +
> >> +Example (deserializer with pins GPIO[3:0] set to bridged output
> >> +	 function and pin GPIO4 in standard hogged GPIO function):
> >> +
> >> +deserializer {
> >> +	compatible = "ti,ds90ub928q", "ti,ds90ux9xx";
> >> +
> >> +	ds90ux928_pctrl: pin-controller {
> >> +		compatible = "ti,ds90ux928-pinctrl", "ti,ds90ux9xx-pinctrl";
> >> +		gpio-controller;
> >> +		#gpio-cells = <2>;
> >> +		gpio-ranges = <&ds90ux928_pctrl 0 0 8>;
> >> +
> >> +		pinctrl-names = "default";
> >> +		pinctrl-0 = <&ds90ux928_pins>;
> >> +
> >> +		ds90ux928_pins: pinmux {
> >> +			gpio-remote {
> >> +				pins = "gpio0", "gpio1", "gpio2", "gpio3";
> >> +				function = "gpio-remote";
> >> +			};
> >> +		};
> >> +
> >> +		rst {
> >> +			gpio-hog;
> >> +			gpios = <4 GPIO_ACTIVE_HIGH>;
> >> +			output-high;
> >> +		};
> >> +	};
> >> +};

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 13:59                 ` Vladimir Zapolskiy
@ 2018-10-16 13:08                   ` Laurent Pinchart
  2018-10-23  8:16                   ` Vladimir Zapolskiy
  1 sibling, 0 replies; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-16 13:08 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Vladimir Zapolskiy, kieran.bingham, Lee Jones, Linus Walleij,
	Rob Herring, Marek Vasut, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

Hi Vladimir,

On Friday, 12 October 2018 16:59:27 EEST Vladimir Zapolskiy wrote:
> On 10/12/2018 04:01 PM, Laurent Pinchart wrote:
> > On Friday, 12 October 2018 14:47:52 EEST Kieran Bingham wrote:
> >> On 12/10/18 11:58, Vladimir Zapolskiy wrote:
> >>> On 10/12/2018 12:20 PM, Kieran Bingham wrote:
> >>>> On 12/10/18 09:39, Lee Jones wrote:
> >>>>> On Fri, 12 Oct 2018, Vladimir Zapolskiy wrote:
> >>>>>> On 10/12/2018 09:03 AM, Lee Jones wrote:
> >>>>>>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> >>>>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>>>>> 
> >>>>>>>> The change adds I2C device driver for TI DS90Ux9xx de-/serializers,
> >>>>>>>> support of subdevice controllers is done in separate drivers,
> >>>>>>>> because not all IC functionality may be needed in particular
> >>>>>>>> situations, and this can be fine grained controlled in device tree.
> >>>>>>>> 
> >>>>>>>> The development of the driver was a collaborative work, the
> >>>>>>>> contribution done by Balasubramani Vivekanandan includes:
> >>>>>>>> * original implementation of the driver based on a reference
> >>>>>>>> driver,
> >>>>>>>> * regmap powered interrupt controller support on serializers,
> >>>>>>>> * support of implicitly or improperly specified in device tree ICs,
> >>>>>>>> * support of device properties and attributes: backward compatible
> >>>>>>>>   mode, low frequency operation mode, spread spectrum clock
> >>>>>>>>   generator.
> >>>>>>>> 
> >>>>>>>> Contribution by Steve Longerbeam:
> >>>>>>>> * added ds90ux9xx_read_indirect() function,
> >>>>>>>> * moved number of links property and added
> >>>>>>>> ds90ux9xx_num_fpd_links(),
> >>>>>>>> * moved and updated ds90ux9xx_get_link_status() function to core
> >>>>>>>> driver,
> >>>>>>>> * added fpd_link_show device attribute.
> >>>>>>>> 
> >>>>>>>> Sandeep Jain added support of pixel clock edge configuration.
> >>>>>>>> 
> >>>>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>>>>>> ---
> >>>>>>>> 
> >>>>>>>>  drivers/mfd/Kconfig           |  14 +
> >>>>>>>>  drivers/mfd/Makefile          |   1 +
> >>>>>>>>  drivers/mfd/ds90ux9xx-core.c  | 879
> >>>>>>>>  ++++++++++++++++++++++++++++++++
> >>>>>>>>  include/linux/mfd/ds90ux9xx.h |  42 ++
> >>>>>>>>  4 files changed, 936 insertions(+)
> >>>>>>>>  create mode 100644 drivers/mfd/ds90ux9xx-core.c
> >>>>>>>>  create mode 100644 include/linux/mfd/ds90ux9xx.h
> >>>>>>>> 
> >>>>>>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> >>>>>>>> index 8c5dfdce4326..a969fa123f64 100644
> >>>>>>>> --- a/drivers/mfd/Kconfig
> >>>>>>>> +++ b/drivers/mfd/Kconfig
> >>>>>>>> @@ -1280,6 +1280,20 @@ config MFD_DM355EVM_MSP
> >>>>>>>> 
> >>>>>>>>  	  boards.  MSP430 firmware manages resets and power sequencing,
> >>>>>>>>  	  inputs from buttons and the IR remote, LEDs, an RTC, and more.
> >>>>>>>> 
> >>>>>>>> +config MFD_DS90UX9XX
> >>>>>>>> +	tristate "TI DS90Ux9xx FPD-Link de-/serializer driver"
> >>>>>>>> +	depends on I2C && OF
> >>>>>>>> +	select MFD_CORE
> >>>>>>>> +	select REGMAP_I2C
> >>>>>>>> +	help
> >>>>>>>> +	  Say yes here to enable support for TI DS90UX9XX de-/serializer
> >>>>>>>> ICs.
> >>>>>>>> +
> >>>>>>>> +	  This driver provides basic support for setting up the
> >>>>>>>> de-/serializer
> >>>>>>>> +	  chips. Additional functionalities like connection handling to
> >>>>>>>> +	  remote de-/serializers, I2C bridging, pin multiplexing, GPIO
> >>>>>>>> +	  controller and so on are provided by separate drivers and
> >>>>>>>> should
> >>>>>>>> +	  enabled individually.
> >>>>>>> 
> >>>>>>> This is not an MFD driver.
> >>>>>> 
> >>>>>> Why do you think so? The representation of the ICs into device tree
> >>>>>> format of hardware description shows that this is a truly MFD driver
> >>>>>> with multiple IP subcomponents naturally mapped into MFD cells.
> >>>>> 
> >>>>> This driver does too much real work ('stuff') to be an MFD driver.
> >>>>> MFD drivers should not need to care of; links, gates, modes, pixels,
> >>>>> frequencies maps or properties.  Nor should they contain elaborate
> >>>>> sysfs structures to control the aforementioned 'stuff'.
> >>>>> 
> >>>>> Granted, there may be some code in there which could be appropriate
> >>>>> for an MFD driver.  However most of it needs moving out into a
> >>>>> function driver (or two).
> >>>>> 
> >>>>>> Basically it is possible to replace explicit of_platform_populate()
> >>>>>> by adding a "simple-mfd" compatible, if it is desired.
> >>>>>> 
> >>>>>>> After a 30 second Google of what this device actually does, perhaps
> >>>>>>> drivers/media might be a better fit?
> >>>>>> 
> >>>>>> I assume it would be quite unusual to add a driver with NO media
> >>>>>> functions and controls into drivers/media.
> >>>>> 
> >>>>> drivers/media may very well not be the correct place for this.  In my
> >>>>> 30 second Google, I saw that this device has a lot to do with cameras,
> >>>>> hence my media association.
> >>>>> 
> >>>>> If *all* else fails, there is always drivers/misc, but this should be
> >>>>> avoided if at all possible.
> >>>> 
> >>>> The device as a whole is FPD Link for camera devices I believe, but it
> >>> 
> >>> I still don't understand (I could be biased though) why there is such
> >>> a strong emphasis on cameras and media stuff in the discussion.
> >>> 
> >>> No, "the device as a whole is FPD Link for camera devices" is a wrong
> >>> statement. On hand I have a number of boards with
> >>> serializers/deserializers from the TI DS90Ux9xx IC series and sensors
> >>> are NOT connected to them.
> > 
> > I understand what is not connected to them, but could you tell us what is
> > connected then ? :-)
> 
> You got it right, the most two common ways of using the ICs:
> 
> 1) SoC -> serializer ("local") -> deserializer ("remote") -> panel,
> 2) sensor -> serializer ("remote") -> deserializer ("local") -> SoC.
> 
> The point is that the published drivers naturally support both data chains
> and even more of them, e.g. transferring audio data only or just setting
> GPIO line signals on a "remote" PCB.

At the cost of code being added where it doesn't belong (as pointed out by 
Lee) and DT bindings not following the standard models (data connections 
described by OF graph and control buses described by parent-child 
relationships). Let's focus on fixing the DT bindings first, and we'll then 
see how we can handle the driver side.

> >> Yes - My apologies, this is a good point.
> >> 
> >> Especially as the clue is in the name "Flat Panel Display".
> >> I have been stuck with my GMSL hat on for too long.
> >> 
> >> Even GMSL is in the same boat. It's just that 'we' are using GMSL for
> >> cameras, but it can be used equally for displays and data.
> >> 
> >> These devices are serialiser-deserialiser pairs with power and control
> >> paths.
> > 
> > And data paths, that are designed to transport video (and audio in this
> > case). The devices are thus media-focussed, although in a broader sense
> > than drivers/ media/
> 
> The devices are media-focused only in the sense that media functionality
> casts a shadow onto inalienable GPIO or I2C bridging functionality.

Seriously, do you really expect that they will be used for the sole purpose of 
transporting a few GPIOs ?

> Anyway MFD driver representation of the ICs allows to keep pinmuxing, V4L2,
> DRM, audio bridging, interrupt controller and all other subcontroller
> functions separately, configure them separately, store under separate
> driver frameworks etc. That's a perfect flexibility on drivers level
> as I can see it.

The resulting complexity is still overkill. As mentioned above, let's focus on 
the DT bindings first.

> >> Essentially they are multi purpose buses - which do not yet have a home.
> >> We have used media as a home because of our use case.
> >> 
> >> The use case whether they transfer frames from a camera or to a display
> >> are of course closely related, but ultimately covered by two separate
> >> subsystems at the pixel level (DRM vs V4L, or other for other data)
> >> 
> >> Perhaps as they are buses - on a level with USB or I2C (except they can
> >> of course carry I2C or Serial as well as 'bi-directional video' etc ),
> >> they are looking for their own subsystem.
> >> 
> >> Except I don't think we don't want to add a new subsystem for just one
> >> (or two) devices...
> > 
> > I'm not sure a new subsystem is needed. As you've noted there's an overlap
> > between drivers/media/ and drivers/gpu/drm/ in terms of supported
> > hardware. We even have a devices supported by two drivers, one in
> > drivers/media/ and one in drivers/gpu/drm/ (I'm thinking about the
> > adv7511 in particular). This is a well known issue, and so far nothing
> > has been done in mainline to try and solve it.
> 
> Right, presumably this IC series would have *cell* drivers in both
> drivers/media and drivers/gpu/drm/ and other folders like drivers/pinctrl/
> or sound/.

Even with cell drivers you'll have the problem of DRM vs. V4L2. My advice is 
to go for DRM only for now.

> The interesting thing is that the published drivers do NOT require any new
> cell drivers (at least non-trivial ones with >200 LoC) in drivers/media/
> or drivers/gpu/drm/ to get the expected operation of DS90Ux925/926/927/928
> ICs (any ser-des connection combination), and we have a DS90Ux940 cell
> driver targeted to drivers/media/

That's because you abuse the rest of the APIs to cover up for what's lacking 
in media/ and gpu/drm/ :-)

> > Trying to find another home in drivers/mfd/ to escape from the problem
> > isn't a good solution in my opinion. The best option from a Linux point
> > of view would be to unify V4L2 and DRM/KMS when it comes to bridge
> > support, but that's a long way down the road (I won't complain if you
> > want to give it a go though :-)). As your use cases are display, focused,
> > I would propose to start with drivers/gpu/drm/bridge/, and leave the
> > problem of camera support for first person who will have such a use case.
> 
> Well, what should I do with pinctrl or audio bridging device drivers?

I'll defer the audio problems to people more knowledgeable about audio. For 
pinctrl I believe you're making it way more complicated than it should be. 
Again, DT bindings first, drivers second. And please provide DT examples for 
real use cases, I think that will be key to proper DT bindings design.

> Stick all drivers together into an unmaintainable clod of tangled code?

You know this isn't what I proposed, let's stay fair in this discussion. Your 
proposal is too complex in my opinion, I want to simplify it, which will 
result in easier to maintain code.

> Let's better exploit the excellent opportunity for code modularity given
> by the MFD framework.
> 
> >>>> certainly has different functions which are broken out in this
> >>>> implementation.
> >>> 
> >>> No, there is absolutely nothing broken out from the presented MFD
> >>> drivers, the drivers are completely integral and basically I don't
> >>> expect any.
> >>> 
> >>> If you are concerned about media functionality, the correspondent MFD
> >>> *cell* drivers will be added into drivers/media, drivers/gpu/drm or
> >>> whatever is to be a proper place.
> >>> 
> >>>> I think it might be quite awkward having the i2c components in
> >>>> drivers/i2c and the media components in drivers/media/i2c, so what
> >>>> about creating drivers/media/i2c/fpd-link (or such) as a container?
> >>> 
> >>> I open drivers/media/i2c/Kconfig and all entries with no exception are
> >>> under from 'if VIDEO_V4L2'. The MFD drivers do NOT require on depend on
> >>> VIDEO_V4L2 or any other multimedia frameworks, nor the MFD drivers
> >>> export any multimedia controls.
> >>> 
> >>>> Our GMSL implementation is also a complex camera(s) device - but does
> >>>> not yet use the MFD framework, perhaps that's something to add to my
> >>>> todo list.
> > 
> > Nope, please don't :-) The GMSL (de)serializers are no MFD devices either.
> > 
> >>> Okay, but the TI DS90Ux9xx is NOT a camera device, and it is NOT a
> >>> multimedia device, but it is a pure MFD device so the argument is not
> >>> applicable.
> > 
> > For the reasons pointed out in the review of other patches, and also
> > pointed out by Lee in his review of this patch, I disagree with that.
> > This isn't an MFD device.
> 
> Eh, it is an MFD device. Just probably drivers/mfd is really not the best
> place to store this particular MFD device driver...

We still disagree. Those chips are video serializers and deserializers with a 
few additional features to support those use cases. The fact that additional 
support features are available don't automatically make them a true MFD. To 
give you another example, my camera ISP that happens to be able to output a 
clock for the camera sensor is also not an MFD, and I can still support clock 
control through CCF without requiring the MFD framework.

> >>>> We currently keep all of the complexity within the max9286.c driver,
> >>>> but I could foresee that being split further if more devices add to the
> >>>> complexity of managing the bus. At which point we might want an
> >>>> equivalent drivers/media/i2c/gmsl/ perhaps?
> >>>> 
> >>>>>> Laurent, can you please share your opinion?
> > 
> > Done :-)
> > 
> > I'd like to mention that I would prefer focusing on the DT bindings first,
> > and
> 
> Sure, thank you for your comments :)
> 
> > then move to the driver side. In that area I would like to have a full
> > example of a system using these chips, as the "initial support" is too
> > limited for a proper review. This won't come as a surprise, but I will
> > expect the OF graph bindings to be used to model data connections.
> 
> The leverage of "the initial support" to "the complete support" requires:
> * audio bridge cell driver -- trivial, just one mute/unmute control,
> * interrupt controller cell driver -- trivial, but for sake of perfection
>   it requires some minimal changes in drivers/base/regmap/regmap-irq.c

This is a topic we haven't discussed yet, don't jump to conclusions and 
consider that an interrupt controller driver is needed. Could you please 
explain the use cases and point to the right documentation ?

> * DS90Ux940 MIPI CSI-2 -- non-trivial one, but we have it ready, I just
>   don't want to add it to the pile at the moment, otherwise we'll continue
>   discussing cameras, and I'd like to postpone it :)

I think it plays a crucial role in the architecture design. I don't want to 
reach an agreement on an architecture that wouldn't include CSI-2 support and 
then find out that it was the wrong path to add CSI-2 support.

> No more than that is needed to get absolutely complete support of 5 claimed
> DS90UB9xx ICs, really. 5 other DS90UH9xx will require HDCP support in
> addition.

I'm not too concern by HDCP, as long as you have a DRM bridge driver, it 
shouldn't be a big issue.

> I'll try to roll out an example of DTS snippet soon.

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-13 15:10                 ` Vladimir Zapolskiy
@ 2018-10-16 13:12                   ` Laurent Pinchart
  2018-10-16 18:32                     ` Vladimir Zapolskiy
  0 siblings, 1 reply; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-16 13:12 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: kieran.bingham, Lee Jones, Vladimir Zapolskiy, Linus Walleij,
	Rob Herring, Marek Vasut, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

Hi Vladimir,

On Saturday, 13 October 2018 18:10:25 EEST Vladimir Zapolskiy wrote:
> On 10/12/2018 04:01 PM, Laurent Pinchart wrote:
> > On Friday, 12 October 2018 14:47:52 EEST Kieran Bingham wrote:
> >> On 12/10/18 11:58, Vladimir Zapolskiy wrote:
> [snip]
> 
> >> Essentially they are multi purpose buses - which do not yet have a home.
> >> We have used media as a home because of our use case.
> >> 
> >> The use case whether they transfer frames from a camera or to a display
> >> are of course closely related, but ultimately covered by two separate
> >> subsystems at the pixel level (DRM vs V4L, or other for other data)
> >> 
> >> Perhaps as they are buses - on a level with USB or I2C (except they can
> >> of course carry I2C or Serial as well as 'bi-directional video' etc ),
> >> they are looking for their own subsystem.
> >> 
> >> Except I don't think we don't want to add a new subsystem for just one
> >> (or two) devices...
> > 
> > I'm not sure a new subsystem is needed. As you've noted there's an overlap
> > between drivers/media/ and drivers/gpu/drm/ in terms of supported
> > hardware. We even have a devices supported by two drivers, one in drivers/
> > media/ and one in drivers/gpu/drm/ (I'm thinking about the adv7511 in
> > particular). This is a well known issue, and so far nothing has been done
> > in mainline to try and solve it.
> 
> I agree that there's an overlap between drivers/media/ and drivers/gpu/drm/,
> formally a hypothetical (sic!) DS90Ux9xx video bridge cell driver should be
> added into both subsystems also, and the actual driver of two should be
> selected in runtime. I call such a driver 'hypothetical', because in fact I
> don't have it, and I'm not so sure that its existence is justified, but
> that's only because DS90Ux9xx video bridge functionality is _transparent_,
> it does not have any controls literally, but it is a pure luck eventually.

I don't think that's entirely correct, there's at least the video bus width 
(18-bit/24-bit) that needs to be selected. You currently do so through a 
pinctrl property, but that's not right.

> So, as I've stated in my cover letter, I can misuse yours 'lvds-encoder'
> driver only for the purpose of establishing a mediated link between
> an LVDS controller and a panel over a serializer-deserializer pair.
> 
> > Trying to find another home in drivers/mfd/ to escape from the problem
> > isn't a good solution in my opinion. The best option from a Linux point
> > of view would be to unify V4L2 and DRM/KMS when it comes to bridge
> > support, but that's a long way down the road (I won't complain if you
> > want to give it a go though> 
> > :-)).
> 
> I return you a wider smile :)
> 
> > As your use cases are display, focused, I would propose to start with
> > drivers/gpu/drm/bridge/, and leave the problem of camera support for first
> > person who will have such a use case.
> 
> Frankly speaking I would like to start from copy-pasting your 'lvds-encoder'
> driver into an 'absolutely-transparent-video-bridge' driver with no LVDS or
> 'encoder' specifics, adding just a new compatible may suffice, if the
> driver is renamed/redefined.
> 
> PS, I remember I owe you a reference OF snippet of data path to a panel.

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver
  2018-10-12 14:36         ` Vladimir Zapolskiy
@ 2018-10-16 14:06           ` Laurent Pinchart
  0 siblings, 0 replies; 62+ messages in thread
From: Laurent Pinchart @ 2018-10-16 14:06 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Vladimir,

On Friday, 12 October 2018 17:36:39 EEST Vladimir Zapolskiy wrote:
> On 10/12/2018 04:12 PM, Laurent Pinchart wrote:
> > On Friday, 12 October 2018 10:32:32 EEST Vladimir Zapolskiy wrote:
> >> On 10/12/2018 09:04 AM, Lee Jones wrote:
> >>> On Tue, 09 Oct 2018, Vladimir Zapolskiy wrote:
> >>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>> 
> >>>> The change adds TI DS90Ux9xx I2C bridge/alias subdevice driver and
> >>>> FPD Link connection handling mechanism.
> >>>> 
> >>>> Access to I2C devices connected to a remote de-/serializer is done in
> >>>> a transparent way, on established link detection event such devices
> >>>> are registered on an I2C bus, which serves a local de-/serializer IC.
> >>>> 
> >>>> The development of the driver was a collaborative work, the
> >>>> contribution done by Balasubramani Vivekanandan includes:
> >>>> * original simplistic implementation of the driver,
> >>>> * support of implicitly specified devices in device tree,
> >>>> * support of multiple FPD links for TI DS90Ux9xx,
> >>>> * other kind of valuable review comments, clean-ups and fixes.
> >>>> 
> >>>> Also Steve Longerbeam made the following changes:
> >>>> * clear address maps after linked device removal,
> >>>> * disable pass-through in disconnection,
> >>>> * qualify locked status with non-zero remote address.
> >>>> 
> >>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> >>>> ---
> >>>> 
> >>>>  drivers/mfd/Kconfig                |   8 +
> >>>>  drivers/mfd/Makefile               |   1 +
> >>>>  drivers/mfd/ds90ux9xx-i2c-bridge.c | 764 +++++++++++++++++++++++++++++
> >>>>  3 files changed, 773 insertions(+)
> >>>>  create mode 100644 drivers/mfd/ds90ux9xx-i2c-bridge.c
> >>> 
> >>> Shouldn't this live in drivers/i2c?
> >> 
> >> no, the driver is not for an I2C controller of any kind, and the driver
> >> does not register itself in the I2C subsystem by calling
> >> i2c_add_adapter() or i2c_add_numbered_adapter() or i2c_mux_add_adapter()
> >> etc, this topic was discussed with Wolfram also.
> > 
> > (Who is now on CC)
> 
> Wolfram has copies of the drivers and discussion right from the beginning,
> hopefully he won't get two copies ;)
> 
> >> Formally the driver converts the managed IC into a multi-address I2C
> >> slave device, I understand that it does not sound like a well suited
> >> driver for MFD, but ds90ux9xx-core.c and ds90ux9xx-i2c-bridge.c drivers
> >> are quite tightly coupled.
> > 
> > As mentioned in other e-mails in this thread I don't think this should be
> > split out to a separate driver,> I would move the functionality to the
> > ds90ux9xx driver.
> 
> The proposal may have the grounds, but the I2C bridging functionality of ICs
> is quite detached from all other ones, thus it found its place in the cell
> driver per se.
> 
> > You may want to register an I2C mux, but as you have a single port, that
> > could be overkill. I haven't studied in details how to best support this
> > chip using the existing I2C subsystems APIs (which we may want to extend
> > if it needed), but I believe that (in your use cases) the deserializer
> > should be a child of the serializer, and modeled as an I2C device.
> 
> Formally in OF terms to define a link between devices by a phandle should
> be sufficient, panels are not the children of LVDS controllers under OF
> graph constraints in DT representation, the panels become secondary in
> runtime only, I'd like to reuse the concept. Also it adds a better sense of
> symmetry of deserializer <-> serializer connections relatively to a
> SoC/data source.

As I explained, DT models control buses through parent/child relationships. 
That's why I2C slaves are children of their I2C master. OF graph adds a second 
topology to describe data connections, which are orthogonal to the control bus 
relationship. In your case the device at the remote side of the link is 
controlled over the link, and that control flow goes from the SoC to the 
device on the local side of the link. That's why the remote device should be a 
child of the local device.

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-16 13:12                   ` Laurent Pinchart
@ 2018-10-16 18:32                     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-16 18:32 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Vladimir Zapolskiy, kieran.bingham, Lee Jones, Linus Walleij,
	Rob Herring, Marek Vasut, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

Hi Laurent,

On 10/16/2018 04:12 PM, Laurent Pinchart wrote:
> Hi Vladimir,
> 
> On Saturday, 13 October 2018 18:10:25 EEST Vladimir Zapolskiy wrote:
>> On 10/12/2018 04:01 PM, Laurent Pinchart wrote:
>>> On Friday, 12 October 2018 14:47:52 EEST Kieran Bingham wrote:
>>>> On 12/10/18 11:58, Vladimir Zapolskiy wrote:
>> [snip]
>>
>>>> Essentially they are multi purpose buses - which do not yet have a home.
>>>> We have used media as a home because of our use case.
>>>>
>>>> The use case whether they transfer frames from a camera or to a display
>>>> are of course closely related, but ultimately covered by two separate
>>>> subsystems at the pixel level (DRM vs V4L, or other for other data)
>>>>
>>>> Perhaps as they are buses - on a level with USB or I2C (except they can
>>>> of course carry I2C or Serial as well as 'bi-directional video' etc ),
>>>> they are looking for their own subsystem.
>>>>
>>>> Except I don't think we don't want to add a new subsystem for just one
>>>> (or two) devices...
>>>
>>> I'm not sure a new subsystem is needed. As you've noted there's an overlap
>>> between drivers/media/ and drivers/gpu/drm/ in terms of supported
>>> hardware. We even have a devices supported by two drivers, one in drivers/
>>> media/ and one in drivers/gpu/drm/ (I'm thinking about the adv7511 in
>>> particular). This is a well known issue, and so far nothing has been done
>>> in mainline to try and solve it.
>>
>> I agree that there's an overlap between drivers/media/ and drivers/gpu/drm/,
>> formally a hypothetical (sic!) DS90Ux9xx video bridge cell driver should be
>> added into both subsystems also, and the actual driver of two should be
>> selected in runtime. I call such a driver 'hypothetical', because in fact I
>> don't have it, and I'm not so sure that its existence is justified, but
>> that's only because DS90Ux9xx video bridge functionality is _transparent_,
>> it does not have any controls literally, but it is a pure luck eventually.
> 
> I don't think that's entirely correct, there's at least the video bus width 
> (18-bit/24-bit) that needs to be selected. You currently do so through a 
> pinctrl property, but that's not right.

if you deal with a complex IC/IP which supports parallel video output routed
over multiplexed pins, you have to specify a pinmux configuration, it is
unavoidable (for reference see arch/arm/boot/dts/imx6qdl-sabrelite.dtsi and
&pinctrl_j15 pin group, why does pinctrl setting exist?), so the property
will remain as a pinmux/pinctrl property in one or another form independently
on a probable video bus width selection of a DS90Ux9xx video bridge cell.

In this particular case the pinmux/pinctrl driver shall be aware of
'ti,video-depth-18bit' property of 'parallel' pin function to resolve pin
resource conflicts with GPIO and audio bridging functions of IC, this is
a clear hardware pinmux (or pinctrl of "parallel" function) property.

Please don't neglect the complexity and necessity of pinmuxing and other
IC functions, if all provided functions of DS90Ux9xx ICs are put aside and
just video bridging is left, only then you justify the device as a media
device, but the IC and its configuration is simply more complex than
you describe it. And, as I've said before, the video bridging function is
extremely trivial and it has no real controls, but other functions have.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  2018-10-10  8:45   ` Linus Walleij
@ 2018-10-17 15:02     ` Rob Herring
  0 siblings, 0 replies; 62+ messages in thread
From: Rob Herring @ 2018-10-17 15:02 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Vladimir Zapolskiy, Lee Jones, Mark Vasut, Laurent Pinchart,
	Wolfram Sang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:GPIO SUBSYSTEM, linux-media, linux-kernel,
	Vladimir Zapolskiy

On Wed, Oct 10, 2018 at 10:45:43AM +0200, Linus Walleij wrote:
> Hi Vladimir,
> 
> thanks for your patch!
> 
> Can we change the subject to something like "add DT bindings" rather than
> "add description" as it is more specific and makes it easier for me as
> maintainer.

To add to the nitpicking, The subject already says DT and bindings, so 
no need to repeat it. I'd just drop "description of" if anything.

Rob

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-12 13:59                 ` Vladimir Zapolskiy
  2018-10-16 13:08                   ` Laurent Pinchart
@ 2018-10-23  8:16                   ` Vladimir Zapolskiy
  2018-10-30 16:44                     ` Luca Ceresoli
  1 sibling, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-23  8:16 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Vladimir Zapolskiy, kieran.bingham, Lee Jones, Linus Walleij,
	Rob Herring, Marek Vasut, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

Hi Laurent,

On 10/12/2018 02:59 PM, Vladimir Zapolskiy wrote:
> Hello Laurent.
> 
> On 10/12/2018 04:01 PM, Laurent Pinchart wrote:
>> Hello Vladimir,
>>

...

>> then move to the driver side. In that area I would like to have a full example 
>> of a system using these chips, as the "initial support" is too limited for a 
>> proper review. This won't come as a surprise, but I will expect the OF graph 
>> bindings to be used to model data connections.
>>
> 
> The leverage of "the initial support" to "the complete support" requires:
> * audio bridge cell driver -- trivial, just one mute/unmute control,
> * interrupt controller cell driver -- trivial, but for sake of perfection
>   it requires some minimal changes in drivers/base/regmap/regmap-irq.c
> * DS90Ux940 MIPI CSI-2 -- non-trivial one, but we have it ready, I just
>   don't want to add it to the pile at the moment, otherwise we'll continue
>   discussing cameras, and I'd like to postpone it :)
> 
> No more than that is needed to get absolutely complete support of 5 claimed
> DS90UB9xx ICs, really. 5 other DS90UH9xx will require HDCP support in addition.
> 
> I'll try to roll out an example of DTS snippet soon.

Below I share an example of the serializer and deserializer equipped boards
described in DT.

The example naturally describes *two* simplistic boards in device tree
representation -- main board with an application SoC (ordinary i.MX6*)
and panel display module board. For demonstation I select a simple
FPD-Link III connection between two boards, note that significantly
more advanced configurations are also supported by the published
drivers, for example deliberately I skip audio bridging functionality.

The main board features:
* TI DS90UB927Q serializer (LVDS input) at 0xc, connected to SoC over I2C2,
  SoC GPIO5[10] signal is connected to the IC PDB pin,
* a status LED connected to DS90UB927Q GPIO2, it shall turn on,
  if FPD-Link III connection is established,
* TI DS90UB928Q GPIO0 line signal is pulled-up,
* TI DS90UB927Q GPIO3 line serves as generic GPIO, it is supposed to be
  controlled from userspace,
* TI DS90UB927Q INTB line is connected to SoC GPIO5[4], the line serves
  as an interrupt line routed from a touchscreen controller on a panel
  display module.

The panel display module board features:
* TI DS90UB928Q deserializer (LVDS output), *mapped* to have 0x3b address,
* AUO C070EAT01 panel,
* I2C EEPROM at 0x50, *mapped* to have 0x52 address on SoC I2C bus,
* Atmel MaxTouch touchscreen controller at 0x4b, *mapped* to have 0x60
  address on SoC I2C bus, power-up control signal is connected to DS90UB928Q GPIO4,
* a status LED connected to DS90UB928Q GPIO0, its on/off status shall
  repeat a user-defined status of DS90UB927Q GPIO0 on the main board,
* TI DS90UB928Q GPIO1 controls panel backlight, bridges DS90UB927Q
  GPIO1 signal level, which in turn is connected to a SoC controlled GPIO,
* TI DS90UB928Q GPIO2 line signal is pulled-up,
* TI DS90UB928Q GPIO3 line serves as generic GPIOs, it is supposed to be
  controlled from userspace.

All OF hard-coded controls like pinmuxing, I2C bridging of a remote
deserializer and I2C devices behind it, GPIO line state setting and so
forth must be applied with no interaction from a user -- and it just
works with the current / published versions of the drivers, in other
words a panel display module as a whole is truly hot-pluggable over
FPD-Link III connection.

The example is quite close to ones found in reality, if we put aside
production main boards from the real world, *the panel display modules*
or sensor modules (in case of a reverted serializer to deserializer link
connection to SoC) are even more complex, they host FPGAs, all kinds of
sensors, RF tuners, audio sources and sinks, and loads of other
incredible and fascinating stuff.

The published drivers allow to support very intricate and fine grained
control of "remote" PCBs, and reducing the complexity to "just a media
device" level could be done only if various IC functions are excluded
from the consideration. Here my purpose is to demonstrate that
* pinmux and GPIO controller functions are crucial and non-replaceable,
* I2C bridge function modeled as another cell device actually does not
  fit into the existing I2C host/mux device driver models, and it is
  a completely new abstraction with custom device tree properties,
* video bridge is absolutely transparent, thus trivial, and is modeled
  as another cell device, if needed it would be possible to write a
  DRM driver at no cost,
* reusing OF graph model fits naturally, bus vs. link discussion can
  be started separately, note that LVDS (a.k.a FPD-Link) is formally
  an electric bus, so please define the difference,
* to sum up I see no real objections to the given model of IC series
  support in Linux as an MFD parent device driver, plus pinmux/GPIO
  controller cell device driver, plus other needed cell device drivers.

For video bridging I fabricated a "video-bridge" device driver, it can
be substituted by your "lvds-encoder" driver, here I just need a simple
transparent video bridge driver with NO media controls, its only purpose
is to establish OF graph links, also note that on "remote" side a
video bridge cell node can be omitted (but it may ).

The example is NOT build tested and it may contain errors of secondary
importance, but it tends to repeat the real usage and description of
TI DS90Ux9xx equipped boards.

======== The panel display module board device tree description ========

/ {
	display-module {
		panel {
			compatible = "auo,c070eat01", "panel-lvds";
			pinctrl-names = "default";
			pinctrl-0 = <&panel_pins>;

			width-mm = <153>;
			height-mm = <90>;

			data-mapping = "jeida-24";

			panel-timing {
				clock-frequency = <71000000>;
				hactive = <1280>;
				vactive = <800>;
				hsync-len = <70>;
				hfront-porch = <20>;
				hback-porch = <70>;
				vsync-len = <5>;
				vfront-porch = <3>;
				vback-porch = <15>;
			};

			port {
				panel_input: endpoint {
					remote-endpoint = <&ds90ub928_output>;
				};
			};
		};

		deserializer: deserializer {
			compatible = "ti,ds90ub928q", "ti,ds90ux9xx";

			i2c-bridge {
				compatible = "ti,ds90ux9xx-i2c-bridge";
				#address-cells = <1>;
				#size-cells = <0>;

				touchscreen@4b {
					compatible = "atmel,maxtouch";
					reg = <0x4b>;
					pinctrl-names = "default";
					pinctrl-0 = <&touchscreen_pins>;
					interrupt-parent = <&ds90ub927_intc>;
					interrupts = <0>;
					atmel,mtu = <200>;
				};

				eeprom@50 {
					compatible = "microchip,24lc128";
					reg = <0x50>;
					pagesize = <64>;
				};
			};

			ds90ub928_pctrl: pin-controller {
				compatible = "ti,ds90ub928q-pinctrl", "ti,ds90ux9xx-pinctrl";
				gpio-controller;
				#gpio-cells = <2>;
				gpio-ranges = <&ds90ub928_pctrl 0 0 8>;

				pinctrl-names = "default";
				pinctrl-0 = <&led_pins>;

				led_pins: pinmux {
					gpio-remote {
						pins = "gpio0";
						function = "gpio-remote";
					};
				};

				panel_pins: panel-pwm {
					gpio-remote {
						pins = "gpio1";
						function = "gpio-remote";
					};
				};

				touchscreen_pins: touchscreen-power-up {
					gpio-hog;
					gpios = <4 GPIO_ACTIVE_HIGH>;
					output-high;
				};
			};

			/*
			 * For simplicity video-bridge can be simply removed here
			 * by "connecting" ds90ub927_fpd to &panel_input directly.
			 */
			video-bridge {
				compatible = "ti,ds90ux9xx-video-bridge", "video-bridge";

				ports {
					#address-cells = <1>;
					#size-cells = <0>;

					port@0 {
						reg = <0>;
						ds90ub928_fpd: endpoint {
							remote-endpoint = <&ds90ub927_fpd>;
						};
					};

					port@1 {
						reg = <1>;
						ds90ub928_output: endpoint {
							remote-endpoint = <&panel_input>;
						};
					};
				};
			};
		};
	};
};

======== The main board device tree description ========

/ {
	/* iMX6 series SoC for demonstration purpose */

	&ldb {
		status = "okay";

		lvds-channel@1 {
			status = "okay";
			fsl,data-mapping = "jeida";
			fsl,data-width = <24>;

			port@4 {
				reg = <4>;

				lvds1_out: endpoint {
					remote-endpoint = <&ds90ub927_lvds>;
				};
			};
		};
	};

	&i2c2 {
		status = "okay";
		clock-frequency = <400000>;

		serializer: serializer@c {
			compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
			reg = <0xc>;
			power-gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>;
			ti,backward-compatible-mode = <0>;
			ti,low-frequency-mode = <0>;

			i2c-bridge {
				compatible = "ti,ds90ux9xx-i2c-bridge";
				ti,i2c-bridges = <&deserializer 0 0x3b>;
				ti,i2c-bridge-maps = <0 0x4b 0x60>, <0 0x50 0x52>;
			};

			ds90ub927_intc: interrupt-controller {
				compatible = "ti,ds90ub927-intc";
				interrupt-parent = <&gpio5>;
				interrupts = <4 IRQ_TYPE_EDGE_RISING>;
				interrupt-controller;
				#interrupt-cells = <1>;
			};

			ds90ub927_pctrl: pin-controller {
				compatible = "ti,ds90ub927b-pinctrl", "ti,ds90ux9xx-pinctrl";
				gpio-controller;
				#gpio-cells = <2>;
				gpio-ranges = <&ds90ub927_pctrl 0 0 8>;

				/* Wired to some SoC controlled GPIO */
				pwm-backlight {
					gpio-hog;
					gpios = <1 GPIO_ACTIVE_HIGH>;
					input;
				};

				led_pins: pinmux {
					gpio-remote {
						pins = "gpio2";
						function = "gpio-remote";
					};
				};
			};

			video-bridge {
				compatible = "ti,ds90ux9xx-video-bridge", "video-bridge";

				ports {
					#address-cells = <1>;
					#size-cells = <0>;

					port@0 {
						reg = <0>;
						ds90ub927_lvds: endpoint {
							remote-endpoint = <&lvds1_out>;
						};
					};

					port@1 {
						reg = <1>;
						ds90ub927_fpd: endpoint {
							remote-endpoint = <&ds90ub928_fpd>;
						};
					};
				};
			};
		};
	};
};

==== end of example =====

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-08 21:11 ` [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description " Vladimir Zapolskiy
                     ` (2 preceding siblings ...)
  2018-10-12 11:44   ` Laurent Pinchart
@ 2018-10-30 16:43   ` Luca Ceresoli
  2018-10-30 23:40     ` Vladimir Zapolskiy
  3 siblings, 1 reply; 62+ messages in thread
From: Luca Ceresoli @ 2018-10-30 16:43 UTC (permalink / raw)
  To: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel, Sandeep Jain,
	Vladimir Zapolskiy

Hi Vladimir,

On 08/10/18 23:11, Vladimir Zapolskiy wrote:
> From: Sandeep Jain <Sandeep_Jain@mentor.com>
> 
> The change adds device tree binding description of TI DS90Ux9xx
> series of serializer and deserializer controllers which support video,
> audio and control data transmission over FPD-III Link connection.
[...]
> +Example:
> +
> +serializer: serializer@c {
> +	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
> +	reg = <0xc>;
> +	power-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
> +	ti,backward-compatible-mode = <0>;
> +	ti,low-frequency-mode = <0>;
> +	ti,pixel-clock-edge = <0>;
> +	...
> +}
> +
> +deserializer: deserializer@3c {
> +	compatible = "ti,ds90ub940q", "ti,ds90ux9xx";
> +	reg = <0x3c>;
> +	power-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
> +	...
> +}

Interesting patchset, thanks. At the moment I'm working on a driver for
the TI FPD-III camera serdes chips [0]. At very first sight they have
many commonalities with the display chipsets [1] you implemented. Did
you have a look into them? Do you think they could be implemented by the
same driver?

The camera serdes chips lack some features found on the display chips
(e.g. audio, white balance). OTOH they have dual or quad input
deserializers, which adds complexity.

I'm commenting on the details in reply to the following patches
documenting the DT bindings.

[0] http://www.ti.com/interface/fpd-link-serdes/camera-serdes/overview.html
[1] http://www.ti.com/interface/fpd-link-serdes/display-serdes/overview.html

Bye,
-- 
Luca

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge
  2018-10-08 21:12 ` [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge Vladimir Zapolskiy
  2018-10-12 11:54   ` Laurent Pinchart
@ 2018-10-30 16:43   ` Luca Ceresoli
  2018-10-31 20:12     ` Vladimir Zapolskiy
  1 sibling, 1 reply; 62+ messages in thread
From: Luca Ceresoli @ 2018-10-30 16:43 UTC (permalink / raw)
  To: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring
  Cc: Marek Vasut, Laurent Pinchart, Wolfram Sang, devicetree,
	linux-gpio, linux-media, linux-kernel, Vladimir Zapolskiy

Hi Vladimir,

On 08/10/18 23:12, Vladimir Zapolskiy wrote:
> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> 
> TI DS90Ux9xx de-/serializers are capable to route I2C messages to
> I2C slave devices connected to a remote de-/serializer in a pair,
> the change adds description of device tree bindings of the subcontroller
> to configure and enable this functionality.
> 
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> ---
>  .../bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt  | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
> new file mode 100644
> index 000000000000..4169e382073a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
> @@ -0,0 +1,61 @@
> +TI DS90Ux9xx de-/serializer I2C bridge subcontroller
> +
> +Required properties:
> +- compatible: Must contain a generic "ti,ds90ux9xx-i2c-bridge" value and
> +	may contain one more specific value from the list:
> +	"ti,ds90ux925-i2c-bridge",
> +	"ti,ds90ux926-i2c-bridge",
> +	"ti,ds90ux927-i2c-bridge",
> +	"ti,ds90ux928-i2c-bridge",
> +	"ti,ds90ux940-i2c-bridge".
> +
> +Required properties of a de-/serializer device connected to a local I2C bus:
> +- ti,i2c-bridges: List of phandles to remote de-/serializer devices with
> +	two arguments: id of a local de-/serializer FPD link and an assigned
> +	I2C address of a remote de-/serializer to be accessed on a local
> +	I2C bus.
> +
> +Optional properties of a de-/serializer device connected to a local I2C bus:
> +- ti,i2c-bridge-maps: List of 3-cell values:
> +	- the first argument is id of a local de-/serializer FPD link,
> +	- the second argument is an I2C address of a device connected to
> +	  a remote de-/serializer IC,
> +	- the third argument is an I2C address of the remote I2C device
> +	  for access on a local I2C bus.

BTW I usually use names "remove slave" address and "alias" for bullets 2
and 3. These are the names from the datasheets, and are clearer IMO.

Now to the big stuff.

I find a static map in the "local" chip DT node is a limit. You might
have to support multiple models of remote device, where you'll know the
model only when after it gets connected. Think Beaglebone capes, but
over FPD-Link 3. This scenario opens several issues, but specifically
for I2C address mapping I addressed it by adding in the "local" chip's
DT node a pool of I2C aliases it can use. The DT author is responsible
to pick addresses that are not used on the same I2C bus, which cannot be
done at runtime reliably.

Here's my current draft on a dual/quad port deserializer:

&i2c0 {
    serializer@3d {
        reg = <0x3d>;
        ...

        /* Guaranteed not physically present on i2c0 */
        i2c-alias-pool = /bits/ 8 <0x20 0x21 0x22 0x23 0x24 0x25>;

        rxports {
            #address-cells = <1>;
            #size-cells = <0>;

            rxport@0 {
                reg = <0>;
                remote-i2c-bus { /* The proxied I2C bus on rxport 0 */
                    #address-cells = <1>;
                    #size-cells = <0>;

                    eeprom@51 {
                        reg = <0x51>;
                        compatible = "at,24c02";
                    };
                };

            rxport@1 {
                reg = <1>;
                remote-i2c-bus { /* The proxied I2C bus on rxport 1 */
                    #address-cells = <1>;
                    #size-cells = <0>;

                    eeprom@51 {
                        reg = <0x51>;
                        compatible = "at,24c02";
                    };
                };
            };
        };
    };
};

At probe time the serializer driver instantiates one new i2c_adapter for
each rxport. Any remote device is added (removed) to that adapter, then
the driver finds an available alias and maps (unmaps) it. The
transactions are handled in a way similar to i2c-mux, i.e. the ds90*
i2c_adapter has a master_xfer callback that changes the remote slave
address to the corresponding alias, then calls parent->algo->master_xfer().

Note how both eeproms in the example have the same physical address.
They will be given two different aliases.

> +- ti,i2c-bridge-auto-ack: Enables AUTO ACK mode.

It this useful other than for debugging? And, as Laurent noted, this
should not be in DT: it doesn't describe the hardware.

> +- ti,i2c-bridge-pass-all: Enables PASS ALL mode, remote I2C slave devices
> +	are accessible on a local (host) I2C bus without I2C address
> +	remappings.

It should be clear from the DT docs that either ti,i2c-bridge-pass-all
is enabled or the alias map/pool is used, but not both.

Bye,
-- 
Luca

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  2018-10-16 12:48       ` Laurent Pinchart
@ 2018-10-30 16:44         ` Luca Ceresoli
  2018-10-31 20:31           ` Vladimir Zapolskiy
  0 siblings, 1 reply; 62+ messages in thread
From: Luca Ceresoli @ 2018-10-30 16:44 UTC (permalink / raw)
  To: Laurent Pinchart, Vladimir Zapolskiy
  Cc: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Vladimir,

On 16/10/18 14:48, Laurent Pinchart wrote:
> Hi Vladimir,
> 
> On Saturday, 13 October 2018 16:47:48 EEST Vladimir Zapolskiy wrote:
>> On 10/12/2018 03:01 PM, Laurent Pinchart wrote:
>>> On Tuesday, 9 October 2018 00:12:01 EEST Vladimir Zapolskiy wrote:
>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>
>>>> TI DS90Ux9xx de-/serializers have a capability to multiplex pin
>>>> functions, in particular a pin may have selectable functions of GPIO,
>>>> GPIO line transmitter, one of I2S lines, one of RGB24 video signal lines
>>>> and so on.
>>>>
>>>> The change adds a description of DS90Ux9xx pin multiplexers and GPIO
>>>> controllers.
>>>>
>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
[...]
>>>> +Available pins, groups and functions (reference to device datasheets):
>>>> +
>>>> +function: "gpio" ("gpio4" is on DS90Ux925 and DS90Ux926 only,
>>>> +		  "gpio9" is on DS90Ux940 only)
>>>> + - pins: "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6",
>>>> +	 "gpio7", "gpio8", "gpio9"
>>>> +
>>>> +function: "gpio-remote"
>>>> + - pins: "gpio0", "gpio1", "gpio2", "gpio3"
>>>> +
>>>> +function: "pass" (DS90Ux940 specific only)
>>>> + - pins: "gpio0", "gpio3"
>>>
>>> What do those functions mean ?
>>
>> "gpio" function should be already familiar to you.
> 
> I assume this function is only available for the local device, not the remote 
> one ?
> 
>> "gpio-remote" function is the pin function for a GPIO line bridging.
>>
>> "pass" function sets a pin to a status pin function for detecting
>> display timing issues, namely DE or Vsync length value mismatch.
> 
> All this is not clear at all from the proposed DT bindings, it should be 
> properly documented.

It's not clear to me as well. The "gpio-remote" can mean two different
things (at least in the camera serdes TI chips):

 - a GPIO input on the the *local* chip, replicated as an output on the
   *remote* chip
 - a GPIO input on the the *remote* chip, replicated as an output on the
   *local* chip

How to you differentiate them in DT?

The "pass" function is also not clear. A comprehensive example would
help a lot.

Bye,
-- 
Luca

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver
  2018-10-23  8:16                   ` Vladimir Zapolskiy
@ 2018-10-30 16:44                     ` Luca Ceresoli
  0 siblings, 0 replies; 62+ messages in thread
From: Luca Ceresoli @ 2018-10-30 16:44 UTC (permalink / raw)
  To: Vladimir Zapolskiy, Laurent Pinchart
  Cc: Vladimir Zapolskiy, kieran.bingham, Lee Jones, Linus Walleij,
	Rob Herring, Marek Vasut, Wolfram Sang, devicetree, linux-gpio,
	linux-media, linux-kernel

Hi Vladimir,

On 23/10/18 10:16, Vladimir Zapolskiy wrote:
> Hi Laurent,
> 
> On 10/12/2018 02:59 PM, Vladimir Zapolskiy wrote:
>> Hello Laurent.
>>
>> On 10/12/2018 04:01 PM, Laurent Pinchart wrote:
>>> Hello Vladimir,
>>>
> 
> ...
> 
>>> then move to the driver side. In that area I would like to have a full example 
>>> of a system using these chips, as the "initial support" is too limited for a 
>>> proper review. This won't come as a surprise, but I will expect the OF graph 
>>> bindings to be used to model data connections.
>>>
>>
>> The leverage of "the initial support" to "the complete support" requires:
>> * audio bridge cell driver -- trivial, just one mute/unmute control,
>> * interrupt controller cell driver -- trivial, but for sake of perfection
>>   it requires some minimal changes in drivers/base/regmap/regmap-irq.c
>> * DS90Ux940 MIPI CSI-2 -- non-trivial one, but we have it ready, I just
>>   don't want to add it to the pile at the moment, otherwise we'll continue
>>   discussing cameras, and I'd like to postpone it :)
>>
>> No more than that is needed to get absolutely complete support of 5 claimed
>> DS90UB9xx ICs, really. 5 other DS90UH9xx will require HDCP support in addition.
>>
>> I'll try to roll out an example of DTS snippet soon.
> 
> Below I share an example of the serializer and deserializer equipped boards
> described in DT.
> 
> The example naturally describes *two* simplistic boards in device tree
> representation -- main board with an application SoC (ordinary i.MX6*)
> and panel display module board. For demonstation I select a simple
> FPD-Link III connection between two boards, note that significantly
> more advanced configurations are also supported by the published
> drivers, for example deliberately I skip audio bridging functionality.

Thanks for the comprehensive example, it helps a lot in understanding
your proposal.

> The main board features:
> * TI DS90UB927Q serializer (LVDS input) at 0xc, connected to SoC over I2C2,
>   SoC GPIO5[10] signal is connected to the IC PDB pin,
> * a status LED connected to DS90UB927Q GPIO2, it shall turn on,
>   if FPD-Link III connection is established,
> * TI DS90UB928Q GPIO0 line signal is pulled-up,
> * TI DS90UB927Q GPIO3 line serves as generic GPIO, it is supposed to be
>   controlled from userspace,
> * TI DS90UB927Q INTB line is connected to SoC GPIO5[4], the line serves
>   as an interrupt line routed from a touchscreen controller on a panel
>   display module.
> 
> The panel display module board features:
> * TI DS90UB928Q deserializer (LVDS output), *mapped* to have 0x3b address,
> * AUO C070EAT01 panel,
> * I2C EEPROM at 0x50, *mapped* to have 0x52 address on SoC I2C bus,
> * Atmel MaxTouch touchscreen controller at 0x4b, *mapped* to have 0x60
>   address on SoC I2C bus, power-up control signal is connected to DS90UB928Q GPIO4,
> * a status LED connected to DS90UB928Q GPIO0, its on/off status shall
>   repeat a user-defined status of DS90UB927Q GPIO0 on the main board,
> * TI DS90UB928Q GPIO1 controls panel backlight, bridges DS90UB927Q
>   GPIO1 signal level, which in turn is connected to a SoC controlled GPIO,
> * TI DS90UB928Q GPIO2 line signal is pulled-up,
> * TI DS90UB928Q GPIO3 line serves as generic GPIOs, it is supposed to be
>   controlled from userspace.
> 
> All OF hard-coded controls like pinmuxing, I2C bridging of a remote
> deserializer and I2C devices behind it, GPIO line state setting and so
> forth must be applied with no interaction from a user -- and it just
> works with the current / published versions of the drivers, in other
> words a panel display module as a whole is truly hot-pluggable over
> FPD-Link III connection.
> 
> The example is quite close to ones found in reality, if we put aside
> production main boards from the real world, *the panel display modules*
> or sensor modules (in case of a reverted serializer to deserializer link
> connection to SoC) are even more complex, they host FPGAs, all kinds of
> sensors, RF tuners, audio sources and sinks, and loads of other
> incredible and fascinating stuff.
> 
> The published drivers allow to support very intricate and fine grained
> control of "remote" PCBs, and reducing the complexity to "just a media
> device" level could be done only if various IC functions are excluded
> from the consideration. Here my purpose is to demonstrate that
> * pinmux and GPIO controller functions are crucial and non-replaceable,
> * I2C bridge function modeled as another cell device actually does not
>   fit into the existing I2C host/mux device driver models, and it is
>   a completely new abstraction with custom device tree properties,
> * video bridge is absolutely transparent, thus trivial, and is modeled
>   as another cell device, if needed it would be possible to write a
>   DRM driver at no cost,
> * reusing OF graph model fits naturally, bus vs. link discussion can
>   be started separately, note that LVDS (a.k.a FPD-Link) is formally
>   an electric bus, so please define the difference,
> * to sum up I see no real objections to the given model of IC series
>   support in Linux as an MFD parent device driver, plus pinmux/GPIO
>   controller cell device driver, plus other needed cell device drivers.
> 
> For video bridging I fabricated a "video-bridge" device driver, it can
> be substituted by your "lvds-encoder" driver, here I just need a simple
> transparent video bridge driver with NO media controls, its only purpose
> is to establish OF graph links, also note that on "remote" side a
> video bridge cell node can be omitted (but it may ).
> 
> The example is NOT build tested and it may contain errors of secondary
> importance, but it tends to repeat the real usage and description of
> TI DS90Ux9xx equipped boards.
> 
> ======== The panel display module board device tree description ========
> 
> / {
> 	display-module {
> 		panel {
> 			compatible = "auo,c070eat01", "panel-lvds";
> 			pinctrl-names = "default";
> 			pinctrl-0 = <&panel_pins>;
> 
> 			width-mm = <153>;
> 			height-mm = <90>;
> 
> 			data-mapping = "jeida-24";
> 
> 			panel-timing {
> 				clock-frequency = <71000000>;
> 				hactive = <1280>;
> 				vactive = <800>;
> 				hsync-len = <70>;
> 				hfront-porch = <20>;
> 				hback-porch = <70>;
> 				vsync-len = <5>;
> 				vfront-porch = <3>;
> 				vback-porch = <15>;
> 			};
> 
> 			port {
> 				panel_input: endpoint {
> 					remote-endpoint = <&ds90ub928_output>;
> 				};
> 			};
> 		};
> 
> 		deserializer: deserializer {
> 			compatible = "ti,ds90ub928q", "ti,ds90ux9xx";
> 
> 			i2c-bridge {
> 				compatible = "ti,ds90ux9xx-i2c-bridge";
> 				#address-cells = <1>;
> 				#size-cells = <0>;
> 
> 				touchscreen@4b {
> 					compatible = "atmel,maxtouch";
> 					reg = <0x4b>;
> 					pinctrl-names = "default";
> 					pinctrl-0 = <&touchscreen_pins>;
> 					interrupt-parent = <&ds90ub927_intc>;
> 					interrupts = <0>;
> 					atmel,mtu = <200>;
> 				};
> 
> 				eeprom@50 {
> 					compatible = "microchip,24lc128";
> 					reg = <0x50>;
> 					pagesize = <64>;
> 				};
> 			};
> 
> 			ds90ub928_pctrl: pin-controller {
> 				compatible = "ti,ds90ub928q-pinctrl", "ti,ds90ux9xx-pinctrl";
> 				gpio-controller;
> 				#gpio-cells = <2>;
> 				gpio-ranges = <&ds90ub928_pctrl 0 0 8>;
> 
> 				pinctrl-names = "default";
> 				pinctrl-0 = <&led_pins>;
> 
> 				led_pins: pinmux {
> 					gpio-remote {
> 						pins = "gpio0";
> 						function = "gpio-remote";
> 					};
> 				};
> 
> 				panel_pins: panel-pwm {
> 					gpio-remote {
> 						pins = "gpio1";
> 						function = "gpio-remote";
> 					};
> 				};
> 
> 				touchscreen_pins: touchscreen-power-up {
> 					gpio-hog;
> 					gpios = <4 GPIO_ACTIVE_HIGH>;
> 					output-high;
> 				};
> 			};
> 
> 			/*
> 			 * For simplicity video-bridge can be simply removed here
> 			 * by "connecting" ds90ub927_fpd to &panel_input directly.
> 			 */
> 			video-bridge {
> 				compatible = "ti,ds90ux9xx-video-bridge", "video-bridge";
> 
> 				ports {
> 					#address-cells = <1>;
> 					#size-cells = <0>;
> 
> 					port@0 {
> 						reg = <0>;
> 						ds90ub928_fpd: endpoint {
> 							remote-endpoint = <&ds90ub927_fpd>;
> 						};
> 					};
> 
> 					port@1 {
> 						reg = <1>;
> 						ds90ub928_output: endpoint {
> 							remote-endpoint = <&panel_input>;
> 						};
> 					};
> 				};
> 			};
> 		};
> 	};
> };
> 
> ======== The main board device tree description ========
> 
> / {
> 	/* iMX6 series SoC for demonstration purpose */
> 
> 	&ldb {
> 		status = "okay";
> 
> 		lvds-channel@1 {
> 			status = "okay";
> 			fsl,data-mapping = "jeida";
> 			fsl,data-width = <24>;
> 
> 			port@4 {
> 				reg = <4>;
> 
> 				lvds1_out: endpoint {
> 					remote-endpoint = <&ds90ub927_lvds>;
> 				};
> 			};
> 		};
> 	};
> 
> 	&i2c2 {
> 		status = "okay";
> 		clock-frequency = <400000>;
> 
> 		serializer: serializer@c {
> 			compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
> 			reg = <0xc>;
> 			power-gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>;
> 			ti,backward-compatible-mode = <0>;
> 			ti,low-frequency-mode = <0>;
> 
> 			i2c-bridge {
> 				compatible = "ti,ds90ux9xx-i2c-bridge";
> 				ti,i2c-bridges = <&deserializer 0 0x3b>;

DT should describe the connections with leaf nodes pointing towards the
centre (CPU). Thus the local chip (serializer) pointing to the remote
chip (serializer) is wrong here. Among others, it forbids the
display-module tree from being a DT overlay inserted at runtime. This is
fundamental to have different remote boards, detected at runtime.

Of course runtime insertion/removal opens other issues, namely the fact
that media-ctl nodes point to each other, and a media pipeline is not
quite modifiable while streaming. But that is another issue.

> 				ti,i2c-bridge-maps = <0 0x4b 0x60>, <0 0x50 0x52>;
> 			};
> 
> 			ds90ub927_intc: interrupt-controller {
> 				compatible = "ti,ds90ub927-intc";
> 				interrupt-parent = <&gpio5>;
> 				interrupts = <4 IRQ_TYPE_EDGE_RISING>;
> 				interrupt-controller;
> 				#interrupt-cells = <1>;
> 			};
> 
> 			ds90ub927_pctrl: pin-controller {
> 				compatible = "ti,ds90ub927b-pinctrl", "ti,ds90ux9xx-pinctrl";
> 				gpio-controller;
> 				#gpio-cells = <2>;
> 				gpio-ranges = <&ds90ub927_pctrl 0 0 8>;
> 
> 				/* Wired to some SoC controlled GPIO */
> 				pwm-backlight {
> 					gpio-hog;
> 					gpios = <1 GPIO_ACTIVE_HIGH>;
> 					input;
> 				};
> 
> 				led_pins: pinmux {
> 					gpio-remote {
> 						pins = "gpio2";
> 						function = "gpio-remote";
> 					};
> 				};
> 			};
> 
> 			video-bridge {
> 				compatible = "ti,ds90ux9xx-video-bridge", "video-bridge";
> 
> 				ports {
> 					#address-cells = <1>;
> 					#size-cells = <0>;
> 
> 					port@0 {
> 						reg = <0>;
> 						ds90ub927_lvds: endpoint {
> 							remote-endpoint = <&lvds1_out>;
> 						};
> 					};
> 
> 					port@1 {
> 						reg = <1>;
> 						ds90ub927_fpd: endpoint {
> 							remote-endpoint = <&ds90ub928_fpd>;
> 						};
> 					};
> 				};
> 			};
> 		};
> 	};
> };
> 
> ==== end of example =====
> 
> --
> Best wishes,
> Vladimir
> 

-- 
Luca

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx ICs
  2018-10-30 16:43   ` Luca Ceresoli
@ 2018-10-30 23:40     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-30 23:40 UTC (permalink / raw)
  To: Luca Ceresoli, Lee Jones, Rob Herring
  Cc: Linus Walleij, Marek Vasut, Laurent Pinchart, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel, Sandeep Jain,
	Vladimir Zapolskiy

Hi Luca,

thank you for review, please find my comments below.

On 10/30/2018 06:43 PM, Luca Ceresoli wrote:
> Hi Vladimir,
> 
> On 08/10/18 23:11, Vladimir Zapolskiy wrote:
>> From: Sandeep Jain <Sandeep_Jain@mentor.com>
>>
>> The change adds device tree binding description of TI DS90Ux9xx
>> series of serializer and deserializer controllers which support video,
>> audio and control data transmission over FPD-III Link connection.
> [...]
>> +Example:
>> +
>> +serializer: serializer@c {
>> +	compatible = "ti,ds90ub927q", "ti,ds90ux9xx";
>> +	reg = <0xc>;
>> +	power-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
>> +	ti,backward-compatible-mode = <0>;
>> +	ti,low-frequency-mode = <0>;
>> +	ti,pixel-clock-edge = <0>;
>> +	...
>> +}
>> +
>> +deserializer: deserializer@3c {
>> +	compatible = "ti,ds90ub940q", "ti,ds90ux9xx";
>> +	reg = <0x3c>;
>> +	power-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
>> +	...
>> +}
> 
> Interesting patchset, thanks. At the moment I'm working on a driver for
> the TI FPD-III camera serdes chips [0]. At very first sight they have
> many commonalities with the display chipsets [1] you implemented. Did
> you have a look into them? Do you think they could be implemented by the
> same driver?

Absolutely, I believe that it should be no more than a matter of adding
the correspondent data fields to describe IC specifics to the set of the
published drivers.

In general, and from my experience, there is no big difference between
camera and display ICs from the series, my understanding is that it's
just a marketing or common usecase difference.

> 
> The camera serdes chips lack some features found on the display chips
> (e.g. audio, white balance). OTOH they have dual or quad input
> deserializers, which adds complexity.

For what it's worth the shown core drivers support DS90Ux940 (2 mutually
exclusive links, the support is already added to the series of drivers)
and DS90UB964 (4 parallel independent links) ICs, both deserializers are
used in connection to camera sensors.

So, the short answer is that multi-link ICs are also well supported,
and my intention is to push the essential core drivers firstly, then
add remarkably more trivial DRM and V4L2 drivers as cell drivers.

> I'm commenting on the details in reply to the following patches
> documenting the DT bindings.
> 

Thank you for review, I'm planning to collect more review comments and
publish v2 in about two weeks, any kind of essential rework is not
expected, the selected design of having an MFD and the drivers are
proven to be easily scalable, as usual any additional wanted features
could be added later on.

> [0] http://www.ti.com/interface/fpd-link-serdes/camera-serdes/overview.html
> [1] http://www.ti.com/interface/fpd-link-serdes/display-serdes/overview.html
> 

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge
  2018-10-30 16:43   ` Luca Ceresoli
@ 2018-10-31 20:12     ` Vladimir Zapolskiy
  2018-11-03 21:00       ` Luca Ceresoli
  0 siblings, 1 reply; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-31 20:12 UTC (permalink / raw)
  To: Luca Ceresoli, Lee Jones, Rob Herring
  Cc: Linus Walleij, Marek Vasut, Laurent Pinchart, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel,
	Vladimir Zapolskiy

Hi Luca,

thank you for review.

On 10/30/2018 06:43 PM, Luca Ceresoli wrote:
> Hi Vladimir,
> 
> On 08/10/18 23:12, Vladimir Zapolskiy wrote:
>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>
>> TI DS90Ux9xx de-/serializers are capable to route I2C messages to
>> I2C slave devices connected to a remote de-/serializer in a pair,
>> the change adds description of device tree bindings of the subcontroller
>> to configure and enable this functionality.
>>
>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>> ---
>>  .../bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt  | 61 +++++++++++++++++++
>>  1 file changed, 61 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>> new file mode 100644
>> index 000000000000..4169e382073a
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>> @@ -0,0 +1,61 @@
>> +TI DS90Ux9xx de-/serializer I2C bridge subcontroller
>> +
>> +Required properties:
>> +- compatible: Must contain a generic "ti,ds90ux9xx-i2c-bridge" value and
>> +	may contain one more specific value from the list:
>> +	"ti,ds90ux925-i2c-bridge",
>> +	"ti,ds90ux926-i2c-bridge",
>> +	"ti,ds90ux927-i2c-bridge",
>> +	"ti,ds90ux928-i2c-bridge",
>> +	"ti,ds90ux940-i2c-bridge".
>> +
>> +Required properties of a de-/serializer device connected to a local I2C bus:
>> +- ti,i2c-bridges: List of phandles to remote de-/serializer devices with
>> +	two arguments: id of a local de-/serializer FPD link and an assigned
>> +	I2C address of a remote de-/serializer to be accessed on a local
>> +	I2C bus.
>> +
>> +Optional properties of a de-/serializer device connected to a local I2C bus:
>> +- ti,i2c-bridge-maps: List of 3-cell values:
>> +	- the first argument is id of a local de-/serializer FPD link,
>> +	- the second argument is an I2C address of a device connected to
>> +	  a remote de-/serializer IC,
>> +	- the third argument is an I2C address of the remote I2C device
>> +	  for access on a local I2C bus.
> 
> BTW I usually use names "remove slave" address and "alias" for bullets 2
> and 3. These are the names from the datasheets, and are clearer IMO.
> 

Definitely you are correct, I find that verbose descriptions might be
more appropriate and self-explanatory for anyone, who is not closely familiar
with the IC series. I'll consider to add the names from the datasheets
as well.

> Now to the big stuff.
> 
> I find a static map in the "local" chip DT node is a limit. You might
> have to support multiple models of remote device, where you'll know the
> model only when after it gets connected. Think Beaglebone capes, but
> over FPD-Link 3. This scenario opens several issues, but specifically
> for I2C address mapping I addressed it by adding in the "local" chip's
> DT node a pool of I2C aliases it can use. The DT author is responsible
> to pick addresses that are not used on the same I2C bus, which cannot be
> done at runtime reliably.

Here I see several important topics raised.

1) A static map in the "local" chip DT node is not a limit in sense that
   it is optional, so it would be a working model just to omit the property,
   however it may (or may not) require another handlers to bridge remote
   I2C devices, for instance 'ti,i2c-bridge-pass-all' property, or new
   UAPI.

2) About supporting multiple models of remote PCBs in the same dts file,
   it might be an excessive complication to predict a proper description
   of an unknown in advance complex device, so, a better solution should
   be to apply DT overlays in runtime, but at any time the hardware
   description and the mapping shall be precisely defined.

3) About a pool of vacant I2C addresses, I dislike the idea that there
   will be no definite or constant I2C address in runtime for a particular
   remote slave device. As I've mentioned above, it would be better to
   utilize DT overlays to handle "multiple models of remote device"
   dynamically in runtime, adding this feature could be done on top of
   the shown code.

> Here's my current draft on a dual/quad port deserializer:
> 
> &i2c0 {
>     serializer@3d {
>         reg = <0x3d>;
>         ...
> 
>         /* Guaranteed not physically present on i2c0 */
>         i2c-alias-pool = /bits/ 8 <0x20 0x21 0x22 0x23 0x24 0x25>;
> 
>         rxports {
>             #address-cells = <1>;
>             #size-cells = <0>;
> 
>             rxport@0 {
>                 reg = <0>;
>                 remote-i2c-bus { /* The proxied I2C bus on rxport 0 */
>                     #address-cells = <1>;
>                     #size-cells = <0>;
> 
>                     eeprom@51 {
>                         reg = <0x51>;
>                         compatible = "at,24c02";
>                     };
>                 };
> 
>             rxport@1 {
>                 reg = <1>;
>                 remote-i2c-bus { /* The proxied I2C bus on rxport 1 */
>                     #address-cells = <1>;
>                     #size-cells = <0>;
> 
>                     eeprom@51 {
>                         reg = <0x51>;
>                         compatible = "at,24c02";
>                     };
>                 };
>             };
>         };
>     };
> };
> 
> At probe time the serializer driver instantiates one new i2c_adapter for
> each rxport. Any remote device is added (removed) to that adapter, then
> the driver finds an available alias and maps (unmaps) it. The

I avoid using i2c_adapter object, because then you get a confusing access
to right the same device on two logical I2C buses. This is not the way
how I2C muxes operate or are expected to operate, commonly I2C muxes contain
a protocol to access muxed devices, which are "invisible" on a host bus,
and here a local IC behaves like an I2C device with multiple addresses.

Note, that following an advice from Wolfram I'm going to send the i2c-bridge
cell driver into inclusion under drivers/i2c/muxes/ , even if the device
driver does not register a mux.

> transactions are handled in a way similar to i2c-mux, i.e. the ds90*
> i2c_adapter has a master_xfer callback that changes the remote slave
> address to the corresponding alias, then calls parent->algo->master_xfer().
> 
> Note how both eeproms in the example have the same physical address.
> They will be given two different aliases.

The question is how to determine which runtime assigned address represents
which eeprom of two. The remote/alias scheme I propose makes it transparent.

>> +- ti,i2c-bridge-auto-ack: Enables AUTO ACK mode.
> 
> It this useful other than for debugging? And, as Laurent noted, this
> should not be in DT: it doesn't describe the hardware.
> 

I'll drop it, I've just checked that it is unused in any of production dts
files, which are accessible to me.

By "hardware description" I generally mean a hardware specific handle.
If IC supports a meaningful, one time programmable non-standard 1-bit field
configuration, then using a bool property in DT sounds reasonable to me.

>> +- ti,i2c-bridge-pass-all: Enables PASS ALL mode, remote I2C slave devices
>> +	are accessible on a local (host) I2C bus without I2C address
>> +	remappings.
> 
> It should be clear from the DT docs that either ti,i2c-bridge-pass-all
> is enabled or the alias map/pool is used, but not both.
> 

Sure, I'll add this information, thank you for pointing it out.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux
  2018-10-30 16:44         ` Luca Ceresoli
@ 2018-10-31 20:31           ` Vladimir Zapolskiy
  0 siblings, 0 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-10-31 20:31 UTC (permalink / raw)
  To: Luca Ceresoli, Laurent Pinchart
  Cc: Vladimir Zapolskiy, Lee Jones, Linus Walleij, Rob Herring,
	Marek Vasut, Wolfram Sang, devicetree, linux-gpio, linux-media,
	linux-kernel

Hi Luca,

On 10/30/2018 06:44 PM, Luca Ceresoli wrote:
> Hi Vladimir,
> 
> On 16/10/18 14:48, Laurent Pinchart wrote:
>> Hi Vladimir,
>>
>> On Saturday, 13 October 2018 16:47:48 EEST Vladimir Zapolskiy wrote:
>>> On 10/12/2018 03:01 PM, Laurent Pinchart wrote:
>>>> On Tuesday, 9 October 2018 00:12:01 EEST Vladimir Zapolskiy wrote:
>>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>>
>>>>> TI DS90Ux9xx de-/serializers have a capability to multiplex pin
>>>>> functions, in particular a pin may have selectable functions of GPIO,
>>>>> GPIO line transmitter, one of I2S lines, one of RGB24 video signal lines
>>>>> and so on.
>>>>>
>>>>> The change adds a description of DS90Ux9xx pin multiplexers and GPIO
>>>>> controllers.
>>>>>
>>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
> [...]
>>>>> +Available pins, groups and functions (reference to device datasheets):
>>>>> +
>>>>> +function: "gpio" ("gpio4" is on DS90Ux925 and DS90Ux926 only,
>>>>> +		  "gpio9" is on DS90Ux940 only)
>>>>> + - pins: "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6",
>>>>> +	 "gpio7", "gpio8", "gpio9"
>>>>> +
>>>>> +function: "gpio-remote"
>>>>> + - pins: "gpio0", "gpio1", "gpio2", "gpio3"
>>>>> +
>>>>> +function: "pass" (DS90Ux940 specific only)
>>>>> + - pins: "gpio0", "gpio3"
>>>>
>>>> What do those functions mean ?
>>>
>>> "gpio" function should be already familiar to you.
>>
>> I assume this function is only available for the local device, not the remote 
>> one ?
>>
>>> "gpio-remote" function is the pin function for a GPIO line bridging.
>>>
>>> "pass" function sets a pin to a status pin function for detecting
>>> display timing issues, namely DE or Vsync length value mismatch.
>>
>> All this is not clear at all from the proposed DT bindings, it should be 
>> properly documented.
> 
> It's not clear to me as well. The "gpio-remote" can mean two different
> things (at least in the camera serdes TI chips):
> 
>  - a GPIO input on the the *local* chip, replicated as an output on the
>    *remote* chip
>  - a GPIO input on the the *remote* chip, replicated as an output on the
>    *local* chip
> 
> How to you differentiate them in DT?
> 

"gpio-remote" function is directly translated into "GPIOx Remote Enable"
bit setting, the documentation says:

1) Deserializer IC pin configuration:

	Enable GPIO control from remote Serializer. The GPIO pin will
	be an output, and the value is received from the remote Serializer.

2) Serializer IC pin configuration:

	Enable GPIO control from remote Deserializer. The GPIO pin will
	be an output, and the value is received from the remote Deserializer.

So, it is always an output signal, the line signal is "bridged" (repeated)
as a corresponding line signal on a remote IC, note that there is no
difference between serializer and deserializer ICs.

> The "pass" function is also not clear. A comprehensive example would
> help a lot.

As this devicetree documentation says, the "pass" pin function is specific
for DS90Ux940 deserializer, I would suggest to check its datasheet for
getting a comprehensive answer, but I've already copy-pasted information
from the datasheet into my previous answer to Laurent.

The reason why the "pass" pin function is listed is quite simple, the
pin function interferes other pin functions, see DS90Ux940 GPIO0 and
GPIO3 controls, I hope I've managed to describe it properly by
DS90UX940_GPIO(0, ...) and DS90UX940_GPIO(3, ...) pin descriptions in
the pinctrl driver.

--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge
  2018-10-31 20:12     ` Vladimir Zapolskiy
@ 2018-11-03 21:00       ` Luca Ceresoli
  2018-11-03 22:07         ` Vladimir Zapolskiy
  0 siblings, 1 reply; 62+ messages in thread
From: Luca Ceresoli @ 2018-11-03 21:00 UTC (permalink / raw)
  To: Vladimir Zapolskiy, Lee Jones, Rob Herring
  Cc: Linus Walleij, Marek Vasut, Laurent Pinchart, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel,
	Vladimir Zapolskiy

Hi Vladimir,

On 31/10/18 21:12, Vladimir Zapolskiy wrote:
> Hi Luca,
> 
> thank you for review.
> 
> On 10/30/2018 06:43 PM, Luca Ceresoli wrote:
>> Hi Vladimir,
>>
>> On 08/10/18 23:12, Vladimir Zapolskiy wrote:
>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>
>>> TI DS90Ux9xx de-/serializers are capable to route I2C messages to
>>> I2C slave devices connected to a remote de-/serializer in a pair,
>>> the change adds description of device tree bindings of the subcontroller
>>> to configure and enable this functionality.
>>>
>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>> ---
>>>  .../bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt  | 61 +++++++++++++++++++
>>>  1 file changed, 61 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>>> new file mode 100644
>>> index 000000000000..4169e382073a
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>>> @@ -0,0 +1,61 @@
>>> +TI DS90Ux9xx de-/serializer I2C bridge subcontroller
>>> +
>>> +Required properties:
>>> +- compatible: Must contain a generic "ti,ds90ux9xx-i2c-bridge" value and
>>> +	may contain one more specific value from the list:
>>> +	"ti,ds90ux925-i2c-bridge",
>>> +	"ti,ds90ux926-i2c-bridge",
>>> +	"ti,ds90ux927-i2c-bridge",
>>> +	"ti,ds90ux928-i2c-bridge",
>>> +	"ti,ds90ux940-i2c-bridge".
>>> +
>>> +Required properties of a de-/serializer device connected to a local I2C bus:
>>> +- ti,i2c-bridges: List of phandles to remote de-/serializer devices with
>>> +	two arguments: id of a local de-/serializer FPD link and an assigned
>>> +	I2C address of a remote de-/serializer to be accessed on a local
>>> +	I2C bus.
>>> +
>>> +Optional properties of a de-/serializer device connected to a local I2C bus:
>>> +- ti,i2c-bridge-maps: List of 3-cell values:
>>> +	- the first argument is id of a local de-/serializer FPD link,
>>> +	- the second argument is an I2C address of a device connected to
>>> +	  a remote de-/serializer IC,
>>> +	- the third argument is an I2C address of the remote I2C device
>>> +	  for access on a local I2C bus.
>>
>> BTW I usually use names "remove slave" address and "alias" for bullets 2
>> and 3. These are the names from the datasheets, and are clearer IMO.
>>
> 
> Definitely you are correct, I find that verbose descriptions might be
> more appropriate and self-explanatory for anyone, who is not closely familiar
> with the IC series. I'll consider to add the names from the datasheets
> as well.
> 
>> Now to the big stuff.
>>
>> I find a static map in the "local" chip DT node is a limit. You might
>> have to support multiple models of remote device, where you'll know the
>> model only when after it gets connected. Think Beaglebone capes, but
>> over FPD-Link 3. This scenario opens several issues, but specifically
>> for I2C address mapping I addressed it by adding in the "local" chip's
>> DT node a pool of I2C aliases it can use. The DT author is responsible
>> to pick addresses that are not used on the same I2C bus, which cannot be
>> done at runtime reliably.
> 
> Here I see several important topics raised.
> 
> 1) A static map in the "local" chip DT node is not a limit in sense that
>    it is optional, so it would be a working model just to omit the property,
>    however it may (or may not) require another handlers to bridge remote
>    I2C devices, for instance 'ti,i2c-bridge-pass-all' property, or new
>    UAPI.

Do you mean when the "pass-all" method and the "static map in the local
node" method are insufficient, then the solution is to implement a third
method that is powerful enough? If that's what you mean, then I think we
should rather [try to] implement from the beginning a method that is
powerful enough to handle all the cases we can foresee.

> 2) About supporting multiple models of remote PCBs in the same dts file,
>    it might be an excessive complication to predict a proper description
>    of an unknown in advance complex device, so, a better solution should
>    be to apply DT overlays in runtime, but at any time the hardware
>    description and the mapping shall be precisely defined.

I agree runtime DT overlays is the correct way of handling multiple
remote boards, but not if they contain a ti,i2c-bridge-maps
(physical-to-alias I2C address map).

Consider the case where we have N different main board (with SoC and
"local" [de]serializer) and M peripheral boards (display+deserializer or
sensor+serializer). Then we'd need up to N*M DT overlays, each with the
alias map for a specific <main_board, peripheral_board> pair. This is
because the map maps a physical address that exists on the remote side
(peripheral board) to an alias that exists on the local side (main board).

To realistically model the hardware, the DT overlay should contain the
removable components, including the physical address on the remote side
(e.g. touchscreen slave address), but not including the alias on the
local side (a slave address that is not used on the SoC i2c bus).

> 3) About a pool of vacant I2C addresses, I dislike the idea that there
>    will be no definite or constant I2C address in runtime for a particular
>    remote slave device.

Indeed that's a little annoyance. But you'll face it only during kernel
development and debugging, not at the userspace interface. See below the
discussion about i2c_adapter.

[...]

>> Here's my current draft on a dual/quad port deserializer:
>>
>> &i2c0 {
>>     serializer@3d {
>>         reg = <0x3d>;
>>         ...
>>
>>         /* Guaranteed not physically present on i2c0 */
>>         i2c-alias-pool = /bits/ 8 <0x20 0x21 0x22 0x23 0x24 0x25>;
>>
>>         rxports {
>>             #address-cells = <1>;
>>             #size-cells = <0>;
>>
>>             rxport@0 {
>>                 reg = <0>;
>>                 remote-i2c-bus { /* The proxied I2C bus on rxport 0 */
>>                     #address-cells = <1>;
>>                     #size-cells = <0>;
>>
>>                     eeprom@51 {
>>                         reg = <0x51>;
>>                         compatible = "at,24c02";
>>                     };
>>                 };
>>
>>             rxport@1 {
>>                 reg = <1>;
>>                 remote-i2c-bus { /* The proxied I2C bus on rxport 1 */
>>                     #address-cells = <1>;
>>                     #size-cells = <0>;
>>
>>                     eeprom@51 {
>>                         reg = <0x51>;
>>                         compatible = "at,24c02";
>>                     };
>>                 };
>>             };
>>         };
>>     };
>> };
>>
>> At probe time the serializer driver instantiates one new i2c_adapter for
>> each rxport. Any remote device is added (removed) to that adapter, then
>> the driver finds an available alias and maps (unmaps) it. The
> 
> I avoid using i2c_adapter object, because then you get a confusing access
> to right the same device on two logical I2C buses. This is not the way
> how I2C muxes operate or are expected to operate, commonly I2C muxes contain
> a protocol to access muxed devices, which are "invisible" on a host bus,
> and here a local IC behaves like an I2C device with multiple addresses.

Sorry, this whole paragraph is not quite clear to me.

Well, except "I avoid using i2c_adapter object", which is very clear and
opposite to my approach. :) I'm instantiating an i2c_adapter for each rx
port because it's the best model of the real world that I could devise.
See the picture:

                .----------------.
                |                |   i2c-5    ,-- touch@50
----.   i2c-0   |        adap0----------------+-- eeprom@51
SoC |-----------| atr@3d         |
----'           |        adap1----------------+-- eeprom@51
                |                |   i2c-6    `-- touch@50
                `----------------'

I called the central object ATR (address translator), which is the i2c
remotizer feature in the DS90Ux chipset. Topologically it is somewhat
similar to a mux, but:

 * it also translates addresses (hence the name)
 * electrically it never attaches the upstream and downstream busses,
   they are driven independently, with message buffering etc.

The touch and eeprom in the example are instantiated on the physical
busses where they are wired (i2c-5 or i2c-6) with their physical
addresses on those busses.

> Note, that following an advice from Wolfram I'm going to send the i2c-bridge
> cell driver into inclusion under drivers/i2c/muxes/ , even if the device
> driver does not register a mux.
> 
>> transactions are handled in a way similar to i2c-mux, i.e. the ds90*
>> i2c_adapter has a master_xfer callback that changes the remote slave
>> address to the corresponding alias, then calls parent->algo->master_xfer().
>>
>> Note how both eeproms in the example have the same physical address.
>> They will be given two different aliases.
> 
> The question is how to determine which runtime assigned address represents
> which eeprom of two. The remote/alias scheme I propose makes it transparent.

You generally don't care about the assigned alias. To access e.g. each
of the eeproms the path is always reliable and represents the physical
world:

 - i2c-0 -> 00-003d -> rxport0 -> ??-0051
 - i2c-0 -> 00-003d -> rxport1 -> ??-0051

The alias matters only when debugging the driver or inspecting the
physical bus with a protocol analyzer or oscilloscope.

Bye,
-- 
Luca

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge
  2018-11-03 21:00       ` Luca Ceresoli
@ 2018-11-03 22:07         ` Vladimir Zapolskiy
  0 siblings, 0 replies; 62+ messages in thread
From: Vladimir Zapolskiy @ 2018-11-03 22:07 UTC (permalink / raw)
  To: Luca Ceresoli, Lee Jones, Rob Herring
  Cc: Linus Walleij, Marek Vasut, Laurent Pinchart, Wolfram Sang,
	devicetree, linux-gpio, linux-media, linux-kernel,
	Vladimir Zapolskiy

Hi Luca,

On 11/03/2018 11:00 PM, Luca Ceresoli wrote:
> Hi Vladimir,
> 
> On 31/10/18 21:12, Vladimir Zapolskiy wrote:
>> Hi Luca,
>>
>> thank you for review.
>>
>> On 10/30/2018 06:43 PM, Luca Ceresoli wrote:
>>> Hi Vladimir,
>>>
>>> On 08/10/18 23:12, Vladimir Zapolskiy wrote:
>>>> From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>>
>>>> TI DS90Ux9xx de-/serializers are capable to route I2C messages to
>>>> I2C slave devices connected to a remote de-/serializer in a pair,
>>>> the change adds description of device tree bindings of the subcontroller
>>>> to configure and enable this functionality.
>>>>
>>>> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
>>>> ---
>>>>  .../bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt  | 61 +++++++++++++++++++
>>>>  1 file changed, 61 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>>>> new file mode 100644
>>>> index 000000000000..4169e382073a
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mfd/ti,ds90ux9xx-i2c-bridge.txt
>>>> @@ -0,0 +1,61 @@
>>>> +TI DS90Ux9xx de-/serializer I2C bridge subcontroller
>>>> +
>>>> +Required properties:
>>>> +- compatible: Must contain a generic "ti,ds90ux9xx-i2c-bridge" value and
>>>> +	may contain one more specific value from the list:
>>>> +	"ti,ds90ux925-i2c-bridge",
>>>> +	"ti,ds90ux926-i2c-bridge",
>>>> +	"ti,ds90ux927-i2c-bridge",
>>>> +	"ti,ds90ux928-i2c-bridge",
>>>> +	"ti,ds90ux940-i2c-bridge".
>>>> +
>>>> +Required properties of a de-/serializer device connected to a local I2C bus:
>>>> +- ti,i2c-bridges: List of phandles to remote de-/serializer devices with
>>>> +	two arguments: id of a local de-/serializer FPD link and an assigned
>>>> +	I2C address of a remote de-/serializer to be accessed on a local
>>>> +	I2C bus.
>>>> +
>>>> +Optional properties of a de-/serializer device connected to a local I2C bus:
>>>> +- ti,i2c-bridge-maps: List of 3-cell values:
>>>> +	- the first argument is id of a local de-/serializer FPD link,
>>>> +	- the second argument is an I2C address of a device connected to
>>>> +	  a remote de-/serializer IC,
>>>> +	- the third argument is an I2C address of the remote I2C device
>>>> +	  for access on a local I2C bus.
>>>
>>> BTW I usually use names "remove slave" address and "alias" for bullets 2
>>> and 3. These are the names from the datasheets, and are clearer IMO.
>>>
>>
>> Definitely you are correct, I find that verbose descriptions might be
>> more appropriate and self-explanatory for anyone, who is not closely familiar
>> with the IC series. I'll consider to add the names from the datasheets
>> as well.
>>
>>> Now to the big stuff.
>>>
>>> I find a static map in the "local" chip DT node is a limit. You might
>>> have to support multiple models of remote device, where you'll know the
>>> model only when after it gets connected. Think Beaglebone capes, but
>>> over FPD-Link 3. This scenario opens several issues, but specifically
>>> for I2C address mapping I addressed it by adding in the "local" chip's
>>> DT node a pool of I2C aliases it can use. The DT author is responsible
>>> to pick addresses that are not used on the same I2C bus, which cannot be
>>> done at runtime reliably.
>>
>> Here I see several important topics raised.
>>
>> 1) A static map in the "local" chip DT node is not a limit in sense that
>>    it is optional, so it would be a working model just to omit the property,
>>    however it may (or may not) require another handlers to bridge remote
>>    I2C devices, for instance 'ti,i2c-bridge-pass-all' property, or new
>>    UAPI.
> 
> Do you mean when the "pass-all" method and the "static map in the local
> node" method are insufficient, then the solution is to implement a third
> method that is powerful enough? If that's what you mean, then I think we
> should rather [try to] implement from the beginning a method that is
> powerful enough to handle all the cases we can foresee.

To my best knowledge "static map in the local node" method from my design
is completely sufficient alone. On top of it, if hardware design of a series
of remote PCBs is thought-out enough, then adding DT overlays allows to
manage connections and instantiatings of unknown in advance remote PCBs
in runtime, but this is out of scope of classic IC device tree design,
because device trees are for description of non-discoverable hardware, thus
clearly a complex PCB behind an FPD-Link III shall find its description
in DTB in more or less precise way.

PASS ALL setting may be helpful for testing or adding initial support
of remote PCBs, by the way I've recollected that ICs support simultaneous
slave/alias mappings and PASS ALL function, the practical sense is not
clear though.

>> 2) About supporting multiple models of remote PCBs in the same dts file,
>>    it might be an excessive complication to predict a proper description
>>    of an unknown in advance complex device, so, a better solution should
>>    be to apply DT overlays in runtime, but at any time the hardware
>>    description and the mapping shall be precisely defined.
> 
> I agree runtime DT overlays is the correct way of handling multiple
> remote boards, but not if they contain a ti,i2c-bridge-maps
> (physical-to-alias I2C address map).
> 
> Consider the case where we have N different main board (with SoC and
> "local" [de]serializer) and M peripheral boards (display+deserializer or
> sensor+serializer). Then we'd need up to N*M DT overlays, each with the
> alias map for a specific <main_board, peripheral_board> pair. This is
> because the map maps a physical address that exists on the remote side
> (peripheral board) to an alias that exists on the local side (main board).

If you take into account my statement above about thought-out PCB design,
then multiplication is not needed, but in general you are correct.

And again, device trees are used for description of any non-discoverable
hardware, both main boards and peripheral boards fall into this category,
so the argument about complexity is quite vain, think of an option to
reduce a number of, let say, arch/arm/boot/dts/imx6*.dts files in 3 times
and still get all boards properly supported.

So, DT overlays is the only right method to deal with complexity of
M peripheral boards.

> To realistically model the hardware, the DT overlay should contain the
> removable components, including the physical address on the remote side
> (e.g. touchscreen slave address), but not including the alias on the
> local side (a slave address that is not used on the SoC i2c bus).
> 

The alias on the local side is also a hardware description in sense
that 

>> 3) About a pool of vacant I2C addresses, I dislike the idea that there
>>    will be no definite or constant I2C address in runtime for a particular
>>    remote slave device.
> 
> Indeed that's a little annoyance. But you'll face it only during kernel
> development and debugging, not at the userspace interface. See below the
> discussion about i2c_adapter.
> 

It depends, most likely the good written userspace applications can
deal with the remote side devices correctly, but, for instance, I can't
instantly imagine how to distinguish two identical eeproms on a peripheral
boards with different I2C addresses. My method allows to overcome this
kind of problems.

What I think, is that 

> [...]
> 
>>> Here's my current draft on a dual/quad port deserializer:
>>>
>>> &i2c0 {
>>>     serializer@3d {
>>>         reg = <0x3d>;
>>>         ...
>>>
>>>         /* Guaranteed not physically present on i2c0 */
>>>         i2c-alias-pool = /bits/ 8 <0x20 0x21 0x22 0x23 0x24 0x25>;
>>>
>>>         rxports {
>>>             #address-cells = <1>;
>>>             #size-cells = <0>;
>>>
>>>             rxport@0 {
>>>                 reg = <0>;
>>>                 remote-i2c-bus { /* The proxied I2C bus on rxport 0 */
>>>                     #address-cells = <1>;
>>>                     #size-cells = <0>;
>>>
>>>                     eeprom@51 {
>>>                         reg = <0x51>;
>>>                         compatible = "at,24c02";
>>>                     };
>>>                 };
>>>
>>>             rxport@1 {
>>>                 reg = <1>;
>>>                 remote-i2c-bus { /* The proxied I2C bus on rxport 1 */
>>>                     #address-cells = <1>;
>>>                     #size-cells = <0>;
>>>
>>>                     eeprom@51 {
>>>                         reg = <0x51>;
>>>                         compatible = "at,24c02";
>>>                     };
>>>                 };
>>>             };
>>>         };
>>>     };
>>> };
>>>
>>> At probe time the serializer driver instantiates one new i2c_adapter for
>>> each rxport. Any remote device is added (removed) to that adapter, then
>>> the driver finds an available alias and maps (unmaps) it. The
>>
>> I avoid using i2c_adapter object, because then you get a confusing access
>> to right the same device on two logical I2C buses. This is not the way
>> how I2C muxes operate or are expected to operate, commonly I2C muxes contain
>> a protocol to access muxed devices, which are "invisible" on a host bus,
>> and here a local IC behaves like an I2C device with multiple addresses.
> 
> Sorry, this whole paragraph is not quite clear to me.
> 
> Well, except "I avoid using i2c_adapter object", which is very clear and
> opposite to my approach. :) I'm instantiating an i2c_adapter for each rx
> port because it's the best model of the real world that I could devise.

If you use an i2c_adapter in the discussed case, it allows to discover and
access right the same I2C device on two logical buses at the same time.

> See the picture:
> 
>                 .----------------.
>                 |                |   i2c-5    ,-- touch@50
> ----.   i2c-0   |        adap0----------------+-- eeprom@51
> SoC |-----------| atr@3d         |
> ----'           |        adap1----------------+-- eeprom@51
>                 |                |   i2c-6    `-- touch@50
>                 `----------------'
> 
> I called the central object ATR (address translator), which is the i2c
> remotizer feature in the DS90Ux chipset. Topologically it is somewhat
> similar to a mux, but:
> 
>  * it also translates addresses (hence the name)
>  * electrically it never attaches the upstream and downstream busses,
>    they are driven independently, with message buffering etc.

To my point above, "eeprom@51" device will be accessible both on
i2c-0 and i2c-5, this is something that I want to avoid by any means.

> The touch and eeprom in the example are instantiated on the physical
> busses where they are wired (i2c-5 or i2c-6) with their physical
> addresses on those busses.

At the cost of disadvantage that touch and eeprom are discoverable on
i2c-0 also. The same device mapped into two logical I2C busses at the
same time does not sound correct or even thoroughly tested, sorry.

>> Note, that following an advice from Wolfram I'm going to send the i2c-bridge
>> cell driver into inclusion under drivers/i2c/muxes/ , even if the device
>> driver does not register a mux.
>>
>>> transactions are handled in a way similar to i2c-mux, i.e. the ds90*
>>> i2c_adapter has a master_xfer callback that changes the remote slave
>>> address to the corresponding alias, then calls parent->algo->master_xfer().
>>>
>>> Note how both eeproms in the example have the same physical address.
>>> They will be given two different aliases.
>>
>> The question is how to determine which runtime assigned address represents
>> which eeprom of two. The remote/alias scheme I propose makes it transparent.
> 
> You generally don't care about the assigned alias. To access e.g. each
> of the eeproms the path is always reliable and represents the physical
> world:
> 
>  - i2c-0 -> 00-003d -> rxport0 -> ??-0051
>  - i2c-0 -> 00-003d -> rxport1 -> ??-0051
> 
> The alias matters only when debugging the driver or inspecting the
> physical bus with a protocol analyzer or oscilloscope.
> 

Please see my point about userspace interfaces. udev won't tell if mapped
eeprom@20 is actually an eeprom@50 or eeprom@51 device on a peripheral
board. This uncertainty shall be avoided, my DT design removes the riddle.


--
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 62+ messages in thread

end of thread, back to index

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-08 21:11 [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Vladimir Zapolskiy
2018-10-08 21:11 ` [PATCH 1/7] dt-bindings: mfd: ds90ux9xx: add description " Vladimir Zapolskiy
2018-10-09  0:13   ` Marek Vasut
2018-10-09 11:11     ` Vladimir Zapolskiy
2018-10-09 20:55       ` Vladimir Zapolskiy
2018-10-09 21:03         ` Marek Vasut
2018-10-10  8:41   ` Linus Walleij
2018-10-12 11:44   ` Laurent Pinchart
2018-10-13 14:28     ` Vladimir Zapolskiy
2018-10-16 12:30       ` Laurent Pinchart
2018-10-30 16:43   ` Luca Ceresoli
2018-10-30 23:40     ` Vladimir Zapolskiy
2018-10-08 21:12 ` [PATCH 2/7] dt-bindings: mfd: ds90ux9xx: add description of TI DS90Ux9xx I2C bridge Vladimir Zapolskiy
2018-10-12 11:54   ` Laurent Pinchart
2018-10-30 16:43   ` Luca Ceresoli
2018-10-31 20:12     ` Vladimir Zapolskiy
2018-11-03 21:00       ` Luca Ceresoli
2018-11-03 22:07         ` Vladimir Zapolskiy
2018-10-08 21:12 ` [PATCH 3/7] dt-bindings: pinctrl: ds90ux9xx: add description of TI DS90Ux9xx pinmux Vladimir Zapolskiy
2018-10-10  8:45   ` Linus Walleij
2018-10-17 15:02     ` Rob Herring
2018-10-12 12:01   ` Laurent Pinchart
2018-10-13 13:47     ` Vladimir Zapolskiy
2018-10-16 12:48       ` Laurent Pinchart
2018-10-30 16:44         ` Luca Ceresoli
2018-10-31 20:31           ` Vladimir Zapolskiy
2018-10-08 21:12 ` [PATCH 4/7] mfd: ds90ux9xx: add TI DS90Ux9xx de-/serializer MFD driver Vladimir Zapolskiy
2018-10-09  4:08   ` kbuild test robot
2018-10-09 11:14     ` Vladimir Zapolskiy
2018-10-12  6:03   ` Lee Jones
2018-10-12  7:41     ` Vladimir Zapolskiy
2018-10-12  8:39       ` Lee Jones
2018-10-12  9:20         ` Kieran Bingham
2018-10-12 10:58           ` Vladimir Zapolskiy
2018-10-12 11:34             ` Lee Jones
2018-10-12 14:13               ` Vladimir Zapolskiy
2018-10-12 14:25                 ` Lee Jones
2018-10-12 11:47             ` Kieran Bingham
2018-10-12 13:01               ` Laurent Pinchart
2018-10-12 13:59                 ` Vladimir Zapolskiy
2018-10-16 13:08                   ` Laurent Pinchart
2018-10-23  8:16                   ` Vladimir Zapolskiy
2018-10-30 16:44                     ` Luca Ceresoli
2018-10-13 15:10                 ` Vladimir Zapolskiy
2018-10-16 13:12                   ` Laurent Pinchart
2018-10-16 18:32                     ` Vladimir Zapolskiy
2018-10-13 12:33               ` Vladimir Zapolskiy
2018-10-12 11:24         ` Vladimir Zapolskiy
2018-10-12 11:43           ` Lee Jones
2018-10-12 14:23             ` Vladimir Zapolskiy
2018-10-12 13:07           ` Laurent Pinchart
2018-10-08 21:12 ` [PATCH 5/7] mfd: ds90ux9xx: add I2C bridge/alias and link connection driver Vladimir Zapolskiy
2018-10-12  6:04   ` Lee Jones
2018-10-12  7:32     ` Vladimir Zapolskiy
2018-10-12  9:03       ` Lee Jones
2018-10-12 13:12       ` Laurent Pinchart
2018-10-12 14:36         ` Vladimir Zapolskiy
2018-10-16 14:06           ` Laurent Pinchart
2018-10-08 21:12 ` [PATCH 6/7] pinctrl: ds90ux9xx: add TI DS90Ux9xx pinmux and GPIO controller driver Vladimir Zapolskiy
2018-10-10  9:04   ` Linus Walleij
2018-10-08 21:12 ` [PATCH 7/7] MAINTAINERS: add entry for TI DS90Ux9xx FPD-Link III drivers Vladimir Zapolskiy
2018-10-12 11:34 ` [PATCH 0/7] mfd/pinctrl: add initial support of TI DS90Ux9xx ICs Laurent Pinchart

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git