aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-09-15 10:33:54 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 22:47:36 -0400
commit02b20b0b4cde011f7ad6b5363fb88b93f7ad4e5b (patch)
treede8dbf798a2867a58d2108684e1aef76ec9bbfc0 /drivers
parent78f28b7c555359c67c2a0d23f7436e915329421e (diff)
V4L/DVB (12730): Add conexant cx25821 driver
GIT_BRANCH=devel GIT_AUTHOR_DATE=1252851239 GIT_AUTHOR_NAME=Palash Bandyopadhyay GIT_AUTHOR_EMAIL=Palash.Bandyopadhyay@conexant.com Add conexant cx25821 driver release v106 of the Athena driver. Signed-off-by: Palash Bandyopadhyay <palash.bandyopadhyay@conexant.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/cx25821/Kconfig34
-rw-r--r--drivers/staging/cx25821/Makefile15
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c791
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c825
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.h62
-rw-r--r--drivers/staging/cx25821/cx25821-audio.h60
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c441
-rw-r--r--drivers/staging/cx25821/cx25821-biffuncs.h45
-rw-r--r--drivers/staging/cx25821/cx25821-cards.c72
-rw-r--r--drivers/staging/cx25821/cx25821-core.c1565
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.c116
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.h3
-rw-r--r--drivers/staging/cx25821/cx25821-i2c.c437
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-defines.h51
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-reg.h456
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c769
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.h51
-rw-r--r--drivers/staging/cx25821/cx25821-reg.h1609
-rw-r--r--drivers/staging/cx25821/cx25821-sram.h266
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.c847
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.h107
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c923
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.h113
-rw-r--r--drivers/staging/cx25821/cx25821-video.c1337
-rw-r--r--drivers/staging/cx25821/cx25821-video.h172
-rw-r--r--drivers/staging/cx25821/cx25821-video0.c457
-rw-r--r--drivers/staging/cx25821/cx25821-video1.c456
-rw-r--r--drivers/staging/cx25821/cx25821-video2.c459
-rw-r--r--drivers/staging/cx25821/cx25821-video3.c458
-rw-r--r--drivers/staging/cx25821/cx25821-video4.c456
-rw-r--r--drivers/staging/cx25821/cx25821-video5.c455
-rw-r--r--drivers/staging/cx25821/cx25821-video6.c455
-rw-r--r--drivers/staging/cx25821/cx25821-video7.c454
-rw-r--r--drivers/staging/cx25821/cx25821-videoioctl.c500
-rw-r--r--drivers/staging/cx25821/cx25821-vidups10.c443
-rw-r--r--drivers/staging/cx25821/cx25821-vidups9.c441
-rw-r--r--drivers/staging/cx25821/cx25821.h589
37 files changed, 16790 insertions, 0 deletions
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
new file mode 100644
index 00000000000..88871156c0d
--- /dev/null
+++ b/drivers/staging/cx25821/Kconfig
@@ -0,0 +1,34 @@
1config VIDEO_CX25821
2 tristate "Conexant cx25821 support"
3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
4 select I2C_ALGOBIT
5 select VIDEO_BTCX
6 select VIDEO_TVEEPROM
7 select VIDEO_IR
8 select VIDEOBUF_DVB
9 select VIDEOBUF_DMA_SG
10 select VIDEO_CX25840
11 select VIDEO_CX2341X
12 ---help---
13 This is a video4linux driver for Conexant 25821 based
14 TV cards.
15
16 To compile this driver as a module, choose M here: the
17 module will be called cx25821
18
19config VIDEO_CX25821_ALSA
20 tristate "Conexant 25821 DMA audio support"
21 depends on VIDEO_CX25821 && SND && EXPERIMENTAL
22 select SND_PCM
23 ---help---
24 This is a video4linux driver for direct (DMA) audio on
25 Conexant 25821 based capture cards using ALSA.
26
27 It only works with boards with function 01 enabled.
28 To check if your board supports, use lspci -n.
29 If supported, you should see 14f1:8801 or 14f1:8811
30 PCI device.
31
32 To compile this driver as a module, choose M here: the
33 module will be called cx25821-alsa.
34
diff --git a/drivers/staging/cx25821/Makefile b/drivers/staging/cx25821/Makefile
new file mode 100644
index 00000000000..020d8440493
--- /dev/null
+++ b/drivers/staging/cx25821/Makefile
@@ -0,0 +1,15 @@
1cx25821-objs := cx25821-core.o cx25821-cards.o cx25821-i2c.o cx25821-gpio.o \
2 cx25821-medusa-video.o cx25821-video.o cx25821-video0.o cx25821-video1.o \
3 cx25821-video2.o cx25821-video3.o cx25821-video4.o cx25821-video5.o \
4 cx25821-video6.o cx25821-video7.o cx25821-vidups9.o cx25821-vidups10.o \
5 cx25821-audups11.o cx25821-video-upstream.o cx25821-video-upstream-ch2.o \
6 cx25821-audio-upstream.o cx25821-videoioctl.o
7
8obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
9obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
10
11EXTRA_CFLAGS += -Idrivers/media/video
12EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
13EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
14
15EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
new file mode 100644
index 00000000000..6b2e86acc12
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -0,0 +1,791 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on SAA713x ALSA driver and CX88 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/device.h>
27#include <linux/interrupt.h>
28#include <linux/vmalloc.h>
29#include <linux/dma-mapping.h>
30#include <linux/pci.h>
31
32#include <asm/delay.h>
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/control.h>
37#include <sound/initval.h>
38#include <sound/tlv.h>
39
40
41#include "cx25821.h"
42#include "cx25821-reg.h"
43
44#define AUDIO_SRAM_CHANNEL SRAM_CH08
45
46#define dprintk(level,fmt, arg...) if (debug >= level) \
47 printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg)
48
49#define dprintk_core(level,fmt, arg...) if (debug >= level) \
50 printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg)
51
52
53/****************************************************************************
54 Data type declarations - Can be moded to a header file later
55 ****************************************************************************/
56
57
58static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];
59static int devno;
60
61struct cx25821_audio_dev {
62 struct cx25821_dev *dev;
63 struct cx25821_dmaqueue q;
64
65 /* pci i/o */
66 struct pci_dev *pci;
67
68 /* audio controls */
69 int irq;
70
71 struct snd_card *card;
72
73 unsigned long iobase;
74 spinlock_t reg_lock;
75 atomic_t count;
76
77 unsigned int dma_size;
78 unsigned int period_size;
79 unsigned int num_periods;
80
81 struct videobuf_dmabuf *dma_risc;
82
83 struct cx25821_buffer *buf;
84
85 struct snd_pcm_substream *substream;
86};
87typedef struct cx25821_audio_dev snd_cx25821_card_t;
88
89
90
91/****************************************************************************
92 Module global static vars
93 ****************************************************************************/
94
95static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
96static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
97static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
98
99module_param_array(enable, bool, NULL, 0444);
100MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
101
102module_param_array(index, int, NULL, 0444);
103MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s).");
104
105
106/****************************************************************************
107 Module macros
108 ****************************************************************************/
109
110MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards");
111MODULE_AUTHOR("Hiep Huynh");
112MODULE_LICENSE("GPL");
113MODULE_SUPPORTED_DEVICE("{{Conexant,25821}");//"{{Conexant,23881},"
114
115static unsigned int debug;
116module_param(debug,int,0644);
117MODULE_PARM_DESC(debug,"enable debug messages");
118
119/****************************************************************************
120 Module specific funtions
121 ****************************************************************************/
122/* Constants taken from cx88-reg.h */
123#define AUD_INT_DN_RISCI1 (1 << 0)
124#define AUD_INT_UP_RISCI1 (1 << 1)
125#define AUD_INT_RDS_DN_RISCI1 (1 << 2)
126#define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */
127#define AUD_INT_UP_RISCI2 (1 << 5)
128#define AUD_INT_RDS_DN_RISCI2 (1 << 6)
129#define AUD_INT_DN_SYNC (1 << 12)
130#define AUD_INT_UP_SYNC (1 << 13)
131#define AUD_INT_RDS_DN_SYNC (1 << 14)
132#define AUD_INT_OPC_ERR (1 << 16)
133#define AUD_INT_BER_IRQ (1 << 20)
134#define AUD_INT_MCHG_IRQ (1 << 21)
135#define GP_COUNT_CONTROL_RESET 0x3
136
137#define PCI_MSK_AUD_EXT (1 << 4)
138#define PCI_MSK_AUD_INT (1 << 3)
139/*
140 * BOARD Specific: Sets audio DMA
141 */
142
143static int _cx25821_start_audio_dma(snd_cx25821_card_t *chip)
144{
145 struct cx25821_buffer *buf = chip->buf;
146 struct cx25821_dev * dev = chip->dev;
147 struct sram_channel *audio_ch = &cx25821_sram_channels[AUDIO_SRAM_CHANNEL];
148 u32 tmp = 0;
149
150 // enable output on the GPIO 0 for the MCLK ADC (Audio)
151 cx25821_set_gpiopin_direction( chip->dev, 0, 0 );
152
153 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
154 cx_clear(AUD_INT_DMA_CTL, FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN );
155
156 /* setup fifo + format - out channel */
157 cx25821_sram_channel_setup_audio(chip->dev, audio_ch, buf->bpl, buf->risc.dma);
158
159 /* sets bpl size */
160 cx_write(AUD_A_LNGTH, buf->bpl);
161
162 /* reset counter */
163 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); //GP_COUNT_CONTROL_RESET = 0x3
164 atomic_set(&chip->count, 0);
165
166 //Set the input mode to 16-bit
167 tmp = cx_read(AUD_A_CFG);
168 cx_write(AUD_A_CFG, tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE | FLD_AUD_CLK_ENABLE);
169
170 //printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d "
171 // "byte buffer\n", buf->bpl, audio_ch->cmds_start, cx_read(audio_ch->cmds_start + 12)>>1,
172 // chip->num_periods, buf->bpl * chip->num_periods);
173
174
175 /* Enables corresponding bits at AUD_INT_STAT */
176 cx_write(AUD_A_INT_MSK, FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | FLD_AUD_DST_SYNC | FLD_AUD_DST_OPC_ERR );
177
178 /* Clean any pending interrupt bits already set */
179 cx_write(AUD_A_INT_STAT, ~0);
180
181 /* enable audio irqs */
182 cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT);
183
184 // Turn on audio downstream fifo and risc enable 0x101
185 tmp = cx_read(AUD_INT_DMA_CTL);
186 cx_set(AUD_INT_DMA_CTL, tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN) );
187
188 mdelay(100);
189 return 0;
190}
191
192/*
193 * BOARD Specific: Resets audio DMA
194 */
195static int _cx25821_stop_audio_dma(snd_cx25821_card_t *chip)
196{
197 struct cx25821_dev *dev = chip->dev;
198
199 /* stop dma */
200 cx_clear(AUD_INT_DMA_CTL, FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN );
201
202 /* disable irqs */
203 cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT);
204 cx_clear(AUD_A_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
205
206 return 0;
207}
208
209#define MAX_IRQ_LOOP 50
210
211/*
212 * BOARD Specific: IRQ dma bits
213 */
214static char *cx25821_aud_irqs[32] = {
215 "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
216 NULL, /* reserved */
217 "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
218 NULL, /* reserved */
219 "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
220 NULL, /* reserved */
221 "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
222 NULL, /* reserved */
223 "opc_err", "par_err", "rip_err", /* 16-18 */
224 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
225};
226
227/*
228 * BOARD Specific: Threats IRQ audio specific calls
229 */
230static void cx25821_aud_irq(snd_cx25821_card_t *chip, u32 status, u32 mask)
231{
232 struct cx25821_dev *dev = chip->dev;
233
234 if (0 == (status & mask))
235 {
236 return;
237 }
238
239 cx_write(AUD_A_INT_STAT, status);
240 if (debug > 1 || (status & mask & ~0xff))
241 cx25821_print_irqbits(dev->name, "irq aud",
242 cx25821_aud_irqs, ARRAY_SIZE(cx25821_aud_irqs),
243 status, mask);
244
245 /* risc op code error */
246 if (status & AUD_INT_OPC_ERR) {
247 printk(KERN_WARNING "WARNING %s/1: Audio risc op code error\n",dev->name);
248
249 cx_clear(AUD_INT_DMA_CTL, FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN );
250 cx25821_sram_channel_dump_audio(dev, &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]);
251 }
252 if (status & AUD_INT_DN_SYNC) {
253 printk(KERN_WARNING "WARNING %s: Downstream sync error!\n",dev->name);
254 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
255 return;
256 }
257
258
259 /* risc1 downstream */
260 if (status & AUD_INT_DN_RISCI1) {
261 atomic_set(&chip->count, cx_read(AUD_A_GPCNT));
262 snd_pcm_period_elapsed(chip->substream);
263 }
264}
265
266
267/*
268 * BOARD Specific: Handles IRQ calls
269 */
270static irqreturn_t cx25821_irq(int irq, void *dev_id)
271{
272 snd_cx25821_card_t *chip = dev_id;
273 struct cx25821_dev *dev = chip->dev;
274 u32 status, pci_status;
275 u32 audint_status, audint_mask;
276 int loop, handled = 0;
277 int audint_count = 0;
278
279
280 audint_status = cx_read(AUD_A_INT_STAT);
281 audint_mask = cx_read(AUD_A_INT_MSK);
282 audint_count = cx_read(AUD_A_GPCNT);
283 status = cx_read(PCI_INT_STAT);
284
285 for (loop = 0; loop < 1; loop++)
286 {
287 status = cx_read(PCI_INT_STAT);
288 if (0 == status)
289 {
290 status = cx_read(PCI_INT_STAT);
291 audint_status = cx_read(AUD_A_INT_STAT);
292 audint_mask = cx_read(AUD_A_INT_MSK);
293
294 if (status)
295 {
296 handled = 1;
297 cx_write(PCI_INT_STAT, status);
298
299 cx25821_aud_irq(chip, audint_status, audint_mask);
300 break;
301 }
302 else
303 goto out;
304 }
305
306 handled = 1;
307 cx_write(PCI_INT_STAT, status);
308
309 cx25821_aud_irq(chip, audint_status, audint_mask);
310 }
311
312 pci_status = cx_read(PCI_INT_STAT);
313
314 if (handled)
315 cx_write(PCI_INT_STAT, pci_status);
316
317 out:
318 return IRQ_RETVAL(handled);
319}
320
321
322static int dsp_buffer_free(snd_cx25821_card_t *chip)
323{
324 BUG_ON(!chip->dma_size);
325
326 dprintk(2,"Freeing buffer\n");
327 videobuf_sg_dma_unmap(&chip->pci->dev, chip->dma_risc);
328 videobuf_dma_free(chip->dma_risc);
329 btcx_riscmem_free(chip->pci,&chip->buf->risc);
330 kfree(chip->buf);
331
332 chip->dma_risc = NULL;
333 chip->dma_size = 0;
334
335 return 0;
336}
337
338/****************************************************************************
339 ALSA PCM Interface
340 ****************************************************************************/
341
342/*
343 * Digital hardware definition
344 */
345#define DEFAULT_FIFO_SIZE 384
346static struct snd_pcm_hardware snd_cx25821_digital_hw = {
347 .info = SNDRV_PCM_INFO_MMAP |
348 SNDRV_PCM_INFO_INTERLEAVED |
349 SNDRV_PCM_INFO_BLOCK_TRANSFER |
350 SNDRV_PCM_INFO_MMAP_VALID,
351 .formats = SNDRV_PCM_FMTBIT_S16_LE,
352
353 .rates = SNDRV_PCM_RATE_48000,
354 .rate_min = 48000,
355 .rate_max = 48000,
356 .channels_min = 2,
357 .channels_max = 2,
358 /* Analog audio output will be full of clicks and pops if there
359 are not exactly four lines in the SRAM FIFO buffer. */
360 .period_bytes_min = DEFAULT_FIFO_SIZE/3,
361 .period_bytes_max = DEFAULT_FIFO_SIZE/3,
362 .periods_min = 1,
363 .periods_max = AUDIO_LINE_SIZE,
364 .buffer_bytes_max = (AUDIO_LINE_SIZE*AUDIO_LINE_SIZE), //128*128 = 16384 = 1024 * 16
365};
366
367
368
369/*
370 * audio pcm capture open callback
371 */
372static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
373{
374 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
375 struct snd_pcm_runtime *runtime = substream->runtime;
376 int err;
377 unsigned int bpl = 0;
378
379 if (!chip) {
380 printk(KERN_ERR "DEBUG: cx25821 can't find device struct."
381 " Can't proceed with open\n");
382 return -ENODEV;
383 }
384
385 err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
386 if (err < 0)
387 goto _error;
388
389 chip->substream = substream;
390
391 runtime->hw = snd_cx25821_digital_hw;
392
393 if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size != DEFAULT_FIFO_SIZE)
394 {
395 bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3; //since there are 3 audio Clusters
396 bpl &= ~7; /* must be multiple of 8 */
397
398 if( bpl > AUDIO_LINE_SIZE )
399 {
400 bpl = AUDIO_LINE_SIZE;
401 }
402 runtime->hw.period_bytes_min = bpl;
403 runtime->hw.period_bytes_max = bpl;
404 }
405
406 return 0;
407_error:
408 dprintk(1,"Error opening PCM!\n");
409 return err;
410}
411
412/*
413 * audio close callback
414 */
415static int snd_cx25821_close(struct snd_pcm_substream *substream)
416{
417 return 0;
418}
419
420/*
421 * hw_params callback
422 */
423static int snd_cx25821_hw_params(struct snd_pcm_substream * substream,
424 struct snd_pcm_hw_params * hw_params)
425{
426 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
427 struct videobuf_dmabuf *dma;
428
429 struct cx25821_buffer *buf;
430 int ret;
431
432 if (substream->runtime->dma_area) {
433 dsp_buffer_free(chip);
434 substream->runtime->dma_area = NULL;
435 }
436
437
438 chip->period_size = params_period_bytes(hw_params);
439 chip->num_periods = params_periods(hw_params);
440 chip->dma_size = chip->period_size * params_periods(hw_params);
441
442 BUG_ON(!chip->dma_size);
443 BUG_ON(chip->num_periods & (chip->num_periods-1));
444
445 buf = videobuf_sg_alloc(sizeof(*buf));
446 if (NULL == buf)
447 return -ENOMEM;
448
449
450 if( chip->period_size > AUDIO_LINE_SIZE )
451 {
452 chip->period_size = AUDIO_LINE_SIZE;
453 }
454
455
456 buf->vb.memory = V4L2_MEMORY_MMAP;
457 buf->vb.field = V4L2_FIELD_NONE;
458 buf->vb.width = chip->period_size;
459 buf->bpl = chip->period_size;
460 buf->vb.height = chip->num_periods;
461 buf->vb.size = chip->dma_size;
462
463 dma = videobuf_to_dma(&buf->vb);
464 videobuf_dma_init(dma);
465
466 ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
467 (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
468 if (ret < 0)
469 goto error;
470
471 ret = videobuf_sg_dma_map(&chip->pci->dev, dma);
472 if (ret < 0)
473 goto error;
474
475
476 ret = cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist, buf->vb.width, buf->vb.height, 1);
477 if (ret < 0)
478 {
479 printk(KERN_INFO "DEBUG: ERROR after cx25821_risc_databuffer_audio() \n");
480 goto error;
481 }
482
483
484 /* Loop back to start of program */
485 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC);
486 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
487 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
488
489 buf->vb.state = VIDEOBUF_PREPARED;
490
491 chip->buf = buf;
492 chip->dma_risc = dma;
493
494 substream->runtime->dma_area = chip->dma_risc->vmalloc;
495 substream->runtime->dma_bytes = chip->dma_size;
496 substream->runtime->dma_addr = 0;
497
498 return 0;
499
500error:
501 kfree(buf);
502 return ret;
503}
504
505/*
506 * hw free callback
507 */
508static int snd_cx25821_hw_free(struct snd_pcm_substream * substream)
509{
510 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
511
512 if (substream->runtime->dma_area) {
513 dsp_buffer_free(chip);
514 substream->runtime->dma_area = NULL;
515 }
516
517 return 0;
518}
519
520/*
521 * prepare callback
522 */
523static int snd_cx25821_prepare(struct snd_pcm_substream *substream)
524{
525 return 0;
526}
527
528/*
529 * trigger callback
530 */
531static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream, int cmd)
532{
533 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
534 int err = 0;
535
536 /* Local interrupts are already disabled by ALSA */
537 spin_lock(&chip->reg_lock);
538
539 switch (cmd)
540 {
541 case SNDRV_PCM_TRIGGER_START:
542 err = _cx25821_start_audio_dma(chip);
543 break;
544 case SNDRV_PCM_TRIGGER_STOP:
545 err = _cx25821_stop_audio_dma(chip);
546 break;
547 default:
548 err = -EINVAL;
549 break;
550 }
551
552 spin_unlock(&chip->reg_lock);
553
554 return err;
555}
556
557/*
558 * pointer callback
559 */
560static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream *substream)
561{
562 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
563 struct snd_pcm_runtime *runtime = substream->runtime;
564 u16 count;
565
566 count = atomic_read(&chip->count);
567
568 return runtime->period_size * (count & (runtime->periods-1));
569}
570
571/*
572 * page callback (needed for mmap)
573 */
574static struct page *snd_cx25821_page(struct snd_pcm_substream *substream,
575 unsigned long offset)
576{
577 void *pageptr = substream->runtime->dma_area + offset;
578
579 return vmalloc_to_page(pageptr);
580}
581
582/*
583 * operators
584 */
585static struct snd_pcm_ops snd_cx25821_pcm_ops = {
586 .open = snd_cx25821_pcm_open,
587 .close = snd_cx25821_close,
588 .ioctl = snd_pcm_lib_ioctl,
589 .hw_params = snd_cx25821_hw_params,
590 .hw_free = snd_cx25821_hw_free,
591 .prepare = snd_cx25821_prepare,
592 .trigger = snd_cx25821_card_trigger,
593 .pointer = snd_cx25821_pointer,
594 .page = snd_cx25821_page,
595};
596
597
598/*
599 * ALSA create a PCM device: Called when initializing the board. Sets up the name and hooks up
600 * the callbacks
601 */
602static int snd_cx25821_pcm(snd_cx25821_card_t *chip, int device, char *name)
603{
604 struct snd_pcm *pcm;
605 int err;
606
607 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
608 if (err < 0)
609 {
610 printk(KERN_INFO "ERROR: FAILED snd_pcm_new() in %s\n", __func__);
611 return err;
612 }
613 pcm->private_data = chip;
614 pcm->info_flags = 0;
615 strcpy(pcm->name, name);
616 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx25821_pcm_ops);
617
618 return 0;
619}
620
621
622/****************************************************************************
623 Basic Flow for Sound Devices
624 ****************************************************************************/
625
626/*
627 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
628 * Only boards with eeprom and byte 1 at eeprom=1 have it
629 */
630
631static struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = {
632 {0x14f1,0x0920,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
633 {0, }
634};
635MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
636
637/*
638 * Not used in the function snd_cx25821_dev_free so removing
639 * from the file.
640 */
641/*
642static int snd_cx25821_free(snd_cx25821_card_t *chip)
643{
644 if (chip->irq >= 0)
645 free_irq(chip->irq, chip);
646
647 cx25821_dev_unregister(chip->dev);
648 pci_disable_device(chip->pci);
649
650 return 0;
651}
652*/
653
654/*
655 * Component Destructor
656 */
657static void snd_cx25821_dev_free(struct snd_card * card)
658{
659 snd_cx25821_card_t *chip = card->private_data;
660
661 //snd_cx25821_free(chip);
662 snd_card_free(chip->card);
663}
664
665
666/*
667 * Alsa Constructor - Component probe
668 */
669static int cx25821_audio_initdev(struct cx25821_dev *dev)
670{
671 struct snd_card *card;
672 snd_cx25821_card_t *chip;
673 int err;
674
675 if (devno >= SNDRV_CARDS)
676 {
677 printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n", __func__);
678 return (-ENODEV);
679 }
680
681 if (!enable[devno]) {
682 ++devno;
683 printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__);
684 return (-ENOENT);
685 }
686
687 card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx25821_card_t));
688 if (!card)
689 {
690 printk(KERN_INFO "DEBUG ERROR: cannot create snd_card_new in %s\n", __func__);
691 return (-ENOMEM);
692 }
693
694 strcpy(card->driver, "cx25821");
695
696 /* Card "creation" */
697 card->private_free = snd_cx25821_dev_free;
698 chip = (snd_cx25821_card_t *) card->private_data;
699 spin_lock_init(&chip->reg_lock);
700
701 chip->dev = dev;
702 chip->card = card;
703 chip->pci = dev->pci;
704 chip->iobase = pci_resource_start(dev->pci, 0);
705
706
707 chip->irq = dev->pci->irq;
708
709 err = request_irq(dev->pci->irq, cx25821_irq,
710 IRQF_SHARED | IRQF_DISABLED, chip->dev->name, chip);
711
712 if (err < 0) {
713 printk(KERN_ERR "ERROR %s: can't get IRQ %d for ALSA\n", chip->dev->name, dev->pci->irq);
714 goto error;
715 }
716
717
718 if ((err = snd_cx25821_pcm(chip, 0, "cx25821 Digital")) < 0)
719 {
720 printk(KERN_INFO "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n", __func__);
721 goto error;
722 }
723
724 snd_card_set_dev(card, &chip->pci->dev);
725
726
727 strcpy(card->shortname, "cx25821");
728 sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name, chip->iobase, chip->irq);
729 strcpy (card->mixername, "CX25821");
730
731 printk(KERN_INFO "%s/%i: ALSA support for cx25821 boards\n", card->driver, devno);
732
733 err = snd_card_register(card);
734 if (err < 0)
735 {
736 printk(KERN_INFO "DEBUG ERROR: cannot register sound card %s\n", __func__);
737 goto error;
738 }
739
740 snd_cx25821_cards[devno] = card;
741
742 devno++;
743 return 0;
744
745error:
746 snd_card_free(card);
747 return err;
748}
749
750
751/****************************************************************************
752 LINUX MODULE INIT
753 ****************************************************************************/
754static void cx25821_audio_fini(void)
755{
756 snd_card_free(snd_cx25821_cards[0]);
757}
758
759/*
760 * Module initializer
761 *
762 * Loops through present saa7134 cards, and assigns an ALSA device
763 * to each one
764 *
765 */
766static int cx25821_alsa_init(void)
767{
768 struct cx25821_dev *dev = NULL;
769 struct list_head *list;
770
771 list_for_each(list,&cx25821_devlist) {
772 dev = list_entry(list, struct cx25821_dev, devlist);
773 cx25821_audio_initdev(dev);
774 }
775
776 if (dev == NULL)
777 printk(KERN_INFO "cx25821 ERROR ALSA: no cx25821 cards found\n");
778
779 return 0;
780
781}
782
783late_initcall(cx25821_alsa_init);
784module_exit(cx25821_audio_fini);
785
786/* ----------------------------------------------------------- */
787/*
788 * Local variables:
789 * c-basic-offset: 8
790 * End:
791 */
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
new file mode 100644
index 00000000000..9138767e4d7
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -0,0 +1,825 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24#include "cx25821-video.h"
25#include "cx25821-audio-upstream.h"
26
27#include <linux/fs.h>
28#include <linux/errno.h>
29#include <linux/kernel.h>
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/syscalls.h>
33#include <linux/file.h>
34#include <linux/fcntl.h>
35#include <linux/delay.h>
36#include <asm/uaccess.h>
37
38
39MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
40MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
41MODULE_LICENSE("GPL");
42
43
44static int _intr_msk = FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC | FLD_AUD_SRC_OPC_ERR;
45
46
47int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
48 struct sram_channel *ch,
49 unsigned int bpl, u32 risc)
50{
51 unsigned int i, lines;
52 u32 cdt;
53
54
55 if (ch->cmds_start == 0) {
56 cx_write(ch->ptr1_reg, 0);
57 cx_write(ch->ptr2_reg, 0);
58 cx_write(ch->cnt2_reg, 0);
59 cx_write(ch->cnt1_reg, 0);
60 return 0;
61 }
62
63 bpl = (bpl + 7) & ~7; /* alignment */
64 cdt = ch->cdt;
65 lines = ch->fifo_size / bpl;
66
67 if (lines > 3)
68 {
69 lines = 3;
70 }
71
72 BUG_ON(lines < 2);
73
74
75 /* write CDT */
76 for (i = 0; i < lines; i++) {
77 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
78 cx_write(cdt + 16*i + 4, 0);
79 cx_write(cdt + 16*i + 8, 0);
80 cx_write(cdt + 16*i + 12, 0);
81 }
82
83 /* write CMDS */
84 cx_write(ch->cmds_start + 0, risc);
85
86 cx_write(ch->cmds_start + 4, 0);
87 cx_write(ch->cmds_start + 8, cdt);
88 cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW);
89 cx_write(ch->cmds_start + 16, ch->ctrl_start);
90
91 //IQ size
92 cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW);
93
94 for (i = 24; i < 80; i += 4)
95 cx_write(ch->cmds_start + i, 0);
96
97 /* fill registers */
98 cx_write(ch->ptr1_reg, ch->fifo_start);
99 cx_write(ch->ptr2_reg, cdt);
100 cx_write(ch->cnt2_reg, AUDIO_CDT_SIZE_QW);
101 cx_write(ch->cnt1_reg, AUDIO_CLUSTER_SIZE_QW - 1);
102
103 return 0;
104}
105
106
107static __le32 *cx25821_risc_field_upstream_audio( struct cx25821_dev *dev, __le32 *rp,
108 dma_addr_t databuf_phys_addr,
109 unsigned int bpl, int fifo_enable)
110{
111 unsigned int line;
112 struct sram_channel *sram_ch = &dev->sram_channels[dev->_audio_upstream_channel_select];
113 int offset = 0;
114
115
116 /* scan lines */
117 for (line = 0; line < LINES_PER_AUDIO_BUFFER; line++)
118 {
119 *(rp++) = cpu_to_le32(RISC_READ|RISC_SOL|RISC_EOL|bpl);
120 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
121 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
122
123 // Check if we need to enable the FIFO after the first 3 lines
124 // For the upstream audio channel, the risc engine will enable the FIFO.
125 if ( fifo_enable && line == 2 )
126 {
127 *(rp++) = RISC_WRITECR;
128 *(rp++) = sram_ch->dma_ctl;
129 *(rp++) = sram_ch->fld_aud_fifo_en;
130 *(rp++) = 0x00000020;
131 }
132
133 offset += AUDIO_LINE_SIZE;
134 }
135
136 return rp;
137}
138
139int cx25821_risc_buffer_upstream_audio( struct cx25821_dev *dev,
140 struct pci_dev *pci,
141 unsigned int bpl, unsigned int lines)
142{
143 __le32 *rp;
144 int fifo_enable = 0;
145 int frame = 0, i = 0;
146 int frame_size = AUDIO_DATA_BUF_SZ;
147 int databuf_offset = 0;
148 int risc_flag = RISC_CNT_INC;
149 dma_addr_t risc_phys_jump_addr;
150
151
152 /* Virtual address of Risc buffer program */
153 rp = dev->_risc_virt_addr;
154
155 /* sync instruction */
156 *(rp++) = cpu_to_le32(RISC_RESYNC | AUDIO_SYNC_LINE);
157
158
159 for( frame = 0; frame < NUM_AUDIO_FRAMES; frame++ )
160 {
161 databuf_offset = frame_size * frame;
162
163 if( frame == 0 )
164 {
165 fifo_enable = 1;
166 risc_flag = RISC_CNT_RESET;
167 }
168 else
169 {
170 fifo_enable = 0;
171 risc_flag = RISC_CNT_INC;
172 }
173
174 //Calculate physical jump address
175 if( (frame+1) == NUM_AUDIO_FRAMES )
176 {
177 risc_phys_jump_addr = dev->_risc_phys_start_addr + RISC_SYNC_INSTRUCTION_SIZE;
178 }
179 else
180 {
181 risc_phys_jump_addr = dev->_risc_phys_start_addr + RISC_SYNC_INSTRUCTION_SIZE + AUDIO_RISC_DMA_BUF_SIZE*(frame+1);
182 }
183
184 rp = cx25821_risc_field_upstream_audio(dev, rp, dev->_audiodata_buf_phys_addr+databuf_offset, bpl, fifo_enable);
185
186
187 if( USE_RISC_NOOP_AUDIO )
188 {
189 for( i = 0; i < NUM_NO_OPS; i++ )
190 {
191 *(rp++) = cpu_to_le32(RISC_NOOP);
192 }
193 }
194
195
196 // Loop to (Nth)FrameRISC or to Start of Risc program & generate IRQ
197 *(rp++) = cpu_to_le32(RISC_JUMP|RISC_IRQ1|risc_flag);
198 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
199 *(rp++) = cpu_to_le32(0);
200
201 //Recalculate virtual address based on frame index
202 rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE/4 + (AUDIO_RISC_DMA_BUF_SIZE*(frame+1)/4 ) ;
203 }
204
205 return 0;
206}
207
208
209void cx25821_free_memory_audio(struct cx25821_dev *dev)
210{
211 if (dev->_risc_virt_addr)
212 {
213 pci_free_consistent(dev->pci, dev->_audiorisc_size, dev->_risc_virt_addr, dev->_risc_phys_addr);
214 dev->_risc_virt_addr = NULL;
215 }
216
217 if (dev->_audiodata_buf_virt_addr)
218 {
219 pci_free_consistent(dev->pci, dev->_audiodata_buf_size, dev->_audiodata_buf_virt_addr, dev->_audiodata_buf_phys_addr);
220 dev->_audiodata_buf_virt_addr = NULL;
221 }
222}
223
224void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
225{
226 struct sram_channel *sram_ch = &dev->sram_channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B];
227 u32 tmp = 0;
228
229 if( !dev->_audio_is_running )
230 {
231 printk("cx25821: No audio file is currently running so return!\n");
232 return;
233 }
234
235 //Disable RISC interrupts
236 cx_write( sram_ch->int_msk, 0 );
237
238 //Turn OFF risc and fifo enable in AUD_DMA_CNTRL
239 tmp = cx_read( sram_ch->dma_ctl );
240 cx_write( sram_ch->dma_ctl, tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en) );
241
242 //Clear data buffer memory
243 if( dev->_audiodata_buf_virt_addr )
244 memset( dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size );
245
246 dev->_audio_is_running = 0;
247 dev->_is_first_audio_frame = 0;
248 dev->_audioframe_count = 0;
249 dev->_audiofile_status = END_OF_FILE;
250
251 if( dev->_irq_audio_queues )
252 {
253 kfree(dev->_irq_audio_queues);
254 dev->_irq_audio_queues = NULL;
255 }
256
257 if( dev->_audiofilename != NULL )
258 kfree(dev->_audiofilename);
259}
260
261
262void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
263{
264 if( dev->_audio_is_running )
265 {
266 cx25821_stop_upstream_audio(dev);
267 }
268
269 cx25821_free_memory_audio(dev);
270}
271
272
273int cx25821_get_audio_data(struct cx25821_dev *dev, struct sram_channel *sram_ch )
274{
275 struct file * myfile;
276 int frame_index_temp = dev->_audioframe_index;
277 int i = 0;
278 int line_size = AUDIO_LINE_SIZE;
279 int frame_size = AUDIO_DATA_BUF_SZ;
280 int frame_offset = frame_size * frame_index_temp;
281 ssize_t vfs_read_retval = 0;
282 char mybuf[line_size];
283 loff_t file_offset = dev->_audioframe_count * frame_size;
284 loff_t pos;
285 mm_segment_t old_fs;
286
287
288 if( dev->_audiofile_status == END_OF_FILE )
289 return 0;
290
291 myfile = filp_open( dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0 );
292
293
294 if (IS_ERR(myfile))
295 {
296 const int open_errno = -PTR_ERR(myfile);
297 printk("%s(): ERROR opening file(%s) with errno = %d! \n", __func__, dev->_audiofilename, open_errno);
298 return PTR_ERR(myfile);
299 }
300 else
301 {
302 if( !(myfile->f_op) )
303 {
304 printk("%s: File has no file operations registered!\n", __func__);
305 filp_close(myfile, NULL);
306 return -EIO;
307 }
308
309
310 if( !myfile->f_op->read )
311 {
312 printk("%s: File has no READ operations registered! \n", __func__);
313 filp_close(myfile, NULL);
314 return -EIO;
315 }
316
317 pos = myfile->f_pos;
318 old_fs = get_fs();
319 set_fs(KERNEL_DS);
320
321
322 for( i = 0; i < dev->_audio_lines_count; i++ )
323 {
324 pos = file_offset;
325
326 vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos);
327
328
329 if( vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_audiodata_buf_virt_addr != NULL )
330 {
331 memcpy( (void*)(dev->_audiodata_buf_virt_addr+frame_offset/4), mybuf, vfs_read_retval);
332 }
333
334 file_offset += vfs_read_retval;
335 frame_offset += vfs_read_retval;
336
337 if( vfs_read_retval < line_size )
338 {
339 printk(KERN_INFO "Done: exit %s() since no more bytes to read from Audio file.\n", __func__ );
340 break;
341 }
342 }
343
344 if( i > 0 )
345 dev->_audioframe_count++;
346
347 dev->_audiofile_status = (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
348
349
350 set_fs(old_fs);
351 filp_close(myfile, NULL);
352 }
353
354 return 0;
355}
356
357static void cx25821_audioups_handler(struct work_struct *work)
358{
359 struct cx25821_dev *dev = container_of(work, struct cx25821_dev, _audio_work_entry);
360
361 if( !dev )
362 {
363 printk("ERROR %s(): since container_of(work_struct) FAILED! \n", __func__ );
364 return;
365 }
366
367 cx25821_get_audio_data( dev, &dev->sram_channels[dev->_audio_upstream_channel_select] );
368}
369
370int cx25821_openfile_audio(struct cx25821_dev *dev, struct sram_channel *sram_ch)
371{
372 struct file * myfile;
373 int i = 0, j = 0;
374 int line_size = AUDIO_LINE_SIZE;
375 ssize_t vfs_read_retval = 0;
376 char mybuf[line_size];
377 loff_t pos;
378 loff_t offset = (unsigned long)0;
379 mm_segment_t old_fs;
380
381
382 myfile = filp_open( dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0 );
383
384
385 if (IS_ERR(myfile))
386 {
387 const int open_errno = -PTR_ERR(myfile);
388 printk("%s(): ERROR opening file(%s) with errno = %d! \n", __func__, dev->_audiofilename, open_errno);
389 return PTR_ERR(myfile);
390 }
391 else
392 {
393 if( !(myfile->f_op) )
394 {
395 printk("%s: File has no file operations registered! \n", __func__);
396 filp_close(myfile, NULL);
397 return -EIO;
398 }
399
400
401 if( !myfile->f_op->read )
402 {
403 printk("%s: File has no READ operations registered! \n", __func__);
404 filp_close(myfile, NULL);
405 return -EIO;
406 }
407
408 pos = myfile->f_pos;
409 old_fs = get_fs();
410 set_fs(KERNEL_DS);
411
412
413 for( j = 0; j < NUM_AUDIO_FRAMES; j++ )
414 {
415 for( i = 0; i < dev->_audio_lines_count; i++ )
416 {
417 pos = offset;
418
419 vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos);
420
421
422 if( vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_audiodata_buf_virt_addr != NULL )
423 {
424 memcpy( (void*)(dev->_audiodata_buf_virt_addr+offset/4), mybuf, vfs_read_retval);
425 }
426
427 offset += vfs_read_retval;
428
429 if( vfs_read_retval < line_size )
430 {
431 printk(KERN_INFO "Done: exit %s() since no more bytes to read from Audio file.\n", __func__ );
432 break;
433 }
434 }
435
436 if( i > 0 )
437 {
438 dev->_audioframe_count++;
439 }
440
441 if( vfs_read_retval < line_size )
442 {
443 break;
444 }
445 }
446
447 dev->_audiofile_status = (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
448
449 set_fs(old_fs);
450 myfile->f_pos = 0;
451 filp_close(myfile, NULL);
452 }
453
454 return 0;
455}
456
457static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
458 struct sram_channel *sram_ch,
459 int bpl)
460{
461 int ret = 0;
462 dma_addr_t dma_addr;
463 dma_addr_t data_dma_addr;
464
465
466 cx25821_free_memory_audio(dev);
467
468 dev->_risc_virt_addr = pci_alloc_consistent(dev->pci, dev->audio_upstream_riscbuf_size, &dma_addr);
469 dev->_risc_virt_start_addr = dev->_risc_virt_addr;
470 dev->_risc_phys_start_addr = dma_addr;
471 dev->_risc_phys_addr = dma_addr;
472 dev->_audiorisc_size = dev->audio_upstream_riscbuf_size;
473
474
475 if (!dev->_risc_virt_addr)
476 {
477 printk("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n");
478 return -ENOMEM;
479 }
480
481 //Clear out memory at address
482 memset( dev->_risc_virt_addr, 0, dev->_audiorisc_size );
483
484
485 //For Audio Data buffer allocation
486 dev->_audiodata_buf_virt_addr = pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size, &data_dma_addr);
487 dev->_audiodata_buf_phys_addr = data_dma_addr;
488 dev->_audiodata_buf_size = dev->audio_upstream_databuf_size;
489
490 if (!dev->_audiodata_buf_virt_addr)
491 {
492 printk("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning. \n");
493 return -ENOMEM;
494 }
495
496 //Clear out memory at address
497 memset( dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size );
498
499
500 ret = cx25821_openfile_audio(dev, sram_ch);
501 if( ret < 0 )
502 return ret;
503
504
505 //Creating RISC programs
506 ret = cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl, dev->_audio_lines_count );
507 if (ret < 0)
508 {
509 printk(KERN_DEBUG "cx25821 ERROR creating audio upstream RISC programs! \n");
510 goto error;
511 }
512
513 return 0;
514
515error:
516 return ret;
517}
518
519int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num, u32 status)
520{
521 int i = 0;
522 u32 int_msk_tmp;
523 struct sram_channel *channel = &dev->sram_channels[chan_num];
524 dma_addr_t risc_phys_jump_addr;
525 __le32 * rp;
526
527
528 if (status & FLD_AUD_SRC_RISCI1)
529 {
530 //Get interrupt_index of the program that interrupted
531 u32 prog_cnt = cx_read( channel->gpcnt );
532
533 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
534 cx_write(channel->int_msk, 0);
535 cx_write(channel->int_stat, cx_read(channel->int_stat) );
536
537 spin_lock(&dev->slock);
538
539
540 while(prog_cnt != dev->_last_index_irq)
541 {
542 //Update _last_index_irq
543 if(dev->_last_index_irq < (NUMBER_OF_PROGRAMS-1))
544 {
545 dev->_last_index_irq++;
546 }
547 else
548 {
549 dev->_last_index_irq = 0;
550 }
551
552 dev->_audioframe_index = dev->_last_index_irq;
553
554 queue_work(dev->_irq_audio_queues, &dev->_audio_work_entry);
555 }
556
557
558 if ( dev->_is_first_audio_frame )
559 {
560 dev->_is_first_audio_frame = 0;
561
562 if( dev->_risc_virt_start_addr != NULL )
563 {
564 risc_phys_jump_addr = dev->_risc_phys_start_addr + RISC_SYNC_INSTRUCTION_SIZE + AUDIO_RISC_DMA_BUF_SIZE;
565
566 rp = cx25821_risc_field_upstream_audio(dev, dev->_risc_virt_start_addr+1, dev->_audiodata_buf_phys_addr, AUDIO_LINE_SIZE, FIFO_DISABLE);
567
568 if( USE_RISC_NOOP_AUDIO )
569 {
570 for( i = 0; i < NUM_NO_OPS; i++ )
571 {
572 *(rp++) = cpu_to_le32(RISC_NOOP);
573 }
574 }
575
576 // Jump to 2nd Audio Frame
577 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_RESET);
578 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
579 *(rp++) = cpu_to_le32(0);
580 }
581 }
582
583 spin_unlock(&dev->slock);
584 }
585 else
586 {
587 if(status & FLD_AUD_SRC_OF)
588 printk("%s: Audio Received Overflow Error Interrupt!\n", __func__);
589
590 if(status & FLD_AUD_SRC_SYNC)
591 printk("%s: Audio Received Sync Error Interrupt!\n", __func__);
592
593 if(status & FLD_AUD_SRC_OPC_ERR)
594 printk("%s: Audio Received OpCode Error Interrupt!\n", __func__);
595
596 // Read and write back the interrupt status register to clear our bits
597 cx_write(channel->int_stat, cx_read(channel->int_stat) );
598 }
599
600
601 if( dev->_audiofile_status == END_OF_FILE )
602 {
603 printk("cx25821: EOF Channel Audio Framecount = %d\n", dev->_audioframe_count );
604 return -1;
605 }
606
607 //ElSE, set the interrupt mask register, re-enable irq.
608 int_msk_tmp = cx_read( channel->int_msk );
609 cx_write( channel->int_msk, int_msk_tmp |= _intr_msk );
610
611 return 0;
612}
613
614static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
615{
616 struct cx25821_dev *dev = dev_id;
617 u32 msk_stat, audio_status;
618 int handled = 0;
619 struct sram_channel *sram_ch;
620
621
622 if( !dev )
623 return -1;
624
625
626 sram_ch = &dev->sram_channels[dev->_audio_upstream_channel_select];
627
628 msk_stat = cx_read(sram_ch->int_mstat);
629 audio_status = cx_read(sram_ch->int_stat);
630
631 // Only deal with our interrupt
632 if(audio_status)
633 {
634 handled = cx25821_audio_upstream_irq(dev, dev->_audio_upstream_channel_select, audio_status);
635 }
636
637
638 if( handled < 0 )
639 {
640 cx25821_stop_upstream_audio(dev);
641 }
642 else
643 {
644 handled += handled;
645 }
646
647 return IRQ_RETVAL(handled);
648}
649
650
651static void cx25821_wait_fifo_enable(struct cx25821_dev *dev, struct sram_channel *sram_ch)
652{
653 int count = 0;
654 u32 tmp;
655
656 do
657 {
658 //Wait 10 microsecond before checking to see if the FIFO is turned ON.
659 udelay(10);
660
661 tmp = cx_read( sram_ch->dma_ctl );
662
663 if(count++ > 1000) //10 millisecond timeout
664 {
665 printk("cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n", __func__);
666 return;
667 }
668
669 } while( !(tmp & sram_ch->fld_aud_fifo_en) );
670
671}
672
673
674int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
675 struct sram_channel *sram_ch)
676{
677 u32 tmp = 0;
678 int err = 0;
679
680
681 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the CMDS.
682 cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr);
683 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
684
685
686 /* reset counter */
687 cx_write(sram_ch->gpcnt_ctl, 3);
688
689 //Set the line length (It looks like we do not need to set the line length)
690 cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH);
691
692 //Set the input mode to 16-bit
693 tmp = cx_read( sram_ch->aud_cfg );
694 tmp |= FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE;
695 cx_write( sram_ch->aud_cfg, tmp );
696
697 // Read and write back the interrupt status register to clear it
698 tmp = cx_read( sram_ch->int_stat);
699 cx_write( sram_ch->int_stat, tmp);
700
701 // Clear our bits from the interrupt status register.
702 cx_write( sram_ch->int_stat, _intr_msk );
703
704
705 //Set the interrupt mask register, enable irq.
706 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
707 tmp = cx_read( sram_ch->int_msk );
708 cx_write( sram_ch->int_msk, tmp |= _intr_msk );
709
710
711 err = request_irq(dev->pci->irq, cx25821_upstream_irq_audio, IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
712 if (err < 0)
713 {
714 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name, dev->pci->irq);
715 goto fail_irq;
716 }
717
718
719 // Start the DMA engine
720 tmp = cx_read( sram_ch->dma_ctl );
721 cx_set( sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en );
722
723 dev->_audio_is_running = 1;
724 dev->_is_first_audio_frame = 1;
725
726 // The fifo_en bit turns on by the first Risc program
727 cx25821_wait_fifo_enable(dev, sram_ch);
728
729 return 0;
730
731
732fail_irq:
733 cx25821_dev_unregister(dev);
734 return err;
735}
736
737
738int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
739{
740 struct sram_channel *sram_ch;
741 int retval = 0;
742 int err = 0;
743 int str_length = 0;
744
745 if( dev->_audio_is_running )
746 {
747 printk("Audio Channel is still running so return!\n");
748 return 0;
749 }
750
751 dev->_audio_upstream_channel_select = channel_select;
752 sram_ch = &dev->sram_channels[channel_select];
753
754 //Work queue
755 INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
756 dev->_irq_audio_queues = create_singlethread_workqueue("cx25821_audioworkqueue");
757
758 if(!dev->_irq_audio_queues)
759 {
760 printk("cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
761 return -ENOMEM;
762 }
763
764
765 dev->_last_index_irq = 0;
766 dev->_audio_is_running = 0;
767 dev->_audioframe_count = 0;
768 dev->_audiofile_status = RESET_STATUS;
769 dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;
770 _line_size = AUDIO_LINE_SIZE;
771
772
773 if( dev->input_audiofilename )
774 {
775 str_length = strlen(dev->input_audiofilename);
776 dev->_audiofilename = (char *) kmalloc(str_length + 1, GFP_KERNEL);
777
778 if( !dev->_audiofilename )
779 goto error;
780
781 memcpy(dev->_audiofilename, dev->input_audiofilename, str_length + 1);
782
783 //Default if filename is empty string
784 if( strcmp(dev->input_audiofilename,"") == 0)
785 {
786 dev->_audiofilename = "/root/audioGOOD.wav";
787 }
788 }
789 else
790 {
791 str_length = strlen(_defaultAudioName);
792 dev->_audiofilename = (char *) kmalloc(str_length + 1, GFP_KERNEL);
793
794 if( !dev->_audiofilename )
795 goto error;
796
797 memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1);
798 }
799
800
801 retval = cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, _line_size, 0);
802
803 dev->audio_upstream_riscbuf_size = AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS + RISC_SYNC_INSTRUCTION_SIZE;
804 dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
805
806
807 //Allocating buffers and prepare RISC program
808 retval = cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size);
809 if (retval < 0)
810 {
811 printk(KERN_ERR "%s: Failed to set up Audio upstream buffers!\n", dev->name);
812 goto error;
813 }
814
815 //Start RISC engine
816 cx25821_start_audio_dma_upstream(dev, sram_ch);
817
818 return 0;
819
820error:
821 cx25821_dev_unregister(dev);
822
823 return err;
824}
825
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.h b/drivers/staging/cx25821/cx25821-audio-upstream.h
new file mode 100644
index 00000000000..7bb136b003b
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.h
@@ -0,0 +1,62 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26
27#define NUM_AUDIO_PROGS 8
28#define NUM_AUDIO_FRAMES 8
29#define END_OF_FILE 0
30#define IN_PROGRESS 1
31#define RESET_STATUS -1
32#define FIFO_DISABLE 0
33#define FIFO_ENABLE 1
34#define NUM_NO_OPS 4
35
36
37#define RISC_READ_INSTRUCTION_SIZE 12
38#define RISC_JUMP_INSTRUCTION_SIZE 12
39#define RISC_WRITECR_INSTRUCTION_SIZE 16
40#define RISC_SYNC_INSTRUCTION_SIZE 4
41#define DWORD_SIZE 4
42#define AUDIO_SYNC_LINE 4
43
44
45#define LINES_PER_AUDIO_BUFFER 15
46#define AUDIO_LINE_SIZE 128
47#define AUDIO_DATA_BUF_SZ (AUDIO_LINE_SIZE * LINES_PER_AUDIO_BUFFER)
48
49#define USE_RISC_NOOP_AUDIO 1
50
51#ifdef USE_RISC_NOOP_AUDIO
52#define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
53#endif
54
55
56#ifndef USE_RISC_NOOP_AUDIO
57#define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
58#endif
59
60static int _line_size;
61char * _defaultAudioName = "/root/audioGOOD.wav";
62
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/staging/cx25821/cx25821-audio.h
new file mode 100644
index 00000000000..1e1351800ba
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio.h
@@ -0,0 +1,60 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __CX25821_AUDIO_H__
24#define __CX25821_AUDIO_H__
25
26
27#define USE_RISC_NOOP 1
28#define LINES_PER_BUFFER 15
29#define AUDIO_LINE_SIZE 128
30
31//Number of buffer programs to use at once.
32#define NUMBER_OF_PROGRAMS 8
33
34//Max size of the RISC program for a buffer. - worst case is 2 writes per line
35// Space is also added for the 4 no-op instructions added on the end.
36
37#ifndef USE_RISC_NOOP
38#define MAX_BUFFER_PROGRAM_SIZE \
39 (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE*4)
40#endif
41
42// MAE 12 July 2005 Try to use NOOP RISC instruction instead
43#ifdef USE_RISC_NOOP
44#define MAX_BUFFER_PROGRAM_SIZE \
45 (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4)
46#endif
47
48
49//Sizes of various instructions in bytes. Used when adding instructions.
50#define RISC_WRITE_INSTRUCTION_SIZE 12
51#define RISC_JUMP_INSTRUCTION_SIZE 12
52#define RISC_SKIP_INSTRUCTION_SIZE 4
53#define RISC_SYNC_INSTRUCTION_SIZE 4
54#define RISC_WRITECR_INSTRUCTION_SIZE 16
55#define RISC_NOOP_INSTRUCTION_SIZE 4
56
57#define MAX_AUDIO_DMA_BUFFER_SIZE (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE)
58
59#endif
60
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
new file mode 100644
index 00000000000..a8e4dce88b9
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -0,0 +1,441 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH11];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH11]);
50 buf->vb.state = VIDEOBUF_ACTIVE;
51 buf->count = q->count++;
52 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
53 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
54 buf, buf->vb. i, buf->count, q->count);
55 } else {
56 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
57 if (prev->vb.width == buf->vb.width &&
58 prev->vb.height == buf->vb.height &&
59 prev->fmt == buf->fmt) {
60 list_add_tail(&buf->vb.queue, &q->active);
61 buf->vb.state = VIDEOBUF_ACTIVE;
62 buf->count = q->count++;
63 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
64
65 /* 64 bit bits 63-32 */
66 prev->risc.jmp[2] = cpu_to_le32(0);
67 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
68
69 } else {
70 list_add_tail(&buf->vb.queue, &q->queued);
71 buf->vb.state = VIDEOBUF_QUEUED;
72 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
73 }
74 }
75
76 if (list_empty(&q->active))
77 {
78 dprintk(2, "active queue empty!\n");
79 }
80}
81
82
83static struct videobuf_queue_ops cx25821_video_qops = {
84 .buf_setup = buffer_setup,
85 .buf_prepare = buffer_prepare,
86 .buf_queue = buffer_queue,
87 .buf_release = buffer_release,
88};
89
90
91static int video_open(struct file *file)
92{
93 int minor = video_devdata(file)->minor;
94 struct cx25821_dev *h, *dev = NULL;
95 struct cx25821_fh *fh;
96 struct list_head *list;
97 enum v4l2_buf_type type = 0;
98
99 lock_kernel();
100 list_for_each(list, &cx25821_devlist)
101 {
102 h = list_entry(list, struct cx25821_dev, devlist);
103
104 if (h->video_dev[SRAM_CH11] && h->video_dev[SRAM_CH11]->minor == minor)
105 {
106 dev = h;
107 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
108 }
109 }
110
111 if (NULL == dev) {
112 unlock_kernel();
113 return -ENODEV;
114 }
115
116 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
117
118 /* allocate + initialize per filehandle data */
119 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
120 if (NULL == fh) {
121 unlock_kernel();
122 return -ENOMEM;
123 }
124
125 file->private_data = fh;
126 fh->dev = dev;
127 fh->type = type;
128 fh->width = 720;
129
130 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
131 fh->height = 576;
132 else
133 fh->height = 480;
134
135 dev->channel_opened = 10;
136 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
137
138 v4l2_prio_open(&dev->prio,&fh->prio);
139
140 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
141 &dev->pci->dev, &dev->slock,
142 V4L2_BUF_TYPE_VIDEO_CAPTURE,
143 V4L2_FIELD_INTERLACED,
144 sizeof(struct cx25821_buffer),
145 fh);
146
147 dprintk(1, "post videobuf_queue_init()\n");
148 unlock_kernel();
149
150 return 0;
151}
152
153static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
154{
155 struct cx25821_fh *fh = file->private_data;
156
157 switch (fh->type)
158 {
159 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
160 if (res_locked(fh->dev, RESOURCE_VIDEO11))
161 return -EBUSY;
162
163 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
164
165 default:
166 BUG();
167 return 0;
168 }
169}
170
171static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
172{
173 struct cx25821_fh *fh = file->private_data;
174 struct cx25821_buffer *buf;
175
176 if (res_check(fh, RESOURCE_VIDEO11)) {
177 /* streaming capture */
178 if (list_empty(&fh->vidq.stream))
179 return POLLERR;
180 buf = list_entry(fh->vidq.stream.next,
181 struct cx25821_buffer, vb.stream);
182 } else {
183 /* read() capture */
184 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
185 if (NULL == buf)
186 return POLLERR;
187 }
188
189 poll_wait(file, &buf->vb.done, wait);
190 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
191 return POLLIN|POLLRDNORM;
192 return 0;
193}
194
195
196static int video_release(struct file *file)
197{
198 struct cx25821_fh *fh = file->private_data;
199 struct cx25821_dev *dev = fh->dev;
200
201 //stop the risc engine and fifo
202 //cx_write(channel11->dma_ctl, 0);
203
204 /* stop video capture */
205 if (res_check(fh, RESOURCE_VIDEO11)) {
206 videobuf_queue_cancel(&fh->vidq);
207 res_free(dev, fh, RESOURCE_VIDEO11);
208 }
209
210 if (fh->vidq.read_buf) {
211 buffer_release(&fh->vidq, fh->vidq.read_buf);
212 kfree(fh->vidq.read_buf);
213 }
214
215 videobuf_mmap_free(&fh->vidq);
216
217 v4l2_prio_close(&dev->prio,&fh->prio);
218
219 file->private_data = NULL;
220 kfree(fh);
221
222 return 0;
223}
224
225
226static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
227{
228 struct cx25821_fh *fh = priv;
229 struct cx25821_dev *dev = fh->dev;
230
231 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
232 {
233 return -EINVAL;
234 }
235
236 if (unlikely(i != fh->type))
237 {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO11))))
242 {
243 return -EBUSY;
244 }
245
246 return videobuf_streamon(get_queue(fh));
247}
248
249static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
250{
251 struct cx25821_fh *fh = priv;
252 struct cx25821_dev *dev = fh->dev;
253 int err, res;
254
255 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
256 return -EINVAL;
257 if (i != fh->type)
258 return -EINVAL;
259
260 res = get_resource(fh, RESOURCE_VIDEO11);
261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0)
263 return err;
264 res_free(dev, fh, res);
265 return 0;
266}
267
268
269static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
270{
271 struct cx25821_fh *fh = priv;
272 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
273 int err;
274
275 if (fh)
276 {
277 err = v4l2_prio_check(&dev->prio, &fh->prio);
278 if (0 != err)
279 return err;
280 }
281
282 dprintk(2, "%s()\n", __func__);
283 err = vidioc_try_fmt_vid_cap(file, priv, f);
284
285 if (0 != err)
286 return err;
287 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
288 fh->width = f->fmt.pix.width;
289 fh->height = f->fmt.pix.height;
290 fh->vidq.field = f->fmt.pix.field;
291 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
292 cx25821_call_all(dev, video, s_fmt, f);
293 return 0;
294}
295
296static long video_ioctl_upstream11(struct file *file, unsigned int cmd, unsigned long arg)
297{
298 struct cx25821_fh *fh = file->private_data;
299 struct cx25821_dev *dev = fh->dev;
300 int command = 0;
301 struct upstream_user_struct *data_from_user;
302
303
304 data_from_user = (struct upstream_user_struct *)arg;
305
306 if( !data_from_user )
307 {
308 printk("cx25821 in %s(): Upstream data is INVALID. Returning.\n", __func__);
309 return 0;
310 }
311
312 command = data_from_user->command;
313
314 if( command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO )
315 {
316 return 0;
317 }
318
319
320 dev->input_filename = data_from_user->input_filename;
321 dev->input_audiofilename = data_from_user->input_filename;
322 dev->vid_stdname = data_from_user->vid_stdname;
323 dev->pixel_format = data_from_user->pixel_format;
324 dev->channel_select = data_from_user->channel_select;
325 dev->command = data_from_user->command;
326
327
328 switch(command)
329 {
330 case UPSTREAM_START_AUDIO:
331 cx25821_start_upstream_audio(dev, data_from_user);
332 break;
333
334 case UPSTREAM_STOP_AUDIO:
335 cx25821_stop_upstream_audio(dev);
336 break;
337 }
338
339 return 0;
340}
341
342static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
343{
344 struct cx25821_fh *fh = priv;
345 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346}
347
348static int vidioc_log_status (struct file *file, void *priv)
349{
350 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
351 char name[32 + 2];
352
353 snprintf(name, sizeof(name), "%s/2", dev->name);
354 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
355 dev->name);
356 cx25821_call_all(dev, core, log_status);
357 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
358 dev->name);
359 return 0;
360}
361
362static int vidioc_s_ctrl(struct file *file, void *priv,
363 struct v4l2_control *ctl)
364{
365 struct cx25821_fh *fh = priv;
366 struct cx25821_dev *dev = fh->dev;
367 int err;
368
369 if (fh)
370 {
371 err = v4l2_prio_check(&dev->prio, &fh->prio);
372 if (0 != err)
373 return err;
374 }
375 return 0;
376}
377// exported stuff
378static const struct v4l2_file_operations video_fops = {
379 .owner = THIS_MODULE,
380 .open = video_open,
381 .release = video_release,
382 .read = video_read,
383 .poll = video_poll,
384 .mmap = video_mmap,
385 .ioctl = video_ioctl_upstream11,
386};
387
388static const struct v4l2_ioctl_ops video_ioctl_ops = {
389 .vidioc_querycap = vidioc_querycap,
390 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
391 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
392 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
393 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
394 .vidioc_reqbufs = vidioc_reqbufs,
395 .vidioc_querybuf = vidioc_querybuf,
396 .vidioc_qbuf = vidioc_qbuf,
397 .vidioc_dqbuf = vidioc_dqbuf,
398#ifdef TUNER_FLAG
399 .vidioc_s_std = vidioc_s_std,
400 .vidioc_querystd = vidioc_querystd,
401#endif
402 .vidioc_cropcap = vidioc_cropcap,
403 .vidioc_s_crop = vidioc_s_crop,
404 .vidioc_g_crop = vidioc_g_crop,
405 .vidioc_enum_input = vidioc_enum_input,
406 .vidioc_g_input = vidioc_g_input,
407 .vidioc_s_input = vidioc_s_input,
408 .vidioc_g_ctrl = vidioc_g_ctrl,
409 .vidioc_s_ctrl = vidioc_s_ctrl,
410 .vidioc_queryctrl = vidioc_queryctrl,
411 .vidioc_streamon = vidioc_streamon,
412 .vidioc_streamoff = vidioc_streamoff,
413 .vidioc_log_status = vidioc_log_status,
414 .vidioc_g_priority = vidioc_g_priority,
415 .vidioc_s_priority = vidioc_s_priority,
416#ifdef CONFIG_VIDEO_V4L1_COMPAT
417 .vidiocgmbuf = vidiocgmbuf,
418#endif
419#ifdef TUNER_FLAG
420 .vidioc_g_tuner = vidioc_g_tuner,
421 .vidioc_s_tuner = vidioc_s_tuner,
422 .vidioc_g_frequency = vidioc_g_frequency,
423 .vidioc_s_frequency = vidioc_s_frequency,
424#endif
425#ifdef CONFIG_VIDEO_ADV_DEBUG
426 .vidioc_g_register = vidioc_g_register,
427 .vidioc_s_register = vidioc_s_register,
428#endif
429};
430
431struct video_device cx25821_video_template11 = {
432 .name = "cx25821-audioupstream",
433 .fops = &video_fops,
434 .minor = -1,
435 .ioctl_ops = &video_ioctl_ops,
436 .tvnorms = CX25821_NORMS,
437 .current_norm = V4L2_STD_NTSC_M,
438};
439
440
441
diff --git a/drivers/staging/cx25821/cx25821-biffuncs.h b/drivers/staging/cx25821/cx25821-biffuncs.h
new file mode 100644
index 00000000000..a5c053507a4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-biffuncs.h
@@ -0,0 +1,45 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _BITFUNCS_H
24#define _BITFUNCS_H
25
26#define SetBit(Bit) (1 << Bit)
27
28inline u8 getBit(u32 sample, u8 index)
29{
30 return (u8) ((sample >> index) & 1);
31}
32
33inline u32 clearBitAtPos(u32 value, u8 bit)
34{
35 return value & ~(1 << bit);
36}
37
38inline u32 setBitAtPos(u32 sample, u8 bit)
39{
40 sample |= (1 << bit);
41 return sample;
42
43}
44
45#endif
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/staging/cx25821/cx25821-cards.c
new file mode 100644
index 00000000000..eaaa56707c1
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-cards.c
@@ -0,0 +1,72 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28#include <media/cx25840.h>
29
30#include "cx25821.h"
31#include "tuner-xc2028.h"
32
33// board config info
34
35struct cx25821_board cx25821_boards[] = {
36 [UNKNOWN_BOARD] = {
37 .name = "UNKNOWN/GENERIC",
38 // Ensure safe default for unknown boards
39 .clk_freq = 0,
40 },
41
42 [CX25821_BOARD] = {
43 .name = "CX25821",
44 .portb = CX25821_RAW,
45 .portc = CX25821_264,
46 .input[0].type = CX25821_VMUX_COMPOSITE,
47 },
48
49};
50
51const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards);
52
53struct cx25821_subid cx25821_subids[]={
54 {
55 .subvendor = 0x14f1,
56 .subdevice = 0x0920,
57 .card = CX25821_BOARD,
58 },
59};
60
61
62void cx25821_card_setup(struct cx25821_dev *dev)
63{
64 static u8 eeprom[256];
65
66 if (dev->i2c_bus[0].i2c_rc == 0)
67 {
68 dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
69 tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom));
70 }
71}
72
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
new file mode 100644
index 00000000000..adca7af1e50
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -0,0 +1,1565 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include <linux/i2c.h>
25#include "cx25821.h"
26#include "cx25821-sram.h"
27#include "cx25821-video.h"
28
29MODULE_DESCRIPTION("Driver for Athena cards");
30MODULE_AUTHOR("Shu Lin - Hiep Huynh");
31MODULE_LICENSE("GPL");
32
33struct list_head cx25821_devlist;
34
35static unsigned int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "enable debug messages");
38
39static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
40module_param_array(card, int, NULL, 0444);
41MODULE_PARM_DESC(card, "card type");
42
43
44static unsigned int cx25821_devcount = 0;
45
46static DEFINE_MUTEX(devlist);
47LIST_HEAD(cx25821_devlist);
48
49
50struct sram_channel cx25821_sram_channels[] = {
51 [SRAM_CH00] = {
52 .i = SRAM_CH00,
53 .name = "VID A",
54 .cmds_start = VID_A_DOWN_CMDS,
55 .ctrl_start = VID_A_IQ,
56 .cdt = VID_A_CDT,
57 .fifo_start = VID_A_DOWN_CLUSTER_1,
58 .fifo_size = (VID_CLUSTER_SIZE<<2),
59 .ptr1_reg = DMA1_PTR1,
60 .ptr2_reg = DMA1_PTR2,
61 .cnt1_reg = DMA1_CNT1,
62 .cnt2_reg = DMA1_CNT2,
63 .int_msk = VID_A_INT_MSK,
64 .int_stat = VID_A_INT_STAT,
65 .int_mstat = VID_A_INT_MSTAT,
66 .dma_ctl = VID_DST_A_DMA_CTL,
67 .gpcnt_ctl = VID_DST_A_GPCNT_CTL,
68 .gpcnt = VID_DST_A_GPCNT,
69 .vip_ctl = VID_DST_A_VIP_CTL,
70 .pix_frmt = VID_DST_A_PIX_FRMT,
71 },
72
73 [SRAM_CH01] = {
74 .i = SRAM_CH01,
75 .name = "VID B",
76 .cmds_start = VID_B_DOWN_CMDS,
77 .ctrl_start = VID_B_IQ,
78 .cdt = VID_B_CDT,
79 .fifo_start = VID_B_DOWN_CLUSTER_1,
80 .fifo_size = (VID_CLUSTER_SIZE<<2),
81 .ptr1_reg = DMA2_PTR1,
82 .ptr2_reg = DMA2_PTR2,
83 .cnt1_reg = DMA2_CNT1,
84 .cnt2_reg = DMA2_CNT2,
85 .int_msk = VID_B_INT_MSK,
86 .int_stat = VID_B_INT_STAT,
87 .int_mstat = VID_B_INT_MSTAT,
88 .dma_ctl = VID_DST_B_DMA_CTL,
89 .gpcnt_ctl = VID_DST_B_GPCNT_CTL,
90 .gpcnt = VID_DST_B_GPCNT,
91 .vip_ctl = VID_DST_B_VIP_CTL,
92 .pix_frmt = VID_DST_B_PIX_FRMT,
93 },
94
95 [SRAM_CH02] = {
96 .i = SRAM_CH02,
97 .name = "VID C",
98 .cmds_start = VID_C_DOWN_CMDS,
99 .ctrl_start = VID_C_IQ,
100 .cdt = VID_C_CDT,
101 .fifo_start = VID_C_DOWN_CLUSTER_1,
102 .fifo_size = (VID_CLUSTER_SIZE<<2),
103 .ptr1_reg = DMA3_PTR1,
104 .ptr2_reg = DMA3_PTR2,
105 .cnt1_reg = DMA3_CNT1,
106 .cnt2_reg = DMA3_CNT2,
107 .int_msk = VID_C_INT_MSK,
108 .int_stat = VID_C_INT_STAT,
109 .int_mstat = VID_C_INT_MSTAT,
110 .dma_ctl = VID_DST_C_DMA_CTL,
111 .gpcnt_ctl = VID_DST_C_GPCNT_CTL,
112 .gpcnt = VID_DST_C_GPCNT,
113 .vip_ctl = VID_DST_C_VIP_CTL,
114 .pix_frmt = VID_DST_C_PIX_FRMT,
115 },
116
117 [SRAM_CH03] = {
118 .i = SRAM_CH03,
119 .name = "VID D",
120 .cmds_start = VID_D_DOWN_CMDS,
121 .ctrl_start = VID_D_IQ,
122 .cdt = VID_D_CDT,
123 .fifo_start = VID_D_DOWN_CLUSTER_1,
124 .fifo_size = (VID_CLUSTER_SIZE<<2),
125 .ptr1_reg = DMA4_PTR1,
126 .ptr2_reg = DMA4_PTR2,
127 .cnt1_reg = DMA4_CNT1,
128 .cnt2_reg = DMA4_CNT2,
129 .int_msk = VID_D_INT_MSK,
130 .int_stat = VID_D_INT_STAT,
131 .int_mstat = VID_D_INT_MSTAT,
132 .dma_ctl = VID_DST_D_DMA_CTL,
133 .gpcnt_ctl = VID_DST_D_GPCNT_CTL,
134 .gpcnt = VID_DST_D_GPCNT,
135 .vip_ctl = VID_DST_D_VIP_CTL,
136 .pix_frmt = VID_DST_D_PIX_FRMT,
137 },
138
139 [SRAM_CH04] = {
140 .i = SRAM_CH04,
141 .name = "VID E",
142 .cmds_start = VID_E_DOWN_CMDS,
143 .ctrl_start = VID_E_IQ,
144 .cdt = VID_E_CDT,
145 .fifo_start = VID_E_DOWN_CLUSTER_1,
146 .fifo_size = (VID_CLUSTER_SIZE<<2),
147 .ptr1_reg = DMA5_PTR1,
148 .ptr2_reg = DMA5_PTR2,
149 .cnt1_reg = DMA5_CNT1,
150 .cnt2_reg = DMA5_CNT2,
151 .int_msk = VID_E_INT_MSK,
152 .int_stat = VID_E_INT_STAT,
153 .int_mstat = VID_E_INT_MSTAT,
154 .dma_ctl = VID_DST_E_DMA_CTL,
155 .gpcnt_ctl = VID_DST_E_GPCNT_CTL,
156 .gpcnt = VID_DST_E_GPCNT,
157 .vip_ctl = VID_DST_E_VIP_CTL,
158 .pix_frmt = VID_DST_E_PIX_FRMT,
159 },
160
161 [SRAM_CH05] = {
162 .i = SRAM_CH05,
163 .name = "VID F",
164 .cmds_start = VID_F_DOWN_CMDS,
165 .ctrl_start = VID_F_IQ,
166 .cdt = VID_F_CDT,
167 .fifo_start = VID_F_DOWN_CLUSTER_1,
168 .fifo_size = (VID_CLUSTER_SIZE<<2),
169 .ptr1_reg = DMA6_PTR1,
170 .ptr2_reg = DMA6_PTR2,
171 .cnt1_reg = DMA6_CNT1,
172 .cnt2_reg = DMA6_CNT2,
173 .int_msk = VID_F_INT_MSK,
174 .int_stat = VID_F_INT_STAT,
175 .int_mstat = VID_F_INT_MSTAT,
176 .dma_ctl = VID_DST_F_DMA_CTL,
177 .gpcnt_ctl = VID_DST_F_GPCNT_CTL,
178 .gpcnt = VID_DST_F_GPCNT,
179 .vip_ctl = VID_DST_F_VIP_CTL,
180 .pix_frmt = VID_DST_F_PIX_FRMT,
181 },
182
183 [SRAM_CH06] = {
184 .i = SRAM_CH06,
185 .name = "VID G",
186 .cmds_start = VID_G_DOWN_CMDS,
187 .ctrl_start = VID_G_IQ,
188 .cdt = VID_G_CDT,
189 .fifo_start = VID_G_DOWN_CLUSTER_1,
190 .fifo_size = (VID_CLUSTER_SIZE<<2),
191 .ptr1_reg = DMA7_PTR1,
192 .ptr2_reg = DMA7_PTR2,
193 .cnt1_reg = DMA7_CNT1,
194 .cnt2_reg = DMA7_CNT2,
195 .int_msk = VID_G_INT_MSK,
196 .int_stat = VID_G_INT_STAT,
197 .int_mstat = VID_G_INT_MSTAT,
198 .dma_ctl = VID_DST_G_DMA_CTL,
199 .gpcnt_ctl = VID_DST_G_GPCNT_CTL,
200 .gpcnt = VID_DST_G_GPCNT,
201 .vip_ctl = VID_DST_G_VIP_CTL,
202 .pix_frmt = VID_DST_G_PIX_FRMT,
203 },
204
205 [SRAM_CH07] = {
206 .i = SRAM_CH07,
207 .name = "VID H",
208 .cmds_start = VID_H_DOWN_CMDS,
209 .ctrl_start = VID_H_IQ,
210 .cdt = VID_H_CDT,
211 .fifo_start = VID_H_DOWN_CLUSTER_1,
212 .fifo_size = (VID_CLUSTER_SIZE<<2),
213 .ptr1_reg = DMA8_PTR1,
214 .ptr2_reg = DMA8_PTR2,
215 .cnt1_reg = DMA8_CNT1,
216 .cnt2_reg = DMA8_CNT2,
217 .int_msk = VID_H_INT_MSK,
218 .int_stat = VID_H_INT_STAT,
219 .int_mstat = VID_H_INT_MSTAT,
220 .dma_ctl = VID_DST_H_DMA_CTL,
221 .gpcnt_ctl = VID_DST_H_GPCNT_CTL,
222 .gpcnt = VID_DST_H_GPCNT,
223 .vip_ctl = VID_DST_H_VIP_CTL,
224 .pix_frmt = VID_DST_H_PIX_FRMT,
225 },
226
227 [SRAM_CH08] = {
228 .name = "audio from",
229 .cmds_start = AUD_A_DOWN_CMDS,
230 .ctrl_start = AUD_A_IQ,
231 .cdt = AUD_A_CDT,
232 .fifo_start = AUD_A_DOWN_CLUSTER_1,
233 .fifo_size = AUDIO_CLUSTER_SIZE * 3,
234 .ptr1_reg = DMA17_PTR1,
235 .ptr2_reg = DMA17_PTR2,
236 .cnt1_reg = DMA17_CNT1,
237 .cnt2_reg = DMA17_CNT2,
238 },
239
240 [SRAM_CH09] = {
241 .i = SRAM_CH09,
242 .name = "VID Upstream I",
243 .cmds_start = VID_I_UP_CMDS,
244 .ctrl_start = VID_I_IQ,
245 .cdt = VID_I_CDT,
246 .fifo_start = VID_I_UP_CLUSTER_1,
247 .fifo_size = (VID_CLUSTER_SIZE<<2),
248 .ptr1_reg = DMA15_PTR1,
249 .ptr2_reg = DMA15_PTR2,
250 .cnt1_reg = DMA15_CNT1,
251 .cnt2_reg = DMA15_CNT2,
252 .int_msk = VID_I_INT_MSK,
253 .int_stat = VID_I_INT_STAT,
254 .int_mstat = VID_I_INT_MSTAT,
255 .dma_ctl = VID_SRC_I_DMA_CTL,
256 .gpcnt_ctl = VID_SRC_I_GPCNT_CTL,
257 .gpcnt = VID_SRC_I_GPCNT,
258
259 .vid_fmt_ctl = VID_SRC_I_FMT_CTL,
260 .vid_active_ctl1= VID_SRC_I_ACTIVE_CTL1,
261 .vid_active_ctl2= VID_SRC_I_ACTIVE_CTL2,
262 .vid_cdt_size = VID_SRC_I_CDT_SZ,
263 .irq_bit = 8,
264 },
265
266 [SRAM_CH10] = {
267 .i = SRAM_CH10,
268 .name = "VID Upstream J",
269 .cmds_start = VID_J_UP_CMDS,
270 .ctrl_start = VID_J_IQ,
271 .cdt = VID_J_CDT,
272 .fifo_start = VID_J_UP_CLUSTER_1,
273 .fifo_size = (VID_CLUSTER_SIZE<<2),
274 .ptr1_reg = DMA16_PTR1,
275 .ptr2_reg = DMA16_PTR2,
276 .cnt1_reg = DMA16_CNT1,
277 .cnt2_reg = DMA16_CNT2,
278 .int_msk = VID_J_INT_MSK,
279 .int_stat = VID_J_INT_STAT,
280 .int_mstat = VID_J_INT_MSTAT,
281 .dma_ctl = VID_SRC_J_DMA_CTL,
282 .gpcnt_ctl = VID_SRC_J_GPCNT_CTL,
283 .gpcnt = VID_SRC_J_GPCNT,
284
285 .vid_fmt_ctl = VID_SRC_J_FMT_CTL,
286 .vid_active_ctl1= VID_SRC_J_ACTIVE_CTL1,
287 .vid_active_ctl2= VID_SRC_J_ACTIVE_CTL2,
288 .vid_cdt_size = VID_SRC_J_CDT_SZ,
289 .irq_bit = 9,
290 },
291
292
293 [SRAM_CH11] = {
294 .i = SRAM_CH11,
295 .name = "Audio Upstream Channel B",
296 .cmds_start = AUD_B_UP_CMDS,
297 .ctrl_start = AUD_B_IQ,
298 .cdt = AUD_B_CDT,
299 .fifo_start = AUD_B_UP_CLUSTER_1,
300 .fifo_size = (AUDIO_CLUSTER_SIZE*3),
301 .ptr1_reg = DMA22_PTR1,
302 .ptr2_reg = DMA22_PTR2,
303 .cnt1_reg = DMA22_CNT1,
304 .cnt2_reg = DMA22_CNT2,
305 .int_msk = AUD_B_INT_MSK,
306 .int_stat = AUD_B_INT_STAT,
307 .int_mstat = AUD_B_INT_MSTAT,
308 .dma_ctl = AUD_INT_DMA_CTL,
309 .gpcnt_ctl = AUD_B_GPCNT_CTL,
310 .gpcnt = AUD_B_GPCNT,
311 .aud_length = AUD_B_LNGTH,
312 .aud_cfg = AUD_B_CFG,
313 .fld_aud_fifo_en = FLD_AUD_SRC_B_FIFO_EN,
314 .fld_aud_risc_en = FLD_AUD_SRC_B_RISC_EN,
315 .irq_bit = 11,
316 },
317};
318
319
320struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00];
321struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01];
322struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02];
323struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03];
324struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04];
325struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05];
326struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06];
327struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07];
328struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09];
329struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10];
330struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11];
331
332struct cx25821_dmaqueue mpegq;
333
334static int cx25821_risc_decode(u32 risc)
335{
336 static char *instr[16] = {
337 [RISC_SYNC >> 28] = "sync",
338 [RISC_WRITE >> 28] = "write",
339 [RISC_WRITEC >> 28] = "writec",
340 [RISC_READ >> 28] = "read",
341 [RISC_READC >> 28] = "readc",
342 [RISC_JUMP >> 28] = "jump",
343 [RISC_SKIP >> 28] = "skip",
344 [RISC_WRITERM >> 28] = "writerm",
345 [RISC_WRITECM >> 28] = "writecm",
346 [RISC_WRITECR >> 28] = "writecr",
347 };
348 static int incr[16] = {
349 [RISC_WRITE >> 28] = 3,
350 [RISC_JUMP >> 28] = 3,
351 [RISC_SKIP >> 28] = 1,
352 [RISC_SYNC >> 28] = 1,
353 [RISC_WRITERM >> 28] = 3,
354 [RISC_WRITECM >> 28] = 3,
355 [RISC_WRITECR >> 28] = 4,
356 };
357 static char *bits[] = {
358 "12", "13", "14", "resync",
359 "cnt0", "cnt1", "18", "19",
360 "20", "21", "22", "23",
361 "irq1", "irq2", "eol", "sol",
362 };
363 int i;
364
365 printk("0x%08x [ %s", risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
366 for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--)
367 {
368 if (risc & (1 << (i + 12)))
369 printk(" %s", bits[i]);
370 }
371 printk(" count=%d ]\n", risc & 0xfff);
372 return incr[risc >> 28] ? incr[risc >> 28] : 1;
373}
374
375static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
376{
377 struct cx25821_i2c *bus = i2c_adap->algo_data;
378 struct cx25821_dev *dev = bus->dev;
379 return cx_read(bus->reg_stat) & 0x01;
380}
381
382
383void cx_i2c_read_print(struct cx25821_dev *dev, u32 reg, const char* reg_string)
384{
385 int tmp = 0;
386 u32 value = 0;
387
388 value = cx25821_i2c_read(&dev->i2c_bus[0], reg, &tmp);
389}
390
391static void cx25821_registers_init(struct cx25821_dev *dev)
392{
393 u32 tmp;
394
395 // enable RUN_RISC in Pecos
396 cx_write( DEV_CNTRL2, 0x20 );
397
398 // Set the master PCI interrupt masks to enable video, audio, MBIF, and GPIO interrupts
399 // I2C interrupt masking is handled by the I2C objects themselves.
400 cx_write( PCI_INT_MSK, 0x2001FFFF );
401
402 tmp = cx_read( RDR_TLCTL0 );
403 tmp &= ~FLD_CFG_RCB_CK_EN; // Clear the RCB_CK_EN bit
404 cx_write( RDR_TLCTL0, tmp);
405
406 // PLL-A setting for the Audio Master Clock
407 cx_write( PLL_A_INT_FRAC, 0x9807A58B );
408
409 // PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1
410 cx_write( PLL_A_POST_STAT_BIST, 0x8000019C);
411
412 // clear reset bit [31]
413 tmp = cx_read( PLL_A_INT_FRAC );
414 cx_write( PLL_A_INT_FRAC, tmp & 0x7FFFFFFF);
415
416 // PLL-B setting for Mobilygen Host Bus Interface
417 cx_write( PLL_B_INT_FRAC, 0x9883A86F);
418
419 // PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0
420 cx_write( PLL_B_POST_STAT_BIST, 0x8000018D);
421
422 // clear reset bit [31]
423 tmp = cx_read( PLL_B_INT_FRAC );
424 cx_write( PLL_B_INT_FRAC, tmp & 0x7FFFFFFF);
425
426 // PLL-C setting for video upstream channel
427 cx_write( PLL_C_INT_FRAC, 0x96A0EA3F);
428
429 // PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0
430 cx_write( PLL_C_POST_STAT_BIST, 0x80000103);
431
432 // clear reset bit [31]
433 tmp = cx_read( PLL_C_INT_FRAC );
434 cx_write( PLL_C_INT_FRAC, tmp & 0x7FFFFFFF);
435
436 // PLL-D setting for audio upstream channel
437 cx_write( PLL_D_INT_FRAC, 0x98757F5B);
438
439 // PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0
440 cx_write( PLL_D_POST_STAT_BIST, 0x80000113);
441
442 // clear reset bit [31]
443 tmp = cx_read( PLL_D_INT_FRAC );
444 cx_write( PLL_D_INT_FRAC, tmp & 0x7FFFFFFF);
445
446
447 // This selects the PLL C clock source for the video upstream channel I and J
448 tmp = cx_read( VID_CH_CLK_SEL );
449 cx_write( VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000);
450
451
452 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
453 //select 656/VIP DST for downstream Channel A - C
454 tmp = cx_read( VID_CH_MODE_SEL );
455 //cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
456 cx_write( VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
457
458
459 // enables 656 port I and J as output
460 tmp = cx_read( CLK_RST );
461 tmp |= FLD_USE_ALT_PLL_REF; // use external ALT_PLL_REF pin as its reference clock instead
462 cx_write( CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE) );
463
464 mdelay(100);
465}
466
467
468int cx25821_sram_channel_setup(struct cx25821_dev *dev,
469 struct sram_channel *ch,
470 unsigned int bpl, u32 risc)
471{
472 unsigned int i, lines;
473 u32 cdt;
474
475 if (ch->cmds_start == 0) {
476 cx_write(ch->ptr1_reg, 0);
477 cx_write(ch->ptr2_reg, 0);
478 cx_write(ch->cnt2_reg, 0);
479 cx_write(ch->cnt1_reg, 0);
480 return 0;
481 }
482
483 bpl = (bpl + 7) & ~7; /* alignment */
484 cdt = ch->cdt;
485 lines = ch->fifo_size / bpl;
486
487 if (lines > 4)
488 {
489 lines = 4;
490 }
491
492 BUG_ON(lines < 2);
493
494 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
495 cx_write(8 + 4, 8);
496 cx_write(8 + 8, 0);
497
498 /* write CDT */
499 for (i = 0; i < lines; i++) {
500 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
501 cx_write(cdt + 16*i + 4, 0);
502 cx_write(cdt + 16*i + 8, 0);
503 cx_write(cdt + 16*i + 12, 0);
504 }
505
506 //init the first cdt buffer
507 for(i=0; i<128; i++)
508 cx_write(ch->fifo_start+4*i, i);
509
510 /* write CMDS */
511 if (ch->jumponly)
512 {
513 cx_write(ch->cmds_start + 0, 8);
514 }
515 else
516 {
517 cx_write(ch->cmds_start + 0, risc);
518 }
519
520 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
521 cx_write(ch->cmds_start + 8, cdt);
522 cx_write(ch->cmds_start + 12, (lines*16) >> 3);
523 cx_write(ch->cmds_start + 16, ch->ctrl_start);
524
525 if (ch->jumponly)
526 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
527 else
528 cx_write(ch->cmds_start + 20, 64 >> 2);
529
530 for (i = 24; i < 80; i += 4)
531 cx_write(ch->cmds_start + i, 0);
532
533 /* fill registers */
534 cx_write(ch->ptr1_reg, ch->fifo_start);
535 cx_write(ch->ptr2_reg, cdt);
536 cx_write(ch->cnt2_reg, (lines*16) >> 3);
537 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
538
539 return 0;
540}
541
542int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
543 struct sram_channel *ch,
544 unsigned int bpl, u32 risc)
545{
546 unsigned int i, lines;
547 u32 cdt;
548
549
550 if (ch->cmds_start == 0) {
551 cx_write(ch->ptr1_reg, 0);
552 cx_write(ch->ptr2_reg, 0);
553 cx_write(ch->cnt2_reg, 0);
554 cx_write(ch->cnt1_reg, 0);
555 return 0;
556 }
557
558 bpl = (bpl + 7) & ~7; /* alignment */
559 cdt = ch->cdt;
560 lines = ch->fifo_size / bpl;
561
562 if (lines > 3)
563 {
564 lines = 3; //for AUDIO
565 }
566
567 BUG_ON(lines < 2);
568
569
570 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
571 cx_write(8 + 4, 8);
572 cx_write(8 + 8, 0);
573
574 /* write CDT */
575 for (i = 0; i < lines; i++) {
576 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
577 cx_write(cdt + 16*i + 4, 0);
578 cx_write(cdt + 16*i + 8, 0);
579 cx_write(cdt + 16*i + 12, 0);
580 }
581
582 /* write CMDS */
583 if (ch->jumponly)
584 {
585 cx_write(ch->cmds_start + 0, 8);
586 }
587 else
588 {
589 cx_write(ch->cmds_start + 0, risc);
590 }
591
592 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
593 cx_write(ch->cmds_start + 8, cdt);
594 cx_write(ch->cmds_start + 12, (lines*16) >> 3);
595 cx_write(ch->cmds_start + 16, ch->ctrl_start);
596
597 //IQ size
598 if (ch->jumponly)
599 {
600 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
601 }
602 else
603 {
604 cx_write(ch->cmds_start + 20, 64 >> 2);
605 }
606
607 //zero out
608 for (i = 24; i < 80; i += 4)
609 cx_write(ch->cmds_start + i, 0);
610
611 /* fill registers */
612 cx_write(ch->ptr1_reg, ch->fifo_start);
613 cx_write(ch->ptr2_reg, cdt);
614 cx_write(ch->cnt2_reg, (lines*16) >> 3);
615 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
616
617 return 0;
618}
619
620
621void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
622{
623 static char *name[] = {
624 "init risc lo",
625 "init risc hi",
626 "cdt base",
627 "cdt size",
628 "iq base",
629 "iq size",
630 "risc pc lo",
631 "risc pc hi",
632 "iq wr ptr",
633 "iq rd ptr",
634 "cdt current",
635 "pci target lo",
636 "pci target hi",
637 "line / byte",
638 };
639 u32 risc;
640 unsigned int i, j, n;
641
642 printk(KERN_WARNING "%s: %s - dma channel status dump\n", dev->name, ch->name);
643 for (i = 0; i < ARRAY_SIZE(name); i++)
644 printk(KERN_WARNING "cmds + 0x%2x: %-15s: 0x%08x\n", i*4, name[i],
645 cx_read(ch->cmds_start + 4*i));
646
647 j=i*4;
648 for (i = 0; i < 4; ) {
649 risc = cx_read(ch->cmds_start + 4 * (i + 14));
650 printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j+i*4, i);
651 i +=cx25821_risc_decode(risc);
652 }
653
654 for (i = 0; i < (64 >> 2); i += n) {
655 risc = cx_read(ch->ctrl_start + 4 * i);
656 /* No consideration for bits 63-32 */
657
658 printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i*4, ch->ctrl_start + 4 * i, i);
659 n = cx25821_risc_decode(risc);
660 for (j = 1; j < n; j++) {
661 risc = cx_read(ch->ctrl_start + 4 * (i + j));
662 printk(KERN_WARNING "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n", 4*(i+j), i+j, risc, j);
663 }
664 }
665
666 printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n", ch->fifo_start, ch->fifo_start+ch->fifo_size);
667 printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n", ch->ctrl_start, ch->ctrl_start + 6*16);
668 printk(KERN_WARNING " : ptr1_reg: 0x%08x\n", cx_read(ch->ptr1_reg));
669 printk(KERN_WARNING " : ptr2_reg: 0x%08x\n", cx_read(ch->ptr2_reg));
670 printk(KERN_WARNING " : cnt1_reg: 0x%08x\n", cx_read(ch->cnt1_reg));
671 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg));
672}
673
674void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, struct sram_channel *ch)
675{
676 static char *name[] = {
677 "init risc lo",
678 "init risc hi",
679 "cdt base",
680 "cdt size",
681 "iq base",
682 "iq size",
683 "risc pc lo",
684 "risc pc hi",
685 "iq wr ptr",
686 "iq rd ptr",
687 "cdt current",
688 "pci target lo",
689 "pci target hi",
690 "line / byte",
691 };
692
693 u32 risc, value, tmp;
694 unsigned int i, j, n;
695
696
697 printk(KERN_INFO "\n%s: %s - dma Audio channel status dump\n", dev->name, ch->name);
698
699 for (i = 0; i < ARRAY_SIZE(name); i++)
700 printk(KERN_INFO "%s: cmds + 0x%2x: %-15s: 0x%08x\n", dev->name, i*4, name[i], cx_read(ch->cmds_start + 4*i));
701
702
703 j=i*4;
704 for (i = 0; i < 4; ) {
705 risc = cx_read(ch->cmds_start + 4 * (i + 14));
706 printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j+i*4, i);
707 i += cx25821_risc_decode(risc);
708 }
709
710 for (i = 0; i < (64 >> 2); i += n) {
711 risc = cx_read(ch->ctrl_start + 4 * i);
712 /* No consideration for bits 63-32 */
713
714 printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i*4, ch->ctrl_start + 4 * i, i);
715 n = cx25821_risc_decode(risc);
716
717 for (j = 1; j < n; j++) {
718 risc = cx_read(ch->ctrl_start + 4 * (i + j));
719 printk(KERN_WARNING "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n", 4*(i+j), i+j, risc, j);
720 }
721 }
722
723 printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n", ch->fifo_start, ch->fifo_start+ch->fifo_size);
724 printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n", ch->ctrl_start, ch->ctrl_start + 6*16);
725 printk(KERN_WARNING " : ptr1_reg: 0x%08x\n", cx_read(ch->ptr1_reg));
726 printk(KERN_WARNING " : ptr2_reg: 0x%08x\n", cx_read(ch->ptr2_reg));
727 printk(KERN_WARNING " : cnt1_reg: 0x%08x\n", cx_read(ch->cnt1_reg));
728 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg));
729
730 for( i=0; i < 4; i++)
731 {
732 risc = cx_read(ch->cmds_start + 56 + (i*4));
733 printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc);
734 }
735
736 //read data from the first cdt buffer
737 risc = cx_read(AUD_A_CDT);
738 printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc);
739 for(i=0; i<8; i++)
740 {
741 n = cx_read(risc+i*4);
742 printk(KERN_WARNING "0x%x ", n);
743 }
744 printk(KERN_WARNING "\n\n");
745
746
747 value = cx_read(CLK_RST);
748 CX25821_INFO(" CLK_RST = 0x%x \n\n", value);
749
750 value = cx_read(PLL_A_POST_STAT_BIST);
751 CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x \n\n", value);
752 value = cx_read(PLL_A_INT_FRAC);
753 CX25821_INFO(" PLL_A_INT_FRAC = 0x%x \n\n", value);
754
755 value = cx_read(PLL_B_POST_STAT_BIST);
756 CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x \n\n", value);
757 value = cx_read(PLL_B_INT_FRAC);
758 CX25821_INFO(" PLL_B_INT_FRAC = 0x%x \n\n", value);
759
760 value = cx_read(PLL_C_POST_STAT_BIST);
761 CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x \n\n", value);
762 value = cx_read(PLL_C_INT_FRAC);
763 CX25821_INFO(" PLL_C_INT_FRAC = 0x%x \n\n", value);
764
765 value = cx_read(PLL_D_POST_STAT_BIST);
766 CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x \n\n", value);
767 value = cx_read(PLL_D_INT_FRAC);
768 CX25821_INFO(" PLL_D_INT_FRAC = 0x%x \n\n", value);
769
770 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
771 CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x \n\n", value);
772}
773
774static void cx25821_shutdown(struct cx25821_dev *dev)
775{
776 int i;
777
778 /* disable RISC controller */
779 cx_write(DEV_CNTRL2, 0);
780
781 /* Disable Video A/B activity */
782 for(i=0; i<VID_CHANNEL_NUM; i++)
783 {
784 cx_write(dev->sram_channels[i].dma_ctl, 0);
785 cx_write(dev->sram_channels[i].int_msk, 0);
786 }
787
788 for( i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++)
789 {
790 cx_write(dev->sram_channels[i].dma_ctl, 0);
791 cx_write(dev->sram_channels[i].int_msk, 0);
792 }
793
794 /* Disable Audio activity */
795 cx_write(AUD_INT_DMA_CTL, 0);
796
797 /* Disable Serial port */
798 cx_write(UART_CTL, 0);
799
800 /* Disable Interrupts */
801 cx_write(PCI_INT_MSK, 0);
802 cx_write(AUD_A_INT_MSK, 0);
803}
804
805void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select, u32 format)
806{
807 struct sram_channel *ch;
808
809 if( channel_select <= 7 && channel_select >= 0 )
810 {
811 ch = &cx25821_sram_channels[channel_select];
812 cx_write(ch->pix_frmt, format);
813 dev->pixel_formats[channel_select] = format;
814 }
815}
816
817static void cx25821_set_vip_mode(struct cx25821_dev *dev, struct sram_channel *ch)
818{
819 cx_write(ch->pix_frmt, PIXEL_FRMT_422);
820 cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1);
821}
822
823static void cx25821_initialize(struct cx25821_dev *dev)
824{
825 int i;
826
827 dprintk(1, "%s()\n", __func__);
828
829 cx25821_shutdown(dev);
830 cx_write(PCI_INT_STAT, 0xffffffff);
831
832 for(i=0; i<VID_CHANNEL_NUM; i++)
833 cx_write(dev->sram_channels[i].int_stat, 0xffffffff);
834
835
836 cx_write(AUD_A_INT_STAT, 0xffffffff);
837 cx_write(AUD_B_INT_STAT, 0xffffffff);
838 cx_write(AUD_C_INT_STAT, 0xffffffff);
839 cx_write(AUD_D_INT_STAT, 0xffffffff);
840 cx_write(AUD_E_INT_STAT, 0xffffffff);
841
842 cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
843 cx_write(PAD_CTRL, 0x12); //for I2C
844 cx25821_registers_init(dev); //init Pecos registers
845 mdelay(100);
846
847
848 for(i=0; i<VID_CHANNEL_NUM; i++)
849 {
850 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
851 cx25821_sram_channel_setup(dev, &dev->sram_channels[i], 1440, 0);
852 dev->pixel_formats[i] = PIXEL_FRMT_422;
853 dev->use_cif_resolution[i] = FALSE;
854 }
855
856 //Probably only affect Downstream
857 for( i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++)
858 {
859 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
860 }
861
862 cx25821_sram_channel_setup_audio(dev, &dev->sram_channels[SRAM_CH08], 128, 0);
863
864 cx25821_gpio_init(dev);
865}
866
867static int get_resources(struct cx25821_dev *dev)
868{
869 if (request_mem_region(pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0), dev->name))
870 return 0;
871
872 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
873 dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
874
875 return -EBUSY;
876}
877
878
879static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
880{
881 dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
882
883 printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", __func__, dev->hwrevision);
884}
885
886static void cx25821_iounmap(struct cx25821_dev *dev)
887{
888 if (dev == NULL)
889 return;
890
891 /* Releasing IO memory */
892 if (dev->lmmio != NULL)
893 {
894 CX25821_INFO("Releasing lmmio.\n");
895 iounmap(dev->lmmio);
896 dev->lmmio = NULL;
897 }
898}
899
900
901static int cx25821_dev_setup(struct cx25821_dev *dev)
902{
903 int io_size = 0, i;
904
905 struct video_device *video_template[] = {
906 &cx25821_video_template0,
907 &cx25821_video_template1,
908 &cx25821_video_template2,
909 &cx25821_video_template3,
910 &cx25821_video_template4,
911 &cx25821_video_template5,
912 &cx25821_video_template6,
913 &cx25821_video_template7,
914 &cx25821_video_template9,
915 &cx25821_video_template10,
916 &cx25821_video_template11,
917 &cx25821_videoioctl_template,
918 };
919
920 printk(KERN_INFO "\n***********************************\n");
921 printk(KERN_INFO "cx25821 set up\n");
922 printk(KERN_INFO "***********************************\n\n");
923
924 mutex_init(&dev->lock);
925
926 atomic_inc(&dev->refcount);
927
928 dev->nr = ++cx25821_devcount;
929 sprintf(dev->name, "cx25821[%d]", dev->nr);
930
931 mutex_lock(&devlist);
932 list_add_tail(&dev->devlist, &cx25821_devlist);
933 mutex_unlock(&devlist);
934
935 strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown");
936 strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
937
938
939 if( dev->pci->device != 0x8210 )
940 {
941 printk(KERN_INFO "%s() Exiting. Incorrect Hardware device = 0x%02x\n",
942 __func__, dev->pci->device);
943 return -1;
944 }
945 else
946 {
947 printk(KERN_INFO "Athena Hardware device = 0x%02x\n", dev->pci->device);
948 }
949
950 /* Apply a sensible clock frequency for the PCIe bridge */
951 dev->clk_freq = 28000000;
952 dev->sram_channels = cx25821_sram_channels;
953
954 if(dev->nr > 1)
955 {
956 CX25821_INFO("dev->nr > 1!");
957 }
958
959 /* board config */
960 dev->board = 1; //card[dev->nr];
961 dev->_max_num_decoders = MAX_DECODERS;
962
963
964 dev->pci_bus = dev->pci->bus->number;
965 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
966 dev->pci_irqmask = 0x001f00;
967
968 /* External Master 1 Bus */
969 dev->i2c_bus[0].nr = 0;
970 dev->i2c_bus[0].dev = dev;
971 dev->i2c_bus[0].reg_stat = I2C1_STAT;
972 dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
973 dev->i2c_bus[0].reg_addr = I2C1_ADDR;
974 dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
975 dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
976 dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
977
978
979
980 if (get_resources(dev) < 0)
981 {
982 printk(KERN_ERR "%s No more PCIe resources for "
983 "subsystem: %04x:%04x\n",
984 dev->name, dev->pci->subsystem_vendor,
985 dev->pci->subsystem_device);
986
987 cx25821_devcount--;
988 return -ENODEV;
989 }
990
991 /* PCIe stuff */
992 dev->base_io_addr = pci_resource_start(dev->pci, 0);
993 io_size = pci_resource_len(dev->pci, 0);
994
995 if (!dev->base_io_addr) {
996 CX25821_ERR("No PCI Memory resources, exiting!\n");
997 return -ENODEV;
998 }
999
1000 dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0));
1001
1002 if (!dev->lmmio) {
1003 CX25821_ERR("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
1004 cx25821_iounmap(dev);
1005 return -ENOMEM;
1006 }
1007
1008
1009 dev->bmmio = (u8 __iomem *)dev->lmmio;
1010
1011 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1012 dev->name, dev->pci->subsystem_vendor,
1013 dev->pci->subsystem_device, cx25821_boards[dev->board].name,
1014 dev->board, card[dev->nr] == dev->board ?
1015 "insmod option" : "autodetected");
1016
1017 /* init hardware */
1018 cx25821_initialize(dev);
1019
1020 cx25821_i2c_register(&dev->i2c_bus[0]);
1021// cx25821_i2c_register(&dev->i2c_bus[1]);
1022// cx25821_i2c_register(&dev->i2c_bus[2]);
1023
1024 CX25821_INFO("i2c register! bus->i2c_rc = %d\n", dev->i2c_bus[0].i2c_rc);
1025
1026 cx25821_card_setup(dev);
1027 medusa_video_init(dev);
1028
1029 for(i = 0; i < VID_CHANNEL_NUM; i++)
1030 {
1031 if (cx25821_video_register(dev, i, video_template[i]) < 0) {
1032 printk(KERN_ERR "%s() Failed to register analog video adapters on VID channel %d\n", __func__, i);
1033 }
1034 }
1035
1036
1037 for(i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++)
1038 {
1039 //Since we don't have template8 for Audio Downstream
1040 if (cx25821_video_register(dev, i, video_template[i-1]) < 0) {
1041 printk(KERN_ERR "%s() Failed to register analog video adapters for Upstream channel %d.\n", __func__, i);
1042 }
1043 }
1044
1045 // register IOCTL device
1046 dev->ioctl_dev = cx25821_vdev_init(dev, dev->pci, video_template[VIDEO_IOCTL_CH], "video");
1047
1048 if( video_register_device(dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0 )
1049 {
1050 cx25821_videoioctl_unregister(dev);
1051 printk(KERN_ERR "%s() Failed to register video adapter for IOCTL so releasing.\n", __func__);
1052 }
1053
1054 cx25821_dev_checkrevision(dev);
1055 CX25821_INFO("cx25821 setup done!\n");
1056
1057 return 0;
1058}
1059
1060
1061void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, struct upstream_user_struct *up_data)
1062{
1063 dev->_isNTSC = !strcmp(dev->vid_stdname,"NTSC") ? 1 : 0;
1064
1065 dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1066 medusa_set_videostandard(dev);
1067
1068 cx25821_vidupstream_init_ch1(dev, dev->channel_select, dev->pixel_format);
1069}
1070
1071
1072void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, struct upstream_user_struct *up_data)
1073{
1074 dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2,"NTSC") ? 1 : 0;
1075
1076 dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1077 medusa_set_videostandard(dev);
1078
1079 cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2, dev->pixel_format_ch2);
1080}
1081
1082
1083void cx25821_start_upstream_audio(struct cx25821_dev *dev, struct upstream_user_struct *up_data)
1084{
1085 cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B);
1086}
1087
1088void cx25821_dev_unregister(struct cx25821_dev *dev)
1089{
1090 int i;
1091
1092 if (!dev->base_io_addr)
1093 return;
1094
1095 cx25821_free_mem_upstream_ch1(dev);
1096 cx25821_free_mem_upstream_ch2(dev);
1097 cx25821_free_mem_upstream_audio(dev);
1098
1099 release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0));
1100
1101 if (!atomic_dec_and_test(&dev->refcount))
1102 return;
1103
1104 for(i=0; i < VID_CHANNEL_NUM; i++)
1105 cx25821_video_unregister(dev, i);
1106
1107
1108 for(i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++)
1109 {
1110 cx25821_video_unregister(dev, i);
1111 }
1112
1113 cx25821_videoioctl_unregister(dev);
1114
1115 cx25821_i2c_unregister( &dev->i2c_bus[0] );
1116 cx25821_iounmap(dev);
1117}
1118
1119
1120
1121static __le32 *cx25821_risc_field(__le32 *rp, struct scatterlist *sglist,
1122 unsigned int offset, u32 sync_line,
1123 unsigned int bpl, unsigned int padding,
1124 unsigned int lines)
1125{
1126 struct scatterlist *sg;
1127 unsigned int line, todo;
1128
1129 /* sync instruction */
1130 if (sync_line != NO_SYNC_LINE)
1131 {
1132 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1133 }
1134
1135 /* scan lines */
1136 sg = sglist;
1137 for (line = 0; line < lines; line++) {
1138 while (offset && offset >= sg_dma_len(sg)) {
1139 offset -= sg_dma_len(sg);
1140 sg++;
1141 }
1142 if (bpl <= sg_dma_len(sg)-offset) {
1143 /* fits into current chunk */
1144 *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
1145 *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
1146 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1147 offset += bpl;
1148 } else {
1149 /* scanline needs to be split */
1150 todo = bpl;
1151 *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|(sg_dma_len(sg)-offset));
1152 *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
1153 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1154 todo -= (sg_dma_len(sg)-offset);
1155 offset = 0;
1156 sg++;
1157 while (todo > sg_dma_len(sg)) {
1158 *(rp++) = cpu_to_le32(RISC_WRITE|sg_dma_len(sg));
1159 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1160 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1161 todo -= sg_dma_len(sg);
1162 sg++;
1163 }
1164 *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
1165 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1166 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1167 offset += todo;
1168 }
1169
1170 offset += padding;
1171 }
1172
1173 return rp;
1174}
1175
1176int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
1177 struct scatterlist *sglist, unsigned int top_offset,
1178 unsigned int bottom_offset, unsigned int bpl,
1179 unsigned int padding, unsigned int lines)
1180{
1181 u32 instructions;
1182 u32 fields;
1183 __le32 *rp;
1184 int rc;
1185
1186 fields = 0;
1187 if (UNSET != top_offset)
1188 fields++;
1189 if (UNSET != bottom_offset)
1190 fields++;
1191
1192 /* estimate risc mem: worst case is one write per page border +
1193 one write per scan line + syncs + jump (all 2 dwords). Padding
1194 can cause next bpl to start close to a page border. First DMA
1195 region may be smaller than PAGE_SIZE */
1196 /* write and jump need and extra dword */
1197 instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
1198 instructions += 2;
1199 rc = btcx_riscmem_alloc(pci, risc, instructions*12);
1200
1201 if (rc < 0)
1202 return rc;
1203
1204 /* write risc instructions */
1205 rp = risc->cpu;
1206
1207 if (UNSET != top_offset)
1208 {
1209 rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding, lines);
1210 }
1211
1212 if (UNSET != bottom_offset)
1213 {
1214 rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl, padding, lines);
1215 }
1216
1217 /* save pointer to jmp instruction address */
1218 risc->jmp = rp;
1219 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1220
1221 return 0;
1222}
1223
1224
1225static __le32* cx25821_risc_field_audio(__le32 *rp, struct scatterlist *sglist,
1226 unsigned int offset, u32 sync_line,
1227 unsigned int bpl, unsigned int padding,
1228 unsigned int lines, unsigned int lpi)
1229{
1230 struct scatterlist *sg;
1231 unsigned int line, todo, sol;
1232
1233 /* sync instruction */
1234 if (sync_line != NO_SYNC_LINE)
1235 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1236
1237 /* scan lines */
1238 sg = sglist;
1239 for (line = 0; line < lines; line++) {
1240 while (offset && offset >= sg_dma_len(sg)) {
1241 offset -= sg_dma_len(sg);
1242 sg++;
1243 }
1244
1245 if (lpi && line > 0 && !(line % lpi))
1246 sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
1247 else
1248 sol = RISC_SOL;
1249
1250 if (bpl <= sg_dma_len(sg)-offset) {
1251 /* fits into current chunk */
1252 *(rp++) = cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl);
1253 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
1254 *(rp++)=cpu_to_le32(0); /* bits 63-32 */
1255 offset+=bpl;
1256 } else {
1257 /* scanline needs to be split */
1258 todo = bpl;
1259 *(rp++) = cpu_to_le32(RISC_WRITE|sol|
1260 (sg_dma_len(sg)-offset));
1261 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
1262 *(rp++)=cpu_to_le32(0); /* bits 63-32 */
1263 todo -= (sg_dma_len(sg)-offset);
1264 offset = 0;
1265 sg++;
1266 while (todo > sg_dma_len(sg)) {
1267 *(rp++)=cpu_to_le32(RISC_WRITE|
1268 sg_dma_len(sg));
1269 *(rp++)=cpu_to_le32(sg_dma_address(sg));
1270 *(rp++)=cpu_to_le32(0); /* bits 63-32 */
1271 todo -= sg_dma_len(sg);
1272 sg++;
1273 }
1274 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
1275 *(rp++)=cpu_to_le32(sg_dma_address(sg));
1276 *(rp++)=cpu_to_le32(0); /* bits 63-32 */
1277 offset += todo;
1278 }
1279 offset += padding;
1280 }
1281
1282 return rp;
1283}
1284
1285int cx25821_risc_databuffer_audio(struct pci_dev *pci,
1286 struct btcx_riscmem *risc,
1287 struct scatterlist *sglist,
1288 unsigned int bpl,
1289 unsigned int lines,
1290 unsigned int lpi)
1291{
1292 u32 instructions;
1293 __le32 *rp;
1294 int rc;
1295
1296 /* estimate risc mem: worst case is one write per page border +
1297 one write per scan line + syncs + jump (all 2 dwords). Here
1298 there is no padding and no sync. First DMA region may be smaller
1299 than PAGE_SIZE */
1300 /* Jump and write need an extra dword */
1301 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
1302 instructions += 1;
1303
1304 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
1305 return rc;
1306
1307
1308 /* write risc instructions */
1309 rp = risc->cpu;
1310 rp = cx25821_risc_field_audio(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi);
1311
1312 /* save pointer to jmp instruction address */
1313 risc->jmp = rp;
1314 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
1315 return 0;
1316}
1317
1318
1319int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,u32 reg, u32 mask, u32 value)
1320{
1321 __le32 *rp;
1322 int rc;
1323
1324 rc = btcx_riscmem_alloc(pci, risc, 4*16);
1325
1326 if (rc < 0)
1327 return rc;
1328
1329 /* write risc instructions */
1330 rp = risc->cpu;
1331
1332 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ1);
1333 *(rp++) = cpu_to_le32(reg);
1334 *(rp++) = cpu_to_le32(value);
1335 *(rp++) = cpu_to_le32(mask);
1336 *(rp++) = cpu_to_le32(RISC_JUMP);
1337 *(rp++) = cpu_to_le32(risc->dma);
1338 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1339 return 0;
1340}
1341
1342void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
1343{
1344 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
1345
1346 BUG_ON(in_interrupt());
1347 videobuf_waiton(&buf->vb, 0, 0);
1348 videobuf_dma_unmap(q, dma);
1349 videobuf_dma_free(dma);
1350 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
1351 buf->vb.state = VIDEOBUF_NEEDS_INIT;
1352}
1353
1354
1355static irqreturn_t cx25821_irq(int irq, void *dev_id)
1356{
1357 struct cx25821_dev *dev = dev_id;
1358 u32 pci_status, pci_mask;
1359 u32 vid_status;
1360 int i, handled = 0;
1361 u32 mask[8] = {1, 2, 4, 8, 16, 32, 64, 128};
1362
1363 pci_status = cx_read(PCI_INT_STAT);
1364 pci_mask = cx_read(PCI_INT_MSK);
1365
1366
1367 if (pci_status == 0)
1368 goto out;
1369
1370 for(i = 0; i < VID_CHANNEL_NUM; i++)
1371 {
1372 if(pci_status & mask[i])
1373 {
1374 vid_status = cx_read(dev->sram_channels[i].int_stat);
1375
1376 if(vid_status)
1377 handled += cx25821_video_irq(dev, i, vid_status);
1378
1379 cx_write(PCI_INT_STAT, mask[i]);
1380 }
1381 }
1382
1383out:
1384 return IRQ_RETVAL(handled);
1385}
1386
1387void cx25821_print_irqbits(char *name, char *tag, char **strings,
1388 int len, u32 bits, u32 mask)
1389{
1390 unsigned int i;
1391
1392 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
1393
1394 for (i = 0; i < len; i++) {
1395 if (!(bits & (1 << i)))
1396 continue;
1397 if (strings[i])
1398 printk(" %s", strings[i]);
1399 else
1400 printk(" %d", i);
1401 if (!(mask & (1 << i)))
1402 continue;
1403 printk("*");
1404 }
1405 printk("\n");
1406}
1407
1408struct cx25821_dev* cx25821_dev_get(struct pci_dev *pci)
1409{
1410 struct cx25821_dev *dev = pci_get_drvdata(pci);
1411 return dev;
1412}
1413
1414static int __devinit cx25821_initdev(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
1415{
1416 struct cx25821_dev *dev;
1417 int err = 0;
1418
1419 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1420 if (NULL == dev)
1421 return -ENOMEM;
1422
1423
1424 err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
1425 if (err < 0)
1426 goto fail_free;
1427
1428 /* pci init */
1429 dev->pci = pci_dev;
1430 if (pci_enable_device(pci_dev))
1431 {
1432 err = -EIO;
1433
1434 printk(KERN_INFO "pci enable failed! ");
1435
1436 goto fail_unregister_device;
1437 }
1438
1439 printk(KERN_INFO "cx25821 Athena pci enable ! \n");
1440
1441 if (cx25821_dev_setup(dev) < 0)
1442 {
1443 err = -EINVAL;
1444 goto fail_unregister_device;
1445 }
1446
1447 /* print pci info */
1448 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1449 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1450 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1451 "latency: %d, mmio: 0x%llx\n", dev->name,
1452 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1453 dev->pci_lat,
1454 (unsigned long long)dev->base_io_addr );
1455
1456
1457 pci_set_master(pci_dev);
1458 if (!pci_dma_supported(pci_dev, 0xffffffff))
1459 {
1460 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
1461 err = -EIO;
1462 goto fail_irq;
1463 }
1464
1465 err = request_irq(pci_dev->irq, cx25821_irq, IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
1466
1467 if (err < 0)
1468 {
1469 printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name, pci_dev->irq);
1470 goto fail_irq;
1471 }
1472
1473 return 0;
1474
1475fail_irq:
1476 printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ ! \n");
1477 cx25821_dev_unregister(dev);
1478
1479fail_unregister_device:
1480 v4l2_device_unregister(&dev->v4l2_dev);
1481
1482fail_free:
1483 kfree(dev);
1484 return err;
1485}
1486
1487static void __devexit cx25821_finidev(struct pci_dev *pci_dev)
1488{
1489 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1490 struct cx25821_dev *dev = get_cx25821(v4l2_dev);
1491
1492 cx25821_shutdown(dev);
1493 pci_disable_device(pci_dev);
1494
1495 /* unregister stuff */
1496 if( pci_dev->irq )
1497 free_irq(pci_dev->irq, dev);
1498
1499
1500 mutex_lock(&devlist);
1501 list_del(&dev->devlist);
1502 mutex_unlock(&devlist);
1503
1504 cx25821_dev_unregister(dev);
1505 v4l2_device_unregister(v4l2_dev);
1506 kfree(dev);
1507}
1508
1509static struct pci_device_id cx25821_pci_tbl[] = {
1510 {
1511 /* CX25821 Athena*/
1512 .vendor = 0x14f1,
1513 .device = 0x8210,
1514 .subvendor = 0x14f1,
1515 .subdevice = 0x0920,
1516 },
1517 {
1518 /* --- end of list --- */
1519 }
1520};
1521
1522MODULE_DEVICE_TABLE(pci, cx25821_pci_tbl);
1523
1524static struct pci_driver cx25821_pci_driver =
1525{
1526 .name = "cx25821",
1527 .id_table = cx25821_pci_tbl,
1528 .probe = cx25821_initdev,
1529 .remove = __devexit_p(cx25821_finidev),
1530 /* TODO */
1531 .suspend = NULL,
1532 .resume = NULL,
1533};
1534
1535static int cx25821_init(void)
1536{
1537 INIT_LIST_HEAD(&cx25821_devlist);
1538 printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n",
1539 (CX25821_VERSION_CODE >> 16) & 0xff,
1540 (CX25821_VERSION_CODE >> 8) & 0xff,
1541 CX25821_VERSION_CODE & 0xff);
1542 return pci_register_driver(&cx25821_pci_driver);
1543}
1544
1545static void cx25821_fini(void)
1546{
1547 pci_unregister_driver(&cx25821_pci_driver);
1548}
1549
1550
1551EXPORT_SYMBOL(cx25821_devlist);
1552EXPORT_SYMBOL(cx25821_sram_channels);
1553EXPORT_SYMBOL(cx25821_print_irqbits);
1554EXPORT_SYMBOL(cx25821_dev_get);
1555EXPORT_SYMBOL(cx25821_dev_unregister);
1556EXPORT_SYMBOL(cx25821_sram_channel_setup);
1557EXPORT_SYMBOL(cx25821_sram_channel_dump);
1558EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
1559EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
1560EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
1561EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
1562
1563module_init(cx25821_init);
1564module_exit(cx25821_fini);
1565
diff --git a/drivers/staging/cx25821/cx25821-gpio.c b/drivers/staging/cx25821/cx25821-gpio.c
new file mode 100644
index 00000000000..aa029fe3438
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.c
@@ -0,0 +1,116 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821.h"
24
25
26/********************* GPIO stuffs *********************/
27void cx25821_set_gpiopin_direction( struct cx25821_dev *dev,
28 int pin_number,
29 int pin_logic_value)
30{
31 int bit = pin_number;
32 u32 gpio_oe_reg = GPIO_LO_OE;
33 u32 gpio_register = 0;
34 u32 value = 0;
35
36 // Check for valid pinNumber
37 if ( pin_number >= 47 )
38 return;
39
40
41 if ( pin_number > 31 )
42 {
43 bit = pin_number - 31;
44 gpio_oe_reg = GPIO_HI_OE;
45 }
46
47 // Here we will make sure that the GPIOs 0 and 1 are output. keep the rest as is
48 gpio_register = cx_read( gpio_oe_reg );
49
50 if (pin_logic_value == 1)
51 {
52 value = gpio_register | Set_GPIO_Bit(bit) ;
53 }
54 else
55 {
56 value = gpio_register & Clear_GPIO_Bit(bit) ;
57 }
58
59 cx_write( gpio_oe_reg, value );
60}
61
62static void cx25821_set_gpiopin_logicvalue( struct cx25821_dev *dev,
63 int pin_number,
64 int pin_logic_value)
65{
66 int bit = pin_number;
67 u32 gpio_reg = GPIO_LO;
68 u32 value = 0;
69
70
71 // Check for valid pinNumber
72 if (pin_number >= 47)
73 return;
74
75 cx25821_set_gpiopin_direction(dev, pin_number, 0); // change to output direction
76
77
78 if ( pin_number > 31 )
79 {
80 bit = pin_number - 31;
81 gpio_reg = GPIO_HI;
82 }
83
84 value = cx_read( gpio_reg );
85
86
87 if (pin_logic_value == 0)
88 {
89 value &= Clear_GPIO_Bit(bit);
90 }
91 else
92 {
93 value |= Set_GPIO_Bit(bit);
94 }
95
96 cx_write( gpio_reg, value);
97}
98
99void cx25821_gpio_init(struct cx25821_dev *dev)
100{
101 if( dev == NULL )
102 {
103 return;
104 }
105
106 switch (dev->board)
107 {
108 case CX25821_BOARD_CONEXANT_ATHENA10:
109 default:
110 //set GPIO 5 to select the path for Medusa/Athena
111 cx25821_set_gpiopin_logicvalue(dev, 5, 1);
112 mdelay(20);
113 break;
114 }
115
116}
diff --git a/drivers/staging/cx25821/cx25821-gpio.h b/drivers/staging/cx25821/cx25821-gpio.h
new file mode 100644
index 00000000000..2dd938dbdc4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.h
@@ -0,0 +1,3 @@
1
2void cx25821_gpio_init(struct athena_dev *dev);
3
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
new file mode 100644
index 00000000000..16303f80d4f
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -0,0 +1,437 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821.h"
25#include <linux/i2c.h>
26
27
28static unsigned int i2c_debug;
29module_param(i2c_debug, int, 0644);
30MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
31
32static unsigned int i2c_scan=0;
33module_param(i2c_scan, int, 0444);
34MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
35
36#define dprintk(level, fmt, arg...)\
37 do { if (i2c_debug >= level)\
38 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
39 } while (0)
40
41#define I2C_WAIT_DELAY 32
42#define I2C_WAIT_RETRY 64
43
44#define I2C_EXTEND (1 << 3)
45#define I2C_NOSTOP (1 << 4)
46
47
48static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
49{
50 struct cx25821_i2c *bus = i2c_adap->algo_data;
51 struct cx25821_dev *dev = bus->dev;
52 return cx_read(bus->reg_stat) & 0x01;
53}
54
55static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
56{
57 struct cx25821_i2c *bus = i2c_adap->algo_data;
58 struct cx25821_dev *dev = bus->dev;
59 return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
60}
61
62static int i2c_wait_done(struct i2c_adapter *i2c_adap)
63{
64 int count;
65
66 for (count = 0; count < I2C_WAIT_RETRY; count++) {
67 if (!i2c_is_busy(i2c_adap))
68 break;
69 udelay(I2C_WAIT_DELAY);
70 }
71
72 if (I2C_WAIT_RETRY == count)
73 return 0;
74
75 return 1;
76}
77
78static int i2c_sendbytes(struct i2c_adapter *i2c_adap, const struct i2c_msg *msg, int joined_rlen)
79{
80 struct cx25821_i2c *bus = i2c_adap->algo_data;
81 struct cx25821_dev *dev = bus->dev;
82 u32 wdata, addr, ctrl;
83 int retval, cnt;
84
85 if (joined_rlen)
86 dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, msg->len, joined_rlen);
87 else
88 dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len);
89
90 /* Deal with i2c probe functions with zero payload */
91 if (msg->len == 0)
92 {
93 cx_write(bus->reg_addr, msg->addr << 25);
94 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
95
96 if (!i2c_wait_done(i2c_adap))
97 return -EIO;
98
99 if (!i2c_slave_did_ack(i2c_adap))
100 return -EIO;
101
102 dprintk(1, "%s() returns 0\n", __func__);
103 return 0;
104 }
105
106 /* dev, reg + first byte */
107 addr = (msg->addr << 25) | msg->buf[0];
108 wdata = msg->buf[0];
109
110 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
111
112 if (msg->len > 1)
113 ctrl |= I2C_NOSTOP | I2C_EXTEND;
114 else if (joined_rlen)
115 ctrl |= I2C_NOSTOP;
116
117 cx_write(bus->reg_addr, addr);
118 cx_write(bus->reg_wdata, wdata);
119 cx_write(bus->reg_ctrl, ctrl);
120
121 retval = i2c_wait_done(i2c_adap);
122 if (retval < 0)
123 goto err;
124
125 if (retval == 0)
126 goto eio;
127
128 if (i2c_debug)
129 {
130 if (!(ctrl & I2C_NOSTOP))
131 printk(" >\n");
132 }
133
134 for (cnt = 1; cnt < msg->len; cnt++) {
135 /* following bytes */
136 wdata = msg->buf[cnt];
137 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
138
139 if (cnt < msg->len - 1)
140 ctrl |= I2C_NOSTOP | I2C_EXTEND;
141 else if (joined_rlen)
142 ctrl |= I2C_NOSTOP;
143
144 cx_write(bus->reg_addr, addr);
145 cx_write(bus->reg_wdata, wdata);
146 cx_write(bus->reg_ctrl, ctrl);
147
148 retval = i2c_wait_done(i2c_adap);
149 if (retval < 0)
150 goto err;
151
152 if (retval == 0)
153 goto eio;
154
155 if (i2c_debug)
156 {
157 dprintk(1, " %02x", msg->buf[cnt]);
158 if (!(ctrl & I2C_NOSTOP))
159 dprintk(1, " >\n");
160 }
161 }
162
163 return msg->len;
164
165 eio:
166 retval = -EIO;
167 err:
168 if (i2c_debug)
169 printk(KERN_ERR " ERR: %d\n", retval);
170 return retval;
171}
172
173static int i2c_readbytes(struct i2c_adapter *i2c_adap, const struct i2c_msg *msg, int joined)
174{
175 struct cx25821_i2c *bus = i2c_adap->algo_data;
176 struct cx25821_dev *dev = bus->dev;
177 u32 ctrl, cnt;
178 int retval;
179
180
181 if (i2c_debug && !joined)
182 dprintk(1, "6-%s(msg->len=%d)\n", __func__, msg->len);
183
184 /* Deal with i2c probe functions with zero payload */
185 if (msg->len == 0) {
186 cx_write(bus->reg_addr, msg->addr << 25);
187 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
188 if (!i2c_wait_done(i2c_adap))
189 return -EIO;
190 if (!i2c_slave_did_ack(i2c_adap))
191 return -EIO;
192
193
194 dprintk(1, "%s() returns 0\n", __func__);
195 return 0;
196 }
197
198 if (i2c_debug) {
199 if (joined)
200 dprintk(1, " R");
201 else
202 dprintk(1, " <R %02x", (msg->addr << 1) + 1);
203 }
204
205 for (cnt = 0; cnt < msg->len; cnt++) {
206
207 ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
208
209 if (cnt < msg->len - 1)
210 ctrl |= I2C_NOSTOP | I2C_EXTEND;
211
212
213 cx_write(bus->reg_addr, msg->addr << 25);
214 cx_write(bus->reg_ctrl, ctrl);
215
216 retval = i2c_wait_done(i2c_adap);
217 if (retval < 0)
218 goto err;
219 if (retval == 0)
220 goto eio;
221 msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
222
223 if (i2c_debug) {
224 dprintk(1, " %02x", msg->buf[cnt]);
225 if (!(ctrl & I2C_NOSTOP))
226 dprintk(1, " >\n");
227 }
228 }
229
230 return msg->len;
231 eio:
232 retval = -EIO;
233 err:
234 if (i2c_debug)
235 printk(KERN_ERR " ERR: %d\n", retval);
236 return retval;
237}
238
239static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
240{
241 struct cx25821_i2c *bus = i2c_adap->algo_data;
242 struct cx25821_dev *dev = bus->dev;
243 int i, retval = 0;
244
245 dprintk(1, "%s(num = %d)\n", __func__, num);
246
247 for (i = 0 ; i < num; i++)
248 {
249 dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
250 __func__, num, msgs[i].addr, msgs[i].len);
251
252 if (msgs[i].flags & I2C_M_RD)
253 {
254 /* read */
255 retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
256 }
257 else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
258 msgs[i].addr == msgs[i + 1].addr)
259 {
260 /* write then read from same address */
261 retval = i2c_sendbytes(i2c_adap, &msgs[i], msgs[i + 1].len);
262
263 if (retval < 0)
264 goto err;
265 i++;
266 retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
267 }
268 else
269 {
270 /* write */
271 retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
272 }
273
274 if (retval < 0)
275 goto err;
276 }
277 return num;
278
279 err:
280 return retval;
281}
282
283
284static u32 cx25821_functionality(struct i2c_adapter *adap)
285{
286 return I2C_FUNC_SMBUS_EMUL |
287 I2C_FUNC_I2C |
288 I2C_FUNC_SMBUS_WORD_DATA |
289 I2C_FUNC_SMBUS_READ_WORD_DATA |
290 I2C_FUNC_SMBUS_WRITE_WORD_DATA;
291}
292
293static struct i2c_algorithm cx25821_i2c_algo_template = {
294 .master_xfer = i2c_xfer,
295 .functionality = cx25821_functionality,
296};
297
298
299static struct i2c_adapter cx25821_i2c_adap_template = {
300 .name = "cx25821",
301 .owner = THIS_MODULE,
302 .id = I2C_HW_B_CX25821,
303 .algo = &cx25821_i2c_algo_template,
304};
305
306static struct i2c_client cx25821_i2c_client_template = {
307 .name = "cx25821 internal",
308};
309
310/* init + register i2c algo-bit adapter */
311int cx25821_i2c_register(struct cx25821_i2c *bus)
312{
313 struct cx25821_dev *dev = bus->dev;
314
315 dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);
316
317 memcpy(&bus->i2c_adap, &cx25821_i2c_adap_template,
318 sizeof(bus->i2c_adap));
319 memcpy(&bus->i2c_algo, &cx25821_i2c_algo_template,
320 sizeof(bus->i2c_algo));
321 memcpy(&bus->i2c_client, &cx25821_i2c_client_template,
322 sizeof(bus->i2c_client));
323
324 bus->i2c_adap.dev.parent = &dev->pci->dev;
325
326 strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
327
328 bus->i2c_algo.data = bus;
329 bus->i2c_adap.algo_data = bus;
330 i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
331 i2c_add_adapter(&bus->i2c_adap);
332
333 bus->i2c_client.adapter = &bus->i2c_adap;
334
335 //set up the I2c
336 bus->i2c_client.addr = (0x88>>1);
337
338 return bus->i2c_rc;
339}
340
341int cx25821_i2c_unregister(struct cx25821_i2c *bus)
342{
343 i2c_del_adapter(&bus->i2c_adap);
344 return 0;
345}
346
347void cx25821_av_clk(struct cx25821_dev *dev, int enable)
348{
349 /* write 0 to bus 2 addr 0x144 via i2x_xfer() */
350 char buffer[3];
351 struct i2c_msg msg;
352 dprintk(1, "%s(enabled = %d)\n", __func__, enable);
353
354 /* Register 0x144 */
355 buffer[0] = 0x01;
356 buffer[1] = 0x44;
357 if (enable == 1)
358 buffer[2] = 0x05;
359 else
360 buffer[2] = 0x00;
361
362 msg.addr = 0x44;
363 msg.flags = I2C_M_TEN;
364 msg.len = 3;
365 msg.buf = buffer;
366
367 i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1);
368}
369
370
371int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
372{
373 struct i2c_client *client = &bus->i2c_client;
374 int retval = 0;
375 int v = 0;
376 u8 addr[2] = {0, 0};
377 u8 buf[4] = {0,0,0,0};
378
379 struct i2c_msg msgs[2]={
380 {
381 .addr = client->addr,
382 .flags = 0,
383 .len = 2,
384 .buf = addr,
385 }, {
386 .addr = client->addr,
387 .flags = I2C_M_RD,
388 .len = 4,
389 .buf = buf,
390 }
391 };
392
393
394 addr[0] = (reg_addr>>8);
395 addr[1] = (reg_addr & 0xff);
396 msgs[0].addr = 0x44;
397 msgs[1].addr = 0x44;
398
399 retval = i2c_xfer(client->adapter, msgs, 2);
400
401 v = (buf[3]<<24) | (buf[2]<<16) | (buf[1]<<8) | buf[0];
402 *value = v;
403
404 return v;
405}
406
407
408int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value)
409{
410 struct i2c_client *client = &bus->i2c_client;
411 int retval = 0;
412 u8 buf[6] = {0, 0, 0, 0, 0, 0};
413
414 struct i2c_msg msgs[1]={
415 {
416 .addr = client->addr,
417 .flags = 0,
418 .len = 6,
419 .buf = buf,
420 }
421 };
422
423
424 buf[0] = reg_addr>>8;
425 buf[1] = reg_addr & 0xff;
426 buf[5] = (value>>24) & 0xff;
427 buf[4] = (value>>16) & 0xff;
428 buf[3] = (value>>8) & 0xff;
429 buf[2] = value & 0xff;
430 client->flags = 0;
431 msgs[0].addr = 0x44;
432
433 retval = i2c_xfer(client->adapter, msgs, 1);
434
435 return retval;
436}
437
diff --git a/drivers/staging/cx25821/cx25821-medusa-defines.h b/drivers/staging/cx25821/cx25821-medusa-defines.h
new file mode 100644
index 00000000000..75161e488e1
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-defines.h
@@ -0,0 +1,51 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _MEDUSA_DEF_H_
24#define _MEDUSA_DEF_H_
25
26// Video deocder that we supported
27#define VDEC_A 0
28#define VDEC_B 1
29#define VDEC_C 2
30#define VDEC_D 3
31#define VDEC_E 4
32#define VDEC_F 5
33#define VDEC_G 6
34#define VDEC_H 7
35
36//#define AUTO_SWITCH_BIT[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
37
38// The following bit position enables automatic source switching for decoder A-H.
39// Display index per camera.
40//#define VDEC_INDEX[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
41
42// Select input bit to video decoder A-H.
43//#define CH_SRC_SEL_BIT[] = {24, 25, 26, 27, 28, 29, 30, 31};
44
45// end of display sequence
46#define END_OF_SEQ 0xF;
47
48// registry string size
49#define MAX_REGISTRY_SZ 40;
50
51#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-reg.h b/drivers/staging/cx25821/cx25821-medusa-reg.h
new file mode 100644
index 00000000000..b877cd284aa
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-reg.h
@@ -0,0 +1,456 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __MEDUSA_REGISTERS__
24#define __MEDUSA_REGISTERS__
25
26// Serial Slave Registers
27#define HOST_REGISTER1 0x0000
28#define HOST_REGISTER2 0x0001
29
30// Chip Configuration Registers
31#define CHIP_CTRL 0x0100
32#define AFE_AB_CTRL 0x0104
33#define AFE_CD_CTRL 0x0108
34#define AFE_EF_CTRL 0x010C
35#define AFE_GH_CTRL 0x0110
36#define DENC_AB_CTRL 0x0114
37#define BYP_AB_CTRL 0x0118
38#define MON_A_CTRL 0x011C
39#define DISP_SEQ_A 0x0120
40#define DISP_SEQ_B 0x0124
41#define DISP_AB_CNT 0x0128
42#define DISP_CD_CNT 0x012C
43#define DISP_EF_CNT 0x0130
44#define DISP_GH_CNT 0x0134
45#define DISP_IJ_CNT 0x0138
46#define PIN_OE_CTRL 0x013C
47#define PIN_SPD_CTRL 0x0140
48#define PIN_SPD_CTRL2 0x0144
49#define IRQ_STAT_CTRL 0x0148
50#define POWER_CTRL_AB 0x014C
51#define POWER_CTRL_CD 0x0150
52#define POWER_CTRL_EF 0x0154
53#define POWER_CTRL_GH 0x0158
54#define TUNE_CTRL 0x015C
55#define BIAS_CTRL 0x0160
56#define AFE_AB_DIAG_CTRL 0x0164
57#define AFE_CD_DIAG_CTRL 0x0168
58#define AFE_EF_DIAG_CTRL 0x016C
59#define AFE_GH_DIAG_CTRL 0x0170
60#define PLL_AB_DIAG_CTRL 0x0174
61#define PLL_CD_DIAG_CTRL 0x0178
62#define PLL_EF_DIAG_CTRL 0x017C
63#define PLL_GH_DIAG_CTRL 0x0180
64#define TEST_CTRL 0x0184
65#define BIST_STAT 0x0188
66#define BIST_STAT2 0x018C
67#define BIST_VID_PLL_AB_STAT 0x0190
68#define BIST_VID_PLL_CD_STAT 0x0194
69#define BIST_VID_PLL_EF_STAT 0x0198
70#define BIST_VID_PLL_GH_STAT 0x019C
71#define DLL_DIAG_CTRL 0x01A0
72#define DEV_CH_ID_CTRL 0x01A4
73#define ABIST_CTRL_STATUS 0x01A8
74#define ABIST_FREQ 0x01AC
75#define ABIST_GOERT_SHIFT 0x01B0
76#define ABIST_COEF12 0x01B4
77#define ABIST_COEF34 0x01B8
78#define ABIST_COEF56 0x01BC
79#define ABIST_COEF7_SNR 0x01C0
80#define ABIST_ADC_CAL 0x01C4
81#define ABIST_BIN1_VGA0 0x01C8
82#define ABIST_BIN2_VGA1 0x01CC
83#define ABIST_BIN3_VGA2 0x01D0
84#define ABIST_BIN4_VGA3 0x01D4
85#define ABIST_BIN5_VGA4 0x01D8
86#define ABIST_BIN6_VGA5 0x01DC
87#define ABIST_BIN7_VGA6 0x0x1E0
88#define ABIST_CLAMP_A 0x0x1E4
89#define ABIST_CLAMP_B 0x0x1E8
90#define ABIST_CLAMP_C 0x01EC
91#define ABIST_CLAMP_D 0x01F0
92#define ABIST_CLAMP_E 0x01F4
93#define ABIST_CLAMP_F 0x01F8
94
95// Digital Video Encoder A Registers
96#define DENC_A_REG_1 0x0200
97#define DENC_A_REG_2 0x0204
98#define DENC_A_REG_3 0x0208
99#define DENC_A_REG_4 0x020C
100#define DENC_A_REG_5 0x0210
101#define DENC_A_REG_6 0x0214
102#define DENC_A_REG_7 0x0218
103#define DENC_A_REG_8 0x021C
104
105// Digital Video Encoder B Registers
106#define DENC_B_REG_1 0x0300
107#define DENC_B_REG_2 0x0304
108#define DENC_B_REG_3 0x0308
109#define DENC_B_REG_4 0x030C
110#define DENC_B_REG_5 0x0310
111#define DENC_B_REG_6 0x0314
112#define DENC_B_REG_7 0x0318
113#define DENC_B_REG_8 0x031C
114
115// Video Decoder A Registers
116#define MODE_CTRL 0x1000
117#define OUT_CTRL1 0x1004
118#define OUT_CTRL_NS 0x1008
119#define GEN_STAT 0x100C
120#define INT_STAT_MASK 0x1010
121#define LUMA_CTRL 0x1014
122#define CHROMA_CTRL 0x1018
123#define CRUSH_CTRL 0x101C
124#define HORIZ_TIM_CTRL 0x1020
125#define VERT_TIM_CTRL 0x1024
126#define MISC_TIM_CTRL 0x1028
127#define FIELD_COUNT 0x102C
128#define HSCALE_CTRL 0x1030
129#define VSCALE_CTRL 0x1034
130#define MAN_VGA_CTRL 0x1038
131#define MAN_AGC_CTRL 0x103C
132#define DFE_CTRL1 0x1040
133#define DFE_CTRL2 0x1044
134#define DFE_CTRL3 0x1048
135#define PLL_CTRL 0x104C
136#define PLL_CTRL_FAST 0x1050
137#define HTL_CTRL 0x1054
138#define SRC_CFG 0x1058
139#define SC_STEP_SIZE 0x105C
140#define SC_CONVERGE_CTRL 0x1060
141#define SC_LOOP_CTRL 0x1064
142#define COMB_2D_HFS_CFG 0x1068
143#define COMB_2D_HFD_CFG 0x106C
144#define COMB_2D_LF_CFG 0x1070
145#define COMB_2D_BLEND 0x1074
146#define COMB_MISC_CTRL 0x1078
147#define COMB_FLAT_THRESH_CTRL 0x107C
148#define COMB_TEST 0x1080
149#define BP_MISC_CTRL 0x1084
150#define VCR_DET_CTRL 0x1088
151#define NOISE_DET_CTRL 0x108C
152#define COMB_FLAT_NOISE_CTRL 0x1090
153#define VERSION 0x11F8
154#define SOFT_RST_CTRL 0x11FC
155
156// Video Decoder B Registers
157#define VDEC_B_MODE_CTRL 0x1200
158#define VDEC_B_OUT_CTRL1 0x1204
159#define VDEC_B_OUT_CTRL_NS 0x1208
160#define VDEC_B_GEN_STAT 0x120C
161#define VDEC_B_INT_STAT_MASK 0x1210
162#define VDEC_B_LUMA_CTRL 0x1214
163#define VDEC_B_CHROMA_CTRL 0x1218
164#define VDEC_B_CRUSH_CTRL 0x121C
165#define VDEC_B_HORIZ_TIM_CTRL 0x1220
166#define VDEC_B_VERT_TIM_CTRL 0x1224
167#define VDEC_B_MISC_TIM_CTRL 0x1228
168#define VDEC_B_FIELD_COUNT 0x122C
169#define VDEC_B_HSCALE_CTRL 0x1230
170#define VDEC_B_VSCALE_CTRL 0x1234
171#define VDEC_B_MAN_VGA_CTRL 0x1238
172#define VDEC_B_MAN_AGC_CTRL 0x123C
173#define VDEC_B_DFE_CTRL1 0x1240
174#define VDEC_B_DFE_CTRL2 0x1244
175#define VDEC_B_DFE_CTRL3 0x1248
176#define VDEC_B_PLL_CTRL 0x124C
177#define VDEC_B_PLL_CTRL_FAST 0x1250
178#define VDEC_B_HTL_CTRL 0x1254
179#define VDEC_B_SRC_CFG 0x1258
180#define VDEC_B_SC_STEP_SIZE 0x125C
181#define VDEC_B_SC_CONVERGE_CTRL 0x1260
182#define VDEC_B_SC_LOOP_CTRL 0x1264
183#define VDEC_B_COMB_2D_HFS_CFG 0x1268
184#define VDEC_B_COMB_2D_HFD_CFG 0x126C
185#define VDEC_B_COMB_2D_LF_CFG 0x1270
186#define VDEC_B_COMB_2D_BLEND 0x1274
187#define VDEC_B_COMB_MISC_CTRL 0x1278
188#define VDEC_B_COMB_FLAT_THRESH_CTRL 0x127C
189#define VDEC_B_COMB_TEST 0x1280
190#define VDEC_B_BP_MISC_CTRL 0x1284
191#define VDEC_B_VCR_DET_CTRL 0x1288
192#define VDEC_B_NOISE_DET_CTRL 0x128C
193#define VDEC_B_COMB_FLAT_NOISE_CTRL 0x1290
194#define VDEC_B_VERSION 0x13F8
195#define VDEC_B_SOFT_RST_CTRL 0x13FC
196
197// Video Decoder C Registers
198#define VDEC_C_MODE_CTRL 0x1400
199#define VDEC_C_OUT_CTRL1 0x1404
200#define VDEC_C_OUT_CTRL_NS 0x1408
201#define VDEC_C_GEN_STAT 0x140C
202#define VDEC_C_INT_STAT_MASK 0x1410
203#define VDEC_C_LUMA_CTRL 0x1414
204#define VDEC_C_CHROMA_CTRL 0x1418
205#define VDEC_C_CRUSH_CTRL 0x141C
206#define VDEC_C_HORIZ_TIM_CTRL 0x1420
207#define VDEC_C_VERT_TIM_CTRL 0x1424
208#define VDEC_C_MISC_TIM_CTRL 0x1428
209#define VDEC_C_FIELD_COUNT 0x142C
210#define VDEC_C_HSCALE_CTRL 0x1430
211#define VDEC_C_VSCALE_CTRL 0x1434
212#define VDEC_C_MAN_VGA_CTRL 0x1438
213#define VDEC_C_MAN_AGC_CTRL 0x143C
214#define VDEC_C_DFE_CTRL1 0x1440
215#define VDEC_C_DFE_CTRL2 0x1444
216#define VDEC_C_DFE_CTRL3 0x1448
217#define VDEC_C_PLL_CTRL 0x144C
218#define VDEC_C_PLL_CTRL_FAST 0x1450
219#define VDEC_C_HTL_CTRL 0x1454
220#define VDEC_C_SRC_CFG 0x1458
221#define VDEC_C_SC_STEP_SIZE 0x145C
222#define VDEC_C_SC_CONVERGE_CTRL 0x1460
223#define VDEC_C_SC_LOOP_CTRL 0x1464
224#define VDEC_C_COMB_2D_HFS_CFG 0x1468
225#define VDEC_C_COMB_2D_HFD_CFG 0x146C
226#define VDEC_C_COMB_2D_LF_CFG 0x1470
227#define VDEC_C_COMB_2D_BLEND 0x1474
228#define VDEC_C_COMB_MISC_CTRL 0x1478
229#define VDEC_C_COMB_FLAT_THRESH_CTRL 0x147C
230#define VDEC_C_COMB_TEST 0x1480
231#define VDEC_C_BP_MISC_CTRL 0x1484
232#define VDEC_C_VCR_DET_CTRL 0x1488
233#define VDEC_C_NOISE_DET_CTRL 0x148C
234#define VDEC_C_COMB_FLAT_NOISE_CTRL 0x1490
235#define VDEC_C_VERSION 0x15F8
236#define VDEC_C_SOFT_RST_CTRL 0x15FC
237
238// Video Decoder D Registers
239#define VDEC_D_MODE_CTRL 0x1600
240#define VDEC_D_OUT_CTRL1 0x1604
241#define VDEC_D_OUT_CTRL_NS 0x1608
242#define VDEC_D_GEN_STAT 0x160C
243#define VDEC_D_INT_STAT_MASK 0x1610
244#define VDEC_D_LUMA_CTRL 0x1614
245#define VDEC_D_CHROMA_CTRL 0x1618
246#define VDEC_D_CRUSH_CTRL 0x161C
247#define VDEC_D_HORIZ_TIM_CTRL 0x1620
248#define VDEC_D_VERT_TIM_CTRL 0x1624
249#define VDEC_D_MISC_TIM_CTRL 0x1628
250#define VDEC_D_FIELD_COUNT 0x162C
251#define VDEC_D_HSCALE_CTRL 0x1630
252#define VDEC_D_VSCALE_CTRL 0x1634
253#define VDEC_D_MAN_VGA_CTRL 0x1638
254#define VDEC_D_MAN_AGC_CTRL 0x163C
255#define VDEC_D_DFE_CTRL1 0x1640
256#define VDEC_D_DFE_CTRL2 0x1644
257#define VDEC_D_DFE_CTRL3 0x1648
258#define VDEC_D_PLL_CTRL 0x164C
259#define VDEC_D_PLL_CTRL_FAST 0x1650
260#define VDEC_D_HTL_CTRL 0x1654
261#define VDEC_D_SRC_CFG 0x1658
262#define VDEC_D_SC_STEP_SIZE 0x165C
263#define VDEC_D_SC_CONVERGE_CTRL 0x1660
264#define VDEC_D_SC_LOOP_CTRL 0x1664
265#define VDEC_D_COMB_2D_HFS_CFG 0x1668
266#define VDEC_D_COMB_2D_HFD_CFG 0x166C
267#define VDEC_D_COMB_2D_LF_CFG 0x1670
268#define VDEC_D_COMB_2D_BLEND 0x1674
269#define VDEC_D_COMB_MISC_CTRL 0x1678
270#define VDEC_D_COMB_FLAT_THRESH_CTRL 0x167C
271#define VDEC_D_COMB_TEST 0x1680
272#define VDEC_D_BP_MISC_CTRL 0x1684
273#define VDEC_D_VCR_DET_CTRL 0x1688
274#define VDEC_D_NOISE_DET_CTRL 0x168C
275#define VDEC_D_COMB_FLAT_NOISE_CTRL 0x1690
276#define VDEC_D_VERSION 0x17F8
277#define VDEC_D_SOFT_RST_CTRL 0x17FC
278
279// Video Decoder E Registers
280#define VDEC_E_MODE_CTRL 0x1800
281#define VDEC_E_OUT_CTRL1 0x1804
282#define VDEC_E_OUT_CTRL_NS 0x1808
283#define VDEC_E_GEN_STAT 0x180C
284#define VDEC_E_INT_STAT_MASK 0x1810
285#define VDEC_E_LUMA_CTRL 0x1814
286#define VDEC_E_CHROMA_CTRL 0x1818
287#define VDEC_E_CRUSH_CTRL 0x181C
288#define VDEC_E_HORIZ_TIM_CTRL 0x1820
289#define VDEC_E_VERT_TIM_CTRL 0x1824
290#define VDEC_E_MISC_TIM_CTRL 0x1828
291#define VDEC_E_FIELD_COUNT 0x182C
292#define VDEC_E_HSCALE_CTRL 0x1830
293#define VDEC_E_VSCALE_CTRL 0x1834
294#define VDEC_E_MAN_VGA_CTRL 0x1838
295#define VDEC_E_MAN_AGC_CTRL 0x183C
296#define VDEC_E_DFE_CTRL1 0x1840
297#define VDEC_E_DFE_CTRL2 0x1844
298#define VDEC_E_DFE_CTRL3 0x1848
299#define VDEC_E_PLL_CTRL 0x184C
300#define VDEC_E_PLL_CTRL_FAST 0x1850
301#define VDEC_E_HTL_CTRL 0x1854
302#define VDEC_E_SRC_CFG 0x1858
303#define VDEC_E_SC_STEP_SIZE 0x185C
304#define VDEC_E_SC_CONVERGE_CTRL 0x1860
305#define VDEC_E_SC_LOOP_CTRL 0x1864
306#define VDEC_E_COMB_2D_HFS_CFG 0x1868
307#define VDEC_E_COMB_2D_HFD_CFG 0x186C
308#define VDEC_E_COMB_2D_LF_CFG 0x1870
309#define VDEC_E_COMB_2D_BLEND 0x1874
310#define VDEC_E_COMB_MISC_CTRL 0x1878
311#define VDEC_E_COMB_FLAT_THRESH_CTRL 0x187C
312#define VDEC_E_COMB_TEST 0x1880
313#define VDEC_E_BP_MISC_CTRL 0x1884
314#define VDEC_E_VCR_DET_CTRL 0x1888
315#define VDEC_E_NOISE_DET_CTRL 0x188C
316#define VDEC_E_COMB_FLAT_NOISE_CTRL 0x1890
317#define VDEC_E_VERSION 0x19F8
318#define VDEC_E_SOFT_RST_CTRL 0x19FC
319
320// Video Decoder F Registers
321#define VDEC_F_MODE_CTRL 0x1A00
322#define VDEC_F_OUT_CTRL1 0x1A04
323#define VDEC_F_OUT_CTRL_NS 0x1A08
324#define VDEC_F_GEN_STAT 0x1A0C
325#define VDEC_F_INT_STAT_MASK 0x1A10
326#define VDEC_F_LUMA_CTRL 0x1A14
327#define VDEC_F_CHROMA_CTRL 0x1A18
328#define VDEC_F_CRUSH_CTRL 0x1A1C
329#define VDEC_F_HORIZ_TIM_CTRL 0x1A20
330#define VDEC_F_VERT_TIM_CTRL 0x1A24
331#define VDEC_F_MISC_TIM_CTRL 0x1A28
332#define VDEC_F_FIELD_COUNT 0x1A2C
333#define VDEC_F_HSCALE_CTRL 0x1A30
334#define VDEC_F_VSCALE_CTRL 0x1A34
335#define VDEC_F_MAN_VGA_CTRL 0x1A38
336#define VDEC_F_MAN_AGC_CTRL 0x1A3C
337#define VDEC_F_DFE_CTRL1 0x1A40
338#define VDEC_F_DFE_CTRL2 0x1A44
339#define VDEC_F_DFE_CTRL3 0x1A48
340#define VDEC_F_PLL_CTRL 0x1A4C
341#define VDEC_F_PLL_CTRL_FAST 0x1A50
342#define VDEC_F_HTL_CTRL 0x1A54
343#define VDEC_F_SRC_CFG 0x1A58
344#define VDEC_F_SC_STEP_SIZE 0x1A5C
345#define VDEC_F_SC_CONVERGE_CTRL 0x1A60
346#define VDEC_F_SC_LOOP_CTRL 0x1A64
347#define VDEC_F_COMB_2D_HFS_CFG 0x1A68
348#define VDEC_F_COMB_2D_HFD_CFG 0x1A6C
349#define VDEC_F_COMB_2D_LF_CFG 0x1A70
350#define VDEC_F_COMB_2D_BLEND 0x1A74
351#define VDEC_F_COMB_MISC_CTRL 0x1A78
352#define VDEC_F_COMB_FLAT_THRESH_CTRL 0x1A7C
353#define VDEC_F_COMB_TEST 0x1A80
354#define VDEC_F_BP_MISC_CTRL 0x1A84
355#define VDEC_F_VCR_DET_CTRL 0x1A88
356#define VDEC_F_NOISE_DET_CTRL 0x1A8C
357#define VDEC_F_COMB_FLAT_NOISE_CTRL 0x1A90
358#define VDEC_F_VERSION 0x1BF8
359#define VDEC_F_SOFT_RST_CTRL 0x1BFC
360
361// Video Decoder G Registers
362#define VDEC_G_MODE_CTRL 0x1C00
363#define VDEC_G_OUT_CTRL1 0x1C04
364#define VDEC_G_OUT_CTRL_NS 0x1C08
365#define VDEC_G_GEN_STAT 0x1C0C
366#define VDEC_G_INT_STAT_MASK 0x1C10
367#define VDEC_G_LUMA_CTRL 0x1C14
368#define VDEC_G_CHROMA_CTRL 0x1C18
369#define VDEC_G_CRUSH_CTRL 0x1C1C
370#define VDEC_G_HORIZ_TIM_CTRL 0x1C20
371#define VDEC_G_VERT_TIM_CTRL 0x1C24
372#define VDEC_G_MISC_TIM_CTRL 0x1C28
373#define VDEC_G_FIELD_COUNT 0x1C2C
374#define VDEC_G_HSCALE_CTRL 0x1C30
375#define VDEC_G_VSCALE_CTRL 0x1C34
376#define VDEC_G_MAN_VGA_CTRL 0x1C38
377#define VDEC_G_MAN_AGC_CTRL 0x1C3C
378#define VDEC_G_DFE_CTRL1 0x1C40
379#define VDEC_G_DFE_CTRL2 0x1C44
380#define VDEC_G_DFE_CTRL3 0x1C48
381#define VDEC_G_PLL_CTRL 0x1C4C
382#define VDEC_G_PLL_CTRL_FAST 0x1C50
383#define VDEC_G_HTL_CTRL 0x1C54
384#define VDEC_G_SRC_CFG 0x1C58
385#define VDEC_G_SC_STEP_SIZE 0x1C5C
386#define VDEC_G_SC_CONVERGE_CTRL 0x1C60
387#define VDEC_G_SC_LOOP_CTRL 0x1C64
388#define VDEC_G_COMB_2D_HFS_CFG 0x1C68
389#define VDEC_G_COMB_2D_HFD_CFG 0x1C6C
390#define VDEC_G_COMB_2D_LF_CFG 0x1C70
391#define VDEC_G_COMB_2D_BLEND 0x1C74
392#define VDEC_G_COMB_MISC_CTRL 0x1C78
393#define VDEC_G_COMB_FLAT_THRESH_CTRL 0x1C7C
394#define VDEC_G_COMB_TEST 0x1C80
395#define VDEC_G_BP_MISC_CTRL 0x1C84
396#define VDEC_G_VCR_DET_CTRL 0x1C88
397#define VDEC_G_NOISE_DET_CTRL 0x1C8C
398#define VDEC_G_COMB_FLAT_NOISE_CTRL 0x1C90
399#define VDEC_G_VERSION 0x1DF8
400#define VDEC_G_SOFT_RST_CTRL 0x1DFC
401
402// Video Decoder H Registers
403#define VDEC_H_MODE_CTRL 0x1E00
404#define VDEC_H_OUT_CTRL1 0x1E04
405#define VDEC_H_OUT_CTRL_NS 0x1E08
406#define VDEC_H_GEN_STAT 0x1E0C
407#define VDEC_H_INT_STAT_MASK 0x1E1E
408#define VDEC_H_LUMA_CTRL 0x1E14
409#define VDEC_H_CHROMA_CTRL 0x1E18
410#define VDEC_H_CRUSH_CTRL 0x1E1C
411#define VDEC_H_HORIZ_TIM_CTRL 0x1E20
412#define VDEC_H_VERT_TIM_CTRL 0x1E24
413#define VDEC_H_MISC_TIM_CTRL 0x1E28
414#define VDEC_H_FIELD_COUNT 0x1E2C
415#define VDEC_H_HSCALE_CTRL 0x1E30
416#define VDEC_H_VSCALE_CTRL 0x1E34
417#define VDEC_H_MAN_VGA_CTRL 0x1E38
418#define VDEC_H_MAN_AGC_CTRL 0x1E3C
419#define VDEC_H_DFE_CTRL1 0x1E40
420#define VDEC_H_DFE_CTRL2 0x1E44
421#define VDEC_H_DFE_CTRL3 0x1E48
422#define VDEC_H_PLL_CTRL 0x1E4C
423#define VDEC_H_PLL_CTRL_FAST 0x1E50
424#define VDEC_H_HTL_CTRL 0x1E54
425#define VDEC_H_SRC_CFG 0x1E58
426#define VDEC_H_SC_STEP_SIZE 0x1E5C
427#define VDEC_H_SC_CONVERGE_CTRL 0x1E60
428#define VDEC_H_SC_LOOP_CTRL 0x1E64
429#define VDEC_H_COMB_2D_HFS_CFG 0x1E68
430#define VDEC_H_COMB_2D_HFD_CFG 0x1E6C
431#define VDEC_H_COMB_2D_LF_CFG 0x1E70
432#define VDEC_H_COMB_2D_BLEND 0x1E74
433#define VDEC_H_COMB_MISC_CTRL 0x1E78
434#define VDEC_H_COMB_FLAT_THRESH_CTRL 0x1E7C
435#define VDEC_H_COMB_TEST 0x1E80
436#define VDEC_H_BP_MISC_CTRL 0x1E84
437#define VDEC_H_VCR_DET_CTRL 0x1E88
438#define VDEC_H_NOISE_DET_CTRL 0x1E8C
439#define VDEC_H_COMB_FLAT_NOISE_CTRL 0x1E90
440#define VDEC_H_VERSION 0x1FF8
441#define VDEC_H_SOFT_RST_CTRL 0x1FFC
442
443//*****************************************************************************
444// LUMA_CTRL register fields
445#define VDEC_A_BRITE_CTRL 0x1014
446#define VDEC_A_CNTRST_CTRL 0x1015
447#define VDEC_A_PEAK_SEL 0x1016
448
449//*****************************************************************************
450// CHROMA_CTRL register fields
451#define VDEC_A_USAT_CTRL 0x1018
452#define VDEC_A_VSAT_CTRL 0x1019
453#define VDEC_A_HUE_CTRL 0x101A
454
455
456#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
new file mode 100644
index 00000000000..6225f1079bc
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -0,0 +1,769 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821.h"
24#include "cx25821-medusa-video.h"
25#include "cx25821-biffuncs.h"
26
27
28/////////////////////////////////////////////////////////////////////////////////////////
29//medusa_enable_bluefield_output()
30//
31// Enable the generation of blue filed output if no video
32//
33static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel, int enable)
34{
35 int ret_val = 1;
36 u32 value = 0;
37 u32 tmp = 0;
38 int out_ctrl = OUT_CTRL1;
39 int out_ctrl_ns = OUT_CTRL_NS;
40
41
42 switch (channel)
43 {
44 default:
45 case VDEC_A:
46 break;
47 case VDEC_B:
48 out_ctrl = VDEC_B_OUT_CTRL1;
49 out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
50 break;
51 case VDEC_C:
52 out_ctrl = VDEC_C_OUT_CTRL1;
53 out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
54 break;
55 case VDEC_D:
56 out_ctrl = VDEC_D_OUT_CTRL1;
57 out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
58 break;
59 case VDEC_E:
60 out_ctrl = VDEC_E_OUT_CTRL1;
61 out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
62 return;
63 case VDEC_F:
64 out_ctrl = VDEC_F_OUT_CTRL1;
65 out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
66 return;
67 case VDEC_G:
68 out_ctrl = VDEC_G_OUT_CTRL1;
69 out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
70 return;
71 case VDEC_H:
72 out_ctrl = VDEC_H_OUT_CTRL1;
73 out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
74 return;
75 }
76
77 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
78 value &= 0xFFFFFF7F; // clear BLUE_FIELD_EN
79 if (enable)
80 value |= 0x00000080; // set BLUE_FIELD_EN
81 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
82
83 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
84 value &= 0xFFFFFF7F;
85 if (enable)
86 value |= 0x00000080; // set BLUE_FIELD_EN
87 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
88}
89
90
91static int medusa_initialize_ntsc(struct cx25821_dev *dev)
92{
93 int ret_val = 0;
94 int i = 0;
95 u32 value = 0;
96 u32 tmp = 0;
97
98 mutex_lock(&dev->lock);
99
100
101 for (i=0; i < MAX_DECODERS; i++)
102 {
103 // set video format NTSC-M
104 value = cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL+(0x200*i), &tmp);
105 value &= 0xFFFFFFF0;
106 value |= 0x10001; // enable the fast locking mode bit[16]
107 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL+(0x200*i), value);
108
109 // resolution NTSC 720x480
110 value = cx25821_i2c_read(&dev->i2c_bus[0], HORIZ_TIM_CTRL+(0x200*i), &tmp);
111 value &= 0x00C00C00;
112 value |= 0x612D0074;
113 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HORIZ_TIM_CTRL+(0x200*i), value);
114
115 value = cx25821_i2c_read(&dev->i2c_bus[0], VERT_TIM_CTRL+(0x200*i), &tmp);
116 value &= 0x00C00C00;
117 value |= 0x1C1E001A; // vblank_cnt + 2 to get camera ID
118 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VERT_TIM_CTRL+(0x200*i), value);
119
120 // chroma subcarrier step size
121 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], SC_STEP_SIZE+(0x200*i), 0x43E00000);
122
123 // enable VIP optional active
124 value = cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL_NS+(0x200*i), &tmp);
125 value &= 0xFFFBFFFF;
126 value |= 0x00040000;
127 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL_NS+(0x200*i), value);
128
129 // enable VIP optional active (VIP_OPT_AL) for direct output.
130 value = cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1+(0x200*i), &tmp);
131 value &= 0xFFFBFFFF;
132 value |= 0x00040000;
133 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1+(0x200*i), value);
134
135 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
136 // when the input switching rate < 16 fields
137 //
138 value = cx25821_i2c_read(&dev->i2c_bus[0], MISC_TIM_CTRL+(0x200*i), &tmp);
139 value = setBitAtPos(value, 14); // disable special play detection
140 value = clearBitAtPos(value, 15);
141 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MISC_TIM_CTRL+(0x200*i), value);
142
143 // set vbi_gate_en to 0
144 value = cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1+(0x200*i), &tmp);
145 value = clearBitAtPos(value, 29);
146 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1+(0x200*i), value);
147
148 // Enable the generation of blue field output if no video
149 medusa_enable_bluefield_output(dev, i, 1);
150 }
151
152
153 for (i=0; i < MAX_ENCODERS; i++)
154 {
155 // NTSC hclock
156 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_1+(0x100*i), &tmp);
157 value &= 0xF000FC00;
158 value |= 0x06B402D0;
159 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_1+(0x100*i), value);
160
161 // burst begin and burst end
162 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_2+(0x100*i), &tmp);
163 value &= 0xFF000000;
164 value |= 0x007E9054;
165 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_2+(0x100*i), value);
166
167 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_3+(0x100*i), &tmp);
168 value &= 0xFC00FE00;
169 value |= 0x00EC00F0;
170 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_3+(0x100*i), value);
171
172 // set NTSC vblank, no phase alternation, 7.5 IRE pedestal
173 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4+(0x100*i), &tmp);
174 value &= 0x00FCFFFF;
175 value |= 0x13020000;
176 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4+(0x100*i), value);
177
178 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_5+(0x100*i), &tmp);
179 value &= 0xFFFF0000;
180 value |= 0x0000E575;
181 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_5+(0x100*i), value);
182
183 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_6+(0x100*i), 0x009A89C1);
184
185 // Subcarrier Increment
186 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_7+(0x100*i), 0x21F07C1F);
187 }
188
189
190 //set picture resolutions
191 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
192 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 480
193
194 // set Bypass input format to NTSC 525 lines
195 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
196 value |= 0x00080200;
197 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
198
199 mutex_unlock(&dev->lock);
200
201 return ret_val;
202}
203
204
205static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
206{
207 int ret_val = -1;
208 u32 value = 0, tmp = 0;
209
210 // Setup for 2D threshold
211 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG+(0x200*dec), 0x20002861);
212 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG+(0x200*dec), 0x20002861);
213 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG+(0x200*dec), 0x200A1023);
214
215 // Setup flat chroma and luma thresholds
216 value = cx25821_i2c_read(&dev->i2c_bus[0], COMB_FLAT_THRESH_CTRL+(0x200*dec), &tmp);
217 value &= 0x06230000;
218 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_FLAT_THRESH_CTRL+(0x200*dec), value);
219
220 // set comb 2D blend
221 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND+(0x200*dec), 0x210F0F0F);
222
223 // COMB MISC CONTROL
224 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL+(0x200*dec), 0x41120A7F);
225
226 return ret_val;
227}
228
229
230static int medusa_initialize_pal(struct cx25821_dev *dev)
231{
232 int ret_val = 0;
233 int i = 0;
234 u32 value = 0;
235 u32 tmp = 0;
236
237 mutex_lock(&dev->lock);
238
239 for (i=0; i < MAX_DECODERS; i++)
240 {
241 // set video format PAL-BDGHI
242 value = cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL+(0x200*i), &tmp);
243 value &= 0xFFFFFFF0;
244 value |= 0x10004; // enable the fast locking mode bit[16]
245 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL+(0x200*i), value);
246
247
248 // resolution PAL 720x576
249 value = cx25821_i2c_read(&dev->i2c_bus[0], HORIZ_TIM_CTRL+(0x200*i), &tmp);
250 value &= 0x00C00C00;
251 value |= 0x632D007D;
252 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HORIZ_TIM_CTRL+(0x200*i), value);
253
254 // vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24
255 value = cx25821_i2c_read(&dev->i2c_bus[0], VERT_TIM_CTRL+(0x200*i), &tmp);
256 value &= 0x00C00C00;
257 value |= 0x28240026; // vblank_cnt + 2 to get camera ID
258 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VERT_TIM_CTRL+(0x200*i), value);
259
260 // chroma subcarrier step size
261 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], SC_STEP_SIZE+(0x200*i), 0x5411E2D0);
262
263 // enable VIP optional active
264 value = cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL_NS+(0x200*i), &tmp);
265 value &= 0xFFFBFFFF;
266 value |= 0x00040000;
267 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL_NS+(0x200*i), value);
268
269 // enable VIP optional active (VIP_OPT_AL) for direct output.
270 value = cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1+(0x200*i), &tmp);
271 value &= 0xFFFBFFFF;
272 value |= 0x00040000;
273 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1+(0x200*i), value);
274
275 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
276 // when the input switching rate < 16 fields
277 value = cx25821_i2c_read(&dev->i2c_bus[0], MISC_TIM_CTRL+(0x200*i), &tmp);
278 value = setBitAtPos(value, 14); // disable special play detection
279 value = clearBitAtPos(value, 15);
280 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MISC_TIM_CTRL+(0x200*i), value);
281
282 // set vbi_gate_en to 0
283 value = cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1+(0x200*i), &tmp);
284 value = clearBitAtPos(value, 29);
285 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1+(0x200*i), value);
286
287 medusa_PALCombInit(dev, i);
288
289 // Enable the generation of blue field output if no video
290 medusa_enable_bluefield_output(dev, i, 1);
291 }
292
293
294 for (i=0; i < MAX_ENCODERS; i++)
295 {
296 // PAL hclock
297 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_1+(0x100*i), &tmp);
298 value &= 0xF000FC00;
299 value |= 0x06C002D0;
300 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_1+(0x100*i), value);
301
302 // burst begin and burst end
303 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_2+(0x100*i), &tmp);
304 value &= 0xFF000000;
305 value |= 0x007E9754;
306 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_2+(0x100*i), value);
307
308 // hblank and vactive
309 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_3+(0x100*i), &tmp);
310 value &= 0xFC00FE00;
311 value |= 0x00FC0120;
312 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_3+(0x100*i), value);
313
314 // set PAL vblank, phase alternation, 0 IRE pedestal
315 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4+(0x100*i), &tmp);
316 value &= 0x00FCFFFF;
317 value |= 0x14010000;
318 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4+(0x100*i), value);
319
320
321 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_5+(0x100*i), &tmp);
322 value &= 0xFFFF0000;
323 value |= 0x0000F078;
324 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_5+(0x100*i), value);
325
326 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_6+(0x100*i), 0x00A493CF);
327
328 // Subcarrier Increment
329 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_7+(0x100*i), 0x2A098ACB);
330 }
331
332
333 //set picture resolutions
334 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
335 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 576
336
337 // set Bypass input format to PAL 625 lines
338 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
339 value &= 0xFFF7FDFF;
340 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
341
342 mutex_unlock(&dev->lock);
343
344 return ret_val;
345}
346
347
348int medusa_set_videostandard(struct cx25821_dev *dev)
349{
350 int status = STATUS_SUCCESS;
351 u32 value = 0, tmp = 0;
352
353
354 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
355 {
356 status = medusa_initialize_pal(dev);
357 }
358 else
359 {
360 status = medusa_initialize_ntsc(dev);
361 }
362
363 // Enable DENC_A output
364 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
365 value = setBitAtPos(value, 4);
366 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
367
368 // Enable DENC_B output
369 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
370 value = setBitAtPos(value, 4);
371 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
372
373 return status;
374}
375
376
377void medusa_set_resolution(struct cx25821_dev *dev, int width, int decoder_select)
378{
379 int decoder = 0;
380 int decoder_count = 0;
381 int ret_val = 0;
382 u32 hscale = 0x0;
383 u32 vscale = 0x0;
384 const int MAX_WIDTH = 720;
385
386 mutex_lock(&dev->lock);
387
388 // validate the width - cannot be negative
389 if (width > MAX_WIDTH)
390 {
391 printk("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH \n", __func__, width, MAX_WIDTH);
392 width = MAX_WIDTH;
393 }
394
395 if( decoder_select <= 7 && decoder_select >= 0 )
396 {
397 decoder = decoder_select;
398 decoder_count = decoder_select + 1;
399 }
400 else
401 {
402 decoder = 0;
403 decoder_count = _num_decoders;
404 }
405
406
407 switch( width )
408 {
409 case 320:
410 hscale = 0x13E34B;
411 vscale = 0x0;
412 break;
413
414 case 352:
415 hscale = 0x10A273;
416 vscale = 0x0;
417 break;
418
419 case 176:
420 hscale = 0x3115B2;
421 vscale = 0x1E00;
422 break;
423
424 case 160:
425 hscale = 0x378D84;
426 vscale = 0x1E00;
427 break;
428
429 default: //720
430 hscale = 0x0;
431 vscale = 0x0;
432 break;
433 }
434
435 for( ; decoder < decoder_count; decoder++)
436 {
437 // write scaling values for each decoder
438 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL+(0x200*decoder), hscale);
439 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL+(0x200*decoder), vscale);
440 }
441
442 mutex_unlock(&dev->lock);
443}
444
445static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, int duration)
446{
447 int ret_val = 0;
448 u32 fld_cnt = 0;
449 u32 tmp = 0;
450 u32 disp_cnt_reg = DISP_AB_CNT;
451
452 mutex_lock(&dev->lock);
453
454 // no support
455 if (decoder < VDEC_A && decoder > VDEC_H)
456 {
457 mutex_unlock(&dev->lock);
458 return;
459 }
460
461 switch (decoder)
462 {
463 default:
464 break;
465 case VDEC_C:
466 case VDEC_D:
467 disp_cnt_reg = DISP_CD_CNT;
468 break;
469 case VDEC_E:
470 case VDEC_F:
471 disp_cnt_reg = DISP_EF_CNT;
472 break;
473 case VDEC_G:
474 case VDEC_H:
475 disp_cnt_reg = DISP_GH_CNT;
476 break;
477 }
478
479 _display_field_cnt[decoder] = duration;
480
481 // update hardware
482 fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
483
484 if (!(decoder % 2)) // EVEN decoder
485 {
486 fld_cnt &= 0xFFFF0000;
487 fld_cnt |= duration;
488 }
489 else
490 {
491 fld_cnt &= 0x0000FFFF;
492 fld_cnt |= ((u32)duration) << 16;
493 }
494
495 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
496
497 mutex_unlock(&dev->lock);
498}
499
500/////////////////////////////////////////////////////////////////////////////////////////
501// Map to Medusa register setting
502static int mapM(
503 int srcMin,
504 int srcMax,
505 int srcVal,
506 int dstMin,
507 int dstMax,
508 int* dstVal
509)
510{
511 int numerator;
512 int denominator;
513 int quotient;
514
515 if((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
516 {
517 return -1;
518 }
519
520 // This is the overall expression used:
521 // *dstVal = (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
522 // but we need to account for rounding so below we use the modulus
523 // operator to find the remainder and increment if necessary.
524 numerator = (srcVal - srcMin)*(dstMax - dstMin);
525 denominator = srcMax - srcMin;
526 quotient = numerator/denominator;
527
528 if(2 * ( numerator % denominator ) >= denominator)
529 {
530 quotient++;
531 }
532
533 *dstVal = quotient + dstMin;
534
535 return 0;
536}
537
538static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
539{
540 unsigned char temp;
541
542 if (numeric >= 0)
543 return numeric;
544 else
545 {
546 temp = ~(abs(numeric) & 0xFF);
547 temp += 1;
548 return temp;
549 }
550}
551/////////////////////////////////////////////////////////////////////////////////////////
552int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
553{
554 int ret_val = 0;
555 int value = 0;
556 u32 val = 0, tmp = 0;
557
558 mutex_lock(&dev->lock);
559 if((brightness > VIDEO_PROCAMP_MAX) || (brightness < VIDEO_PROCAMP_MIN))
560 {
561 mutex_unlock(&dev->lock);
562 return -1;
563 }
564 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
565 value = convert_to_twos(value, 8);
566 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_BRITE_CTRL+(0x200*decoder), &tmp);
567 val &= 0xFFFFFF00;
568 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_BRITE_CTRL+(0x200*decoder), val | value);
569 mutex_unlock(&dev->lock);
570 return ret_val;
571}
572
573/////////////////////////////////////////////////////////////////////////////////////////
574int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
575{
576 int ret_val = 0;
577 int value = 0;
578 u32 val = 0, tmp = 0;
579
580 mutex_lock(&dev->lock);
581
582 if((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN))
583 {
584 mutex_unlock(&dev->lock);
585 return -1;
586 }
587
588 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast, UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
589 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_CNTRST_CTRL+(0x200*decoder), &tmp);
590 val &= 0xFFFFFF00;
591 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_CNTRST_CTRL+(0x200*decoder), val | value);
592
593 mutex_unlock(&dev->lock);
594 return ret_val;
595}
596
597/////////////////////////////////////////////////////////////////////////////////////////
598int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
599{
600 int ret_val = 0;
601 int value = 0;
602 u32 val = 0, tmp = 0;
603
604 mutex_lock(&dev->lock);
605
606 if((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN))
607 {
608 mutex_unlock(&dev->lock);
609 return -1;
610 }
611
612 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
613
614 value = convert_to_twos(value, 8);
615 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_HUE_CTRL+(0x200*decoder), &tmp);
616 val &= 0xFFFFFF00;
617
618 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_HUE_CTRL+(0x200*decoder), val | value);
619
620 mutex_unlock(&dev->lock);
621 return ret_val;
622}
623
624
625/////////////////////////////////////////////////////////////////////////////////////////
626int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
627{
628 int ret_val = 0;
629 int value = 0;
630 u32 val = 0, tmp = 0;
631
632 mutex_lock(&dev->lock);
633
634 if((saturation > VIDEO_PROCAMP_MAX) || (saturation < VIDEO_PROCAMP_MIN))
635 {
636 mutex_unlock(&dev->lock);
637 return -1;
638 }
639
640 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation, UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
641
642 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_USAT_CTRL+(0x200*decoder), &tmp);
643 val &= 0xFFFFFF00;
644 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_USAT_CTRL+(0x200*decoder), val | value);
645
646 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_VSAT_CTRL+(0x200*decoder), &tmp);
647 val &= 0xFFFFFF00;
648 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_VSAT_CTRL+(0x200*decoder), val | value);
649
650 mutex_unlock(&dev->lock);
651 return ret_val;
652}
653
654
655/////////////////////////////////////////////////////////////////////////////////////////
656// Program the display sequence and monitor output.
657//
658int medusa_video_init(struct cx25821_dev *dev)
659{
660 u32 value = 0, tmp = 0;
661 int ret_val = 0;
662 int i=0;
663
664 mutex_lock(&dev->lock);
665
666 _num_decoders = dev->_max_num_decoders;
667
668
669 // disable Auto source selection on all video decoders
670 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
671 value &= 0xFFFFF0FF;
672 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
673
674 if (ret_val < 0)
675 {
676 mutex_unlock(&dev->lock);
677 return -EINVAL;
678 }
679
680 // Turn off Master source switch enable
681 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
682 value &= 0xFFFFFFDF;
683 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
684
685 if (ret_val < 0)
686 {
687 mutex_unlock(&dev->lock);
688 return -EINVAL;
689 }
690
691 mutex_unlock(&dev->lock);
692
693 for (i=0; i < _num_decoders; i++)
694 {
695 medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
696 }
697
698 mutex_lock(&dev->lock);
699
700 // Select monitor as DENC A input, power up the DAC
701 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
702 value &= 0xFF70FF70;
703 value |= 0x00090008; // set en_active
704 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
705
706 if (ret_val < 0)
707 {
708 mutex_unlock(&dev->lock);
709 return -EINVAL;
710 }
711
712 // enable input is VIP/656
713 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
714 value |= 0x00040100; // enable VIP
715 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
716
717 if (ret_val < 0)
718 {
719 mutex_unlock(&dev->lock);
720 return -EINVAL;
721 }
722
723 // select AFE clock to output mode
724 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
725 value &= 0x83FFFFFF;
726 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, value | 0x10000000);
727
728 if (ret_val < 0)
729 {
730 mutex_unlock(&dev->lock);
731 return -EINVAL;
732 }
733
734 // Turn on all of the data out and control output pins.
735 value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
736 value &= 0xFEF0FE00;
737 if (_num_decoders == MAX_DECODERS)
738 {
739 // Note: The octal board does not support control pins(bit16-19).
740 // These bits are ignored in the octal board.
741 value |= 0x010001F8; // disable VDEC A-C port, default to Mobilygen Interface
742 }
743 else
744 {
745 value |= 0x010F0108; // disable VDEC A-C port, default to Mobilygen Interface
746 }
747
748 value |= 7;
749 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
750 if (ret_val < 0)
751 {
752 mutex_unlock(&dev->lock);
753 return -EINVAL;
754 }
755
756 mutex_unlock(&dev->lock);
757
758
759 ret_val = medusa_set_videostandard(dev);
760
761
762 if (ret_val < 0)
763 {
764 mutex_unlock(&dev->lock);
765 return -EINVAL;
766 }
767
768 return 1;
769}
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.h b/drivers/staging/cx25821/cx25821-medusa-video.h
new file mode 100644
index 00000000000..0ba3cc7db5a
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.h
@@ -0,0 +1,51 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _MEDUSA_VIDEO_H
24#define _MEDUSA_VIDEO_H
25
26#include "cx25821-medusa-defines.h"
27
28
29// Color control constants
30#define VIDEO_PROCAMP_MIN 0
31#define VIDEO_PROCAMP_MAX 10000
32#define UNSIGNED_BYTE_MIN 0
33#define UNSIGNED_BYTE_MAX 0xFF
34#define SIGNED_BYTE_MIN -128
35#define SIGNED_BYTE_MAX 127
36
37// Default video color settings
38#define SHARPNESS_DEFAULT 50
39#define SATURATION_DEFAULT 5000
40#define BRIGHTNESS_DEFAULT 6200
41#define CONTRAST_DEFAULT 5000
42#define HUE_DEFAULT 5000
43
44
45unsigned short _num_decoders;
46unsigned short _num_cameras;
47
48unsigned int _video_standard;
49int _display_field_cnt[MAX_DECODERS];
50
51#endif
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/staging/cx25821/cx25821-reg.h
new file mode 100644
index 00000000000..82f4f16b831
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-reg.h
@@ -0,0 +1,1609 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __CX25821_REGISTERS__
24#define __CX25821_REGISTERS__
25
26/* Risc Instructions */
27#define RISC_CNT_INC 0x00010000
28#define RISC_CNT_RESET 0x00030000
29#define RISC_IRQ1 0x01000000
30#define RISC_IRQ2 0x02000000
31#define RISC_EOL 0x04000000
32#define RISC_SOL 0x08000000
33#define RISC_WRITE 0x10000000
34#define RISC_SKIP 0x20000000
35#define RISC_JUMP 0x70000000
36#define RISC_SYNC 0x80000000
37#define RISC_RESYNC 0x80008000
38#define RISC_READ 0x90000000
39#define RISC_WRITERM 0xB0000000
40#define RISC_WRITECM 0xC0000000
41#define RISC_WRITECR 0xD0000000
42#define RISC_WRITEC 0x50000000
43#define RISC_READC 0xA0000000
44
45#define RISC_SYNC_ODD 0x00000000
46#define RISC_SYNC_EVEN 0x00000200
47#define RISC_SYNC_ODD_VBI 0x00000006
48#define RISC_SYNC_EVEN_VBI 0x00000207
49#define RISC_NOOP 0xF0000000
50
51//*****************************************************************************
52// ASB SRAM
53//*****************************************************************************
54#define TX_SRAM 0x000000 // Transmit SRAM
55
56//*****************************************************************************
57#define RX_RAM 0x010000 // Receive SRAM
58
59//*****************************************************************************
60// Application Layer (AL)
61//*****************************************************************************
62#define DEV_CNTRL2 0x040000 // Device control
63#define FLD_RUN_RISC 0x00000020
64
65//*****************************************************************************
66#define PCI_INT_MSK 0x040010 // PCI interrupt mask
67#define PCI_INT_STAT 0x040014 // PCI interrupt status
68#define PCI_INT_MSTAT 0x040018 // PCI interrupt masked status
69#define FLD_HAMMERHEAD_INT (1 << 27)
70#define FLD_UART_INT (1 << 26)
71#define FLD_IRQN_INT (1 << 25)
72#define FLD_TM_INT (1 << 28)
73#define FLD_I2C_3_RACK (1 << 27)
74#define FLD_I2C_3_INT (1 << 26)
75#define FLD_I2C_2_RACK (1 << 25)
76#define FLD_I2C_2_INT (1 << 24)
77#define FLD_I2C_1_RACK (1 << 23)
78#define FLD_I2C_1_INT (1 << 22)
79
80#define FLD_APB_DMA_BERR_INT (1 << 21)
81#define FLD_AL_WR_BERR_INT (1 << 20)
82#define FLD_AL_RD_BERR_INT (1 << 19)
83#define FLD_RISC_WR_BERR_INT (1 << 18)
84#define FLD_RISC_RD_BERR_INT (1 << 17)
85
86#define FLD_VID_I_INT (1 << 8)
87#define FLD_VID_H_INT (1 << 7)
88#define FLD_VID_G_INT (1 << 6)
89#define FLD_VID_F_INT (1 << 5)
90#define FLD_VID_E_INT (1 << 4)
91#define FLD_VID_D_INT (1 << 3)
92#define FLD_VID_C_INT (1 << 2)
93#define FLD_VID_B_INT (1 << 1)
94#define FLD_VID_A_INT (1 << 0)
95
96//*****************************************************************************
97#define VID_A_INT_MSK 0x040020 // Video A interrupt mask
98#define VID_A_INT_STAT 0x040024 // Video A interrupt status
99#define VID_A_INT_MSTAT 0x040028 // Video A interrupt masked status
100#define VID_A_INT_SSTAT 0x04002C // Video A interrupt set status
101
102//*****************************************************************************
103#define VID_B_INT_MSK 0x040030 // Video B interrupt mask
104#define VID_B_INT_STAT 0x040034 // Video B interrupt status
105#define VID_B_INT_MSTAT 0x040038 // Video B interrupt masked status
106#define VID_B_INT_SSTAT 0x04003C // Video B interrupt set status
107
108//*****************************************************************************
109#define VID_C_INT_MSK 0x040040 // Video C interrupt mask
110#define VID_C_INT_STAT 0x040044 // Video C interrupt status
111#define VID_C_INT_MSTAT 0x040048 // Video C interrupt masked status
112#define VID_C_INT_SSTAT 0x04004C // Video C interrupt set status
113
114//*****************************************************************************
115#define VID_D_INT_MSK 0x040050 // Video D interrupt mask
116#define VID_D_INT_STAT 0x040054 // Video D interrupt status
117#define VID_D_INT_MSTAT 0x040058 // Video D interrupt masked status
118#define VID_D_INT_SSTAT 0x04005C // Video D interrupt set status
119
120//*****************************************************************************
121#define VID_E_INT_MSK 0x040060 // Video E interrupt mask
122#define VID_E_INT_STAT 0x040064 // Video E interrupt status
123#define VID_E_INT_MSTAT 0x040068 // Video E interrupt masked status
124#define VID_E_INT_SSTAT 0x04006C // Video E interrupt set status
125
126//*****************************************************************************
127#define VID_F_INT_MSK 0x040070 // Video F interrupt mask
128#define VID_F_INT_STAT 0x040074 // Video F interrupt status
129#define VID_F_INT_MSTAT 0x040078 // Video F interrupt masked status
130#define VID_F_INT_SSTAT 0x04007C // Video F interrupt set status
131
132//*****************************************************************************
133#define VID_G_INT_MSK 0x040080 // Video G interrupt mask
134#define VID_G_INT_STAT 0x040084 // Video G interrupt status
135#define VID_G_INT_MSTAT 0x040088 // Video G interrupt masked status
136#define VID_G_INT_SSTAT 0x04008C // Video G interrupt set status
137
138//*****************************************************************************
139#define VID_H_INT_MSK 0x040090 // Video H interrupt mask
140#define VID_H_INT_STAT 0x040094 // Video H interrupt status
141#define VID_H_INT_MSTAT 0x040098 // Video H interrupt masked status
142#define VID_H_INT_SSTAT 0x04009C // Video H interrupt set status
143
144//*****************************************************************************
145#define VID_I_INT_MSK 0x0400A0 // Video I interrupt mask
146#define VID_I_INT_STAT 0x0400A4 // Video I interrupt status
147#define VID_I_INT_MSTAT 0x0400A8 // Video I interrupt masked status
148#define VID_I_INT_SSTAT 0x0400AC // Video I interrupt set status
149
150//*****************************************************************************
151#define VID_J_INT_MSK 0x0400B0 // Video J interrupt mask
152#define VID_J_INT_STAT 0x0400B4 // Video J interrupt status
153#define VID_J_INT_MSTAT 0x0400B8 // Video J interrupt masked status
154#define VID_J_INT_SSTAT 0x0400BC // Video J interrupt set status
155
156#define FLD_VID_SRC_OPC_ERR 0x00020000
157#define FLD_VID_DST_OPC_ERR 0x00010000
158#define FLD_VID_SRC_SYNC 0x00002000
159#define FLD_VID_DST_SYNC 0x00001000
160#define FLD_VID_SRC_UF 0x00000200
161#define FLD_VID_DST_OF 0x00000100
162#define FLD_VID_SRC_RISC2 0x00000020
163#define FLD_VID_DST_RISC2 0x00000010
164#define FLD_VID_SRC_RISC1 0x00000002
165#define FLD_VID_DST_RISC1 0x00000001
166#define FLD_VID_SRC_ERRORS FLD_VID_SRC_OPC_ERR | FLD_VID_SRC_SYNC | FLD_VID_SRC_UF
167#define FLD_VID_DST_ERRORS FLD_VID_DST_OPC_ERR | FLD_VID_DST_SYNC | FLD_VID_DST_OF
168
169
170//*****************************************************************************
171#define AUD_A_INT_MSK 0x0400C0 // Audio Int interrupt mask
172#define AUD_A_INT_STAT 0x0400C4 // Audio Int interrupt status
173#define AUD_A_INT_MSTAT 0x0400C8 // Audio Int interrupt masked status
174#define AUD_A_INT_SSTAT 0x0400CC // Audio Int interrupt set status
175
176//*****************************************************************************
177#define AUD_B_INT_MSK 0x0400D0 // Audio Int interrupt mask
178#define AUD_B_INT_STAT 0x0400D4 // Audio Int interrupt status
179#define AUD_B_INT_MSTAT 0x0400D8 // Audio Int interrupt masked status
180#define AUD_B_INT_SSTAT 0x0400DC // Audio Int interrupt set status
181
182//*****************************************************************************
183#define AUD_C_INT_MSK 0x0400E0 // Audio Int interrupt mask
184#define AUD_C_INT_STAT 0x0400E4 // Audio Int interrupt status
185#define AUD_C_INT_MSTAT 0x0400E8 // Audio Int interrupt masked status
186#define AUD_C_INT_SSTAT 0x0400EC // Audio Int interrupt set status
187
188//*****************************************************************************
189#define AUD_D_INT_MSK 0x0400F0 // Audio Int interrupt mask
190#define AUD_D_INT_STAT 0x0400F4 // Audio Int interrupt status
191#define AUD_D_INT_MSTAT 0x0400F8 // Audio Int interrupt masked status
192#define AUD_D_INT_SSTAT 0x0400FC // Audio Int interrupt set status
193
194//*****************************************************************************
195#define AUD_E_INT_MSK 0x040100 // Audio Int interrupt mask
196#define AUD_E_INT_STAT 0x040104 // Audio Int interrupt status
197#define AUD_E_INT_MSTAT 0x040108 // Audio Int interrupt masked status
198#define AUD_E_INT_SSTAT 0x04010C // Audio Int interrupt set status
199
200#define FLD_AUD_SRC_OPC_ERR 0x00020000
201#define FLD_AUD_DST_OPC_ERR 0x00010000
202#define FLD_AUD_SRC_SYNC 0x00002000
203#define FLD_AUD_DST_SYNC 0x00001000
204#define FLD_AUD_SRC_OF 0x00000200
205#define FLD_AUD_DST_OF 0x00000100
206#define FLD_AUD_SRC_RISCI2 0x00000020
207#define FLD_AUD_DST_RISCI2 0x00000010
208#define FLD_AUD_SRC_RISCI1 0x00000002
209#define FLD_AUD_DST_RISCI1 0x00000001
210
211//*****************************************************************************
212#define MBIF_A_INT_MSK 0x040110 // MBIF Int interrupt mask
213#define MBIF_A_INT_STAT 0x040114 // MBIF Int interrupt status
214#define MBIF_A_INT_MSTAT 0x040118 // MBIF Int interrupt masked status
215#define MBIF_A_INT_SSTAT 0x04011C // MBIF Int interrupt set status
216
217//*****************************************************************************
218#define MBIF_B_INT_MSK 0x040120 // MBIF Int interrupt mask
219#define MBIF_B_INT_STAT 0x040124 // MBIF Int interrupt status
220#define MBIF_B_INT_MSTAT 0x040128 // MBIF Int interrupt masked status
221#define MBIF_B_INT_SSTAT 0x04012C // MBIF Int interrupt set status
222
223#define FLD_MBIF_DST_OPC_ERR 0x00010000
224#define FLD_MBIF_DST_SYNC 0x00001000
225#define FLD_MBIF_DST_OF 0x00000100
226#define FLD_MBIF_DST_RISCI2 0x00000010
227#define FLD_MBIF_DST_RISCI1 0x00000001
228
229//*****************************************************************************
230#define AUD_EXT_INT_MSK 0x040060 // Audio Ext interrupt mask
231#define AUD_EXT_INT_STAT 0x040064 // Audio Ext interrupt status
232#define AUD_EXT_INT_MSTAT 0x040068 // Audio Ext interrupt masked status
233#define AUD_EXT_INT_SSTAT 0x04006C // Audio Ext interrupt set status
234#define FLD_AUD_EXT_OPC_ERR 0x00010000
235#define FLD_AUD_EXT_SYNC 0x00001000
236#define FLD_AUD_EXT_OF 0x00000100
237#define FLD_AUD_EXT_RISCI2 0x00000010
238#define FLD_AUD_EXT_RISCI1 0x00000001
239
240
241//*****************************************************************************
242#define GPIO_LO 0x110010 // Lower of GPIO pins [31:0]
243#define GPIO_HI 0x110014 // Upper WORD of GPIO pins [47:31]
244
245#define GPIO_LO_OE 0x110018 // Lower of GPIO output enable [31:0]
246#define GPIO_HI_OE 0x11001C // Upper word of GPIO output enable [47:32]
247
248#define GPIO_LO_INT_MSK 0x11003C // GPIO interrupt mask
249#define GPIO_LO_INT_STAT 0x110044 // GPIO interrupt status
250#define GPIO_LO_INT_MSTAT 0x11004C // GPIO interrupt masked status
251#define GPIO_LO_ISM_SNS 0x110054 // GPIO interrupt sensitivity
252#define GPIO_LO_ISM_POL 0x11005C // GPIO interrupt polarity
253
254#define GPIO_HI_INT_MSK 0x110040 // GPIO interrupt mask
255#define GPIO_HI_INT_STAT 0x110048 // GPIO interrupt status
256#define GPIO_HI_INT_MSTAT 0x110050 // GPIO interrupt masked status
257#define GPIO_HI_ISM_SNS 0x110058 // GPIO interrupt sensitivity
258#define GPIO_HI_ISM_POL 0x110060 // GPIO interrupt polarity
259
260#define FLD_GPIO43_INT (1 << 11)
261#define FLD_GPIO42_INT (1 << 10)
262#define FLD_GPIO41_INT (1 << 9)
263#define FLD_GPIO40_INT (1 << 8)
264
265#define FLD_GPIO9_INT (1 << 9)
266#define FLD_GPIO8_INT (1 << 8)
267#define FLD_GPIO7_INT (1 << 7)
268#define FLD_GPIO6_INT (1 << 6)
269#define FLD_GPIO5_INT (1 << 5)
270#define FLD_GPIO4_INT (1 << 4)
271#define FLD_GPIO3_INT (1 << 3)
272#define FLD_GPIO2_INT (1 << 2)
273#define FLD_GPIO1_INT (1 << 1)
274#define FLD_GPIO0_INT (1 << 0)
275
276//*****************************************************************************
277#define TC_REQ 0x040090 // Rider PCI Express traFFic class request
278
279//*****************************************************************************
280#define TC_REQ_SET 0x040094 // Rider PCI Express traFFic class request set
281
282
283//*****************************************************************************
284// Rider
285//*****************************************************************************
286
287// PCI Compatible Header
288//*****************************************************************************
289#define RDR_CFG0 0x050000
290#define RDR_VENDOR_DEVICE_ID_CFG 0x050000
291
292//*****************************************************************************
293#define RDR_CFG1 0x050004
294
295//*****************************************************************************
296#define RDR_CFG2 0x050008
297
298//*****************************************************************************
299#define RDR_CFG3 0x05000C
300
301//*****************************************************************************
302#define RDR_CFG4 0x050010
303
304//*****************************************************************************
305#define RDR_CFG5 0x050014
306
307//*****************************************************************************
308#define RDR_CFG6 0x050018
309
310//*****************************************************************************
311#define RDR_CFG7 0x05001C
312
313//*****************************************************************************
314#define RDR_CFG8 0x050020
315
316//*****************************************************************************
317#define RDR_CFG9 0x050024
318
319//*****************************************************************************
320#define RDR_CFGA 0x050028
321
322//*****************************************************************************
323#define RDR_CFGB 0x05002C
324#define RDR_SUSSYSTEM_ID_CFG 0x05002C
325
326//*****************************************************************************
327#define RDR_CFGC 0x050030
328
329//*****************************************************************************
330#define RDR_CFGD 0x050034
331
332//*****************************************************************************
333#define RDR_CFGE 0x050038
334
335//*****************************************************************************
336#define RDR_CFGF 0x05003C
337
338//*****************************************************************************
339// PCI-Express Capabilities
340//*****************************************************************************
341#define RDR_PECAP 0x050040
342
343//*****************************************************************************
344#define RDR_PEDEVCAP 0x050044
345
346//*****************************************************************************
347#define RDR_PEDEVSC 0x050048
348
349//*****************************************************************************
350#define RDR_PELINKCAP 0x05004C
351
352//*****************************************************************************
353#define RDR_PELINKSC 0x050050
354
355//*****************************************************************************
356#define RDR_PMICAP 0x050080
357
358//*****************************************************************************
359#define RDR_PMCSR 0x050084
360
361//*****************************************************************************
362#define RDR_VPDCAP 0x050090
363
364//*****************************************************************************
365#define RDR_VPDDATA 0x050094
366
367//*****************************************************************************
368#define RDR_MSICAP 0x0500A0
369
370//*****************************************************************************
371#define RDR_MSIARL 0x0500A4
372
373//*****************************************************************************
374#define RDR_MSIARU 0x0500A8
375
376//*****************************************************************************
377#define RDR_MSIDATA 0x0500AC
378
379//*****************************************************************************
380// PCI Express Extended Capabilities
381//*****************************************************************************
382#define RDR_AERXCAP 0x050100
383
384//*****************************************************************************
385#define RDR_AERUESTA 0x050104
386
387//*****************************************************************************
388#define RDR_AERUEMSK 0x050108
389
390//*****************************************************************************
391#define RDR_AERUESEV 0x05010C
392
393//*****************************************************************************
394#define RDR_AERCESTA 0x050110
395
396//*****************************************************************************
397#define RDR_AERCEMSK 0x050114
398
399//*****************************************************************************
400#define RDR_AERCC 0x050118
401
402//*****************************************************************************
403#define RDR_AERHL0 0x05011C
404
405//*****************************************************************************
406#define RDR_AERHL1 0x050120
407
408//*****************************************************************************
409#define RDR_AERHL2 0x050124
410
411//*****************************************************************************
412#define RDR_AERHL3 0x050128
413
414//*****************************************************************************
415#define RDR_VCXCAP 0x050200
416
417//*****************************************************************************
418#define RDR_VCCAP1 0x050204
419
420//*****************************************************************************
421#define RDR_VCCAP2 0x050208
422
423//*****************************************************************************
424#define RDR_VCSC 0x05020C
425
426//*****************************************************************************
427#define RDR_VCR0_CAP 0x050210
428
429//*****************************************************************************
430#define RDR_VCR0_CTRL 0x050214
431
432//*****************************************************************************
433#define RDR_VCR0_STAT 0x050218
434
435//*****************************************************************************
436#define RDR_VCR1_CAP 0x05021C
437
438//*****************************************************************************
439#define RDR_VCR1_CTRL 0x050220
440
441//*****************************************************************************
442#define RDR_VCR1_STAT 0x050224
443
444//*****************************************************************************
445#define RDR_VCR2_CAP 0x050228
446
447//*****************************************************************************
448#define RDR_VCR2_CTRL 0x05022C
449
450//*****************************************************************************
451#define RDR_VCR2_STAT 0x050230
452
453//*****************************************************************************
454#define RDR_VCR3_CAP 0x050234
455
456//*****************************************************************************
457#define RDR_VCR3_CTRL 0x050238
458
459//*****************************************************************************
460#define RDR_VCR3_STAT 0x05023C
461
462//*****************************************************************************
463#define RDR_VCARB0 0x050240
464
465//*****************************************************************************
466#define RDR_VCARB1 0x050244
467
468//*****************************************************************************
469#define RDR_VCARB2 0x050248
470
471//*****************************************************************************
472#define RDR_VCARB3 0x05024C
473
474//*****************************************************************************
475#define RDR_VCARB4 0x050250
476
477//*****************************************************************************
478#define RDR_VCARB5 0x050254
479
480//*****************************************************************************
481#define RDR_VCARB6 0x050258
482
483//*****************************************************************************
484#define RDR_VCARB7 0x05025C
485
486//*****************************************************************************
487#define RDR_RDRSTAT0 0x050300
488
489//*****************************************************************************
490#define RDR_RDRSTAT1 0x050304
491
492//*****************************************************************************
493#define RDR_RDRCTL0 0x050308
494
495//*****************************************************************************
496#define RDR_RDRCTL1 0x05030C
497
498//*****************************************************************************
499// Transaction Layer Registers
500//*****************************************************************************
501#define RDR_TLSTAT0 0x050310
502
503//*****************************************************************************
504#define RDR_TLSTAT1 0x050314
505
506//*****************************************************************************
507#define RDR_TLCTL0 0x050318
508#define FLD_CFG_UR_CPL_MODE 0x00000040
509#define FLD_CFG_CORR_ERR_QUITE 0x00000020
510#define FLD_CFG_RCB_CK_EN 0x00000010
511#define FLD_CFG_BNDRY_CK_EN 0x00000008
512#define FLD_CFG_BYTE_EN_CK_EN 0x00000004
513#define FLD_CFG_RELAX_ORDER_MSK 0x00000002
514#define FLD_CFG_TAG_ORDER_EN 0x00000001
515
516//*****************************************************************************
517#define RDR_TLCTL1 0x05031C
518
519//*****************************************************************************
520#define RDR_REQRCAL 0x050320
521
522//*****************************************************************************
523#define RDR_REQRCAU 0x050324
524
525//*****************************************************************************
526#define RDR_REQEPA 0x050328
527
528//*****************************************************************************
529#define RDR_REQCTRL 0x05032C
530
531//*****************************************************************************
532#define RDR_REQSTAT 0x050330
533
534//*****************************************************************************
535#define RDR_TL_TEST 0x050334
536
537//*****************************************************************************
538#define RDR_VCR01_CTL 0x050348
539
540//*****************************************************************************
541#define RDR_VCR23_CTL 0x05034C
542
543//*****************************************************************************
544#define RDR_RX_VCR0_FC 0x050350
545
546//*****************************************************************************
547#define RDR_RX_VCR1_FC 0x050354
548
549//*****************************************************************************
550#define RDR_RX_VCR2_FC 0x050358
551
552//*****************************************************************************
553#define RDR_RX_VCR3_FC 0x05035C
554
555//*****************************************************************************
556// Data Link Layer Registers
557//*****************************************************************************
558#define RDR_DLLSTAT 0x050360
559
560//*****************************************************************************
561#define RDR_DLLCTRL 0x050364
562
563//*****************************************************************************
564#define RDR_REPLAYTO 0x050368
565
566//*****************************************************************************
567#define RDR_ACKLATTO 0x05036C
568
569//*****************************************************************************
570// MAC Layer Registers
571//*****************************************************************************
572#define RDR_MACSTAT0 0x050380
573
574//*****************************************************************************
575#define RDR_MACSTAT1 0x050384
576
577//*****************************************************************************
578#define RDR_MACCTRL0 0x050388
579
580//*****************************************************************************
581#define RDR_MACCTRL1 0x05038C
582
583//*****************************************************************************
584#define RDR_MACCTRL2 0x050390
585
586//*****************************************************************************
587#define RDR_MAC_LB_DATA 0x050394
588
589//*****************************************************************************
590#define RDR_L0S_EXIT_LAT 0x050398
591
592//*****************************************************************************
593// DMAC
594//*****************************************************************************
595#define DMA1_PTR1 0x100000 // DMA Current Ptr : Ch#1
596
597//*****************************************************************************
598#define DMA2_PTR1 0x100004 // DMA Current Ptr : Ch#2
599
600//*****************************************************************************
601#define DMA3_PTR1 0x100008 // DMA Current Ptr : Ch#3
602
603//*****************************************************************************
604#define DMA4_PTR1 0x10000C // DMA Current Ptr : Ch#4
605
606//*****************************************************************************
607#define DMA5_PTR1 0x100010 // DMA Current Ptr : Ch#5
608
609//*****************************************************************************
610#define DMA6_PTR1 0x100014 // DMA Current Ptr : Ch#6
611
612//*****************************************************************************
613#define DMA7_PTR1 0x100018 // DMA Current Ptr : Ch#7
614
615//*****************************************************************************
616#define DMA8_PTR1 0x10001C // DMA Current Ptr : Ch#8
617
618//*****************************************************************************
619#define DMA9_PTR1 0x100020 // DMA Current Ptr : Ch#9
620
621//*****************************************************************************
622#define DMA10_PTR1 0x100024 // DMA Current Ptr : Ch#10
623
624//*****************************************************************************
625#define DMA11_PTR1 0x100028 // DMA Current Ptr : Ch#11
626
627//*****************************************************************************
628#define DMA12_PTR1 0x10002C // DMA Current Ptr : Ch#12
629
630//*****************************************************************************
631#define DMA13_PTR1 0x100030 // DMA Current Ptr : Ch#13
632
633//*****************************************************************************
634#define DMA14_PTR1 0x100034 // DMA Current Ptr : Ch#14
635
636//*****************************************************************************
637#define DMA15_PTR1 0x100038 // DMA Current Ptr : Ch#15
638
639//*****************************************************************************
640#define DMA16_PTR1 0x10003C // DMA Current Ptr : Ch#16
641
642//*****************************************************************************
643#define DMA17_PTR1 0x100040 // DMA Current Ptr : Ch#17
644
645//*****************************************************************************
646#define DMA18_PTR1 0x100044 // DMA Current Ptr : Ch#18
647
648//*****************************************************************************
649#define DMA19_PTR1 0x100048 // DMA Current Ptr : Ch#19
650
651//*****************************************************************************
652#define DMA20_PTR1 0x10004C // DMA Current Ptr : Ch#20
653
654//*****************************************************************************
655#define DMA21_PTR1 0x100050 // DMA Current Ptr : Ch#21
656
657//*****************************************************************************
658#define DMA22_PTR1 0x100054 // DMA Current Ptr : Ch#22
659
660//*****************************************************************************
661#define DMA23_PTR1 0x100058 // DMA Current Ptr : Ch#23
662
663//*****************************************************************************
664#define DMA24_PTR1 0x10005C // DMA Current Ptr : Ch#24
665
666//*****************************************************************************
667#define DMA25_PTR1 0x100060 // DMA Current Ptr : Ch#25
668
669//*****************************************************************************
670#define DMA26_PTR1 0x100064 // DMA Current Ptr : Ch#26
671
672
673//*****************************************************************************
674#define DMA1_PTR2 0x100080 // DMA Tab Ptr : Ch#1
675
676//*****************************************************************************
677#define DMA2_PTR2 0x100084 // DMA Tab Ptr : Ch#2
678
679//*****************************************************************************
680#define DMA3_PTR2 0x100088 // DMA Tab Ptr : Ch#3
681
682//*****************************************************************************
683#define DMA4_PTR2 0x10008C // DMA Tab Ptr : Ch#4
684
685//*****************************************************************************
686#define DMA5_PTR2 0x100090 // DMA Tab Ptr : Ch#5
687
688//*****************************************************************************
689#define DMA6_PTR2 0x100094 // DMA Tab Ptr : Ch#6
690
691//*****************************************************************************
692#define DMA7_PTR2 0x100098 // DMA Tab Ptr : Ch#7
693
694//*****************************************************************************
695#define DMA8_PTR2 0x10009C // DMA Tab Ptr : Ch#8
696
697//*****************************************************************************
698#define DMA9_PTR2 0x1000A0 // DMA Tab Ptr : Ch#9
699
700//*****************************************************************************
701#define DMA10_PTR2 0x1000A4 // DMA Tab Ptr : Ch#10
702
703//*****************************************************************************
704#define DMA11_PTR2 0x1000A8 // DMA Tab Ptr : Ch#11
705
706//*****************************************************************************
707#define DMA12_PTR2 0x1000AC // DMA Tab Ptr : Ch#12
708
709//*****************************************************************************
710#define DMA13_PTR2 0x1000B0 // DMA Tab Ptr : Ch#13
711
712//*****************************************************************************
713#define DMA14_PTR2 0x1000B4 // DMA Tab Ptr : Ch#14
714
715//*****************************************************************************
716#define DMA15_PTR2 0x1000B8 // DMA Tab Ptr : Ch#15
717
718//*****************************************************************************
719#define DMA16_PTR2 0x1000BC // DMA Tab Ptr : Ch#16
720
721//*****************************************************************************
722#define DMA17_PTR2 0x1000C0 // DMA Tab Ptr : Ch#17
723
724//*****************************************************************************
725#define DMA18_PTR2 0x1000C4 // DMA Tab Ptr : Ch#18
726
727//*****************************************************************************
728#define DMA19_PTR2 0x1000C8 // DMA Tab Ptr : Ch#19
729
730//*****************************************************************************
731#define DMA20_PTR2 0x1000CC // DMA Tab Ptr : Ch#20
732
733//*****************************************************************************
734#define DMA21_PTR2 0x1000D0 // DMA Tab Ptr : Ch#21
735
736//*****************************************************************************
737#define DMA22_PTR2 0x1000D4 // DMA Tab Ptr : Ch#22
738
739//*****************************************************************************
740#define DMA23_PTR2 0x1000D8 // DMA Tab Ptr : Ch#23
741
742//*****************************************************************************
743#define DMA24_PTR2 0x1000DC // DMA Tab Ptr : Ch#24
744
745//*****************************************************************************
746#define DMA25_PTR2 0x1000E0 // DMA Tab Ptr : Ch#25
747
748//*****************************************************************************
749#define DMA26_PTR2 0x1000E4 // DMA Tab Ptr : Ch#26
750
751
752
753//*****************************************************************************
754#define DMA1_CNT1 0x100100 // DMA BuFFer Size : Ch#1
755
756//*****************************************************************************
757#define DMA2_CNT1 0x100104 // DMA BuFFer Size : Ch#2
758
759//*****************************************************************************
760#define DMA3_CNT1 0x100108 // DMA BuFFer Size : Ch#3
761
762//*****************************************************************************
763#define DMA4_CNT1 0x10010C // DMA BuFFer Size : Ch#4
764
765//*****************************************************************************
766#define DMA5_CNT1 0x100110 // DMA BuFFer Size : Ch#5
767
768//*****************************************************************************
769#define DMA6_CNT1 0x100114 // DMA BuFFer Size : Ch#6
770
771//*****************************************************************************
772#define DMA7_CNT1 0x100118 // DMA BuFFer Size : Ch#7
773
774//*****************************************************************************
775#define DMA8_CNT1 0x10011C // DMA BuFFer Size : Ch#8
776
777//*****************************************************************************
778#define DMA9_CNT1 0x100120 // DMA BuFFer Size : Ch#9
779
780//*****************************************************************************
781#define DMA10_CNT1 0x100124 // DMA BuFFer Size : Ch#10
782
783//*****************************************************************************
784#define DMA11_CNT1 0x100128 // DMA BuFFer Size : Ch#11
785
786//*****************************************************************************
787#define DMA12_CNT1 0x10012C // DMA BuFFer Size : Ch#12
788
789//*****************************************************************************
790#define DMA13_CNT1 0x100130 // DMA BuFFer Size : Ch#13
791
792//*****************************************************************************
793#define DMA14_CNT1 0x100134 // DMA BuFFer Size : Ch#14
794
795//*****************************************************************************
796#define DMA15_CNT1 0x100138 // DMA BuFFer Size : Ch#15
797
798//*****************************************************************************
799#define DMA16_CNT1 0x10013C // DMA BuFFer Size : Ch#16
800
801//*****************************************************************************
802#define DMA17_CNT1 0x100140 // DMA BuFFer Size : Ch#17
803
804//*****************************************************************************
805#define DMA18_CNT1 0x100144 // DMA BuFFer Size : Ch#18
806
807//*****************************************************************************
808#define DMA19_CNT1 0x100148 // DMA BuFFer Size : Ch#19
809
810//*****************************************************************************
811#define DMA20_CNT1 0x10014C // DMA BuFFer Size : Ch#20
812
813//*****************************************************************************
814#define DMA21_CNT1 0x100150 // DMA BuFFer Size : Ch#21
815
816//*****************************************************************************
817#define DMA22_CNT1 0x100154 // DMA BuFFer Size : Ch#22
818
819//*****************************************************************************
820#define DMA23_CNT1 0x100158 // DMA BuFFer Size : Ch#23
821
822//*****************************************************************************
823#define DMA24_CNT1 0x10015C // DMA BuFFer Size : Ch#24
824
825//*****************************************************************************
826#define DMA25_CNT1 0x100160 // DMA BuFFer Size : Ch#25
827
828//*****************************************************************************
829#define DMA26_CNT1 0x100164 // DMA BuFFer Size : Ch#26
830
831
832//*****************************************************************************
833#define DMA1_CNT2 0x100180 // DMA Table Size : Ch#1
834
835//*****************************************************************************
836#define DMA2_CNT2 0x100184 // DMA Table Size : Ch#2
837
838//*****************************************************************************
839#define DMA3_CNT2 0x100188 // DMA Table Size : Ch#3
840
841//*****************************************************************************
842#define DMA4_CNT2 0x10018C // DMA Table Size : Ch#4
843
844//*****************************************************************************
845#define DMA5_CNT2 0x100190 // DMA Table Size : Ch#5
846
847//*****************************************************************************
848#define DMA6_CNT2 0x100194 // DMA Table Size : Ch#6
849
850//*****************************************************************************
851#define DMA7_CNT2 0x100198 // DMA Table Size : Ch#7
852
853//*****************************************************************************
854#define DMA8_CNT2 0x10019C // DMA Table Size : Ch#8
855
856//*****************************************************************************
857#define DMA9_CNT2 0x1001A0 // DMA Table Size : Ch#9
858
859//*****************************************************************************
860#define DMA10_CNT2 0x1001A4 // DMA Table Size : Ch#10
861
862//*****************************************************************************
863#define DMA11_CNT2 0x1001A8 // DMA Table Size : Ch#11
864
865//*****************************************************************************
866#define DMA12_CNT2 0x1001AC // DMA Table Size : Ch#12
867
868//*****************************************************************************
869#define DMA13_CNT2 0x1001B0 // DMA Table Size : Ch#13
870
871//*****************************************************************************
872#define DMA14_CNT2 0x1001B4 // DMA Table Size : Ch#14
873
874//*****************************************************************************
875#define DMA15_CNT2 0x1001B8 // DMA Table Size : Ch#15
876
877//*****************************************************************************
878#define DMA16_CNT2 0x1001BC // DMA Table Size : Ch#16
879
880//*****************************************************************************
881#define DMA17_CNT2 0x1001C0 // DMA Table Size : Ch#17
882
883//*****************************************************************************
884#define DMA18_CNT2 0x1001C4 // DMA Table Size : Ch#18
885
886//*****************************************************************************
887#define DMA19_CNT2 0x1001C8 // DMA Table Size : Ch#19
888
889//*****************************************************************************
890#define DMA20_CNT2 0x1001CC // DMA Table Size : Ch#20
891
892//*****************************************************************************
893#define DMA21_CNT2 0x1001D0 // DMA Table Size : Ch#21
894
895//*****************************************************************************
896#define DMA22_CNT2 0x1001D4 // DMA Table Size : Ch#22
897
898//*****************************************************************************
899#define DMA23_CNT2 0x1001D8 // DMA Table Size : Ch#23
900
901//*****************************************************************************
902#define DMA24_CNT2 0x1001DC // DMA Table Size : Ch#24
903
904//*****************************************************************************
905#define DMA25_CNT2 0x1001E0 // DMA Table Size : Ch#25
906
907//*****************************************************************************
908#define DMA26_CNT2 0x1001E4 // DMA Table Size : Ch#26
909
910
911
912//*****************************************************************************
913 // ITG
914//*****************************************************************************
915#define TM_CNT_LDW 0x110000 // Timer : Counter low
916
917//*****************************************************************************
918#define TM_CNT_UW 0x110004 // Timer : Counter high word
919
920//*****************************************************************************
921#define TM_LMT_LDW 0x110008 // Timer : Limit low
922
923//*****************************************************************************
924#define TM_LMT_UW 0x11000C // Timer : Limit high word
925
926//*****************************************************************************
927#define GP0_IO 0x110010 // GPIO output enables data I/O
928#define FLD_GP_OE 0x00FF0000 // GPIO: GP_OE output enable
929#define FLD_GP_IN 0x0000FF00 // GPIO: GP_IN status
930#define FLD_GP_OUT 0x000000FF // GPIO: GP_OUT control
931
932//*****************************************************************************
933#define GPIO_ISM 0x110014 // GPIO interrupt sensitivity mode
934#define FLD_GP_ISM_SNS 0x00000070
935#define FLD_GP_ISM_POL 0x00000007
936
937//*****************************************************************************
938#define SOFT_RESET 0x11001C // Output system reset reg
939#define FLD_PECOS_SOFT_RESET 0x00000001
940
941//*****************************************************************************
942#define MC416_RWD 0x110020 // MC416 GPIO[18:3] pin
943#define MC416_OEN 0x110024 // Output enable of GPIO[18:3]
944#define MC416_CTL 0x110028
945
946//*****************************************************************************
947#define ALT_PIN_OUT_SEL 0x11002C // Alternate GPIO output select
948
949#define FLD_ALT_GPIO_OUT_SEL 0xF0000000
950// 0 Disabled <-- default
951// 1 GPIO[0]
952// 2 GPIO[10]
953// 3 VIP_656_DATA_VAL
954// 4 VIP_656_DATA[0]
955// 5 VIP_656_CLK
956// 6 VIP_656_DATA_EXT[1]
957// 7 VIP_656_DATA_EXT[0]
958// 8 ATT_IF
959
960#define FLD_AUX_PLL_CLK_ALT_SEL 0x0F000000
961// 0 AUX_PLL_CLK<-- default
962// 1 GPIO[2]
963// 2 GPIO[10]
964// 3 VIP_656_DATA_VAL
965// 4 VIP_656_DATA[0]
966// 5 VIP_656_CLK
967// 6 VIP_656_DATA_EXT[1]
968// 7 VIP_656_DATA_EXT[0]
969
970#define FLD_IR_TX_ALT_SEL 0x00F00000
971// 0 IR_TX <-- default
972// 1 GPIO[1]
973// 2 GPIO[10]
974// 3 VIP_656_DATA_VAL
975// 4 VIP_656_DATA[0]
976// 5 VIP_656_CLK
977// 6 VIP_656_DATA_EXT[1]
978// 7 VIP_656_DATA_EXT[0]
979
980#define FLD_IR_RX_ALT_SEL 0x000F0000
981// 0 IR_RX <-- default
982// 1 GPIO[0]
983// 2 GPIO[10]
984// 3 VIP_656_DATA_VAL
985// 4 VIP_656_DATA[0]
986// 5 VIP_656_CLK
987// 6 VIP_656_DATA_EXT[1]
988// 7 VIP_656_DATA_EXT[0]
989
990#define FLD_GPIO10_ALT_SEL 0x0000F000
991// 0 GPIO[10] <-- default
992// 1 GPIO[0]
993// 2 GPIO[10]
994// 3 VIP_656_DATA_VAL
995// 4 VIP_656_DATA[0]
996// 5 VIP_656_CLK
997// 6 VIP_656_DATA_EXT[1]
998// 7 VIP_656_DATA_EXT[0]
999
1000#define FLD_GPIO2_ALT_SEL 0x00000F00
1001// 0 GPIO[2] <-- default
1002// 1 GPIO[1]
1003// 2 GPIO[10]
1004// 3 VIP_656_DATA_VAL
1005// 4 VIP_656_DATA[0]
1006// 5 VIP_656_CLK
1007// 6 VIP_656_DATA_EXT[1]
1008// 7 VIP_656_DATA_EXT[0]
1009
1010#define FLD_GPIO1_ALT_SEL 0x000000F0
1011// 0 GPIO[1] <-- default
1012// 1 GPIO[0]
1013// 2 GPIO[10]
1014// 3 VIP_656_DATA_VAL
1015// 4 VIP_656_DATA[0]
1016// 5 VIP_656_CLK
1017// 6 VIP_656_DATA_EXT[1]
1018// 7 VIP_656_DATA_EXT[0]
1019
1020#define FLD_GPIO0_ALT_SEL 0x0000000F
1021// 0 GPIO[0] <-- default
1022// 1 GPIO[1]
1023// 2 GPIO[10]
1024// 3 VIP_656_DATA_VAL
1025// 4 VIP_656_DATA[0]
1026// 5 VIP_656_CLK
1027// 6 VIP_656_DATA_EXT[1]
1028// 7 VIP_656_DATA_EXT[0]
1029
1030#define ALT_PIN_IN_SEL 0x110030 // Alternate GPIO input select
1031
1032#define FLD_GPIO10_ALT_IN_SEL 0x0000F000
1033// 0 GPIO[10] <-- default
1034// 1 IR_RX
1035// 2 IR_TX
1036// 3 AUX_PLL_CLK
1037// 4 IF_ATT_SEL
1038// 5 GPIO[0]
1039// 6 GPIO[1]
1040// 7 GPIO[2]
1041
1042#define FLD_GPIO2_ALT_IN_SEL 0x00000F00
1043// 0 GPIO[2] <-- default
1044// 1 IR_RX
1045// 2 IR_TX
1046// 3 AUX_PLL_CLK
1047// 4 IF_ATT_SEL
1048
1049#define FLD_GPIO1_ALT_IN_SEL 0x000000F0
1050// 0 GPIO[1] <-- default
1051// 1 IR_RX
1052// 2 IR_TX
1053// 3 AUX_PLL_CLK
1054// 4 IF_ATT_SEL
1055
1056#define FLD_GPIO0_ALT_IN_SEL 0x0000000F
1057// 0 GPIO[0] <-- default
1058// 1 IR_RX
1059// 2 IR_TX
1060// 3 AUX_PLL_CLK
1061// 4 IF_ATT_SEL
1062
1063//*****************************************************************************
1064#define TEST_BUS_CTL1 0x110040 // Test bus control register #1
1065
1066//*****************************************************************************
1067#define TEST_BUS_CTL2 0x110044 // Test bus control register #2
1068
1069//*****************************************************************************
1070#define CLK_DELAY 0x110048 // Clock delay
1071#define FLD_MOE_CLK_DIS 0x80000000 // Disable MoE clock
1072
1073
1074//*****************************************************************************
1075#define PAD_CTRL 0x110068 // Pad drive strength control
1076
1077//*****************************************************************************
1078#define MBIST_CTRL 0x110050 // SRAM memory built-in self test control
1079
1080//*****************************************************************************
1081#define MBIST_STAT 0x110054 // SRAM memory built-in self test status
1082
1083//*****************************************************************************
1084// PLL registers
1085//*****************************************************************************
1086#define PLL_A_INT_FRAC 0x110088
1087#define PLL_A_POST_STAT_BIST 0x11008C
1088#define PLL_B_INT_FRAC 0x110090
1089#define PLL_B_POST_STAT_BIST 0x110094
1090#define PLL_C_INT_FRAC 0x110098
1091#define PLL_C_POST_STAT_BIST 0x11009C
1092#define PLL_D_INT_FRAC 0x1100A0
1093#define PLL_D_POST_STAT_BIST 0x1100A4
1094
1095#define CLK_RST 0x11002C
1096#define FLD_VID_I_CLK_NOE 0x00001000
1097#define FLD_VID_J_CLK_NOE 0x00002000
1098#define FLD_USE_ALT_PLL_REF 0x00004000
1099
1100#define VID_CH_MODE_SEL 0x110078
1101#define VID_CH_CLK_SEL 0x11007C
1102
1103
1104//*****************************************************************************
1105#define VBI_A_DMA 0x130008 // VBI A DMA data port
1106
1107//*****************************************************************************
1108#define VID_A_VIP_CTL 0x130080 // Video A VIP format control
1109#define FLD_VIP_MODE 0x00000001
1110
1111//*****************************************************************************
1112#define VID_A_PIXEL_FRMT 0x130084 // Video A pixel format
1113#define FLD_VID_A_GAMMA_DIS 0x00000008
1114#define FLD_VID_A_FORMAT 0x00000007
1115#define FLD_VID_A_GAMMA_FACTOR 0x00000010
1116
1117//*****************************************************************************
1118#define VID_A_VBI_CTL 0x130088 // Video A VBI miscellaneous control
1119#define FLD_VID_A_VIP_EXT 0x00000003
1120
1121//*****************************************************************************
1122#define VID_B_DMA 0x130100 // Video B DMA data port
1123
1124//*****************************************************************************
1125#define VBI_B_DMA 0x130108 // VBI B DMA data port
1126
1127//*****************************************************************************
1128#define VID_B_SRC_SEL 0x130144 // Video B source select
1129#define FLD_VID_B_SRC_SEL 0x00000000
1130
1131//*****************************************************************************
1132#define VID_B_LNGTH 0x130150 // Video B line length
1133#define FLD_VID_B_LN_LNGTH 0x00000FFF
1134
1135//*****************************************************************************
1136#define VID_B_VIP_CTL 0x130180 // Video B VIP format control
1137
1138//*****************************************************************************
1139#define VID_B_PIXEL_FRMT 0x130184 // Video B pixel format
1140#define FLD_VID_B_GAMMA_DIS 0x00000008
1141#define FLD_VID_B_FORMAT 0x00000007
1142#define FLD_VID_B_GAMMA_FACTOR 0x00000010
1143
1144//*****************************************************************************
1145#define VID_C_DMA 0x130200 // Video C DMA data port
1146
1147//*****************************************************************************
1148#define VID_C_LNGTH 0x130250 // Video C line length
1149#define FLD_VID_C_LN_LNGTH 0x00000FFF
1150
1151
1152//*****************************************************************************
1153// Video Destination Channels
1154//*****************************************************************************
1155
1156#define VID_DST_A_GPCNT 0x130020 // Video A general purpose counter
1157#define VID_DST_B_GPCNT 0x130120 // Video B general purpose counter
1158#define VID_DST_C_GPCNT 0x130220 // Video C general purpose counter
1159#define VID_DST_D_GPCNT 0x130320 // Video D general purpose counter
1160#define VID_DST_E_GPCNT 0x130420 // Video E general purpose counter
1161#define VID_DST_F_GPCNT 0x130520 // Video F general purpose counter
1162#define VID_DST_G_GPCNT 0x130620 // Video G general purpose counter
1163#define VID_DST_H_GPCNT 0x130720 // Video H general purpose counter
1164
1165//*****************************************************************************
1166
1167#define VID_DST_A_GPCNT_CTL 0x130030 // Video A general purpose control
1168#define VID_DST_B_GPCNT_CTL 0x130130 // Video B general purpose control
1169#define VID_DST_C_GPCNT_CTL 0x130230 // Video C general purpose control
1170#define VID_DST_D_GPCNT_CTL 0x130330 // Video D general purpose control
1171#define VID_DST_E_GPCNT_CTL 0x130430 // Video E general purpose control
1172#define VID_DST_F_GPCNT_CTL 0x130530 // Video F general purpose control
1173#define VID_DST_G_GPCNT_CTL 0x130630 // Video G general purpose control
1174#define VID_DST_H_GPCNT_CTL 0x130730 // Video H general purpose control
1175
1176
1177//*****************************************************************************
1178
1179#define VID_DST_A_DMA_CTL 0x130040 // Video A DMA control
1180#define VID_DST_B_DMA_CTL 0x130140 // Video B DMA control
1181#define VID_DST_C_DMA_CTL 0x130240 // Video C DMA control
1182#define VID_DST_D_DMA_CTL 0x130340 // Video D DMA control
1183#define VID_DST_E_DMA_CTL 0x130440 // Video E DMA control
1184#define VID_DST_F_DMA_CTL 0x130540 // Video F DMA control
1185#define VID_DST_G_DMA_CTL 0x130640 // Video G DMA control
1186#define VID_DST_H_DMA_CTL 0x130740 // Video H DMA control
1187
1188#define FLD_VID_RISC_EN 0x00000010
1189#define FLD_VID_FIFO_EN 0x00000001
1190
1191//*****************************************************************************
1192
1193#define VID_DST_A_VIP_CTL 0x130080 // Video A VIP control
1194#define VID_DST_B_VIP_CTL 0x130180 // Video B VIP control
1195#define VID_DST_C_VIP_CTL 0x130280 // Video C VIP control
1196#define VID_DST_D_VIP_CTL 0x130380 // Video D VIP control
1197#define VID_DST_E_VIP_CTL 0x130480 // Video E VIP control
1198#define VID_DST_F_VIP_CTL 0x130580 // Video F VIP control
1199#define VID_DST_G_VIP_CTL 0x130680 // Video G VIP control
1200#define VID_DST_H_VIP_CTL 0x130780 // Video H VIP control
1201
1202//*****************************************************************************
1203
1204#define VID_DST_A_PIX_FRMT 0x130084 // Video A Pixel format
1205#define VID_DST_B_PIX_FRMT 0x130184 // Video B Pixel format
1206#define VID_DST_C_PIX_FRMT 0x130284 // Video C Pixel format
1207#define VID_DST_D_PIX_FRMT 0x130384 // Video D Pixel format
1208#define VID_DST_E_PIX_FRMT 0x130484 // Video E Pixel format
1209#define VID_DST_F_PIX_FRMT 0x130584 // Video F Pixel format
1210#define VID_DST_G_PIX_FRMT 0x130684 // Video G Pixel format
1211#define VID_DST_H_PIX_FRMT 0x130784 // Video H Pixel format
1212
1213//*****************************************************************************
1214// Video Source Channels
1215//*****************************************************************************
1216
1217#define VID_SRC_A_GPCNT_CTL 0x130804 // Video A general purpose control
1218#define VID_SRC_B_GPCNT_CTL 0x130904 // Video B general purpose control
1219#define VID_SRC_C_GPCNT_CTL 0x130A04 // Video C general purpose control
1220#define VID_SRC_D_GPCNT_CTL 0x130B04 // Video D general purpose control
1221#define VID_SRC_E_GPCNT_CTL 0x130C04 // Video E general purpose control
1222#define VID_SRC_F_GPCNT_CTL 0x130D04 // Video F general purpose control
1223#define VID_SRC_I_GPCNT_CTL 0x130E04 // Video I general purpose control
1224#define VID_SRC_J_GPCNT_CTL 0x130F04 // Video J general purpose control
1225
1226//*****************************************************************************
1227
1228#define VID_SRC_A_GPCNT 0x130808 // Video A general purpose counter
1229#define VID_SRC_B_GPCNT 0x130908 // Video B general purpose counter
1230#define VID_SRC_C_GPCNT 0x130A08 // Video C general purpose counter
1231#define VID_SRC_D_GPCNT 0x130B08 // Video D general purpose counter
1232#define VID_SRC_E_GPCNT 0x130C08 // Video E general purpose counter
1233#define VID_SRC_F_GPCNT 0x130D08 // Video F general purpose counter
1234#define VID_SRC_I_GPCNT 0x130E08 // Video I general purpose counter
1235#define VID_SRC_J_GPCNT 0x130F08 // Video J general purpose counter
1236
1237//*****************************************************************************
1238
1239#define VID_SRC_A_DMA_CTL 0x13080C // Video A DMA control
1240#define VID_SRC_B_DMA_CTL 0x13090C // Video B DMA control
1241#define VID_SRC_C_DMA_CTL 0x130A0C // Video C DMA control
1242#define VID_SRC_D_DMA_CTL 0x130B0C // Video D DMA control
1243#define VID_SRC_E_DMA_CTL 0x130C0C // Video E DMA control
1244#define VID_SRC_F_DMA_CTL 0x130D0C // Video F DMA control
1245#define VID_SRC_I_DMA_CTL 0x130E0C // Video I DMA control
1246#define VID_SRC_J_DMA_CTL 0x130F0C // Video J DMA control
1247
1248#define FLD_APB_RISC_EN 0x00000010
1249#define FLD_APB_FIFO_EN 0x00000001
1250
1251//*****************************************************************************
1252
1253#define VID_SRC_A_FMT_CTL 0x130810 // Video A format control
1254#define VID_SRC_B_FMT_CTL 0x130910 // Video B format control
1255#define VID_SRC_C_FMT_CTL 0x130A10 // Video C format control
1256#define VID_SRC_D_FMT_CTL 0x130B10 // Video D format control
1257#define VID_SRC_E_FMT_CTL 0x130C10 // Video E format control
1258#define VID_SRC_F_FMT_CTL 0x130D10 // Video F format control
1259#define VID_SRC_I_FMT_CTL 0x130E10 // Video I format control
1260#define VID_SRC_J_FMT_CTL 0x130F10 // Video J format control
1261
1262//*****************************************************************************
1263
1264#define VID_SRC_A_ACTIVE_CTL1 0x130814 // Video A active control 1
1265#define VID_SRC_B_ACTIVE_CTL1 0x130914 // Video B active control 1
1266#define VID_SRC_C_ACTIVE_CTL1 0x130A14 // Video C active control 1
1267#define VID_SRC_D_ACTIVE_CTL1 0x130B14 // Video D active control 1
1268#define VID_SRC_E_ACTIVE_CTL1 0x130C14 // Video E active control 1
1269#define VID_SRC_F_ACTIVE_CTL1 0x130D14 // Video F active control 1
1270#define VID_SRC_I_ACTIVE_CTL1 0x130E14 // Video I active control 1
1271#define VID_SRC_J_ACTIVE_CTL1 0x130F14 // Video J active control 1
1272
1273//*****************************************************************************
1274
1275#define VID_SRC_A_ACTIVE_CTL2 0x130818 // Video A active control 2
1276#define VID_SRC_B_ACTIVE_CTL2 0x130918 // Video B active control 2
1277#define VID_SRC_C_ACTIVE_CTL2 0x130A18 // Video C active control 2
1278#define VID_SRC_D_ACTIVE_CTL2 0x130B18 // Video D active control 2
1279#define VID_SRC_E_ACTIVE_CTL2 0x130C18 // Video E active control 2
1280#define VID_SRC_F_ACTIVE_CTL2 0x130D18 // Video F active control 2
1281#define VID_SRC_I_ACTIVE_CTL2 0x130E18 // Video I active control 2
1282#define VID_SRC_J_ACTIVE_CTL2 0x130F18 // Video J active control 2
1283
1284//*****************************************************************************
1285
1286#define VID_SRC_A_CDT_SZ 0x13081C // Video A CDT size
1287#define VID_SRC_B_CDT_SZ 0x13091C // Video B CDT size
1288#define VID_SRC_C_CDT_SZ 0x130A1C // Video C CDT size
1289#define VID_SRC_D_CDT_SZ 0x130B1C // Video D CDT size
1290#define VID_SRC_E_CDT_SZ 0x130C1C // Video E CDT size
1291#define VID_SRC_F_CDT_SZ 0x130D1C // Video F CDT size
1292#define VID_SRC_I_CDT_SZ 0x130E1C // Video I CDT size
1293#define VID_SRC_J_CDT_SZ 0x130F1C // Video J CDT size
1294
1295//*****************************************************************************
1296// Audio I/F
1297//*****************************************************************************
1298#define AUD_DST_A_DMA 0x140000 // Audio Int A DMA data port
1299#define AUD_SRC_A_DMA 0x140008 // Audio Int A DMA data port
1300
1301#define AUD_A_GPCNT 0x140010 // Audio Int A gp counter
1302#define FLD_AUD_A_GP_CNT 0x0000FFFF
1303
1304#define AUD_A_GPCNT_CTL 0x140014 // Audio Int A gp control
1305
1306#define AUD_A_LNGTH 0x140018 // Audio Int A line length
1307
1308#define AUD_A_CFG 0x14001C // Audio Int A configuration
1309
1310//*****************************************************************************
1311#define AUD_DST_B_DMA 0x140100 // Audio Int B DMA data port
1312#define AUD_SRC_B_DMA 0x140108 // Audio Int B DMA data port
1313
1314#define AUD_B_GPCNT 0x140110 // Audio Int B gp counter
1315#define FLD_AUD_B_GP_CNT 0x0000FFFF
1316
1317#define AUD_B_GPCNT_CTL 0x140114 // Audio Int B gp control
1318
1319#define AUD_B_LNGTH 0x140118 // Audio Int B line length
1320
1321#define AUD_B_CFG 0x14011C // Audio Int B configuration
1322
1323//*****************************************************************************
1324#define AUD_DST_C_DMA 0x140200 // Audio Int C DMA data port
1325#define AUD_SRC_C_DMA 0x140208 // Audio Int C DMA data port
1326
1327#define AUD_C_GPCNT 0x140210 // Audio Int C gp counter
1328#define FLD_AUD_C_GP_CNT 0x0000FFFF
1329
1330#define AUD_C_GPCNT_CTL 0x140214 // Audio Int C gp control
1331
1332#define AUD_C_LNGTH 0x140218 // Audio Int C line length
1333
1334#define AUD_C_CFG 0x14021C // Audio Int C configuration
1335
1336//*****************************************************************************
1337#define AUD_DST_D_DMA 0x140300 // Audio Int D DMA data port
1338#define AUD_SRC_D_DMA 0x140308 // Audio Int D DMA data port
1339
1340#define AUD_D_GPCNT 0x140310 // Audio Int D gp counter
1341#define FLD_AUD_D_GP_CNT 0x0000FFFF
1342
1343#define AUD_D_GPCNT_CTL 0x140314 // Audio Int D gp control
1344
1345#define AUD_D_LNGTH 0x140318 // Audio Int D line length
1346
1347#define AUD_D_CFG 0x14031C // Audio Int D configuration
1348
1349//*****************************************************************************
1350#define AUD_SRC_E_DMA 0x140400 // Audio Int E DMA data port
1351
1352#define AUD_E_GPCNT 0x140410 // Audio Int E gp counter
1353#define FLD_AUD_E_GP_CNT 0x0000FFFF
1354
1355#define AUD_E_GPCNT_CTL 0x140414 // Audio Int E gp control
1356
1357#define AUD_E_CFG 0x14041C // Audio Int E configuration
1358
1359//*****************************************************************************
1360
1361#define FLD_AUD_DST_LN_LNGTH 0x00000FFF
1362
1363#define FLD_AUD_DST_PK_MODE 0x00004000
1364
1365#define FLD_AUD_CLK_ENABLE 0x00000200
1366
1367#define FLD_AUD_MASTER_MODE 0x00000002
1368
1369#define FLD_AUD_SONY_MODE 0x00000001
1370
1371#define FLD_AUD_CLK_SELECT_PLL_D 0x00001800
1372
1373#define FLD_AUD_DST_ENABLE 0x00020000
1374
1375#define FLD_AUD_SRC_ENABLE 0x00010000
1376
1377//*****************************************************************************
1378#define AUD_INT_DMA_CTL 0x140500 // Audio Int DMA control
1379
1380#define FLD_AUD_SRC_E_RISC_EN 0x00008000
1381#define FLD_AUD_SRC_C_RISC_EN 0x00004000
1382#define FLD_AUD_SRC_B_RISC_EN 0x00002000
1383#define FLD_AUD_SRC_A_RISC_EN 0x00001000
1384
1385#define FLD_AUD_DST_D_RISC_EN 0x00000800
1386#define FLD_AUD_DST_C_RISC_EN 0x00000400
1387#define FLD_AUD_DST_B_RISC_EN 0x00000200
1388#define FLD_AUD_DST_A_RISC_EN 0x00000100
1389
1390#define FLD_AUD_SRC_E_FIFO_EN 0x00000080
1391#define FLD_AUD_SRC_C_FIFO_EN 0x00000040
1392#define FLD_AUD_SRC_B_FIFO_EN 0x00000020
1393#define FLD_AUD_SRC_A_FIFO_EN 0x00000010
1394
1395#define FLD_AUD_DST_D_FIFO_EN 0x00000008
1396#define FLD_AUD_DST_C_FIFO_EN 0x00000004
1397#define FLD_AUD_DST_B_FIFO_EN 0x00000002
1398#define FLD_AUD_DST_A_FIFO_EN 0x00000001
1399
1400
1401//*****************************************************************************
1402//
1403// Mobilygen Interface Registers
1404//
1405//*****************************************************************************
1406// Mobilygen Interface A
1407//*****************************************************************************
1408#define MB_IF_A_DMA 0x150000 // MBIF A DMA data port
1409#define MB_IF_A_GPCN 0x150008 // MBIF A GP counter
1410#define MB_IF_A_GPCN_CTRL 0x15000C
1411#define MB_IF_A_DMA_CTRL 0x150010
1412#define MB_IF_A_LENGTH 0x150014
1413#define MB_IF_A_HDMA_XFER_SZ 0x150018
1414#define MB_IF_A_HCMD 0x15001C
1415#define MB_IF_A_HCONFIG 0x150020
1416#define MB_IF_A_DATA_STRUCT_0 0x150024
1417#define MB_IF_A_DATA_STRUCT_1 0x150028
1418#define MB_IF_A_DATA_STRUCT_2 0x15002C
1419#define MB_IF_A_DATA_STRUCT_3 0x150030
1420#define MB_IF_A_DATA_STRUCT_4 0x150034
1421#define MB_IF_A_DATA_STRUCT_5 0x150038
1422#define MB_IF_A_DATA_STRUCT_6 0x15003C
1423#define MB_IF_A_DATA_STRUCT_7 0x150040
1424#define MB_IF_A_DATA_STRUCT_8 0x150044
1425#define MB_IF_A_DATA_STRUCT_9 0x150048
1426#define MB_IF_A_DATA_STRUCT_A 0x15004C
1427#define MB_IF_A_DATA_STRUCT_B 0x150050
1428#define MB_IF_A_DATA_STRUCT_C 0x150054
1429#define MB_IF_A_DATA_STRUCT_D 0x150058
1430#define MB_IF_A_DATA_STRUCT_E 0x15005C
1431#define MB_IF_A_DATA_STRUCT_F 0x150060
1432//*****************************************************************************
1433// Mobilygen Interface B
1434//*****************************************************************************
1435#define MB_IF_B_DMA 0x160000 // MBIF A DMA data port
1436#define MB_IF_B_GPCN 0x160008 // MBIF A GP counter
1437#define MB_IF_B_GPCN_CTRL 0x16000C
1438#define MB_IF_B_DMA_CTRL 0x160010
1439#define MB_IF_B_LENGTH 0x160014
1440#define MB_IF_B_HDMA_XFER_SZ 0x160018
1441#define MB_IF_B_HCMD 0x16001C
1442#define MB_IF_B_HCONFIG 0x160020
1443#define MB_IF_B_DATA_STRUCT_0 0x160024
1444#define MB_IF_B_DATA_STRUCT_1 0x160028
1445#define MB_IF_B_DATA_STRUCT_2 0x16002C
1446#define MB_IF_B_DATA_STRUCT_3 0x160030
1447#define MB_IF_B_DATA_STRUCT_4 0x160034
1448#define MB_IF_B_DATA_STRUCT_5 0x160038
1449#define MB_IF_B_DATA_STRUCT_6 0x16003C
1450#define MB_IF_B_DATA_STRUCT_7 0x160040
1451#define MB_IF_B_DATA_STRUCT_8 0x160044
1452#define MB_IF_B_DATA_STRUCT_9 0x160048
1453#define MB_IF_B_DATA_STRUCT_A 0x16004C
1454#define MB_IF_B_DATA_STRUCT_B 0x160050
1455#define MB_IF_B_DATA_STRUCT_C 0x160054
1456#define MB_IF_B_DATA_STRUCT_D 0x160058
1457#define MB_IF_B_DATA_STRUCT_E 0x16005C
1458#define MB_IF_B_DATA_STRUCT_F 0x160060
1459
1460// MB_DMA_CTRL
1461#define FLD_MB_IF_RISC_EN 0x00000010
1462#define FLD_MB_IF_FIFO_EN 0x00000001
1463
1464// MB_LENGTH
1465#define FLD_MB_IF_LN_LNGTH 0x00000FFF
1466
1467// MB_HCMD register
1468#define FLD_MB_HCMD_H_GO 0x80000000
1469#define FLD_MB_HCMD_H_BUSY 0x40000000
1470#define FLD_MB_HCMD_H_DMA_HOLD 0x10000000
1471#define FLD_MB_HCMD_H_DMA_BUSY 0x08000000
1472#define FLD_MB_HCMD_H_DMA_TYPE 0x04000000
1473#define FLD_MB_HCMD_H_DMA_XACT 0x02000000
1474#define FLD_MB_HCMD_H_RW_N 0x01000000
1475#define FLD_MB_HCMD_H_ADDR 0x00FF0000
1476#define FLD_MB_HCMD_H_DATA 0x0000FFFF
1477
1478
1479//*****************************************************************************
1480// I2C #1
1481//*****************************************************************************
1482#define I2C1_ADDR 0x180000 // I2C #1 address
1483#define FLD_I2C_DADDR 0xfe000000 // RW [31:25] I2C Device Address
1484 // RO [24] reserved
1485//*****************************************************************************
1486#define FLD_I2C_SADDR 0x00FFFFFF // RW [23:0] I2C Sub-address
1487
1488//*****************************************************************************
1489#define I2C1_WDATA 0x180004 // I2C #1 write data
1490#define FLD_I2C_WDATA 0xFFFFFFFF // RW [31:0]
1491
1492//*****************************************************************************
1493#define I2C1_CTRL 0x180008 // I2C #1 control
1494#define FLD_I2C_PERIOD 0xFF000000 // RW [31:24]
1495#define FLD_I2C_SCL_IN 0x00200000 // RW [21]
1496#define FLD_I2C_SDA_IN 0x00100000 // RW [20]
1497 // RO [19:18] reserved
1498#define FLD_I2C_SCL_OUT 0x00020000 // RW [17]
1499#define FLD_I2C_SDA_OUT 0x00010000 // RW [16]
1500 // RO [15] reserved
1501#define FLD_I2C_DATA_LEN 0x00007000 // RW [14:12]
1502#define FLD_I2C_SADDR_INC 0x00000800 // RW [11]
1503 // RO [10:9] reserved
1504#define FLD_I2C_SADDR_LEN 0x00000300 // RW [9:8]
1505 // RO [7:6] reserved
1506#define FLD_I2C_SOFT 0x00000020 // RW [5]
1507#define FLD_I2C_NOSTOP 0x00000010 // RW [4]
1508#define FLD_I2C_EXTEND 0x00000008 // RW [3]
1509#define FLD_I2C_SYNC 0x00000004 // RW [2]
1510#define FLD_I2C_READ_SA 0x00000002 // RW [1]
1511#define FLD_I2C_READ_WRN 0x00000001 // RW [0]
1512
1513//*****************************************************************************
1514#define I2C1_RDATA 0x18000C // I2C #1 read data
1515#define FLD_I2C_RDATA 0xFFFFFFFF // RO [31:0]
1516
1517//*****************************************************************************
1518#define I2C1_STAT 0x180010 // I2C #1 status
1519#define FLD_I2C_XFER_IN_PROG 0x00000002 // RO [1]
1520#define FLD_I2C_RACK 0x00000001 // RO [0]
1521
1522//*****************************************************************************
1523// I2C #2
1524//*****************************************************************************
1525#define I2C2_ADDR 0x190000 // I2C #2 address
1526
1527//*****************************************************************************
1528#define I2C2_WDATA 0x190004 // I2C #2 write data
1529
1530//*****************************************************************************
1531#define I2C2_CTRL 0x190008 // I2C #2 control
1532
1533//*****************************************************************************
1534#define I2C2_RDATA 0x19000C // I2C #2 read data
1535
1536//*****************************************************************************
1537#define I2C2_STAT 0x190010 // I2C #2 status
1538
1539//*****************************************************************************
1540// I2C #3
1541//*****************************************************************************
1542#define I2C3_ADDR 0x1A0000 // I2C #3 address
1543
1544//*****************************************************************************
1545#define I2C3_WDATA 0x1A0004 // I2C #3 write data
1546
1547//*****************************************************************************
1548#define I2C3_CTRL 0x1A0008 // I2C #3 control
1549
1550//*****************************************************************************
1551#define I2C3_RDATA 0x1A000C // I2C #3 read data
1552
1553//*****************************************************************************
1554#define I2C3_STAT 0x1A0010 // I2C #3 status
1555
1556//*****************************************************************************
1557// UART
1558//*****************************************************************************
1559#define UART_CTL 0x1B0000 // UART Control Register
1560#define FLD_LOOP_BACK_EN (1 << 7) // RW field - default 0
1561#define FLD_RX_TRG_SZ (3 << 2) // RW field - default 0
1562#define FLD_RX_EN (1 << 1) // RW field - default 0
1563#define FLD_TX_EN (1 << 0) // RW field - default 0
1564
1565//*****************************************************************************
1566#define UART_BRD 0x1B0004 // UART Baud Rate Divisor
1567#define FLD_BRD 0x0000FFFF // RW field - default 0x197
1568
1569//*****************************************************************************
1570#define UART_DBUF 0x1B0008 // UART Tx/Rx Data BuFFer
1571#define FLD_DB 0xFFFFFFFF // RW field - default 0
1572
1573//*****************************************************************************
1574#define UART_ISR 0x1B000C // UART Interrupt Status
1575#define FLD_RXD_TIMEOUT_EN (1 << 7) // RW field - default 0
1576#define FLD_FRM_ERR_EN (1 << 6) // RW field - default 0
1577#define FLD_RXD_RDY_EN (1 << 5) // RW field - default 0
1578#define FLD_TXD_EMPTY_EN (1 << 4) // RW field - default 0
1579#define FLD_RXD_OVERFLOW (1 << 3) // RW field - default 0
1580#define FLD_FRM_ERR (1 << 2) // RW field - default 0
1581#define FLD_RXD_RDY (1 << 1) // RW field - default 0
1582#define FLD_TXD_EMPTY (1 << 0) // RW field - default 0
1583
1584//*****************************************************************************
1585#define UART_CNT 0x1B0010 // UART Tx/Rx FIFO Byte Count
1586#define FLD_TXD_CNT (0x1F << 8) // RW field - default 0
1587#define FLD_RXD_CNT (0x1F << 0) // RW field - default 0
1588
1589//*****************************************************************************
1590// Motion Detection
1591#define MD_CH0_GRID_BLOCK_YCNT 0x170014
1592#define MD_CH1_GRID_BLOCK_YCNT 0x170094
1593#define MD_CH2_GRID_BLOCK_YCNT 0x170114
1594#define MD_CH3_GRID_BLOCK_YCNT 0x170194
1595#define MD_CH4_GRID_BLOCK_YCNT 0x170214
1596#define MD_CH5_GRID_BLOCK_YCNT 0x170294
1597#define MD_CH6_GRID_BLOCK_YCNT 0x170314
1598#define MD_CH7_GRID_BLOCK_YCNT 0x170394
1599
1600#define PIXEL_FRMT_422 4
1601#define PIXEL_FRMT_411 5
1602#define PIXEL_FRMT_Y8 6
1603
1604#define PIXEL_ENGINE_VIP1 0
1605#define PIXEL_ENGINE_VIP2 1
1606
1607#endif //Athena_REGISTERS
1608
1609
diff --git a/drivers/staging/cx25821/cx25821-sram.h b/drivers/staging/cx25821/cx25821-sram.h
new file mode 100644
index 00000000000..81306358226
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-sram.h
@@ -0,0 +1,266 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __ATHENA_SRAM_H__
24#define __ATHENA_SRAM_H__
25
26//#define RX_SRAM_START_SIZE = 0; // Start of reserved SRAM
27#define VID_CMDS_SIZE 80 // Video CMDS size in bytes
28#define AUDIO_CMDS_SIZE 80 // AUDIO CMDS size in bytes
29#define MBIF_CMDS_SIZE 80 // MBIF CMDS size in bytes
30
31//#define RX_SRAM_POOL_START_SIZE = 0; // Start of useable RX SRAM for buffers
32#define VID_IQ_SIZE 64 // VID instruction queue size in bytes
33#define MBIF_IQ_SIZE 64
34#define AUDIO_IQ_SIZE 64 // AUD instruction queue size in bytes
35
36#define VID_CDT_SIZE 64 // VID cluster descriptor table size in bytes
37#define MBIF_CDT_SIZE 64 // MBIF/HBI cluster descriptor table size in bytes
38#define AUDIO_CDT_SIZE 48 // AUD cluster descriptor table size in bytes
39
40//#define RX_SRAM_POOL_FREE_SIZE = 16; // Start of available RX SRAM
41//#define RX_SRAM_END_SIZE = 0; // End of RX SRAM
42
43//#define TX_SRAM_POOL_START_SIZE = 0; // Start of transmit pool SRAM
44//#define MSI_DATA_SIZE = 64; // Reserved (MSI Data, RISC working stora
45
46#define VID_CLUSTER_SIZE 1440 // VID cluster data line
47#define AUDIO_CLUSTER_SIZE 128 // AUDIO cluster data line
48#define MBIF_CLUSTER_SIZE 1440 // MBIF/HBI cluster data line
49
50
51//#define TX_SRAM_POOL_FREE_SIZE = 704; // Start of available TX SRAM
52//#define TX_SRAM_END_SIZE = 0; // End of TX SRAM
53
54// Receive SRAM
55#define RX_SRAM_START 0x10000
56#define VID_A_DOWN_CMDS 0x10000
57#define VID_B_DOWN_CMDS 0x10050
58#define VID_C_DOWN_CMDS 0x100A0
59#define VID_D_DOWN_CMDS 0x100F0
60#define VID_E_DOWN_CMDS 0x10140
61#define VID_F_DOWN_CMDS 0x10190
62#define VID_G_DOWN_CMDS 0x101E0
63#define VID_H_DOWN_CMDS 0x10230
64#define VID_A_UP_CMDS 0x10280
65#define VID_B_UP_CMDS 0x102D0
66#define VID_C_UP_CMDS 0x10320
67#define VID_D_UP_CMDS 0x10370
68#define VID_E_UP_CMDS 0x103C0
69#define VID_F_UP_CMDS 0x10410
70#define VID_I_UP_CMDS 0x10460
71#define VID_J_UP_CMDS 0x104B0
72#define AUD_A_DOWN_CMDS 0x10500
73#define AUD_B_DOWN_CMDS 0x10550
74#define AUD_C_DOWN_CMDS 0x105A0
75#define AUD_D_DOWN_CMDS 0x105F0
76#define AUD_A_UP_CMDS 0x10640
77#define AUD_B_UP_CMDS 0x10690
78#define AUD_C_UP_CMDS 0x106E0
79#define AUD_E_UP_CMDS 0x10730
80#define MBIF_A_DOWN_CMDS 0x10780
81#define MBIF_B_DOWN_CMDS 0x107D0
82#define DMA_SCRATCH_PAD 0x10820 // Scratch pad area from 0x10820 to 0x10B40
83
84//#define RX_SRAM_POOL_START = 0x105B0;
85
86#define VID_A_IQ 0x11000
87#define VID_B_IQ 0x11040
88#define VID_C_IQ 0x11080
89#define VID_D_IQ 0x110C0
90#define VID_E_IQ 0x11100
91#define VID_F_IQ 0x11140
92#define VID_G_IQ 0x11180
93#define VID_H_IQ 0x111C0
94#define VID_I_IQ 0x11200
95#define VID_J_IQ 0x11240
96#define AUD_A_IQ 0x11280
97#define AUD_B_IQ 0x112C0
98#define AUD_C_IQ 0x11300
99#define AUD_D_IQ 0x11340
100#define AUD_E_IQ 0x11380
101#define MBIF_A_IQ 0x11000
102#define MBIF_B_IQ 0x110C0
103
104#define VID_A_CDT 0x10C00
105#define VID_B_CDT 0x10C40
106#define VID_C_CDT 0x10C80
107#define VID_D_CDT 0x10CC0
108#define VID_E_CDT 0x10D00
109#define VID_F_CDT 0x10D40
110#define VID_G_CDT 0x10D80
111#define VID_H_CDT 0x10DC0
112#define VID_I_CDT 0x10E00
113#define VID_J_CDT 0x10E40
114#define AUD_A_CDT 0x10E80
115#define AUD_B_CDT 0x10EB0
116#define AUD_C_CDT 0x10EE0
117#define AUD_D_CDT 0x10F10
118#define AUD_E_CDT 0x10F40
119#define MBIF_A_CDT 0x10C00
120#define MBIF_B_CDT 0x10CC0
121
122// Cluster Buffer for RX
123#define VID_A_UP_CLUSTER_1 0x11400
124#define VID_A_UP_CLUSTER_2 0x119A0
125#define VID_A_UP_CLUSTER_3 0x11F40
126#define VID_A_UP_CLUSTER_4 0x124E0
127
128#define VID_B_UP_CLUSTER_1 0x12A80
129#define VID_B_UP_CLUSTER_2 0x13020
130#define VID_B_UP_CLUSTER_3 0x135C0
131#define VID_B_UP_CLUSTER_4 0x13B60
132
133#define VID_C_UP_CLUSTER_1 0x14100
134#define VID_C_UP_CLUSTER_2 0x146A0
135#define VID_C_UP_CLUSTER_3 0x14C40
136#define VID_C_UP_CLUSTER_4 0x151E0
137
138#define VID_D_UP_CLUSTER_1 0x15780
139#define VID_D_UP_CLUSTER_2 0x15D20
140#define VID_D_UP_CLUSTER_3 0x162C0
141#define VID_D_UP_CLUSTER_4 0x16860
142
143#define VID_E_UP_CLUSTER_1 0x16E00
144#define VID_E_UP_CLUSTER_2 0x173A0
145#define VID_E_UP_CLUSTER_3 0x17940
146#define VID_E_UP_CLUSTER_4 0x17EE0
147
148#define VID_F_UP_CLUSTER_1 0x18480
149#define VID_F_UP_CLUSTER_2 0x18A20
150#define VID_F_UP_CLUSTER_3 0x18FC0
151#define VID_F_UP_CLUSTER_4 0x19560
152
153#define VID_I_UP_CLUSTER_1 0x19B00
154#define VID_I_UP_CLUSTER_2 0x1A0A0
155#define VID_I_UP_CLUSTER_3 0x1A640
156#define VID_I_UP_CLUSTER_4 0x1ABE0
157
158#define VID_J_UP_CLUSTER_1 0x1B180
159#define VID_J_UP_CLUSTER_2 0x1B720
160#define VID_J_UP_CLUSTER_3 0x1BCC0
161#define VID_J_UP_CLUSTER_4 0x1C260
162
163#define AUD_A_UP_CLUSTER_1 0x1C800
164#define AUD_A_UP_CLUSTER_2 0x1C880
165#define AUD_A_UP_CLUSTER_3 0x1C900
166
167#define AUD_B_UP_CLUSTER_1 0x1C980
168#define AUD_B_UP_CLUSTER_2 0x1CA00
169#define AUD_B_UP_CLUSTER_3 0x1CA80
170
171#define AUD_C_UP_CLUSTER_1 0x1CB00
172#define AUD_C_UP_CLUSTER_2 0x1CB80
173#define AUD_C_UP_CLUSTER_3 0x1CC00
174
175#define AUD_E_UP_CLUSTER_1 0x1CC80
176#define AUD_E_UP_CLUSTER_2 0x1CD00
177#define AUD_E_UP_CLUSTER_3 0x1CD80
178
179#define RX_SRAM_POOL_FREE 0x1CE00
180#define RX_SRAM_END 0x1D000
181
182// Free Receive SRAM 144 Bytes
183
184
185// Transmit SRAM
186#define TX_SRAM_POOL_START 0x00000
187
188#define VID_A_DOWN_CLUSTER_1 0x00040
189#define VID_A_DOWN_CLUSTER_2 0x005E0
190#define VID_A_DOWN_CLUSTER_3 0x00B80
191#define VID_A_DOWN_CLUSTER_4 0x01120
192
193#define VID_B_DOWN_CLUSTER_1 0x016C0
194#define VID_B_DOWN_CLUSTER_2 0x01C60
195#define VID_B_DOWN_CLUSTER_3 0x02200
196#define VID_B_DOWN_CLUSTER_4 0x027A0
197
198#define VID_C_DOWN_CLUSTER_1 0x02D40
199#define VID_C_DOWN_CLUSTER_2 0x032E0
200#define VID_C_DOWN_CLUSTER_3 0x03880
201#define VID_C_DOWN_CLUSTER_4 0x03E20
202
203#define VID_D_DOWN_CLUSTER_1 0x043C0
204#define VID_D_DOWN_CLUSTER_2 0x04960
205#define VID_D_DOWN_CLUSTER_3 0x04F00
206#define VID_D_DOWN_CLUSTER_4 0x054A0
207
208#define VID_E_DOWN_CLUSTER_1 0x05a40
209#define VID_E_DOWN_CLUSTER_2 0x05FE0
210#define VID_E_DOWN_CLUSTER_3 0x06580
211#define VID_E_DOWN_CLUSTER_4 0x06B20
212
213#define VID_F_DOWN_CLUSTER_1 0x070C0
214#define VID_F_DOWN_CLUSTER_2 0x07660
215#define VID_F_DOWN_CLUSTER_3 0x07C00
216#define VID_F_DOWN_CLUSTER_4 0x081A0
217
218#define VID_G_DOWN_CLUSTER_1 0x08740
219#define VID_G_DOWN_CLUSTER_2 0x08CE0
220#define VID_G_DOWN_CLUSTER_3 0x09280
221#define VID_G_DOWN_CLUSTER_4 0x09820
222
223#define VID_H_DOWN_CLUSTER_1 0x09DC0
224#define VID_H_DOWN_CLUSTER_2 0x0A360
225#define VID_H_DOWN_CLUSTER_3 0x0A900
226#define VID_H_DOWN_CLUSTER_4 0x0AEA0
227
228#define AUD_A_DOWN_CLUSTER_1 0x0B500
229#define AUD_A_DOWN_CLUSTER_2 0x0B580
230#define AUD_A_DOWN_CLUSTER_3 0x0B600
231
232#define AUD_B_DOWN_CLUSTER_1 0x0B680
233#define AUD_B_DOWN_CLUSTER_2 0x0B700
234#define AUD_B_DOWN_CLUSTER_3 0x0B780
235
236#define AUD_C_DOWN_CLUSTER_1 0x0B800
237#define AUD_C_DOWN_CLUSTER_2 0x0B880
238#define AUD_C_DOWN_CLUSTER_3 0x0B900
239
240#define AUD_D_DOWN_CLUSTER_1 0x0B980
241#define AUD_D_DOWN_CLUSTER_2 0x0BA00
242#define AUD_D_DOWN_CLUSTER_3 0x0BA80
243
244#define TX_SRAM_POOL_FREE 0x0BB00
245#define TX_SRAM_END 0x0C000
246
247
248#define BYTES_TO_DWORDS(bcount) ((bcount) >> 2)
249#define BYTES_TO_QWORDS(bcount) ((bcount) >> 3)
250#define BYTES_TO_OWORDS(bcount) ((bcount) >> 4)
251
252#define VID_IQ_SIZE_DW BYTES_TO_DWORDS(VID_IQ_SIZE)
253#define VID_CDT_SIZE_QW BYTES_TO_QWORDS(VID_CDT_SIZE)
254#define VID_CLUSTER_SIZE_OW BYTES_TO_OWORDS(VID_CLUSTER_SIZE)
255
256#define AUDIO_IQ_SIZE_DW BYTES_TO_DWORDS(AUDIO_IQ_SIZE)
257#define AUDIO_CDT_SIZE_QW BYTES_TO_QWORDS(AUDIO_CDT_SIZE)
258#define AUDIO_CLUSTER_SIZE_QW BYTES_TO_QWORDS(AUDIO_CLUSTER_SIZE)
259
260#define MBIF_IQ_SIZE_DW BYTES_TO_DWORDS(MBIF_IQ_SIZE)
261#define MBIF_CDT_SIZE_QW BYTES_TO_QWORDS(MBIF_CDT_SIZE)
262#define MBIF_CLUSTER_SIZE_OW BYTES_TO_OWORDS(MBIF_CLUSTER_SIZE)
263
264
265#endif
266
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
new file mode 100644
index 00000000000..ca91b832b01
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -0,0 +1,847 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24#include "cx25821-video.h"
25#include "cx25821-video-upstream-ch2.h"
26
27#include <linux/fs.h>
28#include <linux/errno.h>
29#include <linux/kernel.h>
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/syscalls.h>
33#include <linux/file.h>
34#include <linux/fcntl.h>
35#include <asm/uaccess.h>
36
37
38MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
39MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
40MODULE_LICENSE("GPL");
41
42
43static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
44
45
46static __le32 *cx25821_update_riscprogram_ch2( struct cx25821_dev *dev,
47 __le32 *rp, unsigned int offset, unsigned int bpl,
48 u32 sync_line, unsigned int lines, int fifo_enable, int field_type)
49{
50 unsigned int line, i;
51 int dist_betwn_starts = bpl * 2;
52
53
54 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
55
56
57 if( USE_RISC_NOOP_VIDEO )
58 {
59 for( i = 0; i < NUM_NO_OPS; i++ )
60 {
61 *(rp++) = cpu_to_le32(RISC_NOOP);
62 }
63 }
64
65 /* scan lines */
66 for (line = 0; line < lines; line++)
67 {
68 *(rp++) = cpu_to_le32(RISC_READ|RISC_SOL|RISC_EOL|bpl);
69 *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2+offset);
70 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
71
72 if ( (lines <= NTSC_FIELD_HEIGHT) || (line < (NTSC_FIELD_HEIGHT-1)) || !(dev->_isNTSC_ch2) )
73 {
74 offset += dist_betwn_starts;
75 }
76 }
77
78 return rp;
79}
80
81static __le32 *cx25821_risc_field_upstream_ch2( struct cx25821_dev *dev,
82 __le32 *rp,
83 dma_addr_t databuf_phys_addr,
84 unsigned int offset, u32 sync_line, unsigned int bpl,
85 unsigned int lines, int fifo_enable, int field_type)
86{
87 unsigned int line, i;
88 struct sram_channel *sram_ch = &dev->sram_channels[dev->_channel2_upstream_select];
89 int dist_betwn_starts = bpl * 2;
90
91
92 /* sync instruction */
93 if (sync_line != NO_SYNC_LINE)
94 {
95 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
96 }
97
98
99 if( USE_RISC_NOOP_VIDEO )
100 {
101 for( i = 0; i < NUM_NO_OPS; i++ )
102 {
103 *(rp++) = cpu_to_le32(RISC_NOOP);
104 }
105 }
106
107 /* scan lines */
108 for (line = 0; line < lines; line++)
109 {
110 *(rp++) = cpu_to_le32(RISC_READ|RISC_SOL|RISC_EOL|bpl);
111 *(rp++) = cpu_to_le32(databuf_phys_addr+offset);
112 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
113
114
115 if ( (lines <= NTSC_FIELD_HEIGHT) || (line < (NTSC_FIELD_HEIGHT-1)) || !(dev->_isNTSC_ch2) )
116 {
117 offset += dist_betwn_starts;
118 }
119
120
121 // check if we need to enable the FIFO after the first 4 lines
122 // For the upstream video channel, the risc engine will enable the FIFO.
123 if ( fifo_enable && line == 3 )
124 {
125 *(rp++) = RISC_WRITECR;
126 *(rp++) = sram_ch->dma_ctl;
127 *(rp++) = FLD_VID_FIFO_EN;
128 *(rp++) = 0x00000001;
129 }
130 }
131
132 return rp;
133}
134
135int cx25821_risc_buffer_upstream_ch2( struct cx25821_dev *dev, struct pci_dev *pci,
136 unsigned int top_offset,
137 unsigned int bpl, unsigned int lines)
138{
139 __le32 *rp;
140 int fifo_enable = 0;
141 int singlefield_lines = lines >> 1; //get line count for single field
142 int odd_num_lines = singlefield_lines;
143 int frame = 0;
144 int frame_size = 0;
145 int databuf_offset = 0;
146 int risc_program_size = 0;
147 int risc_flag = RISC_CNT_RESET;
148 unsigned int bottom_offset = bpl;
149 dma_addr_t risc_phys_jump_addr;
150
151
152 if( dev->_isNTSC_ch2 )
153 {
154 odd_num_lines = singlefield_lines + 1;
155 risc_program_size = FRAME1_VID_PROG_SIZE;
156 frame_size = (bpl == Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
157 }
158 else
159 {
160 risc_program_size = PAL_VID_PROG_SIZE;
161 frame_size = (bpl == Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
162 }
163
164
165 /* Virtual address of Risc buffer program */
166 rp = dev->_dma_virt_addr_ch2;
167
168 for( frame = 0; frame < NUM_FRAMES; frame++ )
169 {
170 databuf_offset = frame_size * frame;
171
172
173 if (UNSET != top_offset)
174 {
175 fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
176 rp = cx25821_risc_field_upstream_ch2(dev, rp, dev->_data_buf_phys_addr_ch2 + databuf_offset, top_offset, 0, bpl, odd_num_lines, fifo_enable, ODD_FIELD);
177 }
178
179 fifo_enable = FIFO_DISABLE;
180
181
182 //Even field
183 rp = cx25821_risc_field_upstream_ch2(dev, rp, dev->_data_buf_phys_addr_ch2 + databuf_offset, bottom_offset, 0x200, bpl, singlefield_lines, fifo_enable, EVEN_FIELD);
184
185
186 if( frame == 0 )
187 {
188 risc_flag = RISC_CNT_RESET;
189 risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2 + risc_program_size;
190 }
191 else
192 {
193 risc_flag = RISC_CNT_INC;
194 risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2;
195 }
196
197
198 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
199 *(rp++) = cpu_to_le32(RISC_JUMP|RISC_IRQ1|risc_flag);
200 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
201 *(rp++) = cpu_to_le32(0);
202 }
203
204 return 0;
205}
206
207
208void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
209{
210 struct sram_channel *sram_ch = &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_J];
211 u32 tmp = 0;
212
213 if( !dev->_is_running_ch2 )
214 {
215 printk("cx25821: No video file is currently running so return!\n");
216 return;
217 }
218
219 //Disable RISC interrupts
220 tmp = cx_read( sram_ch->int_msk );
221 cx_write( sram_ch->int_msk, tmp & ~_intr_msk);
222
223 //Turn OFF risc and fifo
224 tmp = cx_read( sram_ch->dma_ctl );
225 cx_write( sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN) );
226
227 //Clear data buffer memory
228 if( dev->_data_buf_virt_addr_ch2 )
229 memset( dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2 );
230
231 dev->_is_running_ch2 = 0;
232 dev->_is_first_frame_ch2 = 0;
233 dev->_frame_count_ch2 = 0;
234 dev->_file_status_ch2 = END_OF_FILE;
235
236 if( dev->_irq_queues_ch2 )
237 {
238 kfree(dev->_irq_queues_ch2);
239 dev->_irq_queues_ch2 = NULL;
240 }
241
242 if( dev->_filename_ch2 != NULL )
243 kfree(dev->_filename_ch2);
244
245 tmp = cx_read( VID_CH_MODE_SEL );
246 cx_write( VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
247}
248
249void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev)
250{
251 if( dev->_is_running_ch2 )
252 {
253 cx25821_stop_upstream_video_ch2(dev);
254 }
255
256 if (dev->_dma_virt_addr_ch2)
257 {
258 pci_free_consistent(dev->pci, dev->_risc_size_ch2, dev->_dma_virt_addr_ch2, dev->_dma_phys_addr_ch2);
259 dev->_dma_virt_addr_ch2 = NULL;
260 }
261
262 if (dev->_data_buf_virt_addr_ch2)
263 {
264 pci_free_consistent(dev->pci, dev->_data_buf_size_ch2, dev->_data_buf_virt_addr_ch2, dev->_data_buf_phys_addr_ch2);
265 dev->_data_buf_virt_addr_ch2 = NULL;
266 }
267}
268
269
270int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch )
271{
272 struct file * myfile;
273 int frame_index_temp = dev->_frame_index_ch2;
274 int i = 0;
275 int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
276 int frame_size = 0;
277 int frame_offset = 0;
278 ssize_t vfs_read_retval = 0;
279 char mybuf[line_size];
280 loff_t file_offset;
281 loff_t pos;
282 mm_segment_t old_fs;
283
284
285 if( dev->_file_status_ch2 == END_OF_FILE )
286 return 0;
287
288 if( dev->_isNTSC_ch2 )
289 {
290 frame_size = (line_size == Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
291 }
292 else
293 {
294 frame_size = (line_size == Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
295 }
296
297 frame_offset = (frame_index_temp > 0) ? frame_size : 0;
298 file_offset = dev->_frame_count_ch2 * frame_size;
299
300
301 myfile = filp_open( dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0 );
302
303
304 if (IS_ERR(myfile))
305 {
306 const int open_errno = -PTR_ERR(myfile);
307 printk("%s(): ERROR opening file(%s) with errno = %d! \n", __func__, dev->_filename_ch2, open_errno);
308 return PTR_ERR(myfile);
309 }
310 else
311 {
312 if( !(myfile->f_op) )
313 {
314 printk("%s: File has no file operations registered!", __func__);
315 filp_close(myfile, NULL);
316 return -EIO;
317 }
318
319
320 if( !myfile->f_op->read )
321 {
322 printk("%s: File has no READ operations registered!", __func__);
323 filp_close(myfile, NULL);
324 return -EIO;
325 }
326
327 pos = myfile->f_pos;
328 old_fs = get_fs();
329 set_fs(KERNEL_DS);
330
331
332 for( i = 0; i < dev->_lines_count_ch2; i++ )
333 {
334 pos = file_offset;
335
336 vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos);
337
338 if( vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_data_buf_virt_addr_ch2 != NULL )
339 {
340 memcpy( (void*)(dev->_data_buf_virt_addr_ch2+frame_offset/4), mybuf, vfs_read_retval);
341 }
342
343 file_offset += vfs_read_retval;
344 frame_offset += vfs_read_retval;
345
346 if( vfs_read_retval < line_size )
347 {
348 printk(KERN_INFO "Done: exit %s() since no more bytes to read from Video file.\n", __func__ );
349 break;
350 }
351 }
352
353 if( i > 0 )
354 dev->_frame_count_ch2++;
355
356 dev->_file_status_ch2 = (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
357
358
359 set_fs(old_fs);
360 filp_close(myfile, NULL);
361 }
362
363 return 0;
364}
365
366static void cx25821_vidups_handler_ch2(struct work_struct *work)
367{
368 struct cx25821_dev *dev = container_of(work, struct cx25821_dev, _irq_work_entry_ch2);
369
370 if( !dev )
371 {
372 printk("ERROR %s(): since container_of(work_struct) FAILED! \n", __func__ );
373 return;
374 }
375
376 cx25821_get_frame_ch2( dev, &dev->sram_channels[dev->_channel2_upstream_select] );
377}
378
379
380int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
381{
382 struct file * myfile;
383 int i = 0, j = 0;
384 int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
385 ssize_t vfs_read_retval = 0;
386 char mybuf[line_size];
387 loff_t pos;
388 loff_t offset = (unsigned long)0;
389 mm_segment_t old_fs;
390
391
392 myfile = filp_open( dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0 );
393
394
395 if (IS_ERR(myfile))
396 {
397 const int open_errno = -PTR_ERR(myfile);
398 printk("%s(): ERROR opening file(%s) with errno = %d! \n", __func__, dev->_filename_ch2, open_errno);
399 return PTR_ERR(myfile);
400 }
401 else
402 {
403 if( !(myfile->f_op) )
404 {
405 printk("%s: File has no file operations registered!", __func__);
406 filp_close(myfile, NULL);
407 return -EIO;
408 }
409
410
411 if( !myfile->f_op->read )
412 {
413 printk("%s: File has no READ operations registered! Returning.", __func__);
414 filp_close(myfile, NULL);
415 return -EIO;
416 }
417
418 pos = myfile->f_pos;
419 old_fs = get_fs();
420 set_fs(KERNEL_DS);
421
422
423 for( j = 0; j < NUM_FRAMES; j++ )
424 {
425 for( i = 0; i < dev->_lines_count_ch2; i++ )
426 {
427 pos = offset;
428
429 vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos);
430
431 if( vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_data_buf_virt_addr_ch2 != NULL )
432 {
433 memcpy( (void*)(dev->_data_buf_virt_addr_ch2+offset/4), mybuf, vfs_read_retval);
434 }
435
436
437 offset += vfs_read_retval;
438
439 if( vfs_read_retval < line_size )
440 {
441 printk(KERN_INFO "Done: exit %s() since no more bytes to read from Video file.\n", __func__ );
442 break;
443 }
444 }
445
446 if( i > 0 )
447 dev->_frame_count_ch2++;
448
449 if( vfs_read_retval < line_size )
450 {
451 break;
452 }
453 }
454
455 dev->_file_status_ch2 = (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
456
457 set_fs(old_fs);
458 myfile->f_pos = 0;
459 filp_close(myfile, NULL);
460 }
461
462 return 0;
463}
464
465
466static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
467 struct sram_channel *sram_ch,
468 int bpl)
469{
470 int ret = 0;
471 dma_addr_t dma_addr;
472 dma_addr_t data_dma_addr;
473
474
475 if( dev->_dma_virt_addr_ch2 != NULL )
476 {
477 pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2, dev->_dma_virt_addr_ch2, dev->_dma_phys_addr_ch2);
478 }
479
480 dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size_ch2, &dma_addr);
481 dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2;
482 dev->_dma_phys_start_addr_ch2 = dma_addr;
483 dev->_dma_phys_addr_ch2 = dma_addr;
484 dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;
485
486
487 if (!dev->_dma_virt_addr_ch2)
488 {
489 printk("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
490 return -ENOMEM;
491 }
492
493
494 //Iniitize at this address until n bytes to 0
495 memset( dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2 );
496
497
498 if( dev->_data_buf_virt_addr_ch2 != NULL )
499 {
500 pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2, dev->_data_buf_virt_addr_ch2, dev->_data_buf_phys_addr_ch2);
501 }
502
503 //For Video Data buffer allocation
504 dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2, &data_dma_addr);
505 dev->_data_buf_phys_addr_ch2 = data_dma_addr;
506 dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
507
508 if (!dev->_data_buf_virt_addr_ch2)
509 {
510 printk("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
511 return -ENOMEM;
512 }
513
514
515 //Initialize at this address until n bytes to 0
516 memset( dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2 );
517
518
519 ret = cx25821_openfile_ch2(dev, sram_ch);
520 if( ret < 0 )
521 return ret;
522
523
524 //Creating RISC programs
525 ret = cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl, dev->_lines_count_ch2 );
526 if (ret < 0)
527 {
528 printk(KERN_INFO "cx25821: Failed creating Video Upstream Risc programs! \n");
529 goto error;
530 }
531
532 return 0;
533
534error:
535 return ret;
536}
537
538int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num, u32 status)
539{
540 u32 int_msk_tmp;
541 struct sram_channel *channel = &dev->sram_channels[chan_num];
542 int singlefield_lines = NTSC_FIELD_HEIGHT;
543 int line_size_in_bytes = Y422_LINE_SZ;
544 int odd_risc_prog_size = 0;
545 dma_addr_t risc_phys_jump_addr;
546 __le32 * rp;
547
548
549
550 if (status & FLD_VID_SRC_RISC1)
551 {
552 // We should only process one program per call
553 u32 prog_cnt = cx_read( channel->gpcnt );
554
555 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
556 int_msk_tmp = cx_read(channel->int_msk);
557 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
558 cx_write( channel->int_stat, _intr_msk );
559
560 spin_lock(&dev->slock);
561
562 dev->_frame_index_ch2 = prog_cnt;
563
564 queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2);
565
566
567 if ( dev->_is_first_frame_ch2 )
568 {
569 dev->_is_first_frame_ch2 = 0;
570
571 if( dev->_isNTSC_ch2 )
572 {
573 singlefield_lines += 1;
574 odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
575 }
576 else
577 {
578 singlefield_lines = PAL_FIELD_HEIGHT;
579 odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
580 }
581
582
583 if( dev->_dma_virt_start_addr_ch2 != NULL )
584 {
585 line_size_in_bytes = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
586 risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2 + odd_risc_prog_size;
587
588 rp = cx25821_update_riscprogram_ch2(dev, dev->_dma_virt_start_addr_ch2, TOP_OFFSET, line_size_in_bytes, 0x0, singlefield_lines, FIFO_DISABLE, ODD_FIELD);
589
590 // Jump to Even Risc program of 1st Frame
591 *(rp++) = cpu_to_le32(RISC_JUMP);
592 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
593 *(rp++) = cpu_to_le32(0);
594 }
595 }
596
597 spin_unlock(&dev->slock);
598 }
599
600
601 if( dev->_file_status_ch2 == END_OF_FILE )
602 {
603 printk("cx25821: EOF Channel 2 Framecount = %d\n", dev->_frame_count_ch2 );
604 return -1;
605 }
606
607 //ElSE, set the interrupt mask register, re-enable irq.
608 int_msk_tmp = cx_read( channel->int_msk );
609 cx_write( channel->int_msk, int_msk_tmp |= _intr_msk );
610
611 return 0;
612}
613
614static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
615{
616 struct cx25821_dev *dev = dev_id;
617 u32 msk_stat, vid_status;
618 int handled = 0;
619 int channel_num = 0;
620 struct sram_channel *sram_ch;
621
622
623 if( !dev )
624 return -1;
625
626 channel_num = VID_UPSTREAM_SRAM_CHANNEL_J;
627
628 sram_ch = &dev->sram_channels[channel_num];
629
630 msk_stat = cx_read(sram_ch->int_mstat);
631 vid_status = cx_read(sram_ch->int_stat);
632
633 // Only deal with our interrupt
634 if(vid_status)
635 {
636 handled = cx25821_video_upstream_irq_ch2(dev, channel_num, vid_status);
637 }
638
639
640 if( handled < 0 )
641 {
642 cx25821_stop_upstream_video_ch2(dev);
643 }
644 else
645 {
646 handled += handled;
647 }
648
649 return IRQ_RETVAL(handled);
650}
651
652
653static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev, struct sram_channel *ch, int pix_format)
654{
655 int width = WIDTH_D1;
656 int height = dev->_lines_count_ch2;
657 int num_lines, odd_num_lines;
658 u32 value;
659 int vip_mode = PIXEL_ENGINE_VIP1;
660
661
662 value = ( (pix_format & 0x3) << 12 ) | ( vip_mode & 0x7 );
663 value &= 0xFFFFFFEF;
664 value |= dev->_isNTSC_ch2 ? 0 : 0x10;
665 cx_write( ch->vid_fmt_ctl, value );
666
667 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
668 cx_write( ch->vid_active_ctl1, width );
669
670 num_lines = (height / 2) & 0x3FF;
671 odd_num_lines = num_lines;
672
673 if(dev->_isNTSC_ch2)
674 {
675 odd_num_lines += 1;
676 }
677
678 value = (num_lines << 16) | odd_num_lines;
679
680 // set number of active lines in field 0 (top) and field 1 (bottom)
681 cx_write( ch->vid_active_ctl2, value );
682
683 cx_write( ch->vid_cdt_size, VID_CDT_SIZE >> 3 );
684}
685
686
687int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
688 struct sram_channel *sram_ch)
689{
690 u32 tmp = 0;
691 int err = 0;
692
693
694 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
695 tmp = cx_read( VID_CH_MODE_SEL );
696 cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
697
698
699 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
700 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2);
701 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
702
703 /* reset counter */
704 cx_write(sram_ch->gpcnt_ctl, 3);
705
706 // Clear our bits from the interrupt status register.
707 cx_write( sram_ch->int_stat, _intr_msk );
708
709
710 //Set the interrupt mask register, enable irq.
711 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
712 tmp = cx_read( sram_ch->int_msk );
713 cx_write( sram_ch->int_msk, tmp |= _intr_msk );
714
715
716 err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
717 if (err < 0)
718 {
719 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name, dev->pci->irq);
720 goto fail_irq;
721 }
722
723 // Start the DMA engine
724 tmp = cx_read( sram_ch->dma_ctl );
725 cx_set( sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN );
726
727 dev->_is_running_ch2 = 1;
728 dev->_is_first_frame_ch2 = 1;
729
730 return 0;
731
732
733fail_irq:
734 cx25821_dev_unregister(dev);
735 return err;
736}
737
738
739int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, int pixel_format)
740{
741 struct sram_channel *sram_ch;
742 u32 tmp;
743 int retval = 0;
744 int err = 0;
745 int data_frame_size = 0;
746 int risc_buffer_size = 0;
747 int str_length = 0;
748
749 if( dev->_is_running_ch2 )
750 {
751 printk("Video Channel is still running so return!\n");
752 return 0;
753 }
754
755 dev->_channel2_upstream_select = channel_select;
756 sram_ch = &dev->sram_channels[channel_select];
757
758
759 INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2);
760 dev->_irq_queues_ch2 = create_singlethread_workqueue("cx25821_workqueue2");
761
762 if(!dev->_irq_queues_ch2)
763 {
764 printk("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
765 return -ENOMEM;
766 }
767
768 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
769 tmp = cx_read( VID_CH_MODE_SEL );
770 cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
771
772
773 dev->_is_running_ch2 = 0;
774 dev->_frame_count_ch2 = 0;
775 dev->_file_status_ch2 = RESET_STATUS;
776 dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576;
777 dev->_pixel_format_ch2 = pixel_format;
778 dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
779 data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
780 risc_buffer_size = dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
781
782
783 if( dev->input_filename_ch2 )
784 {
785 str_length = strlen(dev->input_filename_ch2);
786 dev->_filename_ch2 = (char *) kmalloc(str_length + 1, GFP_KERNEL);
787
788 if( !dev->_filename_ch2 )
789 goto error;
790
791 memcpy(dev->_filename_ch2, dev->input_filename_ch2, str_length + 1);
792 }
793 else
794 {
795 str_length = strlen(dev->_defaultname_ch2);
796 dev->_filename_ch2 = (char *) kmalloc(str_length + 1, GFP_KERNEL);
797
798 if( !dev->_filename_ch2 )
799 goto error;
800
801 memcpy(dev->_filename_ch2, dev->_defaultname_ch2, str_length + 1);
802 }
803
804
805 //Default if filename is empty string
806 if( strcmp(dev->input_filename_ch2,"") == 0)
807 {
808 if( dev->_isNTSC_ch2 )
809 {
810 dev->_filename_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? "/root/vid411.yuv" : "/root/vidtest.yuv";
811 }
812 else
813 {
814 dev->_filename_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? "/root/pal411.yuv" : "/root/pal422.yuv";
815 }
816 }
817
818
819 retval = cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size_ch2, 0);
820
821
822 /* setup fifo + format */
823 cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2);
824
825 dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2;
826 dev->upstream_databuf_size_ch2 = data_frame_size * 2;
827
828
829 //Allocating buffers and prepare RISC program
830 retval = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch, dev->_line_size_ch2);
831 if (retval < 0)
832 {
833 printk(KERN_ERR "%s: Failed to set up Video upstream buffers!\n", dev->name);
834 goto error;
835 }
836
837
838 cx25821_start_video_dma_upstream_ch2(dev, sram_ch);
839
840 return 0;
841
842error:
843 cx25821_dev_unregister(dev);
844
845 return err;
846}
847
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
new file mode 100644
index 00000000000..71de8742be6
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
@@ -0,0 +1,107 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26
27#define OPEN_FILE_1 0
28#define NUM_PROGS 8
29#define NUM_FRAMES 2
30#define ODD_FIELD 0
31#define EVEN_FIELD 1
32#define TOP_OFFSET 0
33#define FIFO_DISABLE 0
34#define FIFO_ENABLE 1
35#define TEST_FRAMES 5
36#define END_OF_FILE 0
37#define IN_PROGRESS 1
38#define RESET_STATUS -1
39#define NUM_NO_OPS 5
40
41
42
43// PAL and NTSC line sizes and number of lines.
44#define WIDTH_D1 720
45#define NTSC_LINES_PER_FRAME 480
46#define PAL_LINES_PER_FRAME 576
47#define PAL_LINE_SZ 1440
48#define Y422_LINE_SZ 1440
49#define Y411_LINE_SZ 1080
50#define NTSC_FIELD_HEIGHT 240
51#define NTSC_ODD_FLD_LINES 241
52#define PAL_FIELD_HEIGHT 288
53
54#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
55#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
56#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
57#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
58
59#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
60#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
61
62#define RISC_WRITECR_INSTRUCTION_SIZE 16
63#define RISC_SYNC_INSTRUCTION_SIZE 4
64#define JUMP_INSTRUCTION_SIZE 12
65#define MAXSIZE_NO_OPS 36
66#define DWORD_SIZE 4
67
68
69
70#define USE_RISC_NOOP_VIDEO 1
71
72#ifdef USE_RISC_NOOP_VIDEO
73#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
74 RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
75
76#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
77
78#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
79 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
80
81#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
82 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
83
84#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
85 JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
86
87#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
88
89#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
90 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
91#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
92 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
93#endif
94
95
96#ifndef USE_RISC_NOOP_VIDEO
97#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
98#define PAL_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE) )
99#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
100 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
101#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
102#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
103#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
104#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
105#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
106 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
107#endif
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
new file mode 100644
index 00000000000..14d204aaa84
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -0,0 +1,923 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24#include "cx25821-video.h"
25#include "cx25821-video-upstream.h"
26
27#include <linux/fs.h>
28#include <linux/errno.h>
29#include <linux/kernel.h>
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/syscalls.h>
33#include <linux/file.h>
34#include <linux/fcntl.h>
35#include <asm/uaccess.h>
36
37
38MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
39MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
40MODULE_LICENSE("GPL");
41
42
43static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
44
45int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
46 struct sram_channel *ch,
47 unsigned int bpl, u32 risc)
48{
49 unsigned int i, lines;
50 u32 cdt;
51
52
53 if (ch->cmds_start == 0) {
54 cx_write(ch->ptr1_reg, 0);
55 cx_write(ch->ptr2_reg, 0);
56 cx_write(ch->cnt2_reg, 0);
57 cx_write(ch->cnt1_reg, 0);
58 return 0;
59 }
60
61 bpl = (bpl + 7) & ~7; /* alignment */
62 cdt = ch->cdt;
63 lines = ch->fifo_size / bpl;
64
65 if (lines > 4)
66 {
67 lines = 4;
68 }
69
70 BUG_ON(lines < 2);
71
72
73 /* write CDT */
74 for (i = 0; i < lines; i++) {
75 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
76 cx_write(cdt + 16*i + 4, 0);
77 cx_write(cdt + 16*i + 8, 0);
78 cx_write(cdt + 16*i + 12, 0);
79 }
80
81 /* write CMDS */
82 cx_write(ch->cmds_start + 0, risc);
83
84 cx_write(ch->cmds_start + 4, 0);
85 cx_write(ch->cmds_start + 8, cdt);
86 cx_write(ch->cmds_start + 12, (lines*16) >> 3);
87 cx_write(ch->cmds_start + 16, ch->ctrl_start);
88
89
90 cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);
91
92 for (i = 24; i < 80; i += 4)
93 cx_write(ch->cmds_start + i, 0);
94
95 /* fill registers */
96 cx_write(ch->ptr1_reg, ch->fifo_start);
97 cx_write(ch->ptr2_reg, cdt);
98 cx_write(ch->cnt2_reg, (lines*16) >> 3);
99 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
100
101 return 0;
102}
103
104static __le32 *cx25821_update_riscprogram( struct cx25821_dev *dev,
105 __le32 *rp, unsigned int offset, unsigned int bpl,
106 u32 sync_line, unsigned int lines, int fifo_enable, int field_type)
107{
108 unsigned int line, i;
109 int dist_betwn_starts = bpl * 2;
110
111
112 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
113
114
115 if( USE_RISC_NOOP_VIDEO )
116 {
117 for( i = 0; i < NUM_NO_OPS; i++ )
118 {
119 *(rp++) = cpu_to_le32(RISC_NOOP);
120 }
121 }
122
123 /* scan lines */
124 for (line = 0; line < lines; line++)
125 {
126 *(rp++) = cpu_to_le32(RISC_READ|RISC_SOL|RISC_EOL|bpl);
127 *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr+offset);
128 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
129
130 if ( (lines <= NTSC_FIELD_HEIGHT) || (line < (NTSC_FIELD_HEIGHT-1)) || !(dev->_isNTSC) )
131 {
132 offset += dist_betwn_starts;
133 }
134 }
135
136 return rp;
137}
138
139static __le32 *cx25821_risc_field_upstream( struct cx25821_dev *dev, __le32 *rp,
140 dma_addr_t databuf_phys_addr,
141 unsigned int offset, u32 sync_line,
142 unsigned int bpl, unsigned int lines, int fifo_enable, int field_type)
143{
144 unsigned int line, i;
145 struct sram_channel *sram_ch = &dev->sram_channels[dev->_channel_upstream_select];
146 int dist_betwn_starts = bpl * 2;
147
148
149 /* sync instruction */
150 if (sync_line != NO_SYNC_LINE)
151 {
152 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
153 }
154
155
156 if( USE_RISC_NOOP_VIDEO )
157 {
158 for( i = 0; i < NUM_NO_OPS; i++ )
159 {
160 *(rp++) = cpu_to_le32(RISC_NOOP);
161 }
162 }
163
164 /* scan lines */
165 for (line = 0; line < lines; line++)
166 {
167 *(rp++) = cpu_to_le32(RISC_READ|RISC_SOL|RISC_EOL|bpl);
168 *(rp++) = cpu_to_le32(databuf_phys_addr+offset);
169 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
170
171
172 if ( (lines <= NTSC_FIELD_HEIGHT) || (line < (NTSC_FIELD_HEIGHT-1)) || !(dev->_isNTSC) )
173 {
174 offset += dist_betwn_starts; //to skip the other field line
175 }
176
177
178 // check if we need to enable the FIFO after the first 4 lines
179 // For the upstream video channel, the risc engine will enable the FIFO.
180 if ( fifo_enable && line == 3 )
181 {
182 *(rp++) = RISC_WRITECR;
183 *(rp++) = sram_ch->dma_ctl;
184 *(rp++) = FLD_VID_FIFO_EN;
185 *(rp++) = 0x00000001;
186 }
187 }
188
189 return rp;
190}
191
192int cx25821_risc_buffer_upstream( struct cx25821_dev *dev,
193 struct pci_dev *pci,
194 unsigned int top_offset,
195 unsigned int bpl, unsigned int lines)
196{
197 __le32 *rp;
198 int fifo_enable = 0;
199 int singlefield_lines = lines >> 1; //get line count for single field
200 int odd_num_lines = singlefield_lines;
201 int frame = 0;
202 int frame_size = 0;
203 int databuf_offset = 0;
204 int risc_program_size = 0;
205 int risc_flag = RISC_CNT_RESET;
206 unsigned int bottom_offset = bpl;
207 dma_addr_t risc_phys_jump_addr;
208
209 if( dev->_isNTSC )
210 {
211 odd_num_lines = singlefield_lines + 1;
212 risc_program_size = FRAME1_VID_PROG_SIZE;
213 frame_size = (bpl == Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
214 }
215 else
216 {
217 risc_program_size = PAL_VID_PROG_SIZE;
218 frame_size = (bpl == Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
219 }
220
221
222 /* Virtual address of Risc buffer program */
223 rp = dev->_dma_virt_addr;
224
225 for( frame = 0; frame < NUM_FRAMES; frame++ )
226 {
227 databuf_offset = frame_size * frame;
228
229 if (UNSET != top_offset)
230 {
231 fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
232 rp = cx25821_risc_field_upstream(dev, rp, dev->_data_buf_phys_addr+databuf_offset, top_offset, 0, bpl, odd_num_lines, fifo_enable, ODD_FIELD);
233 }
234
235
236 fifo_enable = FIFO_DISABLE;
237
238
239 //Even Field
240 rp = cx25821_risc_field_upstream(dev, rp, dev->_data_buf_phys_addr+databuf_offset, bottom_offset, 0x200, bpl, singlefield_lines, fifo_enable, EVEN_FIELD);
241
242
243 if( frame == 0 )
244 {
245 risc_flag = RISC_CNT_RESET;
246 risc_phys_jump_addr = dev->_dma_phys_start_addr + risc_program_size;
247 }
248 else
249 {
250 risc_phys_jump_addr = dev->_dma_phys_start_addr;
251 risc_flag = RISC_CNT_INC;
252 }
253
254
255 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
256 *(rp++) = cpu_to_le32(RISC_JUMP|RISC_IRQ1|risc_flag);
257 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
258 *(rp++) = cpu_to_le32(0);
259 }
260
261 return 0;
262}
263
264
265void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
266{
267 struct sram_channel *sram_ch = &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_I];
268 u32 tmp = 0;
269
270 if( !dev->_is_running )
271 {
272 printk("cx25821: No video file is currently running so return!\n");
273 return;
274 }
275
276 //Disable RISC interrupts
277 tmp = cx_read( sram_ch->int_msk );
278 cx_write( sram_ch->int_msk, tmp & ~_intr_msk);
279
280 //Turn OFF risc and fifo enable
281 tmp = cx_read( sram_ch->dma_ctl );
282 cx_write( sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN) );
283
284 //Clear data buffer memory
285 if( dev->_data_buf_virt_addr )
286 memset( dev->_data_buf_virt_addr, 0, dev->_data_buf_size );
287
288 dev->_is_running = 0;
289 dev->_is_first_frame = 0;
290 dev->_frame_count = 0;
291 dev->_file_status = END_OF_FILE;
292
293 if( dev->_irq_queues )
294 {
295 kfree(dev->_irq_queues);
296 dev->_irq_queues = NULL;
297 }
298
299 if( dev->_filename != NULL )
300 kfree(dev->_filename);
301
302 tmp = cx_read( VID_CH_MODE_SEL );
303 cx_write( VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
304}
305
306void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
307{
308 if( dev->_is_running )
309 {
310 cx25821_stop_upstream_video_ch1(dev);
311 }
312
313 if (dev->_dma_virt_addr)
314 {
315 pci_free_consistent(dev->pci, dev->_risc_size, dev->_dma_virt_addr, dev->_dma_phys_addr);
316 dev->_dma_virt_addr = NULL;
317 }
318
319 if (dev->_data_buf_virt_addr)
320 {
321 pci_free_consistent(dev->pci, dev->_data_buf_size, dev->_data_buf_virt_addr, dev->_data_buf_phys_addr);
322 dev->_data_buf_virt_addr = NULL;
323 }
324}
325
326
327int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch )
328{
329 struct file * myfile;
330 int frame_index_temp = dev->_frame_index;
331 int i = 0;
332 int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
333 int frame_size = 0;
334 int frame_offset = 0;
335 ssize_t vfs_read_retval = 0;
336 char mybuf[line_size];
337 loff_t file_offset;
338 loff_t pos;
339 mm_segment_t old_fs;
340
341
342 if( dev->_file_status == END_OF_FILE )
343 return 0;
344
345 if( dev->_isNTSC )
346 {
347 frame_size = (line_size == Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
348 }
349 else
350 {
351 frame_size = (line_size == Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
352 }
353
354 frame_offset = (frame_index_temp > 0) ? frame_size : 0;
355 file_offset = dev->_frame_count * frame_size;
356
357
358 myfile = filp_open( dev->_filename, O_RDONLY | O_LARGEFILE, 0 );
359
360
361 if (IS_ERR(myfile))
362 {
363 const int open_errno = -PTR_ERR(myfile);
364 printk("%s(): ERROR opening file(%s) with errno = %d! \n", __func__, dev->_filename, open_errno);
365 return PTR_ERR(myfile);
366 }
367 else
368 {
369 if( !(myfile->f_op) )
370 {
371 printk("%s: File has no file operations registered!", __func__);
372 filp_close(myfile, NULL);
373 return -EIO;
374 }
375
376
377 if( !myfile->f_op->read )
378 {
379 printk("%s: File has no READ operations registered!", __func__);
380 filp_close(myfile, NULL);
381 return -EIO;
382 }
383
384 pos = myfile->f_pos;
385 old_fs = get_fs();
386 set_fs(KERNEL_DS);
387
388
389 for( i = 0; i < dev->_lines_count; i++ )
390 {
391 pos = file_offset;
392
393 vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos);
394
395 if( vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_data_buf_virt_addr != NULL )
396 {
397 memcpy( (void*)(dev->_data_buf_virt_addr+frame_offset/4), mybuf, vfs_read_retval);
398 }
399
400 file_offset += vfs_read_retval;
401 frame_offset += vfs_read_retval;
402
403 if( vfs_read_retval < line_size )
404 {
405 printk(KERN_INFO "Done: exit %s() since no more bytes to read from Video file.\n", __func__ );
406 break;
407 }
408 }
409
410 if( i > 0 )
411 dev->_frame_count++;
412
413 dev->_file_status = (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
414
415
416 set_fs(old_fs);
417 filp_close(myfile, NULL);
418 }
419
420 return 0;
421}
422
423static void cx25821_vidups_handler(struct work_struct *work)
424{
425 struct cx25821_dev *dev = container_of(work, struct cx25821_dev, _irq_work_entry);
426
427 if( !dev )
428 {
429 printk("ERROR %s(): since container_of(work_struct) FAILED! \n", __func__ );
430 return;
431 }
432
433 cx25821_get_frame( dev, &dev->sram_channels[dev->_channel_upstream_select] );
434}
435
436
437int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
438{
439 struct file * myfile;
440 int i = 0, j = 0;
441 int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
442 ssize_t vfs_read_retval = 0;
443 char mybuf[line_size];
444 loff_t pos;
445 loff_t offset = (unsigned long)0;
446 mm_segment_t old_fs;
447
448
449 myfile = filp_open( dev->_filename, O_RDONLY | O_LARGEFILE, 0 );
450
451
452 if (IS_ERR(myfile))
453 {
454 const int open_errno = -PTR_ERR(myfile);
455 printk("%s(): ERROR opening file(%s) with errno = %d! \n", __func__, dev->_filename, open_errno);
456 return PTR_ERR(myfile);
457 }
458 else
459 {
460 if( !(myfile->f_op) )
461 {
462 printk("%s: File has no file operations registered!", __func__);
463 filp_close(myfile, NULL);
464 return -EIO;
465 }
466
467
468 if( !myfile->f_op->read )
469 {
470 printk("%s: File has no READ operations registered! Returning.", __func__);
471 filp_close(myfile, NULL);
472 return -EIO;
473 }
474
475 pos = myfile->f_pos;
476 old_fs = get_fs();
477 set_fs(KERNEL_DS);
478
479
480 for( j = 0; j < NUM_FRAMES; j++ )
481 {
482 for( i = 0; i < dev->_lines_count; i++ )
483 {
484 pos = offset;
485
486 vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos);
487
488 if( vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_data_buf_virt_addr != NULL )
489 {
490 memcpy( (void*)(dev->_data_buf_virt_addr+offset/4), mybuf, vfs_read_retval);
491 }
492
493
494 offset += vfs_read_retval;
495
496 if( vfs_read_retval < line_size )
497 {
498 printk(KERN_INFO "Done: exit %s() since no more bytes to read from Video file.\n", __func__ );
499 break;
500 }
501 }
502
503 if( i > 0 )
504 dev->_frame_count++;
505
506 if( vfs_read_retval < line_size )
507 {
508 break;
509 }
510 }
511
512
513 dev->_file_status = (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
514
515 set_fs(old_fs);
516 myfile->f_pos = 0;
517 filp_close(myfile, NULL);
518 }
519
520 return 0;
521}
522
523
524int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
525 struct sram_channel *sram_ch,
526 int bpl)
527{
528 int ret = 0;
529 dma_addr_t dma_addr;
530 dma_addr_t data_dma_addr;
531
532 if( dev->_dma_virt_addr != NULL )
533 {
534 pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, dev->_dma_virt_addr, dev->_dma_phys_addr);
535 }
536
537
538 dev->_dma_virt_addr = pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size, &dma_addr);
539 dev->_dma_virt_start_addr = dev->_dma_virt_addr;
540 dev->_dma_phys_start_addr = dma_addr;
541 dev->_dma_phys_addr = dma_addr;
542 dev->_risc_size = dev->upstream_riscbuf_size;
543
544
545 if (!dev->_dma_virt_addr)
546 {
547 printk("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
548 return -ENOMEM;
549 }
550
551
552 //Clear memory at address
553 memset( dev->_dma_virt_addr, 0, dev->_risc_size );
554
555
556 if( dev->_data_buf_virt_addr != NULL )
557 {
558 pci_free_consistent(dev->pci, dev->upstream_databuf_size, dev->_data_buf_virt_addr, dev->_data_buf_phys_addr);
559 }
560
561 //For Video Data buffer allocation
562 dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, dev->upstream_databuf_size, &data_dma_addr);
563 dev->_data_buf_phys_addr = data_dma_addr;
564 dev->_data_buf_size = dev->upstream_databuf_size;
565
566 if (!dev->_data_buf_virt_addr)
567 {
568 printk("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
569 return -ENOMEM;
570 }
571
572
573 //Clear memory at address
574 memset( dev->_data_buf_virt_addr, 0, dev->_data_buf_size );
575
576
577 ret = cx25821_openfile(dev, sram_ch);
578 if( ret < 0 )
579 return ret;
580
581
582 //Create RISC programs
583 ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, dev->_lines_count );
584 if (ret < 0)
585 {
586 printk(KERN_INFO "cx25821: Failed creating Video Upstream Risc programs! \n");
587 goto error;
588 }
589
590 return 0;
591
592error:
593 return ret;
594}
595
596int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, u32 status)
597{
598 u32 int_msk_tmp;
599 struct sram_channel *channel = &dev->sram_channels[chan_num];
600 int singlefield_lines = NTSC_FIELD_HEIGHT;
601 int line_size_in_bytes = Y422_LINE_SZ;
602 int odd_risc_prog_size = 0;
603 dma_addr_t risc_phys_jump_addr;
604 __le32 * rp;
605
606
607
608 if (status & FLD_VID_SRC_RISC1)
609 {
610 // We should only process one program per call
611 u32 prog_cnt = cx_read( channel->gpcnt );
612
613 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
614 int_msk_tmp = cx_read(channel->int_msk);
615 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
616 cx_write( channel->int_stat, _intr_msk );
617
618 spin_lock(&dev->slock);
619
620 dev->_frame_index = prog_cnt;
621
622 queue_work(dev->_irq_queues, &dev->_irq_work_entry);
623
624
625 if ( dev->_is_first_frame )
626 {
627 dev->_is_first_frame = 0;
628
629 if( dev->_isNTSC )
630 {
631 singlefield_lines += 1;
632 odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
633 }
634 else
635 {
636 singlefield_lines = PAL_FIELD_HEIGHT;
637 odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
638 }
639
640
641 if( dev->_dma_virt_start_addr != NULL )
642 {
643 line_size_in_bytes = (dev->_pixel_format == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
644 risc_phys_jump_addr = dev->_dma_phys_start_addr + odd_risc_prog_size;
645
646 rp = cx25821_update_riscprogram(dev, dev->_dma_virt_start_addr, TOP_OFFSET, line_size_in_bytes, 0x0, singlefield_lines, FIFO_DISABLE, ODD_FIELD);
647
648 // Jump to Even Risc program of 1st Frame
649 *(rp++) = cpu_to_le32(RISC_JUMP);
650 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
651 *(rp++) = cpu_to_le32(0);
652 }
653 }
654
655 spin_unlock(&dev->slock);
656 }
657 else
658 {
659 if(status & FLD_VID_SRC_UF)
660 printk("%s: Video Received Underflow Error Interrupt!\n", __func__);
661
662 if(status & FLD_VID_SRC_SYNC)
663 printk("%s: Video Received Sync Error Interrupt!\n", __func__);
664
665 if(status & FLD_VID_SRC_OPC_ERR)
666 printk("%s: Video Received OpCode Error Interrupt!\n", __func__);
667 }
668
669
670 if( dev->_file_status == END_OF_FILE )
671 {
672 printk("cx25821: EOF Channel 1 Framecount = %d\n", dev->_frame_count );
673 return -1;
674 }
675
676 //ElSE, set the interrupt mask register, re-enable irq.
677 int_msk_tmp = cx_read( channel->int_msk );
678 cx_write( channel->int_msk, int_msk_tmp |= _intr_msk );
679
680 return 0;
681}
682
683static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
684{
685 struct cx25821_dev *dev = dev_id;
686 u32 msk_stat, vid_status;
687 int handled = 0;
688 int channel_num = 0;
689 struct sram_channel *sram_ch;
690
691
692 if( !dev )
693 return -1;
694
695 channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;
696
697 sram_ch = &dev->sram_channels[channel_num];
698
699 msk_stat = cx_read(sram_ch->int_mstat);
700 vid_status = cx_read(sram_ch->int_stat);
701
702 // Only deal with our interrupt
703 if(vid_status)
704 {
705 handled = cx25821_video_upstream_irq(dev, channel_num, vid_status);
706 }
707
708 if( handled < 0 )
709 {
710 cx25821_stop_upstream_video_ch1(dev);
711 }
712 else
713 {
714 handled += handled;
715 }
716
717 return IRQ_RETVAL(handled);
718}
719
720
721void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch, int pix_format)
722{
723 int width = WIDTH_D1;
724 int height = dev->_lines_count;
725 int num_lines, odd_num_lines;
726 u32 value;
727 int vip_mode = OUTPUT_FRMT_656;
728
729
730 value = ( (pix_format & 0x3) << 12 ) | ( vip_mode & 0x7 );
731 value &= 0xFFFFFFEF;
732 value |= dev->_isNTSC ? 0 : 0x10;
733 cx_write( ch->vid_fmt_ctl, value );
734
735
736 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
737 cx_write( ch->vid_active_ctl1, width );
738
739 num_lines = (height / 2) & 0x3FF;
740 odd_num_lines = num_lines;
741
742 if(dev->_isNTSC)
743 {
744 odd_num_lines += 1;
745 }
746
747 value = (num_lines << 16) | odd_num_lines;
748
749 // set number of active lines in field 0 (top) and field 1 (bottom)
750 cx_write( ch->vid_active_ctl2, value );
751
752 cx_write( ch->vid_cdt_size, VID_CDT_SIZE >> 3 );
753}
754
755
756int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
757 struct sram_channel *sram_ch)
758{
759 u32 tmp = 0;
760 int err = 0;
761
762
763 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
764 tmp = cx_read( VID_CH_MODE_SEL );
765 cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
766
767
768 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
769 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
770 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
771
772 /* reset counter */
773 cx_write(sram_ch->gpcnt_ctl, 3);
774
775 // Clear our bits from the interrupt status register.
776 cx_write( sram_ch->int_stat, _intr_msk );
777
778
779 //Set the interrupt mask register, enable irq.
780 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
781 tmp = cx_read( sram_ch->int_msk );
782 cx_write( sram_ch->int_msk, tmp |= _intr_msk );
783
784
785 err = request_irq(dev->pci->irq, cx25821_upstream_irq, IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
786 if (err < 0)
787 {
788 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name, dev->pci->irq);
789 goto fail_irq;
790 }
791
792
793 // Start the DMA engine
794 tmp = cx_read( sram_ch->dma_ctl );
795 cx_set( sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN );
796
797 dev->_is_running = 1;
798 dev->_is_first_frame = 1;
799
800 return 0;
801
802fail_irq:
803 cx25821_dev_unregister(dev);
804 return err;
805}
806
807
808int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, int pixel_format)
809{
810 struct sram_channel *sram_ch;
811 u32 tmp;
812 int retval = 0;
813 int err = 0;
814 int data_frame_size = 0;
815 int risc_buffer_size = 0;
816 int str_length = 0;
817
818
819 if( dev->_is_running )
820 {
821 printk("Video Channel is still running so return!\n");
822 return 0;
823 }
824
825
826 dev->_channel_upstream_select = channel_select;
827 sram_ch = &dev->sram_channels[channel_select];
828
829
830 INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
831 dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
832
833 if(!dev->_irq_queues)
834 {
835 printk("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
836 return -ENOMEM;
837 }
838
839 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
840 tmp = cx_read( VID_CH_MODE_SEL );
841 cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
842
843
844 dev->_is_running = 0;
845 dev->_frame_count = 0;
846 dev->_file_status = RESET_STATUS;
847 dev->_lines_count = dev->_isNTSC ? 480 : 576;
848 dev->_pixel_format = pixel_format;
849 dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
850 data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
851 risc_buffer_size = dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
852
853
854 if( dev->input_filename )
855 {
856 str_length = strlen(dev->input_filename);
857 dev->_filename = (char *) kmalloc(str_length + 1, GFP_KERNEL);
858
859 if( !dev->_filename )
860 goto error;
861
862 memcpy(dev->_filename, dev->input_filename, str_length + 1);
863 }
864 else
865 {
866 str_length = strlen(dev->_defaultname);
867 dev->_filename = (char *) kmalloc(str_length + 1, GFP_KERNEL);
868
869 if( !dev->_filename )
870 goto error;
871
872 memcpy(dev->_filename, dev->_defaultname, str_length + 1);
873 }
874
875
876 //Default if filename is empty string
877 if( strcmp(dev->input_filename,"") == 0)
878 {
879 if( dev->_isNTSC )
880 {
881 dev->_filename = (dev->_pixel_format == PIXEL_FRMT_411) ? "/root/vid411.yuv" : "/root/vidtest.yuv";
882 }
883 else
884 {
885 dev->_filename = (dev->_pixel_format == PIXEL_FRMT_411) ? "/root/pal411.yuv" : "/root/pal422.yuv";
886 }
887 }
888
889 dev->_is_running = 0;
890 dev->_frame_count = 0;
891 dev->_file_status = RESET_STATUS;
892 dev->_lines_count = dev->_isNTSC ? 480 : 576;
893 dev->_pixel_format = pixel_format;
894 dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
895
896 retval = cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size, 0);
897
898 /* setup fifo + format */
899 cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);
900
901 dev->upstream_riscbuf_size = risc_buffer_size * 2;
902 dev->upstream_databuf_size = data_frame_size * 2;
903
904
905 //Allocating buffers and prepare RISC program
906 retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
907 if (retval < 0)
908 {
909 printk(KERN_ERR "%s: Failed to set up Video upstream buffers!\n", dev->name);
910 goto error;
911 }
912
913
914 cx25821_start_video_dma_upstream(dev, sram_ch);
915
916 return 0;
917
918error:
919 cx25821_dev_unregister(dev);
920
921 return err;
922}
923
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/staging/cx25821/cx25821-video-upstream.h
new file mode 100644
index 00000000000..632ccc65bc7
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.h
@@ -0,0 +1,113 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26#define OUTPUT_FRMT_656 0
27#define OPEN_FILE_1 0
28#define NUM_PROGS 8
29#define NUM_FRAMES 2
30#define ODD_FIELD 0
31#define EVEN_FIELD 1
32#define TOP_OFFSET 0
33#define FIFO_DISABLE 0
34#define FIFO_ENABLE 1
35#define TEST_FRAMES 5
36#define END_OF_FILE 0
37#define IN_PROGRESS 1
38#define RESET_STATUS -1
39#define NUM_NO_OPS 5
40
41
42
43// PAL and NTSC line sizes and number of lines.
44#define WIDTH_D1 720
45#define NTSC_LINES_PER_FRAME 480
46#define PAL_LINES_PER_FRAME 576
47#define PAL_LINE_SZ 1440
48#define Y422_LINE_SZ 1440
49#define Y411_LINE_SZ 1080
50#define NTSC_FIELD_HEIGHT 240
51#define NTSC_ODD_FLD_LINES 241
52#define PAL_FIELD_HEIGHT 288
53
54#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
55#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
56#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
57#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
58
59#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
60#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
61
62#define RISC_WRITECR_INSTRUCTION_SIZE 16
63#define RISC_SYNC_INSTRUCTION_SIZE 4
64#define JUMP_INSTRUCTION_SIZE 12
65#define MAXSIZE_NO_OPS 36
66#define DWORD_SIZE 4
67
68
69#define USE_RISC_NOOP_VIDEO 1
70
71#ifdef USE_RISC_NOOP_VIDEO
72#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
73 RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
74
75#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
76
77#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
78 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
79
80#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
81 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
82
83#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
84 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
85
86#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
87 JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
88
89#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
90
91#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
92 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
93
94#endif
95
96
97#ifndef USE_RISC_NOOP_VIDEO
98#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
99 RISC_SYNC_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
100
101#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
102
103#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
104 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
105
106#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
107#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
108
109#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
110#define NTSC_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
111#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
112 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
113#endif
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
new file mode 100644
index 00000000000..512cbe3bae8
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -0,0 +1,1337 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
27MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
28MODULE_LICENSE("GPL");
29
30static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
31static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
32
33module_param_array(video_nr, int, NULL, 0444);
34module_param_array(radio_nr, int, NULL, 0444);
35
36MODULE_PARM_DESC(video_nr, "video device numbers");
37MODULE_PARM_DESC(radio_nr, "radio device numbers");
38
39static unsigned int video_debug=VIDEO_DEBUG;
40module_param(video_debug, int, 0644);
41MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
42
43static unsigned int irq_debug;
44module_param(irq_debug, int, 0644);
45MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
46
47unsigned int vid_limit = 16;
48module_param(vid_limit, int, 0644);
49MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
50
51static void init_controls(struct cx25821_dev *dev, int chan_num);
52
53#define FORMAT_FLAGS_PACKED 0x01
54
55struct cx25821_fmt formats[] = {
56 {
57 .name = "8 bpp, gray",
58 .fourcc = V4L2_PIX_FMT_GREY,
59 .depth = 8,
60 .flags = FORMAT_FLAGS_PACKED,
61 }, {
62 .name = "4:1:1, packed, Y41P",
63 .fourcc = V4L2_PIX_FMT_Y41P,
64 .depth = 12,
65 .flags = FORMAT_FLAGS_PACKED,
66 }, {
67 .name = "4:2:2, packed, YUYV",
68 .fourcc = V4L2_PIX_FMT_YUYV,
69 .depth = 16,
70 .flags = FORMAT_FLAGS_PACKED,
71 }, {
72 .name = "4:2:2, packed, UYVY",
73 .fourcc = V4L2_PIX_FMT_UYVY,
74 .depth = 16,
75 .flags = FORMAT_FLAGS_PACKED,
76 },{
77 .name = "4:2:0, YUV",
78 .fourcc = V4L2_PIX_FMT_YUV420,
79 .depth = 12,
80 .flags = FORMAT_FLAGS_PACKED,
81 },
82};
83
84
85int get_format_size(void)
86{
87 return ARRAY_SIZE(formats);
88}
89
90
91struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
92{
93 unsigned int i;
94
95 if( fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P )
96 {
97 return formats+1;
98 }
99
100 for (i = 0; i < ARRAY_SIZE(formats); i++)
101 if (formats[i].fourcc == fourcc)
102 return formats+i;
103
104 printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
105 return NULL;
106}
107
108void dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q)
109{
110 struct cx25821_buffer *buf;
111 struct list_head *item;
112 dprintk(1, "%s()\n", __func__);
113
114 if (!list_empty(&q->active)) {
115 list_for_each(item, &q->active)
116 buf = list_entry(item, struct cx25821_buffer, vb.queue);
117 }
118
119 if (!list_empty(&q->queued))
120 {
121 list_for_each(item, &q->queued)
122 buf = list_entry(item, struct cx25821_buffer, vb.queue);
123 }
124
125}
126
127
128void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, u32 count)
129{
130 struct cx25821_buffer *buf;
131 int bc;
132
133 for (bc = 0;; bc++) {
134 if (list_empty(&q->active))
135 {
136 dprintk(1, "bc=%d (=0: active empty)\n", bc);
137 break;
138 }
139
140 buf = list_entry(q->active.next, struct cx25821_buffer, vb.queue);
141
142 /* count comes from the hw and it is 16bit wide --
143 * this trick handles wrap-arounds correctly for
144 * up to 32767 buffers in flight... */
145 if ((s16) (count - buf->count) < 0)
146 {
147 break;
148 }
149
150 do_gettimeofday(&buf->vb.ts);
151 buf->vb.state = VIDEOBUF_DONE;
152 list_del(&buf->vb.queue);
153 wake_up(&buf->vb.done);
154 }
155
156 if (list_empty(&q->active))
157 del_timer(&q->timeout);
158 else
159 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
160 if (bc != 1)
161 printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", __func__, bc);
162}
163
164#ifdef TUNER_FLAG
165int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
166{
167 dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
168 (unsigned int)norm,
169 v4l2_norm_to_name(norm));
170
171 dev->tvnorm = norm;
172
173 /* Tell the internal A/V decoder */
174 cx25821_call_all(dev, core, s_std, norm);
175
176 return 0;
177}
178#endif
179
180struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
181 struct pci_dev *pci,
182 struct video_device *template,
183 char *type)
184{
185 struct video_device *vfd;
186 dprintk(1, "%s()\n", __func__);
187
188 vfd = video_device_alloc();
189 if (NULL == vfd)
190 return NULL;
191 *vfd = *template;
192 vfd->minor = -1;
193 vfd->v4l2_dev = &dev->v4l2_dev;
194 vfd->release = video_device_release;
195 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx25821_boards[dev->board].name);
196 return vfd;
197}
198
199/*
200static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
201{
202 int i;
203
204 if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
205 return -EINVAL;
206 for (i = 0; i < CX25821_CTLS; i++)
207 if (cx25821_ctls[i].v.id == qctrl->id)
208 break;
209 if (i == CX25821_CTLS) {
210 *qctrl = no_ctl;
211 return 0;
212 }
213 *qctrl = cx25821_ctls[i].v;
214 return 0;
215}
216*/
217
218// resource management
219int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
220{
221 dprintk(1, "%s()\n", __func__);
222 if (fh->resources & bit)
223 /* have it already allocated */
224 return 1;
225
226 /* is it free? */
227 mutex_lock(&dev->lock);
228 if (dev->resources & bit) {
229 /* no, someone else uses it */
230 mutex_unlock(&dev->lock);
231 return 0;
232 }
233 /* it's free, grab it */
234 fh->resources |= bit;
235 dev->resources |= bit;
236 dprintk(1, "res: get %d\n", bit);
237 mutex_unlock(&dev->lock);
238 return 1;
239}
240
241int res_check(struct cx25821_fh *fh, unsigned int bit)
242{
243 return fh->resources & bit;
244}
245
246int res_locked(struct cx25821_dev *dev, unsigned int bit)
247{
248 return dev->resources & bit;
249}
250
251void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
252{
253 BUG_ON((fh->resources & bits) != bits);
254 dprintk(1, "%s()\n", __func__);
255
256 mutex_lock(&dev->lock);
257 fh->resources &= ~bits;
258 dev->resources &= ~bits;
259 dprintk(1, "res: put %d\n", bits);
260 mutex_unlock(&dev->lock);
261}
262
263int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
264{
265 struct v4l2_routing route;
266 memset(&route, 0, sizeof(route));
267
268 dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", __func__,
269 input, INPUT(input)->vmux,
270 INPUT(input)->gpio0, INPUT(input)->gpio1,
271 INPUT(input)->gpio2, INPUT(input)->gpio3);
272 dev->input = input;
273
274 route.input = INPUT(input)->vmux;
275
276 /* Tell the internal A/V decoder */
277 cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
278
279 return 0;
280}
281
282int cx25821_start_video_dma(struct cx25821_dev *dev,
283 struct cx25821_dmaqueue *q,
284 struct cx25821_buffer *buf,
285 struct sram_channel *channel)
286{
287 int tmp = 0;
288
289 /* setup fifo + format */
290 cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
291
292 /* reset counter */
293 cx_write(channel->gpcnt_ctl, 3);
294 q->count = 1;
295
296 /* enable irq */
297 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1<<channel->i));
298 cx_set(channel->int_msk, 0x11);
299
300 /* start dma */
301 cx_write(channel->dma_ctl, 0x11); /* FIFO and RISC enable */
302
303 /* make sure upstream setting if any is reversed */
304 tmp = cx_read( VID_CH_MODE_SEL );
305 cx_write( VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
306
307 return 0;
308}
309
310
311int cx25821_restart_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, struct sram_channel *channel)
312{
313 struct cx25821_buffer *buf, *prev;
314 struct list_head *item;
315
316 if (!list_empty(&q->active)) {
317 buf = list_entry(q->active.next, struct cx25821_buffer, vb.queue);
318
319 cx25821_start_video_dma(dev, q, buf, channel);
320
321 list_for_each(item, &q->active) {
322 buf = list_entry(item, struct cx25821_buffer, vb.queue);
323 buf->count = q->count++;
324 }
325
326 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
327 return 0;
328 }
329
330 prev = NULL;
331 for (;;) {
332 if (list_empty(&q->queued))
333 return 0;
334
335 buf = list_entry(q->queued.next, struct cx25821_buffer, vb.queue);
336
337 if (NULL == prev) {
338 list_move_tail(&buf->vb.queue, &q->active);
339 cx25821_start_video_dma(dev, q, buf, channel);
340 buf->vb.state = VIDEOBUF_ACTIVE;
341 buf->count = q->count++;
342 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
343 } else if (prev->vb.width == buf->vb.width &&
344 prev->vb.height == buf->vb.height &&
345 prev->fmt == buf->fmt) {
346 list_move_tail(&buf->vb.queue, &q->active);
347 buf->vb.state = VIDEOBUF_ACTIVE;
348 buf->count = q->count++;
349 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
350 prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
351 } else {
352 return 0;
353 }
354 prev = buf;
355 }
356}
357
358void cx25821_vid_timeout(unsigned long data)
359{
360 struct cx25821_data *timeout_data = (struct cx25821_data *)data;
361 struct cx25821_dev *dev = timeout_data->dev;
362 struct sram_channel *channel = timeout_data->channel;
363 struct cx25821_dmaqueue *q = &dev->vidq[channel->i];
364 struct cx25821_buffer *buf;
365 unsigned long flags;
366
367 //cx25821_sram_channel_dump(dev, channel);
368 cx_clear(channel->dma_ctl, 0x11);
369
370 spin_lock_irqsave(&dev->slock, flags);
371 while (!list_empty(&q->active)) {
372 buf = list_entry(q->active.next, struct cx25821_buffer, vb.queue);
373 list_del(&buf->vb.queue);
374
375 buf->vb.state = VIDEOBUF_ERROR;
376 wake_up(&buf->vb.done);
377 }
378
379 cx25821_restart_video_queue(dev, q, channel);
380 spin_unlock_irqrestore(&dev->slock, flags);
381}
382
383int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
384{
385 u32 count=0;
386 int handled = 0;
387 u32 mask;
388 struct sram_channel *channel = &dev->sram_channels[chan_num];
389
390 mask = cx_read(channel->int_msk);
391 if (0 == (status & mask))
392 return handled;
393
394 cx_write(channel->int_stat, status);
395
396 /* risc op code error */
397 if (status & (1 << 16)) {
398 printk(KERN_WARNING "%s, %s: video risc op code error\n", dev->name, channel->name);
399 cx_clear(channel->dma_ctl, 0x11);
400 cx25821_sram_channel_dump(dev, channel);
401 }
402
403 /* risc1 y */
404 if (status & FLD_VID_DST_RISC1) {
405 spin_lock(&dev->slock);
406 count = cx_read(channel->gpcnt);
407 cx25821_video_wakeup(dev, &dev->vidq[channel->i], count);
408 spin_unlock(&dev->slock);
409 handled++;
410 }
411
412 /* risc2 y */
413 if (status & 0x10) {
414 dprintk(2, "stopper video\n");
415 spin_lock(&dev->slock);
416 cx25821_restart_video_queue(dev, &dev->vidq[channel->i], channel);
417 spin_unlock(&dev->slock);
418 handled++;
419 }
420 return handled;
421}
422
423void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
424{
425 if( dev->ioctl_dev )
426 {
427 if (dev->ioctl_dev->minor != -1)
428 video_unregister_device(dev->ioctl_dev);
429 else
430 video_device_release(dev->ioctl_dev);
431
432 dev->ioctl_dev = NULL;
433 }
434}
435
436void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
437{
438 cx_clear(PCI_INT_MSK, 1);
439
440 if (dev->video_dev[chan_num]) {
441 if (-1 != dev->video_dev[chan_num]->minor)
442 video_unregister_device(dev->video_dev[chan_num]);
443 else
444 video_device_release(dev->video_dev[chan_num]);
445
446 dev->video_dev[chan_num] = NULL;
447
448 btcx_riscmem_free(dev->pci, &dev->vidq[chan_num].stopper);
449
450 printk(KERN_WARNING "device %d released!\n", chan_num);
451 }
452
453}
454
455
456int cx25821_video_register(struct cx25821_dev *dev, int chan_num, struct video_device *video_template)
457{
458 int err;
459
460 spin_lock_init(&dev->slock);
461
462 //printk(KERN_WARNING "Channel %d\n", chan_num);
463
464#ifdef TUNER_FLAG
465 dev->tvnorm = video_template->current_norm;
466#endif
467
468 /* init video dma queues */
469 dev->timeout_data[chan_num].dev = dev;
470 dev->timeout_data[chan_num].channel = &dev->sram_channels[chan_num];
471 INIT_LIST_HEAD(&dev->vidq[chan_num].active);
472 INIT_LIST_HEAD(&dev->vidq[chan_num].queued);
473 dev->vidq[chan_num].timeout.function = cx25821_vid_timeout;
474 dev->vidq[chan_num].timeout.data = (unsigned long)&dev->timeout_data[chan_num];
475 init_timer(&dev->vidq[chan_num].timeout);
476 cx25821_risc_stopper(dev->pci, &dev->vidq[chan_num].stopper, dev->sram_channels[chan_num].dma_ctl, 0x11, 0);
477
478
479 /* register v4l devices */
480 dev->video_dev[chan_num] = cx25821_vdev_init(dev, dev->pci, video_template, "video");
481 err = video_register_device(dev->video_dev[chan_num], VFL_TYPE_GRABBER, video_nr[dev->nr]);
482
483 if (err < 0) {
484 goto fail_unreg;
485 }
486
487 //set PCI interrupt
488 cx_set(PCI_INT_MSK, 0xff);
489
490
491 /* initial device configuration */
492 mutex_lock(&dev->lock);
493#ifdef TUNER_FLAG
494 cx25821_set_tvnorm(dev, dev->tvnorm);
495#endif
496 mutex_unlock(&dev->lock);
497
498 init_controls(dev, chan_num);
499
500 return 0;
501
502fail_unreg:
503 cx25821_video_unregister(dev, chan_num);
504 return err;
505}
506
507int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
508{
509 struct cx25821_fh *fh = q->priv_data;
510
511 *size = fh->fmt->depth*fh->width*fh->height >> 3;
512
513
514 if (0 == *count)
515 *count = 32;
516
517 while (*size * *count > vid_limit * 1024 * 1024)
518 (*count)--;
519
520 return 0;
521}
522
523int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field)
524{
525 struct cx25821_fh *fh = q->priv_data;
526 struct cx25821_dev *dev = fh->dev;
527 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
528 int rc, init_buffer = 0;
529 u32 line0_offset, line1_offset;
530 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
531 int bpl_local = LINE_SIZE_D1;
532 int channel_opened = 0;
533
534
535 BUG_ON(NULL == fh->fmt);
536 if (fh->width < 48 || fh->width > 720 ||
537 fh->height < 32 || fh->height > 576)
538 return -EINVAL;
539
540 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
541
542 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
543 return -EINVAL;
544
545
546 if (buf->fmt != fh->fmt ||
547 buf->vb.width != fh->width ||
548 buf->vb.height != fh->height ||
549 buf->vb.field != field) {
550 buf->fmt = fh->fmt;
551 buf->vb.width = fh->width;
552 buf->vb.height = fh->height;
553 buf->vb.field = field;
554 init_buffer = 1;
555 }
556
557 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
558 init_buffer = 1;
559 rc = videobuf_iolock(q, &buf->vb, NULL);
560 if (0 != rc)
561 {
562 printk(KERN_DEBUG "videobuf_iolock failed!\n");
563 goto fail;
564 }
565 }
566
567 dprintk(1, "init_buffer=%d\n", init_buffer);
568
569 if (init_buffer) {
570
571 channel_opened = dev->channel_opened;
572 channel_opened = (channel_opened < 0 || channel_opened > 7) ? 7 : channel_opened;
573
574 if( dev->pixel_formats[channel_opened] == PIXEL_FRMT_411 )
575 buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
576 else
577 buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
578
579
580 if( dev->pixel_formats[channel_opened] == PIXEL_FRMT_411 )
581 {
582 bpl_local = buf->bpl;
583 }
584 else
585 {
586 bpl_local = buf->bpl; //Default
587
588 if( channel_opened >= 0 && channel_opened <= 7 )
589 {
590 if( dev->use_cif_resolution[channel_opened] )
591 {
592 if( dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK )
593 bpl_local = 352 << 1;
594 else
595 bpl_local = dev->cif_width[channel_opened] << 1;
596 }
597 }
598 }
599
600
601 switch (buf->vb.field) {
602 case V4L2_FIELD_TOP:
603 cx25821_risc_buffer(dev->pci, &buf->risc,
604 dma->sglist, 0, UNSET,
605 buf->bpl, 0, buf->vb.height);
606 break;
607 case V4L2_FIELD_BOTTOM:
608 cx25821_risc_buffer(dev->pci, &buf->risc,
609 dma->sglist, UNSET, 0,
610 buf->bpl, 0, buf->vb.height);
611 break;
612 case V4L2_FIELD_INTERLACED:
613 /* All other formats are top field first */
614 line0_offset = 0;
615 line1_offset = buf->bpl;
616 dprintk(1, "top field first\n");
617
618 cx25821_risc_buffer(dev->pci, &buf->risc,
619 dma->sglist, line0_offset,
620 bpl_local, bpl_local, bpl_local,
621 buf->vb.height >> 1);
622 break;
623 case V4L2_FIELD_SEQ_TB:
624 cx25821_risc_buffer(dev->pci, &buf->risc,
625 dma->sglist,
626 0, buf->bpl * (buf->vb.height >> 1),
627 buf->bpl, 0,
628 buf->vb.height >> 1);
629 break;
630 case V4L2_FIELD_SEQ_BT:
631 cx25821_risc_buffer(dev->pci, &buf->risc,
632 dma->sglist,
633 buf->bpl * (buf->vb.height >> 1), 0,
634 buf->bpl, 0,
635 buf->vb.height >> 1);
636 break;
637 default:
638 BUG();
639 }
640 }
641
642 dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
643 buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth, fh->fmt->name,
644 (unsigned long)buf->risc.dma);
645
646 buf->vb.state = VIDEOBUF_PREPARED;
647
648 return 0;
649
650 fail:
651 cx25821_free_buffer(q, buf);
652 return rc;
653}
654
655
656void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
657{
658 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
659
660 cx25821_free_buffer(q, buf);
661}
662
663
664struct videobuf_queue *get_queue(struct cx25821_fh *fh)
665{
666 switch (fh->type) {
667 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
668 return &fh->vidq;
669 default:
670 BUG();
671 return NULL;
672 }
673}
674
675int get_resource(struct cx25821_fh *fh, int resource)
676{
677 switch (fh->type) {
678 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
679 return resource;
680 default:
681 BUG();
682 return 0;
683 }
684}
685
686
687int video_mmap(struct file *file, struct vm_area_struct *vma)
688{
689 struct cx25821_fh *fh = file->private_data;
690
691 return videobuf_mmap_mapper(get_queue(fh), vma);
692}
693
694/* VIDEO IOCTLS */
695int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
696{
697 struct cx25821_fh *fh = priv;
698
699 f->fmt.pix.width = fh->width;
700 f->fmt.pix.height = fh->height;
701 f->fmt.pix.field = fh->vidq.field;
702 f->fmt.pix.pixelformat = fh->fmt->fourcc;
703 f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
704 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
705
706 return 0;
707}
708
709int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
710{
711 struct cx25821_fmt *fmt;
712 enum v4l2_field field;
713 unsigned int maxw, maxh;
714
715 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
716 if (NULL == fmt)
717 return -EINVAL;
718
719 field = f->fmt.pix.field;
720 maxw = 720;
721 maxh = 576;
722
723 if (V4L2_FIELD_ANY == field) {
724 field = (f->fmt.pix.height > maxh/2)
725 ? V4L2_FIELD_INTERLACED
726 : V4L2_FIELD_TOP;
727 }
728
729 switch (field) {
730 case V4L2_FIELD_TOP:
731 case V4L2_FIELD_BOTTOM:
732 maxh = maxh / 2;
733 break;
734 case V4L2_FIELD_INTERLACED:
735 break;
736 default:
737 return -EINVAL;
738 }
739
740 f->fmt.pix.field = field;
741 if (f->fmt.pix.height < 32)
742 f->fmt.pix.height = 32;
743 if (f->fmt.pix.height > maxh)
744 f->fmt.pix.height = maxh;
745 if (f->fmt.pix.width < 48)
746 f->fmt.pix.width = 48;
747 if (f->fmt.pix.width > maxw)
748 f->fmt.pix.width = maxw;
749 f->fmt.pix.width &= ~0x03;
750 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
751 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
752
753 return 0;
754}
755
756
757
758int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
759{
760 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
761
762 strcpy(cap->driver, "cx25821");
763 strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
764 sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
765 cap->version = CX25821_VERSION_CODE;
766 cap->capabilities =
767 V4L2_CAP_VIDEO_CAPTURE |
768 V4L2_CAP_READWRITE |
769 V4L2_CAP_STREAMING;
770 if (UNSET != dev->tuner_type)
771 cap->capabilities |= V4L2_CAP_TUNER;
772 return 0;
773}
774
775int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f)
776{
777 if (unlikely(f->index >= ARRAY_SIZE(formats)))
778 return -EINVAL;
779
780 strlcpy(f->description, formats[f->index].name, sizeof(f->description));
781 f->pixelformat = formats[f->index].fourcc;
782
783 return 0;
784}
785
786#ifdef CONFIG_VIDEO_V4L1_COMPAT
787int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
788{
789 struct cx25821_fh *fh = priv;
790 struct videobuf_queue *q;
791 struct v4l2_requestbuffers req;
792 unsigned int i;
793 int err;
794
795 q = get_queue(fh);
796 memset(&req, 0, sizeof(req));
797 req.type = q->type;
798 req.count = 8;
799 req.memory = V4L2_MEMORY_MMAP;
800 err = videobuf_reqbufs(q, &req);
801 if (err < 0)
802 return err;
803
804 mbuf->frames = req.count;
805 mbuf->size = 0;
806 for (i = 0; i < mbuf->frames; i++) {
807 mbuf->offsets[i] = q->bufs[i]->boff;
808 mbuf->size += q->bufs[i]->bsize;
809 }
810 return 0;
811}
812#endif
813
814int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
815{
816 struct cx25821_fh *fh = priv;
817 return videobuf_reqbufs(get_queue(fh), p);
818}
819
820int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
821{
822 struct cx25821_fh *fh = priv;
823 return videobuf_querybuf(get_queue(fh), p);
824}
825
826int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
827{
828 struct cx25821_fh *fh = priv;
829 return videobuf_qbuf(get_queue(fh), p);
830}
831
832int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
833{
834 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
835
836 *p = v4l2_prio_max(&dev->prio);
837
838 return 0;
839}
840
841int vidioc_s_priority(struct file *file, void *f,
842 enum v4l2_priority prio)
843{
844 struct cx25821_fh *fh = f;
845 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
846
847 return v4l2_prio_change(&dev->prio, &fh->prio, prio);
848}
849
850
851#ifdef TUNER_FLAG
852int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms)
853{
854 struct cx25821_fh *fh = priv;
855 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
856 int err;
857
858 dprintk(1, "%s()\n", __func__);
859
860 if (fh)
861 {
862 err = v4l2_prio_check(&dev->prio, &fh->prio);
863 if (0 != err)
864 return err;
865 }
866
867 if( dev->tvnorm == *tvnorms )
868 {
869 return 0;
870 }
871
872 mutex_lock(&dev->lock);
873 cx25821_set_tvnorm(dev, *tvnorms);
874 mutex_unlock(&dev->lock);
875
876 medusa_set_videostandard(dev);
877
878 return 0;
879}
880#endif
881
882int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
883{
884 static const char *iname[] = {
885 [CX25821_VMUX_COMPOSITE] = "Composite",
886 [CX25821_VMUX_SVIDEO] = "S-Video",
887 [CX25821_VMUX_DEBUG] = "for debug only",
888 };
889 unsigned int n;
890 dprintk(1, "%s()\n", __func__);
891
892 n = i->index;
893 if (n > 2)
894 return -EINVAL;
895
896 if (0 == INPUT(n)->type)
897 return -EINVAL;
898
899 memset(i, 0, sizeof(*i));
900 i->index = n;
901 i->type = V4L2_INPUT_TYPE_CAMERA;
902 strcpy(i->name, iname[INPUT(n)->type]);
903
904 i->std = CX25821_NORMS;
905 return 0;
906}
907
908int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
909{
910 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
911 dprintk(1, "%s()\n", __func__);
912 return cx25821_enum_input(dev, i);
913}
914
915int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
916{
917 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
918
919 *i = dev->input;
920 dprintk(1, "%s() returns %d\n", __func__, *i);
921 return 0;
922}
923
924
925int vidioc_s_input(struct file *file, void *priv, unsigned int i)
926{
927 struct cx25821_fh *fh = priv;
928 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
929 int err;
930
931 dprintk(1, "%s(%d)\n", __func__, i);
932
933 if (fh)
934 {
935 err = v4l2_prio_check(&dev->prio, &fh->prio);
936 if (0 != err)
937 return err;
938 }
939
940 if (i > 2) {
941 dprintk(1, "%s() -EINVAL\n", __func__);
942 return -EINVAL;
943 }
944
945 mutex_lock(&dev->lock);
946 cx25821_video_mux(dev, i);
947 mutex_unlock(&dev->lock);
948 return 0;
949}
950
951#ifdef TUNER_FLAG
952int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
953{
954 struct cx25821_fh *fh = priv;
955 struct cx25821_dev *dev = fh->dev;
956
957 f->frequency = dev->freq;
958
959 cx25821_call_all(dev, tuner, g_frequency, f);
960
961 return 0;
962}
963
964int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
965{
966 mutex_lock(&dev->lock);
967 dev->freq = f->frequency;
968
969 cx25821_call_all(dev, tuner, s_frequency, f);
970
971 /* When changing channels it is required to reset TVAUDIO */
972 msleep(10);
973
974 mutex_unlock(&dev->lock);
975
976 return 0;
977}
978
979int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
980{
981 struct cx25821_fh *fh = priv;
982 struct cx25821_dev *dev = fh->dev;
983 int err;
984
985 if (fh)
986 {
987 err = v4l2_prio_check(&dev->prio, &fh->prio);
988 if (0 != err)
989 return err;
990 }
991
992 return cx25821_set_freq(dev, f);
993}
994#endif
995
996#ifdef CONFIG_VIDEO_ADV_DEBUG
997int vidioc_g_register(struct file *file, void *fh,
998 struct v4l2_dbg_register *reg)
999{
1000 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
1001
1002 if (!v4l2_chip_match_host(&reg->match))
1003 return -EINVAL;
1004
1005 cx25821_call_all(dev, core, g_register, reg);
1006
1007 return 0;
1008}
1009
1010int vidioc_s_register(struct file *file, void *fh,
1011 struct v4l2_dbg_register *reg)
1012{
1013 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
1014
1015 if (!v4l2_chip_match_host(&reg->match))
1016 return -EINVAL;
1017
1018 cx25821_call_all(dev, core, s_register, reg);
1019
1020 return 0;
1021}
1022
1023#endif
1024
1025
1026#ifdef TUNER_FLAG
1027int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1028{
1029 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1030
1031 if (unlikely(UNSET == dev->tuner_type))
1032 return -EINVAL;
1033 if (0 != t->index)
1034 return -EINVAL;
1035
1036 strcpy(t->name, "Television");
1037 t->type = V4L2_TUNER_ANALOG_TV;
1038 t->capability = V4L2_TUNER_CAP_NORM;
1039 t->rangehigh = 0xffffffffUL;
1040
1041 t->signal = 0xffff ; /* LOCKED */
1042 return 0;
1043}
1044
1045int vidioc_s_tuner(struct file *file, void *priv,
1046 struct v4l2_tuner *t)
1047{
1048 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1049 struct cx25821_fh *fh = priv;
1050 int err;
1051
1052 if (fh)
1053 {
1054 err = v4l2_prio_check(&dev->prio, &fh->prio);
1055 if (0 != err)
1056 return err;
1057 }
1058
1059 dprintk(1, "%s()\n", __func__);
1060 if (UNSET == dev->tuner_type)
1061 return -EINVAL;
1062 if (0 != t->index)
1063 return -EINVAL;
1064
1065 return 0;
1066}
1067
1068#endif
1069// ******************************************************************************************
1070static const struct v4l2_queryctrl no_ctl = {
1071 .name = "42",
1072 .flags = V4L2_CTRL_FLAG_DISABLED,
1073};
1074
1075static struct v4l2_queryctrl cx25821_ctls[] = {
1076 /* --- video --- */
1077 {
1078 .id = V4L2_CID_BRIGHTNESS,
1079 .name = "Brightness",
1080 .minimum = 0,
1081 .maximum = 10000,
1082 .step = 1,
1083 .default_value = 6200,
1084 .type = V4L2_CTRL_TYPE_INTEGER,
1085 },{
1086 .id = V4L2_CID_CONTRAST,
1087 .name = "Contrast",
1088 .minimum = 0,
1089 .maximum = 10000,
1090 .step = 1,
1091 .default_value = 5000,
1092 .type = V4L2_CTRL_TYPE_INTEGER,
1093 },{
1094 .id = V4L2_CID_SATURATION,
1095 .name = "Saturation",
1096 .minimum = 0,
1097 .maximum = 10000,
1098 .step = 1,
1099 .default_value = 5000,
1100 .type = V4L2_CTRL_TYPE_INTEGER,
1101 },{
1102 .id = V4L2_CID_HUE,
1103 .name = "Hue",
1104 .minimum = 0,
1105 .maximum = 10000,
1106 .step = 1,
1107 .default_value = 5000,
1108 .type = V4L2_CTRL_TYPE_INTEGER,
1109 }
1110};
1111static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
1112
1113static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
1114{
1115 int i;
1116
1117 if (qctrl->id < V4L2_CID_BASE ||
1118 qctrl->id >= V4L2_CID_LASTP1)
1119 return -EINVAL;
1120 for (i = 0; i < CX25821_CTLS; i++)
1121 if (cx25821_ctls[i].id == qctrl->id)
1122 break;
1123 if (i == CX25821_CTLS) {
1124 *qctrl = no_ctl;
1125 return 0;
1126 }
1127 *qctrl = cx25821_ctls[i];
1128 return 0;
1129}
1130
1131int vidioc_queryctrl(struct file *file, void *priv,
1132 struct v4l2_queryctrl *qctrl)
1133{
1134 return cx25821_ctrl_query(qctrl);
1135}
1136
1137/* ------------------------------------------------------------------ */
1138/* VIDEO CTRL IOCTLS */
1139
1140static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id)
1141{
1142 unsigned int i;
1143
1144 for (i = 0; i < CX25821_CTLS; i++)
1145 if (cx25821_ctls[i].id == id)
1146 return cx25821_ctls+i;
1147 return NULL;
1148}
1149
1150int vidioc_g_ctrl(struct file *file,
1151 void *priv,
1152 struct v4l2_control *ctl)
1153{
1154 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1155
1156 const struct v4l2_queryctrl* ctrl;
1157
1158 ctrl = ctrl_by_id(ctl->id);
1159
1160 if (NULL == ctrl)
1161 return -EINVAL;
1162 switch (ctl->id)
1163 {
1164 case V4L2_CID_BRIGHTNESS:
1165 ctl->value = dev->ctl_bright;
1166 break;
1167 case V4L2_CID_HUE:
1168 ctl->value = dev->ctl_hue;
1169 break;
1170 case V4L2_CID_CONTRAST:
1171 ctl->value = dev->ctl_contrast;
1172 break;
1173 case V4L2_CID_SATURATION:
1174 ctl->value = dev->ctl_saturation;
1175 break;
1176 }
1177 return 0;
1178}
1179
1180int cx25821_set_control(struct cx25821_dev *dev,
1181 struct v4l2_control *ctl, int chan_num)
1182{
1183 int err;
1184 const struct v4l2_queryctrl* ctrl;
1185
1186 err = -EINVAL;
1187
1188 ctrl = ctrl_by_id(ctl->id);
1189
1190 if (NULL == ctrl)
1191 return err;
1192
1193 switch (ctrl->type)
1194 {
1195 case V4L2_CTRL_TYPE_BOOLEAN:
1196 case V4L2_CTRL_TYPE_MENU:
1197 case V4L2_CTRL_TYPE_INTEGER:
1198 if (ctl->value < ctrl->minimum)
1199 ctl->value = ctrl->minimum;
1200 if (ctl->value > ctrl->maximum)
1201 ctl->value = ctrl->maximum;
1202 break;
1203 default:
1204 /* nothing */;
1205 };
1206
1207 switch (ctl->id)
1208 {
1209 case V4L2_CID_BRIGHTNESS:
1210 dev->ctl_bright = ctl->value;
1211 medusa_set_brightness(dev, ctl->value, chan_num);
1212 break;
1213 case V4L2_CID_HUE:
1214 dev->ctl_hue = ctl->value;
1215 medusa_set_hue(dev, ctl->value, chan_num);
1216 break;
1217 case V4L2_CID_CONTRAST:
1218 dev->ctl_contrast = ctl->value;
1219 medusa_set_contrast(dev, ctl->value, chan_num);
1220 break;
1221 case V4L2_CID_SATURATION:
1222 dev->ctl_saturation = ctl->value;
1223 medusa_set_saturation(dev, ctl->value, chan_num);
1224 break;
1225 }
1226
1227 err = 0;
1228
1229 return err;
1230}
1231
1232static void init_controls(struct cx25821_dev *dev, int chan_num)
1233{
1234 struct v4l2_control ctrl;
1235 int i;
1236 for (i = 0; i < CX25821_CTLS; i++) {
1237 ctrl.id = cx25821_ctls[i].id;
1238 ctrl.value = cx25821_ctls[i].default_value;
1239
1240 cx25821_set_control(dev, &ctrl, chan_num);
1241 }
1242}
1243
1244int vidioc_cropcap(struct file *file,
1245 void *priv,
1246 struct v4l2_cropcap *cropcap)
1247{
1248 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1249
1250 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1251 return -EINVAL;
1252 cropcap->bounds.top = cropcap->bounds.left = 0;
1253 cropcap->bounds.width = 720;
1254 cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
1255 cropcap->pixelaspect.numerator = dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
1256 cropcap->pixelaspect.denominator = dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
1257 cropcap->defrect = cropcap->bounds;
1258 return 0;
1259}
1260
1261int vidioc_s_crop(struct file *file,
1262 void *priv,
1263 struct v4l2_crop *crop)
1264{
1265 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1266 struct cx25821_fh *fh = priv;
1267 int err;
1268
1269 if (fh)
1270 {
1271 err = v4l2_prio_check(&dev->prio, &fh->prio);
1272 if (0 != err)
1273 return err;
1274 }
1275 // vidioc_s_crop not supported
1276 return -EINVAL;
1277}
1278
1279int vidioc_g_crop(struct file *file,
1280 void *priv,
1281 struct v4l2_crop *crop)
1282{
1283 // vidioc_g_crop not supported
1284 return -EINVAL;
1285}
1286
1287int vidioc_querystd(struct file *file,
1288 void *priv,
1289 v4l2_std_id *norm)
1290{
1291 // medusa does not support video standard sensing of current input
1292 *norm = CX25821_NORMS;
1293
1294 return 0;
1295}
1296
1297int is_valid_width(u32 width, v4l2_std_id tvnorm)
1298{
1299 if(tvnorm == V4L2_STD_PAL_BG)
1300 {
1301 if (width == 352 || width == 720)
1302 return 1;
1303 else
1304 return 0;
1305 }
1306
1307 if(tvnorm == V4L2_STD_NTSC_M)
1308 {
1309 if (width == 320 || width == 352 || width == 720)
1310 return 1;
1311 else
1312 return 0;
1313 }
1314 return 0;
1315}
1316
1317int is_valid_height(u32 height, v4l2_std_id tvnorm)
1318{
1319 if(tvnorm == V4L2_STD_PAL_BG)
1320 {
1321 if (height == 576 || height == 288)
1322 return 1;
1323 else
1324 return 0;
1325 }
1326
1327 if(tvnorm == V4L2_STD_NTSC_M)
1328 {
1329 if (height == 480 || height == 240)
1330 return 1;
1331 else
1332 return 0;
1333 }
1334
1335 return 0;
1336}
1337
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
new file mode 100644
index 00000000000..fa2ec788535
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -0,0 +1,172 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#ifndef CX25821_VIDEO_H_
25#define CX25821_VIDEO_H_
26
27
28#include <linux/init.h>
29#include <linux/list.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/kmod.h>
33#include <linux/kernel.h>
34#include <linux/slab.h>
35#include <linux/interrupt.h>
36#include <linux/delay.h>
37#include <linux/kthread.h>
38#include <asm/div64.h>
39
40#include "cx25821.h"
41#include <media/v4l2-common.h>
42#include <media/v4l2-ioctl.h>
43
44#ifdef CONFIG_VIDEO_V4L1_COMPAT
45/* Include V4L1 specific functions. Should be removed soon */
46#include <linux/videodev.h>
47#endif
48
49#define TUNER_FLAG
50
51#define VIDEO_DEBUG 0
52
53#define dprintk(level, fmt, arg...)\
54 do { if (VIDEO_DEBUG >= level)\
55 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
56 } while (0)
57
58
59//For IOCTL to identify running upstream
60#define UPSTREAM_START_VIDEO 700
61#define UPSTREAM_STOP_VIDEO 701
62#define UPSTREAM_START_AUDIO 702
63#define UPSTREAM_STOP_AUDIO 703
64#define UPSTREAM_DUMP_REGISTERS 702
65#define SET_VIDEO_STD 800
66#define SET_PIXEL_FORMAT 1000
67#define ENABLE_CIF_RESOLUTION 1001
68
69#define REG_READ 900
70#define REG_WRITE 901
71#define MEDUSA_READ 910
72#define MEDUSA_WRITE 911
73
74extern struct sram_channel *channel0;
75extern struct sram_channel *channel1;
76extern struct sram_channel *channel2;
77extern struct sram_channel *channel3;
78extern struct sram_channel *channel4;
79extern struct sram_channel *channel5;
80extern struct sram_channel *channel6;
81extern struct sram_channel *channel7;
82extern struct sram_channel *channel9;
83extern struct sram_channel *channel10;
84extern struct sram_channel *channel11;
85extern struct video_device cx25821_video_template0;
86extern struct video_device cx25821_video_template1;
87extern struct video_device cx25821_video_template2;
88extern struct video_device cx25821_video_template3;
89extern struct video_device cx25821_video_template4;
90extern struct video_device cx25821_video_template5;
91extern struct video_device cx25821_video_template6;
92extern struct video_device cx25821_video_template7;
93extern struct video_device cx25821_video_template9;
94extern struct video_device cx25821_video_template10;
95extern struct video_device cx25821_video_template11;
96extern struct video_device cx25821_videoioctl_template;
97//extern const u32 *ctrl_classes[];
98
99extern unsigned int vid_limit;
100
101#define FORMAT_FLAGS_PACKED 0x01
102extern struct cx25821_fmt formats[];
103extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc);
104extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
105
106extern void dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q);
107extern void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, u32 count);
108
109#ifdef TUNER_FLAG
110extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm);
111#endif
112
113
114extern int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit);
115extern int res_check(struct cx25821_fh *fh, unsigned int bit);
116extern int res_locked(struct cx25821_dev *dev, unsigned int bit);
117extern void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits);
118extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);
119extern int cx25821_start_video_dma(struct cx25821_dev *dev,
120 struct cx25821_dmaqueue *q,
121 struct cx25821_buffer *buf,
122 struct sram_channel *channel);
123
124extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width, unsigned int height, enum v4l2_field field);
125extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);
126extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);
127extern int cx25821_video_register(struct cx25821_dev *dev, int chan_num, struct video_device *video_template);
128extern int get_format_size(void);
129
130extern int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size);
131extern int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field);
132extern void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb);
133extern struct videobuf_queue *get_queue(struct cx25821_fh *fh);
134extern int get_resource(struct cx25821_fh *fh, int resource);
135extern int video_mmap(struct file *file, struct vm_area_struct *vma);
136extern int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
137extern int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap);
138extern int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f);
139extern int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf);
140extern int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p);
141extern int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p);
142extern int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
143extern int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms);
144extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i);
145extern int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i);
146extern int vidioc_g_input(struct file *file, void *priv, unsigned int *i);
147extern int vidioc_s_input(struct file *file, void *priv, unsigned int i);
148extern int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl);
149extern int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
150extern int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f);
151extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f);
152extern int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f);
153extern int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg);
154extern int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg);
155extern int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
156extern int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
157
158extern int is_valid_width(u32 width, v4l2_std_id tvnorm);
159extern int is_valid_height(u32 height, v4l2_std_id tvnorm);
160
161extern int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p);
162extern int vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio);
163
164extern int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qctrl);
165extern int cx25821_set_control(struct cx25821_dev *dev, struct v4l2_control *ctrl, int chan_num);
166
167extern int vidioc_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap);
168extern int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop);
169extern int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop);
170
171extern int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm);
172#endif
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c
new file mode 100644
index 00000000000..9dbd740f1e2
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video0.c
@@ -0,0 +1,457 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH00];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH00]);
50 buf->vb.state = VIDEOBUF_ACTIVE;
51 buf->count = q->count++;
52 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
53 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
54 buf, buf->vb. i, buf->count, q->count);
55 } else {
56 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
57 if (prev->vb.width == buf->vb.width &&
58 prev->vb.height == buf->vb.height &&
59 prev->fmt == buf->fmt) {
60 list_add_tail(&buf->vb.queue, &q->active);
61 buf->vb.state = VIDEOBUF_ACTIVE;
62 buf->count = q->count++;
63 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
64
65 /* 64 bit bits 63-32 */
66 prev->risc.jmp[2] = cpu_to_le32(0);
67 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
68
69 } else {
70 list_add_tail(&buf->vb.queue, &q->queued);
71 buf->vb.state = VIDEOBUF_QUEUED;
72 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
73 }
74 }
75
76 if (list_empty(&q->active))
77 {
78 dprintk(2, "active queue empty!\n");
79 }
80}
81
82
83static struct videobuf_queue_ops cx25821_video_qops = {
84 .buf_setup = buffer_setup,
85 .buf_prepare = buffer_prepare,
86 .buf_queue = buffer_queue,
87 .buf_release = buffer_release,
88};
89
90
91static int video_open(struct file *file)
92{
93 int minor = video_devdata(file)->minor;
94 struct cx25821_dev *h, *dev = NULL;
95 struct cx25821_fh *fh;
96 struct list_head *list;
97 enum v4l2_buf_type type = 0;
98 u32 pix_format;
99
100 lock_kernel();
101 list_for_each(list, &cx25821_devlist)
102 {
103 h = list_entry(list, struct cx25821_dev, devlist);
104
105 if (h->video_dev[SRAM_CH00] && h->video_dev[SRAM_CH00]->minor == minor)
106 {
107 dev = h;
108 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
109 }
110 }
111
112 if (NULL == dev) {
113 unlock_kernel();
114 return -ENODEV;
115 }
116
117 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
118
119 /* allocate + initialize per filehandle data */
120 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
121 if (NULL == fh) {
122 unlock_kernel();
123 return -ENOMEM;
124 }
125
126 file->private_data = fh;
127 fh->dev = dev;
128 fh->type = type;
129 fh->width = 720;
130
131 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
132 fh->height = 576;
133 else
134 fh->height = 480;
135
136 dev->channel_opened = SRAM_CH00;
137 pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
138 fh->fmt = format_by_fourcc(pix_format);
139
140 v4l2_prio_open(&dev->prio,&fh->prio);
141
142 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
143 &dev->pci->dev, &dev->slock,
144 V4L2_BUF_TYPE_VIDEO_CAPTURE,
145 V4L2_FIELD_INTERLACED,
146 sizeof(struct cx25821_buffer),
147 fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
156{
157 struct cx25821_fh *fh = file->private_data;
158
159 switch (fh->type)
160 {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO0))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
166
167 default:
168 BUG();
169 return 0;
170 }
171}
172
173static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
174{
175 struct cx25821_fh *fh = file->private_data;
176 struct cx25821_buffer *buf;
177
178 if (res_check(fh, RESOURCE_VIDEO0)) {
179 /* streaming capture */
180 if (list_empty(&fh->vidq.stream))
181 return POLLERR;
182 buf = list_entry(fh->vidq.stream.next,
183 struct cx25821_buffer, vb.stream);
184 } else {
185 /* read() capture */
186 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
187 if (NULL == buf)
188 return POLLERR;
189 }
190
191 poll_wait(file, &buf->vb.done, wait);
192 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
193 {
194 if( buf->vb.state == VIDEOBUF_DONE )
195 {
196 struct cx25821_dev *dev = fh->dev;
197
198 if( dev && dev->use_cif_resolution[SRAM_CH00] )
199 {
200 u8 cam_id = *((char*)buf->vb.baddr+3);
201 memcpy((char*)buf->vb.baddr, (char*)buf->vb.baddr + (fh->width * 2), (fh->width * 2));
202 *((char*)buf->vb.baddr+3) = cam_id;
203 }
204 }
205
206 return POLLIN|POLLRDNORM;
207 }
208
209 return 0;
210}
211
212
213static int video_release(struct file *file)
214{
215 struct cx25821_fh *fh = file->private_data;
216 struct cx25821_dev *dev = fh->dev;
217
218 //stop the risc engine and fifo
219 cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
220
221 /* stop video capture */
222 if (res_check(fh, RESOURCE_VIDEO0)) {
223 videobuf_queue_cancel(&fh->vidq);
224 res_free(dev, fh, RESOURCE_VIDEO0);
225 }
226
227 if (fh->vidq.read_buf) {
228 buffer_release(&fh->vidq, fh->vidq.read_buf);
229 kfree(fh->vidq.read_buf);
230 }
231
232 videobuf_mmap_free(&fh->vidq);
233
234 v4l2_prio_close(&dev->prio,&fh->prio);
235 file->private_data = NULL;
236 kfree(fh);
237
238 return 0;
239}
240
241
242static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
243{
244 struct cx25821_fh *fh = priv;
245 struct cx25821_dev *dev = fh->dev;
246
247 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
248 {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type))
253 {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO0))))
258 {
259 return -EBUSY;
260 }
261
262 return videobuf_streamon(get_queue(fh));
263}
264
265static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
266{
267 struct cx25821_fh *fh = priv;
268 struct cx25821_dev *dev = fh->dev;
269 int err, res;
270
271 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
272 return -EINVAL;
273 if (i != fh->type)
274 return -EINVAL;
275
276 res = get_resource(fh, RESOURCE_VIDEO0);
277 err = videobuf_streamoff(get_queue(fh));
278 if (err < 0)
279 return err;
280 res_free(dev, fh, res);
281 return 0;
282}
283
284
285static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
286{
287 struct cx25821_fh *fh = priv;
288 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
289 int err;
290 int pix_format = PIXEL_FRMT_422;
291
292 if (fh)
293 {
294 err = v4l2_prio_check(&dev->prio, &fh->prio);
295 if (0 != err)
296 return err;
297 }
298
299 dprintk(2, "%s()\n", __func__);
300 err = vidioc_try_fmt_vid_cap(file, priv, f);
301
302 if (0 != err)
303 return err;
304
305 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
306 fh->vidq.field = f->fmt.pix.field;
307
308 // check if width and height is valid based on set standard
309 if (is_valid_width(f->fmt.pix.width, dev->tvnorm))
310 {
311 fh->width = f->fmt.pix.width;
312 }
313
314 if (is_valid_height(f->fmt.pix.height, dev->tvnorm))
315 {
316 fh->height = f->fmt.pix.height;
317 }
318
319 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
320 pix_format = PIXEL_FRMT_411;
321 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
322 pix_format = PIXEL_FRMT_422;
323 else
324 return -EINVAL;
325
326 cx25821_set_pixel_format( dev, SRAM_CH00, pix_format );
327
328 // check if cif resolution
329 if (fh->width == 320 || fh->width == 352)
330 {
331 dev->use_cif_resolution[SRAM_CH00] = 1;
332 }else
333 {
334 dev->use_cif_resolution[SRAM_CH00] = 0;
335 }
336 dev->cif_width[SRAM_CH00] = fh->width;
337 medusa_set_resolution( dev, fh->width, SRAM_CH00 );
338
339 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
340 cx25821_call_all(dev, video, s_fmt, f);
341
342 return 0;
343}
344
345static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
346{
347 int ret_val = 0;
348 struct cx25821_fh *fh = priv;
349 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
350
351 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
352
353 p->sequence = dev->vidq[SRAM_CH00].count;
354
355 return ret_val;
356}
357
358static int vidioc_log_status (struct file *file, void *priv)
359{
360 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
361 char name[32 + 2];
362
363 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH00];
364 u32 tmp = 0;
365
366 snprintf(name, sizeof(name), "%s/2", dev->name);
367 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
368 dev->name);
369 cx25821_call_all(dev, core, log_status);
370 tmp = cx_read(sram_ch->dma_ctl);
371 printk(KERN_INFO "Video input 0 is %s\n", (tmp & 0x11)?"streaming" : "stopped");
372 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
373 dev->name);
374 return 0;
375}
376
377static int vidioc_s_ctrl(struct file *file, void *priv,
378 struct v4l2_control *ctl)
379{
380 struct cx25821_fh *fh = priv;
381 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
382 int err;
383
384 if (fh) {
385 err = v4l2_prio_check(&dev->prio, &fh->prio);
386 if (0 != err)
387 return err;
388 }
389
390 return cx25821_set_control(dev, ctl, SRAM_CH00);
391}
392
393// exported stuff
394static const struct v4l2_file_operations video_fops = {
395 .owner = THIS_MODULE,
396 .open = video_open,
397 .release = video_release,
398 .read = video_read,
399 .poll = video_poll,
400 .mmap = video_mmap,
401 .ioctl = video_ioctl2,
402};
403
404static const struct v4l2_ioctl_ops video_ioctl_ops = {
405 .vidioc_querycap = vidioc_querycap,
406 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
407 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
408 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
409 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
410 .vidioc_reqbufs = vidioc_reqbufs,
411 .vidioc_querybuf = vidioc_querybuf,
412 .vidioc_qbuf = vidioc_qbuf,
413 .vidioc_dqbuf = vidioc_dqbuf,
414#ifdef TUNER_FLAG
415 .vidioc_s_std = vidioc_s_std,
416 .vidioc_querystd = vidioc_querystd,
417#endif
418 .vidioc_cropcap = vidioc_cropcap,
419 .vidioc_s_crop = vidioc_s_crop,
420 .vidioc_g_crop = vidioc_g_crop,
421 .vidioc_enum_input = vidioc_enum_input,
422 .vidioc_g_input = vidioc_g_input,
423 .vidioc_s_input = vidioc_s_input,
424 .vidioc_g_ctrl = vidioc_g_ctrl,
425 .vidioc_s_ctrl = vidioc_s_ctrl,
426 .vidioc_queryctrl = vidioc_queryctrl,
427 .vidioc_streamon = vidioc_streamon,
428 .vidioc_streamoff = vidioc_streamoff,
429 .vidioc_log_status = vidioc_log_status,
430 .vidioc_g_priority = vidioc_g_priority,
431 .vidioc_s_priority = vidioc_s_priority,
432#ifdef CONFIG_VIDEO_V4L1_COMPAT
433 .vidiocgmbuf = vidiocgmbuf,
434#endif
435#ifdef TUNER_FLAG
436 .vidioc_g_tuner = vidioc_g_tuner,
437 .vidioc_s_tuner = vidioc_s_tuner,
438 .vidioc_g_frequency = vidioc_g_frequency,
439 .vidioc_s_frequency = vidioc_s_frequency,
440#endif
441#ifdef CONFIG_VIDEO_ADV_DEBUG
442 .vidioc_g_register = vidioc_g_register,
443 .vidioc_s_register = vidioc_s_register,
444#endif
445};
446
447struct video_device cx25821_video_template0 = {
448 .name = "cx25821-video",
449 .fops = &video_fops,
450 .minor = -1,
451 .ioctl_ops = &video_ioctl_ops,
452 .tvnorms = CX25821_NORMS,
453 .current_norm = V4L2_STD_NTSC_M,
454};
455
456
457
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c
new file mode 100644
index 00000000000..44db11940ff
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video1.c
@@ -0,0 +1,456 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH01];
34
35
36 /* add jump to stopper */
37 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
38 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
39 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
40
41 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
42
43 if (!list_empty(&q->queued)) {
44 list_add_tail(&buf->vb.queue, &q->queued);
45 buf->vb.state = VIDEOBUF_QUEUED;
46 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH01]);
51 buf->vb.state = VIDEOBUF_ACTIVE;
52 buf->count = q->count++;
53 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
54 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
55 buf, buf->vb. i, buf->count, q->count);
56 } else {
57 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
58 if (prev->vb.width == buf->vb.width &&
59 prev->vb.height == buf->vb.height &&
60 prev->fmt == buf->fmt) {
61 list_add_tail(&buf->vb.queue, &q->active);
62 buf->vb.state = VIDEOBUF_ACTIVE;
63 buf->count = q->count++;
64 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
65
66 /* 64 bit bits 63-32 */
67 prev->risc.jmp[2] = cpu_to_le32(0);
68 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
69
70 } else {
71 list_add_tail(&buf->vb.queue, &q->queued);
72 buf->vb.state = VIDEOBUF_QUEUED;
73 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
74 }
75 }
76
77 if (list_empty(&q->active))
78 {
79 dprintk(2, "active queue empty!\n");
80 }
81}
82
83
84static struct videobuf_queue_ops cx25821_video_qops = {
85 .buf_setup = buffer_setup,
86 .buf_prepare = buffer_prepare,
87 .buf_queue = buffer_queue,
88 .buf_release = buffer_release,
89};
90
91
92static int video_open(struct file *file)
93{
94 int minor = video_devdata(file)->minor;
95 struct cx25821_dev *h, *dev = NULL;
96 struct cx25821_fh *fh;
97 struct list_head *list;
98 enum v4l2_buf_type type = 0;
99 u32 pix_format;
100
101 lock_kernel();
102 list_for_each(list, &cx25821_devlist)
103 {
104 h = list_entry(list, struct cx25821_dev, devlist);
105
106 if (h->video_dev[SRAM_CH01] && h->video_dev[SRAM_CH01]->minor == minor) {
107 dev = h;
108 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
109 }
110 }
111
112 if (NULL == dev) {
113 unlock_kernel();
114 return -ENODEV;
115 }
116
117 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
118
119 /* allocate + initialize per filehandle data */
120 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
121 if (NULL == fh) {
122 unlock_kernel();
123 return -ENOMEM;
124 }
125
126 file->private_data = fh;
127 fh->dev = dev;
128 fh->type = type;
129 fh->width = 720;
130
131 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
132 fh->height = 576;
133 else
134 fh->height = 480;
135
136 dev->channel_opened = SRAM_CH01;
137 pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
138 fh->fmt = format_by_fourcc(pix_format);
139
140 v4l2_prio_open(&dev->prio,&fh->prio);
141
142 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
143 &dev->pci->dev, &dev->slock,
144 V4L2_BUF_TYPE_VIDEO_CAPTURE,
145 V4L2_FIELD_INTERLACED,
146 sizeof(struct cx25821_buffer),
147 fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
156{
157 struct cx25821_fh *fh = file->private_data;
158
159 switch (fh->type)
160 {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO1))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
166
167 default:
168 BUG();
169 return 0;
170 }
171}
172
173static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
174{
175 struct cx25821_fh *fh = file->private_data;
176 struct cx25821_buffer *buf;
177
178 if (res_check(fh, RESOURCE_VIDEO1)) {
179 /* streaming capture */
180 if (list_empty(&fh->vidq.stream))
181 return POLLERR;
182 buf = list_entry(fh->vidq.stream.next,
183 struct cx25821_buffer, vb.stream);
184 } else {
185 /* read() capture */
186 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
187 if (NULL == buf)
188 return POLLERR;
189 }
190
191 poll_wait(file, &buf->vb.done, wait);
192 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
193 {
194 if( buf->vb.state == VIDEOBUF_DONE )
195 {
196 struct cx25821_dev *dev = fh->dev;
197
198 if( dev && dev->use_cif_resolution[SRAM_CH01] )
199 {
200 u8 cam_id = *((char*)buf->vb.baddr+3);
201 memcpy((char*)buf->vb.baddr, (char*)buf->vb.baddr + (fh->width * 2), (fh->width * 2));
202 *((char*)buf->vb.baddr+3) = cam_id;
203 }
204 }
205
206 return POLLIN|POLLRDNORM;
207 }
208
209 return 0;
210}
211
212static int video_release(struct file *file)
213{
214 struct cx25821_fh *fh = file->private_data;
215 struct cx25821_dev *dev = fh->dev;
216
217 //stop the risc engine and fifo
218 cx_write(channel1->dma_ctl, 0); /* FIFO and RISC disable */
219
220 /* stop video capture */
221 if (res_check(fh, RESOURCE_VIDEO1)) {
222 videobuf_queue_cancel(&fh->vidq);
223 res_free(dev, fh, RESOURCE_VIDEO1);
224 }
225
226 if (fh->vidq.read_buf) {
227 buffer_release(&fh->vidq, fh->vidq.read_buf);
228 kfree(fh->vidq.read_buf);
229 }
230
231 videobuf_mmap_free(&fh->vidq);
232
233 v4l2_prio_close(&dev->prio,&fh->prio);
234 file->private_data = NULL;
235 kfree(fh);
236
237 return 0;
238}
239
240
241static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
242{
243 struct cx25821_fh *fh = priv;
244 struct cx25821_dev *dev = fh->dev;
245
246 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
247 {
248 return -EINVAL;
249 }
250
251 if (unlikely(i != fh->type))
252 {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO1))))
257 {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO1);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283
284
285static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
286{
287 struct cx25821_fh *fh = priv;
288 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
289 int err;
290 int pix_format = 0;
291
292 if (fh)
293 {
294 err = v4l2_prio_check(&dev->prio, &fh->prio);
295 if (0 != err)
296 return err;
297 }
298
299 dprintk(2, "%s()\n", __func__);
300 err = vidioc_try_fmt_vid_cap(file, priv, f);
301
302 if (0 != err)
303 return err;
304
305 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
306 fh->vidq.field = f->fmt.pix.field;
307
308 // check if width and height is valid based on set standard
309 if (is_valid_width(f->fmt.pix.width, dev->tvnorm))
310 {
311 fh->width = f->fmt.pix.width;
312 }
313
314 if (is_valid_height(f->fmt.pix.height, dev->tvnorm))
315 {
316 fh->height = f->fmt.pix.height;
317 }
318
319 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
320 pix_format = PIXEL_FRMT_411;
321 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
322 pix_format = PIXEL_FRMT_422;
323 else
324 return -EINVAL;
325
326 cx25821_set_pixel_format( dev, SRAM_CH01, pix_format );
327
328 // check if cif resolution
329 if (fh->width == 320 || fh->width == 352)
330 {
331 dev->use_cif_resolution[SRAM_CH01] = 1;
332 }else
333 {
334 dev->use_cif_resolution[SRAM_CH01] = 0;
335 }
336 dev->cif_width[SRAM_CH01] = fh->width;
337 medusa_set_resolution( dev, fh->width, SRAM_CH01 );
338
339 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
340 cx25821_call_all(dev, video, s_fmt, f);
341
342 return 0;
343}
344
345static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
346{
347 int ret_val = 0;
348 struct cx25821_fh *fh = priv;
349 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
350
351 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
352
353 p->sequence = dev->vidq[SRAM_CH01].count;
354
355 return ret_val;
356}
357
358static int vidioc_log_status (struct file *file, void *priv)
359{
360 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
361 char name[32 + 2];
362
363 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH01];
364 u32 tmp = 0;
365
366 snprintf(name, sizeof(name), "%s/2", dev->name);
367 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
368 dev->name);
369 cx25821_call_all(dev, core, log_status);
370 tmp = cx_read(sram_ch->dma_ctl);
371 printk(KERN_INFO "Video input 1 is %s\n", (tmp & 0x11)?"streaming" : "stopped");
372 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
373 dev->name);
374 return 0;
375}
376
377static int vidioc_s_ctrl(struct file *file, void *priv,
378 struct v4l2_control *ctl)
379{
380 struct cx25821_fh *fh = priv;
381 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
382 int err;
383
384 if (fh) {
385 err = v4l2_prio_check(&dev->prio, &fh->prio);
386 if (0 != err)
387 return err;
388 }
389
390 return cx25821_set_control(dev, ctl, SRAM_CH01);
391}
392//exported stuff
393static const struct v4l2_file_operations video_fops = {
394 .owner = THIS_MODULE,
395 .open = video_open,
396 .release = video_release,
397 .read = video_read,
398 .poll = video_poll,
399 .mmap = video_mmap,
400 .ioctl = video_ioctl2,
401};
402
403static const struct v4l2_ioctl_ops video_ioctl_ops = {
404 .vidioc_querycap = vidioc_querycap,
405 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
406 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
407 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
408 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
409 .vidioc_reqbufs = vidioc_reqbufs,
410 .vidioc_querybuf = vidioc_querybuf,
411 .vidioc_qbuf = vidioc_qbuf,
412 .vidioc_dqbuf = vidioc_dqbuf,
413#ifdef TUNER_FLAG
414 .vidioc_s_std = vidioc_s_std,
415 .vidioc_querystd = vidioc_querystd,
416#endif
417 .vidioc_cropcap = vidioc_cropcap,
418 .vidioc_s_crop = vidioc_s_crop,
419 .vidioc_g_crop = vidioc_g_crop,
420 .vidioc_enum_input = vidioc_enum_input,
421 .vidioc_g_input = vidioc_g_input,
422 .vidioc_s_input = vidioc_s_input,
423 .vidioc_g_ctrl = vidioc_g_ctrl,
424 .vidioc_s_ctrl = vidioc_s_ctrl,
425 .vidioc_queryctrl = vidioc_queryctrl,
426 .vidioc_streamon = vidioc_streamon,
427 .vidioc_streamoff = vidioc_streamoff,
428 .vidioc_log_status = vidioc_log_status,
429 .vidioc_g_priority = vidioc_g_priority,
430 .vidioc_s_priority = vidioc_s_priority,
431#ifdef CONFIG_VIDEO_V4L1_COMPAT
432 .vidiocgmbuf = vidiocgmbuf,
433#endif
434#ifdef TUNER_FLAG
435 .vidioc_g_tuner = vidioc_g_tuner,
436 .vidioc_s_tuner = vidioc_s_tuner,
437 .vidioc_g_frequency = vidioc_g_frequency,
438 .vidioc_s_frequency = vidioc_s_frequency,
439#endif
440#ifdef CONFIG_VIDEO_ADV_DEBUG
441 .vidioc_g_register = vidioc_g_register,
442 .vidioc_s_register = vidioc_s_register,
443#endif
444};
445
446struct video_device cx25821_video_template1 = {
447 .name = "cx25821-video",
448 .fops = &video_fops,
449 .minor = -1,
450 .ioctl_ops = &video_ioctl_ops,
451 .tvnorms = CX25821_NORMS,
452 .current_norm = V4L2_STD_NTSC_M,
453};
454
455
456
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c
new file mode 100644
index 00000000000..98db1488dcf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video2.c
@@ -0,0 +1,459 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH02];
34
35
36 /* add jump to stopper */
37 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
38 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
39 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
40
41 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
42
43 if (!list_empty(&q->queued)) {
44 list_add_tail(&buf->vb.queue, &q->queued);
45 buf->vb.state = VIDEOBUF_QUEUED;
46 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH02]);
51 buf->vb.state = VIDEOBUF_ACTIVE;
52 buf->count = q->count++;
53 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
54 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
55 buf, buf->vb. i, buf->count, q->count);
56 } else {
57 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
58 if (prev->vb.width == buf->vb.width &&
59 prev->vb.height == buf->vb.height &&
60 prev->fmt == buf->fmt) {
61 list_add_tail(&buf->vb.queue, &q->active);
62 buf->vb.state = VIDEOBUF_ACTIVE;
63 buf->count = q->count++;
64 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
65
66 /* 64 bit bits 63-32 */
67 prev->risc.jmp[2] = cpu_to_le32(0);
68 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
69
70 } else {
71 list_add_tail(&buf->vb.queue, &q->queued);
72 buf->vb.state = VIDEOBUF_QUEUED;
73 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
74 }
75 }
76
77 if (list_empty(&q->active))
78 {
79 dprintk(2, "active queue empty!\n");
80 }
81}
82
83
84static struct videobuf_queue_ops cx25821_video_qops = {
85 .buf_setup = buffer_setup,
86 .buf_prepare = buffer_prepare,
87 .buf_queue = buffer_queue,
88 .buf_release = buffer_release,
89};
90
91
92static int video_open(struct file *file)
93{
94 int minor = video_devdata(file)->minor;
95 struct cx25821_dev *h, *dev = NULL;
96 struct cx25821_fh *fh;
97 struct list_head *list;
98 enum v4l2_buf_type type = 0;
99 u32 pix_format;
100
101 lock_kernel();
102 list_for_each(list, &cx25821_devlist)
103 {
104 h = list_entry(list, struct cx25821_dev, devlist);
105
106 if (h->video_dev[SRAM_CH02] && h->video_dev[SRAM_CH02]->minor == minor) {
107 dev = h;
108 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
109 }
110 }
111
112 if (NULL == dev) {
113 unlock_kernel();
114 return -ENODEV;
115 }
116
117 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
118
119 /* allocate + initialize per filehandle data */
120 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
121 if (NULL == fh) {
122 unlock_kernel();
123 return -ENOMEM;
124 }
125 file->private_data = fh;
126 fh->dev = dev;
127 fh->type = type;
128 fh->width = 720;
129
130 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
131 fh->height = 576;
132 else
133 fh->height = 480;
134
135 dev->channel_opened = SRAM_CH02;
136 pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
137 fh->fmt = format_by_fourcc(pix_format);
138
139 v4l2_prio_open(&dev->prio,&fh->prio);
140
141 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
142 &dev->pci->dev, &dev->slock,
143 V4L2_BUF_TYPE_VIDEO_CAPTURE,
144 V4L2_FIELD_INTERLACED,
145 sizeof(struct cx25821_buffer),
146 fh);
147
148 dprintk(1, "post videobuf_queue_init()\n");
149 unlock_kernel();
150
151 return 0;
152}
153
154static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
155{
156 struct cx25821_fh *fh = file->private_data;
157
158 switch (fh->type)
159 {
160 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
161 if (res_locked(fh->dev, RESOURCE_VIDEO2))
162 return -EBUSY;
163
164 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
165
166 default:
167 BUG();
168 return 0;
169 }
170}
171
172static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
173{
174 struct cx25821_fh *fh = file->private_data;
175 struct cx25821_buffer *buf;
176
177 if (res_check(fh, RESOURCE_VIDEO2)) {
178 /* streaming capture */
179 if (list_empty(&fh->vidq.stream))
180 return POLLERR;
181 buf = list_entry(fh->vidq.stream.next,
182 struct cx25821_buffer, vb.stream);
183 } else {
184 /* read() capture */
185 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
186 if (NULL == buf)
187 return POLLERR;
188 }
189
190 poll_wait(file, &buf->vb.done, wait);
191 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
192 {
193 if( buf->vb.state == VIDEOBUF_DONE )
194 {
195 struct cx25821_dev *dev = fh->dev;
196
197 if( dev && dev->use_cif_resolution[SRAM_CH02] )
198 {
199 u8 cam_id = *((char*)buf->vb.baddr+3);
200 memcpy((char*)buf->vb.baddr, (char*)buf->vb.baddr + (fh->width * 2), (fh->width * 2));
201 *((char*)buf->vb.baddr+3) = cam_id;
202 }
203 }
204
205 return POLLIN|POLLRDNORM;
206 }
207
208 return 0;
209}
210
211
212static int video_release(struct file *file)
213{
214 struct cx25821_fh *fh = file->private_data;
215 struct cx25821_dev *dev = fh->dev;
216
217 //stop the risc engine and fifo
218 cx_write(channel2->dma_ctl, 0); /* FIFO and RISC disable */
219
220 /* stop video capture */
221 if (res_check(fh, RESOURCE_VIDEO2)) {
222 videobuf_queue_cancel(&fh->vidq);
223 res_free(dev, fh, RESOURCE_VIDEO2);
224 }
225
226 if (fh->vidq.read_buf) {
227 buffer_release(&fh->vidq, fh->vidq.read_buf);
228 kfree(fh->vidq.read_buf);
229 }
230
231 videobuf_mmap_free(&fh->vidq);
232
233 v4l2_prio_close(&dev->prio,&fh->prio);
234 file->private_data = NULL;
235 kfree(fh);
236
237 return 0;
238}
239
240
241static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
242{
243 struct cx25821_fh *fh = priv;
244 struct cx25821_dev *dev = fh->dev;
245
246 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
247 {
248 return -EINVAL;
249 }
250
251 if (unlikely(i != fh->type))
252 {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO2))))
257 {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO2);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283
284
285static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
286{
287 struct cx25821_fh *fh = priv;
288 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
289 int err;
290 int pix_format = 0;
291
292 if (fh)
293 {
294 err = v4l2_prio_check(&dev->prio, &fh->prio);
295 if (0 != err)
296 return err;
297 }
298
299 dprintk(2, "%s()\n", __func__);
300 err = vidioc_try_fmt_vid_cap(file, priv, f);
301
302 if (0 != err)
303 return err;
304
305 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
306 fh->vidq.field = f->fmt.pix.field;
307
308 // check if width and height is valid based on set standard
309 if (is_valid_width(f->fmt.pix.width, dev->tvnorm))
310 {
311 fh->width = f->fmt.pix.width;
312 }
313
314 if (is_valid_height(f->fmt.pix.height, dev->tvnorm))
315 {
316 fh->height = f->fmt.pix.height;
317 }
318
319 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
320 pix_format = PIXEL_FRMT_411;
321 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
322 pix_format = PIXEL_FRMT_422;
323 else
324 return -EINVAL;
325
326 cx25821_set_pixel_format( dev, SRAM_CH02, pix_format );
327
328 // check if cif resolution
329 if (fh->width == 320 || fh->width == 352)
330 {
331 dev->use_cif_resolution[SRAM_CH02] = 1;
332 }else
333 {
334 dev->use_cif_resolution[SRAM_CH02] = 0;
335 }
336 dev->cif_width[SRAM_CH02] = fh->width;
337 medusa_set_resolution( dev, fh->width, SRAM_CH02 );
338
339
340 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
341 cx25821_call_all(dev, video, s_fmt, f);
342
343 return 0;
344}
345
346static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
347{
348 int ret_val = 0;
349 struct cx25821_fh *fh = priv;
350 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
351
352 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
353
354 p->sequence = dev->vidq[SRAM_CH02].count;
355
356 return ret_val;
357}
358
359static int vidioc_log_status (struct file *file, void *priv)
360{
361 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
362 char name[32 + 2];
363
364 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH02];
365 u32 tmp = 0;
366
367 snprintf(name, sizeof(name), "%s/2", dev->name);
368 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
369 dev->name);
370
371 cx25821_call_all(dev, core, log_status);
372
373 tmp = cx_read(sram_ch->dma_ctl);
374 printk(KERN_INFO "Video input 2 is %s\n", (tmp & 0x11)?"streaming" : "stopped");
375 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
376 dev->name);
377 return 0;
378}
379
380static int vidioc_s_ctrl(struct file *file, void *priv,
381 struct v4l2_control *ctl)
382{
383 struct cx25821_fh *fh = priv;
384 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
385 int err;
386
387 if (fh) {
388 err = v4l2_prio_check(&dev->prio, &fh->prio);
389 if (0 != err)
390 return err;
391 }
392
393 return cx25821_set_control(dev, ctl, SRAM_CH02);
394}
395// exported stuff
396static const struct v4l2_file_operations video_fops = {
397 .owner = THIS_MODULE,
398 .open = video_open,
399 .release = video_release,
400 .read = video_read,
401 .poll = video_poll,
402 .mmap = video_mmap,
403 .ioctl = video_ioctl2,
404};
405
406static const struct v4l2_ioctl_ops video_ioctl_ops = {
407 .vidioc_querycap = vidioc_querycap,
408 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
409 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
410 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
411 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
412 .vidioc_reqbufs = vidioc_reqbufs,
413 .vidioc_querybuf = vidioc_querybuf,
414 .vidioc_qbuf = vidioc_qbuf,
415 .vidioc_dqbuf = vidioc_dqbuf,
416#ifdef TUNER_FLAG
417 .vidioc_s_std = vidioc_s_std,
418 .vidioc_querystd = vidioc_querystd,
419#endif
420 .vidioc_cropcap = vidioc_cropcap,
421 .vidioc_s_crop = vidioc_s_crop,
422 .vidioc_g_crop = vidioc_g_crop,
423 .vidioc_enum_input = vidioc_enum_input,
424 .vidioc_g_input = vidioc_g_input,
425 .vidioc_s_input = vidioc_s_input,
426 .vidioc_g_ctrl = vidioc_g_ctrl,
427 .vidioc_s_ctrl = vidioc_s_ctrl,
428 .vidioc_queryctrl = vidioc_queryctrl,
429 .vidioc_streamon = vidioc_streamon,
430 .vidioc_streamoff = vidioc_streamoff,
431 .vidioc_log_status = vidioc_log_status,
432 .vidioc_g_priority = vidioc_g_priority,
433 .vidioc_s_priority = vidioc_s_priority,
434#ifdef CONFIG_VIDEO_V4L1_COMPAT
435 .vidiocgmbuf = vidiocgmbuf,
436#endif
437#ifdef TUNER_FLAG
438 .vidioc_g_tuner = vidioc_g_tuner,
439 .vidioc_s_tuner = vidioc_s_tuner,
440 .vidioc_g_frequency = vidioc_g_frequency,
441 .vidioc_s_frequency = vidioc_s_frequency,
442#endif
443#ifdef CONFIG_VIDEO_ADV_DEBUG
444 .vidioc_g_register = vidioc_g_register,
445 .vidioc_s_register = vidioc_s_register,
446#endif
447};
448
449struct video_device cx25821_video_template2 = {
450 .name = "cx25821-video",
451 .fops = &video_fops,
452 .minor = -1,
453 .ioctl_ops = &video_ioctl_ops,
454 .tvnorms = CX25821_NORMS,
455 .current_norm = V4L2_STD_NTSC_M,
456};
457
458
459
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c
new file mode 100644
index 00000000000..3dcecd26466
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video3.c
@@ -0,0 +1,458 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH03];
34
35
36 /* add jump to stopper */
37 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
38 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
39 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
40
41 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
42
43 if (!list_empty(&q->queued)) {
44 list_add_tail(&buf->vb.queue, &q->queued);
45 buf->vb.state = VIDEOBUF_QUEUED;
46 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH03]);
51 buf->vb.state = VIDEOBUF_ACTIVE;
52 buf->count = q->count++;
53 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
54 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
55 buf, buf->vb. i, buf->count, q->count);
56 } else {
57 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
58 if (prev->vb.width == buf->vb.width &&
59 prev->vb.height == buf->vb.height &&
60 prev->fmt == buf->fmt) {
61 list_add_tail(&buf->vb.queue, &q->active);
62 buf->vb.state = VIDEOBUF_ACTIVE;
63 buf->count = q->count++;
64 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
65
66 /* 64 bit bits 63-32 */
67 prev->risc.jmp[2] = cpu_to_le32(0);
68 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
69
70 } else {
71 list_add_tail(&buf->vb.queue, &q->queued);
72 buf->vb.state = VIDEOBUF_QUEUED;
73 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
74 }
75 }
76
77 if (list_empty(&q->active))
78 {
79 dprintk(2, "active queue empty!\n");
80 }
81}
82
83
84static struct videobuf_queue_ops cx25821_video_qops = {
85 .buf_setup = buffer_setup,
86 .buf_prepare = buffer_prepare,
87 .buf_queue = buffer_queue,
88 .buf_release = buffer_release,
89};
90
91
92static int video_open(struct file *file)
93{
94 int minor = video_devdata(file)->minor;
95 struct cx25821_dev *h, *dev = NULL;
96 struct cx25821_fh *fh;
97 struct list_head *list;
98 enum v4l2_buf_type type = 0;
99 u32 pix_format;
100
101 lock_kernel();
102 list_for_each(list, &cx25821_devlist)
103 {
104 h = list_entry(list, struct cx25821_dev, devlist);
105
106 if (h->video_dev[SRAM_CH03] && h->video_dev[SRAM_CH03]->minor == minor) {
107 dev = h;
108 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
109 }
110 }
111
112 if (NULL == dev) {
113 unlock_kernel();
114 return -ENODEV;
115 }
116
117 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
118
119 /* allocate + initialize per filehandle data */
120 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
121 if (NULL == fh) {
122 unlock_kernel();
123 return -ENOMEM;
124 }
125 file->private_data = fh;
126 fh->dev = dev;
127 fh->type = type;
128 fh->width = 720;
129
130 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
131 fh->height = 576;
132 else
133 fh->height = 480;
134
135 dev->channel_opened = SRAM_CH03;
136 pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
137 fh->fmt = format_by_fourcc(pix_format);
138
139 v4l2_prio_open(&dev->prio,&fh->prio);
140
141 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
142 &dev->pci->dev, &dev->slock,
143 V4L2_BUF_TYPE_VIDEO_CAPTURE,
144 V4L2_FIELD_INTERLACED,
145 sizeof(struct cx25821_buffer),
146 fh);
147
148 dprintk(1, "post videobuf_queue_init()\n");
149 unlock_kernel();
150
151 return 0;
152}
153
154static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
155{
156 struct cx25821_fh *fh = file->private_data;
157
158 switch (fh->type)
159 {
160 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
161 if (res_locked(fh->dev, RESOURCE_VIDEO3))
162 return -EBUSY;
163
164 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
165
166 default:
167 BUG();
168 return 0;
169 }
170}
171
172static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
173{
174 struct cx25821_fh *fh = file->private_data;
175 struct cx25821_buffer *buf;
176
177 if (res_check(fh, RESOURCE_VIDEO3)) {
178 /* streaming capture */
179 if (list_empty(&fh->vidq.stream))
180 return POLLERR;
181 buf = list_entry(fh->vidq.stream.next,
182 struct cx25821_buffer, vb.stream);
183 } else {
184 /* read() capture */
185 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
186 if (NULL == buf)
187 return POLLERR;
188 }
189
190 poll_wait(file, &buf->vb.done, wait);
191 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
192 {
193 if( buf->vb.state == VIDEOBUF_DONE )
194 {
195 struct cx25821_dev *dev = fh->dev;
196
197 if( dev && dev->use_cif_resolution[SRAM_CH03] )
198 {
199 u8 cam_id = *((char*)buf->vb.baddr+3);
200 memcpy((char*)buf->vb.baddr, (char*)buf->vb.baddr + (fh->width * 2), (fh->width * 2));
201 *((char*)buf->vb.baddr+3) = cam_id;
202 }
203 }
204
205 return POLLIN|POLLRDNORM;
206 }
207
208 return 0;
209}
210
211
212static int video_release(struct file *file)
213{
214 struct cx25821_fh *fh = file->private_data;
215 struct cx25821_dev *dev = fh->dev;
216
217 //stop the risc engine and fifo
218 cx_write(channel3->dma_ctl, 0); /* FIFO and RISC disable */
219
220 /* stop video capture */
221 if (res_check(fh, RESOURCE_VIDEO3)) {
222 videobuf_queue_cancel(&fh->vidq);
223 res_free(dev, fh, RESOURCE_VIDEO3);
224 }
225
226 if (fh->vidq.read_buf) {
227 buffer_release(&fh->vidq, fh->vidq.read_buf);
228 kfree(fh->vidq.read_buf);
229 }
230
231 videobuf_mmap_free(&fh->vidq);
232
233 v4l2_prio_close(&dev->prio,&fh->prio);
234 file->private_data = NULL;
235 kfree(fh);
236
237 return 0;
238}
239
240
241static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
242{
243 struct cx25821_fh *fh = priv;
244 struct cx25821_dev *dev = fh->dev;
245
246 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
247 {
248 return -EINVAL;
249 }
250
251 if (unlikely(i != fh->type))
252 {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO3))))
257 {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO3);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283
284
285static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
286{
287 struct cx25821_fh *fh = priv;
288 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
289 int err;
290 int pix_format = 0;
291
292 if (fh)
293 {
294 err = v4l2_prio_check(&dev->prio, &fh->prio);
295 if (0 != err)
296 return err;
297 }
298
299 dprintk(2, "%s()\n", __func__);
300 err = vidioc_try_fmt_vid_cap(file, priv, f);
301
302 if (0 != err)
303 return err;
304
305 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
306 fh->vidq.field = f->fmt.pix.field;
307
308 // check if width and height is valid based on set standard
309 if (is_valid_width(f->fmt.pix.width, dev->tvnorm))
310 {
311 fh->width = f->fmt.pix.width;
312 }
313
314 if (is_valid_height(f->fmt.pix.height, dev->tvnorm))
315 {
316 fh->height = f->fmt.pix.height;
317 }
318
319 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
320 pix_format = PIXEL_FRMT_411;
321 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
322 pix_format = PIXEL_FRMT_422;
323 else
324 return -EINVAL;
325
326 cx25821_set_pixel_format( dev, SRAM_CH03, pix_format );
327
328 // check if cif resolution
329 if (fh->width == 320 || fh->width == 352)
330 {
331 dev->use_cif_resolution[SRAM_CH03] = 1;
332 }else
333 {
334 dev->use_cif_resolution[SRAM_CH03] = 0;
335 }
336 dev->cif_width[SRAM_CH03] = fh->width;
337 medusa_set_resolution( dev, fh->width, SRAM_CH03 );
338
339 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
340 cx25821_call_all(dev, video, s_fmt, f);
341
342 return 0;
343}
344
345static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
346{
347 int ret_val = 0;
348 struct cx25821_fh *fh = priv;
349 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
350
351 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
352
353 p->sequence = dev->vidq[SRAM_CH03].count;
354
355 return ret_val;
356}
357
358static int vidioc_log_status (struct file *file, void *priv)
359{
360 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
361 char name[32 + 2];
362
363 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH03];
364 u32 tmp = 0;
365
366 snprintf(name, sizeof(name), "%s/2", dev->name);
367 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
368 dev->name);
369 cx25821_call_all(dev, core, log_status);
370
371 tmp = cx_read(sram_ch->dma_ctl);
372 printk(KERN_INFO "Video input 3 is %s\n", (tmp & 0x11)?"streaming" : "stopped");
373 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
374 dev->name);
375 return 0;
376}
377
378static int vidioc_s_ctrl(struct file *file, void *priv,
379 struct v4l2_control *ctl)
380{
381 struct cx25821_fh *fh = priv;
382 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
383 int err;
384
385 if (fh) {
386 err = v4l2_prio_check(&dev->prio, &fh->prio);
387 if (0 != err)
388 return err;
389 }
390
391 return cx25821_set_control(dev, ctl, SRAM_CH03);
392}
393
394// exported stuff
395static const struct v4l2_file_operations video_fops = {
396 .owner = THIS_MODULE,
397 .open = video_open,
398 .release = video_release,
399 .read = video_read,
400 .poll = video_poll,
401 .mmap = video_mmap,
402 .ioctl = video_ioctl2,
403};
404
405static const struct v4l2_ioctl_ops video_ioctl_ops = {
406 .vidioc_querycap = vidioc_querycap,
407 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
408 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
409 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
410 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
411 .vidioc_reqbufs = vidioc_reqbufs,
412 .vidioc_querybuf = vidioc_querybuf,
413 .vidioc_qbuf = vidioc_qbuf,
414 .vidioc_dqbuf = vidioc_dqbuf,
415#ifdef TUNER_FLAG
416 .vidioc_s_std = vidioc_s_std,
417 .vidioc_querystd = vidioc_querystd,
418#endif
419 .vidioc_cropcap = vidioc_cropcap,
420 .vidioc_s_crop = vidioc_s_crop,
421 .vidioc_g_crop = vidioc_g_crop,
422 .vidioc_enum_input = vidioc_enum_input,
423 .vidioc_g_input = vidioc_g_input,
424 .vidioc_s_input = vidioc_s_input,
425 .vidioc_g_ctrl = vidioc_g_ctrl,
426 .vidioc_s_ctrl = vidioc_s_ctrl,
427 .vidioc_queryctrl = vidioc_queryctrl,
428 .vidioc_streamon = vidioc_streamon,
429 .vidioc_streamoff = vidioc_streamoff,
430 .vidioc_log_status = vidioc_log_status,
431 .vidioc_g_priority = vidioc_g_priority,
432 .vidioc_s_priority = vidioc_s_priority,
433#ifdef CONFIG_VIDEO_V4L1_COMPAT
434 .vidiocgmbuf = vidiocgmbuf,
435#endif
436#ifdef TUNER_FLAG
437 .vidioc_g_tuner = vidioc_g_tuner,
438 .vidioc_s_tuner = vidioc_s_tuner,
439 .vidioc_g_frequency = vidioc_g_frequency,
440 .vidioc_s_frequency = vidioc_s_frequency,
441#endif
442#ifdef CONFIG_VIDEO_ADV_DEBUG
443 .vidioc_g_register = vidioc_g_register,
444 .vidioc_s_register = vidioc_s_register,
445#endif
446};
447
448struct video_device cx25821_video_template3 = {
449 .name = "cx25821-video",
450 .fops = &video_fops,
451 .minor = -1,
452 .ioctl_ops = &video_ioctl_ops,
453 .tvnorms = CX25821_NORMS,
454 .current_norm = V4L2_STD_NTSC_M,
455};
456
457
458
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c
new file mode 100644
index 00000000000..03da3642cc3
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video4.c
@@ -0,0 +1,456 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH04];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH04]);
50 buf->vb.state = VIDEOBUF_ACTIVE;
51 buf->count = q->count++;
52 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
53 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
54 buf, buf->vb. i, buf->count, q->count);
55 } else {
56 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
57 if (prev->vb.width == buf->vb.width &&
58 prev->vb.height == buf->vb.height &&
59 prev->fmt == buf->fmt) {
60 list_add_tail(&buf->vb.queue, &q->active);
61 buf->vb.state = VIDEOBUF_ACTIVE;
62 buf->count = q->count++;
63 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
64
65 /* 64 bit bits 63-32 */
66 prev->risc.jmp[2] = cpu_to_le32(0);
67 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
68
69 } else {
70 list_add_tail(&buf->vb.queue, &q->queued);
71 buf->vb.state = VIDEOBUF_QUEUED;
72 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
73 }
74 }
75
76 if (list_empty(&q->active))
77 {
78 dprintk(2, "active queue empty!\n");
79 }
80}
81
82
83static struct videobuf_queue_ops cx25821_video_qops = {
84 .buf_setup = buffer_setup,
85 .buf_prepare = buffer_prepare,
86 .buf_queue = buffer_queue,
87 .buf_release = buffer_release,
88};
89
90
91static int video_open(struct file *file)
92{
93 int minor = video_devdata(file)->minor;
94 struct cx25821_dev *h, *dev = NULL;
95 struct cx25821_fh *fh;
96 struct list_head *list;
97 enum v4l2_buf_type type = 0;
98 u32 pix_format;
99
100 lock_kernel();
101 list_for_each(list, &cx25821_devlist)
102 {
103 h = list_entry(list, struct cx25821_dev, devlist);
104
105 if (h->video_dev[SRAM_CH04] && h->video_dev[SRAM_CH04]->minor == minor) {
106 dev = h;
107 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
108 }
109 }
110
111 if (NULL == dev) {
112 unlock_kernel();
113 return -ENODEV;
114 }
115
116 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
117
118 /* allocate + initialize per filehandle data */
119 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
120 if (NULL == fh) {
121 unlock_kernel();
122 return -ENOMEM;
123 }
124 file->private_data = fh;
125 fh->dev = dev;
126 fh->type = type;
127 fh->width = 720;
128
129 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
130 fh->height = 576;
131 else
132 fh->height = 480;
133
134 dev->channel_opened = SRAM_CH04;
135 pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
136 fh->fmt = format_by_fourcc(pix_format);
137
138 v4l2_prio_open(&dev->prio,&fh->prio);
139 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
140 &dev->pci->dev, &dev->slock,
141 V4L2_BUF_TYPE_VIDEO_CAPTURE,
142 V4L2_FIELD_INTERLACED,
143 sizeof(struct cx25821_buffer),
144 fh);
145
146 dprintk(1, "post videobuf_queue_init()\n");
147 unlock_kernel();
148
149 return 0;
150}
151
152static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
153{
154 struct cx25821_fh *fh = file->private_data;
155
156 switch (fh->type)
157 {
158 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
159 if (res_locked(fh->dev, RESOURCE_VIDEO4))
160 return -EBUSY;
161
162 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
163
164 default:
165 BUG();
166 return 0;
167 }
168}
169
170static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
171{
172 struct cx25821_fh *fh = file->private_data;
173 struct cx25821_buffer *buf;
174
175 if (res_check(fh, RESOURCE_VIDEO4)) {
176 /* streaming capture */
177 if (list_empty(&fh->vidq.stream))
178 return POLLERR;
179 buf = list_entry(fh->vidq.stream.next,
180 struct cx25821_buffer, vb.stream);
181 } else {
182 /* read() capture */
183 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
184 if (NULL == buf)
185 return POLLERR;
186 }
187
188 poll_wait(file, &buf->vb.done, wait);
189 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
190 {
191 if( buf->vb.state == VIDEOBUF_DONE )
192 {
193 struct cx25821_dev *dev = fh->dev;
194
195 if( dev && dev->use_cif_resolution[SRAM_CH04] )
196 {
197 u8 cam_id = *((char*)buf->vb.baddr+3);
198 memcpy((char*)buf->vb.baddr, (char*)buf->vb.baddr + (fh->width * 2), (fh->width * 2));
199 *((char*)buf->vb.baddr+3) = cam_id;
200 }
201 }
202
203 return POLLIN|POLLRDNORM;
204 }
205
206 return 0;
207}
208
209
210static int video_release(struct file *file)
211{
212 struct cx25821_fh *fh = file->private_data;
213 struct cx25821_dev *dev = fh->dev;
214
215 //stop the risc engine and fifo
216 cx_write(channel4->dma_ctl, 0); /* FIFO and RISC disable */
217
218 /* stop video capture */
219 if (res_check(fh, RESOURCE_VIDEO4)) {
220 videobuf_queue_cancel(&fh->vidq);
221 res_free(dev, fh, RESOURCE_VIDEO4);
222 }
223
224 if (fh->vidq.read_buf) {
225 buffer_release(&fh->vidq, fh->vidq.read_buf);
226 kfree(fh->vidq.read_buf);
227 }
228
229 videobuf_mmap_free(&fh->vidq);
230
231 v4l2_prio_close(&dev->prio,&fh->prio);
232 file->private_data = NULL;
233 kfree(fh);
234
235 return 0;
236}
237
238
239static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
240{
241 struct cx25821_fh *fh = priv;
242 struct cx25821_dev *dev = fh->dev;
243
244 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
245 {
246 return -EINVAL;
247 }
248
249 if (unlikely(i != fh->type))
250 {
251 return -EINVAL;
252 }
253
254 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO4))))
255 {
256 return -EBUSY;
257 }
258
259 return videobuf_streamon(get_queue(fh));
260}
261
262static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
263{
264 struct cx25821_fh *fh = priv;
265 struct cx25821_dev *dev = fh->dev;
266 int err, res;
267
268 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
269 return -EINVAL;
270 if (i != fh->type)
271 return -EINVAL;
272
273 res = get_resource(fh, RESOURCE_VIDEO4);
274 err = videobuf_streamoff(get_queue(fh));
275 if (err < 0)
276 return err;
277 res_free(dev, fh, res);
278 return 0;
279}
280
281
282
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
284{
285 struct cx25821_fh *fh = priv;
286 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
287 int err;
288 int pix_format = 0;
289
290 // check priority
291 if (fh)
292 {
293 err = v4l2_prio_check(&dev->prio, &fh->prio);
294 if (0 != err)
295 return err;
296 }
297 dprintk(2, "%s()\n", __func__);
298 err = vidioc_try_fmt_vid_cap(file, priv, f);
299
300 if (0 != err)
301 return err;
302
303 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
304 fh->vidq.field = f->fmt.pix.field;
305
306 // check if width and height is valid based on set standard
307 if (is_valid_width(f->fmt.pix.width, dev->tvnorm))
308 {
309 fh->width = f->fmt.pix.width;
310 }
311
312 if (is_valid_height(f->fmt.pix.height, dev->tvnorm))
313 {
314 fh->height = f->fmt.pix.height;
315 }
316
317 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
318 pix_format = PIXEL_FRMT_411;
319 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
320 pix_format = PIXEL_FRMT_422;
321 else
322 return -EINVAL;
323
324 cx25821_set_pixel_format( dev, SRAM_CH04, pix_format );
325
326 // check if cif resolution
327 if (fh->width == 320 || fh->width == 352)
328 {
329 dev->use_cif_resolution[SRAM_CH04] = 1;
330 }else
331 {
332 dev->use_cif_resolution[SRAM_CH04] = 0;
333 }
334 dev->cif_width[SRAM_CH04] = fh->width;
335 medusa_set_resolution( dev, fh->width, SRAM_CH04);
336
337 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
338 cx25821_call_all(dev, video, s_fmt, f);
339
340 return 0;
341}
342
343static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
344{
345 int ret_val = 0;
346 struct cx25821_fh *fh = priv;
347 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
348
349 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
350
351 p->sequence = dev->vidq[SRAM_CH04].count;
352
353 return ret_val;
354}
355
356static int vidioc_log_status (struct file *file, void *priv)
357{
358 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
359 char name[32 + 2];
360
361 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH04];
362 u32 tmp = 0;
363
364 snprintf(name, sizeof(name), "%s/2", dev->name);
365 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
366 dev->name);
367 cx25821_call_all(dev, core, log_status);
368
369 tmp = cx_read(sram_ch->dma_ctl);
370 printk(KERN_INFO "Video input 4 is %s\n", (tmp & 0x11)?"streaming" : "stopped");
371 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
372 dev->name);
373 return 0;
374}
375
376static int vidioc_s_ctrl(struct file *file, void *priv,
377 struct v4l2_control *ctl)
378{
379 struct cx25821_fh *fh = priv;
380 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
381 int err;
382
383 if (fh) {
384 err = v4l2_prio_check(&dev->prio, &fh->prio);
385 if (0 != err)
386 return err;
387 }
388
389 return cx25821_set_control(dev, ctl, SRAM_CH04);
390}
391
392// exported stuff
393static const struct v4l2_file_operations video_fops = {
394 .owner = THIS_MODULE,
395 .open = video_open,
396 .release = video_release,
397 .read = video_read,
398 .poll = video_poll,
399 .mmap = video_mmap,
400 .ioctl = video_ioctl2,
401};
402
403static const struct v4l2_ioctl_ops video_ioctl_ops = {
404 .vidioc_querycap = vidioc_querycap,
405 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
406 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
407 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
408 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
409 .vidioc_reqbufs = vidioc_reqbufs,
410 .vidioc_querybuf = vidioc_querybuf,
411 .vidioc_qbuf = vidioc_qbuf,
412 .vidioc_dqbuf = vidioc_dqbuf,
413#ifdef TUNER_FLAG
414 .vidioc_s_std = vidioc_s_std,
415 .vidioc_querystd = vidioc_querystd,
416#endif
417 .vidioc_cropcap = vidioc_cropcap,
418 .vidioc_s_crop = vidioc_s_crop,
419 .vidioc_g_crop = vidioc_g_crop,
420 .vidioc_enum_input = vidioc_enum_input,
421 .vidioc_g_input = vidioc_g_input,
422 .vidioc_s_input = vidioc_s_input,
423 .vidioc_g_ctrl = vidioc_g_ctrl,
424 .vidioc_s_ctrl = vidioc_s_ctrl,
425 .vidioc_queryctrl = vidioc_queryctrl,
426 .vidioc_streamon = vidioc_streamon,
427 .vidioc_streamoff = vidioc_streamoff,
428 .vidioc_log_status = vidioc_log_status,
429 .vidioc_g_priority = vidioc_g_priority,
430 .vidioc_s_priority = vidioc_s_priority,
431#ifdef CONFIG_VIDEO_V4L1_COMPAT
432 .vidiocgmbuf = vidiocgmbuf,
433#endif
434#ifdef TUNER_FLAG
435 .vidioc_g_tuner = vidioc_g_tuner,
436 .vidioc_s_tuner = vidioc_s_tuner,
437 .vidioc_g_frequency = vidioc_g_frequency,
438 .vidioc_s_frequency = vidioc_s_frequency,
439#endif
440#ifdef CONFIG_VIDEO_ADV_DEBUG
441 .vidioc_g_register = vidioc_g_register,
442 .vidioc_s_register = vidioc_s_register,
443#endif
444};
445
446struct video_device cx25821_video_template4 = {
447 .name = "cx25821-video",
448 .fops = &video_fops,
449 .minor = -1,
450 .ioctl_ops = &video_ioctl_ops,
451 .tvnorms = CX25821_NORMS,
452 .current_norm = V4L2_STD_NTSC_M,
453};
454
455
456
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c
new file mode 100644
index 00000000000..1d47543920b
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video5.c
@@ -0,0 +1,455 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH05];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH05]);
50 buf->vb.state = VIDEOBUF_ACTIVE;
51 buf->count = q->count++;
52 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
53 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
54 buf, buf->vb. i, buf->count, q->count);
55 } else {
56 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
57 if (prev->vb.width == buf->vb.width &&
58 prev->vb.height == buf->vb.height &&
59 prev->fmt == buf->fmt) {
60 list_add_tail(&buf->vb.queue, &q->active);
61 buf->vb.state = VIDEOBUF_ACTIVE;
62 buf->count = q->count++;
63 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
64
65 /* 64 bit bits 63-32 */
66 prev->risc.jmp[2] = cpu_to_le32(0);
67 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
68
69 } else {
70 list_add_tail(&buf->vb.queue, &q->queued);
71 buf->vb.state = VIDEOBUF_QUEUED;
72 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
73 }
74 }
75
76 if (list_empty(&q->active))
77 {
78 dprintk(2, "active queue empty!\n");
79 }
80}
81
82
83static struct videobuf_queue_ops cx25821_video_qops = {
84 .buf_setup = buffer_setup,
85 .buf_prepare = buffer_prepare,
86 .buf_queue = buffer_queue,
87 .buf_release = buffer_release,
88};
89
90
91static int video_open(struct file *file)
92{
93 int minor = video_devdata(file)->minor;
94 struct cx25821_dev *h, *dev = NULL;
95 struct cx25821_fh *fh;
96 struct list_head *list;
97 enum v4l2_buf_type type = 0;
98 u32 pix_format;
99
100 lock_kernel();
101 list_for_each(list, &cx25821_devlist)
102 {
103 h = list_entry(list, struct cx25821_dev, devlist);
104
105 if (h->video_dev[SRAM_CH05] && h->video_dev[SRAM_CH05]->minor == minor) {
106 dev = h;
107 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
108 }
109 }
110
111 if (NULL == dev) {
112 unlock_kernel();
113 return -ENODEV;
114 }
115
116 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
117
118 /* allocate + initialize per filehandle data */
119 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
120 if (NULL == fh) {
121 unlock_kernel();
122 return -ENOMEM;
123 }
124 file->private_data = fh;
125 fh->dev = dev;
126 fh->type = type;
127 fh->width = 720;
128
129 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
130 fh->height = 576;
131 else
132 fh->height = 480;
133
134 dev->channel_opened = SRAM_CH05;
135 pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
136 fh->fmt = format_by_fourcc(pix_format);
137
138 v4l2_prio_open(&dev->prio,&fh->prio);
139
140 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
141 &dev->pci->dev, &dev->slock,
142 V4L2_BUF_TYPE_VIDEO_CAPTURE,
143 V4L2_FIELD_INTERLACED,
144 sizeof(struct cx25821_buffer),
145 fh);
146
147 dprintk(1, "post videobuf_queue_init()\n");
148 unlock_kernel();
149
150 return 0;
151}
152
153static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
154{
155 struct cx25821_fh *fh = file->private_data;
156
157 switch (fh->type)
158 {
159 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
160 if (res_locked(fh->dev, RESOURCE_VIDEO5))
161 return -EBUSY;
162
163 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
164
165 default:
166 BUG();
167 return 0;
168 }
169}
170
171static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
172{
173 struct cx25821_fh *fh = file->private_data;
174 struct cx25821_buffer *buf;
175
176 if (res_check(fh, RESOURCE_VIDEO5)) {
177 /* streaming capture */
178 if (list_empty(&fh->vidq.stream))
179 return POLLERR;
180 buf = list_entry(fh->vidq.stream.next,
181 struct cx25821_buffer, vb.stream);
182 } else {
183 /* read() capture */
184 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
185 if (NULL == buf)
186 return POLLERR;
187 }
188
189 poll_wait(file, &buf->vb.done, wait);
190 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
191 {
192 if( buf->vb.state == VIDEOBUF_DONE )
193 {
194 struct cx25821_dev *dev = fh->dev;
195
196 if( dev && dev->use_cif_resolution[SRAM_CH05] )
197 {
198 u8 cam_id = *((char*)buf->vb.baddr+3);
199 memcpy((char*)buf->vb.baddr, (char*)buf->vb.baddr + (fh->width * 2), (fh->width * 2));
200 *((char*)buf->vb.baddr+3) = cam_id;
201 }
202 }
203
204 return POLLIN|POLLRDNORM;
205 }
206
207 return 0;
208}
209
210
211static int video_release(struct file *file)
212{
213 struct cx25821_fh *fh = file->private_data;
214 struct cx25821_dev *dev = fh->dev;
215
216 //stop the risc engine and fifo
217 cx_write(channel5->dma_ctl, 0); /* FIFO and RISC disable */
218
219 /* stop video capture */
220 if (res_check(fh, RESOURCE_VIDEO5)) {
221 videobuf_queue_cancel(&fh->vidq);
222 res_free(dev, fh, RESOURCE_VIDEO5);
223 }
224
225 if (fh->vidq.read_buf) {
226 buffer_release(&fh->vidq, fh->vidq.read_buf);
227 kfree(fh->vidq.read_buf);
228 }
229
230 videobuf_mmap_free(&fh->vidq);
231
232 v4l2_prio_close(&dev->prio,&fh->prio);
233 file->private_data = NULL;
234 kfree(fh);
235
236 return 0;
237}
238
239
240static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
241{
242 struct cx25821_fh *fh = priv;
243 struct cx25821_dev *dev = fh->dev;
244
245 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
246 {
247 return -EINVAL;
248 }
249
250 if (unlikely(i != fh->type))
251 {
252 return -EINVAL;
253 }
254
255 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO5))))
256 {
257 return -EBUSY;
258 }
259
260 return videobuf_streamon(get_queue(fh));
261}
262
263static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
264{
265 struct cx25821_fh *fh = priv;
266 struct cx25821_dev *dev = fh->dev;
267 int err, res;
268
269 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
270 return -EINVAL;
271 if (i != fh->type)
272 return -EINVAL;
273
274 res = get_resource(fh, RESOURCE_VIDEO5);
275 err = videobuf_streamoff(get_queue(fh));
276 if (err < 0)
277 return err;
278 res_free(dev, fh, res);
279 return 0;
280}
281
282
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
284{
285 struct cx25821_fh *fh = priv;
286 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
287 int err;
288 int pix_format = 0;
289
290 if (fh)
291 {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296
297 dprintk(2, "%s()\n", __func__);
298 err = vidioc_try_fmt_vid_cap(file, priv, f);
299
300 if (0 != err)
301 return err;
302
303 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
304 fh->vidq.field = f->fmt.pix.field;
305
306 // check if width and height is valid based on set standard
307 if (is_valid_width(f->fmt.pix.width, dev->tvnorm))
308 {
309 fh->width = f->fmt.pix.width;
310 }
311
312 if (is_valid_height(f->fmt.pix.height, dev->tvnorm))
313 {
314 fh->height = f->fmt.pix.height;
315 }
316
317 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
318 pix_format = PIXEL_FRMT_411;
319 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
320 pix_format = PIXEL_FRMT_422;
321 else
322 return -EINVAL;
323
324 cx25821_set_pixel_format( dev, SRAM_CH05, pix_format );
325
326 // check if cif resolution
327 if (fh->width == 320 || fh->width == 352)
328 {
329 dev->use_cif_resolution[SRAM_CH05] = 1;
330 }else
331 {
332 dev->use_cif_resolution[SRAM_CH05] = 0;
333 }
334 dev->cif_width[SRAM_CH05] = fh->width;
335 medusa_set_resolution( dev, fh->width, SRAM_CH05 );
336
337 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
338 cx25821_call_all(dev, video, s_fmt, f);
339
340 return 0;
341}
342
343static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
344{
345 int ret_val = 0;
346 struct cx25821_fh *fh = priv;
347 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
348
349 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
350
351 p->sequence = dev->vidq[SRAM_CH05].count;
352
353 return ret_val;
354}
355static int vidioc_log_status (struct file *file, void *priv)
356{
357 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
358 char name[32 + 2];
359
360 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH05];
361 u32 tmp = 0;
362
363 snprintf(name, sizeof(name), "%s/2", dev->name);
364 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
365 dev->name);
366 cx25821_call_all(dev, core, log_status);
367
368 tmp = cx_read(sram_ch->dma_ctl);
369 printk(KERN_INFO "Video input 5 is %s\n", (tmp & 0x11)?"streaming" : "stopped");
370 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
371 dev->name);
372 return 0;
373}
374
375static int vidioc_s_ctrl(struct file *file, void *priv,
376 struct v4l2_control *ctl)
377{
378 struct cx25821_fh *fh = priv;
379 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
380 int err;
381
382 if (fh) {
383 err = v4l2_prio_check(&dev->prio, &fh->prio);
384 if (0 != err)
385 return err;
386 }
387
388 return cx25821_set_control(dev, ctl, SRAM_CH05);
389}
390
391// exported stuff
392static const struct v4l2_file_operations video_fops = {
393 .owner = THIS_MODULE,
394 .open = video_open,
395 .release = video_release,
396 .read = video_read,
397 .poll = video_poll,
398 .mmap = video_mmap,
399 .ioctl = video_ioctl2,
400};
401
402static const struct v4l2_ioctl_ops video_ioctl_ops = {
403 .vidioc_querycap = vidioc_querycap,
404 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
405 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
406 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
407 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
408 .vidioc_reqbufs = vidioc_reqbufs,
409 .vidioc_querybuf = vidioc_querybuf,
410 .vidioc_qbuf = vidioc_qbuf,
411 .vidioc_dqbuf = vidioc_dqbuf,
412#ifdef TUNER_FLAG
413 .vidioc_s_std = vidioc_s_std,
414 .vidioc_querystd = vidioc_querystd,
415#endif
416 .vidioc_cropcap = vidioc_cropcap,
417 .vidioc_s_crop = vidioc_s_crop,
418 .vidioc_g_crop = vidioc_g_crop,
419 .vidioc_enum_input = vidioc_enum_input,
420 .vidioc_g_input = vidioc_g_input,
421 .vidioc_s_input = vidioc_s_input,
422 .vidioc_g_ctrl = vidioc_g_ctrl,
423 .vidioc_s_ctrl = vidioc_s_ctrl,
424 .vidioc_queryctrl = vidioc_queryctrl,
425 .vidioc_streamon = vidioc_streamon,
426 .vidioc_streamoff = vidioc_streamoff,
427 .vidioc_log_status = vidioc_log_status,
428 .vidioc_g_priority = vidioc_g_priority,
429 .vidioc_s_priority = vidioc_s_priority,
430#ifdef CONFIG_VIDEO_V4L1_COMPAT
431 .vidiocgmbuf = vidiocgmbuf,
432#endif
433#ifdef TUNER_FLAG
434 .vidioc_g_tuner = vidioc_g_tuner,
435 .vidioc_s_tuner = vidioc_s_tuner,
436 .vidioc_g_frequency = vidioc_g_frequency,
437 .vidioc_s_frequency = vidioc_s_frequency,
438#endif
439#ifdef CONFIG_VIDEO_ADV_DEBUG
440 .vidioc_g_register = vidioc_g_register,
441 .vidioc_s_register = vidioc_s_register,
442#endif
443};
444
445struct video_device cx25821_video_template5 = {
446 .name = "cx25821-video",
447 .fops = &video_fops,
448 .minor = -1,
449 .ioctl_ops = &video_ioctl_ops,
450 .tvnorms = CX25821_NORMS,
451 .current_norm = V4L2_STD_NTSC_M,
452};
453
454
455
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c
new file mode 100644
index 00000000000..980565af5c3
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video6.c
@@ -0,0 +1,455 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH06];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH06]);
50 buf->vb.state = VIDEOBUF_ACTIVE;
51 buf->count = q->count++;
52 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
53 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
54 buf, buf->vb. i, buf->count, q->count);
55 } else {
56 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
57 if (prev->vb.width == buf->vb.width &&
58 prev->vb.height == buf->vb.height &&
59 prev->fmt == buf->fmt) {
60 list_add_tail(&buf->vb.queue, &q->active);
61 buf->vb.state = VIDEOBUF_ACTIVE;
62 buf->count = q->count++;
63 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
64
65 /* 64 bit bits 63-32 */
66 prev->risc.jmp[2] = cpu_to_le32(0);
67 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
68
69 } else {
70 list_add_tail(&buf->vb.queue, &q->queued);
71 buf->vb.state = VIDEOBUF_QUEUED;
72 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
73 }
74 }
75
76 if (list_empty(&q->active))
77 {
78 dprintk(2, "active queue empty!\n");
79 }
80}
81
82
83static struct videobuf_queue_ops cx25821_video_qops = {
84 .buf_setup = buffer_setup,
85 .buf_prepare = buffer_prepare,
86 .buf_queue = buffer_queue,
87 .buf_release = buffer_release,
88};
89
90
91static int video_open(struct file *file)
92{
93 int minor = video_devdata(file)->minor;
94 struct cx25821_dev *h, *dev = NULL;
95 struct cx25821_fh *fh;
96 struct list_head *list;
97 enum v4l2_buf_type type = 0;
98 u32 pix_format;
99
100 lock_kernel();
101 list_for_each(list, &cx25821_devlist)
102 {
103 h = list_entry(list, struct cx25821_dev, devlist);
104
105 if (h->video_dev[SRAM_CH06] && h->video_dev[SRAM_CH06]->minor == minor) {
106 dev = h;
107 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
108 }
109 }
110
111 if (NULL == dev) {
112 unlock_kernel();
113 return -ENODEV;
114 }
115
116 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
117
118 /* allocate + initialize per filehandle data */
119 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
120 if (NULL == fh) {
121 unlock_kernel();
122 return -ENOMEM;
123 }
124 file->private_data = fh;
125 fh->dev = dev;
126 fh->type = type;
127 fh->width = 720;
128
129 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
130 fh->height = 576;
131 else
132 fh->height = 480;
133
134 dev->channel_opened = SRAM_CH06;
135 pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
136 fh->fmt = format_by_fourcc(pix_format);
137
138 v4l2_prio_open(&dev->prio,&fh->prio);
139
140 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
141 &dev->pci->dev, &dev->slock,
142 V4L2_BUF_TYPE_VIDEO_CAPTURE,
143 V4L2_FIELD_INTERLACED,
144 sizeof(struct cx25821_buffer),
145 fh);
146
147 dprintk(1, "post videobuf_queue_init()\n");
148 unlock_kernel();
149
150 return 0;
151}
152
153static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
154{
155 struct cx25821_fh *fh = file->private_data;
156
157 switch (fh->type)
158 {
159 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
160 if (res_locked(fh->dev, RESOURCE_VIDEO6))
161 return -EBUSY;
162
163 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
164
165 default:
166 BUG();
167 return 0;
168 }
169}
170
171static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
172{
173 struct cx25821_fh *fh = file->private_data;
174 struct cx25821_buffer *buf;
175
176 if (res_check(fh, RESOURCE_VIDEO6)) {
177 /* streaming capture */
178 if (list_empty(&fh->vidq.stream))
179 return POLLERR;
180 buf = list_entry(fh->vidq.stream.next,
181 struct cx25821_buffer, vb.stream);
182 } else {
183 /* read() capture */
184 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
185 if (NULL == buf)
186 return POLLERR;
187 }
188
189 poll_wait(file, &buf->vb.done, wait);
190 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
191 {
192 if( buf->vb.state == VIDEOBUF_DONE )
193 {
194 struct cx25821_dev *dev = fh->dev;
195
196 if( dev && dev->use_cif_resolution[SRAM_CH06] )
197 {
198 u8 cam_id = *((char*)buf->vb.baddr+3);
199 memcpy((char*)buf->vb.baddr, (char*)buf->vb.baddr + (fh->width * 2), (fh->width * 2));
200 *((char*)buf->vb.baddr+3) = cam_id;
201 }
202 }
203
204 return POLLIN|POLLRDNORM;
205 }
206
207 return 0;
208}
209
210
211static int video_release(struct file *file)
212{
213 struct cx25821_fh *fh = file->private_data;
214 struct cx25821_dev *dev = fh->dev;
215
216 //stop the risc engine and fifo
217 cx_write(channel6->dma_ctl, 0); /* FIFO and RISC disable */
218
219 /* stop video capture */
220 if (res_check(fh, RESOURCE_VIDEO6)) {
221 videobuf_queue_cancel(&fh->vidq);
222 res_free(dev, fh, RESOURCE_VIDEO6);
223 }
224 if (fh->vidq.read_buf) {
225 buffer_release(&fh->vidq, fh->vidq.read_buf);
226 kfree(fh->vidq.read_buf);
227 }
228
229 videobuf_mmap_free(&fh->vidq);
230
231 v4l2_prio_close(&dev->prio,&fh->prio);
232 file->private_data = NULL;
233 kfree(fh);
234
235 return 0;
236}
237
238
239static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
240{
241 struct cx25821_fh *fh = priv;
242 struct cx25821_dev *dev = fh->dev;
243
244 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
245 {
246 return -EINVAL;
247 }
248
249 if (unlikely(i != fh->type))
250 {
251 return -EINVAL;
252 }
253
254 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO6))))
255 {
256 return -EBUSY;
257 }
258
259 return videobuf_streamon(get_queue(fh));
260}
261
262static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
263{
264 struct cx25821_fh *fh = priv;
265 struct cx25821_dev *dev = fh->dev;
266 int err, res;
267
268 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
269 return -EINVAL;
270 if (i != fh->type)
271 return -EINVAL;
272
273 res = get_resource(fh, RESOURCE_VIDEO6);
274 err = videobuf_streamoff(get_queue(fh));
275 if (err < 0)
276 return err;
277 res_free(dev, fh, res);
278 return 0;
279}
280
281
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
283{
284 struct cx25821_fh *fh = priv;
285 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
286 int err;
287 int pix_format = 0;
288
289 if (fh)
290 {
291 err = v4l2_prio_check(&dev->prio, &fh->prio);
292 if (0 != err)
293 return err;
294 }
295
296 dprintk(2, "%s()\n", __func__);
297 err = vidioc_try_fmt_vid_cap(file, priv, f);
298
299 if (0 != err)
300 return err;
301
302 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
303 fh->vidq.field = f->fmt.pix.field;
304
305 // check if width and height is valid based on set standard
306 if (is_valid_width(f->fmt.pix.width, dev->tvnorm))
307 {
308 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm))
312 {
313 fh->height = f->fmt.pix.height;
314 }
315
316 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
317 pix_format = PIXEL_FRMT_411;
318 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
319 pix_format = PIXEL_FRMT_422;
320 else
321 return -EINVAL;
322
323 cx25821_set_pixel_format( dev, SRAM_CH06, pix_format );
324
325 // check if cif resolution
326 if (fh->width == 320 || fh->width == 352)
327 {
328 dev->use_cif_resolution[SRAM_CH06] = 1;
329 }else
330 {
331 dev->use_cif_resolution[SRAM_CH06] = 0;
332 }
333 dev->cif_width[SRAM_CH06] = fh->width;
334 medusa_set_resolution( dev, fh->width, SRAM_CH06 );
335
336 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
337 cx25821_call_all(dev, video, s_fmt, f);
338
339 return 0;
340}
341
342static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
343{
344 int ret_val = 0;
345 struct cx25821_fh *fh = priv;
346 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
347
348 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
349
350 p->sequence = dev->vidq[SRAM_CH06].count;
351
352 return ret_val;
353}
354
355static int vidioc_log_status (struct file *file, void *priv)
356{
357 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
358 char name[32 + 2];
359
360 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH06];
361 u32 tmp = 0;
362
363 snprintf(name, sizeof(name), "%s/2", dev->name);
364 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
365 dev->name);
366 cx25821_call_all(dev, core, log_status);
367
368 tmp = cx_read(sram_ch->dma_ctl);
369 printk(KERN_INFO "Video input 6 is %s\n", (tmp & 0x11)?"streaming" : "stopped");
370 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
371 dev->name);
372 return 0;
373}
374
375static int vidioc_s_ctrl(struct file *file, void *priv,
376 struct v4l2_control *ctl)
377{
378 struct cx25821_fh *fh = priv;
379 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
380 int err;
381
382 if (fh) {
383 err = v4l2_prio_check(&dev->prio, &fh->prio);
384 if (0 != err)
385 return err;
386 }
387
388 return cx25821_set_control(dev, ctl, SRAM_CH06);
389}
390
391// exported stuff
392static const struct v4l2_file_operations video_fops = {
393 .owner = THIS_MODULE,
394 .open = video_open,
395 .release = video_release,
396 .read = video_read,
397 .poll = video_poll,
398 .mmap = video_mmap,
399 .ioctl = video_ioctl2,
400};
401
402static const struct v4l2_ioctl_ops video_ioctl_ops = {
403 .vidioc_querycap = vidioc_querycap,
404 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
405 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
406 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
407 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
408 .vidioc_reqbufs = vidioc_reqbufs,
409 .vidioc_querybuf = vidioc_querybuf,
410 .vidioc_qbuf = vidioc_qbuf,
411 .vidioc_dqbuf = vidioc_dqbuf,
412#ifdef TUNER_FLAG
413 .vidioc_s_std = vidioc_s_std,
414 .vidioc_querystd = vidioc_querystd,
415#endif
416 .vidioc_cropcap = vidioc_cropcap,
417 .vidioc_s_crop = vidioc_s_crop,
418 .vidioc_g_crop = vidioc_g_crop,
419 .vidioc_enum_input = vidioc_enum_input,
420 .vidioc_g_input = vidioc_g_input,
421 .vidioc_s_input = vidioc_s_input,
422 .vidioc_g_ctrl = vidioc_g_ctrl,
423 .vidioc_s_ctrl = vidioc_s_ctrl,
424 .vidioc_queryctrl = vidioc_queryctrl,
425 .vidioc_streamon = vidioc_streamon,
426 .vidioc_streamoff = vidioc_streamoff,
427 .vidioc_log_status = vidioc_log_status,
428 .vidioc_g_priority = vidioc_g_priority,
429 .vidioc_s_priority = vidioc_s_priority,
430#ifdef CONFIG_VIDEO_V4L1_COMPAT
431 .vidiocgmbuf = vidiocgmbuf,
432#endif
433#ifdef TUNER_FLAG
434 .vidioc_g_tuner = vidioc_g_tuner,
435 .vidioc_s_tuner = vidioc_s_tuner,
436 .vidioc_g_frequency = vidioc_g_frequency,
437 .vidioc_s_frequency = vidioc_s_frequency,
438#endif
439#ifdef CONFIG_VIDEO_ADV_DEBUG
440 .vidioc_g_register = vidioc_g_register,
441 .vidioc_s_register = vidioc_s_register,
442#endif
443};
444
445struct video_device cx25821_video_template6 = {
446 .name = "cx25821-video",
447 .fops = &video_fops,
448 .minor = -1,
449 .ioctl_ops = &video_ioctl_ops,
450 .tvnorms = CX25821_NORMS,
451 .current_norm = V4L2_STD_NTSC_M,
452};
453
454
455
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c
new file mode 100644
index 00000000000..966e369a4ab
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video7.c
@@ -0,0 +1,454 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH07];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41 if (!list_empty(&q->queued)) {
42 list_add_tail(&buf->vb.queue, &q->queued);
43 buf->vb.state = VIDEOBUF_QUEUED;
44 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
45
46 } else if (list_empty(&q->active)) {
47 list_add_tail(&buf->vb.queue, &q->active);
48 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH07]);
49 buf->vb.state = VIDEOBUF_ACTIVE;
50 buf->count = q->count++;
51 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
52 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
53 buf, buf->vb. i, buf->count, q->count);
54 } else {
55 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
56 if (prev->vb.width == buf->vb.width &&
57 prev->vb.height == buf->vb.height &&
58 prev->fmt == buf->fmt) {
59 list_add_tail(&buf->vb.queue, &q->active);
60 buf->vb.state = VIDEOBUF_ACTIVE;
61 buf->count = q->count++;
62 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
63
64 /* 64 bit bits 63-32 */
65 prev->risc.jmp[2] = cpu_to_le32(0);
66 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
67
68 } else {
69 list_add_tail(&buf->vb.queue, &q->queued);
70 buf->vb.state = VIDEOBUF_QUEUED;
71 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
72 }
73 }
74
75 if (list_empty(&q->active))
76 {
77 dprintk(2, "active queue empty!\n");
78 }
79}
80
81
82static struct videobuf_queue_ops cx25821_video_qops = {
83 .buf_setup = buffer_setup,
84 .buf_prepare = buffer_prepare,
85 .buf_queue = buffer_queue,
86 .buf_release = buffer_release,
87};
88
89
90static int video_open(struct file *file)
91{
92 int minor = video_devdata(file)->minor;
93 struct cx25821_dev *h, *dev = NULL;
94 struct cx25821_fh *fh;
95 struct list_head *list;
96 enum v4l2_buf_type type = 0;
97 u32 pix_format;
98
99 lock_kernel();
100 list_for_each(list, &cx25821_devlist)
101 {
102 h = list_entry(list, struct cx25821_dev, devlist);
103
104 if (h->video_dev[SRAM_CH07] && h->video_dev[SRAM_CH07]->minor == minor) {
105 dev = h;
106 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
107 }
108 }
109
110 if (NULL == dev) {
111 unlock_kernel();
112 return -ENODEV;
113 }
114
115 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
116
117 /* allocate + initialize per filehandle data */
118 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
119 if (NULL == fh) {
120 unlock_kernel();
121 return -ENOMEM;
122 }
123 file->private_data = fh;
124 fh->dev = dev;
125 fh->type = type;
126 fh->width = 720;
127
128 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
129 fh->height = 576;
130 else
131 fh->height = 480;
132
133 dev->channel_opened = SRAM_CH07;
134 pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
135 fh->fmt = format_by_fourcc(pix_format);
136
137 v4l2_prio_open(&dev->prio,&fh->prio);
138
139 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
140 &dev->pci->dev, &dev->slock,
141 V4L2_BUF_TYPE_VIDEO_CAPTURE,
142 V4L2_FIELD_INTERLACED,
143 sizeof(struct cx25821_buffer),
144 fh);
145
146 dprintk(1, "post videobuf_queue_init()\n");
147 unlock_kernel();
148
149 return 0;
150}
151
152static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
153{
154 struct cx25821_fh *fh = file->private_data;
155
156 switch (fh->type)
157 {
158 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
159 if (res_locked(fh->dev, RESOURCE_VIDEO7))
160 return -EBUSY;
161
162 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
163
164 default:
165 BUG();
166 return 0;
167 }
168}
169
170static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
171{
172 struct cx25821_fh *fh = file->private_data;
173 struct cx25821_buffer *buf;
174
175 if (res_check(fh, RESOURCE_VIDEO7)) {
176 /* streaming capture */
177 if (list_empty(&fh->vidq.stream))
178 return POLLERR;
179 buf = list_entry(fh->vidq.stream.next,
180 struct cx25821_buffer, vb.stream);
181 } else {
182 /* read() capture */
183 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
184 if (NULL == buf)
185 return POLLERR;
186 }
187
188 poll_wait(file, &buf->vb.done, wait);
189 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
190 {
191 if( buf->vb.state == VIDEOBUF_DONE )
192 {
193 struct cx25821_dev *dev = fh->dev;
194
195 if( dev && dev->use_cif_resolution[SRAM_CH07] )
196 {
197 u8 cam_id = *((char*)buf->vb.baddr+3);
198 memcpy((char*)buf->vb.baddr, (char*)buf->vb.baddr + (fh->width * 2), (fh->width * 2));
199 *((char*)buf->vb.baddr+3) = cam_id;
200 }
201 }
202
203 return POLLIN|POLLRDNORM;
204 }
205
206 return 0;
207}
208
209
210static int video_release(struct file *file)
211{
212 struct cx25821_fh *fh = file->private_data;
213 struct cx25821_dev *dev = fh->dev;
214
215 //stop the risc engine and fifo
216 cx_write(channel7->dma_ctl, 0); /* FIFO and RISC disable */
217
218 /* stop video capture */
219 if (res_check(fh, RESOURCE_VIDEO7)) {
220 videobuf_queue_cancel(&fh->vidq);
221 res_free(dev, fh, RESOURCE_VIDEO7);
222 }
223
224 if (fh->vidq.read_buf) {
225 buffer_release(&fh->vidq, fh->vidq.read_buf);
226 kfree(fh->vidq.read_buf);
227 }
228
229 videobuf_mmap_free(&fh->vidq);
230
231 v4l2_prio_close(&dev->prio,&fh->prio);
232 file->private_data = NULL;
233 kfree(fh);
234
235 return 0;
236}
237
238
239static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
240{
241 struct cx25821_fh *fh = priv;
242 struct cx25821_dev *dev = fh->dev;
243
244 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
245 {
246 return -EINVAL;
247 }
248
249 if (unlikely(i != fh->type))
250 {
251 return -EINVAL;
252 }
253
254 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO7))))
255 {
256 return -EBUSY;
257 }
258
259 return videobuf_streamon(get_queue(fh));
260}
261
262static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
263{
264 struct cx25821_fh *fh = priv;
265 struct cx25821_dev *dev = fh->dev;
266 int err, res;
267
268 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
269 return -EINVAL;
270 if (i != fh->type)
271 return -EINVAL;
272
273 res = get_resource(fh, RESOURCE_VIDEO7);
274 err = videobuf_streamoff(get_queue(fh));
275 if (err < 0)
276 return err;
277 res_free(dev, fh, res);
278 return 0;
279}
280
281
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
283{
284 struct cx25821_fh *fh = priv;
285 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
286 int err;
287 int pix_format = 0;
288
289 if (fh)
290 {
291 err = v4l2_prio_check(&dev->prio, &fh->prio);
292 if (0 != err)
293 return err;
294 }
295
296 dprintk(2, "%s()\n", __func__);
297 err = vidioc_try_fmt_vid_cap(file, priv, f);
298
299 if (0 != err)
300 return err;
301
302 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
303 fh->vidq.field = f->fmt.pix.field;
304
305 // check if width and height is valid based on set standard
306 if (is_valid_width(f->fmt.pix.width, dev->tvnorm))
307 {
308 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm))
312 {
313 fh->height = f->fmt.pix.height;
314 }
315
316 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
317 pix_format = PIXEL_FRMT_411;
318 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
319 pix_format = PIXEL_FRMT_422;
320 else
321 return -EINVAL;
322
323 cx25821_set_pixel_format( dev, SRAM_CH07, pix_format );
324
325 // check if cif resolution
326 if (fh->width == 320 || fh->width == 352)
327 {
328 dev->use_cif_resolution[SRAM_CH07] = 1;
329 }else
330 {
331 dev->use_cif_resolution[SRAM_CH07] = 0;
332 }
333 dev->cif_width[SRAM_CH07] = fh->width;
334 medusa_set_resolution( dev, fh->width, SRAM_CH07 );
335
336 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
337 cx25821_call_all(dev, video, s_fmt, f);
338
339 return 0;
340}
341
342static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
343{
344 int ret_val = 0;
345 struct cx25821_fh *fh = priv;
346 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
347
348 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
349
350 p->sequence = dev->vidq[SRAM_CH07].count;
351
352 return ret_val;
353}
354static int vidioc_log_status (struct file *file, void *priv)
355{
356 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
357 char name[32 + 2];
358
359 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH07];
360 u32 tmp = 0;
361
362 snprintf(name, sizeof(name), "%s/2", dev->name);
363 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
364 dev->name);
365 cx25821_call_all(dev, core, log_status);
366
367 tmp = cx_read(sram_ch->dma_ctl);
368 printk(KERN_INFO "Video input 7 is %s\n", (tmp & 0x11)?"streaming" : "stopped");
369 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
370 dev->name);
371 return 0;
372}
373
374static int vidioc_s_ctrl(struct file *file, void *priv,
375 struct v4l2_control *ctl)
376{
377 struct cx25821_fh *fh = priv;
378 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
379 int err;
380
381 if (fh) {
382 err = v4l2_prio_check(&dev->prio, &fh->prio);
383 if (0 != err)
384 return err;
385 }
386
387 return cx25821_set_control(dev, ctl, SRAM_CH07);
388}
389
390// exported stuff
391static const struct v4l2_file_operations video_fops = {
392 .owner = THIS_MODULE,
393 .open = video_open,
394 .release = video_release,
395 .read = video_read,
396 .poll = video_poll,
397 .mmap = video_mmap,
398 .ioctl = video_ioctl2,
399};
400
401static const struct v4l2_ioctl_ops video_ioctl_ops = {
402 .vidioc_querycap = vidioc_querycap,
403 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
404 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
405 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
406 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
407 .vidioc_reqbufs = vidioc_reqbufs,
408 .vidioc_querybuf = vidioc_querybuf,
409 .vidioc_qbuf = vidioc_qbuf,
410 .vidioc_dqbuf = vidioc_dqbuf,
411#ifdef TUNER_FLAG
412 .vidioc_s_std = vidioc_s_std,
413 .vidioc_querystd = vidioc_querystd,
414#endif
415 .vidioc_cropcap = vidioc_cropcap,
416 .vidioc_s_crop = vidioc_s_crop,
417 .vidioc_g_crop = vidioc_g_crop,
418 .vidioc_enum_input = vidioc_enum_input,
419 .vidioc_g_input = vidioc_g_input,
420 .vidioc_s_input = vidioc_s_input,
421 .vidioc_g_ctrl = vidioc_g_ctrl,
422 .vidioc_s_ctrl = vidioc_s_ctrl,
423 .vidioc_queryctrl = vidioc_queryctrl,
424 .vidioc_streamon = vidioc_streamon,
425 .vidioc_streamoff = vidioc_streamoff,
426 .vidioc_log_status = vidioc_log_status,
427 .vidioc_g_priority = vidioc_g_priority,
428 .vidioc_s_priority = vidioc_s_priority,
429#ifdef CONFIG_VIDEO_V4L1_COMPAT
430 .vidiocgmbuf = vidiocgmbuf,
431#endif
432#ifdef TUNER_FLAG
433 .vidioc_g_tuner = vidioc_g_tuner,
434 .vidioc_s_tuner = vidioc_s_tuner,
435 .vidioc_g_frequency = vidioc_g_frequency,
436 .vidioc_s_frequency = vidioc_s_frequency,
437#endif
438#ifdef CONFIG_VIDEO_ADV_DEBUG
439 .vidioc_g_register = vidioc_g_register,
440 .vidioc_s_register = vidioc_s_register,
441#endif
442};
443
444struct video_device cx25821_video_template7 = {
445 .name = "cx25821-video",
446 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M,
451};
452
453
454
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c
new file mode 100644
index 00000000000..a5363e486f7
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-videoioctl.c
@@ -0,0 +1,500 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[VIDEO_IOCTL_CH];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[VIDEO_IOCTL_CH]);
50 buf->vb.state = VIDEOBUF_ACTIVE;
51 buf->count = q->count++;
52 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
53 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
54 buf, buf->vb. i, buf->count, q->count);
55 } else {
56 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
57 if (prev->vb.width == buf->vb.width &&
58 prev->vb.height == buf->vb.height &&
59 prev->fmt == buf->fmt) {
60 list_add_tail(&buf->vb.queue, &q->active);
61 buf->vb.state = VIDEOBUF_ACTIVE;
62 buf->count = q->count++;
63 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
64
65 /* 64 bit bits 63-32 */
66 prev->risc.jmp[2] = cpu_to_le32(0);
67 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
68
69 } else {
70 list_add_tail(&buf->vb.queue, &q->queued);
71 buf->vb.state = VIDEOBUF_QUEUED;
72 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
73 }
74 }
75
76 if (list_empty(&q->active))
77 {
78 dprintk(2, "active queue empty!\n");
79 }
80}
81
82
83static struct videobuf_queue_ops cx25821_video_qops = {
84 .buf_setup = buffer_setup,
85 .buf_prepare = buffer_prepare,
86 .buf_queue = buffer_queue,
87 .buf_release = buffer_release,
88};
89
90
91static int video_open(struct file *file)
92{
93 int minor = video_devdata(file)->minor;
94 struct cx25821_dev *h, *dev = NULL;
95 struct cx25821_fh *fh;
96 struct list_head *list;
97 enum v4l2_buf_type type = 0;
98 u32 pix_format;
99
100 lock_kernel();
101 list_for_each(list, &cx25821_devlist)
102 {
103 h = list_entry(list, struct cx25821_dev, devlist);
104
105 if (h->ioctl_dev && h->ioctl_dev->minor == minor)
106 {
107 dev = h;
108 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
109 }
110 }
111
112 if (NULL == dev) {
113 unlock_kernel();
114 return -ENODEV;
115 }
116
117 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
118
119 /* allocate + initialize per filehandle data */
120 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
121 if (NULL == fh) {
122 unlock_kernel();
123 return -ENOMEM;
124 }
125
126 file->private_data = fh;
127 fh->dev = dev;
128 fh->type = type;
129 fh->width = 720;
130
131 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
132 fh->height = 576;
133 else
134 fh->height = 480;
135
136 dev->channel_opened = VIDEO_IOCTL_CH;
137 pix_format = V4L2_PIX_FMT_YUYV;
138 fh->fmt = format_by_fourcc(pix_format);
139
140 v4l2_prio_open(&dev->prio,&fh->prio);
141
142 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
143 &dev->pci->dev, &dev->slock,
144 V4L2_BUF_TYPE_VIDEO_CAPTURE,
145 V4L2_FIELD_INTERLACED,
146 sizeof(struct cx25821_buffer),
147 fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
156{
157 struct cx25821_fh *fh = file->private_data;
158
159 switch (fh->type)
160 {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO_IOCTL))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
166
167 default:
168 BUG();
169 return 0;
170 }
171}
172
173static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
174{
175 struct cx25821_fh *fh = file->private_data;
176 struct cx25821_buffer *buf;
177
178 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
179 /* streaming capture */
180 if (list_empty(&fh->vidq.stream))
181 return POLLERR;
182 buf = list_entry(fh->vidq.stream.next,
183 struct cx25821_buffer, vb.stream);
184 } else {
185 /* read() capture */
186 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
187 if (NULL == buf)
188 return POLLERR;
189 }
190
191 poll_wait(file, &buf->vb.done, wait);
192 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
193 return POLLIN|POLLRDNORM;
194
195 return 0;
196}
197
198
199static int video_release(struct file *file)
200{
201 struct cx25821_fh *fh = file->private_data;
202 struct cx25821_dev *dev = fh->dev;
203
204 /* stop video capture */
205 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
206 videobuf_queue_cancel(&fh->vidq);
207 res_free(dev, fh, RESOURCE_VIDEO_IOCTL);
208 }
209
210 if (fh->vidq.read_buf) {
211 buffer_release(&fh->vidq, fh->vidq.read_buf);
212 kfree(fh->vidq.read_buf);
213 }
214
215 videobuf_mmap_free(&fh->vidq);
216
217 v4l2_prio_close(&dev->prio,&fh->prio);
218
219 file->private_data = NULL;
220 kfree(fh);
221
222 return 0;
223}
224
225
226static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
227{
228 struct cx25821_fh *fh = priv;
229 struct cx25821_dev *dev = fh->dev;
230
231 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
232 {
233 return -EINVAL;
234 }
235
236 if (unlikely(i != fh->type))
237 {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO_IOCTL))))
242 {
243 return -EBUSY;
244 }
245
246 return videobuf_streamon(get_queue(fh));
247}
248
249static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
250{
251 struct cx25821_fh *fh = priv;
252 struct cx25821_dev *dev = fh->dev;
253 int err, res;
254
255 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
256 return -EINVAL;
257 if (i != fh->type)
258 return -EINVAL;
259
260 res = get_resource(fh, RESOURCE_VIDEO_IOCTL);
261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0)
263 return err;
264 res_free(dev, fh, res);
265 return 0;
266}
267
268
269static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
270{
271 struct cx25821_fh *fh = priv;
272 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
273 int err;
274
275 if (fh)
276 {
277 err = v4l2_prio_check(&dev->prio, &fh->prio);
278 if (0 != err)
279 return err;
280 }
281
282 dprintk(2, "%s()\n", __func__);
283 err = vidioc_try_fmt_vid_cap(file, priv, f);
284
285 if (0 != err)
286 return err;
287 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
288 fh->width = f->fmt.pix.width;
289 fh->height = f->fmt.pix.height;
290 fh->vidq.field = f->fmt.pix.field;
291 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
292 cx25821_call_all(dev, video, s_fmt, f);
293 return 0;
294}
295
296static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
297{
298 struct cx25821_fh *fh = priv;
299 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
300}
301
302static long video_ioctl_set(struct file *file, unsigned int cmd, unsigned long arg)
303{
304 struct cx25821_fh *fh = file->private_data;
305 struct cx25821_dev *dev = fh->dev;
306 struct downstream_user_struct *data_from_user;
307 int command;
308 int width = 720;
309 int selected_channel = 0, pix_format = 0, i = 0;
310 int cif_enable = 0, cif_width = 0;
311 u32 value = 0;
312
313
314 data_from_user = (struct downstream_user_struct *)arg;
315
316 if( !data_from_user )
317 {
318 printk("cx25821 in %s(): User data is INVALID. Returning.\n", __func__);
319 return 0;
320 }
321
322 command = data_from_user->command;
323
324 if( command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT && command != ENABLE_CIF_RESOLUTION &&
325 command != REG_READ && command != REG_WRITE && command != MEDUSA_READ && command != MEDUSA_WRITE)
326 {
327 return 0;
328 }
329
330
331 switch(command)
332 {
333 case SET_VIDEO_STD:
334 dev->tvnorm = !strcmp(data_from_user->vid_stdname,"PAL") ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
335 medusa_set_videostandard(dev);
336 break;
337
338 case SET_PIXEL_FORMAT:
339 selected_channel = data_from_user->decoder_select;
340 pix_format = data_from_user->pixel_format;
341
342 if( !(selected_channel <= 7 && selected_channel >= 0) )
343 {
344 selected_channel -= 4;
345 selected_channel = selected_channel % 8;
346 }
347
348 if( selected_channel >= 0 )
349 cx25821_set_pixel_format( dev, selected_channel, pix_format );
350
351 break;
352
353 case ENABLE_CIF_RESOLUTION:
354 selected_channel = data_from_user->decoder_select;
355 cif_enable = data_from_user->cif_resolution_enable;
356 cif_width = data_from_user->cif_width;
357
358 if( cif_enable )
359 {
360 if( dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK )
361 width = 352;
362 else
363 width = (cif_width == 320 || cif_width == 352) ? cif_width : 320;
364 }
365
366 if( !(selected_channel <= 7 && selected_channel >= 0) )
367 {
368 selected_channel -= 4;
369 selected_channel = selected_channel % 8;
370 }
371
372
373 if( selected_channel <= 7 && selected_channel >= 0 )
374 {
375 dev->use_cif_resolution[selected_channel] = cif_enable;
376 dev->cif_width[selected_channel] = width;
377 }
378 else
379 {
380 for( i=0; i < VID_CHANNEL_NUM; i++ )
381 {
382 dev->use_cif_resolution[i] = cif_enable;
383 dev->cif_width[i] = width;
384 }
385 }
386
387 medusa_set_resolution( dev, width, selected_channel );
388 break;
389 case REG_READ:
390 data_from_user->reg_data = cx_read(data_from_user->reg_address);
391 break;
392 case REG_WRITE:
393 cx_write(data_from_user->reg_address, data_from_user->reg_data);
394 break;
395 case MEDUSA_READ:
396 value = cx25821_i2c_read(&dev->i2c_bus[0], (u16)data_from_user->reg_address, &data_from_user->reg_data);
397 break;
398 case MEDUSA_WRITE:
399 cx25821_i2c_write(&dev->i2c_bus[0], (u16)data_from_user->reg_address, data_from_user->reg_data);
400 break;
401 }
402
403 return 0;
404}
405
406static int vidioc_log_status (struct file *file, void *priv)
407{
408 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
409 char name[32 + 2];
410
411 snprintf(name, sizeof(name), "%s/2", dev->name);
412 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
413 dev->name);
414 cx25821_call_all(dev, core, log_status);
415 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
416 dev->name);
417 return 0;
418}
419
420static int vidioc_s_ctrl(struct file *file, void *priv,
421 struct v4l2_control *ctl)
422{
423 struct cx25821_fh *fh = priv;
424 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
425 int err;
426
427 if (fh)
428 {
429 err = v4l2_prio_check(&dev->prio, &fh->prio);
430 if (0 != err)
431 return err;
432 }
433
434 return 0;
435}
436// exported stuff
437static const struct v4l2_file_operations video_fops = {
438 .owner = THIS_MODULE,
439 .open = video_open,
440 .release = video_release,
441 .read = video_read,
442 .poll = video_poll,
443 .mmap = video_mmap,
444 .ioctl = video_ioctl_set,
445};
446
447static const struct v4l2_ioctl_ops video_ioctl_ops = {
448 .vidioc_querycap = vidioc_querycap,
449 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
450 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
451 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
452 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
453 .vidioc_reqbufs = vidioc_reqbufs,
454 .vidioc_querybuf = vidioc_querybuf,
455 .vidioc_qbuf = vidioc_qbuf,
456 .vidioc_dqbuf = vidioc_dqbuf,
457#ifdef TUNER_FLAG
458 .vidioc_s_std = vidioc_s_std,
459 .vidioc_querystd = vidioc_querystd,
460#endif
461 .vidioc_cropcap = vidioc_cropcap,
462 .vidioc_s_crop = vidioc_s_crop,
463 .vidioc_g_crop = vidioc_g_crop,
464 .vidioc_enum_input = vidioc_enum_input,
465 .vidioc_g_input = vidioc_g_input,
466 .vidioc_s_input = vidioc_s_input,
467 .vidioc_g_ctrl = vidioc_g_ctrl,
468 .vidioc_s_ctrl = vidioc_s_ctrl,
469 .vidioc_queryctrl = vidioc_queryctrl,
470 .vidioc_streamon = vidioc_streamon,
471 .vidioc_streamoff = vidioc_streamoff,
472 .vidioc_log_status = vidioc_log_status,
473 .vidioc_g_priority = vidioc_g_priority,
474 .vidioc_s_priority = vidioc_s_priority,
475#ifdef CONFIG_VIDEO_V4L1_COMPAT
476 .vidiocgmbuf = vidiocgmbuf,
477#endif
478#ifdef TUNER_FLAG
479 .vidioc_g_tuner = vidioc_g_tuner,
480 .vidioc_s_tuner = vidioc_s_tuner,
481 .vidioc_g_frequency = vidioc_g_frequency,
482 .vidioc_s_frequency = vidioc_s_frequency,
483#endif
484#ifdef CONFIG_VIDEO_ADV_DEBUG
485 .vidioc_g_register = vidioc_g_register,
486 .vidioc_s_register = vidioc_s_register,
487#endif
488};
489
490struct video_device cx25821_videoioctl_template = {
491 .name = "cx25821-videoioctl",
492 .fops = &video_fops,
493 .minor = -1,
494 .ioctl_ops = &video_ioctl_ops,
495 .tvnorms = CX25821_NORMS,
496 .current_norm = V4L2_STD_NTSC_M,
497};
498
499
500
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c
new file mode 100644
index 00000000000..4738e9184a8
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups10.c
@@ -0,0 +1,443 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH10];
34
35
36 /* add jump to stopper */
37 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
38 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
39 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
40
41 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
42
43 if (!list_empty(&q->queued)) {
44 list_add_tail(&buf->vb.queue, &q->queued);
45 buf->vb.state = VIDEOBUF_QUEUED;
46 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH10]);
51 buf->vb.state = VIDEOBUF_ACTIVE;
52 buf->count = q->count++;
53 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
54 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
55 buf, buf->vb. i, buf->count, q->count);
56 } else {
57 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
58 if (prev->vb.width == buf->vb.width &&
59 prev->vb.height == buf->vb.height &&
60 prev->fmt == buf->fmt) {
61 list_add_tail(&buf->vb.queue, &q->active);
62 buf->vb.state = VIDEOBUF_ACTIVE;
63 buf->count = q->count++;
64 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
65
66 /* 64 bit bits 63-32 */
67 prev->risc.jmp[2] = cpu_to_le32(0);
68 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
69
70 } else {
71 list_add_tail(&buf->vb.queue, &q->queued);
72 buf->vb.state = VIDEOBUF_QUEUED;
73 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
74 }
75 }
76
77 if (list_empty(&q->active))
78 {
79 dprintk(2, "active queue empty!\n");
80 }
81}
82
83
84static struct videobuf_queue_ops cx25821_video_qops = {
85 .buf_setup = buffer_setup,
86 .buf_prepare = buffer_prepare,
87 .buf_queue = buffer_queue,
88 .buf_release = buffer_release,
89};
90
91
92static int video_open(struct file *file)
93{
94 int minor = video_devdata(file)->minor;
95 struct cx25821_dev *h, *dev = NULL;
96 struct cx25821_fh *fh;
97 struct list_head *list;
98 enum v4l2_buf_type type = 0;
99
100 lock_kernel();
101 list_for_each(list, &cx25821_devlist)
102 {
103 h = list_entry(list, struct cx25821_dev, devlist);
104
105 if (h->video_dev[SRAM_CH10] && h->video_dev[SRAM_CH10]->minor == minor) {
106 dev = h;
107 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
108 }
109 }
110
111 if (NULL == dev) {
112 unlock_kernel();
113 return -ENODEV;
114 }
115
116 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
117
118 /* allocate + initialize per filehandle data */
119 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
120 if (NULL == fh) {
121 unlock_kernel();
122 return -ENOMEM;
123 }
124
125 file->private_data = fh;
126 fh->dev = dev;
127 fh->type = type;
128 fh->width = 720;
129
130 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
131 fh->height = 576;
132 else
133 fh->height = 480;
134
135
136 dev->channel_opened = 9;
137 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
138
139 v4l2_prio_open(&dev->prio,&fh->prio);
140
141 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
142 &dev->pci->dev, &dev->slock,
143 V4L2_BUF_TYPE_VIDEO_CAPTURE,
144 V4L2_FIELD_INTERLACED,
145 sizeof(struct cx25821_buffer),
146 fh);
147
148 dprintk(1, "post videobuf_queue_init()\n");
149 unlock_kernel();
150
151 return 0;
152}
153
154static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
155{
156 struct cx25821_fh *fh = file->private_data;
157
158 switch (fh->type)
159 {
160 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
161 if (res_locked(fh->dev, RESOURCE_VIDEO10))
162 return -EBUSY;
163
164 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
165
166 default:
167 BUG();
168 return 0;
169 }
170}
171
172static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
173{
174 struct cx25821_fh *fh = file->private_data;
175 struct cx25821_buffer *buf;
176
177 if (res_check(fh, RESOURCE_VIDEO10)) {
178 /* streaming capture */
179 if (list_empty(&fh->vidq.stream))
180 return POLLERR;
181 buf = list_entry(fh->vidq.stream.next,
182 struct cx25821_buffer, vb.stream);
183 } else {
184 /* read() capture */
185 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
186 if (NULL == buf)
187 return POLLERR;
188 }
189
190 poll_wait(file, &buf->vb.done, wait);
191 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
192 return POLLIN|POLLRDNORM;
193 return 0;
194}
195
196static int video_release(struct file *file)
197{
198 struct cx25821_fh *fh = file->private_data;
199 struct cx25821_dev *dev = fh->dev;
200
201 //stop the risc engine and fifo
202 //cx_write(channel10->dma_ctl, 0);
203
204 /* stop video capture */
205 if (res_check(fh, RESOURCE_VIDEO10)) {
206 videobuf_queue_cancel(&fh->vidq);
207 res_free(dev, fh, RESOURCE_VIDEO10);
208 }
209
210 if (fh->vidq.read_buf) {
211 buffer_release(&fh->vidq, fh->vidq.read_buf);
212 kfree(fh->vidq.read_buf);
213 }
214
215 videobuf_mmap_free(&fh->vidq);
216
217 v4l2_prio_close(&dev->prio,&fh->prio);
218
219 file->private_data = NULL;
220 kfree(fh);
221
222 return 0;
223}
224
225
226static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
227{
228 struct cx25821_fh *fh = priv;
229 struct cx25821_dev *dev = fh->dev;
230
231 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
232 {
233 return -EINVAL;
234 }
235
236 if (unlikely(i != fh->type))
237 {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO10))))
242 {
243 return -EBUSY;
244 }
245
246 return videobuf_streamon(get_queue(fh));
247}
248
249static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
250{
251 struct cx25821_fh *fh = priv;
252 struct cx25821_dev *dev = fh->dev;
253 int err, res;
254
255 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
256 return -EINVAL;
257 if (i != fh->type)
258 return -EINVAL;
259
260 res = get_resource(fh, RESOURCE_VIDEO10);
261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0)
263 return err;
264 res_free(dev, fh, res);
265 return 0;
266}
267
268
269static long video_ioctl_upstream10(struct file *file, unsigned int cmd, unsigned long arg)
270{
271 struct cx25821_fh *fh = file->private_data;
272 struct cx25821_dev *dev = fh->dev;
273 int command = 0;
274 struct upstream_user_struct *data_from_user;
275
276
277 data_from_user = (struct upstream_user_struct *)arg;
278
279 if( !data_from_user )
280 {
281 printk("cx25821 in %s(): Upstream data is INVALID. Returning.\n", __func__);
282 return 0;
283 }
284
285 command = data_from_user->command;
286
287 if( command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO )
288 {
289 return 0;
290 }
291
292 dev->input_filename_ch2 = data_from_user->input_filename;
293 dev->input_audiofilename = data_from_user->input_filename;
294 dev->vid_stdname_ch2 = data_from_user->vid_stdname;
295 dev->pixel_format_ch2 = data_from_user->pixel_format;
296 dev->channel_select_ch2 = data_from_user->channel_select;
297 dev->command_ch2 = data_from_user->command;
298
299
300 switch(command)
301 {
302 case UPSTREAM_START_VIDEO:
303 cx25821_start_upstream_video_ch2(dev, data_from_user);
304 break;
305
306 case UPSTREAM_STOP_VIDEO:
307 cx25821_stop_upstream_video_ch2(dev);
308 break;
309 }
310
311 return 0;
312}
313
314
315static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
316{
317 struct cx25821_fh *fh = priv;
318 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
319 int err;
320
321 if (fh)
322 {
323 err = v4l2_prio_check(&dev->prio, &fh->prio);
324 if (0 != err)
325 return err;
326 }
327
328 dprintk(2, "%s()\n", __func__);
329 err = vidioc_try_fmt_vid_cap(file, priv, f);
330
331 if (0 != err)
332 return err;
333 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
334 fh->width = f->fmt.pix.width;
335 fh->height = f->fmt.pix.height;
336 fh->vidq.field = f->fmt.pix.field;
337 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
338 cx25821_call_all(dev, video, s_fmt, f);
339 return 0;
340}
341
342static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
343{
344 struct cx25821_fh *fh = priv;
345 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346}
347
348static int vidioc_log_status (struct file *file, void *priv)
349{
350 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
351 char name[32 + 2];
352
353 snprintf(name, sizeof(name), "%s/2", dev->name);
354 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
355 dev->name);
356 cx25821_call_all(dev, core, log_status);
357 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
358 dev->name);
359 return 0;
360}
361
362static int vidioc_s_ctrl(struct file *file, void *priv,
363 struct v4l2_control *ctl)
364{
365 struct cx25821_fh *fh = priv;
366 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
367 int err;
368
369 if (fh)
370 {
371 err = v4l2_prio_check(&dev->prio, &fh->prio);
372 if (0 != err)
373 return err;
374 }
375
376 return 0;
377}
378
379//exported stuff
380static const struct v4l2_file_operations video_fops = {
381 .owner = THIS_MODULE,
382 .open = video_open,
383 .release = video_release,
384 .read = video_read,
385 .poll = video_poll,
386 .mmap = video_mmap,
387 .ioctl = video_ioctl_upstream10,
388};
389
390static const struct v4l2_ioctl_ops video_ioctl_ops = {
391 .vidioc_querycap = vidioc_querycap,
392 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
393 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
394 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
395 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
396 .vidioc_reqbufs = vidioc_reqbufs,
397 .vidioc_querybuf = vidioc_querybuf,
398 .vidioc_qbuf = vidioc_qbuf,
399 .vidioc_dqbuf = vidioc_dqbuf,
400#ifdef TUNER_FLAG
401 .vidioc_s_std = vidioc_s_std,
402 .vidioc_querystd = vidioc_querystd,
403#endif
404 .vidioc_cropcap = vidioc_cropcap,
405 .vidioc_s_crop = vidioc_s_crop,
406 .vidioc_g_crop = vidioc_g_crop,
407 .vidioc_enum_input = vidioc_enum_input,
408 .vidioc_g_input = vidioc_g_input,
409 .vidioc_s_input = vidioc_s_input,
410 .vidioc_g_ctrl = vidioc_g_ctrl,
411 .vidioc_s_ctrl = vidioc_s_ctrl,
412 .vidioc_queryctrl = vidioc_queryctrl,
413 .vidioc_streamon = vidioc_streamon,
414 .vidioc_streamoff = vidioc_streamoff,
415 .vidioc_log_status = vidioc_log_status,
416 .vidioc_g_priority = vidioc_g_priority,
417 .vidioc_s_priority = vidioc_s_priority,
418#ifdef CONFIG_VIDEO_V4L1_COMPAT
419 .vidiocgmbuf = vidiocgmbuf,
420#endif
421#ifdef TUNER_FLAG
422 .vidioc_g_tuner = vidioc_g_tuner,
423 .vidioc_s_tuner = vidioc_s_tuner,
424 .vidioc_g_frequency = vidioc_g_frequency,
425 .vidioc_s_frequency = vidioc_s_frequency,
426#endif
427#ifdef CONFIG_VIDEO_ADV_DEBUG
428 .vidioc_g_register = vidioc_g_register,
429 .vidioc_s_register = vidioc_s_register,
430#endif
431};
432
433struct video_device cx25821_video_template10 = {
434 .name = "cx25821-upstream10",
435 .fops = &video_fops,
436 .minor = -1,
437 .ioctl_ops = &video_ioctl_ops,
438 .tvnorms = CX25821_NORMS,
439 .current_norm = V4L2_STD_NTSC_M,
440};
441
442
443
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c
new file mode 100644
index 00000000000..7832fd1603b
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups9.c
@@ -0,0 +1,441 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#include "cx25821-video.h"
25
26
27static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
28{
29 struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH09];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf, &dev->sram_channels[SRAM_CH09]);
50 buf->vb.state = VIDEOBUF_ACTIVE;
51 buf->count = q->count++;
52 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
53 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
54 buf, buf->vb. i, buf->count, q->count);
55 } else {
56 prev = list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
57 if (prev->vb.width == buf->vb.width &&
58 prev->vb.height == buf->vb.height &&
59 prev->fmt == buf->fmt) {
60 list_add_tail(&buf->vb.queue, &q->active);
61 buf->vb.state = VIDEOBUF_ACTIVE;
62 buf->count = q->count++;
63 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
64
65 /* 64 bit bits 63-32 */
66 prev->risc.jmp[2] = cpu_to_le32(0);
67 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", buf, buf->vb.i, buf->count);
68
69 } else {
70 list_add_tail(&buf->vb.queue, &q->queued);
71 buf->vb.state = VIDEOBUF_QUEUED;
72 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i);
73 }
74 }
75
76 if (list_empty(&q->active))
77 {
78 dprintk(2, "active queue empty!\n");
79 }
80}
81
82
83static struct videobuf_queue_ops cx25821_video_qops = {
84 .buf_setup = buffer_setup,
85 .buf_prepare = buffer_prepare,
86 .buf_queue = buffer_queue,
87 .buf_release = buffer_release,
88};
89
90
91static int video_open(struct file *file)
92{
93 int minor = video_devdata(file)->minor;
94 struct cx25821_dev *h, *dev = NULL;
95 struct cx25821_fh *fh;
96 struct list_head *list;
97 enum v4l2_buf_type type = 0;
98
99 lock_kernel();
100 list_for_each(list, &cx25821_devlist)
101 {
102 h = list_entry(list, struct cx25821_dev, devlist);
103
104 if (h->video_dev[SRAM_CH09] && h->video_dev[SRAM_CH09]->minor == minor)
105 {
106 dev = h;
107 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
108 }
109 }
110
111 if (NULL == dev) {
112 unlock_kernel();
113 return -ENODEV;
114 }
115
116 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
117
118 /* allocate + initialize per filehandle data */
119 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
120 if (NULL == fh) {
121 unlock_kernel();
122 return -ENOMEM;
123 }
124
125 file->private_data = fh;
126 fh->dev = dev;
127 fh->type = type;
128 fh->width = 720;
129
130 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
131 fh->height = 576;
132 else
133 fh->height = 480;
134
135 dev->channel_opened = 8;
136 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
137
138 v4l2_prio_open(&dev->prio,&fh->prio);
139
140 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
141 &dev->pci->dev, &dev->slock,
142 V4L2_BUF_TYPE_VIDEO_CAPTURE,
143 V4L2_FIELD_INTERLACED,
144 sizeof(struct cx25821_buffer),
145 fh);
146
147 dprintk(1, "post videobuf_queue_init()\n");
148 unlock_kernel();
149
150 return 0;
151}
152
153static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
154{
155 struct cx25821_fh *fh = file->private_data;
156
157 switch (fh->type)
158 {
159 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
160 if (res_locked(fh->dev, RESOURCE_VIDEO9))
161 return -EBUSY;
162
163 return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK);
164
165 default:
166 BUG();
167 return 0;
168 }
169}
170
171static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
172{
173 struct cx25821_fh *fh = file->private_data;
174 struct cx25821_buffer *buf;
175
176 if (res_check(fh, RESOURCE_VIDEO9)) {
177 /* streaming capture */
178 if (list_empty(&fh->vidq.stream))
179 return POLLERR;
180 buf = list_entry(fh->vidq.stream.next,
181 struct cx25821_buffer, vb.stream);
182 } else {
183 /* read() capture */
184 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
185 if (NULL == buf)
186 return POLLERR;
187 }
188
189 poll_wait(file, &buf->vb.done, wait);
190 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
191 return POLLIN|POLLRDNORM;
192 return 0;
193}
194
195
196static int video_release(struct file *file)
197{
198 struct cx25821_fh *fh = file->private_data;
199 struct cx25821_dev *dev = fh->dev;
200
201 //stop the risc engine and fifo
202 //cx_write(channel9->dma_ctl, 0);
203
204 /* stop video capture */
205 if (res_check(fh, RESOURCE_VIDEO9)) {
206 videobuf_queue_cancel(&fh->vidq);
207 res_free(dev, fh, RESOURCE_VIDEO9);
208 }
209
210 if (fh->vidq.read_buf) {
211 buffer_release(&fh->vidq, fh->vidq.read_buf);
212 kfree(fh->vidq.read_buf);
213 }
214
215 videobuf_mmap_free(&fh->vidq);
216
217 v4l2_prio_close(&dev->prio,&fh->prio);
218
219 file->private_data = NULL;
220 kfree(fh);
221
222 return 0;
223}
224
225
226static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
227{
228 struct cx25821_fh *fh = priv;
229 struct cx25821_dev *dev = fh->dev;
230
231 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
232 {
233 return -EINVAL;
234 }
235
236 if (unlikely(i != fh->type))
237 {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO9))))
242 {
243 return -EBUSY;
244 }
245
246 return videobuf_streamon(get_queue(fh));
247}
248
249static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
250{
251 struct cx25821_fh *fh = priv;
252 struct cx25821_dev *dev = fh->dev;
253 int err, res;
254
255 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
256 return -EINVAL;
257 if (i != fh->type)
258 return -EINVAL;
259
260 res = get_resource(fh, RESOURCE_VIDEO9);
261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0)
263 return err;
264 res_free(dev, fh, res);
265 return 0;
266}
267
268
269static long video_ioctl_upstream9(struct file *file, unsigned int cmd, unsigned long arg)
270{
271 struct cx25821_fh *fh = file->private_data;
272 struct cx25821_dev *dev = fh->dev;
273 int command = 0;
274 struct upstream_user_struct *data_from_user;
275
276
277 data_from_user = (struct upstream_user_struct *)arg;
278
279 if( !data_from_user )
280 {
281 printk("cx25821 in %s(): Upstream data is INVALID. Returning.\n", __func__);
282 return 0;
283 }
284
285 command = data_from_user->command;
286
287 if( command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO )
288 {
289 return 0;
290 }
291
292
293 dev->input_filename = data_from_user->input_filename;
294 dev->input_audiofilename = data_from_user->input_filename;
295 dev->vid_stdname = data_from_user->vid_stdname;
296 dev->pixel_format = data_from_user->pixel_format;
297 dev->channel_select = data_from_user->channel_select;
298 dev->command = data_from_user->command;
299
300
301 switch(command)
302 {
303 case UPSTREAM_START_VIDEO:
304 cx25821_start_upstream_video_ch1(dev, data_from_user);
305 break;
306
307 case UPSTREAM_STOP_VIDEO:
308 cx25821_stop_upstream_video_ch1(dev);
309 break;
310 }
311
312 return 0;
313}
314
315
316static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
317{
318 struct cx25821_fh *fh = priv;
319 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
320 int err;
321
322 if (fh)
323 {
324 err = v4l2_prio_check(&dev->prio, &fh->prio);
325 if (0 != err)
326 return err;
327 }
328
329 dprintk(2, "%s()\n", __func__);
330 err = vidioc_try_fmt_vid_cap(file, priv, f);
331
332 if (0 != err)
333 return err;
334 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
335 fh->width = f->fmt.pix.width;
336 fh->height = f->fmt.pix.height;
337 fh->vidq.field = f->fmt.pix.field;
338 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field);
339 cx25821_call_all(dev, video, s_fmt, f);
340 return 0;
341}
342
343static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
344{
345 struct cx25821_fh *fh = priv;
346 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347}
348static int vidioc_log_status (struct file *file, void *priv)
349{
350 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
351 char name[32 + 2];
352
353 snprintf(name, sizeof(name), "%s/2", dev->name);
354 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
355 dev->name);
356 cx25821_call_all(dev, core, log_status);
357 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
358 dev->name);
359 return 0;
360}
361
362static int vidioc_s_ctrl(struct file *file, void *priv,
363 struct v4l2_control *ctl)
364{
365 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
366 struct cx25821_fh *fh = priv;
367 int err;
368 if (fh)
369 {
370 err = v4l2_prio_check(&dev->prio, &fh->prio);
371 if (0 != err)
372 return err;
373 }
374
375 return 0;
376}
377// exported stuff
378static const struct v4l2_file_operations video_fops = {
379 .owner = THIS_MODULE,
380 .open = video_open,
381 .release = video_release,
382 .read = video_read,
383 .poll = video_poll,
384 .mmap = video_mmap,
385 .ioctl = video_ioctl_upstream9,
386};
387
388static const struct v4l2_ioctl_ops video_ioctl_ops = {
389 .vidioc_querycap = vidioc_querycap,
390 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
391 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
392 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
393 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
394 .vidioc_reqbufs = vidioc_reqbufs,
395 .vidioc_querybuf = vidioc_querybuf,
396 .vidioc_qbuf = vidioc_qbuf,
397 .vidioc_dqbuf = vidioc_dqbuf,
398#ifdef TUNER_FLAG
399 .vidioc_s_std = vidioc_s_std,
400 .vidioc_querystd = vidioc_querystd,
401#endif
402 .vidioc_cropcap = vidioc_cropcap,
403 .vidioc_s_crop = vidioc_s_crop,
404 .vidioc_g_crop = vidioc_g_crop,
405 .vidioc_enum_input = vidioc_enum_input,
406 .vidioc_g_input = vidioc_g_input,
407 .vidioc_s_input = vidioc_s_input,
408 .vidioc_g_ctrl = vidioc_g_ctrl,
409 .vidioc_s_ctrl = vidioc_s_ctrl,
410 .vidioc_queryctrl = vidioc_queryctrl,
411 .vidioc_streamon = vidioc_streamon,
412 .vidioc_streamoff = vidioc_streamoff,
413 .vidioc_log_status = vidioc_log_status,
414 .vidioc_g_priority = vidioc_g_priority,
415 .vidioc_s_priority = vidioc_s_priority,
416#ifdef CONFIG_VIDEO_V4L1_COMPAT
417 .vidiocgmbuf = vidiocgmbuf,
418#endif
419#ifdef TUNER_FLAG
420 .vidioc_g_tuner = vidioc_g_tuner,
421 .vidioc_s_tuner = vidioc_s_tuner,
422 .vidioc_g_frequency = vidioc_g_frequency,
423 .vidioc_s_frequency = vidioc_s_frequency,
424#endif
425#ifdef CONFIG_VIDEO_ADV_DEBUG
426 .vidioc_g_register = vidioc_g_register,
427 .vidioc_s_register = vidioc_s_register,
428#endif
429};
430
431struct video_device cx25821_video_template9 = {
432 .name = "cx25821-upstream9",
433 .fops = &video_fops,
434 .minor = -1,
435 .ioctl_ops = &video_ioctl_ops,
436 .tvnorms = CX25821_NORMS,
437 .current_norm = V4L2_STD_NTSC_M,
438};
439
440
441
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
new file mode 100644
index 00000000000..074ea34c3b2
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821.h
@@ -0,0 +1,589 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
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#ifndef CX25821_H_
26#define CX25821_H_
27
28#include <linux/pci.h>
29#include <linux/i2c.h>
30#include <linux/i2c-algo-bit.h>
31#include <linux/interrupt.h>
32#include <linux/delay.h>
33#include <linux/sched.h>
34#include <linux/kdev_t.h>
35
36#include <media/v4l2-common.h>
37#include <media/v4l2-device.h>
38#include <media/tuner.h>
39#include <media/tveeprom.h>
40#include <media/videobuf-dma-sg.h>
41#include <media/videobuf-dvb.h>
42
43#include "btcx-risc.h"
44#include "cx25821-reg.h"
45#include "cx25821-medusa-reg.h"
46#include "cx25821-sram.h"
47#include "cx25821-audio.h"
48#include "media/cx2341x.h"
49
50#include <linux/version.h>
51#include <linux/mutex.h>
52
53#define CX25821_VERSION_CODE KERNEL_VERSION(0, 0, 106)
54
55#define UNSET (-1U)
56#define NO_SYNC_LINE (-1U)
57
58#define CX25821_MAXBOARDS 2
59
60#define TRUE 1
61#define FALSE 0
62#define LINE_SIZE_D1 1440
63
64// Number of decoders and encoders
65#define MAX_DECODERS 8
66#define MAX_ENCODERS 2
67#define QUAD_DECODERS 4
68#define MAX_CAMERAS 16
69
70/* Max number of inputs by card */
71#define MAX_CX25821_INPUT 8
72#define INPUT(nr) (&cx25821_boards[dev->board].input[nr])
73#define RESOURCE_VIDEO0 1
74#define RESOURCE_VIDEO1 2
75#define RESOURCE_VIDEO2 4
76#define RESOURCE_VIDEO3 8
77#define RESOURCE_VIDEO4 16
78#define RESOURCE_VIDEO5 32
79#define RESOURCE_VIDEO6 64
80#define RESOURCE_VIDEO7 128
81#define RESOURCE_VIDEO8 256
82#define RESOURCE_VIDEO9 512
83#define RESOURCE_VIDEO10 1024
84#define RESOURCE_VIDEO11 2048
85#define RESOURCE_VIDEO_IOCTL 4096
86
87
88#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
89
90#define UNKNOWN_BOARD 0
91#define CX25821_BOARD 1
92
93/* Currently supported by the driver */
94#define CX25821_NORMS (\
95 V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \
96 V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
97 V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_H | \
98 V4L2_STD_PAL_Nc )
99
100#define CX25821_BOARD_CONEXANT_ATHENA10 1
101#define MAX_VID_CHANNEL_NUM 12
102#define VID_CHANNEL_NUM 8
103
104struct cx25821_fmt {
105 char *name;
106 u32 fourcc; /* v4l2 format id */
107 int depth;
108 int flags;
109 u32 cxformat;
110};
111
112struct cx25821_ctrl {
113 struct v4l2_queryctrl v;
114 u32 off;
115 u32 reg;
116 u32 mask;
117 u32 shift;
118};
119
120struct cx25821_tvnorm {
121 char *name;
122 v4l2_std_id id;
123 u32 cxiformat;
124 u32 cxoformat;
125};
126
127struct cx25821_fh {
128 struct cx25821_dev *dev;
129 enum v4l2_buf_type type;
130 int radio;
131 u32 resources;
132
133 enum v4l2_priority prio;
134
135 /* video overlay */
136 struct v4l2_window win;
137 struct v4l2_clip *clips;
138 unsigned int nclips;
139
140 /* video capture */
141 struct cx25821_fmt *fmt;
142 unsigned int width, height;
143
144 /* vbi capture */
145 struct videobuf_queue vidq;
146 struct videobuf_queue vbiq;
147
148 /* H264 Encoder specifics ONLY */
149 struct videobuf_queue mpegq;
150 atomic_t v4l_reading;
151};
152
153enum cx25821_itype {
154 CX25821_VMUX_COMPOSITE = 1,
155 CX25821_VMUX_SVIDEO,
156 CX25821_VMUX_DEBUG,
157 CX25821_RADIO,
158};
159
160enum cx25821_src_sel_type {
161 CX25821_SRC_SEL_EXT_656_VIDEO = 0,
162 CX25821_SRC_SEL_PARALLEL_MPEG_VIDEO
163};
164
165/* buffer for one video frame */
166struct cx25821_buffer {
167 /* common v4l buffer stuff -- must be first */
168 struct videobuf_buffer vb;
169
170 /* cx25821 specific */
171 unsigned int bpl;
172 struct btcx_riscmem risc;
173 struct cx25821_fmt *fmt;
174 u32 count;
175};
176
177struct cx25821_input {
178 enum cx25821_itype type;
179 unsigned int vmux;
180 u32 gpio0, gpio1, gpio2, gpio3;
181};
182
183typedef enum {
184 CX25821_UNDEFINED = 0,
185 CX25821_RAW,
186 CX25821_264
187} port_t;
188
189struct cx25821_board {
190 char *name;
191 port_t porta, portb, portc;
192 unsigned int tuner_type;
193 unsigned int radio_type;
194 unsigned char tuner_addr;
195 unsigned char radio_addr;
196
197 u32 clk_freq;
198 struct cx25821_input input[2];
199};
200
201struct cx25821_subid {
202 u16 subvendor;
203 u16 subdevice;
204 u32 card;
205};
206
207struct cx25821_i2c {
208 struct cx25821_dev *dev;
209
210 int nr;
211
212 /* i2c i/o */
213 struct i2c_adapter i2c_adap;
214 struct i2c_algo_bit_data i2c_algo;
215 struct i2c_client i2c_client;
216 u32 i2c_rc;
217
218 /* cx25821 registers used for raw addess */
219 u32 i2c_period;
220 u32 reg_ctrl;
221 u32 reg_stat;
222 u32 reg_addr;
223 u32 reg_rdata;
224 u32 reg_wdata;
225};
226
227struct cx25821_dmaqueue {
228 struct list_head active;
229 struct list_head queued;
230 struct timer_list timeout;
231 struct btcx_riscmem stopper;
232 u32 count;
233};
234
235struct cx25821_data {
236 struct cx25821_dev *dev;
237 struct sram_channel *channel;
238};
239
240struct cx25821_dev {
241 struct list_head devlist;
242 atomic_t refcount;
243 struct v4l2_device v4l2_dev;
244
245 struct v4l2_prio_state prio;
246
247 /* pci stuff */
248 struct pci_dev *pci;
249 unsigned char pci_rev, pci_lat;
250 int pci_bus, pci_slot;
251 u32 base_io_addr;
252 u32 __iomem *lmmio;
253 u8 __iomem *bmmio;
254 int pci_irqmask;
255 int hwrevision;
256
257 u32 clk_freq;
258
259 /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
260 struct cx25821_i2c i2c_bus[3];
261
262 int nr;
263 struct mutex lock;
264
265 /* board details */
266 unsigned int board;
267 char name[32];
268
269 /* sram configuration */
270 struct sram_channel *sram_channels;
271
272 /* Analog video */
273 u32 resources;
274 unsigned int input;
275 u32 tvaudio;
276 v4l2_std_id tvnorm;
277 unsigned int tuner_type;
278 unsigned char tuner_addr;
279 unsigned int radio_type;
280 unsigned char radio_addr;
281 unsigned int has_radio;
282 unsigned int videc_type;
283 unsigned char videc_addr;
284 unsigned short _max_num_decoders;
285
286 int ctl_bright;
287 int ctl_contrast;
288 int ctl_hue;
289 int ctl_saturation;
290
291 struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
292
293 /* Analog Audio Upstream */
294 int _audio_is_running;
295 int _audiopixel_format;
296 int _is_first_audio_frame;
297 int _audiofile_status;
298 int _audio_lines_count;
299 int _audioframe_count;
300 int _audio_upstream_channel_select;
301 int _last_index_irq; //The last interrupt index processed.
302
303 __le32 * _risc_audio_jmp_addr;
304 __le32 * _risc_virt_start_addr;
305 __le32 * _risc_virt_addr;
306 dma_addr_t _risc_phys_addr;
307 dma_addr_t _risc_phys_start_addr;
308
309 unsigned int _audiorisc_size;
310 unsigned int _audiodata_buf_size;
311 __le32 * _audiodata_buf_virt_addr;
312 dma_addr_t _audiodata_buf_phys_addr;
313 char *_audiofilename;
314
315 /* V4l */
316 u32 freq;
317 struct video_device *video_dev[MAX_VID_CHANNEL_NUM];
318 struct video_device *vbi_dev;
319 struct video_device *radio_dev;
320 struct video_device *ioctl_dev;
321
322 struct cx25821_dmaqueue vidq[MAX_VID_CHANNEL_NUM];
323 spinlock_t slock;
324
325 /* Video Upstream */
326 int _line_size;
327 int _prog_cnt;
328 int _pixel_format;
329 int _is_first_frame;
330 int _is_running;
331 int _file_status;
332 int _lines_count;
333 int _frame_count;
334 int _channel_upstream_select;
335 unsigned int _risc_size;
336
337 __le32 * _dma_virt_start_addr;
338 __le32 * _dma_virt_addr;
339 dma_addr_t _dma_phys_addr;
340 dma_addr_t _dma_phys_start_addr;
341
342 unsigned int _data_buf_size;
343 __le32 * _data_buf_virt_addr;
344 dma_addr_t _data_buf_phys_addr;
345 char * _filename;
346 char * _defaultname;
347
348
349 int _line_size_ch2;
350 int _prog_cnt_ch2;
351 int _pixel_format_ch2;
352 int _is_first_frame_ch2;
353 int _is_running_ch2;
354 int _file_status_ch2;
355 int _lines_count_ch2;
356 int _frame_count_ch2;
357 int _channel2_upstream_select;
358 unsigned int _risc_size_ch2;
359
360 __le32 * _dma_virt_start_addr_ch2;
361 __le32 * _dma_virt_addr_ch2;
362 dma_addr_t _dma_phys_addr_ch2;
363 dma_addr_t _dma_phys_start_addr_ch2;
364
365 unsigned int _data_buf_size_ch2;
366 __le32 * _data_buf_virt_addr_ch2;
367 dma_addr_t _data_buf_phys_addr_ch2;
368 char * _filename_ch2;
369 char * _defaultname_ch2;
370
371 /* MPEG Encoder ONLY settings */
372 u32 cx23417_mailbox;
373 struct cx2341x_mpeg_params mpeg_params;
374 struct video_device *v4l_device;
375 atomic_t v4l_reader_count;
376 struct cx25821_tvnorm encodernorm;
377
378 u32 upstream_riscbuf_size;
379 u32 upstream_databuf_size;
380 u32 upstream_riscbuf_size_ch2;
381 u32 upstream_databuf_size_ch2;
382 u32 audio_upstream_riscbuf_size;
383 u32 audio_upstream_databuf_size;
384 int _isNTSC;
385 int _frame_index;
386 int _audioframe_index;
387 struct workqueue_struct * _irq_queues;
388 struct work_struct _irq_work_entry;
389 struct workqueue_struct * _irq_queues_ch2;
390 struct work_struct _irq_work_entry_ch2;
391 struct workqueue_struct * _irq_audio_queues;
392 struct work_struct _audio_work_entry;
393 char *input_filename;
394 char *input_filename_ch2;
395 int _frame_index_ch2;
396 int _isNTSC_ch2;
397 char *vid_stdname_ch2;
398 int pixel_format_ch2;
399 int channel_select_ch2;
400 int command_ch2;
401 char *input_audiofilename;
402 char *vid_stdname;
403 int pixel_format;
404 int channel_select;
405 int command;
406 int pixel_formats[VID_CHANNEL_NUM];
407 int use_cif_resolution[VID_CHANNEL_NUM];
408 int cif_width[VID_CHANNEL_NUM];
409 int channel_opened;
410};
411
412
413struct upstream_user_struct {
414 char *input_filename;
415 char *vid_stdname;
416 int pixel_format;
417 int channel_select;
418 int command;
419};
420
421struct downstream_user_struct {
422 char *vid_stdname;
423 int pixel_format;
424 int cif_resolution_enable;
425 int cif_width;
426 int decoder_select;
427 int command;
428 int reg_address;
429 int reg_data;
430};
431
432extern struct upstream_user_struct *up_data;
433
434static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)
435{
436 return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev);
437}
438
439#define cx25821_call_all(dev, o, f, args...) \
440 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
441
442extern struct list_head cx25821_devlist;
443extern struct cx25821_board cx25821_boards[];
444extern struct cx25821_subid cx25821_subids[];
445
446#define SRAM_CH00 0 /* Video A */
447#define SRAM_CH01 1 /* Video B */
448#define SRAM_CH02 2 /* Video C */
449#define SRAM_CH03 3 /* Video D */
450#define SRAM_CH04 4 /* Video E */
451#define SRAM_CH05 5 /* Video F */
452#define SRAM_CH06 6 /* Video G */
453#define SRAM_CH07 7 /* Video H */
454
455#define SRAM_CH08 8 /* Audio A */
456#define SRAM_CH09 9 /* Video Upstream I */
457#define SRAM_CH10 10 /* Video Upstream J */
458#define SRAM_CH11 11 /* Audio Upstream AUD_CHANNEL_B */
459
460
461
462#define VID_UPSTREAM_SRAM_CHANNEL_I SRAM_CH09
463#define VID_UPSTREAM_SRAM_CHANNEL_J SRAM_CH10
464#define AUDIO_UPSTREAM_SRAM_CHANNEL_B SRAM_CH11
465#define VIDEO_IOCTL_CH 11
466
467struct sram_channel {
468 char *name;
469 u32 i;
470 u32 cmds_start;
471 u32 ctrl_start;
472 u32 cdt;
473 u32 fifo_start;
474 u32 fifo_size;
475 u32 ptr1_reg;
476 u32 ptr2_reg;
477 u32 cnt1_reg;
478 u32 cnt2_reg;
479 u32 int_msk;
480 u32 int_stat;
481 u32 int_mstat;
482 u32 dma_ctl;
483 u32 gpcnt_ctl;
484 u32 gpcnt;
485 u32 aud_length;
486 u32 aud_cfg;
487 u32 fld_aud_fifo_en;
488 u32 fld_aud_risc_en;
489
490 //For Upstream Video
491 u32 vid_fmt_ctl;
492 u32 vid_active_ctl1;
493 u32 vid_active_ctl2;
494 u32 vid_cdt_size;
495
496 u32 vip_ctl;
497 u32 pix_frmt;
498 u32 jumponly;
499 u32 irq_bit;
500};
501extern struct sram_channel cx25821_sram_channels[];
502
503#define STATUS_SUCCESS 0
504#define STATUS_UNSUCCESSFUL -1
505
506#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
507#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2))
508
509#define cx_andor(reg, mask, value) \
510 writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
511 ((value) & (mask)), dev->lmmio+((reg)>>2))
512
513#define cx_set(reg, bit) cx_andor((reg), (bit), (bit))
514#define cx_clear(reg, bit) cx_andor((reg), (bit), 0)
515
516#define Set_GPIO_Bit(Bit) (1 << Bit)
517#define Clear_GPIO_Bit(Bit) (~(1 << Bit))
518
519#define CX25821_ERR(fmt, args...) printk(KERN_ERR "cx25821(%d): " fmt, dev->board, ## args)
520#define CX25821_WARN(fmt, args...) printk(KERN_WARNING "cx25821(%d): " fmt, dev->board , ## args)
521#define CX25821_INFO(fmt, args...) printk(KERN_INFO "cx25821(%d): " fmt, dev->board , ## args)
522
523extern int cx25821_i2c_register(struct cx25821_i2c *bus);
524extern void cx25821_card_setup(struct cx25821_dev *dev);
525extern int cx25821_ir_init(struct cx25821_dev *dev);
526extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value);
527extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value);
528extern int cx25821_i2c_unregister(struct cx25821_i2c *bus);
529extern void cx25821_gpio_init(struct cx25821_dev *dev);
530extern void cx25821_set_gpiopin_direction( struct cx25821_dev *dev,
531 int pin_number,
532 int pin_logic_value);
533
534extern int medusa_video_init(struct cx25821_dev *dev);
535extern int medusa_set_videostandard(struct cx25821_dev *dev);
536extern void medusa_set_resolution(struct cx25821_dev *dev, int width, int decoder_select);
537extern int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder);
538extern int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder);
539extern int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder);
540extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder);
541
542extern int cx25821_sram_channel_setup(struct cx25821_dev *dev, struct sram_channel *ch, unsigned int bpl, u32 risc);
543
544extern int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
545 struct scatterlist *sglist,
546 unsigned int top_offset,
547 unsigned int bottom_offset,
548 unsigned int bpl,
549 unsigned int padding,
550 unsigned int lines);
551extern int cx25821_risc_databuffer_audio(struct pci_dev *pci,
552 struct btcx_riscmem *risc,
553 struct scatterlist *sglist,
554 unsigned int bpl,
555 unsigned int lines,
556 unsigned int lpi);
557extern void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf);
558extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,u32 reg, u32 mask, u32 value);
559extern void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch);
560extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, struct sram_channel *ch);
561
562
563extern struct cx25821_dev* cx25821_dev_get(struct pci_dev *pci);
564extern void cx25821_print_irqbits(char *name, char *tag, char **strings, int len, u32 bits, u32 mask);
565extern void cx25821_dev_unregister(struct cx25821_dev *dev);
566extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
567 struct sram_channel *ch,
568 unsigned int bpl, u32 risc);
569
570extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, int pixel_format);
571extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, int pixel_format);
572extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select);
573extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev);
574extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev);
575extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev);
576extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, struct upstream_user_struct *up_data);
577extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, struct upstream_user_struct *up_data);
578extern void cx25821_start_upstream_audio(struct cx25821_dev *dev, struct upstream_user_struct *up_data);
579extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev);
580extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev);
581extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev);
582extern int cx25821_sram_channel_setup_upstream( struct cx25821_dev *dev, struct sram_channel *ch, unsigned int bpl, u32 risc);
583extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel, u32 format);
584extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev);
585extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
586 struct pci_dev *pci,
587 struct video_device *template,
588 char *type);
589#endif