From 2c0b6e88d3a926ef7a9e118642f1aedf091c29f8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 6 Nov 2008 01:12:56 +0000 Subject: Add TerraTec Cinergy S USB support From: Igor M. Liplianin Add TerraTec Cinergy S USB support Signed-off-by: Igor M. Liplianin Acked-by: Thorsten Leupold Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/dw2102.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/dvb-usb') diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.c b/linux/drivers/media/dvb/dvb-usb/dw2102.c index c9431713d..bc5e47a2b 100644 --- a/linux/drivers/media/dvb/dvb-usb/dw2102.c +++ b/linux/drivers/media/dvb/dvb-usb/dw2102.c @@ -26,6 +26,10 @@ #define USB_PID_DW2104 0x2104 #endif +#ifndef USB_PID_CINERGY_S +#define USB_PID_CINERGY_S 0x0064 +#endif + #define DW210X_READ_MSG 0 #define DW210X_WRITE_MSG 1 @@ -577,6 +581,7 @@ static struct usb_device_id dw2102_table[] = { {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, {USB_DEVICE(0x9022, 0xd650)}, + {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, { } }; @@ -646,6 +651,7 @@ static int dw2102_load_firmware(struct usb_device *dev, dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, DW210X_WRITE_MSG); break; + case USB_PID_CINERGY_S: case USB_PID_DW2102: dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, DW210X_WRITE_MSG); @@ -725,7 +731,7 @@ static struct dvb_usb_device_properties dw2102_properties = { }, } }, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { {"DVBWorld DVB-S 2102 USB2.0", {&dw2102_table[0], NULL}, @@ -735,6 +741,10 @@ static struct dvb_usb_device_properties dw2102_properties = { {&dw2102_table[1], NULL}, {NULL}, }, + {"TerraTec Cinergy S USB", + {&dw2102_table[4], NULL}, + {NULL}, + }, } }; -- cgit v1.2.3 From 9690379dc06a080d7172bc3b2d21544f2bf3d8e1 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Wed, 12 Nov 2008 00:56:56 -0200 Subject: usb-urb: fix memory leak From: Douglas Schilling Landgraf Free allocated memory Priority: high Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/dvb/dvb-usb/usb-urb.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-usb') diff --git a/linux/drivers/media/dvb/dvb-usb/usb-urb.c b/linux/drivers/media/dvb/dvb-usb/usb-urb.c index 5caec2034..eb3aaaf7a 100644 --- a/linux/drivers/media/dvb/dvb-usb/usb-urb.c +++ b/linux/drivers/media/dvb/dvb-usb/usb-urb.c @@ -139,7 +139,7 @@ stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]) static int usb_bulk_urb_init(struct usb_data_stream *stream) { - int i; + int i, j; if ((i = usb_allocate_stream_buffers(stream,stream->props.count, stream->props.u.bulk.buffersize)) < 0) @@ -147,9 +147,13 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream) /* allocate the URBs */ for (i = 0; i < stream->props.count; i++) { - if ((stream->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL) + stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); + if (!stream->urb_list[i]) { + deb_mem("not enough memory for urb_alloc_urb!.\n"); + for (j = 0; j < i; j++) + usb_free_urb(stream->urb_list[i]); return -ENOMEM; - + } usb_fill_bulk_urb( stream->urb_list[i], stream->udev, usb_rcvbulkpipe(stream->udev,stream->props.endpoint), stream->buf_list[i], @@ -174,9 +178,14 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream) for (i = 0; i < stream->props.count; i++) { struct urb *urb; int frame_offset = 0; - if ((stream->urb_list[i] = - usb_alloc_urb(stream->props.u.isoc.framesperurb,GFP_ATOMIC)) == NULL) + + stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC); + if (!stream->urb_list[i]) { + deb_mem("not enough memory for urb_alloc_urb!\n"); + for (j = 0; j < i; j++) + usb_free_urb(stream->urb_list[i]); return -ENOMEM; + } urb = stream->urb_list[i]; -- cgit v1.2.3 From 6c862246c352268e001c5dfb9f657f2b4832364e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 15 Nov 2008 04:08:45 +0000 Subject: dvb: cinergyt2 annotate struct endianness, remove unused variable, add static From: Harvey Harrison All noticed by sparse: drivers/media/dvb/dvb-usb/cinergyT2-core.c:35:5: warning: symbol 'disable_remote' was not declared. Should it be static? drivers/media/dvb/dvb-usb/cinergyT2-core.c:48:23: warning: symbol 'cinergyt2_usb_device' was not declared. Should it be static? drivers/media/dvb/dvb-usb/cinergyT2-fe.c:160:15: warning: cast to restricted __le16 drivers/media/dvb/dvb-usb/cinergyT2-fe.c:190:9: warning: cast to restricted __le32 drivers/media/dvb/dvb-usb/cinergyT2-fe.c:208:9: warning: cast to restricted __le32 drivers/media/dvb/dvb-usb/cinergyT2-fe.c:227:24: warning: cast to restricted __le16 drivers/media/dvb/dvb-usb/cinergyT2-fe.c:275:12: warning: incorrect type in assignment (different base types) drivers/media/dvb/dvb-usb/cinergyT2-fe.c:275:12: expected unsigned short [unsigned] [assigned] [usertype] tps drivers/media/dvb/dvb-usb/cinergyT2-fe.c:275:12: got restricted __le16 [usertype] drivers/media/dvb/dvb-usb/cinergyT2-fe.c:276:13: warning: incorrect type in assignment (different base types) drivers/media/dvb/dvb-usb/cinergyT2-fe.c:276:13: expected unsigned int [unsigned] [assigned] [usertype] freq drivers/media/dvb/dvb-usb/cinergyT2-fe.c:276:13: got restricted __le32 [usertype] Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton CC: Thierry Merle Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/cinergyT2-core.c | 3 +-- linux/drivers/media/dvb/dvb-usb/cinergyT2.h | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-usb') diff --git a/linux/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/linux/drivers/media/dvb/dvb-usb/cinergyT2-core.c index 3ac9f74e9..80e37a0d0 100644 --- a/linux/drivers/media/dvb/dvb-usb/cinergyT2-core.c +++ b/linux/drivers/media/dvb/dvb-usb/cinergyT2-core.c @@ -32,7 +32,6 @@ /* debug */ int dvb_usb_cinergyt2_debug; -int disable_remote; module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 " @@ -45,7 +44,7 @@ struct cinergyt2_state { }; /* We are missing a release hook with usb_device data */ -struct dvb_usb_device *cinergyt2_usb_device; +static struct dvb_usb_device *cinergyt2_usb_device; static struct dvb_usb_device_properties cinergyt2_properties; diff --git a/linux/drivers/media/dvb/dvb-usb/cinergyT2.h b/linux/drivers/media/dvb/dvb-usb/cinergyT2.h index f008b41ad..4e3247d04 100644 --- a/linux/drivers/media/dvb/dvb-usb/cinergyT2.h +++ b/linux/drivers/media/dvb/dvb-usb/cinergyT2.h @@ -74,11 +74,11 @@ struct dvbt_get_status_msg { uint8_t bandwidth; uint16_t tps; uint8_t flags; - uint16_t gain; + __le16 gain; uint8_t snr; - uint32_t viterbi_error_rate; + __le32 viterbi_error_rate; uint32_t rs_error_rate; - uint32_t uncorrected_block_count; + __le32 uncorrected_block_count; uint8_t lock_bits; uint8_t prev_lock_bits; } __attribute__((packed)); @@ -86,9 +86,9 @@ struct dvbt_get_status_msg { struct dvbt_set_parameters_msg { uint8_t cmd; - uint32_t freq; + __le32 freq; uint8_t bandwidth; - uint16_t tps; + __le16 tps; uint8_t flags; } __attribute__((packed)); -- cgit v1.2.3 From 0dd5f609f5faa9eabdd86966e9bf7dd9d8d45b05 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Nov 2008 21:19:56 +0000 Subject: usb vendor_ids/product_ids are __le16 From: Harvey Harrison Noticed by sparse: drivers/media/dvb/dvb-usb/af9015.c:756:25: warning: restricted __le16 degrades to integer drivers/media/dvb/dvb-usb/af9015.c:744:28: warning: restricted __le16 degrades to integer Signed-off-by: Harvey Harrison Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/af9015.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-usb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index 6bc55614d..21e10fa23 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -742,7 +742,7 @@ static int af9015_read_config(struct usb_device *udev) } } else { switch (udev->descriptor.idVendor) { - case USB_VID_LEADTEK: + case cpu_to_le16(USB_VID_LEADTEK): af9015_properties[i].rc_key_map = af9015_rc_keys_leadtek; af9015_properties[i].rc_key_map_size = @@ -752,9 +752,9 @@ static int af9015_read_config(struct usb_device *udev) af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_leadtek); break; - case USB_VID_VISIONPLUS: + case cpu_to_le16(USB_VID_VISIONPLUS): if (udev->descriptor.idProduct == - USB_PID_AZUREWAVE_AD_TU700) { + cpu_to_le16(USB_PID_AZUREWAVE_AD_TU700)) { af9015_properties[i].rc_key_map = af9015_rc_keys_twinhan; af9015_properties[i].rc_key_map_size = @@ -765,7 +765,7 @@ static int af9015_read_config(struct usb_device *udev) ARRAY_SIZE(af9015_ir_table_twinhan); } break; - case USB_VID_KWORLD_2: + case cpu_to_le16(USB_VID_KWORLD_2): /* TODO: use correct rc keys */ af9015_properties[i].rc_key_map = af9015_rc_keys_twinhan; @@ -778,7 +778,7 @@ static int af9015_read_config(struct usb_device *udev) /* Check USB manufacturer and product strings and try to determine correct remote in case of chip vendor reference IDs are used. */ - case USB_VID_AFATECH: + case cpu_to_le16(USB_VID_AFATECH): memset(manufacturer, 0, sizeof(manufacturer)); usb_string(udev, udev->descriptor.iManufacturer, manufacturer, sizeof(manufacturer)); @@ -806,7 +806,7 @@ static int af9015_read_config(struct usb_device *udev) ARRAY_SIZE(af9015_ir_table_msi); } break; - case USB_VID_AVERMEDIA: + case cpu_to_le16(USB_VID_AVERMEDIA): af9015_properties[i].rc_key_map = af9015_rc_keys_avermedia; af9015_properties[i].rc_key_map_size = -- cgit v1.2.3 From 0a07568bd0fb79c5dbd57d88a42e771cb6224f05 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 15 Nov 2008 11:13:07 +0100 Subject: Make dib0700 remote control support work with firmware v1.20 From: Devin Heitmueller The format for reading the IR controller changed in firmware 1.20. It now provides the events on bulk endpoint 1 instead of using a control request. Support the new format, providing backward compatibility for users who might be using older firmware. Thanks to Patrick Boettcher for providing the required information on how the version 1.20 firmware works. Priority: high Signed-off-by: Devin Heitmueller Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700.h | 5 +- linux/drivers/media/dvb/dvb-usb/dib0700_core.c | 16 +++ linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 139 +++++++++++++++++++++- 3 files changed, 158 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-usb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700.h b/linux/drivers/media/dvb/dvb-usb/dib0700.h index 739193943..8b544fe79 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700.h +++ b/linux/drivers/media/dvb/dvb-usb/dib0700.h @@ -22,7 +22,7 @@ extern int dvb_usb_dib0700_debug; #define REQUEST_I2C_READ 0x2 #define REQUEST_I2C_WRITE 0x3 -#define REQUEST_POLL_RC 0x4 +#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */ #define REQUEST_JUMPRAM 0x8 #define REQUEST_SET_CLOCK 0xB #define REQUEST_SET_GPIO 0xC @@ -40,11 +40,14 @@ struct dib0700_state { u16 mt2060_if1[2]; u8 rc_toggle; u8 rc_counter; + u8 rc_func_version; u8 is_dib7000pc; u8 fw_use_new_i2c_api; u8 disable_streaming_master_mode; }; +extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, + u32 *romversion, u32 *ramversion, u32 *fwtype); extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c index 3c7bdef28..2fbb7049a 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -19,6 +19,22 @@ MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (defau DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, + u32 *romversion, u32 *ramversion, u32 *fwtype) +{ + u8 b[16]; + int ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), + REQUEST_GET_VERSION, + USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, + b, sizeof(b), USB_CTRL_GET_TIMEOUT); + *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; + *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; + *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; + *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; + return ret; +} + /* expecting rx buffer: request data[0] data[1] ... data[2] */ static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen) { diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index 0cfccc24b..f28d3ae59 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -38,6 +38,7 @@ static struct mt2060_config bristol_mt2060_config[2] = { } }; + static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = { .band_caps = BAND_VHF | BAND_UHF, .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0), @@ -451,8 +452,13 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; /* Number of keypresses to ignore before start repeating */ #define RC_REPEAT_DELAY 2 +#define RC_REPEAT_DELAY_V1_20 5 -static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) + + +/* Used by firmware versions < 1.20 (deprecated) */ +static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event, + int *state) { u8 key[4]; int i; @@ -529,6 +535,137 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) return 0; } +/* This is the structure of the RC response packet starting in firmware 1.20 */ +struct dib0700_rc_response { + u8 report_id; + u8 data_state; + u8 system_msb; + u8 system_lsb; + u8 data; + u8 not_data; +}; + +/* This supports the new IR response format for firmware v1.20 */ +static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, + int *state) +{ + struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + struct dib0700_state *st = d->priv; + struct dib0700_rc_response poll_reply; + u8 buf[6]; + int i; + int status; + int actlen; + int found = 0; + + /* Set initial results in case we exit the function early */ + *event = 0; + *state = REMOTE_NO_KEY_PRESSED; + + /* Firmware v1.20 provides RC data via bulk endpoint 1 */ + status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf, + sizeof(buf), &actlen, 50); + if (status < 0) { + /* No data available (meaning no key press) */ + return 0; + } + + if (actlen != sizeof(buf)) { + /* We didn't get back the 6 byte message we expected */ + err("Unexpected RC response size [%d]", actlen); + return -1; + } + + poll_reply.report_id = buf[0]; + poll_reply.data_state = buf[1]; + poll_reply.system_msb = buf[2]; + poll_reply.system_lsb = buf[3]; + poll_reply.data = buf[4]; + poll_reply.not_data = buf[5]; + + /* + info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n", + poll_reply.report_id, poll_reply.data_state, + poll_reply.system_msb, poll_reply.system_lsb, + poll_reply.data, poll_reply.not_data); + */ + + if ((poll_reply.data + poll_reply.not_data) != 0xff) { + /* Key failed integrity check */ + err("key failed integrity check: %02x %02x %02x %02x", + poll_reply.system_msb, poll_reply.system_lsb, + poll_reply.data, poll_reply.not_data); + return -1; + } + + /* Find the key in the map */ + for (i = 0; i < d->props.rc_key_map_size; i++) { + if (keymap[i].custom == poll_reply.system_lsb && + keymap[i].data == poll_reply.data) { + *event = keymap[i].event; + found = 1; + break; + } + } + + if (found == 0) { + err("Unknown remote controller key: %02x %02x %02x %02x", + poll_reply.system_msb, poll_reply.system_lsb, + poll_reply.data, poll_reply.not_data); + d->last_event = 0; + return 0; + } + + if (poll_reply.data_state == 1) { + /* New key hit */ + st->rc_counter = 0; + *event = keymap[i].event; + *state = REMOTE_KEY_PRESSED; + d->last_event = keymap[i].event; + } else if (poll_reply.data_state == 2) { + /* Key repeated */ + st->rc_counter++; + + /* prevents unwanted double hits */ + if (st->rc_counter > RC_REPEAT_DELAY_V1_20) { + *event = d->last_event; + *state = REMOTE_KEY_PRESSED; + st->rc_counter = RC_REPEAT_DELAY_V1_20; + } + } else { + err("Unknown data state [%d]", poll_reply.data_state); + } + + return 0; +} + +static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + struct dib0700_state *st = d->priv; + + /* Because some people may have improperly named firmware files, + let's figure out whether to use the new firmware call or the legacy + call based on the firmware version embedded in the file */ + if (st->rc_func_version == 0) { + u32 hwver, romver, ramver, fwtype; + int ret = dib0700_get_version(d, &hwver, &romver, &ramver, + &fwtype); + if (ret < 0) { + err("Could not determine version info"); + return -1; + } + if (ramver < 0x10200) + st->rc_func_version = 1; + else + st->rc_func_version = 2; + } + + if (st->rc_func_version == 2) + return dib0700_rc_query_v1_20(d, event, state); + else + return dib0700_rc_query_legacy(d, event, state); +} + static struct dvb_usb_rc_key dib0700_rc_keys[] = { /* Key codes for the tiny Pinnacle remote*/ { 0x07, 0x00, KEY_MUTE }, -- cgit v1.2.3