v4l2: sc2235 sensor use pinctrl set power
authorchanghuang.liang <changhuang.liang@starfivetech.com>
Mon, 18 Apr 2022 11:38:38 +0000 (19:38 +0800)
committerchanghuang.liang <changhuang.liang@starfivetech.com>
Tue, 26 Apr 2022 09:39:36 +0000 (17:39 +0800)
arch/riscv/boot/dts/starfive/jh7110-common.dtsi
arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi
drivers/media/platform/starfive/v4l2_driver/sc2235.c

index 1660776..8103985 100755 (executable)
                sc2235-pwdn-gpios = <&gpio 15 0>;
                sc2235-esync-gpios = <&gpio 17 0>;
                sc2235-oen-gpios = <&gpio 18 0>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&sc2235_pins>;
+               pinctrl-names = "default", "reset_low", "reset_high";
+               pinctrl-0 = <&sc2235_pins_default>;
+               pinctrl-1 = <&sc2235_reset_low>;
+               pinctrl-2 = <&sc2235_reset_high>;
 
                port {
                        /* Parallel bus endpoint */
index 2b85784..186d96c 100644 (file)
                };
        };
 
-       sc2235_pins: sc2235-pins {
+       sc2235_pins_default: sc2235-pins {
                sc2235-1V8-pins {
                        sf,pins = <PAD_GPIO11>;
                        sf,pinmux = <PAD_GPIO11_FUNC_SEL 0>;
                        sf,pin-ioconfig = <IO(GPIO_IE(1))>;
-                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
                        sf,pin-gpio-doen = <OEN_LOW>;
                };
 
                        sf,pins = <PAD_GPIO12>;
                        sf,pinmux = <PAD_GPIO12_FUNC_SEL 0>;
                        sf,pin-ioconfig = <IO(GPIO_IE(1))>;
-                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
                        sf,pin-gpio-doen = <OEN_LOW>;
                };
 
                        sf,pins = <PAD_GPIO10>;
                        sf,pinmux = <PAD_GPIO10_FUNC_SEL 0>;
                        sf,pin-ioconfig = <IO(GPIO_IE(1))>;
-                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
                        sf,pin-gpio-doen = <OEN_LOW>;
                };
 
                        sf,pins = <PAD_GPIO16>;
                        sf,pinmux = <PAD_GPIO16_FUNC_SEL 0>;
                        sf,pin-ioconfig = <IO(GPIO_IE(1))>;
-                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
                        sf,pin-gpio-doen = <OEN_LOW>;
                };
 
                        sf,pins = <PAD_GPIO15>;
                        sf,pinmux = <PAD_GPIO15_FUNC_SEL 0>;
                        sf,pin-ioconfig = <IO(GPIO_IE(1))>;
-                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
                        sf,pin-gpio-doen = <OEN_LOW>;
                };
 
                };
        };
 
