#include <linux/fwnode.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
+#include <linux/gpio/machine.h>
 #include <linux/i2c.h>
 #include <linux/i2c-mux.h>
 #include <linux/module.h>
        u32 init_rev_chan_mv;
        u32 rev_chan_mv;
 
+       u32 gpio_poc[2];
+
        struct v4l2_ctrl_handler ctrls;
        struct v4l2_ctrl *pixelrate;
 
        return 0;
 }
 
-static void max9286_gpio_set(struct gpio_chip *chip,
-                            unsigned int offset, int value)
+static int max9286_gpio_set(struct max9286_priv *priv, unsigned int offset,
+                           int value)
 {
-       struct max9286_priv *priv = gpiochip_get_data(chip);
-
        if (value)
                priv->gpio_state |= BIT(offset);
        else
                priv->gpio_state &= ~BIT(offset);
 
-       max9286_write(priv, 0x0f, MAX9286_0X0F_RESERVED | priv->gpio_state);
+       return max9286_write(priv, 0x0f,
+                            MAX9286_0X0F_RESERVED | priv->gpio_state);
 }
 
-static int max9286_gpio_get(struct gpio_chip *chip, unsigned int offset)
+static void max9286_gpiochip_set(struct gpio_chip *chip,
+                                unsigned int offset, int value)
+{
+       struct max9286_priv *priv = gpiochip_get_data(chip);
+
+       max9286_gpio_set(priv, offset, value);
+}
+
+static int max9286_gpiochip_get(struct gpio_chip *chip, unsigned int offset)
 {
        struct max9286_priv *priv = gpiochip_get_data(chip);
 
        gpio->owner = THIS_MODULE;
        gpio->ngpio = 2;
        gpio->base = -1;
-       gpio->set = max9286_gpio_set;
-       gpio->get = max9286_gpio_get;
+       gpio->set = max9286_gpiochip_set;
+       gpio->get = max9286_gpiochip_get;
        gpio->can_sleep = true;
 
-       /* GPIO values default to high */
-       priv->gpio_state = BIT(0) | BIT(1);
-
        ret = devm_gpiochip_add_data(dev, gpio, priv);
        if (ret)
                dev_err(dev, "Unable to create gpio_chip\n");
        return ret;
 }
 
+static int max9286_parse_gpios(struct max9286_priv *priv)
+{
+       struct device *dev = &priv->client->dev;
+       int ret;
+
+       /* GPIO values default to high */
+       priv->gpio_state = BIT(0) | BIT(1);
+
+       /*
+        * Parse the "gpio-poc" vendor property. If the property is not
+        * specified the camera power is controlled by a regulator.
+        */
+       ret = of_property_read_u32_array(dev->of_node, "maxim,gpio-poc",
+                                        priv->gpio_poc, 2);
+       if (ret == -EINVAL) {
+               /*
+                * If gpio lines are not used for the camera power, register
+                * a gpio controller for consumers.
+                */
+               ret = max9286_register_gpio(priv);
+               if (ret)
+                       return ret;
+
+               priv->regulator = devm_regulator_get(dev, "poc");
+               if (IS_ERR(priv->regulator)) {
+                       return dev_err_probe(dev, PTR_ERR(priv->regulator),
+                                            "Unable to get PoC regulator (%ld)\n",
+                                            PTR_ERR(priv->regulator));
+               }
+
+               return 0;
+       }
+
+       /* If the property is specified make sure it is well formed. */
+       if (ret || priv->gpio_poc[0] > 1 ||
+           (priv->gpio_poc[1] != GPIO_ACTIVE_HIGH &&
+            priv->gpio_poc[1] != GPIO_ACTIVE_LOW)) {
+               dev_err(dev, "Invalid 'gpio-poc' property\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int max9286_poc_enable(struct max9286_priv *priv, bool enable)
+{
+       int ret;
+
+       /* If the regulator is not available, use gpio to control power. */
+       if (!priv->regulator)
+               ret = max9286_gpio_set(priv, priv->gpio_poc[0],
+                                      enable ^ priv->gpio_poc[1]);
+       else if (enable)
+               ret = regulator_enable(priv->regulator);
+       else
+               ret = regulator_disable(priv->regulator);
+
+       if (ret < 0)
+               dev_err(&priv->client->dev, "Unable to turn power %s\n",
+                       enable ? "on" : "off");
+
+       return ret;
+}
+
 static int max9286_init(struct device *dev)
 {
        struct max9286_priv *priv;
        client = to_i2c_client(dev);
        priv = i2c_get_clientdata(client);
 
-       /* Enable the bus power. */
-       ret = regulator_enable(priv->regulator);
-       if (ret < 0) {
-               dev_err(&client->dev, "Unable to turn PoC on\n");
+       ret = max9286_poc_enable(priv, true);
+       if (ret)
                return ret;
-       }
 
        ret = max9286_setup(priv);
        if (ret) {
                dev_err(dev, "Unable to setup max9286\n");
-               goto err_regulator;
+               goto err_poc_disable;
        }
 
        /*
        ret = max9286_v4l2_register(priv);
        if (ret) {
                dev_err(dev, "Failed to register with V4L2\n");
-               goto err_regulator;
+               goto err_poc_disable;
        }
 
        ret = max9286_i2c_mux_init(priv);
 
 err_v4l2_register:
        max9286_v4l2_unregister(priv);
-err_regulator:
-       regulator_disable(priv->regulator);
+err_poc_disable:
+       max9286_poc_enable(priv, false);
 
        return ret;
 }
         */
        max9286_configure_i2c(priv, false);
 
-       ret = max9286_register_gpio(priv);
+       ret = max9286_parse_gpios(priv);
        if (ret)
                goto err_powerdown;
 
-       priv->regulator = devm_regulator_get(&client->dev, "poc");
-       if (IS_ERR(priv->regulator)) {
-               ret = PTR_ERR(priv->regulator);
-               dev_err_probe(&client->dev, ret,
-                             "Unable to get PoC regulator\n");
-               goto err_powerdown;
-       }
-
        ret = max9286_parse_dt(priv);
        if (ret)
                goto err_powerdown;
 
        max9286_v4l2_unregister(priv);
 
-       regulator_disable(priv->regulator);
+       max9286_poc_enable(priv, false);
 
        gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);