فهرست منبع

Merge branch 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6:
  [media] fix saa7111 non-detection
  [media] rc/streamzap: fix reporting response times
  [media] mceusb: really fix remaining keybounce issues
  [media] rc: use time unit conversion macros correctly
  [media] rc/ir-lirc-codec: add back debug spew
  [media] ir-kbd-i2c: improve remote behavior with z8 behind usb
  [media] lirc_zilog: z8 on usb doesn't like back-to-back i2c_master_send
  [media] hdpvr: fix up i2c device registration
  [media] rc/mce: add mappings for missing keys
  [media] gspca - zc3xx: Discard the partial frames
  [media] gspca - zc3xx: Fix bad images with the sensor hv7131r
  [media] gspca - zc3xx: Bad delay when given by a table
Linus Torvalds 14 سال پیش
والد
کامیت
f2f1756d7d

+ 5 - 1
drivers/media/rc/ir-lirc-codec.c

@@ -1,4 +1,4 @@
-/* ir-lirc-codec.c - ir-core to classic lirc interface bridge
+/* ir-lirc-codec.c - rc-core to classic lirc interface bridge
  *
  *
  * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
  * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
  *
  *
@@ -47,6 +47,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
 	/* Carrier reports */
 	/* Carrier reports */
 	if (ev.carrier_report) {
 	if (ev.carrier_report) {
 		sample = LIRC_FREQUENCY(ev.carrier);
 		sample = LIRC_FREQUENCY(ev.carrier);
+		IR_dprintk(2, "carrier report (freq: %d)\n", sample);
 
 
 	/* Packet end */
 	/* Packet end */
 	} else if (ev.timeout) {
 	} else if (ev.timeout) {
@@ -62,6 +63,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
 			return 0;
 			return 0;
 
 
 		sample = LIRC_TIMEOUT(ev.duration / 1000);
 		sample = LIRC_TIMEOUT(ev.duration / 1000);
+		IR_dprintk(2, "timeout report (duration: %d)\n", sample);
 
 
 	/* Normal sample */
 	/* Normal sample */
 	} else {
 	} else {
@@ -85,6 +87,8 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
 
 
 		sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
 		sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
 					LIRC_SPACE(ev.duration / 1000);
 					LIRC_SPACE(ev.duration / 1000);
+		IR_dprintk(2, "delivering %uus %s to lirc_dev\n",
+			   TO_US(ev.duration), TO_STR(ev.pulse));
 	}
 	}
 
 
 	lirc_buffer_write(dev->raw->lirc.drv->rbuf,
 	lirc_buffer_write(dev->raw->lirc.drv->rbuf,

+ 6 - 0
drivers/media/rc/keymaps/rc-rc6-mce.c

@@ -3,6 +3,9 @@
  *
  *
  * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
  * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
  *
  *
+ * See http://mediacenterguides.com/book/export/html/31 for details on
+ * key mappings.
+ *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * the Free Software Foundation; either version 2 of the License, or
@@ -60,6 +63,9 @@ static struct rc_map_table rc6_mce[] = {
 	{ 0x800f0426, KEY_EPG },		/* Guide */
 	{ 0x800f0426, KEY_EPG },		/* Guide */
 	{ 0x800f0427, KEY_ZOOM },		/* Aspect */
 	{ 0x800f0427, KEY_ZOOM },		/* Aspect */
 
 
+	{ 0x800f0432, KEY_MODE },		/* Visualization */
+	{ 0x800f0433, KEY_PRESENTATION },	/* Slide Show */
+	{ 0x800f0434, KEY_EJECTCD },
 	{ 0x800f043a, KEY_BRIGHTNESSUP },
 	{ 0x800f043a, KEY_BRIGHTNESSUP },
 
 
 	{ 0x800f0446, KEY_TV },
 	{ 0x800f0446, KEY_TV },

+ 6 - 3
drivers/media/rc/mceusb.c

@@ -816,7 +816,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
 	switch (ir->buf_in[index]) {
 	switch (ir->buf_in[index]) {
 	/* 2-byte return value commands */
 	/* 2-byte return value commands */
 	case MCE_CMD_S_TIMEOUT:
 	case MCE_CMD_S_TIMEOUT:
-		ir->rc->timeout = MS_TO_NS((hi << 8 | lo) / 2);
+		ir->rc->timeout = US_TO_NS((hi << 8 | lo) / 2);
 		break;
 		break;
 
 
 	/* 1-byte return value commands */
 	/* 1-byte return value commands */
@@ -855,9 +855,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
 			break;
 			break;
 		case PARSE_IRDATA:
 		case PARSE_IRDATA:
 			ir->rem--;
 			ir->rem--;
+			init_ir_raw_event(&rawir);
 			rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
 			rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
 			rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
 			rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
-					 * MS_TO_US(MCE_TIME_UNIT);
+					 * US_TO_NS(MCE_TIME_UNIT);
 
 
 			dev_dbg(ir->dev, "Storing %s with duration %d\n",
 			dev_dbg(ir->dev, "Storing %s with duration %d\n",
 				rawir.pulse ? "pulse" : "space",
 				rawir.pulse ? "pulse" : "space",
@@ -883,6 +884,8 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
 					     i, ir->rem + 1, false);
 					     i, ir->rem + 1, false);
 			if (ir->rem)
 			if (ir->rem)
 				ir->parser_state = PARSE_IRDATA;
 				ir->parser_state = PARSE_IRDATA;
+			else
+				ir_raw_event_reset(ir->rc);
 			break;
 			break;
 		}
 		}
 
 
@@ -1060,7 +1063,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
 	rc->priv = ir;
 	rc->priv = ir;
 	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->allowed_protos = RC_TYPE_ALL;
 	rc->allowed_protos = RC_TYPE_ALL;
-	rc->timeout = MS_TO_NS(1000);
+	rc->timeout = US_TO_NS(1000);
 	if (!ir->flags.no_tx) {
 	if (!ir->flags.no_tx) {
 		rc->s_tx_mask = mceusb_set_tx_mask;
 		rc->s_tx_mask = mceusb_set_tx_mask;
 		rc->s_tx_carrier = mceusb_set_tx_carrier;
 		rc->s_tx_carrier = mceusb_set_tx_carrier;

+ 3 - 3
drivers/media/rc/nuvoton-cir.c

@@ -460,7 +460,7 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt)
 		return 0;
 		return 0;
 	}
 	}
 
 
-	carrier = (count * 1000000) / duration;
+	carrier = MS_TO_NS(count) / duration;
 
 
 	if ((carrier > MAX_CARRIER) || (carrier < MIN_CARRIER))
 	if ((carrier > MAX_CARRIER) || (carrier < MIN_CARRIER))
 		nvt_dbg("WTF? Carrier frequency out of range!");
 		nvt_dbg("WTF? Carrier frequency out of range!");
@@ -612,8 +612,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
 		sample = nvt->buf[i];
 		sample = nvt->buf[i];
 
 
 		rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
 		rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
-		rawir.duration = (sample & BUF_LEN_MASK)
-					* SAMPLE_PERIOD * 1000;
+		rawir.duration = US_TO_NS((sample & BUF_LEN_MASK)
+					  * SAMPLE_PERIOD);
 
 
 		if ((sample & BUF_LEN_MASK) == BUF_LEN_MASK) {
 		if ((sample & BUF_LEN_MASK) == BUF_LEN_MASK) {
 			if (nvt->rawir.pulse == rawir.pulse)
 			if (nvt->rawir.pulse == rawir.pulse)

+ 8 - 6
drivers/media/rc/streamzap.c

@@ -164,7 +164,7 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
 				sz->signal_start.tv_usec -
 				sz->signal_start.tv_usec -
 				sz->signal_last.tv_usec);
 				sz->signal_last.tv_usec);
 			rawir.duration -= sz->sum;
 			rawir.duration -= sz->sum;
-			rawir.duration *= 1000;
+			rawir.duration = US_TO_NS(rawir.duration);
 			rawir.duration &= IR_MAX_DURATION;
 			rawir.duration &= IR_MAX_DURATION;
 		}
 		}
 		sz_push(sz, rawir);
 		sz_push(sz, rawir);
@@ -177,7 +177,7 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
 	rawir.duration = ((int) value) * SZ_RESOLUTION;
 	rawir.duration = ((int) value) * SZ_RESOLUTION;
 	rawir.duration += SZ_RESOLUTION / 2;
 	rawir.duration += SZ_RESOLUTION / 2;
 	sz->sum += rawir.duration;
 	sz->sum += rawir.duration;
-	rawir.duration *= 1000;
+	rawir.duration = US_TO_NS(rawir.duration);
 	rawir.duration &= IR_MAX_DURATION;
 	rawir.duration &= IR_MAX_DURATION;
 	sz_push(sz, rawir);
 	sz_push(sz, rawir);
 }
 }
@@ -197,7 +197,7 @@ static void sz_push_full_space(struct streamzap_ir *sz,
 	rawir.duration = ((int) value) * SZ_RESOLUTION;
 	rawir.duration = ((int) value) * SZ_RESOLUTION;
 	rawir.duration += SZ_RESOLUTION / 2;
 	rawir.duration += SZ_RESOLUTION / 2;
 	sz->sum += rawir.duration;
 	sz->sum += rawir.duration;
-	rawir.duration *= 1000;
+	rawir.duration = US_TO_NS(rawir.duration);
 	sz_push(sz, rawir);
 	sz_push(sz, rawir);
 }
 }
 
 
@@ -273,6 +273,7 @@ static void streamzap_callback(struct urb *urb)
 				if (sz->timeout_enabled)
 				if (sz->timeout_enabled)
 					sz_push(sz, rawir);
 					sz_push(sz, rawir);
 				ir_raw_event_handle(sz->rdev);
 				ir_raw_event_handle(sz->rdev);
+				ir_raw_event_reset(sz->rdev);
 			} else {
 			} else {
 				sz_push_full_space(sz, sz->buf_in[i]);
 				sz_push_full_space(sz, sz->buf_in[i]);
 			}
 			}
@@ -290,6 +291,7 @@ static void streamzap_callback(struct urb *urb)
 		}
 		}
 	}
 	}
 
 
+	ir_raw_event_handle(sz->rdev);
 	usb_submit_urb(urb, GFP_ATOMIC);
 	usb_submit_urb(urb, GFP_ATOMIC);
 
 
 	return;
 	return;
@@ -430,13 +432,13 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
 	sz->decoder_state = PulseSpace;
 	sz->decoder_state = PulseSpace;
 	/* FIXME: don't yet have a way to set this */
 	/* FIXME: don't yet have a way to set this */
 	sz->timeout_enabled = true;
 	sz->timeout_enabled = true;
-	sz->rdev->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
+	sz->rdev->timeout = ((US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION) &
 				IR_MAX_DURATION) | 0x03000000);
 				IR_MAX_DURATION) | 0x03000000);
 	#if 0
 	#if 0
 	/* not yet supported, depends on patches from maxim */
 	/* not yet supported, depends on patches from maxim */
 	/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
 	/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
-	sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
-	sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
+	sz->min_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION);
+	sz->max_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION);
 	#endif
 	#endif
 
 
 	do_gettimeofday(&sz->signal_start);
 	do_gettimeofday(&sz->signal_start);

+ 26 - 5
drivers/media/video/gspca/zc3xx.c

@@ -5793,7 +5793,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
 			break;
 			break;
 		default:
 		default:
 /*		case 0xdd:	 * delay */
 /*		case 0xdd:	 * delay */
-			msleep(action->val / 64 + 10);
+			msleep(action->idx);
 			break;
 			break;
 		}
 		}
 		action++;
 		action++;
@@ -5830,7 +5830,7 @@ static void setmatrix(struct gspca_dev *gspca_dev)
 		[SENSOR_GC0305] =	gc0305_matrix,
 		[SENSOR_GC0305] =	gc0305_matrix,
 		[SENSOR_HDCS2020b] =	NULL,
 		[SENSOR_HDCS2020b] =	NULL,
 		[SENSOR_HV7131B] =	NULL,
 		[SENSOR_HV7131B] =	NULL,
