@@ -1064,13 +1064,33 @@ static ssize_t fimc_md_sysfs_store(struct device *dev,
static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
fimc_md_sysfs_show, fimc_md_sysfs_store);
+static int fimc_md_get_pinctrl(struct fimc_md *fmd)
+{
+ fmd->pinctl = devm_pinctrl_get_select_default(&fmd->pdev->dev);
+ if (IS_ERR(fmd->pinctl))
+ return PTR_ERR(fmd->pinctl);
+
+ fmd->pinctl_state_default = pinctrl_lookup_state(fmd->pinctl,
+ PINCTRL_STATE_DEFAULT);
+ if (IS_ERR(fmd->pinctl_state_default))
+ return PTR_ERR(fmd->pinctl_state_default);
+
+ fmd->pinctl_state_idle = pinctrl_lookup_state(fmd->pinctl,
+ PINCTRL_STATE_INACTIVE);
+ if (IS_ERR(fmd->pinctl_state_idle))
+ return PTR_ERR(fmd->pinctl_state_idle);
+
+ return 0;
+}
+
static int fimc_md_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct v4l2_device *v4l2_dev;
struct fimc_md *fmd;
int ret;
- fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL);
+ fmd = devm_kzalloc(dev, sizeof(*fmd), GFP_KERNEL);
if (!fmd)
return -ENOMEM;
@@ -1080,7 +1100,7 @@ static int fimc_md_probe(struct platform_device *pdev)
strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
sizeof(fmd->media_dev.model));
fmd->media_dev.link_notify = fimc_md_link_notify;
- fmd->media_dev.dev = &pdev->dev;
+ fmd->media_dev.dev = dev;
v4l2_dev = &fmd->v4l2_dev;
v4l2_dev->mdev = &fmd->media_dev;
@@ -1088,7 +1108,7 @@ static int fimc_md_probe(struct platform_device *pdev)
strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name));
- ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev);
+ 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;
@@ -1107,15 +1127,22 @@ static int fimc_md_probe(struct platform_device *pdev)
/* Protect the media graph while we're registering entities */
mutex_lock(&fmd->media_dev.graph_mutex);
+ if (dev->of_node) {
+ ret = fimc_md_get_pinctrl(fmd);
+ if (ret < 0)
+ goto err_unlock;
+ }
+
ret = fimc_md_register_platform_entities(fmd);
if (ret)
goto err_unlock;
- if (pdev->dev.platform_data || pdev->dev.of_node) {
+ if (dev->platform_data || dev->of_node) {
ret = fimc_md_register_sensor_entities(fmd);
if (ret)
goto err_unlock;
}
+
ret = fimc_md_create_links(fmd);
if (ret)
goto err_unlock;
@@ -10,6 +10,7 @@
#define FIMC_MDEVICE_H_
#include <linux/clk.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <media/media-device.h>
@@ -25,6 +26,8 @@
#define FIMC_LITE_OF_NODE_NAME "fimc_lite"
#define CSIS_OF_NODE_NAME "csis"
+#define PINCTRL_STATE_INACTIVE "inactive"
+
/* Group IDs of sensor, MIPI-CSIS, FIMC-LITE and the writeback subdevs. */
#define GRP_ID_SENSOR (1 << 8)
#define GRP_ID_FIMC_IS_SENSOR (1 << 9)
@@ -85,6 +88,9 @@ struct fimc_md {
struct media_device media_dev;
struct v4l2_device v4l2_dev;
struct platform_device *pdev;
+ struct pinctrl *pinctl;
+ struct pinctrl_state *pinctl_state_default;
+ struct pinctrl_state *pinctl_state_idle;
bool user_subdev_api;
spinlock_t slock;
};