Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03ed2a11 authored by Jean-François Moine's avatar Jean-François Moine Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB: gspca - sonixj: Add sensor soi768



The webcams 0c45:613e may contain the sensors ov7630 or soi768.
A sensor probe is done at init time when the sensor is declared ov7630.

Signed-off-by: default avatarJean-François Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e3302cad
Loading
Loading
Loading
Loading
+94 −1
Original line number Original line Diff line number Diff line
@@ -80,6 +80,7 @@ enum {
	SENSOR_OV7660,
	SENSOR_OV7660,
	SENSOR_PO1030,
	SENSOR_PO1030,
	SENSOR_PO2030N,
	SENSOR_PO2030N,
	SENSOR_SOI768,
	SENSOR_SP80708,
	SENSOR_SP80708,
} sensors;
} sensors;
	u8 i2c_addr;
	u8 i2c_addr;
@@ -330,6 +331,10 @@ static const __u32 ctrl_dis[] = {
			(1 << INFRARED_IDX) |
			(1 << INFRARED_IDX) |
			(1 << VFLIP_IDX) |
			(1 << VFLIP_IDX) |
			(1 << FREQ_IDX),
			(1 << FREQ_IDX),
[SENSOR_SOI768] =	(1 << AUTOGAIN_IDX) |
			(1 << INFRARED_IDX) |
			(1 << VFLIP_IDX) |
			(1 << FREQ_IDX),


[SENSOR_SP80708] =	(1 << AUTOGAIN_IDX) |
[SENSOR_SP80708] =	(1 << AUTOGAIN_IDX) |
			(1 << INFRARED_IDX) |
			(1 << INFRARED_IDX) |
@@ -495,6 +500,17 @@ static const u8 sn_po2030n[0x1c] = {
	0x07,	0x00,	0x00,	0x00
	0x07,	0x00,	0x00,	0x00
};
};


static const u8 sn_soi768[0x1c] = {
/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
	0x00,	0x21,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
	0x03,	0x00,	0x00,	0x01,	0x08,	0x28,	0x1e,	0x00,
/*	reg18	reg19	reg1a	reg1b */
	0x07,	0x00,	0x00,	0x00
};

static const u8 sn_sp80708[0x1c] = {
static const u8 sn_sp80708[0x1c] = {
/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
	0x00,	0x63,	0x60,	0x00,	0x1a,	0x20,	0x20,	0x20,
	0x00,	0x63,	0x60,	0x00,	0x1a,	0x20,	0x20,	0x20,
@@ -520,7 +536,8 @@ static const u8 *sn_tb[] = {
[SENSOR_OV7660] =	sn_ov7660,
[SENSOR_OV7660] =	sn_ov7660,
[SENSOR_PO1030] =	sn_po1030,
[SENSOR_PO1030] =	sn_po1030,
[SENSOR_PO2030N] =	sn_po2030n,
[SENSOR_PO2030N] =	sn_po2030n,
[SENSOR_SP80708] =	sn_sp80708
[SENSOR_SOI768] =	sn_soi768,
[SENSOR_SP80708] =	sn_sp80708,
};
};


/* default gamma table */
/* default gamma table */
@@ -1173,6 +1190,37 @@ static const u8 po2030n_sensor_param1[][8] = {
	{}
	{}
};
};


