Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc40b261 authored by Chris Pascoe's avatar Chris Pascoe Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (3220): Add support for VP-3054 HDTV board




- Added support for VP-3054 (aka DigitalNow DNTV Live! DVB-T Pro!).
- This board has a secondary I2C bus and remote control.
- Added a new module to handle secondary I2C bus on this board.

Signed-off-by: default avatarChris Pascoe <c.pascoe@itee.uq.edu.au>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@brturbo.com.br>
parent 50c25fff
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -40,3 +40,4 @@
 39 -> KWorld DVB-S 100                                    [17de:08b2]
 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid                [0070:9400,0070:9402]
 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)  [0070:9800,0070:9802]
 42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025]
+2 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ cx8800-objs := cx88-video.o cx88-vbi.o
cx8802-objs	:= cx88-mpeg.o

obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o

EXTRA_CFLAGS += -I$(src)/..
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
@@ -17,5 +17,6 @@ extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1
extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
extra-cflags-$(CONFIG_DVB_CX24123)   += -DHAVE_CX24123=1
extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1

EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
+34 −0
Original line number Diff line number Diff line
@@ -982,6 +982,33 @@ struct cx88_board cx88_boards[] = {
		/* fixme: Add radio support */
		.dvb		= 1,
	},
	[CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = {
		.name           = "digitalnow DNTV Live! DVB-T Pro",
		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
		.radio_type     = UNSET,
		.tuner_addr	= ADDR_UNSET,
		.radio_addr	= ADDR_UNSET,
		.tda9887_conf   = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
				  TDA9887_PORT2_ACTIVE,
		.input          = {{
			.type   = CX88_VMUX_TELEVISION,
			.vmux   = 0,
			.gpio0  = 0xf80808,
		},{
			.type   = CX88_VMUX_COMPOSITE1,
			.vmux   = 1,
			.gpio0	= 0xf80808,
		},{
			.type   = CX88_VMUX_SVIDEO,
			.vmux   = 2,
			.gpio0	= 0xf80808,
		}},
		.radio = {
			 .type  = CX88_RADIO,
			 .gpio0 = 0xf80808,
		},
		.dvb            = 1,
	},
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);

@@ -1165,6 +1192,10 @@ struct cx88_subid cx88_subids[] = {
		.subvendor = 0x0070,
		.subdevice = 0x9001,
		.card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
	},{
		.subvendor = 0x1822,
		.subdevice = 0x0025,
		.card      = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
	},
};
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1362,6 +1393,9 @@ void cx88_card_setup(struct cx88_core *core)
		cx_clear(MO_GP0_IO, 0x00000007);
		cx_set(MO_GP2_IO, 0x00000101);
		break;
	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
		cx_write(MO_GP0_IO, 0x00080808);
		break;
	case CX88_BOARD_ATI_HDTVWONDER:
		if (0 == core->i2c_rc) {
			/* enable tuner */
+89 −3
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * device driver for Conexant 2388x based TV cards
 * MPEG Transport Stream (DVB) routines
 *
 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
 *
 *  This program is free software; you can redistribute it and/or modify
@@ -35,6 +35,9 @@
#ifdef HAVE_MT352
# include "mt352.h"
# include "mt352_priv.h"
# ifdef HAVE_VP3054_I2C
#  include "cx88-vp3054-i2c.h"
# endif
#endif
#ifdef HAVE_CX22702
# include "cx22702.h"
@@ -108,7 +111,7 @@ static struct videobuf_queue_ops dvb_qops = {
/* ------------------------------------------------------------------ */

#ifdef HAVE_MT352
static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
static int generic_mt352_demod_init(struct dvb_frontend* fe)
{
	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
	static u8 reset []         = { RESET,      0x80 };
@@ -166,7 +169,7 @@ static int mt352_pll_set(struct dvb_frontend* fe,

static struct mt352_config dvico_fusionhdtv = {
	.demod_address = 0x0F,
	.demod_init    = dvico_fusionhdtv_demod_init,
	.demod_init    = generic_mt352_demod_init,
	.pll_set       = mt352_pll_set,
};

@@ -175,6 +178,69 @@ static struct mt352_config dntv_live_dvbt_config = {
	.demod_init    = dntv_live_dvbt_demod_init,
	.pll_set       = mt352_pll_set,
};

#ifdef HAVE_VP3054_I2C
static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
{
	struct cx8802_dev *dev= fe->dvb->priv;

	/* this message is to set up ATC and ALC */
	static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
	struct i2c_msg msg =
		{ .addr = dev->core->pll_addr, .flags = 0,
		  .buf = fmd1216_init, .len = sizeof(fmd1216_init) };
	int err;

	if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
		if (err < 0)
			return err;
		else
			return -EREMOTEIO;
	}

	return 0;
}

static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe,
				      struct dvb_frontend_parameters* params,
				      u8* pllbuf)
{
	struct cx8802_dev *dev= fe->dvb->priv;
	struct i2c_msg msg =
		{ .addr = dev->core->pll_addr, .flags = 0,
		  .buf = pllbuf+1, .len = 4 };
	int err;

	/* Switch PLL to DVB mode */
	err = philips_fmd1216_pll_init(fe);
	if (err)
		return err;

	/* Tune PLL */
	pllbuf[0] = dev->core->pll_addr << 1;
	dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
			  params->frequency,
			  params->u.ofdm.bandwidth);
	if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
		printk(KERN_WARNING "cx88-dvb: %s error "
			   "(addr %02x <- %02x, err = %i)\n",
			   __FUNCTION__, pllbuf[0], pllbuf[1], err);
		if (err < 0)
			return err;
		else
			return -EREMOTEIO;
	}

	return 0;
}

