Path: blob/master/drivers/media/dvb/ttusb-dec/ttusb_dec.c
15115 views
/*1* TTUSB DEC Driver2*3* Copyright (C) 2003-2004 Alex Woods <[email protected]>4* IR support by Peter Beutner <[email protected]>5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License as published by8* the Free Software Foundation; either version 2 of the License, or9* (at your option) any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program; if not, write to the Free Software18* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.19*20*/2122#include <linux/list.h>23#include <linux/module.h>24#include <linux/pci.h>25#include <linux/slab.h>26#include <linux/spinlock.h>27#include <linux/usb.h>28#include <linux/interrupt.h>29#include <linux/firmware.h>30#include <linux/crc32.h>31#include <linux/init.h>32#include <linux/input.h>3334#include <linux/mutex.h>3536#include "dmxdev.h"37#include "dvb_demux.h"38#include "dvb_filter.h"39#include "dvb_frontend.h"40#include "dvb_net.h"41#include "ttusbdecfe.h"4243static int debug;44static int output_pva;45static int enable_rc;4647module_param(debug, int, 0644);48MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");49module_param(output_pva, int, 0444);50MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");51module_param(enable_rc, int, 0644);52MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");5354DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);5556#define dprintk if (debug) printk5758#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB"5960#define COMMAND_PIPE 0x0361#define RESULT_PIPE 0x0462#define IN_PIPE 0x0863#define OUT_PIPE 0x0764#define IRQ_PIPE 0x0A6566#define COMMAND_PACKET_SIZE 0x3c67#define ARM_PACKET_SIZE 0x100068#define IRQ_PACKET_SIZE 0x86970#define ISO_BUF_COUNT 0x0471#define FRAMES_PER_ISO_BUF 0x0472#define ISO_FRAME_SIZE 0x03807374#define MAX_PVA_LENGTH 61447576enum ttusb_dec_model {77TTUSB_DEC2000T,78TTUSB_DEC2540T,79TTUSB_DEC3000S80};8182enum ttusb_dec_packet_type {83TTUSB_DEC_PACKET_PVA,84TTUSB_DEC_PACKET_SECTION,85TTUSB_DEC_PACKET_EMPTY86};8788enum ttusb_dec_interface {89TTUSB_DEC_INTERFACE_INITIAL,90TTUSB_DEC_INTERFACE_IN,91TTUSB_DEC_INTERFACE_OUT92};9394struct ttusb_dec {95enum ttusb_dec_model model;96char *model_name;97char *firmware_name;98int can_playback;99100/* DVB bits */101struct dvb_adapter adapter;102struct dmxdev dmxdev;103struct dvb_demux demux;104struct dmx_frontend frontend;105struct dvb_net dvb_net;106struct dvb_frontend* fe;107108u16 pid[DMX_PES_OTHER];109110/* USB bits */111struct usb_device *udev;112u8 trans_count;113unsigned int command_pipe;114unsigned int result_pipe;115unsigned int in_pipe;116unsigned int out_pipe;117unsigned int irq_pipe;118enum ttusb_dec_interface interface;119struct mutex usb_mutex;120121void *irq_buffer;122struct urb *irq_urb;123dma_addr_t irq_dma_handle;124void *iso_buffer;125dma_addr_t iso_dma_handle;126struct urb *iso_urb[ISO_BUF_COUNT];127int iso_stream_count;128struct mutex iso_mutex;129130u8 packet[MAX_PVA_LENGTH + 4];131enum ttusb_dec_packet_type packet_type;132int packet_state;133int packet_length;134int packet_payload_length;135u16 next_packet_id;136137int pva_stream_count;138int filter_stream_count;139140struct dvb_filter_pes2ts a_pes2ts;141struct dvb_filter_pes2ts v_pes2ts;142143u8 v_pes[16 + MAX_PVA_LENGTH];144int v_pes_length;145int v_pes_postbytes;146147struct list_head urb_frame_list;148struct tasklet_struct urb_tasklet;149spinlock_t urb_frame_list_lock;150151struct dvb_demux_filter *audio_filter;152struct dvb_demux_filter *video_filter;153struct list_head filter_info_list;154spinlock_t filter_info_list_lock;155156struct input_dev *rc_input_dev;157char rc_phys[64];158159int active; /* Loaded successfully */160};161162struct urb_frame {163u8 data[ISO_FRAME_SIZE];164int length;165struct list_head urb_frame_list;166};167168struct filter_info {169u8 stream_id;170struct dvb_demux_filter *filter;171struct list_head filter_info_list;172};173174static u16 rc_keys[] = {175KEY_POWER,176KEY_MUTE,177KEY_1,178KEY_2,179KEY_3,180KEY_4,181KEY_5,182KEY_6,183KEY_7,184KEY_8,185KEY_9,186KEY_0,187KEY_CHANNELUP,188KEY_VOLUMEDOWN,189KEY_OK,190KEY_VOLUMEUP,191KEY_CHANNELDOWN,192KEY_PREVIOUS,193KEY_ESC,194KEY_RED,195KEY_GREEN,196KEY_YELLOW,197KEY_BLUE,198KEY_OPTION,199KEY_M,200KEY_RADIO201};202203static void ttusb_dec_set_model(struct ttusb_dec *dec,204enum ttusb_dec_model model);205206static void ttusb_dec_handle_irq( struct urb *urb)207{208struct ttusb_dec * dec = urb->context;209char *buffer = dec->irq_buffer;210int retval;211212switch(urb->status) {213case 0: /*success*/214break;215case -ECONNRESET:216case -ENOENT:217case -ESHUTDOWN:218case -ETIME:219/* this urb is dead, cleanup */220dprintk("%s:urb shutting down with status: %d\n",221__func__, urb->status);222return;223default:224dprintk("%s:nonzero status received: %d\n",225__func__,urb->status);226goto exit;227}228229if( (buffer[0] == 0x1) && (buffer[2] == 0x15) ) {230/* IR - Event */231/* this is an fact a bit too simple implementation;232* the box also reports a keyrepeat signal233* (with buffer[3] == 0x40) in an intervall of ~100ms.234* But to handle this correctly we had to imlemenent some235* kind of timer which signals a 'key up' event if no236* keyrepeat signal is received for lets say 200ms.237* this should/could be added later ...238* for now lets report each signal as a key down and up*/239dprintk("%s:rc signal:%d\n", __func__, buffer[4]);240input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);241input_sync(dec->rc_input_dev);242input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);243input_sync(dec->rc_input_dev);244}245246exit: retval = usb_submit_urb(urb, GFP_ATOMIC);247if(retval)248printk("%s - usb_commit_urb failed with result: %d\n",249__func__, retval);250}251252static u16 crc16(u16 crc, const u8 *buf, size_t len)253{254u16 tmp;255256while (len--) {257crc ^= *buf++;258crc ^= (u8)crc >> 4;259tmp = (u8)crc;260crc ^= (tmp ^ (tmp << 1)) << 4;261}262return crc;263}264265static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,266int param_length, const u8 params[],267int *result_length, u8 cmd_result[])268{269int result, actual_len, i;270u8 *b;271272dprintk("%s\n", __func__);273274b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);275if (!b)276return -ENOMEM;277278if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {279kfree(b);280printk("%s: Failed to lock usb mutex.\n", __func__);281return result;282}283284b[0] = 0xaa;285b[1] = ++dec->trans_count;286b[2] = command;287b[3] = param_length;288289if (params)290memcpy(&b[4], params, param_length);291292if (debug) {293printk("%s: command: ", __func__);294for (i = 0; i < param_length + 4; i++)295printk("0x%02X ", b[i]);296printk("\n");297}298299result = usb_bulk_msg(dec->udev, dec->command_pipe, b,300COMMAND_PACKET_SIZE + 4, &actual_len, 1000);301302if (result) {303printk("%s: command bulk message failed: error %d\n",304__func__, result);305mutex_unlock(&dec->usb_mutex);306kfree(b);307return result;308}309310result = usb_bulk_msg(dec->udev, dec->result_pipe, b,311COMMAND_PACKET_SIZE + 4, &actual_len, 1000);312313if (result) {314printk("%s: result bulk message failed: error %d\n",315__func__, result);316mutex_unlock(&dec->usb_mutex);317kfree(b);318return result;319} else {320if (debug) {321printk("%s: result: ", __func__);322for (i = 0; i < actual_len; i++)323printk("0x%02X ", b[i]);324printk("\n");325}326327if (result_length)328*result_length = b[3];329if (cmd_result && b[3] > 0)330memcpy(cmd_result, &b[4], b[3]);331332mutex_unlock(&dec->usb_mutex);333334kfree(b);335return 0;336}337}338339static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,340unsigned int *model, unsigned int *version)341{342u8 c[COMMAND_PACKET_SIZE];343int c_length;344int result;345__be32 tmp;346347dprintk("%s\n", __func__);348349result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);350if (result)351return result;352353if (c_length >= 0x0c) {354if (mode != NULL) {355memcpy(&tmp, c, 4);356*mode = ntohl(tmp);357}358if (model != NULL) {359memcpy(&tmp, &c[4], 4);360*model = ntohl(tmp);361}362if (version != NULL) {363memcpy(&tmp, &c[8], 4);364*version = ntohl(tmp);365}366return 0;367} else {368return -1;369}370}371372static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)373{374struct ttusb_dec *dec = priv;375376dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,377&dec->audio_filter->feed->feed.ts,378DMX_OK);379380return 0;381}382383static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)384{385struct ttusb_dec *dec = priv;386387dec->video_filter->feed->cb.ts(data, 188, NULL, 0,388&dec->video_filter->feed->feed.ts,389DMX_OK);390391return 0;392}393394static void ttusb_dec_set_pids(struct ttusb_dec *dec)395{396u8 b[] = { 0x00, 0x00, 0x00, 0x00,3970x00, 0x00, 0xff, 0xff,3980xff, 0xff, 0xff, 0xff };399400__be16 pcr = htons(dec->pid[DMX_PES_PCR]);401__be16 audio = htons(dec->pid[DMX_PES_AUDIO]);402__be16 video = htons(dec->pid[DMX_PES_VIDEO]);403404dprintk("%s\n", __func__);405406memcpy(&b[0], &pcr, 2);407memcpy(&b[2], &audio, 2);408memcpy(&b[4], &video, 2);409410ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);411412dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],413ttusb_dec_audio_pes2ts_cb, dec);414dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],415ttusb_dec_video_pes2ts_cb, dec);416dec->v_pes_length = 0;417dec->v_pes_postbytes = 0;418}419420static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)421{422if (length < 8) {423printk("%s: packet too short - discarding\n", __func__);424return;425}426427if (length > 8 + MAX_PVA_LENGTH) {428printk("%s: packet too long - discarding\n", __func__);429return;430}431432switch (pva[2]) {433434case 0x01: { /* VideoStream */435int prebytes = pva[5] & 0x03;436int postbytes = (pva[5] & 0x0c) >> 2;437__be16 v_pes_payload_length;438439if (output_pva) {440dec->video_filter->feed->cb.ts(pva, length, NULL, 0,441&dec->video_filter->feed->feed.ts, DMX_OK);442return;443}444445if (dec->v_pes_postbytes > 0 &&446dec->v_pes_postbytes == prebytes) {447memcpy(&dec->v_pes[dec->v_pes_length],448&pva[12], prebytes);449450dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,451dec->v_pes_length + prebytes, 1);452}453454if (pva[5] & 0x10) {455dec->v_pes[7] = 0x80;456dec->v_pes[8] = 0x05;457458dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);459dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |460((pva[9] & 0xc0) >> 6);461dec->v_pes[11] = 0x01 |462((pva[9] & 0x3f) << 2) |463((pva[10] & 0x80) >> 6);464dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |465((pva[11] & 0xc0) >> 7);466dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);467468memcpy(&dec->v_pes[14], &pva[12 + prebytes],469length - 12 - prebytes);470dec->v_pes_length = 14 + length - 12 - prebytes;471} else {472dec->v_pes[7] = 0x00;473dec->v_pes[8] = 0x00;474475memcpy(&dec->v_pes[9], &pva[8], length - 8);476dec->v_pes_length = 9 + length - 8;477}478479dec->v_pes_postbytes = postbytes;480481if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&482dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&483dec->v_pes[11 + dec->v_pes[8]] == 0x01)484dec->v_pes[6] = 0x84;485else486dec->v_pes[6] = 0x80;487488v_pes_payload_length = htons(dec->v_pes_length - 6 +489postbytes);490memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);491492if (postbytes == 0)493dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,494dec->v_pes_length, 1);495496break;497}498499case 0x02: /* MainAudioStream */500if (output_pva) {501dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,502&dec->audio_filter->feed->feed.ts, DMX_OK);503return;504}505506dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,507pva[5] & 0x10);508break;509510default:511printk("%s: unknown PVA type: %02x.\n", __func__,512pva[2]);513break;514}515}516517static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,518int length)519{520struct list_head *item;521struct filter_info *finfo;522struct dvb_demux_filter *filter = NULL;523unsigned long flags;524u8 sid;525526sid = packet[1];527spin_lock_irqsave(&dec->filter_info_list_lock, flags);528for (item = dec->filter_info_list.next; item != &dec->filter_info_list;529item = item->next) {530finfo = list_entry(item, struct filter_info, filter_info_list);531if (finfo->stream_id == sid) {532filter = finfo->filter;533break;534}535}536spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);537538if (filter)539filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,540&filter->filter, DMX_OK);541}542543static void ttusb_dec_process_packet(struct ttusb_dec *dec)544{545int i;546u16 csum = 0;547u16 packet_id;548549if (dec->packet_length % 2) {550printk("%s: odd sized packet - discarding\n", __func__);551return;552}553554for (i = 0; i < dec->packet_length; i += 2)555csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);556557if (csum) {558printk("%s: checksum failed - discarding\n", __func__);559return;560}561562packet_id = dec->packet[dec->packet_length - 4] << 8;563packet_id += dec->packet[dec->packet_length - 3];564565if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {566printk("%s: warning: lost packets between %u and %u\n",567__func__, dec->next_packet_id - 1, packet_id);568}569570if (packet_id == 0xffff)571dec->next_packet_id = 0x8000;572else573dec->next_packet_id = packet_id + 1;574575switch (dec->packet_type) {576case TTUSB_DEC_PACKET_PVA:577if (dec->pva_stream_count)578ttusb_dec_process_pva(dec, dec->packet,579dec->packet_payload_length);580break;581582case TTUSB_DEC_PACKET_SECTION:583if (dec->filter_stream_count)584ttusb_dec_process_filter(dec, dec->packet,585dec->packet_payload_length);586break;587588case TTUSB_DEC_PACKET_EMPTY:589break;590}591}592593static void swap_bytes(u8 *b, int length)594{595u8 c;596597length -= length % 2;598for (; length; b += 2, length -= 2) {599c = *b;600*b = *(b + 1);601*(b + 1) = c;602}603}604605static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,606int length)607{608swap_bytes(b, length);609610while (length) {611switch (dec->packet_state) {612613case 0:614case 1:615case 2:616if (*b++ == 0xaa)617dec->packet_state++;618else619dec->packet_state = 0;620621length--;622break;623624case 3:625if (*b == 0x00) {626dec->packet_state++;627dec->packet_length = 0;628} else if (*b != 0xaa) {629dec->packet_state = 0;630}631632b++;633length--;634break;635636case 4:637dec->packet[dec->packet_length++] = *b++;638639if (dec->packet_length == 2) {640if (dec->packet[0] == 'A' &&641dec->packet[1] == 'V') {642dec->packet_type =643TTUSB_DEC_PACKET_PVA;644dec->packet_state++;645} else if (dec->packet[0] == 'S') {646dec->packet_type =647TTUSB_DEC_PACKET_SECTION;648dec->packet_state++;649} else if (dec->packet[0] == 0x00) {650dec->packet_type =651TTUSB_DEC_PACKET_EMPTY;652dec->packet_payload_length = 2;653dec->packet_state = 7;654} else {655printk("%s: unknown packet type: "656"%02x%02x\n", __func__,657dec->packet[0], dec->packet[1]);658dec->packet_state = 0;659}660}661662length--;663break;664665case 5:666dec->packet[dec->packet_length++] = *b++;667668if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&669dec->packet_length == 8) {670dec->packet_state++;671dec->packet_payload_length = 8 +672(dec->packet[6] << 8) +673dec->packet[7];674} else if (dec->packet_type ==675TTUSB_DEC_PACKET_SECTION &&676dec->packet_length == 5) {677dec->packet_state++;678dec->packet_payload_length = 5 +679((dec->packet[3] & 0x0f) << 8) +680dec->packet[4];681}682683length--;684break;685686case 6: {687int remainder = dec->packet_payload_length -688dec->packet_length;689690if (length >= remainder) {691memcpy(dec->packet + dec->packet_length,692b, remainder);693dec->packet_length += remainder;694b += remainder;695length -= remainder;696dec->packet_state++;697} else {698memcpy(&dec->packet[dec->packet_length],699b, length);700dec->packet_length += length;701length = 0;702}703704break;705}706707case 7: {708int tail = 4;709710dec->packet[dec->packet_length++] = *b++;711712if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&713dec->packet_payload_length % 2)714tail++;715716if (dec->packet_length ==717dec->packet_payload_length + tail) {718ttusb_dec_process_packet(dec);719dec->packet_state = 0;720}721722length--;723break;724}725726default:727printk("%s: illegal packet state encountered.\n",728__func__);729dec->packet_state = 0;730}731}732}733734static void ttusb_dec_process_urb_frame_list(unsigned long data)735{736struct ttusb_dec *dec = (struct ttusb_dec *)data;737struct list_head *item;738struct urb_frame *frame;739unsigned long flags;740741while (1) {742spin_lock_irqsave(&dec->urb_frame_list_lock, flags);743if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {744frame = list_entry(item, struct urb_frame,745urb_frame_list);746list_del(&frame->urb_frame_list);747} else {748spin_unlock_irqrestore(&dec->urb_frame_list_lock,749flags);750return;751}752spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);753754ttusb_dec_process_urb_frame(dec, frame->data, frame->length);755kfree(frame);756}757}758759static void ttusb_dec_process_urb(struct urb *urb)760{761struct ttusb_dec *dec = urb->context;762763if (!urb->status) {764int i;765766for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {767struct usb_iso_packet_descriptor *d;768u8 *b;769int length;770struct urb_frame *frame;771772d = &urb->iso_frame_desc[i];773b = urb->transfer_buffer + d->offset;774length = d->actual_length;775776if ((frame = kmalloc(sizeof(struct urb_frame),777GFP_ATOMIC))) {778unsigned long flags;779780memcpy(frame->data, b, length);781frame->length = length;782783spin_lock_irqsave(&dec->urb_frame_list_lock,784flags);785list_add_tail(&frame->urb_frame_list,786&dec->urb_frame_list);787spin_unlock_irqrestore(&dec->urb_frame_list_lock,788flags);789790tasklet_schedule(&dec->urb_tasklet);791}792}793} else {794/* -ENOENT is expected when unlinking urbs */795if (urb->status != -ENOENT)796dprintk("%s: urb error: %d\n", __func__,797urb->status);798}799800if (dec->iso_stream_count)801usb_submit_urb(urb, GFP_ATOMIC);802}803804static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)805{806int i, j, buffer_offset = 0;807808dprintk("%s\n", __func__);809810for (i = 0; i < ISO_BUF_COUNT; i++) {811int frame_offset = 0;812struct urb *urb = dec->iso_urb[i];813814urb->dev = dec->udev;815urb->context = dec;816urb->complete = ttusb_dec_process_urb;817urb->pipe = dec->in_pipe;818urb->transfer_flags = URB_ISO_ASAP;819urb->interval = 1;820urb->number_of_packets = FRAMES_PER_ISO_BUF;821urb->transfer_buffer_length = ISO_FRAME_SIZE *822FRAMES_PER_ISO_BUF;823urb->transfer_buffer = dec->iso_buffer + buffer_offset;824buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;825826for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {827urb->iso_frame_desc[j].offset = frame_offset;828urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;829frame_offset += ISO_FRAME_SIZE;830}831}832}833834static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)835{836int i;837838dprintk("%s\n", __func__);839840if (mutex_lock_interruptible(&dec->iso_mutex))841return;842843dec->iso_stream_count--;844845if (!dec->iso_stream_count) {846for (i = 0; i < ISO_BUF_COUNT; i++)847usb_kill_urb(dec->iso_urb[i]);848}849850mutex_unlock(&dec->iso_mutex);851}852853/* Setting the interface of the DEC tends to take down the USB communications854* for a short period, so it's important not to call this function just before855* trying to talk to it.856*/857static int ttusb_dec_set_interface(struct ttusb_dec *dec,858enum ttusb_dec_interface interface)859{860int result = 0;861u8 b[] = { 0x05 };862863if (interface != dec->interface) {864switch (interface) {865case TTUSB_DEC_INTERFACE_INITIAL:866result = usb_set_interface(dec->udev, 0, 0);867break;868case TTUSB_DEC_INTERFACE_IN:869result = ttusb_dec_send_command(dec, 0x80, sizeof(b),870b, NULL, NULL);871if (result)872return result;873result = usb_set_interface(dec->udev, 0, 8);874break;875case TTUSB_DEC_INTERFACE_OUT:876result = usb_set_interface(dec->udev, 0, 1);877break;878}879880if (result)881return result;882883dec->interface = interface;884}885886return 0;887}888889static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)890{891int i, result;892893dprintk("%s\n", __func__);894895if (mutex_lock_interruptible(&dec->iso_mutex))896return -EAGAIN;897898if (!dec->iso_stream_count) {899ttusb_dec_setup_urbs(dec);900901dec->packet_state = 0;902dec->v_pes_postbytes = 0;903dec->next_packet_id = 0;904905for (i = 0; i < ISO_BUF_COUNT; i++) {906if ((result = usb_submit_urb(dec->iso_urb[i],907GFP_ATOMIC))) {908printk("%s: failed urb submission %d: "909"error %d\n", __func__, i, result);910911while (i) {912usb_kill_urb(dec->iso_urb[i - 1]);913i--;914}915916mutex_unlock(&dec->iso_mutex);917return result;918}919}920}921922dec->iso_stream_count++;923924mutex_unlock(&dec->iso_mutex);925926return 0;927}928929static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)930{931struct dvb_demux *dvbdmx = dvbdmxfeed->demux;932struct ttusb_dec *dec = dvbdmx->priv;933u8 b0[] = { 0x05 };934int result = 0;935936dprintk("%s\n", __func__);937938dprintk(" ts_type:");939940if (dvbdmxfeed->ts_type & TS_DECODER)941dprintk(" TS_DECODER");942943if (dvbdmxfeed->ts_type & TS_PACKET)944dprintk(" TS_PACKET");945946if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)947dprintk(" TS_PAYLOAD_ONLY");948949dprintk("\n");950951switch (dvbdmxfeed->pes_type) {952953case DMX_TS_PES_VIDEO:954dprintk(" pes_type: DMX_TS_PES_VIDEO\n");955dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;956dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;957dec->video_filter = dvbdmxfeed->filter;958ttusb_dec_set_pids(dec);959break;960961case DMX_TS_PES_AUDIO:962dprintk(" pes_type: DMX_TS_PES_AUDIO\n");963dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;964dec->audio_filter = dvbdmxfeed->filter;965ttusb_dec_set_pids(dec);966break;967968case DMX_TS_PES_TELETEXT:969dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;970dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n");971return -ENOSYS;972973case DMX_TS_PES_PCR:974dprintk(" pes_type: DMX_TS_PES_PCR\n");975dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;976ttusb_dec_set_pids(dec);977break;978979case DMX_TS_PES_OTHER:980dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n");981return -ENOSYS;982983default:984dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);985return -EINVAL;986987}988989result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);990if (result)991return result;992993dec->pva_stream_count++;994return ttusb_dec_start_iso_xfer(dec);995}996997static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)998{999struct ttusb_dec *dec = dvbdmxfeed->demux->priv;1000u8 b0[] = { 0x00, 0x00, 0x00, 0x01,10010x00, 0x00, 0x00, 0x00,10020x00, 0x00, 0x00, 0x00,10030x00, 0x00, 0x00, 0x00,10040x00, 0xff, 0x00, 0x00,10050x00, 0x00, 0x00, 0x00,10060x00, 0x00, 0x00, 0x00,10070x00 };1008__be16 pid;1009u8 c[COMMAND_PACKET_SIZE];1010int c_length;1011int result;1012struct filter_info *finfo;1013unsigned long flags;1014u8 x = 1;10151016dprintk("%s\n", __func__);10171018pid = htons(dvbdmxfeed->pid);1019memcpy(&b0[0], &pid, 2);1020memcpy(&b0[4], &x, 1);1021memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);10221023result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,1024&c_length, c);10251026if (!result) {1027if (c_length == 2) {1028if (!(finfo = kmalloc(sizeof(struct filter_info),1029GFP_ATOMIC)))1030return -ENOMEM;10311032finfo->stream_id = c[1];1033finfo->filter = dvbdmxfeed->filter;10341035spin_lock_irqsave(&dec->filter_info_list_lock, flags);1036list_add_tail(&finfo->filter_info_list,1037&dec->filter_info_list);1038spin_unlock_irqrestore(&dec->filter_info_list_lock,1039flags);10401041dvbdmxfeed->priv = finfo;10421043dec->filter_stream_count++;1044return ttusb_dec_start_iso_xfer(dec);1045}10461047return -EAGAIN;1048} else1049return result;1050}10511052static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)1053{1054struct dvb_demux *dvbdmx = dvbdmxfeed->demux;10551056dprintk("%s\n", __func__);10571058if (!dvbdmx->dmx.frontend)1059return -EINVAL;10601061dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid);10621063switch (dvbdmxfeed->type) {10641065case DMX_TYPE_TS:1066return ttusb_dec_start_ts_feed(dvbdmxfeed);1067break;10681069case DMX_TYPE_SEC:1070return ttusb_dec_start_sec_feed(dvbdmxfeed);1071break;10721073default:1074dprintk(" type: unknown (%d)\n", dvbdmxfeed->type);1075return -EINVAL;10761077}1078}10791080static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)1081{1082struct ttusb_dec *dec = dvbdmxfeed->demux->priv;1083u8 b0[] = { 0x00 };10841085ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);10861087dec->pva_stream_count--;10881089ttusb_dec_stop_iso_xfer(dec);10901091return 0;1092}10931094static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)1095{1096struct ttusb_dec *dec = dvbdmxfeed->demux->priv;1097u8 b0[] = { 0x00, 0x00 };1098struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;1099unsigned long flags;11001101b0[1] = finfo->stream_id;1102spin_lock_irqsave(&dec->filter_info_list_lock, flags);1103list_del(&finfo->filter_info_list);1104spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);1105kfree(finfo);1106ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);11071108dec->filter_stream_count--;11091110ttusb_dec_stop_iso_xfer(dec);11111112return 0;1113}11141115static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)1116{1117dprintk("%s\n", __func__);11181119switch (dvbdmxfeed->type) {1120case DMX_TYPE_TS:1121return ttusb_dec_stop_ts_feed(dvbdmxfeed);1122break;11231124case DMX_TYPE_SEC:1125return ttusb_dec_stop_sec_feed(dvbdmxfeed);1126break;1127}11281129return 0;1130}11311132static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)1133{1134int i;11351136dprintk("%s\n", __func__);11371138for (i = 0; i < ISO_BUF_COUNT; i++)1139usb_free_urb(dec->iso_urb[i]);11401141pci_free_consistent(NULL,1142ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *1143ISO_BUF_COUNT),1144dec->iso_buffer, dec->iso_dma_handle);1145}11461147static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)1148{1149int i;11501151dprintk("%s\n", __func__);11521153dec->iso_buffer = pci_alloc_consistent(NULL,1154ISO_FRAME_SIZE *1155(FRAMES_PER_ISO_BUF *1156ISO_BUF_COUNT),1157&dec->iso_dma_handle);11581159if (!dec->iso_buffer) {1160dprintk("%s: pci_alloc_consistent - not enough memory\n",1161__func__);1162return -ENOMEM;1163}11641165memset(dec->iso_buffer, 0,1166ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));11671168for (i = 0; i < ISO_BUF_COUNT; i++) {1169struct urb *urb;11701171if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {1172ttusb_dec_free_iso_urbs(dec);1173return -ENOMEM;1174}11751176dec->iso_urb[i] = urb;1177}11781179ttusb_dec_setup_urbs(dec);11801181return 0;1182}11831184static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)1185{1186spin_lock_init(&dec->urb_frame_list_lock);1187INIT_LIST_HEAD(&dec->urb_frame_list);1188tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,1189(unsigned long)dec);1190}11911192static int ttusb_init_rc( struct ttusb_dec *dec)1193{1194struct input_dev *input_dev;1195u8 b[] = { 0x00, 0x01 };1196int i;1197int err;11981199usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));1200strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));12011202input_dev = input_allocate_device();1203if (!input_dev)1204return -ENOMEM;12051206input_dev->name = "ttusb_dec remote control";1207input_dev->phys = dec->rc_phys;1208input_dev->evbit[0] = BIT_MASK(EV_KEY);1209input_dev->keycodesize = sizeof(u16);1210input_dev->keycodemax = 0x1a;1211input_dev->keycode = rc_keys;12121213for (i = 0; i < ARRAY_SIZE(rc_keys); i++)1214set_bit(rc_keys[i], input_dev->keybit);12151216err = input_register_device(input_dev);1217if (err) {1218input_free_device(input_dev);1219return err;1220}12211222dec->rc_input_dev = input_dev;1223if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))1224printk("%s: usb_submit_urb failed\n",__func__);1225/* enable irq pipe */1226ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);12271228return 0;1229}12301231static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)1232{1233dprintk("%s\n", __func__);12341235dec->v_pes[0] = 0x00;1236dec->v_pes[1] = 0x00;1237dec->v_pes[2] = 0x01;1238dec->v_pes[3] = 0xe0;1239}12401241static int ttusb_dec_init_usb(struct ttusb_dec *dec)1242{1243dprintk("%s\n", __func__);12441245mutex_init(&dec->usb_mutex);1246mutex_init(&dec->iso_mutex);12471248dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);1249dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);1250dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);1251dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);1252dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);12531254if(enable_rc) {1255dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);1256if(!dec->irq_urb) {1257return -ENOMEM;1258}1259dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,1260GFP_ATOMIC, &dec->irq_dma_handle);1261if(!dec->irq_buffer) {1262usb_free_urb(dec->irq_urb);1263return -ENOMEM;1264}1265usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,1266dec->irq_buffer, IRQ_PACKET_SIZE,1267ttusb_dec_handle_irq, dec, 1);1268dec->irq_urb->transfer_dma = dec->irq_dma_handle;1269dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;1270}12711272return ttusb_dec_alloc_iso_urbs(dec);1273}12741275static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)1276{1277int i, j, actual_len, result, size, trans_count;1278u8 b0[] = { 0x00, 0x00, 0x00, 0x00,12790x00, 0x00, 0x00, 0x00,12800x61, 0x00 };1281u8 b1[] = { 0x61 };1282u8 *b;1283char idstring[21];1284const u8 *firmware = NULL;1285size_t firmware_size = 0;1286u16 firmware_csum = 0;1287__be16 firmware_csum_ns;1288__be32 firmware_size_nl;1289u32 crc32_csum, crc32_check;1290__be32 tmp;1291const struct firmware *fw_entry = NULL;12921293dprintk("%s\n", __func__);12941295if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {1296printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",1297__func__, dec->firmware_name);1298return 1;1299}13001301firmware = fw_entry->data;1302firmware_size = fw_entry->size;13031304if (firmware_size < 60) {1305printk("%s: firmware size too small for DSP code (%zu < 60).\n",1306__func__, firmware_size);1307release_firmware(fw_entry);1308return -1;1309}13101311/* a 32 bit checksum over the first 56 bytes of the DSP Code is stored1312at offset 56 of file, so use it to check if the firmware file is1313valid. */1314crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;1315memcpy(&tmp, &firmware[56], 4);1316crc32_check = ntohl(tmp);1317if (crc32_csum != crc32_check) {1318printk("%s: crc32 check of DSP code failed (calculated "1319"0x%08x != 0x%08x in file), file invalid.\n",1320__func__, crc32_csum, crc32_check);1321release_firmware(fw_entry);1322return -1;1323}1324memcpy(idstring, &firmware[36], 20);1325idstring[20] = '\0';1326printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);13271328firmware_size_nl = htonl(firmware_size);1329memcpy(b0, &firmware_size_nl, 4);1330firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;1331firmware_csum_ns = htons(firmware_csum);1332memcpy(&b0[6], &firmware_csum_ns, 2);13331334result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);13351336if (result) {1337release_firmware(fw_entry);1338return result;1339}13401341trans_count = 0;1342j = 0;13431344b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);1345if (b == NULL) {1346release_firmware(fw_entry);1347return -ENOMEM;1348}13491350for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {1351size = firmware_size - i;1352if (size > COMMAND_PACKET_SIZE)1353size = COMMAND_PACKET_SIZE;13541355b[j + 0] = 0xaa;1356b[j + 1] = trans_count++;1357b[j + 2] = 0xf0;1358b[j + 3] = size;1359memcpy(&b[j + 4], &firmware[i], size);13601361j += COMMAND_PACKET_SIZE + 4;13621363if (j >= ARM_PACKET_SIZE) {1364result = usb_bulk_msg(dec->udev, dec->command_pipe, b,1365ARM_PACKET_SIZE, &actual_len,1366100);1367j = 0;1368} else if (size < COMMAND_PACKET_SIZE) {1369result = usb_bulk_msg(dec->udev, dec->command_pipe, b,1370j - COMMAND_PACKET_SIZE + size,1371&actual_len, 100);1372}1373}13741375result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);13761377release_firmware(fw_entry);1378kfree(b);13791380return result;1381}13821383static int ttusb_dec_init_stb(struct ttusb_dec *dec)1384{1385int result;1386unsigned int mode = 0, model = 0, version = 0;13871388dprintk("%s\n", __func__);13891390result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);13911392if (!result) {1393if (!mode) {1394if (version == 0xABCDEFAB)1395printk(KERN_INFO "ttusb_dec: no version "1396"info in Firmware\n");1397else1398printk(KERN_INFO "ttusb_dec: Firmware "1399"%x.%02x%c%c\n",1400version >> 24, (version >> 16) & 0xff,1401(version >> 8) & 0xff, version & 0xff);14021403result = ttusb_dec_boot_dsp(dec);1404if (result)1405return result;1406else1407return 1;1408} else {1409/* We can't trust the USB IDs that some firmwares1410give the box */1411switch (model) {1412case 0x00070001:1413case 0x00070008:1414case 0x0007000c:1415ttusb_dec_set_model(dec, TTUSB_DEC3000S);1416break;1417case 0x00070009:1418case 0x00070013:1419ttusb_dec_set_model(dec, TTUSB_DEC2000T);1420break;1421case 0x00070011:1422ttusb_dec_set_model(dec, TTUSB_DEC2540T);1423break;1424default:1425printk(KERN_ERR "%s: unknown model returned "1426"by firmware (%08x) - please report\n",1427__func__, model);1428return -1;1429break;1430}14311432if (version >= 0x01770000)1433dec->can_playback = 1;14341435return 0;1436}1437}1438else1439return result;1440}14411442static int ttusb_dec_init_dvb(struct ttusb_dec *dec)1443{1444int result;14451446dprintk("%s\n", __func__);14471448if ((result = dvb_register_adapter(&dec->adapter,1449dec->model_name, THIS_MODULE,1450&dec->udev->dev,1451adapter_nr)) < 0) {1452printk("%s: dvb_register_adapter failed: error %d\n",1453__func__, result);14541455return result;1456}14571458dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;14591460dec->demux.priv = (void *)dec;1461dec->demux.filternum = 31;1462dec->demux.feednum = 31;1463dec->demux.start_feed = ttusb_dec_start_feed;1464dec->demux.stop_feed = ttusb_dec_stop_feed;1465dec->demux.write_to_decoder = NULL;14661467if ((result = dvb_dmx_init(&dec->demux)) < 0) {1468printk("%s: dvb_dmx_init failed: error %d\n", __func__,1469result);14701471dvb_unregister_adapter(&dec->adapter);14721473return result;1474}14751476dec->dmxdev.filternum = 32;1477dec->dmxdev.demux = &dec->demux.dmx;1478dec->dmxdev.capabilities = 0;14791480if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {1481printk("%s: dvb_dmxdev_init failed: error %d\n",1482__func__, result);14831484dvb_dmx_release(&dec->demux);1485dvb_unregister_adapter(&dec->adapter);14861487return result;1488}14891490dec->frontend.source = DMX_FRONTEND_0;14911492if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,1493&dec->frontend)) < 0) {1494printk("%s: dvb_dmx_init failed: error %d\n", __func__,1495result);14961497dvb_dmxdev_release(&dec->dmxdev);1498dvb_dmx_release(&dec->demux);1499dvb_unregister_adapter(&dec->adapter);15001501return result;1502}15031504if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,1505&dec->frontend)) < 0) {1506printk("%s: dvb_dmx_init failed: error %d\n", __func__,1507result);15081509dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);1510dvb_dmxdev_release(&dec->dmxdev);1511dvb_dmx_release(&dec->demux);1512dvb_unregister_adapter(&dec->adapter);15131514return result;1515}15161517dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);15181519return 0;1520}15211522static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)1523{1524dprintk("%s\n", __func__);15251526dvb_net_release(&dec->dvb_net);1527dec->demux.dmx.close(&dec->demux.dmx);1528dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);1529dvb_dmxdev_release(&dec->dmxdev);1530dvb_dmx_release(&dec->demux);1531if (dec->fe) {1532dvb_unregister_frontend(dec->fe);1533if (dec->fe->ops.release)1534dec->fe->ops.release(dec->fe);1535}1536dvb_unregister_adapter(&dec->adapter);1537}15381539static void ttusb_dec_exit_rc(struct ttusb_dec *dec)1540{15411542dprintk("%s\n", __func__);1543/* we have to check whether the irq URB is already submitted.1544* As the irq is submitted after the interface is changed,1545* this is the best method i figured out.1546* Any others?*/1547if (dec->interface == TTUSB_DEC_INTERFACE_IN)1548usb_kill_urb(dec->irq_urb);15491550usb_free_urb(dec->irq_urb);15511552usb_free_coherent(dec->udev,IRQ_PACKET_SIZE,1553dec->irq_buffer, dec->irq_dma_handle);15541555if (dec->rc_input_dev) {1556input_unregister_device(dec->rc_input_dev);1557dec->rc_input_dev = NULL;1558}1559}156015611562static void ttusb_dec_exit_usb(struct ttusb_dec *dec)1563{1564int i;15651566dprintk("%s\n", __func__);15671568dec->iso_stream_count = 0;15691570for (i = 0; i < ISO_BUF_COUNT; i++)1571usb_kill_urb(dec->iso_urb[i]);15721573ttusb_dec_free_iso_urbs(dec);1574}15751576static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)1577{1578struct list_head *item;1579struct urb_frame *frame;15801581tasklet_kill(&dec->urb_tasklet);15821583while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {1584frame = list_entry(item, struct urb_frame, urb_frame_list);1585list_del(&frame->urb_frame_list);1586kfree(frame);1587}1588}15891590static void ttusb_dec_init_filters(struct ttusb_dec *dec)1591{1592INIT_LIST_HEAD(&dec->filter_info_list);1593spin_lock_init(&dec->filter_info_list_lock);1594}15951596static void ttusb_dec_exit_filters(struct ttusb_dec *dec)1597{1598struct list_head *item;1599struct filter_info *finfo;16001601while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {1602finfo = list_entry(item, struct filter_info, filter_info_list);1603list_del(&finfo->filter_info_list);1604kfree(finfo);1605}1606}16071608static int fe_send_command(struct dvb_frontend* fe, const u8 command,1609int param_length, const u8 params[],1610int *result_length, u8 cmd_result[])1611{1612struct ttusb_dec* dec = fe->dvb->priv;1613return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);1614}16151616static struct ttusbdecfe_config fe_config = {1617.send_command = fe_send_command1618};16191620static int ttusb_dec_probe(struct usb_interface *intf,1621const struct usb_device_id *id)1622{1623struct usb_device *udev;1624struct ttusb_dec *dec;16251626dprintk("%s\n", __func__);16271628udev = interface_to_usbdev(intf);16291630if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {1631printk("%s: couldn't allocate memory.\n", __func__);1632return -ENOMEM;1633}16341635usb_set_intfdata(intf, (void *)dec);16361637switch (id->idProduct) {1638case 0x1006:1639ttusb_dec_set_model(dec, TTUSB_DEC3000S);1640break;16411642case 0x1008:1643ttusb_dec_set_model(dec, TTUSB_DEC2000T);1644break;16451646case 0x1009:1647ttusb_dec_set_model(dec, TTUSB_DEC2540T);1648break;1649}16501651dec->udev = udev;16521653if (ttusb_dec_init_usb(dec))1654return 0;1655if (ttusb_dec_init_stb(dec)) {1656ttusb_dec_exit_usb(dec);1657return 0;1658}1659ttusb_dec_init_dvb(dec);16601661dec->adapter.priv = dec;1662switch (id->idProduct) {1663case 0x1006:1664dec->fe = ttusbdecfe_dvbs_attach(&fe_config);1665break;16661667case 0x1008:1668case 0x1009:1669dec->fe = ttusbdecfe_dvbt_attach(&fe_config);1670break;1671}16721673if (dec->fe == NULL) {1674printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n",1675le16_to_cpu(dec->udev->descriptor.idVendor),1676le16_to_cpu(dec->udev->descriptor.idProduct));1677} else {1678if (dvb_register_frontend(&dec->adapter, dec->fe)) {1679printk("budget-ci: Frontend registration failed!\n");1680if (dec->fe->ops.release)1681dec->fe->ops.release(dec->fe);1682dec->fe = NULL;1683}1684}16851686ttusb_dec_init_v_pes(dec);1687ttusb_dec_init_filters(dec);1688ttusb_dec_init_tasklet(dec);16891690dec->active = 1;16911692ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);16931694if (enable_rc)1695ttusb_init_rc(dec);16961697return 0;1698}16991700static void ttusb_dec_disconnect(struct usb_interface *intf)1701{1702struct ttusb_dec *dec = usb_get_intfdata(intf);17031704usb_set_intfdata(intf, NULL);17051706dprintk("%s\n", __func__);17071708if (dec->active) {1709ttusb_dec_exit_tasklet(dec);1710ttusb_dec_exit_filters(dec);1711if(enable_rc)1712ttusb_dec_exit_rc(dec);1713ttusb_dec_exit_usb(dec);1714ttusb_dec_exit_dvb(dec);1715}17161717kfree(dec);1718}17191720static void ttusb_dec_set_model(struct ttusb_dec *dec,1721enum ttusb_dec_model model)1722{1723dec->model = model;17241725switch (model) {1726case TTUSB_DEC2000T:1727dec->model_name = "DEC2000-t";1728dec->firmware_name = "dvb-ttusb-dec-2000t.fw";1729break;17301731case TTUSB_DEC2540T:1732dec->model_name = "DEC2540-t";1733dec->firmware_name = "dvb-ttusb-dec-2540t.fw";1734break;17351736case TTUSB_DEC3000S:1737dec->model_name = "DEC3000-s";1738dec->firmware_name = "dvb-ttusb-dec-3000s.fw";1739break;1740}1741}17421743static struct usb_device_id ttusb_dec_table[] = {1744{USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */1745/*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */1746{USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */1747{USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */1748{}1749};17501751static struct usb_driver ttusb_dec_driver = {1752.name = "ttusb-dec",1753.probe = ttusb_dec_probe,1754.disconnect = ttusb_dec_disconnect,1755.id_table = ttusb_dec_table,1756};17571758static int __init ttusb_dec_init(void)1759{1760int result;17611762if ((result = usb_register(&ttusb_dec_driver)) < 0) {1763printk("%s: initialisation failed: error %d.\n", __func__,1764result);1765return result;1766}17671768return 0;1769}17701771static void __exit ttusb_dec_exit(void)1772{1773usb_deregister(&ttusb_dec_driver);1774}17751776module_init(ttusb_dec_init);1777module_exit(ttusb_dec_exit);17781779MODULE_AUTHOR("Alex Woods <[email protected]>");1780MODULE_DESCRIPTION(DRIVER_NAME);1781MODULE_LICENSE("GPL");1782MODULE_DEVICE_TABLE(usb, ttusb_dec_table);178317841785