1786baecfSMauro Carvalho Chehab /* 2786baecfSMauro Carvalho Chehab * TTUSB DEC Driver 3786baecfSMauro Carvalho Chehab * 4786baecfSMauro Carvalho Chehab * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org> 5786baecfSMauro Carvalho Chehab * IR support by Peter Beutner <p.beutner@gmx.net> 6786baecfSMauro Carvalho Chehab * 7786baecfSMauro Carvalho Chehab * This program is free software; you can redistribute it and/or modify 8786baecfSMauro Carvalho Chehab * it under the terms of the GNU General Public License as published by 9786baecfSMauro Carvalho Chehab * the Free Software Foundation; either version 2 of the License, or 10786baecfSMauro Carvalho Chehab * (at your option) any later version. 11786baecfSMauro Carvalho Chehab * 12786baecfSMauro Carvalho Chehab * This program is distributed in the hope that it will be useful, 13786baecfSMauro Carvalho Chehab * but WITHOUT ANY WARRANTY; without even the implied warranty of 14786baecfSMauro Carvalho Chehab * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15786baecfSMauro Carvalho Chehab * GNU General Public License for more details. 16786baecfSMauro Carvalho Chehab * 17786baecfSMauro Carvalho Chehab * You should have received a copy of the GNU General Public License 18786baecfSMauro Carvalho Chehab * along with this program; if not, write to the Free Software 19786baecfSMauro Carvalho Chehab * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20786baecfSMauro Carvalho Chehab * 21786baecfSMauro Carvalho Chehab */ 22786baecfSMauro Carvalho Chehab 23786baecfSMauro Carvalho Chehab #include <linux/list.h> 24786baecfSMauro Carvalho Chehab #include <linux/module.h> 25786baecfSMauro Carvalho Chehab #include <linux/pci.h> 26786baecfSMauro Carvalho Chehab #include <linux/slab.h> 27786baecfSMauro Carvalho Chehab #include <linux/spinlock.h> 28786baecfSMauro Carvalho Chehab #include <linux/usb.h> 29786baecfSMauro Carvalho Chehab #include <linux/interrupt.h> 30786baecfSMauro Carvalho Chehab #include <linux/firmware.h> 31786baecfSMauro Carvalho Chehab #include <linux/crc32.h> 32786baecfSMauro Carvalho Chehab #include <linux/init.h> 33786baecfSMauro Carvalho Chehab #include <linux/input.h> 34786baecfSMauro Carvalho Chehab 35786baecfSMauro Carvalho Chehab #include <linux/mutex.h> 36786baecfSMauro Carvalho Chehab 37786baecfSMauro Carvalho Chehab #include "dmxdev.h" 38786baecfSMauro Carvalho Chehab #include "dvb_demux.h" 39786baecfSMauro Carvalho Chehab #include "dvb_filter.h" 40786baecfSMauro Carvalho Chehab #include "dvb_frontend.h" 41786baecfSMauro Carvalho Chehab #include "dvb_net.h" 42786baecfSMauro Carvalho Chehab #include "ttusbdecfe.h" 43786baecfSMauro Carvalho Chehab 44786baecfSMauro Carvalho Chehab static int debug; 45786baecfSMauro Carvalho Chehab static int output_pva; 46786baecfSMauro Carvalho Chehab static int enable_rc; 47786baecfSMauro Carvalho Chehab 48786baecfSMauro Carvalho Chehab module_param(debug, int, 0644); 49786baecfSMauro Carvalho Chehab MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); 50786baecfSMauro Carvalho Chehab module_param(output_pva, int, 0444); 51786baecfSMauro Carvalho Chehab MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)"); 52786baecfSMauro Carvalho Chehab module_param(enable_rc, int, 0644); 53786baecfSMauro Carvalho Chehab MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)"); 54786baecfSMauro Carvalho Chehab 55786baecfSMauro Carvalho Chehab DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 56786baecfSMauro Carvalho Chehab 57786baecfSMauro Carvalho Chehab #define dprintk if (debug) printk 58786baecfSMauro Carvalho Chehab 59786baecfSMauro Carvalho Chehab #define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB" 60786baecfSMauro Carvalho Chehab 61786baecfSMauro Carvalho Chehab #define COMMAND_PIPE 0x03 62786baecfSMauro Carvalho Chehab #define RESULT_PIPE 0x04 63786baecfSMauro Carvalho Chehab #define IN_PIPE 0x08 64786baecfSMauro Carvalho Chehab #define OUT_PIPE 0x07 65786baecfSMauro Carvalho Chehab #define IRQ_PIPE 0x0A 66786baecfSMauro Carvalho Chehab 67786baecfSMauro Carvalho Chehab #define COMMAND_PACKET_SIZE 0x3c 68786baecfSMauro Carvalho Chehab #define ARM_PACKET_SIZE 0x1000 69786baecfSMauro Carvalho Chehab #define IRQ_PACKET_SIZE 0x8 70786baecfSMauro Carvalho Chehab 71786baecfSMauro Carvalho Chehab #define ISO_BUF_COUNT 0x04 72786baecfSMauro Carvalho Chehab #define FRAMES_PER_ISO_BUF 0x04 73786baecfSMauro Carvalho Chehab #define ISO_FRAME_SIZE 0x0380 74786baecfSMauro Carvalho Chehab 75786baecfSMauro Carvalho Chehab #define MAX_PVA_LENGTH 6144 76786baecfSMauro Carvalho Chehab 77786baecfSMauro Carvalho Chehab enum ttusb_dec_model { 78786baecfSMauro Carvalho Chehab TTUSB_DEC2000T, 79786baecfSMauro Carvalho Chehab TTUSB_DEC2540T, 80786baecfSMauro Carvalho Chehab TTUSB_DEC3000S 81786baecfSMauro Carvalho Chehab }; 82786baecfSMauro Carvalho Chehab 83786baecfSMauro Carvalho Chehab enum ttusb_dec_packet_type { 84786baecfSMauro Carvalho Chehab TTUSB_DEC_PACKET_PVA, 85786baecfSMauro Carvalho Chehab TTUSB_DEC_PACKET_SECTION, 86786baecfSMauro Carvalho Chehab TTUSB_DEC_PACKET_EMPTY 87786baecfSMauro Carvalho Chehab }; 88786baecfSMauro Carvalho Chehab 89786baecfSMauro Carvalho Chehab enum ttusb_dec_interface { 90786baecfSMauro Carvalho Chehab TTUSB_DEC_INTERFACE_INITIAL, 91786baecfSMauro Carvalho Chehab TTUSB_DEC_INTERFACE_IN, 92786baecfSMauro Carvalho Chehab TTUSB_DEC_INTERFACE_OUT 93786baecfSMauro Carvalho Chehab }; 94786baecfSMauro Carvalho Chehab 95786baecfSMauro Carvalho Chehab struct ttusb_dec { 96786baecfSMauro Carvalho Chehab enum ttusb_dec_model model; 97786baecfSMauro Carvalho Chehab char *model_name; 98786baecfSMauro Carvalho Chehab char *firmware_name; 99786baecfSMauro Carvalho Chehab int can_playback; 100786baecfSMauro Carvalho Chehab 101786baecfSMauro Carvalho Chehab /* DVB bits */ 102786baecfSMauro Carvalho Chehab struct dvb_adapter adapter; 103786baecfSMauro Carvalho Chehab struct dmxdev dmxdev; 104786baecfSMauro Carvalho Chehab struct dvb_demux demux; 105786baecfSMauro Carvalho Chehab struct dmx_frontend frontend; 106786baecfSMauro Carvalho Chehab struct dvb_net dvb_net; 107786baecfSMauro Carvalho Chehab struct dvb_frontend* fe; 108786baecfSMauro Carvalho Chehab 109786baecfSMauro Carvalho Chehab u16 pid[DMX_PES_OTHER]; 110786baecfSMauro Carvalho Chehab 111786baecfSMauro Carvalho Chehab /* USB bits */ 112786baecfSMauro Carvalho Chehab struct usb_device *udev; 113786baecfSMauro Carvalho Chehab u8 trans_count; 114786baecfSMauro Carvalho Chehab unsigned int command_pipe; 115786baecfSMauro Carvalho Chehab unsigned int result_pipe; 116786baecfSMauro Carvalho Chehab unsigned int in_pipe; 117786baecfSMauro Carvalho Chehab unsigned int out_pipe; 118786baecfSMauro Carvalho Chehab unsigned int irq_pipe; 119786baecfSMauro Carvalho Chehab enum ttusb_dec_interface interface; 120786baecfSMauro Carvalho Chehab struct mutex usb_mutex; 121786baecfSMauro Carvalho Chehab 122786baecfSMauro Carvalho Chehab void *irq_buffer; 123786baecfSMauro Carvalho Chehab struct urb *irq_urb; 124786baecfSMauro Carvalho Chehab dma_addr_t irq_dma_handle; 125786baecfSMauro Carvalho Chehab void *iso_buffer; 126786baecfSMauro Carvalho Chehab dma_addr_t iso_dma_handle; 127786baecfSMauro Carvalho Chehab struct urb *iso_urb[ISO_BUF_COUNT]; 128786baecfSMauro Carvalho Chehab int iso_stream_count; 129786baecfSMauro Carvalho Chehab struct mutex iso_mutex; 130786baecfSMauro Carvalho Chehab 131786baecfSMauro Carvalho Chehab u8 packet[MAX_PVA_LENGTH + 4]; 132786baecfSMauro Carvalho Chehab enum ttusb_dec_packet_type packet_type; 133786baecfSMauro Carvalho Chehab int packet_state; 134786baecfSMauro Carvalho Chehab int packet_length; 135786baecfSMauro Carvalho Chehab int packet_payload_length; 136786baecfSMauro Carvalho Chehab u16 next_packet_id; 137786baecfSMauro Carvalho Chehab 138786baecfSMauro Carvalho Chehab int pva_stream_count; 139786baecfSMauro Carvalho Chehab int filter_stream_count; 140786baecfSMauro Carvalho Chehab 141786baecfSMauro Carvalho Chehab struct dvb_filter_pes2ts a_pes2ts; 142786baecfSMauro Carvalho Chehab struct dvb_filter_pes2ts v_pes2ts; 143786baecfSMauro Carvalho Chehab 144786baecfSMauro Carvalho Chehab u8 v_pes[16 + MAX_PVA_LENGTH]; 145786baecfSMauro Carvalho Chehab int v_pes_length; 146786baecfSMauro Carvalho Chehab int v_pes_postbytes; 147786baecfSMauro Carvalho Chehab 148786baecfSMauro Carvalho Chehab struct list_head urb_frame_list; 149786baecfSMauro Carvalho Chehab struct tasklet_struct urb_tasklet; 150786baecfSMauro Carvalho Chehab spinlock_t urb_frame_list_lock; 151786baecfSMauro Carvalho Chehab 152786baecfSMauro Carvalho Chehab struct dvb_demux_filter *audio_filter; 153786baecfSMauro Carvalho Chehab struct dvb_demux_filter *video_filter; 154786baecfSMauro Carvalho Chehab struct list_head filter_info_list; 155786baecfSMauro Carvalho Chehab spinlock_t filter_info_list_lock; 156786baecfSMauro Carvalho Chehab 157786baecfSMauro Carvalho Chehab struct input_dev *rc_input_dev; 158786baecfSMauro Carvalho Chehab char rc_phys[64]; 159786baecfSMauro Carvalho Chehab 160786baecfSMauro Carvalho Chehab int active; /* Loaded successfully */ 161786baecfSMauro Carvalho Chehab }; 162786baecfSMauro Carvalho Chehab 163786baecfSMauro Carvalho Chehab struct urb_frame { 164786baecfSMauro Carvalho Chehab u8 data[ISO_FRAME_SIZE]; 165786baecfSMauro Carvalho Chehab int length; 166786baecfSMauro Carvalho Chehab struct list_head urb_frame_list; 167786baecfSMauro Carvalho Chehab }; 168786baecfSMauro Carvalho Chehab 169786baecfSMauro Carvalho Chehab struct filter_info { 170786baecfSMauro Carvalho Chehab u8 stream_id; 171786baecfSMauro Carvalho Chehab struct dvb_demux_filter *filter; 172786baecfSMauro Carvalho Chehab struct list_head filter_info_list; 173786baecfSMauro Carvalho Chehab }; 174786baecfSMauro Carvalho Chehab 175786baecfSMauro Carvalho Chehab static u16 rc_keys[] = { 176786baecfSMauro Carvalho Chehab KEY_POWER, 177786baecfSMauro Carvalho Chehab KEY_MUTE, 178786baecfSMauro Carvalho Chehab KEY_1, 179786baecfSMauro Carvalho Chehab KEY_2, 180786baecfSMauro Carvalho Chehab KEY_3, 181786baecfSMauro Carvalho Chehab KEY_4, 182786baecfSMauro Carvalho Chehab KEY_5, 183786baecfSMauro Carvalho Chehab KEY_6, 184786baecfSMauro Carvalho Chehab KEY_7, 185786baecfSMauro Carvalho Chehab KEY_8, 186786baecfSMauro Carvalho Chehab KEY_9, 187786baecfSMauro Carvalho Chehab KEY_0, 188786baecfSMauro Carvalho Chehab KEY_CHANNELUP, 189786baecfSMauro Carvalho Chehab KEY_VOLUMEDOWN, 190786baecfSMauro Carvalho Chehab KEY_OK, 191786baecfSMauro Carvalho Chehab KEY_VOLUMEUP, 192786baecfSMauro Carvalho Chehab KEY_CHANNELDOWN, 193786baecfSMauro Carvalho Chehab KEY_PREVIOUS, 194786baecfSMauro Carvalho Chehab KEY_ESC, 195786baecfSMauro Carvalho Chehab KEY_RED, 196786baecfSMauro Carvalho Chehab KEY_GREEN, 197786baecfSMauro Carvalho Chehab KEY_YELLOW, 198786baecfSMauro Carvalho Chehab KEY_BLUE, 199786baecfSMauro Carvalho Chehab KEY_OPTION, 200786baecfSMauro Carvalho Chehab KEY_M, 201786baecfSMauro Carvalho Chehab KEY_RADIO 202786baecfSMauro Carvalho Chehab }; 203786baecfSMauro Carvalho Chehab 204786baecfSMauro Carvalho Chehab static void ttusb_dec_set_model(struct ttusb_dec *dec, 205786baecfSMauro Carvalho Chehab enum ttusb_dec_model model); 206786baecfSMauro Carvalho Chehab 207786baecfSMauro Carvalho Chehab static void ttusb_dec_handle_irq( struct urb *urb) 208786baecfSMauro Carvalho Chehab { 209786baecfSMauro Carvalho Chehab struct ttusb_dec * dec = urb->context; 210786baecfSMauro Carvalho Chehab char *buffer = dec->irq_buffer; 211786baecfSMauro Carvalho Chehab int retval; 212786baecfSMauro Carvalho Chehab 213786baecfSMauro Carvalho Chehab switch(urb->status) { 214786baecfSMauro Carvalho Chehab case 0: /*success*/ 215786baecfSMauro Carvalho Chehab break; 216786baecfSMauro Carvalho Chehab case -ECONNRESET: 217786baecfSMauro Carvalho Chehab case -ENOENT: 218786baecfSMauro Carvalho Chehab case -ESHUTDOWN: 219786baecfSMauro Carvalho Chehab case -ETIME: 220786baecfSMauro Carvalho Chehab /* this urb is dead, cleanup */ 221786baecfSMauro Carvalho Chehab dprintk("%s:urb shutting down with status: %d\n", 222786baecfSMauro Carvalho Chehab __func__, urb->status); 223786baecfSMauro Carvalho Chehab return; 224786baecfSMauro Carvalho Chehab default: 225786baecfSMauro Carvalho Chehab dprintk("%s:nonzero status received: %d\n", 226786baecfSMauro Carvalho Chehab __func__,urb->status); 227786baecfSMauro Carvalho Chehab goto exit; 228786baecfSMauro Carvalho Chehab } 229786baecfSMauro Carvalho Chehab 230786baecfSMauro Carvalho Chehab if( (buffer[0] == 0x1) && (buffer[2] == 0x15) ) { 231786baecfSMauro Carvalho Chehab /* IR - Event */ 232786baecfSMauro Carvalho Chehab /* this is an fact a bit too simple implementation; 233786baecfSMauro Carvalho Chehab * the box also reports a keyrepeat signal 234786baecfSMauro Carvalho Chehab * (with buffer[3] == 0x40) in an intervall of ~100ms. 235786baecfSMauro Carvalho Chehab * But to handle this correctly we had to imlemenent some 236786baecfSMauro Carvalho Chehab * kind of timer which signals a 'key up' event if no 237786baecfSMauro Carvalho Chehab * keyrepeat signal is received for lets say 200ms. 238786baecfSMauro Carvalho Chehab * this should/could be added later ... 239786baecfSMauro Carvalho Chehab * for now lets report each signal as a key down and up*/ 240786baecfSMauro Carvalho Chehab dprintk("%s:rc signal:%d\n", __func__, buffer[4]); 241786baecfSMauro Carvalho Chehab input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1); 242786baecfSMauro Carvalho Chehab input_sync(dec->rc_input_dev); 243786baecfSMauro Carvalho Chehab input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0); 244786baecfSMauro Carvalho Chehab input_sync(dec->rc_input_dev); 245786baecfSMauro Carvalho Chehab } 246786baecfSMauro Carvalho Chehab 247786baecfSMauro Carvalho Chehab exit: retval = usb_submit_urb(urb, GFP_ATOMIC); 248786baecfSMauro Carvalho Chehab if(retval) 249786baecfSMauro Carvalho Chehab printk("%s - usb_commit_urb failed with result: %d\n", 250786baecfSMauro Carvalho Chehab __func__, retval); 251786baecfSMauro Carvalho Chehab } 252786baecfSMauro Carvalho Chehab 253786baecfSMauro Carvalho Chehab static u16 crc16(u16 crc, const u8 *buf, size_t len) 254786baecfSMauro Carvalho Chehab { 255786baecfSMauro Carvalho Chehab u16 tmp; 256786baecfSMauro Carvalho Chehab 257786baecfSMauro Carvalho Chehab while (len--) { 258786baecfSMauro Carvalho Chehab crc ^= *buf++; 259786baecfSMauro Carvalho Chehab crc ^= (u8)crc >> 4; 260786baecfSMauro Carvalho Chehab tmp = (u8)crc; 261786baecfSMauro Carvalho Chehab crc ^= (tmp ^ (tmp << 1)) << 4; 262786baecfSMauro Carvalho Chehab } 263786baecfSMauro Carvalho Chehab return crc; 264786baecfSMauro Carvalho Chehab } 265786baecfSMauro Carvalho Chehab 266786baecfSMauro Carvalho Chehab static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, 267786baecfSMauro Carvalho Chehab int param_length, const u8 params[], 268786baecfSMauro Carvalho Chehab int *result_length, u8 cmd_result[]) 269786baecfSMauro Carvalho Chehab { 270786baecfSMauro Carvalho Chehab int result, actual_len, i; 271786baecfSMauro Carvalho Chehab u8 *b; 272786baecfSMauro Carvalho Chehab 273786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 274786baecfSMauro Carvalho Chehab 275786baecfSMauro Carvalho Chehab b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL); 276786baecfSMauro Carvalho Chehab if (!b) 277786baecfSMauro Carvalho Chehab return -ENOMEM; 278786baecfSMauro Carvalho Chehab 279786baecfSMauro Carvalho Chehab if ((result = mutex_lock_interruptible(&dec->usb_mutex))) { 280786baecfSMauro Carvalho Chehab kfree(b); 281786baecfSMauro Carvalho Chehab printk("%s: Failed to lock usb mutex.\n", __func__); 282786baecfSMauro Carvalho Chehab return result; 283786baecfSMauro Carvalho Chehab } 284786baecfSMauro Carvalho Chehab 285786baecfSMauro Carvalho Chehab b[0] = 0xaa; 286786baecfSMauro Carvalho Chehab b[1] = ++dec->trans_count; 287786baecfSMauro Carvalho Chehab b[2] = command; 288786baecfSMauro Carvalho Chehab b[3] = param_length; 289786baecfSMauro Carvalho Chehab 290786baecfSMauro Carvalho Chehab if (params) 291786baecfSMauro Carvalho Chehab memcpy(&b[4], params, param_length); 292786baecfSMauro Carvalho Chehab 293786baecfSMauro Carvalho Chehab if (debug) { 294786baecfSMauro Carvalho Chehab printk("%s: command: ", __func__); 295786baecfSMauro Carvalho Chehab for (i = 0; i < param_length + 4; i++) 296786baecfSMauro Carvalho Chehab printk("0x%02X ", b[i]); 297786baecfSMauro Carvalho Chehab printk("\n"); 298786baecfSMauro Carvalho Chehab } 299786baecfSMauro Carvalho Chehab 300786baecfSMauro Carvalho Chehab result = usb_bulk_msg(dec->udev, dec->command_pipe, b, 301786baecfSMauro Carvalho Chehab COMMAND_PACKET_SIZE + 4, &actual_len, 1000); 302786baecfSMauro Carvalho Chehab 303786baecfSMauro Carvalho Chehab if (result) { 304786baecfSMauro Carvalho Chehab printk("%s: command bulk message failed: error %d\n", 305786baecfSMauro Carvalho Chehab __func__, result); 306786baecfSMauro Carvalho Chehab mutex_unlock(&dec->usb_mutex); 307786baecfSMauro Carvalho Chehab kfree(b); 308786baecfSMauro Carvalho Chehab return result; 309786baecfSMauro Carvalho Chehab } 310786baecfSMauro Carvalho Chehab 311786baecfSMauro Carvalho Chehab result = usb_bulk_msg(dec->udev, dec->result_pipe, b, 312786baecfSMauro Carvalho Chehab COMMAND_PACKET_SIZE + 4, &actual_len, 1000); 313786baecfSMauro Carvalho Chehab 314786baecfSMauro Carvalho Chehab if (result) { 315786baecfSMauro Carvalho Chehab printk("%s: result bulk message failed: error %d\n", 316786baecfSMauro Carvalho Chehab __func__, result); 317786baecfSMauro Carvalho Chehab mutex_unlock(&dec->usb_mutex); 318786baecfSMauro Carvalho Chehab kfree(b); 319786baecfSMauro Carvalho Chehab return result; 320786baecfSMauro Carvalho Chehab } else { 321786baecfSMauro Carvalho Chehab if (debug) { 322786baecfSMauro Carvalho Chehab printk("%s: result: ", __func__); 323786baecfSMauro Carvalho Chehab for (i = 0; i < actual_len; i++) 324786baecfSMauro Carvalho Chehab printk("0x%02X ", b[i]); 325786baecfSMauro Carvalho Chehab printk("\n"); 326786baecfSMauro Carvalho Chehab } 327786baecfSMauro Carvalho Chehab 328786baecfSMauro Carvalho Chehab if (result_length) 329786baecfSMauro Carvalho Chehab *result_length = b[3]; 330786baecfSMauro Carvalho Chehab if (cmd_result && b[3] > 0) 331786baecfSMauro Carvalho Chehab memcpy(cmd_result, &b[4], b[3]); 332786baecfSMauro Carvalho Chehab 333786baecfSMauro Carvalho Chehab mutex_unlock(&dec->usb_mutex); 334786baecfSMauro Carvalho Chehab 335786baecfSMauro Carvalho Chehab kfree(b); 336786baecfSMauro Carvalho Chehab return 0; 337786baecfSMauro Carvalho Chehab } 338786baecfSMauro Carvalho Chehab } 339786baecfSMauro Carvalho Chehab 340786baecfSMauro Carvalho Chehab static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, 341786baecfSMauro Carvalho Chehab unsigned int *model, unsigned int *version) 342786baecfSMauro Carvalho Chehab { 343786baecfSMauro Carvalho Chehab u8 c[COMMAND_PACKET_SIZE]; 344786baecfSMauro Carvalho Chehab int c_length; 345786baecfSMauro Carvalho Chehab int result; 346786baecfSMauro Carvalho Chehab __be32 tmp; 347786baecfSMauro Carvalho Chehab 348786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 349786baecfSMauro Carvalho Chehab 350786baecfSMauro Carvalho Chehab result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c); 351786baecfSMauro Carvalho Chehab if (result) 352786baecfSMauro Carvalho Chehab return result; 353786baecfSMauro Carvalho Chehab 354786baecfSMauro Carvalho Chehab if (c_length >= 0x0c) { 355786baecfSMauro Carvalho Chehab if (mode != NULL) { 356786baecfSMauro Carvalho Chehab memcpy(&tmp, c, 4); 357786baecfSMauro Carvalho Chehab *mode = ntohl(tmp); 358786baecfSMauro Carvalho Chehab } 359786baecfSMauro Carvalho Chehab if (model != NULL) { 360786baecfSMauro Carvalho Chehab memcpy(&tmp, &c[4], 4); 361786baecfSMauro Carvalho Chehab *model = ntohl(tmp); 362786baecfSMauro Carvalho Chehab } 363786baecfSMauro Carvalho Chehab if (version != NULL) { 364786baecfSMauro Carvalho Chehab memcpy(&tmp, &c[8], 4); 365786baecfSMauro Carvalho Chehab *version = ntohl(tmp); 366786baecfSMauro Carvalho Chehab } 367786baecfSMauro Carvalho Chehab return 0; 368786baecfSMauro Carvalho Chehab } else { 369cf732b5fSAlexey Khoroshilov return -ENOENT; 370786baecfSMauro Carvalho Chehab } 371786baecfSMauro Carvalho Chehab } 372786baecfSMauro Carvalho Chehab 373786baecfSMauro Carvalho Chehab static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) 374786baecfSMauro Carvalho Chehab { 375786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = priv; 376786baecfSMauro Carvalho Chehab 377786baecfSMauro Carvalho Chehab dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, 378*2f684b23SMauro Carvalho Chehab &dec->audio_filter->feed->feed.ts); 379786baecfSMauro Carvalho Chehab 380786baecfSMauro Carvalho Chehab return 0; 381786baecfSMauro Carvalho Chehab } 382786baecfSMauro Carvalho Chehab 383786baecfSMauro Carvalho Chehab static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) 384786baecfSMauro Carvalho Chehab { 385786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = priv; 386786baecfSMauro Carvalho Chehab 387786baecfSMauro Carvalho Chehab dec->video_filter->feed->cb.ts(data, 188, NULL, 0, 388*2f684b23SMauro Carvalho Chehab &dec->video_filter->feed->feed.ts); 389786baecfSMauro Carvalho Chehab 390786baecfSMauro Carvalho Chehab return 0; 391786baecfSMauro Carvalho Chehab } 392786baecfSMauro Carvalho Chehab 393786baecfSMauro Carvalho Chehab static void ttusb_dec_set_pids(struct ttusb_dec *dec) 394786baecfSMauro Carvalho Chehab { 395786baecfSMauro Carvalho Chehab u8 b[] = { 0x00, 0x00, 0x00, 0x00, 396786baecfSMauro Carvalho Chehab 0x00, 0x00, 0xff, 0xff, 397786baecfSMauro Carvalho Chehab 0xff, 0xff, 0xff, 0xff }; 398786baecfSMauro Carvalho Chehab 399786baecfSMauro Carvalho Chehab __be16 pcr = htons(dec->pid[DMX_PES_PCR]); 400786baecfSMauro Carvalho Chehab __be16 audio = htons(dec->pid[DMX_PES_AUDIO]); 401786baecfSMauro Carvalho Chehab __be16 video = htons(dec->pid[DMX_PES_VIDEO]); 402786baecfSMauro Carvalho Chehab 403786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 404786baecfSMauro Carvalho Chehab 405786baecfSMauro Carvalho Chehab memcpy(&b[0], &pcr, 2); 406786baecfSMauro Carvalho Chehab memcpy(&b[2], &audio, 2); 407786baecfSMauro Carvalho Chehab memcpy(&b[4], &video, 2); 408786baecfSMauro Carvalho Chehab 409786baecfSMauro Carvalho Chehab ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL); 410786baecfSMauro Carvalho Chehab 411786baecfSMauro Carvalho Chehab dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO], 412786baecfSMauro Carvalho Chehab ttusb_dec_audio_pes2ts_cb, dec); 413786baecfSMauro Carvalho Chehab dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO], 414786baecfSMauro Carvalho Chehab ttusb_dec_video_pes2ts_cb, dec); 415786baecfSMauro Carvalho Chehab dec->v_pes_length = 0; 416786baecfSMauro Carvalho Chehab dec->v_pes_postbytes = 0; 417786baecfSMauro Carvalho Chehab } 418786baecfSMauro Carvalho Chehab 419786baecfSMauro Carvalho Chehab static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) 420786baecfSMauro Carvalho Chehab { 421786baecfSMauro Carvalho Chehab if (length < 8) { 422786baecfSMauro Carvalho Chehab printk("%s: packet too short - discarding\n", __func__); 423786baecfSMauro Carvalho Chehab return; 424786baecfSMauro Carvalho Chehab } 425786baecfSMauro Carvalho Chehab 426786baecfSMauro Carvalho Chehab if (length > 8 + MAX_PVA_LENGTH) { 427786baecfSMauro Carvalho Chehab printk("%s: packet too long - discarding\n", __func__); 428786baecfSMauro Carvalho Chehab return; 429786baecfSMauro Carvalho Chehab } 430786baecfSMauro Carvalho Chehab 431786baecfSMauro Carvalho Chehab switch (pva[2]) { 432786baecfSMauro Carvalho Chehab 433786baecfSMauro Carvalho Chehab case 0x01: { /* VideoStream */ 434786baecfSMauro Carvalho Chehab int prebytes = pva[5] & 0x03; 435786baecfSMauro Carvalho Chehab int postbytes = (pva[5] & 0x0c) >> 2; 436786baecfSMauro Carvalho Chehab __be16 v_pes_payload_length; 437786baecfSMauro Carvalho Chehab 438786baecfSMauro Carvalho Chehab if (output_pva) { 439786baecfSMauro Carvalho Chehab dec->video_filter->feed->cb.ts(pva, length, NULL, 0, 440*2f684b23SMauro Carvalho Chehab &dec->video_filter->feed->feed.ts); 441786baecfSMauro Carvalho Chehab return; 442786baecfSMauro Carvalho Chehab } 443786baecfSMauro Carvalho Chehab 444786baecfSMauro Carvalho Chehab if (dec->v_pes_postbytes > 0 && 445786baecfSMauro Carvalho Chehab dec->v_pes_postbytes == prebytes) { 446786baecfSMauro Carvalho Chehab memcpy(&dec->v_pes[dec->v_pes_length], 447786baecfSMauro Carvalho Chehab &pva[12], prebytes); 448786baecfSMauro Carvalho Chehab 449786baecfSMauro Carvalho Chehab dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes, 450786baecfSMauro Carvalho Chehab dec->v_pes_length + prebytes, 1); 451786baecfSMauro Carvalho Chehab } 452786baecfSMauro Carvalho Chehab 453786baecfSMauro Carvalho Chehab if (pva[5] & 0x10) { 454786baecfSMauro Carvalho Chehab dec->v_pes[7] = 0x80; 455786baecfSMauro Carvalho Chehab dec->v_pes[8] = 0x05; 456786baecfSMauro Carvalho Chehab 457786baecfSMauro Carvalho Chehab dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5); 458786baecfSMauro Carvalho Chehab dec->v_pes[10] = ((pva[8] & 0x3f) << 2) | 459786baecfSMauro Carvalho Chehab ((pva[9] & 0xc0) >> 6); 460786baecfSMauro Carvalho Chehab dec->v_pes[11] = 0x01 | 461786baecfSMauro Carvalho Chehab ((pva[9] & 0x3f) << 2) | 462786baecfSMauro Carvalho Chehab ((pva[10] & 0x80) >> 6); 463786baecfSMauro Carvalho Chehab dec->v_pes[12] = ((pva[10] & 0x7f) << 1) | 464786baecfSMauro Carvalho Chehab ((pva[11] & 0xc0) >> 7); 465786baecfSMauro Carvalho Chehab dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1); 466786baecfSMauro Carvalho Chehab 467786baecfSMauro Carvalho Chehab memcpy(&dec->v_pes[14], &pva[12 + prebytes], 468786baecfSMauro Carvalho Chehab length - 12 - prebytes); 469786baecfSMauro Carvalho Chehab dec->v_pes_length = 14 + length - 12 - prebytes; 470786baecfSMauro Carvalho Chehab } else { 471786baecfSMauro Carvalho Chehab dec->v_pes[7] = 0x00; 472786baecfSMauro Carvalho Chehab dec->v_pes[8] = 0x00; 473786baecfSMauro Carvalho Chehab 474786baecfSMauro Carvalho Chehab memcpy(&dec->v_pes[9], &pva[8], length - 8); 475786baecfSMauro Carvalho Chehab dec->v_pes_length = 9 + length - 8; 476786baecfSMauro Carvalho Chehab } 477786baecfSMauro Carvalho Chehab 478786baecfSMauro Carvalho Chehab dec->v_pes_postbytes = postbytes; 479786baecfSMauro Carvalho Chehab 480786baecfSMauro Carvalho Chehab if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 && 481786baecfSMauro Carvalho Chehab dec->v_pes[10 + dec->v_pes[8]] == 0x00 && 482786baecfSMauro Carvalho Chehab dec->v_pes[11 + dec->v_pes[8]] == 0x01) 483786baecfSMauro Carvalho Chehab dec->v_pes[6] = 0x84; 484786baecfSMauro Carvalho Chehab else 485786baecfSMauro Carvalho Chehab dec->v_pes[6] = 0x80; 486786baecfSMauro Carvalho Chehab 487786baecfSMauro Carvalho Chehab v_pes_payload_length = htons(dec->v_pes_length - 6 + 488786baecfSMauro Carvalho Chehab postbytes); 489786baecfSMauro Carvalho Chehab memcpy(&dec->v_pes[4], &v_pes_payload_length, 2); 490786baecfSMauro Carvalho Chehab 491786baecfSMauro Carvalho Chehab if (postbytes == 0) 492786baecfSMauro Carvalho Chehab dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes, 493786baecfSMauro Carvalho Chehab dec->v_pes_length, 1); 494786baecfSMauro Carvalho Chehab 495786baecfSMauro Carvalho Chehab break; 496786baecfSMauro Carvalho Chehab } 497786baecfSMauro Carvalho Chehab 498786baecfSMauro Carvalho Chehab case 0x02: /* MainAudioStream */ 499786baecfSMauro Carvalho Chehab if (output_pva) { 500786baecfSMauro Carvalho Chehab dec->audio_filter->feed->cb.ts(pva, length, NULL, 0, 501*2f684b23SMauro Carvalho Chehab &dec->audio_filter->feed->feed.ts); 502786baecfSMauro Carvalho Chehab return; 503786baecfSMauro Carvalho Chehab } 504786baecfSMauro Carvalho Chehab 505786baecfSMauro Carvalho Chehab dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8, 506786baecfSMauro Carvalho Chehab pva[5] & 0x10); 507786baecfSMauro Carvalho Chehab break; 508786baecfSMauro Carvalho Chehab 509786baecfSMauro Carvalho Chehab default: 510786baecfSMauro Carvalho Chehab printk("%s: unknown PVA type: %02x.\n", __func__, 511786baecfSMauro Carvalho Chehab pva[2]); 512786baecfSMauro Carvalho Chehab break; 513786baecfSMauro Carvalho Chehab } 514786baecfSMauro Carvalho Chehab } 515786baecfSMauro Carvalho Chehab 516786baecfSMauro Carvalho Chehab static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet, 517786baecfSMauro Carvalho Chehab int length) 518786baecfSMauro Carvalho Chehab { 519786baecfSMauro Carvalho Chehab struct list_head *item; 520786baecfSMauro Carvalho Chehab struct filter_info *finfo; 521786baecfSMauro Carvalho Chehab struct dvb_demux_filter *filter = NULL; 522786baecfSMauro Carvalho Chehab unsigned long flags; 523786baecfSMauro Carvalho Chehab u8 sid; 524786baecfSMauro Carvalho Chehab 525786baecfSMauro Carvalho Chehab sid = packet[1]; 526786baecfSMauro Carvalho Chehab spin_lock_irqsave(&dec->filter_info_list_lock, flags); 527786baecfSMauro Carvalho Chehab for (item = dec->filter_info_list.next; item != &dec->filter_info_list; 528786baecfSMauro Carvalho Chehab item = item->next) { 529786baecfSMauro Carvalho Chehab finfo = list_entry(item, struct filter_info, filter_info_list); 530786baecfSMauro Carvalho Chehab if (finfo->stream_id == sid) { 531786baecfSMauro Carvalho Chehab filter = finfo->filter; 532786baecfSMauro Carvalho Chehab break; 533786baecfSMauro Carvalho Chehab } 534786baecfSMauro Carvalho Chehab } 535786baecfSMauro Carvalho Chehab spin_unlock_irqrestore(&dec->filter_info_list_lock, flags); 536786baecfSMauro Carvalho Chehab 537786baecfSMauro Carvalho Chehab if (filter) 538786baecfSMauro Carvalho Chehab filter->feed->cb.sec(&packet[2], length - 2, NULL, 0, 539*2f684b23SMauro Carvalho Chehab &filter->filter); 540786baecfSMauro Carvalho Chehab } 541786baecfSMauro Carvalho Chehab 542786baecfSMauro Carvalho Chehab static void ttusb_dec_process_packet(struct ttusb_dec *dec) 543786baecfSMauro Carvalho Chehab { 544786baecfSMauro Carvalho Chehab int i; 545786baecfSMauro Carvalho Chehab u16 csum = 0; 546786baecfSMauro Carvalho Chehab u16 packet_id; 547786baecfSMauro Carvalho Chehab 548786baecfSMauro Carvalho Chehab if (dec->packet_length % 2) { 549786baecfSMauro Carvalho Chehab printk("%s: odd sized packet - discarding\n", __func__); 550786baecfSMauro Carvalho Chehab return; 551786baecfSMauro Carvalho Chehab } 552786baecfSMauro Carvalho Chehab 553786baecfSMauro Carvalho Chehab for (i = 0; i < dec->packet_length; i += 2) 554786baecfSMauro Carvalho Chehab csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]); 555786baecfSMauro Carvalho Chehab 556786baecfSMauro Carvalho Chehab if (csum) { 557786baecfSMauro Carvalho Chehab printk("%s: checksum failed - discarding\n", __func__); 558786baecfSMauro Carvalho Chehab return; 559786baecfSMauro Carvalho Chehab } 560786baecfSMauro Carvalho Chehab 561786baecfSMauro Carvalho Chehab packet_id = dec->packet[dec->packet_length - 4] << 8; 562786baecfSMauro Carvalho Chehab packet_id += dec->packet[dec->packet_length - 3]; 563786baecfSMauro Carvalho Chehab 564786baecfSMauro Carvalho Chehab if ((packet_id != dec->next_packet_id) && dec->next_packet_id) { 565786baecfSMauro Carvalho Chehab printk("%s: warning: lost packets between %u and %u\n", 566786baecfSMauro Carvalho Chehab __func__, dec->next_packet_id - 1, packet_id); 567786baecfSMauro Carvalho Chehab } 568786baecfSMauro Carvalho Chehab 569786baecfSMauro Carvalho Chehab if (packet_id == 0xffff) 570786baecfSMauro Carvalho Chehab dec->next_packet_id = 0x8000; 571786baecfSMauro Carvalho Chehab else 572786baecfSMauro Carvalho Chehab dec->next_packet_id = packet_id + 1; 573786baecfSMauro Carvalho Chehab 574786baecfSMauro Carvalho Chehab switch (dec->packet_type) { 575786baecfSMauro Carvalho Chehab case TTUSB_DEC_PACKET_PVA: 576786baecfSMauro Carvalho Chehab if (dec->pva_stream_count) 577786baecfSMauro Carvalho Chehab ttusb_dec_process_pva(dec, dec->packet, 578786baecfSMauro Carvalho Chehab dec->packet_payload_length); 579786baecfSMauro Carvalho Chehab break; 580786baecfSMauro Carvalho Chehab 581786baecfSMauro Carvalho Chehab case TTUSB_DEC_PACKET_SECTION: 582786baecfSMauro Carvalho Chehab if (dec->filter_stream_count) 583786baecfSMauro Carvalho Chehab ttusb_dec_process_filter(dec, dec->packet, 584786baecfSMauro Carvalho Chehab dec->packet_payload_length); 585786baecfSMauro Carvalho Chehab break; 586786baecfSMauro Carvalho Chehab 587786baecfSMauro Carvalho Chehab case TTUSB_DEC_PACKET_EMPTY: 588786baecfSMauro Carvalho Chehab break; 589786baecfSMauro Carvalho Chehab } 590786baecfSMauro Carvalho Chehab } 591786baecfSMauro Carvalho Chehab 592786baecfSMauro Carvalho Chehab static void swap_bytes(u8 *b, int length) 593786baecfSMauro Carvalho Chehab { 594786baecfSMauro Carvalho Chehab length -= length % 2; 59541cc14baSFabian Frederick for (; length; b += 2, length -= 2) 59641cc14baSFabian Frederick swap(*b, *(b + 1)); 597786baecfSMauro Carvalho Chehab } 598786baecfSMauro Carvalho Chehab 599786baecfSMauro Carvalho Chehab static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b, 600786baecfSMauro Carvalho Chehab int length) 601786baecfSMauro Carvalho Chehab { 602786baecfSMauro Carvalho Chehab swap_bytes(b, length); 603786baecfSMauro Carvalho Chehab 604786baecfSMauro Carvalho Chehab while (length) { 605786baecfSMauro Carvalho Chehab switch (dec->packet_state) { 606786baecfSMauro Carvalho Chehab 607786baecfSMauro Carvalho Chehab case 0: 608786baecfSMauro Carvalho Chehab case 1: 609786baecfSMauro Carvalho Chehab case 2: 610786baecfSMauro Carvalho Chehab if (*b++ == 0xaa) 611786baecfSMauro Carvalho Chehab dec->packet_state++; 612786baecfSMauro Carvalho Chehab else 613786baecfSMauro Carvalho Chehab dec->packet_state = 0; 614786baecfSMauro Carvalho Chehab 615786baecfSMauro Carvalho Chehab length--; 616786baecfSMauro Carvalho Chehab break; 617786baecfSMauro Carvalho Chehab 618786baecfSMauro Carvalho Chehab case 3: 619786baecfSMauro Carvalho Chehab if (*b == 0x00) { 620786baecfSMauro Carvalho Chehab dec->packet_state++; 621786baecfSMauro Carvalho Chehab dec->packet_length = 0; 622786baecfSMauro Carvalho Chehab } else if (*b != 0xaa) { 623786baecfSMauro Carvalho Chehab dec->packet_state = 0; 624786baecfSMauro Carvalho Chehab } 625786baecfSMauro Carvalho Chehab 626786baecfSMauro Carvalho Chehab b++; 627786baecfSMauro Carvalho Chehab length--; 628786baecfSMauro Carvalho Chehab break; 629786baecfSMauro Carvalho Chehab 630786baecfSMauro Carvalho Chehab case 4: 631786baecfSMauro Carvalho Chehab dec->packet[dec->packet_length++] = *b++; 632786baecfSMauro Carvalho Chehab 633786baecfSMauro Carvalho Chehab if (dec->packet_length == 2) { 634786baecfSMauro Carvalho Chehab if (dec->packet[0] == 'A' && 635786baecfSMauro Carvalho Chehab dec->packet[1] == 'V') { 636786baecfSMauro Carvalho Chehab dec->packet_type = 637786baecfSMauro Carvalho Chehab TTUSB_DEC_PACKET_PVA; 638786baecfSMauro Carvalho Chehab dec->packet_state++; 639786baecfSMauro Carvalho Chehab } else if (dec->packet[0] == 'S') { 640786baecfSMauro Carvalho Chehab dec->packet_type = 641786baecfSMauro Carvalho Chehab TTUSB_DEC_PACKET_SECTION; 642786baecfSMauro Carvalho Chehab dec->packet_state++; 643786baecfSMauro Carvalho Chehab } else if (dec->packet[0] == 0x00) { 644786baecfSMauro Carvalho Chehab dec->packet_type = 645786baecfSMauro Carvalho Chehab TTUSB_DEC_PACKET_EMPTY; 646786baecfSMauro Carvalho Chehab dec->packet_payload_length = 2; 647786baecfSMauro Carvalho Chehab dec->packet_state = 7; 648786baecfSMauro Carvalho Chehab } else { 649786baecfSMauro Carvalho Chehab printk("%s: unknown packet type: " 650786baecfSMauro Carvalho Chehab "%02x%02x\n", __func__, 651786baecfSMauro Carvalho Chehab dec->packet[0], dec->packet[1]); 652786baecfSMauro Carvalho Chehab dec->packet_state = 0; 653786baecfSMauro Carvalho Chehab } 654786baecfSMauro Carvalho Chehab } 655786baecfSMauro Carvalho Chehab 656786baecfSMauro Carvalho Chehab length--; 657786baecfSMauro Carvalho Chehab break; 658786baecfSMauro Carvalho Chehab 659786baecfSMauro Carvalho Chehab case 5: 660786baecfSMauro Carvalho Chehab dec->packet[dec->packet_length++] = *b++; 661786baecfSMauro Carvalho Chehab 662786baecfSMauro Carvalho Chehab if (dec->packet_type == TTUSB_DEC_PACKET_PVA && 663786baecfSMauro Carvalho Chehab dec->packet_length == 8) { 664786baecfSMauro Carvalho Chehab dec->packet_state++; 665786baecfSMauro Carvalho Chehab dec->packet_payload_length = 8 + 666786baecfSMauro Carvalho Chehab (dec->packet[6] << 8) + 667786baecfSMauro Carvalho Chehab dec->packet[7]; 668786baecfSMauro Carvalho Chehab } else if (dec->packet_type == 669786baecfSMauro Carvalho Chehab TTUSB_DEC_PACKET_SECTION && 670786baecfSMauro Carvalho Chehab dec->packet_length == 5) { 671786baecfSMauro Carvalho Chehab dec->packet_state++; 672786baecfSMauro Carvalho Chehab dec->packet_payload_length = 5 + 673786baecfSMauro Carvalho Chehab ((dec->packet[3] & 0x0f) << 8) + 674786baecfSMauro Carvalho Chehab dec->packet[4]; 675786baecfSMauro Carvalho Chehab } 676786baecfSMauro Carvalho Chehab 677786baecfSMauro Carvalho Chehab length--; 678786baecfSMauro Carvalho Chehab break; 679786baecfSMauro Carvalho Chehab 680786baecfSMauro Carvalho Chehab case 6: { 681786baecfSMauro Carvalho Chehab int remainder = dec->packet_payload_length - 682786baecfSMauro Carvalho Chehab dec->packet_length; 683786baecfSMauro Carvalho Chehab 684786baecfSMauro Carvalho Chehab if (length >= remainder) { 685786baecfSMauro Carvalho Chehab memcpy(dec->packet + dec->packet_length, 686786baecfSMauro Carvalho Chehab b, remainder); 687786baecfSMauro Carvalho Chehab dec->packet_length += remainder; 688786baecfSMauro Carvalho Chehab b += remainder; 689786baecfSMauro Carvalho Chehab length -= remainder; 690786baecfSMauro Carvalho Chehab dec->packet_state++; 691786baecfSMauro Carvalho Chehab } else { 692786baecfSMauro Carvalho Chehab memcpy(&dec->packet[dec->packet_length], 693786baecfSMauro Carvalho Chehab b, length); 694786baecfSMauro Carvalho Chehab dec->packet_length += length; 695786baecfSMauro Carvalho Chehab length = 0; 696786baecfSMauro Carvalho Chehab } 697786baecfSMauro Carvalho Chehab 698786baecfSMauro Carvalho Chehab break; 699786baecfSMauro Carvalho Chehab } 700786baecfSMauro Carvalho Chehab 701786baecfSMauro Carvalho Chehab case 7: { 702786baecfSMauro Carvalho Chehab int tail = 4; 703786baecfSMauro Carvalho Chehab 704786baecfSMauro Carvalho Chehab dec->packet[dec->packet_length++] = *b++; 705786baecfSMauro Carvalho Chehab 706786baecfSMauro Carvalho Chehab if (dec->packet_type == TTUSB_DEC_PACKET_SECTION && 707786baecfSMauro Carvalho Chehab dec->packet_payload_length % 2) 708786baecfSMauro Carvalho Chehab tail++; 709786baecfSMauro Carvalho Chehab 710786baecfSMauro Carvalho Chehab if (dec->packet_length == 711786baecfSMauro Carvalho Chehab dec->packet_payload_length + tail) { 712786baecfSMauro Carvalho Chehab ttusb_dec_process_packet(dec); 713786baecfSMauro Carvalho Chehab dec->packet_state = 0; 714786baecfSMauro Carvalho Chehab } 715786baecfSMauro Carvalho Chehab 716786baecfSMauro Carvalho Chehab length--; 717786baecfSMauro Carvalho Chehab break; 718786baecfSMauro Carvalho Chehab } 719786baecfSMauro Carvalho Chehab 720786baecfSMauro Carvalho Chehab default: 721786baecfSMauro Carvalho Chehab printk("%s: illegal packet state encountered.\n", 722786baecfSMauro Carvalho Chehab __func__); 723786baecfSMauro Carvalho Chehab dec->packet_state = 0; 724786baecfSMauro Carvalho Chehab } 725786baecfSMauro Carvalho Chehab } 726786baecfSMauro Carvalho Chehab } 727786baecfSMauro Carvalho Chehab 728786baecfSMauro Carvalho Chehab static void ttusb_dec_process_urb_frame_list(unsigned long data) 729786baecfSMauro Carvalho Chehab { 730786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = (struct ttusb_dec *)data; 731786baecfSMauro Carvalho Chehab struct list_head *item; 732786baecfSMauro Carvalho Chehab struct urb_frame *frame; 733786baecfSMauro Carvalho Chehab unsigned long flags; 734786baecfSMauro Carvalho Chehab 735786baecfSMauro Carvalho Chehab while (1) { 736786baecfSMauro Carvalho Chehab spin_lock_irqsave(&dec->urb_frame_list_lock, flags); 737786baecfSMauro Carvalho Chehab if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) { 738786baecfSMauro Carvalho Chehab frame = list_entry(item, struct urb_frame, 739786baecfSMauro Carvalho Chehab urb_frame_list); 740786baecfSMauro Carvalho Chehab list_del(&frame->urb_frame_list); 741786baecfSMauro Carvalho Chehab } else { 742786baecfSMauro Carvalho Chehab spin_unlock_irqrestore(&dec->urb_frame_list_lock, 743786baecfSMauro Carvalho Chehab flags); 744786baecfSMauro Carvalho Chehab return; 745786baecfSMauro Carvalho Chehab } 746786baecfSMauro Carvalho Chehab spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags); 747786baecfSMauro Carvalho Chehab 748786baecfSMauro Carvalho Chehab ttusb_dec_process_urb_frame(dec, frame->data, frame->length); 749786baecfSMauro Carvalho Chehab kfree(frame); 750786baecfSMauro Carvalho Chehab } 751786baecfSMauro Carvalho Chehab } 752786baecfSMauro Carvalho Chehab 753786baecfSMauro Carvalho Chehab static void ttusb_dec_process_urb(struct urb *urb) 754786baecfSMauro Carvalho Chehab { 755786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = urb->context; 756786baecfSMauro Carvalho Chehab 757786baecfSMauro Carvalho Chehab if (!urb->status) { 758786baecfSMauro Carvalho Chehab int i; 759786baecfSMauro Carvalho Chehab 760786baecfSMauro Carvalho Chehab for (i = 0; i < FRAMES_PER_ISO_BUF; i++) { 761786baecfSMauro Carvalho Chehab struct usb_iso_packet_descriptor *d; 762786baecfSMauro Carvalho Chehab u8 *b; 763786baecfSMauro Carvalho Chehab int length; 764786baecfSMauro Carvalho Chehab struct urb_frame *frame; 765786baecfSMauro Carvalho Chehab 766786baecfSMauro Carvalho Chehab d = &urb->iso_frame_desc[i]; 767786baecfSMauro Carvalho Chehab b = urb->transfer_buffer + d->offset; 768786baecfSMauro Carvalho Chehab length = d->actual_length; 769786baecfSMauro Carvalho Chehab 770786baecfSMauro Carvalho Chehab if ((frame = kmalloc(sizeof(struct urb_frame), 771786baecfSMauro Carvalho Chehab GFP_ATOMIC))) { 772786baecfSMauro Carvalho Chehab unsigned long flags; 773786baecfSMauro Carvalho Chehab 774786baecfSMauro Carvalho Chehab memcpy(frame->data, b, length); 775786baecfSMauro Carvalho Chehab frame->length = length; 776786baecfSMauro Carvalho Chehab 777786baecfSMauro Carvalho Chehab spin_lock_irqsave(&dec->urb_frame_list_lock, 778786baecfSMauro Carvalho Chehab flags); 779786baecfSMauro Carvalho Chehab list_add_tail(&frame->urb_frame_list, 780786baecfSMauro Carvalho Chehab &dec->urb_frame_list); 781786baecfSMauro Carvalho Chehab spin_unlock_irqrestore(&dec->urb_frame_list_lock, 782786baecfSMauro Carvalho Chehab flags); 783786baecfSMauro Carvalho Chehab 784786baecfSMauro Carvalho Chehab tasklet_schedule(&dec->urb_tasklet); 785786baecfSMauro Carvalho Chehab } 786786baecfSMauro Carvalho Chehab } 787786baecfSMauro Carvalho Chehab } else { 788786baecfSMauro Carvalho Chehab /* -ENOENT is expected when unlinking urbs */ 789786baecfSMauro Carvalho Chehab if (urb->status != -ENOENT) 790786baecfSMauro Carvalho Chehab dprintk("%s: urb error: %d\n", __func__, 791786baecfSMauro Carvalho Chehab urb->status); 792786baecfSMauro Carvalho Chehab } 793786baecfSMauro Carvalho Chehab 794786baecfSMauro Carvalho Chehab if (dec->iso_stream_count) 795786baecfSMauro Carvalho Chehab usb_submit_urb(urb, GFP_ATOMIC); 796786baecfSMauro Carvalho Chehab } 797786baecfSMauro Carvalho Chehab 798786baecfSMauro Carvalho Chehab static void ttusb_dec_setup_urbs(struct ttusb_dec *dec) 799786baecfSMauro Carvalho Chehab { 800786baecfSMauro Carvalho Chehab int i, j, buffer_offset = 0; 801786baecfSMauro Carvalho Chehab 802786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 803786baecfSMauro Carvalho Chehab 804786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) { 805786baecfSMauro Carvalho Chehab int frame_offset = 0; 806786baecfSMauro Carvalho Chehab struct urb *urb = dec->iso_urb[i]; 807786baecfSMauro Carvalho Chehab 808786baecfSMauro Carvalho Chehab urb->dev = dec->udev; 809786baecfSMauro Carvalho Chehab urb->context = dec; 810786baecfSMauro Carvalho Chehab urb->complete = ttusb_dec_process_urb; 811786baecfSMauro Carvalho Chehab urb->pipe = dec->in_pipe; 812786baecfSMauro Carvalho Chehab urb->transfer_flags = URB_ISO_ASAP; 813786baecfSMauro Carvalho Chehab urb->interval = 1; 814786baecfSMauro Carvalho Chehab urb->number_of_packets = FRAMES_PER_ISO_BUF; 815786baecfSMauro Carvalho Chehab urb->transfer_buffer_length = ISO_FRAME_SIZE * 816786baecfSMauro Carvalho Chehab FRAMES_PER_ISO_BUF; 817786baecfSMauro Carvalho Chehab urb->transfer_buffer = dec->iso_buffer + buffer_offset; 818786baecfSMauro Carvalho Chehab buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF; 819786baecfSMauro Carvalho Chehab 820786baecfSMauro Carvalho Chehab for (j = 0; j < FRAMES_PER_ISO_BUF; j++) { 821786baecfSMauro Carvalho Chehab urb->iso_frame_desc[j].offset = frame_offset; 822786baecfSMauro Carvalho Chehab urb->iso_frame_desc[j].length = ISO_FRAME_SIZE; 823786baecfSMauro Carvalho Chehab frame_offset += ISO_FRAME_SIZE; 824786baecfSMauro Carvalho Chehab } 825786baecfSMauro Carvalho Chehab } 826786baecfSMauro Carvalho Chehab } 827786baecfSMauro Carvalho Chehab 828786baecfSMauro Carvalho Chehab static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) 829786baecfSMauro Carvalho Chehab { 830786baecfSMauro Carvalho Chehab int i; 831786baecfSMauro Carvalho Chehab 832786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 833786baecfSMauro Carvalho Chehab 834786baecfSMauro Carvalho Chehab if (mutex_lock_interruptible(&dec->iso_mutex)) 835786baecfSMauro Carvalho Chehab return; 836786baecfSMauro Carvalho Chehab 837786baecfSMauro Carvalho Chehab dec->iso_stream_count--; 838786baecfSMauro Carvalho Chehab 839786baecfSMauro Carvalho Chehab if (!dec->iso_stream_count) { 840786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) 841786baecfSMauro Carvalho Chehab usb_kill_urb(dec->iso_urb[i]); 842786baecfSMauro Carvalho Chehab } 843786baecfSMauro Carvalho Chehab 844786baecfSMauro Carvalho Chehab mutex_unlock(&dec->iso_mutex); 845786baecfSMauro Carvalho Chehab } 846786baecfSMauro Carvalho Chehab 847786baecfSMauro Carvalho Chehab /* Setting the interface of the DEC tends to take down the USB communications 848786baecfSMauro Carvalho Chehab * for a short period, so it's important not to call this function just before 849786baecfSMauro Carvalho Chehab * trying to talk to it. 850786baecfSMauro Carvalho Chehab */ 851786baecfSMauro Carvalho Chehab static int ttusb_dec_set_interface(struct ttusb_dec *dec, 852786baecfSMauro Carvalho Chehab enum ttusb_dec_interface interface) 853786baecfSMauro Carvalho Chehab { 854786baecfSMauro Carvalho Chehab int result = 0; 855786baecfSMauro Carvalho Chehab u8 b[] = { 0x05 }; 856786baecfSMauro Carvalho Chehab 857786baecfSMauro Carvalho Chehab if (interface != dec->interface) { 858786baecfSMauro Carvalho Chehab switch (interface) { 859786baecfSMauro Carvalho Chehab case TTUSB_DEC_INTERFACE_INITIAL: 860786baecfSMauro Carvalho Chehab result = usb_set_interface(dec->udev, 0, 0); 861786baecfSMauro Carvalho Chehab break; 862786baecfSMauro Carvalho Chehab case TTUSB_DEC_INTERFACE_IN: 863786baecfSMauro Carvalho Chehab result = ttusb_dec_send_command(dec, 0x80, sizeof(b), 864786baecfSMauro Carvalho Chehab b, NULL, NULL); 865786baecfSMauro Carvalho Chehab if (result) 866786baecfSMauro Carvalho Chehab return result; 867786baecfSMauro Carvalho Chehab result = usb_set_interface(dec->udev, 0, 8); 868786baecfSMauro Carvalho Chehab break; 869786baecfSMauro Carvalho Chehab case TTUSB_DEC_INTERFACE_OUT: 870786baecfSMauro Carvalho Chehab result = usb_set_interface(dec->udev, 0, 1); 871786baecfSMauro Carvalho Chehab break; 872786baecfSMauro Carvalho Chehab } 873786baecfSMauro Carvalho Chehab 874786baecfSMauro Carvalho Chehab if (result) 875786baecfSMauro Carvalho Chehab return result; 876786baecfSMauro Carvalho Chehab 877786baecfSMauro Carvalho Chehab dec->interface = interface; 878786baecfSMauro Carvalho Chehab } 879786baecfSMauro Carvalho Chehab 880786baecfSMauro Carvalho Chehab return 0; 881786baecfSMauro Carvalho Chehab } 882786baecfSMauro Carvalho Chehab 883786baecfSMauro Carvalho Chehab static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) 884786baecfSMauro Carvalho Chehab { 885786baecfSMauro Carvalho Chehab int i, result; 886786baecfSMauro Carvalho Chehab 887786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 888786baecfSMauro Carvalho Chehab 889786baecfSMauro Carvalho Chehab if (mutex_lock_interruptible(&dec->iso_mutex)) 890786baecfSMauro Carvalho Chehab return -EAGAIN; 891786baecfSMauro Carvalho Chehab 892786baecfSMauro Carvalho Chehab if (!dec->iso_stream_count) { 893786baecfSMauro Carvalho Chehab ttusb_dec_setup_urbs(dec); 894786baecfSMauro Carvalho Chehab 895786baecfSMauro Carvalho Chehab dec->packet_state = 0; 896786baecfSMauro Carvalho Chehab dec->v_pes_postbytes = 0; 897786baecfSMauro Carvalho Chehab dec->next_packet_id = 0; 898786baecfSMauro Carvalho Chehab 899786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) { 900786baecfSMauro Carvalho Chehab if ((result = usb_submit_urb(dec->iso_urb[i], 901786baecfSMauro Carvalho Chehab GFP_ATOMIC))) { 902786baecfSMauro Carvalho Chehab printk("%s: failed urb submission %d: " 903786baecfSMauro Carvalho Chehab "error %d\n", __func__, i, result); 904786baecfSMauro Carvalho Chehab 905786baecfSMauro Carvalho Chehab while (i) { 906786baecfSMauro Carvalho Chehab usb_kill_urb(dec->iso_urb[i - 1]); 907786baecfSMauro Carvalho Chehab i--; 908786baecfSMauro Carvalho Chehab } 909786baecfSMauro Carvalho Chehab 910786baecfSMauro Carvalho Chehab mutex_unlock(&dec->iso_mutex); 911786baecfSMauro Carvalho Chehab return result; 912786baecfSMauro Carvalho Chehab } 913786baecfSMauro Carvalho Chehab } 914786baecfSMauro Carvalho Chehab } 915786baecfSMauro Carvalho Chehab 916786baecfSMauro Carvalho Chehab dec->iso_stream_count++; 917786baecfSMauro Carvalho Chehab 918786baecfSMauro Carvalho Chehab mutex_unlock(&dec->iso_mutex); 919786baecfSMauro Carvalho Chehab 920786baecfSMauro Carvalho Chehab return 0; 921786baecfSMauro Carvalho Chehab } 922786baecfSMauro Carvalho Chehab 923786baecfSMauro Carvalho Chehab static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) 924786baecfSMauro Carvalho Chehab { 925786baecfSMauro Carvalho Chehab struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 926786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = dvbdmx->priv; 927786baecfSMauro Carvalho Chehab u8 b0[] = { 0x05 }; 928786baecfSMauro Carvalho Chehab int result = 0; 929786baecfSMauro Carvalho Chehab 930786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 931786baecfSMauro Carvalho Chehab 932786baecfSMauro Carvalho Chehab dprintk(" ts_type:"); 933786baecfSMauro Carvalho Chehab 934786baecfSMauro Carvalho Chehab if (dvbdmxfeed->ts_type & TS_DECODER) 935786baecfSMauro Carvalho Chehab dprintk(" TS_DECODER"); 936786baecfSMauro Carvalho Chehab 937786baecfSMauro Carvalho Chehab if (dvbdmxfeed->ts_type & TS_PACKET) 938786baecfSMauro Carvalho Chehab dprintk(" TS_PACKET"); 939786baecfSMauro Carvalho Chehab 940786baecfSMauro Carvalho Chehab if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) 941786baecfSMauro Carvalho Chehab dprintk(" TS_PAYLOAD_ONLY"); 942786baecfSMauro Carvalho Chehab 943786baecfSMauro Carvalho Chehab dprintk("\n"); 944786baecfSMauro Carvalho Chehab 945786baecfSMauro Carvalho Chehab switch (dvbdmxfeed->pes_type) { 946786baecfSMauro Carvalho Chehab 947fde04ab9SMauro Carvalho Chehab case DMX_PES_VIDEO: 948fde04ab9SMauro Carvalho Chehab dprintk(" pes_type: DMX_PES_VIDEO\n"); 949786baecfSMauro Carvalho Chehab dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid; 950786baecfSMauro Carvalho Chehab dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid; 951786baecfSMauro Carvalho Chehab dec->video_filter = dvbdmxfeed->filter; 952786baecfSMauro Carvalho Chehab ttusb_dec_set_pids(dec); 953786baecfSMauro Carvalho Chehab break; 954786baecfSMauro Carvalho Chehab 955fde04ab9SMauro Carvalho Chehab case DMX_PES_AUDIO: 956fde04ab9SMauro Carvalho Chehab dprintk(" pes_type: DMX_PES_AUDIO\n"); 957786baecfSMauro Carvalho Chehab dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid; 958786baecfSMauro Carvalho Chehab dec->audio_filter = dvbdmxfeed->filter; 959786baecfSMauro Carvalho Chehab ttusb_dec_set_pids(dec); 960786baecfSMauro Carvalho Chehab break; 961786baecfSMauro Carvalho Chehab 962fde04ab9SMauro Carvalho Chehab case DMX_PES_TELETEXT: 963786baecfSMauro Carvalho Chehab dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; 964fde04ab9SMauro Carvalho Chehab dprintk(" pes_type: DMX_PES_TELETEXT(not supported)\n"); 965786baecfSMauro Carvalho Chehab return -ENOSYS; 966786baecfSMauro Carvalho Chehab 967fde04ab9SMauro Carvalho Chehab case DMX_PES_PCR: 968fde04ab9SMauro Carvalho Chehab dprintk(" pes_type: DMX_PES_PCR\n"); 969786baecfSMauro Carvalho Chehab dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid; 970786baecfSMauro Carvalho Chehab ttusb_dec_set_pids(dec); 971786baecfSMauro Carvalho Chehab break; 972786baecfSMauro Carvalho Chehab 973fde04ab9SMauro Carvalho Chehab case DMX_PES_OTHER: 974fde04ab9SMauro Carvalho Chehab dprintk(" pes_type: DMX_PES_OTHER(not supported)\n"); 975786baecfSMauro Carvalho Chehab return -ENOSYS; 976786baecfSMauro Carvalho Chehab 977786baecfSMauro Carvalho Chehab default: 978786baecfSMauro Carvalho Chehab dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); 979786baecfSMauro Carvalho Chehab return -EINVAL; 980786baecfSMauro Carvalho Chehab 981786baecfSMauro Carvalho Chehab } 982786baecfSMauro Carvalho Chehab 983786baecfSMauro Carvalho Chehab result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL); 984786baecfSMauro Carvalho Chehab if (result) 985786baecfSMauro Carvalho Chehab return result; 986786baecfSMauro Carvalho Chehab 987786baecfSMauro Carvalho Chehab dec->pva_stream_count++; 988786baecfSMauro Carvalho Chehab return ttusb_dec_start_iso_xfer(dec); 989786baecfSMauro Carvalho Chehab } 990786baecfSMauro Carvalho Chehab 991786baecfSMauro Carvalho Chehab static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed) 992786baecfSMauro Carvalho Chehab { 993786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = dvbdmxfeed->demux->priv; 994786baecfSMauro Carvalho Chehab u8 b0[] = { 0x00, 0x00, 0x00, 0x01, 995786baecfSMauro Carvalho Chehab 0x00, 0x00, 0x00, 0x00, 996786baecfSMauro Carvalho Chehab 0x00, 0x00, 0x00, 0x00, 997786baecfSMauro Carvalho Chehab 0x00, 0x00, 0x00, 0x00, 998786baecfSMauro Carvalho Chehab 0x00, 0xff, 0x00, 0x00, 999786baecfSMauro Carvalho Chehab 0x00, 0x00, 0x00, 0x00, 1000786baecfSMauro Carvalho Chehab 0x00, 0x00, 0x00, 0x00, 1001786baecfSMauro Carvalho Chehab 0x00 }; 1002786baecfSMauro Carvalho Chehab __be16 pid; 1003786baecfSMauro Carvalho Chehab u8 c[COMMAND_PACKET_SIZE]; 1004786baecfSMauro Carvalho Chehab int c_length; 1005786baecfSMauro Carvalho Chehab int result; 1006786baecfSMauro Carvalho Chehab struct filter_info *finfo; 1007786baecfSMauro Carvalho Chehab unsigned long flags; 1008786baecfSMauro Carvalho Chehab u8 x = 1; 1009786baecfSMauro Carvalho Chehab 1010786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1011786baecfSMauro Carvalho Chehab 1012786baecfSMauro Carvalho Chehab pid = htons(dvbdmxfeed->pid); 1013786baecfSMauro Carvalho Chehab memcpy(&b0[0], &pid, 2); 1014786baecfSMauro Carvalho Chehab memcpy(&b0[4], &x, 1); 1015786baecfSMauro Carvalho Chehab memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1); 1016786baecfSMauro Carvalho Chehab 1017786baecfSMauro Carvalho Chehab result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0, 1018786baecfSMauro Carvalho Chehab &c_length, c); 1019786baecfSMauro Carvalho Chehab 1020786baecfSMauro Carvalho Chehab if (!result) { 1021786baecfSMauro Carvalho Chehab if (c_length == 2) { 1022786baecfSMauro Carvalho Chehab if (!(finfo = kmalloc(sizeof(struct filter_info), 1023786baecfSMauro Carvalho Chehab GFP_ATOMIC))) 1024786baecfSMauro Carvalho Chehab return -ENOMEM; 1025786baecfSMauro Carvalho Chehab 1026786baecfSMauro Carvalho Chehab finfo->stream_id = c[1]; 1027786baecfSMauro Carvalho Chehab finfo->filter = dvbdmxfeed->filter; 1028786baecfSMauro Carvalho Chehab 1029786baecfSMauro Carvalho Chehab spin_lock_irqsave(&dec->filter_info_list_lock, flags); 1030786baecfSMauro Carvalho Chehab list_add_tail(&finfo->filter_info_list, 1031786baecfSMauro Carvalho Chehab &dec->filter_info_list); 1032786baecfSMauro Carvalho Chehab spin_unlock_irqrestore(&dec->filter_info_list_lock, 1033786baecfSMauro Carvalho Chehab flags); 1034786baecfSMauro Carvalho Chehab 1035786baecfSMauro Carvalho Chehab dvbdmxfeed->priv = finfo; 1036786baecfSMauro Carvalho Chehab 1037786baecfSMauro Carvalho Chehab dec->filter_stream_count++; 1038786baecfSMauro Carvalho Chehab return ttusb_dec_start_iso_xfer(dec); 1039786baecfSMauro Carvalho Chehab } 1040786baecfSMauro Carvalho Chehab 1041786baecfSMauro Carvalho Chehab return -EAGAIN; 1042786baecfSMauro Carvalho Chehab } else 1043786baecfSMauro Carvalho Chehab return result; 1044786baecfSMauro Carvalho Chehab } 1045786baecfSMauro Carvalho Chehab 1046786baecfSMauro Carvalho Chehab static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed) 1047786baecfSMauro Carvalho Chehab { 1048786baecfSMauro Carvalho Chehab struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 1049786baecfSMauro Carvalho Chehab 1050786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1051786baecfSMauro Carvalho Chehab 1052786baecfSMauro Carvalho Chehab if (!dvbdmx->dmx.frontend) 1053786baecfSMauro Carvalho Chehab return -EINVAL; 1054786baecfSMauro Carvalho Chehab 1055786baecfSMauro Carvalho Chehab dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid); 1056786baecfSMauro Carvalho Chehab 1057786baecfSMauro Carvalho Chehab switch (dvbdmxfeed->type) { 1058786baecfSMauro Carvalho Chehab 1059786baecfSMauro Carvalho Chehab case DMX_TYPE_TS: 1060786baecfSMauro Carvalho Chehab return ttusb_dec_start_ts_feed(dvbdmxfeed); 1061786baecfSMauro Carvalho Chehab break; 1062786baecfSMauro Carvalho Chehab 1063786baecfSMauro Carvalho Chehab case DMX_TYPE_SEC: 1064786baecfSMauro Carvalho Chehab return ttusb_dec_start_sec_feed(dvbdmxfeed); 1065786baecfSMauro Carvalho Chehab break; 1066786baecfSMauro Carvalho Chehab 1067786baecfSMauro Carvalho Chehab default: 1068786baecfSMauro Carvalho Chehab dprintk(" type: unknown (%d)\n", dvbdmxfeed->type); 1069786baecfSMauro Carvalho Chehab return -EINVAL; 1070786baecfSMauro Carvalho Chehab 1071786baecfSMauro Carvalho Chehab } 1072786baecfSMauro Carvalho Chehab } 1073786baecfSMauro Carvalho Chehab 1074786baecfSMauro Carvalho Chehab static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed) 1075786baecfSMauro Carvalho Chehab { 1076786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = dvbdmxfeed->demux->priv; 1077786baecfSMauro Carvalho Chehab u8 b0[] = { 0x00 }; 1078786baecfSMauro Carvalho Chehab 1079786baecfSMauro Carvalho Chehab ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL); 1080786baecfSMauro Carvalho Chehab 1081786baecfSMauro Carvalho Chehab dec->pva_stream_count--; 1082786baecfSMauro Carvalho Chehab 1083786baecfSMauro Carvalho Chehab ttusb_dec_stop_iso_xfer(dec); 1084786baecfSMauro Carvalho Chehab 1085786baecfSMauro Carvalho Chehab return 0; 1086786baecfSMauro Carvalho Chehab } 1087786baecfSMauro Carvalho Chehab 1088786baecfSMauro Carvalho Chehab static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed) 1089786baecfSMauro Carvalho Chehab { 1090786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = dvbdmxfeed->demux->priv; 1091786baecfSMauro Carvalho Chehab u8 b0[] = { 0x00, 0x00 }; 1092786baecfSMauro Carvalho Chehab struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv; 1093786baecfSMauro Carvalho Chehab unsigned long flags; 1094786baecfSMauro Carvalho Chehab 1095786baecfSMauro Carvalho Chehab b0[1] = finfo->stream_id; 1096786baecfSMauro Carvalho Chehab spin_lock_irqsave(&dec->filter_info_list_lock, flags); 1097786baecfSMauro Carvalho Chehab list_del(&finfo->filter_info_list); 1098786baecfSMauro Carvalho Chehab spin_unlock_irqrestore(&dec->filter_info_list_lock, flags); 1099786baecfSMauro Carvalho Chehab kfree(finfo); 1100786baecfSMauro Carvalho Chehab ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL); 1101786baecfSMauro Carvalho Chehab 1102786baecfSMauro Carvalho Chehab dec->filter_stream_count--; 1103786baecfSMauro Carvalho Chehab 1104786baecfSMauro Carvalho Chehab ttusb_dec_stop_iso_xfer(dec); 1105786baecfSMauro Carvalho Chehab 1106786baecfSMauro Carvalho Chehab return 0; 1107786baecfSMauro Carvalho Chehab } 1108786baecfSMauro Carvalho Chehab 1109786baecfSMauro Carvalho Chehab static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed) 1110786baecfSMauro Carvalho Chehab { 1111786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1112786baecfSMauro Carvalho Chehab 1113786baecfSMauro Carvalho Chehab switch (dvbdmxfeed->type) { 1114786baecfSMauro Carvalho Chehab case DMX_TYPE_TS: 1115786baecfSMauro Carvalho Chehab return ttusb_dec_stop_ts_feed(dvbdmxfeed); 1116786baecfSMauro Carvalho Chehab break; 1117786baecfSMauro Carvalho Chehab 1118786baecfSMauro Carvalho Chehab case DMX_TYPE_SEC: 1119786baecfSMauro Carvalho Chehab return ttusb_dec_stop_sec_feed(dvbdmxfeed); 1120786baecfSMauro Carvalho Chehab break; 1121786baecfSMauro Carvalho Chehab } 1122786baecfSMauro Carvalho Chehab 1123786baecfSMauro Carvalho Chehab return 0; 1124786baecfSMauro Carvalho Chehab } 1125786baecfSMauro Carvalho Chehab 1126786baecfSMauro Carvalho Chehab static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec) 1127786baecfSMauro Carvalho Chehab { 1128786baecfSMauro Carvalho Chehab int i; 1129786baecfSMauro Carvalho Chehab 1130786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1131786baecfSMauro Carvalho Chehab 1132786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) 1133786baecfSMauro Carvalho Chehab usb_free_urb(dec->iso_urb[i]); 1134786baecfSMauro Carvalho Chehab 1135786baecfSMauro Carvalho Chehab pci_free_consistent(NULL, 1136786baecfSMauro Carvalho Chehab ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * 1137786baecfSMauro Carvalho Chehab ISO_BUF_COUNT), 1138786baecfSMauro Carvalho Chehab dec->iso_buffer, dec->iso_dma_handle); 1139786baecfSMauro Carvalho Chehab } 1140786baecfSMauro Carvalho Chehab 1141786baecfSMauro Carvalho Chehab static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec) 1142786baecfSMauro Carvalho Chehab { 1143786baecfSMauro Carvalho Chehab int i; 1144786baecfSMauro Carvalho Chehab 1145786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1146786baecfSMauro Carvalho Chehab 11476850aeabSJoe Perches dec->iso_buffer = pci_zalloc_consistent(NULL, 11486850aeabSJoe Perches ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT), 1149786baecfSMauro Carvalho Chehab &dec->iso_dma_handle); 1150786baecfSMauro Carvalho Chehab 1151786baecfSMauro Carvalho Chehab if (!dec->iso_buffer) { 1152786baecfSMauro Carvalho Chehab dprintk("%s: pci_alloc_consistent - not enough memory\n", 1153786baecfSMauro Carvalho Chehab __func__); 1154786baecfSMauro Carvalho Chehab return -ENOMEM; 1155786baecfSMauro Carvalho Chehab } 1156786baecfSMauro Carvalho Chehab 1157786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) { 1158786baecfSMauro Carvalho Chehab struct urb *urb; 1159786baecfSMauro Carvalho Chehab 1160786baecfSMauro Carvalho Chehab if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) { 1161786baecfSMauro Carvalho Chehab ttusb_dec_free_iso_urbs(dec); 1162786baecfSMauro Carvalho Chehab return -ENOMEM; 1163786baecfSMauro Carvalho Chehab } 1164786baecfSMauro Carvalho Chehab 1165786baecfSMauro Carvalho Chehab dec->iso_urb[i] = urb; 1166786baecfSMauro Carvalho Chehab } 1167786baecfSMauro Carvalho Chehab 1168786baecfSMauro Carvalho Chehab ttusb_dec_setup_urbs(dec); 1169786baecfSMauro Carvalho Chehab 1170786baecfSMauro Carvalho Chehab return 0; 1171786baecfSMauro Carvalho Chehab } 1172786baecfSMauro Carvalho Chehab 1173786baecfSMauro Carvalho Chehab static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) 1174786baecfSMauro Carvalho Chehab { 1175786baecfSMauro Carvalho Chehab spin_lock_init(&dec->urb_frame_list_lock); 1176786baecfSMauro Carvalho Chehab INIT_LIST_HEAD(&dec->urb_frame_list); 1177786baecfSMauro Carvalho Chehab tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list, 1178786baecfSMauro Carvalho Chehab (unsigned long)dec); 1179786baecfSMauro Carvalho Chehab } 1180786baecfSMauro Carvalho Chehab 1181786baecfSMauro Carvalho Chehab static int ttusb_init_rc( struct ttusb_dec *dec) 1182786baecfSMauro Carvalho Chehab { 1183786baecfSMauro Carvalho Chehab struct input_dev *input_dev; 1184786baecfSMauro Carvalho Chehab u8 b[] = { 0x00, 0x01 }; 1185786baecfSMauro Carvalho Chehab int i; 1186786baecfSMauro Carvalho Chehab int err; 1187786baecfSMauro Carvalho Chehab 1188786baecfSMauro Carvalho Chehab usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys)); 1189786baecfSMauro Carvalho Chehab strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys)); 1190786baecfSMauro Carvalho Chehab 1191786baecfSMauro Carvalho Chehab input_dev = input_allocate_device(); 1192786baecfSMauro Carvalho Chehab if (!input_dev) 1193786baecfSMauro Carvalho Chehab return -ENOMEM; 1194786baecfSMauro Carvalho Chehab 1195786baecfSMauro Carvalho Chehab input_dev->name = "ttusb_dec remote control"; 1196786baecfSMauro Carvalho Chehab input_dev->phys = dec->rc_phys; 1197786baecfSMauro Carvalho Chehab input_dev->evbit[0] = BIT_MASK(EV_KEY); 1198786baecfSMauro Carvalho Chehab input_dev->keycodesize = sizeof(u16); 1199786baecfSMauro Carvalho Chehab input_dev->keycodemax = 0x1a; 1200786baecfSMauro Carvalho Chehab input_dev->keycode = rc_keys; 1201786baecfSMauro Carvalho Chehab 1202786baecfSMauro Carvalho Chehab for (i = 0; i < ARRAY_SIZE(rc_keys); i++) 1203786baecfSMauro Carvalho Chehab set_bit(rc_keys[i], input_dev->keybit); 1204786baecfSMauro Carvalho Chehab 1205786baecfSMauro Carvalho Chehab err = input_register_device(input_dev); 1206786baecfSMauro Carvalho Chehab if (err) { 1207786baecfSMauro Carvalho Chehab input_free_device(input_dev); 1208786baecfSMauro Carvalho Chehab return err; 1209786baecfSMauro Carvalho Chehab } 1210786baecfSMauro Carvalho Chehab 1211786baecfSMauro Carvalho Chehab dec->rc_input_dev = input_dev; 1212786baecfSMauro Carvalho Chehab if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) 1213786baecfSMauro Carvalho Chehab printk("%s: usb_submit_urb failed\n",__func__); 1214786baecfSMauro Carvalho Chehab /* enable irq pipe */ 1215786baecfSMauro Carvalho Chehab ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); 1216786baecfSMauro Carvalho Chehab 1217786baecfSMauro Carvalho Chehab return 0; 1218786baecfSMauro Carvalho Chehab } 1219786baecfSMauro Carvalho Chehab 1220786baecfSMauro Carvalho Chehab static void ttusb_dec_init_v_pes(struct ttusb_dec *dec) 1221786baecfSMauro Carvalho Chehab { 1222786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1223786baecfSMauro Carvalho Chehab 1224786baecfSMauro Carvalho Chehab dec->v_pes[0] = 0x00; 1225786baecfSMauro Carvalho Chehab dec->v_pes[1] = 0x00; 1226786baecfSMauro Carvalho Chehab dec->v_pes[2] = 0x01; 1227786baecfSMauro Carvalho Chehab dec->v_pes[3] = 0xe0; 1228786baecfSMauro Carvalho Chehab } 1229786baecfSMauro Carvalho Chehab 1230786baecfSMauro Carvalho Chehab static int ttusb_dec_init_usb(struct ttusb_dec *dec) 1231786baecfSMauro Carvalho Chehab { 1232cf732b5fSAlexey Khoroshilov int result; 1233cf732b5fSAlexey Khoroshilov 1234786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1235786baecfSMauro Carvalho Chehab 1236786baecfSMauro Carvalho Chehab mutex_init(&dec->usb_mutex); 1237786baecfSMauro Carvalho Chehab mutex_init(&dec->iso_mutex); 1238786baecfSMauro Carvalho Chehab 1239786baecfSMauro Carvalho Chehab dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE); 1240786baecfSMauro Carvalho Chehab dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE); 1241786baecfSMauro Carvalho Chehab dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE); 1242786baecfSMauro Carvalho Chehab dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE); 1243786baecfSMauro Carvalho Chehab dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE); 1244786baecfSMauro Carvalho Chehab 1245786baecfSMauro Carvalho Chehab if(enable_rc) { 1246786baecfSMauro Carvalho Chehab dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL); 1247786baecfSMauro Carvalho Chehab if(!dec->irq_urb) { 1248786baecfSMauro Carvalho Chehab return -ENOMEM; 1249786baecfSMauro Carvalho Chehab } 1250786baecfSMauro Carvalho Chehab dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE, 1251cf732b5fSAlexey Khoroshilov GFP_KERNEL, &dec->irq_dma_handle); 1252786baecfSMauro Carvalho Chehab if(!dec->irq_buffer) { 1253786baecfSMauro Carvalho Chehab usb_free_urb(dec->irq_urb); 1254786baecfSMauro Carvalho Chehab return -ENOMEM; 1255786baecfSMauro Carvalho Chehab } 1256786baecfSMauro Carvalho Chehab usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe, 1257786baecfSMauro Carvalho Chehab dec->irq_buffer, IRQ_PACKET_SIZE, 1258786baecfSMauro Carvalho Chehab ttusb_dec_handle_irq, dec, 1); 1259786baecfSMauro Carvalho Chehab dec->irq_urb->transfer_dma = dec->irq_dma_handle; 1260786baecfSMauro Carvalho Chehab dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1261786baecfSMauro Carvalho Chehab } 1262786baecfSMauro Carvalho Chehab 1263cf732b5fSAlexey Khoroshilov result = ttusb_dec_alloc_iso_urbs(dec); 1264cf732b5fSAlexey Khoroshilov if (result) { 1265cf732b5fSAlexey Khoroshilov usb_free_urb(dec->irq_urb); 1266cf732b5fSAlexey Khoroshilov usb_free_coherent(dec->udev, IRQ_PACKET_SIZE, 1267cf732b5fSAlexey Khoroshilov dec->irq_buffer, dec->irq_dma_handle); 1268cf732b5fSAlexey Khoroshilov } 1269cf732b5fSAlexey Khoroshilov return result; 1270786baecfSMauro Carvalho Chehab } 1271786baecfSMauro Carvalho Chehab 1272786baecfSMauro Carvalho Chehab static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) 1273786baecfSMauro Carvalho Chehab { 1274786baecfSMauro Carvalho Chehab int i, j, actual_len, result, size, trans_count; 1275786baecfSMauro Carvalho Chehab u8 b0[] = { 0x00, 0x00, 0x00, 0x00, 1276786baecfSMauro Carvalho Chehab 0x00, 0x00, 0x00, 0x00, 1277786baecfSMauro Carvalho Chehab 0x61, 0x00 }; 1278786baecfSMauro Carvalho Chehab u8 b1[] = { 0x61 }; 1279786baecfSMauro Carvalho Chehab u8 *b; 1280786baecfSMauro Carvalho Chehab char idstring[21]; 1281786baecfSMauro Carvalho Chehab const u8 *firmware = NULL; 1282786baecfSMauro Carvalho Chehab size_t firmware_size = 0; 1283786baecfSMauro Carvalho Chehab u16 firmware_csum = 0; 1284786baecfSMauro Carvalho Chehab __be16 firmware_csum_ns; 1285786baecfSMauro Carvalho Chehab __be32 firmware_size_nl; 1286786baecfSMauro Carvalho Chehab u32 crc32_csum, crc32_check; 1287786baecfSMauro Carvalho Chehab __be32 tmp; 1288786baecfSMauro Carvalho Chehab const struct firmware *fw_entry = NULL; 1289786baecfSMauro Carvalho Chehab 1290786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1291786baecfSMauro Carvalho Chehab 1292cf732b5fSAlexey Khoroshilov result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev); 1293cf732b5fSAlexey Khoroshilov if (result) { 1294786baecfSMauro Carvalho Chehab printk(KERN_ERR "%s: Firmware (%s) unavailable.\n", 1295786baecfSMauro Carvalho Chehab __func__, dec->firmware_name); 1296cf732b5fSAlexey Khoroshilov return result; 1297786baecfSMauro Carvalho Chehab } 1298786baecfSMauro Carvalho Chehab 1299786baecfSMauro Carvalho Chehab firmware = fw_entry->data; 1300786baecfSMauro Carvalho Chehab firmware_size = fw_entry->size; 1301786baecfSMauro Carvalho Chehab 1302786baecfSMauro Carvalho Chehab if (firmware_size < 60) { 1303786baecfSMauro Carvalho Chehab printk("%s: firmware size too small for DSP code (%zu < 60).\n", 1304786baecfSMauro Carvalho Chehab __func__, firmware_size); 1305786baecfSMauro Carvalho Chehab release_firmware(fw_entry); 1306cf732b5fSAlexey Khoroshilov return -ENOENT; 1307786baecfSMauro Carvalho Chehab } 1308786baecfSMauro Carvalho Chehab 1309786baecfSMauro Carvalho Chehab /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored 1310786baecfSMauro Carvalho Chehab at offset 56 of file, so use it to check if the firmware file is 1311786baecfSMauro Carvalho Chehab valid. */ 1312786baecfSMauro Carvalho Chehab crc32_csum = crc32(~0L, firmware, 56) ^ ~0L; 1313786baecfSMauro Carvalho Chehab memcpy(&tmp, &firmware[56], 4); 1314786baecfSMauro Carvalho Chehab crc32_check = ntohl(tmp); 1315786baecfSMauro Carvalho Chehab if (crc32_csum != crc32_check) { 1316786baecfSMauro Carvalho Chehab printk("%s: crc32 check of DSP code failed (calculated " 1317786baecfSMauro Carvalho Chehab "0x%08x != 0x%08x in file), file invalid.\n", 1318786baecfSMauro Carvalho Chehab __func__, crc32_csum, crc32_check); 1319786baecfSMauro Carvalho Chehab release_firmware(fw_entry); 1320cf732b5fSAlexey Khoroshilov return -ENOENT; 1321786baecfSMauro Carvalho Chehab } 1322786baecfSMauro Carvalho Chehab memcpy(idstring, &firmware[36], 20); 1323786baecfSMauro Carvalho Chehab idstring[20] = '\0'; 1324786baecfSMauro Carvalho Chehab printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring); 1325786baecfSMauro Carvalho Chehab 1326786baecfSMauro Carvalho Chehab firmware_size_nl = htonl(firmware_size); 1327786baecfSMauro Carvalho Chehab memcpy(b0, &firmware_size_nl, 4); 1328786baecfSMauro Carvalho Chehab firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0; 1329786baecfSMauro Carvalho Chehab firmware_csum_ns = htons(firmware_csum); 1330786baecfSMauro Carvalho Chehab memcpy(&b0[6], &firmware_csum_ns, 2); 1331786baecfSMauro Carvalho Chehab 1332786baecfSMauro Carvalho Chehab result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL); 1333786baecfSMauro Carvalho Chehab 1334786baecfSMauro Carvalho Chehab if (result) { 1335786baecfSMauro Carvalho Chehab release_firmware(fw_entry); 1336786baecfSMauro Carvalho Chehab return result; 1337786baecfSMauro Carvalho Chehab } 1338786baecfSMauro Carvalho Chehab 1339786baecfSMauro Carvalho Chehab trans_count = 0; 1340786baecfSMauro Carvalho Chehab j = 0; 1341786baecfSMauro Carvalho Chehab 1342786baecfSMauro Carvalho Chehab b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL); 1343786baecfSMauro Carvalho Chehab if (b == NULL) { 1344786baecfSMauro Carvalho Chehab release_firmware(fw_entry); 1345786baecfSMauro Carvalho Chehab return -ENOMEM; 1346786baecfSMauro Carvalho Chehab } 1347786baecfSMauro Carvalho Chehab 1348786baecfSMauro Carvalho Chehab for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) { 1349786baecfSMauro Carvalho Chehab size = firmware_size - i; 1350786baecfSMauro Carvalho Chehab if (size > COMMAND_PACKET_SIZE) 1351786baecfSMauro Carvalho Chehab size = COMMAND_PACKET_SIZE; 1352786baecfSMauro Carvalho Chehab 1353786baecfSMauro Carvalho Chehab b[j + 0] = 0xaa; 1354786baecfSMauro Carvalho Chehab b[j + 1] = trans_count++; 1355786baecfSMauro Carvalho Chehab b[j + 2] = 0xf0; 1356786baecfSMauro Carvalho Chehab b[j + 3] = size; 1357786baecfSMauro Carvalho Chehab memcpy(&b[j + 4], &firmware[i], size); 1358786baecfSMauro Carvalho Chehab 1359786baecfSMauro Carvalho Chehab j += COMMAND_PACKET_SIZE + 4; 1360786baecfSMauro Carvalho Chehab 1361786baecfSMauro Carvalho Chehab if (j >= ARM_PACKET_SIZE) { 1362786baecfSMauro Carvalho Chehab result = usb_bulk_msg(dec->udev, dec->command_pipe, b, 1363786baecfSMauro Carvalho Chehab ARM_PACKET_SIZE, &actual_len, 1364786baecfSMauro Carvalho Chehab 100); 1365786baecfSMauro Carvalho Chehab j = 0; 1366786baecfSMauro Carvalho Chehab } else if (size < COMMAND_PACKET_SIZE) { 1367786baecfSMauro Carvalho Chehab result = usb_bulk_msg(dec->udev, dec->command_pipe, b, 1368786baecfSMauro Carvalho Chehab j - COMMAND_PACKET_SIZE + size, 1369786baecfSMauro Carvalho Chehab &actual_len, 100); 1370786baecfSMauro Carvalho Chehab } 1371786baecfSMauro Carvalho Chehab } 1372786baecfSMauro Carvalho Chehab 1373786baecfSMauro Carvalho Chehab result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL); 1374786baecfSMauro Carvalho Chehab 1375786baecfSMauro Carvalho Chehab release_firmware(fw_entry); 1376786baecfSMauro Carvalho Chehab kfree(b); 1377786baecfSMauro Carvalho Chehab 1378786baecfSMauro Carvalho Chehab return result; 1379786baecfSMauro Carvalho Chehab } 1380786baecfSMauro Carvalho Chehab 1381786baecfSMauro Carvalho Chehab static int ttusb_dec_init_stb(struct ttusb_dec *dec) 1382786baecfSMauro Carvalho Chehab { 1383786baecfSMauro Carvalho Chehab int result; 1384786baecfSMauro Carvalho Chehab unsigned int mode = 0, model = 0, version = 0; 1385786baecfSMauro Carvalho Chehab 1386786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1387786baecfSMauro Carvalho Chehab 1388786baecfSMauro Carvalho Chehab result = ttusb_dec_get_stb_state(dec, &mode, &model, &version); 1389cf732b5fSAlexey Khoroshilov if (result) 1390cf732b5fSAlexey Khoroshilov return result; 1391786baecfSMauro Carvalho Chehab 1392786baecfSMauro Carvalho Chehab if (!mode) { 1393786baecfSMauro Carvalho Chehab if (version == 0xABCDEFAB) 1394786baecfSMauro Carvalho Chehab printk(KERN_INFO "ttusb_dec: no version " 1395786baecfSMauro Carvalho Chehab "info in Firmware\n"); 1396786baecfSMauro Carvalho Chehab else 1397786baecfSMauro Carvalho Chehab printk(KERN_INFO "ttusb_dec: Firmware " 1398786baecfSMauro Carvalho Chehab "%x.%02x%c%c\n", 1399786baecfSMauro Carvalho Chehab version >> 24, (version >> 16) & 0xff, 1400786baecfSMauro Carvalho Chehab (version >> 8) & 0xff, version & 0xff); 1401786baecfSMauro Carvalho Chehab 1402786baecfSMauro Carvalho Chehab result = ttusb_dec_boot_dsp(dec); 1403786baecfSMauro Carvalho Chehab if (result) 1404786baecfSMauro Carvalho Chehab return result; 1405786baecfSMauro Carvalho Chehab } else { 1406786baecfSMauro Carvalho Chehab /* We can't trust the USB IDs that some firmwares 1407786baecfSMauro Carvalho Chehab give the box */ 1408786baecfSMauro Carvalho Chehab switch (model) { 1409786baecfSMauro Carvalho Chehab case 0x00070001: 1410786baecfSMauro Carvalho Chehab case 0x00070008: 1411786baecfSMauro Carvalho Chehab case 0x0007000c: 1412786baecfSMauro Carvalho Chehab ttusb_dec_set_model(dec, TTUSB_DEC3000S); 1413786baecfSMauro Carvalho Chehab break; 1414786baecfSMauro Carvalho Chehab case 0x00070009: 1415786baecfSMauro Carvalho Chehab case 0x00070013: 1416786baecfSMauro Carvalho Chehab ttusb_dec_set_model(dec, TTUSB_DEC2000T); 1417786baecfSMauro Carvalho Chehab break; 1418786baecfSMauro Carvalho Chehab case 0x00070011: 1419786baecfSMauro Carvalho Chehab ttusb_dec_set_model(dec, TTUSB_DEC2540T); 1420786baecfSMauro Carvalho Chehab break; 1421786baecfSMauro Carvalho Chehab default: 1422786baecfSMauro Carvalho Chehab printk(KERN_ERR "%s: unknown model returned " 1423786baecfSMauro Carvalho Chehab "by firmware (%08x) - please report\n", 1424786baecfSMauro Carvalho Chehab __func__, model); 1425cf732b5fSAlexey Khoroshilov return -ENOENT; 1426786baecfSMauro Carvalho Chehab } 1427786baecfSMauro Carvalho Chehab if (version >= 0x01770000) 1428786baecfSMauro Carvalho Chehab dec->can_playback = 1; 1429cf732b5fSAlexey Khoroshilov } 1430786baecfSMauro Carvalho Chehab return 0; 1431786baecfSMauro Carvalho Chehab } 1432786baecfSMauro Carvalho Chehab 1433786baecfSMauro Carvalho Chehab static int ttusb_dec_init_dvb(struct ttusb_dec *dec) 1434786baecfSMauro Carvalho Chehab { 1435786baecfSMauro Carvalho Chehab int result; 1436786baecfSMauro Carvalho Chehab 1437786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1438786baecfSMauro Carvalho Chehab 1439786baecfSMauro Carvalho Chehab if ((result = dvb_register_adapter(&dec->adapter, 1440786baecfSMauro Carvalho Chehab dec->model_name, THIS_MODULE, 1441786baecfSMauro Carvalho Chehab &dec->udev->dev, 1442786baecfSMauro Carvalho Chehab adapter_nr)) < 0) { 1443786baecfSMauro Carvalho Chehab printk("%s: dvb_register_adapter failed: error %d\n", 1444786baecfSMauro Carvalho Chehab __func__, result); 1445786baecfSMauro Carvalho Chehab 1446786baecfSMauro Carvalho Chehab return result; 1447786baecfSMauro Carvalho Chehab } 1448786baecfSMauro Carvalho Chehab 1449786baecfSMauro Carvalho Chehab dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; 1450786baecfSMauro Carvalho Chehab 1451786baecfSMauro Carvalho Chehab dec->demux.priv = (void *)dec; 1452786baecfSMauro Carvalho Chehab dec->demux.filternum = 31; 1453786baecfSMauro Carvalho Chehab dec->demux.feednum = 31; 1454786baecfSMauro Carvalho Chehab dec->demux.start_feed = ttusb_dec_start_feed; 1455786baecfSMauro Carvalho Chehab dec->demux.stop_feed = ttusb_dec_stop_feed; 1456786baecfSMauro Carvalho Chehab dec->demux.write_to_decoder = NULL; 1457786baecfSMauro Carvalho Chehab 1458786baecfSMauro Carvalho Chehab if ((result = dvb_dmx_init(&dec->demux)) < 0) { 1459786baecfSMauro Carvalho Chehab printk("%s: dvb_dmx_init failed: error %d\n", __func__, 1460786baecfSMauro Carvalho Chehab result); 1461786baecfSMauro Carvalho Chehab 1462786baecfSMauro Carvalho Chehab dvb_unregister_adapter(&dec->adapter); 1463786baecfSMauro Carvalho Chehab 1464786baecfSMauro Carvalho Chehab return result; 1465786baecfSMauro Carvalho Chehab } 1466786baecfSMauro Carvalho Chehab 1467786baecfSMauro Carvalho Chehab dec->dmxdev.filternum = 32; 1468786baecfSMauro Carvalho Chehab dec->dmxdev.demux = &dec->demux.dmx; 1469786baecfSMauro Carvalho Chehab dec->dmxdev.capabilities = 0; 1470786baecfSMauro Carvalho Chehab 1471786baecfSMauro Carvalho Chehab if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) { 1472786baecfSMauro Carvalho Chehab printk("%s: dvb_dmxdev_init failed: error %d\n", 1473786baecfSMauro Carvalho Chehab __func__, result); 1474786baecfSMauro Carvalho Chehab 1475786baecfSMauro Carvalho Chehab dvb_dmx_release(&dec->demux); 1476786baecfSMauro Carvalho Chehab dvb_unregister_adapter(&dec->adapter); 1477786baecfSMauro Carvalho Chehab 1478786baecfSMauro Carvalho Chehab return result; 1479786baecfSMauro Carvalho Chehab } 1480786baecfSMauro Carvalho Chehab 1481786baecfSMauro Carvalho Chehab dec->frontend.source = DMX_FRONTEND_0; 1482786baecfSMauro Carvalho Chehab 1483786baecfSMauro Carvalho Chehab if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx, 1484786baecfSMauro Carvalho Chehab &dec->frontend)) < 0) { 1485786baecfSMauro Carvalho Chehab printk("%s: dvb_dmx_init failed: error %d\n", __func__, 1486786baecfSMauro Carvalho Chehab result); 1487786baecfSMauro Carvalho Chehab 1488786baecfSMauro Carvalho Chehab dvb_dmxdev_release(&dec->dmxdev); 1489786baecfSMauro Carvalho Chehab dvb_dmx_release(&dec->demux); 1490786baecfSMauro Carvalho Chehab dvb_unregister_adapter(&dec->adapter); 1491786baecfSMauro Carvalho Chehab 1492786baecfSMauro Carvalho Chehab return result; 1493786baecfSMauro Carvalho Chehab } 1494786baecfSMauro Carvalho Chehab 1495786baecfSMauro Carvalho Chehab if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx, 1496786baecfSMauro Carvalho Chehab &dec->frontend)) < 0) { 1497786baecfSMauro Carvalho Chehab printk("%s: dvb_dmx_init failed: error %d\n", __func__, 1498786baecfSMauro Carvalho Chehab result); 1499786baecfSMauro Carvalho Chehab 1500786baecfSMauro Carvalho Chehab dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend); 1501786baecfSMauro Carvalho Chehab dvb_dmxdev_release(&dec->dmxdev); 1502786baecfSMauro Carvalho Chehab dvb_dmx_release(&dec->demux); 1503786baecfSMauro Carvalho Chehab dvb_unregister_adapter(&dec->adapter); 1504786baecfSMauro Carvalho Chehab 1505786baecfSMauro Carvalho Chehab return result; 1506786baecfSMauro Carvalho Chehab } 1507786baecfSMauro Carvalho Chehab 1508786baecfSMauro Carvalho Chehab dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx); 1509786baecfSMauro Carvalho Chehab 1510786baecfSMauro Carvalho Chehab return 0; 1511786baecfSMauro Carvalho Chehab } 1512786baecfSMauro Carvalho Chehab 1513786baecfSMauro Carvalho Chehab static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) 1514786baecfSMauro Carvalho Chehab { 1515786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1516786baecfSMauro Carvalho Chehab 1517786baecfSMauro Carvalho Chehab dvb_net_release(&dec->dvb_net); 1518786baecfSMauro Carvalho Chehab dec->demux.dmx.close(&dec->demux.dmx); 1519786baecfSMauro Carvalho Chehab dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend); 1520786baecfSMauro Carvalho Chehab dvb_dmxdev_release(&dec->dmxdev); 1521786baecfSMauro Carvalho Chehab dvb_dmx_release(&dec->demux); 1522786baecfSMauro Carvalho Chehab if (dec->fe) { 1523786baecfSMauro Carvalho Chehab dvb_unregister_frontend(dec->fe); 1524786baecfSMauro Carvalho Chehab if (dec->fe->ops.release) 1525786baecfSMauro Carvalho Chehab dec->fe->ops.release(dec->fe); 1526786baecfSMauro Carvalho Chehab } 1527786baecfSMauro Carvalho Chehab dvb_unregister_adapter(&dec->adapter); 1528786baecfSMauro Carvalho Chehab } 1529786baecfSMauro Carvalho Chehab 1530786baecfSMauro Carvalho Chehab static void ttusb_dec_exit_rc(struct ttusb_dec *dec) 1531786baecfSMauro Carvalho Chehab { 1532786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1533786baecfSMauro Carvalho Chehab 1534786baecfSMauro Carvalho Chehab if (dec->rc_input_dev) { 1535786baecfSMauro Carvalho Chehab input_unregister_device(dec->rc_input_dev); 1536786baecfSMauro Carvalho Chehab dec->rc_input_dev = NULL; 1537786baecfSMauro Carvalho Chehab } 1538786baecfSMauro Carvalho Chehab } 1539786baecfSMauro Carvalho Chehab 1540786baecfSMauro Carvalho Chehab 1541786baecfSMauro Carvalho Chehab static void ttusb_dec_exit_usb(struct ttusb_dec *dec) 1542786baecfSMauro Carvalho Chehab { 1543786baecfSMauro Carvalho Chehab int i; 1544786baecfSMauro Carvalho Chehab 1545786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1546786baecfSMauro Carvalho Chehab 1547cf732b5fSAlexey Khoroshilov if (enable_rc) { 1548cf732b5fSAlexey Khoroshilov /* we have to check whether the irq URB is already submitted. 1549cf732b5fSAlexey Khoroshilov * As the irq is submitted after the interface is changed, 1550cf732b5fSAlexey Khoroshilov * this is the best method i figured out. 1551cf732b5fSAlexey Khoroshilov * Any others?*/ 1552cf732b5fSAlexey Khoroshilov if (dec->interface == TTUSB_DEC_INTERFACE_IN) 1553cf732b5fSAlexey Khoroshilov usb_kill_urb(dec->irq_urb); 1554cf732b5fSAlexey Khoroshilov 1555cf732b5fSAlexey Khoroshilov usb_free_urb(dec->irq_urb); 1556cf732b5fSAlexey Khoroshilov 1557cf732b5fSAlexey Khoroshilov usb_free_coherent(dec->udev, IRQ_PACKET_SIZE, 1558cf732b5fSAlexey Khoroshilov dec->irq_buffer, dec->irq_dma_handle); 1559cf732b5fSAlexey Khoroshilov } 1560cf732b5fSAlexey Khoroshilov 1561786baecfSMauro Carvalho Chehab dec->iso_stream_count = 0; 1562786baecfSMauro Carvalho Chehab 1563786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) 1564786baecfSMauro Carvalho Chehab usb_kill_urb(dec->iso_urb[i]); 1565786baecfSMauro Carvalho Chehab 1566786baecfSMauro Carvalho Chehab ttusb_dec_free_iso_urbs(dec); 1567786baecfSMauro Carvalho Chehab } 1568786baecfSMauro Carvalho Chehab 1569786baecfSMauro Carvalho Chehab static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec) 1570786baecfSMauro Carvalho Chehab { 1571786baecfSMauro Carvalho Chehab struct list_head *item; 1572786baecfSMauro Carvalho Chehab struct urb_frame *frame; 1573786baecfSMauro Carvalho Chehab 1574786baecfSMauro Carvalho Chehab tasklet_kill(&dec->urb_tasklet); 1575786baecfSMauro Carvalho Chehab 1576786baecfSMauro Carvalho Chehab while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) { 1577786baecfSMauro Carvalho Chehab frame = list_entry(item, struct urb_frame, urb_frame_list); 1578786baecfSMauro Carvalho Chehab list_del(&frame->urb_frame_list); 1579786baecfSMauro Carvalho Chehab kfree(frame); 1580786baecfSMauro Carvalho Chehab } 1581786baecfSMauro Carvalho Chehab } 1582786baecfSMauro Carvalho Chehab 1583786baecfSMauro Carvalho Chehab static void ttusb_dec_init_filters(struct ttusb_dec *dec) 1584786baecfSMauro Carvalho Chehab { 1585786baecfSMauro Carvalho Chehab INIT_LIST_HEAD(&dec->filter_info_list); 1586786baecfSMauro Carvalho Chehab spin_lock_init(&dec->filter_info_list_lock); 1587786baecfSMauro Carvalho Chehab } 1588786baecfSMauro Carvalho Chehab 1589786baecfSMauro Carvalho Chehab static void ttusb_dec_exit_filters(struct ttusb_dec *dec) 1590786baecfSMauro Carvalho Chehab { 1591786baecfSMauro Carvalho Chehab struct list_head *item; 1592786baecfSMauro Carvalho Chehab struct filter_info *finfo; 1593786baecfSMauro Carvalho Chehab 1594786baecfSMauro Carvalho Chehab while ((item = dec->filter_info_list.next) != &dec->filter_info_list) { 1595786baecfSMauro Carvalho Chehab finfo = list_entry(item, struct filter_info, filter_info_list); 1596786baecfSMauro Carvalho Chehab list_del(&finfo->filter_info_list); 1597786baecfSMauro Carvalho Chehab kfree(finfo); 1598786baecfSMauro Carvalho Chehab } 1599786baecfSMauro Carvalho Chehab } 1600786baecfSMauro Carvalho Chehab 1601786baecfSMauro Carvalho Chehab static int fe_send_command(struct dvb_frontend* fe, const u8 command, 1602786baecfSMauro Carvalho Chehab int param_length, const u8 params[], 1603786baecfSMauro Carvalho Chehab int *result_length, u8 cmd_result[]) 1604786baecfSMauro Carvalho Chehab { 1605786baecfSMauro Carvalho Chehab struct ttusb_dec* dec = fe->dvb->priv; 1606786baecfSMauro Carvalho Chehab return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); 1607786baecfSMauro Carvalho Chehab } 1608786baecfSMauro Carvalho Chehab 1609786baecfSMauro Carvalho Chehab static struct ttusbdecfe_config fe_config = { 1610786baecfSMauro Carvalho Chehab .send_command = fe_send_command 1611786baecfSMauro Carvalho Chehab }; 1612786baecfSMauro Carvalho Chehab 1613786baecfSMauro Carvalho Chehab static int ttusb_dec_probe(struct usb_interface *intf, 1614786baecfSMauro Carvalho Chehab const struct usb_device_id *id) 1615786baecfSMauro Carvalho Chehab { 1616786baecfSMauro Carvalho Chehab struct usb_device *udev; 1617786baecfSMauro Carvalho Chehab struct ttusb_dec *dec; 1618cf732b5fSAlexey Khoroshilov int result; 1619786baecfSMauro Carvalho Chehab 1620786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1621786baecfSMauro Carvalho Chehab 1622786baecfSMauro Carvalho Chehab udev = interface_to_usbdev(intf); 1623786baecfSMauro Carvalho Chehab 1624786baecfSMauro Carvalho Chehab if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) { 1625786baecfSMauro Carvalho Chehab printk("%s: couldn't allocate memory.\n", __func__); 1626786baecfSMauro Carvalho Chehab return -ENOMEM; 1627786baecfSMauro Carvalho Chehab } 1628786baecfSMauro Carvalho Chehab 1629786baecfSMauro Carvalho Chehab usb_set_intfdata(intf, (void *)dec); 1630786baecfSMauro Carvalho Chehab 1631786baecfSMauro Carvalho Chehab switch (id->idProduct) { 1632786baecfSMauro Carvalho Chehab case 0x1006: 1633786baecfSMauro Carvalho Chehab ttusb_dec_set_model(dec, TTUSB_DEC3000S); 1634786baecfSMauro Carvalho Chehab break; 1635786baecfSMauro Carvalho Chehab 1636786baecfSMauro Carvalho Chehab case 0x1008: 1637786baecfSMauro Carvalho Chehab ttusb_dec_set_model(dec, TTUSB_DEC2000T); 1638786baecfSMauro Carvalho Chehab break; 1639786baecfSMauro Carvalho Chehab 1640786baecfSMauro Carvalho Chehab case 0x1009: 1641786baecfSMauro Carvalho Chehab ttusb_dec_set_model(dec, TTUSB_DEC2540T); 1642786baecfSMauro Carvalho Chehab break; 1643786baecfSMauro Carvalho Chehab } 1644786baecfSMauro Carvalho Chehab 1645786baecfSMauro Carvalho Chehab dec->udev = udev; 1646786baecfSMauro Carvalho Chehab 1647cf732b5fSAlexey Khoroshilov result = ttusb_dec_init_usb(dec); 1648cf732b5fSAlexey Khoroshilov if (result) 1649cf732b5fSAlexey Khoroshilov goto err_usb; 1650cf732b5fSAlexey Khoroshilov result = ttusb_dec_init_stb(dec); 1651cf732b5fSAlexey Khoroshilov if (result) 1652cf732b5fSAlexey Khoroshilov goto err_stb; 1653cf732b5fSAlexey Khoroshilov result = ttusb_dec_init_dvb(dec); 1654cf732b5fSAlexey Khoroshilov if (result) 1655cf732b5fSAlexey Khoroshilov goto err_stb; 1656786baecfSMauro Carvalho Chehab 1657786baecfSMauro Carvalho Chehab dec->adapter.priv = dec; 1658786baecfSMauro Carvalho Chehab switch (id->idProduct) { 1659786baecfSMauro Carvalho Chehab case 0x1006: 1660786baecfSMauro Carvalho Chehab dec->fe = ttusbdecfe_dvbs_attach(&fe_config); 1661786baecfSMauro Carvalho Chehab break; 1662786baecfSMauro Carvalho Chehab 1663786baecfSMauro Carvalho Chehab case 0x1008: 1664786baecfSMauro Carvalho Chehab case 0x1009: 1665786baecfSMauro Carvalho Chehab dec->fe = ttusbdecfe_dvbt_attach(&fe_config); 1666786baecfSMauro Carvalho Chehab break; 1667786baecfSMauro Carvalho Chehab } 1668786baecfSMauro Carvalho Chehab 1669786baecfSMauro Carvalho Chehab if (dec->fe == NULL) { 1670786baecfSMauro Carvalho Chehab printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n", 1671786baecfSMauro Carvalho Chehab le16_to_cpu(dec->udev->descriptor.idVendor), 1672786baecfSMauro Carvalho Chehab le16_to_cpu(dec->udev->descriptor.idProduct)); 1673786baecfSMauro Carvalho Chehab } else { 1674786baecfSMauro Carvalho Chehab if (dvb_register_frontend(&dec->adapter, dec->fe)) { 1675786baecfSMauro Carvalho Chehab printk("budget-ci: Frontend registration failed!\n"); 1676786baecfSMauro Carvalho Chehab if (dec->fe->ops.release) 1677786baecfSMauro Carvalho Chehab dec->fe->ops.release(dec->fe); 1678786baecfSMauro Carvalho Chehab dec->fe = NULL; 1679786baecfSMauro Carvalho Chehab } 1680786baecfSMauro Carvalho Chehab } 1681786baecfSMauro Carvalho Chehab 1682786baecfSMauro Carvalho Chehab ttusb_dec_init_v_pes(dec); 1683786baecfSMauro Carvalho Chehab ttusb_dec_init_filters(dec); 1684786baecfSMauro Carvalho Chehab ttusb_dec_init_tasklet(dec); 1685786baecfSMauro Carvalho Chehab 1686786baecfSMauro Carvalho Chehab dec->active = 1; 1687786baecfSMauro Carvalho Chehab 1688786baecfSMauro Carvalho Chehab ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN); 1689786baecfSMauro Carvalho Chehab 1690786baecfSMauro Carvalho Chehab if (enable_rc) 1691786baecfSMauro Carvalho Chehab ttusb_init_rc(dec); 1692786baecfSMauro Carvalho Chehab 1693786baecfSMauro Carvalho Chehab return 0; 1694cf732b5fSAlexey Khoroshilov err_stb: 1695cf732b5fSAlexey Khoroshilov ttusb_dec_exit_usb(dec); 1696cf732b5fSAlexey Khoroshilov err_usb: 1697cf732b5fSAlexey Khoroshilov kfree(dec); 1698cf732b5fSAlexey Khoroshilov return result; 1699786baecfSMauro Carvalho Chehab } 1700786baecfSMauro Carvalho Chehab 1701786baecfSMauro Carvalho Chehab static void ttusb_dec_disconnect(struct usb_interface *intf) 1702786baecfSMauro Carvalho Chehab { 1703786baecfSMauro Carvalho Chehab struct ttusb_dec *dec = usb_get_intfdata(intf); 1704786baecfSMauro Carvalho Chehab 1705786baecfSMauro Carvalho Chehab usb_set_intfdata(intf, NULL); 1706786baecfSMauro Carvalho Chehab 1707786baecfSMauro Carvalho Chehab dprintk("%s\n", __func__); 1708786baecfSMauro Carvalho Chehab 1709786baecfSMauro Carvalho Chehab if (dec->active) { 1710786baecfSMauro Carvalho Chehab ttusb_dec_exit_tasklet(dec); 1711786baecfSMauro Carvalho Chehab ttusb_dec_exit_filters(dec); 1712786baecfSMauro Carvalho Chehab if(enable_rc) 1713786baecfSMauro Carvalho Chehab ttusb_dec_exit_rc(dec); 1714786baecfSMauro Carvalho Chehab ttusb_dec_exit_usb(dec); 1715786baecfSMauro Carvalho Chehab ttusb_dec_exit_dvb(dec); 1716786baecfSMauro Carvalho Chehab } 1717786baecfSMauro Carvalho Chehab 1718786baecfSMauro Carvalho Chehab kfree(dec); 1719786baecfSMauro Carvalho Chehab } 1720786baecfSMauro Carvalho Chehab 1721786baecfSMauro Carvalho Chehab static void ttusb_dec_set_model(struct ttusb_dec *dec, 1722786baecfSMauro Carvalho Chehab enum ttusb_dec_model model) 1723786baecfSMauro Carvalho Chehab { 1724786baecfSMauro Carvalho Chehab dec->model = model; 1725786baecfSMauro Carvalho Chehab 1726786baecfSMauro Carvalho Chehab switch (model) { 1727786baecfSMauro Carvalho Chehab case TTUSB_DEC2000T: 1728786baecfSMauro Carvalho Chehab dec->model_name = "DEC2000-t"; 1729786baecfSMauro Carvalho Chehab dec->firmware_name = "dvb-ttusb-dec-2000t.fw"; 1730786baecfSMauro Carvalho Chehab break; 1731786baecfSMauro Carvalho Chehab 1732786baecfSMauro Carvalho Chehab case TTUSB_DEC2540T: 1733786baecfSMauro Carvalho Chehab dec->model_name = "DEC2540-t"; 1734786baecfSMauro Carvalho Chehab dec->firmware_name = "dvb-ttusb-dec-2540t.fw"; 1735786baecfSMauro Carvalho Chehab break; 1736786baecfSMauro Carvalho Chehab 1737786baecfSMauro Carvalho Chehab case TTUSB_DEC3000S: 1738786baecfSMauro Carvalho Chehab dec->model_name = "DEC3000-s"; 1739786baecfSMauro Carvalho Chehab dec->firmware_name = "dvb-ttusb-dec-3000s.fw"; 1740786baecfSMauro Carvalho Chehab break; 1741786baecfSMauro Carvalho Chehab } 1742786baecfSMauro Carvalho Chehab } 1743786baecfSMauro Carvalho Chehab 1744786baecfSMauro Carvalho Chehab static struct usb_device_id ttusb_dec_table[] = { 1745786baecfSMauro Carvalho Chehab {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */ 1746786baecfSMauro Carvalho Chehab /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */ 1747786baecfSMauro Carvalho Chehab {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */ 1748786baecfSMauro Carvalho Chehab {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */ 1749786baecfSMauro Carvalho Chehab {} 1750786baecfSMauro Carvalho Chehab }; 1751786baecfSMauro Carvalho Chehab 1752786baecfSMauro Carvalho Chehab static struct usb_driver ttusb_dec_driver = { 1753786baecfSMauro Carvalho Chehab .name = "ttusb-dec", 1754786baecfSMauro Carvalho Chehab .probe = ttusb_dec_probe, 1755786baecfSMauro Carvalho Chehab .disconnect = ttusb_dec_disconnect, 1756786baecfSMauro Carvalho Chehab .id_table = ttusb_dec_table, 1757786baecfSMauro Carvalho Chehab }; 1758786baecfSMauro Carvalho Chehab 1759786baecfSMauro Carvalho Chehab module_usb_driver(ttusb_dec_driver); 1760786baecfSMauro Carvalho Chehab 1761786baecfSMauro Carvalho Chehab MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>"); 1762786baecfSMauro Carvalho Chehab MODULE_DESCRIPTION(DRIVER_NAME); 1763786baecfSMauro Carvalho Chehab MODULE_LICENSE("GPL"); 1764786baecfSMauro Carvalho Chehab MODULE_DEVICE_TABLE(usb, ttusb_dec_table); 1765