Commit 4163851f authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab

[media] s5p-fimc: Use pinctrl API for camera ports configuration

Before the camera ports can be used the pinmux needs to be configured
properly. This patch adds a function to set the camera ports pinctrl
to a default state within the media driver's probe().
The camera port(s) are then configured for the video bus operation.
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2b13f7d4
...@@ -21,6 +21,15 @@ Required properties: ...@@ -21,6 +21,15 @@ Required properties:
- clock-names : must contain "fimc", "sclk_fimc" entries, matching entries - clock-names : must contain "fimc", "sclk_fimc" entries, matching entries
in the clocks property. in the clocks property.
The pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt must be used
to define a required pinctrl state named "default" and optional pinctrl states:
"idle", "active-a", active-b". These optional states can be used to switch the
camera port pinmux at runtime. The "idle" state should configure both the camera
ports A and B into high impedance state, especially the CAMCLK clock output
should be inactive. For the "active-a" state the camera port A must be activated
and the port B deactivated and for the state "active-b" it should be the other
way around.
The 'camera' node must include at least one 'fimc' child node. The 'camera' node must include at least one 'fimc' child node.
...@@ -146,6 +155,9 @@ Example: ...@@ -146,6 +155,9 @@ Example:
#size-cells = <1>; #size-cells = <1>;
status = "okay"; status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cam_port_a_clk_active>;
/* parallel camera ports */ /* parallel camera ports */
parallel-ports { parallel-ports {
/* camera A input */ /* camera A input */
......
...@@ -1174,6 +1174,25 @@ static ssize_t fimc_md_sysfs_store(struct device *dev, ...@@ -1174,6 +1174,25 @@ static ssize_t fimc_md_sysfs_store(struct device *dev,
static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO, static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
fimc_md_sysfs_show, fimc_md_sysfs_store); fimc_md_sysfs_show, fimc_md_sysfs_store);
static int fimc_md_get_pinctrl(struct fimc_md *fmd)
{
struct device *dev = &fmd->pdev->dev;
struct fimc_pinctrl *pctl = &fmd->pinctl;
pctl->pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(pctl->pinctrl))
return PTR_ERR(pctl->pinctrl);
pctl->state_default = pinctrl_lookup_state(pctl->pinctrl,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(pctl->state_default))
return PTR_ERR(pctl->state_default);
pctl->state_idle = pinctrl_lookup_state(pctl->pinctrl,
PINCTRL_STATE_IDLE);
return 0;
}
static int fimc_md_probe(struct platform_device *pdev) static int fimc_md_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -1217,6 +1236,13 @@ static int fimc_md_probe(struct platform_device *pdev) ...@@ -1217,6 +1236,13 @@ static int fimc_md_probe(struct platform_device *pdev)
/* Protect the media graph while we're registering entities */ /* Protect the media graph while we're registering entities */
mutex_lock(&fmd->media_dev.graph_mutex); mutex_lock(&fmd->media_dev.graph_mutex);
ret = fimc_md_get_pinctrl(fmd);
if (ret < 0) {
if (ret != EPROBE_DEFER)
dev_err(dev, "Failed to get pinctrl: %d\n", ret);
goto err_unlock;
}
if (dev->of_node) if (dev->of_node)
ret = fimc_md_register_of_platform_entities(fmd, dev->of_node); ret = fimc_md_register_of_platform_entities(fmd, dev->of_node);
else else
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/pinctrl/consumer.h>
#include <media/media-device.h> #include <media/media-device.h>
#include <media/media-entity.h> #include <media/media-entity.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
...@@ -26,6 +27,8 @@ ...@@ -26,6 +27,8 @@
#define FIMC_IS_OF_NODE_NAME "fimc-is" #define FIMC_IS_OF_NODE_NAME "fimc-is"
#define CSIS_OF_NODE_NAME "csis" #define CSIS_OF_NODE_NAME "csis"
#define PINCTRL_STATE_IDLE "idle"
/* Group IDs of sensor, MIPI-CSIS, FIMC-LITE and the writeback subdevs. */ /* Group IDs of sensor, MIPI-CSIS, FIMC-LITE and the writeback subdevs. */
#define GRP_ID_SENSOR (1 << 8) #define GRP_ID_SENSOR (1 << 8)
#define GRP_ID_FIMC_IS_SENSOR (1 << 9) #define GRP_ID_FIMC_IS_SENSOR (1 << 9)
...@@ -73,6 +76,9 @@ struct fimc_sensor_info { ...@@ -73,6 +76,9 @@ struct fimc_sensor_info {
* @media_dev: top level media device * @media_dev: top level media device
* @v4l2_dev: top level v4l2_device holding up the subdevs * @v4l2_dev: top level v4l2_device holding up the subdevs
* @pdev: platform device this media device is hooked up into * @pdev: platform device this media device is hooked up into
* @pinctrl: camera port pinctrl handle
* @state_default: pinctrl default state handle
* @state_idle: pinctrl idle state handle
* @user_subdev_api: true if subdevs are not configured by the host driver * @user_subdev_api: true if subdevs are not configured by the host driver
* @slock: spinlock protecting @sensor array * @slock: spinlock protecting @sensor array
*/ */
...@@ -86,6 +92,11 @@ struct fimc_md { ...@@ -86,6 +92,11 @@ struct fimc_md {
struct media_device media_dev; struct media_device media_dev;
struct v4l2_device v4l2_dev; struct v4l2_device v4l2_dev;
struct platform_device *pdev; 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; bool user_subdev_api;
spinlock_t slock; spinlock_t slock;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment