summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTroy Kisky <troy.kisky@boundarydevices.com>2013-06-04 18:26:46 -0700
committerEric Nelson <eric.nelson@boundarydevices.com>2013-09-03 14:12:28 -0700
commit032fb3740225bc178df5595084eafeb29580b488 (patch)
treed67954c87a35275b92fe30da75fe49a5d584e41b /drivers
parentc77ec8fc7e7d7fcf89e5ab59465cda4ab42fa711 (diff)
adv7180: cleanup
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/mxc/capture/adv7180.c1019
1 files changed, 555 insertions, 464 deletions
diff --git a/drivers/media/video/mxc/capture/adv7180.c b/drivers/media/video/mxc/capture/adv7180.c
index 3c12fdc7d14c..66cc2850b9d5 100644
--- a/drivers/media/video/mxc/capture/adv7180.c
+++ b/drivers/media/video/mxc/capture/adv7180.c
@@ -32,12 +32,6 @@
#include <media/v4l2-int-device.h>
#include "mxc_v4l2_capture.h"
-static struct regulator *dvddio_regulator;
-static struct regulator *dvdd_regulator;
-static struct regulator *avdd_regulator;
-static struct regulator *pvdd_regulator;
-static struct fsl_mxc_tvin_platform_data *tvin_plat;
-
extern void gpio_sensor_active(void);
extern void gpio_sensor_inactive(void);
@@ -65,11 +59,21 @@ static struct i2c_driver adv7180_i2c_driver = {
/*!
* Maintains the information on the current state of the sensor.
*/
-struct sensor {
+struct adv7180_priv {
struct sensor_data sen;
v4l2_std_id std_id;
-} adv7180_data;
+#define DVDDIO_REG 0
+#define DVDD_REG 1
+#define AVDD_REG 2
+#define PVDD_REG 3
+ struct regulator *regulators[4];
+ void (*pwdn)(int pwdn);
+ void (*reset)(void);
+ bool cvbs;
+};
+static void adv7180_hard_reset(struct adv7180_priv *adv);
+static int set_power(struct adv7180_priv *adv, int on);
/*! List of input video formats supported. The video formats is corresponding
* with v4l2 id in video_fmt_t
@@ -139,6 +143,7 @@ static DEFINE_MUTEX(mutex);
#define IF_NAME "adv7180"
#define ADV7180_INPUT_CTL 0x00 /* Input Control */
#define ADV7180_STATUS_1 0x10 /* Status #1 */
+#define ADV7180_STATUS_2 0x12 /* Status #2 */
#define ADV7180_BRIGHTNESS 0x0a /* Brightness */
#define ADV7180_IDENT 0x11 /* IDENT */
#define ADV7180_VSYNC_FIELD_CTL_1 0x31 /* VSYNC Field Control #1 */
@@ -173,7 +178,7 @@ static struct v4l2_queryctrl adv7180_qctrl[] = {
};
/***********************************************************************
- * I2C transfert.
+ * I2C transfer.
***********************************************************************/
/*! Read one register from a ADV7180 i2c slave device.
@@ -182,12 +187,13 @@ static struct v4l2_queryctrl adv7180_qctrl[] = {
*
* @return 0 if success, an error code otherwise.
*/
-static inline int adv7180_read(u8 reg)
+static inline int adv7180_read(struct adv7180_priv *adv, u8 reg)
{
int val;
- val = i2c_smbus_read_byte_data(adv7180_data.sen.i2c_client, reg);
+
+ val = i2c_smbus_read_byte_data(adv->sen.i2c_client, reg);
if (val < 0) {
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
"%s:read reg error: reg=%2x\n", __func__, reg);
return -1;
}
@@ -200,13 +206,13 @@ static inline int adv7180_read(u8 reg)
*
* @return 0 if success, an error code otherwise.
*/
-static int adv7180_write_reg(u8 reg, u8 val)
+static int adv7180_write_reg(struct adv7180_priv *adv, u8 reg, u8 val)
{
s32 ret;
- ret = i2c_smbus_write_byte_data(adv7180_data.sen.i2c_client, reg, val);
+ ret = i2c_smbus_write_byte_data(adv->sen.i2c_client, reg, val);
if (ret < 0) {
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
"%s:write reg error:reg=%2x,val=%2x\n", __func__,
reg, val);
return -1;
@@ -218,48 +224,77 @@ static int adv7180_write_reg(u8 reg, u8 val)
* mxc_v4l2_capture interface.
***********************************************************************/
-/*!
- * Return attributes of current video standard.
- * Since this device autodetects the current standard, this function also
- * sets the values that need to be changed if the standard changes.
- * There is no set std equivalent function.
- *
- * @return None.
- */
-static void adv7180_get_std(v4l2_std_id *std)
+void get_std(struct adv7180_priv *adv)
{
int tmp;
int idx;
+ unsigned long orig_jiffies = jiffies;
+ v4l2_std_id std_id;
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_get_std\n");
-
- /* Read the AD_RESULT to get the detect output video standard */
- tmp = adv7180_read(ADV7180_STATUS_1) & 0x70;
-
+ dev_dbg(&adv->sen.i2c_client->dev, "In adv7180_get_std\n");
+ while (1) {
+ /* Read the AD_RESULT to get the detect output video standard */
+ tmp = adv7180_read(adv, ADV7180_STATUS_1);
+ pr_info("%s: status_1=%x\n", __func__, tmp);
+// if ((tmp & 5) == 5)
+// break;
+ if ((tmp & 0x75) == 5)
+ break;
+ if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(2500))) {
+ dev_err(&adv->sen.i2c_client->dev,
+ "no video lock\n");
+ tmp = 0; /* default to NTSC */
+ break;
+ }
+ msleep(1);
+ }
+ tmp &= 0x70;
mutex_lock(&mutex);
if (tmp == 0x40) {
/* PAL */
- *std = V4L2_STD_PAL;
+ std_id = V4L2_STD_PAL;
idx = ADV7180_PAL;
} else if (tmp == 0) {
/*NTSC*/
- *std = V4L2_STD_NTSC;
+ std_id = V4L2_STD_NTSC;
idx = ADV7180_NTSC;
} else {
- *std = V4L2_STD_ALL;
+ std_id = V4L2_STD_ALL;
idx = ADV7180_NOT_LOCKED;
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
- "Got invalid video standard!\n");
+ dev_err(&adv->sen.i2c_client->dev,
+ "Got invalid video standard(%x,%x)!\n",
+ adv7180_read(adv, ADV7180_STATUS_1),
+ adv7180_read(adv, ADV7180_STATUS_2));
}
- mutex_unlock(&mutex);
/* This assumes autodetect which this device uses. */
- if (*std != adv7180_data.std_id) {
+ if (adv->std_id != std_id) {
+ adv->std_id = std_id;
video_idx = idx;
- adv7180_data.std_id = *std;
- adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
- adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
+ adv->sen.pix.width = video_fmts[video_idx].raw_width;
+ adv->sen.pix.height = video_fmts[video_idx].raw_height;
}
+ mutex_unlock(&mutex);
+}
+
+/*!
+ * Return attributes of current video standard.
+ * Since this device autodetects the current standard, this function also
+ * sets the values that need to be changed if the standard changes.
+ * There is no set std equivalent function.
+ *
+ * @return None.
+ */
+static void adv7180_get_std(struct adv7180_priv *adv, v4l2_std_id *std)
+{
+ dev_dbg(&adv->sen.i2c_client->dev, "In adv7180_get_std\n");
+
+ /* Make sure power is on */
+ set_power(adv, 1);
+ if (adv->std_id == V4L2_STD_ALL)
+ get_std(adv);
+
+ *std = adv->std_id;
}
/***********************************************************************
@@ -283,7 +318,8 @@ static void adv7180_get_std(v4l2_std_id *std)
*/
static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
{
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_ifparm\n");
+ struct adv7180_priv *adv = s->priv;
+ dev_dbg(&adv->sen.i2c_client->dev, "adv7180:ioctl_g_ifparm\n");
if (s == NULL) {
pr_err(" ERROR!! no slave device set!\n");
@@ -315,33 +351,44 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
* Sets devices power state to requrested state, if possible.
* This is called on open, close, suspend and resume.
*/
-static int ioctl_s_power(struct v4l2_int_device *s, int on)
+static int set_power(struct adv7180_priv *adv, int on)
{
- struct sensor *sensor = s->priv;
-
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_s_power\n");
-
- if (on && !sensor->sen.on) {
- gpio_sensor_active();
- if (adv7180_write_reg(ADV7180_PWR_MNG, 0x04) != 0)
- return -EIO;
-
- /*
- * FIXME:Additional 400ms to wait the chip to be stable?
- * This is a workaround for preview scrolling issue.
- */
- msleep(400);
- } else if (!on && sensor->sen.on) {
- if (adv7180_write_reg(ADV7180_PWR_MNG, 0x24) != 0)
- return -EIO;
- gpio_sensor_inactive();
+ dev_dbg(&adv->sen.i2c_client->dev, "adv7180:ioctl_s_power\n");
+
+ if (on != adv->sen.on) {
+ if (on) {
+ gpio_sensor_active();
+
+ if (adv->pwdn)
+ adv->pwdn(0);
+
+ if (adv7180_write_reg(adv, ADV7180_PWR_MNG, 0x04) != 0)
+ return -EIO;
+
+ /*! ADV7180 initialization. */
+ adv7180_hard_reset(adv);
+ /*
+ * Wait for video format detection to be stable
+ */
+ msleep(400);
+ get_std(adv);
+ } else {
+ if (adv7180_write_reg(adv, ADV7180_PWR_MNG, 0x24) != 0)
+ return -EIO;
+ if (adv->pwdn)
+ adv->pwdn(1);
+ gpio_sensor_inactive();
+ }
+ adv->sen.on = on;
}
-
- sensor->sen.on = on;
-
return 0;
}
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ return set_power(s->priv, on);
+}
+
/*!
* ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
* @s: pointer to standard V4L2 device structure
@@ -351,10 +398,10 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
*/
static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct adv7180_priv *adv = s->priv;
struct v4l2_captureparm *cparm = &a->parm.capture;
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_parm\n");
+ dev_dbg(&adv->sen.i2c_client->dev, "In adv7180:ioctl_g_parm\n");
switch (a->type) {
/* These are all the possible cases. */
@@ -362,9 +409,9 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
memset(a, 0, sizeof(*a));
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cparm->capability = sensor->sen.streamcap.capability;
- cparm->timeperframe = sensor->sen.streamcap.timeperframe;
- cparm->capturemode = sensor->sen.streamcap.capturemode;
+ cparm->capability = adv->sen.streamcap.capability;
+ cparm->timeperframe = adv->sen.streamcap.timeperframe;
+ cparm->capturemode = adv->sen.streamcap.capturemode;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -396,22 +443,22 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_parm\n");
+ struct adv7180_priv *adv = s->priv;
+ dev_dbg(&adv->sen.i2c_client->dev, "In adv7180:ioctl_s_parm\n");
switch (a->type) {
/* These are all the possible cases. */
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VBI_CAPTURE:
case V4L2_BUF_TYPE_VBI_OUTPUT:
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- break;
-
default:
pr_debug(" type is unknown - %d\n", a->type);
- break;
+ return -EINVAL;
}
return 0;
@@ -427,26 +474,26 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
{
- struct sensor *sensor = s->priv;
+ struct adv7180_priv *adv = s->priv;
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_fmt_cap\n");
+ dev_dbg(&adv->sen.i2c_client->dev, "adv7180:ioctl_g_fmt_cap\n");
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
pr_debug(" Returning size of %dx%d\n",
- sensor->sen.pix.width, sensor->sen.pix.height);
- f->fmt.pix = sensor->sen.pix;
+ adv->sen.pix.width, adv->sen.pix.height);
+ f->fmt.pix = adv->sen.pix;
break;
case V4L2_BUF_TYPE_PRIVATE: {
v4l2_std_id std;
- adv7180_get_std(&std);
+ adv7180_get_std(adv, &std);
f->fmt.pix.pixelformat = (u32)std;
}
break;
default:
- f->fmt.pix = sensor->sen.pix;
+ f->fmt.pix = adv->sen.pix;
break;
}
@@ -465,9 +512,10 @@ static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
static int ioctl_queryctrl(struct v4l2_int_device *s,
struct v4l2_queryctrl *qc)
{
+ struct adv7180_priv *adv = s->priv;
int i;
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_queryctrl\n");
+ dev_dbg(&adv->sen.i2c_client->dev, "adv7180:ioctl_queryctrl\n");
for (i = 0; i < ARRAY_SIZE(adv7180_qctrl); i++)
if (qc->id && qc->id == adv7180_qctrl[i].id) {
@@ -490,80 +538,84 @@ static int ioctl_queryctrl(struct v4l2_int_device *s,
*/
static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
{
+ struct adv7180_priv *adv = s->priv;
int ret = 0;
int sat = 0;
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_ctrl\n");
+ dev_dbg(&adv->sen.i2c_client->dev, "In adv7180:ioctl_g_ctrl\n");
+
+ /* Make sure power on */
+ set_power(adv, 1);
switch (vc->id) {
case V4L2_CID_BRIGHTNESS:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_BRIGHTNESS\n");
- adv7180_data.sen.brightness = adv7180_read(ADV7180_BRIGHTNESS);
- vc->value = adv7180_data.sen.brightness;
+ adv->sen.brightness = adv7180_read(adv, ADV7180_BRIGHTNESS);
+ vc->value = adv->sen.brightness;
break;
case V4L2_CID_CONTRAST:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_CONTRAST\n");
- vc->value = adv7180_data.sen.contrast;
+ vc->value = adv->sen.contrast;
break;
case V4L2_CID_SATURATION:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_SATURATION\n");
- sat = adv7180_read(ADV7180_SD_SATURATION_CB);
- adv7180_data.sen.saturation = sat;
- vc->value = adv7180_data.sen.saturation;
+ sat = adv7180_read(adv, ADV7180_SD_SATURATION_CB);
+ adv->sen.saturation = sat;
+ vc->value = adv->sen.saturation;
break;
case V4L2_CID_HUE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_HUE\n");
- vc->value = adv7180_data.sen.hue;
+ vc->value = adv->sen.hue;
break;
case V4L2_CID_AUTO_WHITE_BALANCE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_AUTO_WHITE_BALANCE\n");
break;
case V4L2_CID_DO_WHITE_BALANCE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_DO_WHITE_BALANCE\n");
break;
case V4L2_CID_RED_BALANCE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_RED_BALANCE\n");
- vc->value = adv7180_data.sen.red;
+ vc->value = adv->sen.red;
break;
case V4L2_CID_BLUE_BALANCE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_BLUE_BALANCE\n");
- vc->value = adv7180_data.sen.blue;
+ vc->value = adv->sen.blue;
break;
case V4L2_CID_GAMMA:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_GAMMA\n");
break;
case V4L2_CID_EXPOSURE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_EXPOSURE\n");
- vc->value = adv7180_data.sen.ae_mode;
+ vc->value = adv->sen.ae_mode;
break;
case V4L2_CID_AUTOGAIN:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_AUTOGAIN\n");
break;
case V4L2_CID_GAIN:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_GAIN\n");
break;
case V4L2_CID_HFLIP:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_HFLIP\n");
break;
case V4L2_CID_VFLIP:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_VFLIP\n");
break;
default:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" Default case\n");
vc->value = 0;
ret = -EPERM;
@@ -584,77 +636,81 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
*/
static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
{
+ struct adv7180_priv *adv = s->priv;
int retval = 0;
u8 tmp;
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_ctrl\n");
+ dev_dbg(&adv->sen.i2c_client->dev, "In adv7180:ioctl_s_ctrl\n");
+
+ /* Make sure power on */
+ set_power(adv, 1);
switch (vc->id) {
case V4L2_CID_BRIGHTNESS:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_BRIGHTNESS\n");
tmp = vc->value;
- adv7180_write_reg(ADV7180_BRIGHTNESS, tmp);
- adv7180_data.sen.brightness = vc->value;
+ adv7180_write_reg(adv, ADV7180_BRIGHTNESS, tmp);
+ adv->sen.brightness = vc->value;
break;
case V4L2_CID_CONTRAST:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_CONTRAST\n");
break;
case V4L2_CID_SATURATION:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_SATURATION\n");
tmp = vc->value;
- adv7180_write_reg(ADV7180_SD_SATURATION_CB, tmp);
- adv7180_write_reg(ADV7180_SD_SATURATION_CR, tmp);
- adv7180_data.sen.saturation = vc->value;
+ adv7180_write_reg(adv, ADV7180_SD_SATURATION_CB, tmp);
+ adv7180_write_reg(adv, ADV7180_SD_SATURATION_CR, tmp);
+ adv->sen.saturation = vc->value;
break;
case V4L2_CID_HUE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_HUE\n");
break;
case V4L2_CID_AUTO_WHITE_BALANCE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_AUTO_WHITE_BALANCE\n");
break;
case V4L2_CID_DO_WHITE_BALANCE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_DO_WHITE_BALANCE\n");
break;
case V4L2_CID_RED_BALANCE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_RED_BALANCE\n");
break;
case V4L2_CID_BLUE_BALANCE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_BLUE_BALANCE\n");
break;
case V4L2_CID_GAMMA:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_GAMMA\n");
break;
case V4L2_CID_EXPOSURE:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_EXPOSURE\n");
break;
case V4L2_CID_AUTOGAIN:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_AUTOGAIN\n");
break;
case V4L2_CID_GAIN:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_GAIN\n");
break;
case V4L2_CID_HFLIP:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_HFLIP\n");
break;
case V4L2_CID_VFLIP:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" V4L2_CID_VFLIP\n");
break;
default:
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
" Default case\n");
retval = -EPERM;
break;
@@ -674,12 +730,14 @@ static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
static int ioctl_enum_framesizes(struct v4l2_int_device *s,
struct v4l2_frmsizeenum *fsize)
{
- if (fsize->index >= 1)
- return -EINVAL;
+ struct adv7180_priv *adv = s->priv;
- fsize->discrete.width = video_fmts[video_idx].active_width;
- fsize->discrete.height = video_fmts[video_idx].active_height;
+ if (fsize->index > ADV7180_STD_MAX)
+ return -EINVAL;
+ fsize->pixel_format = adv->sen.pix.pixelformat;
+ fsize->discrete.width = video_fmts[fsize->index].active_width;
+ fsize->discrete.height = video_fmts[fsize->index].active_height;
return 0;
}
@@ -703,12 +761,32 @@ static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
}
/*!
+ * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
+ * @s: pointer to standard V4L2 device structure
+ * @fmt: pointer to standard V4L2 fmt description structure
+ *
+ * Return 0.
+ */
+static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
+ struct v4l2_fmtdesc *fmt)
+{
+ struct adv7180_priv *adv = s->priv;
+
+ if (fmt->index > ADV7180_STD_MAX)
+ return -EINVAL;
+ fmt->pixelformat = adv->sen.pix.pixelformat;
+ return 0;
+}
+
+/*!
* ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
* @s: pointer to standard V4L2 device structure
*/
static int ioctl_init(struct v4l2_int_device *s)
{
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_init\n");
+ struct adv7180_priv *adv = s->priv;
+
+ dev_dbg(&adv->sen.i2c_client->dev, "In adv7180:ioctl_init\n");
return 0;
}
@@ -720,7 +798,9 @@ static int ioctl_init(struct v4l2_int_device *s)
*/
static int ioctl_dev_init(struct v4l2_int_device *s)
{
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_dev_init\n");
+ struct adv7180_priv *adv = s->priv;
+
+ dev_dbg(&adv->sen.i2c_client->dev, "adv7180:ioctl_dev_init\n");
return 0;
}
@@ -747,8 +827,8 @@ static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = {
/*!
* VIDIOC_ENUM_FMT ioctl for the CAPTURE buffer type.
*/
-/* {vidioc_int_enum_fmt_cap_num,
- (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */
+ {vidioc_int_enum_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap},
/*!
* VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type.
@@ -773,7 +853,7 @@ static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = {
{vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func*)ioctl_g_ctrl},
{vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
{vidioc_int_enum_framesizes_num,
- (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
+ (v4l2_int_ioctl_func *)ioctl_enum_framesizes},
{vidioc_int_g_chip_ident_num,
(v4l2_int_ioctl_func *)ioctl_g_chip_ident},
};
@@ -792,6 +872,258 @@ static struct v4l2_int_device adv7180_int_device = {
},
};
+/* Datasheet recommends */
+const unsigned char sensor_init_data[] = {
+#if 0
+ 0x04, 0x44,
+ 0x17, 0x01,
+ ADV7180_VSYNC_FIELD_CTL_1, 0x02, //0x31
+ ADV7180_MANUAL_WIN_CTL, 0xa2, //0x3d
+// 0x3E, 0x6A,
+// 0x3F, 0xA0,
+ 0x0E, 0x00,
+ 0x55, 0x81,
+#else
+ 0x01, 0xc8,
+ 0x02, 0x04,
+ 0x03, 0x00,
+ 0x04, 0x44,
+ 0x05, 0x00,
+ 0x06, 0x02,
+ 0x07, 0x7e,
+ 0x08, 0x80,
+ ADV7180_BRIGHTNESS, 0x00,
+ 0x0B, 0x00,
+ 0x0C, 0x36,
+ 0x0D, 0x7C,
+ 0x0E, 0x00,
+ ADV7180_SD_SATURATION_CR, 0x00,
+ 0x13, 0x00,
+ 0x14, 0x12,
+ 0x15, 0x00,
+ 0x16, 0x00,
+ 0x17, 0x01,
+ 0x18, 0x93,
+ 0xF1, 0x19,
+ 0x1A, 0x00,
+ 0x1B, 0x00,
+ 0x1C, 0x00,
+ 0x1D, 0x40,
+ 0x1E, 0x00,
+ 0x1F, 0x00,
+ 0x20, 0x00,
+ 0x21, 0x00,
+ 0x22, 0x00,
+ 0x23, 0xC0,
+ 0x24, 0x00,
+ 0x25, 0x00,
+ 0x26, 0x00,
+ 0x27, 0x58,
+ 0x28, 0x00,
+ 0x29, 0x00,
+ 0x2A, 0x00,
+ 0x2B, 0xE1,
+ 0x2C, 0xAE,
+ 0x2D, 0xF4,
+ 0x2E, 0x00,
+ 0x2F, 0xF0,
+ 0x30, 0x00,
+ ADV7180_VSYNC_FIELD_CTL_1, 0x12,
+ 0x32, 0x41,
+ 0x33, 0x84,
+ 0x34, 0x00,
+ 0x35, 0x02,
+ 0x36, 0x00,
+ 0x37, 0x01,
+ 0x38, 0x80,
+ 0x39, 0xC0,
+ 0x3A, 0x10,
+ 0x3B, 0x05,
+ 0x3C, 0x58,
+ ADV7180_MANUAL_WIN_CTL, 0xB2,
+ 0x3E, 0x64,
+ 0x3F, 0xE4,
+ 0x40, 0x90,
+ 0x41, 0x01,
+ 0x42, 0x7E,
+ 0x43, 0xA4,
+ 0x44, 0xFF,
+ 0x45, 0xB6,
+ 0x46, 0x12,
+ 0x48, 0x00,
+ 0x49, 0x00,
+ 0x4A, 0x00,
+ 0x4B, 0x00,
+ 0x4C, 0x00,
+ 0x4D, 0xEF,
+ 0x4E, 0x08,
+ 0x4F, 0x08,
+ 0x50, 0x08,
+ 0x51, 0x24,
+ 0x52, 0x0B,
+ 0x53, 0x4E,
+ 0x54, 0x80,
+ 0x55, 0x00,
+ 0x56, 0x10,
+ 0x57, 0x00,
+ 0x58, 0x00,
+ 0x59, 0x00,
+ 0x5A, 0x00,
+ 0x5B, 0x00,
+ 0x5C, 0x00,
+ 0x5D, 0x00,
+ 0x5E, 0x00,
+ 0x5F, 0x00,
+ 0x60, 0x00,
+ 0x61, 0x00,
+ 0x62, 0x20,
+ 0x63, 0x00,
+ 0x64, 0x00,
+ 0x65, 0x00,
+ 0x66, 0x00,
+ 0x67, 0x03,
+ 0x68, 0x01,
+ 0x69, 0x00,
+ 0x6A, 0x00,
+ 0x6B, 0xC0,
+ 0x6C, 0x00,
+ 0x6D, 0x00,
+ 0x6E, 0x00,
+ 0x6F, 0x00,
+ 0x70, 0x00,
+ 0x71, 0x00,
+ 0x72, 0x00,
+ 0x73, 0x10,
+ 0x74, 0x04,
+ 0x75, 0x01,
+ 0x76, 0x00,
+ 0x77, 0x3F,
+ 0x78, 0xFF,
+ 0x79, 0xFF,
+ 0x7A, 0xFF,
+ 0x7B, 0x1E,
+ 0x7C, 0xC0,
+ 0x7D, 0x00,
+ 0x7E, 0x00,
+ 0x7F, 0x00,
+ 0x80, 0x00,
+ 0x81, 0xC0,
+ 0x82, 0x04,
+ 0x83, 0x00,
+ 0x84, 0x0C,
+ 0x85, 0x02,
+ 0x86, 0x03,
+ 0x87, 0x63,
+ 0x88, 0x5A,
+ 0x89, 0x08,
+ 0x8A, 0x10,
+ 0x8B, 0x00,
+ 0x8C, 0x40,
+ 0x8D, 0x00,
+ 0x8E, 0x40,
+ 0x8F, 0x00,
+ 0x90, 0x00,
+ 0x91, 0x50,
+ 0x92, 0x00,
+ 0x93, 0x00,
+ 0x94, 0x00,
+ 0x95, 0x00,
+ 0x96, 0x00,
+ 0x97, 0xF0,
+ 0x98, 0x00,
+ 0x99, 0x00,
+ 0x9A, 0x00,
+ 0x9B, 0x00,
+ 0x9C, 0x00,
+ 0x9D, 0x00,
+ 0x9E, 0x00,
+ 0x9F, 0x00,
+ 0xA0, 0x00,
+ 0xA1, 0x00,
+ 0xA2, 0x00,
+ 0xA3, 0x00,
+ 0xA4, 0x00,
+ 0xA5, 0x00,
+ 0xA6, 0x00,
+ 0xA7, 0x00,
+ 0xA8, 0x00,
+ 0xA9, 0x00,
+ 0xAA, 0x00,
+ 0xAB, 0x00,
+ 0xAC, 0x00,
+ 0xAD, 0x00,
+ 0xAE, 0x60,
+ 0xAF, 0x00,
+ 0xB0, 0x00,
+ 0xB1, 0x60,
+ 0xB2, 0x1C,
+ 0xB3, 0x54,
+ 0xB4, 0x00,
+ 0xB5, 0x00,
+ 0xB6, 0x00,
+ 0xB7, 0x13,
+ 0xB8, 0x03,
+ 0xB9, 0x33,
+ 0xBF, 0x02,
+ 0xC0, 0x00,
+ 0xC1, 0x00,
+ 0xC2, 0x00,
+ 0xC3, 0x00,
+ 0xC4, 0x00,
+ 0xC5, 0x81,
+ 0xC6, 0x00,
+ 0xC7, 0x00,
+ 0xC8, 0x00,
+ 0xC9, 0x04,
+ 0xCC, 0x69,
+ 0xCD, 0x00,
+ 0xCE, 0x01,
+ 0xCF, 0xB4,
+ 0xD0, 0x00,
+ 0xD1, 0x10,
+ 0xD2, 0xFF,
+ 0xD3, 0xFF,
+ 0xD4, 0x7F,
+ 0xD5, 0x7F,
+ 0xD6, 0x3E,
+ 0xD7, 0x08,
+ 0xD8, 0x3C,
+ 0xD9, 0x08,
+ 0xDA, 0x3C,
+ 0xDB, 0x9B,
+ 0xDC, 0xAC,
+ 0xDD, 0x4C,
+ 0xDE, 0x00,
+ 0xDF, 0x00,
+ 0xE0, 0x14,
+ 0xE1, 0x80,
+ 0xE2, 0x80,
+ ADV7180_SD_SATURATION_CB, 0x80,
+ ADV7180_SD_SATURATION_CR, 0x80,
+ 0xE5, 0x25,
+ 0xE6, 0x44,
+ 0xE7, 0x63,
+ 0xE8, 0x65,
+ 0xE9, 0x14,
+ 0xEA, 0x63,
+ 0xEB, 0x55,
+ 0xEC, 0x55,
+ 0xEE, 0x00,
+ 0xEF, 0x4A,
+ 0xF0, 0x44,
+ 0xF1, 0x0C,
+ 0xF2, 0x32,
+ 0xF3, 0x00,
+ 0xF4, 0x3F,
+ 0xF5, 0xE0,
+ 0xF6, 0x69,
+ 0xF7, 0x10,
+ 0xF8, 0x00,
+ 0xF9, 0x03,
+ 0xFA, 0xFA,
+ 0xFB, 0x40,
+#endif
+};
/***********************************************************************
* I2C client and driver.
@@ -801,261 +1133,27 @@ static struct v4l2_int_device adv7180_int_device = {
*
* @return None.
*/
-static void adv7180_hard_reset(bool cvbs)
+static void adv7180_hard_reset(struct adv7180_priv *adv)
{
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ int i;
+ const unsigned char *p;
+
+ dev_dbg(&adv->sen.i2c_client->dev,
"In adv7180:adv7180_hard_reset\n");
- if (cvbs) {
+ if (adv->cvbs) {
/* Set CVBS input on AIN1 */
- adv7180_write_reg(ADV7180_INPUT_CTL, 0x00);
+ adv7180_write_reg(adv, ADV7180_INPUT_CTL, 0x50);
} else {
/*
* Set YPbPr input on AIN1,4,5 and normal
* operations(autodection of all stds).
*/
- adv7180_write_reg(ADV7180_INPUT_CTL, 0x09);
+ adv7180_write_reg(adv, ADV7180_INPUT_CTL, 0x09);
+ }
+ for (p = sensor_init_data, i = 0; i < ARRAY_SIZE(sensor_init_data); i += 2, p += 2) {
+ adv7180_write_reg(adv, p[0], p[1]);
}
-
- /* Datasheet recommends */
- adv7180_write_reg(0x01, 0xc8);
- adv7180_write_reg(0x02, 0x04);
- adv7180_write_reg(0x03, 0x00);
- adv7180_write_reg(0x04, 0x45);
- adv7180_write_reg(0x05, 0x00);
- adv7180_write_reg(0x06, 0x02);
- adv7180_write_reg(0x07, 0x7F);
- adv7180_write_reg(0x08, 0x80);
- adv7180_write_reg(0x0A, 0x00);
- adv7180_write_reg(0x0B, 0x00);
- adv7180_write_reg(0x0C, 0x36);
- adv7180_write_reg(0x0D, 0x7C);
- adv7180_write_reg(0x0E, 0x00);
- adv7180_write_reg(0x0F, 0x00);
- adv7180_write_reg(0x13, 0x00);
- adv7180_write_reg(0x14, 0x12);
- adv7180_write_reg(0x15, 0x00);
- adv7180_write_reg(0x16, 0x00);
- adv7180_write_reg(0x17, 0x01);
- adv7180_write_reg(0x18, 0x93);
- adv7180_write_reg(0xF1, 0x19);
- adv7180_write_reg(0x1A, 0x00);
- adv7180_write_reg(0x1B, 0x00);
- adv7180_write_reg(0x1C, 0x00);
- adv7180_write_reg(0x1D, 0x40);
- adv7180_write_reg(0x1E, 0x00);
- adv7180_write_reg(0x1F, 0x00);
- adv7180_write_reg(0x20, 0x00);
- adv7180_write_reg(0x21, 0x00);
- adv7180_write_reg(0x22, 0x00);
- adv7180_write_reg(0x23, 0xC0);
- adv7180_write_reg(0x24, 0x00);
- adv7180_write_reg(0x25, 0x00);
- adv7180_write_reg(0x26, 0x00);
- adv7180_write_reg(0x27, 0x58);
- adv7180_write_reg(0x28, 0x00);
- adv7180_write_reg(0x29, 0x00);
- adv7180_write_reg(0x2A, 0x00);
- adv7180_write_reg(0x2B, 0xE1);
- adv7180_write_reg(0x2C, 0xAE);
- adv7180_write_reg(0x2D, 0xF4);
- adv7180_write_reg(0x2E, 0x00);
- adv7180_write_reg(0x2F, 0xF0);
- adv7180_write_reg(0x30, 0x00);
- adv7180_write_reg(0x31, 0x12);
- adv7180_write_reg(0x32, 0x41);
- adv7180_write_reg(0x33, 0x84);
- adv7180_write_reg(0x34, 0x00);
- adv7180_write_reg(0x35, 0x02);
- adv7180_write_reg(0x36, 0x00);
- adv7180_write_reg(0x37, 0x01);
- adv7180_write_reg(0x38, 0x80);
- adv7180_write_reg(0x39, 0xC0);
- adv7180_write_reg(0x3A, 0x10);
- adv7180_write_reg(0x3B, 0x05);
- adv7180_write_reg(0x3C, 0x58);
- adv7180_write_reg(0x3D, 0xB2);
- adv7180_write_reg(0x3E, 0x64);
- adv7180_write_reg(0x3F, 0xE4);
- adv7180_write_reg(0x40, 0x90);
- adv7180_write_reg(0x41, 0x01);
- adv7180_write_reg(0x42, 0x7E);
- adv7180_write_reg(0x43, 0xA4);
- adv7180_write_reg(0x44, 0xFF);
- adv7180_write_reg(0x45, 0xB6);
- adv7180_write_reg(0x46, 0x12);
- adv7180_write_reg(0x48, 0x00);
- adv7180_write_reg(0x49, 0x00);
- adv7180_write_reg(0x4A, 0x00);
- adv7180_write_reg(0x4B, 0x00);
- adv7180_write_reg(0x4C, 0x00);
- adv7180_write_reg(0x4D, 0xEF);
- adv7180_write_reg(0x4E, 0x08);
- adv7180_write_reg(0x4F, 0x08);
- adv7180_write_reg(0x50, 0x08);
- adv7180_write_reg(0x51, 0x24);
- adv7180_write_reg(0x52, 0x0B);
- adv7180_write_reg(0x53, 0x4E);
- adv7180_write_reg(0x54, 0x80);
- adv7180_write_reg(0x55, 0x00);
- adv7180_write_reg(0x56, 0x10);
- adv7180_write_reg(0x57, 0x00);
- adv7180_write_reg(0x58, 0x00);
- adv7180_write_reg(0x59, 0x00);
- adv7180_write_reg(0x5A, 0x00);
- adv7180_write_reg(0x5B, 0x00);
- adv7180_write_reg(0x5C, 0x00);
- adv7180_write_reg(0x5D, 0x00);
- adv7180_write_reg(0x5E, 0x00);
- adv7180_write_reg(0x5F, 0x00);
- adv7180_write_reg(0x60, 0x00);
- adv7180_write_reg(0x61, 0x00);
- adv7180_write_reg(0x62, 0x20);
- adv7180_write_reg(0x63, 0x00);
- adv7180_write_reg(0x64, 0x00);
- adv7180_write_reg(0x65, 0x00);
- adv7180_write_reg(0x66, 0x00);
- adv7180_write_reg(0x67, 0x03);
- adv7180_write_reg(0x68, 0x01);
- adv7180_write_reg(0x69, 0x00);
- adv7180_write_reg(0x6A, 0x00);
- adv7180_write_reg(0x6B, 0xC0);
- adv7180_write_reg(0x6C, 0x00);
- adv7180_write_reg(0x6D, 0x00);
- adv7180_write_reg(0x6E, 0x00);
- adv7180_write_reg(0x6F, 0x00);
- adv7180_write_reg(0x70, 0x00);
- adv7180_write_reg(0x71, 0x00);
- adv7180_write_reg(0x72, 0x00);
- adv7180_write_reg(0x73, 0x10);
- adv7180_write_reg(0x74, 0x04);
- adv7180_write_reg(0x75, 0x01);
- adv7180_write_reg(0x76, 0x00);
- adv7180_write_reg(0x77, 0x3F);
- adv7180_write_reg(0x78, 0xFF);
- adv7180_write_reg(0x79, 0xFF);
- adv7180_write_reg(0x7A, 0xFF);
- adv7180_write_reg(0x7B, 0x1E);
- adv7180_write_reg(0x7C, 0xC0);
- adv7180_write_reg(0x7D, 0x00);
- adv7180_write_reg(0x7E, 0x00);
- adv7180_write_reg(0x7F, 0x00);
- adv7180_write_reg(0x80, 0x00);
- adv7180_write_reg(0x81, 0xC0);
- adv7180_write_reg(0x82, 0x04);
- adv7180_write_reg(0x83, 0x00);
- adv7180_write_reg(0x84, 0x0C);
- adv7180_write_reg(0x85, 0x02);
- adv7180_write_reg(0x86, 0x03);
- adv7180_write_reg(0x87, 0x63);
- adv7180_write_reg(0x88, 0x5A);
- adv7180_write_reg(0x89, 0x08);
- adv7180_write_reg(0x8A, 0x10);
- adv7180_write_reg(0x8B, 0x00);
- adv7180_write_reg(0x8C, 0x40);
- adv7180_write_reg(0x8D, 0x00);
- adv7180_write_reg(0x8E, 0x40);
- adv7180_write_reg(0x8F, 0x00);
- adv7180_write_reg(0x90, 0x00);
- adv7180_write_reg(0x91, 0x50);
- adv7180_write_reg(0x92, 0x00);
- adv7180_write_reg(0x93, 0x00);
- adv7180_write_reg(0x94, 0x00);
- adv7180_write_reg(0x95, 0x00);
- adv7180_write_reg(0x96, 0x00);
- adv7180_write_reg(0x97, 0xF0);
- adv7180_write_reg(0x98, 0x00);
- adv7180_write_reg(0x99, 0x00);
- adv7180_write_reg(0x9A, 0x00);
- adv7180_write_reg(0x9B, 0x00);
- adv7180_write_reg(0x9C, 0x00);
- adv7180_write_reg(0x9D, 0x00);
- adv7180_write_reg(0x9E, 0x00);
- adv7180_write_reg(0x9F, 0x00);
- adv7180_write_reg(0xA0, 0x00);
- adv7180_write_reg(0xA1, 0x00);
- adv7180_write_reg(0xA2, 0x00);
- adv7180_write_reg(0xA3, 0x00);
- adv7180_write_reg(0xA4, 0x00);
- adv7180_write_reg(0xA5, 0x00);
- adv7180_write_reg(0xA6, 0x00);
- adv7180_write_reg(0xA7, 0x00);
- adv7180_write_reg(0xA8, 0x00);
- adv7180_write_reg(0xA9, 0x00);
- adv7180_write_reg(0xAA, 0x00);
- adv7180_write_reg(0xAB, 0x00);
- adv7180_write_reg(0xAC, 0x00);
- adv7180_write_reg(0xAD, 0x00);
- adv7180_write_reg(0xAE, 0x60);
- adv7180_write_reg(0xAF, 0x00);
- adv7180_write_reg(0xB0, 0x00);
- adv7180_write_reg(0xB1, 0x60);
- adv7180_write_reg(0xB2, 0x1C);
- adv7180_write_reg(0xB3, 0x54);
- adv7180_write_reg(0xB4, 0x00);
- adv7180_write_reg(0xB5, 0x00);
- adv7180_write_reg(0xB6, 0x00);
- adv7180_write_reg(0xB7, 0x13);
- adv7180_write_reg(0xB8, 0x03);
- adv7180_write_reg(0xB9, 0x33);
- adv7180_write_reg(0xBF, 0x02);
- adv7180_write_reg(0xC0, 0x00);
- adv7180_write_reg(0xC1, 0x00);
- adv7180_write_reg(0xC2, 0x00);
- adv7180_write_reg(0xC3, 0x00);
- adv7180_write_reg(0xC4, 0x00);
- adv7180_write_reg(0xC5, 0x81);
- adv7180_write_reg(0xC6, 0x00);
- adv7180_write_reg(0xC7, 0x00);
- adv7180_write_reg(0xC8, 0x00);
- adv7180_write_reg(0xC9, 0x04);
- adv7180_write_reg(0xCC, 0x69);
- adv7180_write_reg(0xCD, 0x00);
- adv7180_write_reg(0xCE, 0x01);
- adv7180_write_reg(0xCF, 0xB4);
- adv7180_write_reg(0xD0, 0x00);
- adv7180_write_reg(0xD1, 0x10);
- adv7180_write_reg(0xD2, 0xFF);
- adv7180_write_reg(0xD3, 0xFF);
- adv7180_write_reg(0xD4, 0x7F);
- adv7180_write_reg(0xD5, 0x7F);
- adv7180_write_reg(0xD6, 0x3E);
- adv7180_write_reg(0xD7, 0x08);
- adv7180_write_reg(0xD8, 0x3C);
- adv7180_write_reg(0xD9, 0x08);
- adv7180_write_reg(0xDA, 0x3C);
- adv7180_write_reg(0xDB, 0x9B);
- adv7180_write_reg(0xDC, 0xAC);
- adv7180_write_reg(0xDD, 0x4C);
- adv7180_write_reg(0xDE, 0x00);
- adv7180_write_reg(0xDF, 0x00);
- adv7180_write_reg(0xE0, 0x14);
- adv7180_write_reg(0xE1, 0x80);
- adv7180_write_reg(0xE2, 0x80);
- adv7180_write_reg(0xE3, 0x80);
- adv7180_write_reg(0xE4, 0x80);
- adv7180_write_reg(0xE5, 0x25);
- adv7180_write_reg(0xE6, 0x44);
- adv7180_write_reg(0xE7, 0x63);
- adv7180_write_reg(0xE8, 0x65);
- adv7180_write_reg(0xE9, 0x14);
- adv7180_write_reg(0xEA, 0x63);
- adv7180_write_reg(0xEB, 0x55);
- adv7180_write_reg(0xEC, 0x55);
- adv7180_write_reg(0xEE, 0x00);
- adv7180_write_reg(0xEF, 0x4A);
- adv7180_write_reg(0xF0, 0x44);
- adv7180_write_reg(0xF1, 0x0C);
- adv7180_write_reg(0xF2, 0x32);
- adv7180_write_reg(0xF3, 0x00);
- adv7180_write_reg(0xF4, 0x3F);
- adv7180_write_reg(0xF5, 0xE0);
- adv7180_write_reg(0xF6, 0x69);
- adv7180_write_reg(0xF7, 0x10);
- adv7180_write_reg(0xF8, 0x00);
- adv7180_write_reg(0xF9, 0x03);
- adv7180_write_reg(0xFA, 0xFA);
- adv7180_write_reg(0xFB, 0x40);
}
/*! ADV7180 I2C attach function.
@@ -1077,101 +1175,101 @@ static void adv7180_hard_reset(bool cvbs)
static int adv7180_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct adv7180_priv *adv;
int rev_id;
int ret = 0;
- tvin_plat = client->dev.platform_data;
+ int i;
+ char *regulator_names[4];
+ unsigned reg_volt[4];
+ struct fsl_mxc_tvin_platform_data *tvin_plat = client->dev.platform_data;
- printk(KERN_ERR"DBG sensor data is at %p\n", &adv7180_data);
pr_debug("In adv7180_probe\n");
-
- if (tvin_plat->dvddio_reg) {
- dvddio_regulator =
- regulator_get(&client->dev, tvin_plat->dvddio_reg);
- if (!IS_ERR_VALUE((unsigned long)dvddio_regulator)) {
- regulator_set_voltage(dvddio_regulator, 3300000, 3300000);
- if (regulator_enable(dvddio_regulator) != 0)
- return -ENODEV;
- }
- }
-
- if (tvin_plat->dvdd_reg) {
- dvdd_regulator =
- regulator_get(&client->dev, tvin_plat->dvdd_reg);
- if (!IS_ERR_VALUE((unsigned long)dvdd_regulator)) {
- regulator_set_voltage(dvdd_regulator, 1800000, 1800000);
- if (regulator_enable(dvdd_regulator) != 0)
- return -ENODEV;
- }
- }
-
- if (tvin_plat->avdd_reg) {
- avdd_regulator =
- regulator_get(&client->dev, tvin_plat->avdd_reg);
- if (!IS_ERR_VALUE((unsigned long)avdd_regulator)) {
- regulator_set_voltage(avdd_regulator, 1800000, 1800000);
- if (regulator_enable(avdd_regulator) != 0)
- return -ENODEV;
- }
+ if (!tvin_plat) {
+ pr_err("%s: Platform data needed\n", __func__);
+ return -ENOMEM;
}
- if (tvin_plat->pvdd_reg) {
- pvdd_regulator =
- regulator_get(&client->dev, tvin_plat->pvdd_reg);
- if (!IS_ERR_VALUE((unsigned long)pvdd_regulator)) {
- regulator_set_voltage(pvdd_regulator, 1800000, 1800000);
- if (regulator_enable(pvdd_regulator) != 0)
- return -ENODEV;
+ adv = kzalloc(sizeof(struct adv7180_priv), GFP_KERNEL);
+ if (!adv)
+ return -ENOMEM;
+
+ printk(KERN_ERR"DBG adv data is at %p\n", adv);
+
+ regulator_names[DVDDIO_REG] = tvin_plat->dvddio_reg;
+ regulator_names[DVDD_REG] = tvin_plat->dvdd_reg;
+ regulator_names[AVDD_REG] = tvin_plat->avdd_reg;
+ regulator_names[PVDD_REG] = tvin_plat->pvdd_reg;
+
+ reg_volt[DVDDIO_REG] = 3300000;
+ reg_volt[DVDD_REG] = 1800000;
+ reg_volt[AVDD_REG] = 1800000;
+ reg_volt[PVDD_REG] = 1800000;
+ for (i = 0; i < ARRAY_SIZE(adv->regulators); i++) {
+ char *p = regulator_names[i];
+
+ if (p) {
+ adv->regulators[i] = regulator_get(&client->dev, p);
+ if (!IS_ERR_VALUE((unsigned long)adv->regulators[i])) {
+ regulator_set_voltage(adv->regulators[i], reg_volt[i], reg_volt[i]);
+ if (regulator_enable(adv->regulators[i]) != 0) {
+ kfree(adv);
+ return -ENODEV;
+ }
+ }
}
}
if (tvin_plat->io_init)
tvin_plat->io_init();
+ adv->cvbs = tvin_plat->cvbs;
+ adv->reset = tvin_plat->reset;
+ adv->pwdn = tvin_plat->pwdn;
+ adv->sen.ipu = tvin_plat->ipu;
+ adv->sen.csi = tvin_plat->csi;
- if (tvin_plat->reset)
- tvin_plat->reset();
+ if (adv->reset)
+ adv->reset();
- if (tvin_plat->pwdn)
- tvin_plat->pwdn(0);
+ if (adv->pwdn)
+ adv->pwdn(0);
msleep(1);
-
- /* Set initial values for the sensor struct. */
- memset(&adv7180_data, 0, sizeof(adv7180_data));
- adv7180_data.sen.i2c_client = client;
- adv7180_data.sen.streamcap.timeperframe.denominator = 30;
- adv7180_data.sen.streamcap.timeperframe.numerator = 1;
- adv7180_data.std_id = V4L2_STD_ALL;
+ adv->sen.i2c_client = client;
+ adv->sen.streamcap.timeperframe.denominator = 30;
+ adv->sen.streamcap.timeperframe.numerator = 1;
+ adv->std_id = V4L2_STD_ALL;
video_idx = ADV7180_NOT_LOCKED;
- adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
- adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
- adv7180_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
- adv7180_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
- adv7180_data.sen.on = true;
+ adv->sen.pix.width = video_fmts[video_idx].raw_width;
+ adv->sen.pix.height = video_fmts[video_idx].raw_height;
+ adv->sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
+ adv->sen.pix.priv = 1; /* 1 is used to indicate TV in */
+ adv->sen.on = true;
gpio_sensor_active();
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ dev_dbg(&adv->sen.i2c_client->dev,
"%s:adv7180 probe i2c address is 0x%02X\n",
- __func__, adv7180_data.sen.i2c_client->addr);
+ __func__, adv->sen.i2c_client->addr);
/*! Read the revision ID of the tvin chip */
- rev_id = adv7180_read(ADV7180_IDENT);
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ rev_id = adv7180_read(adv, ADV7180_IDENT);
+ dev_dbg(&adv->sen.i2c_client->dev,
"%s:Analog Device adv7%2X0 detected!\n", __func__,
rev_id);
- /*! ADV7180 initialization. */
- adv7180_hard_reset(tvin_plat->cvbs);
+ set_power(adv, 0);
pr_debug(" type is %d (expect %d)\n",
adv7180_int_device.type, v4l2_int_type_slave);
pr_debug(" num ioctls is %d\n",
adv7180_int_device.u.slave->num_ioctls);
- /* This function attaches this structure to the /dev/video0 device.
- * The pointer in priv points to the mt9v111_data structure here.*/
- adv7180_int_device.priv = &adv7180_data;
+ /*
+ * This function attaches this structure to the /dev/video0 device.
+ */
+ adv7180_int_device.priv = adv;
+ i2c_set_clientdata(client, adv);
ret = v4l2_int_device_register(&adv7180_int_device);
return ret;
@@ -1187,35 +1285,28 @@ static int adv7180_probe(struct i2c_client *client,
*/
static int adv7180_detach(struct i2c_client *client)
{
- dev_dbg(&adv7180_data.sen.i2c_client->dev,
+ struct adv7180_priv *adv = i2c_get_clientdata(client);
+ int i;
+
+ if (!adv)
+ return 0;
+ dev_dbg(&adv->sen.i2c_client->dev,
"%s:Removing %s video decoder @ 0x%02X from adapter %s\n",
__func__, IF_NAME, client->addr << 1, client->adapter->name);
- /* Power down via i2c */
- adv7180_write_reg(ADV7180_PWR_MNG, 0x24);
+ set_power(adv, 0);
- if (dvddio_regulator) {
- regulator_disable(dvddio_regulator);
- regulator_put(dvddio_regulator);
- }
+ for (i = 0; i < ARRAY_SIZE(adv->regulators); i++) {
+ struct regulator *reg = adv->regulators[i];
- if (dvdd_regulator) {
- regulator_disable(dvdd_regulator);
- regulator_put(dvdd_regulator);
- }
-
- if (avdd_regulator) {
- regulator_disable(avdd_regulator);
- regulator_put(avdd_regulator);
- }
-
- if (pvdd_regulator) {
- regulator_disable(pvdd_regulator);
- regulator_put(pvdd_regulator);
+ if (reg) {
+ regulator_disable(reg);
+ regulator_put(reg);
+ }
}
v4l2_int_device_unregister(&adv7180_int_device);
-
+ kfree(adv);
return 0;
}
@@ -1248,7 +1339,7 @@ static __init int adv7180_init(void)
*/
static void __exit adv7180_clean(void)
{
- dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_clean\n");
+ pr_debug("In adv7180_clean\n");
i2c_del_driver(&adv7180_i2c_driver);
gpio_sensor_inactive();
}