Skip to contentSkip to conversation

Add device tree support for Exynos4 SoC camera subsystem

PATCH Superseded Sylwester Nawrocki 3 participants 11 messages Oct 17, 2013 – Jan 7, 2014

Subsystems (5)

v3 of 6 Superseded Latest is v6 →

lore
Share & tools
lore

Sylwester Nawrocki

author maintainer
#0 lore raw

v3 cover Add device tree support for Exynos4 SoC camera subsystem

This series is intended to add device tree support for both cameras on the Exynos4412 SoC Trats 2 board. It converts related drivers to use the v4l2-async API and expose the sensor's master clock, supplied by the camera host interface, through the common clock API.

This changeset is an updated version of my patch series [1]. I didn't receive any feedback until then and the changes in this iteration are rather minor. I'm going to send a pull request including those patches this week.

[1] http://www.spinics.net/lists/linux-media/msg67574.html

Thanks,
Sylwester

Sylwester Nawrocki (6):
V4L: s5k6a3: Add DT binding documentation
V4L: Add driver for s5k6a3 image sensor
V4L: s5c73m3: Add device tree support
exynos4-is: Add clock provider for the external clocks
exynos4-is: Use external s5k6a3 sensor driver
exynos4-is: Add support for asynchronous subdevices registration

 .../devicetree/bindings/media/samsung-fimc.txt     |   19 +-
 .../devicetree/bindings/media/samsung-s5c73m3.txt  |   95 +++++
 .../devicetree/bindings/media/samsung-s5k6a3.txt   |   32 ++
 drivers/media/i2c/Kconfig                          |    8 +
 drivers/media/i2c/Makefile                         |    1 +
 drivers/media/i2c/s5c73m3/s5c73m3-core.c           |  208 ++++++++---
 drivers/media/i2c/s5c73m3/s5c73m3-spi.c            |    6 +
 drivers/media/i2c/s5c73m3/s5c73m3.h                |    4 +
 drivers/media/i2c/s5k6a3.c                         |  387 ++++++++++++++++++++
 drivers/media/platform/exynos4-is/fimc-is-regs.c   |    2 +-
 drivers/media/platform/exynos4-is/fimc-is-sensor.c |  285 +-------------
 drivers/media/platform/exynos4-is/fimc-is-sensor.h |   49 +--
 drivers/media/platform/exynos4-is/fimc-is.c        |   97 ++---
 drivers/media/platform/exynos4-is/fimc-is.h        |    4 +-
 drivers/media/platform/exynos4-is/media-dev.c      |  327 ++++++++++++-----
 drivers/media/platform/exynos4-is/media-dev.h      |   31 +-
 16 files changed, 1024 insertions(+), 531 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/samsung-s5c73m3.txt
 create mode 100644 Documentation/devicetree/bindings/media/samsung-s5k6a3.txt
 create mode 100644 drivers/media/i2c/s5k6a3.c

--
1.7.9.5

author maintainer
#1 lore raw

PATCH v3 1/6 V4L: s5k6a3: Add DT binding documentation

This patch adds binding documentation for the Samsung S5K6A3(YX) raw image sensor.

---
Changes since v2:
- added AF regulator supply.

---
 .../devicetree/bindings/media/samsung-s5k6a3.txt   |   32 ++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/samsung-s5k6a3.txt
Documentation/devicetree/bindings/media/samsung-s5k6a3.txt new file +32 -0
new file mode 100644
index 0000000..3806e77
@@ -0,0 +1,32 @@
+Samsung S5K6A3(YX) raw image sensor
+---------------------------------
+
+S5K6A3(YX) is a raw image sensor with MIPI CSI-2 and CCP2 image data interfaces
+and CCI (I2C compatible) control bus.
+
+Required properties:
+
+- compatible	: "samsung,s5k6a3";
+- reg		: I2C slave address of the sensor;
+- svdda-supply	: core voltage supply;
+- svddio-supply	: I/O voltage supply;
+- afvdd-supply	: AF (actuator) voltage supply;
+- gpios		: specifier of a GPIO connected to the RESET pin;
+- clocks	: should contain the sensor's EXTCLK clock specifier,
+		  from common clock bindings;
+- clock-names	: should contain "extclk" entry;
+
+Optional properties:
+
+- clock-frequency : the frequency at which the "extclk" clock should be
+		    configured to operate, in Hz; if this property is not
+		    specified default 24 MHz value will be used.
+
+The common video interfaces bindings (see video-interfaces.txt) should be
+used to specify link to the image data receiver. The S5K6A3(YX) device
+node should contain one 'port' child node with an 'endpoint' subnode.
+
+Following properties are valid for the endpoint node:
+
+- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
+  video-interfaces.txt.  The sensor supports only one data lane.
Signature · 1 line
1.7.9.5
#2 lore raw

Re: [PATCH v3 1/6] V4L: s5k6a3: Add DT binding documentation

Quoted 5 lines · Sylwester Nawrocki

This patch adds binding documentation for the Samsung S5K6A3(YX) raw image sensor.

Hi Mauro,

Can we merge it now without a DT binding maintainer Ack ?
There was no comments for 2 months and I believe the Ack is not mandatory for this kind of standard binding and very similar binding has been already reviewed (for the S5K5BAF sensor).

I just updated slightly the clock/clock-names property description, so I would post patch [1] to the mailing lists before adding it to a pull request.

Thanks,
Sylwester

[1] http://git.linuxtv.org/snawrocki/samsung.git/commitdiff/4249788ea8c9b9d9bc95cd088351e2cdda1838f6

Quoted 46 lines

---
Changes since v2:
- added AF regulator supply.

---
  .../devicetree/bindings/media/samsung-s5k6a3.txt   |   32 ++++++++++++++++++++
  1 file changed, 32 insertions(+)

create mode 100644 Documentation/devicetree/bindings/media/samsung-s5k6a3.txt

Documentation/devicetree/bindings/media/samsung-s5k6a3.txt new file +32 -0
new file mode 100644
index 0000000..3806e77
@@ -0,0 +1,32 @@
+Samsung S5K6A3(YX) raw image sensor
+---------------------------------
+
+S5K6A3(YX) is a raw image sensor with MIPI CSI-2 and CCP2 image data interfaces
+and CCI (I2C compatible) control bus.
+
+Required properties:
+
+- compatible	: "samsung,s5k6a3";
+- reg		: I2C slave address of the sensor;
+- svdda-supply	: core voltage supply;
+- svddio-supply	: I/O voltage supply;
+- afvdd-supply	: AF (actuator) voltage supply;
+- gpios		: specifier of a GPIO connected to the RESET pin;
+- clocks	: should contain the sensor's EXTCLK clock specifier,
+		  from common clock bindings;
+- clock-names	: should contain "extclk" entry;
+
+Optional properties:
+
+- clock-frequency : the frequency at which the "extclk" clock should be
+		    configured to operate, in Hz; if this property is not
+		    specified default 24 MHz value will be used.
+
+The common video interfaces bindings (see video-interfaces.txt) should be
+used to specify link to the image data receiver. The S5K6A3(YX) device
+node should contain one 'port' child node with an 'endpoint' subnode.
+
+Following properties are valid for the endpoint node:
+
+- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
+  video-interfaces.txt.  The sensor supports only one data lane.
author maintainer
#3 lore raw

PATCH v3 2/6 V4L: Add driver for s5k6a3 image sensor

In reply to Sylwester Nawrocki

This patch adds subdev driver for Samsung S5K6A3 raw image sensor. As it is intended at the moment to be used only with the Exynos FIMC-IS (camera ISP) subsystem it is pretty minimal subdev driver. It doesn't do any I2C communication since the sensor is controlled by the ISP and its own firmware.
This driver can be updated in future, should anyone need it to be a regular subdev driver where the main CPU communicates with the sensor directly.

---
Changes since v1:
- added missing pm_runtime_disable(),
- removed subdev name overriding,
- s/S5K6A3_DEF_PIX/S5K6A3_DEFAULT_,
- merged patch adding v4l2-async API support,
- clock-frequency property is now optional and a default frequency value will be used when it is missing, rather than bailing out,
- reset GPIO made mandatory as it is required for proper power on/off sequences and all known boards use it,
- maximum image size is now 1412x1412 pixels, as specified in in the S5K6A3YX datasheet.
- regulator_enable()/disable() used instead of the regulator bulk API to ensure proper regulators enable/disable sequences.

---
 drivers/media/i2c/Kconfig  |    8 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/s5k6a3.c |  387 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 396 insertions(+)
 create mode 100644 drivers/media/i2c/s5k6a3.c
drivers/media/i2c/Kconfig +8 -0
index d18be19..c3619a5 100644
@@ -587,6 +587,14 @@ config VIDEO_S5K6AA
 	  This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
 	  camera sensor with an embedded SoC image signal processor.
 
+config VIDEO_S5K6A3
+	tristate "Samsung S5K6A3 sensor support"
+	depends on MEDIA_CAMERA_SUPPORT
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+	---help---
+	  This is a V4L2 sensor-level driver for Samsung S5K6A3 raw
+	  camera sensor.
+
 config VIDEO_S5K4ECGX
         tristate "Samsung S5K4ECGX sensor support"
         depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
drivers/media/i2c/Makefile +1 -0
index 9f462df..e7be364 100644
@@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
 obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+obj-$(CONFIG_VIDEO_S5K6A3)	+= s5k6a3.o
 obj-$(CONFIG_VIDEO_S5K4ECGX)	+= s5k4ecgx.o
 obj-$(CONFIG_VIDEO_S5C73M3)	+= s5c73m3/
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
drivers/media/i2c/s5k6a3.c new file +387 -0

387 lines not on this page · raw message

Signature · 1 line
1.7.9.5
author maintainer
#4 lore raw

PATCH v4 2/6 V4L: Add driver for s5k6a3 image sensor

This patch adds subdev driver for Samsung S5K6A3 raw image sensor. As it is intended at the moment to be used only with the Exynos FIMC-IS (camera ISP) subsystem it is pretty minimal subdev driver. It doesn't do any I2C communication since the sensor is controlled by the ISP and its own firmware.
This driver can be updated in future, should anyone need it to be a regular subdev driver where the main CPU communicates with the sensor directly.

---
v3 was a wrong untested version I sent by mistake.

Changes since v2:
- reset GPIO made mandatory as it is required for proper power on/off sequences and all known boards use it,
- maximum image size is now 1412x1412 pixels, as specified in in the S5K6A3YX datasheet.
- regulator_enable()/disable() used instead of the regulator bulk API to ensure proper regulators enable/disable sequences.

Changes since v1:
- added missing pm_runtime_disable(),
- removed subdev name overriding,
- s/S5K6A3_DEF_PIX/S5K6A3_DEFAULT_,
- merged patch adding v4l2-async API support,
- clock-frequency property is now optional and a default frequency value will be used when it is missing, rather than bailing out,

---
 drivers/media/i2c/Kconfig  |    8 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/s5k6a3.c |  391 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 400 insertions(+)
 create mode 100644 drivers/media/i2c/s5k6a3.c
drivers/media/i2c/Kconfig +8 -0
index d18be19..c3619a5 100644
@@ -587,6 +587,14 @@ config VIDEO_S5K6AA
 	  This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
 	  camera sensor with an embedded SoC image signal processor.
 
+config VIDEO_S5K6A3
+	tristate "Samsung S5K6A3 sensor support"
+	depends on MEDIA_CAMERA_SUPPORT
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+	---help---
+	  This is a V4L2 sensor-level driver for Samsung S5K6A3 raw
+	  camera sensor.
+
 config VIDEO_S5K4ECGX
         tristate "Samsung S5K4ECGX sensor support"
         depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
drivers/media/i2c/Makefile +1 -0
index 9f462df..e7be364 100644
@@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
 obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+obj-$(CONFIG_VIDEO_S5K6A3)	+= s5k6a3.o
 obj-$(CONFIG_VIDEO_S5K4ECGX)	+= s5k4ecgx.o
 obj-$(CONFIG_VIDEO_S5C73M3)	+= s5c73m3/
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
drivers/media/i2c/s5k6a3.c new file +391 -0

391 lines not on this page · raw message

--
1.7.9.5

author maintainer
#5 lore raw

PATCH v3 3/6 V4L: s5c73m3: Add device tree support

In reply to Sylwester Nawrocki

This patch adds the V4L2 asynchronous subdev registration and device tree support. Common clock API is used to control the sensor master clock from within the subdev.

--
Changes since v2:
- call clk_get() before enabling the clock and clk_put() after each clk_disable().

---
 .../devicetree/bindings/media/samsung-s5c73m3.txt  |   95 +++++++++
 drivers/media/i2c/s5c73m3/s5c73m3-core.c           |  208 +++++++++++++++-----
 drivers/media/i2c/s5c73m3/s5c73m3-spi.c            |    6 +
 drivers/media/i2c/s5c73m3/s5c73m3.h                |    4 +
 4 files changed, 263 insertions(+), 50 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/samsung-s5c73m3.txt
Documentation/devicetree/bindings/media/samsung-s5c73m3.txt new file +95 -0
new file mode 100644
index 0000000..d419e4e
@@ -0,0 +1,95 @@
+Samsung S5C73M3 8Mp camera ISP
+------------------------------
+
+The S5C73M3 camera ISP supports MIPI CSI-2 and parallel (ITU-R BT.656) video
+data busses. The I2C bus is the main control bus and additionally the SPI bus
+is used, mostly for transferring the firmware to and from the device. Two
+slave device nodes corresponding to these control bus interfaces are required
+and should be placed under respective bus controller nodes.
+
+I2C slave device node
+---------------------
+
+Required properties:
+
+- compatible	    : "samsung,s5c73m3";
+- reg		    : I2C slave address of the sensor;
+- vdd-int-supply    : digital power supply (1.2V);
+- vdda-supply	    : analog power supply (1.2V);
+- vdd-reg-supply    : regulator input power supply (2.8V);
+- vddio-host-supply : host I/O power supply (1.8V to 2.8V);
+- vddio-cis-supply  : CIS I/O power supply (1.2V to 1.8V);
+- vdd-af-supply	    : lens power supply (2.8V);
+- xshutdown-gpios   : specifier of GPIO connected to the XSHUTDOWN pin;
+- standby-gpios     : specifier of GPIO connected to the STANDBY pin;
+- clocks	    : should contain the sensor's CIS_EXTCLK clock specifier;
+- clock-names	    : should contain "cis_extclk" entry;
+
+Optional properties:
+
+- clock-frequency   : the frequency at which the "cis_extclk" clock should be
+		      configured to operate, in Hz; if this property is not
+		      specified default 24 MHz value will be used.
+
+The common video interfaces bindings (see video-interfaces.txt) should be used
+to specify link from the S5C73M3 to an external image data receiver. The S5C73M3
+device node should contain one 'port' child node with an 'endpoint' subnode for
+this purpose. The data link from a raw image sensor to the S5C73M3 can be
+similarly specified, but it is optional since the S5C73M3 ISP and a raw image
+sensor are usually inseparable and form a hybrid module.
+
+Following properties are valid for the endpoint node(s):
+
+endpoint subnode
+----------------
+
+- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
+  video-interfaces.txt. This sensor doesn't support data lane remapping
+  and physical lane indexes in subsequent elements of the array should
+  be only consecutive ascending values.
+
+SPI device node
+---------------
+
+Required properties:
+
+- compatible	    : "samsung,s5c73m3";
+
+For more details see description of the SPI busses bindings
+(../spi/spi-bus.txt) and bindings of a specific bus controller.
+
+Example:
+
+i2c@138A000000 {
+	...
+	s5c73m3@3c {
+		compatible = "samsung,s5c73m3";
+		reg = <0x3c>;
+		vdd-int-supply = <&buck9_reg>;
+		vdda-supply = <&ldo17_reg>;
+		vdd-reg-supply = <&cam_io_reg>;
+		vddio-host-supply = <&ldo18_reg>;
+		vddio-cis-supply = <&ldo9_reg>;
+		vdd-af-supply = <&cam_af_reg>;
+		clock-frequency = <24000000>;
+		clocks = <&clk 0>;
+		clock-names = "cis_extclk";
+		reset-gpios = <&gpf1 3 1>;
+		standby-gpios = <&gpm0 1 1>;
+		port {
+			s5c73m3_ep: endpoint {
+				remote-endpoint = <&csis0_ep>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+spi@1392000 {
+	...
+	s5c73m3_spi: s5c73m3 {
+		compatible = "samsung,s5c73m3";
+		reg = <0>;
+		...
+	};
+};
drivers/media/i2c/s5c73m3/s5c73m3-core.c +158 -50

335 lines not on this page · raw message

drivers/media/i2c/s5c73m3/s5c73m3-spi.c +6 -0
index 8079e26..f60b265 100644
@@ -27,6 +27,11 @@
 
 #define S5C73M3_SPI_DRV_NAME "S5C73M3-SPI"
 
+static const struct of_device_id s5c73m3_spi_ids[] = {
+	{ .compatible = "samsung,s5c73m3" },
+	{ }
+};
+
 enum spi_direction {
 	SPI_DIR_RX,
 	SPI_DIR_TX
@@ -146,6 +151,7 @@ int s5c73m3_register_spi_driver(struct s5c73m3 *state)
 	spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
 	spidrv->driver.bus = &spi_bus_type;
 	spidrv->driver.owner = THIS_MODULE;
+	spidrv->driver.of_match_table = s5c73m3_spi_ids;
 
 	return spi_register_driver(spidrv);
 }
drivers/media/i2c/s5c73m3/s5c73m3.h +4 -0
index 9d2c086..2917857 100644
@@ -17,6 +17,7 @@
 #ifndef S5C73M3_H_
 #define S5C73M3_H_
 
+#include <linux/clk.h>
 #include <linux/kernel.h>
 #include <linux/regulator/consumer.h>
 #include <media/v4l2-common.h>
@@ -321,6 +322,7 @@ enum s5c73m3_oif_pads {
 
 
 #define S5C73M3_MAX_SUPPLIES			6
+#define S5C73M3_DEFAULT_MCLK_FREQ		24000000U
 
 struct s5c73m3_ctrls {
 	struct v4l2_ctrl_handler handler;
@@ -391,6 +393,8 @@ struct s5c73m3 {
 	struct regulator_bulk_data supplies[S5C73M3_MAX_SUPPLIES];
 	struct s5c73m3_gpio gpio[GPIO_NUM];
 
+	struct clk *clock;
+
 	/* External master clock frequency */
 	u32 mclk_frequency;
 	/* Video bus type - MIPI-CSI2/paralell */
Signature · 1 line
1.7.9.5
author maintainer
#6 lore raw

PATCH v3 4/6 exynos4-is: Add clock provider for the external clocks

In reply to Sylwester Nawrocki

This patch adds clock provider to expose the sclk_cam0/1 clocks for external image sensor devices.

---
Changes since v2:
- use 'camera' DT node drirectly as clock provider node, rather than creating additional clock-controller child node.

---
 .../devicetree/bindings/media/samsung-fimc.txt     |   15 ++-
 drivers/media/platform/exynos4-is/media-dev.c      |  108 ++++++++++++++++++++
 drivers/media/platform/exynos4-is/media-dev.h      |   18 +++-
 3 files changed, 137 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/media/samsung-fimc.txt +12 -3
index 96312f6..968e065 100644
@@ -32,6 +32,15 @@ way around.
 
 The 'camera' node must include at least one 'fimc' child node.
 
+Optional properties:
+
+- #clock-cells: from the common clock bindings (../clock/clock-bindings.txt),
+  must be 1. A clock provider is associated with the camera node and it should
+  be referenced by external sensors that use clocks provided by the SoC on
+  CAM_*_CLKOUT pins. The second cell of the clock specifier is a clock's index.
+  The indexes are 0, 1 for CAM_A_CLKOUT, CAM_B_CLKOUT clocks respectively.
+
+
 'fimc' device nodes
 -------------------
 
@@ -114,7 +123,7 @@ Example:
 			vddio-supply = <...>;
 
 			clock-frequency = <24000000>;
-			clocks = <...>;
+			clocks = <&camera 1>;
 			clock-names = "mclk";
 
 			port {
@@ -135,7 +144,7 @@ Example:
 			vddio-supply = <...>;
 
 			clock-frequency = <24000000>;
-			clocks = <...>;
+			clocks = <&camera 0>;
 			clock-names = "mclk";
 
 			port {
@@ -151,8 +160,8 @@ Example:
 		compatible = "samsung,fimc", "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		#clock-cells = <1>;
 		status = "okay";
-
 		pinctrl-names = "default";
 		pinctrl-0 = <&cam_port_a_clk_active>;
 
drivers/media/platform/exynos4-is/media-dev.c +108 -0

154 lines not on this page · raw message

drivers/media/platform/exynos4-is/media-dev.h +17 -1
index 62599fd..240ca71 100644
@@ -10,6 +10,7 @@
 #define FIMC_MDEVICE_H_
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
@@ -89,6 +90,12 @@ struct fimc_sensor_info {
 	struct fimc_dev *host;
 };
 
+struct cam_clk {
+	struct clk_hw hw;
+	struct fimc_md *fmd;
+};
+#define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw)
+
 /**
  * struct fimc_md - fimc media device information
  * @csis: MIPI CSIS subdevs data
@@ -105,6 +112,7 @@ struct fimc_sensor_info {
  * @pinctrl: camera port pinctrl handle
  * @state_default: pinctrl default state handle
  * @state_idle: pinctrl idle state handle
+ * @cam_clk_provider: CAMCLK clock provider structure
  * @user_subdev_api: true if subdevs are not configured by the host driver
  * @slock: spinlock protecting @sensor array
  */
@@ -122,13 +130,21 @@ struct fimc_md {
 	struct media_device media_dev;
 	struct v4l2_device v4l2_dev;
 	struct platform_device *pdev;
+
 	struct fimc_pinctrl {
 		struct pinctrl *pinctrl;
 		struct pinctrl_state *state_default;
 		struct pinctrl_state *state_idle;
 	} pinctl;
-	bool user_subdev_api;
 
+	struct cam_clk_provider {
+		struct clk *clks[FIMC_MAX_CAMCLKS];
+		struct clk_onecell_data clk_data;
+		struct device_node *of_node;
+		struct cam_clk camclk[FIMC_MAX_CAMCLKS];
+	} clk_provider;
+
+	bool user_subdev_api;
 	spinlock_t slock;
 	struct list_head pipelines;
 };
Signature · 1 line
1.7.9.5
#7 lore raw

Re: [PATCH v3 4/6] exynos4-is: Add clock provider for the external clocks

Em Thu, 17 Oct 2013 20:06:49 +0200
Sylwester Nawrocki <[email protected]> escreveu:

Quoted 54 lines

This patch adds clock provider to expose the sclk_cam0/1 clocks for external image sensor devices.

---
Changes since v2:
- use 'camera' DT node drirectly as clock provider node, rather than creating additional clock-controller child node.

---
 .../devicetree/bindings/media/samsung-fimc.txt     |   15 ++-
 drivers/media/platform/exynos4-is/media-dev.c      |  108 ++++++++++++++++++++
 drivers/media/platform/exynos4-is/media-dev.h      |   18 +++-
 3 files changed, 137 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/media/samsung-fimc.txt +11 -2
index 96312f6..968e065 100644
@@ -32,6 +32,15 @@ way around.
 
 The 'camera' node must include at least one 'fimc' child node.
 
+Optional properties:
+
+- #clock-cells: from the common clock bindings (../clock/clock-bindings.txt),
+  must be 1. A clock provider is associated with the camera node and it should
+  be referenced by external sensors that use clocks provided by the SoC on
+  CAM_*_CLKOUT pins. The second cell of the clock specifier is a clock's index.
+  The indexes are 0, 1 for CAM_A_CLKOUT, CAM_B_CLKOUT clocks respectively.
+
+
 'fimc' device nodes
 -------------------
 
@@ -114,7 +123,7 @@ Example:
 			vddio-supply = <...>;
 
 			clock-frequency = <24000000>;
-			clocks = <...>;
+			clocks = <&camera 1>;
 			clock-names = "mclk";
 
 			port {
@@ -135,7 +144,7 @@ Example:
 			vddio-supply = <...>;
 
 			clock-frequency = <24000000>;
-			clocks = <...>;
+			clocks = <&camera 0>;
 			clock-names = "mclk";
 
 			port {

Documentation/devicetree/bindings/media/samsung-fimc.txt Example: · line 166

Quoted 8 lines
Documentation/devicetree/bindings/media/samsung-fimc.txt +1 -1
@@ -151,8 +160,8 @@ Example:
 		compatible = "samsung,fimc", "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		#clock-cells = <1>;
 		status = "okay";
-
 		pinctrl-names = "default";
 		pinctrl-0 = <&cam_port_a_clk_active>;

I didn't see the above on the patch series you sent me on your git pull request. Where is it?

Quoted 49 lines
drivers/media/platform/exynos4-is/media-dev.c +33 -0
index a835112..d78e3da 100644
@@ -11,6 +11,8 @@
  */
 
 #include <linux/bug.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
@@ -1437,6 +1439,101 @@ static int fimc_md_get_pinctrl(struct fimc_md *fmd)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static int cam_clk_prepare(struct clk_hw *hw)
+{
+	struct cam_clk *camclk = to_cam_clk(hw);
+	int ret;
+
+	if (camclk->fmd->pmf == NULL)
+		return -ENODEV;
+
+	ret = pm_runtime_get_sync(camclk->fmd->pmf);
+	return ret < 0 ? ret : 0;
+}
+
+static void cam_clk_unprepare(struct clk_hw *hw)
+{
+	struct cam_clk *camclk = to_cam_clk(hw);
+
+	if (camclk->fmd->pmf == NULL)
+		return;
+
+	pm_runtime_put_sync(camclk->fmd->pmf);
+}
+
+static const struct clk_ops cam_clk_ops = {
+	.prepare = cam_clk_prepare,
+	.unprepare = cam_clk_unprepare,
+};
+
+static const char *cam_clk_p_names[] = { "sclk_cam0", "sclk_cam1" };
+
+static void fimc_md_unregister_clk_provider(struct fimc_md *fmd)

drivers/media/platform/exynos4-is/media-dev.c static int fimc_md_get_pinctrl(struct fimc_md *fmd) · line 1482

Quoted 10 lines
drivers/media/platform/exynos4-is/media-dev.c +10 -0
+{
+	struct cam_clk_provider *cp = &fmd->clk_provider;
+	unsigned int i;
+
+	if (cp->of_node)
+		of_clk_del_provider(cp->of_node);
+
+	for (i = 0; i < ARRAY_SIZE(cp->clks); i++)
+		if (!IS_ERR(cp->clks[i]))
+			clk_unregister(cp->clks[i]);

Huh? Why to initialize an array with an error code??? Does it make sense to have one of the clocks with an error and the others ok, and to store the error code? The code below doesn't seem to allow that.

Just initialize cp->clks with zero and test it with:

	if (cp->clks[i])
		clk_unregister(cp->clks[i]);

That makes it easier to understand and review.

drivers/media/platform/exynos4-is/media-dev.c static int fimc_md_get_pinctrl(struct fimc_md *fmd) · line 1492

Quoted 10 lines
drivers/media/platform/exynos4-is/media-dev.c +10 -0
+}
+
+static int fimc_md_register_clk_provider(struct fimc_md *fmd)
+{
+	struct cam_clk_provider *cp = &fmd->clk_provider;
+	struct device *dev = &fmd->pdev->dev;
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(cp->clks); i++)
+		cp->clks[i] = ERR_PTR(-EINVAL);

That looks weird for me, due to several reasons:

1) ARRAY_SIZE(cp->clks) is equal to FIMC_MAX_CAMCLKS. Why are you using different syntaxes on the first loop and on the next one? Just to loose more time from reviewers to double check what number is bigger?

2) Why don't you just do:

	memset(cp->clks, ARRAY_SIZE(cp->clks), 0).

or initialize struct fimc_md with kzalloc()?

Quoted 152 lines
drivers/media/platform/exynos4-is/media-dev.c +55 -0
+
+	for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
+		struct cam_clk *camclk = &cp->camclk[i];
+		struct clk_init_data init;
+		char clk_name[16];
+		struct clk *clk;
+
+		snprintf(clk_name, sizeof(clk_name), "cam_clkout%d", i);
+
+		init.name = clk_name;
+		init.ops = &cam_clk_ops;
+		init.flags = CLK_SET_RATE_PARENT;
+		init.parent_names = &cam_clk_p_names[i];
+		init.num_parents = 1;
+		camclk->hw.init = &init;
+		camclk->fmd = fmd;
+
+		clk = clk_register(dev, &camclk->hw);
+		if (IS_ERR(clk)) {
+			dev_err(dev, "failed to register clock: %s (%ld)\n",
+						clk_name, PTR_ERR(clk));
+			ret = PTR_ERR(clk);
+			goto err;
+		}
+		cp->clks[i] = clk;
+	}
+
+	cp->clk_data.clks = cp->clks;
+	cp->clk_data.clk_num = i;
+	cp->of_node = dev->of_node;
+
+	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
+				  &cp->clk_data);
+	if (!ret)
+		return 0;
+err:
+	fimc_md_unregister_clk_provider(fmd);
+	return ret;
+}
+#else
+#define fimc_md_register_clk_provider(fmd) (0)
+#define fimc_md_unregister_clk_provider(fmd) (0)
+#endif
+
 static int fimc_md_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1464,16 +1561,24 @@ static int fimc_md_probe(struct platform_device *pdev)
 
 	fmd->use_isp = fimc_md_is_isp_available(dev->of_node);
 
+	ret = fimc_md_register_clk_provider(fmd);
+	if (ret < 0) {
+		v4l2_err(v4l2_dev, "clock provider registration failed\n");
+		return ret;
+	}
+
 	ret = v4l2_device_register(dev, &fmd->v4l2_dev);
 	if (ret < 0) {
 		v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
 		return ret;
 	}
+
 	ret = media_device_register(&fmd->media_dev);
 	if (ret < 0) {
 		v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
 		goto err_md;
 	}
+
 	ret = fimc_md_get_clocks(fmd);
 	if (ret)
 		goto err_clk;
@@ -1507,6 +1612,7 @@ static int fimc_md_probe(struct platform_device *pdev)
 	ret = fimc_md_create_links(fmd);
 	if (ret)
 		goto err_unlock;
+
 	ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
 	if (ret)
 		goto err_unlock;
@@ -1527,6 +1633,7 @@ err_clk:
 	media_device_unregister(&fmd->media_dev);
 err_md:
 	v4l2_device_unregister(&fmd->v4l2_dev);
+	fimc_md_unregister_clk_provider(fmd);
 	return ret;
 }
 
@@ -1537,6 +1644,7 @@ static int fimc_md_remove(struct platform_device *pdev)
 	if (!fmd)
 		return 0;
 
+	fimc_md_unregister_clk_provider(fmd);
 	v4l2_device_unregister(&fmd->v4l2_dev);
 	device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
 	fimc_md_unregister_entities(fmd);
drivers/media/platform/exynos4-is/media-dev.h +17 -1
index 62599fd..240ca71 100644
@@ -10,6 +10,7 @@
 #define FIMC_MDEVICE_H_
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
@@ -89,6 +90,12 @@ struct fimc_sensor_info {
 	struct fimc_dev *host;
 };
 
+struct cam_clk {
+	struct clk_hw hw;
+	struct fimc_md *fmd;
+};
+#define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw)
+
 /**
  * struct fimc_md - fimc media device information
  * @csis: MIPI CSIS subdevs data
@@ -105,6 +112,7 @@ struct fimc_sensor_info {
  * @pinctrl: camera port pinctrl handle
  * @state_default: pinctrl default state handle
  * @state_idle: pinctrl idle state handle
+ * @cam_clk_provider: CAMCLK clock provider structure
  * @user_subdev_api: true if subdevs are not configured by the host driver
  * @slock: spinlock protecting @sensor array
  */
@@ -122,13 +130,21 @@ struct fimc_md {
 	struct media_device media_dev;
 	struct v4l2_device v4l2_dev;
 	struct platform_device *pdev;
+
 	struct fimc_pinctrl {
 		struct pinctrl *pinctrl;
 		struct pinctrl_state *state_default;
 		struct pinctrl_state *state_idle;
 	} pinctl;
-	bool user_subdev_api;
 
+	struct cam_clk_provider {
+		struct clk *clks[FIMC_MAX_CAMCLKS];
+		struct clk_onecell_data clk_data;
+		struct device_node *of_node;
+		struct cam_clk camclk[FIMC_MAX_CAMCLKS];
+	} clk_provider;
+
+	bool user_subdev_api;
 	spinlock_t slock;
 	struct list_head pipelines;
 };
Signature · 2 lines
Cheers,
Mauro
#8 lore raw

PATCH v3 4/6 exynos4-is: Add clock provider for the external clocks

Quoted 55 lines · Mauro Carvalho Chehab

Em Thu, 17 Oct 2013 20:06:49 +0200
Sylwester Nawrocki<[email protected]> escreveu:

Quoted 52 lines

This patch adds clock provider to expose the sclk_cam0/1 clocks for external image sensor devices.

---
Changes since v2:
- use 'camera' DT node drirectly as clock provider node, rather than creating additional clock-controller child node.

---
  .../devicetree/bindings/media/samsung-fimc.txt     |   15 ++-
  drivers/media/platform/exynos4-is/media-dev.c      |  108 ++++++++++++++++++++
  drivers/media/platform/exynos4-is/media-dev.h      |   18 +++-
  3 files changed, 137 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/media/samsung-fimc.txt +11 -2
index 96312f6..968e065 100644
@@ -32,6 +32,15 @@ way around.
 
  The 'camera' node must include at least one 'fimc' child node.
 
+Optional properties:
+
+- #clock-cells: from the common clock bindings (../clock/clock-bindings.txt),
+  must be 1. A clock provider is associated with the camera node and it should
+  be referenced by external sensors that use clocks provided by the SoC on
+  CAM_*_CLKOUT pins. The second cell of the clock specifier is a clock's index.
+  The indexes are 0, 1 for CAM_A_CLKOUT, CAM_B_CLKOUT clocks respectively.
+
+
  'fimc' device nodes
  -------------------
 
@@ -114,7 +123,7 @@ Example:
  			vddio-supply =<...>;
 
  			clock-frequency =<24000000>;
-			clocks =<...>;
+			clocks =<&camera 1>;
  			clock-names = "mclk";
 
  			port {
@@ -135,7 +144,7 @@ Example:
  			vddio-supply =<...>;
 
  			clock-frequency =<24000000>;
-			clocks =<...>;
+			clocks =<&camera 0>;
  			clock-names = "mclk";
 
Quoted 13 lines

Documentation/devicetree/bindings/media/samsung-fimc.txt Example: · line 166

Quoted 10 lines
Documentation/devicetree/bindings/media/samsung-fimc.txt +1 -1
  			port {
@@ -151,8 +160,8 @@ Example:
  		compatible = "samsung,fimc", "simple-bus";
  		#address-cells =<1>;
  		#size-cells =<1>;
+		#clock-cells =<1>;
  		status = "okay";
-
  		pinctrl-names = "default";
  		pinctrl-0 =<&cam_port_a_clk_active>;

I didn't see the above on the patch series you sent me on your git pull request. Where is it?

Mauro, I've moved it into a separate patch, since it is more appropriate as that's a change in the DT binding [1].

My plan was to send it through the devicetree tree with your Ack, but I forgot to resend the whole series. Sorry about that.

Moreover I did this split because you are requiring an explicit ACK from a DT maintainer for anything that is related to devicetree. I believe it is physically impossible to have every single patch acked by a DT maintainer. Subsystem maintainers should handle minor stuff, otherwise we won't be able to have _anything_ merged upstream.

Pinging the DT maintainers for every single patch seems a bit silly and I'm already fed up with it. I find this whole process frustrating and very long times to get things merged really discourage to develop anything in mainline.

[...]

Quoted 9 lines
Quoted 9 lines
Documentation/devicetree/bindings/media/samsung-fimc.txt +9 -0
+static const char *cam_clk_p_names[] = { "sclk_cam0", "sclk_cam1" };
+
+static void fimc_md_unregister_clk_provider(struct fimc_md *fmd)
+{
+	struct cam_clk_provider *cp =&fmd->clk_provider;
+	unsigned int i;
+
+	if (cp->of_node)
+		of_clk_del_provider(cp->of_node);
Quoted 8 lines

Documentation/devicetree/bindings/media/samsung-fimc.txt

Quoted 4 lines
Documentation/devicetree/bindings/media/samsung-fimc.txt +4 -0
+
+	for (i = 0; i<  ARRAY_SIZE(cp->clks); i++)
+		if (!IS_ERR(cp->clks[i]))
+			clk_unregister(cp->clks[i]);

Huh? Why to initialize an array with an error code??? Does it make sense to have one of the clocks with an error and the others ok, and to store the error code? The code below doesn't seem to allow that.

If fimc_md_unregister_clk_provider() fails at any point fimc_md_register_clk_provider() can be called to undo what has been registered successfully. That's the point of storing the error codes. The error paths in probe() are already complex enough.

Quoted 4 lines

Just initialize cp->clks with zero and test it with:

	if (cp->clks[i])
		clk_unregister(cp->clks[i]);

I'm afraid this is incorrect, clock pointers should be treated as opaque cookies and tested only with IS_ERR(). Clk users should not assume NULL clk pointer indicate an invalid clock.

Quoted 1 line

That makes it easier to understand and review.

Maybe it is easier to understand but it is a wrong API usage. And I believe it should never be suggested in reviews.

Quoted 13 lines

Documentation/devicetree/bindings/media/samsung-fimc.txt

Quoted 10 lines
Documentation/devicetree/bindings/media/samsung-fimc.txt +10 -0
+}
+
+static int fimc_md_register_clk_provider(struct fimc_md *fmd)
+{
+	struct cam_clk_provider *cp =&fmd->clk_provider;
+	struct device *dev =&fmd->pdev->dev;
+	int i, ret;
+
+	for (i = 0; i<  ARRAY_SIZE(cp->clks); i++)
+		cp->clks[i] = ERR_PTR(-EINVAL);

That looks weird for me, due to several reasons:

Quoted 3 lines

1) ARRAY_SIZE(cp->clks) is equal to FIMC_MAX_CAMCLKS. Why are you using different syntaxes on the first loop and on the next one? Just to loose more time from reviewers to double check what number is bigger?

The loop limit argument is valid, I can correct that so the code is easier to follow.

Quoted 5 lines

2) Why don't you just do:

	memset(cp->clks, ARRAY_SIZE(cp->clks), 0).

or initialize struct fimc_md with kzalloc()?

Because it isn't correct. struct fimc_md is already allocated with kzalloc(), I would certainly consider the above simpler code if it were valid.

Quoted 35 lines
Quoted 35 lines
Documentation/devicetree/bindings/media/samsung-fimc.txt +35 -0
+
+	for (i = 0; i<  FIMC_MAX_CAMCLKS; i++) {
+		struct cam_clk *camclk =&cp->camclk[i];
+		struct clk_init_data init;
+		char clk_name[16];
+		struct clk *clk;
+
+		snprintf(clk_name, sizeof(clk_name), "cam_clkout%d", i);
+
+		init.name = clk_name;
+		init.ops =&cam_clk_ops;
+		init.flags = CLK_SET_RATE_PARENT;
+		init.parent_names =&cam_clk_p_names[i];
+		init.num_parents = 1;
+		camclk->hw.init =&init;
+		camclk->fmd = fmd;
+
+		clk = clk_register(dev,&camclk->hw);
+		if (IS_ERR(clk)) {
+			dev_err(dev, "failed to register clock: %s (%ld)\n",
+						clk_name, PTR_ERR(clk));
+			ret = PTR_ERR(clk);
+			goto err;
+		}
+		cp->clks[i] = clk;
+	}
+
+	cp->clk_data.clks = cp->clks;
+	cp->clk_data.clk_num = i;
+	cp->of_node = dev->of_node;
+
+	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
+				&cp->clk_data);
+	if (!ret)
+		return 0;
Quoted 8 lines

Documentation/devicetree/bindings/media/samsung-fimc.txt

Quoted 8 lines
Documentation/devicetree/bindings/media/samsung-fimc.txt +8 -0
+err:
+	fimc_md_unregister_clk_provider(fmd);
+	return ret;
+}
+#else
+#define fimc_md_register_clk_provider(fmd) (0)
+#define fimc_md_unregister_clk_provider(fmd) (0)
+#endif

--
Regards,
Sylwester

[1]
http://git.linuxtv.org/snawrocki/samsung.git/shortlog/refs/heads/v3.14-exynos4-is-dt

author maintainer
#9 lore raw

PATCH v3 5/6 exynos4-is: Use external s5k6a3 sensor driver

In reply to Sylwester Nawrocki

This patch removes the common fimc-is-sensor driver for image sensors that are normally controlled by the FIMC-IS firmware. The FIMC-IS driver now contains only a table of properties specific to each sensor. The sensor properties required for the ISP's firmware are parsed from device tree and retrieved from the internal table, which is selected based on the compatible property of an image sensor.

To use the Exynos4x12 internal ISP the S5K6A3 sensor driver (drivers/ media/i2c/s5k6a3.c) is now required.

---
 drivers/media/platform/exynos4-is/fimc-is-regs.c   |    2 +-
 drivers/media/platform/exynos4-is/fimc-is-sensor.c |  285 +-------------------
 drivers/media/platform/exynos4-is/fimc-is-sensor.h |   49 +---
 drivers/media/platform/exynos4-is/fimc-is.c        |   97 +++----
 drivers/media/platform/exynos4-is/fimc-is.h        |    4 +-
 5 files changed, 57 insertions(+), 380 deletions(-)
drivers/media/platform/exynos4-is/fimc-is-regs.c +1 -1
index f758e26..c1bc76d 100644
@@ -136,7 +136,7 @@ void fimc_is_hw_set_sensor_num(struct fimc_is *is)
 	mcuctl_write(IH_REPLY_DONE, is, MCUCTL_REG_ISSR(0));
 	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
 	mcuctl_write(IHC_GET_SENSOR_NUM, is, MCUCTL_REG_ISSR(2));
-	mcuctl_write(FIMC_IS_SENSOR_NUM, is, MCUCTL_REG_ISSR(3));
+	mcuctl_write(FIMC_IS_SENSORS_NUM, is, MCUCTL_REG_ISSR(3));
 }
 
 void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index)
drivers/media/platform/exynos4-is/fimc-is-sensor.c +7 -278

310 lines not on this page · raw message

drivers/media/platform/exynos4-is/fimc-is-sensor.h +8 -41

77 lines not on this page · raw message

drivers/media/platform/exynos4-is/fimc-is.c +39 -58

159 lines not on this page · raw message

drivers/media/platform/exynos4-is/fimc-is.h +2 -2
index 61bb012..01f802f 100644
@@ -39,7 +39,7 @@
 #define FIMC_IS_FW_LOAD_TIMEOUT		1000 /* ms */
 #define FIMC_IS_POWER_ON_TIMEOUT	1000 /* us */
 
-#define FIMC_IS_SENSOR_NUM		2
+#define FIMC_IS_SENSORS_NUM		2
 
 /* Memory definitions */
 #define FIMC_IS_CPU_MEM_SIZE		(0xa00000)
@@ -253,7 +253,7 @@ struct fimc_is {
 	struct firmware			*f_w;
 
 	struct fimc_isp			isp;
-	struct fimc_is_sensor		*sensor;
+	struct fimc_is_sensor		sensor[FIMC_IS_SENSORS_NUM];
 	struct fimc_is_setfile		setfile;
 
 	struct vb2_alloc_ctx		*alloc_ctx;
Signature · 1 line
1.7.9.5
author maintainer
#10 lore raw

PATCH v3 6/6 exynos4-is: Add support for asynchronous subdevices registration

In reply to Sylwester Nawrocki

Add support for registering external sensor subdevs using the v4l2-async API. The async API is used only for sensor subdevs and only for dt platforms.

---
 .../devicetree/bindings/media/samsung-fimc.txt     |    4 +-
 drivers/media/platform/exynos4-is/media-dev.c      |  233 +++++++++++---------
 drivers/media/platform/exynos4-is/media-dev.h      |   13 +-
 3 files changed, 146 insertions(+), 104 deletions(-)
Documentation/devicetree/bindings/media/samsung-fimc.txt +2 -2
index 968e065..f8aaf3b 100644
@@ -106,8 +106,8 @@ Image sensor nodes
 The sensor device nodes should be added to their control bus controller (e.g.
 I2C0) nodes and linked to a port node in the csis or the parallel-ports node,
 using the common video interfaces bindings, defined in video-interfaces.txt.
-The implementation of this bindings requires clock-frequency property to be
-present in the sensor device nodes.
+An optional clock-frequency property needs to be present in the sensor device
+nodes. Default value when this property is not present is 24 MHz.
 
 Example:
 
drivers/media/platform/exynos4-is/media-dev.c +132 -101

355 lines not on this page · raw message

drivers/media/platform/exynos4-is/media-dev.h +12 -1
index 240ca71..169972a 100644
@@ -32,8 +32,9 @@
 
 #define PINCTRL_STATE_IDLE	"idle"
 
-#define FIMC_MAX_SENSORS	8
+#define FIMC_MAX_SENSORS	4
 #define FIMC_MAX_CAMCLKS	2
+#define DEFAULT_SENSOR_CLK_FREQ	24000000U
 
 /* LCD/ISP Writeback clocks (PIXELASYNCMx) */
 enum {
@@ -79,6 +80,7 @@ struct fimc_camclk_info {
 /**
  * struct fimc_sensor_info - image data source subdev information
  * @pdata: sensor's atrributes passed as media device's platform data
+ * @asd: asynchronous subdev registration data structure
  * @subdev: image sensor v4l2 subdev
  * @host: fimc device the sensor is currently linked to
  *
@@ -86,6 +88,7 @@ struct fimc_camclk_info {
  */
 struct fimc_sensor_info {
 	struct fimc_source_info pdata;
+	struct v4l2_async_subdev asd;
 	struct v4l2_subdev *subdev;
 	struct fimc_dev *host;
 };
@@ -144,6 +147,9 @@ struct fimc_md {
 		struct cam_clk camclk[FIMC_MAX_CAMCLKS];
 	} clk_provider;
 
+	struct v4l2_async_notifier subdev_notifier;
+	struct v4l2_async_subdev *async_subdevs[FIMC_MAX_SENSORS];
+
 	bool user_subdev_api;
 	spinlock_t slock;
 	struct list_head pipelines;
@@ -161,6 +167,11 @@ static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
 		container_of(me->parent, struct fimc_md, media_dev);
 }
 
+static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
+{
+	return container_of(n, struct fimc_md, subdev_notifier);
+}
+
 static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
 {
 	mutex_lock(&ve->vdev.entity.parent->graph_mutex);
Signature · 1 line
1.7.9.5