-		[SENSOR_HV7131R] =	NULL,
+		[SENSOR_HV7131R] =	po2030_matrix,
 		[SENSOR_ICM105A] =	po2030_matrix,
 		[SENSOR_ICM105A] =	po2030_matrix,
 		[SENSOR_MC501CB] =	NULL,
 		[SENSOR_MC501CB] =	NULL,
 		[SENSOR_MT9V111_1] =	gc0305_matrix,
 		[SENSOR_MT9V111_1] =	gc0305_matrix,
@@ -5936,6 +5936,7 @@ static void setquality(struct gspca_dev *gspca_dev)
 	case SENSOR_ADCM2700:
 	case SENSOR_ADCM2700:
 	case SENSOR_GC0305:
 	case SENSOR_GC0305:
 	case SENSOR_HV7131B:
 	case SENSOR_HV7131B:
+	case SENSOR_HV7131R:
 	case SENSOR_OV7620:
 	case SENSOR_OV7620:
 	case SENSOR_PAS202B:
 	case SENSOR_PAS202B:
 	case SENSOR_PO2030:
 	case SENSOR_PO2030:
@@ -6108,11 +6109,13 @@ static void send_unknown(struct gspca_dev *gspca_dev, int sensor)
 		reg_w(gspca_dev, 0x02, 0x003b);
 		reg_w(gspca_dev, 0x02, 0x003b);
 		reg_w(gspca_dev, 0x00, 0x0038);
 		reg_w(gspca_dev, 0x00, 0x0038);
 		break;
 		break;
+	case SENSOR_HV7131R:
 	case SENSOR_PAS202B:
 	case SENSOR_PAS202B:
 		reg_w(gspca_dev, 0x03, 0x003b);
 		reg_w(gspca_dev, 0x03, 0x003b);
 		reg_w(gspca_dev, 0x0c, 0x003a);
 		reg_w(gspca_dev, 0x0c, 0x003a);
 		reg_w(gspca_dev, 0x0b, 0x0039);
 		reg_w(gspca_dev, 0x0b, 0x0039);
-		reg_w(gspca_dev, 0x0b, 0x0038);
+		if (sensor == SENSOR_PAS202B)
+			reg_w(gspca_dev, 0x0b, 0x0038);
 		break;
 		break;
 	}
 	}
 }
 }
@@ -6704,10 +6707,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg_w(gspca_dev, 0x02, 0x003b);
 		reg_w(gspca_dev, 0x02, 0x003b);
 		reg_w(gspca_dev, 0x00, 0x0038);
 		reg_w(gspca_dev, 0x00, 0x0038);
 		break;
 		break;
+	case SENSOR_HV7131R:
 	case SENSOR_PAS202B:
 	case SENSOR_PAS202B:
 		reg_w(gspca_dev, 0x03, 0x003b);
 		reg_w(gspca_dev, 0x03, 0x003b);
 		reg_w(gspca_dev, 0x0c, 0x003a);
 		reg_w(gspca_dev, 0x0c, 0x003a);
 		reg_w(gspca_dev, 0x0b, 0x0039);
 		reg_w(gspca_dev, 0x0b, 0x0039);
+		if (sd->sensor == SENSOR_HV7131R)
+			reg_w(gspca_dev, 0x50, ZC3XX_R11D_GLOBALGAIN);
 		break;
 		break;
 	}
 	}
 
 
@@ -6720,6 +6726,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		break;
 		break;
 	case SENSOR_PAS202B:
 	case SENSOR_PAS202B:
 	case SENSOR_GC0305:
 	case SENSOR_GC0305:
+	case SENSOR_HV7131R:
 	case SENSOR_TAS5130C:
 	case SENSOR_TAS5130C:
 		reg_r(gspca_dev, 0x0008);
 		reg_r(gspca_dev, 0x0008);
 		/* fall thru */
 		/* fall thru */
@@ -6760,6 +6767,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
 						/* ms-win + */
 						/* ms-win + */
 		reg_w(gspca_dev, 0x40, 0x0117);
 		reg_w(gspca_dev, 0x40, 0x0117);
 		break;
 		break;
