Skip to content

Commit

Permalink
[PATCH] dvb: usb: add supprt for WideView WT-220U
Browse files Browse the repository at this point in the history
Add support and rewrote some parts with the help of vendor information
(Thanks to Steve Chang from WideView, Inc.):

o added support for the WT-220U (Pensize DVB-T receiver)
o corrected byte order for unc,ber and the pid filter
o corrected number of pids that can be fetched at the same time.
o added some comments in Kconfig-file
o added USB IDs for the WT-220U

Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Patrick Boettcher authored and Linus Torvalds committed Jul 8, 2005
1 parent 4b2bd30 commit d590f9c
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 73 deletions.
4 changes: 3 additions & 1 deletion drivers/media/dvb/dvb-usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ config DVB_USB_NOVA_T_USB2
Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.

config DVB_USB_DTT200U
tristate "WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support"
tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
depends on DVB_USB
help
Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.

The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).

The WT-220U and its clones are pen-sized.
72 changes: 37 additions & 35 deletions drivers/media/dvb/dvb-usb/dtt200u-fe.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,61 +14,58 @@
struct dtt200u_fe_state {
struct dvb_usb_device *d;

fe_status_t stat;

struct dvb_frontend_parameters fep;
struct dvb_frontend frontend;
};

#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what)

static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
u8 bw = GET_TUNE_STAT;
u8 br[3] = { 0 };
// u8 bdeb[5] = { 0 };
u8 st = GET_TUNE_STATUS, b[3];

dvb_usb_generic_rw(state->d,&st,1,b,3,0);

dvb_usb_generic_rw(state->d,&bw,1,br,3,0);
switch (br[0]) {
switch (b[0]) {
case 0x01:
*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
break;
case 0x00:
*stat = 0;
case 0x00: /* pending */
*stat = FE_TIMEDOUT; /* during set_frontend */
break;
default:
moan("br[0]",GET_TUNE_STAT);
case 0x02: /* failed */
*stat = 0;
break;
}

// bw[0] = 0x88;
// dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0);

// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);

return 0;
}

static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
u8 bw = GET_BER;
*ber = 0;
dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0);
u8 bw = GET_VIT_ERR_CNT,b[3];
dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
*ber = (b[0] << 16) | (b[1] << 8) | b[2];
return 0;
}

static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
u8 bw = GET_UNK;
*unc = 0;
dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0);
u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];

dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
*unc = (b[0] << 8) | b[1];
return 0;
}

static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
u8 bw = GET_SIG_STRENGTH, b;
u8 bw = GET_AGC, b;
dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
*strength = (b << 8) | b;
return 0;
Expand All @@ -86,7 +83,7 @@ static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
static int dtt200u_fe_init(struct dvb_frontend* fe)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
u8 b = RESET_DEMOD;
u8 b = SET_INIT;
return dvb_usb_generic_write(state->d,&b,1);
}

Expand All @@ -98,36 +95,41 @@ static int dtt200u_fe_sleep(struct dvb_frontend* fe)
static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 1500;
tune->step_size = 166667;
tune->max_drift = 166667 * 2;
tune->step_size = 0;
tune->max_drift = 0;
return 0;
}

static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
struct dvb_frontend_parameters *fep)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
int i;
fe_status_t st;
u16 freq = fep->frequency / 250000;
u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 };
u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };

switch (fep->u.ofdm.bandwidth) {
case BANDWIDTH_8_MHZ: bw = 8; break;
case BANDWIDTH_7_MHZ: bw = 7; break;
case BANDWIDTH_6_MHZ: bw = 6; break;
case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break;
case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break;
case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break;
case BANDWIDTH_AUTO: return -EOPNOTSUPP;
default:
return -EINVAL;
}
deb_info("set_frontend\n");

bwbuf[1] = bw;
dvb_usb_generic_write(state->d,bwbuf,2);

freqbuf[1] = freq & 0xff;
freqbuf[2] = (freq >> 8) & 0xff;
dvb_usb_generic_write(state->d,freqbuf,3);

memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters));
for (i = 0; i < 30; i++) {
msleep(20);
dtt200u_fe_read_status(fe, &st);
if (st & FE_TIMEDOUT)
continue;
}

return 0;
}
Expand Down Expand Up @@ -174,7 +176,7 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)

static struct dvb_frontend_ops dtt200u_fe_ops = {
.info = {
.name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T",
.name = "WideView USB DVB-T",
.type = FE_OFDM,
.frequency_min = 44250000,
.frequency_max = 867250000,
Expand Down
86 changes: 74 additions & 12 deletions drivers/media/dvb/dvb-usb/dtt200u.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
*
* Thanks to Steve Chang from WideView for providing support for the WT-220U.
*
* 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.
Expand All @@ -16,14 +18,24 @@ int dvb_usb_dtt200u_debug;
module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);

static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 b = SET_INIT;

if (onoff)
dvb_usb_generic_write(d,&b,2);

return 0;
}

static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 b_streaming[2] = { SET_TS_CTRL, onoff };
u8 b_streaming[2] = { SET_STREAMING, onoff };
u8 b_rst_pid = RESET_PID_FILTER;

dvb_usb_generic_write(d,b_streaming,2);

if (!onoff)
if (onoff == 0)
dvb_usb_generic_write(d,&b_rst_pid,1);
return 0;
}
Expand All @@ -36,7 +48,7 @@ static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int
b_pid[0] = SET_PID_FILTER;
b_pid[1] = index;
b_pid[2] = pid & 0xff;
b_pid[3] = (pid >> 8) & 0xff;
b_pid[3] = (pid >> 8) & 0x1f;

return dvb_usb_generic_write(d,b_pid,4);
}
Expand All @@ -54,9 +66,9 @@ static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
{ 0x80, 0x08, KEY_5 },
{ 0x80, 0x09, KEY_6 },
{ 0x80, 0x0a, KEY_7 },
{ 0x00, 0x0c, KEY_ZOOM },
{ 0x80, 0x0c, KEY_ZOOM },
{ 0x80, 0x0d, KEY_0 },
{ 0x00, 0x0e, KEY_SELECT },
{ 0x80, 0x0e, KEY_SELECT },
{ 0x80, 0x12, KEY_POWER },
{ 0x80, 0x1a, KEY_CHANNELUP },
{ 0x80, 0x1b, KEY_8 },
Expand All @@ -66,7 +78,7 @@ static struct dvb_usb_rc_key dtt200u_rc_keys[] = {

static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
u8 key[5],cmd = GET_RC_KEY;
u8 key[5],cmd = GET_RC_CODE;
dvb_usb_generic_rw(d,&cmd,1,key,5,0);
dvb_usb_nec_rc_key_to_event(d,key,event,state);
if (key[0] != 0)
Expand All @@ -81,32 +93,41 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d)
}

static struct dvb_usb_properties dtt200u_properties;
static struct dvb_usb_properties wt220u_properties;

static int dtt200u_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE);
if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 ||
dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0)
return 0;

return -ENODEV;
}

static struct usb_device_id dtt200u_usb_table [] = {
// { USB_DEVICE(0x04b4,0x8613) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
{ 0 },
};
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);

static struct dvb_usb_properties dtt200u_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
.pid_filter_count = 255, /* It is a guess, but there are at least 10 */
.pid_filter_count = 15,

.usb_ctrl = CYPRESS_FX2,
.firmware = "dvb-usb-dtt200u-01.fw",

.power_ctrl = dtt200u_power_ctrl,
.streaming_ctrl = dtt200u_streaming_ctrl,
.pid_filter = dtt200u_pid_filter,
.frontend_attach = dtt200u_frontend_attach,

.rc_interval = 200,
.rc_interval = 300,
.rc_key_map = dtt200u_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
.rc_query = dtt200u_rc_query,
Expand All @@ -127,18 +148,59 @@ static struct dvb_usb_properties dtt200u_properties = {

.num_device_descs = 1,
.devices = {
{ .name = "WideView/Yakumo/Hama/Typhoon DVB-T USB2.0)",
{ .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
.cold_ids = { &dtt200u_usb_table[0], NULL },
.warm_ids = { &dtt200u_usb_table[1], NULL },
},
{ 0 },
}
};

static struct dvb_usb_properties wt220u_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
.pid_filter_count = 15,

.usb_ctrl = CYPRESS_FX2,
.firmware = "dvb-usb-wt220u-01.fw",

.power_ctrl = dtt200u_power_ctrl,
.streaming_ctrl = dtt200u_streaming_ctrl,
.pid_filter = dtt200u_pid_filter,
.frontend_attach = dtt200u_frontend_attach,

.rc_interval = 300,
.rc_key_map = dtt200u_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
.rc_query = dtt200u_rc_query,

.generic_bulk_ctrl_endpoint = 0x01,

/* parameter for the MPEG2-data transfer */
.urb = {
.type = DVB_USB_BULK,
.count = 7,
.endpoint = 0x02,
.u = {
.bulk = {
.buffersize = 4096,
}
}
},

.num_device_descs = 1,
.devices = {
{ .name = "WideView WT-220U PenType Receiver (and clones)",
.cold_ids = { &dtt200u_usb_table[2], NULL },
.warm_ids = { &dtt200u_usb_table[3], NULL },
},
{ 0 },
}
};

/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver dtt200u_usb_driver = {
.owner = THIS_MODULE,
.name = "dtt200u",
.name = "dvb_usb_dtt200u",
.probe = dtt200u_usb_probe,
.disconnect = dvb_usb_device_exit,
.id_table = dtt200u_usb_table,
Expand Down Expand Up @@ -166,6 +228,6 @@ module_init(dtt200u_usb_module_init);
module_exit(dtt200u_usb_module_exit);

MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 device");
MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 devices");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");
Loading

0 comments on commit d590f9c

Please sign in to comment.