Commit 3bc80e89 authored by Dave Stevenson's avatar Dave Stevenson Committed by Mauro Carvalho Chehab
Browse files

media: i2c: ov9282: Add support for regulators.



The sensor takes 3 supply rails - AVDD, DVDD, and DOVDD.

Add hooks into the regulator framework for each of these
regulators.

Signed-off-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 91707453
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>

#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
@@ -91,6 +92,14 @@
#define OV9282_REG_MIN		0x00
#define OV9282_REG_MAX		0xfffff

static const char * const ov9282_supply_names[] = {
	"avdd",		/* Analog power */
	"dovdd",	/* Digital I/O power */
	"dvdd",		/* Digital core power */
};

#define OV9282_NUM_SUPPLIES ARRAY_SIZE(ov9282_supply_names)

/**
 * struct ov9282_reg - ov9282 sensor register
 * @address: Register address
@@ -162,6 +171,7 @@ struct ov9282 {
	struct media_pad pad;
	struct gpio_desc *reset_gpio;
	struct clk *inclk;
	struct regulator_bulk_data supplies[OV9282_NUM_SUPPLIES];
	struct v4l2_ctrl_handler ctrl_handler;
	struct v4l2_ctrl *link_freq_ctrl;
	struct v4l2_ctrl *hblank_ctrl;
@@ -1081,6 +1091,18 @@ static int ov9282_detect(struct ov9282 *ov9282)
	return 0;
}

static int ov9282_configure_regulators(struct ov9282 *ov9282)
{
	unsigned int i;

	for (i = 0; i < OV9282_NUM_SUPPLIES; i++)
		ov9282->supplies[i].supply = ov9282_supply_names[i];

	return devm_regulator_bulk_get(ov9282->dev,
				       OV9282_NUM_SUPPLIES,
				       ov9282->supplies);
}

/**
 * ov9282_parse_hw_config() - Parse HW configuration and check if supported
 * @ov9282: pointer to ov9282 device
@@ -1117,6 +1139,12 @@ static int ov9282_parse_hw_config(struct ov9282 *ov9282)
		return PTR_ERR(ov9282->inclk);
	}

	ret = ov9282_configure_regulators(ov9282);
	if (ret) {
		dev_err(ov9282->dev, "Failed to get power regulators\n");
		return ret;
	}

	rate = clk_get_rate(ov9282->inclk);
	if (rate != OV9282_INCLK_RATE) {
		dev_err(ov9282->dev, "inclk frequency mismatch");
@@ -1198,6 +1226,12 @@ static int ov9282_power_on(struct device *dev)
	struct ov9282 *ov9282 = to_ov9282(sd);
	int ret;

	ret = regulator_bulk_enable(OV9282_NUM_SUPPLIES, ov9282->supplies);
	if (ret < 0) {
		dev_err(dev, "Failed to enable regulators\n");
		return ret;
	}

	usleep_range(400, 600);

	gpiod_set_value_cansleep(ov9282->reset_gpio, 1);
@@ -1223,6 +1257,8 @@ static int ov9282_power_on(struct device *dev)
error_reset:
	gpiod_set_value_cansleep(ov9282->reset_gpio, 0);

	regulator_bulk_disable(OV9282_NUM_SUPPLIES, ov9282->supplies);

	return ret;
}

@@ -1241,6 +1277,8 @@ static int ov9282_power_off(struct device *dev)

	clk_disable_unprepare(ov9282->inclk);

	regulator_bulk_disable(OV9282_NUM_SUPPLIES, ov9282->supplies);

	return 0;
}