static struct mt352_config dntv_live_dvbt_pro_config = {
	.demod_address = 0x0f,
	.no_tuner      = 1,
	.demod_init    = generic_mt352_demod_init,
	.pll_set       = dntv_live_dvbt_pro_pll_set,
};
#endif
#endif

#ifdef HAVE_CX22702
@@ -403,6 +469,16 @@ static int dvb_register(struct cx8802_dev *dev)
		dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
						 &dev->core->i2c_adap);
		break;
	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
#ifdef HAVE_VP3054_I2C
		dev->core->pll_addr = 0x61;
		dev->core->pll_desc = &dvb_pll_fmd1216me;
		dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config,
			&((struct vp3054_i2c_state *)dev->card_priv)->adap);
#else
		printk("%s: built without vp3054 support\n", dev->core->name);
#endif
		break;
#endif
#ifdef HAVE_OR51132
	case CX88_BOARD_PCHDTV_HD3000:
@@ -532,6 +608,12 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
	if (0 != err)
		goto fail_free;

#ifdef HAVE_VP3054_I2C
	err = vp3054_i2c_probe(dev);
	if (0 != err)
		goto fail_free;
#endif

	/* dvb stuff */
	printk("%s/2: cx2388x based dvb card\n", core->name);
	videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
@@ -567,6 +649,10 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev)
	/* dvb */
	videobuf_dvb_unregister(&dev->dvb);

#ifdef HAVE_VP3054_I2C
	vp3054_i2c_remove(dev);
#endif

	/* common */
	cx8802_fini_common(dev);
	cx88_core_put(dev->core,dev->pci);
+74 −4
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *
 * Copyright (c) 2003 Pavel Machek
 * Copyright (c) 2004 Gerd Knorr
 * Copyright (c) 2004 Chris Pascoe
 * Copyright (c) 2004, 2005 Chris Pascoe
 *
 * 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
