diff options
Diffstat (limited to 'drivers/media/video/gspca/sonixj.c')
| -rw-r--r-- | drivers/media/video/gspca/sonixj.c | 341 | 
1 files changed, 264 insertions, 77 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 0bd36a00dd2..83d5773d462 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -21,6 +21,7 @@  #define MODULE_NAME "sonixj" +#include <linux/input.h>  #include "gspca.h"  #include "jpeg.h" @@ -45,6 +46,7 @@ struct sd {  	u8 red;  	u8 gamma;  	u8 vflip;			/* ov7630/ov7648 only */ +	u8 sharpness;  	u8 infrared;			/* mt9v111 only */  	u8 freq;			/* ov76xx only */  	u8 quality;			/* image quality */ @@ -64,16 +66,17 @@ struct sd {  #define BRIDGE_SN9C110 2  #define BRIDGE_SN9C120 3  	u8 sensor;			/* Type of image sensor chip */ -#define SENSOR_HV7131R 0 -#define SENSOR_MI0360 1 -#define SENSOR_MO4000 2 -#define SENSOR_MT9V111 3 -#define SENSOR_OM6802 4 -#define SENSOR_OV7630 5 -#define SENSOR_OV7648 6 -#define SENSOR_OV7660 7 -#define SENSOR_PO1030 8 -#define SENSOR_SP80708 9 +#define SENSOR_ADCM1700 0 +#define SENSOR_HV7131R 1 +#define SENSOR_MI0360 2 +#define SENSOR_MO4000 3 +#define SENSOR_MT9V111 4 +#define SENSOR_OM6802 5 +#define SENSOR_OV7630 6 +#define SENSOR_OV7648 7 +#define SENSOR_OV7660 8 +#define SENSOR_PO1030 9 +#define SENSOR_SP80708 10  	u8 i2c_addr;  	u8 *jpeg_hdr; @@ -96,12 +99,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);  static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);  static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);  static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);  static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);  static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);  static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);  static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); -static struct ctrl sd_ctrls[] = { +static const struct ctrl sd_ctrls[] = {  #define BRIGHTNESS_IDX 0  	{  	    { @@ -225,8 +230,23 @@ static struct ctrl sd_ctrls[] = {  	    .set = sd_setvflip,  	    .get = sd_getvflip,  	}, +#define SHARPNESS_IDX 8 +	{ +	    { +		.id	 = V4L2_CID_SHARPNESS, +		.type    = V4L2_CTRL_TYPE_INTEGER, +		.name    = "Sharpness", +		.minimum = 0, +		.maximum = 255, +		.step    = 1, +#define SHARPNESS_DEF 90 +		.default_value = SHARPNESS_DEF, +	    }, +	    .set = sd_setsharpness, +	    .get = sd_getsharpness, +	},  /* mt9v111 only */ -#define INFRARED_IDX 8 +#define INFRARED_IDX 9  	{  	    {  		.id      = V4L2_CID_INFRARED, @@ -242,7 +262,7 @@ static struct ctrl sd_ctrls[] = {  	    .get = sd_getinfrared,  	},  /* ov7630/ov7648/ov7660 only */ -#define FREQ_IDX 9 +#define FREQ_IDX 10  	{  	    {  		.id	 = V4L2_CID_POWER_LINE_FREQUENCY, @@ -261,28 +281,37 @@ static struct ctrl sd_ctrls[] = {  /* table of the disabled controls */  static __u32 ctrl_dis[] = { +	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX) | +			(1 << AUTOGAIN_IDX),	/* SENSOR_ADCM1700 0 */ +	(1 << INFRARED_IDX) | (1 << FREQ_IDX), +						/* SENSOR_HV7131R 1 */  	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), -						/* SENSOR_HV7131R 0 */ +						/* SENSOR_MI0360 2 */  	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), -						/* SENSOR_MI0360 1 */ -	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), -						/* SENSOR_MO4000 2 */ +						/* SENSOR_MO4000 3 */  	(1 << VFLIP_IDX) | (1 << FREQ_IDX), -						/* SENSOR_MT9V111 3 */ +						/* SENSOR_MT9V111 4 */  	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), -						/* SENSOR_OM6802 4 */ +						/* SENSOR_OM6802 5 */  	(1 << INFRARED_IDX), -						/* SENSOR_OV7630 5 */ +						/* SENSOR_OV7630 6 */  	(1 << INFRARED_IDX), -						/* SENSOR_OV7648 6 */ +						/* SENSOR_OV7648 7 */  	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), -						/* SENSOR_OV7660 7 */ +						/* SENSOR_OV7660 8 */  	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | -			      (1 << FREQ_IDX),	/* SENSOR_PO1030 8 */ +			      (1 << FREQ_IDX),	/* SENSOR_PO1030 9 */  	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | -			      (1 << FREQ_IDX),	/* SENSOR_SP80708 9 */ +			      (1 << FREQ_IDX),	/* SENSOR_SP80708 10 */  }; +static const struct v4l2_pix_format cif_mode[] = { +	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, +		.bytesperline = 352, +		.sizeimage = 352 * 288 * 4 / 8 + 590, +		.colorspace = V4L2_COLORSPACE_JPEG, +		.priv = 0}, +};  static const struct v4l2_pix_format vga_mode[] = {  	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,  		.bytesperline = 160, @@ -302,6 +331,17 @@ static const struct v4l2_pix_format vga_mode[] = {  		.priv = 0},  }; +static const u8 sn_adcm1700[0x1c] = { +/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */ +	0x00,	0x43,	0x60,	0x00,	0x1a,	0x00,	0x00,	0x00, +/*	reg8	reg9	rega	regb	regc	regd	rege	regf */ +	0x80,	0x51,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00, +/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */ +	0x03,	0x00,	0x05,	0x01,	0x05,	0x16,	0x12,	0x42, +/*	reg18	reg19	reg1a	reg1b */ +	0x06,	0x00,	0x00,	0x00 +}; +  /*Data from sn9c102p+hv7131r */  static const u8 sn_hv7131[0x1c] = {  /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */ @@ -415,6 +455,7 @@ static const u8 sn_sp80708[0x1c] = {  /* sequence specific to the sensors - !! index = SENSOR_xxx */  static const u8 *sn_tb[] = { +	sn_adcm1700,  	sn_hv7131,  	sn_mi0360,  	sn_mo4000, @@ -432,6 +473,11 @@ static const u8 gamma_def[17] = {  	0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,  	0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff  }; +/* gamma for sensor ADCM1700 */ +static const u8 gamma_spec_0[17] = { +	0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4, +	0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5 +};  /* gamma for sensors HV7131R and MT9V111 */  static const u8 gamma_spec_1[17] = {  	0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, @@ -450,6 +496,42 @@ static const u8 reg84[] = {  	0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,	/* VR VG VB */  	0x00, 0x00, 0x00			/* YUV offsets */  }; +static const u8 adcm1700_sensor_init[][8] = { +	{0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10},	/* reset */ +	{0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +	{0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}, +	{0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +	{0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10}, +	{0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +	{0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10}, +	{0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +	{0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10}, +	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, +	{} +}; +static const u8 adcm1700_sensor_param1[][8] = { +	{0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10},	/* exposure? */ +	{0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10}, + +	{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10}, +	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10}, +	{0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10},	/* exposure? */ + +	{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10}, +	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10}, +	{0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10}, +	{} +};  static const u8 hv7131r_sensor_init[][8] = {  	{0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},  	{0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, @@ -986,17 +1068,18 @@ static const u8 sp80708_sensor_param1[][8] = {  	{}  }; -static const u8 (*sensor_init[10])[8] = { -	hv7131r_sensor_init,	/* HV7131R 0 */ -	mi0360_sensor_init,	/* MI0360 1 */ -	mo4000_sensor_init,	/* MO4000 2 */ -	mt9v111_sensor_init,	/* MT9V111 3 */ -	om6802_sensor_init,	/* OM6802 4 */ -	ov7630_sensor_init,	/* OV7630 5 */ -	ov7648_sensor_init,	/* OV7648 6 */ -	ov7660_sensor_init,	/* OV7660 7 */ -	po1030_sensor_init,	/* PO1030 8 */ -	sp80708_sensor_init,	/* SP80708 9 */ +static const u8 (*sensor_init[11])[8] = { +	adcm1700_sensor_init,	/* ADCM1700 0 */ +	hv7131r_sensor_init,	/* HV7131R 1 */ +	mi0360_sensor_init,	/* MI0360 2 */ +	mo4000_sensor_init,	/* MO4000 3 */ +	mt9v111_sensor_init,	/* MT9V111 4 */ +	om6802_sensor_init,	/* OM6802 5 */ +	ov7630_sensor_init,	/* OV7630 6 */ +	ov7648_sensor_init,	/* OV7648 7 */ +	ov7660_sensor_init,	/* OV7660 8 */ +	po1030_sensor_init,	/* PO1030 9 */ +	sp80708_sensor_init,	/* SP80708 10 */  };  /* read <len> bytes to gspca_dev->usb_buf */ @@ -1064,6 +1147,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)  	PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);  	switch (sd->sensor) { +	case SENSOR_ADCM1700:  	case SENSOR_OM6802:		/* i2c command = a0 (100 kHz) */  		gspca_dev->usb_buf[0] = 0x80 | (2 << 4);  		break; @@ -1110,6 +1194,7 @@ static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)  	u8 mode[8];  	switch (sd->sensor) { +	case SENSOR_ADCM1700:  	case SENSOR_OM6802:		/* i2c command = 90 (100 kHz) */  		mode[0] = 0x80 | 0x10;  		break; @@ -1260,7 +1345,8 @@ static void bridge_init(struct gspca_dev *gspca_dev,  		{0x00, 0x40, 0x38, 0x30, 0x00, 0x20};  	static const u8 regd4[] = {0x60, 0x00, 0x00}; -	reg_w1(gspca_dev, 0xf1, 0x00); +	/* sensor clock already enabled in sd_init */ +	/* reg_w1(gspca_dev, 0xf1, 0x00); */  	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);  	/* configure gpio */ @@ -1284,6 +1370,12 @@ static void bridge_init(struct gspca_dev *gspca_dev,  	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);  	switch (sd->sensor) { +	case SENSOR_ADCM1700: +		reg_w1(gspca_dev, 0x01, 0x43); +		reg_w1(gspca_dev, 0x17, 0x62); +		reg_w1(gspca_dev, 0x01, 0x42); +		reg_w1(gspca_dev, 0x01, 0x42); +		break;  	case SENSOR_MT9V111:  		reg_w1(gspca_dev, 0x01, 0x61);  		reg_w1(gspca_dev, 0x17, 0x61); @@ -1357,14 +1449,19 @@ static int sd_config(struct gspca_dev *gspca_dev,  	struct sd *sd = (struct sd *) gspca_dev;  	struct cam *cam; -	cam = &gspca_dev->cam; -	cam->cam_mode = vga_mode; -	cam->nmodes = ARRAY_SIZE(vga_mode); -	cam->npkt = 24;			/* 24 packets per ISOC message */ -  	sd->bridge = id->driver_info >> 16;  	sd->sensor = id->driver_info; +	cam = &gspca_dev->cam; +	if (sd->sensor == SENSOR_ADCM1700) { +		cam->cam_mode = cif_mode; +		cam->nmodes = ARRAY_SIZE(cif_mode); +	} else { +		cam->cam_mode = vga_mode; +		cam->nmodes = ARRAY_SIZE(vga_mode); +	} +	cam->npkt = 24;			/* 24 packets per ISOC message */ +  	sd->brightness = BRIGHTNESS_DEF;  	sd->contrast = CONTRAST_DEF;  	sd->colors = COLOR_DEF; @@ -1374,6 +1471,14 @@ static int sd_config(struct gspca_dev *gspca_dev,  	sd->autogain = AUTOGAIN_DEF;  	sd->ag_cnt = -1;  	sd->vflip = VFLIP_DEF; +	switch (sd->sensor) { +	case SENSOR_OM6802: +		sd->sharpness = 0x10; +		break; +	default: +		sd->sharpness = SHARPNESS_DEF; +		break; +	}  	sd->infrared = INFRARED_DEF;  	sd->freq = FREQ_DEF;  	sd->quality = QUALITY_DEF; @@ -1433,7 +1538,9 @@ static int sd_init(struct gspca_dev *gspca_dev)  		break;  	} -	reg_w1(gspca_dev, 0xf1, 0x01); +	/* Note we do not disable the sensor clock here (power saving mode), +	   as that also disables the button on the cam. */ +	reg_w1(gspca_dev, 0xf1, 0x00);  	/* set the i2c address */  	sn9c1xx = sn_tb[sd->sensor]; @@ -1543,6 +1650,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)  	k2 = ((int) sd->brightness - 0x8000) >> 10;  	switch (sd->sensor) { +	case SENSOR_ADCM1700: +		if (k2 > 0x1f) +			k2 = 0;		/* only positive Y offset */ +		break;  	case SENSOR_HV7131R:  		expo = sd->brightness << 4;  		if (expo > 0x002dc6c0) @@ -1625,6 +1736,9 @@ static void setgamma(struct gspca_dev *gspca_dev)  	};  	switch (sd->sensor) { +	case SENSOR_ADCM1700: +		gamma_base = gamma_spec_0; +		break;  	case SENSOR_HV7131R:  	case SENSOR_MT9V111:  		gamma_base = gamma_spec_1; @@ -1670,23 +1784,39 @@ static void setautogain(struct gspca_dev *gspca_dev)  		sd->ag_cnt = -1;  } -/* ov7630/ov7648 only */ +/* hv7131r/ov7630/ov7648 only */  static void setvflip(struct sd *sd)  {  	u8 comn;  	if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))  		return; -	if (sd->sensor == SENSOR_OV7630) { +	switch (sd->sensor) { +	case SENSOR_HV7131R: +		comn = 0x18;			/* clkdiv = 1, ablcen = 1 */ +		if (sd->vflip) +			comn |= 0x01; +		i2c_w1(&sd->gspca_dev, 0x01, comn);	/* sctra */ +		break; +	case SENSOR_OV7630:  		comn = 0x02;  		if (!sd->vflip)  			comn |= 0x80; -	} else { +		i2c_w1(&sd->gspca_dev, 0x75, comn); +		break; +	default: +/*	case SENSOR_OV7648: */  		comn = 0x06;  		if (sd->vflip)  			comn |= 0x80; +		i2c_w1(&sd->gspca_dev, 0x75, comn); +		break;  	} -	i2c_w1(&sd->gspca_dev, 0x75, comn); +} + +static void setsharpness(struct sd *sd) +{ +	reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);  }  static void setinfrared(struct sd *sd) @@ -1804,6 +1934,8 @@ static int sd_start(struct gspca_dev *gspca_dev)  	int mode;  	static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };  	static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; +	static const u8 CA_adcm1700[] = +				{ 0x14, 0xec, 0x0a, 0xf6 };  	static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };	/* MI0360 */  	static const u8 CE_ov76xx[] =  				{ 0x32, 0xdd, 0x32, 0xdd }; @@ -1824,6 +1956,9 @@ static int sd_start(struct gspca_dev *gspca_dev)  	i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);  	switch (sd->sensor) { +	case SENSOR_ADCM1700: +		reg2 = 0x60; +		break;  	case SENSOR_OM6802:  		reg2 = 0x71;  		break; @@ -1842,17 +1977,28 @@ static int sd_start(struct gspca_dev *gspca_dev)  	reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);  	reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);  	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); -	reg_w1(gspca_dev, 0xd2, 0x6a);		/* DC29 */ -	reg_w1(gspca_dev, 0xd3, 0x50); +	if (sd->sensor == SENSOR_ADCM1700) { +		reg_w1(gspca_dev, 0xd2, 0x3a);	/* AE_H_SIZE = 116 */ +		reg_w1(gspca_dev, 0xd3, 0x30);	/* AE_V_SIZE = 96 */ +	} else { +		reg_w1(gspca_dev, 0xd2, 0x6a);	/* AE_H_SIZE = 212 */ +		reg_w1(gspca_dev, 0xd3, 0x50);	/* AE_V_SIZE = 160 */ +	}  	reg_w1(gspca_dev, 0xc6, 0x00);  	reg_w1(gspca_dev, 0xc7, 0x00); -	reg_w1(gspca_dev, 0xc8, 0x50); -	reg_w1(gspca_dev, 0xc9, 0x3c); +	if (sd->sensor == SENSOR_ADCM1700) { +		reg_w1(gspca_dev, 0xc8, 0x2c);	/* AW_H_STOP = 352 */ +		reg_w1(gspca_dev, 0xc9, 0x24);	/* AW_V_STOP = 288 */ +	} else { +		reg_w1(gspca_dev, 0xc8, 0x50);	/* AW_H_STOP = 640 */ +		reg_w1(gspca_dev, 0xc9, 0x3c);	/* AW_V_STOP = 480 */ +	}  	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);  	switch (sd->sensor) {  	case SENSOR_MT9V111:  		reg17 = 0xe0;  		break; +	case SENSOR_ADCM1700:  	case SENSOR_OV7630:  		reg17 = 0xe2;  		break; @@ -1870,44 +2016,39 @@ static int sd_start(struct gspca_dev *gspca_dev)  		break;  	}  	reg_w1(gspca_dev, 0x17, reg17); -/* set reg1 was here */ -	reg_w1(gspca_dev, 0x05, sn9c1xx[5]);	/* red */ -	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);	/* green */ -	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);	/* blue */ + +	reg_w1(gspca_dev, 0x05, 0x00);		/* red */ +	reg_w1(gspca_dev, 0x07, 0x00);		/* green */ +	reg_w1(gspca_dev, 0x06, 0x00);		/* blue */  	reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);  	setgamma(gspca_dev); +/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */  	for (i = 0; i < 8; i++)  		reg_w(gspca_dev, 0x84, reg84, sizeof reg84);  	switch (sd->sensor) { +	case SENSOR_ADCM1700: +	case SENSOR_OV7660: +	case SENSOR_SP80708: +		reg_w1(gspca_dev, 0x9a, 0x05); +		break;  	case SENSOR_MT9V111:  		reg_w1(gspca_dev, 0x9a, 0x07); -		reg_w1(gspca_dev, 0x99, 0x59); -		break; -	case SENSOR_OM6802: -		reg_w1(gspca_dev, 0x9a, 0x08); -		reg_w1(gspca_dev, 0x99, 0x10);  		break;  	case SENSOR_OV7648:  		reg_w1(gspca_dev, 0x9a, 0x0a); -		reg_w1(gspca_dev, 0x99, 0x60); -		break; -	case SENSOR_OV7660: -	case SENSOR_SP80708: -		reg_w1(gspca_dev, 0x9a, 0x05); -		reg_w1(gspca_dev, 0x99, 0x59);  		break;  	default:  		reg_w1(gspca_dev, 0x9a, 0x08); -		reg_w1(gspca_dev, 0x99, 0x59);  		break;  	} +	setsharpness(sd);  	reg_w(gspca_dev, 0x84, reg84, sizeof reg84); -	reg_w1(gspca_dev, 0x05, sn9c1xx[5]);	/* red */ -	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);	/* green */ -	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);	/* blue */ +	reg_w1(gspca_dev, 0x05, 0x20);		/* red */ +	reg_w1(gspca_dev, 0x07, 0x20);		/* green */ +	reg_w1(gspca_dev, 0x06, 0x20);		/* blue */  	init = NULL;  	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; @@ -1917,6 +2058,11 @@ static int sd_start(struct gspca_dev *gspca_dev)  		reg1 = 0x06;	/* 640x480: clk 24Mhz, video trf enable */  	reg17 = 0x61;		/* 0x:20: enable sensor clock */  	switch (sd->sensor) { +	case SENSOR_ADCM1700: +		init = adcm1700_sensor_param1; +		reg1 = 0x46; +		reg17 = 0xe2; +		break;  	case SENSOR_MO4000:  		if (mode) {  /*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */ @@ -1940,7 +2086,6 @@ static int sd_start(struct gspca_dev *gspca_dev)  		reg17 = 0x64;		/* 640 MCKSIZE */  		break;  	case SENSOR_OV7630: -		setvflip(sd);  		reg17 = 0xe2;  		reg1 = 0x44;  		break; @@ -1986,8 +2131,12 @@ static int sd_start(struct gspca_dev *gspca_dev)  	}  	reg_w(gspca_dev, 0xc0, C0, 6); -	reg_w(gspca_dev, 0xca, CA, 4); +	if (sd->sensor == SENSOR_ADCM1700) +		reg_w(gspca_dev, 0xca, CA_adcm1700, 4); +	else +		reg_w(gspca_dev, 0xca, CA, 4);  	switch (sd->sensor) { +	case SENSOR_ADCM1700:  	case SENSOR_OV7630:  	case SENSOR_OV7648:  	case SENSOR_OV7660: @@ -2008,11 +2157,7 @@ static int sd_start(struct gspca_dev *gspca_dev)  	reg_w1(gspca_dev, 0x17, reg17);  	reg_w1(gspca_dev, 0x01, reg1); -	switch (sd->sensor) { -	case SENSOR_OV7630: -		setvflip(sd); -		break; -	} +	setvflip(sd);  	setbrightness(gspca_dev);  	setcontrast(gspca_dev);  	setautogain(gspca_dev); @@ -2056,7 +2201,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)  	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);  	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);  	reg_w1(gspca_dev, 0x01, data); -	reg_w1(gspca_dev, 0xf1, 0x00); +	/* Don't disable sensor clock as that disables the button on the cam */ +	/* reg_w1(gspca_dev, 0xf1, 0x01); */  }  static void sd_stop0(struct gspca_dev *gspca_dev) @@ -2288,6 +2434,24 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)  	return 0;  } +static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) +{ +	struct sd *sd = (struct sd *) gspca_dev; + +	sd->sharpness = val; +	if (gspca_dev->streaming) +		setsharpness(sd); +	return 0; +} + +static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) +{ +	struct sd *sd = (struct sd *) gspca_dev; + +	*val = sd->sharpness; +	return 0; +} +  static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)  {  	struct sd *sd = (struct sd *) gspca_dev; @@ -2391,6 +2555,25 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,  	return -EINVAL;  } +#ifdef CONFIG_INPUT +static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, +			u8 *data,		/* interrupt packet data */ +			int len)		/* interrupt packet length */ +{ +	int ret = -EINVAL; + +	if (len == 1 && data[0] == 1) { +		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); +		input_sync(gspca_dev->input_dev); +		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); +		input_sync(gspca_dev->input_dev); +		ret = 0; +	} + +	return ret; +} +#endif +  /* sub-driver description */  static const struct sd_desc sd_desc = {  	.name = MODULE_NAME, @@ -2406,6 +2589,9 @@ static const struct sd_desc sd_desc = {  	.get_jcomp = sd_get_jcomp,  	.set_jcomp = sd_set_jcomp,  	.querymenu = sd_querymenu, +#ifdef CONFIG_INPUT +	.int_pkt_scan = sd_int_pkt_scan, +#endif  };  /* -- module initialisation -- */ @@ -2472,6 +2658,7 @@ static const __devinitdata struct usb_device_id device_table[] = {  /*	{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},	 *sn9c120b*/  	{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},	/*sn9c120b*/  	{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},	/*sn9c120b*/ +	{USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)},	/*sn9c120b*/  	{}  };  MODULE_DEVICE_TABLE(usb, device_table);  |