+       sc2235_reset_low: sc2235-pins {
+               sc2235-1V8-pins {
+                       sf,pins = <PAD_GPIO11>;
+                       sf,pinmux = <PAD_GPIO11_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+
+               sc2235-1V5-pins {
+                       sf,pins = <PAD_GPIO12>;
+                       sf,pinmux = <PAD_GPIO12_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+
+               sc2235-2V8-pins {
+                       sf,pins = <PAD_GPIO10>;
+                       sf,pinmux = <PAD_GPIO10_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+
+               sc2235-reset-pins {
+                       sf,pins = <PAD_GPIO16>;
+                       sf,pinmux = <PAD_GPIO16_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+
+               sc2235-pwdn-pins {
+                       sf,pins = <PAD_GPIO15>;
+                       sf,pinmux = <PAD_GPIO15_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_LOW>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+       };
+
+       sc2235_reset_high: sc2235-pins {
+               sc2235-1V8-pins {
+                       sf,pins = <PAD_GPIO11>;
+                       sf,pinmux = <PAD_GPIO11_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+
+               sc2235-1V5-pins {
+                       sf,pins = <PAD_GPIO12>;
+                       sf,pinmux = <PAD_GPIO12_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+
+               sc2235-2V8-pins {
+                       sf,pins = <PAD_GPIO10>;
+                       sf,pinmux = <PAD_GPIO10_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+
+               sc2235-reset-pins {
+                       sf,pins = <PAD_GPIO16>;
+                       sf,pinmux = <PAD_GPIO16_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+
+               sc2235-pwdn-pins {
+                       sf,pins = <PAD_GPIO15>;
+                       sf,pinmux = <PAD_GPIO15_FUNC_SEL 0>;
+                       sf,pin-ioconfig = <IO(GPIO_IE(1))>;
+                       sf,pin-gpio-dout = <GPO_HIGH>;
+                       sf,pin-gpio-doen = <OEN_LOW>;
+               };
+       };
+
        dvp_pins: dvp-pins {
                dvp-clk-pins {
                        sf,pins = <PAD_GPIO21>;
index 1fec4c9..9bdb4ef 100755 (executable)
@@ -25,6 +25,7 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-subdev.h>
+#include <linux/pinctrl/pinctrl.h>
 #include "stfcamss.h"
 
 /* min/typical/max system clock (xclk) frequencies */
@@ -127,6 +128,13 @@ struct sc2235_ctrls {
        struct v4l2_ctrl *vflip;
 };
 
+struct sensor_pinctrl_info {
+       struct pinctrl *pinctrl;
+       struct pinctrl_state *reset_state_low;
+       struct pinctrl_state *reset_state_high;
+       bool use_pinctrl;
+};
+
 struct sc2235_dev {
        struct i2c_client *i2c_client;
        struct v4l2_subdev sd;
@@ -160,8 +168,36 @@ struct sc2235_dev {
 
        bool pending_mode_change;
        bool streaming;
+
+       struct sensor_pinctrl_info sc2235_pctrl;
 };
 
+int sc2235_sensor_pinctrl_init(
+        struct sensor_pinctrl_info *sensor_pctrl, struct device *dev)
+{
+       sensor_pctrl->pinctrl = devm_pinctrl_get(dev);
+       if (IS_ERR_OR_NULL(sensor_pctrl->pinctrl)) {
+               pr_err("Getting pinctrl handle failed\n");
+               return -EINVAL;
+       }
+       sensor_pctrl->reset_state_low
+               = pinctrl_lookup_state(sensor_pctrl->pinctrl, "reset_low");
+       if (IS_ERR_OR_NULL(sensor_pctrl->reset_state_low)) {
+               pr_err("Failed to get the reset_low pinctrl handle\n");
+               return -EINVAL;
+       }
+       sensor_pctrl->reset_state_high
+               = pinctrl_lookup_state(sensor_pctrl->pinctrl, "reset_high");
+       if (IS_ERR_OR_NULL(sensor_pctrl->reset_state_high)) {
+               pr_err("Failed to get the reset_high pinctrl handle\n");
+               return -EINVAL;
+       }
+
+       sensor_pctrl->use_pinctrl = true;
+
+       return 0;
+}
+
 static inline struct sc2235_dev *to_sc2235_dev(struct v4l2_subdev *sd)
 {
        return container_of(sd, struct sc2235_dev, sd);
@@ -827,6 +863,7 @@ static void sc2235_reset(struct sc2235_dev *sensor)
 static int sc2235_set_power_on(struct sc2235_dev *sensor)
 {
        struct i2c_client *client = sensor->i2c_client;
+       struct sensor_pinctrl_info *sensor_pctrl = &sensor->sc2235_pctrl;
        int ret;
 
        ret = clk_prepare_enable(sensor->xclk);
@@ -844,8 +881,16 @@ static int sc2235_set_power_on(struct sc2235_dev *sensor)
                goto xclk_off;
        }
 
-       sc2235_reset(sensor);
-       sc2235_power(sensor, true);
+       if (sensor_pctrl->use_pinctrl) {
+               ret = pinctrl_select_state(
+                       sensor_pctrl->pinctrl,
+                       sensor_pctrl->reset_state_high);
+               if (ret)
+                       pr_err("cannot set reset pin to high\n");
+       } else {
+               sc2235_reset(sensor);
+               sc2235_power(sensor, true);
+       }
 
        return 0;
 
@@ -856,7 +901,19 @@ xclk_off:
 
 static void sc2235_set_power_off(struct sc2235_dev *sensor)
 {
-       sc2235_power(sensor, false);
+       struct sensor_pinctrl_info *sensor_pctrl = &sensor->sc2235_pctrl;
+       int ret;
+
+       if (sensor_pctrl->use_pinctrl) {
+               ret = pinctrl_select_state(
+                       sensor_pctrl->pinctrl,
+                       sensor_pctrl->reset_state_low);
+               if (ret)
+                       pr_err("cannot set reset pin to low\n");
+       } else {
+               sc2235_power(sensor, false);
+       }
+
        regulator_bulk_disable(SC2235_NUM_SUPPLIES, sensor->supplies);
        clk_disable_unprepare(sensor->xclk);
 }
@@ -1726,22 +1783,14 @@ static int sc2235_probe(struct i2c_client *client)
                        sensor->xclk_freq);
                return -EINVAL;
        }
-#if 0
-       /*At present, the GPIO of the sensor is configured in the Uboot system,
-       and these GPIOs are controlled by the kernel GPIO subsystem API after
-        it is ready 2021 1110 */
-       /* request optional power down pin */
-       sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
-                                               GPIOD_OUT_HIGH);
-       if (IS_ERR(sensor->pwdn_gpio))
-               return PTR_ERR(sensor->pwdn_gpio);
-
-       /* request optional reset pin */
-       sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
-                                               GPIOD_OUT_HIGH);
-       if (IS_ERR(sensor->reset_gpio))
-               return PTR_ERR(sensor->reset_gpio);
-#endif
+
+       ret = sc2235_sensor_pinctrl_init(&sensor->sc2235_pctrl, dev);
+       if (ret) {
+               pr_err("Can't get pinctrl, use gpio to ctrl\n");
+               sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+               sensor->sc2235_pctrl.use_pinctrl = false;
+       }
+
        v4l2_i2c_subdev_init(&sensor->sd, client, &sc2235_subdev_ops);
 
        sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |