summaryrefslogtreecommitdiff
path: root/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-21 22:10:30 +0300
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-21 22:10:30 +0300
commite695e10bc996d6f83df7d85f1011c8d00573f68b (patch)
tree3d0ba107ea8fe7d0090e3cfd5e36cdb4abcaab99 /drivers/media/video/sn9c102/sn9c102_pas202bcb.c
parent3a5f10e3708e00c406f154bae412652ec3eb2b48 (diff)
parentf6982d59480953a8f5a84c237a9dabff39f788ce (diff)
downloadlinux-e695e10bc996d6f83df7d85f1011c8d00573f68b.tar.xz
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (196 commits) V4L/DVB (5253): Qt1010: whitespace / 80 column cleanups V4L/DVB (5252): Qt1010: use ARRAY_SIZE macro when appropriate V4L/DVB (5251): Qt1010: fix compiler warning V4L/DVB (5249): Fix compiler warning in vivi.c V4L/DVB (5247): Stv0297: Enable BER/UNC counting V4L/DVB (5246): Budget-ci: IR handling fixups V4L/DVB (5245): Dvb-ttpci: use i2c gate ctrl from stv0297 frontend driver V4L/DVB (5244): Dvbdev: fix illegal re-usage of fileoperations struct V4L/DVB (5178): Avoid race when deregistering the IR control for dvb-usb V4L/DVB (5240): Qt1010: use i2c_gate_ctrl where appropriate V4L/DVB (5239): Whitespace / 80-column cleanups V4L/DVB (5238): Kconfig: qt1010 should be selected by gl861 and au6610 V4L/DVB (5237): Dvb: add new qt1010 tuner module V4L/DVB (5236): Initial support for Sigmatek DVB-110 DVB-T V4L/DVB (5235): Gl861: use parallel_ts V4L/DVB (5234): Gl861: remove unneeded declaration V4L/DVB (5233): Gl861: correct address of the bulk endpoint V4L/DVB (5232): Gl861: correct oops when loading module V4L/DVB (5231): Gl861: whitespace cleanups V4L/DVB (5230): Gl861: remove NULL entry from gl861_properties ...
Diffstat (limited to 'drivers/media/video/sn9c102/sn9c102_pas202bcb.c')
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas202bcb.c97
1 files changed, 81 insertions, 16 deletions
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
index e3c1178e339c..7894f01b56e8 100644
--- a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
+++ b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
@@ -1,13 +1,13 @@
/***************************************************************************
- * Plug-in for PAS202BCB image sensor connected to the SN9C10x PC Camera *
+ * Plug-in for PAS202BCB image sensor connected to the SN9C1xx PC Camera *
* Controllers *
* *
* Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio *
* <medaglia@undl.org.br> *
* http://cadu.homelinux.com:8080/ *
* *
- * DAC Magnitude, exposure and green gain controls added by *
- * Luca Risolia <luca.risolia@studio.unibo.it> *
+ * Support for SN9C103, DAC Magnitude, exposure and green gain controls *
+ * added by Luca Risolia <luca.risolia@studio.unibo.it> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@@ -35,12 +35,54 @@ static int pas202bcb_init(struct sn9c102_device* cam)
{
int err = 0;
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C101:
+ case BRIDGE_SN9C102:
err += sn9c102_write_reg(cam, 0x00, 0x10);
err += sn9c102_write_reg(cam, 0x00, 0x11);
err += sn9c102_write_reg(cam, 0x00, 0x14);
err += sn9c102_write_reg(cam, 0x20, 0x17);
err += sn9c102_write_reg(cam, 0x30, 0x19);
err += sn9c102_write_reg(cam, 0x09, 0x18);
+ break;
+ case BRIDGE_SN9C103:
+ err += sn9c102_write_reg(cam, 0x00, 0x02);
+ err += sn9c102_write_reg(cam, 0x00, 0x03);
+ err += sn9c102_write_reg(cam, 0x1a, 0x04);
+ err += sn9c102_write_reg(cam, 0x20, 0x05);
+ err += sn9c102_write_reg(cam, 0x20, 0x06);
+ err += sn9c102_write_reg(cam, 0x20, 0x07);
+ err += sn9c102_write_reg(cam, 0x00, 0x10);
+ err += sn9c102_write_reg(cam, 0x00, 0x11);
+ err += sn9c102_write_reg(cam, 0x00, 0x14);
+ err += sn9c102_write_reg(cam, 0x20, 0x17);
+ err += sn9c102_write_reg(cam, 0x30, 0x19);
+ err += sn9c102_write_reg(cam, 0x09, 0x18);
+ err += sn9c102_write_reg(cam, 0x02, 0x1c);
+ err += sn9c102_write_reg(cam, 0x03, 0x1d);
+ err += sn9c102_write_reg(cam, 0x0f, 0x1e);
+ err += sn9c102_write_reg(cam, 0x0c, 0x1f);
+ err += sn9c102_write_reg(cam, 0x00, 0x20);
+ err += sn9c102_write_reg(cam, 0x10, 0x21);
+ err += sn9c102_write_reg(cam, 0x20, 0x22);
+ err += sn9c102_write_reg(cam, 0x30, 0x23);
+ err += sn9c102_write_reg(cam, 0x40, 0x24);
+ err += sn9c102_write_reg(cam, 0x50, 0x25);
+ err += sn9c102_write_reg(cam, 0x60, 0x26);
+ err += sn9c102_write_reg(cam, 0x70, 0x27);
+ err += sn9c102_write_reg(cam, 0x80, 0x28);
+ err += sn9c102_write_reg(cam, 0x90, 0x29);
+ err += sn9c102_write_reg(cam, 0xa0, 0x2a);
+ err += sn9c102_write_reg(cam, 0xb0, 0x2b);
+ err += sn9c102_write_reg(cam, 0xc0, 0x2c);
+ err += sn9c102_write_reg(cam, 0xd0, 0x2d);
+ err += sn9c102_write_reg(cam, 0xe0, 0x2e);
+ err += sn9c102_write_reg(cam, 0xf0, 0x2f);
+ err += sn9c102_write_reg(cam, 0xff, 0x30);
+ break;
+ default:
+ break;
+ }
err += sn9c102_i2c_write(cam, 0x02, 0x14);
err += sn9c102_i2c_write(cam, 0x03, 0x40);
@@ -107,7 +149,7 @@ static int pas202bcb_set_pix_format(struct sn9c102_device* cam,
int err = 0;
if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x24, 0x17);
+ err += sn9c102_write_reg(cam, 0x28, 0x17);
else
err += sn9c102_write_reg(cam, 0x20, 0x17);
@@ -152,11 +194,23 @@ static int pas202bcb_set_ctrl(struct sn9c102_device* cam,
static int pas202bcb_set_crop(struct sn9c102_device* cam,
const struct v4l2_rect* rect)
{
- struct sn9c102_sensor* s = &pas202bcb;
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4,
+ u8 h_start = 0,
v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C101:
+ case BRIDGE_SN9C102:
+ h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4;
+ break;
+ case BRIDGE_SN9C103:
+ h_start = (u8)(rect->left - s->cropcap.bounds.left) + 3;
+ break;
+ default:
+ break;
+ }
+
err += sn9c102_write_reg(cam, h_start, 0x12);
err += sn9c102_write_reg(cam, v_start, 0x13);
@@ -166,8 +220,8 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
static struct sn9c102_sensor pas202bcb = {
.name = "PAS202BCB",
- .maintainer = "Carlos Eduardo Medaglia Dyonisio "
- "<medaglia@undl.org.br>",
+ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
.sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
@@ -191,7 +245,7 @@ static struct sn9c102_sensor pas202bcb = {
.minimum = 0x00,
.maximum = 0x1f,
.step = 0x01,
- .default_value = 0x0c,
+ .default_value = 0x0b,
.flags = 0,
},
{
@@ -201,7 +255,7 @@ static struct sn9c102_sensor pas202bcb = {
.minimum = 0x00,
.maximum = 0x0f,
.step = 0x01,
- .default_value = 0x01,
+ .default_value = 0x00,
.flags = 0,
},
{
@@ -271,16 +325,27 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
* Minimal initialization to enable the I2C communication
* NOTE: do NOT change the values!
*/
- err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */
- err += sn9c102_write_reg(cam, 0x40, 0x01); /* sensor power on */
- err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */
- if (err)
- return -EIO;
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C101:
+ case BRIDGE_SN9C102:
+ err += sn9c102_write_reg(cam, 0x01, 0x01); /* power down */
+ err += sn9c102_write_reg(cam, 0x40, 0x01); /* power on */
+ err += sn9c102_write_reg(cam, 0x28, 0x17); /* clock 24 MHz */
+ break;
+ case BRIDGE_SN9C103: /* do _not_ change anything! */
+ err += sn9c102_write_reg(cam, 0x09, 0x01);
+ err += sn9c102_write_reg(cam, 0x44, 0x01);
+ err += sn9c102_write_reg(cam, 0x44, 0x02);
+ err += sn9c102_write_reg(cam, 0x29, 0x17);
+ break;
+ default:
+ break;
+ }
r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
- if (r0 < 0 || r1 < 0)
+ if (err || r0 < 0 || r1 < 0)
return -EIO;
pid = (r0 << 4) | ((r1 & 0xf0) >> 4);