V4L/DVB (7448): Add support for Kworld ATSC 120
This board has a s5h1409 demod, plus a xc30x8 tuner (probably, xc3018). This patch adds proper support for radio, video, s-video, composite and ATSC. However, support for radio and video depends on having s5h1409 i2c gate open, otherwise, xc30x8 chip won't be visible. For a better support, some rework is needed on cx88 driver, to allow adding xc30x8 to i2c bus without sending i2c 0 byte reading to 0xc2 address. Thanks to Vanessa Ezekowitz <vanessaezekowitz@gmail.com> for helping to figure out the proper parameters for s5h1409 and the GPIO pins used by each configuration. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
a2401d9eed
commit
99e09eac25
4 changed files with 114 additions and 30 deletions
|
@ -65,3 +65,4 @@
|
|||
64 -> DViCO FusionHDTV DVB-T PRO [18ac:db30]
|
||||
65 -> DViCO FusionHDTV 7 Gold [18ac:d610]
|
||||
66 -> Prolink Pixelview MPEG 8000GT [1554:4935]
|
||||
67 -> Kworld PlusTV HD PCI 120 (ATSC 120) [17de:08c1]
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "cx88.h"
|
||||
#include "tea5767.h"
|
||||
#include "tuner-xc2028.h"
|
||||
|
||||
static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
|
||||
static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
|
||||
|
@ -1614,6 +1613,45 @@ static const struct cx88_board cx88_boards[] = {
|
|||
.gpio2 = 0x0cfb,
|
||||
},
|
||||
},
|
||||
/* Both radio, analog and ATSC work with this board.
|
||||
However, for analog to work, s5h1409 gate should be open,
|
||||
otherwise, tuner-xc3028 won't be detected.
|
||||
A proper fix require using the newer i2c methods to add
|
||||
tuner-xc3028 without doing an i2c probe.
|
||||
*/
|
||||
[CX88_BOARD_KWORLD_ATSC_120] = {
|
||||
.name = "Kworld PlusTV HD PCI 120 (ATSC 120)",
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.input = { {
|
||||
.type = CX88_VMUX_TELEVISION,
|
||||
.vmux = 0,
|
||||
.gpio0 = 0x000000ff,
|
||||
.gpio1 = 0x0000f35d,
|
||||
.gpio2 = 0x00000000,
|
||||
}, {
|
||||
.type = CX88_VMUX_COMPOSITE1,
|
||||
.vmux = 1,
|
||||
.gpio0 = 0x000000ff,
|
||||
.gpio1 = 0x0000f37e,
|
||||
.gpio2 = 0x00000000,
|
||||
}, {
|
||||
.type = CX88_VMUX_SVIDEO,
|
||||
.vmux = 2,
|
||||
.gpio0 = 0x000000ff,
|
||||
.gpio1 = 0x0000f37e,
|
||||
.gpio2 = 0x00000000,
|
||||
} },
|
||||
.radio = {
|
||||
.type = CX88_RADIO,
|
||||
.gpio0 = 0x000000ff,
|
||||
.gpio1 = 0x0000f35d,
|
||||
.gpio2 = 0x00000000,
|
||||
},
|
||||
.mpeg = CX88_MPEG_DVB,
|
||||
},
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
@ -1959,6 +1997,10 @@ static const struct cx88_subid cx88_subids[] = {
|
|||
.subvendor = 0x1554,
|
||||
.subdevice = 0x4935,
|
||||
.card = CX88_BOARD_PROLINK_PV_8000GT,
|
||||
}, {
|
||||
.subvendor = 0x17de,
|
||||
.subdevice = 0x08c1,
|
||||
.card = CX88_BOARD_KWORLD_ATSC_120,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -2200,6 +2242,7 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
|
|||
case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
|
||||
case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
|
||||
case CX88_BOARD_GENIATECH_X8000_MT:
|
||||
case CX88_BOARD_KWORLD_ATSC_120:
|
||||
return cx88_xc3028_geniatech_tuner_callback(core,
|
||||
command, arg);
|
||||
case CX88_BOARD_PROLINK_PV_8000GT:
|
||||
|
@ -2363,6 +2406,40 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets board-dependent xc3028 configuration
|
||||
*/
|
||||
void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
|
||||
{
|
||||
memset(ctl, 0, sizeof(*ctl));
|
||||
|
||||
ctl->fname = XC2028_DEFAULT_FIRMWARE;
|
||||
ctl->max_len = 64;
|
||||
|
||||
switch (core->boardnr) {
|
||||
case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
|
||||
/* Doesn't work with firmware version 2.7 */
|
||||
ctl->fname = "xc3028-v25.fw";
|
||||
break;
|
||||
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
|
||||
ctl->scode_table = XC3028_FE_ZARLINK456;
|
||||
break;
|
||||
case CX88_BOARD_KWORLD_ATSC_120:
|
||||
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
|
||||
ctl->demod = XC3028_FE_OREN538;
|
||||
break;
|
||||
case CX88_BOARD_PROLINK_PV_8000GT:
|
||||
/*
|
||||
* This board uses non-MTS firmware
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
ctl->demod = XC3028_FE_OREN538;
|
||||
ctl->mts = 1;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
|
||||
|
||||
static void cx88_card_setup(struct cx88_core *core)
|
||||
{
|
||||
static u8 eeprom[256];
|
||||
|
@ -2481,36 +2558,13 @@ static void cx88_card_setup(struct cx88_core *core)
|
|||
struct v4l2_priv_tun_config xc2028_cfg;
|
||||
struct xc2028_ctrl ctl;
|
||||
|
||||
/* Fills device-dependent initialization parameters */
|
||||
cx88_setup_xc3028(core, &ctl);
|
||||
|
||||
/* Sends parameters to xc2028/3028 tuner */
|
||||
memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
|
||||
memset(&ctl, 0, sizeof(ctl));
|
||||
|
||||
ctl.fname = XC2028_DEFAULT_FIRMWARE;
|
||||
ctl.max_len = 64;
|
||||
|
||||
switch (core->boardnr) {
|
||||
case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
|
||||
/* Doesn't work with firmware version 2.7 */
|
||||
ctl.fname = "xc3028-v25.fw";
|
||||
break;
|
||||
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
|
||||
ctl.scode_table = XC3028_FE_ZARLINK456;
|
||||
break;
|
||||
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
|
||||
ctl.demod = XC3028_FE_OREN538;
|
||||
break;
|
||||
case CX88_BOARD_PROLINK_PV_8000GT:
|
||||
/*
|
||||
* This board uses non-MTS firmware
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
ctl.demod = XC3028_FE_OREN538;
|
||||
ctl.mts = 1;
|
||||
}
|
||||
|
||||
xc2028_cfg.tuner = TUNER_XC2028;
|
||||
xc2028_cfg.priv = &ctl;
|
||||
|
||||
info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
|
||||
ctl.fname);
|
||||
cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "nxt200x.h"
|
||||
#include "cx24123.h"
|
||||
#include "isl6421.h"
|
||||
#include "tuner-xc2028.h"
|
||||
#include "tuner-xc2028-types.h"
|
||||
#include "tuner-simple.h"
|
||||
#include "tda9887.h"
|
||||
|
@ -443,6 +442,16 @@ static struct s5h1409_config dvico_hdtv5_pci_nano_config = {
|
|||
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
|
||||
};
|
||||
|
||||
static struct s5h1409_config kworld_atsc_120_config = {
|
||||
.demod_address = 0x32 >> 1,
|
||||
.qam_if = 44000,
|
||||
.output_mode = S5H1409_SERIAL_OUTPUT,
|
||||
.gpio = S5H1409_GPIO_OFF,
|
||||
.inversion = S5H1409_INVERSION_OFF,
|
||||
.status_mode = S5H1409_DEMODLOCKING,
|
||||
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
|
||||
};
|
||||
|
||||
static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
|
||||
.i2c_address = 0x64,
|
||||
.if_khz = 5380,
|
||||
|
@ -457,9 +466,12 @@ static struct zl10353_config cx88_geniatech_x8000_mt = {
|
|||
static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
|
||||
{
|
||||
struct dvb_frontend *fe;
|
||||
struct xc2028_ctrl ctl;
|
||||
struct xc2028_config cfg = {
|
||||
.i2c_adap = &dev->core->i2c_adap,
|
||||
.i2c_addr = addr,
|
||||
.ctrl = &ctl,
|
||||
.callback = cx88_tuner_callback,
|
||||
};
|
||||
|
||||
if (!dev->dvb.frontend) {
|
||||
|
@ -469,6 +481,13 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some xc3028 devices may be hidden by an I2C gate. This is known
|
||||
* to happen with some s5h1409-based devices.
|
||||
* Now that I2C gate is open, sets up xc3028 configuration
|
||||
*/
|
||||
cx88_setup_xc3028(dev->core, &ctl);
|
||||
|
||||
fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
|
||||
if (!fe) {
|
||||
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
|
||||
|
@ -810,7 +829,7 @@ static int dvb_register(struct cx8802_dev *dev)
|
|||
return -EINVAL;
|
||||
break;
|
||||
case CX88_BOARD_GENIATECH_X8000_MT:
|
||||
dev->ts_gen_cntrl = 0x00;
|
||||
dev->ts_gen_cntrl = 0x00;
|
||||
|
||||
dev->dvb.frontend = dvb_attach(zl10353_attach,
|
||||
&cx88_geniatech_x8000_mt,
|
||||
|
@ -818,6 +837,13 @@ static int dvb_register(struct cx8802_dev *dev)
|
|||
if (attach_xc3028(0x61, dev) < 0)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case CX88_BOARD_KWORLD_ATSC_120:
|
||||
dev->dvb.frontend = dvb_attach(s5h1409_attach,
|
||||
&kworld_atsc_120_config,
|
||||
&dev->core->i2c_adap);
|
||||
if (attach_xc3028(0x61, dev) < 0)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
|
||||
dev->core->name);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "btcx-risc.h"
|
||||
#include "cx88-reg.h"
|
||||
#include "tuner-xc2028.h"
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/mutex.h>
|
||||
|
@ -219,6 +220,7 @@ extern struct sram_channel cx88_sram_channels[];
|
|||
#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO 64
|
||||
#define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65
|
||||
#define CX88_BOARD_PROLINK_PV_8000GT 66
|
||||
#define CX88_BOARD_KWORLD_ATSC_120 67
|
||||
|
||||
enum cx88_itype {
|
||||
CX88_VMUX_COMPOSITE1 = 1,
|
||||
|
@ -603,6 +605,7 @@ extern int cx88_tuner_callback(void *dev, int command, int arg);
|
|||
extern int cx88_get_resources(const struct cx88_core *core,
|
||||
struct pci_dev *pci);
|
||||
extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr);
|
||||
extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
/* cx88-tvaudio.c */
|
||||
|
|
Loading…
Reference in a new issue