Commit 23a52386 authored by Janusz Krzysztofik's avatar Janusz Krzysztofik Committed by Mauro Carvalho Chehab

media: ov6650: convert to standalone v4l2 subdevice

Remove the soc_camera dependencies and move the diver to i2c

Lost features, fortunately not used or not critical on test platform:
- soc_camera power on/off callback - replaced with clock enable/disable
  only, no support for platform provided regulators nor power callback,
- soc_camera sense request - replaced with arbitrarily selected default
  master clock rate and pixel clock limit, no support for platform
  requested values,
- soc_camera board flags - no support for platform requested mbus config
  tweaks.

Tested on Amstrad Delta with now out of tree but still locally
maintained omap1_camera host driver.
Signed-off-by: default avatarJanusz Krzysztofik <jmkrzyszt@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 474dfccf
...@@ -593,6 +593,17 @@ config VIDEO_OV5647 ...@@ -593,6 +593,17 @@ config VIDEO_OV5647
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ov5647. module will be called ov5647.
config VIDEO_OV6650
tristate "OmniVision OV6650 sensor support"
depends on I2C && VIDEO_V4L2
depends on MEDIA_CAMERA_SUPPORT
---help---
This is a Video4Linux2 sensor-level driver for the OmniVision
OV6650 camera.
To compile this driver as a module, choose M here: the
module will be called ov6650.
config VIDEO_OV7640 config VIDEO_OV7640
tristate "OmniVision OV7640 sensor support" tristate "OmniVision OV7640 sensor support"
depends on I2C && VIDEO_V4L2 depends on I2C && VIDEO_V4L2
......
...@@ -62,6 +62,7 @@ obj-$(CONFIG_VIDEO_OV2640) += ov2640.o ...@@ -62,6 +62,7 @@ obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
obj-$(CONFIG_VIDEO_OV5640) += ov5640.o obj-$(CONFIG_VIDEO_OV5640) += ov5640.o
obj-$(CONFIG_VIDEO_OV5645) += ov5645.o obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
obj-$(CONFIG_VIDEO_OV5647) += ov5647.o obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
obj-$(CONFIG_VIDEO_OV7640) += ov7640.o obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
obj-$(CONFIG_VIDEO_OV9650) += ov9650.o obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
......
/* /*
* V4L2 SoC Camera driver for OmniVision OV6650 Camera Sensor * V4L2 subdevice driver for OmniVision OV6650 Camera Sensor
* *
* Copyright (C) 2010 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> * Copyright (C) 2010 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
* *
...@@ -31,9 +31,9 @@ ...@@ -31,9 +31,9 @@
#include <linux/v4l2-mediabus.h> #include <linux/v4l2-mediabus.h>
#include <linux/module.h> #include <linux/module.h>
#include <media/soc_camera.h>
#include <media/v4l2-clk.h> #include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
/* Register definitions */ /* Register definitions */
#define REG_GAIN 0x00 /* range 00 - 3F */ #define REG_GAIN 0x00 /* range 00 - 3F */
...@@ -426,10 +426,15 @@ static int ov6650_set_register(struct v4l2_subdev *sd, ...@@ -426,10 +426,15 @@ static int ov6650_set_register(struct v4l2_subdev *sd,
static int ov6650_s_power(struct v4l2_subdev *sd, int on) static int ov6650_s_power(struct v4l2_subdev *sd, int on)
{ {
struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
struct ov6650 *priv = to_ov6650(client); struct ov6650 *priv = to_ov6650(client);
int ret = 0;
return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); if (on)
ret = v4l2_clk_enable(priv->clk);
else
v4l2_clk_disable(priv->clk);
return ret;
} }
static int ov6650_get_selection(struct v4l2_subdev *sd, static int ov6650_get_selection(struct v4l2_subdev *sd,
...@@ -471,14 +476,13 @@ static int ov6650_set_selection(struct v4l2_subdev *sd, ...@@ -471,14 +476,13 @@ static int ov6650_set_selection(struct v4l2_subdev *sd,
sel->target != V4L2_SEL_TGT_CROP) sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL; return -EINVAL;
rect.left = ALIGN(rect.left, 2); v4l_bound_align_image(&rect.width, 2, W_CIF, 1,
rect.width = ALIGN(rect.width, 2); &rect.height, 2, H_CIF, 1, 0);
rect.top = ALIGN(rect.top, 2); v4l_bound_align_image(&rect.left, DEF_HSTRT << 1,
rect.height = ALIGN(rect.height, 2); (DEF_HSTRT << 1) + W_CIF - (__s32)rect.width, 1,
soc_camera_limit_side(&rect.left, &rect.width, &rect.top, DEF_VSTRT << 1,
DEF_HSTRT << 1, 2, W_CIF); (DEF_VSTRT << 1) + H_CIF - (__s32)rect.height, 1,
soc_camera_limit_side(&rect.top, &rect.height, 0);
DEF_VSTRT << 1, 2, H_CIF);
ret = ov6650_reg_write(client, REG_HSTRT, rect.left >> 1); ret = ov6650_reg_write(client, REG_HSTRT, rect.left >> 1);
if (!ret) { if (!ret) {
...@@ -547,8 +551,6 @@ static u8 to_clkrc(struct v4l2_fract *timeperframe, ...@@ -547,8 +551,6 @@ static u8 to_clkrc(struct v4l2_fract *timeperframe,
static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
{ {
struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
struct soc_camera_sense *sense = icd->sense;
struct ov6650 *priv = to_ov6650(client); struct ov6650 *priv = to_ov6650(client);
bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect);
struct v4l2_subdev_selection sel = { struct v4l2_subdev_selection sel = {
...@@ -640,32 +642,10 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) ...@@ -640,32 +642,10 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
} }
priv->half_scale = half_scale; priv->half_scale = half_scale;
if (sense) { clkrc = CLKRC_12MHz;
if (sense->master_clock == 8000000) { mclk = 12000000;
dev_dbg(&client->dev, "8MHz input clock\n"); priv->pclk_limit = 1334000;
clkrc = CLKRC_6MHz; dev_dbg(&client->dev, "using 12MHz input clock\n");
} else if (sense->master_clock == 12000000) {
dev_dbg(&client->dev, "12MHz input clock\n");
clkrc = CLKRC_12MHz;
} else if (sense->master_clock == 16000000) {
dev_dbg(&client->dev, "16MHz input clock\n");
clkrc = CLKRC_16MHz;
} else if (sense->master_clock == 24000000) {
dev_dbg(&client->dev, "24MHz input clock\n");
clkrc = CLKRC_24MHz;
} else {
dev_err(&client->dev,
"unsupported input clock, check platform data\n");
return -EINVAL;
}
mclk = sense->master_clock;
priv->pclk_limit = sense->pixel_clock_max;
} else {
clkrc = CLKRC_24MHz;
mclk = 24000000;
priv->pclk_limit = 0;
dev_dbg(&client->dev, "using default 24MHz input clock\n");
}
clkrc |= to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); clkrc |= to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max);
...@@ -899,8 +879,6 @@ static const struct v4l2_subdev_core_ops ov6650_core_ops = { ...@@ -899,8 +879,6 @@ static const struct v4l2_subdev_core_ops ov6650_core_ops = {
static int ov6650_g_mbus_config(struct v4l2_subdev *sd, static int ov6650_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg) struct v4l2_mbus_config *cfg)
{ {
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
cfg->flags = V4L2_MBUS_MASTER | cfg->flags = V4L2_MBUS_MASTER |
V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
...@@ -908,7 +886,6 @@ static int ov6650_g_mbus_config(struct v4l2_subdev *sd, ...@@ -908,7 +886,6 @@ static int ov6650_g_mbus_config(struct v4l2_subdev *sd,
V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
V4L2_MBUS_DATA_ACTIVE_HIGH; V4L2_MBUS_DATA_ACTIVE_HIGH;
cfg->type = V4L2_MBUS_PARALLEL; cfg->type = V4L2_MBUS_PARALLEL;
cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
return 0; return 0;
} }
...@@ -918,25 +895,23 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd, ...@@ -918,25 +895,23 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
const struct v4l2_mbus_config *cfg) const struct v4l2_mbus_config *cfg)
{ {
struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg);
int ret; int ret;
if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0); ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
else else
ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING); ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
if (ret) if (ret)
return ret; return ret;
if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0); ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
else else
ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW); ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
if (ret) if (ret)
return ret; return ret;
if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0); ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
else else
ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH); ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
...@@ -973,14 +948,8 @@ static int ov6650_probe(struct i2c_client *client, ...@@ -973,14 +948,8 @@ static int ov6650_probe(struct i2c_client *client,
const struct i2c_device_id *did) const struct i2c_device_id *did)
{ {
struct ov6650 *priv; struct ov6650 *priv;
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
int ret; int ret;
if (!ssdd) {
dev_err(&client->dev, "Missing platform_data for driver\n");
return -EINVAL;
}
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) { if (!priv) {
dev_err(&client->dev, dev_err(&client->dev,
......
...@@ -47,12 +47,6 @@ config SOC_CAMERA_OV5642 ...@@ -47,12 +47,6 @@ config SOC_CAMERA_OV5642
help help
This is a V4L2 camera driver for the OmniVision OV5642 sensor This is a V4L2 camera driver for the OmniVision OV5642 sensor
config SOC_CAMERA_OV6650
tristate "ov6650 sensor support"
depends on SOC_CAMERA && I2C
---help---
This is a V4L2 SoC camera driver for the OmniVision OV6650 sensor
config SOC_CAMERA_OV772X config SOC_CAMERA_OV772X
tristate "ov772x camera support" tristate "ov772x camera support"
depends on SOC_CAMERA && I2C depends on SOC_CAMERA && I2C
......
...@@ -4,7 +4,6 @@ obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o ...@@ -4,7 +4,6 @@ obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment