Path: blob/master/drivers/media/dvb/dvb-usb/dib0700_core.c
15111 views
/* Linux driver for devices based on the DiBcom DiB0700 USB bridge1*2* This program is free software; you can redistribute it and/or modify it3* under the terms of the GNU General Public License as published by the Free4* Software Foundation, version 2.5*6* Copyright (C) 2005-6 DiBcom, SA7*/8#include "dib0700.h"910/* debug */11int dvb_usb_dib0700_debug;12module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);13MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);1415static int nb_packet_buffer_size = 21;16module_param(nb_packet_buffer_size, int, 0644);17MODULE_PARM_DESC(nb_packet_buffer_size,18"Set the dib0700 driver data buffer size. This parameter "19"corresponds to the number of TS packets. The actual size of "20"the data buffer corresponds to this parameter "21"multiplied by 188 (default: 21)");2223DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);242526int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,27u32 *romversion, u32 *ramversion, u32 *fwtype)28{29struct dib0700_state *st = d->priv;30int ret;3132ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),33REQUEST_GET_VERSION,34USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,35st->buf, 16, USB_CTRL_GET_TIMEOUT);36if (hwversion != NULL)37*hwversion = (st->buf[0] << 24) | (st->buf[1] << 16) |38(st->buf[2] << 8) | st->buf[3];39if (romversion != NULL)40*romversion = (st->buf[4] << 24) | (st->buf[5] << 16) |41(st->buf[6] << 8) | st->buf[7];42if (ramversion != NULL)43*ramversion = (st->buf[8] << 24) | (st->buf[9] << 16) |44(st->buf[10] << 8) | st->buf[11];45if (fwtype != NULL)46*fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) |47(st->buf[14] << 8) | st->buf[15];48return ret;49}5051/* expecting rx buffer: request data[0] data[1] ... data[2] */52static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)53{54int status;5556deb_data(">>> ");57debug_dump(tx, txlen, deb_data);5859status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),60tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,61USB_CTRL_GET_TIMEOUT);6263if (status != txlen)64deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen);6566return status < 0 ? status : 0;67}6869/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */70int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)71{72u16 index, value;73int status;7475if (txlen < 2) {76err("tx buffer length is smaller than 2. Makes no sense.");77return -EINVAL;78}79if (txlen > 4) {80err("tx buffer length is larger than 4. Not supported.");81return -EINVAL;82}8384deb_data(">>> ");85debug_dump(tx,txlen,deb_data);8687value = ((txlen - 2) << 8) | tx[1];88index = 0;89if (txlen > 2)90index |= (tx[2] << 8);91if (txlen > 3)92index |= tx[3];9394status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],95USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,96USB_CTRL_GET_TIMEOUT);9798if (status < 0)99deb_info("ep 0 read error (status = %d)\n",status);100101deb_data("<<< ");102debug_dump(rx, rxlen, deb_data);103104return status; /* length in case of success */105}106107int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)108{109struct dib0700_state *st = d->priv;110s16 ret;111112st->buf[0] = REQUEST_SET_GPIO;113st->buf[1] = gpio;114st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6);115116ret = dib0700_ctrl_wr(d, st->buf, 3);117118return ret;119}120121static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)122{123struct dib0700_state *st = d->priv;124int ret;125126if (st->fw_version >= 0x10201) {127st->buf[0] = REQUEST_SET_USB_XFER_LEN;128st->buf[1] = (nb_ts_packets >> 8) & 0xff;129st->buf[2] = nb_ts_packets & 0xff;130131deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);132133ret = dib0700_ctrl_wr(d, st->buf, 3);134} else {135deb_info("this firmware does not allow to change the USB xfer len\n");136ret = -EIO;137}138139return ret;140}141142/*143* I2C master xfer function (supported in 1.20 firmware)144*/145static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,146int num)147{148/* The new i2c firmware messages are more reliable and in particular149properly support i2c read calls not preceded by a write */150151struct dvb_usb_device *d = i2c_get_adapdata(adap);152struct dib0700_state *st = d->priv;153uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */154uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */155uint8_t en_start = 0;156uint8_t en_stop = 0;157int result, i;158159/* Ensure nobody else hits the i2c bus while we're sending our160sequence of messages, (such as the remote control thread) */161if (mutex_lock_interruptible(&d->i2c_mutex) < 0)162return -EAGAIN;163164for (i = 0; i < num; i++) {165if (i == 0) {166/* First message in the transaction */167en_start = 1;168} else if (!(msg[i].flags & I2C_M_NOSTART)) {169/* Device supports repeated-start */170en_start = 1;171} else {172/* Not the first packet and device doesn't support173repeated start */174en_start = 0;175}176if (i == (num - 1)) {177/* Last message in the transaction */178en_stop = 1;179}180181if (msg[i].flags & I2C_M_RD) {182/* Read request */183u16 index, value;184uint8_t i2c_dest;185186i2c_dest = (msg[i].addr << 1);187value = ((en_start << 7) | (en_stop << 6) |188(msg[i].len & 0x3F)) << 8 | i2c_dest;189/* I2C ctrl + FE bus; */190index = ((gen_mode << 6) & 0xC0) |191((bus_mode << 4) & 0x30);192193result = usb_control_msg(d->udev,194usb_rcvctrlpipe(d->udev, 0),195REQUEST_NEW_I2C_READ,196USB_TYPE_VENDOR | USB_DIR_IN,197value, index, msg[i].buf,198msg[i].len,199USB_CTRL_GET_TIMEOUT);200if (result < 0) {201deb_info("i2c read error (status = %d)\n", result);202break;203}204205deb_data("<<< ");206debug_dump(msg[i].buf, msg[i].len, deb_data);207208} else {209/* Write request */210st->buf[0] = REQUEST_NEW_I2C_WRITE;211st->buf[1] = msg[i].addr << 1;212st->buf[2] = (en_start << 7) | (en_stop << 6) |213(msg[i].len & 0x3F);214/* I2C ctrl + FE bus; */215st->buf[3] = ((gen_mode << 6) & 0xC0) |216((bus_mode << 4) & 0x30);217/* The Actual i2c payload */218memcpy(&st->buf[4], msg[i].buf, msg[i].len);219220deb_data(">>> ");221debug_dump(st->buf, msg[i].len + 4, deb_data);222223result = usb_control_msg(d->udev,224usb_sndctrlpipe(d->udev, 0),225REQUEST_NEW_I2C_WRITE,226USB_TYPE_VENDOR | USB_DIR_OUT,2270, 0, st->buf, msg[i].len + 4,228USB_CTRL_GET_TIMEOUT);229if (result < 0) {230deb_info("i2c write error (status = %d)\n", result);231break;232}233}234}235mutex_unlock(&d->i2c_mutex);236return i;237}238239/*240* I2C master xfer function (pre-1.20 firmware)241*/242static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,243struct i2c_msg *msg, int num)244{245struct dvb_usb_device *d = i2c_get_adapdata(adap);246struct dib0700_state *st = d->priv;247int i,len;248249if (mutex_lock_interruptible(&d->i2c_mutex) < 0)250return -EAGAIN;251252for (i = 0; i < num; i++) {253/* fill in the address */254st->buf[1] = msg[i].addr << 1;255/* fill the buffer */256memcpy(&st->buf[2], msg[i].buf, msg[i].len);257258/* write/read request */259if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {260st->buf[0] = REQUEST_I2C_READ;261st->buf[1] |= 1;262263/* special thing in the current firmware: when length is zero the read-failed */264len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,265msg[i+1].buf, msg[i+1].len);266if (len <= 0) {267deb_info("I2C read failed on address 0x%02x\n",268msg[i].addr);269break;270}271272msg[i+1].len = len;273274i++;275} else {276st->buf[0] = REQUEST_I2C_WRITE;277if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)278break;279}280}281mutex_unlock(&d->i2c_mutex);282283return i;284}285286static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,287int num)288{289struct dvb_usb_device *d = i2c_get_adapdata(adap);290struct dib0700_state *st = d->priv;291292if (st->fw_use_new_i2c_api == 1) {293/* User running at least fw 1.20 */294return dib0700_i2c_xfer_new(adap, msg, num);295} else {296/* Use legacy calls */297return dib0700_i2c_xfer_legacy(adap, msg, num);298}299}300301static u32 dib0700_i2c_func(struct i2c_adapter *adapter)302{303return I2C_FUNC_I2C;304}305306struct i2c_algorithm dib0700_i2c_algo = {307.master_xfer = dib0700_i2c_xfer,308.functionality = dib0700_i2c_func,309};310311int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,312struct dvb_usb_device_description **desc, int *cold)313{314s16 ret;315u8 *b;316317b = kmalloc(16, GFP_KERNEL);318if (!b)319return -ENOMEM;320321322ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),323REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);324325deb_info("FW GET_VERSION length: %d\n",ret);326327*cold = ret <= 0;328deb_info("cold: %d\n", *cold);329330kfree(b);331return 0;332}333334static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,335u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,336u16 pll_loopdiv, u16 free_div, u16 dsuScaler)337{338struct dib0700_state *st = d->priv;339s16 ret;340341st->buf[0] = REQUEST_SET_CLOCK;342st->buf[1] = (en_pll << 7) | (pll_src << 6) |343(pll_range << 5) | (clock_gpio3 << 4);344st->buf[2] = (pll_prediv >> 8) & 0xff; /* MSB */345st->buf[3] = pll_prediv & 0xff; /* LSB */346st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */347st->buf[5] = pll_loopdiv & 0xff; /* LSB */348st->buf[6] = (free_div >> 8) & 0xff; /* MSB */349st->buf[7] = free_div & 0xff; /* LSB */350st->buf[8] = (dsuScaler >> 8) & 0xff; /* MSB */351st->buf[9] = dsuScaler & 0xff; /* LSB */352353ret = dib0700_ctrl_wr(d, st->buf, 10);354355return ret;356}357358int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)359{360struct dib0700_state *st = d->priv;361u16 divider;362363if (scl_kHz == 0)364return -EINVAL;365366st->buf[0] = REQUEST_SET_I2C_PARAM;367divider = (u16) (30000 / scl_kHz);368st->buf[1] = 0;369st->buf[2] = (u8) (divider >> 8);370st->buf[3] = (u8) (divider & 0xff);371divider = (u16) (72000 / scl_kHz);372st->buf[4] = (u8) (divider >> 8);373st->buf[5] = (u8) (divider & 0xff);374divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */375st->buf[6] = (u8) (divider >> 8);376st->buf[7] = (u8) (divider & 0xff);377378deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",379(st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |380st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);381return dib0700_ctrl_wr(d, st->buf, 8);382}383384385int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)386{387switch (clk_MHz) {388case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break;389default: return -EINVAL;390}391return 0;392}393394static int dib0700_jumpram(struct usb_device *udev, u32 address)395{396int ret = 0, actlen;397u8 *buf;398399buf = kmalloc(8, GFP_KERNEL);400if (!buf)401return -ENOMEM;402buf[0] = REQUEST_JUMPRAM;403buf[1] = 0;404buf[2] = 0;405buf[3] = 0;406buf[4] = (address >> 24) & 0xff;407buf[5] = (address >> 16) & 0xff;408buf[6] = (address >> 8) & 0xff;409buf[7] = address & 0xff;410411if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {412deb_fw("jumpram to 0x%x failed\n",address);413goto out;414}415if (actlen != 8) {416deb_fw("jumpram to 0x%x failed\n",address);417ret = -EIO;418goto out;419}420out:421kfree(buf);422return ret;423}424425int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)426{427struct hexline hx;428int pos = 0, ret, act_len, i, adap_num;429u8 *buf;430u32 fw_version;431432buf = kmalloc(260, GFP_KERNEL);433if (!buf)434return -ENOMEM;435436while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {437deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",438hx.addr, hx.len, hx.chk);439440buf[0] = hx.len;441buf[1] = (hx.addr >> 8) & 0xff;442buf[2] = hx.addr & 0xff;443buf[3] = hx.type;444memcpy(&buf[4],hx.data,hx.len);445buf[4+hx.len] = hx.chk;446447ret = usb_bulk_msg(udev,448usb_sndbulkpipe(udev, 0x01),449buf,450hx.len + 5,451&act_len,4521000);453454if (ret < 0) {455err("firmware download failed at %d with %d",pos,ret);456goto out;457}458}459460if (ret == 0) {461/* start the firmware */462if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {463info("firmware started successfully.");464msleep(500);465}466} else467ret = -EIO;468469/* the number of ts packet has to be at least 1 */470if (nb_packet_buffer_size < 1)471nb_packet_buffer_size = 1;472473/* get the fimware version */474usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),475REQUEST_GET_VERSION,476USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,477buf, 16, USB_CTRL_GET_TIMEOUT);478fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];479480/* set the buffer size - DVB-USB is allocating URB buffers481* only after the firwmare download was successful */482for (i = 0; i < dib0700_device_count; i++) {483for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;484adap_num++) {485if (fw_version >= 0x10201) {486dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;487} else {488/* for fw version older than 1.20.1,489* the buffersize has to be n times 512 */490dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;491if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512)492dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512;493}494}495}496out:497kfree(buf);498return ret;499}500501int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)502{503struct dib0700_state *st = adap->dev->priv;504int ret;505506if ((onoff != 0) && (st->fw_version >= 0x10201)) {507/* for firmware later than 1.20.1,508* the USB xfer length can be set */509ret = dib0700_set_usb_xfer_len(adap->dev,510st->nb_packet_buffer_size);511if (ret < 0) {512deb_info("can not set the USB xfer len\n");513return ret;514}515}516517st->buf[0] = REQUEST_ENABLE_VIDEO;518/* this bit gives a kind of command,519* rather than enabling something or not */520st->buf[1] = (onoff << 4) | 0x00;521522if (st->disable_streaming_master_mode == 1)523st->buf[2] = 0x00;524else525st->buf[2] = 0x01 << 4; /* Master mode */526527st->buf[3] = 0x00;528529deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);530531st->channel_state &= ~0x3;532if ((adap->stream.props.endpoint != 2)533&& (adap->stream.props.endpoint != 3)) {534deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint);535if (onoff)536st->channel_state |= 1 << (adap->id);537else538st->channel_state |= 1 << ~(adap->id);539} else {540if (onoff)541st->channel_state |= 1 << (adap->stream.props.endpoint-2);542else543st->channel_state |= 1 << (3-adap->stream.props.endpoint);544}545546st->buf[2] |= st->channel_state;547548deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);549550return dib0700_ctrl_wr(adap->dev, st->buf, 4);551}552553int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)554{555struct dvb_usb_device *d = rc->priv;556struct dib0700_state *st = d->priv;557int new_proto, ret;558559st->buf[0] = REQUEST_SET_RC;560st->buf[1] = 0;561st->buf[2] = 0;562563/* Set the IR mode */564if (rc_type == RC_TYPE_RC5)565new_proto = 1;566else if (rc_type == RC_TYPE_NEC)567new_proto = 0;568else if (rc_type == RC_TYPE_RC6) {569if (st->fw_version < 0x10200)570return -EINVAL;571572new_proto = 2;573} else574return -EINVAL;575576st->buf[1] = new_proto;577578ret = dib0700_ctrl_wr(d, st->buf, 3);579if (ret < 0) {580err("ir protocol setup failed");581return ret;582}583584d->props.rc.core.protocol = rc_type;585586return ret;587}588589/* Number of keypresses to ignore before start repeating */590#define RC_REPEAT_DELAY_V1_20 10591592/* This is the structure of the RC response packet starting in firmware 1.20 */593struct dib0700_rc_response {594u8 report_id;595u8 data_state;596union {597u16 system16;598struct {599u8 not_system;600u8 system;601};602};603u8 data;604u8 not_data;605};606#define RC_MSG_SIZE_V1_20 6607608static void dib0700_rc_urb_completion(struct urb *purb)609{610struct dvb_usb_device *d = purb->context;611struct dib0700_rc_response *poll_reply;612u32 uninitialized_var(keycode);613u8 toggle;614615deb_info("%s()\n", __func__);616if (d == NULL)617return;618619if (d->rc_dev == NULL) {620/* This will occur if disable_rc_polling=1 */621usb_free_urb(purb);622return;623}624625poll_reply = purb->transfer_buffer;626627if (purb->status < 0) {628deb_info("discontinuing polling\n");629usb_free_urb(purb);630return;631}632633if (purb->actual_length != RC_MSG_SIZE_V1_20) {634deb_info("malformed rc msg size=%d\n", purb->actual_length);635goto resubmit;636}637638deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n",639poll_reply->report_id, poll_reply->data_state,640poll_reply->system, poll_reply->not_system,641poll_reply->data, poll_reply->not_data,642purb->actual_length);643644switch (d->props.rc.core.protocol) {645case RC_TYPE_NEC:646toggle = 0;647648/* NEC protocol sends repeat code as 0 0 0 FF */649if ((poll_reply->system == 0x00) && (poll_reply->data == 0x00)650&& (poll_reply->not_data == 0xff)) {651poll_reply->data_state = 2;652break;653}654655if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {656deb_data("NEC extended protocol\n");657/* NEC extended code - 24 bits */658keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;659} else {660deb_data("NEC normal protocol\n");661/* normal NEC code - 16 bits */662keycode = poll_reply->system << 8 | poll_reply->data;663}664665break;666default:667deb_data("RC5 protocol\n");668/* RC5 Protocol */669toggle = poll_reply->report_id;670keycode = poll_reply->system << 8 | poll_reply->data;671672break;673}674675if ((poll_reply->data + poll_reply->not_data) != 0xff) {676/* Key failed integrity check */677err("key failed integrity check: %04x %02x %02x",678poll_reply->system,679poll_reply->data, poll_reply->not_data);680goto resubmit;681}682683rc_keydown(d->rc_dev, keycode, toggle);684685resubmit:686/* Clean the buffer before we requeue */687memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);688689/* Requeue URB */690usb_submit_urb(purb, GFP_ATOMIC);691}692693int dib0700_rc_setup(struct dvb_usb_device *d)694{695struct dib0700_state *st = d->priv;696struct urb *purb;697int ret;698699/* Poll-based. Don't initialize bulk mode */700if (st->fw_version < 0x10200)701return 0;702703/* Starting in firmware 1.20, the RC info is provided on a bulk pipe */704purb = usb_alloc_urb(0, GFP_KERNEL);705if (purb == NULL) {706err("rc usb alloc urb failed\n");707return -ENOMEM;708}709710purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);711if (purb->transfer_buffer == NULL) {712err("rc kzalloc failed\n");713usb_free_urb(purb);714return -ENOMEM;715}716717purb->status = -EINPROGRESS;718usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),719purb->transfer_buffer, RC_MSG_SIZE_V1_20,720dib0700_rc_urb_completion, d);721722ret = usb_submit_urb(purb, GFP_ATOMIC);723if (ret)724err("rc submit urb failed\n");725726return ret;727}728729static int dib0700_probe(struct usb_interface *intf,730const struct usb_device_id *id)731{732int i;733struct dvb_usb_device *dev;734735for (i = 0; i < dib0700_device_count; i++)736if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,737&dev, adapter_nr) == 0) {738struct dib0700_state *st = dev->priv;739u32 hwversion, romversion, fw_version, fwtype;740741dib0700_get_version(dev, &hwversion, &romversion,742&fw_version, &fwtype);743744deb_info("Firmware version: %x, %d, 0x%x, %d\n",745hwversion, romversion, fw_version, fwtype);746747st->fw_version = fw_version;748st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;749750/* Disable polling mode on newer firmwares */751if (st->fw_version >= 0x10200)752dev->props.rc.core.bulk_mode = true;753else754dev->props.rc.core.bulk_mode = false;755756dib0700_rc_setup(dev);757758return 0;759}760761return -ENODEV;762}763764static struct usb_driver dib0700_driver = {765.name = "dvb_usb_dib0700",766.probe = dib0700_probe,767.disconnect = dvb_usb_device_exit,768.id_table = dib0700_usb_id_table,769};770771/* module stuff */772static int __init dib0700_module_init(void)773{774int result;775info("loaded with support for %d different device-types", dib0700_device_count);776if ((result = usb_register(&dib0700_driver))) {777err("usb_register failed. Error number %d",result);778return result;779}780781return 0;782}783784static void __exit dib0700_module_exit(void)785{786/* deregister this driver from the USB subsystem */787usb_deregister(&dib0700_driver);788}789790module_init (dib0700_module_init);791module_exit (dib0700_module_exit);792793MODULE_AUTHOR("Patrick Boettcher <[email protected]>");794MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");795MODULE_VERSION("1.0");796MODULE_LICENSE("GPL");797798799