V4L/DVB (9044): Add support for Pinnacle PCTV HD Pro 801e (ATSC only)

Add digital support for the Pinnacle PCTV HD Pro 801e (usb id 2304:023a)

Thanks to Patrick Boettcher <patrick.boettcher@desy.de> for providing new
firmware fixing the issue with the i2c that prevented the xc5000 from working.

Signed-off-by: Devin Heitmueller <devin.heitmueller@gmail.com>
Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Devin Heitmueller 2008-09-08 05:42:42 -03:00 committed by Mauro Carvalho Chehab
parent 5769743ad3
commit cb22cb5213
4 changed files with 119 additions and 1 deletions

View File

@ -42,6 +42,7 @@ struct dib0700_state {
u8 rc_counter; u8 rc_counter;
u8 is_dib7000pc; u8 is_dib7000pc;
u8 fw_use_new_i2c_api; u8 fw_use_new_i2c_api;
u8 disable_streaming_master_mode;
}; };
extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);

View File

@ -350,7 +350,12 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
b[0] = REQUEST_ENABLE_VIDEO; b[0] = REQUEST_ENABLE_VIDEO;
b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
b[2] = (0x01 << 4); /* Master mode */
if (st->disable_streaming_master_mode == 1)
b[2] = 0x00;
else
b[2] = (0x01 << 4); /* Master mode */
b[3] = 0x00; b[3] = 0x00;
deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);

View File

@ -14,6 +14,8 @@
#include "mt2060.h" #include "mt2060.h"
#include "mt2266.h" #include "mt2266.h"
#include "tuner-xc2028.h" #include "tuner-xc2028.h"
#include "xc5000.h"
#include "s5h1411.h"
#include "dib0070.h" #include "dib0070.h"
static int force_lna_activation; static int force_lna_activation;
@ -1078,6 +1080,89 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
return adap->fe == NULL ? -ENODEV : 0; return adap->fe == NULL ? -ENODEV : 0;
} }
/* S5H1411 */
static struct s5h1411_config pinnacle_801e_config = {
.output_mode = S5H1411_PARALLEL_OUTPUT,
.gpio = S5H1411_GPIO_OFF,
.mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
.qam_if = S5H1411_IF_44000,
.vsb_if = S5H1411_IF_44000,
.inversion = S5H1411_INVERSION_OFF,
.status_mode = S5H1411_DEMODLOCKING
};
/* Pinnacle PCTV HD Pro 801e GPIOs map:
GPIO0 - currently unknown
GPIO1 - xc5000 tuner reset
GPIO2 - CX25843 sleep
GPIO3 - currently unknown
GPIO4 - currently unknown
GPIO6 - currently unknown
GPIO7 - currently unknown
GPIO9 - currently unknown
GPIO10 - CX25843 reset
*/
static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_state *st = adap->dev->priv;
/* Make use of the new i2c functions from FW 1.20 */
st->fw_use_new_i2c_api = 1;
/* The s5h1411 requires the dib0700 to not be in master mode */
st->disable_streaming_master_mode = 1;
/* All msleep values taken from Windows USB trace */
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
msleep(400);
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
msleep(60);
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(30);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
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, GPIO2, GPIO_OUT, 0);
msleep(30);
/* Put the CX25843 to sleep for now since we're in digital mode */
dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
/* GPIOs are initialized, do the attach */
adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
&adap->dev->i2c_adap);
return adap->fe == NULL ? -ENODEV : 0;
}
int dib0700_xc5000_tuner_callback(void *priv, int command, int arg)
{
struct dvb_usb_adapter *adap = priv;
/* Reset the tuner */
dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
msleep(330); /* from Windows USB trace */
dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
msleep(330); /* from Windows USB trace */
return 0;
}
static struct xc5000_config s5h1411_xc5000_tunerconfig = {
.i2c_address = 0x64,
.if_khz = 5380,
.tuner_callback = dib0700_xc5000_tuner_callback
};
static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
{
return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
&s5h1411_xc5000_tunerconfig, adap)
== NULL ? -ENODEV : 0;
}
/* DVB-USB and USB stuff follows */ /* DVB-USB and USB stuff follows */
struct usb_device_id dib0700_usb_id_table[] = { struct usb_device_id dib0700_usb_id_table[] = {
/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
@ -1122,6 +1207,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) }, { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) }, { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) }, { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
{ 0 } /* Terminating entry */ { 0 } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@ -1442,6 +1528,31 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_key_map = dib0700_rc_keys, .rc_key_map = dib0700_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
.rc_query = dib0700_rc_query .rc_query = dib0700_rc_query
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
.adapter = {
{
.frontend_attach = s5h1411_frontend_attach,
.tuner_attach = xc5000_tuner_attach,
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
.size_of_priv = sizeof(struct
dib0700_adapter_state),
},
},
.num_device_descs = 1,
.devices = {
{ "Pinnacle PCTV HD Pro USB Stick",
{ &dib0700_usb_id_table[40], NULL },
{ NULL },
},
},
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dib0700_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
.rc_query = dib0700_rc_query
}, },
}; };

View File

@ -171,6 +171,7 @@
#define USB_PID_PINNACLE_PCTV71E 0x022b #define USB_PID_PINNACLE_PCTV71E 0x022b
#define USB_PID_PINNACLE_PCTV72E 0x0236 #define USB_PID_PINNACLE_PCTV72E 0x0236
#define USB_PID_PINNACLE_PCTV73E 0x0237 #define USB_PID_PINNACLE_PCTV73E 0x0237
#define USB_PID_PINNACLE_PCTV801E 0x023a
#define USB_PID_PCTV_200E 0x020e #define USB_PID_PCTV_200E 0x020e
#define USB_PID_PCTV_400E 0x020f #define USB_PID_PCTV_400E 0x020f
#define USB_PID_PCTV_450E 0x0222 #define USB_PID_PCTV_450E 0x0222