/* 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/REDME.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_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen,
u8 *rbuf, u16 rlen, int delay_ms)
{
int actlen, ret = -ENOMEM;
if (wbuf == NULL || wlen == 0)
return -EINVAL;
if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
return ret;
deb_xfer(">>> ");
debug_dump(wbuf, wlen, deb_xfer);
ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
2), wbuf, wlen,
&actlen, 2000);
if (ret)
err("bulk message failed: %d (%d/%d)", ret, wlen, actlen);
else
ret = actlen != wlen ? -1 : 0;
/* an answer is expected, and no error before */
if (!ret && rbuf && rlen) {
if (delay_ms)
msleep(delay_ms);
ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
0x01), rbuf,
rlen, &actlen, 2000);
if (ret)
err("recv bulk message failed: %d", ret);
else {
deb_xfer("<<< ");
debug_dump(rbuf, actlen, deb_xfer);
}
}
mutex_unlock(&d->usb_mutex);
return ret;
}
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