diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 6e04ac79f401..3c699ac5233f 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -75,6 +75,7 @@ enum sensors {
 	SENSOR_GC0307,
 	SENSOR_HV7131R,
 	SENSOR_MI0360,
+	SENSOR_MI0360B,
 	SENSOR_MO4000,
 	SENSOR_MT9V111,
 	SENSOR_OM6802,
@@ -302,6 +303,10 @@ static const __u32 ctrl_dis[] = {
 			(1 << VFLIP_IDX) |
 			(1 << FREQ_IDX),
 
+[SENSOR_MI0360B] =	(1 << INFRARED_IDX) |
+			(1 << VFLIP_IDX) |
+			(1 << FREQ_IDX),
+
 [SENSOR_MO4000] =	(1 << INFRARED_IDX) |
 			(1 << VFLIP_IDX) |
 			(1 << FREQ_IDX),
@@ -411,6 +416,17 @@ static const u8 sn_mi0360[0x1c] = {
 	0x06,	0x00,	0x00,	0x00
 };
 
+static const u8 sn_mi0360b[0x1c] = {
+/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
+	0x00,	0x61,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
+/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
+	0x81,	0x5d,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
+/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
+	0x03,	0x00,	0x00,	0x02,	0x0a,	0x28,	0x1e,	0x40,
+/*	reg18	reg19	reg1a	reg1b */
+	0x06,	0x00,	0x00,	0x00
+};
+
 static const u8 sn_mo4000[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x23,	0x60,	0x00,	0x1a,	0x00,	0x20,	0x18,
@@ -527,6 +543,7 @@ static const u8 *sn_tb[] = {
 [SENSOR_GC0307] =	sn_gc0307,
 [SENSOR_HV7131R] =	sn_hv7131,
 [SENSOR_MI0360] =	sn_mi0360,
+[SENSOR_MI0360B] =	sn_mi0360b,
 [SENSOR_MO4000] =	sn_mo4000,
 [SENSOR_MT9V111] =	sn_mt9v111,
 [SENSOR_OM6802] =	sn_om6802,
@@ -747,6 +764,62 @@ static const u8 mi0360_sensor_init[][8] = {
 	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
 	{}
 };
+static const u8 mi0360b_sensor_init[][8] = {
+	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
+	{0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
+	{0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
+	{0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
+	{0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
+	{0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
+	{0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
+	{0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
+	{0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
+	{0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
+	{0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
+
+	{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
+	{0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
+	{}
+};
+static const u8 mi0360b_sensor_param1[][8] = {
+	{0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
+
+	{0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
+	{0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
+	{0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
+	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
+	{}
+};
 static const u8 mo4000_sensor_init[][8] = {
 	{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -1310,6 +1383,7 @@ static const u8 (*sensor_init[])[8] = {
 [SENSOR_GC0307] =	gc0307_sensor_init,
 [SENSOR_HV7131R] =	hv7131r_sensor_init,
 [SENSOR_MI0360] =	mi0360_sensor_init,
+[SENSOR_MI0360B] =	mi0360b_sensor_init,
 [SENSOR_MO4000] =	mo4000_sensor_init,
 [SENSOR_MT9V111] =	mt9v111_sensor_init,
 [SENSOR_OM6802] =	om6802_sensor_init,
@@ -1571,6 +1645,10 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
 	if (gspca_dev->usb_err < 0)
 		return;
 	switch (val) {
+	case 0x8221:
+		PDEBUG(D_PROBE, "Sensor mi0360b");
+		sd->sensor = SENSOR_MI0360B;
+		break;
 	case 0x823a:
 		PDEBUG(D_PROBE, "Sensor mt9v111");
 		sd->sensor = SENSOR_MT9V111;
@@ -1744,6 +1822,12 @@ static void bridge_init(struct gspca_dev *gspca_dev,
 		reg_w1(gspca_dev, 0x01, 0x40);
 		msleep(50);
 		break;
+	case SENSOR_MI0360B:
+		reg_w1(gspca_dev, 0x01, 0x61);
+		reg_w1(gspca_dev, 0x17, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x40);
+		break;
 	case SENSOR_MT9V111:
 		reg_w1(gspca_dev, 0x01, 0x61);
 		reg_w1(gspca_dev, 0x17, 0x61);
@@ -1961,7 +2045,8 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
 		i2c_w8(gspca_dev, Expodoit);
 		break;
 	    }
-	case SENSOR_MI0360: {
+	case SENSOR_MI0360:
+	case SENSOR_MI0360B: {
 		u8 expoMi[] =		/* exposure 0x0635 -> 4 fp/s 0x10 */
 			{ 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
 		static const u8 doit[] =		/* update sensor */
@@ -2061,6 +2146,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
 		expo = sd->brightness >> 4;
 		sd->exposure = setexposure(gspca_dev, expo);
 		break;
+	case SENSOR_MI0360B:
+		expo = sd->brightness >> 6;
+		sd->exposure = setexposure(gspca_dev, expo);
+		break;
 	case SENSOR_GC0307:
 	case SENSOR_MT9V111:
 		expo = sd->brightness >> 8;
@@ -2096,12 +2185,21 @@ static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i, v;
+	const s16 *uv;
 	u8 reg8a[12];			/* U & V gains */
-	static const s16 uv[6] = {	/* same as reg84 in signed decimal */
+	static const s16 uv_com[6] = {	/* same as reg84 in signed decimal */
 		-24, -38, 64,		/* UR UG UB */
 		 62, -51, -9		/* VR VG VB */
 	};
+	static const s16 uv_mi0360b[6] = {
+		-20, -38, 64,		/* UR UG UB */
+		 60, -51, -9		/* VR VG VB */
+	};
 
+	if (sd->sensor == SENSOR_MI0360B)
+		uv = uv_mi0360b;
+	else
+		uv = uv_com;
 	for (i = 0; i < 6; i++) {
 		v = uv[i] * sd->colors / COLOR_DEF;
 		reg8a[i * 2] = v;
@@ -2135,6 +2233,7 @@ static void setgamma(struct gspca_dev *gspca_dev)
 		gamma_base = gamma_spec_0;
 		break;
 	case SENSOR_HV7131R:
+	case SENSOR_MI0360B:
 	case SENSOR_MT9V111:
 		gamma_base = gamma_spec_1;
 		break;
@@ -2383,6 +2482,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg17 = 0xa2;
 		break;
 	case SENSOR_MT9V111:
+	case SENSOR_MI0360B:
 		reg17 = 0xe0;
 		break;
 	case SENSOR_ADCM1700:
@@ -2424,6 +2524,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		break;
 	case SENSOR_GC0307:
 	case SENSOR_MT9V111:
+	case SENSOR_MI0360B:
 		reg_w1(gspca_dev, 0x9a, 0x07);
 		break;
 	case SENSOR_OV7630:
@@ -2463,6 +2564,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg17 = 0xa2;
 		reg1 = 0x44;
 		break;
+	case SENSOR_MI0360B:
+		init = mi0360b_sensor_param1;
+		reg1 &= ~0x02;		/* don't inverse pin S_PWR_DN */
+		reg17 = 0xe2;
+		break;
 	case SENSOR_MO4000:
 		if (mode) {
 /*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */
@@ -2617,6 +2723,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 		data = 0x2b;
 		break;
 	case SENSOR_MI0360:
+	case SENSOR_MI0360B:
 		i2c_w8(gspca_dev, stopmi0360);
 		data = 0x29;
 		break;
@@ -2690,6 +2797,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
 		default:
 /*		case SENSOR_MO4000: */
 /*		case SENSOR_MI0360: */
+/*		case SENSOR_MI0360B: */
 /*		case SENSOR_MT9V111: */
 			expotimes = sd->exposure;
 			expotimes += (luma_mean - delta) >> 6;
@@ -3054,6 +3162,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
 /*	{USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
 	{USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
+						/* or MT9V111 */
 /*	{USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
 /*	{USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
 /*	{USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
@@ -3086,6 +3195,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 /*	{USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
+						/* or MT9V111 / MI0360B */
 #endif
 /*	{USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
 	{USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},