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/ttusb-budget/Kconfig"
|
||||
source "drivers/media/dvb/ttusb-dec/Kconfig"
|
||||
source "drivers/media/dvb/cinergyT2/Kconfig"
|
||||
source "drivers/media/dvb/siano/Kconfig"
|
||||
|
||||
comment "Supported FlexCopII (B2C2) Adapters"
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
# 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
|
||||
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
|
||||
tristate "Anysee DVB-T/C USB2.0 support"
|
||||
depends on DVB_USB
|
||||
|
|
|
@ -73,6 +73,10 @@ obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
|
|||
dvb-usb-af9015-objs = 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/
|
||||
# due to tuner-xc3028
|
||||
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