Commit 93627736 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

V4L/DVB (8868): gspca: Support for vga modes with sif sensors in sonixb.

- Add documentation for some known registers
- Add support for vga modes (320x240, 160x120) for sif sensors
- Remove F_RAW sensor flag raw mode should work on any sensor as its a bridge
   only thing and keeping the flag was becoming awkward.
- Fixup ov6650 and pas106 auto exposure window settings
Signed-off-by: default avatarHans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: default avatarJean-Francois Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 5d8538c1
......@@ -20,6 +20,26 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Some documentation on known sonixb registers:
Reg Use
0x10 high nibble red gain low nibble blue gain
0x11 low nibble green gain
0x12 hstart
0x13 vstart
0x15 hsize (hsize = register-value * 16)
0x16 vsize (vsize = register-value * 16)
0x17 bit 0 toggle compression quality (according to sn9c102 driver)
0x18 bit 7 enables compression, bit 4-5 set image down scaling:
00 scale 1, 01 scale 1/2, 10, scale 1/4
0x19 high-nibble is sensor clock divider, changes exposure on sensors which
use a clock generated by the bridge. Some sensors have their own clock.
0x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32)
0x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32)
0x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
0x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
*/
#define MODULE_NAME "sonixb"
#include "gspca.h"
......@@ -74,10 +94,10 @@ struct sensor_data {
/* sensor_data flags */
#define F_GAIN 0x01 /* has gain */
#define F_SIF 0x02 /* sif or vga */
#define F_RAW 0x04 /* sensor tested ok with raw bayer mode */
/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
#define MODE_RAW 0x10 /* raw bayer mode */
#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
/* ctrl_dis helper macros */
#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
......@@ -211,7 +231,7 @@ static struct ctrl sd_ctrls[] = {
static struct v4l2_pix_format vga_mode[] = {
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 160 * 120,
.sizeimage = 160 * 120 * 5 / 4,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 2 | MODE_RAW},
{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
......@@ -231,9 +251,19 @@ static struct v4l2_pix_format vga_mode[] = {
.priv = 0},
};
static struct v4l2_pix_format sif_mode[] = {
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 160 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 160 * 120 * 5 / 4,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1 | MODE_REDUCED_SIF},
{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 176,
.sizeimage = 176 * 144,
.sizeimage = 176 * 144 * 5 / 4,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1 | MODE_RAW},
{176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
......@@ -241,6 +271,11 @@ static struct v4l2_pix_format sif_mode[] = {
.sizeimage = 176 * 144 * 5 / 4,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1},
{320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 5 / 4,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 0 | MODE_REDUCED_SIF},
{352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
.bytesperline = 352,
.sizeimage = 352 * 288 * 5 / 4,
......@@ -266,7 +301,7 @@ static const __u8 initOv6650[] = {
0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
};
static const __u8 ov6650_sensor_init[][8] =
{
......@@ -350,7 +385,7 @@ static const __u8 initPas106[] = {
0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
0x16, 0x12, 0x24, COMP1, MCK_INIT1,
0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
0x18, 0x10, 0x02, 0x02, 0x09, 0x07
};
/* compression 0x86 mckinit1 0x2b */
static const __u8 pas106_sensor_init[][8] = {
......@@ -456,15 +491,14 @@ static const __u8 tas5130_sensor_init[][8] = {
struct sensor_data sensor_data[] = {
SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, 0,
0x60),
SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
F_GAIN, 0, 0x21),
SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
0),
SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_RAW,
SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
NO_EXPO|NO_FREQ, 0),
SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW,
SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
NO_BRIGHTNESS|NO_FREQ, 0),
SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
0),
......@@ -834,10 +868,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
if (!(sensor_data[sd->sensor].flags & F_RAW)) {
cam->cam_mode++;
cam->nmodes--;
}
sd->brightness = BRIGHTNESS_DEF;
sd->gain = GAIN_DEF;
sd->exposure = EXPOSURE_DEF;
......@@ -864,31 +894,39 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
int mode, l;
const __u8 *sn9c10x;
__u8 reg17_19[3];
__u8 reg12_19[8];
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 0x07;
mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
reg17_19[0] = sn9c10x[0x17 - 1];
reg17_19[1] = sn9c10x[0x18 - 1] | (mode << 4);
reg17_19[2] = sn9c10x[0x19 - 1];
memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
/* Special cases where reg 17 and or 19 value depends on mode */
switch (sd->sensor) {
case SENSOR_PAS202:
reg17_19[0] = mode ? 0x24 : 0x20;
reg12_19[5] = mode ? 0x24 : 0x20;
break;
case SENSOR_TAS5130CXX:
/* probably not mode specific at all most likely the upper
nibble of 0x19 is exposure (clock divider) just as with
the tas5110, we need someone to test this. */
reg17_19[2] = mode ? 0x23 : 0x43;
reg12_19[7] = mode ? 0x23 : 0x43;
break;
}
/* Disable compression when the raw bayer format has been selected */
if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
reg17_19[1] &= ~0x80;
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
reg12_19[6] &= ~0x80;
/* Vga mode emulation on SIF sensor? */
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
reg12_19[0] += 16; /* 0x12: hstart adjust */
reg12_19[1] += 24; /* 0x13: vstart adjust */
reg12_19[3] = 320 / 16; /* 0x15: hsize */
reg12_19[4] = 240 / 16; /* 0x16: vsize */
}
/* reg 0x01 bit 2 video transfert on */
reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
......@@ -907,24 +945,24 @@ static void sd_start(struct gspca_dev *gspca_dev)
sd->bridge]);
/* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
/* compression register */
reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
/* H_start */
reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
/* V_START */
reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
/* reset 0x17 SensorClk enable inv Clk 0x60 */
/*fixme: ov7630 [17]=68 8f (+20 if 102)*/
reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
/*MCKSIZE ->3 */ /*fixme: not ov7630*/
reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
/* AE_STRX AE_STRY AE_ENDX AE_ENDY */
reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
/* Enable video transfert */
reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
/* Compression */
reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
msleep(20);
sd->reg11 = -1;
......
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