From 739ff04f63ba6498b287021649cb999e639c3c83 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sun, 31 Oct 2010 16:24:19 -0300 Subject: [media] technisat-usb2: added driver for Technisat's USB2.0 DVB-S/S2 receiver This patch is adding support for Technisat's new USB2.0 DVB-S/S2 receiver device. The development was sponsored by Technisat. The Green led is toggle depending on the frontend-state. The Red LED is turned on all the time. The MAC address reading from the EEPROM along with the LRC-method to check whether its valid. Support for the IR-receiver of the Technisat USB2 box. The keys of small, black remote-control are built-in, repeated key behaviour are simulated. The i2c-mutex of the dvb-usb-structure is used as a general mutex for USB requests, as there are 3 threads racing for atomic requests consisting of multiple usb-requests. A module option is there which disables the toggling of LEDs by the driver on certain triggers. Useful when being used in a "dark" environment. [mchehab@redhat.com: Fix merge conflicts with RC renaming patches] Signed-off-by: Martin Wilks Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 8 + drivers/media/dvb/dvb-usb/Makefile | 3 + drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 2 +- drivers/media/dvb/dvb-usb/dvb-usb.h | 2 + drivers/media/dvb/dvb-usb/technisat-usb2.c | 808 +++++++++++++++++++++++++++++ 6 files changed, 823 insertions(+), 1 deletion(-) create mode 100644 drivers/media/dvb/dvb-usb/technisat-usb2.c (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 3d48ba01934..fe4f894183f 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -358,3 +358,11 @@ config DVB_USB_LME2510 select DVB_IX2505V if !DVB_FE_CUSTOMISE help Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . + +config DVB_USB_TECHNISAT_USB2 + tristate "Technisat DVB-S/S2 USB2.0 support" + depends on DVB_USB + select DVB_STB0899 if !DVB_FE_CUSTOMISE + select DVB_STB6100 if !DVB_FE_CUSTOMISE + help + Say Y here to support the Technisat USB2 DVB-S/S2 device diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 5b1d12f2d59..4bac13da0c3 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -91,6 +91,9 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o dvb-usb-lmedm04-objs = lmedm04.o obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o +dvb-usb-technisat-usb2-objs = technisat-usb2.o +obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 1a6310b6192..d0bce0445cc 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -312,4 +312,5 @@ #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac #define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001 #define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002 +#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500 #endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 23005b3cf30..f511418b144 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -246,7 +246,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) dev->map_name = d->props.rc.core.rc_codes; dev->change_protocol = d->props.rc.core.change_protocol; dev->allowed_protos = d->props.rc.core.allowed_protos; - dev->driver_type = RC_DRIVER_SCANCODE; + dev->driver_type = d->props.rc.core.driver_type; usb_to_input_id(d->udev, &dev->input_id); dev->input_name = "IR-receiver inside an USB DVB receiver"; dev->input_phys = d->rc_phys; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 65fa9268e7f..76a80968482 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -181,6 +181,7 @@ struct dvb_rc_legacy { * @rc_codes: name of rc codes table * @protocol: type of protocol(s) currently used by the driver * @allowed_protos: protocol(s) supported by the driver + * @driver_type: Used to point if a device supports raw mode * @change_protocol: callback to change protocol * @rc_query: called to query an event event. * @rc_interval: time in ms between two queries. @@ -190,6 +191,7 @@ struct dvb_rc { char *rc_codes; u64 protocol; u64 allowed_protos; + enum rc_driver_type driver_type; int (*change_protocol)(struct rc_dev *dev, u64 rc_type); char *module_name; int (*rc_query) (struct dvb_usb_device *d); diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c new file mode 100644 index 00000000000..406602a1499 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c @@ -0,0 +1,808 @@ +/* + * Linux driver for Technisat DVB-S/S2 USB 2.0 device + * + * Copyright (C) 2010 Patrick Boettcher, + * Kernel Labs Inc. PO Box 745, St James, NY 11780 + * + * Development was sponsored by Technisat Digital UK Limited, whose + * registered office is Witan Gate House 500 - 600 Witan Gate West, + * Milton Keynes, MK9 1SH + * + * 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. + * + * + * 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. + * + * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND + * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER + * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the + * GNU General Public License for more details. + */ + +#define DVB_USB_LOG_PREFIX "technisat-usb2" +#include "dvb-usb.h" + +#include "stv6110x.h" +#include "stv090x.h" + +/* module parameters */ +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, + "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \ + DVB_USB_DEBUG_STATUS); + +/* disables all LED control command and + * also does not start the signal polling thread */ +static int disable_led_control; +module_param(disable_led_control, int, 0444); +MODULE_PARM_DESC(disable_led_control, + "disable LED control of the device " + "(default: 0 - LED control is active)."); + +/* device private data */ +struct technisat_usb2_state { + struct dvb_usb_device *dev; + struct delayed_work green_led_work; + u8 power_state; + + u16 last_scan_code; +}; + +/* debug print helpers */ +#define deb_info(args...) dprintk(debug, 0x01, args) +#define deb_eeprom(args...) dprintk(debug, 0x02, args) +#define deb_i2c(args...) dprintk(debug, 0x04, args) +#define deb_rc(args...) dprintk(debug, 0x08, args) + +/* vendor requests */ +#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3 +#define SET_FRONT_END_RESET_VENDOR_REQUEST 0xB4 +#define GET_VERSION_INFO_VENDOR_REQUEST 0xB5 +#define SET_GREEN_LED_VENDOR_REQUEST 0xB6 +#define SET_RED_LED_VENDOR_REQUEST 0xB7 +#define GET_IR_DATA_VENDOR_REQUEST 0xB8 +#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST 0xB9 +#define SET_USB_REENUMERATION 0xBA + +/* i2c-access methods */ +#define I2C_SPEED_100KHZ_BIT 0x40 + +#define I2C_STATUS_NAK 7 +#define I2C_STATUS_OK 8 + +static int technisat_usb2_i2c_access(struct usb_device *udev, + u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen) +{ + u8 b[64]; + int ret, actual_length; + + deb_i2c("i2c-access: %02x, tx: ", device_addr); + debug_dump(tx, txlen, deb_i2c); + deb_i2c(" "); + + if (txlen > 62) { + err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)", + device_addr); + txlen = 62; + } + if (rxlen > 62) { + err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)", + device_addr); + txlen = 62; + } + + b[0] = I2C_SPEED_100KHZ_BIT; + b[1] = device_addr << 1; + + if (rx != NULL) { + b[0] |= rxlen; + b[1] |= 1; + } + + memcpy(&b[2], tx, txlen); + ret = usb_bulk_msg(udev, + usb_sndbulkpipe(udev, 0x01), + b, 2 + txlen, + NULL, 1000); + + if (ret < 0) { + err("i2c-error: out failed %02x = %d", device_addr, ret); + return -ENODEV; + } + + ret = usb_bulk_msg(udev, + usb_rcvbulkpipe(udev, 0x01), + b, 64, &actual_length, 1000); + if (ret < 0) { + err("i2c-error: in failed %02x = %d", device_addr, ret); + return -ENODEV; + } + + if (b[0] != I2C_STATUS_OK) { + err("i2c-error: %02x = %d", device_addr, b[0]); + /* handle tuner-i2c-nak */ + if (!(b[0] == I2C_STATUS_NAK && + device_addr == 0x60 + /* && device_is_technisat_usb2 */)) + return -ENODEV; + } + + deb_i2c("status: %d, ", b[0]); + + if (rx != NULL) { + memcpy(rx, &b[2], rxlen); + + deb_i2c("rx (%d): ", rxlen); + debug_dump(rx, rxlen, deb_i2c); + } + + deb_i2c("\n"); + + return 0; +} + +static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, + int num) +{ + int ret = 0, i; + struct dvb_usb_device *d = i2c_get_adapdata(adap); + + /* Ensure nobody else hits the i2c bus while we're sending our + sequence of messages, (such as the remote control thread) */ + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + for (i = 0; i < num; i++) { + if (i+1 < num && msg[i+1].flags & I2C_M_RD) { + ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr, + msg[i].buf, msg[i].len, + msg[i+1].buf, msg[i+1].len); + if (ret != 0) + break; + i++; + } else { + ret = technisat_usb2_i2c_access(d->udev, msg[i].addr, + msg[i].buf, msg[i].len, + NULL, 0); + if (ret != 0) + break; + } + } + + if (ret == 0) + ret = i; + + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm technisat_usb2_i2c_algo = { + .master_xfer = technisat_usb2_i2c_xfer, + .functionality = technisat_usb2_i2c_func, +}; + +#if 0 +static void technisat_usb2_frontend_reset(struct usb_device *udev) +{ + usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + SET_FRONT_END_RESET_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_OUT, + 10, 0, + NULL, 0, 500); +} +#endif + +/* LED control */ +enum technisat_usb2_led_state { + LED_OFF, + LED_BLINK, + LED_ON, + LED_UNDEFINED +}; + +static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state) +{ + int ret; + + u8 led[8] = { + red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST, + 0 + }; + + if (disable_led_control && state != LED_OFF) + return 0; + + switch (state) { + case LED_ON: + led[1] = 0x82; + break; + case LED_BLINK: + led[1] = 0x82; + if (red) { + led[2] = 0x02; + led[3] = 10; + led[4] = 10; + } else { + led[2] = 0xff; + led[3] = 50; + led[4] = 50; + } + led[5] = 1; + break; + + default: + case LED_OFF: + led[1] = 0x80; + break; + } + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), + red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_OUT, + 0, 0, + led, sizeof(led), 500); + + mutex_unlock(&d->i2c_mutex); + return ret; +} + +static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green) +{ + int ret; + u8 b = 0; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), + SET_LED_TIMER_DIVIDER_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_OUT, + (red << 8) | green, 0, + &b, 1, 500); + + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +static void technisat_usb2_green_led_control(struct work_struct *work) +{ + struct technisat_usb2_state *state = + container_of(work, struct technisat_usb2_state, green_led_work.work); + struct dvb_frontend *fe = state->dev->adapter[0].fe; + + if (state->power_state == 0) + goto schedule; + + if (fe != NULL) { + enum fe_status status; + + if (fe->ops.read_status(fe, &status) != 0) + goto schedule; + + if (status & FE_HAS_LOCK) { + u32 ber; + + if (fe->ops.read_ber(fe, &ber) != 0) + goto schedule; + + if (ber > 1000) + technisat_usb2_set_led(state->dev, 0, LED_BLINK); + else + technisat_usb2_set_led(state->dev, 0, LED_ON); + } else + technisat_usb2_set_led(state->dev, 0, LED_OFF); + } + +schedule: + schedule_delayed_work(&state->green_led_work, + msecs_to_jiffies(500)); +} + +/* method to find out whether the firmware has to be downloaded or not */ +static int technisat_usb2_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, int *cold) +{ + int ret; + u8 version[3]; + + /* first select the interface */ + if (usb_set_interface(udev, 0, 1) != 0) { + err("could not set alternate setting to 0"); + } else { + info("set alternate setting"); + } + + *cold = 0; /* by default do not download a firmware - just in case something is wrong */ + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + GET_VERSION_INFO_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_IN, + 0, 0, + version, sizeof(version), 500); + + if (ret < 0) + *cold = 1; + else { + info("firmware version: %d.%d", version[1], version[2]); + *cold = 0; + } + + return 0; +} + +/* power control */ +static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level) +{ + struct technisat_usb2_state *state = d->priv; + + state->power_state = level; + + if (disable_led_control) + return 0; + + /* green led is turned off in any case - will be turned on when tuning */ + technisat_usb2_set_led(d, 0, LED_OFF); + /* red led is turned on all the time */ + technisat_usb2_set_led(d, 1, LED_ON); + return 0; +} + +/* mac address reading - from the eeprom */ +#if 0 +static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d) +{ + u8 reg; + u8 b[16]; + int i,j; + + /* full EEPROM dump */ + for (j = 0; j < 256 * 4; j += 16) { + reg = j; + if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, ®, 1, b, 16) != 0) + break; + + deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg); + for (i = 0; i < 16; i++) + deb_eeprom("%02x ", b[i]); + deb_eeprom("\n"); + } +} +#endif + +static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length) +{ + u8 lrc = 0; + while (--length) + lrc ^= *b++; + return lrc; +} + +static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d, + u16 offset, u8 *b, u16 length, u8 tries) +{ + u8 bo = offset & 0xff; + struct i2c_msg msg[] = { + { + .addr = 0x50 | ((offset >> 8) & 0x3), + .buf = &bo, + .len = 1 + }, { + .addr = 0x50 | ((offset >> 8) & 0x3), + .flags = I2C_M_RD, + .buf = b, + .len = length + } + }; + + while (tries--) { + int status; + + if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) + break; + + status = + technisat_usb2_calc_lrc(b, length - 1) == b[length - 1]; + + if (status) + return 0; + } + + return -EREMOTEIO; +} + +#define EEPROM_MAC_START 0x3f8 +#define EEPROM_MAC_TOTAL 8 +static int technisat_usb2_read_mac_address(struct dvb_usb_device *d, + u8 mac[]) +{ + u8 buf[EEPROM_MAC_TOTAL]; + + if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START, + buf, EEPROM_MAC_TOTAL, 4) != 0) + return -ENODEV; + + memcpy(mac, buf, 6); + return 0; +} + +/* frontend attach */ +static int technisat_usb2_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + int i; + u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */ + + gpio[2] = 1; /* high - voltage ? */ + + switch (voltage) { + case SEC_VOLTAGE_13: + gpio[0] = 1; + break; + case SEC_VOLTAGE_18: + gpio[0] = 1; + gpio[1] = 1; + break; + default: + case SEC_VOLTAGE_OFF: + break; + } + + for (i = 0; i < 3; i++) + if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0) + return -EREMOTEIO; + return 0; +} + +static struct stv090x_config technisat_usb2_stv090x_config = { + .device = STV0903, + .demod_mode = STV090x_SINGLE, + .clk_mode = STV090x_CLK_EXT, + + .xtal = 8000000, + .address = 0x68, + + .ts1_mode = STV090x_TSMODE_DVBCI, + .ts1_clk = 13400000, + .ts1_tei = 1, + + .repeater_level = STV090x_RPTLEVEL_64, + + .tuner_bbgain = 6, +}; + +static struct stv6110x_config technisat_usb2_stv6110x_config = { + .addr = 0x60, + .refclk = 16000000, + .clk_div = 2, +}; + +static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a) +{ + struct usb_device *udev = a->dev->udev; + int ret; + + a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config, + &a->dev->i2c_adap, STV090x_DEMODULATOR_0); + + if (a->fe) { + struct stv6110x_devctl *ctl; + + ctl = dvb_attach(stv6110x_attach, + a->fe, + &technisat_usb2_stv6110x_config, + &a->dev->i2c_adap); + + if (ctl) { + technisat_usb2_stv090x_config.tuner_init = ctl->tuner_init; + technisat_usb2_stv090x_config.tuner_sleep = ctl->tuner_sleep; + technisat_usb2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; + technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; + technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; + technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; + technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; + technisat_usb2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; + technisat_usb2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; + technisat_usb2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; + technisat_usb2_stv090x_config.tuner_get_status = ctl->tuner_get_status; + + /* call the init function once to initialize + tuner's clock output divider and demod's + master clock */ + if (a->fe->ops.init) + a->fe->ops.init(a->fe); + + if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0) + return -EAGAIN; + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_OUT, + 0, 0, + NULL, 0, 500); + mutex_unlock(&a->dev->i2c_mutex); + + if (ret != 0) + err("could not set IF_CLK to external"); + + a->fe->ops.set_voltage = technisat_usb2_set_voltage; + + /* if everything was successful assign a nice name to the frontend */ + strlcpy(a->fe->ops.info.name, a->dev->desc->name, + sizeof(a->fe->ops.info.name)); + } else { + dvb_frontend_detach(a->fe); + a->fe = NULL; + } + } + + technisat_usb2_set_led_timer(a->dev, 1, 1); + + return a->fe == NULL ? -ENODEV : 0; +} + +/* Remote control */ + +/* the device is giving providing raw IR-signals to the host mapping + * it only to one remote control is just the default implementation + */ +#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889 +#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US) + +#define FIRMWARE_CLOCK_TICK 83333 +#define FIRMWARE_CLOCK_DIVISOR 256 + +#define IR_PERCENT_TOLERANCE 15 + +#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK) +#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR) + +#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK) +#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR) + +#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) +#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) + +#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) +#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) + +static int technisat_usb2_get_ir(struct dvb_usb_device *d) +{ + u8 buf[62], *b; + int ret; + struct ir_raw_event ev; + + buf[0] = GET_IR_DATA_VENDOR_REQUEST; + buf[1] = 0x08; + buf[2] = 0x8f; + buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT; + buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), + GET_IR_DATA_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_OUT, + 0, 0, + buf, 5, 500); + if (ret < 0) + goto unlock; + + buf[1] = 0; + buf[2] = 0; + ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), + GET_IR_DATA_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_IN, + 0x8080, 0, + buf, sizeof(buf), 500); + +unlock: + mutex_unlock(&d->i2c_mutex); + + if (ret < 0) + return ret; + + if (ret == 1) + return 0; /* no key pressed */ + + /* decoding */ + b = buf+1; + +#if 0 + deb_rc("RC: %d ", ret); + debug_dump(b, ret, deb_rc); +#endif + + ev.pulse = 0; + while (1) { + ev.pulse = !ev.pulse; + ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000; + ir_raw_event_store(d->rc_dev, &ev); + + b++; + if (*b == 0xff) { + ev.pulse = 0; + ev.duration = 888888*2; + ir_raw_event_store(d->rc_dev, &ev); + break; + } + } + + ir_raw_event_handle(d->rc_dev); + + return 1; +} + +static int technisat_usb2_rc_query(struct dvb_usb_device *d) +{ + int ret = technisat_usb2_get_ir(d); + + if (ret < 0) + return ret; + + if (ret == 0) + return 0; + + if (!disable_led_control) + technisat_usb2_set_led(d, 1, LED_BLINK); + + return 0; +} + +/* DVB-USB and USB stuff follows */ +static struct usb_device_id technisat_usb2_id_table[] = { + { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) }, + { 0 } /* Terminating entry */ +}; + +/* device description */ +static struct dvb_usb_device_properties technisat_usb2_devices = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .identify_state = technisat_usb2_identify_state, + .firmware = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw", + + .size_of_priv = sizeof(struct technisat_usb2_state), + + .i2c_algo = &technisat_usb2_i2c_algo, + + .power_ctrl = technisat_usb2_power_ctrl, + .read_mac_address = technisat_usb2_read_mac_address, + + .num_adapters = 1, + .adapter = { + { + .frontend_attach = technisat_usb2_frontend_attach, + + .stream = { + .type = USB_ISOC, + .count = 8, + .endpoint = 0x2, + .u = { + .isoc = { + .framesperurb = 32, + .framesize = 2048, + .interval = 3, + } + } + }, + + .size_of_priv = 0, + }, + }, + + .num_device_descs = 1, + .devices = { + { "Technisat SkyStar USB HD (DVB-S/S2)", + { &technisat_usb2_id_table[0], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = 100, + .rc_codes = RC_MAP_TECHNISAT_USB2, + .module_name = "technisat-usb2", + .rc_query = technisat_usb2_rc_query, + .allowed_protos = RC_TYPE_ALL, + .driver_type = RC_DRIVER_IR_RAW, + } +}; + +static int technisat_usb2_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct dvb_usb_device *dev; + + if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE, + &dev, adapter_nr) != 0) + return -ENODEV; + + if (dev) { + struct technisat_usb2_state *state = dev->priv; + state->dev = dev; + + if (!disable_led_control) { + INIT_DELAYED_WORK(&state->green_led_work, + technisat_usb2_green_led_control); + schedule_delayed_work(&state->green_led_work, + msecs_to_jiffies(500)); + } + } + + return 0; +} + +static void technisat_usb2_disconnect(struct usb_interface *intf) +{ + struct dvb_usb_device *dev = usb_get_intfdata(intf); + + /* work and stuff was only created when the device is is hot-state */ + if (dev != NULL) { + struct technisat_usb2_state *state = dev->priv; + if (state != NULL) { + cancel_rearming_delayed_work(&state->green_led_work); + flush_scheduled_work(); + } + } + + dvb_usb_device_exit(intf); +} + +static struct usb_driver technisat_usb2_driver = { + .name = "dvb_usb_technisat_usb2", + .probe = technisat_usb2_probe, + .disconnect = technisat_usb2_disconnect, + .id_table = technisat_usb2_id_table, +}; + +/* module stuff */ +static int __init technisat_usb2_module_init(void) +{ + int result = usb_register(&technisat_usb2_driver); + if (result) { + err("usb_register failed. Code %d", result); + return result; + } + + return 0; +} + +static void __exit technisat_usb2_module_exit(void) +{ + usb_deregister(&technisat_usb2_driver); +} + +module_init(technisat_usb2_module_init); +module_exit(technisat_usb2_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 4ec02ea0d88d811f61e2c7765418eff770936871 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 10 Jan 2011 21:42:12 -0200 Subject: [media] technisat-usb2: Don't use a deprecated call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/dvb/dvb-usb/technisat-usb2.c: In function ‘technisat_usb2_disconnect’: drivers/media/dvb/dvb-usb/technisat-usb2.c:770: warning: ‘cancel_rearming_delayed_work’ is deprecated (declared at include/linux/workqueue.h:421) Cc: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/technisat-usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c index 406602a1499..10151aa4923 100644 --- a/drivers/media/dvb/dvb-usb/technisat-usb2.c +++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c @@ -767,7 +767,7 @@ static void technisat_usb2_disconnect(struct usb_interface *intf) if (dev != NULL) { struct technisat_usb2_state *state = dev->priv; if (state != NULL) { - cancel_rearming_delayed_work(&state->green_led_work); + cancel_delayed_work_sync(&state->green_led_work); flush_scheduled_work(); } } -- cgit v1.2.3-70-g09d2 From 7757ddda6f4febbc52342d82440dd4f7a7d4f14f Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Mon, 3 Jan 2011 15:30:14 -0300 Subject: [media] DiB0700: add function to change I2C-speed This commit adds a function to the DiB0700 USB driver which allows drivers to change the I2C clock speed. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700.h | 2 ++ drivers/media/dvb/dvb-usb/dib0700_core.c | 42 +++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 3537d65c04b..b2a87f2c2c3 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h @@ -32,6 +32,7 @@ extern int dvb_usb_dib0700_debug; // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) +#define REQUEST_SET_I2C_PARAM 0x10 #define REQUEST_SET_RC 0x11 #define REQUEST_NEW_I2C_READ 0x12 #define REQUEST_NEW_I2C_WRITE 0x13 @@ -61,6 +62,7 @@ extern struct i2c_algorithm dib0700_i2c_algo; extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold); extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type); +extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz); extern int dib0700_device_count; extern int dvb_usb_dib0700_ir_proto; diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 98ffb40728e..ebda77dde97 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -328,6 +328,30 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, return dib0700_ctrl_wr(d, b, 10); } +int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) +{ + u16 divider; + u8 b[8]; + + if (scl_kHz == 0) + return -EINVAL; + + b[0] = REQUEST_SET_I2C_PARAM; + divider = (u16) (30000 / scl_kHz); + b[2] = (u8) (divider >> 8); + b[3] = (u8) (divider & 0xff); + divider = (u16) (72000 / scl_kHz); + b[4] = (u8) (divider >> 8); + b[5] = (u8) (divider & 0xff); + divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */ + b[6] = (u8) (divider >> 8); + b[7] = (u8) (divider & 0xff); + + deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", (b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz); + return dib0700_ctrl_wr(d, b, 8); +} + + int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) { switch (clk_MHz) { @@ -459,10 +483,20 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); - if (onoff) - st->channel_state |= 1 << adap->id; - else - st->channel_state &= ~(1 << adap->id); + st->channel_state &= ~0x3; + if ((adap->stream.props.endpoint != 2) && (adap->stream.props.endpoint != 3)) { + deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint); + if (onoff) + st->channel_state |= 1 << (adap->id); + else + st->channel_state |= 1 << ~(adap->id); + } + else { + if (onoff) + st->channel_state |= 1 << (adap->stream.props.endpoint-2); + else + st->channel_state |= 1 << (3-adap->stream.props.endpoint); + } b[2] |= st->channel_state; -- cgit v1.2.3-70-g09d2 From be9bae10ffa5aeeef051e893c3b15a5d10eb657d Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Tue, 4 Jan 2011 05:42:19 -0300 Subject: [media] DiB0700: add support for several board-layouts This patchs adds support for DiBcom's NIM8096MD, NIM9090M, NIM9090MD, NIM7090, TFE7090PVR (no diversity) reference designs. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_core.c | 4 +- drivers/media/dvb/dvb-usb/dib0700_devices.c | 1401 ++++++++++++++++++++++++--- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 5 + 3 files changed, 1280 insertions(+), 130 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index ebda77dde97..9ab57132b44 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -186,7 +186,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, msg[i].len, USB_CTRL_GET_TIMEOUT); if (result < 0) { - err("i2c read error (status = %d)\n", result); + deb_info("i2c read error (status = %d)\n", result); break; } @@ -215,7 +215,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, 0, 0, buf, msg[i].len + 4, USB_CTRL_GET_TIMEOUT); if (result < 0) { - err("i2c write error (status = %d)\n", result); + deb_info("i2c write error (status = %d)\n", result); break; } } diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 193cdb77b76..2b919034db8 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -12,6 +12,7 @@ #include "dib7000m.h" #include "dib7000p.h" #include "dib8000.h" +#include "dib9000.h" #include "mt2060.h" #include "mt2266.h" #include "tuner-xc2028.h" @@ -29,6 +30,7 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif struct dib0700_adapter_state { int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); + const struct firmware *frontend_firmware; }; /* Hauppauge Nova-T 500 (aka Bristol) @@ -1243,13 +1245,13 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { - return dib8000_pid_filter(adapter->fe, index, pid, onoff); + return dib8000_pid_filter(adapter->fe, index, pid, onoff); } static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, - int onoff) + int onoff) { - return dib8000_pid_filter_ctrl(adapter->fe, onoff); + return dib8000_pid_filter_ctrl(adapter->fe, onoff); } /* STK807x */ @@ -1321,11 +1323,11 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) /* STK8096GP */ struct dibx000_agc_config dib8090_agc_config[2] = { - { + { BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, - * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, - * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), @@ -1362,12 +1364,12 @@ struct dibx000_agc_config dib8090_agc_config[2] = { 51, 0, - }, - { + }, + { BAND_CBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, - * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, - * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), @@ -1404,159 +1406,1098 @@ struct dibx000_agc_config dib8090_agc_config[2] = { 51, 0, - } + } }; static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { - 54000, 13500, - 1, 18, 3, 1, 0, - 0, 0, 1, 1, 2, - (3 << 14) | (1 << 12) | (599 << 0), - (0 << 25) | 0, - 20199727, - 12000000, + 54000, 13500, + 1, 18, 3, 1, 0, + 0, 0, 1, 1, 2, + (3 << 14) | (1 << 12) | (599 << 0), + (0 << 25) | 0, + 20199727, + 12000000, }; static int dib8090_get_adc_power(struct dvb_frontend *fe) { - return dib8000_get_adc_power(fe, 1); + return dib8000_get_adc_power(fe, 1); +} + +static struct dib8000_config dib809x_dib8000_config[2] = { + { + .output_mpeg2_in_188_bytes = 1, + + .agc_config_count = 2, + .agc = dib8090_agc_config, + .agc_control = dib0090_dcc_freq, + .pll = &dib8090_pll_config_12mhz, + .tuner_is_baseband = 1, + + .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, + + .hostbus_diversity = 1, + .div_cfg = 0x31, + .output_mode = OUTMODE_MPEG2_FIFO, + .drives = 0x2d98, + .diversity_delay = 48, + .refclksel = 3, + },{ + .output_mpeg2_in_188_bytes = 1, + + .agc_config_count = 2, + .agc = dib8090_agc_config, + .agc_control = dib0090_dcc_freq, + .pll = &dib8090_pll_config_12mhz, + .tuner_is_baseband = 1, + + .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, + + .hostbus_diversity = 1, + .div_cfg = 0x31, + .output_mode = OUTMODE_DIVERSITY, + .drives = 0x2d08, + .diversity_delay = 1, + .refclksel = 3, + } +}; + +static struct dib0090_wbd_slope dib8090_wbd_table[] = { + /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */ + { 120, 0, 500, 0, 500, 4 }, /* CBAND */ + { 170, 0, 450, 0, 450, 4 }, /* CBAND */ + { 380, 48, 373, 28, 259, 6 }, /* VHF */ + { 860, 34, 700, 36, 616, 6 }, /* high UHF */ + { 0xFFFF, 34, 700, 36, 616, 6 }, /* default */ +}; + +static struct dib0090_config dib809x_dib0090_config = { + .io.pll_bypass = 1, + .io.pll_range = 1, + .io.pll_prediv = 1, + .io.pll_loopdiv = 20, + .io.adc_clock_ratio = 8, + .io.pll_int_loop_filt = 0, + .io.clock_khz = 12000, + .reset = dib80xx_tuner_reset, + .sleep = dib80xx_tuner_sleep, + .clkouttobamse = 1, + .analog_output = 1, + .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS, + .use_pwm_agc = 1, + .clkoutdrive = 1, + .get_adc_power = dib8090_get_adc_power, + .freq_offset_khz_uhf = -63, + .freq_offset_khz_vhf = -143, + .wbd = dib8090_wbd_table, + .fref_clock_ratio = 6, +}; + +static int dib8096_set_param_override(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fep) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u16 target; + int ret = 0; + enum frontend_tune_state tune_state = CT_SHUTDOWN; + u16 ltgain, rf_gain_limit; + + ret = state->set_param_save(fe, fep); + if (ret < 0) + return ret; + + target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; + dib8000_set_wbd_ref(fe, target); + + + if (band == BAND_CBAND) { + deb_info("tuning in CBAND - soft-AGC startup\n"); + /* TODO specific wbd target for dib0090 - needed for startup ? */ + dib0090_set_tune_state(fe, CT_AGC_START); + do { + ret = dib0090_gain_control(fe); + msleep(ret); + tune_state = dib0090_get_tune_state(fe); + if (tune_state == CT_AGC_STEP_0) + dib8000_set_gpio(fe, 6, 0, 1); + else if (tune_state == CT_AGC_STEP_1) { + dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); + if (rf_gain_limit == 0) + dib8000_set_gpio(fe, 6, 0, 0); + } + } while (tune_state < CT_AGC_STOP); + dib0090_pwm_gain_reset(fe); + dib8000_pwm_agc_reset(fe); + dib8000_set_tune_state(fe, CT_DEMOD_START); + } else { + deb_info("not tuning in CBAND - standard AGC startup\n"); + dib0090_pwm_gain_reset(fe); + } + + return 0; +} + +static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + + if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) + return -ENODEV; + + st->set_param_save = adap->fe->ops.tuner_ops.set_params; + adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; + return 0; +} + +static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) +{ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); + + adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); + + return adap->fe == NULL ? -ENODEV : 0; +} + +static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c; + struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe, 1); + + if (fe_slave) { + tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1); + if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL) + return -ENODEV; + fe_slave->dvb = adap->fe->dvb; + fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override; + } + tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) + return -ENODEV; + + st->set_param_save = adap->fe->ops.tuner_ops.set_params; + adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; + + return 0; +} + +static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dvb_frontend *fe_slave; + + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(1000); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80); + + adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); + if (adap->fe == NULL) + return -ENODEV; + + fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]); + dib8000_set_slave_frontend(adap->fe, fe_slave); + + return fe_slave == NULL ? -ENODEV : 0; +} + +/* STK9090M */ +static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) +{ + return dib9000_fw_pid_filter(adapter->fe, index, pid, onoff); +} + +static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) +{ + return dib9000_fw_pid_filter_ctrl(adapter->fe, onoff); +} + +static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff) +{ + return dib9000_set_gpio(fe, 5, 0, !onoff); +} + +static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff) +{ + return dib9000_set_gpio(fe, 0, 0, onoff); +} + +static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len) +{ + u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 }; + u8 rb[2]; + struct i2c_msg msg[2] = { + {.addr = 0x1e >> 1,.flags = 0,.buf = wb,.len = 2}, + {.addr = 0x1e >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2}, + }; + u8 index_data; + + dibx000_i2c_set_speed(i2c, 250); + + if (i2c_transfer(i2c, msg, 2) != 2) + return -EIO; + + switch (rb[0] << 8 | rb[1]) { + case 0: + deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n"); + return -EIO; + case 1: + deb_info("Found DiB0170 rev2"); + break; + case 2: + deb_info("Found DiB0190 rev2"); + break; + default: + deb_info("DiB01x0 not found"); + return -EIO; + } + + for (index_data = 0; index_data < len; index_data += 2) { + wb[2] = (data[index_data + 1] >> 8) & 0xff; + wb[3] = (data[index_data + 1]) & 0xff; + + if (data[index_data] == 0) { + wb[0] = (data[index_data] >> 8) & 0xff; + wb[1] = (data[index_data]) & 0xff; + msg[0].len = 2; + if (i2c_transfer(i2c, msg, 2) != 2) + return -EIO; + wb[2] |= rb[0]; + wb[3] |= rb[1] & ~(3 << 4); + } + + wb[0] = (data[index_data ] >> 8)&0xff; + wb[1] = (data[index_data ] )&0xff; + msg[0].len = 4; + if (i2c_transfer(i2c, &msg[0], 1) != 1) + return -EIO; + } + return 0; +} + +static struct dib9000_config stk9090m_config = { + .output_mpeg2_in_188_bytes = 1, + .output_mode = OUTMODE_MPEG2_FIFO, + .vcxo_timer = 279620, + .timing_frequency = 20452225, + .demod_clock_khz = 60000, + .xtal_clock_khz = 30000, + .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0), + .subband = { + 2, + { + { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */ + { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */ + { 0 }, + }, + }, + .gpio_function = { + { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 }, + { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 }, + }, +}; + +static struct dib9000_config nim9090md_config[2] = { + { + .output_mpeg2_in_188_bytes = 1, + .output_mode = OUTMODE_MPEG2_FIFO, + .vcxo_timer = 279620, + .timing_frequency = 20452225, + .demod_clock_khz = 60000, + .xtal_clock_khz = 30000, + .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0), + }, { + .output_mpeg2_in_188_bytes = 1, + .output_mode = OUTMODE_DIVERSITY, + .vcxo_timer = 279620, + .timing_frequency = 20452225, + .demod_clock_khz = 60000, + .xtal_clock_khz = 30000, + .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0), + .subband = { + 2, + { + { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */ + { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */ + { 0 }, + }, + }, + .gpio_function = { + { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 }, + { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 }, + }, + } +}; + +static struct dib0090_config dib9090_dib0090_config = { + .io.pll_bypass = 0, + .io.pll_range = 1, + .io.pll_prediv = 1, + .io.pll_loopdiv = 8, + .io.adc_clock_ratio = 8, + .io.pll_int_loop_filt = 0, + .io.clock_khz = 30000, + .reset = dib90x0_tuner_reset, + .sleep = dib90x0_tuner_sleep, + .clkouttobamse = 0, + .analog_output = 0, + .use_pwm_agc = 0, + .clkoutdrive = 0, + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = 0, +}; + +static struct dib0090_config nim9090md_dib0090_config[2] = { + { + .io.pll_bypass = 0, + .io.pll_range = 1, + .io.pll_prediv = 1, + .io.pll_loopdiv = 8, + .io.adc_clock_ratio = 8, + .io.pll_int_loop_filt = 0, + .io.clock_khz = 30000, + .reset = dib90x0_tuner_reset, + .sleep = dib90x0_tuner_sleep, + .clkouttobamse = 1, + .analog_output = 0, + .use_pwm_agc = 0, + .clkoutdrive = 0, + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = 0, + },{ + .io.pll_bypass = 0, + .io.pll_range = 1, + .io.pll_prediv = 1, + .io.pll_loopdiv = 8, + .io.adc_clock_ratio = 8, + .io.pll_int_loop_filt = 0, + .io.clock_khz = 30000, + .reset = dib90x0_tuner_reset, + .sleep = dib90x0_tuner_sleep, + .clkouttobamse = 0, + .analog_output = 0, + .use_pwm_agc = 0, + .clkoutdrive = 0, + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = 0, + } +}; + + +static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *state = adap->priv; + struct dib0700_state *st = adap->dev->priv; + u32 fw_version; + + /* Make use of the new i2c functions from FW 1.20 */ + dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL); + if (fw_version >= 0x10200) + st->fw_use_new_i2c_api = 1; + dib0700_set_i2c_speed(adap->dev, 340); + + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80); + + if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { + deb_info("%s: Upload failed. (file not found?)\n", __func__); + return -ENODEV; + } else { + deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size); + } + stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size; + stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data; + + adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config); + + return adap->fe == NULL ? -ENODEV : 0; +} + +static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *state = adap->priv; + struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe); + u16 data_dib190[10] = { + 1, 0x1374, + 2, 0x01a2, + 7, 0x0020, + 0, 0x00ef, + 8, 0x0486, + }; + + if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &dib9090_dib0090_config) == NULL) + return -ENODEV; + i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); + if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) + return -ENODEV; + dib0700_set_i2c_speed(adap->dev, 2000); + if (dib9000_firmware_post_pll_init(adap->fe) < 0) + return -ENODEV; + release_firmware(state->frontend_firmware); + return 0; +} + +static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *state = adap->priv; + struct dib0700_state *st = adap->dev->priv; + struct i2c_adapter *i2c; + struct dvb_frontend *fe_slave; + u32 fw_version; + + /* Make use of the new i2c functions from FW 1.20 */ + dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL); + if (fw_version >= 0x10200) + st->fw_use_new_i2c_api = 1; + dib0700_set_i2c_speed(adap->dev, 340); + + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { + deb_info("%s: Upload failed. (file not found?)\n", __func__); + return -EIO; + } else { + deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size); + } + nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size; + nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data; + nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size; + nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data; + + dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80); + adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]); + + if (adap->fe == NULL) + return -ENODEV; + + i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0); + dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82); + + fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]); + dib9000_set_slave_frontend(adap->fe, fe_slave); + + return fe_slave == NULL ? -ENODEV : 0; } -static struct dib8000_config dib809x_dib8000_config = { - .output_mpeg2_in_188_bytes = 1, - - .agc_config_count = 2, - .agc = dib8090_agc_config, - .agc_control = dib0090_dcc_freq, - .pll = &dib8090_pll_config_12mhz, - .tuner_is_baseband = 1, - - .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, - - .hostbus_diversity = 1, - .div_cfg = 0x31, - .output_mode = OUTMODE_MPEG2_FIFO, - .drives = 0x2d98, - .diversity_delay = 144, - .refclksel = 3, +static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *state = adap->priv; + struct i2c_adapter *i2c; + struct dvb_frontend *fe_slave; + u16 data_dib190[10] = { + 1, 0x5374, + 2, 0x01ae, + 7, 0x0020, + 0, 0x00ef, + 8, 0x0406, + }; + i2c = dib9000_get_tuner_interface(adap->fe); + if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &nim9090md_dib0090_config[0]) == NULL) + return -ENODEV; + i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); + if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) + return -ENODEV; + dib0700_set_i2c_speed(adap->dev, 2000); + if (dib9000_firmware_post_pll_init(adap->fe) < 0) + return -ENODEV; + + fe_slave = dib9000_get_slave_frontend(adap->fe, 1); + if (fe_slave != NULL) { + i2c = dib9000_get_component_bus_interface(adap->fe); + dib9000_set_i2c_adapter(fe_slave, i2c); + + i2c = dib9000_get_tuner_interface(fe_slave); + if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL) + return -ENODEV; + fe_slave->dvb = adap->fe->dvb; + dib9000_fw_set_component_bus_speed(adap->fe, 2000); + if (dib9000_firmware_post_pll_init(fe_slave) < 0) + return -ENODEV; + } + release_firmware(state->frontend_firmware); + + return 0; +} + +/* NIM7090 */ +struct dib7090p_best_adc { + u32 timf; + u32 pll_loopdiv; + u32 pll_prediv; +}; + +static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc) +{ + u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1; + + u16 xtal = 12000; + u32 fcp_min = 1900; /* PLL Minimum Frequency comparator KHz */ + u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */ + u32 fdem_max = 76000; + u32 fdem_min = 69500; + u32 fcp = 0, fs = 0, fdem = 0; + u32 harmonic_id = 0; + + adc->pll_loopdiv = loopdiv; + adc->pll_prediv = prediv; + adc->timf = 0; + + deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min); + + /* Find Min and Max prediv */ + while((xtal/max_prediv) >= fcp_min) + max_prediv++; + + max_prediv--; + min_prediv = max_prediv; + while((xtal/min_prediv) <= fcp_max) { + min_prediv--; + if(min_prediv == 1) + break; + } + deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv); + + min_prediv = 2; + + for(prediv = min_prediv ; prediv < max_prediv; prediv ++) { + fcp = xtal / prediv; + if(fcp > fcp_min && fcp < fcp_max) { + for(loopdiv = 1 ; loopdiv < 64 ; loopdiv++) { + fdem = ((xtal/prediv) * loopdiv); + fs = fdem / 4; + /* test min/max system restrictions */ + + if((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) { + spur = 0; + /* test fs harmonics positions */ + for(harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) { + if(((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) { + spur = 1; + break; + } + } + + if(!spur) { + adc->pll_loopdiv = loopdiv; + adc->pll_prediv = prediv; + adc->timf = 2396745143UL/fdem*(1<<9); + adc->timf+= ((2396745143UL%fdem)<< 9)/fdem; + deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf); + break; + } + } + } + } + if (!spur) + break; + } + + + if(adc->pll_loopdiv == 0 && adc->pll_prediv == 0) { + return -EINVAL; + } else + return 0; +} + +static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + struct dibx000_bandwidth_config pll; + u16 target; + struct dib7090p_best_adc adc; + int ret; + + ret = state->set_param_save(fe, fep); + if (ret < 0) + return ret; + + memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); + dib0090_pwm_gain_reset(fe); + target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2; + dib7000p_set_wbd_ref(fe, target); + + if(dib7090p_get_best_sampling(fe, &adc) == 0) { + pll.pll_ratio = adc.pll_loopdiv; + pll.pll_prediv = adc.pll_prediv; + + dib7000p_update_pll(fe, &pll); + dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); + } + return 0; +} + +static struct dib0090_wbd_slope dib7090_wbd_table[] = { + { 380, 81, 850, 64, 540 ,4}, + { 860, 51, 866, 21, 375 ,4}, + {1700, 0, 250, 0, 100, 6}, //LBAND Predefinition , NOT tested Yet + {2600, 0, 250, 0, 100, 6}, //SBAND Predefinition , NOT tested Yet + { 0xFFFF, 0, 0, 0, 0 ,0}, }; -static struct dib0090_config dib809x_dib0090_config = { - .io.pll_bypass = 1, - .io.pll_range = 1, - .io.pll_prediv = 1, - .io.pll_loopdiv = 20, - .io.adc_clock_ratio = 8, - .io.pll_int_loop_filt = 0, - .io.clock_khz = 12000, - .reset = dib80xx_tuner_reset, - .sleep = dib80xx_tuner_sleep, - .clkouttobamse = 1, - .analog_output = 1, - .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS, - .wbd_vhf_offset = 100, - .wbd_cband_offset = 450, - .use_pwm_agc = 1, - .clkoutdrive = 1, - .get_adc_power = dib8090_get_adc_power, - .freq_offset_khz_uhf = 0, - .freq_offset_khz_vhf = -143, -}; +struct dibx000_agc_config dib7090_agc_config[2] = { + { + .band_caps = BAND_UHF, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, + * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup + + .inv_gain = 687,// inv_gain = 1/ 95.4dB // no boost, lower gain due to ramp quantification + .time_stabiliz = 10, // time_stabiliz + + .alpha_level = 0, // alpha_level + .thlock = 118, // thlock + + .wbd_inv = 0, // wbd_inv + .wbd_ref = 1200, // wbd_ref + .wbd_sel = 3, // wbd_sel + .wbd_alpha = 5, // wbd_alpha + + .agc1_max = 65535, // agc1_max + .agc1_min = 0, // agc1_min + + .agc2_max = 65535, // agc2_max + .agc2_min = 0, // agc2_min + + .agc1_pt1 = 0, // agc1_pt1 + .agc1_pt2 = 32, // agc1_pt2 + .agc1_pt3 = 114, // agc1_pt3 // 40.4dB + .agc1_slope1 = 143, // agc1_slope1 + .agc1_slope2 = 144, // agc1_slope2 + .agc2_pt1 = 114, // agc2_pt1 + .agc2_pt2 = 227, // agc2_pt2 + .agc2_slope1 = 116, // agc2_slope1 + .agc2_slope2 = 117, // agc2_slope2 + + .alpha_mant = 18, // alpha_mant // 5Hz with 95.4dB + .alpha_exp = 0, // alpha_exp + .beta_mant = 20, // beta_mant + .beta_exp = 59, // beta_exp + + .perform_agc_softsplit = 0, // perform_agc_softsplit + } , { + .band_caps = BAND_FM | BAND_VHF | BAND_CBAND, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, + * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup + + .inv_gain = 732,// inv_gain = 1/ 89.5dB // no boost, lower gain due to ramp quantification + .time_stabiliz = 10, // time_stabiliz + + .alpha_level = 0, // alpha_level + .thlock = 118, // thlock + + .wbd_inv = 0, // wbd_inv + .wbd_ref = 1200, // wbd_ref + .wbd_sel = 3, // wbd_sel + .wbd_alpha = 5, // wbd_alpha + + .agc1_max = 65535, // agc1_max : 1 + .agc1_min = 0, // agc1_min + + .agc2_max = 65535, // agc2_max + .agc2_min = 0, // agc2_min + + .agc1_pt1 = 0, // agc1_pt1 + .agc1_pt2 = 0, // agc1_pt2 + .agc1_pt3 = 98, // agc1_pt3 // 34.5dB CBAND P1G + 55dB BB boost = 89.5dB + .agc1_slope1 = 0, // agc1_slope1 + .agc1_slope2 = 167, // agc1_slope2 = Dy/Dx * 2**6 * 2**8 = 1/98 * 2**6 *2**8 : Dy = 1 + .agc1_pt1 = 98, // agc2_pt1 + .agc2_pt2 = 255, // agc2_pt2 + .agc2_slope1 = 104, // agc2_slope1 = Dy/Dx * 2**6 * 2**8 = 1/(255-98) * 2**6 *2**8 + .agc2_slope2 = 0, // agc2_slope2 + + .alpha_mant = 18, // alpha_mant // 5Hz with 95.4dB + .alpha_exp = 0, // alpha_exp + .beta_mant = 20, // beta_mant + .beta_exp = 59, // beta_exp + + .perform_agc_softsplit = 0, // perform_agc_softsplit + } +}; + +static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = { + 60000, 15000, // internal, sampling + 1, 5, 0, 0, 0, // pll_cfg: prediv, ratio, range, reset, bypass + 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo + (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k + (0 << 25) | 0, // ifreq = 0.000000 MHz + 20452225, // timf + 15000000, // xtal_hz +}; + +static struct dib7000p_config nim7090_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = NULL, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_FIFO, + .enMpegOutput = 1, +}; + +static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = { + { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = NULL, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, + .default_i2c_addr = 0x90, + .enMpegOutput = 1, + },{ + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = NULL, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, + .default_i2c_addr = 0x92, + .enMpegOutput = 0, + } +}; + +static const struct dib0090_config nim7090_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib7090_tuner_sleep, + .sleep = dib7090_tuner_sleep, + + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = 0, + + .get_adc_power = dib7090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, +}; + +static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { + { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib7090_tuner_sleep, + .sleep = dib7090_tuner_sleep, + + .freq_offset_khz_uhf = 50, + .freq_offset_khz_vhf = 70, + + .get_adc_power = dib7090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + },{ + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib7090_tuner_sleep, + .sleep = dib7090_tuner_sleep, + + .freq_offset_khz_uhf = -50, + .freq_offset_khz_vhf = -70, + + .get_adc_power = dib7090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + } +}; + +static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) +{ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); -static int dib8096_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct dib0700_adapter_state *state = adap->priv; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); - u16 offset; - int ret = 0; - enum frontend_tune_state tune_state = CT_SHUTDOWN; - u16 ltgain, rf_gain_limit; - - ret = state->set_param_save(fe, fep); - if (ret < 0) - return ret; - - switch (band) { - case BAND_VHF: - offset = 100; - break; - case BAND_UHF: - offset = 550; - break; - default: - offset = 0; - break; - } - offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; - dib8000_set_wbd_ref(fe, offset); - - - if (band == BAND_CBAND) { - deb_info("tuning in CBAND - soft-AGC startup\n"); - /* TODO specific wbd target for dib0090 - needed for startup ? */ - dib0090_set_tune_state(fe, CT_AGC_START); - do { - ret = dib0090_gain_control(fe); - msleep(ret); - tune_state = dib0090_get_tune_state(fe); - if (tune_state == CT_AGC_STEP_0) - dib8000_set_gpio(fe, 6, 0, 1); - else if (tune_state == CT_AGC_STEP_1) { - dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); - if (rf_gain_limit == 0) - dib8000_set_gpio(fe, 6, 0, 0); - } - } while (tune_state < CT_AGC_STOP); - dib0090_pwm_gain_reset(fe); - dib8000_pwm_agc_reset(fe); - dib8000_set_tune_state(fe, CT_DEMOD_START); - } else { - deb_info("not tuning in CBAND - standard AGC startup\n"); - dib0090_pwm_gain_reset(fe); - } + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + return -ENODEV; + } + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); - return 0; + return adap->fe == NULL ? -ENODEV : 0; } -static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) +static int nim7090_tuner_attach(struct dvb_usb_adapter *adap) { - struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); + + if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &nim7090_dib0090_config) == NULL) + return -ENODEV; - if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) - return -ENODEV; + dib7000p_set_gpio(adap->fe, 8, 0, 1); - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; - return 0; + st->set_param_save = adap->fe->ops.tuner_ops.set_params; + adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; + return 0; } -static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) +static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) { + struct dib0700_state *st = adap->dev->priv; + + /* The TFE7090 requires the dib0700 to not be in master mode */ + st->disable_streaming_master_mode = 1; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - dib0700_ctrl_clock(adap->dev, 72, 1); - msleep(10); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); + /* initialize IC 0 */ + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + return -ENODEV; + } - adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config); + dib0700_set_i2c_speed(adap->dev, 340); + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); - return adap->fe == NULL ? -ENODEV : 0; + dib7090_slave_reset(adap->fe); + + if (adap->fe == NULL) + return -ENODEV; + + return 0; +} + +static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap) +{ + struct i2c_adapter *i2c; + + if (adap->dev->adapter[0].fe == NULL) { + err("the master dib7090 has to be initialized first"); + return -ENODEV; /* the master device has not been initialized */ + } + + i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); + if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + return -ENODEV; + } + + adap->fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]); + dib0700_set_i2c_speed(adap->dev, 200); + + return adap->fe == NULL ? -ENODEV : 0; +} + +static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); + + if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL) + return -ENODEV; + + dib7000p_set_gpio(adap->fe, 8, 0, 1); + + st->set_param_save = adap->fe->ops.tuner_ops.set_params; + adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; + return 0; +} + +static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); + + if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL) + return -ENODEV; + + dib7000p_set_gpio(adap->fe, 8, 0, 1); + + st->set_param_save = adap->fe->ops.tuner_ops.set_params; + adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; + return 0; } /* STK7070PD */ @@ -1856,6 +2797,11 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) }, { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090M) }, +/* 70 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM8096MD) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -2609,6 +3555,205 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = dib90x0_pid_filter, + .pid_filter_ctrl = dib90x0_pid_filter_ctrl, + .frontend_attach = stk9090m_frontend_attach, + .tuner_attach = dib9090_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom STK9090M reference design", + { &dib0700_usb_id_table[69], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk80xx_pid_filter, + .pid_filter_ctrl = stk80xx_pid_filter_ctrl, + .frontend_attach = nim8096md_frontend_attach, + .tuner_attach = nim8096md_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom NIM8096MD reference design", + { &dib0700_usb_id_table[70], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = dib90x0_pid_filter, + .pid_filter_ctrl = dib90x0_pid_filter_ctrl, + .frontend_attach = nim9090md_frontend_attach, + .tuner_attach = nim9090md_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom NIM9090MD reference design", + { &dib0700_usb_id_table[71], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = nim7090_frontend_attach, + .tuner_attach = nim7090_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom NIM7090 reference design", + { &dib0700_usb_id_table[72], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 2, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = tfe7090pvr_frontend0_attach, + .tuner_attach = tfe7090pvr_tuner0_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x03), + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = tfe7090pvr_frontend1_attach, + .tuner_attach = tfe7090pvr_tuner1_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE7090PVR reference design", + { &dib0700_usb_id_table[73], NULL }, + { NULL }, + }, + }, + .rc.core = { .rc_interval = DEFAULT_RC_INTERVAL, .rc_codes = RC_MAP_DIB0700_RC5_TABLE, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index d0bce0445cc..b71540d7e07 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -106,8 +106,13 @@ #define USB_PID_DIBCOM_STK807XP 0x1f90 #define USB_PID_DIBCOM_STK807XPVR 0x1f98 #define USB_PID_DIBCOM_STK8096GP 0x1fa0 +#define USB_PID_DIBCOM_NIM8096MD 0x1fa8 #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 #define USB_PID_DIBCOM_STK7770P 0x1e80 +#define USB_PID_DIBCOM_NIM7090 0x1bb2 +#define USB_PID_DIBCOM_TFE7090PVR 0x1bb4 +#define USB_PID_DIBCOM_NIM9090M 0x2383 +#define USB_PID_DIBCOM_NIM9090MD 0x2384 #define USB_PID_DPOSH_M9206_COLD 0x9206 #define USB_PID_DPOSH_M9206_WARM 0xa090 #define USB_PID_E3C_EC168 0x1689 -- cgit v1.2.3-70-g09d2 From b4d6046e841955be9cc49164b03b91c9524f9c2e Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Tue, 4 Jan 2011 13:08:14 -0300 Subject: [media] DiBxxxx: Codingstype updates This patchs fix several conding-style violations. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_core.c | 9 +- drivers/media/dvb/dvb-usb/dib0700_devices.c | 263 +++++++++++---------- drivers/media/dvb/frontends/dib0090.c | 337 ++++++++++++--------------- drivers/media/dvb/frontends/dib7000p.c | 205 ++++++++-------- drivers/media/dvb/frontends/dib7000p.h | 2 +- drivers/media/dvb/frontends/dib8000.c | 163 ++++++------- drivers/media/dvb/frontends/dib8000.h | 7 +- drivers/media/dvb/frontends/dib9000.c | 204 ++++++++-------- drivers/media/dvb/frontends/dib9000.h | 5 +- drivers/media/dvb/frontends/dibx000_common.c | 61 +++-- drivers/media/dvb/frontends/dibx000_common.h | 10 +- 11 files changed, 598 insertions(+), 668 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 9ab57132b44..b79af68c54a 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -347,7 +347,8 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) b[6] = (u8) (divider >> 8); b[7] = (u8) (divider & 0xff); - deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", (b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz); + deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", + (b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz); return dib0700_ctrl_wr(d, b, 8); } @@ -484,14 +485,14 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); st->channel_state &= ~0x3; - if ((adap->stream.props.endpoint != 2) && (adap->stream.props.endpoint != 3)) { + if ((adap->stream.props.endpoint != 2) + && (adap->stream.props.endpoint != 3)) { deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint); if (onoff) st->channel_state |= 1 << (adap->id); else st->channel_state |= 1 << ~(adap->id); - } - else { + } else { if (onoff) st->channel_state |= 1 << (adap->stream.props.endpoint-2); else diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 2b919034db8..c25b4281cff 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1444,7 +1444,7 @@ static struct dib8000_config dib809x_dib8000_config[2] = { .drives = 0x2d98, .diversity_delay = 48, .refclksel = 3, - },{ + }, { .output_mpeg2_in_188_bytes = 1, .agc_config_count = 2, @@ -1517,27 +1517,26 @@ static int dib8096_set_param_override(struct dvb_frontend *fe, if (band == BAND_CBAND) { - deb_info("tuning in CBAND - soft-AGC startup\n"); - /* TODO specific wbd target for dib0090 - needed for startup ? */ - dib0090_set_tune_state(fe, CT_AGC_START); - do { - ret = dib0090_gain_control(fe); - msleep(ret); - tune_state = dib0090_get_tune_state(fe); - if (tune_state == CT_AGC_STEP_0) - dib8000_set_gpio(fe, 6, 0, 1); - else if (tune_state == CT_AGC_STEP_1) { - dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); - if (rf_gain_limit == 0) - dib8000_set_gpio(fe, 6, 0, 0); - } - } while (tune_state < CT_AGC_STOP); - dib0090_pwm_gain_reset(fe); - dib8000_pwm_agc_reset(fe); - dib8000_set_tune_state(fe, CT_DEMOD_START); + deb_info("tuning in CBAND - soft-AGC startup\n"); + dib0090_set_tune_state(fe, CT_AGC_START); + do { + ret = dib0090_gain_control(fe); + msleep(ret); + tune_state = dib0090_get_tune_state(fe); + if (tune_state == CT_AGC_STEP_0) + dib8000_set_gpio(fe, 6, 0, 1); + else if (tune_state == CT_AGC_STEP_1) { + dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); + if (rf_gain_limit == 0) + dib8000_set_gpio(fe, 6, 0, 0); + } + } while (tune_state < CT_AGC_STOP); + dib0090_pwm_gain_reset(fe); + dib8000_pwm_agc_reset(fe); + dib8000_set_tune_state(fe, CT_DEMOD_START); } else { - deb_info("not tuning in CBAND - standard AGC startup\n"); - dib0090_pwm_gain_reset(fe); + deb_info("not tuning in CBAND - standard AGC startup\n"); + dib0090_pwm_gain_reset(fe); } return 0; @@ -1608,7 +1607,7 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) struct dvb_frontend *fe_slave; dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(1000); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); @@ -1619,9 +1618,9 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) dib0700_ctrl_clock(adap->dev, 72, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80); @@ -1662,8 +1661,8 @@ static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len) u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 }; u8 rb[2]; struct i2c_msg msg[2] = { - {.addr = 0x1e >> 1,.flags = 0,.buf = wb,.len = 2}, - {.addr = 0x1e >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2}, + {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2}, + {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2}, }; u8 index_data; @@ -1673,19 +1672,19 @@ static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len) return -EIO; switch (rb[0] << 8 | rb[1]) { - case 0: + case 0: deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n"); return -EIO; - case 1: + case 1: deb_info("Found DiB0170 rev2"); break; - case 2: + case 2: deb_info("Found DiB0190 rev2"); break; - default: + default: deb_info("DiB01x0 not found"); return -EIO; - } + } for (index_data = 0; index_data < len; index_data += 2) { wb[2] = (data[index_data + 1] >> 8) & 0xff; @@ -1701,8 +1700,8 @@ static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len) wb[3] |= rb[1] & ~(3 << 4); } - wb[0] = (data[index_data ] >> 8)&0xff; - wb[1] = (data[index_data ] )&0xff; + wb[0] = (data[index_data] >> 8)&0xff; + wb[1] = (data[index_data])&0xff; msg[0].len = 4; if (i2c_transfer(i2c, &msg[0], 1) != 1) return -EIO; @@ -1799,7 +1798,7 @@ static struct dib0090_config nim9090md_dib0090_config[2] = { .clkoutdrive = 0, .freq_offset_khz_uhf = 0, .freq_offset_khz_vhf = 0, - },{ + }, { .io.pll_bypass = 0, .io.pll_range = 1, .io.pll_prediv = 1, @@ -1832,7 +1831,7 @@ static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_i2c_speed(adap->dev, 340); dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); @@ -1840,9 +1839,9 @@ static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap) dib0700_ctrl_clock(adap->dev, 72, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80); @@ -1881,7 +1880,7 @@ static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) dib0700_set_i2c_speed(adap->dev, 2000); if (dib9000_firmware_post_pll_init(adap->fe) < 0) return -ENODEV; - release_firmware(state->frontend_firmware); + release_firmware(state->frontend_firmware); return 0; } @@ -1900,7 +1899,7 @@ static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_i2c_speed(adap->dev, 340); dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); @@ -1908,9 +1907,9 @@ static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap) dib0700_ctrl_clock(adap->dev, 72, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { @@ -1974,7 +1973,7 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) if (dib9000_firmware_post_pll_init(fe_slave) < 0) return -ENODEV; } - release_firmware(state->frontend_firmware); + release_firmware(state->frontend_firmware); return 0; } @@ -2005,43 +2004,43 @@ static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_ deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min); /* Find Min and Max prediv */ - while((xtal/max_prediv) >= fcp_min) + while ((xtal/max_prediv) >= fcp_min) max_prediv++; max_prediv--; min_prediv = max_prediv; - while((xtal/min_prediv) <= fcp_max) { + while ((xtal/min_prediv) <= fcp_max) { min_prediv--; - if(min_prediv == 1) + if (min_prediv == 1) break; } deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv); min_prediv = 2; - for(prediv = min_prediv ; prediv < max_prediv; prediv ++) { + for (prediv = min_prediv ; prediv < max_prediv; prediv++) { fcp = xtal / prediv; - if(fcp > fcp_min && fcp < fcp_max) { - for(loopdiv = 1 ; loopdiv < 64 ; loopdiv++) { + if (fcp > fcp_min && fcp < fcp_max) { + for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) { fdem = ((xtal/prediv) * loopdiv); fs = fdem / 4; /* test min/max system restrictions */ - if((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) { + if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) { spur = 0; /* test fs harmonics positions */ - for(harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) { - if(((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) { + for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) { + if (((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) { spur = 1; break; } } - if(!spur) { + if (!spur) { adc->pll_loopdiv = loopdiv; adc->pll_prediv = prediv; - adc->timf = 2396745143UL/fdem*(1<<9); - adc->timf+= ((2396745143UL%fdem)<< 9)/fdem; + adc->timf = 2396745143UL/fdem*(1 << 9); + adc->timf += ((2396745143UL%fdem) << 9)/fdem; deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf); break; } @@ -2053,9 +2052,9 @@ static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_ } - if(adc->pll_loopdiv == 0 && adc->pll_prediv == 0) { + if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0) return -EINVAL; - } else + else return 0; } @@ -2077,7 +2076,7 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2; dib7000p_set_wbd_ref(fe, target); - if(dib7090p_get_best_sampling(fe, &adc) == 0) { + if (dib7090p_get_best_sampling(fe, &adc) == 0) { pll.pll_ratio = adc.pll_loopdiv; pll.pll_prediv = adc.pll_prediv; @@ -2088,11 +2087,11 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para } static struct dib0090_wbd_slope dib7090_wbd_table[] = { - { 380, 81, 850, 64, 540 ,4}, - { 860, 51, 866, 21, 375 ,4}, - {1700, 0, 250, 0, 100, 6}, //LBAND Predefinition , NOT tested Yet - {2600, 0, 250, 0, 100, 6}, //SBAND Predefinition , NOT tested Yet - { 0xFFFF, 0, 0, 0, 0 ,0}, + { 380, 81, 850, 64, 540, 4}, + { 860, 51, 866, 21, 375, 4}, + {1700, 0, 250, 0, 100, 6}, + {2600, 0, 250, 0, 100, 6}, + { 0xFFFF, 0, 0, 0, 0, 0}, }; struct dibx000_agc_config dib7090_agc_config[2] = { @@ -2100,91 +2099,91 @@ struct dibx000_agc_config dib7090_agc_config[2] = { .band_caps = BAND_UHF, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - .inv_gain = 687,// inv_gain = 1/ 95.4dB // no boost, lower gain due to ramp quantification - .time_stabiliz = 10, // time_stabiliz + .inv_gain = 687, + .time_stabiliz = 10, - .alpha_level = 0, // alpha_level - .thlock = 118, // thlock + .alpha_level = 0, + .thlock = 118, - .wbd_inv = 0, // wbd_inv - .wbd_ref = 1200, // wbd_ref - .wbd_sel = 3, // wbd_sel - .wbd_alpha = 5, // wbd_alpha + .wbd_inv = 0, + .wbd_ref = 1200, + .wbd_sel = 3, + .wbd_alpha = 5, - .agc1_max = 65535, // agc1_max - .agc1_min = 0, // agc1_min + .agc1_max = 65535, + .agc1_min = 0, - .agc2_max = 65535, // agc2_max - .agc2_min = 0, // agc2_min + .agc2_max = 65535, + .agc2_min = 0, - .agc1_pt1 = 0, // agc1_pt1 - .agc1_pt2 = 32, // agc1_pt2 - .agc1_pt3 = 114, // agc1_pt3 // 40.4dB - .agc1_slope1 = 143, // agc1_slope1 - .agc1_slope2 = 144, // agc1_slope2 - .agc2_pt1 = 114, // agc2_pt1 - .agc2_pt2 = 227, // agc2_pt2 - .agc2_slope1 = 116, // agc2_slope1 - .agc2_slope2 = 117, // agc2_slope2 + .agc1_pt1 = 0, + .agc1_pt2 = 32, + .agc1_pt3 = 114, + .agc1_slope1 = 143, + .agc1_slope2 = 144, + .agc2_pt1 = 114, + .agc2_pt2 = 227, + .agc2_slope1 = 116, + .agc2_slope2 = 117, - .alpha_mant = 18, // alpha_mant // 5Hz with 95.4dB - .alpha_exp = 0, // alpha_exp - .beta_mant = 20, // beta_mant - .beta_exp = 59, // beta_exp + .alpha_mant = 18, + .alpha_exp = 0, + .beta_mant = 20, + .beta_exp = 59, - .perform_agc_softsplit = 0, // perform_agc_softsplit + .perform_agc_softsplit = 0, } , { .band_caps = BAND_FM | BAND_VHF | BAND_CBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - .inv_gain = 732,// inv_gain = 1/ 89.5dB // no boost, lower gain due to ramp quantification - .time_stabiliz = 10, // time_stabiliz + .inv_gain = 732, + .time_stabiliz = 10, - .alpha_level = 0, // alpha_level - .thlock = 118, // thlock + .alpha_level = 0, + .thlock = 118, - .wbd_inv = 0, // wbd_inv - .wbd_ref = 1200, // wbd_ref - .wbd_sel = 3, // wbd_sel - .wbd_alpha = 5, // wbd_alpha + .wbd_inv = 0, + .wbd_ref = 1200, + .wbd_sel = 3, + .wbd_alpha = 5, - .agc1_max = 65535, // agc1_max : 1 - .agc1_min = 0, // agc1_min + .agc1_max = 65535, + .agc1_min = 0, - .agc2_max = 65535, // agc2_max - .agc2_min = 0, // agc2_min + .agc2_max = 65535, + .agc2_min = 0, - .agc1_pt1 = 0, // agc1_pt1 - .agc1_pt2 = 0, // agc1_pt2 - .agc1_pt3 = 98, // agc1_pt3 // 34.5dB CBAND P1G + 55dB BB boost = 89.5dB - .agc1_slope1 = 0, // agc1_slope1 - .agc1_slope2 = 167, // agc1_slope2 = Dy/Dx * 2**6 * 2**8 = 1/98 * 2**6 *2**8 : Dy = 1 - .agc1_pt1 = 98, // agc2_pt1 - .agc2_pt2 = 255, // agc2_pt2 - .agc2_slope1 = 104, // agc2_slope1 = Dy/Dx * 2**6 * 2**8 = 1/(255-98) * 2**6 *2**8 - .agc2_slope2 = 0, // agc2_slope2 + .agc1_pt1 = 0, + .agc1_pt2 = 0, + .agc1_pt3 = 98, + .agc1_slope1 = 0, + .agc1_slope2 = 167, + .agc1_pt1 = 98, + .agc2_pt2 = 255, + .agc2_slope1 = 104, + .agc2_slope2 = 0, - .alpha_mant = 18, // alpha_mant // 5Hz with 95.4dB - .alpha_exp = 0, // alpha_exp - .beta_mant = 20, // beta_mant - .beta_exp = 59, // beta_exp + .alpha_mant = 18, + .alpha_exp = 0, + .beta_mant = 20, + .beta_exp = 59, - .perform_agc_softsplit = 0, // perform_agc_softsplit + .perform_agc_softsplit = 0, } }; static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = { - 60000, 15000, // internal, sampling - 1, 5, 0, 0, 0, // pll_cfg: prediv, ratio, range, reset, bypass - 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo - (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k - (0 << 25) | 0, // ifreq = 0.000000 MHz - 20452225, // timf - 15000000, // xtal_hz + 60000, 15000, + 1, 5, 0, 0, 0, + 0, 0, 1, 1, 2, + (3 << 14) | (1 << 12) | (524 << 0), + (0 << 25) | 0, + 20452225, + 15000000, }; static struct dib7000p_config nim7090_dib7000p_config = { @@ -2243,7 +2242,7 @@ static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = { .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, .default_i2c_addr = 0x90, .enMpegOutput = 1, - },{ + }, { .output_mpeg2_in_188_bytes = 1, .hostbus_diversity = 1, .tuner_is_baseband = 1, @@ -2340,7 +2339,7 @@ static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { .data_tx_drv = 0, .low_if = NULL, .in_soc = 1, - },{ + }, { .io.clock_khz = 12000, .io.pll_bypass = 0, .io.pll_range = 0, @@ -2378,15 +2377,15 @@ static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) { dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) { @@ -2421,15 +2420,15 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) st->disable_streaming_master_mode = 1; dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); + msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); /* initialize IC 0 */ @@ -2441,7 +2440,7 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) dib0700_set_i2c_speed(adap->dev, 340); adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); - dib7090_slave_reset(adap->fe); + dib7090_slave_reset(adap->fe); if (adap->fe == NULL) return -ENODEV; diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index 0e87a0bdf7a..52ff1a252a9 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c @@ -204,8 +204,8 @@ static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) { u8 b[2]; struct i2c_msg msg[2] = { - {.addr = state->config->i2c_address,.flags = 0,.buf = ®,.len = 1}, - {.addr = state->config->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2}, + {.addr = state->config->i2c_address, .flags = 0, .buf = ®, .len = 1}, + {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2}, }; if (i2c_transfer(state->i2c, msg, 2) != 2) { printk(KERN_WARNING "DiB0090 I2C read failed\n"); @@ -217,7 +217,7 @@ static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) { u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; - struct i2c_msg msg = {.addr = state->config->i2c_address,.flags = 0,.buf = b,.len = 3 }; + struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 }; if (i2c_transfer(state->i2c, &msg, 1) != 1) { printk(KERN_WARNING "DiB0090 I2C write failed\n"); return -EREMOTEIO; @@ -228,7 +228,7 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) { u8 b[2]; - struct i2c_msg msg = {.addr = reg,.flags = I2C_M_RD,.buf = b,.len = 2 }; + struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 }; if (i2c_transfer(state->i2c, &msg, 1) != 1) { printk(KERN_WARNING "DiB0090 I2C read failed\n"); return 0; @@ -239,7 +239,7 @@ static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) { u8 b[2] = { val >> 8, val & 0xff }; - struct i2c_msg msg = {.addr = reg,.flags = 0,.buf = b,.len = 2 }; + struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 }; if (i2c_transfer(state->i2c, &msg, 1) != 1) { printk(KERN_WARNING "DiB0090 I2C write failed\n"); return -EREMOTEIO; @@ -347,7 +347,7 @@ static int dib0090_identify(struct dvb_frontend *fe) return 0; - identification_error: +identification_error: return -EIO; } @@ -371,8 +371,6 @@ static int dib0090_fw_identify(struct dvb_frontend *fe) if (identity->product != KROSUS) goto identification_error; - //From the SOC the version definition has changed - if ((identity->version & 0x3) == SOC) { identity->in_soc = 1; switch (identity->version) { @@ -439,7 +437,7 @@ static int dib0090_fw_identify(struct dvb_frontend *fe) return 0; - identification_error: +identification_error: return -EIO;; } @@ -1009,7 +1007,6 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) if (state->current_band == BAND_VHF) { if (state->identity.in_soc) { dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs); - //dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf_socs); /* TODO */ } else { dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf); dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); @@ -1044,9 +1041,8 @@ EXPORT_SYMBOL(dib0090_pwm_gain_reset); static u32 dib0090_get_slow_adc_val(struct dib0090_state *state) { u16 adc_val = dib0090_read_reg(state, 0x1d); - if (state->identity.in_soc) { + if (state->identity.in_soc) adc_val >>= 2; - } return adc_val; } @@ -1200,7 +1196,7 @@ int dib0090_gain_control(struct dvb_frontend *fe) #ifdef DEBUG_AGC dprintk ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm", - (u32) * tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, + (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA)); #endif } @@ -1246,26 +1242,20 @@ u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) if (current_temp > 128) current_temp = 128; - //What Wbd gain to apply for this range of frequency state->wbdmux &= ~(7 << 13); if (wbd->wbd_gain != 0) state->wbdmux |= (wbd->wbd_gain << 13); else - state->wbdmux |= (4 << 13); // 4 is the default WBD gain + state->wbdmux |= (4 << 13); dib0090_write_reg(state, 0x10, state->wbdmux); - //All the curves are linear with slope*f/64+offset wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6); wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6); - // Iet assumes that thot-tcold = 130 equiv 128, current temperature ref is -30deg - wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7; - //for (offset = 0; offset < 1000; offset += 4) - // dbgp("offset = %d -> %d\n", offset, dib0090_wbd_to_db(state, offset)); - state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold); // get the value in dBm from the offset + state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold); dprintk("wbd-target: %d dB", (u32) state->wbd_target); dprintk("wbd offset applied is %d", wbd_tcold); @@ -1323,7 +1313,6 @@ static const u16 dib0090_defaults[] = { }; static const u16 dib0090_p1g_additionnal_defaults[] = { - // additionnal INITIALISATION for p1g to be written after dib0090_defaults 1, 0x05, 0xabcd, @@ -1362,45 +1351,44 @@ static void dib0090_set_default_config(struct dib0090_state *state, const u16 * void dib0090_set_EFUSE(struct dib0090_state *state) { - u8 c,h,n; - u16 e2,e4; - u16 cal; - - e2=dib0090_read_reg(state,0x26); - e4=dib0090_read_reg(state,0x28); - - if ((state->identity.version == P1D_E_F) || // All P1F uses the internal calibration - (state->identity.version == P1G) || (e2 == 0xffff)) { //W0090G11R1 and W0090G11R1-D : We will find the calibration Value of the Baseband - - dib0090_write_reg(state,0x22,0x10); //Start the Calib - cal = (dib0090_read_reg(state,0x22)>>6) & 0x3ff; - - if ((cal<670) || (cal==1023)) //Cal at 800 would give too high value for the n - cal=850; //Recenter the n to 32 - n = 165 - ((cal * 10)>>6) ; - e2 = e4 = (3<<12) | (34<<6) | (n); - } - - if (e2!=e4) { - e2 &= e4; /* Remove the redundancy */ - } - - if (e2 != 0xffff) { - c = e2 & 0x3f; - n = (e2 >> 12) & 0xf; - h= (e2 >> 6) & 0x3f; - - if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN)) - c=32; - if ((h >= HR_MAX) || (h <= HR_MIN)) - h=34; - if ((n >= POLY_MAX) || (n <= POLY_MIN)) - n=3; - - dib0090_write_reg(state,0x13, (h << 10)) ; - e2 = (n<<11) | ((h>>2)<<6) | (c); - dib0090_write_reg(state,0x2, e2) ; /* Load the BB_2 */ - } + u8 c, h, n; + u16 e2, e4; + u16 cal; + + e2 = dib0090_read_reg(state, 0x26); + e4 = dib0090_read_reg(state, 0x28); + + if ((state->identity.version == P1D_E_F) || + (state->identity.version == P1G) || (e2 == 0xffff)) { + + dib0090_write_reg(state, 0x22, 0x10); + cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff; + + if ((cal < 670) || (cal == 1023)) + cal = 850; + n = 165 - ((cal * 10)>>6) ; + e2 = e4 = (3<<12) | (34<<6) | (n); + } + + if (e2 != e4) + e2 &= e4; /* Remove the redundancy */ + + if (e2 != 0xffff) { + c = e2 & 0x3f; + n = (e2 >> 12) & 0xf; + h = (e2 >> 6) & 0x3f; + + if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN)) + c = 32; + if ((h >= HR_MAX) || (h <= HR_MIN)) + h = 34; + if ((n >= POLY_MAX) || (n <= POLY_MIN)) + n = 3; + + dib0090_write_reg(state, 0x13, (h << 10)) ; + e2 = (n<<11) | ((h>>2)<<6) | (c); + dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */ + } } static int dib0090_reset(struct dvb_frontend *fe) @@ -1425,14 +1413,15 @@ static int dib0090_reset(struct dvb_frontend *fe) dib0090_set_default_config(state, dib0090_defaults); - if (state->identity.in_soc) - dib0090_write_reg(state, 0x18, 0x2910); /* charge pump current = 0 */ + if (state->identity.in_soc) + dib0090_write_reg(state, 0x18, 0x2910); /* charge pump current = 0 */ if (state->identity.p1g) dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults); - if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc)) /* Update the efuse : Only available for KROSUS > P1C and SOC as well*/ - dib0090_set_EFUSE(state); + /* Update the efuse : Only available for KROSUS > P1C and SOC as well*/ + if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc)) + dib0090_set_EFUSE(state); /* Congigure in function of the crystal */ if (state->config->io.clock_khz >= 24000) @@ -1501,11 +1490,11 @@ static const struct dc_calibration dc_table[] = { static const struct dc_calibration dc_p1g_table[] = { /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */ /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */ - {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1}, // offset_trim2_i_chann 0 0 5 0 0 1 6 9 5 - {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0}, // offset_trim2_q_chann 0 0 5 0 0 1 7 15 11 + {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1}, + {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0}, /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */ - {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1}, // offset_trim1_i_chann 0 0 5 0 0 1 6 4 0 - {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0}, // offset_trim1_q_chann 0 0 5 0 0 1 6 14 10 + {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1}, + {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0}, {0}, }; @@ -1542,8 +1531,8 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front dib0090_write_reg(state, 0x24, reg); state->wbdmux = dib0090_read_reg(state, 0x10); - dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3); // connect BB, disable WDB enable* - dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14)); //Discard the DataTX + dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3); + dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14)); state->dc = dc_table; @@ -1596,11 +1585,11 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) { /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */ state->step++; - state->min_adc_diff = state->adc_diff; //min is used as N-1 + state->min_adc_diff = state->adc_diff; *tune_state = CT_TUNER_STEP_1; } else { /* the minimum was what we have seen in the step before */ - if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) { //Come back to the previous state since the delta was better + if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) { dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff); state->step--; } @@ -1618,7 +1607,7 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front break; case CT_TUNER_STEP_6: - dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008); //Force the test bus to be off + dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008); dib0090_write_reg(state, 0x1f, 0x7); *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ state->calibrate &= ~DC_CAL; @@ -1653,9 +1642,9 @@ static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tu return 0; } - dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3)); // Force: WBD enable,gain to 4, mux to WBD + dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3)); - dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1))); //Discard all LNA but crystal !!! + dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1))); *tune_state = CT_TUNER_STEP_0; state->wbd_calibration_gain = wbd_gain; return 90; /* wait for the WBDMUX to switch and for the ADC to sample */ @@ -1788,98 +1777,94 @@ static const struct dib0090_tuning dib0090_tuning_table[] = { }; static const struct dib0090_tuning dib0090_p1g_tuning_table[] = { - //max_freq, switch_trim, lna_tune, lna_bias, v2i, mix, load, tuner_enable; #ifdef CONFIG_BAND_CBAND - {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB}, // FM EN_CAB + {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB}, #endif #ifdef CONFIG_BAND_VHF - {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, // VHF EN_VHF - {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, // VHF EN_VHF - {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, // VHF EN_VHF + {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, + {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, + {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, #endif #ifdef CONFIG_BAND_UHF - {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF + {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, #endif #ifdef CONFIG_BAND_LBAND - {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, // LBD EN_LBD - {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, // LBD EN_LBD - {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, // LBD EN_LBD + {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, + {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, + {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, #endif #ifdef CONFIG_BAND_SBAND - {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, // SBD EN_SBD - {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, // SBD EN_SBD + {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, + {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, #endif }; static const struct dib0090_pll dib0090_p1g_pll_table[] = { #ifdef CONFIG_BAND_CBAND - {57000, 0, 11, 48, 6}, // CAB - {70000, 1, 11, 48, 6}, // CAB - {86000, 0, 10, 32, 4}, // CAB - {105000, 1, 10, 32, 4}, // FM - {115000, 0, 9, 24, 6}, // FM - {140000, 1, 9, 24, 6}, // MID FM VHF - {170000, 0, 8, 16, 4}, // MID FM VHF + {57000, 0, 11, 48, 6}, + {70000, 1, 11, 48, 6}, + {86000, 0, 10, 32, 4}, + {105000, 1, 10, 32, 4}, + {115000, 0, 9, 24, 6}, + {140000, 1, 9, 24, 6}, + {170000, 0, 8, 16, 4}, #endif #ifdef CONFIG_BAND_VHF - {200000, 1, 8, 16, 4}, // VHF - {230000, 0, 7, 12, 6}, // VHF - {280000, 1, 7, 12, 6}, // MID VHF UHF - {340000, 0, 6, 8, 4}, // MID VHF UHF - {380000, 1, 6, 8, 4}, // MID VHF UHF - {455000, 0, 5, 6, 6}, // MID VHF UHF + {200000, 1, 8, 16, 4}, + {230000, 0, 7, 12, 6}, + {280000, 1, 7, 12, 6}, + {340000, 0, 6, 8, 4}, + {380000, 1, 6, 8, 4}, + {455000, 0, 5, 6, 6}, #endif #ifdef CONFIG_BAND_UHF - {580000, 1, 5, 6, 6}, // UHF - {680000, 0, 4, 4, 4}, // UHF - {860000, 1, 4, 4, 4}, // UHF + {580000, 1, 5, 6, 6}, + {680000, 0, 4, 4, 4}, + {860000, 1, 4, 4, 4}, #endif #ifdef CONFIG_BAND_LBAND - {1800000, 1, 2, 2, 4}, // LBD + {1800000, 1, 2, 2, 4}, #endif #ifdef CONFIG_BAND_SBAND - {2900000, 0, 1, 1, 6}, // SBD + {2900000, 0, 1, 1, 6}, #endif }; static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = { - //max_freq, switch_trim, lna_tune, lna_bias, v2i, mix, load, tuner_enable; #ifdef CONFIG_BAND_CBAND - {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, // FM EN_CAB // 0x8190 Good perf but higher current //0x4187 Low current - {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, // FM EN_CAB - {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, // FM EN_CAB + {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, + {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, + {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, #endif #ifdef CONFIG_BAND_UHF - {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF - {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, // UHF + {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, #endif #ifdef CONFIG_BAND_LBAND - {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, // LBD EN_LBD - {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, // LBD EN_LBD - {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, // LBD EN_LBD + {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, + {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, + {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, #endif #ifdef CONFIG_BAND_SBAND - {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, // SBD EN_SBD - {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, // SBD EN_SBD + {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, + {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, #endif }; static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = { - //max_freq, switch_trim, lna_tune, lna_bias, v2i, mix, load, tuner_enable; #ifdef CONFIG_BAND_CBAND - //{ 184000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB }, // 0x81ce 0x8190 Good perf but higher current //0x4187 Low current {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, - {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, //0x4187 + {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, #endif @@ -1916,17 +1901,15 @@ static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tun state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f; } } - state->adc_diff = 3000; // start with a unreachable high number : only set for KROSUS < P1G */ + state->adc_diff = 3000; *tune_state = CT_TUNER_STEP_0; } else if (*tune_state == CT_TUNER_STEP_0) { if (state->identity.p1g && !force_soft_search) { - // 30MHz => Code 15 for the ration => 128us to lock. Giving approximately - u8 ratio = 31; // (state->config->io.clock_khz / 1024 + 1) & 0x1f; + u8 ratio = 31; dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1); dib0090_read_reg(state, 0x40); - //dib0090_write_reg(state, 0x40, (3<<7) | ((((state->config->io.clock_khz >> 11)+1) & 0x1f)<<2) | (1<<1) | 1); ret = 50; } else { state->step /= 2; @@ -1968,9 +1951,6 @@ static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tun dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff); state->adc_diff = adc; state->fcaptrim = state->captrim; - //we could break here, to save time, if we reached a close-enough value - //e.g.: if (state->adc_diff < 20) - //break; } state->captrim += step_sign * state->step; @@ -1979,7 +1959,7 @@ static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tun else *tune_state = CT_TUNER_STEP_2; - ret = 25; //LOLO changed from 15 + ret = 25; } } else if (*tune_state == CT_TUNER_STEP_2) { /* this step is only used by krosus < P1G */ /*write the final cptrim config */ @@ -2000,28 +1980,27 @@ static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tu int ret = 15; s16 val; - //The assumption is that the AGC is not active switch (*tune_state) { case CT_TUNER_START: state->wbdmux = dib0090_read_reg(state, 0x10); - dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3)); //Move to the bias and clear the wbd enable + dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3)); state->bias = dib0090_read_reg(state, 0x13); - dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8)); //Move to the Ref + dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8)); *tune_state = CT_TUNER_STEP_0; /* wait for the WBDMUX to switch and for the ADC to sample */ break; case CT_TUNER_STEP_0: - state->adc_diff = dib0090_get_slow_adc_val(state); // Get the value for the Ref - dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8)); //Move to the Ptat + state->adc_diff = dib0090_get_slow_adc_val(state); + dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8)); *tune_state = CT_TUNER_STEP_1; break; case CT_TUNER_STEP_1: - val = dib0090_get_slow_adc_val(state); // Get the value for the Ptat - state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55; // +55 is defined as = -30deg + val = dib0090_get_slow_adc_val(state); + state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55; dprintk("temperature: %d C", state->temperature - 30); @@ -2029,14 +2008,13 @@ static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tu break; case CT_TUNER_STEP_2: - //Reload the start values. dib0090_write_reg(state, 0x13, state->bias); dib0090_write_reg(state, 0x10, state->wbdmux); /* write back original WBDMUX */ *tune_state = CT_TUNER_START; state->calibrate &= ~TEMP_CAL; if (state->config->analog_output == 0) - dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14)); //Set the DataTX + dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14)); break; @@ -2070,16 +2048,17 @@ static int dib0090_tune(struct dvb_frontend *fe) /* deactivate DataTX before some calibrations */ if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL)) dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14)); - else /* Activate DataTX in case a calibration has been done before */ if (state->config->analog_output == 0) - dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14)); + else + /* Activate DataTX in case a calibration has been done before */ + if (state->config->analog_output == 0) + dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14)); } if (state->calibrate & DC_CAL) return dib0090_dc_offset_calibration(state, tune_state); else if (state->calibrate & WBD_CAL) { - if (state->current_rf == 0) { + if (state->current_rf == 0) state->current_rf = state->fe->dtv_property_cache.frequency / 1000; - } return dib0090_wbd_calibration(state, tune_state); } else if (state->calibrate & TEMP_CAL) return dib0090_get_temperature(state, tune_state); @@ -2091,7 +2070,7 @@ static int dib0090_tune(struct dvb_frontend *fe) if (state->config->use_pwm_agc && state->identity.in_soc) { tmp = dib0090_read_reg(state, 0x39); if ((tmp >> 10) & 0x1) - dib0090_write_reg(state, 0x39, tmp & ~(1 << 10)); // disengage mux : en_mux_bb1 = 0 + dib0090_write_reg(state, 0x39, tmp & ~(1 << 10)); } state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000); @@ -2172,22 +2151,17 @@ static int dib0090_tune(struct dvb_frontend *fe) state->current_tune_table_index = tune; state->current_pll_table_index = pll; - // select internal switch dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim)); - // Find the VCO frequency in MHz VCOF_kHz = (pll->hfdiv * state->rf_request) * 2; - FREF = state->config->io.clock_khz; // REFDIV is 1FREF Has to be as Close as possible to 10MHz + FREF = state->config->io.clock_khz; if (state->config->fref_clock_ratio != 0) FREF /= state->config->fref_clock_ratio; - // Determine the FB divider - // The reference is 10MHz, Therefore the FBdivider is on the first digits FBDiv = (VCOF_kHz / pll->topresc / FREF); - Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF; //in kHz + Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF; - // Avoid Spurs in the loopfilter bandwidth if (Rest < LPF) Rest = 0; else if (Rest < 2 * LPF) @@ -2195,8 +2169,7 @@ static int dib0090_tune(struct dvb_frontend *fe) else if (Rest > (FREF - LPF)) { Rest = 0; FBDiv += 1; - } //Go to the next FB - else if (Rest > (FREF - 2 * LPF)) + } else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF; Rest = (Rest * 6528) / (FREF / 10); state->rest = Rest; @@ -2208,8 +2181,6 @@ static int dib0090_tune(struct dvb_frontend *fe) if (Rest == 0) { if (pll->vco_band) lo5 = 0x049f; - //else if (state->config->analog_output) - // lo5 = 0x041f; else lo5 = 0x041f; } else { @@ -2228,12 +2199,11 @@ static int dib0090_tune(struct dvb_frontend *fe) else lo5 = 0x42f; } else - lo5 = 0x42c; //BIAS Lo set to 4 by default in case of the Captrim search does not take care of the VCO Bias + lo5 = 0x42c; } lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */ - //Internal loop filter set... if (!state->config->io.pll_int_loop_filt) { if (state->identity.in_soc) lo6 = 0xff98; @@ -2242,40 +2212,30 @@ static int dib0090_tune(struct dvb_frontend *fe) else lo6 = 0xff28; } else - lo6 = (state->config->io.pll_int_loop_filt << 3); // take the loop filter value given by the layout - //dprintk("lo6 = 0x%04x", (u32)lo6); + lo6 = (state->config->io.pll_int_loop_filt << 3); Den = 1; if (Rest > 0) { if (state->config->analog_output) - lo6 |= (1 << 2) | 2; //SigmaDelta and Dither + lo6 |= (1 << 2) | 2; else { if (state->identity.in_soc) - lo6 |= (1 << 2) | 2; //SigmaDelta and Dither + lo6 |= (1 << 2) | 2; else - lo6 |= (1 << 2) | 2; //SigmaDelta and Dither + lo6 |= (1 << 2) | 2; } Den = 255; } - // Now we have to define the Num and Denum - // LO1 gets the FBdiv dib0090_write_reg(state, 0x15, (u16) FBDiv); - // LO2 gets the REFDiv if (state->config->fref_clock_ratio != 0) dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio); else dib0090_write_reg(state, 0x16, (Den << 8) | 1); - // LO3 for the Numerator dib0090_write_reg(state, 0x17, (u16) Rest); - // VCO and HF DIV dib0090_write_reg(state, 0x19, lo5); - // SIGMA Delta dib0090_write_reg(state, 0x1c, lo6); - // Check if the 0090 is analogged configured - //Disable ADC and DigPLL =0xFF9F, 0xffbf for test purposes. - //Enable The Outputs of the BB on DATA_Tx lo6 = tune->tuner_enable; if (state->config->analog_output) lo6 = (lo6 & 0xff9f) | 0x2; @@ -2294,10 +2254,8 @@ static int dib0090_tune(struct dvb_frontend *fe) else if (*tune_state == CT_TUNER_STEP_0) { /* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */ const struct dib0090_wbd_slope *wbd = state->current_wbd_table; -// if(!state->identity.p1g) { while (state->current_rf / 1000 > wbd->max_freq) wbd++; -// } dib0090_write_reg(state, 0x1e, 0x07ff); dprintk("Final Captrim: %d", (u32) state->fcaptrim); @@ -2311,12 +2269,11 @@ static int dib0090_tune(struct dvb_frontend *fe) #define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ c = 4; - i = 3; //wbdmux_bias + i = 3; - if (wbd->wbd_gain != 0) //&& !state->identity.p1g) + if (wbd->wbd_gain != 0) c = wbd->wbd_gain; - //Store wideband mux register. state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1)); dib0090_write_reg(state, 0x10, state->wbdmux); @@ -2335,15 +2292,12 @@ static int dib0090_tune(struct dvb_frontend *fe) } else if (*tune_state == CT_TUNER_STEP_1) { /* initialize the lt gain register */ state->rf_lt_def = 0x7c00; - // dib0090_write_reg(state, 0x0f, state->rf_lt_def); dib0090_set_bandwidth(state); state->tuner_is_tuned = 1; -// if(!state->identity.p1g) - state->calibrate |= WBD_CAL; // TODO: only do the WBD calibration for new tune -// - state->calibrate |= TEMP_CAL; // Force the Temperature to be remesured at next TUNE. + state->calibrate |= WBD_CAL; + state->calibrate |= TEMP_CAL; *tune_state = CT_TUNER_STOP; } else ret = FE_CALLBACK_TIME_NEVER; @@ -2435,8 +2389,8 @@ static const struct dvb_tuner_ops dib0090_fw_ops = { static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = { {470, 0, 250, 0, 100, 4}, {860, 51, 866, 21, 375, 4}, - {1700, 0, 800, 0, 850, 4}, //LBAND Predefinition , to calibrate - {2900, 0, 250, 0, 100, 6}, //SBAND Predefinition , NOT tested Yet + {1700, 0, 800, 0, 850, 4}, + {2900, 0, 250, 0, 100, 6}, {0xFFFF, 0, 0, 0, 0, 0}, }; @@ -2489,12 +2443,11 @@ struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_ada memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops)); return fe; - free_mem: +free_mem: kfree(st); fe->tuner_priv = NULL; return NULL; } - EXPORT_SYMBOL(dib0090_fw_register); MODULE_AUTHOR("Patrick Boettcher "); diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 18495bd166e..b3ca3e2f8d5 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -79,8 +79,8 @@ static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) u8 wb[2] = { reg >> 8, reg & 0xff }; u8 rb[2]; struct i2c_msg msg[2] = { - {.addr = state->i2c_addr >> 1,.flags = 0,.buf = wb,.len = 2}, - {.addr = state->i2c_addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2}, + {.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, + {.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2}, }; if (i2c_transfer(state->i2c_adap, msg, 2) != 2) @@ -96,7 +96,7 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) (val >> 8) & 0xff, val & 0xff, }; struct i2c_msg msg = { - .addr = state->i2c_addr >> 1,.flags = 0,.buf = b,.len = 4 + .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 }; return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; } @@ -129,13 +129,13 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) dprintk("setting output mode for demod %p to %d", &state->demod, mode); switch (mode) { - case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock + case OUTMODE_MPEG2_PAR_GATED_CLK: outreg = (1 << 10); /* 0x0400 */ break; - case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock + case OUTMODE_MPEG2_PAR_CONT_CLK: outreg = (1 << 10) | (1 << 6); /* 0x0440 */ break; - case OUTMODE_MPEG2_SERIAL: // STBs with serial input + case OUTMODE_MPEG2_SERIAL: outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */ break; case OUTMODE_DIVERSITY: @@ -144,7 +144,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) else outreg = (1 << 11); break; - case OUTMODE_MPEG2_FIFO: // e.g. USB feeding + case OUTMODE_MPEG2_FIFO: smo_mode |= (3 << 1); fifo_threshold = 512; outreg = (1 << 10) | (5 << 6); @@ -152,7 +152,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) case OUTMODE_ANALOG_ADC: outreg = (1 << 10) | (3 << 6); break; - case OUTMODE_HIGH_Z: // disable + case OUTMODE_HIGH_Z: outreg = 0; break; default: @@ -284,7 +284,7 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad reg_909 &= 0x0003; break; - case DIBX000_ADC_OFF: // leave the VBG voltage on + case DIBX000_ADC_OFF: reg_908 |= (1 << 14) | (1 << 13) | (1 << 12); reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); break; @@ -336,13 +336,12 @@ static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) static int dib7000p_sad_calib(struct dib7000p_state *state) { /* internal */ -// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth dib7000p_write_word(state, 73, (0 << 1) | (0 << 0)); if (state->version == SOC7090) - dib7000p_write_word(state, 74, 2048); // P_sad_calib_value = (0.9/1.8)*4096 + dib7000p_write_word(state, 74, 2048); else - dib7000p_write_word(state, 74, 776); // P_sad_calib_value = 0.625*3.3 / 4096 + dib7000p_write_word(state, 74, 776); /* do the calibration */ dib7000p_write_word(state, 73, (1 << 0)); @@ -371,8 +370,8 @@ static void dib7000p_reset_pll(struct dib7000p_state *state) if (state->version == SOC7090) { dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv)); - while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) { - } + while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) + ; dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15)); } else { @@ -420,7 +419,7 @@ int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio); reg_1856 &= 0xf000; reg_1857 = dib7000p_read_word(state, 1857); - dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15)); // desable pll + dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15)); dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f)); @@ -431,11 +430,10 @@ int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff)); dib7000p_write_word(state, 19, (u16) (internal & 0xffff)); - dib7000p_write_word(state, 1857, reg_1857 | (1 << 15)); // enable pll + dib7000p_write_word(state, 1857, reg_1857 | (1 << 15)); - while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) { + while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) dprintk("Waiting for PLL to lock"); - } return 0; } @@ -503,7 +501,7 @@ static u16 dib7000p_defaults[] = { 0xd4c0, 1, 26, - 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26 + 0x6680, /* set ADC level to -16 */ 11, 79, @@ -520,7 +518,7 @@ static u16 dib7000p_defaults[] = { (1 << 13) - 501 - 117, 1, 142, - 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16 + 0x0410, /* disable power smoothing */ 8, 145, @@ -534,42 +532,39 @@ static u16 dib7000p_defaults[] = { 0, 1, 154, - 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0 + 1 << 13, 1, 168, - 0x0ccd, // P_pha3_thres, default 0x3000 - -// 1, 169, -// 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010 + 0x0ccd, 1, 183, - 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005 + 0x200f, 1, 212, - 0x169, // P_vit_ksi_dwn = 5 P_vit_ksi_up = 5 0x1e1, // P_vit_ksi_dwn = 4 P_vit_ksi_up = 7 + 0x169, 5, 187, - 0x023d, // P_adp_regul_cnt=573, default: 410 - 0x00a4, // P_adp_noise_cnt= - 0x00a4, // P_adp_regul_ext - 0x7ff0, // P_adp_noise_ext - 0x3ccc, // P_adp_fil + 0x023d, + 0x00a4, + 0x00a4, + 0x7ff0, + 0x3ccc, 1, 198, - 0x800, // P_equal_thres_wgn + 0x800, 1, 222, - 0x0010, // P_fec_ber_rs_len=2 + 0x0010, 1, 235, - 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard + 0x0062, 2, 901, - 0x0006, // P_clk_cfg1 - (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1 + 0x0006, + (3 << 10) | (1 << 6), 1, 905, - 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive + 0x2c8e, 0, }; @@ -609,8 +604,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */ dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */ dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */ - //dib7000p_write_word(state, 273, (1<<6) | 10); /* P_vit_inoise_sel = 1, P_vit_inoise_gain = 10*/ - dib7000p_write_word(state, 273, (1<<6) | 30); //26/* P_vit_inoise_sel = 1, P_vit_inoise_gain = 26*/// FAG + dib7000p_write_word(state, 273, (1<<6) | 30); } if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) dprintk("OUTPUT_MODE could not be reset."); @@ -624,9 +618,9 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_set_bandwidth(state, 8000); - if(state->version == SOC7090) { + if (state->version == SOC7090) { dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ - } else { // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ... + } else { if (state->cfg.tuner_is_baseband) dib7000p_write_word(state, 36, 0x0755); else @@ -644,9 +638,9 @@ static void dib7000p_pll_clk_cfg(struct dib7000p_state *state) { u16 tmp = 0; tmp = dib7000p_read_word(state, 903); - dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll + dib7000p_write_word(state, 903, (tmp | 0x1)); tmp = dib7000p_read_word(state, 900); - dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock + dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); } static void dib7000p_restart_agc(struct dib7000p_state *state) @@ -660,11 +654,9 @@ static int dib7000p_update_lna(struct dib7000p_state *state) { u16 dyn_gain; - // when there is no LNA to program return immediatly if (state->cfg.update_lna) { - // read dyn_gain here (because it is demod-dependent and not fe) dyn_gain = dib7000p_read_word(state, 394); - if (state->cfg.update_lna(&state->demod, dyn_gain)) { // LNA has changed + if (state->cfg.update_lna(&state->demod, dyn_gain)) { dib7000p_restart_agc(state); return 1; } @@ -763,12 +755,11 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_ switch (state->agc_state) { case 0: - // set power-up level: interf+analog+AGC dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); if (state->version == SOC7090) { reg = dib7000p_read_word(state, 0x79b) & 0xff00; dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */ - dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF)); // bit 14 = enDemodGain + dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF)); /* enable adc i & q */ reg = dib7000p_read_word(state, 0x780); @@ -787,7 +778,6 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_ break; case 1: - // AGC initialization if (state->cfg.agc_control) state->cfg.agc_control(&state->demod, 1); @@ -831,13 +821,11 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_ break; case 4: /* LNA startup */ - // wait AGC accurate lock time ret = 7; if (dib7000p_update_lna(state)) - // wait only AGC rough lock time ret = 5; - else // nothing was done, go to the next state + else (*agc_state)++; break; @@ -971,10 +959,10 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte dib7000p_write_word(state, 208, value); /* offset loop parameters */ - dib7000p_write_word(state, 26, 0x6680); // timf(6xxx) - dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3) - dib7000p_write_word(state, 29, 0x1273); // isi - dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5) + dib7000p_write_word(state, 26, 0x6680); + dib7000p_write_word(state, 32, 0x0003); + dib7000p_write_word(state, 29, 0x1273); + dib7000p_write_word(state, 33, 0x0005); /* P_dvsy_sync_wait */ switch (ch->u.ofdm.transmission_mode) { @@ -1005,9 +993,9 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte break; } if (state->cfg.diversity_delay == 0) - state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo + state->div_sync_wait = (value * 3) / 2 + 48; else - state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo + state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; /* deactive the possibility of diversity reception if extended interleaver */ state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; @@ -1061,16 +1049,15 @@ static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_fron else factor = 6; - // always use the setting for 8MHz here lock_time for 7,6 MHz are longer value = 30 * internal * factor; - dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time - dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time + dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); + dib7000p_write_word(state, 7, (u16) (value & 0xffff)); value = 100 * internal * factor; - dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time - dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time + dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); + dib7000p_write_word(state, 9, (u16) (value & 0xffff)); value = 500 * internal * factor; - dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time - dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time + dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); + dib7000p_write_word(state, 11, (u16) (value & 0xffff)); value = dib7000p_read_word(state, 0); dib7000p_write_word(state, 0, (u16) ((1 << 9) | value)); @@ -1085,13 +1072,13 @@ static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod) struct dib7000p_state *state = demod->demodulator_priv; u16 irq_pending = dib7000p_read_word(state, 1284); - if (irq_pending & 0x1) // failed + if (irq_pending & 0x1) return 1; - if (irq_pending & 0x2) // succeeded + if (irq_pending & 0x2) return 2; - return 0; // still pending + return 0; } static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw) @@ -1202,9 +1189,9 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet if (state->sfn_workaround_active) { dprintk("SFN workaround is active"); tmp |= (1 << 9); - dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift + dib7000p_write_word(state, 166, 0x4000); } else { - dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift + dib7000p_write_word(state, 166, 0x0000); } dib7000p_write_word(state, 29, tmp); @@ -1425,8 +1412,7 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa if (state->version == SOC7090) { dib7090_set_diversity_in(fe, 0); dib7090_set_output_mode(fe, OUTMODE_HIGH_Z); - } - else + } else dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); /* maybe the parameter has been changed */ @@ -1455,7 +1441,7 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa dprintk("autosearch returns: %d", found); if (found == 0 || found == 1) - return 0; // no channel found + return 0; dib7000p_get_frontend(fe, fep); } @@ -1566,8 +1552,8 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap) { u8 tx[2], rx[2]; struct i2c_msg msg[2] = { - {.addr = 18 >> 1,.flags = 0,.buf = tx,.len = 2}, - {.addr = 18 >> 1,.flags = I2C_M_RD,.buf = rx,.len = 2}, + {.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2}, + {.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2}, }; tx[0] = 0x03; @@ -1725,9 +1711,8 @@ static int map_addr_to_serpar_number(struct i2c_msg *msg) msg->buf[0] -= 3; else if (msg->buf[0] == 28) msg->buf[0] = 23; - else { + else return -EINVAL; - } return 0; } @@ -1909,7 +1894,7 @@ static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] if (num == 1) { /* write */ word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]); word &= 0x3; - word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12); //Mask bit 12,13 + word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12); dib7000p_write_word(state, 72, word); /* Set the proper input */ return num; } @@ -1996,7 +1981,7 @@ static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout u16 rx_copy_buf[22]; dprintk("Configure DibStream Tx"); - for (index_buf = 0; index_buf<22; index_buf++) + for (index_buf = 0; index_buf < 22; index_buf++) rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf); dib7000p_write_word(state, 1615, 1); @@ -2009,7 +1994,7 @@ static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout dib7000p_write_word(state, 1612, syncSize); dib7000p_write_word(state, 1615, 0); - for (index_buf = 0; index_buf<22; index_buf++) + for (index_buf = 0; index_buf < 22; index_buf++) dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]); return 0; @@ -2021,8 +2006,7 @@ static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout u32 syncFreq; dprintk("Configure DibStream Rx"); - if ((P_Kin != 0) && (P_Kout != 0)) - { + if ((P_Kin != 0) && (P_Kout != 0)) { syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize); dib7000p_write_word(state, 1542, syncFreq); } @@ -2044,7 +2028,7 @@ static int dib7090_enDivOnHostBus(struct dib7000p_state *state) u16 reg; dprintk("Enable Diversity on host bus"); - reg = (1 << 8) | (1 << 5); // P_enDivOutOnDibTx = 1 ; P_enDibTxOnHostBus = 1 + reg = (1 << 8) | (1 << 5); dib7000p_write_word(state, 1288, reg); return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); @@ -2055,7 +2039,7 @@ static int dib7090_enAdcOnHostBus(struct dib7000p_state *state) u16 reg; dprintk("Enable ADC on host bus"); - reg = (1 << 7) | (1 << 5); //P_enAdcOnDibTx = 1 ; P_enDibTxOnHostBus = 1 + reg = (1 << 7) | (1 << 5); dib7000p_write_word(state, 1288, reg); return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); @@ -2066,7 +2050,7 @@ static int dib7090_enMpegOnHostBus(struct dib7000p_state *state) u16 reg; dprintk("Enable Mpeg on host bus"); - reg = (1 << 9) | (1 << 5); //P_enMpegOnDibTx = 1 ; P_enDibTxOnHostBus = 1 + reg = (1 << 9) | (1 << 5); dib7000p_write_word(state, 1288, reg); return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); @@ -2085,10 +2069,10 @@ static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 e dprintk("Enable Mpeg mux"); dib7000p_write_word(state, 1287, reg); - reg &= ~(1 << 7); // P_restart_mpegMux = 0 + reg &= ~(1 << 7); dib7000p_write_word(state, 1287, reg); - reg = (1 << 4); //P_enMpegMuxOnHostBus = 1 + reg = (1 << 4); dib7000p_write_word(state, 1288, reg); return 0; @@ -2099,10 +2083,10 @@ static int dib7090_disableMpegMux(struct dib7000p_state *state) u16 reg; dprintk("Disable Mpeg mux"); - dib7000p_write_word(state, 1288, 0); //P_enMpegMuxOnHostBus = 0 + dib7000p_write_word(state, 1288, 0); reg = dib7000p_read_word(state, 1287); - reg &= ~(1 << 7); // P_restart_mpegMux = 0 + reg &= ~(1 << 7); dib7000p_write_word(state, 1287, reg); return 0; @@ -2112,19 +2096,19 @@ static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode) { struct dib7000p_state *state = fe->demodulator_priv; - switch(mode) { - case INPUT_MODE_DIVERSITY: + switch (mode) { + case INPUT_MODE_DIVERSITY: dprintk("Enable diversity INPUT"); - dib7090_cfg_DibRx(state, 5,5,0,0,0,0,0); + dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); break; - case INPUT_MODE_MPEG: + case INPUT_MODE_MPEG: dprintk("Enable Mpeg INPUT"); - dib7090_cfg_DibRx(state, 8,5,0,0,0,8,0); /*outputRate = 8 */ + dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ break; - case INPUT_MODE_OFF: - default: + case INPUT_MODE_OFF: + default: dprintk("Disable INPUT"); - dib7090_cfg_DibRx(state, 0,0,0,0,0,0,0); + dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0); break; } return 0; @@ -2175,7 +2159,7 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) } else { /* Use Smooth block */ dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc"); dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1 + dib7000p_write_word(state, 1288, (1 << 6)); outreg |= (2 << 6) | (0 << 1); } break; @@ -2190,7 +2174,7 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) } else { /* Use Smooth block */ dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block"); dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1 + dib7000p_write_word(state, 1288, (1 << 6)); outreg |= (0 << 6); } break; @@ -2198,14 +2182,14 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block"); dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1 + dib7000p_write_word(state, 1288, (1 << 6)); outreg |= (1 << 6); break; case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block"); dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1 + dib7000p_write_word(state, 1288, (1 << 6)); outreg |= (5 << 6); smo_mode |= (3 << 1); fifo_threshold = 512; @@ -2242,12 +2226,11 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) en_cur_state = dib7000p_read_word(state, 1922); - if (en_cur_state > 0xff) { //LNAs and MIX are ON and therefore it is a valid configuration + if (en_cur_state > 0xff) state->tuner_enable = en_cur_state; - } if (onoff) - en_cur_state &= 0x00ff; //Mask to be applied + en_cur_state &= 0x00ff; else { if (state->tuner_enable != 0) en_cur_state = state->tuner_enable; @@ -2275,13 +2258,13 @@ EXPORT_SYMBOL(dib7090_get_adc_power); int dib7090_slave_reset(struct dvb_frontend *fe) { struct dib7000p_state *state = fe->demodulator_priv; - u16 reg; + u16 reg; - reg = dib7000p_read_word(state, 1794); - dib7000p_write_word(state, 1794, reg | (4 << 12)); + reg = dib7000p_read_word(state, 1794); + dib7000p_write_word(state, 1794, reg | (4 << 12)); - dib7000p_write_word(state, 1032, 0xffff); - return 0; + dib7000p_write_word(state, 1032, 0xffff); + return 0; } EXPORT_SYMBOL(dib7090_slave_reset); @@ -2340,7 +2323,7 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, return demod; - error: +error: kfree(st); return NULL; } diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 4e3ffc88834..0179f9474ba 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -39,7 +39,7 @@ struct dib7000p_config { u16 diversity_delay; u8 default_i2c_addr; - u8 enMpegOutput : 1; + u8 enMpegOutput:1; }; #define DEFAULT_DIB7000P_I2C_ADDRESS 18 diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 625e4210d2d..3961fed9da6 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -261,7 +261,8 @@ static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode) fifo_threshold = 1792; smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); - dprintk("-I- Setting output mode for demod %p to %d", &state->fe[0], mode); + dprintk("-I- Setting output mode for demod %p to %d", + &state->fe[0], mode); switch (mode) { case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock @@ -295,7 +296,8 @@ static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode) break; default: - dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe[0]); + dprintk("Unhandled output_mode passed to be set for demod %p", + &state->fe[0]); return -EINVAL; } @@ -345,7 +347,8 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow { /* by default everything is going to be powered off */ u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, - reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; + reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, + reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; /* now, depending on the requested mode, we power on */ switch (mode) { @@ -482,7 +485,8 @@ static void dib8000_reset_pll(struct dib8000_state *state) // clk_cfg1 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | - (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0); + (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | + (pll->pll_range << 1) | (pll->pll_reset << 0); dib8000_write_word(state, 902, clk_cfg1); clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); @@ -492,11 +496,12 @@ static void dib8000_reset_pll(struct dib8000_state *state) /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ if (state->cfg.pll->ADClkSrc == 0) - dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); + dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | + (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); else if (state->cfg.refclksel != 0) - dib8000_write_word(state, 904, - (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll-> - ADClkSrc << 7) | (0 << 1)); + dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | + ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | + (pll->ADClkSrc << 7) | (0 << 1)); else dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); @@ -627,14 +632,14 @@ static const u16 dib8000_defaults[] = { 1, 285, 0x0020, //p_fec_ 1, 299, - 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard + 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */ 1, 338, (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1 - (1 << 10) | // P_ctrl_pre_freq_mode_sat=1 - (0 << 9) | // P_ctrl_pre_freq_inh=0 - (3 << 5) | // P_ctrl_pre_freq_step=3 - (1 << 0), // P_pre_freq_win_len=1 + (1 << 10) | + (0 << 9) | /* P_ctrl_pre_freq_inh=0 */ + (3 << 5) | /* P_ctrl_pre_freq_step=3 */ + (1 << 0), /* P_pre_freq_win_len=1 */ 1, 903, (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) @@ -782,7 +787,7 @@ static int dib8000_update_lna(struct dib8000_state *state) // read dyn_gain here (because it is demod-dependent and not tuner) dyn_gain = dib8000_read_word(state, 390); - if (state->cfg.update_lna(state->fe[0], dyn_gain)) { // LNA has changed + if (state->cfg.update_lna(state->fe[0], dyn_gain)) { dib8000_restart_agc(state); return 1; } @@ -869,7 +874,8 @@ static int dib8000_agc_soft_split(struct dib8000_state *state) split_offset = state->current_agc->split.max; else split_offset = state->current_agc->split.max * - (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres); + (agc - state->current_agc->split.min_thres) / + (state->current_agc->split.max_thres - state->current_agc->split.min_thres); dprintk("AGC split_offset: %d", split_offset); @@ -952,14 +958,13 @@ s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) s32 val; val = dib8000_read32(state, 384); - /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ if (mode) { tmp_val = val; while (tmp_val >>= 1) exp++; mant = (val * 1000 / (1<fe[0]->dtv_property_cache.inversion ^ i); + dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i); if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { //compute new dds_freq for the seg and adjust prbs int seg_offset = - state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx - (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) - + state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx - + (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) - (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2); int clk = state->cfg.pll->internal; u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26) int dds_offset = seg_offset * segtodds; int new_dds, sub_channel; - if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even + if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) dds_offset -= (int)(segtodds / 2); if (state->cfg.pll->ifreq == 0) { @@ -1031,7 +1037,8 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear // - the segment of center frequency with an odd total number of segments // - the segment to the left of center frequency with an even total number of segments // - the segment to the right of center frequency with an even total number of segments - if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) + if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT) + && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) @@ -1051,9 +1058,9 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear } dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff)); dib8000_write_word(state, 28, (u16) (new_dds & 0xffff)); - if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) // if odd + if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3; - else // if even + else sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3; sub_channel -= 6; @@ -1212,7 +1219,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear } break; } - } else { // if not state->fe[0]->dtv_property_cache.isdbt_sb_mode + } else { dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff)); dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff)); dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003)); @@ -1332,8 +1339,8 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear state->differential_constellation = (seg_diff_mask != 0); dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); - if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) // 3-segments + if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) seg_mask13 = 0x00E0; else // 1-segment seg_mask13 = 0x0040; @@ -1355,25 +1362,24 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear dib8000_write_word(state, 353, seg_mask13); // ADDR 353 /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */ - // dib8000_write_word(state, 351, (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 ); // ---- SMALL ---- if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { switch (state->fe[0]->dtv_property_cache.transmission_mode) { case TRANSMISSION_MODE_2K: - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg - if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { + if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) ncoeff = coeff_2k_sb_1seg_dqpsk; else // QPSK or QAM ncoeff = coeff_2k_sb_1seg; } else { // 3-segments - if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment - if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments + if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { + if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; else // QPSK or QAM on external segments ncoeff = coeff_2k_sb_3seg_0dqpsk; } else { // QPSK or QAM on central segment - if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments + if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) ncoeff = coeff_2k_sb_3seg_1dqpsk; else // QPSK or QAM on external segments ncoeff = coeff_2k_sb_3seg; @@ -1382,20 +1388,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear break; case TRANSMISSION_MODE_4K: - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg - if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { + if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) ncoeff = coeff_4k_sb_1seg_dqpsk; else // QPSK or QAM ncoeff = coeff_4k_sb_1seg; } else { // 3-segments - if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment - if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments + if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { + if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; } else { // QPSK or QAM on external segments ncoeff = coeff_4k_sb_3seg_0dqpsk; } } else { // QPSK or QAM on central segment - if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments + if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { ncoeff = coeff_4k_sb_3seg_1dqpsk; } else // QPSK or QAM on external segments ncoeff = coeff_4k_sb_3seg; @@ -1406,20 +1412,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear case TRANSMISSION_MODE_AUTO: case TRANSMISSION_MODE_8K: default: - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg - if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { + if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) ncoeff = coeff_8k_sb_1seg_dqpsk; else // QPSK or QAM ncoeff = coeff_8k_sb_1seg; } else { // 3-segments - if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment - if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments + if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { + if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; } else { // QPSK or QAM on external segments ncoeff = coeff_8k_sb_3seg_0dqpsk; } } else { // QPSK or QAM on central segment - if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments + if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { ncoeff = coeff_8k_sb_3seg_1dqpsk; } else // QPSK or QAM on external segments ncoeff = coeff_8k_sb_3seg; @@ -1437,7 +1443,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear // ---- COFF ---- // Carloff, the most robust - if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots + if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1 @@ -1448,7 +1454,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear /* // P_small_coef_ext_enable = 1 */ /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */ - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1) if (mode == 3) @@ -1512,7 +1518,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); } // ---- FFT ---- - if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) // 1-seg + if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) dib8000_write_word(state, 178, 64); // P_fft_powrange=64 else dib8000_write_word(state, 178, 32); // P_fft_powrange=32 @@ -1542,7 +1548,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear /* offset loop parameters */ if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */ dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40); @@ -1555,7 +1561,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80); if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */ dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode)); @@ -1628,7 +1634,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear // ---- ANA_FE ---- if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) // 3-segments + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) ana_fe = ana_fe_coeff_3seg; else // 1-segment ana_fe = ana_fe_coeff_1seg; @@ -1651,10 +1657,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear // "P_cspu_left_edge" not used => do not care // "P_cspu_right_edge" not used => do not care - if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb + if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0 - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0 // 1-segment + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) { //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15 @@ -1803,7 +1809,7 @@ static int dib8000_tune(struct dvb_frontend *fe) // never achieved a lock before - wait for timfreq to update if (state->timf == 0) { if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) msleep(300); else // Sound Broadcasting mode 3 seg msleep(500); @@ -1811,7 +1817,7 @@ static int dib8000_tune(struct dvb_frontend *fe) msleep(200); } if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { - if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg + if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */ dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40); @@ -1864,9 +1870,9 @@ static int dib8000_wakeup(struct dvb_frontend *fe) if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) dprintk("could not start Slow ADC"); - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]); - if (ret<0) + if (ret < 0) return ret; } @@ -1879,7 +1885,7 @@ static int dib8000_sleep(struct dvb_frontend *fe) u8 index_frontend; int ret; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]); if (ret < 0) return ret; @@ -1914,13 +1920,13 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par fe->dtv_property_cache.bandwidth_hz = 6000000; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); if (stat&FE_HAS_SYNC) { dprintk("TMCC lock on the slave%i", index_frontend); /* synchronize the cache with the other frontends */ state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep); - for (sub_index_frontend=0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) { + for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) { if (sub_index_frontend != index_frontend) { state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode; state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion; @@ -2032,7 +2038,7 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par } /* synchronize the cache with the other frontends */ - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode; state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion; state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode; @@ -2066,7 +2072,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000; } - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { /* synchronization of the cache */ state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); @@ -2081,7 +2087,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par /* start up the AGC */ do { time = dib8000_agc_startup(state->fe[0]); - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { time_slave = dib8000_agc_startup(state->fe[index_frontend]); if (time == FE_CALLBACK_TIME_NEVER) time = time_slave; @@ -2093,7 +2099,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par else break; exit_condition = 1; - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) { exit_condition = 0; break; @@ -2101,7 +2107,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par } } while (exit_condition == 0); - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START); if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) || @@ -2132,31 +2138,30 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par u8 found = 0; u8 tune_failed = 0; - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000); dib8000_autosearch_start(state->fe[index_frontend]); } do { - msleep(10); + msleep(20); nbr_pending = 0; exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */ - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { if (((tune_failed >> index_frontend) & 0x1) == 0) { found = dib8000_autosearch_irq(state->fe[index_frontend]); switch (found) { - case 0: /* tune pending */ + case 0: /* tune pending */ nbr_pending++; break; - case 2: + case 2: dprintk("autosearch succeed on the frontend%i", index_frontend); exit_condition = 2; index_frontend_success = index_frontend; break; - default: + default: dprintk("unhandled autosearch result"); - case 1: - tune_failed |= (1 << index_frontend); + case 1: dprintk("autosearch failed for the frontend%i", index_frontend); break; } @@ -2178,13 +2183,12 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par dib8000_get_frontend(fe, fep); } - for (index_frontend=0, ret=0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) ret = dib8000_tune(state->fe[index_frontend]); - } /* set output mode and diversity input */ dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY); dib8000_set_diversity_in(state->fe[index_frontend-1], 1); } @@ -2195,7 +2199,8 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par return ret; } -static u16 dib8000_read_lock(struct dvb_frontend *fe) { +static u16 dib8000_read_lock(struct dvb_frontend *fe) +{ struct dib8000_state *state = fe->demodulator_priv; return dib8000_read_word(state, 568); @@ -2207,7 +2212,7 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) u16 lock_slave = 0, lock = dib8000_read_word(state, 568); u8 index_frontend; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) lock_slave |= dib8000_read_lock(state->fe[index_frontend]); *stat = 0; @@ -2262,7 +2267,7 @@ static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) u16 val; *strength = 0; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val); if (val > 65535 - *strength) *strength = 65535; @@ -2312,7 +2317,7 @@ static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) u32 snr_master; snr_master = dib8000_get_snr(fe); - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) snr_master += dib8000_get_snr(state->fe[index_frontend]); if (snr_master != 0) { @@ -2361,7 +2366,7 @@ int dib8000_remove_slave_frontend(struct dvb_frontend *fe) } EXPORT_SYMBOL(dib8000_remove_slave_frontend); -struct dvb_frontend * dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) +struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { struct dib8000_state *state = fe->demodulator_priv; @@ -2432,7 +2437,7 @@ static void dib8000_release(struct dvb_frontend *fe) struct dib8000_state *st = fe->demodulator_priv; u8 index_frontend; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) dvb_frontend_detach(st->fe[index_frontend]); dibx000_exit_i2c_master(&st->i2c_master); diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index 558b7e83c72..617f9eba3a0 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h @@ -52,7 +52,7 @@ extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe); -extern struct dvb_frontend * dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); +extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); #else static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) { @@ -126,9 +126,10 @@ int dib8000_remove_slave_frontend(struct dvb_frontend *fe) return -ENODEV; } -static inline struct dvb_frontend * dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { +static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) +{ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; + return NULL; } #endif diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c index a41e02dc08e..43fb6e45424 100644 --- a/drivers/media/dvb/frontends/dib9000.c +++ b/drivers/media/dvb/frontends/dib9000.c @@ -31,7 +31,7 @@ struct i2c_device { /* lock */ #define DIB_LOCK struct mutex -#define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock)<0) dprintk("could not get the lock"); } while (0) +#define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock) < 0) dprintk("could not get the lock"); } while (0) #define DibReleaseLock(lock) mutex_unlock(lock) #define DibInitLock(lock) mutex_init(lock) #define DibFreeLock(lock) @@ -187,8 +187,7 @@ enum dib9000_in_messages { #define FE_MM_W_COMPONENT_ACCESS 16 #define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17 -static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, - u8 * b, u32 len); +static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len); static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len); static u16 to_fw_output_mode(u16 mode) @@ -220,8 +219,8 @@ static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32 int ret; u8 wb[2] = { reg >> 8, reg & 0xff }; struct i2c_msg msg[2] = { - {.addr = state->i2c.i2c_addr >> 1,.flags = 0,.buf = wb,.len = 2}, - {.addr = state->i2c.i2c_addr >> 1,.flags = I2C_M_RD,.buf = b,.len = len}, + {.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, + {.addr = state->i2c.i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = len}, }; if (state->platform.risc.fw_is_running && (reg < 1024)) @@ -257,8 +256,8 @@ static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg) u8 b[2]; u8 wb[2] = { reg >> 8, reg & 0xff }; struct i2c_msg msg[2] = { - {.addr = i2c->i2c_addr >> 1,.flags = 0,.buf = wb,.len = 2}, - {.addr = i2c->i2c_addr >> 1,.flags = I2C_M_RD,.buf = b,.len = 2}, + {.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, + {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = 2}, }; if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) { @@ -295,12 +294,12 @@ static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * int ret; struct i2c_msg msg = { - .addr = state->i2c.i2c_addr >> 1,.flags = 0,.buf = b,.len = len + 2 + .addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = b, .len = len + 2 }; if (state->platform.risc.fw_is_running && (reg < 1024)) { if (dib9000_risc_apb_access_write - (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0) + (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0) return -EINVAL; return 0; } @@ -334,7 +333,7 @@ static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) { u8 b[4] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff }; struct i2c_msg msg = { - .addr = i2c->i2c_addr >> 1,.flags = 0,.buf = b,.len = 4 + .addr = i2c->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 }; return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; @@ -369,24 +368,24 @@ static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u3 { u8 b[14] = { 0 }; -// dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); -// b[0] = 0 << 7; +/* dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */ +/* b[0] = 0 << 7; */ b[1] = 1; -// b[2] = 0; // 1057 -// b[3] = 0; - b[4] = (u8) (addr >> 8); // 1058 +/* b[2] = 0; */ +/* b[3] = 0; */ + b[4] = (u8) (addr >> 8); b[5] = (u8) (addr & 0xff); -// b[10] = 0; // 1061 -// b[11] = 0; - b[12] = (u8) (addr >> 8); // 1062 +/* b[10] = 0; */ +/* b[11] = 0; */ + b[12] = (u8) (addr >> 8); b[13] = (u8) (addr & 0xff); addr += len; -// b[6] = 0; // 1059 -// b[7] = 0; - b[8] = (u8) (addr >> 8); // 1060 +/* b[6] = 0; */ +/* b[7] = 0; */ + b[8] = (u8) (addr >> 8); b[9] = (u8) (addr & 0xff); dib9000_write(state, 1056, b, 14); @@ -400,7 +399,7 @@ static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd) struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f]; /* decide whether we need to "refresh" the memory controller */ if (state->platform.risc.memcmd == cmd && /* same command */ - !(cmd & 0x80 && m->size < 67)) /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */ + !(cmd & 0x80 && m->size < 67)) /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */ return; dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80); state->platform.risc.memcmd = cmd; @@ -506,7 +505,7 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, break; } while (1); - //dprintk( "MBX: size: %d", size); + /*dprintk( "MBX: size: %d", size); */ if (tmp == 0) { ret = -EINVAL; @@ -538,7 +537,7 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, /* update register nb_mes_in_RX */ ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr); - out: +out: DibReleaseLock(&state->platform.risc.mbx_if_lock); return ret; @@ -625,7 +624,7 @@ static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr) if (*block == 0) { size = dib9000_mbx_read(state, block, 1, attr); -// dprintk( "MBX: fetched %04x message to cache", *block); +/* dprintk( "MBX: fetched %04x message to cache", *block); */ switch (*block >> 8) { case IN_MSG_DEBUG_BUF: @@ -671,8 +670,8 @@ static int dib9000_mbx_process(struct dib9000_state *state, u16 attr) ret = dib9000_mbx_fetch_to_cache(state, attr); tmp = dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */ -// if (tmp) -// dprintk( "cleared IRQ: %x", tmp); +/* if (tmp) */ +/* dprintk( "cleared IRQ: %x", tmp); */ DibReleaseLock(&state->platform.risc.mbx_lock); return ret; @@ -805,7 +804,8 @@ static u16 dib9000_identify(struct i2c_device *client) { u16 value; - if ((value = dib9000_i2c_read16(client, 896)) != 0x01b3) { + value = dib9000_i2c_read16(client, 896); + if (value != 0x01b3) { dprintk("wrong Vendor ID (0x%x)", value); return 0; } @@ -916,7 +916,7 @@ static int dib9000_fw_reset(struct dvb_frontend *fe) { struct dib9000_state *state = fe->demodulator_priv; - dib9000_write_word(state, 1817, 0x0003); // SRAM read lead in + P_host_rdy_cmos=1 + dib9000_write_word(state, 1817, 0x0003); dib9000_write_word(state, 1227, 1); dib9000_write_word(state, 1227, 0); @@ -961,8 +961,7 @@ static int dib9000_fw_reset(struct dvb_frontend *fe) return 0; } -static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, - u8 * b, u32 len) +static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len) { u16 mb[10]; u8 i, s; @@ -970,14 +969,14 @@ static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address if (address >= 1024 || !state->platform.risc.fw_is_running) return -EINVAL; - //dprintk( "APB access thru rd fw %d %x", address, attribute); + /* dprintk( "APB access thru rd fw %d %x", address, attribute); */ mb[0] = (u16) address; mb[1] = len / 2; dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute); switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) { case 1: - s--; // address + s--; for (i = 0; i < s; i++) { b[i * 2] = (mb[i + 1] >> 8) & 0xff; b[i * 2 + 1] = (mb[i + 1]) & 0xff; @@ -997,10 +996,10 @@ static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 addres if (address >= 1024 || !state->platform.risc.fw_is_running) return -EINVAL; - //dprintk( "APB access thru wr fw %d %x", address, attribute); + /* dprintk( "APB access thru wr fw %d %x", address, attribute); */ mb[0] = (unsigned short)address; - for (i = 0; i < len && i < 20; i += 2) // 20 bytes max + for (i = 0; i < len && i < 20; i += 2) mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]); dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute); @@ -1031,7 +1030,6 @@ static int dib9000_fw_init(struct dib9000_state *state) u8 size; if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0) - //if (dib9000_fw_boot(state, microcode_A_buffer, microcode_A_size, microcode_B_buffer, microcode_B_size) != 0) return -EIO; /* initialize the firmware */ @@ -1062,7 +1060,6 @@ static int dib9000_fw_init(struct dib9000_state *state) b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask; b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction; b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value; - //dprintk( "SBS: %d %d %x %x %x\n", i, b[1 + i*4], b[2 + i*4], b[3 + i*4], b[4 + i*4]); } b[1 + i * 4] = 0; /* fe_id */ if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0) @@ -1071,7 +1068,7 @@ static int dib9000_fw_init(struct dib9000_state *state) /* 0 - id, 1 - no_of_frontends */ b[0] = (0 << 8) | 1; /* 0 = i2c-address demod, 0 = tuner */ - b[1] = (0 << 8) | (0); //st->i2c_addr ) ); + b[1] = (0 << 8) | (0); b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff); b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff); b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff); @@ -1089,14 +1086,14 @@ static int dib9000_fw_init(struct dib9000_state *state) return -EIO; if (size > ARRAY_SIZE(b)) { - dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size, (int)ARRAY_SIZE(b)); + dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size, + (int)ARRAY_SIZE(b)); return -EINVAL; } for (i = 0; i < size; i += 2) { state->platform.risc.fe_mm[i / 2].addr = b[i + 0]; state->platform.risc.fe_mm[i / 2].size = b[i + 1]; - //dprintk( "MM: %d %d %d", state->platform.risc.fe_mm[i/2].addr, state->platform.risc.fe_mm[i/2].size, ARRAY_SIZE(state->platform.risc.fe_mm)); } return 0; @@ -1150,9 +1147,9 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p ret = -EIO; } - dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) & ch, sizeof(struct dibDVBTChannel)); + dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) &ch, sizeof(struct dibDVBTChannel)); - switch (ch.spectrum_inversion&0x7) { + switch (ch.spectrum_inversion & 0x7) { case 1: state->fe[0]->dtv_property_cache.inversion = INVERSION_ON; break; @@ -1267,7 +1264,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p break; } - error: +error: DibReleaseLock(&state->platform.risc.mem_mbx_lock); return ret; } @@ -1412,7 +1409,7 @@ static int dib9000_fw_set_channel_union(struct dvb_frontend *fe, struct dvb_fron ch.select_hp = 1; ch.intlv_native = 1; - dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) & ch); + dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch); return 0; } @@ -1441,9 +1438,9 @@ static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_paramete break; case CT_DEMOD_STEP_1: if (search) - dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) & i, 1); + dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) &i, 1); else - dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) & i, 1); + dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) &i, 1); switch (i) { /* something happened */ case 0: break; @@ -1484,22 +1481,22 @@ static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode) dprintk("setting output mode for demod %p to %d", fe, mode); switch (mode) { - case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock + case OUTMODE_MPEG2_PAR_GATED_CLK: outreg = (1 << 10); /* 0x0400 */ break; - case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock + case OUTMODE_MPEG2_PAR_CONT_CLK: outreg = (1 << 10) | (1 << 6); /* 0x0440 */ break; - case OUTMODE_MPEG2_SERIAL: // STBs with serial input + case OUTMODE_MPEG2_SERIAL: outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */ break; case OUTMODE_DIVERSITY: outreg = (1 << 10) | (4 << 6); /* 0x0500 */ break; - case OUTMODE_MPEG2_FIFO: // e.g. USB feeding + case OUTMODE_MPEG2_FIFO: outreg = (1 << 10) | (5 << 6); break; - case OUTMODE_HIGH_Z: // disable + case OUTMODE_HIGH_Z: outreg = 0; break; default: @@ -1507,7 +1504,7 @@ static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode) return -EINVAL; } - dib9000_write_word(state, 1795, outreg); // has to be written from outside + dib9000_write_word(state, 1795, outreg); switch (mode) { case OUTMODE_MPEG2_PAR_GATED_CLK: @@ -1596,10 +1593,9 @@ EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed); static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) { struct dib9000_state *state = i2c_get_adapdata(i2c_adap); - u8 type = 0; /* I2C */ + u8 type = 0; /* I2C */ u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4; - u16 scl = state->component_bus_speed; /* SCL frequency */ - //u16 scl = 208; /* SCL frequency */ + u16 scl = state->component_bus_speed; /* SCL frequency */ struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER]; u8 p[13] = { 0 }; @@ -1610,11 +1606,6 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2 p[3] = (u8) scl & 0xff; /* scl */ p[4] = (u8) (scl >> 8); -// p[5] = 0; /* attr */ -// p[6] = 0; - -// p[7] = (u8) (msg[0].addr << 1 ); -// p[8] = (u8) (msg[0].addr >> 7 ); p[7] = 0; p[8] = 0; @@ -1672,7 +1663,6 @@ struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe) struct dib9000_state *st = fe->demodulator_priv; return &st->tuner_adap; } - EXPORT_SYMBOL(dib9000_get_tuner_interface); struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe) @@ -1680,7 +1670,6 @@ struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe) struct dib9000_state *st = fe->demodulator_priv; return &st->component_bus; } - EXPORT_SYMBOL(dib9000_get_component_bus_interface); struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating) @@ -1688,7 +1677,6 @@ struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000 struct dib9000_state *st = fe->demodulator_priv; return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); } - EXPORT_SYMBOL(dib9000_get_i2c_master); int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c) @@ -1698,7 +1686,6 @@ int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c) st->i2c.i2c_adap = i2c; return 0; } - EXPORT_SYMBOL(dib9000_set_i2c_adapter); static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val) @@ -1723,8 +1710,8 @@ int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) struct dib9000_state *state = fe->demodulator_priv; return dib9000_cfg_gpio(state, num, dir, val); } - EXPORT_SYMBOL(dib9000_set_gpio); + int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) { struct dib9000_state *state = fe->demodulator_priv; @@ -1734,15 +1721,14 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) dprintk("PID filter enabled %d", onoff); return dib9000_write_word(state, 294 + 1, val); } - EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl); + int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) { struct dib9000_state *state = fe->demodulator_priv; dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); return dib9000_write_word(state, 300 + 1 + id, onoff ? (1 << 13) | pid : 0); } - EXPORT_SYMBOL(dib9000_fw_pid_filter); int dib9000_firmware_post_pll_init(struct dvb_frontend *fe) @@ -1750,7 +1736,6 @@ int dib9000_firmware_post_pll_init(struct dvb_frontend *fe) struct dib9000_state *state = fe->demodulator_priv; return dib9000_fw_init(state); } - EXPORT_SYMBOL(dib9000_firmware_post_pll_init); static void dib9000_release(struct dvb_frontend *demod) @@ -1758,7 +1743,7 @@ static void dib9000_release(struct dvb_frontend *demod) struct dib9000_state *st = demod->demodulator_priv; u8 index_frontend; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) dvb_frontend_detach(st->fe[index_frontend]); DibFreeLock(&state->platform.risc.mbx_if_lock); @@ -1784,7 +1769,7 @@ static int dib9000_sleep(struct dvb_frontend *fe) u8 index_frontend; int ret; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]); if (ret < 0) return ret; @@ -1805,23 +1790,32 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par fe_status_t stat; int ret; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); if (stat & FE_HAS_SYNC) { dprintk("TPS lock on the slave%i", index_frontend); /* synchronize the cache with the other frontends */ state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep); - for (sub_index_frontend=0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) { + for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); + sub_index_frontend++) { if (sub_index_frontend != index_frontend) { - state->fe[sub_index_frontend]->dtv_property_cache.modulation = state->fe[index_frontend]->dtv_property_cache.modulation; - state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion; - state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode; - state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval; - state->fe[sub_index_frontend]->dtv_property_cache.hierarchy = state->fe[index_frontend]->dtv_property_cache.hierarchy; - state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP = state->fe[index_frontend]->dtv_property_cache.code_rate_HP; - state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP = state->fe[index_frontend]->dtv_property_cache.code_rate_LP; - state->fe[sub_index_frontend]->dtv_property_cache.rolloff = state->fe[index_frontend]->dtv_property_cache.rolloff; + state->fe[sub_index_frontend]->dtv_property_cache.modulation = + state->fe[index_frontend]->dtv_property_cache.modulation; + state->fe[sub_index_frontend]->dtv_property_cache.inversion = + state->fe[index_frontend]->dtv_property_cache.inversion; + state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = + state->fe[index_frontend]->dtv_property_cache.transmission_mode; + state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = + state->fe[index_frontend]->dtv_property_cache.guard_interval; + state->fe[sub_index_frontend]->dtv_property_cache.hierarchy = + state->fe[index_frontend]->dtv_property_cache.hierarchy; + state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP = + state->fe[index_frontend]->dtv_property_cache.code_rate_HP; + state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP = + state->fe[index_frontend]->dtv_property_cache.code_rate_LP; + state->fe[sub_index_frontend]->dtv_property_cache.rolloff = + state->fe[index_frontend]->dtv_property_cache.rolloff; } } return 0; @@ -1834,7 +1828,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par return ret; /* synchronize the cache with the other frontends */ - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion; state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode; state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval; @@ -1894,14 +1888,14 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par /* set the master status */ if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) { + fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) { /* no channel specified, autosearch the channel */ state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN; } else state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET; /* set mode and status for the different frontends */ - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { dib9000_fw_set_diversity_in(state->fe[index_frontend], 1); /* synchronization of the cache */ @@ -1915,11 +1909,11 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par } /* actual tune */ - exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */ + exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */ index_frontend_success = 0; do { sleep_time = dib9000_fw_tune(state->fe[0], NULL); - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL); if (sleep_time == FE_CALLBACK_TIME_NEVER) sleep_time = sleep_time_slave; @@ -1934,23 +1928,23 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par nbr_pending = 0; exit_condition = 0; index_frontend_success = 0; - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { frontend_status = -dib9000_get_status(state->fe[index_frontend]); if (frontend_status > -FE_STATUS_TUNE_PENDING) { - exit_condition = 2; /* tune success */ + exit_condition = 2; /* tune success */ index_frontend_success = index_frontend; break; } if (frontend_status == -FE_STATUS_TUNE_PENDING) - nbr_pending++; /* some frontends are still tuning */ + nbr_pending++; /* some frontends are still tuning */ } if ((exit_condition != 2) && (nbr_pending == 0)) - exit_condition = 1; /* if all tune are done and no success, exit: tune failed */ + exit_condition = 1; /* if all tune are done and no success, exit: tune failed */ } while (exit_condition == 0); /* check the tune result */ - if (exit_condition == 1) { /* tune failed */ + if (exit_condition == 1) { /* tune failed */ dprintk("tune failed"); return 0; } @@ -1962,7 +1956,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par /* retune the other frontends with the found channel */ channel_status.status = CHANNEL_STATUS_PARAMETERS_SET; - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { /* only retune the frontends which was not tuned success */ if (index_frontend != index_frontend_success) { dib9000_set_channel_status(state->fe[index_frontend], &channel_status); @@ -1971,7 +1965,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par } do { sleep_time = FE_CALLBACK_TIME_NEVER; - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { if (index_frontend != index_frontend_success) { sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL); if (sleep_time == FE_CALLBACK_TIME_NEVER) @@ -1986,22 +1980,22 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par break; nbr_pending = 0; - for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { if (index_frontend != index_frontend_success) { frontend_status = -dib9000_get_status(state->fe[index_frontend]); if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING)) - nbr_pending++; /* some frontends are still tuning */ + nbr_pending++; /* some frontends are still tuning */ } } } while (nbr_pending != 0); /* set the output mode */ dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode); - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY); /* turn off the diversity for the last frontend */ - dib9000_fw_set_diversity_in(state->fe[index_frontend-1], 0); + dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0); return 0; } @@ -2019,7 +2013,7 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat) u8 index_frontend; u16 lock = 0, lock_slave = 0; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) lock_slave |= dib9000_read_lock(state->fe[index_frontend]); lock = dib9000_read_word(state, 535); @@ -2063,7 +2057,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) u16 val; *strength = 0; - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val); if (val > 65535 - *strength) *strength = 65535; @@ -2127,7 +2121,7 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr) u32 snr_master; snr_master = dib9000_get_snr(fe); - for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) snr_master += dib9000_get_snr(state->fe[index_frontend]); if ((snr_master >> 16) != 0) { @@ -2161,7 +2155,7 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul struct i2c_device client = {.i2c_adap = i2c }; client.i2c_addr = default_addr + 16; - dib9000_i2c_write16(&client, 1796, 0x0); // select DVB-T output + dib9000_i2c_write16(&client, 1796, 0x0); for (k = no_of_demods - 1; k >= 0; k--) { /* designated i2c address */ @@ -2203,7 +2197,6 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul return 0; } - EXPORT_SYMBOL(dib9000_i2c_enumeration); int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) @@ -2232,7 +2225,7 @@ int dib9000_remove_slave_frontend(struct dvb_frontend *fe) while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) index_frontend++; if (index_frontend != 1) { - dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1); + dprintk("remove slave fe %p (index %i)", state->fe[index_frontend - 1], index_frontend - 1); state->fe[index_frontend] = NULL; return 0; } @@ -2242,7 +2235,7 @@ int dib9000_remove_slave_frontend(struct dvb_frontend *fe) } EXPORT_SYMBOL(dib9000_remove_slave_frontend); -struct dvb_frontend * dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) +struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { struct dib9000_state *state = fe->demodulator_priv; @@ -2313,13 +2306,12 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c return fe; - component_bus_add_error: +component_bus_add_error: i2c_del_adapter(&st->tuner_adap); - error: +error: kfree(st); return NULL; } - EXPORT_SYMBOL(dib9000_attach); static struct dvb_frontend_ops dib9000_ops = { diff --git a/drivers/media/dvb/frontends/dib9000.h b/drivers/media/dvb/frontends/dib9000.h index 995e4bc48a7..b5781a48034 100644 --- a/drivers/media/dvb/frontends/dib9000.h +++ b/drivers/media/dvb/frontends/dib9000.h @@ -38,7 +38,7 @@ extern int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 ono extern int dib9000_firmware_post_pll_init(struct dvb_frontend *fe); extern int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); extern int dib9000_remove_slave_frontend(struct dvb_frontend *fe); -extern struct dvb_frontend * dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); +extern struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); extern struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe); extern int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c); extern int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed); @@ -103,7 +103,8 @@ int dib9000_remove_slave_frontend(struct dvb_frontend *fe) return -ENODEV; } -static inline struct dvb_frontend * dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { +static inline struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) +{ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index 9bd95a978a1..f6938f97feb 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c @@ -26,8 +26,8 @@ static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) u8 wb[2] = { reg >> 8, reg & 0xff }; u8 rb[2]; struct i2c_msg msg[2] = { - {.addr = mst->i2c_addr,.flags = 0,.buf = wb,.len = 2}, - {.addr = mst->i2c_addr,.flags = I2C_M_RD,.buf = rb,.len = 2}, + {.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2}, + {.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2}, }; if (i2c_transfer(mst->i2c_adap, msg, 2) != 2) @@ -38,10 +38,11 @@ static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst) { - int i = 100; // max_i2c_polls; + int i = 100; u16 status; - while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0); + while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0) + ; /* i2c timed out */ if (i == 0) @@ -63,7 +64,7 @@ static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_m const u8 *b = msg->buf; while (txlen) { - dibx000_read_word(mst, mst->base_reg + 2); // reset fifo ptr + dibx000_read_word(mst, mst->base_reg + 2); len = txlen > 8 ? 8 : txlen; for (i = 0; i < len; i += 2) { @@ -72,14 +73,14 @@ static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_m data |= *b++; dibx000_write_word(mst, mst->base_reg, data); } - da = (((u8) (msg->addr)) << 9) | // addr - (1 << 8) | // master - (1 << 7) | // rq - (0 << 6) | // stop - (0 << 5) | // start - ((len & 0x7) << 2) | // nb 8 bytes == 0 here - (0 << 1) | // rw - (0 << 0); // irqen + da = (((u8) (msg->addr)) << 9) | + (1 << 8) | + (1 << 7) | + (0 << 6) | + (0 << 5) | + ((len & 0x7) << 2) | + (0 << 1) | + (0 << 0); if (txlen == msg->len) da |= 1 << 5; /* start */ @@ -105,14 +106,14 @@ static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_ms while (rxlen) { len = rxlen > 8 ? 8 : rxlen; - da = (((u8) (msg->addr)) << 9) | // addr - (1 << 8) | // master - (1 << 7) | // rq - (0 << 6) | // stop - (0 << 5) | // start - ((len & 0x7) << 2) | // nb - (1 << 1) | // rw - (0 << 0); // irqen + da = (((u8) (msg->addr)) << 9) | + (1 << 8) | + (1 << 7) | + (0 << 6) | + (0 << 5) | + ((len & 0x7) << 2) | + (1 << 1) | + (0 << 0); if (rxlen == msg->len) da |= 1 << 5; /* start */ @@ -174,15 +175,12 @@ static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i int ret = 0; dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2); - for (msg_index = 0; msg_index Date: Tue, 9 Nov 2010 22:31:40 -0200 Subject: [media] technisat-usb2: CodingStyle cleanups Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/technisat-usb2.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c index 10151aa4923..08f8842ad28 100644 --- a/drivers/media/dvb/dvb-usb/technisat-usb2.c +++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c @@ -331,11 +331,10 @@ static int technisat_usb2_identify_state(struct usb_device *udev, u8 version[3]; /* first select the interface */ - if (usb_set_interface(udev, 0, 1) != 0) { + if (usb_set_interface(udev, 0, 1) != 0) err("could not set alternate setting to 0"); - } else { + else info("set alternate setting"); - } *cold = 0; /* by default do not download a firmware - just in case something is wrong */ @@ -378,7 +377,7 @@ static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d) { u8 reg; u8 b[16]; - int i,j; + int i, j; /* full EEPROM dump */ for (j = 0; j < 256 * 4; j += 16) { @@ -496,9 +495,9 @@ static struct stv090x_config technisat_usb2_stv090x_config = { }; static struct stv6110x_config technisat_usb2_stv6110x_config = { - .addr = 0x60, - .refclk = 16000000, - .clk_div = 2, + .addr = 0x60, + .refclk = 16000000, + .clk_div = 2, }; static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a) -- cgit v1.2.3-70-g09d2 From feb16e9833ad06ac00f23c1abf1e7d649192e3f5 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:22 -0300 Subject: [media] dw2102: Extend keymap parameter for not used remote Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 2c307ba0d28..21be0cca3c8 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -87,7 +87,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." /* keymaps */ static int ir_keymap; module_param_named(keymap, ir_keymap, int, 0644); -MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); +MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..." + " 256=none"); /* demod probe */ static int demod_probe = 1; @@ -1089,7 +1090,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { keymap = keys_tables[ir_keymap - 1].rc_keys ; keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; - } + } else if (ir_keymap > ARRAY_SIZE(keys_tables)) + return 0; /* none */ *state = REMOTE_NO_KEY_PRESSED; if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { -- cgit v1.2.3-70-g09d2 From 195288da53e03c35f97df8fa08f48f5b625bfb4e Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:22 -0300 Subject: [media] dw2102: use separate firmwares for Prof 1100, TeVii S630, S660 Before this patch we can use only one card type from list due to sharing one firmware name. Now it's fixed. Also driver tries to attach only appropriate demod for this cards. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 72 ++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 21be0cca3c8..f9affdd12d9 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -886,7 +886,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d) return -EIO; } -static int s6x0_frontend_attach(struct dvb_usb_adapter *d) +static int zl100313_frontend_attach(struct dvb_usb_adapter *d) { d->fe = dvb_attach(mt312_attach, &zl313_config, &d->dev->i2c_adap); @@ -899,6 +899,11 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d) } } + return -EIO; +} + +static int stv0288_frontend_attach(struct dvb_usb_adapter *d) +{ d->fe = dvb_attach(stv0288_attach, &earda_config, &d->dev->i2c_adap); if (d->fe != NULL) { @@ -910,6 +915,11 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d) } } + return -EIO; +} + +static int ds3000_frontend_attach(struct dvb_usb_adapter *d) +{ d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, &d->dev->i2c_adap); if (d->fe != NULL) { @@ -1418,7 +1428,7 @@ static struct dvb_usb_device_properties s6x0_properties = { .read_mac_address = s6x0_read_mac_address, .adapter = { { - .frontend_attach = s6x0_frontend_attach, + .frontend_attach = zl100313_frontend_attach, .streaming_ctrl = NULL, .tuner_attach = NULL, .stream = { @@ -1433,23 +1443,29 @@ static struct dvb_usb_device_properties s6x0_properties = { }, } }, - .num_device_descs = 3, + .num_device_descs = 1, .devices = { {"TeVii S630 USB", {&dw2102_table[6], NULL}, {NULL}, }, - {"Prof 1100 USB ", - {&dw2102_table[7], NULL}, - {NULL}, - }, - {"TeVii S660 USB", - {&dw2102_table[8], NULL}, - {NULL}, - }, } }; +struct dvb_usb_device_properties *p1100; +static struct dvb_usb_device_description d1100 = { + "Prof 1100 USB ", + {&dw2102_table[7], NULL}, + {NULL}, +}; + +struct dvb_usb_device_properties *s660; +static struct dvb_usb_device_description d660 = { + "TeVii S660 USB", + {&dw2102_table[8], NULL}, + {NULL}, +}; + struct dvb_usb_device_properties *p7500; static struct dvb_usb_device_description d7500 = { "Prof 7500 USB DVB-S2", @@ -1460,14 +1476,38 @@ static struct dvb_usb_device_description d7500 = { static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { + p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + if (!p1100) + return -ENOMEM; + /* copy default structure */ + memcpy(p1100, &s6x0_properties, + sizeof(struct dvb_usb_device_properties)); + /* fill only different fields */ + p1100->firmware = "dvb-usb-p1100.fw"; + p1100->devices[0] = d1100; + p1100->rc.legacy.rc_map_table = rc_map_tbs_table; + p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); + p1100->adapter->frontend_attach = stv0288_frontend_attach; + + s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + if (!s660) { + kfree(p1100); + return -ENOMEM; + } + memcpy(s660, &s6x0_properties, + sizeof(struct dvb_usb_device_properties)); + s660->firmware = "dvb-usb-s660.fw"; + s660->devices[0] = d660; + s660->adapter->frontend_attach = ds3000_frontend_attach; p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); - if (!p7500) + if (!p7500) { + kfree(p1100); + kfree(s660); return -ENOMEM; - /* copy default structure */ + } memcpy(p7500, &s6x0_properties, sizeof(struct dvb_usb_device_properties)); - /* fill only different fields */ p7500->firmware = "dvb-usb-p7500.fw"; p7500->devices[0] = d7500; p7500->rc.legacy.rc_map_table = rc_map_tbs_table; @@ -1482,6 +1522,10 @@ static int dw2102_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &s6x0_properties, THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, p1100, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, s660, + THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, p7500, THIS_MODULE, NULL, adapter_nr)) return 0; -- cgit v1.2.3-70-g09d2 From d2ffc447cabb3a497d7f413403abd8793b348329 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:22 -0300 Subject: [media] dw2102: add support for Geniatech SU3000 USB DVB-S2 card The card uses ds3000 demod from Montage. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 287 ++++++++++++++++++++++++++++++++++- drivers/media/dvb/frontends/ds3000.c | 40 +++++ drivers/media/dvb/frontends/ds3000.h | 1 + 3 files changed, 325 insertions(+), 3 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index f9affdd12d9..461c96a816d 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1,7 +1,8 @@ /* DVB USB framework compliant Linux driver for the * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, * TeVii S600, S630, S650, -* Prof 1100, 7500 Cards +* Prof 1100, 7500, + * Geniatech SU3000 Cards * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) * * This program is free software; you can redistribute it and/or modify it @@ -67,6 +68,7 @@ #define REG_21_SYMBOLRATE_BYTE2 0x21 /* on my own*/ #define DW2102_VOLTAGE_CTRL (0x1800) +#define SU3000_STREAM_CTRL (0x1900) #define DW2102_RC_QUERY (0x1a00) #define err_str "did not find the firmware file. (%s) " \ @@ -78,6 +80,10 @@ struct rc_map_dvb_usb_table_table { int rc_keys_size; }; +struct su3000_state { + u8 initialized; +}; + /* debug */ static int dvb_usb_dw2102_debug; module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); @@ -570,6 +576,70 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], return num; } +static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + u8 obuf[0x40], ibuf[0x40]; + + if (!d) + return -ENODEV; + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + switch (num) { + case 1: + switch (msg[0].addr) { + case SU3000_STREAM_CTRL: + obuf[0] = msg[0].buf[0] + 0x36; + obuf[1] = 3; + obuf[2] = 0; + if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0) + err("i2c transfer failed."); + break; + case DW2102_RC_QUERY: + obuf[0] = 0x10; + if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0) + err("i2c transfer failed."); + msg[0].buf[1] = ibuf[0]; + msg[0].buf[0] = ibuf[1]; + break; + default: + /* always i2c write*/ + obuf[0] = 0x08; + obuf[1] = msg[0].addr; + obuf[2] = msg[0].len; + + memcpy(&obuf[3], msg[0].buf, msg[0].len); + + if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3, + ibuf, 1, 0) < 0) + err("i2c transfer failed."); + + } + break; + case 2: + /* always i2c read */ + obuf[0] = 0x09; + obuf[1] = msg[0].len; + obuf[2] = msg[1].len; + obuf[3] = msg[0].addr; + memcpy(&obuf[4], msg[0].buf, msg[0].len); + + if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4, + ibuf, msg[1].len + 1, 0) < 0) + err("i2c transfer failed."); + + memcpy(msg[1].buf, &ibuf[1], msg[1].len); + break; + default: + warn("more than 2 i2c messages at a time is not handled yet."); + break; + } + mutex_unlock(&d->i2c_mutex); + return num; +} + static u32 dw210x_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C; @@ -605,6 +675,11 @@ static struct i2c_algorithm s6x0_i2c_algo = { .functionality = dw210x_i2c_func, }; +static struct i2c_algorithm su3000_i2c_algo = { + .master_xfer = su3000_i2c_transfer, + .functionality = dw210x_i2c_func, +}; + static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) { int i; @@ -669,6 +744,82 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) return 0; }; +static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ + static u8 command_start[] = {0x00}; + static u8 command_stop[] = {0x01}; + struct i2c_msg msg = { + .addr = SU3000_STREAM_CTRL, + .flags = 0, + .buf = onoff ? command_start : command_stop, + .len = 1 + }; + + i2c_transfer(&adap->dev->i2c_adap, &msg, 1); + + return 0; +} + +static int su3000_power_ctrl(struct dvb_usb_device *d, int i) +{ + struct su3000_state *state = (struct su3000_state *)d->priv; + u8 obuf[] = {0xde, 0}; + + info("%s: %d, initialized %d\n", __func__, i, state->initialized); + + if (i && !state->initialized) { + state->initialized = 1; + /* reset board */ + dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0); + } + + return 0; +} + +static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) +{ + int i; + u8 obuf[] = { 0x1f, 0xf0 }; + u8 ibuf[] = { 0 }; + struct i2c_msg msg[] = { + { + .addr = 0x51, + .flags = 0, + .buf = obuf, + .len = 2, + }, { + .addr = 0x51, + .flags = I2C_M_RD, + .buf = ibuf, + .len = 1, + + } + }; + + for (i = 0; i < 6; i++) { + obuf[1] = 0xf0 + i; + if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) + break; + else + mac[i] = ibuf[0]; + + debug_dump(mac, 6, printk); + } + + return 0; +} + +static int su3000_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, + int *cold) +{ + info("%s\n", __func__); + + *cold = 0; + return 0; +} + static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { static u8 command_13v[] = {0x00, 0x01}; @@ -774,6 +925,11 @@ static struct stv0900_config prof_7500_stv0900_config = { .tun1_type = 3, }; +static struct ds3000_config su3000_ds3000_config = { + .demod_address = 0x68, + .ci_mode = 1, +}; + static int dw2104_frontend_attach(struct dvb_usb_adapter *d) { struct dvb_tuner_ops *tuner_ops = NULL; @@ -944,6 +1100,43 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) return 0; } +static int su3000_frontend_attach(struct dvb_usb_adapter *d) +{ + u8 obuf[3] = { 0xe, 0x80, 0 }; + u8 ibuf[] = { 0 }; + + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) + err("command 0x0e transfer failed."); + + obuf[0] = 0xe; + obuf[1] = 0x83; + obuf[2] = 0; + + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) + err("command 0x0e transfer failed."); + + obuf[0] = 0xe; + obuf[1] = 0x83; + obuf[2] = 1; + + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) + err("command 0x0e transfer failed."); + + obuf[0] = 0x51; + + if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) + err("command 0x51 transfer failed."); + + d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, + &d->dev->i2c_adap); + if (d->fe == NULL) + return -EIO; + + info("Attached DS3000!\n"); + + return 0; +} + static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) { dvb_attach(dvb_pll_attach, adap->fe, 0x60, @@ -1078,10 +1271,49 @@ static struct rc_map_table rc_map_tbs_table[] = { { 0xf89b, KEY_MODE } }; +static struct rc_map_table rc_map_su3000_table[] = { + { 0x25, KEY_POWER }, /* right-bottom Red */ + { 0x0a, KEY_MUTE }, /* -/-- */ + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + { 0x00, KEY_0 }, + { 0x20, KEY_UP }, /* CH+ */ + { 0x21, KEY_DOWN }, /* CH+ */ + { 0x12, KEY_VOLUMEUP }, /* Brightness Up */ + { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */ + { 0x1f, KEY_RECORD }, + { 0x17, KEY_PLAY }, + { 0x16, KEY_PAUSE }, + { 0x0b, KEY_STOP }, + { 0x27, KEY_FASTFORWARD },/* >> */ + { 0x26, KEY_REWIND }, /* << */ + { 0x0d, KEY_OK }, /* Mute */ + { 0x11, KEY_LEFT }, /* VOL- */ + { 0x10, KEY_RIGHT }, /* VOL+ */ + { 0x29, KEY_BACK }, /* button under 9 */ + { 0x2c, KEY_MENU }, /* TTX */ + { 0x2b, KEY_EPG }, /* EPG */ + { 0x1e, KEY_RED }, /* OSD */ + { 0x0e, KEY_GREEN }, /* Window */ + { 0x2d, KEY_YELLOW }, /* button under << */ + { 0x0f, KEY_BLUE }, /* bottom yellow button */ + { 0x14, KEY_AUDIO }, /* Snapshot */ + { 0x38, KEY_TV }, /* TV/Radio */ + { 0x0c, KEY_ESC } /* upper Red buttton */ +}; + static struct rc_map_dvb_usb_table_table keys_tables[] = { { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) }, { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) }, + { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) }, }; static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) @@ -1137,6 +1369,7 @@ static struct usb_device_id dw2102_table[] = { {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, {USB_DEVICE(0x3034, 0x7500)}, + {USB_DEVICE(0x1f4d, 0x3000)}, { } }; @@ -1473,6 +1706,51 @@ static struct dvb_usb_device_description d7500 = { {NULL}, }; +static struct dvb_usb_device_properties su3000_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .size_of_priv = sizeof(struct su3000_state), + .power_ctrl = su3000_power_ctrl, + .num_adapters = 1, + .identify_state = su3000_identify_state, + .i2c_algo = &su3000_i2c_algo, + + .rc.legacy = { + .rc_map_table = rc_map_su3000_table, + .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), + .rc_interval = 150, + .rc_query = dw2102_rc_query, + }, + + .read_mac_address = su3000_read_mac_address, + + .generic_bulk_ctrl_endpoint = 0x01, + + .adapter = { + { + .streaming_ctrl = su3000_streaming_ctrl, + .frontend_attach = su3000_frontend_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + } + } + }, + .num_device_descs = 1, + .devices = { + { "SU3000HD DVB-S USB2.0", + { &dw2102_table[10], NULL }, + { NULL }, + }, + } +}; + static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1527,7 +1805,9 @@ static int dw2102_probe(struct usb_interface *intf, 0 == dvb_usb_device_init(intf, s660, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, p7500, - THIS_MODULE, NULL, adapter_nr)) + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &su3000_properties, + THIS_MODULE, NULL, adapter_nr)) return 0; return -ENODEV; @@ -1561,6 +1841,7 @@ MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," " DVB-C 3101 USB2.0," " TeVii S600, S630, S650, S660 USB2.0," - " Prof 1100, 7500 USB2.0 devices"); + " Prof 1100, 7500 USB2.0," + " Geniatech SU3000 devices"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c index 993357383fd..3373890c092 100644 --- a/drivers/media/dvb/frontends/ds3000.c +++ b/drivers/media/dvb/frontends/ds3000.c @@ -509,6 +509,33 @@ static int ds3000_load_firmware(struct dvb_frontend *fe, return 0; } +static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +{ + struct ds3000_state *state = fe->demodulator_priv; + u8 data; + + dprintk("%s(%d)\n", __func__, voltage); + + data = ds3000_readreg(state, 0xa2); + data |= 0x03; /* bit0 V/H, bit1 off/on */ + + switch (voltage) { + case SEC_VOLTAGE_18: + data &= ~0x03; + break; + case SEC_VOLTAGE_13: + data &= ~0x03; + data |= 0x01; + break; + case SEC_VOLTAGE_OFF: + break; + } + + ds3000_writereg(state, 0xa2, data); + + return 0; +} + static void ds3000_dump_registers(struct dvb_frontend *fe) { struct ds3000_state *state = fe->demodulator_priv; @@ -1255,6 +1282,18 @@ static int ds3000_tune(struct dvb_frontend *fe, ds3000_writereg(state, 0xfd, 0x42); ds3000_writereg(state, 0x08, 0x07);*/ + if (state->config->ci_mode) { + switch (c->delivery_system) { + case SYS_DVBS: + default: + ds3000_writereg(state, 0xfd, 0x80); + break; + case SYS_DVBS2: + ds3000_writereg(state, 0xfd, 0x01); + break; + } + } + /* ds3000 out of software reset */ ds3000_writereg(state, 0x00, 0x00); /* start ds3000 build-in uC */ @@ -1351,6 +1390,7 @@ static struct dvb_frontend_ops ds3000_ops = { .read_signal_strength = ds3000_read_signal_strength, .read_snr = ds3000_read_snr, .read_ucblocks = ds3000_read_ucblocks, + .set_voltage = ds3000_set_voltage, .set_tone = ds3000_set_tone, .diseqc_send_master_cmd = ds3000_send_diseqc_msg, .diseqc_send_burst = ds3000_diseqc_send_burst, diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h index 67f67038740..00e4e95590e 100644 --- a/drivers/media/dvb/frontends/ds3000.h +++ b/drivers/media/dvb/frontends/ds3000.h @@ -27,6 +27,7 @@ struct ds3000_config { /* the demodulator's i2c address */ u8 demod_address; + u8 ci_mode; }; #if defined(CONFIG_DVB_DS3000) || \ -- cgit v1.2.3-70-g09d2 From 2adc591fb7764bf70f65a5923ff50c1c1b671c20 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:22 -0300 Subject: [media] dw2102: Add Terratec Cinergy S2 USB HD MarkusF wrote: I accidently got a Terratec Cinergy S2 USB HD (instead of a Terratec Cinergy S2 PCI HD). I found in the windows driver, that the driver is for the usb ids: 0CCD:00A8 1F4D:3000 The dvb-s2 usb adapter has the id 0CCD-00A8. So I patches your driver and added the usb id, where the 1F4D:3000 is and it worked (after I downloaded the firmware dvb-fe-ds3000.fw). w_scan found the channels and vdr is working fine. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 461c96a816d..57af4c17d54 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1370,6 +1370,7 @@ static struct usb_device_id dw2102_table[] = { {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, {USB_DEVICE(0x3034, 0x7500)}, {USB_DEVICE(0x1f4d, 0x3000)}, + {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, { } }; @@ -1742,12 +1743,16 @@ static struct dvb_usb_device_properties su3000_properties = { } } }, - .num_device_descs = 1, + .num_device_descs = 2, .devices = { { "SU3000HD DVB-S USB2.0", { &dw2102_table[10], NULL }, { NULL }, }, + { "Terratec Cinergy S2 USB HD", + { &dw2102_table[11], NULL }, + { NULL }, + }, } }; -- cgit v1.2.3-70-g09d2 From fa8bae102fbbabe9ecc4381ace3b74a199684594 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:22 -0300 Subject: [media] dw2102: Prof 7500: Lock LED implemented Code changed for dw2102, stv0900 in order to achieve that. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 29 +++++++++++++++++++++++++++++ drivers/media/dvb/frontends/stv0900.h | 2 ++ drivers/media/dvb/frontends/stv0900_core.c | 23 ++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 57af4c17d54..4ae4fb02164 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -70,6 +70,7 @@ #define DW2102_VOLTAGE_CTRL (0x1800) #define SU3000_STREAM_CTRL (0x1900) #define DW2102_RC_QUERY (0x1a00) +#define DW2102_LED_CTRL (0x1b00) #define err_str "did not find the firmware file. (%s) " \ "Please see linux/Documentation/dvb/ for more details " \ @@ -509,6 +510,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf, 2, DW210X_WRITE_MSG); break; } + case (DW2102_LED_CTRL): { + u8 obuf[2]; + + obuf[0] = 5; + obuf[1] = msg[j].buf[0]; + ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, + obuf, 2, DW210X_WRITE_MSG); + break; + } /*case 0x55: cx24116 case 0x6a: stv0903 case 0x68: ds3000, stv0903 @@ -844,6 +854,24 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) return 0; } +static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) +{ + static u8 led_off[] = { 0 }; + static u8 led_on[] = { 1 }; + struct i2c_msg msg = { + .addr = DW2102_LED_CTRL, + .flags = 0, + .buf = led_off, + .len = 1 + }; + struct dvb_usb_adapter *udev_adap = + (struct dvb_usb_adapter *)(fe->dvb->priv); + + if (offon) + msg.buf = led_on; + i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); +} + static struct stv0299_config sharp_z0194a_config = { .demod_address = 0x68, .inittab = sharp_z0194a_inittab, @@ -923,6 +951,7 @@ static struct stv0900_config prof_7500_stv0900_config = { .tun1_adc = 0,/* 2 Vpp */ .path1_mode = 3, .tun1_type = 3, + .set_lock_led = dw210x_led_ctrl, }; static struct ds3000_config su3000_ds3000_config = { diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h index e3e35d1ce83..91c7ee8b231 100644 --- a/drivers/media/dvb/frontends/stv0900.h +++ b/drivers/media/dvb/frontends/stv0900.h @@ -53,6 +53,8 @@ struct stv0900_config { u8 tun2_type; /* Set device param to start dma */ int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); + /* Hook for Lock LED */ + void (*set_lock_led)(struct dvb_frontend *fe, int offon); }; #if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \ diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 4f5e7d3a0e6..1ca1c835048 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -1660,8 +1660,13 @@ static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - } else + if (state->config->set_lock_led) + state->config->set_lock_led(fe, 1); + } else { + if (state->config->set_lock_led) + state->config->set_lock_led(fe, 0); dprintk("DEMOD LOCK FAIL\n"); + } return 0; } @@ -1831,6 +1836,9 @@ static void stv0900_release(struct dvb_frontend *fe) dprintk("%s\n", __func__); + if (state->config->set_lock_led) + state->config->set_lock_led(fe, 0); + if ((--(state->internal->dmds_used)) <= 0) { dprintk("%s: Actually removing\n", __func__); @@ -1842,6 +1850,18 @@ static void stv0900_release(struct dvb_frontend *fe) kfree(state); } +static int stv0900_sleep(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + + dprintk("%s\n", __func__); + + if (state->config->set_lock_led) + state->config->set_lock_led(fe, 0); + + return 0; +} + static int stv0900_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { @@ -1876,6 +1896,7 @@ static struct dvb_frontend_ops stv0900_ops = { .release = stv0900_release, .init = stv0900_init, .get_frontend = stv0900_get_frontend, + .sleep = stv0900_sleep, .get_frontend_algo = stv0900_frontend_algo, .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, .diseqc_send_master_cmd = stv0900_send_master_cmd, -- cgit v1.2.3-70-g09d2 From 4e59df8f25950520cd6a8b16a39d48b5fa5aeeda Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:23 -0300 Subject: [media] dw2102: Prof 7500 remote fix Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 4ae4fb02164..ea9a01c24fc 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1118,12 +1118,17 @@ static int ds3000_frontend_attach(struct dvb_usb_adapter *d) static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) { + u8 obuf[] = {7, 1}; + d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, &d->dev->i2c_adap, 0); if (d->fe == NULL) return -EIO; + d->fe->ops.set_voltage = dw210x_set_voltage; + dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); + info("Attached STV0900+STB6100A!\n"); return 0; -- cgit v1.2.3-70-g09d2 From d3210b5f9618fc3d231caf39ffd32fda490e3ea5 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:23 -0300 Subject: [media] dw2102: Prof 1100 initialization fix RC keys structure for Prof 1100 already defined, so remove extra initialization. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index ea9a01c24fc..445819965e6 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1464,11 +1464,6 @@ static int dw2102_load_firmware(struct usb_device *dev, } /* init registers */ switch (dev->descriptor.idProduct) { - case USB_PID_PROF_1100: - s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table; - s6x0_properties.rc.legacy.rc_map_size = - ARRAY_SIZE(rc_map_tbs_table); - break; case USB_PID_TEVII_S650: dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table; dw2104_properties.rc.legacy.rc_map_size = -- cgit v1.2.3-70-g09d2 From 69519c3eff2a4a164351792d70666efa900b697e Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:23 -0300 Subject: [media] dw2102: unnecessary NULL's removed Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 445819965e6..d1ddf7e8173 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1546,8 +1546,6 @@ static struct dvb_usb_device_properties dw2102_properties = { .adapter = { { .frontend_attach = dw2102_frontend_attach, - .streaming_ctrl = NULL, - .tuner_attach = NULL, .stream = { .type = USB_BULK, .count = 8, @@ -1599,8 +1597,6 @@ static struct dvb_usb_device_properties dw2104_properties = { .adapter = { { .frontend_attach = dw2104_frontend_attach, - .streaming_ctrl = NULL, - /*.tuner_attach = dw2104_tuner_attach,*/ .stream = { .type = USB_BULK, .count = 8, @@ -1648,7 +1644,6 @@ static struct dvb_usb_device_properties dw3101_properties = { .adapter = { { .frontend_attach = dw3101_frontend_attach, - .streaming_ctrl = NULL, .tuner_attach = dw3101_tuner_attach, .stream = { .type = USB_BULK, @@ -1692,8 +1687,6 @@ static struct dvb_usb_device_properties s6x0_properties = { .adapter = { { .frontend_attach = zl100313_frontend_attach, - .streaming_ctrl = NULL, - .tuner_attach = NULL, .stream = { .type = USB_BULK, .count = 8, -- cgit v1.2.3-70-g09d2 From 52c506e09cd624cbf7d21d9c16283f3e8b32f4bc Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:23 -0300 Subject: [media] dw2102: corrections for TeVii s660 LNB power control There are two TeVii s660 modifications with different LNB power control implementations. It is safe to call both methods for each card. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index d1ddf7e8173..0ab377e3d6f 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -85,6 +85,10 @@ struct su3000_state { u8 initialized; }; +struct s6x0_state { + int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); +}; + /* debug */ static int dvb_usb_dw2102_debug; module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); @@ -854,6 +858,19 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) return 0; } +static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +{ + struct dvb_usb_adapter *d = + (struct dvb_usb_adapter *)(fe->dvb->priv); + struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; + + dw210x_set_voltage(fe, voltage); + if (st->old_set_voltage) + st->old_set_voltage(fe, voltage); + + return 0; +} + static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) { static u8 led_off[] = { 0 }; @@ -1105,15 +1122,19 @@ static int stv0288_frontend_attach(struct dvb_usb_adapter *d) static int ds3000_frontend_attach(struct dvb_usb_adapter *d) { + struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; + d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached ds3000+ds2020!\n"); - return 0; - } - return -EIO; + if (d->fe == NULL) + return -EIO; + + st->old_set_voltage = d->fe->ops.set_voltage; + d->fe->ops.set_voltage = s660_set_voltage; + info("Attached ds3000+ds2020!\n"); + + return 0; } static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) @@ -1669,6 +1690,7 @@ static struct dvb_usb_device_properties dw3101_properties = { static struct dvb_usb_device_properties s6x0_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, + .size_of_priv = sizeof(struct s6x0_state), .firmware = "dvb-usb-s630.fw", .no_reconnect = 1, -- cgit v1.2.3-70-g09d2 From 5a530cbecaa5a21d185e0549ea9a866483661f6f Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:23 -0300 Subject: [media] dw2102: fix TeVii s660 remote control Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 0ab377e3d6f..893149170fa 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -495,10 +495,10 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], for (j = 0; j < num; j++) { switch (msg[j].addr) { case (DW2102_RC_QUERY): { - u8 ibuf[4]; + u8 ibuf[5]; ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 4, DW210X_READ_MSG); - memcpy(msg[j].buf, ibuf + 1, 2); + ibuf, 5, DW210X_READ_MSG); + memcpy(msg[j].buf, ibuf + 3, 2); break; } case (DW2102_VOLTAGE_CTRL): { @@ -1123,6 +1123,7 @@ static int stv0288_frontend_attach(struct dvb_usb_adapter *d) static int ds3000_frontend_attach(struct dvb_usb_adapter *d) { struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; + u8 obuf[] = {7, 1}; d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, &d->dev->i2c_adap); @@ -1132,6 +1133,9 @@ static int ds3000_frontend_attach(struct dvb_usb_adapter *d) st->old_set_voltage = d->fe->ops.set_voltage; d->fe->ops.set_voltage = s660_set_voltage; + + dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); + info("Attached ds3000+ds2020!\n"); return 0; -- cgit v1.2.3-70-g09d2 From e8f5055ac85fb68eeaa335f0dae14b31cc037f6d Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:23 -0300 Subject: [media] dw2102: add support for the TeVii S480 PCIe The card consists of a PCI-e to USB Host Controller and two TeVii S660 equivalent cards. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 893149170fa..c5a0921204b 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1,6 +1,6 @@ /* DVB USB framework compliant Linux driver for the * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, -* TeVii S600, S630, S650, +* TeVii S600, S630, S650, S480 * Prof 1100, 7500, * Geniatech SU3000 Cards * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) @@ -56,6 +56,14 @@ #define USB_PID_TEVII_S660 0xd660 #endif +#ifndef USB_PID_TEVII_S480_1 +#define USB_PID_TEVII_S480_1 0xd481 +#endif + +#ifndef USB_PID_TEVII_S480_2 +#define USB_PID_TEVII_S480_2 0xd482 +#endif + #ifndef USB_PID_PROF_1100 #define USB_PID_PROF_1100 0xb012 #endif @@ -1430,6 +1438,8 @@ static struct usb_device_id dw2102_table[] = { {USB_DEVICE(0x3034, 0x7500)}, {USB_DEVICE(0x1f4d, 0x3000)}, {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, + {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, + {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, { } }; @@ -1748,6 +1758,18 @@ static struct dvb_usb_device_description d660 = { {NULL}, }; +static struct dvb_usb_device_description d480_1 = { + "TeVii S480.1 USB", + {&dw2102_table[12], NULL}, + {NULL}, +}; + +static struct dvb_usb_device_description d480_2 = { + "TeVii S480.2 USB", + {&dw2102_table[13], NULL}, + {NULL}, +}; + struct dvb_usb_device_properties *p7500; static struct dvb_usb_device_description d7500 = { "Prof 7500 USB DVB-S2", @@ -1828,7 +1850,10 @@ static int dw2102_probe(struct usb_interface *intf, memcpy(s660, &s6x0_properties, sizeof(struct dvb_usb_device_properties)); s660->firmware = "dvb-usb-s660.fw"; + s660->num_device_descs = 3; s660->devices[0] = d660; + s660->devices[1] = d480_1; + s660->devices[2] = d480_2; s660->adapter->frontend_attach = ds3000_frontend_attach; p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); @@ -1893,7 +1918,7 @@ module_exit(dw2102_module_exit); MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," " DVB-C 3101 USB2.0," - " TeVii S600, S630, S650, S660 USB2.0," + " TeVii S600, S630, S650, S660, S480," " Prof 1100, 7500 USB2.0," " Geniatech SU3000 devices"); MODULE_VERSION("0.1"); -- cgit v1.2.3-70-g09d2 From 2f30fb49c347e8696a8784c57810b41d185707ec Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 25 Feb 2011 18:41:23 -0300 Subject: [media] dw2102: Copyright, cards list updated Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index c5a0921204b..1a1b84c3a53 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1,16 +1,16 @@ /* DVB USB framework compliant Linux driver for the -* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, -* TeVii S600, S630, S650, S480 -* Prof 1100, 7500, + * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, + * TeVii S600, S630, S650, S660, S480, + * Prof 1100, 7500, * Geniatech SU3000 Cards -* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) -* -* 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, version 2. -* -* see Documentation/dvb/README.dvb-usb for more information -*/ + * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by) + * + * 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, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ #include "dw2102.h" #include "si21xx.h" #include "stv0299.h" -- cgit v1.2.3-70-g09d2 From 498e677cfd78b098342640f382293782bfa0bd63 Mon Sep 17 00:00:00 2001 From: Lukas Max Fisch Date: Tue, 8 Feb 2011 16:51:45 -0300 Subject: [media] Technisat AirStar TeleStick 2 Based on staging 2.6.39. This patch is based on Veit Berwig's work. Signed-off-by: Lukas Fisch Thanks-to: Veit Berwig Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index c25b4281cff..97af266d7f1 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -2801,6 +2801,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) }, + { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -3410,7 +3411,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { { "DiBcom STK7770P reference design", { &dib0700_usb_id_table[59], NULL }, @@ -3422,6 +3423,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { &dib0700_usb_id_table[60], NULL}, { NULL }, }, + { "TechniSat AirStar TeleStick 2", + { &dib0700_usb_id_table[74], NULL }, + { NULL }, + }, }, .rc.core = { diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index b71540d7e07..3a8b7446b7b 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -317,5 +317,6 @@ #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac #define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001 #define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002 +#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004 #define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500 #endif -- cgit v1.2.3-70-g09d2 From 5265ea54bf442cef83bcbb8b5da03d1fdb37bcb8 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 27 Feb 2011 16:17:25 -0300 Subject: [media] dw2102: X3M TV SPC1400HD added The card consist of PCI to USB bridge and USB DVB-S2 receiver. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 1a1b84c3a53..3ec0e8e77bd 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1440,6 +1440,7 @@ static struct usb_device_id dw2102_table[] = { {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, + {USB_DEVICE(0x1f4d, 0x3100)}, { } }; @@ -1813,7 +1814,7 @@ static struct dvb_usb_device_properties su3000_properties = { } } }, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { { "SU3000HD DVB-S USB2.0", { &dw2102_table[10], NULL }, @@ -1823,6 +1824,10 @@ static struct dvb_usb_device_properties su3000_properties = { { &dw2102_table[11], NULL }, { NULL }, }, + { "X3M TV SPC1400HD PCI", + { &dw2102_table[14], NULL }, + { NULL }, + }, } }; -- cgit v1.2.3-70-g09d2 From e86e4dfa5a436ccbef9ea4f7c28907aef40b875f Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 27 Feb 2011 16:18:34 -0300 Subject: [media] dw2102: remove unnecessary delays for i2c transfer for some cards Prof 7500 and TeVii s630, s660, s480 works faster now Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 3ec0e8e77bd..1b75da0aaff 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -590,8 +590,6 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], break; } } - - msleep(3); } mutex_unlock(&d->i2c_mutex); -- cgit v1.2.3-70-g09d2 From a84adf4007d80249cbe04da4ee80689a8cfdffda Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 27 Feb 2011 16:18:38 -0300 Subject: [media] dw2102: i2c transfer corrected for some cards Prof 7500 and TeVii s630, s660, s480 works better now Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 1b75da0aaff..ac70e7b79e2 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -564,14 +564,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i += 16; len -= 16; } while (len > 0); - } else if ((udev->descriptor.idProduct == 0x7500) - && (j < (num - 1))) { + } else if (j < (num - 1)) { /* write register addr before read */ u8 obuf[msg[j].len + 2]; obuf[0] = msg[j + 1].len; obuf[1] = (msg[j].addr << 1); memcpy(obuf + 2, msg[j].buf, msg[j].len); - ret = dw210x_op_rw(d->udev, 0x92, 0, 0, + ret = dw210x_op_rw(d->udev, + udev->descriptor.idProduct == + 0x7500 ? 0x92 : 0x90, 0, 0, obuf, msg[j].len + 2, DW210X_WRITE_MSG); break; @@ -581,8 +582,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf[0] = msg[j].len + 1; obuf[1] = (msg[j].addr << 1); memcpy(obuf + 2, msg[j].buf, msg[j].len); - ret = dw210x_op_rw(d->udev, - (num > 1 ? 0x90 : 0x80), 0, 0, + ret = dw210x_op_rw(d->udev, 0x80, 0, 0, obuf, msg[j].len + 2, DW210X_WRITE_MSG); break; -- cgit v1.2.3-70-g09d2 From b16af29a561c92ed76b5b882dd68bb082b07a09b Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 27 Feb 2011 16:22:57 -0300 Subject: [media] dw2102: i2c transfer corrected for yet another cards Related to Acorp DS120 and some revisions of DVBWorld DW2102. If you read three or more registers at one time, you get wrong value for third etc. Actually, it didn't affect the driver as it reads registers only by one at a time. But it needs to correct. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index ac70e7b79e2..2889d32bec2 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -156,8 +156,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], /* read stv0299 register */ value = msg[0].buf[0];/* register */ for (i = 0; i < msg[1].len; i++) { - value = value + i; - ret = dw210x_op_rw(d->udev, 0xb5, value, 0, + ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0, buf6, 2, DW210X_READ_MSG); msg[1].buf[i] = buf6[0]; } -- cgit v1.2.3-70-g09d2 From fd5466d1dfeba87155c7af70b7d53faa60960c19 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 27 Feb 2011 16:22:52 -0300 Subject: [media] dw2102: prof 1100 corrected Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 2889d32bec2..98cf30270f7 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1111,18 +1111,25 @@ static int zl100313_frontend_attach(struct dvb_usb_adapter *d) static int stv0288_frontend_attach(struct dvb_usb_adapter *d) { + u8 obuf[] = {7, 1}; + d->fe = dvb_attach(stv0288_attach, &earda_config, &d->dev->i2c_adap); - if (d->fe != NULL) { - if (dvb_attach(stb6000_attach, d->fe, 0x61, - &d->dev->i2c_adap)) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached stv0288+stb6000!\n"); - return 0; - } - } - return -EIO; + if (d->fe == NULL) + return -EIO; + + if (NULL == dvb_attach(stb6000_attach, d->fe, 0x61, &d->dev->i2c_adap)) + return -EIO; + + d->fe->ops.set_voltage = dw210x_set_voltage; + + dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); + + info("Attached stv0288+stb6000!\n"); + + return 0; + } static int ds3000_frontend_attach(struct dvb_usb_adapter *d) -- cgit v1.2.3-70-g09d2 From c1e13971b19324305b35fafc080b527465214d3c Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Fri, 18 Mar 2011 19:23:05 -0300 Subject: [media] af9015: enhance RC Patch from Ian Armstrong. I've encountered a couple of problems with the current af9015 driver as supplied with the 2.6.37 kernel, that the attached patch appears to fix. (I've generated this patch against the current v4l-dvb git). Some key-presses are lost. A key-press is only generated upon 'valid' data (buf[14] == (u8) ~buf[15]), but the buffer is wiped before this check. Sometimes the 15th byte has not been set at the time of read, so the data isn't valid & ignored. On the next poll the 15th byte has been set, but the rest of the data was wiped previously, so the data is still invalid & the key is lost. Weird repeat error, where an old key press is sometimes repeated in error. ie. button sequence '1 (pause) 2 (pause) 3 (pause) 4' generates output like '1 (pause) 2 (pause) 23 (pause) 4'. The current driver zeroes the data for the key pushed, but sometimes this data is already zero but with other bytes set suggesting a repeat code. This results in the last key being incorrectly repeated. This patch attempts to reduce the risk of a missed key-press & also stop the random repeat of an old key-press when a new key is pressed. Signed-off-by: Ian Armstrong Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 39 +++++++++++++++++++++++++++----------- drivers/media/dvb/dvb-usb/af9015.h | 1 + 2 files changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 8671ca362c8..6457d042b1a 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -479,6 +479,9 @@ static int af9015_init_endpoint(struct dvb_usb_device *d) ret = af9015_set_reg_bit(d, 0xd50b, 0); else ret = af9015_clear_reg_bit(d, 0xd50b, 0); + if (ret) + goto error; + ret = af9015_write_reg(d, 0x98e9, 0xff); error: if (ret) err("endpoint init failed:%d", ret); @@ -1016,22 +1019,35 @@ static int af9015_rc_query(struct dvb_usb_device *d) { struct af9015_state *priv = d->priv; int ret; - u8 buf[16]; + u8 buf[17]; /* read registers needed to detect remote controller code */ ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); if (ret) goto error; - if (buf[14] || buf[15]) { + /* If any of these are non-zero, assume invalid data */ + if (buf[1] || buf[2] || buf[3]) + return ret; + + /* Check for repeat of previous code */ + if ((priv->rc_repeat != buf[6] || buf[0]) && + !memcmp(&buf[12], priv->rc_last, 4)) { + deb_rc("%s: key repeated\n", __func__); + rc_keydown(d->rc_dev, priv->rc_keycode, 0); + priv->rc_repeat = buf[6]; + return ret; + } + + /* Only process key if canary killed */ + if (buf[16] != 0xff && buf[0] != 0x01) { + /* Reset the canary */ + af9015_write_reg(d, 0x98e9, 0xff); deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, buf[12], buf[13], buf[14], buf[15]); - /* clean IR code from mem */ - ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); - if (ret) - goto error; - + /* Remember this key */ + memcpy(priv->rc_last, &buf[12], 4); if (buf[14] == (u8) ~buf[15]) { if (buf[12] == (u8) ~buf[13]) { /* NEC */ @@ -1041,15 +1057,16 @@ static int af9015_rc_query(struct dvb_usb_device *d) priv->rc_keycode = buf[12] << 16 | buf[13] << 8 | buf[14]; } - rc_keydown(d->rc_dev, priv->rc_keycode, 0); } else { - priv->rc_keycode = 0; /* clear just for sure */ + priv->rc_keycode = buf[12] << 24 | buf[13] << 16 | + buf[14] << 8 | buf[15]; } - } else if (priv->rc_repeat != buf[6] || buf[0]) { - deb_rc("%s: key repeated\n", __func__); rc_keydown(d->rc_dev, priv->rc_keycode, 0); } else { deb_rc("%s: no key press\n", __func__); + /* Invalidate last keypress */ + /* Not really needed, but helps with debug */ + priv->rc_last[2] = priv->rc_last[3]; } priv->rc_repeat = buf[6]; diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index f20cfa6ed69..beb3004f00b 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -102,6 +102,7 @@ struct af9015_state { struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ u8 rc_repeat; u32 rc_keycode; + u8 rc_last[4]; }; struct af9015_config { -- cgit v1.2.3-70-g09d2 From 1e8750c2ac2bcbf2b084d3fa77cbb5eef33b3e7f Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 18 Mar 2011 19:36:42 -0300 Subject: [media] af9015: small RC change Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 6457d042b1a..da2f87efe07 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -479,9 +479,7 @@ static int af9015_init_endpoint(struct dvb_usb_device *d) ret = af9015_set_reg_bit(d, 0xd50b, 0); else ret = af9015_clear_reg_bit(d, 0xd50b, 0); - if (ret) - goto error; - ret = af9015_write_reg(d, 0x98e9, 0xff); + error: if (ret) err("endpoint init failed:%d", ret); @@ -614,6 +612,11 @@ static int af9015_init(struct dvb_usb_device *d) int ret; deb_info("%s:\n", __func__); + /* init RC canary */ + ret = af9015_write_reg(d, 0x98e9, 0xff); + if (ret) + goto error; + ret = af9015_init_endpoint(d); if (ret) goto error; @@ -1041,11 +1044,14 @@ static int af9015_rc_query(struct dvb_usb_device *d) /* Only process key if canary killed */ if (buf[16] != 0xff && buf[0] != 0x01) { - /* Reset the canary */ - af9015_write_reg(d, 0x98e9, 0xff); deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, buf[12], buf[13], buf[14], buf[15]); + /* Reset the canary */ + ret = af9015_write_reg(d, 0x98e9, 0xff); + if (ret) + goto error; + /* Remember this key */ memcpy(priv->rc_last, &buf[12], 4); if (buf[14] == (u8) ~buf[15]) { @@ -1058,6 +1064,7 @@ static int af9015_rc_query(struct dvb_usb_device *d) buf[13] << 8 | buf[14]; } } else { + /* 32 bit NEC */ priv->rc_keycode = buf[12] << 24 | buf[13] << 16 | buf[14] << 8 | buf[15]; } -- cgit v1.2.3-70-g09d2 From 04599c2b1ff1eece19b7abaacd97266b8a6b79f2 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 19 Mar 2011 14:25:36 -0300 Subject: [media] af9015: map remote for TerraTec Cinergy T Stick RC Map rc-terratec-slim-2 for TerraTec Cinergy T Stick RC device. Signed-off-by: Antti Palosaari Cc: Martin Groszhauser Cc: TerraTux Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index da2f87efe07..0bbc91f5038 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -744,6 +744,8 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { }; static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { + { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC, + RC_MAP_TERRATEC_SLIM_2 }, { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, RC_MAP_TERRATEC_SLIM }, { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, -- cgit v1.2.3-70-g09d2 From 582e565caeaccf145e2256b84d4fde827fede72e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 19 Mar 2011 16:51:43 -0300 Subject: [media] af9015: reimplement firmware download Split FW download packages smarter way and bug free. Implementation is based of Andrea Merello's example he provided for tda18218 driver. Count remaining FW bytes down in loop instead of division and modulo combination used earlier. Thanks-to: Andrea Merello Signed-off-by: Antti Palosaari Cc: Andrea Merello Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 0bbc91f5038..100ebc37e99 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -665,9 +665,8 @@ error: static int af9015_download_firmware(struct usb_device *udev, const struct firmware *fw) { - int i, len, packets, remainder, ret; + int i, len, remaining, ret; struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; - u16 addr = 0x5100; /* firmware start address */ u16 checksum = 0; deb_info("%s:\n", __func__); @@ -679,24 +678,20 @@ static int af9015_download_firmware(struct usb_device *udev, af9015_config.firmware_size = fw->size; af9015_config.firmware_checksum = checksum; - #define FW_PACKET_MAX_DATA 55 - - packets = fw->size / FW_PACKET_MAX_DATA; - remainder = fw->size % FW_PACKET_MAX_DATA; - len = FW_PACKET_MAX_DATA; - for (i = 0; i <= packets; i++) { - if (i == packets) /* set size of the last packet */ - len = remainder; + #define FW_ADDR 0x5100 /* firmware start address */ + #define LEN_MAX 55 /* max packet size */ + for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { + len = remaining; + if (len > LEN_MAX) + len = LEN_MAX; req.data_len = len; - req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); - req.addr = addr; - addr += FW_PACKET_MAX_DATA; + req.data = (u8 *) &fw->data[fw->size - remaining]; + req.addr = FW_ADDR + fw->size - remaining; ret = af9015_rw_udev(udev, &req); if (ret) { - err("firmware download failed at packet %d with " \ - "code %d", i, ret); + err("firmware download failed:%d", ret); goto error; } } -- cgit v1.2.3-70-g09d2 From 9d4540c9395f5f01cdd0cf60d230ec8bee165bb8 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sat, 12 Feb 2011 22:35:08 -0300 Subject: [media] v180 - DM04/QQBOX added support for BS2F7HZ0194 versions Old versions of these boxes have the BS2F7HZ0194 tuner module on both the LME2510 and LME2510C. Firmware dvb-usb-lme2510-s0194.fw and/or dvb-usb-lme2510c-s0194.fw files are required. See Documentation/dvb/lmedm04.txt Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/lmedm04.c | 230 ++++++++++++++++++++++++++---------- 1 file changed, 170 insertions(+), 60 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index 46ccd01a769..fa64b6c15ef 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -2,7 +2,9 @@ * * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395 * LME2510C + LG TDQY-P001F + * LME2510C + BS2F7HZ0194 * LME2510 + LG TDQY-P001F + * LME2510 + BS2F7HZ0194 * * MVB7395 (LME2510C+SHARP:BS2F7HZ7395) * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V) @@ -12,20 +14,22 @@ * * MVB0001F (LME2510C+LGTDQT-P001F) * + * MV0194 (LME2510+SHARP:BS2F7HZ0194) + * SHARP:BS2F7HZ0194 = (STV0299+IX2410) + * + * MVB0194 (LME2510C+SHARP0194) + * * For firmware see Documentation/dvb/lmedm04.txt * * I2C addresses: * 0xd0 - STV0288 - Demodulator * 0xc0 - Sharp IX2505V - Tuner - * --or-- + * -- * 0x1c - TDA10086 - Demodulator * 0xc0 - TDA8263 - Tuner - * - * ***Please Note*** - * There are other variants of the DM04 - * ***NOT SUPPORTED*** - * MV0194 (LME2510+SHARP0194) - * MVB0194 (LME2510C+SHARP0194) + * -- + * 0xd0 - STV0299 - Demodulator + * 0xc0 - IX2410 - Tuner * * * VID = 3344 PID LME2510=1122 LME2510C=1120 @@ -55,6 +59,9 @@ * * QQbox suffers from noise on LNB voltage. * + * LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system + * with other tuners. After a cold reset streaming will not start. + * * PID functions have been removed from this driver version due to * problems with different firmware and application versions. */ @@ -69,6 +76,9 @@ #include "tda10086.h" #include "stv0288.h" #include "ix2505v.h" +#include "stv0299.h" +#include "dvb-pll.h" +#include "z0194a.h" @@ -96,8 +106,11 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +#define TUNER_DEFAULT 0x0 #define TUNER_LG 0x1 #define TUNER_S7395 0x2 +#define TUNER_S0194 0x3 struct lme2510_state { u8 id; @@ -249,6 +262,7 @@ static void lme2510_int_response(struct urb *lme_urb) st->time_key = ibuf[7]; break; case TUNER_S7395: + case TUNER_S0194: /* Tweak for earlier firmware*/ if (ibuf[1] == 0x03) { if (ibuf[2] > 1) @@ -364,6 +378,18 @@ static int lme2510_msg(struct dvb_usb_device *d, msleep(5); } break; + case TUNER_S0194: + if (wbuf[2] == 0xd0) { + if (wbuf[3] == 0x1b) { + st->signal_lock = rbuf[1]; + if ((st->stream_on & 1) && + (st->signal_lock & 0x8)) { + lme2510_stream_restart(d); + st->i2c_talk_onoff = 0; + } + } + } + break; default: break; } @@ -423,6 +449,34 @@ static int lme2510_msg(struct dvb_usb_device *d, break; } break; + case TUNER_S0194: + switch (wbuf[3]) { + case 0x18: + rbuf[0] = 0x55; + rbuf[1] = (st->signal_level & 0x80) + ? 0 : (st->signal_level * 2); + break; + case 0x24: + rbuf[0] = 0x55; + rbuf[1] = st->signal_sn; + break; + case 0x1b: + rbuf[0] = 0x55; + rbuf[1] = st->signal_lock; + break; + case 0x19: + case 0x25: + case 0x1e: + case 0x1d: + rbuf[0] = 0x55; + rbuf[1] = 0x00; + break; + default: + lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen); + st->i2c_talk_onoff = 1; + break; + } + break; default: break; } @@ -517,17 +571,14 @@ static int lme2510_identify_state(struct usb_device *udev, struct dvb_usb_device_description **desc, int *cold) { - if (lme2510_return_status(udev) == 0x44) - *cold = 1; - else - *cold = 0; + *cold = 0; return 0; } static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { struct lme2510_state *st = adap->dev->priv; - static u8 clear_reg_3[] = LME_CLEAR_PID; + static u8 clear_reg_3[] = LME_CLEAR_PID; static u8 rbuf[1]; int ret = 0, rlen = sizeof(rbuf); @@ -658,9 +709,6 @@ static int lme2510_download_firmware(struct usb_device *dev, return (ret < 0) ? -ENODEV : 0; } -/* Default firmware for LME2510C */ -char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw"; - static void lme_coldreset(struct usb_device *dev) { int ret = 0, len_in; @@ -678,49 +726,83 @@ static void lme_coldreset(struct usb_device *dev) static int lme_firmware_switch(struct usb_device *udev, int cold) { const struct firmware *fw = NULL; - char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; - char lme2510c_lg[] = "dvb-usb-lme2510c-lg.fw"; - char *firm_msg[] = {"Loading", "Switching to"}; - int ret; + const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; + const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw"; + const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw"; + const char fw_lg[] = "dvb-usb-lme2510-lg.fw"; + const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw"; + const char *fw_lme; + int ret, cold_fw; cold = (cold > 0) ? (cold & 1) : 0; - if (udev->descriptor.idProduct == 0x1122) - return 0; + cold_fw = !cold; - switch (dvb_usb_lme2510_firmware) { - case 0: - default: - memcpy(&lme_firmware, lme2510c_s7395, sizeof(lme2510c_s7395)); - ret = request_firmware(&fw, lme_firmware, &udev->dev); - if (ret == 0) { - info("FRM %s S7395 Firmware", firm_msg[cold]); + if (udev->descriptor.idProduct == 0x1122) { + switch (dvb_usb_lme2510_firmware) { + default: + dvb_usb_lme2510_firmware = TUNER_S0194; + case TUNER_S0194: + fw_lme = fw_s0194; + ret = request_firmware(&fw, fw_lme, &udev->dev); + if (ret == 0) { + cold = 0;/*lme2510-s0194 cannot cold reset*/ + break; + } + dvb_usb_lme2510_firmware = TUNER_LG; + case TUNER_LG: + fw_lme = fw_lg; + ret = request_firmware(&fw, fw_lme, &udev->dev); + if (ret == 0) + break; + info("FRM No Firmware Found - please install"); + dvb_usb_lme2510_firmware = TUNER_DEFAULT; + cold = 0; + cold_fw = 0; break; } - if (cold == 0) - dvb_usb_lme2510_firmware = 1; - else + } else { + switch (dvb_usb_lme2510_firmware) { + default: + dvb_usb_lme2510_firmware = TUNER_S7395; + case TUNER_S7395: + fw_lme = fw_c_s7395; + ret = request_firmware(&fw, fw_lme, &udev->dev); + if (ret == 0) + break; + dvb_usb_lme2510_firmware = TUNER_LG; + case TUNER_LG: + fw_lme = fw_c_lg; + ret = request_firmware(&fw, fw_lme, &udev->dev); + if (ret == 0) + break; + dvb_usb_lme2510_firmware = TUNER_S0194; + case TUNER_S0194: + fw_lme = fw_c_s0194; + ret = request_firmware(&fw, fw_lme, &udev->dev); + if (ret == 0) + break; + info("FRM No Firmware Found - please install"); + dvb_usb_lme2510_firmware = TUNER_DEFAULT; cold = 0; - case 1: - memcpy(&lme_firmware, lme2510c_lg, sizeof(lme2510c_lg)); - ret = request_firmware(&fw, lme_firmware, &udev->dev); - if (ret == 0) { - info("FRM %s LG Firmware", firm_msg[cold]); + cold_fw = 0; break; } - info("FRM No Firmware Found - please install"); - dvb_usb_lme2510_firmware = 0; - cold = 0; - break; } - release_firmware(fw); + if (cold_fw) { + info("FRM Loading %s file", fw_lme); + ret = lme2510_download_firmware(udev, fw); + } if (cold) { + info("FRM Changing to %s firmware", fw_lme); lme_coldreset(udev); return -ENODEV; } + release_firmware(fw); + return ret; } @@ -758,6 +840,18 @@ static struct ix2505v_config lme_tuner = { .tuner_chargepump = 0x3, }; +static struct stv0299_config sharp_z0194_config = { + .demod_address = 0xd0, + .inittab = sharp_z0194a_inittab, + .mclk = 88000000UL, + .invert = 0, + .skip_reinit = 0, + .lock_output = STV0299_LOCKOUTPUT_1, + .volt13_op0_op1 = STV0299_VOLT13_OP1, + .min_delay_ms = 100, + .set_symbol_rate = sharp_z0194a_set_symbol_rate, +}; + static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { @@ -793,7 +887,8 @@ static int lme_name(struct dvb_usb_adapter *adap) { struct lme2510_state *st = adap->dev->priv; const char *desc = adap->dev->desc->name; - char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395"}; + char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395", + " SHARP:BS2F7HZ0194"}; char *name = adap->fe->ops.info.name; strlcpy(name, desc, 128); @@ -820,26 +915,40 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) st->i2c_tuner_gate_r = 4; st->i2c_tuner_addr = 0xc0; st->tuner_config = TUNER_LG; - if (dvb_usb_lme2510_firmware != 1) { - dvb_usb_lme2510_firmware = 1; + if (dvb_usb_lme2510_firmware != TUNER_LG) { + dvb_usb_lme2510_firmware = TUNER_LG; ret = lme_firmware_switch(adap->dev->udev, 1); - } else /*stops LG/Sharp multi tuner problems*/ - dvb_usb_lme2510_firmware = 0; + } + goto end; + } + + st->i2c_gate = 4; + adap->fe = dvb_attach(stv0299_attach, &sharp_z0194_config, + &adap->dev->i2c_adap); + if (adap->fe) { + info("FE Found Stv0299"); + st->i2c_tuner_gate_w = 4; + st->i2c_tuner_gate_r = 5; + st->i2c_tuner_addr = 0xc0; + st->tuner_config = TUNER_S0194; + if (dvb_usb_lme2510_firmware != TUNER_S0194) { + dvb_usb_lme2510_firmware = TUNER_S0194; + ret = lme_firmware_switch(adap->dev->udev, 1); + } goto end; } st->i2c_gate = 5; adap->fe = dvb_attach(stv0288_attach, &lme_config, &adap->dev->i2c_adap); - if (adap->fe) { info("FE Found Stv0288"); st->i2c_tuner_gate_w = 4; st->i2c_tuner_gate_r = 5; st->i2c_tuner_addr = 0xc0; st->tuner_config = TUNER_S7395; - if (dvb_usb_lme2510_firmware != 0) { - dvb_usb_lme2510_firmware = 0; + if (dvb_usb_lme2510_firmware != TUNER_S7395) { + dvb_usb_lme2510_firmware = TUNER_S7395; ret = lme_firmware_switch(adap->dev->udev, 1); } } else { @@ -847,6 +956,7 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) return -ENODEV; } + end: if (ret) { kfree(adap->fe); adap->fe = NULL; @@ -855,14 +965,13 @@ end: if (ret) { adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; ret = lme_name(adap); - return ret; } static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) { struct lme2510_state *st = adap->dev->priv; - char *tun_msg[] = {"", "TDA8263", "IX2505V"}; + char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"}; int ret = 0; switch (st->tuner_config) { @@ -876,6 +985,11 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) &adap->dev->i2c_adap)) ret = st->tuner_config; break; + case TUNER_S0194: + if (dvb_attach(dvb_pll_attach , adap->fe, 0xc0, + &adap->dev->i2c_adap, DVB_PLL_OPERA1)) + ret = st->tuner_config; + break; default: break; } @@ -936,7 +1050,10 @@ static int lme2510_probe(struct usb_interface *intf, return -ENODEV; } - lme_firmware_switch(udev, 0); + if (lme2510_return_status(udev) == 0x44) { + lme_firmware_switch(udev, 0); + return -ENODEV; + } if (0 == dvb_usb_device_init(intf, &lme2510_properties, THIS_MODULE, NULL, adapter_nr)) { @@ -964,10 +1081,6 @@ MODULE_DEVICE_TABLE(usb, lme2510_table); static struct dvb_usb_device_properties lme2510_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, - .download_firmware = lme2510_download_firmware, - .firmware = "dvb-usb-lme2510-lg.fw", - .size_of_priv = sizeof(struct lme2510_state), .num_adapters = 1, .adapter = { @@ -1004,9 +1117,6 @@ static struct dvb_usb_device_properties lme2510_properties = { static struct dvb_usb_device_properties lme2510c_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, - .download_firmware = lme2510_download_firmware, - .firmware = (const char *)&lme_firmware, .size_of_priv = sizeof(struct lme2510_state), .num_adapters = 1, .adapter = { @@ -1109,5 +1219,5 @@ module_exit(lme2510_module_exit); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); -MODULE_VERSION("1.75"); +MODULE_VERSION("1.80"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From f8931f56f51a795e030318b95e4a0f8ac453e35e Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 23 Jan 2011 18:22:45 -0300 Subject: [media] DM04/QQBOX Update V1.76 - use 32 bit remote decoding Use 32 bit decoding to add support for more than one variant of remote control. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/lmedm04.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index fa64b6c15ef..cd26e7c1536 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -204,7 +204,7 @@ static int lme2510_stream_restart(struct dvb_usb_device *d) rbuff, sizeof(rbuff)); return ret; } -static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress) +static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress) { struct dvb_usb_device *d = adap->dev; @@ -250,7 +250,8 @@ static void lme2510_int_response(struct urb *lme_urb) case 0xaa: debug_data_snipet(1, "INT Remote data snipet in", ibuf); lme2510_remote_keypress(adap, - (u16)(ibuf[4]<<8)+ibuf[5]); + (u32)(ibuf[2] << 24) + (ibuf[3] << 16) + + (ibuf[4] << 8) + ibuf[5]); break; case 0xbb: switch (st->tuner_config) { -- cgit v1.2.3-70-g09d2 From 444cc20b3d6141a5fa9a9774a6b710e16af6110d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Jan 2011 12:18:36 -0300 Subject: [media] rc/keymaps: use KEY_CAMERA for snapshots On a few places, KEY_MHP were used for snapshots. However, KEY_CAMERA is used for it on all the other keyboards that have a snapshot/Picture button. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jarod Wilson --- drivers/media/dvb/dvb-usb/digitv.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-m135a.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c | 2 +- drivers/media/rc/keymaps/rc-budget-ci-old.c | 3 ++- drivers/media/rc/keymaps/rc-encore-enltv.c | 2 +- drivers/media/rc/keymaps/rc-hauppauge-new.c | 2 +- drivers/media/rc/keymaps/rc-nebula.c | 2 +- drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index f2dbce7edb3..f6344cdd360 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -176,7 +176,7 @@ static struct rc_map_table rc_map_digitv_table[] = { { 0xaf59, KEY_AUX }, { 0x5f5a, KEY_DVD }, { 0x6f5a, KEY_POWER }, - { 0x9f5a, KEY_MHP }, /* labelled 'Picture' */ + { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */ { 0xaf5a, KEY_AUDIO }, { 0x5f65, KEY_INFO }, { 0x6f65, KEY_F13 }, /* 16:9 */ diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c index 357fea58a46..3d2cbe4e5e4 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c @@ -108,7 +108,7 @@ static struct rc_map_table avermedia_m135a[] = { { 0x0414, KEY_TEXT }, { 0x0415, KEY_EPG }, { 0x041a, KEY_TV2 }, /* PIP */ - { 0x041b, KEY_MHP }, /* Snapshot */ + { 0x041b, KEY_CAMERA }, /* Snapshot */ { 0x0417, KEY_RECORD }, { 0x0416, KEY_PLAYPAUSE }, diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c index e694e6eac37..8cd7f28808b 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c @@ -56,7 +56,7 @@ static struct rc_map_table avermedia_m733a_rm_k6[] = { { 0x0414, KEY_TEXT }, { 0x0415, KEY_EPG }, { 0x041a, KEY_TV2 }, /* PIP */ - { 0x041b, KEY_MHP }, /* Snapshot */ + { 0x041b, KEY_CAMERA }, /* Snapshot */ { 0x0417, KEY_RECORD }, { 0x0416, KEY_PLAYPAUSE }, diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c index 97fc3862f60..2f66e4310d2 100644 --- a/drivers/media/rc/keymaps/rc-budget-ci-old.c +++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c @@ -12,7 +12,8 @@ #include -/* From reading the following remotes: +/* + * From reading the following remotes: * Zenith Universal 7 / TV Mode 807 / VCR Mode 837 * Hauppauge (from NOVA-CI-s box product) * This is a "middle of the road" approach, differences are noted diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c index afa4e92284e..1a0e590b5d2 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv.c @@ -24,7 +24,7 @@ static struct rc_map_table encore_enltv[] = { { 0x1e, KEY_TV }, { 0x00, KEY_VIDEO }, { 0x01, KEY_AUDIO }, /* music */ - { 0x02, KEY_MHP }, /* picture */ + { 0x02, KEY_CAMERA }, /* picture */ { 0x1f, KEY_1 }, { 0x03, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c index bd11da46e56..b6a12feb012 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-hauppauge-new.c @@ -48,7 +48,7 @@ static struct rc_map_table hauppauge_new[] = { "Multimedia Home Platform" - no "PICTURES" key in input.h */ - { 0x1a, KEY_MHP }, + { 0x1a, KEY_CAMERA }, { 0x1b, KEY_EPG }, /* Guide */ { 0x1c, KEY_TV }, diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c index 3e6f077eb70..ddae20e9cd9 100644 --- a/drivers/media/rc/keymaps/rc-nebula.c +++ b/drivers/media/rc/keymaps/rc-nebula.c @@ -27,7 +27,7 @@ static struct rc_map_table nebula[] = { { 0x0b, KEY_AUX }, { 0x0c, KEY_DVD }, { 0x0d, KEY_POWER }, - { 0x0e, KEY_MHP }, /* labelled 'Picture' */ + { 0x0e, KEY_CAMERA }, /* labelled 'Picture' */ { 0x0f, KEY_AUDIO }, { 0x10, KEY_INFO }, { 0x11, KEY_F13 }, /* 16:9 */ diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c index dfc9b15f43a..2ca825b4bef 100644 --- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c @@ -51,7 +51,7 @@ static struct rc_map_table rc5_hauppauge_new[] = { "Multimedia Home Platform" - no "PICTURES" key in input.h */ - { 0x1e1a, KEY_MHP }, + { 0x1e1a, KEY_CAMERA }, { 0x1e1b, KEY_EPG }, /* Guide */ { 0x1e1c, KEY_TV }, -- cgit v1.2.3-70-g09d2 From 991bd3c25e8e07960ecd6bcc7079737f83f17c36 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Jan 2011 12:18:40 -0300 Subject: [media] dw2102: Use multimedia keys instead of an app-specific mapping This driver uses an app-specific keymap for one of the tables. This is wrong. Instead, use the standard keycodes. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jarod Wilson --- drivers/media/dvb/dvb-usb/dw2102.c | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 98cf30270f7..f5b9da18f61 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1224,8 +1224,8 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) } static struct rc_map_table rc_map_dw210x_table[] = { - { 0xf80a, KEY_Q }, /*power*/ - { 0xf80c, KEY_M }, /*mute*/ + { 0xf80a, KEY_POWER2 }, /*power*/ + { 0xf80c, KEY_MUTE }, /*mute*/ { 0xf811, KEY_1 }, { 0xf812, KEY_2 }, { 0xf813, KEY_3 }, @@ -1236,25 +1236,25 @@ static struct rc_map_table rc_map_dw210x_table[] = { { 0xf818, KEY_8 }, { 0xf819, KEY_9 }, { 0xf810, KEY_0 }, - { 0xf81c, KEY_PAGEUP }, /*ch+*/ - { 0xf80f, KEY_PAGEDOWN }, /*ch-*/ - { 0xf81a, KEY_O }, /*vol+*/ - { 0xf80e, KEY_Z }, /*vol-*/ - { 0xf804, KEY_R }, /*rec*/ - { 0xf809, KEY_D }, /*fav*/ - { 0xf808, KEY_BACKSPACE }, /*rewind*/ - { 0xf807, KEY_A }, /*fast*/ - { 0xf80b, KEY_P }, /*pause*/ - { 0xf802, KEY_ESC }, /*cancel*/ - { 0xf803, KEY_G }, /*tab*/ + { 0xf81c, KEY_CHANNELUP }, /*ch+*/ + { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/ + { 0xf81a, KEY_VOLUMEUP }, /*vol+*/ + { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/ + { 0xf804, KEY_RECORD }, /*rec*/ + { 0xf809, KEY_FAVORITES }, /*fav*/ + { 0xf808, KEY_REWIND }, /*rewind*/ + { 0xf807, KEY_FASTFORWARD }, /*fast*/ + { 0xf80b, KEY_PAUSE }, /*pause*/ + { 0xf802, KEY_ESC }, /*cancel*/ + { 0xf803, KEY_TAB }, /*tab*/ { 0xf800, KEY_UP }, /*up*/ - { 0xf81f, KEY_ENTER }, /*ok*/ - { 0xf801, KEY_DOWN }, /*down*/ - { 0xf805, KEY_C }, /*cap*/ - { 0xf806, KEY_S }, /*stop*/ - { 0xf840, KEY_F }, /*full*/ - { 0xf81e, KEY_W }, /*tvmode*/ - { 0xf81b, KEY_B }, /*recall*/ + { 0xf81f, KEY_OK }, /*ok*/ + { 0xf801, KEY_DOWN }, /*down*/ + { 0xf805, KEY_CAMERA }, /*cap*/ + { 0xf806, KEY_STOP }, /*stop*/ + { 0xf840, KEY_ZOOM }, /*full*/ + { 0xf81e, KEY_TV }, /*tvmode*/ + { 0xf81b, KEY_LAST }, /*recall*/ }; static struct rc_map_table rc_map_tevii_table[] = { -- cgit v1.2.3-70-g09d2 From 76fd93b62322e5e4bfdf2744efe92f0de9e6ac4a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Jan 2011 12:18:41 -0300 Subject: [media] opera1: Use multimedia keys instead of an app-specific mapping This driver uses an app-specific keymap for one of the tables. This is wrong. Instead, use the standard keycodes. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jarod Wilson --- drivers/media/dvb/dvb-usb/opera1.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index 1f1b7d6980a..7e569f4dd80 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c @@ -342,23 +342,22 @@ static struct rc_map_table rc_map_opera1_table[] = { {0x49b6, KEY_8}, {0x05fa, KEY_9}, {0x45ba, KEY_0}, - {0x09f6, KEY_UP}, /*chanup */ - {0x1be5, KEY_DOWN}, /*chandown */ - {0x5da3, KEY_LEFT}, /*voldown */ - {0x5fa1, KEY_RIGHT}, /*volup */ - {0x07f8, KEY_SPACE}, /*tab */ - {0x1fe1, KEY_ENTER}, /*play ok */ - {0x1be4, KEY_Z}, /*zoom */ - {0x59a6, KEY_M}, /*mute */ - {0x5ba5, KEY_F}, /*tv/f */ - {0x19e7, KEY_R}, /*rec */ - {0x01fe, KEY_S}, /*Stop */ - {0x03fd, KEY_P}, /*pause */ - {0x03fc, KEY_W}, /*<- -> */ - {0x07f9, KEY_C}, /*capture */ - {0x47b9, KEY_Q}, /*exit */ - {0x43bc, KEY_O}, /*power */ - + {0x09f6, KEY_CHANNELUP}, /*chanup */ + {0x1be5, KEY_CHANNELDOWN}, /*chandown */ + {0x5da3, KEY_VOLUMEDOWN}, /*voldown */ + {0x5fa1, KEY_VOLUMEUP}, /*volup */ + {0x07f8, KEY_SPACE}, /*tab */ + {0x1fe1, KEY_OK}, /*play ok */ + {0x1be4, KEY_ZOOM}, /*zoom */ + {0x59a6, KEY_MUTE}, /*mute */ + {0x5ba5, KEY_RADIO}, /*tv/f */ + {0x19e7, KEY_RECORD}, /*rec */ + {0x01fe, KEY_STOP}, /*Stop */ + {0x03fd, KEY_PAUSE}, /*pause */ + {0x03fc, KEY_SCREEN}, /*<- -> */ + {0x07f9, KEY_CAMERA}, /*capture */ + {0x47b9, KEY_ESC}, /*exit */ + {0x43bc, KEY_POWER2}, /*power */ }; static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) -- cgit v1.2.3-70-g09d2 From 898a83e9243e2398e863887b36476c3cc227074a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Jan 2011 12:18:42 -0300 Subject: [media] a800: Fix a few wrong IR key assignments Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jarod Wilson --- drivers/media/dvb/dvb-usb/a800.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index 53b93a4b6f8..f8e9bf116f2 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c @@ -38,8 +38,8 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr } static struct rc_map_table rc_map_a800_table[] = { - { 0x0201, KEY_PROG1 }, /* SOURCE */ - { 0x0200, KEY_POWER }, /* POWER */ + { 0x0201, KEY_MODE }, /* SOURCE */ + { 0x0200, KEY_POWER2 }, /* POWER */ { 0x0205, KEY_1 }, /* 1 */ { 0x0206, KEY_2 }, /* 2 */ { 0x0207, KEY_3 }, /* 3 */ @@ -52,8 +52,8 @@ static struct rc_map_table rc_map_a800_table[] = { { 0x0212, KEY_LEFT }, /* L / DISPLAY */ { 0x0211, KEY_0 }, /* 0 */ { 0x0213, KEY_RIGHT }, /* R / CH RTN */ - { 0x0217, KEY_PROG2 }, /* SNAP SHOT */ - { 0x0210, KEY_PROG3 }, /* 16-CH PREV */ + { 0x0217, KEY_CAMERA }, /* SNAP SHOT */ + { 0x0210, KEY_LAST }, /* 16-CH PREV */ { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */ { 0x020c, KEY_ZOOM }, /* FULL SCREEN */ { 0x021f, KEY_VOLUMEUP }, /* VOL UP */ -- cgit v1.2.3-70-g09d2