+	case SENSOR_HV7131R:
+		i2c_write(gspca_dev, 0x25, 0x04, 0x00);	/* exposure */
+		i2c_write(gspca_dev, 0x26, 0x93, 0x00);
+		i2c_write(gspca_dev, 0x27, 0xe0, 0x00);
+		reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
+		break;
 	case SENSOR_GC0305:
 	case SENSOR_GC0305:
 	case SENSOR_TAS5130C:
 	case SENSOR_TAS5130C:
 		reg_w(gspca_dev, 0x09, 0x01ad);	/* (from win traces) */
 		reg_w(gspca_dev, 0x09, 0x01ad);	/* (from win traces) */
@@ -6808,9 +6821,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 {
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct sd *sd = (struct sd *) gspca_dev;
 
 
-	if (data[0] == 0xff && data[1] == 0xd8) {	/* start of frame */
+	/* check the JPEG end of frame */
+	if (len >= 3
+	 && data[len - 3] == 0xff && data[len - 2] == 0xd9) {
+/*fixme: what does the last byte mean?*/
 		gspca_frame_add(gspca_dev, LAST_PACKET,
 		gspca_frame_add(gspca_dev, LAST_PACKET,
-					NULL, 0);
+					data, len - 1);
+		return;
+	}
+
+	/* check the JPEG start of a frame */
+	if (data[0] == 0xff && data[1] == 0xd8) {
 		/* put the JPEG header in the new frame */
 		/* put the JPEG header in the new frame */
 		gspca_frame_add(gspca_dev, FIRST_PACKET,
 		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 			sd->jpeg_hdr, JPEG_HDR_SZ);

+ 20 - 4
drivers/media/video/hdpvr/hdpvr-core.c

@@ -283,6 +283,7 @@ static int hdpvr_probe(struct usb_interface *interface,
 	struct hdpvr_device *dev;
 	struct hdpvr_device *dev;
 	struct usb_host_interface *iface_desc;
 	struct usb_host_interface *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_endpoint_descriptor *endpoint;
+	struct i2c_client *client;
 	size_t buffer_size;
 	size_t buffer_size;
 	int i;
 	int i;
 	int retval = -ENOMEM;
 	int retval = -ENOMEM;
@@ -381,13 +382,21 @@ static int hdpvr_probe(struct usb_interface *interface,
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	retval = hdpvr_register_i2c_adapter(dev);
 	retval = hdpvr_register_i2c_adapter(dev);
 	if (retval < 0) {
 	if (retval < 0) {
-		v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
+		v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n");
 		goto error;
 		goto error;
 	}
 	}
 
 
-	retval = hdpvr_register_i2c_ir(dev);
-	if (retval < 0)
-		v4l2_err(&dev->v4l2_dev, "registering i2c IR devices failed\n");
+	client = hdpvr_register_ir_rx_i2c(dev);
+	if (!client) {
+		v4l2_err(&dev->v4l2_dev, "i2c IR RX device register failed\n");
+		goto reg_fail;
+	}
+
+	client = hdpvr_register_ir_tx_i2c(dev);
+	if (!client) {
+		v4l2_err(&dev->v4l2_dev, "i2c IR TX device register failed\n");
+		goto reg_fail;
+	}
 #endif
 #endif
 
 
 	/* let the user know what node this device is now attached to */
 	/* let the user know what node this device is now attached to */
@@ -395,6 +404,10 @@ static int hdpvr_probe(struct usb_interface *interface,
 		  video_device_node_name(dev->video_dev));
 		  video_device_node_name(dev->video_dev));
 	return 0;
 	return 0;
 
 
+reg_fail:
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+	i2c_del_adapter(&dev->i2c_adapter);
+#endif
 error:
 error:
 	if (dev) {
 	if (dev) {
 		/* Destroy single thread */
 		/* Destroy single thread */
@@ -424,6 +437,9 @@ static void hdpvr_disconnect(struct usb_interface *interface)
 	mutex_lock(&dev->io_mutex);
 	mutex_lock(&dev->io_mutex);
 	hdpvr_cancel_queue(dev);
 	hdpvr_cancel_queue(dev);
 	mutex_unlock(&dev->io_mutex);
 	mutex_unlock(&dev->io_mutex);
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+	i2c_del_adapter(&dev->i2c_adapter);
+#endif
 	video_unregister_device(dev->video_dev);
 	video_unregister_device(dev->video_dev);
 	atomic_dec(&dev_nr);
 	atomic_dec(&dev_nr);
 }
 }

+ 19 - 11
drivers/media/video/hdpvr/hdpvr-i2c.c

@@ -31,26 +31,34 @@
 #define Z8F0811_IR_RX_I2C_ADDR	0x71
 #define Z8F0811_IR_RX_I2C_ADDR	0x71
 
 
 
 
-static struct i2c_board_info hdpvr_i2c_board_info = {
-	I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
-	I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
-};
+struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev)
+{
+	struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
+	struct i2c_board_info hdpvr_ir_tx_i2c_board_info = {
+		I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
+	};
+
+	init_data->name = "HD-PVR";
+	hdpvr_ir_tx_i2c_board_info.platform_data = init_data;
 
 
-int hdpvr_register_i2c_ir(struct hdpvr_device *dev)
+	return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_tx_i2c_board_info);
+}
+
+struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
 {
 {
-	struct i2c_client *c;
 	struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
 	struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
+	struct i2c_board_info hdpvr_ir_rx_i2c_board_info = {
+		I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
+	};
 
 
 	/* Our default information for ir-kbd-i2c.c to use */
 	/* Our default information for ir-kbd-i2c.c to use */
 	init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
 	init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
 	init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
 	init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
 	init_data->type = RC_TYPE_RC5;
 	init_data->type = RC_TYPE_RC5;
-	init_data->name = "HD PVR";
-	hdpvr_i2c_board_info.platform_data = init_data;
-
-	c = i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info);
+	init_data->name = "HD-PVR";
+	hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
 
 
-	return (c == NULL) ? -ENODEV : 0;
+	return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info);
 }
 }
 
 
 static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
 static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,

