aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Pascoe <c.pascoe@itee.uq.edu.au>2006-01-09 12:25:35 -0500
committerMauro Carvalho Chehab <mchehab@brturbo.com.br>2006-01-09 12:25:35 -0500
commitfc40b261db15d010455ad0a4e2ac59da2ced730f (patch)
treed91b96cb35c8b2e978d6ff1be5bdf3aad1993709
parent50c25fff5385c6baf3114f7c369b0f75a29ac1e8 (diff)
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: Chris Pascoe <c.pascoe@itee.uq.edu.au> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
-rw-r--r--Documentation/video4linux/CARDLIST.cx881
-rw-r--r--drivers/media/video/cx88/Makefile3
-rw-r--r--drivers/media/video/cx88/cx88-cards.c34
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c92
-rw-r--r--drivers/media/video/cx88/cx88-input.c78
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.c173
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.h35
-rw-r--r--drivers/media/video/cx88/cx88.h3
8 files changed, 411 insertions, 8 deletions
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index bb93a0a1871c..956cf833e931 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -40,3 +40,4 @@
40 39 -> KWorld DVB-S 100 [17de:08b2] 40 39 -> KWorld DVB-S 100 [17de:08b2]
41 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402] 41 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402]
42 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802] 42 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802]
43 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025]
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 90a7ace55f64..e4b2134fe567 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -4,7 +4,7 @@ cx8800-objs := cx88-video.o cx88-vbi.o
4cx8802-objs := cx88-mpeg.o 4cx8802-objs := cx88-mpeg.o
5 5
6obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o 6obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
7obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o 7obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o
8 8
9EXTRA_CFLAGS += -I$(src)/.. 9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
@@ -17,5 +17,6 @@ extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1
17extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 17extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1
18extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 18extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1
19extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 19extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1
20extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1
20 21
21EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) 22EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 85798e1fa047..6b17d1e1e520 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -982,6 +982,33 @@ struct cx88_board cx88_boards[] = {
982 /* fixme: Add radio support */ 982 /* fixme: Add radio support */
983 .dvb = 1, 983 .dvb = 1,
984 }, 984 },
985 [CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = {
986 .name = "digitalnow DNTV Live! DVB-T Pro",
987 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
988 .radio_type = UNSET,
989 .tuner_addr = ADDR_UNSET,
990 .radio_addr = ADDR_UNSET,
991 .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
992 TDA9887_PORT2_ACTIVE,
993 .input = {{
994 .type = CX88_VMUX_TELEVISION,
995 .vmux = 0,
996 .gpio0 = 0xf80808,
997 },{
998 .type = CX88_VMUX_COMPOSITE1,
999 .vmux = 1,
1000 .gpio0 = 0xf80808,
1001 },{
1002 .type = CX88_VMUX_SVIDEO,
1003 .vmux = 2,
1004 .gpio0 = 0xf80808,
1005 }},
1006 .radio = {
1007 .type = CX88_RADIO,
1008 .gpio0 = 0xf80808,
1009 },
1010 .dvb = 1,
1011 },
985}; 1012};
986const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 1013const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
987 1014
@@ -1165,6 +1192,10 @@ struct cx88_subid cx88_subids[] = {
1165 .subvendor = 0x0070, 1192 .subvendor = 0x0070,
1166 .subdevice = 0x9001, 1193 .subdevice = 0x9001,
1167 .card = CX88_BOARD_HAUPPAUGE_DVB_T1, 1194 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
1195 },{
1196 .subvendor = 0x1822,
1197 .subdevice = 0x0025,
1198 .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
1168 }, 1199 },
1169}; 1200};
1170const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1201const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1362,6 +1393,9 @@ void cx88_card_setup(struct cx88_core *core)
1362 cx_clear(MO_GP0_IO, 0x00000007); 1393 cx_clear(MO_GP0_IO, 0x00000007);
1363 cx_set(MO_GP2_IO, 0x00000101); 1394 cx_set(MO_GP2_IO, 0x00000101);
1364 break; 1395 break;
1396 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1397 cx_write(MO_GP0_IO, 0x00080808);
1398 break;
1365 case CX88_BOARD_ATI_HDTVWONDER: 1399 case CX88_BOARD_ATI_HDTVWONDER:
1366 if (0 == core->i2c_rc) { 1400 if (0 == core->i2c_rc) {
1367 /* enable tuner */ 1401 /* enable tuner */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index ed5cfe5f5c0e..201050478711 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -3,7 +3,7 @@
3 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
4 * MPEG Transport Stream (DVB) routines 4 * MPEG Transport Stream (DVB) routines
5 * 5 *
6 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au> 6 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -35,6 +35,9 @@
35#ifdef HAVE_MT352 35#ifdef HAVE_MT352
36# include "mt352.h" 36# include "mt352.h"
37# include "mt352_priv.h" 37# include "mt352_priv.h"
38# ifdef HAVE_VP3054_I2C
39# include "cx88-vp3054-i2c.h"
40# endif
38#endif 41#endif
39#ifdef HAVE_CX22702 42#ifdef HAVE_CX22702
40# include "cx22702.h" 43# include "cx22702.h"
@@ -108,7 +111,7 @@ static struct videobuf_queue_ops dvb_qops = {
108/* ------------------------------------------------------------------ */ 111/* ------------------------------------------------------------------ */
109 112
110#ifdef HAVE_MT352 113#ifdef HAVE_MT352
111static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) 114static int generic_mt352_demod_init(struct dvb_frontend* fe)
112{ 115{
113 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; 116 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
114 static u8 reset [] = { RESET, 0x80 }; 117 static u8 reset [] = { RESET, 0x80 };
@@ -166,7 +169,7 @@ static int mt352_pll_set(struct dvb_frontend* fe,
166 169
167static struct mt352_config dvico_fusionhdtv = { 170static struct mt352_config dvico_fusionhdtv = {
168 .demod_address = 0x0F, 171 .demod_address = 0x0F,
169 .demod_init = dvico_fusionhdtv_demod_init, 172 .demod_init = generic_mt352_demod_init,
170 .pll_set = mt352_pll_set, 173 .pll_set = mt352_pll_set,
171}; 174};
172 175
@@ -175,6 +178,69 @@ static struct mt352_config dntv_live_dvbt_config = {
175 .demod_init = dntv_live_dvbt_demod_init, 178 .demod_init = dntv_live_dvbt_demod_init,
176 .pll_set = mt352_pll_set, 179 .pll_set = mt352_pll_set,
177}; 180};
181
182#ifdef HAVE_VP3054_I2C
183static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
184{
185 struct cx8802_dev *dev= fe->dvb->priv;
186
187 /* this message is to set up ATC and ALC */
188 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
189 struct i2c_msg msg =
190 { .addr = dev->core->pll_addr, .flags = 0,
191 .buf = fmd1216_init, .len = sizeof(fmd1216_init) };
192 int err;
193
194 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
195 if (err < 0)
196 return err;
197 else
198 return -EREMOTEIO;
199 }
200
201 return 0;
202}
203
204static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe,
205 struct dvb_frontend_parameters* params,
206 u8* pllbuf)
207{
208 struct cx8802_dev *dev= fe->dvb->priv;
209 struct i2c_msg msg =
210 { .addr = dev->core->pll_addr, .flags = 0,
211 .buf = pllbuf+1, .len = 4 };
212 int err;
213
214 /* Switch PLL to DVB mode */
215 err = philips_fmd1216_pll_init(fe);
216 if (err)
217 return err;
218
219 /* Tune PLL */
220 pllbuf[0] = dev->core->pll_addr << 1;
221 dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
222 params->frequency,
223 params->u.ofdm.bandwidth);
224 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
225 printk(KERN_WARNING "cx88-dvb: %s error "
226 "(addr %02x <- %02x, err = %i)\n",
227 __FUNCTION__, pllbuf[0], pllbuf[1], err);
228 if (err < 0)
229 return err;
230 else
231 return -EREMOTEIO;
232 }
233
234 return 0;
235}
236
237static struct mt352_config dntv_live_dvbt_pro_config = {
238 .demod_address = 0x0f,
239 .no_tuner = 1,
240 .demod_init = generic_mt352_demod_init,
241 .pll_set = dntv_live_dvbt_pro_pll_set,
242};
243#endif
178#endif 244#endif
179 245
180#ifdef HAVE_CX22702 246#ifdef HAVE_CX22702
@@ -403,6 +469,16 @@ static int dvb_register(struct cx8802_dev *dev)
403 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, 469 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
404 &dev->core->i2c_adap); 470 &dev->core->i2c_adap);
405 break; 471 break;
472 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
473#ifdef HAVE_VP3054_I2C
474 dev->core->pll_addr = 0x61;
475 dev->core->pll_desc = &dvb_pll_fmd1216me;
476 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config,
477 &((struct vp3054_i2c_state *)dev->card_priv)->adap);
478#else
479 printk("%s: built without vp3054 support\n", dev->core->name);
480#endif
481 break;
406#endif 482#endif
407#ifdef HAVE_OR51132 483#ifdef HAVE_OR51132
408 case CX88_BOARD_PCHDTV_HD3000: 484 case CX88_BOARD_PCHDTV_HD3000:
@@ -532,6 +608,12 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
532 if (0 != err) 608 if (0 != err)
533 goto fail_free; 609 goto fail_free;
534 610
611#ifdef HAVE_VP3054_I2C
612 err = vp3054_i2c_probe(dev);
613 if (0 != err)
614 goto fail_free;
615#endif
616
535 /* dvb stuff */ 617 /* dvb stuff */
536 printk("%s/2: cx2388x based dvb card\n", core->name); 618 printk("%s/2: cx2388x based dvb card\n", core->name);
537 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, 619 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
@@ -567,6 +649,10 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev)
567 /* dvb */ 649 /* dvb */
568 videobuf_dvb_unregister(&dev->dvb); 650 videobuf_dvb_unregister(&dev->dvb);
569 651
652#ifdef HAVE_VP3054_I2C
653 vp3054_i2c_remove(dev);
654#endif
655
570 /* common */ 656 /* common */
571 cx8802_fini_common(dev); 657 cx8802_fini_common(dev);
572 cx88_core_put(dev->core,dev->pci); 658 cx88_core_put(dev->core,dev->pci);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 649bbf7bcc29..f40f97026b84 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Copyright (c) 2003 Pavel Machek 6 * Copyright (c) 2003 Pavel Machek
7 * Copyright (c) 2004 Gerd Knorr 7 * Copyright (c) 2004 Gerd Knorr
8 * Copyright (c) 2004 Chris Pascoe 8 * Copyright (c) 2004, 2005 Chris Pascoe
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * 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] = {
305 305
306/* ---------------------------------------------------------------------- */ 306/* ---------------------------------------------------------------------- */
307 307
308/* DigitalNow DNTV Live! DVB-T Pro Remote */
309static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = {
310 [ 0x16 ] = KEY_POWER,
311 [ 0x5b ] = KEY_HOME,
312
313 [ 0x55 ] = KEY_TV, /* live tv */
314 [ 0x58 ] = KEY_TUNER, /* digital Radio */
315 [ 0x5a ] = KEY_RADIO, /* FM radio */
316 [ 0x59 ] = KEY_DVD, /* dvd menu */
317 [ 0x03 ] = KEY_1,
318 [ 0x01 ] = KEY_2,
319 [ 0x06 ] = KEY_3,
320 [ 0x09 ] = KEY_4,
321 [ 0x1d ] = KEY_5,
322 [ 0x1f ] = KEY_6,
323 [ 0x0d ] = KEY_7,
324 [ 0x19 ] = KEY_8,
325 [ 0x1b ] = KEY_9,
326 [ 0x0c ] = KEY_CANCEL,
327 [ 0x15 ] = KEY_0,
328 [ 0x4a ] = KEY_CLEAR,
329 [ 0x13 ] = KEY_BACK,
330 [ 0x00 ] = KEY_TAB,
331 [ 0x4b ] = KEY_UP,
332 [ 0x4e ] = KEY_LEFT,
333 [ 0x4f ] = KEY_OK,
334 [ 0x52 ] = KEY_RIGHT,
335 [ 0x51 ] = KEY_DOWN,
336 [ 0x1e ] = KEY_VOLUMEUP,
337 [ 0x0a ] = KEY_VOLUMEDOWN,
338 [ 0x02 ] = KEY_CHANNELDOWN,
339 [ 0x05 ] = KEY_CHANNELUP,
340 [ 0x11 ] = KEY_RECORD,
341 [ 0x14 ] = KEY_PLAY,
342 [ 0x4c ] = KEY_PAUSE,
343 [ 0x1a ] = KEY_STOP,
344 [ 0x40 ] = KEY_REWIND,
345 [ 0x12 ] = KEY_FASTFORWARD,
346 [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */
347 [ 0x42 ] = KEY_NEXTSONG, /* skip >| */
348 [ 0x54 ] = KEY_CAMERA, /* capture */
349 [ 0x50 ] = KEY_LANGUAGE, /* sap */
350 [ 0x47 ] = KEY_TV2, /* pip */
351 [ 0x4d ] = KEY_SCREEN,
352 [ 0x43 ] = KEY_SUBTITLE,
353 [ 0x10 ] = KEY_MUTE,
354 [ 0x49 ] = KEY_AUDIO, /* l/r */
355 [ 0x07 ] = KEY_SLEEP,
356 [ 0x08 ] = KEY_VIDEO, /* a/v */
357 [ 0x0e ] = KEY_PREVIOUS, /* recall */
358 [ 0x45 ] = KEY_ZOOM, /* zoom + */
359 [ 0x46 ] = KEY_ANGLE, /* zoom - */
360 [ 0x56 ] = KEY_RED,
361 [ 0x57 ] = KEY_GREEN,
362 [ 0x5c ] = KEY_YELLOW,
363 [ 0x5d ] = KEY_BLUE,
364};
365
366/* ---------------------------------------------------------------------- */
367
308struct cx88_IR { 368struct cx88_IR {
309 struct cx88_core *core; 369 struct cx88_core *core;
310 struct input_dev *input; 370 struct input_dev *input;
@@ -313,7 +373,7 @@ struct cx88_IR {
313 char phys[32]; 373 char phys[32];
314 374
315 /* sample from gpio pin 16 */ 375 /* sample from gpio pin 16 */
316 int sampling; 376 u32 sampling;
317 u32 samples[16]; 377 u32 samples[16];
318 int scount; 378 int scount;
319 unsigned long release; 379 unsigned long release;
@@ -431,7 +491,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
431 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 491 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
432 ir_codes = ir_codes_cinergy_1400; 492 ir_codes = ir_codes_cinergy_1400;
433 ir_type = IR_TYPE_PD; 493 ir_type = IR_TYPE_PD;
434 ir->sampling = 1; 494 ir->sampling = 0xeb04; /* address */
435 break; 495 break;
436 case CX88_BOARD_HAUPPAUGE: 496 case CX88_BOARD_HAUPPAUGE:
437 case CX88_BOARD_HAUPPAUGE_DVB_T1: 497 case CX88_BOARD_HAUPPAUGE_DVB_T1:
@@ -484,6 +544,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
484 ir->mask_keydown = 0x02; 544 ir->mask_keydown = 0x02;
485 ir->polling = 50; /* ms */ 545 ir->polling = 50; /* ms */
486 break; 546 break;
547 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
548 ir_codes = ir_codes_dntv_live_dvbt_pro;
549 ir_type = IR_TYPE_PD;
550 ir->sampling = 0xff00; /* address */
551 break;
487 } 552 }
488 553
489 if (NULL == ir_codes) { 554 if (NULL == ir_codes) {
@@ -541,6 +606,10 @@ int cx88_ir_fini(struct cx88_core *core)
541 if (NULL == ir) 606 if (NULL == ir)
542 return 0; 607 return 0;
543 608
609 if (ir->sampling) {
610 cx_write(MO_DDSCFG_IO, 0x0);
611 core->pci_irqmask &= ~(1 << 18);
612 }
544 if (ir->polling) { 613 if (ir->polling) {
545 del_timer(&ir->timer); 614 del_timer(&ir->timer);
546 flush_scheduled_work(); 615 flush_scheduled_work();
@@ -592,6 +661,7 @@ void cx88_ir_irq(struct cx88_core *core)
592 /* decode it */ 661 /* decode it */
593 switch (core->board) { 662 switch (core->board) {
594 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 663 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
664 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
595 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); 665 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
596 666
597 if (ircode == 0xffffffff) { /* decoding error */ 667 if (ircode == 0xffffffff) { /* decoding error */
@@ -607,7 +677,7 @@ void cx88_ir_irq(struct cx88_core *core)
607 break; 677 break;
608 } 678 }
609 679
610 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ 680 if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
611 ir_dprintk("pulse distance decoded wrong address\n"); 681 ir_dprintk("pulse distance decoded wrong address\n");
612 break; 682 break;
613 } 683 }
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
new file mode 100644
index 000000000000..372cd29cedbd
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -0,0 +1,173 @@
1/*
2
3 cx88-vp3054-i2c.c -- support for the secondary I2C bus of the
4 DNTV Live! DVB-T Pro (VP-3054), wired as:
5 GPIO[0] -> SCL, GPIO[1] -> SDA
6
7 (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28
29#include <asm/io.h>
30
31#include "cx88.h"
32#include "cx88-vp3054-i2c.h"
33
34
35/* ----------------------------------------------------------------------- */
36
37static void vp3054_bit_setscl(void *data, int state)
38{
39 struct cx8802_dev *dev = data;
40 struct cx88_core *core = dev->core;
41 struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
42
43 if (state) {
44 vp3054_i2c->state |= 0x0001; /* SCL high */
45 vp3054_i2c->state &= ~0x0100; /* external pullup */
46 } else {
47 vp3054_i2c->state &= ~0x0001; /* SCL low */
48 vp3054_i2c->state |= 0x0100; /* drive pin */
49 }
50 cx_write(MO_GP0_IO, 0x010000 | vp3054_i2c->state);
51 cx_read(MO_GP0_IO);
52}
53
54static void vp3054_bit_setsda(void *data, int state)
55{
56 struct cx8802_dev *dev = data;
57 struct cx88_core *core = dev->core;
58 struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
59
60 if (state) {
61 vp3054_i2c->state |= 0x0002; /* SDA high */
62 vp3054_i2c->state &= ~0x0200; /* tristate pin */
63 } else {
64 vp3054_i2c->state &= ~0x0002; /* SDA low */
65 vp3054_i2c->state |= 0x0200; /* drive pin */
66 }
67 cx_write(MO_GP0_IO, 0x020000 | vp3054_i2c->state);
68 cx_read(MO_GP0_IO);
69}
70
71static int vp3054_bit_getscl(void *data)
72{
73 struct cx8802_dev *dev = data;
74 struct cx88_core *core = dev->core;
75 u32 state;
76
77 state = cx_read(MO_GP0_IO);
78 return (state & 0x01) ? 1 : 0;
79}
80
81static int vp3054_bit_getsda(void *data)
82{
83 struct cx8802_dev *dev = data;
84 struct cx88_core *core = dev->core;
85 u32 state;
86
87 state = cx_read(MO_GP0_IO);
88 return (state & 0x02) ? 1 : 0;
89}
90
91/* ----------------------------------------------------------------------- */
92
93static struct i2c_algo_bit_data vp3054_i2c_algo_template = {
94 .setsda = vp3054_bit_setsda,
95 .setscl = vp3054_bit_setscl,
96 .getsda = vp3054_bit_getsda,
97 .getscl = vp3054_bit_getscl,
98 .udelay = 16,
99 .mdelay = 10,
100 .timeout = 200,
101};
102
103/* ----------------------------------------------------------------------- */
104
105static struct i2c_adapter vp3054_i2c_adap_template = {
106 .name = "cx2388x",
107 .owner = THIS_MODULE,
108 .id = I2C_HW_B_CX2388x,
109};
110
111static struct i2c_client vp3054_i2c_client_template = {
112 .name = "VP-3054",
113};
114
115int vp3054_i2c_probe(struct cx8802_dev *dev)
116{
117 struct cx88_core *core = dev->core;
118 struct vp3054_i2c_state *vp3054_i2c;
119 int rc;
120
121 if (core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
122 return 0;
123
124 dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
125 if (dev->card_priv == NULL)
126 return -ENOMEM;
127 vp3054_i2c = dev->card_priv;
128
129 memcpy(&vp3054_i2c->adap, &vp3054_i2c_adap_template,
130 sizeof(vp3054_i2c->adap));
131 memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
132 sizeof(vp3054_i2c->algo));
133 memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template,
134 sizeof(vp3054_i2c->client));
135
136 vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL;
137
138 vp3054_i2c->adap.dev.parent = &dev->pci->dev;
139 strlcpy(vp3054_i2c->adap.name, core->name,
140 sizeof(vp3054_i2c->adap.name));
141 vp3054_i2c->algo.data = dev;
142 i2c_set_adapdata(&vp3054_i2c->adap, dev);
143 vp3054_i2c->adap.algo_data = &vp3054_i2c->algo;
144 vp3054_i2c->client.adapter = &vp3054_i2c->adap;
145
146 vp3054_bit_setscl(dev,1);
147 vp3054_bit_setsda(dev,1);
148
149 rc = i2c_bit_add_bus(&vp3054_i2c->adap);
150 if (0 != rc) {
151 printk("%s: vp3054_i2c register FAILED\n", core->name);
152
153 kfree(dev->card_priv);
154 dev->card_priv = NULL;
155 }
156
157 return rc;
158}
159
160void vp3054_i2c_remove(struct cx8802_dev *dev)
161{
162 struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
163
164 if (vp3054_i2c == NULL ||
165 dev->core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
166 return;
167
168 i2c_bit_del_bus(&vp3054_i2c->adap);
169 kfree(vp3054_i2c);
170}
171
172EXPORT_SYMBOL(vp3054_i2c_probe);
173EXPORT_SYMBOL(vp3054_i2c_remove);
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.h b/drivers/media/video/cx88/cx88-vp3054-i2c.h
new file mode 100644
index 000000000000..b7a0a04d2423
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.h
@@ -0,0 +1,35 @@
1/*
2
3 cx88-vp3054-i2c.h -- support for the secondary I2C bus of the
4 DNTV Live! DVB-T Pro (VP-3054), wired as:
5 GPIO[0] -> SCL, GPIO[1] -> SDA
6
7 (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25/* ----------------------------------------------------------------------- */
26struct vp3054_i2c_state {
27 struct i2c_adapter adap;
28 struct i2c_algo_bit_data algo;
29 struct i2c_client client;
30 u32 state;
31};
32
33/* ----------------------------------------------------------------------- */
34int vp3054_i2c_probe(struct cx8802_dev *dev);
35void vp3054_i2c_remove(struct cx8802_dev *dev);
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 0bbf68b325c4..6d370d1b333f 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -184,6 +184,7 @@ extern struct sram_channel cx88_sram_channels[];
184#define CX88_BOARD_KWORLD_DVBS_100 39 184#define CX88_BOARD_KWORLD_DVBS_100 39
185#define CX88_BOARD_HAUPPAUGE_HVR1100 40 185#define CX88_BOARD_HAUPPAUGE_HVR1100 40
186#define CX88_BOARD_HAUPPAUGE_HVR1100LP 41 186#define CX88_BOARD_HAUPPAUGE_HVR1100LP 41
187#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42
187 188
188enum cx88_itype { 189enum cx88_itype {
189 CX88_VMUX_COMPOSITE1 = 1, 190 CX88_VMUX_COMPOSITE1 = 1,
@@ -422,6 +423,8 @@ struct cx8802_dev {
422 struct videobuf_dvb dvb; 423 struct videobuf_dvb dvb;
423 void* fe_handle; 424 void* fe_handle;
424 int (*fe_release)(void *handle); 425 int (*fe_release)(void *handle);
426
427 void *card_priv;
425 /* for switching modulation types */ 428 /* for switching modulation types */
426 unsigned char ts_gen_cntrl; 429 unsigned char ts_gen_cntrl;
427 430