/* DVB USB compliant Linux driver for the Afatech 9005
* USB1.1 DVB-T receiver.
*
* Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
*
* Thanks to Afatech who kindly provided information.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* see Documentation/dvb/README.dvb-usb for more information
*/
#include "af9005.h"
/* debug */
int dvb_usb_af9005_debug;
module_param_named(debug, dvb_usb_af9005_debug, int, 0644);
MODULE_PARM_DESC(debug,
"set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."
DVB_USB_DEBUG_STATUS);
/* enable obnoxious led */
int dvb_usb_af9005_led = 1;
module_param_named(led, dvb_usb_af9005_led, bool, 0644);
MODULE_PARM_DESC(led, "enable led (default: 1).");
/* eeprom dump */
static int dvb_usb_af9005_dump_eeprom;
module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
/* remote control decoder */
static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
u32 *event, int *state);
static void *rc_keys;
static int *rc_keys_size;
u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
struct af9005_device_state {
u8 sequence;
int led_state;
};
static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
int readwrite, int type, u8 * values, int len)
{
struct af9005_device_state *st = d->priv;
u8 obuf[16] = { 0 };
u8 ibuf[17] = { 0 };
u8 command;
int i;
int ret;
if (len < 1) {
err("generic read/write, less than 1 byte. Makes no sense.");
return -EINVAL;
}
if (len > 8) {
err("generic read/write, more than 8 bytes. Not supported.");
return -EINVAL;
}
obuf[0] = 14; /* rest of buffer length low */
obuf[1] = 0; /* rest of buffer length high */
obuf[2] = AF9005_REGISTER_RW; /* register operation */
obuf[3] = 12; /* rest of buffer length */
obuf[4] = st->sequence++; /* sequence number */
obuf[5] = (u8) (reg >> 8); /* register address */
obuf[6] = (u8) (reg & 0xff);
if (type == AF9005_OFDM_REG) {
command = AF9005_CMD_OFDM_REG;
} else {
command = AF9005_CMD_TUNER;
}
if (len > 1)
command |=
AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3;
command |= readwrite;
if (readwrite == AF9005_CMD_WRITE)
for (i = 0; i < len; i++)
obuf[8 + i] = values[i];
else if (type == AF9005_TUNER_REG)
/* read command for tuner, the first byte contains the i2c address */
obuf[8] = values[0];
obuf[7] = command;
ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 17, 0);
if (ret)
return ret;
/* sanity check */
if (ibuf[2]