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/Kconfig25
-rw-r--r--drivers/media/video/cx88/Makefile4
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c848
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c18
-rw-r--r--drivers/media/video/cx88/cx88-cards.c227
-rw-r--r--drivers/media/video/cx88/cx88-core.c67
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c215
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c13
-rw-r--r--drivers/media/video/cx88/cx88-input.c142
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c5
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c10
-rw-r--r--drivers/media/video/cx88/cx88-video.c94
-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.h17
15 files changed, 1761 insertions, 132 deletions
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 85ba4106dc79..76fcb4e995c9 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -29,6 +29,21 @@ config VIDEO_CX88_DVB
29 You must also select one or more DVB/ATSC demodulators. 29 You must also select one or more DVB/ATSC demodulators.
30 If you are unsure which you need, choose all of them. 30 If you are unsure which you need, choose all of them.
31 31
32config VIDEO_CX88_ALSA
33 tristate "ALSA DMA audio support"
34 depends on VIDEO_CX88 && SND
35 select SND_PCM_OSS
36 ---help---
37 This is a video4linux driver for direct (DMA) audio on
38 Conexant 2388x based TV cards.
39 It only works with boards with function 01 enabled.
40 To check if your board supports, use lspci -n.
41 If supported, you should see 1471:8801 or 1471:8811
42 PCI device.
43
44 To compile this driver as a module, choose M here: the
45 module will be called cx88-alsa.
46
32config VIDEO_CX88_DVB_ALL_FRONTENDS 47config VIDEO_CX88_DVB_ALL_FRONTENDS
33 bool "Build all supported frontends for cx2388x based TV cards" 48 bool "Build all supported frontends for cx2388x based TV cards"
34 default y 49 default y
@@ -38,6 +53,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
38 select DVB_CX22702 53 select DVB_CX22702
39 select DVB_LGDT330X 54 select DVB_LGDT330X
40 select DVB_NXT200X 55 select DVB_NXT200X
56 select DVB_CX24123
41 ---help--- 57 ---help---
42 This builds cx88-dvb with all currently supported frontend 58 This builds cx88-dvb with all currently supported frontend
43 demodulators. If you wish to tweak your configuration, and 59 demodulators. If you wish to tweak your configuration, and
@@ -89,3 +105,12 @@ config VIDEO_CX88_DVB_NXT200X
89 ---help--- 105 ---help---
90 This adds ATSC 8VSB and QAM64/256 support for cards based on the 106 This adds ATSC 8VSB and QAM64/256 support for cards based on the
91 Connexant 2388x chip and the NXT2002/NXT2004 demodulator. 107 Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
108
109config VIDEO_CX88_DVB_CX24123
110 bool "Conexant CX24123 DVB-S Support"
111 default y
112 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
113 select DVB_CX24123
114 ---help---
115 This adds DVB-S support for cards based on the
116 Connexant 2388x chip and the CX24123 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 54401b02b7ce..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
@@ -16,5 +16,7 @@ extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1
16extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 16extra-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
20extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1
19 21
20EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) 22EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
new file mode 100644
index 000000000000..7695b521eb35
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -0,0 +1,848 @@
1/*
2 *
3 * Support for audio capture
4 * PCI function #1 of the cx2388x.
5 *
6 * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
7 * (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
8 * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
9 * Based on dummy.c by Jaroslav Kysela <perex@suse.cz>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/device.h>
29#include <linux/interrupt.h>
30#include <asm/delay.h>
31#include <sound/driver.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/control.h>
36#include <sound/initval.h>
37
38#include "cx88.h"
39#include "cx88-reg.h"
40
41#define dprintk(level,fmt, arg...) if (debug >= level) \
42 printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg)
43
44#define dprintk_core(level,fmt, arg...) if (debug >= level) \
45 printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg)
46
47
48/****************************************************************************
49 Data type declarations - Can be moded to a header file later
50 ****************************************************************************/
51
52/* These can be replaced after done */
53#define MIXER_ADDR_LAST MAX_CX88_INPUT
54
55struct cx88_audio_dev {
56 struct cx88_core *core;
57 struct cx88_dmaqueue q;
58
59 /* pci i/o */
60 struct pci_dev *pci;
61 unsigned char pci_rev,pci_lat;
62
63 /* audio controls */
64 int irq;
65
66 snd_card_t *card;
67
68 spinlock_t reg_lock;
69
70 unsigned int dma_size;
71 unsigned int period_size;
72 unsigned int num_periods;
73
74 struct videobuf_dmabuf dma_risc;
75
76 int mixer_volume[MIXER_ADDR_LAST+1][2];
77 int capture_source[MIXER_ADDR_LAST+1][2];
78
79 long int read_count;
80 long int read_offset;
81
82 struct cx88_buffer *buf;
83
84 long opened;
85 snd_pcm_substream_t *substream;
86
87};
88typedef struct cx88_audio_dev snd_cx88_card_t;
89
90
91
92/****************************************************************************
93 Module global static vars
94 ****************************************************************************/
95
96static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
97static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
98static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
99static snd_card_t *snd_cx88_cards[SNDRV_CARDS];
100
101module_param_array(enable, bool, NULL, 0444);
102MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
103
104module_param_array(index, int, NULL, 0444);
105MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
106
107
108/****************************************************************************
109 Module macros
110 ****************************************************************************/
111
112MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
113MODULE_AUTHOR("Ricardo Cerqueira");
114MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>");
115MODULE_LICENSE("GPL");
116MODULE_SUPPORTED_DEVICE("{{Conexant,23881},"
117 "{{Conexant,23882},"
118 "{{Conexant,23883}");
119static unsigned int debug = 0;
120module_param(debug,int,0644);
121MODULE_PARM_DESC(debug,"enable debug messages");
122
123/****************************************************************************
124 Module specific funtions
125 ****************************************************************************/
126
127/*
128 * BOARD Specific: Sets audio DMA
129 */
130
131int _cx88_start_audio_dma(snd_cx88_card_t *chip)
132{
133 struct cx88_buffer *buf = chip->buf;
134 struct cx88_core *core=chip->core;
135 struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
136
137
138 dprintk(1, "Starting audio DMA for %i bytes/line and %i (%i) lines at address %08x\n",buf->bpl, chip->num_periods, audio_ch->fifo_size / buf->bpl, audio_ch->fifo_start);
139
140 /* setup fifo + format - out channel */
141 cx88_sram_channel_setup(chip->core, &cx88_sram_channels[SRAM_CH25],
142 buf->bpl, buf->risc.dma);
143
144 /* sets bpl size */
145 cx_write(MO_AUDD_LNGTH, buf->bpl);
146
147 /* reset counter */
148 cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET);
149
150 dprintk(1,"Enabling IRQ, setting mask from 0x%x to 0x%x\n",chip->core->pci_irqmask,(chip->core->pci_irqmask | 0x02));
151 /* enable irqs */
152 cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | 0x02);
153
154
155 /* Enables corresponding bits at AUD_INT_STAT */
156 cx_write(MO_AUD_INTMSK,
157 (1<<16)|
158 (1<<12)|
159 (1<<4)|
160 (1<<0)
161 );
162
163 /* start dma */
164 cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
165 cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */
166
167 if (debug)
168 cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
169
170 return 0;
171}
172
173/*
174 * BOARD Specific: Resets audio DMA
175 */
176int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
177{
178 struct cx88_core *core=chip->core;
179 dprintk(1, "Stopping audio DMA\n");
180
181 /* stop dma */
182 cx_clear(MO_AUD_DMACNTRL, 0x11);
183
184 /* disable irqs */
185 cx_clear(MO_PCI_INTMSK, 0x02);
186 cx_clear(MO_AUD_INTMSK,
187 (1<<16)|
188 (1<<12)|
189 (1<<4)|
190 (1<<0)
191 );
192
193 if (debug)
194 cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
195
196 return 0;
197}
198
199#define MAX_IRQ_LOOP 10
200
201/*
202 * BOARD Specific: IRQ dma bits
203 */
204static char *cx88_aud_irqs[32] = {
205 "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
206 NULL, /* reserved */
207 "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
208 NULL, /* reserved */
209 "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
210 NULL, /* reserved */
211 "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
212 NULL, /* reserved */
213 "opc_err", "par_err", "rip_err", /* 16-18 */
214 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
215};
216
217/*
218 * BOARD Specific: Threats IRQ audio specific calls
219 */
220static void cx8801_aud_irq(snd_cx88_card_t *chip)
221{
222 struct cx88_core *core = chip->core;
223 u32 status, mask;
224 u32 count;
225
226 status = cx_read(MO_AUD_INTSTAT);
227 mask = cx_read(MO_AUD_INTMSK);
228 if (0 == (status & mask)) {
229 spin_unlock(&chip->reg_lock);
230 return;
231 }
232 cx_write(MO_AUD_INTSTAT, status);
233 if (debug > 1 || (status & mask & ~0xff))
234 cx88_print_irqbits(core->name, "irq aud",
235 cx88_aud_irqs, status, mask);
236 /* risc op code error */
237 if (status & (1 << 16)) {
238 printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name);
239 cx_clear(MO_AUD_DMACNTRL, 0x11);
240 cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]);
241 }
242
243 /* risc1 downstream */
244 if (status & 0x01) {
245 spin_lock(&chip->reg_lock);
246 count = cx_read(MO_AUDD_GPCNT);
247 spin_unlock(&chip->reg_lock);
248 if (chip->read_count == 0)
249 chip->read_count += chip->dma_size;
250 }
251
252 if (chip->read_count >= chip->period_size) {
253 dprintk(2, "Elapsing period\n");
254 snd_pcm_period_elapsed(chip->substream);
255 }
256
257 dprintk(3,"Leaving audio IRQ handler...\n");
258
259 /* FIXME: Any other status should deserve a special handling? */
260}
261
262/*
263 * BOARD Specific: Handles IRQ calls
264 */
265static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs)
266{
267 snd_cx88_card_t *chip = dev_id;
268 struct cx88_core *core = chip->core;
269 u32 status;
270 int loop, handled = 0;
271
272 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
273 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02);
274 if (0 == status)
275 goto out;
276 dprintk( 3, "cx8801_irq\n" );
277 dprintk( 3, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
278 dprintk( 3, " status: %d\n", status );
279 handled = 1;
280 cx_write(MO_PCI_INTSTAT, status);
281
282 if (status & 0x02)
283 {
284 dprintk( 2, " ALSA IRQ handling\n" );
285 cx8801_aud_irq(chip);
286 }
287 };
288
289 if (MAX_IRQ_LOOP == loop) {
290 dprintk( 0, "clearing mask\n" );
291 dprintk(1,"%s/0: irq loop -- clearing mask\n",
292 core->name);
293 cx_clear(MO_PCI_INTMSK,0x02);
294 }
295
296 out:
297 return IRQ_RETVAL(handled);
298}
299
300
301static int dsp_buffer_free(snd_cx88_card_t *chip)
302{
303 BUG_ON(!chip->dma_size);
304
305 dprintk(2,"Freeing buffer\n");
306 videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
307 videobuf_dma_free(&chip->dma_risc);
308 btcx_riscmem_free(chip->pci,&chip->buf->risc);
309 kfree(chip->buf);
310
311 chip->dma_size = 0;
312
313 return 0;
314}
315
316/****************************************************************************
317 ALSA PCM Interface
318 ****************************************************************************/
319
320/*
321 * Digital hardware definition
322 */
323static snd_pcm_hardware_t snd_cx88_digital_hw = {
324 .info = SNDRV_PCM_INFO_MMAP |
325 SNDRV_PCM_INFO_INTERLEAVED |
326 SNDRV_PCM_INFO_BLOCK_TRANSFER |
327 SNDRV_PCM_INFO_MMAP_VALID,
328 .formats = SNDRV_PCM_FMTBIT_S16_LE,
329
330 .rates = SNDRV_PCM_RATE_48000,
331 .rate_min = 48000,
332 .rate_max = 48000,
333 .channels_min = 1,
334 .channels_max = 2,
335 .buffer_bytes_max = (2*2048),
336 .period_bytes_min = 256,
337 .period_bytes_max = 2048,
338 .periods_min = 2,
339 .periods_max = 16,
340};
341
342/*
343 * audio pcm capture runtime free
344 */
345static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime)
346{
347}
348/*
349 * audio pcm capture open callback
350 */
351static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
352{
353 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
354 snd_pcm_runtime_t *runtime = substream->runtime;
355 int err;
356
357 if (test_and_set_bit(0, &chip->opened))
358 return -EBUSY;
359
360 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
361 if (err < 0)
362 goto _error;
363
364 chip->substream = substream;
365
366 chip->read_count = 0;
367 chip->read_offset = 0;
368
369 runtime->private_free = snd_card_cx88_runtime_free;
370 runtime->hw = snd_cx88_digital_hw;
371
372 return 0;
373_error:
374 dprintk(1,"Error opening PCM!\n");
375 clear_bit(0, &chip->opened);
376 smp_mb__after_clear_bit();
377 return err;
378}
379
380/*
381 * audio close callback
382 */
383static int snd_cx88_close(snd_pcm_substream_t *substream)
384{
385 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
386
387 clear_bit(0, &chip->opened);
388 smp_mb__after_clear_bit();
389
390 return 0;
391}
392
393/*
394 * hw_params callback
395 */
396static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
397 snd_pcm_hw_params_t * hw_params)
398{
399 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
400 struct cx88_buffer *buf;
401
402 if (substream->runtime->dma_area) {
403 dsp_buffer_free(chip);
404 substream->runtime->dma_area = NULL;
405 }
406
407
408 chip->period_size = params_period_bytes(hw_params);
409 chip->num_periods = params_periods(hw_params);
410 chip->dma_size = chip->period_size * params_periods(hw_params);
411
412 BUG_ON(!chip->dma_size);
413
414 dprintk(1,"Setting buffer\n");
415
416 buf = kmalloc(sizeof(*buf),GFP_KERNEL);
417 if (NULL == buf)
418 return -ENOMEM;
419 memset(buf,0,sizeof(*buf));
420
421
422 buf->vb.memory = V4L2_MEMORY_MMAP;
423 buf->vb.width = chip->period_size;
424 buf->vb.height = chip->num_periods;
425 buf->vb.size = chip->dma_size;
426 buf->vb.field = V4L2_FIELD_NONE;
427
428 videobuf_dma_init(&buf->vb.dma);
429 videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
430 (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
431
432 videobuf_dma_pci_map(chip->pci,&buf->vb.dma);
433
434
435 cx88_risc_databuffer(chip->pci, &buf->risc,
436 buf->vb.dma.sglist,
437 buf->vb.width, buf->vb.height);
438
439 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
440 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
441
442 buf->vb.state = STATE_PREPARED;
443
444 buf->bpl = chip->period_size;
445 chip->buf = buf;
446 chip->dma_risc = buf->vb.dma;
447
448 dprintk(1,"Buffer ready at %u\n",chip->dma_risc.nr_pages);
449 substream->runtime->dma_area = chip->dma_risc.vmalloc;
450 return 0;
451}
452
453/*
454 * hw free callback
455 */
456static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
457{
458
459 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
460
461 if (substream->runtime->dma_area) {
462 dsp_buffer_free(chip);
463 substream->runtime->dma_area = NULL;
464 }
465
466 return 0;
467}
468
469/*
470 * prepare callback
471 */
472static int snd_cx88_prepare(snd_pcm_substream_t *substream)
473{
474 return 0;
475}
476
477
478/*
479 * trigger callback
480 */
481static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
482{
483 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
484 int err;
485
486 spin_lock(&chip->reg_lock);
487
488 switch (cmd) {
489 case SNDRV_PCM_TRIGGER_START:
490 err=_cx88_start_audio_dma(chip);
491 break;
492 case SNDRV_PCM_TRIGGER_STOP:
493 err=_cx88_stop_audio_dma(chip);
494 break;
495 default:
496 err=-EINVAL;
497 break;
498 }
499
500 spin_unlock(&chip->reg_lock);
501
502 return err;
503}
504
505/*
506 * pointer callback
507 */
508static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
509{
510 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
511 snd_pcm_runtime_t *runtime = substream->runtime;
512
513 if (chip->read_count) {
514 chip->read_count -= snd_pcm_lib_period_bytes(substream);
515 chip->read_offset += snd_pcm_lib_period_bytes(substream);
516 if (chip->read_offset == chip->dma_size)
517 chip->read_offset = 0;
518 }
519
520 dprintk(2, "Pointer time, will return %li, read %li\n",chip->read_offset,chip->read_count);
521 return bytes_to_frames(runtime, chip->read_offset);
522
523}
524
525/*
526 * operators
527 */
528static snd_pcm_ops_t snd_cx88_pcm_ops = {
529 .open = snd_cx88_pcm_open,
530 .close = snd_cx88_close,
531 .ioctl = snd_pcm_lib_ioctl,
532 .hw_params = snd_cx88_hw_params,
533 .hw_free = snd_cx88_hw_free,
534 .prepare = snd_cx88_prepare,
535 .trigger = snd_cx88_card_trigger,
536 .pointer = snd_cx88_pointer,
537};
538
539/*
540 * create a PCM device
541 */
542static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
543{
544 int err;
545 snd_pcm_t *pcm;
546
547 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
548 if (err < 0)
549 return err;
550 pcm->private_data = chip;
551 strcpy(pcm->name, name);
552 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);
553
554 return 0;
555}
556
557/****************************************************************************
558 CONTROL INTERFACE
559 ****************************************************************************/
560static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
561{
562 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
563 info->count = 1;
564 info->value.integer.min = 0;
565 info->value.integer.max = 0x3f;
566
567 return 0;
568}
569
570/* OK - TODO: test it */
571static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
572{
573 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
574 struct cx88_core *core=chip->core;
575
576 value->value.integer.value[0] = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
577
578 return 0;
579}
580
581/* OK - TODO: test it */
582static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
583{
584 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
585 struct cx88_core *core=chip->core;
586 int v;
587 u32 old_control;
588
589 spin_lock_irq(&chip->reg_lock);
590 old_control = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
591 v = 0x3f - (value->value.integer.value[0] & 0x3f);
592 cx_andor(AUD_VOL_CTL, 0x3f, v);
593 spin_unlock_irq(&chip->reg_lock);
594
595 return v != old_control;
596}
597
598static snd_kcontrol_new_t snd_cx88_capture_volume = {
599 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
600 .name = "Capture Volume",
601 .info = snd_cx88_capture_volume_info,
602 .get = snd_cx88_capture_volume_get,
603 .put = snd_cx88_capture_volume_put,
604};
605
606
607/****************************************************************************
608 Basic Flow for Sound Devices
609 ****************************************************************************/
610
611/*
612 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
613 * Only boards with eeprom and byte 1 at eeprom=1 have it
614 */
615
616struct pci_device_id cx88_audio_pci_tbl[] = {
617 {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
618 {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
619 {0, }
620};
621MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);
622
623/*
624 * Chip-specific destructor
625 */
626
627static int snd_cx88_free(snd_cx88_card_t *chip)
628{
629
630 if (chip->irq >= 0){
631 synchronize_irq(chip->irq);
632 free_irq(chip->irq, chip);
633 }
634
635 cx88_core_put(chip->core,chip->pci);
636
637 pci_disable_device(chip->pci);
638 return 0;
639}
640
641/*
642 * Component Destructor
643 */
644static void snd_cx88_dev_free(snd_card_t * card)
645{
646 snd_cx88_card_t *chip = card->private_data;
647
648 snd_cx88_free(chip);
649}
650
651
652/*
653 * Alsa Constructor - Component probe
654 */
655
656static int devno=0;
657static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
658 snd_cx88_card_t **rchip)
659{
660 snd_cx88_card_t *chip;
661 struct cx88_core *core;
662 int err;
663
664 *rchip = NULL;
665
666 err = pci_enable_device(pci);
667 if (err < 0)
668 return err;
669
670 pci_set_master(pci);
671
672 chip = (snd_cx88_card_t *) card->private_data;
673
674 core = cx88_core_get(pci);
675
676 if (!pci_dma_supported(pci,0xffffffff)) {
677 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
678 err = -EIO;
679 cx88_core_put(core,pci);
680 return err;
681 }
682
683
684 /* pci init */
685 chip->card = card;
686 chip->pci = pci;
687 chip->irq = -1;
688 spin_lock_init(&chip->reg_lock);
689
690 cx88_reset(core);
691 if (NULL == core) {
692 err = -EINVAL;
693 kfree (chip);
694 return err;
695 }
696 chip->core = core;
697
698 /* get irq */
699 err = request_irq(chip->pci->irq, cx8801_irq,
700 SA_SHIRQ | SA_INTERRUPT, chip->core->name, chip);
701 if (err < 0) {
702 dprintk(0, "%s: can't get IRQ %d\n",
703 chip->core->name, chip->pci->irq);
704 return err;
705 }
706
707 /* print pci info */
708 pci_read_config_byte(pci, PCI_CLASS_REVISION, &chip->pci_rev);
709 pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat);
710
711 dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, "
712 "latency: %d, mmio: 0x%lx\n", core->name, devno,
713 pci_name(pci), chip->pci_rev, pci->irq,
714 chip->pci_lat,pci_resource_start(pci,0));
715
716 chip->irq = pci->irq;
717 synchronize_irq(chip->irq);
718
719 snd_card_set_dev(card, &pci->dev);
720
721 *rchip = chip;
722
723 return 0;
724}
725
726static int __devinit cx88_audio_initdev(struct pci_dev *pci,
727 const struct pci_device_id *pci_id)
728{
729 snd_card_t *card;
730 snd_cx88_card_t *chip;
731 int err;
732
733 if (devno >= SNDRV_CARDS)
734 return (-ENODEV);
735
736 if (!enable[devno]) {
737 ++devno;
738 return (-ENOENT);
739 }
740
741 card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t));
742 if (!card)
743 return (-ENOMEM);
744
745 card->private_free = snd_cx88_dev_free;
746
747 err = snd_cx88_create(card, pci, &chip);
748 if (err < 0)
749 return (err);
750
751 err = snd_cx88_pcm(chip, 0, "CX88 Digital");
752
753 if (err < 0) {
754 snd_card_free(card);
755 return (err);
756 }
757
758 err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));
759 if (err < 0) {
760 snd_card_free(card);
761 return (err);
762 }
763
764 strcpy (card->driver, "CX88x");
765 sprintf(card->shortname, "Conexant CX%x", pci->device);
766 sprintf(card->longname, "%s at %#lx",
767 card->shortname, pci_resource_start(pci, 0));
768 strcpy (card->mixername, "CX88");
769
770 dprintk (0, "%s/%i: ALSA support for cx2388x boards\n",
771 card->driver,devno);
772
773 err = snd_card_register(card);
774 if (err < 0) {
775 snd_card_free(card);
776 return (err);
777 }
778 snd_cx88_cards[devno] = card;
779
780 pci_set_drvdata(pci,card);
781
782 devno++;
783 return 0;
784}
785/*
786 * ALSA destructor
787 */
788static void __devexit cx88_audio_finidev(struct pci_dev *pci)
789{
790 struct cx88_audio_dev *card = pci_get_drvdata(pci);
791
792 snd_card_free((void *)card);
793
794 pci_set_drvdata(pci, NULL);
795
796 devno--;
797}
798
799/*
800 * PCI driver definition
801 */
802
803static struct pci_driver cx88_audio_pci_driver = {
804 .name = "cx88_audio",
805 .id_table = cx88_audio_pci_tbl,
806 .probe = cx88_audio_initdev,
807 .remove = cx88_audio_finidev,
808 SND_PCI_PM_CALLBACKS
809};
810
811/****************************************************************************
812 LINUX MODULE INIT
813 ****************************************************************************/
814
815/*
816 * module init
817 */
818static int cx88_audio_init(void)
819{
820 printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n",
821 (CX88_VERSION_CODE >> 16) & 0xff,
822 (CX88_VERSION_CODE >> 8) & 0xff,
823 CX88_VERSION_CODE & 0xff);
824#ifdef SNAPSHOT
825 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
826 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
827#endif
828 return pci_register_driver(&cx88_audio_pci_driver);
829}
830
831/*
832 * module remove
833 */
834static void cx88_audio_fini(void)
835{
836
837 pci_unregister_driver(&cx88_audio_pci_driver);
838}
839
840module_init(cx88_audio_init);
841module_exit(cx88_audio_fini);
842
843/* ----------------------------------------------------------- */
844/*
845 * Local variables:
846 * c-basic-offset: 8
847 * End:
848 */
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 74e57a53116f..a49062119313 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -32,10 +32,10 @@
32#include <linux/firmware.h> 32#include <linux/firmware.h>
33 33
34#include "cx88.h" 34#include "cx88.h"
35#include <media/v4l2-common.h>
35 36
36MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); 37MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
37MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); 38MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41static unsigned int mpegbufs = 32; 41static unsigned int mpegbufs = 32;
@@ -1375,7 +1375,7 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
1375 struct cx88_core *core = dev->core; 1375 struct cx88_core *core = dev->core;
1376 1376
1377 if (debug > 1) 1377 if (debug > 1)
1378 cx88_print_ioctl(core->name,cmd); 1378 v4l_print_ioctl(core->name,cmd);
1379 1379
1380 switch (cmd) { 1380 switch (cmd) {
1381 1381
@@ -1689,6 +1689,18 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1689 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); 1689 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
1690 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); 1690 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
1691 1691
1692 if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) {
1693
1694 if (core->tuner_formats & V4L2_STD_525_60) {
1695 dev->height = 480;
1696 dev->params.vi_frame_rate = 30;
1697 } else {
1698 dev->height = 576;
1699 dev->params.vi_frame_rate = 25;
1700 }
1701
1702 }
1703
1692 err = cx8802_init_common(dev); 1704 err = cx8802_init_common(dev);
1693 if (0 != err) 1705 if (0 != err)
1694 goto fail_free; 1706 goto fail_free;
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 951709aa88ba..a76d54503b6f 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -611,12 +611,12 @@ struct cx88_board cx88_boards[] = {
611 .input = {{ 611 .input = {{
612 .type = CX88_VMUX_TELEVISION, 612 .type = CX88_VMUX_TELEVISION,
613 .vmux = 0, 613 .vmux = 0,
614 .gpio0 = 0xed12, /* internal decoder */ 614 .gpio0 = 0xed1a,
615 .gpio2 = 0x00ff, 615 .gpio2 = 0x00ff,
616 },{ 616 },{
617 .type = CX88_VMUX_DEBUG, 617 .type = CX88_VMUX_DEBUG,
618 .vmux = 0, 618 .vmux = 0,
619 .gpio0 = 0xff01, /* mono from tuner chip */ 619 .gpio0 = 0xff01,
620 },{ 620 },{
621 .type = CX88_VMUX_COMPOSITE1, 621 .type = CX88_VMUX_COMPOSITE1,
622 .vmux = 1, 622 .vmux = 1,
@@ -708,7 +708,7 @@ struct cx88_board cx88_boards[] = {
708 }, 708 },
709 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { 709 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
710 .name = "DViCO FusionHDTV 3 Gold-T", 710 .name = "DViCO FusionHDTV 3 Gold-T",
711 .tuner_type = TUNER_THOMSON_DTT7611, 711 .tuner_type = TUNER_THOMSON_DTT761X,
712 .radio_type = UNSET, 712 .radio_type = UNSET,
713 .tuner_addr = ADDR_UNSET, 713 .tuner_addr = ADDR_UNSET,
714 .radio_addr = ADDR_UNSET, 714 .radio_addr = ADDR_UNSET,
@@ -897,6 +897,158 @@ struct cx88_board cx88_boards[] = {
897 .gpio3 = 0x0000, 897 .gpio3 = 0x0000,
898 }}, 898 }},
899 }, 899 },
900 [CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1] = {
901 .name = "Hauppauge Nova-S-Plus DVB-S",
902 .tuner_type = TUNER_ABSENT,
903 .radio_type = UNSET,
904 .tuner_addr = ADDR_UNSET,
905 .radio_addr = ADDR_UNSET,
906 .input = {{
907 .type = CX88_VMUX_DVB,
908 .vmux = 0,
909 },{
910 .type = CX88_VMUX_COMPOSITE1,
911 .vmux = 1,
912 },{
913 .type = CX88_VMUX_SVIDEO,
914 .vmux = 2,
915 }},
916 .dvb = 1,
917 },
918 [CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = {
919 .name = "Hauppauge Nova-SE2 DVB-S",
920 .tuner_type = TUNER_ABSENT,
921 .radio_type = UNSET,
922 .tuner_addr = ADDR_UNSET,
923 .radio_addr = ADDR_UNSET,
924 .input = {{
925 .type = CX88_VMUX_DVB,
926 .vmux = 0,
927 }},
928 .dvb = 1,
929 },
930 [CX88_BOARD_KWORLD_DVBS_100] = {
931 .name = "KWorld DVB-S 100",
932 .tuner_type = TUNER_ABSENT,
933 .radio_type = UNSET,
934 .tuner_addr = ADDR_UNSET,
935 .radio_addr = ADDR_UNSET,
936 .input = {{
937 .type = CX88_VMUX_DVB,
938 .vmux = 0,
939 },{
940 .type = CX88_VMUX_COMPOSITE1,
941 .vmux = 1,
942 },{
943 .type = CX88_VMUX_SVIDEO,
944 .vmux = 2,
945 }},
946 .dvb = 1,
947 },
948 [CX88_BOARD_HAUPPAUGE_HVR1100] = {
949 .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid",
950 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
951 .radio_type = UNSET,
952 .tuner_addr = ADDR_UNSET,
953 .radio_addr = ADDR_UNSET,
954 .tda9887_conf = TDA9887_PRESENT,
955 .input = {{
956 .type = CX88_VMUX_TELEVISION,
957 .vmux = 0,
958 },{
959 .type = CX88_VMUX_COMPOSITE1,
960 .vmux = 1,
961 },{
962 .type = CX88_VMUX_SVIDEO,
963 .vmux = 2,
964 }},
965 /* fixme: Add radio support */
966 .dvb = 1,
967 },
968 [CX88_BOARD_HAUPPAUGE_HVR1100LP] = {
969 .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)",
970 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
971 .radio_type = UNSET,
972 .tuner_addr = ADDR_UNSET,
973 .radio_addr = ADDR_UNSET,
974 .tda9887_conf = TDA9887_PRESENT,
975 .input = {{
976 .type = CX88_VMUX_TELEVISION,
977 .vmux = 0,
978 },{
979 .type = CX88_VMUX_COMPOSITE1,
980 .vmux = 1,
981 }},
982 /* fixme: Add radio support */
983 .dvb = 1,
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 },
1012 [CX88_BOARD_KWORLD_DVB_T_CX22702] = {
1013 /* Kworld V-stream Xpert DVB-T with Thomson tuner */
1014 /* DTT 7579 Conexant CX22702-19 Conexant CX2388x */
1015 /* Manenti Marco <marco_manenti@colman.it> */
1016 .name = "KWorld/VStream XPert DVB-T with cx22702",
1017 .tuner_type = TUNER_ABSENT,
1018 .radio_type = UNSET,
1019 .tuner_addr = ADDR_UNSET,
1020 .radio_addr = ADDR_UNSET,
1021 .input = {{
1022 .type = CX88_VMUX_COMPOSITE1,
1023 .vmux = 1,
1024 .gpio0 = 0x0700,
1025 .gpio2 = 0x0101,
1026 },{
1027 .type = CX88_VMUX_SVIDEO,
1028 .vmux = 2,
1029 .gpio0 = 0x0700,
1030 .gpio2 = 0x0101,
1031 }},
1032 .dvb = 1,
1033 },
1034 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = {
1035 .name = "DViCO FusionHDTV DVB-T Dual Digital",
1036 .tuner_type = TUNER_ABSENT, /* No analog tuner */
1037 .radio_type = UNSET,
1038 .tuner_addr = ADDR_UNSET,
1039 .radio_addr = ADDR_UNSET,
1040 .input = {{
1041 .type = CX88_VMUX_COMPOSITE1,
1042 .vmux = 1,
1043 .gpio0 = 0x000027df,
1044 },{
1045 .type = CX88_VMUX_SVIDEO,
1046 .vmux = 2,
1047 .gpio0 = 0x000027df,
1048 }},
1049 .dvb = 1,
1050 },
1051
900}; 1052};
901const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 1053const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
902 1054
@@ -1044,6 +1196,54 @@ struct cx88_subid cx88_subids[] = {
1044 .subvendor = 0x1461, 1196 .subvendor = 0x1461,
1045 .subdevice = 0x000a, 1197 .subdevice = 0x000a,
1046 .card = CX88_BOARD_AVERTV_303, 1198 .card = CX88_BOARD_AVERTV_303,
1199 },{
1200 .subvendor = 0x0070,
1201 .subdevice = 0x9200,
1202 .card = CX88_BOARD_HAUPPAUGE_NOVASE2_S1,
1203 },{
1204 .subvendor = 0x0070,
1205 .subdevice = 0x9201,
1206 .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
1207 },{
1208 .subvendor = 0x0070,
1209 .subdevice = 0x9202,
1210 .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
1211 },{
1212 .subvendor = 0x17de,
1213 .subdevice = 0x08b2,
1214 .card = CX88_BOARD_KWORLD_DVBS_100,
1215 },{
1216 .subvendor = 0x0070,
1217 .subdevice = 0x9400,
1218 .card = CX88_BOARD_HAUPPAUGE_HVR1100,
1219 },{
1220 .subvendor = 0x0070,
1221 .subdevice = 0x9402,
1222 .card = CX88_BOARD_HAUPPAUGE_HVR1100,
1223 },{
1224 .subvendor = 0x0070,
1225 .subdevice = 0x9800,
1226 .card = CX88_BOARD_HAUPPAUGE_HVR1100LP,
1227 },{
1228 .subvendor = 0x0070,
1229 .subdevice = 0x9802,
1230 .card = CX88_BOARD_HAUPPAUGE_HVR1100LP,
1231 },{
1232 .subvendor = 0x0070,
1233 .subdevice = 0x9001,
1234 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
1235 },{
1236 .subvendor = 0x1822,
1237 .subdevice = 0x0025,
1238 .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
1239 },{
1240 .subvendor = 0x17de,
1241 .subdevice = 0x08a1,
1242 .card = CX88_BOARD_KWORLD_DVB_T_CX22702,
1243 },{
1244 .subvendor = 0x18ac,
1245 .subdevice = 0xdb50,
1246 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
1047 }, 1247 },
1048}; 1248};
1049const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1249const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1075,20 +1275,19 @@ static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
1075 core->name, core->tuner_type, eeprom_data[0]); 1275 core->name, core->tuner_type, eeprom_data[0]);
1076} 1276}
1077 1277
1078
1079/* ----------------------------------------------------------------------- */
1080
1081static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) 1278static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
1082{ 1279{
1083 struct tveeprom tv; 1280 struct tveeprom tv;
1084 1281
1085 tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data); 1282 tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
1086 core->tuner_type = tv.tuner_type; 1283 core->tuner_type = tv.tuner_type;
1284 core->tuner_formats = tv.tuner_formats;
1087 core->has_radio = tv.has_radio; 1285 core->has_radio = tv.has_radio;
1088 1286
1089 /* Make sure we support the board model */ 1287 /* Make sure we support the board model */
1090 switch (tv.model) 1288 switch (tv.model)
1091 { 1289 {
1290 case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
1092 case 90002: /* Nova-T-PCI (9002) */ 1291 case 90002: /* Nova-T-PCI (9002) */
1093 case 92001: /* Nova-S-Plus (Video and IR) */ 1292 case 92001: /* Nova-S-Plus (Video and IR) */
1094 case 92002: /* Nova-S-Plus (Video and IR) */ 1293 case 92002: /* Nova-S-Plus (Video and IR) */
@@ -1096,7 +1295,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
1096 case 90500: /* Nova-T-PCI (oem) */ 1295 case 90500: /* Nova-T-PCI (oem) */
1097 case 90501: /* Nova-T-PCI (oem/IR) */ 1296 case 90501: /* Nova-T-PCI (oem/IR) */
1098 case 92000: /* Nova-SE2 (OEM, No Video or IR) */ 1297 case 92000: /* Nova-SE2 (OEM, No Video or IR) */
1099 1298 case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
1299 case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
1300 case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
1100 /* known */ 1301 /* known */
1101 break; 1302 break;
1102 default: 1303 default:
@@ -1211,12 +1412,21 @@ void cx88_card_setup(struct cx88_core *core)
1211 if (0 == core->i2c_rc) 1412 if (0 == core->i2c_rc)
1212 leadtek_eeprom(core,eeprom); 1413 leadtek_eeprom(core,eeprom);
1213 break; 1414 break;
1415 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1416 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1214 case CX88_BOARD_HAUPPAUGE_DVB_T1: 1417 case CX88_BOARD_HAUPPAUGE_DVB_T1:
1418 case CX88_BOARD_HAUPPAUGE_HVR1100:
1419 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
1215 if (0 == core->i2c_rc) 1420 if (0 == core->i2c_rc)
1216 hauppauge_eeprom(core,eeprom); 1421 hauppauge_eeprom(core,eeprom);
1217 break; 1422 break;
1423 case CX88_BOARD_KWORLD_DVBS_100:
1424 cx_write(MO_GP0_IO, 0x000007f8);
1425 cx_write(MO_GP1_IO, 0x00000001);
1426 break;
1218 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 1427 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1219 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 1428 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
1429 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1220 /* GPIO0:0 is hooked to mt352 reset pin */ 1430 /* GPIO0:0 is hooked to mt352 reset pin */
1221 cx_set(MO_GP0_IO, 0x00000101); 1431 cx_set(MO_GP0_IO, 0x00000101);
1222 cx_clear(MO_GP0_IO, 0x00000001); 1432 cx_clear(MO_GP0_IO, 0x00000001);
@@ -1232,6 +1442,9 @@ void cx88_card_setup(struct cx88_core *core)
1232 cx_clear(MO_GP0_IO, 0x00000007); 1442 cx_clear(MO_GP0_IO, 0x00000007);
1233 cx_set(MO_GP2_IO, 0x00000101); 1443 cx_set(MO_GP2_IO, 0x00000101);
1234 break; 1444 break;
1445 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1446 cx_write(MO_GP0_IO, 0x00080808);
1447 break;
1235 case CX88_BOARD_ATI_HDTVWONDER: 1448 case CX88_BOARD_ATI_HDTVWONDER:
1236 if (0 == core->i2c_rc) { 1449 if (0 == core->i2c_rc) {
1237 /* enable tuner */ 1450 /* enable tuner */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index bb6eb54e19ce..9975be1aca38 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -34,6 +34,7 @@
34#include <linux/videodev2.h> 34#include <linux/videodev2.h>
35 35
36#include "cx88.h" 36#include "cx88.h"
37#include <media/v4l2-common.h>
37 38
38MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); 39MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -76,60 +77,6 @@ static unsigned int cx88_devcount;
76static LIST_HEAD(cx88_devlist); 77static LIST_HEAD(cx88_devlist);
77static DECLARE_MUTEX(devlist); 78static DECLARE_MUTEX(devlist);
78 79
79/* ------------------------------------------------------------------ */
80/* debug help functions */
81
82static const char *v4l1_ioctls[] = {
83 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
84 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
85 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
86 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
87 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
88#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
89
90static const char *v4l2_ioctls[] = {
91 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
92 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
93 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
94 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
95 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
96 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
97 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
98 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
99 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
100 "S_MODULATOR"
101};
102#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
103
104void cx88_print_ioctl(char *name, unsigned int cmd)
105{
106 char *dir;
107
108 switch (_IOC_DIR(cmd)) {
109 case _IOC_NONE: dir = "--"; break;
110 case _IOC_READ: dir = "r-"; break;
111 case _IOC_WRITE: dir = "-w"; break;
112 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
113 default: dir = "??"; break;
114 }
115 switch (_IOC_TYPE(cmd)) {
116 case 'v':
117 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
118 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
119 v4l1_ioctls[_IOC_NR(cmd)] : "???");
120 break;
121 case 'V':
122 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
123 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
124 v4l2_ioctls[_IOC_NR(cmd)] : "???");
125 break;
126 default:
127 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
128 name, cmd, dir, _IOC_NR(cmd));
129 }
130}
131
132/* ------------------------------------------------------------------ */
133#define NO_SYNC_LINE (-1U) 80#define NO_SYNC_LINE (-1U)
134 81
135static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, 82static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
@@ -291,9 +238,9 @@ cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
291 * channel 22 (u video) - 2.0k 238 * channel 22 (u video) - 2.0k
292 * channel 23 (v video) - 2.0k 239 * channel 23 (v video) - 2.0k
293 * channel 24 (vbi) - 4.0k 240 * channel 24 (vbi) - 4.0k
294 * channels 25+26 (audio) - 0.5k 241 * channels 25+26 (audio) - 4.0k
295 * channel 28 (mpeg) - 4.0k 242 * channel 28 (mpeg) - 4.0k
296 * TOTAL = 25.5k 243 * TOTAL = 29.0k
297 * 244 *
298 * Every channel has 160 bytes control data (64 bytes instruction 245 * Every channel has 160 bytes control data (64 bytes instruction
299 * queue and 6 CDT entries), which is close to 2k total. 246 * queue and 6 CDT entries), which is close to 2k total.
@@ -359,7 +306,7 @@ struct sram_channel cx88_sram_channels[] = {
359 .ctrl_start = 0x180680, 306 .ctrl_start = 0x180680,
360 .cdt = 0x180680 + 64, 307 .cdt = 0x180680 + 64,
361 .fifo_start = 0x185400, 308 .fifo_start = 0x185400,
362 .fifo_size = 0x000200, 309 .fifo_size = 0x001000,
363 .ptr1_reg = MO_DMA25_PTR1, 310 .ptr1_reg = MO_DMA25_PTR1,
364 .ptr2_reg = MO_DMA25_PTR2, 311 .ptr2_reg = MO_DMA25_PTR2,
365 .cnt1_reg = MO_DMA25_CNT1, 312 .cnt1_reg = MO_DMA25_CNT1,
@@ -371,7 +318,7 @@ struct sram_channel cx88_sram_channels[] = {
371 .ctrl_start = 0x180720, 318 .ctrl_start = 0x180720,
372 .cdt = 0x180680 + 64, /* same as audio IN */ 319 .cdt = 0x180680 + 64, /* same as audio IN */
373 .fifo_start = 0x185400, /* same as audio IN */ 320 .fifo_start = 0x185400, /* same as audio IN */
374 .fifo_size = 0x000200, /* same as audio IN */ 321 .fifo_size = 0x001000, /* same as audio IN */
375 .ptr1_reg = MO_DMA26_PTR1, 322 .ptr1_reg = MO_DMA26_PTR1,
376 .ptr2_reg = MO_DMA26_PTR2, 323 .ptr2_reg = MO_DMA26_PTR2,
377 .cnt1_reg = MO_DMA26_CNT1, 324 .cnt1_reg = MO_DMA26_CNT1,
@@ -382,7 +329,7 @@ struct sram_channel cx88_sram_channels[] = {
382 .cmds_start = 0x180200, 329 .cmds_start = 0x180200,
383 .ctrl_start = 0x1807C0, 330 .ctrl_start = 0x1807C0,
384 .cdt = 0x1807C0 + 64, 331 .cdt = 0x1807C0 + 64,
385 .fifo_start = 0x185600, 332 .fifo_start = 0x186400,
386 .fifo_size = 0x001000, 333 .fifo_size = 0x001000,
387 .ptr1_reg = MO_DMA28_PTR1, 334 .ptr1_reg = MO_DMA28_PTR1,
388 .ptr2_reg = MO_DMA28_PTR2, 335 .ptr2_reg = MO_DMA28_PTR2,
@@ -848,7 +795,6 @@ int cx88_start_audio_dma(struct cx88_core *core)
848 795
849 /* start dma */ 796 /* start dma */
850 cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ 797 cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
851
852 return 0; 798 return 0;
853} 799}
854 800
@@ -1208,7 +1154,6 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1208 1154
1209/* ------------------------------------------------------------------ */ 1155/* ------------------------------------------------------------------ */
1210 1156
1211EXPORT_SYMBOL(cx88_print_ioctl);
1212EXPORT_SYMBOL(cx88_print_irqbits); 1157EXPORT_SYMBOL(cx88_print_irqbits);
1213 1158
1214EXPORT_SYMBOL(cx88_core_irq); 1159EXPORT_SYMBOL(cx88_core_irq);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 99ea955f5987..42c012aaa849 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
@@ -31,10 +31,14 @@
31 31
32#include "cx88.h" 32#include "cx88.h"
33#include "dvb-pll.h" 33#include "dvb-pll.h"
34#include <media/v4l2-common.h>
34 35
35#ifdef HAVE_MT352 36#ifdef HAVE_MT352
36# include "mt352.h" 37# include "mt352.h"
37# include "mt352_priv.h" 38# include "mt352_priv.h"
39# ifdef HAVE_VP3054_I2C
40# include "cx88-vp3054-i2c.h"
41# endif
38#endif 42#endif
39#ifdef HAVE_CX22702 43#ifdef HAVE_CX22702
40# include "cx22702.h" 44# include "cx22702.h"
@@ -48,6 +52,9 @@
48#ifdef HAVE_NXT200X 52#ifdef HAVE_NXT200X
49# include "nxt200x.h" 53# include "nxt200x.h"
50#endif 54#endif
55#ifdef HAVE_CX24123
56# include "cx24123.h"
57#endif
51 58
52MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 59MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 60MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -125,6 +132,27 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
125 return 0; 132 return 0;
126} 133}
127 134
135static int dvico_dual_demod_init(struct dvb_frontend *fe)
136{
137 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
138 static u8 reset [] = { RESET, 0x80 };
139 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
140 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
141 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
142 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
143
144 mt352_write(fe, clock_config, sizeof(clock_config));
145 udelay(200);
146 mt352_write(fe, reset, sizeof(reset));
147 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
148
149 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
150 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
151 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
152
153 return 0;
154}
155
128static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) 156static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
129{ 157{
130 static u8 clock_config [] = { 0x89, 0x38, 0x39 }; 158 static u8 clock_config [] = { 0x89, 0x38, 0x39 };
@@ -172,6 +200,98 @@ static struct mt352_config dntv_live_dvbt_config = {
172 .demod_init = dntv_live_dvbt_demod_init, 200 .demod_init = dntv_live_dvbt_demod_init,
173 .pll_set = mt352_pll_set, 201 .pll_set = mt352_pll_set,
174}; 202};
203
204static struct mt352_config dvico_fusionhdtv_dual = {
205 .demod_address = 0x0F,
206 .demod_init = dvico_dual_demod_init,
207 .pll_set = mt352_pll_set,
208};
209
210#ifdef HAVE_VP3054_I2C
211static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
212{
213 static u8 clock_config [] = { 0x89, 0x38, 0x38 };
214 static u8 reset [] = { 0x50, 0x80 };
215 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
216 static u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
217 0x00, 0xFF, 0x00, 0x40, 0x40 };
218 static u8 dntv_extra[] = { 0xB5, 0x7A };
219 static u8 capt_range_cfg[] = { 0x75, 0x32 };
220
221 mt352_write(fe, clock_config, sizeof(clock_config));
222 udelay(2000);
223 mt352_write(fe, reset, sizeof(reset));
224 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
225
226 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
227 udelay(2000);
228 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
229 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
230
231 return 0;
232}
233
234static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
235{
236 struct cx8802_dev *dev= fe->dvb->priv;
237
238 /* this message is to set up ATC and ALC */
239 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
240 struct i2c_msg msg =
241 { .addr = dev->core->pll_addr, .flags = 0,
242 .buf = fmd1216_init, .len = sizeof(fmd1216_init) };
243 int err;
244
245 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
246 if (err < 0)
247 return err;
248 else
249 return -EREMOTEIO;
250 }
251
252 return 0;
253}
254
255static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe,
256 struct dvb_frontend_parameters* params,
257 u8* pllbuf)
258{
259 struct cx8802_dev *dev= fe->dvb->priv;
260 struct i2c_msg msg =
261 { .addr = dev->core->pll_addr, .flags = 0,
262 .buf = pllbuf+1, .len = 4 };
263 int err;
264
265 /* Switch PLL to DVB mode */
266 err = philips_fmd1216_pll_init(fe);
267 if (err)
268 return err;
269
270 /* Tune PLL */
271 pllbuf[0] = dev->core->pll_addr << 1;
272 dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
273 params->frequency,
274 params->u.ofdm.bandwidth);
275 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
276 printk(KERN_WARNING "cx88-dvb: %s error "
277 "(addr %02x <- %02x, err = %i)\n",
278 __FUNCTION__, pllbuf[0], pllbuf[1], err);
279 if (err < 0)
280 return err;
281 else
282 return -EREMOTEIO;
283 }
284
285 return 0;
286}
287
288static struct mt352_config dntv_live_dvbt_pro_config = {
289 .demod_address = 0x0f,
290 .no_tuner = 1,
291 .demod_init = dntv_live_dvbt_pro_demod_init,
292 .pll_set = dntv_live_dvbt_pro_pll_set,
293};
294#endif
175#endif 295#endif
176 296
177#ifdef HAVE_CX22702 297#ifdef HAVE_CX22702
@@ -188,6 +308,12 @@ static struct cx22702_config hauppauge_novat_config = {
188 .pll_address = 0x61, 308 .pll_address = 0x61,
189 .pll_desc = &dvb_pll_thomson_dtt759x, 309 .pll_desc = &dvb_pll_thomson_dtt759x,
190}; 310};
311static struct cx22702_config hauppauge_hvr1100_config = {
312 .demod_address = 0x63,
313 .output_mode = CX22702_SERIAL_OUTPUT,
314 .pll_address = 0x61,
315 .pll_desc = &dvb_pll_fmd1216me,
316};
191#endif 317#endif
192 318
193#ifdef HAVE_OR51132 319#ifdef HAVE_OR51132
@@ -314,6 +440,40 @@ static struct nxt200x_config ati_hdtvwonder = {
314}; 440};
315#endif 441#endif
316 442
443#ifdef HAVE_CX24123
444static int cx24123_set_ts_param(struct dvb_frontend* fe,
445 int is_punctured)
446{
447 struct cx8802_dev *dev= fe->dvb->priv;
448 dev->ts_gen_cntrl = 0x2;
449 return 0;
450}
451
452static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on)
453{
454 struct cx8802_dev *dev= fe->dvb->priv;
455 struct cx88_core *core = dev->core;
456
457 if (on)
458 cx_write(MO_GP0_IO, 0x000006f9);
459 else
460 cx_write(MO_GP0_IO, 0x000006fB);
461}
462
463static struct cx24123_config hauppauge_novas_config = {
464 .demod_address = 0x55,
465 .use_isl6421 = 1,
466 .set_ts_params = cx24123_set_ts_param,
467};
468
469static struct cx24123_config kworld_dvbs_100_config = {
470 .demod_address = 0x15,
471 .use_isl6421 = 0,
472 .set_ts_params = cx24123_set_ts_param,
473 .enable_lnb_voltage = cx24123_enable_lnb_voltage,
474};
475#endif
476
317static int dvb_register(struct cx8802_dev *dev) 477static int dvb_register(struct cx8802_dev *dev)
318{ 478{
319 /* init struct videobuf_dvb */ 479 /* init struct videobuf_dvb */
@@ -329,10 +489,16 @@ static int dvb_register(struct cx8802_dev *dev)
329 break; 489 break;
330 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 490 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
331 case CX88_BOARD_CONEXANT_DVB_T1: 491 case CX88_BOARD_CONEXANT_DVB_T1:
492 case CX88_BOARD_KWORLD_DVB_T_CX22702:
332 case CX88_BOARD_WINFAST_DTV1000: 493 case CX88_BOARD_WINFAST_DTV1000:
333 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, 494 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
334 &dev->core->i2c_adap); 495 &dev->core->i2c_adap);
335 break; 496 break;
497 case CX88_BOARD_HAUPPAUGE_HVR1100:
498 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
499 dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config,
500 &dev->core->i2c_adap);
501 break;
336#endif 502#endif
337#ifdef HAVE_MT352 503#ifdef HAVE_MT352
338 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 504 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
@@ -355,6 +521,24 @@ static int dvb_register(struct cx8802_dev *dev)
355 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, 521 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
356 &dev->core->i2c_adap); 522 &dev->core->i2c_adap);
357 break; 523 break;
524 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
525#ifdef HAVE_VP3054_I2C
526 dev->core->pll_addr = 0x61;
527 dev->core->pll_desc = &dvb_pll_fmd1216me;
528 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config,
529 &((struct vp3054_i2c_state *)dev->card_priv)->adap);
530#else
531 printk("%s: built without vp3054 support\n", dev->core->name);
532#endif
533 break;
534 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
535 /* The tin box says DEE1601, but it seems to be DTT7579
536 * compatible, with a slightly different MT352 AGC gain. */
537 dev->core->pll_addr = 0x61;
538 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
539 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual,
540 &dev->core->i2c_adap);
541 break;
358#endif 542#endif
359#ifdef HAVE_OR51132 543#ifdef HAVE_OR51132
360 case CX88_BOARD_PCHDTV_HD3000: 544 case CX88_BOARD_PCHDTV_HD3000:
@@ -393,7 +577,7 @@ static int dvb_register(struct cx8802_dev *dev)
393 cx_set(MO_GP0_IO, 9); 577 cx_set(MO_GP0_IO, 9);
394 mdelay(200); 578 mdelay(200);
395 dev->core->pll_addr = 0x61; 579 dev->core->pll_addr = 0x61;
396 dev->core->pll_desc = &dvb_pll_thomson_dtt7611; 580 dev->core->pll_desc = &dvb_pll_thomson_dtt761x;
397 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, 581 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
398 &dev->core->i2c_adap); 582 &dev->core->i2c_adap);
399 } 583 }
@@ -421,6 +605,17 @@ static int dvb_register(struct cx8802_dev *dev)
421 &dev->core->i2c_adap); 605 &dev->core->i2c_adap);
422 break; 606 break;
423#endif 607#endif
608#ifdef HAVE_CX24123
609 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
610 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
611 dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
612 &dev->core->i2c_adap);
613 break;
614 case CX88_BOARD_KWORLD_DVBS_100:
615 dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
616 &dev->core->i2c_adap);
617 break;
618#endif
424 default: 619 default:
425 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 620 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
426 dev->core->name); 621 dev->core->name);
@@ -473,6 +668,12 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
473 if (0 != err) 668 if (0 != err)
474 goto fail_free; 669 goto fail_free;
475 670
671#ifdef HAVE_VP3054_I2C
672 err = vp3054_i2c_probe(dev);
673 if (0 != err)
674 goto fail_free;
675#endif
676
476 /* dvb stuff */ 677 /* dvb stuff */
477 printk("%s/2: cx2388x based dvb card\n", core->name); 678 printk("%s/2: cx2388x based dvb card\n", core->name);
478 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, 679 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
@@ -484,6 +685,9 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
484 err = dvb_register(dev); 685 err = dvb_register(dev);
485 if (0 != err) 686 if (0 != err)
486 goto fail_fini; 687 goto fail_fini;
688
689 /* Maintain a reference to cx88-video can query the 8802 device. */
690 core->dvbdev = dev;
487 return 0; 691 return 0;
488 692
489 fail_fini: 693 fail_fini:
@@ -499,9 +703,16 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev)
499{ 703{
500 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 704 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
501 705
706 /* Destroy any 8802 reference. */
707 dev->core->dvbdev = NULL;
708
502 /* dvb */ 709 /* dvb */
503 videobuf_dvb_unregister(&dev->dvb); 710 videobuf_dvb_unregister(&dev->dvb);
504 711
712#ifdef HAVE_VP3054_I2C
713 vp3054_i2c_remove(dev);
714#endif
715
505 /* common */ 716 /* common */
506 cx8802_fini_common(dev); 717 cx8802_fini_common(dev);
507 cx88_core_put(dev->core,dev->pci); 718 cx88_core_put(dev->core,dev->pci);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 4a8fb161b16a..f720901e9638 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -30,6 +30,7 @@
30#include <asm/io.h> 30#include <asm/io.h>
31 31
32#include "cx88.h" 32#include "cx88.h"
33#include <media/v4l2-common.h>
33 34
34static unsigned int i2c_debug = 0; 35static unsigned int i2c_debug = 0;
35module_param(i2c_debug, int, 0644); 36module_param(i2c_debug, int, 0644);
@@ -135,7 +136,17 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
135{ 136{
136 if (0 != core->i2c_rc) 137 if (0 != core->i2c_rc)
137 return; 138 return;
138 i2c_clients_command(&core->i2c_adap, cmd, arg); 139
140 if (core->dvbdev) {
141 if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl)
142 core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
143
144 i2c_clients_command(&core->i2c_adap, cmd, arg);
145
146 if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl)
147 core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
148 } else
149 i2c_clients_command(&core->i2c_adap, cmd, arg);
139} 150}
140 151
141static struct i2c_algo_bit_data cx8800_i2c_algo_template = { 152static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 461019dca901..286c85b6bdf9 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
@@ -29,9 +29,8 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
31 31
32#include <media/ir-common.h>
33
34#include "cx88.h" 32#include "cx88.h"
33#include <media/ir-common.h>
35 34
36/* ---------------------------------------------------------------------- */ 35/* ---------------------------------------------------------------------- */
37 36
@@ -258,6 +257,114 @@ static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
258 257
259/* ---------------------------------------------------------------------- */ 258/* ---------------------------------------------------------------------- */
260 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
261struct cx88_IR { 368struct cx88_IR {
262 struct cx88_core *core; 369 struct cx88_core *core;
263 struct input_dev *input; 370 struct input_dev *input;
@@ -266,7 +373,7 @@ struct cx88_IR {
266 char phys[32]; 373 char phys[32];
267 374
268 /* sample from gpio pin 16 */ 375 /* sample from gpio pin 16 */
269 int sampling; 376 u32 sampling;
270 u32 samples[16]; 377 u32 samples[16];
271 int scount; 378 int scount;
272 unsigned long release; 379 unsigned long release;
@@ -384,10 +491,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
384 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 491 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
385 ir_codes = ir_codes_cinergy_1400; 492 ir_codes = ir_codes_cinergy_1400;
386 ir_type = IR_TYPE_PD; 493 ir_type = IR_TYPE_PD;
387 ir->sampling = 1; 494 ir->sampling = 0xeb04; /* address */
388 break; 495 break;
389 case CX88_BOARD_HAUPPAUGE: 496 case CX88_BOARD_HAUPPAUGE:
390 case CX88_BOARD_HAUPPAUGE_DVB_T1: 497 case CX88_BOARD_HAUPPAUGE_DVB_T1:
498 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
499 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
500 case CX88_BOARD_HAUPPAUGE_HVR1100:
391 ir_codes = ir_codes_hauppauge_new; 501 ir_codes = ir_codes_hauppauge_new;
392 ir_type = IR_TYPE_RC5; 502 ir_type = IR_TYPE_RC5;
393 ir->sampling = 1; 503 ir->sampling = 1;
@@ -427,6 +537,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
427 ir->mask_keyup = 0x40; 537 ir->mask_keyup = 0x40;
428 ir->polling = 1; /* ms */ 538 ir->polling = 1; /* ms */
429 break; 539 break;
540 case CX88_BOARD_AVERTV_303:
541 case CX88_BOARD_AVERTV_STUDIO_303:
542 ir_codes = ir_codes_avertv_303;
543 ir->gpio_addr = MO_GP2_IO;
544 ir->mask_keycode = 0xfb;
545 ir->mask_keydown = 0x02;
546 ir->polling = 50; /* ms */
547 break;
548 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
549 ir_codes = ir_codes_dntv_live_dvbt_pro;
550 ir_type = IR_TYPE_PD;
551 ir->sampling = 0xff00; /* address */
552 break;
430 } 553 }
431 554
432 if (NULL == ir_codes) { 555 if (NULL == ir_codes) {
@@ -484,6 +607,10 @@ int cx88_ir_fini(struct cx88_core *core)
484 if (NULL == ir) 607 if (NULL == ir)
485 return 0; 608 return 0;
486 609
610 if (ir->sampling) {
611 cx_write(MO_DDSCFG_IO, 0x0);
612 core->pci_irqmask &= ~(1 << 18);
613 }
487 if (ir->polling) { 614 if (ir->polling) {
488 del_timer(&ir->timer); 615 del_timer(&ir->timer);
489 flush_scheduled_work(); 616 flush_scheduled_work();
@@ -535,6 +662,7 @@ void cx88_ir_irq(struct cx88_core *core)
535 /* decode it */ 662 /* decode it */
536 switch (core->board) { 663 switch (core->board) {
537 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 664 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
665 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
538 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); 666 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
539 667
540 if (ircode == 0xffffffff) { /* decoding error */ 668 if (ircode == 0xffffffff) { /* decoding error */
@@ -550,7 +678,7 @@ void cx88_ir_irq(struct cx88_core *core)
550 break; 678 break;
551 } 679 }
552 680
553 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ 681 if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
554 ir_dprintk("pulse distance decoded wrong address\n"); 682 ir_dprintk("pulse distance decoded wrong address\n");
555 break; 683 break;
556 } 684 }
@@ -567,6 +695,8 @@ void cx88_ir_irq(struct cx88_core *core)
567 break; 695 break;
568 case CX88_BOARD_HAUPPAUGE: 696 case CX88_BOARD_HAUPPAUGE:
569 case CX88_BOARD_HAUPPAUGE_DVB_T1: 697 case CX88_BOARD_HAUPPAUGE_DVB_T1:
698 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
699 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
570 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); 700 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
571 ir_dprintk("biphase decoded: %x\n", ircode); 701 ir_dprintk("biphase decoded: %x\n", ircode);
572 if ((ircode & 0xfffff000) != 0x3000) 702 if ((ircode & 0xfffff000) != 0x3000)
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 35e6d0c2b872..c79cc1d2bf8b 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -78,6 +78,11 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
78 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: 78 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
79 cx_write(TS_SOP_STAT, 1<<13); 79 cx_write(TS_SOP_STAT, 1<<13);
80 break; 80 break;
81 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
82 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
83 cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
84 udelay(100);
85 break;
81 default: 86 default:
82 cx_write(TS_SOP_STAT, 0x00); 87 cx_write(TS_SOP_STAT, 0x00);
83 break; 88 break;
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index a1b120c8a9b5..24118e43e73a 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -132,14 +132,22 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
132{ 132{
133 u32 volume; 133 u32 volume;
134 134
135#ifndef USING_CX88_ALSA
135 /* restart dma; This avoids buzz in NICAM and is good in others */ 136 /* restart dma; This avoids buzz in NICAM and is good in others */
136 cx88_stop_audio_dma(core); 137 cx88_stop_audio_dma(core);
138#endif
137 cx_write(AUD_RATE_THRES_DMD, 0x000000C0); 139 cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
140#ifndef USING_CX88_ALSA
138 cx88_start_audio_dma(core); 141 cx88_start_audio_dma(core);
142#endif
139 143
140 if (cx88_boards[core->board].blackbird) { 144 if (cx88_boards[core->board].blackbird) {
141 /* sets sound input from external adc */ 145 /* sets sound input from external adc */
142 cx_set(AUD_CTL, EN_I2SIN_ENABLE); 146 if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN)
147 cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
148 else
149 cx_set(AUD_CTL, EN_I2SIN_ENABLE);
150
143 cx_write(AUD_I2SINPUTCNTL, 4); 151 cx_write(AUD_I2SINPUTCNTL, 4);
144 cx_write(AUD_BAUDRATE, 1); 152 cx_write(AUD_BAUDRATE, 1);
145 /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */ 153 /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 24a48f8a48c1..9a02515fe18b 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -33,6 +33,7 @@
33#include <asm/div64.h> 33#include <asm/div64.h>
34 34
35#include "cx88.h" 35#include "cx88.h"
36#include <media/v4l2-common.h>
36 37
37/* Include V4L1 specific functions. Should be removed soon */ 38/* Include V4L1 specific functions. Should be removed soon */
38#include <linux/videodev.h> 39#include <linux/videodev.h>
@@ -240,7 +241,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
240 .minimum = 0, 241 .minimum = 0,
241 .maximum = 0xff, 242 .maximum = 0xff,
242 .step = 1, 243 .step = 1,
243 .default_value = 0, 244 .default_value = 0x3f,
244 .type = V4L2_CTRL_TYPE_INTEGER, 245 .type = V4L2_CTRL_TYPE_INTEGER,
245 }, 246 },
246 .off = 0, 247 .off = 0,
@@ -271,7 +272,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
271 .minimum = 0, 272 .minimum = 0,
272 .maximum = 0xff, 273 .maximum = 0xff,
273 .step = 1, 274 .step = 1,
274 .default_value = 0, 275 .default_value = 0x7f,
275 .type = V4L2_CTRL_TYPE_INTEGER, 276 .type = V4L2_CTRL_TYPE_INTEGER,
276 }, 277 },
277 .off = 0, 278 .off = 0,
@@ -285,6 +286,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
285 .name = "Mute", 286 .name = "Mute",
286 .minimum = 0, 287 .minimum = 0,
287 .maximum = 1, 288 .maximum = 1,
289 .default_value = 1,
288 .type = V4L2_CTRL_TYPE_BOOLEAN, 290 .type = V4L2_CTRL_TYPE_BOOLEAN,
289 }, 291 },
290 .reg = AUD_VOL_CTL, 292 .reg = AUD_VOL_CTL,
@@ -298,7 +300,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
298 .minimum = 0, 300 .minimum = 0,
299 .maximum = 0x3f, 301 .maximum = 0x3f,
300 .step = 1, 302 .step = 1,
301 .default_value = 0, 303 .default_value = 0x1f,
302 .type = V4L2_CTRL_TYPE_INTEGER, 304 .type = V4L2_CTRL_TYPE_INTEGER,
303 }, 305 },
304 .reg = AUD_VOL_CTL, 306 .reg = AUD_VOL_CTL,
@@ -917,6 +919,9 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
917 ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; 919 ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
918 break; 920 break;
919 } 921 }
922 printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
923 ctl->id, c->reg, ctl->value,
924 c->mask, c->sreg ? " [shadowed]" : "");
920 return 0; 925 return 0;
921} 926}
922 927
@@ -925,13 +930,13 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
925{ 930{
926 /* struct cx88_core *core = dev->core; */ 931 /* struct cx88_core *core = dev->core; */
927 struct cx88_ctrl *c = NULL; 932 struct cx88_ctrl *c = NULL;
928 u32 v_sat_value; 933 u32 value,mask;
929 u32 value;
930 int i; 934 int i;
931 935 for (i = 0; i < CX8800_CTLS; i++) {
932 for (i = 0; i < CX8800_CTLS; i++) 936 if (cx8800_ctls[i].v.id == ctl->id) {
933 if (cx8800_ctls[i].v.id == ctl->id)
934 c = &cx8800_ctls[i]; 937 c = &cx8800_ctls[i];
938 }
939 }
935 if (NULL == c) 940 if (NULL == c)
936 return -EINVAL; 941 return -EINVAL;
937 942
@@ -939,6 +944,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
939 ctl->value = c->v.minimum; 944 ctl->value = c->v.minimum;
940 if (ctl->value > c->v.maximum) 945 if (ctl->value > c->v.maximum)
941 ctl->value = c->v.maximum; 946 ctl->value = c->v.maximum;
947 mask=c->mask;
942 switch (ctl->id) { 948 switch (ctl->id) {
943 case V4L2_CID_AUDIO_BALANCE: 949 case V4L2_CID_AUDIO_BALANCE:
944 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; 950 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
@@ -948,56 +954,44 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
948 break; 954 break;
949 case V4L2_CID_SATURATION: 955 case V4L2_CID_SATURATION:
950 /* special v_sat handling */ 956 /* special v_sat handling */
951 v_sat_value = ctl->value - (0x7f - 0x5a); 957
952 if (v_sat_value > 0xff) 958 value = ((ctl->value - c->off) << c->shift) & c->mask;
953 v_sat_value = 0xff; 959
954 if (v_sat_value < 0x00) 960 if (core->tvnorm->id & V4L2_STD_SECAM) {
955 v_sat_value = 0x00; 961 /* For SECAM, both U and V sat should be equal */
956 cx_andor(MO_UV_SATURATION, 0xff00, v_sat_value << 8); 962 value=value<<8|value;
957 /* fall through to default route for u_sat */ 963 } else {
964 /* Keeps U Saturation proportional to V Sat */
965 value=(value*0x5a)/0x7f<<8|value;
966 }
967 mask=0xffff;
968 break;
958 default: 969 default:
959 value = ((ctl->value - c->off) << c->shift) & c->mask; 970 value = ((ctl->value - c->off) << c->shift) & c->mask;
960 break; 971 break;
961 } 972 }
962 dprintk(1,"set_control id=0x%X reg=0x%x val=0x%x%s\n", 973 printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
963 ctl->id, c->reg, value, c->sreg ? " [shadowed]" : ""); 974 ctl->id, c->reg, value,
975 mask, c->sreg ? " [shadowed]" : "");
964 if (c->sreg) { 976 if (c->sreg) {
965 cx_sandor(c->sreg, c->reg, c->mask, value); 977 cx_sandor(c->sreg, c->reg, mask, value);
966 } else { 978 } else {
967 cx_andor(c->reg, c->mask, value); 979 cx_andor(c->reg, mask, value);
968 } 980 }
969 return 0; 981 return 0;
970} 982}
971 983
972/* static void init_controls(struct cx8800_dev *dev) */
973static void init_controls(struct cx88_core *core) 984static void init_controls(struct cx88_core *core)
974{ 985{
975 static struct v4l2_control mute = { 986 struct v4l2_control ctrl;
976 .id = V4L2_CID_AUDIO_MUTE, 987 int i;
977 .value = 1,
978 };
979 static struct v4l2_control volume = {
980 .id = V4L2_CID_AUDIO_VOLUME,
981 .value = 0x3f,
982 };
983 static struct v4l2_control hue = {
984 .id = V4L2_CID_HUE,
985 .value = 0x80,
986 };
987 static struct v4l2_control contrast = {
988 .id = V4L2_CID_CONTRAST,
989 .value = 0x80,
990 };
991 static struct v4l2_control brightness = {
992 .id = V4L2_CID_BRIGHTNESS,
993 .value = 0x80,
994 };
995 988
996 set_control(core,&mute); 989 for (i = 0; i < CX8800_CTLS; i++) {
997 set_control(core,&volume); 990 ctrl.id=cx8800_ctls[i].v.id;
998 set_control(core,&hue); 991 ctrl.value=cx8800_ctls[i].v.default_value
999 set_control(core,&contrast); 992 +cx8800_ctls[i].off;
1000 set_control(core,&brightness); 993 set_control(core, &ctrl);
994 }
1001} 995}
1002 996
1003/* ------------------------------------------------------------------ */ 997/* ------------------------------------------------------------------ */
@@ -1125,7 +1119,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1125 int err; 1119 int err;
1126 1120
1127 if (video_debug > 1) 1121 if (video_debug > 1)
1128 cx88_print_ioctl(core->name,cmd); 1122 v4l_print_ioctl(core->name,cmd);
1129 switch (cmd) { 1123 switch (cmd) {
1130 1124
1131 /* --- capabilities ------------------------------------------ */ 1125 /* --- capabilities ------------------------------------------ */
@@ -1261,7 +1255,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1261 1255
1262 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); 1256 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1263 if (video_debug > 1) 1257 if (video_debug > 1)
1264 cx88_print_ioctl(core->name,cmd); 1258 v4l_print_ioctl(core->name,cmd);
1265 1259
1266 switch (cmd) { 1260 switch (cmd) {
1267 /* ---------- tv norms ---------- */ 1261 /* ---------- tv norms ---------- */
@@ -1481,7 +1475,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1481 struct cx88_core *core = dev->core; 1475 struct cx88_core *core = dev->core;
1482 1476
1483 if (video_debug > 1) 1477 if (video_debug > 1)
1484 cx88_print_ioctl(core->name,cmd); 1478 v4l_print_ioctl(core->name,cmd);
1485 1479
1486 switch (cmd) { 1480 switch (cmd) {
1487 case VIDIOC_QUERYCAP: 1481 case VIDIOC_QUERYCAP:
@@ -1740,6 +1734,7 @@ static struct file_operations video_fops =
1740 .poll = video_poll, 1734 .poll = video_poll,
1741 .mmap = video_mmap, 1735 .mmap = video_mmap,
1742 .ioctl = video_ioctl, 1736 .ioctl = video_ioctl,
1737 .compat_ioctl = v4l_compat_ioctl32,
1743 .llseek = no_llseek, 1738 .llseek = no_llseek,
1744}; 1739};
1745 1740
@@ -1767,6 +1762,7 @@ static struct file_operations radio_fops =
1767 .open = video_open, 1762 .open = video_open,
1768 .release = video_release, 1763 .release = video_release,
1769 .ioctl = radio_ioctl, 1764 .ioctl = radio_ioctl,
1765 .compat_ioctl = v4l_compat_ioctl32,
1770 .llseek = no_llseek, 1766 .llseek = no_llseek,
1771}; 1767};
1772 1768
@@ -1928,8 +1924,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1928 1924
1929 /* initial device configuration */ 1925 /* initial device configuration */
1930 down(&core->lock); 1926 down(&core->lock);
1931 init_controls(core);
1932 cx88_set_tvnorm(core,tvnorms); 1927 cx88_set_tvnorm(core,tvnorms);
1928 init_controls(core);
1933 video_mux(core,0); 1929 video_mux(core,0);
1934 up(&core->lock); 1930 up(&core->lock);
1935 1931
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 77beafc5c327..e9fd55b57fa6 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -179,6 +179,14 @@ extern struct sram_channel cx88_sram_channels[];
179#define CX88_BOARD_ATI_HDTVWONDER 34 179#define CX88_BOARD_ATI_HDTVWONDER 34
180#define CX88_BOARD_WINFAST_DTV1000 35 180#define CX88_BOARD_WINFAST_DTV1000 35
181#define CX88_BOARD_AVERTV_303 36 181#define CX88_BOARD_AVERTV_303 36
182#define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37
183#define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38
184#define CX88_BOARD_KWORLD_DVBS_100 39
185#define CX88_BOARD_HAUPPAUGE_HVR1100 40
186#define CX88_BOARD_HAUPPAUGE_HVR1100LP 41
187#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42
188#define CX88_BOARD_KWORLD_DVB_T_CX22702 43
189#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44
182 190
183enum cx88_itype { 191enum cx88_itype {
184 CX88_VMUX_COMPOSITE1 = 1, 192 CX88_VMUX_COMPOSITE1 = 1,
@@ -280,6 +288,9 @@ struct cx88_core {
280 unsigned int tda9887_conf; 288 unsigned int tda9887_conf;
281 unsigned int has_radio; 289 unsigned int has_radio;
282 290
291 /* Supported V4L _STD_ tuner formats */
292 unsigned int tuner_formats;
293
283 /* config info -- dvb */ 294 /* config info -- dvb */
284 struct dvb_pll_desc *pll_desc; 295 struct dvb_pll_desc *pll_desc;
285 unsigned int pll_addr; 296 unsigned int pll_addr;
@@ -301,6 +312,9 @@ struct cx88_core {
301 312
302 /* various v4l controls */ 313 /* various v4l controls */
303 u32 freq; 314 u32 freq;
315
316 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
317 struct cx8802_dev *dvbdev;
304}; 318};
305 319
306struct cx8800_dev; 320struct cx8800_dev;
@@ -411,6 +425,8 @@ struct cx8802_dev {
411 struct videobuf_dvb dvb; 425 struct videobuf_dvb dvb;
412 void* fe_handle; 426 void* fe_handle;
413 int (*fe_release)(void *handle); 427 int (*fe_release)(void *handle);
428
429 void *card_priv;
414 /* for switching modulation types */ 430 /* for switching modulation types */
415 unsigned char ts_gen_cntrl; 431 unsigned char ts_gen_cntrl;
416 432
@@ -447,7 +463,6 @@ struct cx8802_dev {
447 463
448extern void cx88_print_irqbits(char *name, char *tag, char **strings, 464extern void cx88_print_irqbits(char *name, char *tag, char **strings,
449 u32 bits, u32 mask); 465 u32 bits, u32 mask);
450extern void cx88_print_ioctl(char *name, unsigned int cmd);
451 466
452extern int cx88_core_irq(struct cx88_core *core, u32 status); 467extern int cx88_core_irq(struct cx88_core *core, u32 status);
453extern void cx88_wakeup(struct cx88_core *core, 468extern void cx88_wakeup(struct cx88_core *core,