summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 3873ccc)
raw | patch | inline | side by side (parent: 3873ccc)
author | Nikhil Devshatwar <nikhil.nd@ti.com> | |
Thu, 5 Dec 2013 18:13:37 +0000 (23:43 +0530) | ||
committer | Arthur Philpott <arthur.philpott@ti.com> | |
Wed, 12 Feb 2014 21:47:47 +0000 (15:47 -0600) |
Don't select muxing GPIOs from sensor name
- Removed sensor_name from private data
Detect sensor connector from the I2C slave address
Request all GPIOs only once and set them before s_fmt
- Static flag to avoid multiple requests
Change-Id: Ic83e3b4d14d2fd423a709b4906212f71c4266cc3
Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
- Removed sensor_name from private data
Detect sensor connector from the I2C slave address
Request all GPIOs only once and set them before s_fmt
- Static flag to avoid multiple requests
Change-Id: Ic83e3b4d14d2fd423a709b4906212f71c4266cc3
Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
drivers/media/i2c/ov1063x.c | patch | blob | history |
index 2ba3baed6bd270aa8fdcdf6e75a255b945d2f6c1..3c42adbbb1d702bc6c278c5713199f21eac32332 100644 (file)
u8 val;
};
+enum sensor_connector {
+ BASE_LI,
+ VIS_LI,
+ VIS_OVCAM,
+ VIS_SERDES
+};
+
struct ov1063x_priv {
struct v4l2_subdev subdev;
struct v4l2_async_subdev asd;
int width;
int height;
- const char *sensor_name;
- int mux_gpio;
+ enum sensor_connector sensor_connector;
+ struct gpio mux_gpios[10];
+ int num_gpios;
int mux1_sel0_gpio;
int mux1_sel1_gpio;
int mux2_sel0_gpio;
int ov_pwdn_gpio;
};
+static int gpio_requested;
+
+static int ov1063x_init_sensor(struct i2c_client *client);
+static int ov1063x_request_gpios(struct i2c_client *client);
+
+static int ov1063x_set_gpios(struct i2c_client *client, int vin2_s0_val,
+ int cam_fpd_mux_s0_val, int mux1_sel0_val, int mux1_sel1_val,
+ int mux2_sel0_val, int mux2_sel1_val, int ov_pwdn_val);
+
static const struct ov1063x_reg ov1063x_regs_default[] = {
/* Register configuration for full resolution : 1280x720 */
{0x103, 0x1}, /** Software Reset */
struct ov1063x_priv *priv = to_ov1063x(client);
int ret;
+ ret = ov1063x_init_sensor(client);
+ if (ret) {
+ dev_err(&client->dev, "Failed to request gpios");
+ return ret;
+ }
+
ret = ov1063x_set_params(client, &mf->width, &mf->height,
mf->code);
if (!ret)
return 0;
}
-static int ov1063x_init_sensor(struct i2c_client *client)
+static int ov1063x_set_gpios(struct i2c_client *client, int vin2_s0_val,
+ int cam_fpd_mux_s0_val, int mux1_sel0_val, int mux1_sel1_val,
+ int mux2_sel0_val, int mux2_sel1_val, int ov_pwdn_val) {
+
+ struct ov1063x_priv *priv = to_ov1063x(client);
+ int ret = 0, X = -1;
+
+ ret = ov1063x_request_gpios(client);
+ if (ret)
+ return ret;
+
+ if (vin2_s0_val != X)
+ ret = gpio_direction_output(priv->vin2_s0_gpio,
+ vin2_s0_val);
+ if (ret)
+ return ret;
+
+ if (cam_fpd_mux_s0_val != X)
+ ret = gpio_direction_output(priv->cam_fpd_mux_s0_gpio,
+ cam_fpd_mux_s0_val);
+ if (ret)
+ return ret;
+
+ if (mux1_sel0_val != X)
+ ret = gpio_direction_output(priv->mux1_sel0_gpio,
+ mux1_sel0_val);
+ if (ret)
+ return ret;
+
+ if (mux1_sel1_val != X)
+ ret = gpio_direction_output(priv->mux1_sel1_gpio,
+ mux1_sel1_val);
+ if (ret)
+ return ret;
+
+ if (mux2_sel0_val != X)
+ ret = gpio_direction_output(priv->mux2_sel0_gpio,
+ mux2_sel0_val);
+ if (ret)
+ return ret;
+
+ if (mux2_sel1_val != X)
+ ret = gpio_direction_output(priv->mux2_sel1_gpio,
+ mux2_sel1_val);
+ if (ret)
+ return ret;
+
+ if (ov_pwdn_val != X)
+ ret = gpio_direction_output(priv->ov_pwdn_gpio,
+ ov_pwdn_val);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ov1063x_request_gpios(struct i2c_client *client)
+
{
struct ov1063x_priv *priv = to_ov1063x(client);
int r;
- if (strcmp(priv->sensor_name, "ov10633") == 0) {
- struct gpio gpios[] = {
- { priv->cam_fpd_mux_s0_gpio, GPIOF_OUT_INIT_LOW,
- "cam_fpd_mux_s0_gpio"},
- };
-
- r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
- if (r)
- return r;
- } else if (strcmp(priv->sensor_name, "ov10635") == 0) {
- struct gpio gpios[] = {
+ if (gpio_requested == 1)
+ return 0;
+
+ struct gpio gpios[] = {
{ priv->vin2_s0_gpio, GPIOF_OUT_INIT_LOW,
"vin2_s0" },
{ priv->cam_fpd_mux_s0_gpio, GPIOF_OUT_INIT_HIGH,
"mux2_sel1" },
{ priv->ov_pwdn_gpio, GPIOF_OUT_INIT_LOW,
"ov_pwdn" },
- };
+ };
- r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
- if (r)
- return r;
- }
+ r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+ if (r)
+ return r;
+ else
+ gpio_requested = 1;
return 0;
}
-static void ov1063x_uninit_sensor(struct i2c_client *client)
+static int ov1063x_detect_sensor(struct i2c_client *client)
{
struct ov1063x_priv *priv = to_ov1063x(client);
- if (strcmp(priv->sensor_name, "ov10633") == 0) {
- gpio_free(priv->cam_fpd_mux_s0_gpio);
- } else if (strcmp(priv->sensor_name, "ov10635") == 0) {
- gpio_free(priv->vin2_s0_gpio);
- gpio_free(priv->cam_fpd_mux_s0_gpio);
- gpio_free(priv->mux1_sel0_gpio);
- gpio_free(priv->mux1_sel1_gpio);
- gpio_free(priv->mux2_sel0_gpio);
- gpio_free(priv->mux2_sel1_gpio);
- gpio_free(priv->ov_pwdn_gpio);
+
+ /* This can be done by adding a dt property also */
+ switch (client->addr) {
+ case 0x30:
+ priv->sensor_connector = VIS_OVCAM;
+ break;
+
+ case 0x37:
+ priv->sensor_connector = BASE_LI;
+ break;
+
+ case 0x33:
+ priv->sensor_connector = VIS_LI;
+ break;
+
+ case 0x38:
+ case 0x39:
+ case 0x3a:
+ case 0x3b:
+ case 0x3c:
+ case 0x3d:
+ priv->sensor_connector = VIS_SERDES;
+ break;
+ default:
+ return -EINVAL;
}
+ return 0;
+}
+
+static int ov1063x_init_sensor(struct i2c_client *client)
+{
+ struct ov1063x_priv *priv = to_ov1063x(client);
+ int ret, X = -1;
+
+ switch (priv->sensor_connector) {
+ case VIS_OVCAM:
+ ret = ov1063x_set_gpios(client, 0, 1, 1, 0, 0, 0, 1);
+ break;
+ case VIS_SERDES:
+ ret = ov1063x_set_gpios(client, 0, 1, X, X, 0, 1, 1);
+ break;
+ case VIS_LI:
+ ret = ov1063x_set_gpios(client, 0, 1, 0, 0, 1, 0, 1);
+ break;
+ case BASE_LI:
+ ret = ov1063x_set_gpios(client, X, 0, X, X, X, X, X);
+ break;
+ default:
+ dev_err(&client->dev, "Unknown connector!\n");
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static void ov1063x_uninit_sensor(struct i2c_client *client)
+{
+ struct ov1063x_priv *priv = to_ov1063x(client);
+
+ gpio_free(priv->vin2_s0_gpio);
+ gpio_free(priv->cam_fpd_mux_s0_gpio);
+ gpio_free(priv->mux1_sel0_gpio);
+ gpio_free(priv->mux1_sel1_gpio);
+ gpio_free(priv->mux2_sel0_gpio);
+ gpio_free(priv->mux2_sel1_gpio);
+ gpio_free(priv->ov_pwdn_gpio);
+
+ gpio_requested = 0;
}
static const struct of_device_id ov1063x_dt_id[];
static int sensor_get_gpios(struct device_node *node, struct i2c_client *client)
{
struct ov1063x_priv *priv = to_ov1063x(client);
- const struct of_device_id *of_dev_id;
- const char *sensor;
int gpio;
- int err;
- of_dev_id = of_match_device(ov1063x_dt_id, &client->dev);
- if (!of_dev_id) {
- dev_err(&client->dev, "%s: Unable to match device\n", __func__);
- return -ENODEV;
- }
- sensor = (const char *)of_dev_id->data;
- if (strcmp(sensor, "ov10635") == 0)
- node = of_find_compatible_node(NULL, NULL, "ti,camera-ov10635");
- else if (strcmp(sensor, "ov10633") == 0)
- node = of_find_compatible_node(NULL, NULL, "ti,camera-ov10633");
- else
- dev_err(&client->dev, "Invalid sensor\n");
+ node = of_find_compatible_node(NULL, NULL, "ti,camera-ov10635");
- priv->sensor_name = sensor;
-
- if (strcmp(priv->sensor_name, "ov10635") == 0) {
- gpio = of_get_gpio(node, 0);
- if (gpio_is_valid(gpio)) {
- priv->vin2_s0_gpio = gpio;
- } else {
- dev_err(&client->dev, "failed to parse VIN2_S0 gpio\n");
- return -EINVAL;
- }
+ gpio = of_get_gpio(node, 0);
+ if (gpio_is_valid(gpio)) {
+ priv->vin2_s0_gpio = gpio;
+ } else {
+ dev_err(&client->dev, "failed to parse VIN2_S0 gpio\n");
+ return -EINVAL;
+ }
- gpio = of_get_gpio(node, 1);
- if (gpio_is_valid(gpio)) {
- priv->cam_fpd_mux_s0_gpio = gpio;
- } else {
- dev_err(&client->dev, "failed to parse CAM_FPD_MUX_S0 gpio\n");
- return -EINVAL;
- }
+ gpio = of_get_gpio(node, 1);
+ if (gpio_is_valid(gpio)) {
+ priv->cam_fpd_mux_s0_gpio = gpio;
+ } else {
+ dev_err(&client->dev, "failed to parse CAM_FPD_MUX_S0 gpio\n");
+ return -EINVAL;
+ }
- gpio = of_get_gpio(node, 2);
- if (gpio_is_valid(gpio)) {
- priv->mux1_sel0_gpio = gpio;
- } else {
- dev_err(&client->dev, "failed to parse MUX1_SEL0 gpio\n");
- return -EINVAL;
- }
+ gpio = of_get_gpio(node, 2);
+ if (gpio_is_valid(gpio)) {
+ priv->mux1_sel0_gpio = gpio;
+ } else {
+ dev_err(&client->dev, "failed to parse MUX1_SEL0 gpio\n");
+ return -EINVAL;
+ }
- gpio = of_get_gpio(node, 3);
- if (gpio_is_valid(gpio)) {
- priv->mux1_sel1_gpio = gpio;
- } else {
- dev_err(&client->dev, "failed to parse MUX1_SEL1 gpio\n");
- return -EINVAL;
- }
+ gpio = of_get_gpio(node, 3);
+ if (gpio_is_valid(gpio)) {
+ priv->mux1_sel1_gpio = gpio;
+ } else {
+ dev_err(&client->dev, "failed to parse MUX1_SEL1 gpio\n");
+ return -EINVAL;
+ }
- gpio = of_get_gpio(node, 4);
- if (gpio_is_valid(gpio)) {
- priv->mux2_sel0_gpio = gpio;
- } else {
- dev_err(&client->dev, "failed to parse MUX2_SEL0 gpio\n");
- return -EINVAL;
- }
+ gpio = of_get_gpio(node, 4);
+ if (gpio_is_valid(gpio)) {
+ priv->mux2_sel0_gpio = gpio;
+ } else {
+ dev_err(&client->dev, "failed to parse MUX2_SEL0 gpio\n");
+ return -EINVAL;
+ }
- gpio = of_get_gpio(node, 5);
- if (gpio_is_valid(gpio)) {
- priv->mux2_sel1_gpio = gpio;
- } else {
- dev_err(&client->dev, "failed to parse MUX2_SEL1 gpio\n");
- return -EINVAL;
- }
+ gpio = of_get_gpio(node, 5);
+ if (gpio_is_valid(gpio)) {
+ priv->mux2_sel1_gpio = gpio;
+ } else {
+ dev_err(&client->dev, "failed to parse MUX2_SEL1 gpio\n");
+ return -EINVAL;
+ }
- gpio = of_get_gpio(node, 6);
- if (gpio_is_valid(gpio)) {
- priv->ov_pwdn_gpio = gpio;
- } else {
- dev_err(&client->dev, "failed to parse OV_PWDN gpio\n");
- return -EINVAL;
- }
- } else if (strcmp(priv->sensor_name, "ov10633") == 0) {
- gpio = of_get_gpio(node, 1);
- if (gpio_is_valid(gpio)) {
- priv->cam_fpd_mux_s0_gpio = gpio;
- } else {
- dev_err(&client->dev, "failed to parse CAM_FPD_MUX_S0 gpio\n");
- return -EINVAL;
- }
+ gpio = of_get_gpio(node, 6);
+ if (gpio_is_valid(gpio)) {
+ priv->ov_pwdn_gpio = gpio;
} else {
- dev_err(&client->dev, "Invalid sensor name\n");
- return -ENODEV;
+ dev_err(&client->dev, "failed to parse OV_PWDN gpio\n");
+ return -EINVAL;
}
return 0;
if (priv->hdl.error)
return priv->hdl.error;
+ ret = ov1063x_detect_sensor(client);
+ if (ret) {
+ dev_err(&client->dev, "Unknown sensor\n");
+ return ret;
+ }
+
ret = sensor_get_gpios(node, client);
if (ret) {
dev_err(&client->dev, "Unable to get gpios\n");