Path: blob/master/drivers/media/dvb/dvb-usb/af9005.c
15112 views
/* DVB USB compliant Linux driver for the Afatech 90051* USB1.1 DVB-T receiver.2*3* Copyright (C) 2007 Luca Olivetti ([email protected])4*5* Thanks to Afatech who kindly provided information.6*7* This program is free software; you can redistribute it and/or modify8* it under the terms of the GNU General Public License as published by9* the Free Software Foundation; either version 2 of the License, or10* (at your option) any later version.11*12* This program is distributed in the hope that it will be useful,13* but WITHOUT ANY WARRANTY; without even the implied warranty of14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15* GNU General Public License for more details.16*17* You should have received a copy of the GNU General Public License18* along with this program; if not, write to the Free Software19* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.20*21* see Documentation/dvb/REDME.dvb-usb for more information22*/23#include "af9005.h"2425/* debug */26int dvb_usb_af9005_debug;27module_param_named(debug, dvb_usb_af9005_debug, int, 0644);28MODULE_PARM_DESC(debug,29"set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."30DVB_USB_DEBUG_STATUS);31/* enable obnoxious led */32int dvb_usb_af9005_led = 1;33module_param_named(led, dvb_usb_af9005_led, bool, 0644);34MODULE_PARM_DESC(led, "enable led (default: 1).");3536/* eeprom dump */37static int dvb_usb_af9005_dump_eeprom;38module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);39MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");4041DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);4243/* remote control decoder */44static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,45u32 *event, int *state);46static void *rc_keys;47static int *rc_keys_size;4849u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };5051struct af9005_device_state {52u8 sequence;53int led_state;54};5556static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,57int readwrite, int type, u8 * values, int len)58{59struct af9005_device_state *st = d->priv;60u8 obuf[16] = { 0 };61u8 ibuf[17] = { 0 };62u8 command;63int i;64int ret;6566if (len < 1) {67err("generic read/write, less than 1 byte. Makes no sense.");68return -EINVAL;69}70if (len > 8) {71err("generic read/write, more than 8 bytes. Not supported.");72return -EINVAL;73}7475obuf[0] = 14; /* rest of buffer length low */76obuf[1] = 0; /* rest of buffer length high */7778obuf[2] = AF9005_REGISTER_RW; /* register operation */79obuf[3] = 12; /* rest of buffer length */8081obuf[4] = st->sequence++; /* sequence number */8283obuf[5] = (u8) (reg >> 8); /* register address */84obuf[6] = (u8) (reg & 0xff);8586if (type == AF9005_OFDM_REG) {87command = AF9005_CMD_OFDM_REG;88} else {89command = AF9005_CMD_TUNER;90}9192if (len > 1)93command |=94AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3;95command |= readwrite;96if (readwrite == AF9005_CMD_WRITE)97for (i = 0; i < len; i++)98obuf[8 + i] = values[i];99else if (type == AF9005_TUNER_REG)100/* read command for tuner, the first byte contains the i2c address */101obuf[8] = values[0];102obuf[7] = command;103104ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 17, 0);105if (ret)106return ret;107108/* sanity check */109if (ibuf[2] != AF9005_REGISTER_RW_ACK) {110err("generic read/write, wrong reply code.");111return -EIO;112}113if (ibuf[3] != 0x0d) {114err("generic read/write, wrong length in reply.");115return -EIO;116}117if (ibuf[4] != obuf[4]) {118err("generic read/write, wrong sequence in reply.");119return -EIO;120}121/*122Windows driver doesn't check these fields, in fact sometimes123the register in the reply is different that what has been sent124125if (ibuf[5] != obuf[5] || ibuf[6] != obuf[6]) {126err("generic read/write, wrong register in reply.");127return -EIO;128}129if (ibuf[7] != command) {130err("generic read/write wrong command in reply.");131return -EIO;132}133*/134if (ibuf[16] != 0x01) {135err("generic read/write wrong status code in reply.");136return -EIO;137}138if (readwrite == AF9005_CMD_READ)139for (i = 0; i < len; i++)140values[i] = ibuf[8 + i];141142return 0;143144}145146int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value)147{148int ret;149deb_reg("read register %x ", reg);150ret = af9005_generic_read_write(d, reg,151AF9005_CMD_READ, AF9005_OFDM_REG,152value, 1);153if (ret)154deb_reg("failed\n");155else156deb_reg("value %x\n", *value);157return ret;158}159160int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,161u8 * values, int len)162{163int ret;164deb_reg("read %d registers %x ", len, reg);165ret = af9005_generic_read_write(d, reg,166AF9005_CMD_READ, AF9005_OFDM_REG,167values, len);168if (ret)169deb_reg("failed\n");170else171debug_dump(values, len, deb_reg);172return ret;173}174175int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value)176{177int ret;178u8 temp = value;179deb_reg("write register %x value %x ", reg, value);180ret = af9005_generic_read_write(d, reg,181AF9005_CMD_WRITE, AF9005_OFDM_REG,182&temp, 1);183if (ret)184deb_reg("failed\n");185else186deb_reg("ok\n");187return ret;188}189190int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,191u8 * values, int len)192{193int ret;194deb_reg("write %d registers %x values ", len, reg);195debug_dump(values, len, deb_reg);196197ret = af9005_generic_read_write(d, reg,198AF9005_CMD_WRITE, AF9005_OFDM_REG,199values, len);200if (ret)201deb_reg("failed\n");202else203deb_reg("ok\n");204return ret;205}206207int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,208u8 len, u8 * value)209{210u8 temp;211int ret;212deb_reg("read bits %x %x %x", reg, pos, len);213ret = af9005_read_ofdm_register(d, reg, &temp);214if (ret) {215deb_reg(" failed\n");216return ret;217}218*value = (temp >> pos) & regmask[len - 1];219deb_reg(" value %x\n", *value);220return 0;221222}223224int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,225u8 len, u8 value)226{227u8 temp, mask;228int ret;229deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value);230if (pos == 0 && len == 8)231return af9005_write_ofdm_register(d, reg, value);232ret = af9005_read_ofdm_register(d, reg, &temp);233if (ret)234return ret;235mask = regmask[len - 1] << pos;236temp = (temp & ~mask) | ((value << pos) & mask);237return af9005_write_ofdm_register(d, reg, temp);238239}240241static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d,242u16 reg, u8 * values, int len)243{244return af9005_generic_read_write(d, reg,245AF9005_CMD_READ, AF9005_TUNER_REG,246values, len);247}248249static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d,250u16 reg, u8 * values, int len)251{252return af9005_generic_read_write(d, reg,253AF9005_CMD_WRITE,254AF9005_TUNER_REG, values, len);255}256257int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,258u8 * values, int len)259{260/* don't let the name of this function mislead you: it's just used261as an interface from the firmware to the i2c bus. The actual262i2c addresses are contained in the data */263int ret, i, done = 0, fail = 0;264u8 temp;265ret = af9005_usb_write_tuner_registers(d, reg, values, len);266if (ret)267return ret;268if (reg != 0xffff) {269/* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */270for (i = 0; i < 200; i++) {271ret =272af9005_read_ofdm_register(d,273xd_I2C_i2c_m_status_wdat_done,274&temp);275if (ret)276return ret;277done = temp & (regmask[i2c_m_status_wdat_done_len - 1]278<< i2c_m_status_wdat_done_pos);279if (done)280break;281fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1]282<< i2c_m_status_wdat_fail_pos);283if (fail)284break;285msleep(50);286}287if (i == 200)288return -ETIMEDOUT;289if (fail) {290/* clear write fail bit */291af9005_write_register_bits(d,292xd_I2C_i2c_m_status_wdat_fail,293i2c_m_status_wdat_fail_pos,294i2c_m_status_wdat_fail_len,2951);296return -EIO;297}298/* clear write done bit */299ret =300af9005_write_register_bits(d,301xd_I2C_i2c_m_status_wdat_fail,302i2c_m_status_wdat_done_pos,303i2c_m_status_wdat_done_len, 1);304if (ret)305return ret;306}307return 0;308}309310int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr,311u8 * values, int len)312{313/* don't let the name of this function mislead you: it's just used314as an interface from the firmware to the i2c bus. The actual315i2c addresses are contained in the data */316int ret, i;317u8 temp, buf[2];318319buf[0] = addr; /* tuner i2c address */320buf[1] = values[0]; /* tuner register */321322values[0] = addr + 0x01; /* i2c read address */323324if (reg == APO_REG_I2C_RW_SILICON_TUNER) {325/* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */326ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2);327if (ret)328return ret;329}330331/* send read command to ofsm */332ret = af9005_usb_read_tuner_registers(d, reg, values, 1);333if (ret)334return ret;335336/* check if read done */337for (i = 0; i < 200; i++) {338ret = af9005_read_ofdm_register(d, 0xa408, &temp);339if (ret)340return ret;341if (temp & 0x01)342break;343msleep(50);344}345if (i == 200)346return -ETIMEDOUT;347348/* clear read done bit (by writing 1) */349ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1);350if (ret)351return ret;352353/* get read data (available from 0xa400) */354for (i = 0; i < len; i++) {355ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp);356if (ret)357return ret;358values[i] = temp;359}360return 0;361}362363static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg,364u8 * data, int len)365{366int ret, i;367u8 buf[3];368deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr,369reg, len);370debug_dump(data, len, deb_i2c);371372for (i = 0; i < len; i++) {373buf[0] = i2caddr;374buf[1] = reg + (u8) i;375buf[2] = data[i];376ret =377af9005_write_tuner_registers(d,378APO_REG_I2C_RW_SILICON_TUNER,379buf, 3);380if (ret) {381deb_i2c("i2c_write failed\n");382return ret;383}384}385deb_i2c("i2c_write ok\n");386return 0;387}388389static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg,390u8 * data, int len)391{392int ret, i;393u8 temp;394deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len);395for (i = 0; i < len; i++) {396temp = reg + i;397ret =398af9005_read_tuner_registers(d,399APO_REG_I2C_RW_SILICON_TUNER,400i2caddr, &temp, 1);401if (ret) {402deb_i2c("i2c_read failed\n");403return ret;404}405data[i] = temp;406}407deb_i2c("i2c data read: ");408debug_dump(data, len, deb_i2c);409return 0;410}411412static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],413int num)414{415/* only implements what the mt2060 module does, don't know how416to make it really generic */417struct dvb_usb_device *d = i2c_get_adapdata(adap);418int ret;419u8 reg, addr;420u8 *value;421422if (mutex_lock_interruptible(&d->i2c_mutex) < 0)423return -EAGAIN;424425if (num > 2)426warn("more than 2 i2c messages at a time is not handled yet. TODO.");427428if (num == 2) {429/* reads a single register */430reg = *msg[0].buf;431addr = msg[0].addr;432value = msg[1].buf;433ret = af9005_i2c_read(d, addr, reg, value, 1);434if (ret == 0)435ret = 2;436} else {437/* write one or more registers */438reg = msg[0].buf[0];439addr = msg[0].addr;440value = &msg[0].buf[1];441ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1);442if (ret == 0)443ret = 1;444}445446mutex_unlock(&d->i2c_mutex);447return ret;448}449450static u32 af9005_i2c_func(struct i2c_adapter *adapter)451{452return I2C_FUNC_I2C;453}454455static struct i2c_algorithm af9005_i2c_algo = {456.master_xfer = af9005_i2c_xfer,457.functionality = af9005_i2c_func,458};459460int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,461int wlen, u8 * rbuf, int rlen)462{463struct af9005_device_state *st = d->priv;464465int ret, i, packet_len;466u8 buf[64];467u8 ibuf[64];468469if (wlen < 0) {470err("send command, wlen less than 0 bytes. Makes no sense.");471return -EINVAL;472}473if (wlen > 54) {474err("send command, wlen more than 54 bytes. Not supported.");475return -EINVAL;476}477if (rlen > 54) {478err("send command, rlen more than 54 bytes. Not supported.");479return -EINVAL;480}481packet_len = wlen + 5;482buf[0] = (u8) (packet_len & 0xff);483buf[1] = (u8) ((packet_len & 0xff00) >> 8);484485buf[2] = 0x26; /* packet type */486buf[3] = wlen + 3;487buf[4] = st->sequence++;488buf[5] = command;489buf[6] = wlen;490for (i = 0; i < wlen; i++)491buf[7 + i] = wbuf[i];492ret = dvb_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0);493if (ret)494return ret;495if (ibuf[2] != 0x27) {496err("send command, wrong reply code.");497return -EIO;498}499if (ibuf[4] != buf[4]) {500err("send command, wrong sequence in reply.");501return -EIO;502}503if (ibuf[5] != 0x01) {504err("send command, wrong status code in reply.");505return -EIO;506}507if (ibuf[6] != rlen) {508err("send command, invalid data length in reply.");509return -EIO;510}511for (i = 0; i < rlen; i++)512rbuf[i] = ibuf[i + 7];513return 0;514}515516int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values,517int len)518{519struct af9005_device_state *st = d->priv;520u8 obuf[16], ibuf[14];521int ret, i;522523memset(obuf, 0, sizeof(obuf));524memset(ibuf, 0, sizeof(ibuf));525526obuf[0] = 14; /* length of rest of packet low */527obuf[1] = 0; /* length of rest of packer high */528529obuf[2] = 0x2a; /* read/write eeprom */530531obuf[3] = 12; /* size */532533obuf[4] = st->sequence++;534535obuf[5] = 0; /* read */536537obuf[6] = len;538obuf[7] = address;539ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 14, 0);540if (ret)541return ret;542if (ibuf[2] != 0x2b) {543err("Read eeprom, invalid reply code");544return -EIO;545}546if (ibuf[3] != 10) {547err("Read eeprom, invalid reply length");548return -EIO;549}550if (ibuf[4] != obuf[4]) {551err("Read eeprom, wrong sequence in reply ");552return -EIO;553}554if (ibuf[5] != 1) {555err("Read eeprom, wrong status in reply ");556return -EIO;557}558for (i = 0; i < len; i++) {559values[i] = ibuf[6 + i];560}561return 0;562}563564static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply)565{566u8 buf[FW_BULKOUT_SIZE + 2];567u16 checksum;568int act_len, i, ret;569memset(buf, 0, sizeof(buf));570buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);571buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);572switch (type) {573case FW_CONFIG:574buf[2] = 0x11;575buf[3] = 0x04;576buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */577buf[5] = 0x03;578checksum = buf[4] + buf[5];579buf[6] = (u8) ((checksum >> 8) & 0xff);580buf[7] = (u8) (checksum & 0xff);581break;582case FW_CONFIRM:583buf[2] = 0x11;584buf[3] = 0x04;585buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */586buf[5] = 0x01;587checksum = buf[4] + buf[5];588buf[6] = (u8) ((checksum >> 8) & 0xff);589buf[7] = (u8) (checksum & 0xff);590break;591case FW_BOOT:592buf[2] = 0x10;593buf[3] = 0x08;594buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */595buf[5] = 0x97;596buf[6] = 0xaa;597buf[7] = 0x55;598buf[8] = 0xa5;599buf[9] = 0x5a;600checksum = 0;601for (i = 4; i <= 9; i++)602checksum += buf[i];603buf[10] = (u8) ((checksum >> 8) & 0xff);604buf[11] = (u8) (checksum & 0xff);605break;606default:607err("boot packet invalid boot packet type");608return -EINVAL;609}610deb_fw(">>> ");611debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);612613ret = usb_bulk_msg(udev,614usb_sndbulkpipe(udev, 0x02),615buf, FW_BULKOUT_SIZE + 2, &act_len, 2000);616if (ret)617err("boot packet bulk message failed: %d (%d/%d)", ret,618FW_BULKOUT_SIZE + 2, act_len);619else620ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0;621if (ret)622return ret;623memset(buf, 0, 9);624ret = usb_bulk_msg(udev,625usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000);626if (ret) {627err("boot packet recv bulk message failed: %d", ret);628return ret;629}630deb_fw("<<< ");631debug_dump(buf, act_len, deb_fw);632checksum = 0;633switch (type) {634case FW_CONFIG:635if (buf[2] != 0x11) {636err("boot bad config header.");637return -EIO;638}639if (buf[3] != 0x05) {640err("boot bad config size.");641return -EIO;642}643if (buf[4] != 0x00) {644err("boot bad config sequence.");645return -EIO;646}647if (buf[5] != 0x04) {648err("boot bad config subtype.");649return -EIO;650}651for (i = 4; i <= 6; i++)652checksum += buf[i];653if (buf[7] * 256 + buf[8] != checksum) {654err("boot bad config checksum.");655return -EIO;656}657*reply = buf[6];658break;659case FW_CONFIRM:660if (buf[2] != 0x11) {661err("boot bad confirm header.");662return -EIO;663}664if (buf[3] != 0x05) {665err("boot bad confirm size.");666return -EIO;667}668if (buf[4] != 0x00) {669err("boot bad confirm sequence.");670return -EIO;671}672if (buf[5] != 0x02) {673err("boot bad confirm subtype.");674return -EIO;675}676for (i = 4; i <= 6; i++)677checksum += buf[i];678if (buf[7] * 256 + buf[8] != checksum) {679err("boot bad confirm checksum.");680return -EIO;681}682*reply = buf[6];683break;684case FW_BOOT:685if (buf[2] != 0x10) {686err("boot bad boot header.");687return -EIO;688}689if (buf[3] != 0x05) {690err("boot bad boot size.");691return -EIO;692}693if (buf[4] != 0x00) {694err("boot bad boot sequence.");695return -EIO;696}697if (buf[5] != 0x01) {698err("boot bad boot pattern 01.");699return -EIO;700}701if (buf[6] != 0x10) {702err("boot bad boot pattern 10.");703return -EIO;704}705for (i = 4; i <= 6; i++)706checksum += buf[i];707if (buf[7] * 256 + buf[8] != checksum) {708err("boot bad boot checksum.");709return -EIO;710}711break;712713}714715return 0;716}717718static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)719{720int i, packets, ret, act_len;721722u8 buf[FW_BULKOUT_SIZE + 2];723u8 reply;724725ret = af9005_boot_packet(udev, FW_CONFIG, &reply);726if (ret)727return ret;728if (reply != 0x01) {729err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply);730return -EIO;731}732packets = fw->size / FW_BULKOUT_SIZE;733buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);734buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);735for (i = 0; i < packets; i++) {736memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE,737FW_BULKOUT_SIZE);738deb_fw(">>> ");739debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);740ret = usb_bulk_msg(udev,741usb_sndbulkpipe(udev, 0x02),742buf, FW_BULKOUT_SIZE + 2, &act_len, 1000);743if (ret) {744err("firmware download failed at packet %d with code %d", i, ret);745return ret;746}747}748ret = af9005_boot_packet(udev, FW_CONFIRM, &reply);749if (ret)750return ret;751if (reply != (u8) (packets & 0xff)) {752err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply);753return -EIO;754}755ret = af9005_boot_packet(udev, FW_BOOT, &reply);756if (ret)757return ret;758ret = af9005_boot_packet(udev, FW_CONFIG, &reply);759if (ret)760return ret;761if (reply != 0x02) {762err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply);763return -EIO;764}765766return 0;767768}769770int af9005_led_control(struct dvb_usb_device *d, int onoff)771{772struct af9005_device_state *st = d->priv;773int temp, ret;774775if (onoff && dvb_usb_af9005_led)776temp = 1;777else778temp = 0;779if (st->led_state != temp) {780ret =781af9005_write_register_bits(d, xd_p_reg_top_locken1,782reg_top_locken1_pos,783reg_top_locken1_len, temp);784if (ret)785return ret;786ret =787af9005_write_register_bits(d, xd_p_reg_top_lock1,788reg_top_lock1_pos,789reg_top_lock1_len, temp);790if (ret)791return ret;792st->led_state = temp;793}794return 0;795}796797static int af9005_frontend_attach(struct dvb_usb_adapter *adap)798{799u8 buf[8];800int i;801802/* without these calls the first commands after downloading803the firmware fail. I put these calls here to simulate804what it is done in dvb-usb-init.c.805*/806struct usb_device *udev = adap->dev->udev;807usb_clear_halt(udev, usb_sndbulkpipe(udev, 2));808usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1));809if (dvb_usb_af9005_dump_eeprom) {810printk("EEPROM DUMP\n");811for (i = 0; i < 255; i += 8) {812af9005_read_eeprom(adap->dev, i, buf, 8);813printk("ADDR %x ", i);814debug_dump(buf, 8, printk);815}816}817adap->fe = af9005_fe_attach(adap->dev);818return 0;819}820821static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)822{823struct af9005_device_state *st = d->priv;824int ret, len;825826u8 obuf[5];827u8 ibuf[256];828829*state = REMOTE_NO_KEY_PRESSED;830if (rc_decode == NULL) {831/* it shouldn't never come here */832return 0;833}834/* deb_info("rc_query\n"); */835obuf[0] = 3; /* rest of packet length low */836obuf[1] = 0; /* rest of packet lentgh high */837obuf[2] = 0x40; /* read remote */838obuf[3] = 1; /* rest of packet length */839obuf[4] = st->sequence++; /* sequence number */840ret = dvb_usb_generic_rw(d, obuf, 5, ibuf, 256, 0);841if (ret) {842err("rc query failed");843return ret;844}845if (ibuf[2] != 0x41) {846err("rc query bad header.");847return -EIO;848}849if (ibuf[4] != obuf[4]) {850err("rc query bad sequence.");851return -EIO;852}853len = ibuf[5];854if (len > 246) {855err("rc query invalid length");856return -EIO;857}858if (len > 0) {859deb_rc("rc data (%d) ", len);860debug_dump((ibuf + 6), len, deb_rc);861ret = rc_decode(d, &ibuf[6], len, event, state);862if (ret) {863err("rc_decode failed");864return ret;865} else {866deb_rc("rc_decode state %x event %x\n", *state, *event);867if (*state == REMOTE_KEY_REPEAT)868*event = d->last_event;869}870}871return 0;872}873874static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff)875{876877return 0;878}879880static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)881{882int ret;883deb_info("pid filter control onoff %d\n", onoff);884if (onoff) {885ret =886af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);887if (ret)888return ret;889ret =890af9005_write_register_bits(adap->dev,891XD_MP2IF_DMX_CTRL, 1, 1, 1);892if (ret)893return ret;894ret =895af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);896} else897ret =898af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0);899if (ret)900return ret;901deb_info("pid filter control ok\n");902return 0;903}904905static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index,906u16 pid, int onoff)907{908u8 cmd = index & 0x1f;909int ret;910deb_info("set pid filter, index %d, pid %x, onoff %d\n", index,911pid, onoff);912if (onoff) {913/* cannot use it as pid_filter_ctrl since it has to be done914before setting the first pid */915if (adap->feedcount == 1) {916deb_info("first pid set, enable pid table\n");917ret = af9005_pid_filter_control(adap, onoff);918if (ret)919return ret;920}921ret =922af9005_write_ofdm_register(adap->dev,923XD_MP2IF_PID_DATA_L,924(u8) (pid & 0xff));925if (ret)926return ret;927ret =928af9005_write_ofdm_register(adap->dev,929XD_MP2IF_PID_DATA_H,930(u8) (pid >> 8));931if (ret)932return ret;933cmd |= 0x20 | 0x40;934} else {935if (adap->feedcount == 0) {936deb_info("last pid unset, disable pid table\n");937ret = af9005_pid_filter_control(adap, onoff);938if (ret)939return ret;940}941}942ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd);943if (ret)944return ret;945deb_info("set pid ok\n");946return 0;947}948949static int af9005_identify_state(struct usb_device *udev,950struct dvb_usb_device_properties *props,951struct dvb_usb_device_description **desc,952int *cold)953{954int ret;955u8 reply;956ret = af9005_boot_packet(udev, FW_CONFIG, &reply);957if (ret)958return ret;959deb_info("result of FW_CONFIG in identify state %d\n", reply);960if (reply == 0x01)961*cold = 1;962else if (reply == 0x02)963*cold = 0;964else965return -EIO;966deb_info("Identify state cold = %d\n", *cold);967return 0;968}969970static struct dvb_usb_device_properties af9005_properties;971972static int af9005_usb_probe(struct usb_interface *intf,973const struct usb_device_id *id)974{975return dvb_usb_device_init(intf, &af9005_properties,976THIS_MODULE, NULL, adapter_nr);977}978979static struct usb_device_id af9005_usb_table[] = {980{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9005)},981{USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE)},982{USB_DEVICE(USB_VID_ANSONIC, USB_PID_ANSONIC_DVBT_USB)},983{0},984};985986MODULE_DEVICE_TABLE(usb, af9005_usb_table);987988static struct dvb_usb_device_properties af9005_properties = {989.caps = DVB_USB_IS_AN_I2C_ADAPTER,990991.usb_ctrl = DEVICE_SPECIFIC,992.firmware = "af9005.fw",993.download_firmware = af9005_download_firmware,994.no_reconnect = 1,995996.size_of_priv = sizeof(struct af9005_device_state),997998.num_adapters = 1,999.adapter = {1000{1001.caps =1002DVB_USB_ADAP_HAS_PID_FILTER |1003DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,1004.pid_filter_count = 32,1005.pid_filter = af9005_pid_filter,1006/* .pid_filter_ctrl = af9005_pid_filter_control, */1007.frontend_attach = af9005_frontend_attach,1008/* .tuner_attach = af9005_tuner_attach, */1009/* parameter for the MPEG2-data transfer */1010.stream = {1011.type = USB_BULK,1012.count = 10,1013.endpoint = 0x04,1014.u = {1015.bulk = {1016.buffersize = 4096, /* actual size seen is 3948 */1017}1018}1019},1020}1021},1022.power_ctrl = af9005_power_ctrl,1023.identify_state = af9005_identify_state,10241025.i2c_algo = &af9005_i2c_algo,10261027.rc.legacy = {1028.rc_interval = 200,1029.rc_map_table = NULL,1030.rc_map_size = 0,1031.rc_query = af9005_rc_query,1032},10331034.generic_bulk_ctrl_endpoint = 2,1035.generic_bulk_ctrl_endpoint_response = 1,10361037.num_device_descs = 3,1038.devices = {1039{.name = "Afatech DVB-T USB1.1 stick",1040.cold_ids = {&af9005_usb_table[0], NULL},1041.warm_ids = {NULL},1042},1043{.name = "TerraTec Cinergy T USB XE",1044.cold_ids = {&af9005_usb_table[1], NULL},1045.warm_ids = {NULL},1046},1047{.name = "Ansonic DVB-T USB1.1 stick",1048.cold_ids = {&af9005_usb_table[2], NULL},1049.warm_ids = {NULL},1050},1051{NULL},1052}1053};10541055/* usb specific object needed to register this driver with the usb subsystem */1056static struct usb_driver af9005_usb_driver = {1057.name = "dvb_usb_af9005",1058.probe = af9005_usb_probe,1059.disconnect = dvb_usb_device_exit,1060.id_table = af9005_usb_table,1061};10621063/* module stuff */1064static int __init af9005_usb_module_init(void)1065{1066int result;1067if ((result = usb_register(&af9005_usb_driver))) {1068err("usb_register failed. (%d)", result);1069return result;1070}1071rc_decode = symbol_request(af9005_rc_decode);1072rc_keys = symbol_request(rc_map_af9005_table);1073rc_keys_size = symbol_request(rc_map_af9005_table_size);1074if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {1075err("af9005_rc_decode function not found, disabling remote");1076af9005_properties.rc.legacy.rc_query = NULL;1077} else {1078af9005_properties.rc.legacy.rc_map_table = rc_keys;1079af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;1080}10811082return 0;1083}10841085static void __exit af9005_usb_module_exit(void)1086{1087/* release rc decode symbols */1088if (rc_decode != NULL)1089symbol_put(af9005_rc_decode);1090if (rc_keys != NULL)1091symbol_put(rc_map_af9005_table);1092if (rc_keys_size != NULL)1093symbol_put(rc_map_af9005_table_size);1094/* deregister this driver from the USB subsystem */1095usb_deregister(&af9005_usb_driver);1096}10971098module_init(af9005_usb_module_init);1099module_exit(af9005_usb_module_exit);11001101MODULE_AUTHOR("Luca Olivetti <[email protected]>");1102MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick");1103MODULE_VERSION("1.0");1104MODULE_LICENSE("GPL");110511061107