-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Patrick Boettcher
authored and
Mauro Carvalho Chehab
committed
Dec 10, 2006
1 parent
4f44c46
commit 9b20f98
Showing
5 changed files
with
355 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 8949f1a2424a38a4080a2a3561a2698f215a7c4a | ||
refs/heads/master: bc2e3913c786d7387e21ee0818c1a3b66a571703 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,270 @@ | ||
/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones | ||
* (e.g. Pinnacle 400e DVB-S USB2.0). | ||
* | ||
* The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes. | ||
* | ||
* TDA8263 + TDA10086 | ||
* | ||
* I2C addresses: | ||
* 0x08 - LNBP21PD - LNB power supply | ||
* 0x0e - TDA10086 - Demodulator | ||
* 0x50 - FX2 eeprom | ||
* 0x60 - TDA8263 - Tuner | ||
* 0x78 ??? | ||
* | ||
* Copyright (c) 2002 Holger Waechtler <holger@convergence.de> | ||
* Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net> | ||
* Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org> | ||
* | ||
* 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 | ||
*/ | ||
#define DVB_USB_LOG_PREFIX "ttusb2" | ||
#include "dvb-usb.h" | ||
|
||
#include "ttusb2.h" | ||
|
||
#include "tda826x.h" | ||
#include "tda10086.h" | ||
#include "lnbp21.h" | ||
|
||
/* debug */ | ||
static int dvb_usb_ttusb2_debug; | ||
#define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args) | ||
module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644); | ||
MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS); | ||
|
||
struct ttusb2_state { | ||
u8 id; | ||
}; | ||
|
||
static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, | ||
u8 *wbuf, int wlen, u8 *rbuf, int rlen) | ||
{ | ||
struct ttusb2_state *st = d->priv; | ||
u8 s[wlen+4],r[64] = { 0 }; | ||
int ret = 0; | ||
|
||
memset(s,0,wlen+4); | ||
|
||
s[0] = 0xaa; | ||
s[1] = ++st->id; | ||
s[2] = cmd; | ||
s[3] = wlen; | ||
memcpy(&s[4],wbuf,wlen); | ||
|
||
ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0); | ||
|
||
if (ret != 0 || | ||
r[0] != 0x55 || | ||
r[1] != s[1] || | ||
r[2] != cmd || | ||
(rlen > 0 && r[3] != rlen)) { | ||
warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]); | ||
return -EIO; | ||
} | ||
|
||
if (rlen > 0) | ||
memcpy(rbuf, &r[4], rlen); | ||
|
||
return 0; | ||
} | ||
|
||
static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) | ||
{ | ||
struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
static u8 obuf[60], ibuf[60]; | ||
int i,read; | ||
|
||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
return -EAGAIN; | ||
|
||
if (num > 2) | ||
warn("more than 2 i2c messages at a time is not handled yet. TODO."); | ||
|
||
for (i = 0; i < num; i++) { | ||
read = i+1 < num && (msg[i+1].flags & I2C_M_RD); | ||
|
||
obuf[0] = (msg[i].addr << 1) | read; | ||
obuf[1] = msg[i].len; | ||
|
||
/* read request */ | ||
if (read) | ||
obuf[2] = msg[i+1].len; | ||
else | ||
obuf[2] = 0; | ||
|
||
memcpy(&obuf[3],msg[i].buf,msg[i].len); | ||
|
||
if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) { | ||
err("i2c transfer failed."); | ||
break; | ||
} | ||
|
||
if (read) { | ||
memcpy(msg[i+1].buf,&ibuf[3],msg[i+1].len); | ||
i++; | ||
} | ||
} | ||
|
||
mutex_unlock(&d->i2c_mutex); | ||
return i; | ||
} | ||
|
||
static u32 ttusb2_i2c_func(struct i2c_adapter *adapter) | ||
{ | ||
return I2C_FUNC_I2C; | ||
} | ||
|
||
static struct i2c_algorithm ttusb2_i2c_algo = { | ||
.master_xfer = ttusb2_i2c_xfer, | ||
.functionality = ttusb2_i2c_func, | ||
}; | ||
|
||
/* Callbacks for DVB USB */ | ||
static int ttusb2_identify_state (struct usb_device *udev, struct | ||
dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, | ||
int *cold) | ||
{ | ||
*cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0; | ||
return 0; | ||
} | ||
|
||
static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
{ | ||
u8 b = onoff; | ||
ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0); | ||
return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0); | ||
} | ||
|
||
|
||
static struct tda10086_config tda10086_config = { | ||
.demod_address = 0x0e, | ||
.invert = 0, | ||
}; | ||
|
||
static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) | ||
{ | ||
if (usb_set_interface(adap->dev->udev,0,3) < 0) | ||
err("set interface to alts=3 failed"); | ||
|
||
if ((adap->fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) { | ||
deb_info("TDA10086 attach failed\n"); | ||
return -ENODEV; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap) | ||
{ | ||
if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) { | ||
deb_info("TDA8263 attach failed\n"); | ||
return -ENODEV; | ||
} | ||
|
||
if (dvb_attach(lnbp21_attach, adap->fe, &adap->dev->i2c_adap, 0, 0) == NULL) { | ||
deb_info("LNBP21 attach failed\n"); | ||
return -ENODEV; | ||
} | ||
return 0; | ||
} | ||
|
||
/* DVB USB Driver stuff */ | ||
static struct dvb_usb_device_properties ttusb2_properties; | ||
|
||
static int ttusb2_probe(struct usb_interface *intf, | ||
const struct usb_device_id *id) | ||
{ | ||
return dvb_usb_device_init(intf,&ttusb2_properties,THIS_MODULE,NULL); | ||
} | ||
|
||
static struct usb_device_id ttusb2_table [] = { | ||
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, | ||
{} /* Terminating entry */ | ||
}; | ||
MODULE_DEVICE_TABLE (usb, ttusb2_table); | ||
|
||
static struct dvb_usb_device_properties ttusb2_properties = { | ||
.caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
|
||
.usb_ctrl = CYPRESS_FX2, | ||
.firmware = "dvb-usb-pctv-400e-01.fw", | ||
|
||
.size_of_priv = sizeof(struct ttusb2_state), | ||
|
||
.num_adapters = 1, | ||
.adapter = { | ||
{ | ||
.streaming_ctrl = NULL, // ttusb2_streaming_ctrl, | ||
|
||
.frontend_attach = ttusb2_frontend_attach, | ||
.tuner_attach = ttusb2_tuner_attach, | ||
|
||
/* parameter for the MPEG2-data transfer */ | ||
.stream = { | ||
.type = USB_ISOC, | ||
.count = 5, | ||
.endpoint = 0x02, | ||
.u = { | ||
.isoc = { | ||
.framesperurb = 4, | ||
.framesize = 940, | ||
.interval = 1, | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
|
||
.power_ctrl = ttusb2_power_ctrl, | ||
.identify_state = ttusb2_identify_state, | ||
|
||
.i2c_algo = &ttusb2_i2c_algo, | ||
|
||
.generic_bulk_ctrl_endpoint = 0x01, | ||
|
||
.num_device_descs = 1, | ||
.devices = { | ||
{ "Pinnacle 400e DVB-S USB2.0", | ||
{ &ttusb2_table[0], NULL }, | ||
{ NULL }, | ||
}, | ||
} | ||
}; | ||
|
||
static struct usb_driver ttusb2_driver = { | ||
.name = "dvb_usb_ttusb2", | ||
.probe = ttusb2_probe, | ||
.disconnect = dvb_usb_device_exit, | ||
.id_table = ttusb2_table, | ||
}; | ||
|
||
/* module stuff */ | ||
static int __init ttusb2_module_init(void) | ||
{ | ||
int result; | ||
if ((result = usb_register(&ttusb2_driver))) { | ||
err("usb_register failed. Error number %d",result); | ||
return result; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static void __exit ttusb2_module_exit(void) | ||
{ | ||
/* deregister this driver from the USB subsystem */ | ||
usb_deregister(&ttusb2_driver); | ||
} | ||
|
||
module_init (ttusb2_module_init); | ||
module_exit (ttusb2_module_exit); | ||
|
||
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0"); | ||
MODULE_VERSION("1.0"); | ||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones | ||
* (e.g. Pinnacle 400e DVB-S USB2.0). | ||
* | ||
* Copyright (c) 2002 Holger Waechtler <holger@convergence.de> | ||
* Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net> | ||
* Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.de> | ||
* | ||
* 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 | ||
*/ | ||
#ifndef _DVB_USB_TTUSB2_H_ | ||
#define _DVB_USB_TTUSB2_H_ | ||
|
||
/* TTUSB protocol | ||
* | ||
* always to messages (out/in) | ||
* out message: | ||
* 0xaa <id> <cmdbyte> <datalen> <data...> | ||
* | ||
* in message (complete block is always 0x40 bytes long) | ||
* 0x55 <id> <cmdbyte> <datalen> <data...> | ||
* | ||
* id is incremented for each transaction | ||
*/ | ||
|
||
#define CMD_DSP_DOWNLOAD 0x13 | ||
/* out data: <byte>[28] | ||
* last block must be empty */ | ||
|
||
#define CMD_DSP_BOOT 0x14 | ||
/* out data: nothing */ | ||
|
||
#define CMD_POWER 0x15 | ||
/* out data: <on=1/off=0> */ | ||
|
||
#define CMD_LNB 0x16 | ||
/* out data: <power=1> <18V=0,13V=1> <tone> <??=1> <??=1> */ | ||
|
||
#define CMD_GET_VERSION 0x17 | ||
/* in data: <version_byte>[5] */ | ||
|
||
#define CMD_DISEQC 0x18 | ||
/* out data: <master=0xff/burst=??> <cmdlen> <cmdbytes>[cmdlen] */ | ||
|
||
#define CMD_PID_ENABLE 0x22 | ||
/* out data: <index> <type: ts=1/sec=2> <pid msb> <pid lsb> */ | ||
|
||
#define CMD_PID_DISABLE 0x23 | ||
/* out data: <index> */ | ||
|
||
#define CMD_FILTER_ENABLE 0x24 | ||
/* out data: <index> <pid_idx> <filter>[12] <mask>[12] */ | ||
|
||
#define CMD_FILTER_DISABLE 0x25 | ||
/* out data: <index> */ | ||
|
||
#define CMD_GET_DSP_VERSION 0x26 | ||
/* in data: <version_byte>[28] */ | ||
|
||
#define CMD_I2C_XFER 0x31 | ||
/* out data: <addr << 1> <sndlen> <rcvlen> <data>[sndlen] | ||
* in data: <addr << 1> <sndlen> <rcvlen> <data>[rcvlen] */ | ||
|
||
#define CMD_I2C_BITRATE 0x32 | ||
/* out data: <default=0> */ | ||
|
||
#endif |