+ 2 - 1
drivers/media/video/hdpvr/hdpvr.h

@@ -313,7 +313,8 @@ int hdpvr_cancel_queue(struct hdpvr_device *dev);
 /* i2c adapter registration */
 /* i2c adapter registration */
 int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
 int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
 
 
-int hdpvr_register_i2c_ir(struct hdpvr_device *dev);
+struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev);
+struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev);
 
 
 /*========================================================================*/
 /*========================================================================*/
 /* buffer management */
 /* buffer management */

+ 13 - 0
drivers/media/video/ir-kbd-i2c.c

@@ -128,6 +128,19 @@ static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 
 
 static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 {
 {
+	int ret;
+	unsigned char buf[1] = { 0 };
+
+	/*
+	 * This is the same apparent "are you ready?" poll command observed
+	 * watching Windows driver traffic and implemented in lirc_zilog. With
+	 * this added, we get far saner remote behavior with z8 chips on usb
+	 * connected devices, even with the default polling interval of 100ms.
+	 */
+	ret = i2c_master_send(ir->c, buf, 1);
+	if (ret != 1)
+		return (ret < 0) ? ret : -EINVAL;
+
 	return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
 	return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
 }
 }
 
 

+ 0 - 1
drivers/media/video/pvrusb2/pvrusb2-i2c-core.c

@@ -597,7 +597,6 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
 		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
 		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
 		init_data->type                  = RC_TYPE_RC5;
 		init_data->type                  = RC_TYPE_RC5;
 		init_data->name                  = hdw->hdw_desc->description;
 		init_data->name                  = hdw->hdw_desc->description;
-		init_data->polling_interval      = 260; /* ms From lirc_zilog */
 		/* IR Receiver */
 		/* IR Receiver */
 		info.addr          = 0x71;
 		info.addr          = 0x71;
 		info.platform_data = init_data;
 		info.platform_data = init_data;

+ 1 - 1
drivers/media/video/saa7115.c

