^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* DVB USB compliant Linux driver for the Afatech 9005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * USB1.1 DVB-T receiver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Thanks to Afatech who kindly provided information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "af9005.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /* debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) int dvb_usb_af9005_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) module_param_named(debug, dvb_usb_af9005_debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) MODULE_PARM_DESC(debug,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) DVB_USB_DEBUG_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* enable obnoxious led */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) bool dvb_usb_af9005_led = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) module_param_named(led, dvb_usb_af9005_led, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) MODULE_PARM_DESC(led, "enable led (default: 1).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* eeprom dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static int dvb_usb_af9005_dump_eeprom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* remote control decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 *event, int *state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void *rc_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int *rc_keys_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct af9005_device_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int led_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned char data[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int readwrite, int type, u8 * values, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct af9005_device_state *st = d->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u8 command, seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (len < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) err("generic read/write, less than 1 byte. Makes no sense.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (len > 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) err("generic read/write, more than 8 bytes. Not supported.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) mutex_lock(&d->data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) st->data[0] = 14; /* rest of buffer length low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) st->data[1] = 0; /* rest of buffer length high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) st->data[2] = AF9005_REGISTER_RW; /* register operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) st->data[3] = 12; /* rest of buffer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) st->data[4] = seq = st->sequence++; /* sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) st->data[5] = (u8) (reg >> 8); /* register address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) st->data[6] = (u8) (reg & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (type == AF9005_OFDM_REG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) command = AF9005_CMD_OFDM_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) command = AF9005_CMD_TUNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (len > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) command |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) command |= readwrite;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (readwrite == AF9005_CMD_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) st->data[8 + i] = values[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) else if (type == AF9005_TUNER_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* read command for tuner, the first byte contains the i2c address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) st->data[8] = values[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) st->data[7] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ret = dvb_usb_generic_rw(d, st->data, 16, st->data, 17, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (st->data[2] != AF9005_REGISTER_RW_ACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) err("generic read/write, wrong reply code.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (st->data[3] != 0x0d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) err("generic read/write, wrong length in reply.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (st->data[4] != seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) err("generic read/write, wrong sequence in reply.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * In thesis, both input and output buffers should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * identical values for st->data[5] to st->data[8].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * However, windows driver doesn't check these fields, in fact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * sometimes the register in the reply is different that what
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * has been sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (st->data[16] != 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) err("generic read/write wrong status code in reply.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (readwrite == AF9005_CMD_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) values[i] = st->data[8 + i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) mutex_unlock(&d->data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) deb_reg("read register %x ", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ret = af9005_generic_read_write(d, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) AF9005_CMD_READ, AF9005_OFDM_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) value, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) deb_reg("failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) deb_reg("value %x\n", *value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 * values, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) deb_reg("read %d registers %x ", len, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ret = af9005_generic_read_write(d, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) AF9005_CMD_READ, AF9005_OFDM_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) values, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) deb_reg("failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) debug_dump(values, len, deb_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u8 temp = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) deb_reg("write register %x value %x ", reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ret = af9005_generic_read_write(d, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) AF9005_CMD_WRITE, AF9005_OFDM_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) &temp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) deb_reg("failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) deb_reg("ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u8 * values, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) deb_reg("write %d registers %x values ", len, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) debug_dump(values, len, deb_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ret = af9005_generic_read_write(d, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) AF9005_CMD_WRITE, AF9005_OFDM_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) values, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) deb_reg("failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) deb_reg("ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u8 len, u8 * value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u8 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) deb_reg("read bits %x %x %x", reg, pos, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = af9005_read_ofdm_register(d, reg, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) deb_reg(" failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *value = (temp >> pos) & regmask[len - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) deb_reg(" value %x\n", *value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u8 len, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u8 temp, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (pos == 0 && len == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return af9005_write_ofdm_register(d, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = af9005_read_ofdm_register(d, reg, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mask = regmask[len - 1] << pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) temp = (temp & ~mask) | ((value << pos) & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return af9005_write_ofdm_register(d, reg, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u16 reg, u8 * values, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return af9005_generic_read_write(d, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) AF9005_CMD_READ, AF9005_TUNER_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) values, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u16 reg, u8 * values, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return af9005_generic_read_write(d, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) AF9005_CMD_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) AF9005_TUNER_REG, values, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u8 * values, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* don't let the name of this function mislead you: it's just used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) as an interface from the firmware to the i2c bus. The actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) i2c addresses are contained in the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int ret, i, done = 0, fail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) u8 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ret = af9005_usb_write_tuner_registers(d, reg, values, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (reg != 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) for (i = 0; i < 200; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) af9005_read_ofdm_register(d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) xd_I2C_i2c_m_status_wdat_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) done = temp & (regmask[i2c_m_status_wdat_done_len - 1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) << i2c_m_status_wdat_done_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) << i2c_m_status_wdat_fail_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (fail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (i == 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (fail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* clear write fail bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) af9005_write_register_bits(d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) xd_I2C_i2c_m_status_wdat_fail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) i2c_m_status_wdat_fail_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) i2c_m_status_wdat_fail_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* clear write done bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) af9005_write_register_bits(d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) xd_I2C_i2c_m_status_wdat_fail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) i2c_m_status_wdat_done_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) i2c_m_status_wdat_done_len, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u8 * values, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* don't let the name of this function mislead you: it's just used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) as an interface from the firmware to the i2c bus. The actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) i2c addresses are contained in the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u8 temp, buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) buf[0] = addr; /* tuner i2c address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) buf[1] = values[0]; /* tuner register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) values[0] = addr + 0x01; /* i2c read address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (reg == APO_REG_I2C_RW_SILICON_TUNER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* send read command to ofsm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ret = af9005_usb_read_tuner_registers(d, reg, values, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* check if read done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) for (i = 0; i < 200; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ret = af9005_read_ofdm_register(d, 0xa408, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (temp & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (i == 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* clear read done bit (by writing 1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* get read data (available from 0xa400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) values[i] = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) u8 * data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) reg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) debug_dump(data, len, deb_i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) buf[0] = i2caddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) buf[1] = reg + (u8) i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) buf[2] = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) af9005_write_tuner_registers(d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) APO_REG_I2C_RW_SILICON_TUNER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) deb_i2c("i2c_write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) deb_i2c("i2c_write ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) u8 * data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) u8 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) temp = reg + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) af9005_read_tuner_registers(d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) APO_REG_I2C_RW_SILICON_TUNER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) i2caddr, &temp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) deb_i2c("i2c_read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) data[i] = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) deb_i2c("i2c data read: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) debug_dump(data, len, deb_i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* only implements what the mt2060 module does, don't know how
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) to make it really generic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct dvb_usb_device *d = i2c_get_adapdata(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) u8 reg, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) u8 *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (num > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) warn("more than 2 i2c messages at a time is not handled yet. TODO.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (num == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* reads a single register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) reg = *msg[0].buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) addr = msg[0].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) value = msg[1].buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ret = af9005_i2c_read(d, addr, reg, value, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ret = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* write one or more registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) reg = msg[0].buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) addr = msg[0].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) value = &msg[0].buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) mutex_unlock(&d->i2c_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static u32 af9005_i2c_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return I2C_FUNC_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static struct i2c_algorithm af9005_i2c_algo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .master_xfer = af9005_i2c_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .functionality = af9005_i2c_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int wlen, u8 * rbuf, int rlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct af9005_device_state *st = d->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int ret, i, packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) u8 seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (wlen < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) err("send command, wlen less than 0 bytes. Makes no sense.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (wlen > 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) err("send command, wlen more than 54 bytes. Not supported.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (rlen > 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) err("send command, rlen more than 54 bytes. Not supported.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) packet_len = wlen + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) mutex_lock(&d->data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) st->data[0] = (u8) (packet_len & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) st->data[1] = (u8) ((packet_len & 0xff00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) st->data[2] = 0x26; /* packet type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) st->data[3] = wlen + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) st->data[4] = seq = st->sequence++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) st->data[5] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) st->data[6] = wlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) for (i = 0; i < wlen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) st->data[7 + i] = wbuf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = dvb_usb_generic_rw(d, st->data, wlen + 7, st->data, rlen + 7, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (st->data[2] != 0x27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) err("send command, wrong reply code.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } else if (st->data[4] != seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) err("send command, wrong sequence in reply.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) } else if (st->data[5] != 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) err("send command, wrong status code in reply.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) } else if (st->data[6] != rlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) err("send command, invalid data length in reply.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) for (i = 0; i < rlen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) rbuf[i] = st->data[i + 7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) mutex_unlock(&d->data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct af9005_device_state *st = d->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u8 seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mutex_lock(&d->data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) memset(st->data, 0, sizeof(st->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) st->data[0] = 14; /* length of rest of packet low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) st->data[1] = 0; /* length of rest of packer high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) st->data[2] = 0x2a; /* read/write eeprom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) st->data[3] = 12; /* size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) st->data[4] = seq = st->sequence++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) st->data[5] = 0; /* read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) st->data[6] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) st->data[7] = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ret = dvb_usb_generic_rw(d, st->data, 16, st->data, 14, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (st->data[2] != 0x2b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) err("Read eeprom, invalid reply code");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) } else if (st->data[3] != 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) err("Read eeprom, invalid reply length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) } else if (st->data[4] != seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) err("Read eeprom, wrong sequence in reply ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) } else if (st->data[5] != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) err("Read eeprom, wrong status in reply ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) values[i] = st->data[6 + i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) mutex_unlock(&d->data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static int af9005_boot_packet(struct usb_device *udev, int type, u8 *reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) u8 *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u16 checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int act_len = 0, i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) memset(buf, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) case FW_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) buf[2] = 0x11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) buf[3] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) buf[5] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) checksum = buf[4] + buf[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) buf[6] = (u8) ((checksum >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) buf[7] = (u8) (checksum & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) case FW_CONFIRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) buf[2] = 0x11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) buf[3] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) buf[5] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) checksum = buf[4] + buf[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) buf[6] = (u8) ((checksum >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) buf[7] = (u8) (checksum & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) case FW_BOOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) buf[2] = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) buf[3] = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) buf[5] = 0x97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) buf[6] = 0xaa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) buf[7] = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) buf[8] = 0xa5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) buf[9] = 0x5a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) for (i = 4; i <= 9; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) checksum += buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) buf[10] = (u8) ((checksum >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) buf[11] = (u8) (checksum & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) err("boot packet invalid boot packet type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) deb_fw(">>> ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ret = usb_bulk_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) usb_sndbulkpipe(udev, 0x02),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) buf, FW_BULKOUT_SIZE + 2, &act_len, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) err("boot packet bulk message failed: %d (%d/%d)", ret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) FW_BULKOUT_SIZE + 2, act_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) memset(buf, 0, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ret = usb_bulk_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) err("boot packet recv bulk message failed: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) deb_fw("<<< ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) debug_dump(buf, act_len, deb_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case FW_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (buf[2] != 0x11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) err("boot bad config header.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (buf[3] != 0x05) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) err("boot bad config size.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (buf[4] != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) err("boot bad config sequence.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (buf[5] != 0x04) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) err("boot bad config subtype.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) for (i = 4; i <= 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) checksum += buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (buf[7] * 256 + buf[8] != checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) err("boot bad config checksum.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) *reply = buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) case FW_CONFIRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (buf[2] != 0x11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) err("boot bad confirm header.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (buf[3] != 0x05) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) err("boot bad confirm size.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (buf[4] != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) err("boot bad confirm sequence.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (buf[5] != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) err("boot bad confirm subtype.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) for (i = 4; i <= 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) checksum += buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (buf[7] * 256 + buf[8] != checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) err("boot bad confirm checksum.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) *reply = buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case FW_BOOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (buf[2] != 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) err("boot bad boot header.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (buf[3] != 0x05) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) err("boot bad boot size.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (buf[4] != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) err("boot bad boot sequence.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (buf[5] != 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) err("boot bad boot pattern 01.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (buf[6] != 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) err("boot bad boot pattern 10.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) for (i = 4; i <= 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) checksum += buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (buf[7] * 256 + buf[8] != checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) err("boot bad boot checksum.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int i, packets, ret, act_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) u8 reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) buf = kmalloc(FW_BULKOUT_SIZE + 2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ret = af9005_boot_packet(udev, FW_CONFIG, &reply, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) FW_BULKOUT_SIZE + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (reply != 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) packets = fw->size / FW_BULKOUT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) for (i = 0; i < packets; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) FW_BULKOUT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) deb_fw(">>> ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ret = usb_bulk_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) usb_sndbulkpipe(udev, 0x02),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) buf, FW_BULKOUT_SIZE + 2, &act_len, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) err("firmware download failed at packet %d with code %d", i, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ret = af9005_boot_packet(udev, FW_CONFIRM, &reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) buf, FW_BULKOUT_SIZE + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (reply != (u8) (packets & 0xff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ret = af9005_boot_packet(udev, FW_BOOT, &reply, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) FW_BULKOUT_SIZE + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ret = af9005_boot_packet(udev, FW_CONFIG, &reply, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) FW_BULKOUT_SIZE + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (reply != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int af9005_led_control(struct dvb_usb_device *d, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct af9005_device_state *st = d->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int temp, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (onoff && dvb_usb_af9005_led)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) temp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (st->led_state != temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) af9005_write_register_bits(d, xd_p_reg_top_locken1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) reg_top_locken1_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) reg_top_locken1_len, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) af9005_write_register_bits(d, xd_p_reg_top_lock1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) reg_top_lock1_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) reg_top_lock1_len, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) st->led_state = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static int af9005_frontend_attach(struct dvb_usb_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) u8 buf[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* without these calls the first commands after downloading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) the firmware fail. I put these calls here to simulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) what it is done in dvb-usb-init.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct usb_device *udev = adap->dev->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) usb_clear_halt(udev, usb_sndbulkpipe(udev, 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (dvb_usb_af9005_dump_eeprom) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) printk("EEPROM DUMP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) for (i = 0; i < 255; i += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) af9005_read_eeprom(adap->dev, i, buf, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) debug_dump(buf, 8, printk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) adap->fe_adap[0].fe = af9005_fe_attach(adap->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct af9005_device_state *st = d->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) int ret, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) u8 seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) *state = REMOTE_NO_KEY_PRESSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (rc_decode == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* it shouldn't never come here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) mutex_lock(&d->data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /* deb_info("rc_query\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) st->data[0] = 3; /* rest of packet length low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) st->data[1] = 0; /* rest of packet length high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) st->data[2] = 0x40; /* read remote */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) st->data[3] = 1; /* rest of packet length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) st->data[4] = seq = st->sequence++; /* sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ret = dvb_usb_generic_rw(d, st->data, 5, st->data, 256, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) err("rc query failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (st->data[2] != 0x41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) err("rc query bad header.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) } else if (st->data[4] != seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) err("rc query bad sequence.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) len = st->data[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (len > 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) err("rc query invalid length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) deb_rc("rc data (%d) ", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) debug_dump((st->data + 6), len, deb_rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) ret = rc_decode(d, &st->data[6], len, event, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) err("rc_decode failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) deb_rc("rc_decode state %x event %x\n", *state, *event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (*state == REMOTE_KEY_REPEAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) *event = d->last_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) mutex_unlock(&d->data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) deb_info("pid filter control onoff %d\n", onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (onoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) af9005_write_register_bits(adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) XD_MP2IF_DMX_CTRL, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) deb_info("pid filter control ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) u16 pid, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) u8 cmd = index & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) deb_info("set pid filter, index %d, pid %x, onoff %d\n", index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) pid, onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (onoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* cannot use it as pid_filter_ctrl since it has to be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) before setting the first pid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (adap->feedcount == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) deb_info("first pid set, enable pid table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ret = af9005_pid_filter_control(adap, onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) af9005_write_ofdm_register(adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) XD_MP2IF_PID_DATA_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) (u8) (pid & 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) af9005_write_ofdm_register(adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) XD_MP2IF_PID_DATA_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) (u8) (pid >> 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) cmd |= 0x20 | 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (adap->feedcount == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) deb_info("last pid unset, disable pid table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) ret = af9005_pid_filter_control(adap, onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) deb_info("set pid ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) static int af9005_identify_state(struct usb_device *udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) const struct dvb_usb_device_properties *props,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) const struct dvb_usb_device_description **desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) int *cold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) u8 reply, *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) buf = kmalloc(FW_BULKOUT_SIZE + 2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ret = af9005_boot_packet(udev, FW_CONFIG, &reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) buf, FW_BULKOUT_SIZE + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) deb_info("result of FW_CONFIG in identify state %d\n", reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (reply == 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) *cold = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) else if (reply == 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) *cold = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) deb_info("Identify state cold = %d\n", *cold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static struct dvb_usb_device_properties af9005_properties;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) static int af9005_usb_probe(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return dvb_usb_device_init(intf, &af9005_properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) THIS_MODULE, NULL, adapter_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) enum af9005_usb_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) AFATECH_AF9005,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) TERRATEC_AF9005,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ANSONIC_AF9005,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static struct usb_device_id af9005_usb_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) [AFATECH_AF9005] = {USB_DEVICE(USB_VID_AFATECH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) USB_PID_AFATECH_AF9005)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) [TERRATEC_AF9005] = {USB_DEVICE(USB_VID_TERRATEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) USB_PID_TERRATEC_CINERGY_T_USB_XE)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) [ANSONIC_AF9005] = {USB_DEVICE(USB_VID_ANSONIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) USB_PID_ANSONIC_DVBT_USB)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) MODULE_DEVICE_TABLE(usb, af9005_usb_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static struct dvb_usb_device_properties af9005_properties = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) .caps = DVB_USB_IS_AN_I2C_ADAPTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) .usb_ctrl = DEVICE_SPECIFIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .firmware = "af9005.fw",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .download_firmware = af9005_download_firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) .no_reconnect = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .size_of_priv = sizeof(struct af9005_device_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .num_adapters = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .adapter = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .num_frontends = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .fe = {{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .caps =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) DVB_USB_ADAP_HAS_PID_FILTER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .pid_filter_count = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .pid_filter = af9005_pid_filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* .pid_filter_ctrl = af9005_pid_filter_control, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .frontend_attach = af9005_frontend_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) /* .tuner_attach = af9005_tuner_attach, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /* parameter for the MPEG2-data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .stream = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .type = USB_BULK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .count = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .endpoint = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .u = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .bulk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .buffersize = 4096, /* actual size seen is 3948 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .power_ctrl = af9005_power_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .identify_state = af9005_identify_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .i2c_algo = &af9005_i2c_algo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .rc.legacy = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .rc_interval = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .rc_map_table = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .rc_map_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .rc_query = af9005_rc_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .generic_bulk_ctrl_endpoint = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .generic_bulk_ctrl_endpoint_response = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .num_device_descs = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .devices = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {.name = "Afatech DVB-T USB1.1 stick",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .warm_ids = {NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {.name = "TerraTec Cinergy T USB XE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) .cold_ids = {&af9005_usb_table[TERRATEC_AF9005], NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) .warm_ids = {NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {.name = "Ansonic DVB-T USB1.1 stick",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .cold_ids = {&af9005_usb_table[ANSONIC_AF9005], NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .warm_ids = {NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* usb specific object needed to register this driver with the usb subsystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static struct usb_driver af9005_usb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) .name = "dvb_usb_af9005",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) .probe = af9005_usb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) .disconnect = dvb_usb_device_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .id_table = af9005_usb_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /* module stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static int __init af9005_usb_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if ((result = usb_register(&af9005_usb_driver))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) err("usb_register failed. (%d)", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) #if IS_MODULE(CONFIG_DVB_USB_AF9005) || defined(CONFIG_DVB_USB_AF9005_REMOTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /* FIXME: convert to todays kernel IR infrastructure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) rc_decode = symbol_request(af9005_rc_decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) rc_keys = symbol_request(rc_map_af9005_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) rc_keys_size = symbol_request(rc_map_af9005_table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) err("af9005_rc_decode function not found, disabling remote");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) af9005_properties.rc.legacy.rc_query = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) af9005_properties.rc.legacy.rc_map_table = rc_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static void __exit af9005_usb_module_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /* release rc decode symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (rc_decode != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) symbol_put(af9005_rc_decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (rc_keys != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) symbol_put(rc_map_af9005_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (rc_keys_size != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) symbol_put(rc_map_af9005_table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) /* deregister this driver from the USB subsystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) usb_deregister(&af9005_usb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) module_init(af9005_usb_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) module_exit(af9005_usb_module_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) MODULE_VERSION("1.0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) MODULE_LICENSE("GPL");