static const u8 soi768_sensor_init[][8] = {
	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
	{0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
	{}
};
static const u8 soi768_sensor_param1[][8] = {
	{0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
	{0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
/* */
/*	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
/*	{0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
	{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
/*	{0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
	{0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
/* the next sequence should be used for auto gain */
	{0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
			/* global gain ? : 07 - change with 0x15 at the end */
	{0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
	{0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
	{0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
			/* exposure ? : 0200 - change with 0x1e at the end */
	{}
};

static const u8 sp80708_sensor_init[][8] = {
static const u8 sp80708_sensor_init[][8] = {
	{0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
	{0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
@@ -1271,6 +1319,7 @@ static const u8 (*sensor_init[])[8] = {
[SENSOR_OV7660] =	ov7660_sensor_init,
[SENSOR_OV7660] =	ov7660_sensor_init,
[SENSOR_PO1030] =	po1030_sensor_init,
[SENSOR_PO1030] =	po1030_sensor_init,
[SENSOR_PO2030N] =	po2030n_sensor_init,
[SENSOR_PO2030N] =	po2030n_sensor_init,
[SENSOR_SOI768] =	soi768_sensor_init,
[SENSOR_SP80708] =	sp80708_sensor_init,
[SENSOR_SP80708] =	sp80708_sensor_init,
};
};


@@ -1495,6 +1544,30 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
	}
	}
}
}


static void ov7630_probe(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	u16 val;

	/* check ov76xx */
	reg_w1(gspca_dev, 0x17, 0x62);
	reg_w1(gspca_dev, 0x01, 0x08);
	sd->i2c_addr = 0x21;
	i2c_r(gspca_dev, 0x0a, 2);
	val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
	reg_w1(gspca_dev, 0x01, 0x29);
	reg_w1(gspca_dev, 0x17, 0x42);
	if (val == 0x7628) {			/* soi768 */
		sd->sensor = SENSOR_SOI768;
/*fixme: only valid for 0c45:613e?*/
		gspca_dev->cam.input_flags =
				V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
		PDEBUG(D_PROBE, "Sensor soi768");
		return;
	}
	PDEBUG(D_PROBE, "Sensor ov%04x", val);
}

static void ov7648_probe(struct gspca_dev *gspca_dev)
static void ov7648_probe(struct gspca_dev *gspca_dev)
{
{
	struct sd *sd = (struct sd *) gspca_dev;
	struct sd *sd = (struct sd *) gspca_dev;
@@ -1591,6 +1664,7 @@ static void bridge_init(struct gspca_dev *gspca_dev,
	case SENSOR_OV7660:
	case SENSOR_OV7660:
	case SENSOR_PO1030:
	case SENSOR_PO1030:
	case SENSOR_PO2030N:
	case SENSOR_PO2030N:
	case SENSOR_SOI768:
	case SENSOR_SP80708:
	case SENSOR_SP80708:
		reg9a = reg9a_spec;
		reg9a = reg9a_spec;
		break;
		break;
@@ -1656,6 +1730,7 @@ static void bridge_init(struct gspca_dev *gspca_dev,
		reg_w1(gspca_dev, 0x01, 0x42);
		reg_w1(gspca_dev, 0x01, 0x42);
		break;
		break;
	case SENSOR_PO1030:
	case SENSOR_PO1030:
	case SENSOR_SOI768:
		reg_w1(gspca_dev, 0x01, 0x61);
		reg_w1(gspca_dev, 0x01, 0x61);
		reg_w1(gspca_dev, 0x17, 0x20);
		reg_w1(gspca_dev, 0x17, 0x20);
		reg_w1(gspca_dev, 0x01, 0x60);
		reg_w1(gspca_dev, 0x01, 0x60);
@@ -1771,6 +1846,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
		case SENSOR_MI0360:
		case SENSOR_MI0360:
			mi0360_probe(gspca_dev);
			mi0360_probe(gspca_dev);
			break;
			break;
		case SENSOR_OV7630:
			ov7630_probe(gspca_dev);
			break;
		case SENSOR_OV7648:
		case SENSOR_OV7648:
			ov7648_probe(gspca_dev);
			ov7648_probe(gspca_dev);
			break;
			break;
@@ -2280,6 +2358,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
		reg17 = 0x20;
		reg17 = 0x20;
		break;
		break;
	case SENSOR_OV7660:
	case SENSOR_OV7660:
	case SENSOR_SOI768:
		reg17 = 0xa0;
		reg17 = 0xa0;
		break;
		break;
	case SENSOR_PO1030:
	case SENSOR_PO1030:
@@ -2317,6 +2396,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
		reg_w1(gspca_dev, 0x9a, 0x0a);
		reg_w1(gspca_dev, 0x9a, 0x0a);
		break;
		break;
	case SENSOR_PO2030N:
	case SENSOR_PO2030N:
	case SENSOR_SOI768:
		reg_w1(gspca_dev, 0x9a, 0x06);
		reg_w1(gspca_dev, 0x9a, 0x06);
		break;
		break;
	default:
	default:
@@ -2403,6 +2483,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
		reg1 = 0x46;
		reg1 = 0x46;
		reg17 = 0xa2;
		reg17 = 0xa2;
		break;
		break;
	case SENSOR_SOI768:
		init = soi768_sensor_param1;
		reg1 = 0x44;
		reg17 = 0xa2;
		break;
	default:
	default:
/*	case SENSOR_SP80708: */
/*	case SENSOR_SP80708: */
		init = sp80708_sensor_param1;
		init = sp80708_sensor_param1;
@@ -2425,6 +2510,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
	switch (sd->sensor) {
	switch (sd->sensor) {
	case SENSOR_ADCM1700:
	case SENSOR_ADCM1700:
	case SENSOR_GC0307:
	case SENSOR_GC0307:
	case SENSOR_SOI768:
		reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
		reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
		break;
		break;
	case SENSOR_PO2030N:
	case SENSOR_PO2030N:
@@ -2439,6 +2525,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
	case SENSOR_OV7630:
	case SENSOR_OV7630:
	case SENSOR_OV7648:
	case SENSOR_OV7648:
	case SENSOR_OV7660:
	case SENSOR_OV7660:
	case SENSOR_SOI768:
		reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
		reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
		break;
		break;
	case SENSOR_GC0307:
	case SENSOR_GC0307:
@@ -2480,6 +2567,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
		{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
		{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
	static const u8 stopov7648[] =
	static const u8 stopov7648[] =
		{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
		{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
	static const u8 stopsoi768[] =
		{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
	u8 data;
	u8 data;
	const u8 *sn9c1xx;
	const u8 *sn9c1xx;


@@ -2504,6 +2593,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
	case SENSOR_PO1030:
	case SENSOR_PO1030:
		data = 0x29;
		data = 0x29;
		break;
		break;
	case SENSOR_SOI768:
		i2c_w8(gspca_dev, stopsoi768);
		data = 0x29;
		break;
	}
	}
	sn9c1xx = sn_tb[sd->sensor];
	sn9c1xx = sn_tb[sd->sensor];
	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);