aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx88')
-rw-r--r--drivers/media/video/cx88/Kconfig11
-rw-r--r--drivers/media/video/cx88/Makefile1
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c10
-rw-r--r--drivers/media/video/cx88/cx88-cards.c111
-rw-r--r--drivers/media/video/cx88/cx88-core.c9
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c108
-rw-r--r--drivers/media/video/cx88/cx88-input.c339
-rw-r--r--drivers/media/video/cx88/cx88-video.c57
-rw-r--r--drivers/media/video/cx88/cx88.h8
9 files changed, 251 insertions, 403 deletions
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 87d79df05336..e140996e6ee4 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -50,6 +50,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
50 depends on VIDEO_CX88_DVB 50 depends on VIDEO_CX88_DVB
51 select DVB_MT352 51 select DVB_MT352
52 select VIDEO_CX88_VP3054 52 select VIDEO_CX88_VP3054
53 select DVB_ZL10353
53 select DVB_OR51132 54 select DVB_OR51132
54 select DVB_CX22702 55 select DVB_CX22702
55 select DVB_LGDT330X 56 select DVB_LGDT330X
@@ -81,6 +82,16 @@ config VIDEO_CX88_VP3054
81 which also require support for the VP-3054 82 which also require support for the VP-3054
82 Secondary I2C bus, such at DNTV Live! DVB-T Pro. 83 Secondary I2C bus, such at DNTV Live! DVB-T Pro.
83 84
85config VIDEO_CX88_DVB_ZL10353
86 bool "Zarlink ZL10353 DVB-T Support"
87 default y
88 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
89 select DVB_ZL10353
90 ---help---
91 This adds DVB-T support for cards based on the
92 Connexant 2388x chip and the ZL10353 demodulator,
93 successor to the Zarlink MT352.
94
84config VIDEO_CX88_DVB_OR51132 95config VIDEO_CX88_DVB_OR51132
85 bool "OR51132 ATSC Support" 96 bool "OR51132 ATSC Support"
86 default y 97 default y
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 2b902784facc..6482b9aa6a1f 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -17,6 +17,7 @@ extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1
17extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1 17extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1
18extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 18extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1
19extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 19extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1
20extra-cflags-$(CONFIG_DVB_ZL10353) += -DHAVE_ZL10353=1
20extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 21extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1
21extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 22extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1
22extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1 23extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index c841914c0244..3170b8f72c68 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -676,6 +676,11 @@ static int __devinit snd_cx88_create(struct snd_card *card,
676 chip = (snd_cx88_card_t *) card->private_data; 676 chip = (snd_cx88_card_t *) card->private_data;
677 677
678 core = cx88_core_get(pci); 678 core = cx88_core_get(pci);
679 if (NULL == core) {
680 err = -EINVAL;
681 kfree (chip);
682 return err;
683 }
679 684
680 if (!pci_dma_supported(pci,0xffffffff)) { 685 if (!pci_dma_supported(pci,0xffffffff)) {
681 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); 686 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
@@ -692,11 +697,6 @@ static int __devinit snd_cx88_create(struct snd_card *card,
692 spin_lock_init(&chip->reg_lock); 697 spin_lock_init(&chip->reg_lock);
693 698
694 cx88_reset(core); 699 cx88_reset(core);
695 if (NULL == core) {
696 err = -EINVAL;
697 kfree (chip);
698 return err;
699 }
700 chip->core = core; 700 chip->core = core;
701 701
702 /* get irq */ 702 /* get irq */
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 1bc999247fdc..c7042cf41231 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -184,17 +184,18 @@ struct cx88_board cx88_boards[] = {
184 .input = {{ 184 .input = {{
185 .type = CX88_VMUX_TELEVISION, 185 .type = CX88_VMUX_TELEVISION,
186 .vmux = 0, 186 .vmux = 0,
187 .gpio1 = 0x309f, 187 .gpio1 = 0xe09f,
188 },{ 188 },{
189 .type = CX88_VMUX_COMPOSITE1, 189 .type = CX88_VMUX_COMPOSITE1,
190 .vmux = 1, 190 .vmux = 1,
191 .gpio1 = 0x305f, 191 .gpio1 = 0xe05f,
192 },{ 192 },{
193 .type = CX88_VMUX_SVIDEO, 193 .type = CX88_VMUX_SVIDEO,
194 .vmux = 2, 194 .vmux = 2,
195 .gpio1 = 0x305f, 195 .gpio1 = 0xe05f,
196 }}, 196 }},
197 .radio = { 197 .radio = {
198 .gpio1 = 0xe0df,
198 .type = CX88_RADIO, 199 .type = CX88_RADIO,
199 }, 200 },
200 }, 201 },
@@ -322,19 +323,19 @@ struct cx88_board cx88_boards[] = {
322 .input = {{ 323 .input = {{
323 .type = CX88_VMUX_TELEVISION, 324 .type = CX88_VMUX_TELEVISION,
324 .vmux = 0, 325 .vmux = 0,
325 .gpio0 = 0xff00, 326 .gpio0 = 0xbff0,
326 },{ 327 },{
327 .type = CX88_VMUX_COMPOSITE1, 328 .type = CX88_VMUX_COMPOSITE1,
328 .vmux = 1, 329 .vmux = 1,
329 .gpio0 = 0xff03, 330 .gpio0 = 0xbff3,
330 },{ 331 },{
331 .type = CX88_VMUX_SVIDEO, 332 .type = CX88_VMUX_SVIDEO,
332 .vmux = 2, 333 .vmux = 2,
333 .gpio0 = 0xff03, 334 .gpio0 = 0xbff3,
334 }}, 335 }},
335 .radio = { 336 .radio = {
336 .type = CX88_RADIO, 337 .type = CX88_RADIO,
337 .gpio0 = 0xff00, 338 .gpio0 = 0xbff0,
338 }, 339 },
339 }, 340 },
340 [CX88_BOARD_ASUS_PVR_416] = { 341 [CX88_BOARD_ASUS_PVR_416] = {
@@ -1048,6 +1049,50 @@ struct cx88_board cx88_boards[] = {
1048 }}, 1049 }},
1049 .dvb = 1, 1050 .dvb = 1,
1050 }, 1051 },
1052 [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = {
1053 /* FIXME: Standard video using the cx88 broadcast decoder is
1054 * working, but blackbird isn't working yet, audio is only
1055 * working correctly for television mode. S-Video and Composite
1056 * are working for video-only, so I have them disabled for now.
1057 */
1058 .name = "KWorld HardwareMpegTV XPert",
1059 .tuner_type = TUNER_PHILIPS_TDA8290,
1060 .radio_type = UNSET,
1061 .tuner_addr = ADDR_UNSET,
1062 .radio_addr = ADDR_UNSET,
1063 .input = {{
1064 .type = CX88_VMUX_TELEVISION,
1065 .vmux = 0,
1066 .gpio0 = 0x3de2,
1067 .gpio2 = 0x00ff,
1068 }},
1069 .radio = {
1070 .type = CX88_RADIO,
1071 .gpio0 = 0x3de6,
1072 .gpio2 = 0x00ff,
1073 },
1074 },
1075 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = {
1076 .name = "DViCO FusionHDTV DVB-T Hybrid",
1077 .tuner_type = TUNER_THOMSON_FE6600,
1078 .radio_type = UNSET,
1079 .tuner_addr = ADDR_UNSET,
1080 .radio_addr = ADDR_UNSET,
1081 .input = {{
1082 .type = CX88_VMUX_TELEVISION,
1083 .vmux = 0,
1084 .gpio0 = 0x0000a75f,
1085 },{
1086 .type = CX88_VMUX_COMPOSITE1,
1087 .vmux = 1,
1088 .gpio0 = 0x0000a75b,
1089 },{
1090 .type = CX88_VMUX_SVIDEO,
1091 .vmux = 2,
1092 .gpio0 = 0x0000a75b,
1093 }},
1094 .dvb = 1,
1095 },
1051 1096
1052}; 1097};
1053const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 1098const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -1254,6 +1299,18 @@ struct cx88_subid cx88_subids[] = {
1254 .subdevice = 0xdb11, 1299 .subdevice = 0xdb11,
1255 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, 1300 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
1256 /* Re-branded DViCO: UltraView DVB-T Plus */ 1301 /* Re-branded DViCO: UltraView DVB-T Plus */
1302 },{
1303 .subvendor = 0x17de,
1304 .subdevice = 0x0840,
1305 .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
1306 },{
1307 .subvendor = 0x18ac,
1308 .subdevice = 0xdb40,
1309 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
1310 },{
1311 .subvendor = 0x18ac,
1312 .subdevice = 0xdb44,
1313 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
1257 }, 1314 },
1258}; 1315};
1259const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1316const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1373,6 +1430,40 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
1373} 1430}
1374 1431
1375/* ----------------------------------------------------------------------- */ 1432/* ----------------------------------------------------------------------- */
1433/* some DViCO specific stuff */
1434
1435static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
1436{
1437 struct i2c_msg msg = { .addr = 0x45, .flags = 0 };
1438 int i, err;
1439 static u8 init_bufs[13][5] = {
1440 { 0x10, 0x00, 0x20, 0x01, 0x03 },
1441 { 0x10, 0x10, 0x01, 0x00, 0x21 },
1442 { 0x10, 0x10, 0x10, 0x00, 0xCA },
1443 { 0x10, 0x10, 0x12, 0x00, 0x08 },
1444 { 0x10, 0x10, 0x13, 0x00, 0x0A },
1445 { 0x10, 0x10, 0x16, 0x01, 0xC0 },
1446 { 0x10, 0x10, 0x22, 0x01, 0x3D },
1447 { 0x10, 0x10, 0x73, 0x01, 0x2E },
1448 { 0x10, 0x10, 0x72, 0x00, 0xC5 },
1449 { 0x10, 0x10, 0x71, 0x01, 0x97 },
1450 { 0x10, 0x10, 0x70, 0x00, 0x0F },
1451 { 0x10, 0x10, 0xB0, 0x00, 0x01 },
1452 { 0x03, 0x0C },
1453 };
1454
1455 for (i = 0; i < 13; i++) {
1456 msg.buf = init_bufs[i];
1457 msg.len = (i != 12 ? 5 : 2);
1458 err = i2c_transfer(&core->i2c_adap, &msg, 1);
1459 if (err != 1) {
1460 printk("dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", i, err);
1461 return;
1462 }
1463 }
1464}
1465
1466/* ----------------------------------------------------------------------- */
1376 1467
1377void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) 1468void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
1378{ 1469{
@@ -1438,11 +1529,15 @@ void cx88_card_setup(struct cx88_core *core)
1438 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 1529 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1439 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 1530 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
1440 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: 1531 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1532 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
1441 /* GPIO0:0 is hooked to mt352 reset pin */ 1533 /* GPIO0:0 is hooked to mt352 reset pin */
1442 cx_set(MO_GP0_IO, 0x00000101); 1534 cx_set(MO_GP0_IO, 0x00000101);
1443 cx_clear(MO_GP0_IO, 0x00000001); 1535 cx_clear(MO_GP0_IO, 0x00000001);
1444 msleep(1); 1536 msleep(1);
1445 cx_set(MO_GP0_IO, 0x00000101); 1537 cx_set(MO_GP0_IO, 0x00000101);
1538 if (0 == core->i2c_rc &&
1539 core->board == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID)
1540 dvico_fusionhdtv_hybrid_init(core);
1446 break; 1541 break;
1447 case CX88_BOARD_KWORLD_DVB_T: 1542 case CX88_BOARD_KWORLD_DVB_T:
1448 case CX88_BOARD_DNTV_LIVE_DVB_T: 1543 case CX88_BOARD_DNTV_LIVE_DVB_T:
@@ -1460,7 +1555,7 @@ void cx88_card_setup(struct cx88_core *core)
1460 if (0 == core->i2c_rc) { 1555 if (0 == core->i2c_rc) {
1461 /* enable tuner */ 1556 /* enable tuner */
1462 int i; 1557 int i;
1463 u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; 1558 static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
1464 core->i2c_client.addr = 0x0a; 1559 core->i2c_client.addr = 0x0a;
1465 1560
1466 for (i = 0; i < 5; i++) 1561 for (i = 0; i < 5; i++)
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 3720f24a25cf..c2cdbafdb77b 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -163,7 +163,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
163 163
164 /* save pointer to jmp instruction address */ 164 /* save pointer to jmp instruction address */
165 risc->jmp = rp; 165 risc->jmp = rp;
166 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); 166 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
167 return 0; 167 return 0;
168} 168}
169 169
@@ -188,7 +188,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
188 188
189 /* save pointer to jmp instruction address */ 189 /* save pointer to jmp instruction address */
190 risc->jmp = rp; 190 risc->jmp = rp;
191 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); 191 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
192 return 0; 192 return 0;
193} 193}
194 194
@@ -215,8 +215,7 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
215void 215void
216cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf) 216cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
217{ 217{
218 if (in_interrupt()) 218 BUG_ON(in_interrupt());
219 BUG();
220 videobuf_waiton(&buf->vb,0,0); 219 videobuf_waiton(&buf->vb,0,0);
221 videobuf_dma_pci_unmap(pci, &buf->vb.dma); 220 videobuf_dma_pci_unmap(pci, &buf->vb.dma);
222 videobuf_dma_free(&buf->vb.dma); 221 videobuf_dma_free(&buf->vb.dma);
@@ -1061,7 +1060,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1061 core->pci_bus = pci->bus->number; 1060 core->pci_bus = pci->bus->number;
1062 core->pci_slot = PCI_SLOT(pci->devfn); 1061 core->pci_slot = PCI_SLOT(pci->devfn);
1063 core->pci_irqmask = 0x00fc00; 1062 core->pci_irqmask = 0x00fc00;
1064 init_MUTEX(&core->lock); 1063 mutex_init(&core->lock);
1065 1064
1066 core->nr = cx88_devcount++; 1065 core->nr = cx88_devcount++;
1067 sprintf(core->name,"cx88[%d]",core->nr); 1066 sprintf(core->name,"cx88[%d]",core->nr);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index e48aa3f6e500..a9fc2695b157 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -40,6 +40,9 @@
40# include "cx88-vp3054-i2c.h" 40# include "cx88-vp3054-i2c.h"
41# endif 41# endif
42#endif 42#endif
43#ifdef HAVE_ZL10353
44# include "zl10353.h"
45#endif
43#ifdef HAVE_CX22702 46#ifdef HAVE_CX22702
44# include "cx22702.h" 47# include "cx22702.h"
45#endif 48#endif
@@ -111,6 +114,21 @@ static struct videobuf_queue_ops dvb_qops = {
111 114
112/* ------------------------------------------------------------------ */ 115/* ------------------------------------------------------------------ */
113 116
117#if defined(HAVE_MT352) || defined(HAVE_ZL10353)
118static int zarlink_pll_set(struct dvb_frontend *fe,
119 struct dvb_frontend_parameters *params,
120 u8 *pllbuf)
121{
122 struct cx8802_dev *dev = fe->dvb->priv;
123
124 pllbuf[0] = dev->core->pll_addr << 1;
125 dvb_pll_configure(dev->core->pll_desc, pllbuf + 1,
126 params->frequency,
127 params->u.ofdm.bandwidth);
128 return 0;
129}
130#endif
131
114#ifdef HAVE_MT352 132#ifdef HAVE_MT352
115static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) 133static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
116{ 134{
@@ -176,35 +194,22 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
176 return 0; 194 return 0;
177} 195}
178 196
179static int mt352_pll_set(struct dvb_frontend* fe,
180 struct dvb_frontend_parameters* params,
181 u8* pllbuf)
182{
183 struct cx8802_dev *dev= fe->dvb->priv;
184
185 pllbuf[0] = dev->core->pll_addr << 1;
186 dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
187 params->frequency,
188 params->u.ofdm.bandwidth);
189 return 0;
190}
191
192static struct mt352_config dvico_fusionhdtv = { 197static struct mt352_config dvico_fusionhdtv = {
193 .demod_address = 0x0F, 198 .demod_address = 0x0F,
194 .demod_init = dvico_fusionhdtv_demod_init, 199 .demod_init = dvico_fusionhdtv_demod_init,
195 .pll_set = mt352_pll_set, 200 .pll_set = zarlink_pll_set,
196}; 201};
197 202
198static struct mt352_config dntv_live_dvbt_config = { 203static struct mt352_config dntv_live_dvbt_config = {
199 .demod_address = 0x0f, 204 .demod_address = 0x0f,
200 .demod_init = dntv_live_dvbt_demod_init, 205 .demod_init = dntv_live_dvbt_demod_init,
201 .pll_set = mt352_pll_set, 206 .pll_set = zarlink_pll_set,
202}; 207};
203 208
204static struct mt352_config dvico_fusionhdtv_dual = { 209static struct mt352_config dvico_fusionhdtv_dual = {
205 .demod_address = 0x0F, 210 .demod_address = 0x0F,
206 .demod_init = dvico_dual_demod_init, 211 .demod_init = dvico_dual_demod_init,
207 .pll_set = mt352_pll_set, 212 .pll_set = zarlink_pll_set,
208}; 213};
209 214
210#ifdef HAVE_VP3054_I2C 215#ifdef HAVE_VP3054_I2C
@@ -294,6 +299,46 @@ static struct mt352_config dntv_live_dvbt_pro_config = {
294#endif 299#endif
295#endif 300#endif
296 301
302#ifdef HAVE_ZL10353
303static int dvico_hybrid_tune_pll(struct dvb_frontend *fe,
304 struct dvb_frontend_parameters *params,
305 u8 *pllbuf)
306{
307 struct cx8802_dev *dev= fe->dvb->priv;
308 struct i2c_msg msg =
309 { .addr = dev->core->pll_addr, .flags = 0,
310 .buf = pllbuf + 1, .len = 4 };
311 int err;
312
313 pllbuf[0] = dev->core->pll_addr << 1;
314 dvb_pll_configure(dev->core->pll_desc, pllbuf + 1,
315 params->frequency,
316 params->u.ofdm.bandwidth);
317
318 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
319 printk(KERN_WARNING "cx88-dvb: %s error "
320 "(addr %02x <- %02x, err = %i)\n",
321 __FUNCTION__, pllbuf[0], pllbuf[1], err);
322 if (err < 0)
323 return err;
324 else
325 return -EREMOTEIO;
326 }
327
328 return 0;
329}
330
331static struct zl10353_config dvico_fusionhdtv_hybrid = {
332 .demod_address = 0x0F,
333 .pll_set = dvico_hybrid_tune_pll,
334};
335
336static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
337 .demod_address = 0x0F,
338 .pll_set = zarlink_pll_set,
339};
340#endif
341
297#ifdef HAVE_CX22702 342#ifdef HAVE_CX22702
298static struct cx22702_config connexant_refboard_config = { 343static struct cx22702_config connexant_refboard_config = {
299 .demod_address = 0x43, 344 .demod_address = 0x43,
@@ -500,16 +545,27 @@ static int dvb_register(struct cx8802_dev *dev)
500 &dev->core->i2c_adap); 545 &dev->core->i2c_adap);
501 break; 546 break;
502#endif 547#endif
548#if defined(HAVE_MT352) || defined(HAVE_ZL10353)
549 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
550 dev->core->pll_addr = 0x60;
551 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
503#ifdef HAVE_MT352 552#ifdef HAVE_MT352
504 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
505 dev->core->pll_addr = 0x61;
506 dev->core->pll_desc = &dvb_pll_lg_z201;
507 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, 553 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
508 &dev->core->i2c_adap); 554 &dev->core->i2c_adap);
555 if (dev->dvb.frontend != NULL)
556 break;
557#endif
558#ifdef HAVE_ZL10353
559 /* ZL10353 replaces MT352 on later cards */
560 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1,
561 &dev->core->i2c_adap);
562#endif
509 break; 563 break;
510 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 564#endif /* HAVE_MT352 || HAVE_ZL10353 */
511 dev->core->pll_addr = 0x60; 565#ifdef HAVE_MT352
512 dev->core->pll_desc = &dvb_pll_thomson_dtt7579; 566 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
567 dev->core->pll_addr = 0x61;
568 dev->core->pll_desc = &dvb_pll_lg_z201;
513 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, 569 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
514 &dev->core->i2c_adap); 570 &dev->core->i2c_adap);
515 break; 571 break;
@@ -540,6 +596,14 @@ static int dvb_register(struct cx8802_dev *dev)
540 &dev->core->i2c_adap); 596 &dev->core->i2c_adap);
541 break; 597 break;
542#endif 598#endif
599#ifdef HAVE_ZL10353
600 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
601 dev->core->pll_addr = 0x61;
602 dev->core->pll_desc = &dvb_pll_thomson_fe6600;
603 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid,
604 &dev->core->i2c_adap);
605 break;
606#endif
543#ifdef HAVE_OR51132 607#ifdef HAVE_OR51132
544 case CX88_BOARD_PCHDTV_HD3000: 608 case CX88_BOARD_PCHDTV_HD3000:
545 dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, 609 dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 165d948624a3..78a63b7dd380 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -34,337 +34,6 @@
34 34
35/* ---------------------------------------------------------------------- */ 35/* ---------------------------------------------------------------------- */
36 36
37/* DigitalNow DNTV Live DVB-T Remote */
38static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
39 [0x00] = KEY_ESC, /* 'go up a level?' */
40 /* Keys 0 to 9 */
41 [0x0a] = KEY_KP0,
42 [0x01] = KEY_KP1,
43 [0x02] = KEY_KP2,
44 [0x03] = KEY_KP3,
45 [0x04] = KEY_KP4,
46 [0x05] = KEY_KP5,
47 [0x06] = KEY_KP6,
48 [0x07] = KEY_KP7,
49 [0x08] = KEY_KP8,
50 [0x09] = KEY_KP9,
51
52 [0x0b] = KEY_TUNER, /* tv/fm */
53 [0x0c] = KEY_SEARCH, /* scan */
54 [0x0d] = KEY_STOP,
55 [0x0e] = KEY_PAUSE,
56 [0x0f] = KEY_LIST, /* source */
57
58 [0x10] = KEY_MUTE,
59 [0x11] = KEY_REWIND, /* backward << */
60 [0x12] = KEY_POWER,
61 [0x13] = KEY_S, /* snap */
62 [0x14] = KEY_AUDIO, /* stereo */
63 [0x15] = KEY_CLEAR, /* reset */
64 [0x16] = KEY_PLAY,
65 [0x17] = KEY_ENTER,
66 [0x18] = KEY_ZOOM, /* full screen */
67 [0x19] = KEY_FASTFORWARD, /* forward >> */
68 [0x1a] = KEY_CHANNELUP,
69 [0x1b] = KEY_VOLUMEUP,
70 [0x1c] = KEY_INFO, /* preview */
71 [0x1d] = KEY_RECORD, /* record */
72 [0x1e] = KEY_CHANNELDOWN,
73 [0x1f] = KEY_VOLUMEDOWN,
74};
75
76/* ---------------------------------------------------------------------- */
77
78/* IO-DATA BCTV7E Remote */
79static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
80 [0x40] = KEY_TV,
81 [0x20] = KEY_RADIO, /* FM */
82 [0x60] = KEY_EPG,
83 [0x00] = KEY_POWER,
84
85 /* Keys 0 to 9 */
86 [0x44] = KEY_KP0, /* 10 */
87 [0x50] = KEY_KP1,
88 [0x30] = KEY_KP2,
89 [0x70] = KEY_KP3,
90 [0x48] = KEY_KP4,
91 [0x28] = KEY_KP5,
92 [0x68] = KEY_KP6,
93 [0x58] = KEY_KP7,
94 [0x38] = KEY_KP8,
95 [0x78] = KEY_KP9,
96
97 [0x10] = KEY_L, /* Live */
98 [0x08] = KEY_T, /* Time Shift */
99
100 [0x18] = KEY_PLAYPAUSE, /* Play */
101
102 [0x24] = KEY_ENTER, /* 11 */
103 [0x64] = KEY_ESC, /* 12 */
104 [0x04] = KEY_M, /* Multi */
105
106 [0x54] = KEY_VIDEO,
107 [0x34] = KEY_CHANNELUP,
108 [0x74] = KEY_VOLUMEUP,
109 [0x14] = KEY_MUTE,
110
111 [0x4c] = KEY_S, /* SVIDEO */
112 [0x2c] = KEY_CHANNELDOWN,
113 [0x6c] = KEY_VOLUMEDOWN,
114 [0x0c] = KEY_ZOOM,
115
116 [0x5c] = KEY_PAUSE,
117 [0x3c] = KEY_C, /* || (red) */
118 [0x7c] = KEY_RECORD, /* recording */
119 [0x1c] = KEY_STOP,
120
121 [0x41] = KEY_REWIND, /* backward << */
122 [0x21] = KEY_PLAY,
123 [0x61] = KEY_FASTFORWARD, /* forward >> */
124 [0x01] = KEY_NEXT, /* skip >| */
125};
126
127/* ---------------------------------------------------------------------- */
128
129/* ADS Tech Instant TV DVB-T PCI Remote */
130static IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = {
131 /* Keys 0 to 9 */
132 [0x4d] = KEY_0,
133 [0x57] = KEY_1,
134 [0x4f] = KEY_2,
135 [0x53] = KEY_3,
136 [0x56] = KEY_4,
137 [0x4e] = KEY_5,
138 [0x5e] = KEY_6,
139 [0x54] = KEY_7,
140 [0x4c] = KEY_8,
141 [0x5c] = KEY_9,
142
143 [0x5b] = KEY_POWER,
144 [0x5f] = KEY_MUTE,
145 [0x55] = KEY_GOTO,
146 [0x5d] = KEY_SEARCH,
147 [0x17] = KEY_EPG, /* Guide */
148 [0x1f] = KEY_MENU,
149 [0x0f] = KEY_UP,
150 [0x46] = KEY_DOWN,
151 [0x16] = KEY_LEFT,
152 [0x1e] = KEY_RIGHT,
153 [0x0e] = KEY_SELECT, /* Enter */
154 [0x5a] = KEY_INFO,
155 [0x52] = KEY_EXIT,
156 [0x59] = KEY_PREVIOUS,
157 [0x51] = KEY_NEXT,
158 [0x58] = KEY_REWIND,
159 [0x50] = KEY_FORWARD,
160 [0x44] = KEY_PLAYPAUSE,
161 [0x07] = KEY_STOP,
162 [0x1b] = KEY_RECORD,
163 [0x13] = KEY_TUNER, /* Live */
164 [0x0a] = KEY_A,
165 [0x12] = KEY_B,
166 [0x03] = KEY_PROG1, /* 1 */
167 [0x01] = KEY_PROG2, /* 2 */
168 [0x00] = KEY_PROG3, /* 3 */
169 [0x06] = KEY_DVD,
170 [0x48] = KEY_AUX, /* Photo */
171 [0x40] = KEY_VIDEO,
172 [0x19] = KEY_AUDIO, /* Music */
173 [0x0b] = KEY_CHANNELUP,
174 [0x08] = KEY_CHANNELDOWN,
175 [0x15] = KEY_VOLUMEUP,
176 [0x1c] = KEY_VOLUMEDOWN,
177};
178
179/* ---------------------------------------------------------------------- */
180
181/* MSI TV@nywhere remote */
182static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
183 /* Keys 0 to 9 */
184 [0x00] = KEY_0,
185 [0x01] = KEY_1,
186 [0x02] = KEY_2,
187 [0x03] = KEY_3,
188 [0x04] = KEY_4,
189 [0x05] = KEY_5,
190 [0x06] = KEY_6,
191 [0x07] = KEY_7,
192 [0x08] = KEY_8,
193 [0x09] = KEY_9,
194
195 [0x0c] = KEY_MUTE,
196 [0x0f] = KEY_SCREEN, /* Full Screen */
197 [0x10] = KEY_F, /* Funtion */
198 [0x11] = KEY_T, /* Time shift */
199 [0x12] = KEY_POWER,
200 [0x13] = KEY_MEDIA, /* MTS */
201 [0x14] = KEY_SLOW,
202 [0x16] = KEY_REWIND, /* backward << */
203 [0x17] = KEY_ENTER, /* Return */
204 [0x18] = KEY_FASTFORWARD, /* forward >> */
205 [0x1a] = KEY_CHANNELUP,
206 [0x1b] = KEY_VOLUMEUP,
207 [0x1e] = KEY_CHANNELDOWN,
208 [0x1f] = KEY_VOLUMEDOWN,
209};
210
211/* ---------------------------------------------------------------------- */
212
213/* Cinergy 1400 DVB-T */
214static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
215 [0x01] = KEY_POWER,
216 [0x02] = KEY_1,
217 [0x03] = KEY_2,
218 [0x04] = KEY_3,
219 [0x05] = KEY_4,
220 [0x06] = KEY_5,
221 [0x07] = KEY_6,
222 [0x08] = KEY_7,
223 [0x09] = KEY_8,
224 [0x0a] = KEY_9,
225 [0x0c] = KEY_0,
226
227 [0x0b] = KEY_VIDEO,
228 [0x0d] = KEY_REFRESH,
229 [0x0e] = KEY_SELECT,
230 [0x0f] = KEY_EPG,
231 [0x10] = KEY_UP,
232 [0x11] = KEY_LEFT,
233 [0x12] = KEY_OK,
234 [0x13] = KEY_RIGHT,
235 [0x14] = KEY_DOWN,
236 [0x15] = KEY_TEXT,
237 [0x16] = KEY_INFO,
238
239 [0x17] = KEY_RED,
240 [0x18] = KEY_GREEN,
241 [0x19] = KEY_YELLOW,
242 [0x1a] = KEY_BLUE,
243
244 [0x1b] = KEY_CHANNELUP,
245 [0x1c] = KEY_VOLUMEUP,
246 [0x1d] = KEY_MUTE,
247 [0x1e] = KEY_VOLUMEDOWN,
248 [0x1f] = KEY_CHANNELDOWN,
249
250 [0x40] = KEY_PAUSE,
251 [0x4c] = KEY_PLAY,
252 [0x58] = KEY_RECORD,
253 [0x54] = KEY_PREVIOUS,
254 [0x48] = KEY_STOP,
255 [0x5c] = KEY_NEXT,
256};
257
258/* ---------------------------------------------------------------------- */
259
260/* AVERTV STUDIO 303 Remote */
261static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = {
262 [ 0x2a ] = KEY_KP1,
263 [ 0x32 ] = KEY_KP2,
264 [ 0x3a ] = KEY_KP3,
265 [ 0x4a ] = KEY_KP4,
266 [ 0x52 ] = KEY_KP5,
267 [ 0x5a ] = KEY_KP6,
268 [ 0x6a ] = KEY_KP7,
269 [ 0x72 ] = KEY_KP8,
270 [ 0x7a ] = KEY_KP9,
271 [ 0x0e ] = KEY_KP0,
272
273 [ 0x02 ] = KEY_POWER,
274 [ 0x22 ] = KEY_VIDEO,
275 [ 0x42 ] = KEY_AUDIO,
276 [ 0x62 ] = KEY_ZOOM,
277 [ 0x0a ] = KEY_TV,
278 [ 0x12 ] = KEY_CD,
279 [ 0x1a ] = KEY_TEXT,
280
281 [ 0x16 ] = KEY_SUBTITLE,
282 [ 0x1e ] = KEY_REWIND,
283 [ 0x06 ] = KEY_PRINT,
284
285 [ 0x2e ] = KEY_SEARCH,
286 [ 0x36 ] = KEY_SLEEP,
287 [ 0x3e ] = KEY_SHUFFLE,
288 [ 0x26 ] = KEY_MUTE,
289
290 [ 0x4e ] = KEY_RECORD,
291 [ 0x56 ] = KEY_PAUSE,
292 [ 0x5e ] = KEY_STOP,
293 [ 0x46 ] = KEY_PLAY,
294
295 [ 0x6e ] = KEY_RED,
296 [ 0x0b ] = KEY_GREEN,
297 [ 0x66 ] = KEY_YELLOW,
298 [ 0x03 ] = KEY_BLUE,
299
300 [ 0x76 ] = KEY_LEFT,
301 [ 0x7e ] = KEY_RIGHT,
302 [ 0x13 ] = KEY_DOWN,
303 [ 0x1b ] = KEY_UP,
304};
305
306/* ---------------------------------------------------------------------- */
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
368struct cx88_IR { 37struct cx88_IR {
369 struct cx88_core *core; 38 struct cx88_core *core;
370 struct input_dev *input; 39 struct input_dev *input;
@@ -517,6 +186,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
517 ir->mask_keydown = 0x02; 186 ir->mask_keydown = 0x02;
518 ir->polling = 5; /* ms */ 187 ir->polling = 5; /* ms */
519 break; 188 break;
189 case CX88_BOARD_PROLINK_PLAYTVPVR:
520 case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: 190 case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
521 ir_codes = ir_codes_pixelview; 191 ir_codes = ir_codes_pixelview;
522 ir->gpio_addr = MO_GP1_IO; 192 ir->gpio_addr = MO_GP1_IO;
@@ -524,6 +194,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
524 ir->mask_keyup = 0x80; 194 ir->mask_keyup = 0x80;
525 ir->polling = 1; /* ms */ 195 ir->polling = 1; /* ms */
526 break; 196 break;
197 case CX88_BOARD_KWORLD_LTV883:
198 ir_codes = ir_codes_pixelview;
199 ir->gpio_addr = MO_GP1_IO;
200 ir->mask_keycode = 0x1f;
201 ir->mask_keyup = 0x60;
202 ir->polling = 1; /* ms */
203 break;
527 case CX88_BOARD_ADSTECH_DVB_T_PCI: 204 case CX88_BOARD_ADSTECH_DVB_T_PCI:
528 ir_codes = ir_codes_adstech_dvb_t_pci; 205 ir_codes = ir_codes_adstech_dvb_t_pci;
529 ir->gpio_addr = MO_GP1_IO; 206 ir->gpio_addr = MO_GP1_IO;
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 073494ceab0f..6c97aa740d27 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -227,7 +227,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
227 .minimum = 0x00, 227 .minimum = 0x00,
228 .maximum = 0xff, 228 .maximum = 0xff,
229 .step = 1, 229 .step = 1,
230 .default_value = 0, 230 .default_value = 0x7f,
231 .type = V4L2_CTRL_TYPE_INTEGER, 231 .type = V4L2_CTRL_TYPE_INTEGER,
232 }, 232 },
233 .off = 128, 233 .off = 128,
@@ -255,7 +255,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
255 .minimum = 0, 255 .minimum = 0,
256 .maximum = 0xff, 256 .maximum = 0xff,
257 .step = 1, 257 .step = 1,
258 .default_value = 0, 258 .default_value = 0x7f,
259 .type = V4L2_CTRL_TYPE_INTEGER, 259 .type = V4L2_CTRL_TYPE_INTEGER,
260 }, 260 },
261 .off = 128, 261 .off = 128,
@@ -300,7 +300,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
300 .minimum = 0, 300 .minimum = 0,
301 .maximum = 0x3f, 301 .maximum = 0x3f,
302 .step = 1, 302 .step = 1,
303 .default_value = 0x1f, 303 .default_value = 0x3f,
304 .type = V4L2_CTRL_TYPE_INTEGER, 304 .type = V4L2_CTRL_TYPE_INTEGER,
305 }, 305 },
306 .reg = AUD_VOL_CTL, 306 .reg = AUD_VOL_CTL,
@@ -336,17 +336,17 @@ static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bi
336 return 1; 336 return 1;
337 337
338 /* is it free? */ 338 /* is it free? */
339 down(&core->lock); 339 mutex_lock(&core->lock);
340 if (dev->resources & bit) { 340 if (dev->resources & bit) {
341 /* no, someone else uses it */ 341 /* no, someone else uses it */
342 up(&core->lock); 342 mutex_unlock(&core->lock);
343 return 0; 343 return 0;
344 } 344 }
345 /* it's free, grab it */ 345 /* it's free, grab it */
346 fh->resources |= bit; 346 fh->resources |= bit;
347 dev->resources |= bit; 347 dev->resources |= bit;
348 dprintk(1,"res: get %d\n",bit); 348 dprintk(1,"res: get %d\n",bit);
349 up(&core->lock); 349 mutex_unlock(&core->lock);
350 return 1; 350 return 1;
351} 351}
352 352
@@ -366,14 +366,13 @@ static
366void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) 366void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
367{ 367{
368 struct cx88_core *core = dev->core; 368 struct cx88_core *core = dev->core;
369 if ((fh->resources & bits) != bits) 369 BUG_ON((fh->resources & bits) != bits);
370 BUG();
371 370
372 down(&core->lock); 371 mutex_lock(&core->lock);
373 fh->resources &= ~bits; 372 fh->resources &= ~bits;
374 dev->resources &= ~bits; 373 dev->resources &= ~bits;
375 dprintk(1,"res: put %d\n",bits); 374 dprintk(1,"res: put %d\n",bits);
376 up(&core->lock); 375 mutex_unlock(&core->lock);
377} 376}
378 377
379/* ------------------------------------------------------------------ */ 378/* ------------------------------------------------------------------ */
@@ -909,7 +908,8 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
909 value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg); 908 value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg);
910 switch (ctl->id) { 909 switch (ctl->id) {
911 case V4L2_CID_AUDIO_BALANCE: 910 case V4L2_CID_AUDIO_BALANCE:
912 ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f)); 911 ctl->value = ((value & 0x7f) < 0x40) ? ((value & 0x7f) + 0x40)
912 : (0x7f - (value & 0x7f));
913 break; 913 break;
914 case V4L2_CID_AUDIO_VOLUME: 914 case V4L2_CID_AUDIO_VOLUME:
915 ctl->value = 0x3f - (value & 0x3f); 915 ctl->value = 0x3f - (value & 0x3f);
@@ -918,9 +918,9 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
918 ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; 918 ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
919 break; 919 break;
920 } 920 }
921 printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", 921 dprintk(1,"get_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
922 ctl->id, c->reg, ctl->value, 922 ctl->id, c->v.name, ctl->value, c->reg,
923 c->mask, c->sreg ? " [shadowed]" : ""); 923 value,c->mask, c->sreg ? " [shadowed]" : "");
924 return 0; 924 return 0;
925} 925}
926 926
@@ -946,7 +946,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
946 mask=c->mask; 946 mask=c->mask;
947 switch (ctl->id) { 947 switch (ctl->id) {
948 case V4L2_CID_AUDIO_BALANCE: 948 case V4L2_CID_AUDIO_BALANCE:
949 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; 949 value = (ctl->value < 0x40) ? (0x7f - ctl->value) : (ctl->value - 0x40);
950 break; 950 break;
951 case V4L2_CID_AUDIO_VOLUME: 951 case V4L2_CID_AUDIO_VOLUME:
952 value = 0x3f - (ctl->value & 0x3f); 952 value = 0x3f - (ctl->value & 0x3f);
@@ -969,9 +969,9 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
969 value = ((ctl->value - c->off) << c->shift) & c->mask; 969 value = ((ctl->value - c->off) << c->shift) & c->mask;
970 break; 970 break;
971 } 971 }
972 printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", 972 dprintk(1,"set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
973 ctl->id, c->reg, value, 973 ctl->id, c->v.name, ctl->value, c->reg, value,
974 mask, c->sreg ? " [shadowed]" : ""); 974 mask, c->sreg ? " [shadowed]" : "");
975 if (c->sreg) { 975 if (c->sreg) {
976 cx_sandor(c->sreg, c->reg, mask, value); 976 cx_sandor(c->sreg, c->reg, mask, value);
977 } else { 977 } else {
@@ -987,8 +987,7 @@ static void init_controls(struct cx88_core *core)
987 987
988 for (i = 0; i < CX8800_CTLS; i++) { 988 for (i = 0; i < CX8800_CTLS; i++) {
989 ctrl.id=cx8800_ctls[i].v.id; 989 ctrl.id=cx8800_ctls[i].v.id;
990 ctrl.value=cx8800_ctls[i].v.default_value 990 ctrl.value=cx8800_ctls[i].v.default_value;
991 +cx8800_ctls[i].off;
992 set_control(core, &ctrl); 991 set_control(core, &ctrl);
993 } 992 }
994} 993}
@@ -1252,7 +1251,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1252{ 1251{
1253 int err; 1252 int err;
1254 1253
1255 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); 1254 dprintk(2, "CORE IOCTL: 0x%x\n", cmd );
1256 if (video_debug > 1) 1255 if (video_debug > 1)
1257 v4l_print_ioctl(core->name,cmd); 1256 v4l_print_ioctl(core->name,cmd);
1258 1257
@@ -1291,9 +1290,9 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1291 if (i == ARRAY_SIZE(tvnorms)) 1290 if (i == ARRAY_SIZE(tvnorms))
1292 return -EINVAL; 1291 return -EINVAL;
1293 1292
1294 down(&core->lock); 1293 mutex_lock(&core->lock);
1295 cx88_set_tvnorm(core,&tvnorms[i]); 1294 cx88_set_tvnorm(core,&tvnorms[i]);
1296 up(&core->lock); 1295 mutex_unlock(&core->lock);
1297 return 0; 1296 return 0;
1298 } 1297 }
1299 1298
@@ -1343,10 +1342,10 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1343 1342
1344 if (*i >= 4) 1343 if (*i >= 4)
1345 return -EINVAL; 1344 return -EINVAL;
1346 down(&core->lock); 1345 mutex_lock(&core->lock);
1347 cx88_newstation(core); 1346 cx88_newstation(core);
1348 video_mux(core,*i); 1347 video_mux(core,*i);
1349 up(&core->lock); 1348 mutex_unlock(&core->lock);
1350 return 0; 1349 return 0;
1351 } 1350 }
1352 1351
@@ -1438,7 +1437,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1438 return -EINVAL; 1437 return -EINVAL;
1439 if (1 == radio && f->type != V4L2_TUNER_RADIO) 1438 if (1 == radio && f->type != V4L2_TUNER_RADIO)
1440 return -EINVAL; 1439 return -EINVAL;
1441 down(&core->lock); 1440 mutex_lock(&core->lock);
1442 core->freq = f->frequency; 1441 core->freq = f->frequency;
1443 cx88_newstation(core); 1442 cx88_newstation(core);
1444 cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); 1443 cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
@@ -1447,7 +1446,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1447 msleep (10); 1446 msleep (10);
1448 cx88_set_tvaudio(core); 1447 cx88_set_tvaudio(core);
1449 1448
1450 up(&core->lock); 1449 mutex_unlock(&core->lock);
1451 return 0; 1450 return 0;
1452 } 1451 }
1453 1452
@@ -1921,11 +1920,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1921 pci_set_drvdata(pci_dev,dev); 1920 pci_set_drvdata(pci_dev,dev);
1922 1921
1923 /* initial device configuration */ 1922 /* initial device configuration */
1924 down(&core->lock); 1923 mutex_lock(&core->lock);
1925 cx88_set_tvnorm(core,tvnorms); 1924 cx88_set_tvnorm(core,tvnorms);
1926 init_controls(core); 1925 init_controls(core);
1927 video_mux(core,0); 1926 video_mux(core,0);
1928 up(&core->lock); 1927 mutex_unlock(&core->lock);
1929 1928
1930 /* start tvaudio thread */ 1929 /* start tvaudio thread */
1931 if (core->tuner_type != TUNER_ABSENT) 1930 if (core->tuner_type != TUNER_ABSENT)
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index e9fd55b57fa6..cfa8668784b4 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -35,6 +35,7 @@
35#include "cx88-reg.h" 35#include "cx88-reg.h"
36 36
37#include <linux/version.h> 37#include <linux/version.h>
38#include <linux/mutex.h>
38#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) 39#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
39 40
40#ifndef TRUE 41#ifndef TRUE
@@ -62,7 +63,7 @@
62/* need "shadow" registers for some write-only ones ... */ 63/* need "shadow" registers for some write-only ones ... */
63#define SHADOW_AUD_VOL_CTL 1 64#define SHADOW_AUD_VOL_CTL 1
64#define SHADOW_AUD_BAL_CTL 2 65#define SHADOW_AUD_BAL_CTL 2
65#define SHADOW_MAX 2 66#define SHADOW_MAX 3
66 67
67/* FM Radio deemphasis type */ 68/* FM Radio deemphasis type */
68enum cx88_deemph_type { 69enum cx88_deemph_type {
@@ -187,6 +188,8 @@ extern struct sram_channel cx88_sram_channels[];
187#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42 188#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42
188#define CX88_BOARD_KWORLD_DVB_T_CX22702 43 189#define CX88_BOARD_KWORLD_DVB_T_CX22702 43
189#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 190#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44
191#define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45
192#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46
190 193
191enum cx88_itype { 194enum cx88_itype {
192 CX88_VMUX_COMPOSITE1 = 1, 195 CX88_VMUX_COMPOSITE1 = 1,
@@ -308,8 +311,7 @@ struct cx88_core {
308 /* IR remote control state */ 311 /* IR remote control state */
309 struct cx88_IR *ir; 312 struct cx88_IR *ir;
310 313
311 struct semaphore lock; 314 struct mutex lock;
312
313 /* various v4l controls */ 315 /* various v4l controls */
314 u32 freq; 316 u32 freq;
315 317