Commit f2f1756d authored by Linus Torvalds's avatar Linus Torvalds

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
parents b8ef289d bed3c1de
/* 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>
*
......@@ -47,6 +47,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
/* Carrier reports */
if (ev.carrier_report) {
sample = LIRC_FREQUENCY(ev.carrier);
IR_dprintk(2, "carrier report (freq: %d)\n", sample);
/* Packet end */
} else if (ev.timeout) {
......@@ -62,6 +63,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
return 0;
sample = LIRC_TIMEOUT(ev.duration / 1000);
IR_dprintk(2, "timeout report (duration: %d)\n", sample);
/* Normal sample */
} 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) :
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,
......
......@@ -3,6 +3,9 @@
*
* 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
* it under the terms of the GNU General Public License as published by
* 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 */
{ 0x800f0427, KEY_ZOOM }, /* Aspect */
{ 0x800f0432, KEY_MODE }, /* Visualization */
{ 0x800f0433, KEY_PRESENTATION }, /* Slide Show */
{ 0x800f0434, KEY_EJECTCD },
{ 0x800f043a, KEY_BRIGHTNESSUP },
{ 0x800f0446, KEY_TV },
......
......@@ -816,7 +816,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
switch (ir->buf_in[index]) {
/* 2-byte return value commands */
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;
/* 1-byte return value commands */
......@@ -855,9 +855,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
break;
case PARSE_IRDATA:
ir->rem--;
init_ir_raw_event(&rawir);
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
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",
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);
if (ir->rem)
ir->parser_state = PARSE_IRDATA;
else
ir_raw_event_reset(ir->rc);
break;
}
......@@ -1060,7 +1063,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
rc->priv = ir;
rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protos = RC_TYPE_ALL;
rc->timeout = MS_TO_NS(1000);
rc->timeout = US_TO_NS(1000);
if (!ir->flags.no_tx) {
rc->s_tx_mask = mceusb_set_tx_mask;
rc->s_tx_carrier = mceusb_set_tx_carrier;
......
......@@ -460,7 +460,7 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt)
return 0;
}
carrier = (count * 1000000) / duration;
carrier = MS_TO_NS(count) / duration;
if ((carrier > MAX_CARRIER) || (carrier < MIN_CARRIER))
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];
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 (nvt->rawir.pulse == rawir.pulse)
......
......@@ -164,7 +164,7 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
sz->signal_start.tv_usec -
sz->signal_last.tv_usec);
rawir.duration -= sz->sum;
rawir.duration *= 1000;
rawir.duration = US_TO_NS(rawir.duration);
rawir.duration &= IR_MAX_DURATION;
}
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 += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
rawir.duration *= 1000;
rawir.duration = US_TO_NS(rawir.duration);
rawir.duration &= IR_MAX_DURATION;
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 += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
rawir.duration *= 1000;
rawir.duration = US_TO_NS(rawir.duration);
sz_push(sz, rawir);
}
......@@ -273,6 +273,7 @@ static void streamzap_callback(struct urb *urb)
if (sz->timeout_enabled)
sz_push(sz, rawir);
ir_raw_event_handle(sz->rdev);
ir_raw_event_reset(sz->rdev);
} else {
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);
return;
......@@ -430,13 +432,13 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */
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);
#if 0
/* not yet supported, depends on patches from maxim */
/* 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
do_gettimeofday(&sz->signal_start);
......
......@@ -5793,7 +5793,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
break;
default:
/* case 0xdd: * delay */
msleep(action->val / 64 + 10);
msleep(action->idx);
break;
}
action++;
......@@ -5830,7 +5830,7 @@ static void setmatrix(struct gspca_dev *gspca_dev)
[SENSOR_GC0305] = gc0305_matrix,
[SENSOR_HDCS2020b] = NULL,
[SENSOR_HV7131B] = NULL,
[SENSOR_HV7131R] = NULL,
[SENSOR_HV7131R] = po2030_matrix,
[SENSOR_ICM105A] = po2030_matrix,
[SENSOR_MC501CB] = NULL,
[SENSOR_MT9V111_1] = gc0305_matrix,
......@@ -5936,6 +5936,7 @@ static void setquality(struct gspca_dev *gspca_dev)
case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_HV7131B:
case SENSOR_HV7131R:
case SENSOR_OV7620:
case SENSOR_PAS202B:
case SENSOR_PO2030:
......@@ -6108,10 +6109,12 @@ static void send_unknown(struct gspca_dev *gspca_dev, int sensor)
reg_w(gspca_dev, 0x02, 0x003b);
reg_w(gspca_dev, 0x00, 0x0038);
break;
case SENSOR_HV7131R:
case SENSOR_PAS202B:
reg_w(gspca_dev, 0x03, 0x003b);
reg_w(gspca_dev, 0x0c, 0x003a);
reg_w(gspca_dev, 0x0b, 0x0039);
if (sensor == SENSOR_PAS202B)
reg_w(gspca_dev, 0x0b, 0x0038);
break;
}
......@@ -6704,10 +6707,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x02, 0x003b);
reg_w(gspca_dev, 0x00, 0x0038);
break;
case SENSOR_HV7131R:
case SENSOR_PAS202B:
reg_w(gspca_dev, 0x03, 0x003b);
reg_w(gspca_dev, 0x0c, 0x003a);
reg_w(gspca_dev, 0x0b, 0x0039);
if (sd->sensor == SENSOR_HV7131R)
reg_w(gspca_dev, 0x50, ZC3XX_R11D_GLOBALGAIN);
break;
}
......@@ -6720,6 +6726,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
break;
case SENSOR_PAS202B:
case SENSOR_GC0305:
case SENSOR_HV7131R:
case SENSOR_TAS5130C:
reg_r(gspca_dev, 0x0008);
/* fall thru */
......@@ -6760,6 +6767,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* ms-win + */
reg_w(gspca_dev, 0x40, 0x0117);
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_TAS5130C:
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;
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,
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 */
gspca_frame_add(gspca_dev, FIRST_PACKET,
sd->jpeg_hdr, JPEG_HDR_SZ);
......
......@@ -283,6 +283,7 @@ static int hdpvr_probe(struct usb_interface *interface,
struct hdpvr_device *dev;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
struct i2c_client *client;
size_t buffer_size;
int i;
int retval = -ENOMEM;
......@@ -381,13 +382,21 @@ static int hdpvr_probe(struct usb_interface *interface,
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
retval = hdpvr_register_i2c_adapter(dev);
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;
}
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
/* 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));
return 0;
reg_fail:
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_adapter(&dev->i2c_adapter);
#endif
error:
if (dev) {
/* Destroy single thread */
......@@ -424,6 +437,9 @@ static void hdpvr_disconnect(struct usb_interface *interface)
mutex_lock(&dev->io_mutex);
hdpvr_cancel_queue(dev);
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);
atomic_dec(&dev_nr);
}
......
......@@ -31,26 +31,34 @@
#define Z8F0811_IR_RX_I2C_ADDR 0x71
static struct i2c_board_info hdpvr_i2c_board_info = {
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),
I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_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 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 */
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
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,
......
......@@ -313,7 +313,8 @@ int hdpvr_cancel_queue(struct hdpvr_device *dev);
/* i2c adapter registration */
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 */
......
......@@ -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)
{
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);
}
......
......@@ -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->type = RC_TYPE_RC5;
init_data->name = hdw->hdw_desc->description;
init_data->polling_interval = 260; /* ms From lirc_zilog */
/* IR Receiver */
info.addr = 0x71;
info.platform_data = init_data;
......
......@@ -1565,7 +1565,7 @@ static int saa711x_probe(struct i2c_client *client,
chip_id = name[5];
/* 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",
client->addr << 1, name);
return -ENODEV;
......
......@@ -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 */
static int send_boot_data(struct IR_tx *tx)
{
int ret;
int ret, i;
unsigned char buf[4];
/* send the boot block */
......@@ -503,7 +503,7 @@ static int send_boot_data(struct IR_tx *tx)
if (ret != 0)
return ret;
/* kick it off? */
/* Hit the go button to activate the new boot data */
buf[0] = 0x00;
buf[1] = 0x20;
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);
return ret < 0 ? ret : -EFAULT;
}
/*
* 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) {
zilog_error("i2c_master_send failed with %d\n", ret);
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);
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;
}
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);
return ret < 0 ? ret : -EFAULT;
}
/* 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) {
zilog_error("i2c_master_send failed with %d\n", ret);
return ret < 0 ? ret : -EFAULT;
......
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