@@ -305,6 +305,66 @@ static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = {

/* ---------------------------------------------------------------------- */

/* DigitalNow DNTV Live! DVB-T Pro Remote */
static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = {
	[ 0x16 ] = KEY_POWER,
	[ 0x5b ] = KEY_HOME,

	[ 0x55 ] = KEY_TV,		/* live tv */
	[ 0x58 ] = KEY_TUNER,		/* digital Radio */
	[ 0x5a ] = KEY_RADIO,		/* FM radio */
	[ 0x59 ] = KEY_DVD,		/* dvd menu */
	[ 0x03 ] = KEY_1,
	[ 0x01 ] = KEY_2,
	[ 0x06 ] = KEY_3,
	[ 0x09 ] = KEY_4,
	[ 0x1d ] = KEY_5,
	[ 0x1f ] = KEY_6,
	[ 0x0d ] = KEY_7,
	[ 0x19 ] = KEY_8,
	[ 0x1b ] = KEY_9,
	[ 0x0c ] = KEY_CANCEL,
	[ 0x15 ] = KEY_0,
	[ 0x4a ] = KEY_CLEAR,
	[ 0x13 ] = KEY_BACK,
	[ 0x00 ] = KEY_TAB,
	[ 0x4b ] = KEY_UP,
	[ 0x4e ] = KEY_LEFT,
	[ 0x4f ] = KEY_OK,
	[ 0x52 ] = KEY_RIGHT,
	[ 0x51 ] = KEY_DOWN,
	[ 0x1e ] = KEY_VOLUMEUP,
	[ 0x0a ] = KEY_VOLUMEDOWN,
	[ 0x02 ] = KEY_CHANNELDOWN,
	[ 0x05 ] = KEY_CHANNELUP,
	[ 0x11 ] = KEY_RECORD,
	[ 0x14 ] = KEY_PLAY,
	[ 0x4c ] = KEY_PAUSE,
	[ 0x1a ] = KEY_STOP,
	[ 0x40 ] = KEY_REWIND,
	[ 0x12 ] = KEY_FASTFORWARD,
	[ 0x41 ] = KEY_PREVIOUSSONG,	/* replay |< */
	[ 0x42 ] = KEY_NEXTSONG,	/* skip >| */
	[ 0x54 ] = KEY_CAMERA,		/* capture */
	[ 0x50 ] = KEY_LANGUAGE,	/* sap */
	[ 0x47 ] = KEY_TV2,		/* pip */
	[ 0x4d ] = KEY_SCREEN,
	[ 0x43 ] = KEY_SUBTITLE,
	[ 0x10 ] = KEY_MUTE,
	[ 0x49 ] = KEY_AUDIO,		/* l/r */
	[ 0x07 ] = KEY_SLEEP,
	[ 0x08 ] = KEY_VIDEO,		/* a/v */
	[ 0x0e ] = KEY_PREVIOUS,	/* recall */
	[ 0x45 ] = KEY_ZOOM,		/* zoom + */
	[ 0x46 ] = KEY_ANGLE,		/* zoom - */
	[ 0x56 ] = KEY_RED,
	[ 0x57 ] = KEY_GREEN,
	[ 0x5c ] = KEY_YELLOW,
	[ 0x5d ] = KEY_BLUE,
};

/* ---------------------------------------------------------------------- */

struct cx88_IR {
	struct cx88_core *core;
	struct input_dev *input;
@@ -313,7 +373,7 @@ struct cx88_IR {
	char phys[32];

	/* sample from gpio pin 16 */
	int sampling;
	u32 sampling;
	u32 samples[16];
	int scount;
	unsigned long release;
@@ -431,7 +491,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
		ir_codes = ir_codes_cinergy_1400;
		ir_type = IR_TYPE_PD;
		ir->sampling = 1;
		ir->sampling = 0xeb04; /* address */
		break;
	case CX88_BOARD_HAUPPAUGE:
	case CX88_BOARD_HAUPPAUGE_DVB_T1:
@@ -484,6 +544,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
		ir->mask_keydown = 0x02;
		ir->polling      = 50; /* ms */
		break;
	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
		ir_codes = ir_codes_dntv_live_dvbt_pro;
		ir_type = IR_TYPE_PD;
		ir->sampling = 0xff00; /* address */
		break;
	}

	if (NULL == ir_codes) {
@@ -541,6 +606,10 @@ int cx88_ir_fini(struct cx88_core *core)
	if (NULL == ir)
		return 0;

	if (ir->sampling) {
		cx_write(MO_DDSCFG_IO, 0x0);
		core->pci_irqmask &= ~(1 << 18);
	}
	if (ir->polling) {
		del_timer(&ir->timer);
		flush_scheduled_work();
@@ -592,6 +661,7 @@ void cx88_ir_irq(struct cx88_core *core)
	/* decode it */
	switch (core->board) {
	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
		ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);

		if (ircode == 0xffffffff) { /* decoding error */
@@ -607,7 +677,7 @@ void cx88_ir_irq(struct cx88_core *core)
			break;
		}

		if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
		if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
			ir_dprintk("pulse distance decoded wrong address\n");
			break;
		}
Loading