@@ -1565,7 +1565,7 @@ static int saa711x_probe(struct i2c_client *client,
 	chip_id = name[5];
 	chip_id = name[5];
 
 
 	/* Check whether this chip is part of the saa711x series */
 	/* Check whether this chip is part of the saa711x series */
-	if (memcmp(name, "1f711", 5)) {
+	if (memcmp(name + 1, "f711", 4)) {
 		v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
 		v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
 			client->addr << 1, name);
 			client->addr << 1, name);
 		return -ENODEV;
 		return -ENODEV;

+ 26 - 6
drivers/staging/lirc/lirc_zilog.c

@@ -495,7 +495,7 @@ static int send_data_block(struct IR_tx *tx, unsigned char *data_block)
 /* send boot data to the IR TX device */
 /* send boot data to the IR TX device */
 static int send_boot_data(struct IR_tx *tx)
 static int send_boot_data(struct IR_tx *tx)
 {
 {
-	int ret;
+	int ret, i;
 	unsigned char buf[4];
 	unsigned char buf[4];
 
 
 	/* send the boot block */
 	/* send the boot block */
@@ -503,7 +503,7 @@ static int send_boot_data(struct IR_tx *tx)
 	if (ret != 0)
 	if (ret != 0)
 		return ret;
 		return ret;
 
 
-	/* kick it off? */
+	/* Hit the go button to activate the new boot data */
 	buf[0] = 0x00;
 	buf[0] = 0x00;
 	buf[1] = 0x20;
 	buf[1] = 0x20;
 	ret = i2c_master_send(tx->c, buf, 2);
 	ret = i2c_master_send(tx->c, buf, 2);
@@ -511,7 +511,19 @@ static int send_boot_data(struct IR_tx *tx)
 		zilog_error("i2c_master_send failed with %d\n", ret);
 		zilog_error("i2c_master_send failed with %d\n", ret);
 		return ret < 0 ? ret : -EFAULT;
 		return ret < 0 ? ret : -EFAULT;
 	}
 	}
-	ret = i2c_master_send(tx->c, buf, 1);
+
+	/*
+	 * Wait for zilog to settle after hitting go post boot block upload.
+	 * Without this delay, the HD-PVR and HVR-1950 both return an -EIO
+	 * upon attempting to get firmware revision, and tx probe thus fails.
+	 */
+	for (i = 0; i < 10; i++) {
+		ret = i2c_master_send(tx->c, buf, 1);
+		if (ret == 1)
+			break;
+		udelay(100);
+	}
+
 	if (ret != 1) {
 	if (ret != 1) {
 		zilog_error("i2c_master_send failed with %d\n", ret);
 		zilog_error("i2c_master_send failed with %d\n", ret);
 		return ret < 0 ? ret : -EFAULT;
 		return ret < 0 ? ret : -EFAULT;
@@ -523,8 +535,8 @@ static int send_boot_data(struct IR_tx *tx)
 		zilog_error("i2c_master_recv failed with %d\n", ret);
 		zilog_error("i2c_master_recv failed with %d\n", ret);
 		return 0;
 		return 0;
 	}
 	}
-	if (buf[0] != 0x80) {
-		zilog_error("unexpected IR TX response: %02x\n", buf[0]);
+	if ((buf[0] != 0x80) && (buf[0] != 0xa0)) {
+		zilog_error("unexpected IR TX init response: %02x\n", buf[0]);
 		return 0;
 		return 0;
 	}
 	}
 	zilog_notify("Zilog/Hauppauge IR blaster firmware version "
 	zilog_notify("Zilog/Hauppauge IR blaster firmware version "
@@ -827,7 +839,15 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key)
 		zilog_error("i2c_master_send failed with %d\n", ret);
 		zilog_error("i2c_master_send failed with %d\n", ret);
 		return ret < 0 ? ret : -EFAULT;
 		return ret < 0 ? ret : -EFAULT;
 	}
 	}
-	ret = i2c_master_send(tx->c, buf, 1);
+
+	/* Give the z8 a moment to process data block */
+	for (i = 0; i < 10; i++) {
+		ret = i2c_master_send(tx->c, buf, 1);
+		if (ret == 1)
+			break;
+		udelay(100);
+	}
+
 	if (ret != 1) {
 	if (ret != 1) {
 		zilog_error("i2c_master_send failed with %d\n", ret);
 		zilog_error("i2c_master_send failed with %d\n", ret);
 		return ret < 0 ? ret : -EFAULT;
 		return ret < 0 ? ret : -EFAULT;