V4L/DVB (9107): Alternative version of Terratec Cinergy T2 driver
Alternative version of the Terratec Cinergy T2 driver that uses the dvb framework. Signed-off-by: Tomi Orava <tomimo@ncircle.nullnet.fi> Signed-off-by: Thierry MERLE <thierry.merle@free.fr> [mchehab@redhat.com: fix dvb Makefile] Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
07c6bb9e6e
commit
986bd1e58b
10 changed files with 689 additions and 1195 deletions
|
@ -20,7 +20,6 @@ comment "Supported USB Adapters"
|
||||||
source "drivers/media/dvb/dvb-usb/Kconfig"
|
source "drivers/media/dvb/dvb-usb/Kconfig"
|
||||||
source "drivers/media/dvb/ttusb-budget/Kconfig"
|
source "drivers/media/dvb/ttusb-budget/Kconfig"
|
||||||
source "drivers/media/dvb/ttusb-dec/Kconfig"
|
source "drivers/media/dvb/ttusb-dec/Kconfig"
|
||||||
source "drivers/media/dvb/cinergyT2/Kconfig"
|
|
||||||
source "drivers/media/dvb/siano/Kconfig"
|
source "drivers/media/dvb/siano/Kconfig"
|
||||||
|
|
||||||
comment "Supported FlexCopII (B2C2) Adapters"
|
comment "Supported FlexCopII (B2C2) Adapters"
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
# Makefile for the kernel multimedia device drivers.
|
# Makefile for the kernel multimedia device drivers.
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ siano/ dm1105/
|
obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
config DVB_CINERGYT2
|
|
||||||
tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
|
|
||||||
depends on DVB_CORE && USB && INPUT
|
|
||||||
help
|
|
||||||
Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
|
|
||||||
|
|
||||||
Say Y if you own such a device and want to use it.
|
|
||||||
|
|
||||||
|
|
||||||
config DVB_CINERGYT2_TUNING
|
|
||||||
bool "sophisticated fine-tuning for CinergyT2 cards"
|
|
||||||
depends on DVB_CINERGYT2
|
|
||||||
help
|
|
||||||
Here you can fine-tune some parameters of the CinergyT2 driver.
|
|
||||||
|
|
||||||
Normally you don't need to touch this, but in exotic setups you
|
|
||||||
may fine-tune your setup and adjust e.g. DMA buffer sizes for
|
|
||||||
a particular application.
|
|
||||||
|
|
||||||
|
|
||||||
config DVB_CINERGYT2_STREAM_URB_COUNT
|
|
||||||
int "Number of queued USB Request Blocks for Highspeed Stream Transfers"
|
|
||||||
depends on DVB_CINERGYT2_TUNING
|
|
||||||
default "32"
|
|
||||||
help
|
|
||||||
USB Request Blocks for Highspeed Stream transfers are scheduled in
|
|
||||||
a queue for the Host Controller.
|
|
||||||
|
|
||||||
Usually the default value is a safe choice.
|
|
||||||
|
|
||||||
You may increase this number if you are using this device in a
|
|
||||||
Server Environment with many high-traffic USB Highspeed devices
|
|
||||||
sharing the same USB bus.
|
|
||||||
|
|
||||||
|
|
||||||
config DVB_CINERGYT2_STREAM_BUF_SIZE
|
|
||||||
int "Size of URB Stream Buffers for Highspeed Transfers"
|
|
||||||
depends on DVB_CINERGYT2_TUNING
|
|
||||||
default "512"
|
|
||||||
help
|
|
||||||
Should be a multiple of native buffer size of 512 bytes.
|
|
||||||
Default value is a safe choice.
|
|
||||||
|
|
||||||
You may increase this number if you are using this device in a
|
|
||||||
Server Environment with many high-traffic USB Highspeed devices
|
|
||||||
sharing the same USB bus.
|
|
||||||
|
|
||||||
|
|
||||||
config DVB_CINERGYT2_QUERY_INTERVAL
|
|
||||||
int "Status update interval [milliseconds]"
|
|
||||||
depends on DVB_CINERGYT2_TUNING
|
|
||||||
default "250"
|
|
||||||
help
|
|
||||||
This is the interval for status readouts from the demodulator.
|
|
||||||
You may try lower values if you need more responsive signal quality
|
|
||||||
measurements.
|
|
||||||
|
|
||||||
Please keep in mind that these updates cause traffic on the tuner
|
|
||||||
control bus and thus may or may not affect reception sensitivity.
|
|
||||||
|
|
||||||
The default value should be a safe choice for common applications.
|
|
||||||
|
|
||||||
|
|
||||||
config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
|
|
||||||
bool "Register the onboard IR Remote Control Receiver as Input Device"
|
|
||||||
depends on DVB_CINERGYT2_TUNING
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
Enable this option if you want to use the onboard Infrared Remote
|
|
||||||
Control Receiver as Linux-Input device.
|
|
||||||
|
|
||||||
Right now only the keycode table for the default Remote Control
|
|
||||||
delivered with the device is supported, please see the driver
|
|
||||||
source code to find out how to add support for other controls.
|
|
||||||
|
|
||||||
|
|
||||||
config DVB_CINERGYT2_RC_QUERY_INTERVAL
|
|
||||||
int "Infrared Remote Controller update interval [milliseconds]"
|
|
||||||
depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
|
|
||||||
default "50"
|
|
||||||
help
|
|
||||||
If you have a very fast-repeating remote control you can try lower
|
|
||||||
values, for normal consumer receivers the default value should be
|
|
||||||
a safe choice.
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
obj-$(CONFIG_DVB_CINERGYT2) += cinergyT2.o
|
|
||||||
|
|
||||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
|
|
File diff suppressed because it is too large
Load diff
|
@ -259,6 +259,14 @@ config DVB_USB_DW2102
|
||||||
Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
|
Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
|
||||||
and the TeVii S650.
|
and the TeVii S650.
|
||||||
|
|
||||||
|
config DVB_USB_CINERGY_T2
|
||||||
|
tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
|
||||||
|
depends on DVB_USB
|
||||||
|
help
|
||||||
|
Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
|
||||||
|
|
||||||
|
Say Y if you own such a device and want to use it.
|
||||||
|
|
||||||
config DVB_USB_ANYSEE
|
config DVB_USB_ANYSEE
|
||||||
tristate "Anysee DVB-T/C USB2.0 support"
|
tristate "Anysee DVB-T/C USB2.0 support"
|
||||||
depends on DVB_USB
|
depends on DVB_USB
|
||||||
|
|
|
@ -73,6 +73,10 @@ obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
|
||||||
dvb-usb-af9015-objs = af9015.o
|
dvb-usb-af9015-objs = af9015.o
|
||||||
obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
|
obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
|
||||||
|
|
||||||
|
dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
|
||||||
|
obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
|
||||||
|
|
||||||
|
|
||||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
|
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
|
||||||
# due to tuner-xc3028
|
# due to tuner-xc3028
|
||||||
EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
||||||
|
|
230
drivers/media/dvb/dvb-usb/cinergyT2-core.c
Normal file
230
drivers/media/dvb/dvb-usb/cinergyT2-core.c
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
/*
|
||||||
|
* TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
|
||||||
|
*
|
||||||
|
* Based on the dvb-usb-framework code and the
|
||||||
|
* original Terratec Cinergy T2 driver by:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
|
||||||
|
* Holger Waechtler <holger@qanu.de>
|
||||||
|
*
|
||||||
|
* Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cinergyT2.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* debug */
|
||||||
|
int dvb_usb_cinergyt2_debug;
|
||||||
|
int disable_remote;
|
||||||
|
|
||||||
|
module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644);
|
||||||
|
MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 "
|
||||||
|
"(or-able)).");
|
||||||
|
|
||||||
|
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
||||||
|
|
||||||
|
|
||||||
|
/* We are missing a release hook with usb_device data */
|
||||||
|
struct dvb_usb_device *cinergyt2_usb_device;
|
||||||
|
|
||||||
|
static struct dvb_usb_device_properties cinergyt2_properties;
|
||||||
|
|
||||||
|
static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
|
||||||
|
{
|
||||||
|
char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
|
||||||
|
char result[64];
|
||||||
|
return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
|
||||||
|
sizeof(result), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
|
||||||
|
{
|
||||||
|
char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
|
||||||
|
char state[3];
|
||||||
|
return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
{
|
||||||
|
char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
|
||||||
|
char state[3];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
adap->fe = cinergyt2_fe_attach(adap->dev);
|
||||||
|
|
||||||
|
ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
|
||||||
|
sizeof(state), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
|
||||||
|
"state info\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy this pointer as we are gonna need it in the release phase */
|
||||||
|
cinergyt2_usb_device = adap->dev;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dvb_usb_rc_key cinergyt2_rc_keys[] = {
|
||||||
|
{ 0x04, 0x01, KEY_POWER },
|
||||||
|
{ 0x04, 0x02, KEY_1 },
|
||||||
|
{ 0x04, 0x03, KEY_2 },
|
||||||
|
{ 0x04, 0x04, KEY_3 },
|
||||||
|
{ 0x04, 0x05, KEY_4 },
|
||||||
|
{ 0x04, 0x06, KEY_5 },
|
||||||
|
{ 0x04, 0x07, KEY_6 },
|
||||||
|
{ 0x04, 0x08, KEY_7 },
|
||||||
|
{ 0x04, 0x09, KEY_8 },
|
||||||
|
{ 0x04, 0x0a, KEY_9 },
|
||||||
|
{ 0x04, 0x0c, KEY_0 },
|
||||||
|
{ 0x04, 0x0b, KEY_VIDEO },
|
||||||
|
{ 0x04, 0x0d, KEY_REFRESH },
|
||||||
|
{ 0x04, 0x0e, KEY_SELECT },
|
||||||
|
{ 0x04, 0x0f, KEY_EPG },
|
||||||
|
{ 0x04, 0x10, KEY_UP },
|
||||||
|
{ 0x04, 0x14, KEY_DOWN },
|
||||||
|
{ 0x04, 0x11, KEY_LEFT },
|
||||||
|
{ 0x04, 0x13, KEY_RIGHT },
|
||||||
|
{ 0x04, 0x12, KEY_OK },
|
||||||
|
{ 0x04, 0x15, KEY_TEXT },
|
||||||
|
{ 0x04, 0x16, KEY_INFO },
|
||||||
|
{ 0x04, 0x17, KEY_RED },
|
||||||
|
{ 0x04, 0x18, KEY_GREEN },
|
||||||
|
{ 0x04, 0x19, KEY_YELLOW },
|
||||||
|
{ 0x04, 0x1a, KEY_BLUE },
|
||||||
|
{ 0x04, 0x1c, KEY_VOLUMEUP },
|
||||||
|
{ 0x04, 0x1e, KEY_VOLUMEDOWN },
|
||||||
|
{ 0x04, 0x1d, KEY_MUTE },
|
||||||
|
{ 0x04, 0x1b, KEY_CHANNELUP },
|
||||||
|
{ 0x04, 0x1f, KEY_CHANNELDOWN },
|
||||||
|
{ 0x04, 0x40, KEY_PAUSE },
|
||||||
|
{ 0x04, 0x4c, KEY_PLAY },
|
||||||
|
{ 0x04, 0x58, KEY_RECORD },
|
||||||
|
{ 0x04, 0x54, KEY_PREVIOUS },
|
||||||
|
{ 0x04, 0x48, KEY_STOP },
|
||||||
|
{ 0x04, 0x5c, KEY_NEXT }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
||||||
|
{
|
||||||
|
u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
|
||||||
|
*state = REMOTE_NO_KEY_PRESSED;
|
||||||
|
|
||||||
|
dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
|
||||||
|
if (key[4] == 0xff)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* hack to pass checksum on the custom field (is set to 0xeb) */
|
||||||
|
key[2] = ~0x04;
|
||||||
|
dvb_usb_nec_rc_key_to_event(d, key, event, state);
|
||||||
|
if (key[0] != 0)
|
||||||
|
deb_info("key: %x %x %x %x %x\n",
|
||||||
|
key[0], key[1], key[2], key[3], key[4]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_usb_probe(struct usb_interface *intf,
|
||||||
|
const struct usb_device_id *id)
|
||||||
|
{
|
||||||
|
return dvb_usb_device_init(intf, &cinergyt2_properties,
|
||||||
|
THIS_MODULE, NULL, adapter_nr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct usb_device_id cinergyt2_usb_table[] = {
|
||||||
|
{ USB_DEVICE(USB_VID_TERRATEC, 0x0038) },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table);
|
||||||
|
|
||||||
|
static struct dvb_usb_device_properties cinergyt2_properties = {
|
||||||
|
|
||||||
|
.num_adapters = 1,
|
||||||
|
.adapter = {
|
||||||
|
{
|
||||||
|
.streaming_ctrl = cinergyt2_streaming_ctrl,
|
||||||
|
.frontend_attach = cinergyt2_frontend_attach,
|
||||||
|
|
||||||
|
/* parameter for the MPEG2-data transfer */
|
||||||
|
.stream = {
|
||||||
|
.type = USB_BULK,
|
||||||
|
.count = 5,
|
||||||
|
.endpoint = 0x02,
|
||||||
|
.u = {
|
||||||
|
.bulk = {
|
||||||
|
.buffersize = 512,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
.power_ctrl = cinergyt2_power_ctrl,
|
||||||
|
|
||||||
|
.rc_interval = 50,
|
||||||
|
.rc_key_map = cinergyt2_rc_keys,
|
||||||
|
.rc_key_map_size = ARRAY_SIZE(cinergyt2_rc_keys),
|
||||||
|
.rc_query = cinergyt2_rc_query,
|
||||||
|
|
||||||
|
.generic_bulk_ctrl_endpoint = 1,
|
||||||
|
|
||||||
|
.num_device_descs = 1,
|
||||||
|
.devices = {
|
||||||
|
{ .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver",
|
||||||
|
.cold_ids = {NULL},
|
||||||
|
.warm_ids = { &cinergyt2_usb_table[0], NULL },
|
||||||
|
},
|
||||||
|
{ NULL },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct usb_driver cinergyt2_driver = {
|
||||||
|
.name = "cinergyT2",
|
||||||
|
.probe = cinergyt2_usb_probe,
|
||||||
|
.disconnect = dvb_usb_device_exit,
|
||||||
|
.id_table = cinergyt2_usb_table
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init cinergyt2_usb_init(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = usb_register(&cinergyt2_driver);
|
||||||
|
if (err) {
|
||||||
|
err("usb_register() failed! (err %i)\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit cinergyt2_usb_exit(void)
|
||||||
|
{
|
||||||
|
usb_deregister(&cinergyt2_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(cinergyt2_usb_init);
|
||||||
|
module_exit(cinergyt2_usb_exit);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Tomi Orava");
|
351
drivers/media/dvb/dvb-usb/cinergyT2-fe.c
Normal file
351
drivers/media/dvb/dvb-usb/cinergyT2-fe.c
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
/*
|
||||||
|
* TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
|
||||||
|
*
|
||||||
|
* Based on the dvb-usb-framework code and the
|
||||||
|
* original Terratec Cinergy T2 driver by:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
|
||||||
|
* Holger Waechtler <holger@qanu.de>
|
||||||
|
*
|
||||||
|
* Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cinergyT2.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert linux-dvb frontend parameter set into TPS.
|
||||||
|
* See ETSI ETS-300744, section 4.6.2, table 9 for details.
|
||||||
|
*
|
||||||
|
* This function is probably reusable and may better get placed in a support
|
||||||
|
* library.
|
||||||
|
*
|
||||||
|
* We replace errornous fields by default TPS fields (the ones with value 0).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint16_t compute_tps(struct dvb_frontend_parameters *p)
|
||||||
|
{
|
||||||
|
struct dvb_ofdm_parameters *op = &p->u.ofdm;
|
||||||
|
uint16_t tps = 0;
|
||||||
|
|
||||||
|
switch (op->code_rate_HP) {
|
||||||
|
case FEC_2_3:
|
||||||
|
tps |= (1 << 7);
|
||||||
|
break;
|
||||||
|
case FEC_3_4:
|
||||||
|
tps |= (2 << 7);
|
||||||
|
break;
|
||||||
|
case FEC_5_6:
|
||||||
|
tps |= (3 << 7);
|
||||||
|
break;
|
||||||
|
case FEC_7_8:
|
||||||
|
tps |= (4 << 7);
|
||||||
|
break;
|
||||||
|
case FEC_1_2:
|
||||||
|
case FEC_AUTO:
|
||||||
|
default:
|
||||||
|
/* tps |= (0 << 7) */;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op->code_rate_LP) {
|
||||||
|
case FEC_2_3:
|
||||||
|
tps |= (1 << 4);
|
||||||
|
break;
|
||||||
|
case FEC_3_4:
|
||||||
|
tps |= (2 << 4);
|
||||||
|
break;
|
||||||
|
case FEC_5_6:
|
||||||
|
tps |= (3 << 4);
|
||||||
|
break;
|
||||||
|
case FEC_7_8:
|
||||||
|
tps |= (4 << 4);
|
||||||
|
break;
|
||||||
|
case FEC_1_2:
|
||||||
|
case FEC_AUTO:
|
||||||
|
default:
|
||||||
|
/* tps |= (0 << 4) */;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op->constellation) {
|
||||||
|
case QAM_16:
|
||||||
|
tps |= (1 << 13);
|
||||||
|
break;
|
||||||
|
case QAM_64:
|
||||||
|
tps |= (2 << 13);
|
||||||
|
break;
|
||||||
|
case QPSK:
|
||||||
|
default:
|
||||||
|
/* tps |= (0 << 13) */;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op->transmission_mode) {
|
||||||
|
case TRANSMISSION_MODE_8K:
|
||||||
|
tps |= (1 << 0);
|
||||||
|
break;
|
||||||
|
case TRANSMISSION_MODE_2K:
|
||||||
|
default:
|
||||||
|
/* tps |= (0 << 0) */;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op->guard_interval) {
|
||||||
|
case GUARD_INTERVAL_1_16:
|
||||||
|
tps |= (1 << 2);
|
||||||
|
break;
|
||||||
|
case GUARD_INTERVAL_1_8:
|
||||||
|
tps |= (2 << 2);
|
||||||
|
break;
|
||||||
|
case GUARD_INTERVAL_1_4:
|
||||||
|
tps |= (3 << 2);
|
||||||
|
break;
|
||||||
|
case GUARD_INTERVAL_1_32:
|
||||||
|
default:
|
||||||
|
/* tps |= (0 << 2) */;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op->hierarchy_information) {
|
||||||
|
case HIERARCHY_1:
|
||||||
|
tps |= (1 << 10);
|
||||||
|
break;
|
||||||
|
case HIERARCHY_2:
|
||||||
|
tps |= (2 << 10);
|
||||||
|
break;
|
||||||
|
case HIERARCHY_4:
|
||||||
|
tps |= (3 << 10);
|
||||||
|
break;
|
||||||
|
case HIERARCHY_NONE:
|
||||||
|
default:
|
||||||
|
/* tps |= (0 << 10) */;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tps;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cinergyt2_fe_state {
|
||||||
|
struct dvb_frontend fe;
|
||||||
|
struct dvb_usb_device *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
|
||||||
|
fe_status_t *status)
|
||||||
|
{
|
||||||
|
struct cinergyt2_fe_state *state = fe->demodulator_priv;
|
||||||
|
struct dvbt_get_status_msg result;
|
||||||
|
u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
|
||||||
|
sizeof(result), 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*status = 0;
|
||||||
|
|
||||||
|
if (0xffff - le16_to_cpu(result.gain) > 30)
|
||||||
|
*status |= FE_HAS_SIGNAL;
|
||||||
|
if (result.lock_bits & (1 << 6))
|
||||||
|
*status |= FE_HAS_LOCK;
|
||||||
|
if (result.lock_bits & (1 << 5))
|
||||||
|
*status |= FE_HAS_SYNC;
|
||||||
|
if (result.lock_bits & (1 << 4))
|
||||||
|
*status |= FE_HAS_CARRIER;
|
||||||
|
if (result.lock_bits & (1 << 1))
|
||||||
|
*status |= FE_HAS_VITERBI;
|
||||||
|
|
||||||
|
if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
|
||||||
|
(FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
|
||||||
|
*status &= ~FE_HAS_LOCK;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||||
|
{
|
||||||
|
struct cinergyt2_fe_state *state = fe->demodulator_priv;
|
||||||
|
struct dvbt_get_status_msg status;
|
||||||
|
char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
|
||||||
|
sizeof(status), 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*ber = le32_to_cpu(status.viterbi_error_rate);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
|
||||||
|
{
|
||||||
|
struct cinergyt2_fe_state *state = fe->demodulator_priv;
|
||||||
|
struct dvbt_get_status_msg status;
|
||||||
|
u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
|
||||||
|
sizeof(status), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*unc = le32_to_cpu(status.uncorrected_block_count);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
|
||||||
|
u16 *strength)
|
||||||
|
{
|
||||||
|
struct cinergyt2_fe_state *state = fe->demodulator_priv;
|
||||||
|
struct dvbt_get_status_msg status;
|
||||||
|
char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
|
||||||
|
sizeof(status), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
err("cinergyt2_fe_read_signal_strength() Failed!"
|
||||||
|
" (Error=%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*strength = (0xffff - le16_to_cpu(status.gain));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||||
|
{
|
||||||
|
struct cinergyt2_fe_state *state = fe->demodulator_priv;
|
||||||
|
struct dvbt_get_status_msg status;
|
||||||
|
char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
|
||||||
|
sizeof(status), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*snr = (status.snr << 8) | status.snr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_init(struct dvb_frontend *fe)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_sleep(struct dvb_frontend *fe)
|
||||||
|
{
|
||||||
|
deb_info("cinergyt2_fe_sleep() Called\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe,
|
||||||
|
struct dvb_frontend_tune_settings *tune)
|
||||||
|
{
|
||||||
|
tune->min_delay_ms = 800;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe,
|
||||||
|
struct dvb_frontend_parameters *fep)
|
||||||
|
{
|
||||||
|
struct cinergyt2_fe_state *state = fe->demodulator_priv;
|
||||||
|
struct dvbt_set_parameters_msg param;
|
||||||
|
char result[2];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
|
||||||
|
param.tps = cpu_to_le16(compute_tps(fep));
|
||||||
|
param.freq = cpu_to_le32(fep->frequency / 1000);
|
||||||
|
param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
|
||||||
|
|
||||||
|
err = dvb_usb_generic_rw(state->d,
|
||||||
|
(char *)¶m, sizeof(param),
|
||||||
|
result, sizeof(result), 0);
|
||||||
|
if (err < 0)
|
||||||
|
err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
|
||||||
|
|
||||||
|
return (err < 0) ? err : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cinergyt2_fe_get_frontend(struct dvb_frontend *fe,
|
||||||
|
struct dvb_frontend_parameters *fep)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cinergyt2_fe_release(struct dvb_frontend *fe)
|
||||||
|
{
|
||||||
|
struct cinergyt2_fe_state *state = fe->demodulator_priv;
|
||||||
|
if (state != NULL)
|
||||||
|
kfree(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dvb_frontend_ops cinergyt2_fe_ops;
|
||||||
|
|
||||||
|
struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
|
||||||
|
{
|
||||||
|
struct cinergyt2_fe_state *s = kzalloc(sizeof(
|
||||||
|
struct cinergyt2_fe_state), GFP_KERNEL);
|
||||||
|
if (s == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
s->d = d;
|
||||||
|
memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
|
||||||
|
s->fe.demodulator_priv = s;
|
||||||
|
return &s->fe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct dvb_frontend_ops cinergyt2_fe_ops = {
|
||||||
|
.info = {
|
||||||
|
.name = DRIVER_NAME,
|
||||||
|
.type = FE_OFDM,
|
||||||
|
.frequency_min = 174000000,
|
||||||
|
.frequency_max = 862000000,
|
||||||
|
.frequency_stepsize = 166667,
|
||||||
|
.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2
|
||||||
|
| FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
|
||||||
|
| FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8
|
||||||
|
| FE_CAN_FEC_AUTO | FE_CAN_QPSK
|
||||||
|
| FE_CAN_QAM_16 | FE_CAN_QAM_64
|
||||||
|
| FE_CAN_QAM_AUTO
|
||||||
|
| FE_CAN_TRANSMISSION_MODE_AUTO
|
||||||
|
| FE_CAN_GUARD_INTERVAL_AUTO
|
||||||
|
| FE_CAN_HIERARCHY_AUTO
|
||||||
|
| FE_CAN_RECOVER
|
||||||
|
| FE_CAN_MUTE_TS
|
||||||
|
},
|
||||||
|
|
||||||
|
.release = cinergyt2_fe_release,
|
||||||
|
|
||||||
|
.init = cinergyt2_fe_init,
|
||||||
|
.sleep = cinergyt2_fe_sleep,
|
||||||
|
|
||||||
|
.set_frontend = cinergyt2_fe_set_frontend,
|
||||||
|
.get_frontend = cinergyt2_fe_get_frontend,
|
||||||
|
.get_tune_settings = cinergyt2_fe_get_tune_settings,
|
||||||
|
|
||||||
|
.read_status = cinergyt2_fe_read_status,
|
||||||
|
.read_ber = cinergyt2_fe_read_ber,
|
||||||
|
.read_signal_strength = cinergyt2_fe_read_signal_strength,
|
||||||
|
.read_snr = cinergyt2_fe_read_snr,
|
||||||
|
.read_ucblocks = cinergyt2_fe_read_unc_blocks,
|
||||||
|
};
|
95
drivers/media/dvb/dvb-usb/cinergyT2.h
Normal file
95
drivers/media/dvb/dvb-usb/cinergyT2.h
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
|
||||||
|
*
|
||||||
|
* Based on the dvb-usb-framework code and the
|
||||||
|
* original Terratec Cinergy T2 driver by:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
|
||||||
|
* Holger Waechtler <holger@qanu.de>
|
||||||
|
*
|
||||||
|
* Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DVB_USB_CINERGYT2_H_
|
||||||
|
#define _DVB_USB_CINERGYT2_H_
|
||||||
|
|
||||||
|
#include <linux/usb/input.h>
|
||||||
|
|
||||||
|
#define DVB_USB_LOG_PREFIX "cinergyT2"
|
||||||
|
#include "dvb-usb.h"
|
||||||
|
|
||||||
|
#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
|
||||||
|
|
||||||
|
extern int dvb_usb_cinergyt2_debug;
|
||||||
|
|
||||||
|
#define deb_info(args...) dprintk(dvb_usb_cinergyt2_debug, 0x001, args)
|
||||||
|
#define deb_xfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x002, args)
|
||||||
|
#define deb_pll(args...) dprintk(dvb_usb_cinergyt2_debug, 0x004, args)
|
||||||
|
#define deb_ts(args...) dprintk(dvb_usb_cinergyt2_debug, 0x008, args)
|
||||||
|
#define deb_err(args...) dprintk(dvb_usb_cinergyt2_debug, 0x010, args)
|
||||||
|
#define deb_rc(args...) dprintk(dvb_usb_cinergyt2_debug, 0x020, args)
|
||||||
|
#define deb_fw(args...) dprintk(dvb_usb_cinergyt2_debug, 0x040, args)
|
||||||
|
#define deb_mem(args...) dprintk(dvb_usb_cinergyt2_debug, 0x080, args)
|
||||||
|
#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x100, args)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum cinergyt2_ep1_cmd {
|
||||||
|
CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
|
||||||
|
CINERGYT2_EP1_PID_SETUP = 0x02,
|
||||||
|
CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
|
||||||
|
CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
|
||||||
|
CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
|
||||||
|
CINERGYT2_EP1_START_SCAN = 0x06,
|
||||||
|
CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
|
||||||
|
CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
|
||||||
|
CINERGYT2_EP1_SLEEP_MODE = 0x09,
|
||||||
|
CINERGYT2_EP1_GET_FIRMWARE_VERSION = 0x0A
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct dvbt_get_status_msg {
|
||||||
|
uint32_t freq;
|
||||||
|
uint8_t bandwidth;
|
||||||
|
uint16_t tps;
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t gain;
|
||||||
|
uint8_t snr;
|
||||||
|
uint32_t viterbi_error_rate;
|
||||||
|
uint32_t rs_error_rate;
|
||||||
|
uint32_t uncorrected_block_count;
|
||||||
|
uint8_t lock_bits;
|
||||||
|
uint8_t prev_lock_bits;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
struct dvbt_set_parameters_msg {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint32_t freq;
|
||||||
|
uint8_t bandwidth;
|
||||||
|
uint16_t tps;
|
||||||
|
uint8_t flags;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d);
|
||||||
|
|
||||||
|
#endif /* _DVB_USB_CINERGYT2_H_ */
|
||||||
|
|
Loading…
Reference in a new issue