From dc97fa56bcfca7d75bb878b71a4979c4d277e2e6 Mon Sep 17 00:00:00 2001 From: "changhuang.liang" Date: Mon, 18 Apr 2022 19:38:38 +0800 Subject: [PATCH] v4l2: sc2235 sensor use pinctrl set power --- arch/riscv/boot/dts/starfive/jh7110-common.dtsi | 6 +- arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi | 96 ++++++++++++++++++++-- .../media/platform/starfive/v4l2_driver/sc2235.c | 87 +++++++++++++++----- 3 files changed, 162 insertions(+), 27 deletions(-) diff --git a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi index 1660776..8103985 100755 --- a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi @@ -87,8 +87,10 @@ 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 */ diff --git a/arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi b/arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi index 2b85784c..186d96c 100644 --- a/arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi @@ -291,12 +291,12 @@ }; }; - sc2235_pins: sc2235-pins { + sc2235_pins_default: sc2235-pins { sc2235-1V8-pins { sf,pins = ; sf,pinmux = ; sf,pin-ioconfig = ; - sf,pin-gpio-dout = ; + sf,pin-gpio-dout = ; sf,pin-gpio-doen = ; }; @@ -304,7 +304,7 @@ sf,pins = ; sf,pinmux = ; sf,pin-ioconfig = ; - sf,pin-gpio-dout = ; + sf,pin-gpio-dout = ; sf,pin-gpio-doen = ; }; @@ -312,7 +312,7 @@ sf,pins = ; sf,pinmux = ; sf,pin-ioconfig = ; - sf,pin-gpio-dout = ; + sf,pin-gpio-dout = ; sf,pin-gpio-doen = ; }; @@ -320,7 +320,7 @@ sf,pins = ; sf,pinmux = ; sf,pin-ioconfig = ; - sf,pin-gpio-dout = ; + sf,pin-gpio-dout = ; sf,pin-gpio-doen = ; }; @@ -328,7 +328,7 @@ sf,pins = ; sf,pinmux = ; sf,pin-ioconfig = ; - sf,pin-gpio-dout = ; + sf,pin-gpio-dout = ; sf,pin-gpio-doen = ; }; @@ -349,6 +349,90 @@ }; }; + sc2235_reset_low: sc2235-pins { + sc2235-1V8-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + + sc2235-1V5-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + + sc2235-2V8-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + + sc2235-reset-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + + sc2235-pwdn-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + }; + + sc2235_reset_high: sc2235-pins { + sc2235-1V8-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + + sc2235-1V5-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + + sc2235-2V8-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + + sc2235-reset-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + + sc2235-pwdn-pins { + sf,pins = ; + sf,pinmux = ; + sf,pin-ioconfig = ; + sf,pin-gpio-dout = ; + sf,pin-gpio-doen = ; + }; + }; + dvp_pins: dvp-pins { dvp-clk-pins { sf,pins = ; diff --git a/drivers/media/platform/starfive/v4l2_driver/sc2235.c b/drivers/media/platform/starfive/v4l2_driver/sc2235.c index 1fec4c9..9bdb4ef 100755 --- a/drivers/media/platform/starfive/v4l2_driver/sc2235.c +++ b/drivers/media/platform/starfive/v4l2_driver/sc2235.c @@ -25,6 +25,7 @@ #include #include #include +#include #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 | -- 2.7.4