aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-21 12:03:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-21 12:03:10 -0400
commitc720f5655df159a630fa0290a0bd67c93e92b0bf (patch)
tree940d139d0ec1ff5201efddef6cc663166a8a2df3 /drivers/staging
parent33e6c1a0de818d3698cdab27c42915661011319d (diff)
parent84d6ae431f315e8973aac3c3fe1d550fc9240ef3 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (222 commits) V4L/DVB (13033): pt1: Don't use a deprecated DMA_BIT_MASK macro V4L/DVB (13029): radio-si4713: remove #include <linux/version.h> V4L/DVB (13027): go7007: convert printks to v4l2_info V4L/DVB (13026): s2250-board: Implement brightness and contrast controls V4L/DVB (13025): s2250-board: Fix memory leaks V4L/DVB (13024): go7007: Implement vidioc_g_std and vidioc_querystd V4L/DVB (13023): go7007: Merge struct gofh and go declarations V4L/DVB (13022): go7007: Fix mpeg controls V4L/DVB (13021): go7007: Fix whitespace and line lengths V4L/DVB (13020): go7007: Updates to Kconfig and Makefile V4L/DVB (13019): video: initial support for ADV7180 V4L/DVB (13018): kzalloc failure ignored in au8522_probe() V4L/DVB (13017): gspca: kmalloc failure ignored in sd_start() V4L/DVB (13016): kmalloc failure ignored in lgdt3304_attach() and s921_attach() V4L/DVB (13015): kmalloc failure ignored in m920x_firmware_download() V4L/DVB (13014): Add support for Compro VideoMate E800 (DVB-T part only) V4L/DVB (13013): FM TX: si4713: Kconfig: Fixed two typos. V4L/DVB (13012): uvc: introduce missing kfree V4L/DVB (13011): Change tuner type of BeholdTV cards V4L/DVB (13009): gspca - stv06xx-hdcs: Reduce exposure range ...
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/cx25821/Kconfig34
-rw-r--r--drivers/staging/cx25821/Makefile14
-rw-r--r--drivers/staging/cx25821/README6
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c789
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c804
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.h57
-rw-r--r--drivers/staging/cx25821/cx25821-audio.h57
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c434
-rw-r--r--drivers/staging/cx25821/cx25821-biffuncs.h45
-rw-r--r--drivers/staging/cx25821/cx25821-cards.c70
-rw-r--r--drivers/staging/cx25821/cx25821-core.c1551
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.c98
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.h2
-rw-r--r--drivers/staging/cx25821/cx25821-i2c.c419
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-defines.h51
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-reg.h455
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c869
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.h49
-rw-r--r--drivers/staging/cx25821/cx25821-reg.h1592
-rw-r--r--drivers/staging/cx25821/cx25821-sram.h261
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.c835
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.h101
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c894
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.h109
-rw-r--r--drivers/staging/cx25821/cx25821-video.c1299
-rw-r--r--drivers/staging/cx25821/cx25821-video.h194
-rw-r--r--drivers/staging/cx25821/cx25821-video0.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video1.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video2.c452
-rw-r--r--drivers/staging/cx25821/cx25821-video3.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video4.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video5.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video6.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video7.c449
-rw-r--r--drivers/staging/cx25821/cx25821-videoioctl.c496
-rw-r--r--drivers/staging/cx25821/cx25821-vidups10.c435
-rw-r--r--drivers/staging/cx25821/cx25821-vidups9.c433
-rw-r--r--drivers/staging/cx25821/cx25821.h602
-rw-r--r--drivers/staging/go7007/Kconfig84
-rw-r--r--drivers/staging/go7007/Makefile20
-rw-r--r--drivers/staging/go7007/go7007-driver.c35
-rw-r--r--drivers/staging/go7007/go7007-fw.c3
-rw-r--r--drivers/staging/go7007/go7007-i2c.c12
-rw-r--r--drivers/staging/go7007/go7007-priv.h6
-rw-r--r--drivers/staging/go7007/go7007-usb.c58
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c225
-rw-r--r--drivers/staging/go7007/go7007.txt176
-rw-r--r--drivers/staging/go7007/s2250-board.c107
-rw-r--r--drivers/staging/go7007/s2250-loader.c8
-rw-r--r--drivers/staging/go7007/snd-go7007.c2
-rw-r--r--drivers/staging/go7007/wis-tw9903.c3
53 files changed, 17103 insertions, 298 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 10d3fcffe91c..82b34893e5b5 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -47,6 +47,8 @@ source "drivers/staging/slicoss/Kconfig"
47 47
48source "drivers/staging/go7007/Kconfig" 48source "drivers/staging/go7007/Kconfig"
49 49
50source "drivers/staging/cx25821/Kconfig"
51
50source "drivers/staging/usbip/Kconfig" 52source "drivers/staging/usbip/Kconfig"
51 53
52source "drivers/staging/winbond/Kconfig" 54source "drivers/staging/winbond/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index c30093bae621..b1cad0d9ba72 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_STAGING) += staging.o
6obj-$(CONFIG_ET131X) += et131x/ 6obj-$(CONFIG_ET131X) += et131x/
7obj-$(CONFIG_SLICOSS) += slicoss/ 7obj-$(CONFIG_SLICOSS) += slicoss/
8obj-$(CONFIG_VIDEO_GO7007) += go7007/ 8obj-$(CONFIG_VIDEO_GO7007) += go7007/
9obj-$(CONFIG_VIDEO_CX25821) += cx25821/
9obj-$(CONFIG_USB_IP_COMMON) += usbip/ 10obj-$(CONFIG_USB_IP_COMMON) += usbip/
10obj-$(CONFIG_W35UND) += winbond/ 11obj-$(CONFIG_W35UND) += winbond/
11obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 12obj-$(CONFIG_PRISM2_USB) += wlan-ng/
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
new file mode 100644
index 000000000000..df7756a95fad
--- /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 000000000000..10f87f05d8e8
--- /dev/null
+++ b/drivers/staging/cx25821/Makefile
@@ -0,0 +1,14 @@
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/common/tuners
13EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
14EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/staging/cx25821/README b/drivers/staging/cx25821/README
new file mode 100644
index 000000000000..a9ba50b9888b
--- /dev/null
+++ b/drivers/staging/cx25821/README
@@ -0,0 +1,6 @@
1Todo:
2 - checkpatch.pl cleanups
3 - sparse cleanups
4
5Please send patches to linux-media@vger.kernel.org
6
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
new file mode 100644
index 000000000000..e0eef12759e4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -0,0 +1,789 @@
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#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/interrupt.h>
27#include <linux/vmalloc.h>
28#include <linux/dma-mapping.h>
29#include <linux/pci.h>
30
31#include <asm/delay.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/control.h>
36#include <sound/initval.h>
37#include <sound/tlv.h>
38
39#include "cx25821.h"
40#include "cx25821-reg.h"
41
42#define AUDIO_SRAM_CHANNEL SRAM_CH08
43
44#define dprintk(level,fmt, arg...) if (debug >= level) \
45 printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg)
46
47#define dprintk_core(level,fmt, arg...) if (debug >= level) \
48 printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg)
49
50/****************************************************************************
51 Data type declarations - Can be moded to a header file later
52 ****************************************************************************/
53
54static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];
55static int devno;
56
57struct cx25821_audio_dev {
58 struct cx25821_dev *dev;
59 struct cx25821_dmaqueue q;
60
61 /* pci i/o */
62 struct pci_dev *pci;
63
64 /* audio controls */
65 int irq;
66
67 struct snd_card *card;
68
69 unsigned long iobase;
70 spinlock_t reg_lock;
71 atomic_t count;
72
73 unsigned int dma_size;
74 unsigned int period_size;
75 unsigned int num_periods;
76
77 struct videobuf_dmabuf *dma_risc;
78
79 struct cx25821_buffer *buf;
80
81 struct snd_pcm_substream *substream;
82};
83typedef struct cx25821_audio_dev snd_cx25821_card_t;
84
85
86/****************************************************************************
87 Module global static vars
88 ****************************************************************************/
89
90static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
91static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
92static int enable[SNDRV_CARDS] = { 1,[1 ... (SNDRV_CARDS - 1)] = 1 };
93
94module_param_array(enable, bool, NULL, 0444);
95MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
96
97module_param_array(index, int, NULL, 0444);
98MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s).");
99
100/****************************************************************************
101 Module macros
102 ****************************************************************************/
103
104MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards");
105MODULE_AUTHOR("Hiep Huynh");
106MODULE_LICENSE("GPL");
107MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); //"{{Conexant,23881},"
108
109static unsigned int debug;
110module_param(debug, int, 0644);
111MODULE_PARM_DESC(debug, "enable debug messages");
112
113/****************************************************************************
114 Module specific funtions
115 ****************************************************************************/
116/* Constants taken from cx88-reg.h */
117#define AUD_INT_DN_RISCI1 (1 << 0)
118#define AUD_INT_UP_RISCI1 (1 << 1)
119#define AUD_INT_RDS_DN_RISCI1 (1 << 2)
120#define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */
121#define AUD_INT_UP_RISCI2 (1 << 5)
122#define AUD_INT_RDS_DN_RISCI2 (1 << 6)
123#define AUD_INT_DN_SYNC (1 << 12)
124#define AUD_INT_UP_SYNC (1 << 13)
125#define AUD_INT_RDS_DN_SYNC (1 << 14)
126#define AUD_INT_OPC_ERR (1 << 16)
127#define AUD_INT_BER_IRQ (1 << 20)
128#define AUD_INT_MCHG_IRQ (1 << 21)
129#define GP_COUNT_CONTROL_RESET 0x3
130
131#define PCI_MSK_AUD_EXT (1 << 4)
132#define PCI_MSK_AUD_INT (1 << 3)
133/*
134 * BOARD Specific: Sets audio DMA
135 */
136
137static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip)
138{
139 struct cx25821_buffer *buf = chip->buf;
140 struct cx25821_dev *dev = chip->dev;
141 struct sram_channel *audio_ch =
142 &cx25821_sram_channels[AUDIO_SRAM_CHANNEL];
143 u32 tmp = 0;
144
145 // enable output on the GPIO 0 for the MCLK ADC (Audio)
146 cx25821_set_gpiopin_direction(chip->dev, 0, 0);
147
148 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
149 cx_clear(AUD_INT_DMA_CTL,
150 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
151
152 /* setup fifo + format - out channel */
153 cx25821_sram_channel_setup_audio(chip->dev, audio_ch, buf->bpl,
154 buf->risc.dma);
155
156 /* sets bpl size */
157 cx_write(AUD_A_LNGTH, buf->bpl);
158
159 /* reset counter */
160 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); //GP_COUNT_CONTROL_RESET = 0x3
161 atomic_set(&chip->count, 0);
162
163 //Set the input mode to 16-bit
164 tmp = cx_read(AUD_A_CFG);
165 cx_write(AUD_A_CFG,
166 tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
167 FLD_AUD_CLK_ENABLE);
168
169 //printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d "
170 // "byte buffer\n", buf->bpl, audio_ch->cmds_start, cx_read(audio_ch->cmds_start + 12)>>1,
171 // chip->num_periods, buf->bpl * chip->num_periods);
172
173 /* Enables corresponding bits at AUD_INT_STAT */
174 cx_write(AUD_A_INT_MSK,
175 FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | FLD_AUD_DST_SYNC |
176 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,
187 tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN));
188
189 mdelay(100);
190 return 0;
191}
192
193/*
194 * BOARD Specific: Resets audio DMA
195 */
196static int _cx25821_stop_audio_dma(snd_cx25821_card_t * chip)
197{
198 struct cx25821_dev *dev = chip->dev;
199
200 /* stop dma */
201 cx_clear(AUD_INT_DMA_CTL,
202 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
203
204 /* disable irqs */
205 cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT);
206 cx_clear(AUD_A_INT_MSK,
207 AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | AUD_INT_DN_RISCI2 |
208 AUD_INT_DN_RISCI1);
209
210 return 0;
211}
212
213#define MAX_IRQ_LOOP 50
214
215/*
216 * BOARD Specific: IRQ dma bits
217 */
218static char *cx25821_aud_irqs[32] = {
219 "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
220 NULL, /* reserved */
221 "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
222 NULL, /* reserved */
223 "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
224 NULL, /* reserved */
225 "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
226 NULL, /* reserved */
227 "opc_err", "par_err", "rip_err", /* 16-18 */
228 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
229};
230
231/*
232 * BOARD Specific: Threats IRQ audio specific calls
233 */
234static void cx25821_aud_irq(snd_cx25821_card_t * chip, u32 status, u32 mask)
235{
236 struct cx25821_dev *dev = chip->dev;
237
238 if (0 == (status & mask)) {
239 return;
240 }
241
242 cx_write(AUD_A_INT_STAT, status);
243 if (debug > 1 || (status & mask & ~0xff))
244 cx25821_print_irqbits(dev->name, "irq aud",
245 cx25821_aud_irqs,
246 ARRAY_SIZE(cx25821_aud_irqs), status,
247 mask);
248
249 /* risc op code error */
250 if (status & AUD_INT_OPC_ERR) {
251 printk(KERN_WARNING "WARNING %s/1: Audio risc op code error\n",
252 dev->name);
253
254 cx_clear(AUD_INT_DMA_CTL,
255 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
256 cx25821_sram_channel_dump_audio(dev,
257 &cx25821_sram_channels
258 [AUDIO_SRAM_CHANNEL]);
259 }
260 if (status & AUD_INT_DN_SYNC) {
261 printk(KERN_WARNING "WARNING %s: Downstream sync error!\n",
262 dev->name);
263 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
264 return;
265 }
266
267 /* risc1 downstream */
268 if (status & AUD_INT_DN_RISCI1) {
269 atomic_set(&chip->count, cx_read(AUD_A_GPCNT));
270 snd_pcm_period_elapsed(chip->substream);
271 }
272}
273
274/*
275 * BOARD Specific: Handles IRQ calls
276 */
277static irqreturn_t cx25821_irq(int irq, void *dev_id)
278{
279 snd_cx25821_card_t *chip = dev_id;
280 struct cx25821_dev *dev = chip->dev;
281 u32 status, pci_status;
282 u32 audint_status, audint_mask;
283 int loop, handled = 0;
284 int audint_count = 0;
285
286 audint_status = cx_read(AUD_A_INT_STAT);
287 audint_mask = cx_read(AUD_A_INT_MSK);
288 audint_count = cx_read(AUD_A_GPCNT);
289 status = cx_read(PCI_INT_STAT);
290
291 for (loop = 0; loop < 1; loop++) {
292 status = cx_read(PCI_INT_STAT);
293 if (0 == status) {
294 status = cx_read(PCI_INT_STAT);
295 audint_status = cx_read(AUD_A_INT_STAT);
296 audint_mask = cx_read(AUD_A_INT_MSK);
297
298 if (status) {
299 handled = 1;
300 cx_write(PCI_INT_STAT, status);
301
302 cx25821_aud_irq(chip, audint_status,
303 audint_mask);
304 break;
305 } else
306 goto out;
307 }
308
309 handled = 1;
310 cx_write(PCI_INT_STAT, status);
311
312 cx25821_aud_irq(chip, audint_status, audint_mask);
313 }
314
315 pci_status = cx_read(PCI_INT_STAT);
316
317 if (handled)
318 cx_write(PCI_INT_STAT, pci_status);
319
320 out:
321 return IRQ_RETVAL(handled);
322}
323
324static int dsp_buffer_free(snd_cx25821_card_t * chip)
325{
326 BUG_ON(!chip->dma_size);
327
328 dprintk(2, "Freeing buffer\n");
329 videobuf_sg_dma_unmap(&chip->pci->dev, chip->dma_risc);
330 videobuf_dma_free(chip->dma_risc);
331 btcx_riscmem_free(chip->pci, &chip->buf->risc);
332 kfree(chip->buf);
333
334 chip->dma_risc = NULL;
335 chip->dma_size = 0;
336
337 return 0;
338}
339
340/****************************************************************************
341 ALSA PCM Interface
342 ****************************************************************************/
343
344/*
345 * Digital hardware definition
346 */
347#define DEFAULT_FIFO_SIZE 384
348static struct snd_pcm_hardware snd_cx25821_digital_hw = {
349 .info = SNDRV_PCM_INFO_MMAP |
350 SNDRV_PCM_INFO_INTERLEAVED |
351 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID,
352 .formats = SNDRV_PCM_FMTBIT_S16_LE,
353
354 .rates = SNDRV_PCM_RATE_48000,
355 .rate_min = 48000,
356 .rate_max = 48000,
357 .channels_min = 2,
358 .channels_max = 2,
359 /* Analog audio output will be full of clicks and pops if there
360 are not exactly four lines in the SRAM FIFO buffer. */
361 .period_bytes_min = DEFAULT_FIFO_SIZE / 3,
362 .period_bytes_max = DEFAULT_FIFO_SIZE / 3,
363 .periods_min = 1,
364 .periods_max = AUDIO_LINE_SIZE,
365 .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE), //128*128 = 16384 = 1024 * 16
366};
367
368/*
369 * audio pcm capture open callback
370 */
371static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
372{
373 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
374 struct snd_pcm_runtime *runtime = substream->runtime;
375 int err;
376 unsigned int bpl = 0;
377
378 if (!chip) {
379 printk(KERN_ERR "DEBUG: cx25821 can't find device struct."
380 " Can't proceed with open\n");
381 return -ENODEV;
382 }
383
384 err =
385 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 !=
394 DEFAULT_FIFO_SIZE) {
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 bpl = AUDIO_LINE_SIZE;
400 }
401 runtime->hw.period_bytes_min = bpl;
402 runtime->hw.period_bytes_max = bpl;
403 }
404
405 return 0;
406 _error:
407 dprintk(1, "Error opening PCM!\n");
408 return err;
409}
410
411/*
412 * audio close callback
413 */
414static int snd_cx25821_close(struct snd_pcm_substream *substream)
415{
416 return 0;
417}
418
419/*
420 * hw_params callback
421 */
422static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
423 struct snd_pcm_hw_params *hw_params)
424{
425 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
426 struct videobuf_dmabuf *dma;
427
428 struct cx25821_buffer *buf;
429 int ret;
430
431 if (substream->runtime->dma_area) {
432 dsp_buffer_free(chip);
433 substream->runtime->dma_area = NULL;
434 }
435
436 chip->period_size = params_period_bytes(hw_params);
437 chip->num_periods = params_periods(hw_params);
438 chip->dma_size = chip->period_size * params_periods(hw_params);
439
440 BUG_ON(!chip->dma_size);
441 BUG_ON(chip->num_periods & (chip->num_periods - 1));
442
443 buf = videobuf_sg_alloc(sizeof(*buf));
444 if (NULL == buf)
445 return -ENOMEM;
446
447 if (chip->period_size > AUDIO_LINE_SIZE) {
448 chip->period_size = AUDIO_LINE_SIZE;
449 }
450
451 buf->vb.memory = V4L2_MEMORY_MMAP;
452 buf->vb.field = V4L2_FIELD_NONE;
453 buf->vb.width = chip->period_size;
454 buf->bpl = chip->period_size;
455 buf->vb.height = chip->num_periods;
456 buf->vb.size = chip->dma_size;
457
458 dma = videobuf_to_dma(&buf->vb);
459 videobuf_dma_init(dma);
460
461 ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
462 (PAGE_ALIGN(buf->vb.size) >>
463 PAGE_SHIFT));
464 if (ret < 0)
465 goto error;
466
467 ret = videobuf_sg_dma_map(&chip->pci->dev, dma);
468 if (ret < 0)
469 goto error;
470
471 ret =
472 cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist,
473 buf->vb.width, buf->vb.height, 1);
474 if (ret < 0) {
475 printk(KERN_INFO
476 "DEBUG: ERROR after cx25821_risc_databuffer_audio() \n");
477 goto error;
478 }
479
480 /* Loop back to start of program */
481 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
482 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
483 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
484
485 buf->vb.state = VIDEOBUF_PREPARED;
486
487 chip->buf = buf;
488 chip->dma_risc = dma;
489
490 substream->runtime->dma_area = chip->dma_risc->vmalloc;
491 substream->runtime->dma_bytes = chip->dma_size;
492 substream->runtime->dma_addr = 0;
493
494 return 0;
495
496 error:
497 kfree(buf);
498 return ret;
499}
500
501/*
502 * hw free callback
503 */
504static int snd_cx25821_hw_free(struct snd_pcm_substream *substream)
505{
506 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
507
508 if (substream->runtime->dma_area) {
509 dsp_buffer_free(chip);
510 substream->runtime->dma_area = NULL;
511 }
512
513 return 0;
514}
515
516/*
517 * prepare callback
518 */
519static int snd_cx25821_prepare(struct snd_pcm_substream *substream)
520{
521 return 0;
522}
523
524/*
525 * trigger callback
526 */
527static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream,
528 int cmd)
529{
530 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
531 int err = 0;
532
533 /* Local interrupts are already disabled by ALSA */
534 spin_lock(&chip->reg_lock);
535
536 switch (cmd) {
537 case SNDRV_PCM_TRIGGER_START:
538 err = _cx25821_start_audio_dma(chip);
539 break;
540 case SNDRV_PCM_TRIGGER_STOP:
541 err = _cx25821_stop_audio_dma(chip);
542 break;
543 default:
544 err = -EINVAL;
545 break;
546 }
547
548 spin_unlock(&chip->reg_lock);
549
550 return err;
551}
552
553/*
554 * pointer callback
555 */
556static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream
557 *substream)
558{
559 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
560 struct snd_pcm_runtime *runtime = substream->runtime;
561 u16 count;
562
563 count = atomic_read(&chip->count);
564
565 return runtime->period_size * (count & (runtime->periods - 1));
566}
567
568/*
569 * page callback (needed for mmap)
570 */
571static struct page *snd_cx25821_page(struct snd_pcm_substream *substream,
572 unsigned long offset)
573{
574 void *pageptr = substream->runtime->dma_area + offset;
575
576 return vmalloc_to_page(pageptr);
577}
578
579/*
580 * operators
581 */
582static struct snd_pcm_ops snd_cx25821_pcm_ops = {
583 .open = snd_cx25821_pcm_open,
584 .close = snd_cx25821_close,
585 .ioctl = snd_pcm_lib_ioctl,
586 .hw_params = snd_cx25821_hw_params,
587 .hw_free = snd_cx25821_hw_free,
588 .prepare = snd_cx25821_prepare,
589 .trigger = snd_cx25821_card_trigger,
590 .pointer = snd_cx25821_pointer,
591 .page = snd_cx25821_page,
592};
593
594/*
595 * ALSA create a PCM device: Called when initializing the board. Sets up the name and hooks up
596 * the callbacks
597 */
598static int snd_cx25821_pcm(snd_cx25821_card_t * chip, int device, char *name)
599{
600 struct snd_pcm *pcm;
601 int err;
602
603 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
604 if (err < 0) {
605 printk(KERN_INFO "ERROR: FAILED snd_pcm_new() in %s\n",
606 __func__);
607 return err;
608 }
609 pcm->private_data = chip;
610 pcm->info_flags = 0;
611 strcpy(pcm->name, name);
612 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx25821_pcm_ops);
613
614 return 0;
615}
616
617/****************************************************************************
618 Basic Flow for Sound Devices
619 ****************************************************************************/
620
621/*
622 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
623 * Only boards with eeprom and byte 1 at eeprom=1 have it
624 */
625
626static struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = {
627 {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
628 {0,}
629};
630
631MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
632
633/*
634 * Not used in the function snd_cx25821_dev_free so removing
635 * from the file.
636 */
637/*
638static int snd_cx25821_free(snd_cx25821_card_t *chip)
639{
640 if (chip->irq >= 0)
641 free_irq(chip->irq, chip);
642
643 cx25821_dev_unregister(chip->dev);
644 pci_disable_device(chip->pci);
645
646 return 0;
647}
648*/
649
650/*
651 * Component Destructor
652 */
653static void snd_cx25821_dev_free(struct snd_card *card)
654{
655 snd_cx25821_card_t *chip = card->private_data;
656
657 //snd_cx25821_free(chip);
658 snd_card_free(chip->card);
659}
660
661/*
662 * Alsa Constructor - Component probe
663 */
664static int cx25821_audio_initdev(struct cx25821_dev *dev)
665{
666 struct snd_card *card;
667 snd_cx25821_card_t *chip;
668 int err;
669
670 if (devno >= SNDRV_CARDS) {
671 printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n",
672 __func__);
673 return (-ENODEV);
674 }
675
676 if (!enable[devno]) {
677 ++devno;
678 printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__);
679 return (-ENOENT);
680 }
681
682 err = snd_card_create(index[devno], id[devno], THIS_MODULE,
683 sizeof(snd_cx25821_card_t), &card);
684 if (err < 0) {
685 printk(KERN_INFO
686 "DEBUG ERROR: cannot create snd_card_new in %s\n",
687 __func__);
688 return err;
689 }
690
691 strcpy(card->driver, "cx25821");
692
693 /* Card "creation" */
694 card->private_free = snd_cx25821_dev_free;
695 chip = (snd_cx25821_card_t *) card->private_data;
696 spin_lock_init(&chip->reg_lock);
697
698 chip->dev = dev;
699 chip->card = card;
700 chip->pci = dev->pci;
701 chip->iobase = pci_resource_start(dev->pci, 0);
702
703 chip->irq = dev->pci->irq;
704
705 err = request_irq(dev->pci->irq, cx25821_irq,
706 IRQF_SHARED | IRQF_DISABLED, chip->dev->name, chip);
707
708 if (err < 0) {
709 printk(KERN_ERR "ERROR %s: can't get IRQ %d for ALSA\n",
710 chip->dev->name, dev->pci->irq);
711 goto error;
712 }
713
714 if ((err = snd_cx25821_pcm(chip, 0, "cx25821 Digital")) < 0) {
715 printk(KERN_INFO
716 "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
717 __func__);
718 goto error;
719 }
720
721 snd_card_set_dev(card, &chip->pci->dev);
722
723 strcpy(card->shortname, "cx25821");
724 sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name,
725 chip->iobase, chip->irq);
726 strcpy(card->mixername, "CX25821");
727
728 printk(KERN_INFO "%s/%i: ALSA support for cx25821 boards\n",
729 card->driver, devno);
730
731 err = snd_card_register(card);
732 if (err < 0) {
733 printk(KERN_INFO "DEBUG ERROR: cannot register sound card %s\n",
734 __func__);
735 goto error;
736 }
737
738 snd_cx25821_cards[devno] = card;
739
740 devno++;
741 return 0;
742
743 error:
744 snd_card_free(card);
745 return err;
746}
747
748/****************************************************************************
749 LINUX MODULE INIT
750 ****************************************************************************/
751static void cx25821_audio_fini(void)
752{
753 snd_card_free(snd_cx25821_cards[0]);
754}
755
756/*
757 * Module initializer
758 *
759 * Loops through present saa7134 cards, and assigns an ALSA device
760 * to each one
761 *
762 */
763static int cx25821_alsa_init(void)
764{
765 struct cx25821_dev *dev = NULL;
766 struct list_head *list;
767
768 list_for_each(list, &cx25821_devlist) {
769 dev = list_entry(list, struct cx25821_dev, devlist);
770 cx25821_audio_initdev(dev);
771 }
772
773 if (dev == NULL)
774 printk(KERN_INFO
775 "cx25821 ERROR ALSA: no cx25821 cards found\n");
776
777 return 0;
778
779}
780
781late_initcall(cx25821_alsa_init);
782module_exit(cx25821_audio_fini);
783
784/* ----------------------------------------------------------- */
785/*
786 * Local variables:
787 * c-basic-offset: 8
788 * End:
789 */
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
new file mode 100644
index 000000000000..ddddf651266b
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -0,0 +1,804 @@
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 "cx25821-video.h"
24#include "cx25821-audio-upstream.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <linux/delay.h>
35#include <asm/uaccess.h>
36
37MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
38MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
39MODULE_LICENSE("GPL");
40
41static int _intr_msk =
42 FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC |
43 FLD_AUD_SRC_OPC_ERR;
44
45int cx25821_sram_channel_setup_upstream_audio(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 if (ch->cmds_start == 0) {
53 cx_write(ch->ptr1_reg, 0);
54 cx_write(ch->ptr2_reg, 0);
55 cx_write(ch->cnt2_reg, 0);
56 cx_write(ch->cnt1_reg, 0);
57 return 0;
58 }
59
60 bpl = (bpl + 7) & ~7; /* alignment */
61 cdt = ch->cdt;
62 lines = ch->fifo_size / bpl;
63
64 if (lines > 3) {
65 lines = 3;
66 }
67
68 BUG_ON(lines < 2);
69
70 /* write CDT */
71 for (i = 0; i < lines; i++) {
72 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
73 cx_write(cdt + 16 * i + 4, 0);
74 cx_write(cdt + 16 * i + 8, 0);
75 cx_write(cdt + 16 * i + 12, 0);
76 }
77
78 /* write CMDS */
79 cx_write(ch->cmds_start + 0, risc);
80
81 cx_write(ch->cmds_start + 4, 0);
82 cx_write(ch->cmds_start + 8, cdt);
83 cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW);
84 cx_write(ch->cmds_start + 16, ch->ctrl_start);
85
86 //IQ size
87 cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW);
88
89 for (i = 24; i < 80; i += 4)
90 cx_write(ch->cmds_start + i, 0);
91
92 /* fill registers */
93 cx_write(ch->ptr1_reg, ch->fifo_start);
94 cx_write(ch->ptr2_reg, cdt);
95 cx_write(ch->cnt2_reg, AUDIO_CDT_SIZE_QW);
96 cx_write(ch->cnt1_reg, AUDIO_CLUSTER_SIZE_QW - 1);
97
98 return 0;
99}
100
101static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
102 __le32 * rp,
103 dma_addr_t databuf_phys_addr,
104 unsigned int bpl,
105 int fifo_enable)
106{
107 unsigned int line;
108 struct sram_channel *sram_ch =
109 &dev->sram_channels[dev->_audio_upstream_channel_select];
110 int offset = 0;
111
112 /* scan lines */
113 for (line = 0; line < LINES_PER_AUDIO_BUFFER; line++) {
114 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
115 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
116 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
117
118 // Check if we need to enable the FIFO after the first 3 lines
119 // For the upstream audio channel, the risc engine will enable the FIFO.
120 if (fifo_enable && line == 2) {
121 *(rp++) = RISC_WRITECR;
122 *(rp++) = sram_ch->dma_ctl;
123 *(rp++) = sram_ch->fld_aud_fifo_en;
124 *(rp++) = 0x00000020;
125 }
126
127 offset += AUDIO_LINE_SIZE;
128 }
129
130 return rp;
131}
132
133int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
134 struct pci_dev *pci,
135 unsigned int bpl, unsigned int lines)
136{
137 __le32 *rp;
138 int fifo_enable = 0;
139 int frame = 0, i = 0;
140 int frame_size = AUDIO_DATA_BUF_SZ;
141 int databuf_offset = 0;
142 int risc_flag = RISC_CNT_INC;
143 dma_addr_t risc_phys_jump_addr;
144
145 /* Virtual address of Risc buffer program */
146 rp = dev->_risc_virt_addr;
147
148 /* sync instruction */
149 *(rp++) = cpu_to_le32(RISC_RESYNC | AUDIO_SYNC_LINE);
150
151 for (frame = 0; frame < NUM_AUDIO_FRAMES; frame++) {
152 databuf_offset = frame_size * frame;
153
154 if (frame == 0) {
155 fifo_enable = 1;
156 risc_flag = RISC_CNT_RESET;
157 } else {
158 fifo_enable = 0;
159 risc_flag = RISC_CNT_INC;
160 }
161
162 //Calculate physical jump address
163 if ((frame + 1) == NUM_AUDIO_FRAMES) {
164 risc_phys_jump_addr =
165 dev->_risc_phys_start_addr +
166 RISC_SYNC_INSTRUCTION_SIZE;
167 } else {
168 risc_phys_jump_addr =
169 dev->_risc_phys_start_addr +
170 RISC_SYNC_INSTRUCTION_SIZE +
171 AUDIO_RISC_DMA_BUF_SIZE * (frame + 1);
172 }
173
174 rp = cx25821_risc_field_upstream_audio(dev, rp,
175 dev->
176 _audiodata_buf_phys_addr
177 + databuf_offset, bpl,
178 fifo_enable);
179
180 if (USE_RISC_NOOP_AUDIO) {
181 for (i = 0; i < NUM_NO_OPS; i++) {
182 *(rp++) = cpu_to_le32(RISC_NOOP);
183 }
184 }
185
186 // Loop to (Nth)FrameRISC or to Start of Risc program & generate IRQ
187 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
188 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
189 *(rp++) = cpu_to_le32(0);
190
191 //Recalculate virtual address based on frame index
192 rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 +
193 (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4);
194 }
195
196 return 0;
197}
198
199void cx25821_free_memory_audio(struct cx25821_dev *dev)
200{
201 if (dev->_risc_virt_addr) {
202 pci_free_consistent(dev->pci, dev->_audiorisc_size,
203 dev->_risc_virt_addr, dev->_risc_phys_addr);
204 dev->_risc_virt_addr = NULL;
205 }
206
207 if (dev->_audiodata_buf_virt_addr) {
208 pci_free_consistent(dev->pci, dev->_audiodata_buf_size,
209 dev->_audiodata_buf_virt_addr,
210 dev->_audiodata_buf_phys_addr);
211 dev->_audiodata_buf_virt_addr = NULL;
212 }
213}
214
215void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
216{
217 struct sram_channel *sram_ch =
218 &dev->sram_channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B];
219 u32 tmp = 0;
220
221 if (!dev->_audio_is_running) {
222 printk
223 ("cx25821: No audio file is currently running so return!\n");
224 return;
225 }
226 //Disable RISC interrupts
227 cx_write(sram_ch->int_msk, 0);
228
229 //Turn OFF risc and fifo enable in AUD_DMA_CNTRL
230 tmp = cx_read(sram_ch->dma_ctl);
231 cx_write(sram_ch->dma_ctl,
232 tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en));
233
234 //Clear data buffer memory
235 if (dev->_audiodata_buf_virt_addr)
236 memset(dev->_audiodata_buf_virt_addr, 0,
237 dev->_audiodata_buf_size);
238
239 dev->_audio_is_running = 0;
240 dev->_is_first_audio_frame = 0;
241 dev->_audioframe_count = 0;
242 dev->_audiofile_status = END_OF_FILE;
243
244 if (dev->_irq_audio_queues) {
245 kfree(dev->_irq_audio_queues);
246 dev->_irq_audio_queues = NULL;
247 }
248
249 if (dev->_audiofilename != NULL)
250 kfree(dev->_audiofilename);
251}
252
253void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
254{
255 if (dev->_audio_is_running) {
256 cx25821_stop_upstream_audio(dev);
257 }
258
259 cx25821_free_memory_audio(dev);
260}
261
262int cx25821_get_audio_data(struct cx25821_dev *dev,
263 struct sram_channel *sram_ch)
264{
265 struct file *myfile;
266 int frame_index_temp = dev->_audioframe_index;
267 int i = 0;
268 int line_size = AUDIO_LINE_SIZE;
269 int frame_size = AUDIO_DATA_BUF_SZ;
270 int frame_offset = frame_size * frame_index_temp;
271 ssize_t vfs_read_retval = 0;
272 char mybuf[line_size];
273 loff_t file_offset = dev->_audioframe_count * frame_size;
274 loff_t pos;
275 mm_segment_t old_fs;
276
277 if (dev->_audiofile_status == END_OF_FILE)
278 return 0;
279
280 myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
281
282 if (IS_ERR(myfile)) {
283 const int open_errno = -PTR_ERR(myfile);
284 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
285 __func__, dev->_audiofilename, open_errno);
286 return PTR_ERR(myfile);
287 } else {
288 if (!(myfile->f_op)) {
289 printk("%s: File has no file operations registered!\n",
290 __func__);
291 filp_close(myfile, NULL);
292 return -EIO;
293 }
294
295 if (!myfile->f_op->read) {
296 printk("%s: File has no READ operations registered! \n",
297 __func__);
298 filp_close(myfile, NULL);
299 return -EIO;
300 }
301
302 pos = myfile->f_pos;
303 old_fs = get_fs();
304 set_fs(KERNEL_DS);
305
306 for (i = 0; i < dev->_audio_lines_count; i++) {
307 pos = file_offset;
308
309 vfs_read_retval =
310 vfs_read(myfile, mybuf, line_size, &pos);
311
312 if (vfs_read_retval > 0 && vfs_read_retval == line_size
313 && dev->_audiodata_buf_virt_addr != NULL) {
314 memcpy((void *)(dev->_audiodata_buf_virt_addr +
315 frame_offset / 4), mybuf,
316 vfs_read_retval);
317 }
318
319 file_offset += vfs_read_retval;
320 frame_offset += vfs_read_retval;
321
322 if (vfs_read_retval < line_size) {
323 printk(KERN_INFO
324 "Done: exit %s() since no more bytes to read from Audio file.\n",
325 __func__);
326 break;
327 }
328 }
329
330 if (i > 0)
331 dev->_audioframe_count++;
332
333 dev->_audiofile_status =
334 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
335
336 set_fs(old_fs);
337 filp_close(myfile, NULL);
338 }
339
340 return 0;
341}
342
343static void cx25821_audioups_handler(struct work_struct *work)
344{
345 struct cx25821_dev *dev =
346 container_of(work, struct cx25821_dev, _audio_work_entry);
347
348 if (!dev) {
349 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
350 __func__);
351 return;
352 }
353
354 cx25821_get_audio_data(dev,
355 &dev->sram_channels[dev->
356 _audio_upstream_channel_select]);
357}
358
359int cx25821_openfile_audio(struct cx25821_dev *dev,
360 struct sram_channel *sram_ch)
361{
362 struct file *myfile;
363 int i = 0, j = 0;
364 int line_size = AUDIO_LINE_SIZE;
365 ssize_t vfs_read_retval = 0;
366 char mybuf[line_size];
367 loff_t pos;
368 loff_t offset = (unsigned long)0;
369 mm_segment_t old_fs;
370
371 myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
372
373 if (IS_ERR(myfile)) {
374 const int open_errno = -PTR_ERR(myfile);
375 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
376 __func__, dev->_audiofilename, open_errno);
377 return PTR_ERR(myfile);
378 } else {
379 if (!(myfile->f_op)) {
380 printk("%s: File has no file operations registered! \n",
381 __func__);
382 filp_close(myfile, NULL);
383 return -EIO;
384 }
385
386 if (!myfile->f_op->read) {
387 printk("%s: File has no READ operations registered! \n",
388 __func__);
389 filp_close(myfile, NULL);
390 return -EIO;
391 }
392
393 pos = myfile->f_pos;
394 old_fs = get_fs();
395 set_fs(KERNEL_DS);
396
397 for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
398 for (i = 0; i < dev->_audio_lines_count; i++) {
399 pos = offset;
400
401 vfs_read_retval =
402 vfs_read(myfile, mybuf, line_size, &pos);
403
404 if (vfs_read_retval > 0
405 && vfs_read_retval == line_size
406 && dev->_audiodata_buf_virt_addr != NULL) {
407 memcpy((void *)(dev->
408 _audiodata_buf_virt_addr
409 + offset / 4), mybuf,
410 vfs_read_retval);
411 }
412
413 offset += vfs_read_retval;
414
415 if (vfs_read_retval < line_size) {
416 printk(KERN_INFO
417 "Done: exit %s() since no more bytes to read from Audio file.\n",
418 __func__);
419 break;
420 }
421 }
422
423 if (i > 0) {
424 dev->_audioframe_count++;
425 }
426
427 if (vfs_read_retval < line_size) {
428 break;
429 }
430 }
431
432 dev->_audiofile_status =
433 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
434
435 set_fs(old_fs);
436 myfile->f_pos = 0;
437 filp_close(myfile, NULL);
438 }
439
440 return 0;
441}
442
443static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
444 struct sram_channel *sram_ch,
445 int bpl)
446{
447 int ret = 0;
448 dma_addr_t dma_addr;
449 dma_addr_t data_dma_addr;
450
451 cx25821_free_memory_audio(dev);
452
453 dev->_risc_virt_addr =
454 pci_alloc_consistent(dev->pci, dev->audio_upstream_riscbuf_size,
455 &dma_addr);
456 dev->_risc_virt_start_addr = dev->_risc_virt_addr;
457 dev->_risc_phys_start_addr = dma_addr;
458 dev->_risc_phys_addr = dma_addr;
459 dev->_audiorisc_size = dev->audio_upstream_riscbuf_size;
460
461 if (!dev->_risc_virt_addr) {
462 printk
463 ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n");
464 return -ENOMEM;
465 }
466 //Clear out memory at address
467 memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size);
468
469 //For Audio Data buffer allocation
470 dev->_audiodata_buf_virt_addr =
471 pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size,
472 &data_dma_addr);
473 dev->_audiodata_buf_phys_addr = data_dma_addr;
474 dev->_audiodata_buf_size = dev->audio_upstream_databuf_size;
475
476 if (!dev->_audiodata_buf_virt_addr) {
477 printk
478 ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning. \n");
479 return -ENOMEM;
480 }
481 //Clear out memory at address
482 memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size);
483
484 ret = cx25821_openfile_audio(dev, sram_ch);
485 if (ret < 0)
486 return ret;
487
488 //Creating RISC programs
489 ret =
490 cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl,
491 dev->_audio_lines_count);
492 if (ret < 0) {
493 printk(KERN_DEBUG
494 "cx25821 ERROR creating audio upstream RISC programs! \n");
495 goto error;
496 }
497
498 return 0;
499
500 error:
501 return ret;
502}
503
504int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
505 u32 status)
506{
507 int i = 0;
508 u32 int_msk_tmp;
509 struct sram_channel *channel = &dev->sram_channels[chan_num];
510 dma_addr_t risc_phys_jump_addr;
511 __le32 *rp;
512
513 if (status & FLD_AUD_SRC_RISCI1) {
514 //Get interrupt_index of the program that interrupted
515 u32 prog_cnt = cx_read(channel->gpcnt);
516
517 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
518 cx_write(channel->int_msk, 0);
519 cx_write(channel->int_stat, cx_read(channel->int_stat));
520
521 spin_lock(&dev->slock);
522
523 while (prog_cnt != dev->_last_index_irq) {
524 //Update _last_index_irq
525 if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1)) {
526 dev->_last_index_irq++;
527 } else {
528 dev->_last_index_irq = 0;
529 }
530
531 dev->_audioframe_index = dev->_last_index_irq;
532
533 queue_work(dev->_irq_audio_queues,
534 &dev->_audio_work_entry);
535 }
536
537 if (dev->_is_first_audio_frame) {
538 dev->_is_first_audio_frame = 0;
539
540 if (dev->_risc_virt_start_addr != NULL) {
541 risc_phys_jump_addr =
542 dev->_risc_phys_start_addr +
543 RISC_SYNC_INSTRUCTION_SIZE +
544 AUDIO_RISC_DMA_BUF_SIZE;
545
546 rp = cx25821_risc_field_upstream_audio(dev,
547 dev->
548 _risc_virt_start_addr
549 + 1,
550 dev->
551 _audiodata_buf_phys_addr,
552 AUDIO_LINE_SIZE,
553 FIFO_DISABLE);
554
555 if (USE_RISC_NOOP_AUDIO) {
556 for (i = 0; i < NUM_NO_OPS; i++) {
557 *(rp++) =
558 cpu_to_le32(RISC_NOOP);
559 }
560 }
561 // Jump to 2nd Audio Frame
562 *(rp++) =
563 cpu_to_le32(RISC_JUMP | RISC_IRQ1 |
564 RISC_CNT_RESET);
565 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
566 *(rp++) = cpu_to_le32(0);
567 }
568 }
569
570 spin_unlock(&dev->slock);
571 } else {
572 if (status & FLD_AUD_SRC_OF)
573 printk("%s: Audio Received Overflow Error Interrupt!\n",
574 __func__);
575
576 if (status & FLD_AUD_SRC_SYNC)
577 printk("%s: Audio Received Sync Error Interrupt!\n",
578 __func__);
579
580 if (status & FLD_AUD_SRC_OPC_ERR)
581 printk("%s: Audio Received OpCode Error Interrupt!\n",
582 __func__);
583
584 // Read and write back the interrupt status register to clear our bits
585 cx_write(channel->int_stat, cx_read(channel->int_stat));
586 }
587
588 if (dev->_audiofile_status == END_OF_FILE) {
589 printk("cx25821: EOF Channel Audio Framecount = %d\n",
590 dev->_audioframe_count);
591 return -1;
592 }
593 //ElSE, set the interrupt mask register, re-enable irq.
594 int_msk_tmp = cx_read(channel->int_msk);
595 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
596
597 return 0;
598}
599
600static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
601{
602 struct cx25821_dev *dev = dev_id;
603 u32 msk_stat, audio_status;
604 int handled = 0;
605 struct sram_channel *sram_ch;
606
607 if (!dev)
608 return -1;
609
610 sram_ch = &dev->sram_channels[dev->_audio_upstream_channel_select];
611
612 msk_stat = cx_read(sram_ch->int_mstat);
613 audio_status = cx_read(sram_ch->int_stat);
614
615 // Only deal with our interrupt
616 if (audio_status) {
617 handled =
618 cx25821_audio_upstream_irq(dev,
619 dev->
620 _audio_upstream_channel_select,
621 audio_status);
622 }
623
624 if (handled < 0) {
625 cx25821_stop_upstream_audio(dev);
626 } else {
627 handled += handled;
628 }
629
630 return IRQ_RETVAL(handled);
631}
632
633static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
634 struct sram_channel *sram_ch)
635{
636 int count = 0;
637 u32 tmp;
638
639 do {
640 //Wait 10 microsecond before checking to see if the FIFO is turned ON.
641 udelay(10);
642
643 tmp = cx_read(sram_ch->dma_ctl);
644
645 if (count++ > 1000) //10 millisecond timeout
646 {
647 printk
648 ("cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
649 __func__);
650 return;
651 }
652
653 } while (!(tmp & sram_ch->fld_aud_fifo_en));
654
655}
656
657int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
658 struct sram_channel *sram_ch)
659{
660 u32 tmp = 0;
661 int err = 0;
662
663 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the CMDS.
664 cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr);
665 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
666
667 /* reset counter */
668 cx_write(sram_ch->gpcnt_ctl, 3);
669
670 //Set the line length (It looks like we do not need to set the line length)
671 cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH);
672
673 //Set the input mode to 16-bit
674 tmp = cx_read(sram_ch->aud_cfg);
675 tmp |=
676 FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
677 FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE;
678 cx_write(sram_ch->aud_cfg, tmp);
679
680 // Read and write back the interrupt status register to clear it
681 tmp = cx_read(sram_ch->int_stat);
682 cx_write(sram_ch->int_stat, tmp);
683
684 // Clear our bits from the interrupt status register.
685 cx_write(sram_ch->int_stat, _intr_msk);
686
687 //Set the interrupt mask register, enable irq.
688 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
689 tmp = cx_read(sram_ch->int_msk);
690 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
691
692 err =
693 request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
694 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
695 if (err < 0) {
696 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
697 dev->pci->irq);
698 goto fail_irq;
699 }
700
701 // Start the DMA engine
702 tmp = cx_read(sram_ch->dma_ctl);
703 cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en);
704
705 dev->_audio_is_running = 1;
706 dev->_is_first_audio_frame = 1;
707
708 // The fifo_en bit turns on by the first Risc program
709 cx25821_wait_fifo_enable(dev, sram_ch);
710
711 return 0;
712
713 fail_irq:
714 cx25821_dev_unregister(dev);
715 return err;
716}
717
718int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
719{
720 struct sram_channel *sram_ch;
721 int retval = 0;
722 int err = 0;
723 int str_length = 0;
724
725 if (dev->_audio_is_running) {
726 printk("Audio Channel is still running so return!\n");
727 return 0;
728 }
729
730 dev->_audio_upstream_channel_select = channel_select;
731 sram_ch = &dev->sram_channels[channel_select];
732
733 //Work queue
734 INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
735 dev->_irq_audio_queues =
736 create_singlethread_workqueue("cx25821_audioworkqueue");
737
738 if (!dev->_irq_audio_queues) {
739 printk
740 ("cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
741 return -ENOMEM;
742 }
743
744 dev->_last_index_irq = 0;
745 dev->_audio_is_running = 0;
746 dev->_audioframe_count = 0;
747 dev->_audiofile_status = RESET_STATUS;
748 dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;
749 _line_size = AUDIO_LINE_SIZE;
750
751 if (dev->input_audiofilename) {
752 str_length = strlen(dev->input_audiofilename);
753 dev->_audiofilename =
754 (char *)kmalloc(str_length + 1, GFP_KERNEL);
755
756 if (!dev->_audiofilename)
757 goto error;
758
759 memcpy(dev->_audiofilename, dev->input_audiofilename,
760 str_length + 1);
761
762 //Default if filename is empty string
763 if (strcmp(dev->input_audiofilename, "") == 0) {
764 dev->_audiofilename = "/root/audioGOOD.wav";
765 }
766 } else {
767 str_length = strlen(_defaultAudioName);
768 dev->_audiofilename =
769 (char *)kmalloc(str_length + 1, GFP_KERNEL);
770
771 if (!dev->_audiofilename)
772 goto error;
773
774 memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1);
775 }
776
777 retval =
778 cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, _line_size,
779 0);
780
781 dev->audio_upstream_riscbuf_size =
782 AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
783 RISC_SYNC_INSTRUCTION_SIZE;
784 dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
785
786 //Allocating buffers and prepare RISC program
787 retval =
788 cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size);
789 if (retval < 0) {
790 printk(KERN_ERR
791 "%s: Failed to set up Audio upstream buffers!\n",
792 dev->name);
793 goto error;
794 }
795 //Start RISC engine
796 cx25821_start_audio_dma_upstream(dev, sram_ch);
797
798 return 0;
799
800 error:
801 cx25821_dev_unregister(dev);
802
803 return err;
804}
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.h b/drivers/staging/cx25821/cx25821-audio-upstream.h
new file mode 100644
index 000000000000..ca987addf815
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.h
@@ -0,0 +1,57 @@
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 NUM_AUDIO_PROGS 8
27#define NUM_AUDIO_FRAMES 8
28#define END_OF_FILE 0
29#define IN_PROGRESS 1
30#define RESET_STATUS -1
31#define FIFO_DISABLE 0
32#define FIFO_ENABLE 1
33#define NUM_NO_OPS 4
34
35#define RISC_READ_INSTRUCTION_SIZE 12
36#define RISC_JUMP_INSTRUCTION_SIZE 12
37#define RISC_WRITECR_INSTRUCTION_SIZE 16
38#define RISC_SYNC_INSTRUCTION_SIZE 4
39#define DWORD_SIZE 4
40#define AUDIO_SYNC_LINE 4
41
42#define LINES_PER_AUDIO_BUFFER 15
43#define AUDIO_LINE_SIZE 128
44#define AUDIO_DATA_BUF_SZ (AUDIO_LINE_SIZE * LINES_PER_AUDIO_BUFFER)
45
46#define USE_RISC_NOOP_AUDIO 1
47
48#ifdef USE_RISC_NOOP_AUDIO
49#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)
50#endif
51
52#ifndef USE_RISC_NOOP_AUDIO
53#define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
54#endif
55
56static int _line_size;
57char *_defaultAudioName = "/root/audioGOOD.wav";
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/staging/cx25821/cx25821-audio.h
new file mode 100644
index 000000000000..503f42f036a8
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio.h
@@ -0,0 +1,57 @@
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#define USE_RISC_NOOP 1
27#define LINES_PER_BUFFER 15
28#define AUDIO_LINE_SIZE 128
29
30//Number of buffer programs to use at once.
31#define NUMBER_OF_PROGRAMS 8
32
33//Max size of the RISC program for a buffer. - worst case is 2 writes per line
34// Space is also added for the 4 no-op instructions added on the end.
35
36#ifndef USE_RISC_NOOP
37#define MAX_BUFFER_PROGRAM_SIZE \
38 (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE*4)
39#endif
40
41// MAE 12 July 2005 Try to use NOOP RISC instruction instead
42#ifdef USE_RISC_NOOP
43#define MAX_BUFFER_PROGRAM_SIZE \
44 (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4)
45#endif
46
47//Sizes of various instructions in bytes. Used when adding instructions.
48#define RISC_WRITE_INSTRUCTION_SIZE 12
49#define RISC_JUMP_INSTRUCTION_SIZE 12
50#define RISC_SKIP_INSTRUCTION_SIZE 4
51#define RISC_SYNC_INSTRUCTION_SIZE 4
52#define RISC_WRITECR_INSTRUCTION_SIZE 16
53#define RISC_NOOP_INSTRUCTION_SIZE 4
54
55#define MAX_AUDIO_DMA_BUFFER_SIZE (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE)
56
57#endif
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
new file mode 100644
index 000000000000..f78b8912d905
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -0,0 +1,434 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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,
46 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,
51 &dev->sram_channels[SRAM_CH11]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH11]
108 && h->video_dev[SRAM_CH11]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 10;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), 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,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO11))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO11)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
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 the risc engine and fifo
205 //cx_write(channel11->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO11)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO11);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO11)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO11);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
268 struct v4l2_format *f)
269{
270 struct cx25821_fh *fh = priv;
271 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
272 int err;
273
274 if (fh) {
275 err = v4l2_prio_check(&dev->prio, &fh->prio);
276 if (0 != err)
277 return err;
278 }
279
280 dprintk(2, "%s()\n", __func__);
281 err = vidioc_try_fmt_vid_cap(file, priv, f);
282
283 if (0 != err)
284 return err;
285 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
286 fh->width = f->fmt.pix.width;
287 fh->height = f->fmt.pix.height;
288 fh->vidq.field = f->fmt.pix.field;
289 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
290 fh->height, fh->vidq.field);
291 cx25821_call_all(dev, video, s_fmt, f);
292 return 0;
293}
294
295static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
296 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 data_from_user = (struct upstream_user_struct *)arg;
304
305 if (!data_from_user) {
306 printk
307 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
308 __func__);
309 return 0;
310 }
311
312 command = data_from_user->command;
313
314 if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) {
315 return 0;
316 }
317
318 dev->input_filename = data_from_user->input_filename;
319 dev->input_audiofilename = data_from_user->input_filename;
320 dev->vid_stdname = data_from_user->vid_stdname;
321 dev->pixel_format = data_from_user->pixel_format;
322 dev->channel_select = data_from_user->channel_select;
323 dev->command = data_from_user->command;
324
325 switch (command) {
326 case UPSTREAM_START_AUDIO:
327 cx25821_start_upstream_audio(dev, data_from_user);
328 break;
329
330 case UPSTREAM_STOP_AUDIO:
331 cx25821_stop_upstream_audio(dev);
332 break;
333 }
334
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343
344static int vidioc_log_status(struct file *file, void *priv)
345{
346 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
347 char name[32 + 2];
348
349 snprintf(name, sizeof(name), "%s/2", dev->name);
350 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
351 dev->name);
352 cx25821_call_all(dev, core, log_status);
353 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
354 dev->name);
355 return 0;
356}
357
358static int vidioc_s_ctrl(struct file *file, void *priv,
359 struct v4l2_control *ctl)
360{
361 struct cx25821_fh *fh = priv;
362 struct cx25821_dev *dev = fh->dev;
363 int err;
364
365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio);
367 if (0 != err)
368 return err;
369 }
370 return 0;
371}
372
373// exported stuff
374static const struct v4l2_file_operations video_fops = {
375 .owner = THIS_MODULE,
376 .open = video_open,
377 .release = video_release,
378 .read = video_read,
379 .poll = video_poll,
380 .mmap = video_mmap,
381 .ioctl = video_ioctl_upstream11,
382};
383
384static const struct v4l2_ioctl_ops video_ioctl_ops = {
385 .vidioc_querycap = vidioc_querycap,
386 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
387 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
388 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
389 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
390 .vidioc_reqbufs = vidioc_reqbufs,
391 .vidioc_querybuf = vidioc_querybuf,
392 .vidioc_qbuf = vidioc_qbuf,
393 .vidioc_dqbuf = vidioc_dqbuf,
394#ifdef TUNER_FLAG
395 .vidioc_s_std = vidioc_s_std,
396 .vidioc_querystd = vidioc_querystd,
397#endif
398 .vidioc_cropcap = vidioc_cropcap,
399 .vidioc_s_crop = vidioc_s_crop,
400 .vidioc_g_crop = vidioc_g_crop,
401 .vidioc_enum_input = vidioc_enum_input,
402 .vidioc_g_input = vidioc_g_input,
403 .vidioc_s_input = vidioc_s_input,
404 .vidioc_g_ctrl = vidioc_g_ctrl,
405 .vidioc_s_ctrl = vidioc_s_ctrl,
406 .vidioc_queryctrl = vidioc_queryctrl,
407 .vidioc_streamon = vidioc_streamon,
408 .vidioc_streamoff = vidioc_streamoff,
409 .vidioc_log_status = vidioc_log_status,
410 .vidioc_g_priority = vidioc_g_priority,
411 .vidioc_s_priority = vidioc_s_priority,
412#ifdef CONFIG_VIDEO_V4L1_COMPAT
413 .vidiocgmbuf = vidiocgmbuf,
414#endif
415#ifdef TUNER_FLAG
416 .vidioc_g_tuner = vidioc_g_tuner,
417 .vidioc_s_tuner = vidioc_s_tuner,
418 .vidioc_g_frequency = vidioc_g_frequency,
419 .vidioc_s_frequency = vidioc_s_frequency,
420#endif
421#ifdef CONFIG_VIDEO_ADV_DEBUG
422 .vidioc_g_register = vidioc_g_register,
423 .vidioc_s_register = vidioc_s_register,
424#endif
425};
426
427struct video_device cx25821_video_template11 = {
428 .name = "cx25821-audioupstream",
429 .fops = &video_fops,
430 .minor = -1,
431 .ioctl_ops = &video_ioctl_ops,
432 .tvnorms = CX25821_NORMS,
433 .current_norm = V4L2_STD_NTSC_M,
434};
diff --git a/drivers/staging/cx25821/cx25821-biffuncs.h b/drivers/staging/cx25821/cx25821-biffuncs.h
new file mode 100644
index 000000000000..9326a7c729ec
--- /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 000000000000..4d0b9eac3e49
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-cards.c
@@ -0,0 +1,70 @@
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
61void cx25821_card_setup(struct cx25821_dev *dev)
62{
63 static u8 eeprom[256];
64
65 if (dev->i2c_bus[0].i2c_rc == 0) {
66 dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
67 tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
68 sizeof(eeprom));
69 }
70}
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
new file mode 100644
index 000000000000..8aceae5a072e
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -0,0 +1,1551 @@
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
43static unsigned int cx25821_devcount = 0;
44
45static DEFINE_MUTEX(devlist);
46LIST_HEAD(cx25821_devlist);
47
48struct sram_channel cx25821_sram_channels[] = {
49 [SRAM_CH00] = {
50 .i = SRAM_CH00,
51 .name = "VID A",
52 .cmds_start = VID_A_DOWN_CMDS,
53 .ctrl_start = VID_A_IQ,
54 .cdt = VID_A_CDT,
55 .fifo_start = VID_A_DOWN_CLUSTER_1,
56 .fifo_size = (VID_CLUSTER_SIZE << 2),
57 .ptr1_reg = DMA1_PTR1,
58 .ptr2_reg = DMA1_PTR2,
59 .cnt1_reg = DMA1_CNT1,
60 .cnt2_reg = DMA1_CNT2,
61 .int_msk = VID_A_INT_MSK,
62 .int_stat = VID_A_INT_STAT,
63 .int_mstat = VID_A_INT_MSTAT,
64 .dma_ctl = VID_DST_A_DMA_CTL,
65 .gpcnt_ctl = VID_DST_A_GPCNT_CTL,
66 .gpcnt = VID_DST_A_GPCNT,
67 .vip_ctl = VID_DST_A_VIP_CTL,
68 .pix_frmt = VID_DST_A_PIX_FRMT,
69 },
70
71 [SRAM_CH01] = {
72 .i = SRAM_CH01,
73 .name = "VID B",
74 .cmds_start = VID_B_DOWN_CMDS,
75 .ctrl_start = VID_B_IQ,
76 .cdt = VID_B_CDT,
77 .fifo_start = VID_B_DOWN_CLUSTER_1,
78 .fifo_size = (VID_CLUSTER_SIZE << 2),
79 .ptr1_reg = DMA2_PTR1,
80 .ptr2_reg = DMA2_PTR2,
81 .cnt1_reg = DMA2_CNT1,
82 .cnt2_reg = DMA2_CNT2,
83 .int_msk = VID_B_INT_MSK,
84 .int_stat = VID_B_INT_STAT,
85 .int_mstat = VID_B_INT_MSTAT,
86 .dma_ctl = VID_DST_B_DMA_CTL,
87 .gpcnt_ctl = VID_DST_B_GPCNT_CTL,
88 .gpcnt = VID_DST_B_GPCNT,
89 .vip_ctl = VID_DST_B_VIP_CTL,
90 .pix_frmt = VID_DST_B_PIX_FRMT,
91 },
92
93 [SRAM_CH02] = {
94 .i = SRAM_CH02,
95 .name = "VID C",
96 .cmds_start = VID_C_DOWN_CMDS,
97 .ctrl_start = VID_C_IQ,
98 .cdt = VID_C_CDT,
99 .fifo_start = VID_C_DOWN_CLUSTER_1,
100 .fifo_size = (VID_CLUSTER_SIZE << 2),
101 .ptr1_reg = DMA3_PTR1,
102 .ptr2_reg = DMA3_PTR2,
103 .cnt1_reg = DMA3_CNT1,
104 .cnt2_reg = DMA3_CNT2,
105 .int_msk = VID_C_INT_MSK,
106 .int_stat = VID_C_INT_STAT,
107 .int_mstat = VID_C_INT_MSTAT,
108 .dma_ctl = VID_DST_C_DMA_CTL,
109 .gpcnt_ctl = VID_DST_C_GPCNT_CTL,
110 .gpcnt = VID_DST_C_GPCNT,
111 .vip_ctl = VID_DST_C_VIP_CTL,
112 .pix_frmt = VID_DST_C_PIX_FRMT,
113 },
114
115 [SRAM_CH03] = {
116 .i = SRAM_CH03,
117 .name = "VID D",
118 .cmds_start = VID_D_DOWN_CMDS,
119 .ctrl_start = VID_D_IQ,
120 .cdt = VID_D_CDT,
121 .fifo_start = VID_D_DOWN_CLUSTER_1,
122 .fifo_size = (VID_CLUSTER_SIZE << 2),
123 .ptr1_reg = DMA4_PTR1,
124 .ptr2_reg = DMA4_PTR2,
125 .cnt1_reg = DMA4_CNT1,
126 .cnt2_reg = DMA4_CNT2,
127 .int_msk = VID_D_INT_MSK,
128 .int_stat = VID_D_INT_STAT,
129 .int_mstat = VID_D_INT_MSTAT,
130 .dma_ctl = VID_DST_D_DMA_CTL,
131 .gpcnt_ctl = VID_DST_D_GPCNT_CTL,
132 .gpcnt = VID_DST_D_GPCNT,
133 .vip_ctl = VID_DST_D_VIP_CTL,
134 .pix_frmt = VID_DST_D_PIX_FRMT,
135 },
136
137 [SRAM_CH04] = {
138 .i = SRAM_CH04,
139 .name = "VID E",
140 .cmds_start = VID_E_DOWN_CMDS,
141 .ctrl_start = VID_E_IQ,
142 .cdt = VID_E_CDT,
143 .fifo_start = VID_E_DOWN_CLUSTER_1,
144 .fifo_size = (VID_CLUSTER_SIZE << 2),
145 .ptr1_reg = DMA5_PTR1,
146 .ptr2_reg = DMA5_PTR2,
147 .cnt1_reg = DMA5_CNT1,
148 .cnt2_reg = DMA5_CNT2,
149 .int_msk = VID_E_INT_MSK,
150 .int_stat = VID_E_INT_STAT,
151 .int_mstat = VID_E_INT_MSTAT,
152 .dma_ctl = VID_DST_E_DMA_CTL,
153 .gpcnt_ctl = VID_DST_E_GPCNT_CTL,
154 .gpcnt = VID_DST_E_GPCNT,
155 .vip_ctl = VID_DST_E_VIP_CTL,
156 .pix_frmt = VID_DST_E_PIX_FRMT,
157 },
158
159 [SRAM_CH05] = {
160 .i = SRAM_CH05,
161 .name = "VID F",
162 .cmds_start = VID_F_DOWN_CMDS,
163 .ctrl_start = VID_F_IQ,
164 .cdt = VID_F_CDT,
165 .fifo_start = VID_F_DOWN_CLUSTER_1,
166 .fifo_size = (VID_CLUSTER_SIZE << 2),
167 .ptr1_reg = DMA6_PTR1,
168 .ptr2_reg = DMA6_PTR2,
169 .cnt1_reg = DMA6_CNT1,
170 .cnt2_reg = DMA6_CNT2,
171 .int_msk = VID_F_INT_MSK,
172 .int_stat = VID_F_INT_STAT,
173 .int_mstat = VID_F_INT_MSTAT,
174 .dma_ctl = VID_DST_F_DMA_CTL,
175 .gpcnt_ctl = VID_DST_F_GPCNT_CTL,
176 .gpcnt = VID_DST_F_GPCNT,
177 .vip_ctl = VID_DST_F_VIP_CTL,
178 .pix_frmt = VID_DST_F_PIX_FRMT,
179 },
180
181 [SRAM_CH06] = {
182 .i = SRAM_CH06,
183 .name = "VID G",
184 .cmds_start = VID_G_DOWN_CMDS,
185 .ctrl_start = VID_G_IQ,
186 .cdt = VID_G_CDT,
187 .fifo_start = VID_G_DOWN_CLUSTER_1,
188 .fifo_size = (VID_CLUSTER_SIZE << 2),
189 .ptr1_reg = DMA7_PTR1,
190 .ptr2_reg = DMA7_PTR2,
191 .cnt1_reg = DMA7_CNT1,
192 .cnt2_reg = DMA7_CNT2,
193 .int_msk = VID_G_INT_MSK,
194 .int_stat = VID_G_INT_STAT,
195 .int_mstat = VID_G_INT_MSTAT,
196 .dma_ctl = VID_DST_G_DMA_CTL,
197 .gpcnt_ctl = VID_DST_G_GPCNT_CTL,
198 .gpcnt = VID_DST_G_GPCNT,
199 .vip_ctl = VID_DST_G_VIP_CTL,
200 .pix_frmt = VID_DST_G_PIX_FRMT,
201 },
202
203 [SRAM_CH07] = {
204 .i = SRAM_CH07,
205 .name = "VID H",
206 .cmds_start = VID_H_DOWN_CMDS,
207 .ctrl_start = VID_H_IQ,
208 .cdt = VID_H_CDT,
209 .fifo_start = VID_H_DOWN_CLUSTER_1,
210 .fifo_size = (VID_CLUSTER_SIZE << 2),
211 .ptr1_reg = DMA8_PTR1,
212 .ptr2_reg = DMA8_PTR2,
213 .cnt1_reg = DMA8_CNT1,
214 .cnt2_reg = DMA8_CNT2,
215 .int_msk = VID_H_INT_MSK,
216 .int_stat = VID_H_INT_STAT,
217 .int_mstat = VID_H_INT_MSTAT,
218 .dma_ctl = VID_DST_H_DMA_CTL,
219 .gpcnt_ctl = VID_DST_H_GPCNT_CTL,
220 .gpcnt = VID_DST_H_GPCNT,
221 .vip_ctl = VID_DST_H_VIP_CTL,
222 .pix_frmt = VID_DST_H_PIX_FRMT,
223 },
224
225 [SRAM_CH08] = {
226 .name = "audio from",
227 .cmds_start = AUD_A_DOWN_CMDS,
228 .ctrl_start = AUD_A_IQ,
229 .cdt = AUD_A_CDT,
230 .fifo_start = AUD_A_DOWN_CLUSTER_1,
231 .fifo_size = AUDIO_CLUSTER_SIZE * 3,
232 .ptr1_reg = DMA17_PTR1,
233 .ptr2_reg = DMA17_PTR2,
234 .cnt1_reg = DMA17_CNT1,
235 .cnt2_reg = DMA17_CNT2,
236 },
237
238 [SRAM_CH09] = {
239 .i = SRAM_CH09,
240 .name = "VID Upstream I",
241 .cmds_start = VID_I_UP_CMDS,
242 .ctrl_start = VID_I_IQ,
243 .cdt = VID_I_CDT,
244 .fifo_start = VID_I_UP_CLUSTER_1,
245 .fifo_size = (VID_CLUSTER_SIZE << 2),
246 .ptr1_reg = DMA15_PTR1,
247 .ptr2_reg = DMA15_PTR2,
248 .cnt1_reg = DMA15_CNT1,
249 .cnt2_reg = DMA15_CNT2,
250 .int_msk = VID_I_INT_MSK,
251 .int_stat = VID_I_INT_STAT,
252 .int_mstat = VID_I_INT_MSTAT,
253 .dma_ctl = VID_SRC_I_DMA_CTL,
254 .gpcnt_ctl = VID_SRC_I_GPCNT_CTL,
255 .gpcnt = VID_SRC_I_GPCNT,
256
257 .vid_fmt_ctl = VID_SRC_I_FMT_CTL,
258 .vid_active_ctl1 = VID_SRC_I_ACTIVE_CTL1,
259 .vid_active_ctl2 = VID_SRC_I_ACTIVE_CTL2,
260 .vid_cdt_size = VID_SRC_I_CDT_SZ,
261 .irq_bit = 8,
262 },
263
264 [SRAM_CH10] = {
265 .i = SRAM_CH10,
266 .name = "VID Upstream J",
267 .cmds_start = VID_J_UP_CMDS,
268 .ctrl_start = VID_J_IQ,
269 .cdt = VID_J_CDT,
270 .fifo_start = VID_J_UP_CLUSTER_1,
271 .fifo_size = (VID_CLUSTER_SIZE << 2),
272 .ptr1_reg = DMA16_PTR1,
273 .ptr2_reg = DMA16_PTR2,
274 .cnt1_reg = DMA16_CNT1,
275 .cnt2_reg = DMA16_CNT2,
276 .int_msk = VID_J_INT_MSK,
277 .int_stat = VID_J_INT_STAT,
278 .int_mstat = VID_J_INT_MSTAT,
279 .dma_ctl = VID_SRC_J_DMA_CTL,
280 .gpcnt_ctl = VID_SRC_J_GPCNT_CTL,
281 .gpcnt = VID_SRC_J_GPCNT,
282
283 .vid_fmt_ctl = VID_SRC_J_FMT_CTL,
284 .vid_active_ctl1 = VID_SRC_J_ACTIVE_CTL1,
285 .vid_active_ctl2 = VID_SRC_J_ACTIVE_CTL2,
286 .vid_cdt_size = VID_SRC_J_CDT_SZ,
287 .irq_bit = 9,
288 },
289
290 [SRAM_CH11] = {
291 .i = SRAM_CH11,
292 .name = "Audio Upstream Channel B",
293 .cmds_start = AUD_B_UP_CMDS,
294 .ctrl_start = AUD_B_IQ,
295 .cdt = AUD_B_CDT,
296 .fifo_start = AUD_B_UP_CLUSTER_1,
297 .fifo_size = (AUDIO_CLUSTER_SIZE * 3),
298 .ptr1_reg = DMA22_PTR1,
299 .ptr2_reg = DMA22_PTR2,
300 .cnt1_reg = DMA22_CNT1,
301 .cnt2_reg = DMA22_CNT2,
302 .int_msk = AUD_B_INT_MSK,
303 .int_stat = AUD_B_INT_STAT,
304 .int_mstat = AUD_B_INT_MSTAT,
305 .dma_ctl = AUD_INT_DMA_CTL,
306 .gpcnt_ctl = AUD_B_GPCNT_CTL,
307 .gpcnt = AUD_B_GPCNT,
308 .aud_length = AUD_B_LNGTH,
309 .aud_cfg = AUD_B_CFG,
310 .fld_aud_fifo_en = FLD_AUD_SRC_B_FIFO_EN,
311 .fld_aud_risc_en = FLD_AUD_SRC_B_RISC_EN,
312 .irq_bit = 11,
313 },
314};
315
316struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00];
317struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01];
318struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02];
319struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03];
320struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04];
321struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05];
322struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06];
323struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07];
324struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09];
325struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10];
326struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11];
327
328struct cx25821_dmaqueue mpegq;
329
330static int cx25821_risc_decode(u32 risc)
331{
332 static char *instr[16] = {
333 [RISC_SYNC >> 28] = "sync",
334 [RISC_WRITE >> 28] = "write",
335 [RISC_WRITEC >> 28] = "writec",
336 [RISC_READ >> 28] = "read",
337 [RISC_READC >> 28] = "readc",
338 [RISC_JUMP >> 28] = "jump",
339 [RISC_SKIP >> 28] = "skip",
340 [RISC_WRITERM >> 28] = "writerm",
341 [RISC_WRITECM >> 28] = "writecm",
342 [RISC_WRITECR >> 28] = "writecr",
343 };
344 static int incr[16] = {
345 [RISC_WRITE >> 28] = 3,
346 [RISC_JUMP >> 28] = 3,
347 [RISC_SKIP >> 28] = 1,
348 [RISC_SYNC >> 28] = 1,
349 [RISC_WRITERM >> 28] = 3,
350 [RISC_WRITECM >> 28] = 3,
351 [RISC_WRITECR >> 28] = 4,
352 };
353 static char *bits[] = {
354 "12", "13", "14", "resync",
355 "cnt0", "cnt1", "18", "19",
356 "20", "21", "22", "23",
357 "irq1", "irq2", "eol", "sol",
358 };
359 int i;
360
361 printk("0x%08x [ %s", risc,
362 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
363 for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) {
364 if (risc & (1 << (i + 12)))
365 printk(" %s", bits[i]);
366 }
367 printk(" count=%d ]\n", risc & 0xfff);
368 return incr[risc >> 28] ? incr[risc >> 28] : 1;
369}
370
371static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
372{
373 struct cx25821_i2c *bus = i2c_adap->algo_data;
374 struct cx25821_dev *dev = bus->dev;
375 return cx_read(bus->reg_stat) & 0x01;
376}
377
378void cx_i2c_read_print(struct cx25821_dev *dev, u32 reg, const char *reg_string)
379{
380 int tmp = 0;
381 u32 value = 0;
382
383 value = cx25821_i2c_read(&dev->i2c_bus[0], reg, &tmp);
384}
385
386static void cx25821_registers_init(struct cx25821_dev *dev)
387{
388 u32 tmp;
389
390 // enable RUN_RISC in Pecos
391 cx_write(DEV_CNTRL2, 0x20);
392
393 // Set the master PCI interrupt masks to enable video, audio, MBIF, and GPIO interrupts
394 // I2C interrupt masking is handled by the I2C objects themselves.
395 cx_write(PCI_INT_MSK, 0x2001FFFF);
396
397 tmp = cx_read(RDR_TLCTL0);
398 tmp &= ~FLD_CFG_RCB_CK_EN; // Clear the RCB_CK_EN bit
399 cx_write(RDR_TLCTL0, tmp);
400
401 // PLL-A setting for the Audio Master Clock
402 cx_write(PLL_A_INT_FRAC, 0x9807A58B);
403
404 // PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1
405 cx_write(PLL_A_POST_STAT_BIST, 0x8000019C);
406
407 // clear reset bit [31]
408 tmp = cx_read(PLL_A_INT_FRAC);
409 cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF);
410
411 // PLL-B setting for Mobilygen Host Bus Interface
412 cx_write(PLL_B_INT_FRAC, 0x9883A86F);
413
414 // PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0
415 cx_write(PLL_B_POST_STAT_BIST, 0x8000018D);
416
417 // clear reset bit [31]
418 tmp = cx_read(PLL_B_INT_FRAC);
419 cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF);
420
421 // PLL-C setting for video upstream channel
422 cx_write(PLL_C_INT_FRAC, 0x96A0EA3F);
423
424 // PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0
425 cx_write(PLL_C_POST_STAT_BIST, 0x80000103);
426
427 // clear reset bit [31]
428 tmp = cx_read(PLL_C_INT_FRAC);
429 cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF);
430
431 // PLL-D setting for audio upstream channel
432 cx_write(PLL_D_INT_FRAC, 0x98757F5B);
433
434 // PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0
435 cx_write(PLL_D_POST_STAT_BIST, 0x80000113);
436
437 // clear reset bit [31]
438 tmp = cx_read(PLL_D_INT_FRAC);
439 cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF);
440
441 // This selects the PLL C clock source for the video upstream channel I and J
442 tmp = cx_read(VID_CH_CLK_SEL);
443 cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000);
444
445 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
446 //select 656/VIP DST for downstream Channel A - C
447 tmp = cx_read(VID_CH_MODE_SEL);
448 //cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
449 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
450
451 // enables 656 port I and J as output
452 tmp = cx_read(CLK_RST);
453 tmp |= FLD_USE_ALT_PLL_REF; // use external ALT_PLL_REF pin as its reference clock instead
454 cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE));
455
456 mdelay(100);
457}
458
459int cx25821_sram_channel_setup(struct cx25821_dev *dev,
460 struct sram_channel *ch,
461 unsigned int bpl, u32 risc)
462{
463 unsigned int i, lines;
464 u32 cdt;
465
466 if (ch->cmds_start == 0) {
467 cx_write(ch->ptr1_reg, 0);
468 cx_write(ch->ptr2_reg, 0);
469 cx_write(ch->cnt2_reg, 0);
470 cx_write(ch->cnt1_reg, 0);
471 return 0;
472 }
473
474 bpl = (bpl + 7) & ~7; /* alignment */
475 cdt = ch->cdt;
476 lines = ch->fifo_size / bpl;
477
478 if (lines > 4) {
479 lines = 4;
480 }
481
482 BUG_ON(lines < 2);
483
484 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
485 cx_write(8 + 4, 8);
486 cx_write(8 + 8, 0);
487
488 /* write CDT */
489 for (i = 0; i < lines; i++) {
490 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
491 cx_write(cdt + 16 * i + 4, 0);
492 cx_write(cdt + 16 * i + 8, 0);
493 cx_write(cdt + 16 * i + 12, 0);
494 }
495
496 //init the first cdt buffer
497 for (i = 0; i < 128; i++)
498 cx_write(ch->fifo_start + 4 * i, i);
499
500 /* write CMDS */
501 if (ch->jumponly) {
502 cx_write(ch->cmds_start + 0, 8);
503 } else {
504 cx_write(ch->cmds_start + 0, risc);
505 }
506
507 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
508 cx_write(ch->cmds_start + 8, cdt);
509 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
510 cx_write(ch->cmds_start + 16, ch->ctrl_start);
511
512 if (ch->jumponly)
513 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
514 else
515 cx_write(ch->cmds_start + 20, 64 >> 2);
516
517 for (i = 24; i < 80; i += 4)
518 cx_write(ch->cmds_start + i, 0);
519
520 /* fill registers */
521 cx_write(ch->ptr1_reg, ch->fifo_start);
522 cx_write(ch->ptr2_reg, cdt);
523 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
524 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
525
526 return 0;
527}
528
529int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
530 struct sram_channel *ch,
531 unsigned int bpl, u32 risc)
532{
533 unsigned int i, lines;
534 u32 cdt;
535
536 if (ch->cmds_start == 0) {
537 cx_write(ch->ptr1_reg, 0);
538 cx_write(ch->ptr2_reg, 0);
539 cx_write(ch->cnt2_reg, 0);
540 cx_write(ch->cnt1_reg, 0);
541 return 0;
542 }
543
544 bpl = (bpl + 7) & ~7; /* alignment */
545 cdt = ch->cdt;
546 lines = ch->fifo_size / bpl;
547
548 if (lines > 3) {
549 lines = 3; //for AUDIO
550 }
551
552 BUG_ON(lines < 2);
553
554 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
555 cx_write(8 + 4, 8);
556 cx_write(8 + 8, 0);
557
558 /* write CDT */
559 for (i = 0; i < lines; i++) {
560 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
561 cx_write(cdt + 16 * i + 4, 0);
562 cx_write(cdt + 16 * i + 8, 0);
563 cx_write(cdt + 16 * i + 12, 0);
564 }
565
566 /* write CMDS */
567 if (ch->jumponly) {
568 cx_write(ch->cmds_start + 0, 8);
569 } else {
570 cx_write(ch->cmds_start + 0, risc);
571 }
572
573 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
574 cx_write(ch->cmds_start + 8, cdt);
575 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
576 cx_write(ch->cmds_start + 16, ch->ctrl_start);
577
578 //IQ size
579 if (ch->jumponly) {
580 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
581 } else {
582 cx_write(ch->cmds_start + 20, 64 >> 2);
583 }
584
585 //zero out
586 for (i = 24; i < 80; i += 4)
587 cx_write(ch->cmds_start + i, 0);
588
589 /* fill registers */
590 cx_write(ch->ptr1_reg, ch->fifo_start);
591 cx_write(ch->ptr2_reg, cdt);
592 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
593 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
594
595 return 0;
596}
597
598void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
599{
600 static char *name[] = {
601 "init risc lo",
602 "init risc hi",
603 "cdt base",
604 "cdt size",
605 "iq base",
606 "iq size",
607 "risc pc lo",
608 "risc pc hi",
609 "iq wr ptr",
610 "iq rd ptr",
611 "cdt current",
612 "pci target lo",
613 "pci target hi",
614 "line / byte",
615 };
616 u32 risc;
617 unsigned int i, j, n;
618
619 printk(KERN_WARNING "%s: %s - dma channel status dump\n", dev->name,
620 ch->name);
621 for (i = 0; i < ARRAY_SIZE(name); i++)
622 printk(KERN_WARNING "cmds + 0x%2x: %-15s: 0x%08x\n", i * 4,
623 name[i], cx_read(ch->cmds_start + 4 * i));
624
625 j = i * 4;
626 for (i = 0; i < 4;) {
627 risc = cx_read(ch->cmds_start + 4 * (i + 14));
628 printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
629 i += cx25821_risc_decode(risc);
630 }
631
632 for (i = 0; i < (64 >> 2); i += n) {
633 risc = cx_read(ch->ctrl_start + 4 * i);
634 /* No consideration for bits 63-32 */
635
636 printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
637 ch->ctrl_start + 4 * i, i);
638 n = cx25821_risc_decode(risc);
639 for (j = 1; j < n; j++) {
640 risc = cx_read(ch->ctrl_start + 4 * (i + j));
641 printk(KERN_WARNING
642 "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
643 4 * (i + j), i + j, risc, j);
644 }
645 }
646
647 printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
648 ch->fifo_start, ch->fifo_start + ch->fifo_size);
649 printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
650 ch->ctrl_start, ch->ctrl_start + 6 * 16);
651 printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
652 cx_read(ch->ptr1_reg));
653 printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
654 cx_read(ch->ptr2_reg));
655 printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
656 cx_read(ch->cnt1_reg));
657 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
658 cx_read(ch->cnt2_reg));
659}
660
661void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
662 struct sram_channel *ch)
663{
664 static char *name[] = {
665 "init risc lo",
666 "init risc hi",
667 "cdt base",
668 "cdt size",
669 "iq base",
670 "iq size",
671 "risc pc lo",
672 "risc pc hi",
673 "iq wr ptr",
674 "iq rd ptr",
675 "cdt current",
676 "pci target lo",
677 "pci target hi",
678 "line / byte",
679 };
680
681 u32 risc, value, tmp;
682 unsigned int i, j, n;
683
684 printk(KERN_INFO "\n%s: %s - dma Audio channel status dump\n",
685 dev->name, ch->name);
686
687 for (i = 0; i < ARRAY_SIZE(name); i++)
688 printk(KERN_INFO "%s: cmds + 0x%2x: %-15s: 0x%08x\n",
689 dev->name, i * 4, name[i],
690 cx_read(ch->cmds_start + 4 * i));
691
692 j = i * 4;
693 for (i = 0; i < 4;) {
694 risc = cx_read(ch->cmds_start + 4 * (i + 14));
695 printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
696 i += cx25821_risc_decode(risc);
697 }
698
699 for (i = 0; i < (64 >> 2); i += n) {
700 risc = cx_read(ch->ctrl_start + 4 * i);
701 /* No consideration for bits 63-32 */
702
703 printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
704 ch->ctrl_start + 4 * i, i);
705 n = cx25821_risc_decode(risc);
706
707 for (j = 1; j < n; j++) {
708 risc = cx_read(ch->ctrl_start + 4 * (i + j));
709 printk(KERN_WARNING
710 "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
711 4 * (i + j), i + j, risc, j);
712 }
713 }
714
715 printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
716 ch->fifo_start, ch->fifo_start + ch->fifo_size);
717 printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
718 ch->ctrl_start, ch->ctrl_start + 6 * 16);
719 printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
720 cx_read(ch->ptr1_reg));
721 printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
722 cx_read(ch->ptr2_reg));
723 printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
724 cx_read(ch->cnt1_reg));
725 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
726 cx_read(ch->cnt2_reg));
727
728 for (i = 0; i < 4; i++) {
729 risc = cx_read(ch->cmds_start + 56 + (i * 4));
730 printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc);
731 }
732
733 //read data from the first cdt buffer
734 risc = cx_read(AUD_A_CDT);
735 printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc);
736 for (i = 0; i < 8; i++) {
737 n = cx_read(risc + i * 4);
738 printk(KERN_WARNING "0x%x ", n);
739 }
740 printk(KERN_WARNING "\n\n");
741
742 value = cx_read(CLK_RST);
743 CX25821_INFO(" CLK_RST = 0x%x \n\n", value);
744
745 value = cx_read(PLL_A_POST_STAT_BIST);
746 CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x \n\n", value);
747 value = cx_read(PLL_A_INT_FRAC);
748 CX25821_INFO(" PLL_A_INT_FRAC = 0x%x \n\n", value);
749
750 value = cx_read(PLL_B_POST_STAT_BIST);
751 CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x \n\n", value);
752 value = cx_read(PLL_B_INT_FRAC);
753 CX25821_INFO(" PLL_B_INT_FRAC = 0x%x \n\n", value);
754
755 value = cx_read(PLL_C_POST_STAT_BIST);
756 CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x \n\n", value);
757 value = cx_read(PLL_C_INT_FRAC);
758 CX25821_INFO(" PLL_C_INT_FRAC = 0x%x \n\n", value);
759
760 value = cx_read(PLL_D_POST_STAT_BIST);
761 CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x \n\n", value);
762 value = cx_read(PLL_D_INT_FRAC);
763 CX25821_INFO(" PLL_D_INT_FRAC = 0x%x \n\n", value);
764
765 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
766 CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x \n\n", value);
767}
768
769static void cx25821_shutdown(struct cx25821_dev *dev)
770{
771 int i;
772
773 /* disable RISC controller */
774 cx_write(DEV_CNTRL2, 0);
775
776 /* Disable Video A/B activity */
777 for (i = 0; i < VID_CHANNEL_NUM; i++) {
778 cx_write(dev->sram_channels[i].dma_ctl, 0);
779 cx_write(dev->sram_channels[i].int_msk, 0);
780 }
781
782 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
783 i++) {
784 cx_write(dev->sram_channels[i].dma_ctl, 0);
785 cx_write(dev->sram_channels[i].int_msk, 0);
786 }
787
788 /* Disable Audio activity */
789 cx_write(AUD_INT_DMA_CTL, 0);
790
791 /* Disable Serial port */
792 cx_write(UART_CTL, 0);
793
794 /* Disable Interrupts */
795 cx_write(PCI_INT_MSK, 0);
796 cx_write(AUD_A_INT_MSK, 0);
797}
798
799void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,
800 u32 format)
801{
802 struct sram_channel *ch;
803
804 if (channel_select <= 7 && channel_select >= 0) {
805 ch = &cx25821_sram_channels[channel_select];
806 cx_write(ch->pix_frmt, format);
807 dev->pixel_formats[channel_select] = format;
808 }
809}
810
811static void cx25821_set_vip_mode(struct cx25821_dev *dev,
812 struct sram_channel *ch)
813{
814 cx_write(ch->pix_frmt, PIXEL_FRMT_422);
815 cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1);
816}
817
818static void cx25821_initialize(struct cx25821_dev *dev)
819{
820 int i;
821
822 dprintk(1, "%s()\n", __func__);
823
824 cx25821_shutdown(dev);
825 cx_write(PCI_INT_STAT, 0xffffffff);
826
827 for (i = 0; i < VID_CHANNEL_NUM; i++)
828 cx_write(dev->sram_channels[i].int_stat, 0xffffffff);
829
830 cx_write(AUD_A_INT_STAT, 0xffffffff);
831 cx_write(AUD_B_INT_STAT, 0xffffffff);
832 cx_write(AUD_C_INT_STAT, 0xffffffff);
833 cx_write(AUD_D_INT_STAT, 0xffffffff);
834 cx_write(AUD_E_INT_STAT, 0xffffffff);
835
836 cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
837 cx_write(PAD_CTRL, 0x12); //for I2C
838 cx25821_registers_init(dev); //init Pecos registers
839 mdelay(100);
840
841 for (i = 0; i < VID_CHANNEL_NUM; i++) {
842 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
843 cx25821_sram_channel_setup(dev, &dev->sram_channels[i], 1440,
844 0);
845 dev->pixel_formats[i] = PIXEL_FRMT_422;
846 dev->use_cif_resolution[i] = FALSE;
847 }
848
849 //Probably only affect Downstream
850 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
851 i++) {
852 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
853 }
854
855 cx25821_sram_channel_setup_audio(dev, &dev->sram_channels[SRAM_CH08],
856 128, 0);
857
858 cx25821_gpio_init(dev);
859}
860
861static int get_resources(struct cx25821_dev *dev)
862{
863 if (request_mem_region
864 (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0),
865 dev->name))
866 return 0;
867
868 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
869 dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
870
871 return -EBUSY;
872}
873
874static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
875{
876 dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
877
878 printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", __func__,
879 dev->hwrevision);
880}
881
882static void cx25821_iounmap(struct cx25821_dev *dev)
883{
884 if (dev == NULL)
885 return;
886
887 /* Releasing IO memory */
888 if (dev->lmmio != NULL) {
889 CX25821_INFO("Releasing lmmio.\n");
890 iounmap(dev->lmmio);
891 dev->lmmio = NULL;
892 }
893}
894
895static int cx25821_dev_setup(struct cx25821_dev *dev)
896{
897 int io_size = 0, i;
898
899 struct video_device *video_template[] = {
900 &cx25821_video_template0,
901 &cx25821_video_template1,
902 &cx25821_video_template2,
903 &cx25821_video_template3,
904 &cx25821_video_template4,
905 &cx25821_video_template5,
906 &cx25821_video_template6,
907 &cx25821_video_template7,
908 &cx25821_video_template9,
909 &cx25821_video_template10,
910 &cx25821_video_template11,
911 &cx25821_videoioctl_template,
912 };
913
914 printk(KERN_INFO "\n***********************************\n");
915 printk(KERN_INFO "cx25821 set up\n");
916 printk(KERN_INFO "***********************************\n\n");
917
918 mutex_init(&dev->lock);
919
920 atomic_inc(&dev->refcount);
921
922 dev->nr = ++cx25821_devcount;
923 sprintf(dev->name, "cx25821[%d]", dev->nr);
924
925 mutex_lock(&devlist);
926 list_add_tail(&dev->devlist, &cx25821_devlist);
927 mutex_unlock(&devlist);
928
929 strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown");
930 strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
931
932 if (dev->pci->device != 0x8210) {
933 printk(KERN_INFO
934 "%s() Exiting. Incorrect Hardware device = 0x%02x\n",
935 __func__, dev->pci->device);
936 return -1;
937 } else {
938 printk(KERN_INFO "Athena Hardware device = 0x%02x\n",
939 dev->pci->device);
940 }
941
942 /* Apply a sensible clock frequency for the PCIe bridge */
943 dev->clk_freq = 28000000;
944 dev->sram_channels = cx25821_sram_channels;
945
946 if (dev->nr > 1) {
947 CX25821_INFO("dev->nr > 1!");
948 }
949
950 /* board config */
951 dev->board = 1; //card[dev->nr];
952 dev->_max_num_decoders = MAX_DECODERS;
953
954 dev->pci_bus = dev->pci->bus->number;
955 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
956 dev->pci_irqmask = 0x001f00;
957
958 /* External Master 1 Bus */
959 dev->i2c_bus[0].nr = 0;
960 dev->i2c_bus[0].dev = dev;
961 dev->i2c_bus[0].reg_stat = I2C1_STAT;
962 dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
963 dev->i2c_bus[0].reg_addr = I2C1_ADDR;
964 dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
965 dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
966 dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
967
968
969 if (get_resources(dev) < 0) {
970 printk(KERN_ERR "%s No more PCIe resources for "
971 "subsystem: %04x:%04x\n",
972 dev->name, dev->pci->subsystem_vendor,
973 dev->pci->subsystem_device);
974
975 cx25821_devcount--;
976 return -ENODEV;
977 }
978
979 /* PCIe stuff */
980 dev->base_io_addr = pci_resource_start(dev->pci, 0);
981 io_size = pci_resource_len(dev->pci, 0);
982
983 if (!dev->base_io_addr) {
984 CX25821_ERR("No PCI Memory resources, exiting!\n");
985 return -ENODEV;
986 }
987
988 dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0));
989
990 if (!dev->lmmio) {
991 CX25821_ERR
992 ("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
993 cx25821_iounmap(dev);
994 return -ENOMEM;
995 }
996
997 dev->bmmio = (u8 __iomem *) dev->lmmio;
998
999 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1000 dev->name, dev->pci->subsystem_vendor,
1001 dev->pci->subsystem_device, cx25821_boards[dev->board].name,
1002 dev->board, card[dev->nr] == dev->board ?
1003 "insmod option" : "autodetected");
1004
1005 /* init hardware */
1006 cx25821_initialize(dev);
1007
1008 cx25821_i2c_register(&dev->i2c_bus[0]);
1009// cx25821_i2c_register(&dev->i2c_bus[1]);
1010// cx25821_i2c_register(&dev->i2c_bus[2]);
1011
1012 CX25821_INFO("i2c register! bus->i2c_rc = %d\n",
1013 dev->i2c_bus[0].i2c_rc);
1014
1015 cx25821_card_setup(dev);
1016 medusa_video_init(dev);
1017
1018 for (i = 0; i < VID_CHANNEL_NUM; i++) {
1019 if (cx25821_video_register(dev, i, video_template[i]) < 0) {
1020 printk(KERN_ERR
1021 "%s() Failed to register analog video adapters on VID channel %d\n",
1022 __func__, i);
1023 }
1024 }
1025
1026 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
1027 i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
1028 //Since we don't have template8 for Audio Downstream
1029 if (cx25821_video_register(dev, i, video_template[i - 1]) < 0) {
1030 printk(KERN_ERR
1031 "%s() Failed to register analog video adapters for Upstream channel %d.\n",
1032 __func__, i);
1033 }
1034 }
1035
1036 // register IOCTL device
1037 dev->ioctl_dev =
1038 cx25821_vdev_init(dev, dev->pci, video_template[VIDEO_IOCTL_CH],
1039 "video");
1040
1041 if (video_register_device
1042 (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
1043 cx25821_videoioctl_unregister(dev);
1044 printk(KERN_ERR
1045 "%s() Failed to register video adapter for IOCTL so releasing.\n",
1046 __func__);
1047 }
1048
1049 cx25821_dev_checkrevision(dev);
1050 CX25821_INFO("cx25821 setup done!\n");
1051
1052 return 0;
1053}
1054
1055void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
1056 struct upstream_user_struct *up_data)
1057{
1058 dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0;
1059
1060 dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1061 medusa_set_videostandard(dev);
1062
1063 cx25821_vidupstream_init_ch1(dev, dev->channel_select,
1064 dev->pixel_format);
1065}
1066
1067void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
1068 struct upstream_user_struct *up_data)
1069{
1070 dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0;
1071
1072 dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1073 medusa_set_videostandard(dev);
1074
1075 cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2,
1076 dev->pixel_format_ch2);
1077}
1078
1079void cx25821_start_upstream_audio(struct cx25821_dev *dev,
1080 struct upstream_user_struct *up_data)
1081{
1082 cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B);
1083}
1084
1085void cx25821_dev_unregister(struct cx25821_dev *dev)
1086{
1087 int i;
1088
1089 if (!dev->base_io_addr)
1090 return;
1091
1092 cx25821_free_mem_upstream_ch1(dev);
1093 cx25821_free_mem_upstream_ch2(dev);
1094 cx25821_free_mem_upstream_audio(dev);
1095
1096 release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0));
1097
1098 if (!atomic_dec_and_test(&dev->refcount))
1099 return;
1100
1101 for (i = 0; i < VID_CHANNEL_NUM; i++)
1102 cx25821_video_unregister(dev, i);
1103
1104 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
1105 i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
1106 cx25821_video_unregister(dev, i);
1107 }
1108
1109 cx25821_videoioctl_unregister(dev);
1110
1111 cx25821_i2c_unregister(&dev->i2c_bus[0]);
1112 cx25821_iounmap(dev);
1113}
1114
1115static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
1116 unsigned int offset, u32 sync_line,
1117 unsigned int bpl, unsigned int padding,
1118 unsigned int lines)
1119{
1120 struct scatterlist *sg;
1121 unsigned int line, todo;
1122
1123 /* sync instruction */
1124 if (sync_line != NO_SYNC_LINE) {
1125 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1126 }
1127
1128 /* scan lines */
1129 sg = sglist;
1130 for (line = 0; line < lines; line++) {
1131 while (offset && offset >= sg_dma_len(sg)) {
1132 offset -= sg_dma_len(sg);
1133 sg++;
1134 }
1135 if (bpl <= sg_dma_len(sg) - offset) {
1136 /* fits into current chunk */
1137 *(rp++) =
1138 cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | bpl);
1139 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1140 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1141 offset += bpl;
1142 } else {
1143 /* scanline needs to be split */
1144 todo = bpl;
1145 *(rp++) =
1146 cpu_to_le32(RISC_WRITE | RISC_SOL |
1147 (sg_dma_len(sg) - offset));
1148 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1149 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1150 todo -= (sg_dma_len(sg) - offset);
1151 offset = 0;
1152 sg++;
1153 while (todo > sg_dma_len(sg)) {
1154 *(rp++) =
1155 cpu_to_le32(RISC_WRITE | sg_dma_len(sg));
1156 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1157 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1158 todo -= sg_dma_len(sg);
1159 sg++;
1160 }
1161 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
1162 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1163 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1164 offset += todo;
1165 }
1166
1167 offset += padding;
1168 }
1169
1170 return rp;
1171}
1172
1173int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
1174 struct scatterlist *sglist, unsigned int top_offset,
1175 unsigned int bottom_offset, unsigned int bpl,
1176 unsigned int padding, unsigned int lines)
1177{
1178 u32 instructions;
1179 u32 fields;
1180 __le32 *rp;
1181 int rc;
1182
1183 fields = 0;
1184 if (UNSET != top_offset)
1185 fields++;
1186 if (UNSET != bottom_offset)
1187 fields++;
1188
1189 /* estimate risc mem: worst case is one write per page border +
1190 one write per scan line + syncs + jump (all 2 dwords). Padding
1191 can cause next bpl to start close to a page border. First DMA
1192 region may be smaller than PAGE_SIZE */
1193 /* write and jump need and extra dword */
1194 instructions =
1195 fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
1196 instructions += 2;
1197 rc = btcx_riscmem_alloc(pci, risc, instructions * 12);
1198
1199 if (rc < 0)
1200 return rc;
1201
1202 /* write risc instructions */
1203 rp = risc->cpu;
1204
1205 if (UNSET != top_offset) {
1206 rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding,
1207 lines);
1208 }
1209
1210 if (UNSET != bottom_offset) {
1211 rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl,
1212 padding, lines);
1213 }
1214
1215 /* save pointer to jmp instruction address */
1216 risc->jmp = rp;
1217 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1218
1219 return 0;
1220}
1221
1222static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist,
1223 unsigned int offset, u32 sync_line,
1224 unsigned int bpl, unsigned int padding,
1225 unsigned int lines, unsigned int lpi)
1226{
1227 struct scatterlist *sg;
1228 unsigned int line, todo, sol;
1229
1230 /* sync instruction */
1231 if (sync_line != NO_SYNC_LINE)
1232 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1233
1234 /* scan lines */
1235 sg = sglist;
1236 for (line = 0; line < lines; line++) {
1237 while (offset && offset >= sg_dma_len(sg)) {
1238 offset -= sg_dma_len(sg);
1239 sg++;
1240 }
1241
1242 if (lpi && line > 0 && !(line % lpi))
1243 sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
1244 else
1245 sol = RISC_SOL;
1246
1247 if (bpl <= sg_dma_len(sg) - offset) {
1248 /* fits into current chunk */
1249 *(rp++) =
1250 cpu_to_le32(RISC_WRITE | sol | RISC_EOL | bpl);
1251 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1252 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1253 offset += bpl;
1254 } else {
1255 /* scanline needs to be split */
1256 todo = bpl;
1257 *(rp++) = cpu_to_le32(RISC_WRITE | sol |
1258 (sg_dma_len(sg) - offset));
1259 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1260 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1261 todo -= (sg_dma_len(sg) - offset);
1262 offset = 0;
1263 sg++;
1264 while (todo > sg_dma_len(sg)) {
1265 *(rp++) = cpu_to_le32(RISC_WRITE |
1266 sg_dma_len(sg));
1267 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1268 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1269 todo -= sg_dma_len(sg);
1270 sg++;
1271 }
1272 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
1273 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1274 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1275 offset += todo;
1276 }
1277 offset += padding;
1278 }
1279
1280 return rp;
1281}
1282
1283int cx25821_risc_databuffer_audio(struct pci_dev *pci,
1284 struct btcx_riscmem *risc,
1285 struct scatterlist *sglist,
1286 unsigned int bpl,
1287 unsigned int lines, unsigned int lpi)
1288{
1289 u32 instructions;
1290 __le32 *rp;
1291 int rc;
1292
1293 /* estimate risc mem: worst case is one write per page border +
1294 one write per scan line + syncs + jump (all 2 dwords). Here
1295 there is no padding and no sync. First DMA region may be smaller
1296 than PAGE_SIZE */
1297 /* Jump and write need an extra dword */
1298 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
1299 instructions += 1;
1300
1301 if ((rc = btcx_riscmem_alloc(pci, risc, instructions * 12)) < 0)
1302 return rc;
1303
1304 /* write risc instructions */
1305 rp = risc->cpu;
1306 rp = cx25821_risc_field_audio(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
1307 lines, lpi);
1308
1309 /* save pointer to jmp instruction address */
1310 risc->jmp = rp;
1311 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1312 return 0;
1313}
1314
1315int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
1316 u32 reg, u32 mask, u32 value)
1317{
1318 __le32 *rp;
1319 int rc;
1320
1321 rc = btcx_riscmem_alloc(pci, risc, 4 * 16);
1322
1323 if (rc < 0)
1324 return rc;
1325
1326 /* write risc instructions */
1327 rp = risc->cpu;
1328
1329 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ1);
1330 *(rp++) = cpu_to_le32(reg);
1331 *(rp++) = cpu_to_le32(value);
1332 *(rp++) = cpu_to_le32(mask);
1333 *(rp++) = cpu_to_le32(RISC_JUMP);
1334 *(rp++) = cpu_to_le32(risc->dma);
1335 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1336 return 0;
1337}
1338
1339void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
1340{
1341 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
1342
1343 BUG_ON(in_interrupt());
1344 videobuf_waiton(&buf->vb, 0, 0);
1345 videobuf_dma_unmap(q, dma);
1346 videobuf_dma_free(dma);
1347 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
1348 buf->vb.state = VIDEOBUF_NEEDS_INIT;
1349}
1350
1351static irqreturn_t cx25821_irq(int irq, void *dev_id)
1352{
1353 struct cx25821_dev *dev = dev_id;
1354 u32 pci_status, pci_mask;
1355 u32 vid_status;
1356 int i, handled = 0;
1357 u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
1358
1359 pci_status = cx_read(PCI_INT_STAT);
1360 pci_mask = cx_read(PCI_INT_MSK);
1361
1362 if (pci_status == 0)
1363 goto out;
1364
1365 for (i = 0; i < VID_CHANNEL_NUM; i++) {
1366 if (pci_status & mask[i]) {
1367 vid_status = cx_read(dev->sram_channels[i].int_stat);
1368
1369 if (vid_status)
1370 handled +=
1371 cx25821_video_irq(dev, i, vid_status);
1372
1373 cx_write(PCI_INT_STAT, mask[i]);
1374 }
1375 }
1376
1377 out:
1378 return IRQ_RETVAL(handled);
1379}
1380
1381void cx25821_print_irqbits(char *name, char *tag, char **strings,
1382 int len, u32 bits, u32 mask)
1383{
1384 unsigned int i;
1385
1386 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
1387
1388 for (i = 0; i < len; i++) {
1389 if (!(bits & (1 << i)))
1390 continue;
1391 if (strings[i])
1392 printk(" %s", strings[i]);
1393 else
1394 printk(" %d", i);
1395 if (!(mask & (1 << i)))
1396 continue;
1397 printk("*");
1398 }
1399 printk("\n");
1400}
1401
1402struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci)
1403{
1404 struct cx25821_dev *dev = pci_get_drvdata(pci);
1405 return dev;
1406}
1407
1408static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
1409 const struct pci_device_id *pci_id)
1410{
1411 struct cx25821_dev *dev;
1412 int err = 0;
1413
1414 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1415 if (NULL == dev)
1416 return -ENOMEM;
1417
1418 err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
1419 if (err < 0)
1420 goto fail_free;
1421
1422 /* pci init */
1423 dev->pci = pci_dev;
1424 if (pci_enable_device(pci_dev)) {
1425 err = -EIO;
1426
1427 printk(KERN_INFO "pci enable failed! ");
1428
1429 goto fail_unregister_device;
1430 }
1431
1432 printk(KERN_INFO "cx25821 Athena pci enable ! \n");
1433
1434 if (cx25821_dev_setup(dev) < 0) {
1435 err = -EINVAL;
1436 goto fail_unregister_device;
1437 }
1438
1439 /* print pci info */
1440 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1441 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1442 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1443 "latency: %d, mmio: 0x%llx\n", dev->name,
1444 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1445 dev->pci_lat, (unsigned long long)dev->base_io_addr);
1446
1447 pci_set_master(pci_dev);
1448 if (!pci_dma_supported(pci_dev, 0xffffffff)) {
1449 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
1450 err = -EIO;
1451 goto fail_irq;
1452 }
1453
1454 err =
1455 request_irq(pci_dev->irq, cx25821_irq, IRQF_SHARED | IRQF_DISABLED,
1456 dev->name, dev);
1457
1458 if (err < 0) {
1459 printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
1460 pci_dev->irq);
1461 goto fail_irq;
1462 }
1463
1464 return 0;
1465
1466 fail_irq:
1467 printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ ! \n");
1468 cx25821_dev_unregister(dev);
1469
1470 fail_unregister_device:
1471 v4l2_device_unregister(&dev->v4l2_dev);
1472
1473 fail_free:
1474 kfree(dev);
1475 return err;
1476}
1477
1478static void __devexit cx25821_finidev(struct pci_dev *pci_dev)
1479{
1480 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1481 struct cx25821_dev *dev = get_cx25821(v4l2_dev);
1482
1483 cx25821_shutdown(dev);
1484 pci_disable_device(pci_dev);
1485
1486 /* unregister stuff */
1487 if (pci_dev->irq)
1488 free_irq(pci_dev->irq, dev);
1489
1490 mutex_lock(&devlist);
1491 list_del(&dev->devlist);
1492 mutex_unlock(&devlist);
1493
1494 cx25821_dev_unregister(dev);
1495 v4l2_device_unregister(v4l2_dev);
1496 kfree(dev);
1497}
1498
1499static struct pci_device_id cx25821_pci_tbl[] = {
1500 {
1501 /* CX25821 Athena */
1502 .vendor = 0x14f1,
1503 .device = 0x8210,
1504 .subvendor = 0x14f1,
1505 .subdevice = 0x0920,
1506 },
1507 {
1508 /* --- end of list --- */
1509 }
1510};
1511
1512MODULE_DEVICE_TABLE(pci, cx25821_pci_tbl);
1513
1514static struct pci_driver cx25821_pci_driver = {
1515 .name = "cx25821",
1516 .id_table = cx25821_pci_tbl,
1517 .probe = cx25821_initdev,
1518 .remove = __devexit_p(cx25821_finidev),
1519 /* TODO */
1520 .suspend = NULL,
1521 .resume = NULL,
1522};
1523
1524static int cx25821_init(void)
1525{
1526 INIT_LIST_HEAD(&cx25821_devlist);
1527 printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n",
1528 (CX25821_VERSION_CODE >> 16) & 0xff,
1529 (CX25821_VERSION_CODE >> 8) & 0xff, CX25821_VERSION_CODE & 0xff);
1530 return pci_register_driver(&cx25821_pci_driver);
1531}
1532
1533static void cx25821_fini(void)
1534{
1535 pci_unregister_driver(&cx25821_pci_driver);
1536}
1537
1538EXPORT_SYMBOL(cx25821_devlist);
1539EXPORT_SYMBOL(cx25821_sram_channels);
1540EXPORT_SYMBOL(cx25821_print_irqbits);
1541EXPORT_SYMBOL(cx25821_dev_get);
1542EXPORT_SYMBOL(cx25821_dev_unregister);
1543EXPORT_SYMBOL(cx25821_sram_channel_setup);
1544EXPORT_SYMBOL(cx25821_sram_channel_dump);
1545EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
1546EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
1547EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
1548EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
1549
1550module_init(cx25821_init);
1551module_exit(cx25821_fini);
diff --git a/drivers/staging/cx25821/cx25821-gpio.c b/drivers/staging/cx25821/cx25821-gpio.c
new file mode 100644
index 000000000000..e8a37b47e437
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.c
@@ -0,0 +1,98 @@
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/********************* GPIO stuffs *********************/
26void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
27 int pin_number, int pin_logic_value)
28{
29 int bit = pin_number;
30 u32 gpio_oe_reg = GPIO_LO_OE;
31 u32 gpio_register = 0;
32 u32 value = 0;
33
34 // Check for valid pinNumber
35 if (pin_number >= 47)
36 return;
37
38 if (pin_number > 31) {
39 bit = pin_number - 31;
40 gpio_oe_reg = GPIO_HI_OE;
41 }
42 // Here we will make sure that the GPIOs 0 and 1 are output. keep the rest as is
43 gpio_register = cx_read(gpio_oe_reg);
44
45 if (pin_logic_value == 1) {
46 value = gpio_register | Set_GPIO_Bit(bit);
47 } else {
48 value = gpio_register & Clear_GPIO_Bit(bit);
49 }
50
51 cx_write(gpio_oe_reg, value);
52}
53
54static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
55 int pin_number, int pin_logic_value)
56{
57 int bit = pin_number;
58 u32 gpio_reg = GPIO_LO;
59 u32 value = 0;
60
61 // Check for valid pinNumber
62 if (pin_number >= 47)
63 return;
64
65 cx25821_set_gpiopin_direction(dev, pin_number, 0); // change to output direction
66
67 if (pin_number > 31) {
68 bit = pin_number - 31;
69 gpio_reg = GPIO_HI;
70 }
71
72 value = cx_read(gpio_reg);
73
74 if (pin_logic_value == 0) {
75 value &= Clear_GPIO_Bit(bit);
76 } else {
77 value |= Set_GPIO_Bit(bit);
78 }
79
80 cx_write(gpio_reg, value);
81}
82
83void cx25821_gpio_init(struct cx25821_dev *dev)
84{
85 if (dev == NULL) {
86 return;
87 }
88
89 switch (dev->board) {
90 case CX25821_BOARD_CONEXANT_ATHENA10:
91 default:
92 //set GPIO 5 to select the path for Medusa/Athena
93 cx25821_set_gpiopin_logicvalue(dev, 5, 1);
94 mdelay(20);
95 break;
96 }
97
98}
diff --git a/drivers/staging/cx25821/cx25821-gpio.h b/drivers/staging/cx25821/cx25821-gpio.h
new file mode 100644
index 000000000000..ca07644154af
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.h
@@ -0,0 +1,2 @@
1
2void cx25821_gpio_init(struct athena_dev *dev);
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
new file mode 100644
index 000000000000..f4f2681d8f1c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -0,0 +1,419 @@
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
27static unsigned int i2c_debug;
28module_param(i2c_debug, int, 0644);
29MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
30
31static unsigned int i2c_scan = 0;
32module_param(i2c_scan, int, 0444);
33MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
34
35#define dprintk(level, fmt, arg...)\
36 do { if (i2c_debug >= level)\
37 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
38 } while (0)
39
40#define I2C_WAIT_DELAY 32
41#define I2C_WAIT_RETRY 64
42
43#define I2C_EXTEND (1 << 3)
44#define I2C_NOSTOP (1 << 4)
45
46static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
47{
48 struct cx25821_i2c *bus = i2c_adap->algo_data;
49 struct cx25821_dev *dev = bus->dev;
50 return cx_read(bus->reg_stat) & 0x01;
51}
52
53static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
54{
55 struct cx25821_i2c *bus = i2c_adap->algo_data;
56 struct cx25821_dev *dev = bus->dev;
57 return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
58}
59
60static int i2c_wait_done(struct i2c_adapter *i2c_adap)
61{
62 int count;
63
64 for (count = 0; count < I2C_WAIT_RETRY; count++) {
65 if (!i2c_is_busy(i2c_adap))
66 break;
67 udelay(I2C_WAIT_DELAY);
68 }
69
70 if (I2C_WAIT_RETRY == count)
71 return 0;
72
73 return 1;
74}
75
76static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
77 const struct i2c_msg *msg, int joined_rlen)
78{
79 struct cx25821_i2c *bus = i2c_adap->algo_data;
80 struct cx25821_dev *dev = bus->dev;
81 u32 wdata, addr, ctrl;
82 int retval, cnt;
83
84 if (joined_rlen)
85 dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__,
86 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 cx_write(bus->reg_addr, msg->addr << 25);
93 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
94
95 if (!i2c_wait_done(i2c_adap))
96 return -EIO;
97
98 if (!i2c_slave_did_ack(i2c_adap))
99 return -EIO;
100
101 dprintk(1, "%s() returns 0\n", __func__);
102 return 0;
103 }
104
105 /* dev, reg + first byte */
106 addr = (msg->addr << 25) | msg->buf[0];
107 wdata = msg->buf[0];
108
109 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
110
111 if (msg->len > 1)
112 ctrl |= I2C_NOSTOP | I2C_EXTEND;
113 else if (joined_rlen)
114 ctrl |= I2C_NOSTOP;
115
116 cx_write(bus->reg_addr, addr);
117 cx_write(bus->reg_wdata, wdata);
118 cx_write(bus->reg_ctrl, ctrl);
119
120 retval = i2c_wait_done(i2c_adap);
121 if (retval < 0)
122 goto err;
123
124 if (retval == 0)
125 goto eio;
126
127 if (i2c_debug) {
128 if (!(ctrl & I2C_NOSTOP))
129 printk(" >\n");
130 }
131
132 for (cnt = 1; cnt < msg->len; cnt++) {
133 /* following bytes */
134 wdata = msg->buf[cnt];
135 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
136
137 if (cnt < msg->len - 1)
138 ctrl |= I2C_NOSTOP | I2C_EXTEND;
139 else if (joined_rlen)
140 ctrl |= I2C_NOSTOP;
141
142 cx_write(bus->reg_addr, addr);
143 cx_write(bus->reg_wdata, wdata);
144 cx_write(bus->reg_ctrl, ctrl);
145
146 retval = i2c_wait_done(i2c_adap);
147 if (retval < 0)
148 goto err;
149
150 if (retval == 0)
151 goto eio;
152
153 if (i2c_debug) {
154 dprintk(1, " %02x", msg->buf[cnt]);
155 if (!(ctrl & I2C_NOSTOP))
156 dprintk(1, " >\n");
157 }
158 }
159
160 return msg->len;
161
162 eio:
163 retval = -EIO;
164 err:
165 if (i2c_debug)
166 printk(KERN_ERR " ERR: %d\n", retval);
167 return retval;
168}
169
170static int i2c_readbytes(struct i2c_adapter *i2c_adap,
171 const struct i2c_msg *msg, int joined)
172{
173 struct cx25821_i2c *bus = i2c_adap->algo_data;
174 struct cx25821_dev *dev = bus->dev;
175 u32 ctrl, cnt;
176 int retval;
177
178 if (i2c_debug && !joined)
179 dprintk(1, "6-%s(msg->len=%d)\n", __func__, msg->len);
180
181 /* Deal with i2c probe functions with zero payload */
182 if (msg->len == 0) {
183 cx_write(bus->reg_addr, msg->addr << 25);
184 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
185 if (!i2c_wait_done(i2c_adap))
186 return -EIO;
187 if (!i2c_slave_did_ack(i2c_adap))
188 return -EIO;
189
190 dprintk(1, "%s() returns 0\n", __func__);
191 return 0;
192 }
193
194 if (i2c_debug) {
195 if (joined)
196 dprintk(1, " R");
197 else
198 dprintk(1, " <R %02x", (msg->addr << 1) + 1);
199 }
200
201 for (cnt = 0; cnt < msg->len; cnt++) {
202
203 ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
204
205 if (cnt < msg->len - 1)
206 ctrl |= I2C_NOSTOP | I2C_EXTEND;
207
208 cx_write(bus->reg_addr, msg->addr << 25);
209 cx_write(bus->reg_ctrl, ctrl);
210
211 retval = i2c_wait_done(i2c_adap);
212 if (retval < 0)
213 goto err;
214 if (retval == 0)
215 goto eio;
216 msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
217
218 if (i2c_debug) {
219 dprintk(1, " %02x", msg->buf[cnt]);
220 if (!(ctrl & I2C_NOSTOP))
221 dprintk(1, " >\n");
222 }
223 }
224
225 return msg->len;
226 eio:
227 retval = -EIO;
228 err:
229 if (i2c_debug)
230 printk(KERN_ERR " ERR: %d\n", retval);
231 return retval;
232}
233
234static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
235{
236 struct cx25821_i2c *bus = i2c_adap->algo_data;
237 struct cx25821_dev *dev = bus->dev;
238 int i, retval = 0;
239
240 dprintk(1, "%s(num = %d)\n", __func__, num);
241
242 for (i = 0; i < num; i++) {
243 dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
244 __func__, num, msgs[i].addr, msgs[i].len);
245
246 if (msgs[i].flags & I2C_M_RD) {
247 /* read */
248 retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
249 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
250 msgs[i].addr == msgs[i + 1].addr) {
251 /* write then read from same address */
252 retval =
253 i2c_sendbytes(i2c_adap, &msgs[i], msgs[i + 1].len);
254
255 if (retval < 0)
256 goto err;
257 i++;
258 retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
259 } else {
260 /* write */
261 retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
262 }
263
264 if (retval < 0)
265 goto err;
266 }
267 return num;
268
269 err:
270 return retval;
271}
272
273
274static u32 cx25821_functionality(struct i2c_adapter *adap)
275{
276 return I2C_FUNC_SMBUS_EMUL |
277 I2C_FUNC_I2C |
278 I2C_FUNC_SMBUS_WORD_DATA |
279 I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
280}
281
282static struct i2c_algorithm cx25821_i2c_algo_template = {
283 .master_xfer = i2c_xfer,
284 .functionality = cx25821_functionality,
285};
286
287static struct i2c_adapter cx25821_i2c_adap_template = {
288 .name = "cx25821",
289 .owner = THIS_MODULE,
290 .algo = &cx25821_i2c_algo_template,
291};
292
293static struct i2c_client cx25821_i2c_client_template = {
294 .name = "cx25821 internal",
295};
296
297/* init + register i2c algo-bit adapter */
298int cx25821_i2c_register(struct cx25821_i2c *bus)
299{
300 struct cx25821_dev *dev = bus->dev;
301
302 dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);
303
304 memcpy(&bus->i2c_adap, &cx25821_i2c_adap_template,
305 sizeof(bus->i2c_adap));
306 memcpy(&bus->i2c_algo, &cx25821_i2c_algo_template,
307 sizeof(bus->i2c_algo));
308 memcpy(&bus->i2c_client, &cx25821_i2c_client_template,
309 sizeof(bus->i2c_client));
310
311 bus->i2c_adap.dev.parent = &dev->pci->dev;
312
313 strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
314
315 bus->i2c_algo.data = bus;
316 bus->i2c_adap.algo_data = bus;
317 i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
318 i2c_add_adapter(&bus->i2c_adap);
319
320 bus->i2c_client.adapter = &bus->i2c_adap;
321
322 //set up the I2c
323 bus->i2c_client.addr = (0x88 >> 1);
324
325 return bus->i2c_rc;
326}
327
328int cx25821_i2c_unregister(struct cx25821_i2c *bus)
329{
330 i2c_del_adapter(&bus->i2c_adap);
331 return 0;
332}
333
334void cx25821_av_clk(struct cx25821_dev *dev, int enable)
335{
336 /* write 0 to bus 2 addr 0x144 via i2x_xfer() */
337 char buffer[3];
338 struct i2c_msg msg;
339 dprintk(1, "%s(enabled = %d)\n", __func__, enable);
340
341 /* Register 0x144 */
342 buffer[0] = 0x01;
343 buffer[1] = 0x44;
344 if (enable == 1)
345 buffer[2] = 0x05;
346 else
347 buffer[2] = 0x00;
348
349 msg.addr = 0x44;
350 msg.flags = I2C_M_TEN;
351 msg.len = 3;
352 msg.buf = buffer;
353
354 i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1);
355}
356
357int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
358{
359 struct i2c_client *client = &bus->i2c_client;
360 int retval = 0;
361 int v = 0;
362 u8 addr[2] = { 0, 0 };
363 u8 buf[4] = { 0, 0, 0, 0 };
364
365 struct i2c_msg msgs[2] = {
366 {
367 .addr = client->addr,
368 .flags = 0,
369 .len = 2,
370 .buf = addr,
371 }, {
372 .addr = client->addr,
373 .flags = I2C_M_RD,
374 .len = 4,
375 .buf = buf,
376 }
377 };
378
379 addr[0] = (reg_addr >> 8);
380 addr[1] = (reg_addr & 0xff);
381 msgs[0].addr = 0x44;
382 msgs[1].addr = 0x44;
383
384 retval = i2c_xfer(client->adapter, msgs, 2);
385
386 v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
387 *value = v;
388
389 return v;
390}
391
392int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value)
393{
394 struct i2c_client *client = &bus->i2c_client;
395 int retval = 0;
396 u8 buf[6] = { 0, 0, 0, 0, 0, 0 };
397
398 struct i2c_msg msgs[1] = {
399 {
400 .addr = client->addr,
401 .flags = 0,
402 .len = 6,
403 .buf = buf,
404 }
405 };
406
407 buf[0] = reg_addr >> 8;
408 buf[1] = reg_addr & 0xff;
409 buf[5] = (value >> 24) & 0xff;
410 buf[4] = (value >> 16) & 0xff;
411 buf[3] = (value >> 8) & 0xff;
412 buf[2] = value & 0xff;
413 client->flags = 0;
414 msgs[0].addr = 0x44;
415
416 retval = i2c_xfer(client->adapter, msgs, 1);
417
418 return retval;
419}
diff --git a/drivers/staging/cx25821/cx25821-medusa-defines.h b/drivers/staging/cx25821/cx25821-medusa-defines.h
new file mode 100644
index 000000000000..b0d216ba7f81
--- /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 000000000000..12c90f831b22
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-reg.h
@@ -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 *
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#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
new file mode 100644
index 000000000000..e4df8134f059
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -0,0 +1,869 @@
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//medusa_enable_bluefield_output()
29//
30// Enable the generation of blue filed output if no video
31//
32static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
33 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 switch (channel) {
42 default:
43 case VDEC_A:
44 break;
45 case VDEC_B:
46 out_ctrl = VDEC_B_OUT_CTRL1;
47 out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
48 break;
49 case VDEC_C:
50 out_ctrl = VDEC_C_OUT_CTRL1;
51 out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
52 break;
53 case VDEC_D:
54 out_ctrl = VDEC_D_OUT_CTRL1;
55 out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
56 break;
57 case VDEC_E:
58 out_ctrl = VDEC_E_OUT_CTRL1;
59 out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
60 return;
61 case VDEC_F:
62 out_ctrl = VDEC_F_OUT_CTRL1;
63 out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
64 return;
65 case VDEC_G:
66 out_ctrl = VDEC_G_OUT_CTRL1;
67 out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
68 return;
69 case VDEC_H:
70 out_ctrl = VDEC_H_OUT_CTRL1;
71 out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
72 return;
73 }
74
75 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
76 value &= 0xFFFFFF7F; // clear BLUE_FIELD_EN
77 if (enable)
78 value |= 0x00000080; // set BLUE_FIELD_EN
79 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
80
81 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
82 value &= 0xFFFFFF7F;
83 if (enable)
84 value |= 0x00000080; // set BLUE_FIELD_EN
85 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
86}
87
88static int medusa_initialize_ntsc(struct cx25821_dev *dev)
89{
90 int ret_val = 0;
91 int i = 0;
92 u32 value = 0;
93 u32 tmp = 0;
94
95 mutex_lock(&dev->lock);
96
97 for (i = 0; i < MAX_DECODERS; i++) {
98 // set video format NTSC-M
99 value =
100 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
101 &tmp);
102 value &= 0xFFFFFFF0;
103 value |= 0x10001; // enable the fast locking mode bit[16]
104 ret_val =
105 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
106 value);
107
108 // resolution NTSC 720x480
109 value =
110 cx25821_i2c_read(&dev->i2c_bus[0],
111 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
112 value &= 0x00C00C00;
113 value |= 0x612D0074;
114 ret_val =
115 cx25821_i2c_write(&dev->i2c_bus[0],
116 HORIZ_TIM_CTRL + (0x200 * i), value);
117
118 value =
119 cx25821_i2c_read(&dev->i2c_bus[0],
120 VERT_TIM_CTRL + (0x200 * i), &tmp);
121 value &= 0x00C00C00;
122 value |= 0x1C1E001A; // vblank_cnt + 2 to get camera ID
123 ret_val =
124 cx25821_i2c_write(&dev->i2c_bus[0],
125 VERT_TIM_CTRL + (0x200 * i), value);
126
127 // chroma subcarrier step size
128 ret_val =
129 cx25821_i2c_write(&dev->i2c_bus[0],
130 SC_STEP_SIZE + (0x200 * i), 0x43E00000);
131
132 // enable VIP optional active
133 value =
134 cx25821_i2c_read(&dev->i2c_bus[0],
135 OUT_CTRL_NS + (0x200 * i), &tmp);
136 value &= 0xFFFBFFFF;
137 value |= 0x00040000;
138 ret_val =
139 cx25821_i2c_write(&dev->i2c_bus[0],
140 OUT_CTRL_NS + (0x200 * i), value);
141
142 // enable VIP optional active (VIP_OPT_AL) for direct output.
143 value =
144 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
145 &tmp);
146 value &= 0xFFFBFFFF;
147 value |= 0x00040000;
148 ret_val =
149 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
150 value);
151
152 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
153 // when the input switching rate < 16 fields
154 //
155 value =
156 cx25821_i2c_read(&dev->i2c_bus[0],
157 MISC_TIM_CTRL + (0x200 * i), &tmp);
158 value = setBitAtPos(value, 14); // disable special play detection
159 value = clearBitAtPos(value, 15);
160 ret_val =
161 cx25821_i2c_write(&dev->i2c_bus[0],
162 MISC_TIM_CTRL + (0x200 * i), value);
163
164 // set vbi_gate_en to 0
165 value =
166 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
167 &tmp);
168 value = clearBitAtPos(value, 29);
169 ret_val =
170 cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
171 value);
172
173 // Enable the generation of blue field output if no video
174 medusa_enable_bluefield_output(dev, i, 1);
175 }
176
177 for (i = 0; i < MAX_ENCODERS; i++) {
178 // NTSC hclock
179 value =
180 cx25821_i2c_read(&dev->i2c_bus[0],
181 DENC_A_REG_1 + (0x100 * i), &tmp);
182 value &= 0xF000FC00;
183 value |= 0x06B402D0;
184 ret_val =
185 cx25821_i2c_write(&dev->i2c_bus[0],
186 DENC_A_REG_1 + (0x100 * i), value);
187
188 // burst begin and burst end
189 value =
190 cx25821_i2c_read(&dev->i2c_bus[0],
191 DENC_A_REG_2 + (0x100 * i), &tmp);
192 value &= 0xFF000000;
193 value |= 0x007E9054;
194 ret_val =
195 cx25821_i2c_write(&dev->i2c_bus[0],
196 DENC_A_REG_2 + (0x100 * i), value);
197
198 value =
199 cx25821_i2c_read(&dev->i2c_bus[0],
200 DENC_A_REG_3 + (0x100 * i), &tmp);
201 value &= 0xFC00FE00;
202 value |= 0x00EC00F0;
203 ret_val =
204 cx25821_i2c_write(&dev->i2c_bus[0],
205 DENC_A_REG_3 + (0x100 * i), value);
206
207 // set NTSC vblank, no phase alternation, 7.5 IRE pedestal
208 value =
209 cx25821_i2c_read(&dev->i2c_bus[0],
210 DENC_A_REG_4 + (0x100 * i), &tmp);
211 value &= 0x00FCFFFF;
212 value |= 0x13020000;
213 ret_val =
214 cx25821_i2c_write(&dev->i2c_bus[0],
215 DENC_A_REG_4 + (0x100 * i), value);
216
217 value =
218 cx25821_i2c_read(&dev->i2c_bus[0],
219 DENC_A_REG_5 + (0x100 * i), &tmp);
220 value &= 0xFFFF0000;
221 value |= 0x0000E575;
222 ret_val =
223 cx25821_i2c_write(&dev->i2c_bus[0],
224 DENC_A_REG_5 + (0x100 * i), value);
225
226 ret_val =
227 cx25821_i2c_write(&dev->i2c_bus[0],
228 DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
229
230 // Subcarrier Increment
231 ret_val =
232 cx25821_i2c_write(&dev->i2c_bus[0],
233 DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
234 }
235
236 //set picture resolutions
237 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
238 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 480
239
240 // set Bypass input format to NTSC 525 lines
241 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
242 value |= 0x00080200;
243 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
244
245 mutex_unlock(&dev->lock);
246
247 return ret_val;
248}
249
250static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
251{
252 int ret_val = -1;
253 u32 value = 0, tmp = 0;
254
255 // Setup for 2D threshold
256 ret_val =
257 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec),
258 0x20002861);
259 ret_val =
260 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG + (0x200 * dec),
261 0x20002861);
262 ret_val =
263 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec),
264 0x200A1023);
265
266 // Setup flat chroma and luma thresholds
267 value =
268 cx25821_i2c_read(&dev->i2c_bus[0],
269 COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
270 value &= 0x06230000;
271 ret_val =
272 cx25821_i2c_write(&dev->i2c_bus[0],
273 COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
274
275 // set comb 2D blend
276 ret_val =
277 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec),
278 0x210F0F0F);
279
280 // COMB MISC CONTROL
281 ret_val =
282 cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec),
283 0x41120A7F);
284
285 return ret_val;
286}
287
288static int medusa_initialize_pal(struct cx25821_dev *dev)
289{
290 int ret_val = 0;
291 int i = 0;
292 u32 value = 0;
293 u32 tmp = 0;
294
295 mutex_lock(&dev->lock);
296
297 for (i = 0; i < MAX_DECODERS; i++) {
298 // set video format PAL-BDGHI
299 value =
300 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
301 &tmp);
302 value &= 0xFFFFFFF0;
303 value |= 0x10004; // enable the fast locking mode bit[16]
304 ret_val =
305 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
306 value);
307
308 // resolution PAL 720x576
309 value =
310 cx25821_i2c_read(&dev->i2c_bus[0],
311 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
312 value &= 0x00C00C00;
313 value |= 0x632D007D;
314 ret_val =
315 cx25821_i2c_write(&dev->i2c_bus[0],
316 HORIZ_TIM_CTRL + (0x200 * i), value);
317
318 // vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24
319 value =
320 cx25821_i2c_read(&dev->i2c_bus[0],
321 VERT_TIM_CTRL + (0x200 * i), &tmp);
322 value &= 0x00C00C00;
323 value |= 0x28240026; // vblank_cnt + 2 to get camera ID
324 ret_val =
325 cx25821_i2c_write(&dev->i2c_bus[0],
326 VERT_TIM_CTRL + (0x200 * i), value);
327
328 // chroma subcarrier step size
329 ret_val =
330 cx25821_i2c_write(&dev->i2c_bus[0],
331 SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
332
333 // enable VIP optional active
334 value =
335 cx25821_i2c_read(&dev->i2c_bus[0],
336 OUT_CTRL_NS + (0x200 * i), &tmp);
337 value &= 0xFFFBFFFF;
338 value |= 0x00040000;
339 ret_val =
340 cx25821_i2c_write(&dev->i2c_bus[0],
341 OUT_CTRL_NS + (0x200 * i), value);
342
343 // enable VIP optional active (VIP_OPT_AL) for direct output.
344 value =
345 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
346 &tmp);
347 value &= 0xFFFBFFFF;
348 value |= 0x00040000;
349 ret_val =
350 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
351 value);
352
353 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
354 // when the input switching rate < 16 fields
355 value =
356 cx25821_i2c_read(&dev->i2c_bus[0],
357 MISC_TIM_CTRL + (0x200 * i), &tmp);
358 value = setBitAtPos(value, 14); // disable special play detection
359 value = clearBitAtPos(value, 15);
360 ret_val =
361 cx25821_i2c_write(&dev->i2c_bus[0],
362 MISC_TIM_CTRL + (0x200 * i), value);
363
364 // set vbi_gate_en to 0
365 value =
366 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
367 &tmp);
368 value = clearBitAtPos(value, 29);
369 ret_val =
370 cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
371 value);
372
373 medusa_PALCombInit(dev, i);
374
375 // Enable the generation of blue field output if no video
376 medusa_enable_bluefield_output(dev, i, 1);
377 }
378
379 for (i = 0; i < MAX_ENCODERS; i++) {
380 // PAL hclock
381 value =
382 cx25821_i2c_read(&dev->i2c_bus[0],
383 DENC_A_REG_1 + (0x100 * i), &tmp);
384 value &= 0xF000FC00;
385 value |= 0x06C002D0;
386 ret_val =
387 cx25821_i2c_write(&dev->i2c_bus[0],
388 DENC_A_REG_1 + (0x100 * i), value);
389
390 // burst begin and burst end
391 value =
392 cx25821_i2c_read(&dev->i2c_bus[0],
393 DENC_A_REG_2 + (0x100 * i), &tmp);
394 value &= 0xFF000000;
395 value |= 0x007E9754;
396 ret_val =
397 cx25821_i2c_write(&dev->i2c_bus[0],
398 DENC_A_REG_2 + (0x100 * i), value);
399
400 // hblank and vactive
401 value =
402 cx25821_i2c_read(&dev->i2c_bus[0],
403 DENC_A_REG_3 + (0x100 * i), &tmp);
404 value &= 0xFC00FE00;
405 value |= 0x00FC0120;
406 ret_val =
407 cx25821_i2c_write(&dev->i2c_bus[0],
408 DENC_A_REG_3 + (0x100 * i), value);
409
410 // set PAL vblank, phase alternation, 0 IRE pedestal
411 value =
412 cx25821_i2c_read(&dev->i2c_bus[0],
413 DENC_A_REG_4 + (0x100 * i), &tmp);
414 value &= 0x00FCFFFF;
415 value |= 0x14010000;
416 ret_val =
417 cx25821_i2c_write(&dev->i2c_bus[0],
418 DENC_A_REG_4 + (0x100 * i), value);
419
420 value =
421 cx25821_i2c_read(&dev->i2c_bus[0],
422 DENC_A_REG_5 + (0x100 * i), &tmp);
423 value &= 0xFFFF0000;
424 value |= 0x0000F078;
425 ret_val =
426 cx25821_i2c_write(&dev->i2c_bus[0],
427 DENC_A_REG_5 + (0x100 * i), value);
428
429 ret_val =
430 cx25821_i2c_write(&dev->i2c_bus[0],
431 DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
432
433 // Subcarrier Increment
434 ret_val =
435 cx25821_i2c_write(&dev->i2c_bus[0],
436 DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
437 }
438
439 //set picture resolutions
440 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
441 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 576
442
443 // set Bypass input format to PAL 625 lines
444 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
445 value &= 0xFFF7FDFF;
446 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
447
448 mutex_unlock(&dev->lock);
449
450 return ret_val;
451}
452
453int medusa_set_videostandard(struct cx25821_dev *dev)
454{
455 int status = STATUS_SUCCESS;
456 u32 value = 0, tmp = 0;
457
458 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) {
459 status = medusa_initialize_pal(dev);
460 } else {
461 status = medusa_initialize_ntsc(dev);
462 }
463
464 // Enable DENC_A output
465 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
466 value = setBitAtPos(value, 4);
467 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
468
469 // Enable DENC_B output
470 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
471 value = setBitAtPos(value, 4);
472 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
473
474 return status;
475}
476
477void medusa_set_resolution(struct cx25821_dev *dev, int width,
478 int decoder_select)
479{
480 int decoder = 0;
481 int decoder_count = 0;
482 int ret_val = 0;
483 u32 hscale = 0x0;
484 u32 vscale = 0x0;
485 const int MAX_WIDTH = 720;
486
487 mutex_lock(&dev->lock);
488
489 // validate the width - cannot be negative
490 if (width > MAX_WIDTH) {
491 printk
492 ("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH \n",
493 __func__, width, MAX_WIDTH);
494 width = MAX_WIDTH;
495 }
496
497 if (decoder_select <= 7 && decoder_select >= 0) {
498 decoder = decoder_select;
499 decoder_count = decoder_select + 1;
500 } else {
501 decoder = 0;
502 decoder_count = _num_decoders;
503 }
504
505 switch (width) {
506 case 320:
507 hscale = 0x13E34B;
508 vscale = 0x0;
509 break;
510
511 case 352:
512 hscale = 0x10A273;
513 vscale = 0x0;
514 break;
515
516 case 176:
517 hscale = 0x3115B2;
518 vscale = 0x1E00;
519 break;
520
521 case 160:
522 hscale = 0x378D84;
523 vscale = 0x1E00;
524 break;
525
526 default: //720
527 hscale = 0x0;
528 vscale = 0x0;
529 break;
530 }
531
532 for (; decoder < decoder_count; decoder++) {
533 // write scaling values for each decoder
534 ret_val =
535 cx25821_i2c_write(&dev->i2c_bus[0],
536 HSCALE_CTRL + (0x200 * decoder), hscale);
537 ret_val =
538 cx25821_i2c_write(&dev->i2c_bus[0],
539 VSCALE_CTRL + (0x200 * decoder), vscale);
540 }
541
542 mutex_unlock(&dev->lock);
543}
544
545static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
546 int duration)
547{
548 int ret_val = 0;
549 u32 fld_cnt = 0;
550 u32 tmp = 0;
551 u32 disp_cnt_reg = DISP_AB_CNT;
552
553 mutex_lock(&dev->lock);
554
555 // no support
556 if (decoder < VDEC_A && decoder > VDEC_H) {
557 mutex_unlock(&dev->lock);
558 return;
559 }
560
561 switch (decoder) {
562 default:
563 break;
564 case VDEC_C:
565 case VDEC_D:
566 disp_cnt_reg = DISP_CD_CNT;
567 break;
568 case VDEC_E:
569 case VDEC_F:
570 disp_cnt_reg = DISP_EF_CNT;
571 break;
572 case VDEC_G:
573 case VDEC_H:
574 disp_cnt_reg = DISP_GH_CNT;
575 break;
576 }
577
578 _display_field_cnt[decoder] = duration;
579
580 // update hardware
581 fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
582
583 if (!(decoder % 2)) // EVEN decoder
584 {
585 fld_cnt &= 0xFFFF0000;
586 fld_cnt |= duration;
587 } else {
588 fld_cnt &= 0x0000FFFF;
589 fld_cnt |= ((u32) duration) << 16;
590 }
591
592 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
593
594 mutex_unlock(&dev->lock);
595}
596
597/////////////////////////////////////////////////////////////////////////////////////////
598// Map to Medusa register setting
599static int mapM(int srcMin,
600 int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal)
601{
602 int numerator;
603 int denominator;
604 int quotient;
605
606 if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax)) {
607 return -1;
608 }
609 // This is the overall expression used:
610 // *dstVal = (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
611 // but we need to account for rounding so below we use the modulus
612 // operator to find the remainder and increment if necessary.
613 numerator = (srcVal - srcMin) * (dstMax - dstMin);
614 denominator = srcMax - srcMin;
615 quotient = numerator / denominator;
616
617 if (2 * (numerator % denominator) >= denominator) {
618 quotient++;
619 }
620
621 *dstVal = quotient + dstMin;
622
623 return 0;
624}
625
626static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
627{
628 unsigned char temp;
629
630 if (numeric >= 0)
631 return numeric;
632 else {
633 temp = ~(abs(numeric) & 0xFF);
634 temp += 1;
635 return temp;
636 }
637}
638
639/////////////////////////////////////////////////////////////////////////////////////////
640int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
641{
642 int ret_val = 0;
643 int value = 0;
644 u32 val = 0, tmp = 0;
645
646 mutex_lock(&dev->lock);
647 if ((brightness > VIDEO_PROCAMP_MAX)
648 || (brightness < VIDEO_PROCAMP_MIN)) {
649 mutex_unlock(&dev->lock);
650 return -1;
651 }
652 ret_val =
653 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
654 SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
655 value = convert_to_twos(value, 8);
656 val =
657 cx25821_i2c_read(&dev->i2c_bus[0],
658 VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
659 val &= 0xFFFFFF00;
660 ret_val |=
661 cx25821_i2c_write(&dev->i2c_bus[0],
662 VDEC_A_BRITE_CTRL + (0x200 * decoder),
663 val | value);
664 mutex_unlock(&dev->lock);
665 return ret_val;
666}
667
668/////////////////////////////////////////////////////////////////////////////////////////
669int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
670{
671 int ret_val = 0;
672 int value = 0;
673 u32 val = 0, tmp = 0;
674
675 mutex_lock(&dev->lock);
676
677 if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
678 mutex_unlock(&dev->lock);
679 return -1;
680 }
681
682 ret_val =
683 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
684 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
685 val =
686 cx25821_i2c_read(&dev->i2c_bus[0],
687 VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
688 val &= 0xFFFFFF00;
689 ret_val |=
690 cx25821_i2c_write(&dev->i2c_bus[0],
691 VDEC_A_CNTRST_CTRL + (0x200 * decoder),
692 val | value);
693
694 mutex_unlock(&dev->lock);
695 return ret_val;
696}
697
698/////////////////////////////////////////////////////////////////////////////////////////
699int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
700{
701 int ret_val = 0;
702 int value = 0;
703 u32 val = 0, tmp = 0;
704
705 mutex_lock(&dev->lock);
706
707 if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
708 mutex_unlock(&dev->lock);
709 return -1;
710 }
711
712 ret_val =
713 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN,
714 SIGNED_BYTE_MAX, &value);
715
716 value = convert_to_twos(value, 8);
717 val =
718 cx25821_i2c_read(&dev->i2c_bus[0],
719 VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
720 val &= 0xFFFFFF00;
721
722 ret_val |=
723 cx25821_i2c_write(&dev->i2c_bus[0],
724 VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
725
726 mutex_unlock(&dev->lock);
727 return ret_val;
728}
729
730/////////////////////////////////////////////////////////////////////////////////////////
731int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
732{
733 int ret_val = 0;
734 int value = 0;
735 u32 val = 0, tmp = 0;
736
737 mutex_lock(&dev->lock);
738
739 if ((saturation > VIDEO_PROCAMP_MAX)
740 || (saturation < VIDEO_PROCAMP_MIN)) {
741 mutex_unlock(&dev->lock);
742 return -1;
743 }
744
745 ret_val =
746 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
747 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
748
749 val =
750 cx25821_i2c_read(&dev->i2c_bus[0],
751 VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
752 val &= 0xFFFFFF00;
753 ret_val |=
754 cx25821_i2c_write(&dev->i2c_bus[0],
755 VDEC_A_USAT_CTRL + (0x200 * decoder),
756 val | value);
757
758 val =
759 cx25821_i2c_read(&dev->i2c_bus[0],
760 VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
761 val &= 0xFFFFFF00;
762 ret_val |=
763 cx25821_i2c_write(&dev->i2c_bus[0],
764 VDEC_A_VSAT_CTRL + (0x200 * decoder),
765 val | value);
766
767 mutex_unlock(&dev->lock);
768 return ret_val;
769}
770
771/////////////////////////////////////////////////////////////////////////////////////////
772// Program the display sequence and monitor output.
773//
774int medusa_video_init(struct cx25821_dev *dev)
775{
776 u32 value = 0, tmp = 0;
777 int ret_val = 0;
778 int i = 0;
779
780 mutex_lock(&dev->lock);
781
782 _num_decoders = dev->_max_num_decoders;
783
784 // disable Auto source selection on all video decoders
785 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
786 value &= 0xFFFFF0FF;
787 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
788
789 if (ret_val < 0) {
790 mutex_unlock(&dev->lock);
791 return -EINVAL;
792 }
793 // Turn off Master source switch enable
794 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
795 value &= 0xFFFFFFDF;
796 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
797
798 if (ret_val < 0) {
799 mutex_unlock(&dev->lock);
800 return -EINVAL;
801 }
802
803 mutex_unlock(&dev->lock);
804
805 for (i = 0; i < _num_decoders; i++) {
806 medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
807 }
808
809 mutex_lock(&dev->lock);
810
811 // Select monitor as DENC A input, power up the DAC
812 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
813 value &= 0xFF70FF70;
814 value |= 0x00090008; // set en_active
815 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
816
817 if (ret_val < 0) {
818 mutex_unlock(&dev->lock);
819 return -EINVAL;
820 }
821 // enable input is VIP/656
822 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
823 value |= 0x00040100; // enable VIP
824 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
825
826 if (ret_val < 0) {
827 mutex_unlock(&dev->lock);
828 return -EINVAL;
829 }
830 // select AFE clock to output mode
831 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
832 value &= 0x83FFFFFF;
833 ret_val =
834 cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
835 value | 0x10000000);
836
837 if (ret_val < 0) {
838 mutex_unlock(&dev->lock);
839 return -EINVAL;
840 }
841 // Turn on all of the data out and control output pins.
842 value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
843 value &= 0xFEF0FE00;
844 if (_num_decoders == MAX_DECODERS) {
845 // Note: The octal board does not support control pins(bit16-19).
846 // These bits are ignored in the octal board.
847 value |= 0x010001F8; // disable VDEC A-C port, default to Mobilygen Interface
848 } else {
849 value |= 0x010F0108; // disable VDEC A-C port, default to Mobilygen Interface
850 }
851
852 value |= 7;
853 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
854 if (ret_val < 0) {
855 mutex_unlock(&dev->lock);
856 return -EINVAL;
857 }
858
859 mutex_unlock(&dev->lock);
860
861 ret_val = medusa_set_videostandard(dev);
862
863 if (ret_val < 0) {
864 mutex_unlock(&dev->lock);
865 return -EINVAL;
866 }
867
868 return 1;
869}
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.h b/drivers/staging/cx25821/cx25821-medusa-video.h
new file mode 100644
index 000000000000..2fab4b2f251c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.h
@@ -0,0 +1,49 @@
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// Color control constants
29#define VIDEO_PROCAMP_MIN 0
30#define VIDEO_PROCAMP_MAX 10000
31#define UNSIGNED_BYTE_MIN 0
32#define UNSIGNED_BYTE_MAX 0xFF
33#define SIGNED_BYTE_MIN -128
34#define SIGNED_BYTE_MAX 127
35
36// Default video color settings
37#define SHARPNESS_DEFAULT 50
38#define SATURATION_DEFAULT 5000
39#define BRIGHTNESS_DEFAULT 6200
40#define CONTRAST_DEFAULT 5000
41#define HUE_DEFAULT 5000
42
43unsigned short _num_decoders;
44unsigned short _num_cameras;
45
46unsigned int _video_standard;
47int _display_field_cnt[MAX_DECODERS];
48
49#endif
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/staging/cx25821/cx25821-reg.h
new file mode 100644
index 000000000000..7241e7ee3fd3
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-reg.h
@@ -0,0 +1,1592 @@
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#define AUD_A_INT_MSK 0x0400C0 // Audio Int interrupt mask
171#define AUD_A_INT_STAT 0x0400C4 // Audio Int interrupt status
172#define AUD_A_INT_MSTAT 0x0400C8 // Audio Int interrupt masked status
173#define AUD_A_INT_SSTAT 0x0400CC // Audio Int interrupt set status
174
175//*****************************************************************************
176#define AUD_B_INT_MSK 0x0400D0 // Audio Int interrupt mask
177#define AUD_B_INT_STAT 0x0400D4 // Audio Int interrupt status
178#define AUD_B_INT_MSTAT 0x0400D8 // Audio Int interrupt masked status
179#define AUD_B_INT_SSTAT 0x0400DC // Audio Int interrupt set status
180
181//*****************************************************************************
182#define AUD_C_INT_MSK 0x0400E0 // Audio Int interrupt mask
183#define AUD_C_INT_STAT 0x0400E4 // Audio Int interrupt status
184#define AUD_C_INT_MSTAT 0x0400E8 // Audio Int interrupt masked status
185#define AUD_C_INT_SSTAT 0x0400EC // Audio Int interrupt set status
186
187//*****************************************************************************
188#define AUD_D_INT_MSK 0x0400F0 // Audio Int interrupt mask
189#define AUD_D_INT_STAT 0x0400F4 // Audio Int interrupt status
190#define AUD_D_INT_MSTAT 0x0400F8 // Audio Int interrupt masked status
191#define AUD_D_INT_SSTAT 0x0400FC // Audio Int interrupt set status
192
193//*****************************************************************************
194#define AUD_E_INT_MSK 0x040100 // Audio Int interrupt mask
195#define AUD_E_INT_STAT 0x040104 // Audio Int interrupt status
196#define AUD_E_INT_MSTAT 0x040108 // Audio Int interrupt masked status
197#define AUD_E_INT_SSTAT 0x04010C // Audio Int interrupt set status
198
199#define FLD_AUD_SRC_OPC_ERR 0x00020000
200#define FLD_AUD_DST_OPC_ERR 0x00010000
201#define FLD_AUD_SRC_SYNC 0x00002000
202#define FLD_AUD_DST_SYNC 0x00001000
203#define FLD_AUD_SRC_OF 0x00000200
204#define FLD_AUD_DST_OF 0x00000100
205#define FLD_AUD_SRC_RISCI2 0x00000020
206#define FLD_AUD_DST_RISCI2 0x00000010
207#define FLD_AUD_SRC_RISCI1 0x00000002
208#define FLD_AUD_DST_RISCI1 0x00000001
209
210//*****************************************************************************
211#define MBIF_A_INT_MSK 0x040110 // MBIF Int interrupt mask
212#define MBIF_A_INT_STAT 0x040114 // MBIF Int interrupt status
213#define MBIF_A_INT_MSTAT 0x040118 // MBIF Int interrupt masked status
214#define MBIF_A_INT_SSTAT 0x04011C // MBIF Int interrupt set status
215
216//*****************************************************************************
217#define MBIF_B_INT_MSK 0x040120 // MBIF Int interrupt mask
218#define MBIF_B_INT_STAT 0x040124 // MBIF Int interrupt status
219#define MBIF_B_INT_MSTAT 0x040128 // MBIF Int interrupt masked status
220#define MBIF_B_INT_SSTAT 0x04012C // MBIF Int interrupt set status
221
222#define FLD_MBIF_DST_OPC_ERR 0x00010000
223#define FLD_MBIF_DST_SYNC 0x00001000
224#define FLD_MBIF_DST_OF 0x00000100
225#define FLD_MBIF_DST_RISCI2 0x00000010
226#define FLD_MBIF_DST_RISCI1 0x00000001
227
228//*****************************************************************************
229#define AUD_EXT_INT_MSK 0x040060 // Audio Ext interrupt mask
230#define AUD_EXT_INT_STAT 0x040064 // Audio Ext interrupt status
231#define AUD_EXT_INT_MSTAT 0x040068 // Audio Ext interrupt masked status
232#define AUD_EXT_INT_SSTAT 0x04006C // Audio Ext interrupt set status
233#define FLD_AUD_EXT_OPC_ERR 0x00010000
234#define FLD_AUD_EXT_SYNC 0x00001000
235#define FLD_AUD_EXT_OF 0x00000100
236#define FLD_AUD_EXT_RISCI2 0x00000010
237#define FLD_AUD_EXT_RISCI1 0x00000001
238
239//*****************************************************************************
240#define GPIO_LO 0x110010 // Lower of GPIO pins [31:0]
241#define GPIO_HI 0x110014 // Upper WORD of GPIO pins [47:31]
242
243#define GPIO_LO_OE 0x110018 // Lower of GPIO output enable [31:0]
244#define GPIO_HI_OE 0x11001C // Upper word of GPIO output enable [47:32]
245
246#define GPIO_LO_INT_MSK 0x11003C // GPIO interrupt mask
247#define GPIO_LO_INT_STAT 0x110044 // GPIO interrupt status
248#define GPIO_LO_INT_MSTAT 0x11004C // GPIO interrupt masked status
249#define GPIO_LO_ISM_SNS 0x110054 // GPIO interrupt sensitivity
250#define GPIO_LO_ISM_POL 0x11005C // GPIO interrupt polarity
251
252#define GPIO_HI_INT_MSK 0x110040 // GPIO interrupt mask
253#define GPIO_HI_INT_STAT 0x110048 // GPIO interrupt status
254#define GPIO_HI_INT_MSTAT 0x110050 // GPIO interrupt masked status
255#define GPIO_HI_ISM_SNS 0x110058 // GPIO interrupt sensitivity
256#define GPIO_HI_ISM_POL 0x110060 // GPIO interrupt polarity
257
258#define FLD_GPIO43_INT (1 << 11)
259#define FLD_GPIO42_INT (1 << 10)
260#define FLD_GPIO41_INT (1 << 9)
261#define FLD_GPIO40_INT (1 << 8)
262
263#define FLD_GPIO9_INT (1 << 9)
264#define FLD_GPIO8_INT (1 << 8)
265#define FLD_GPIO7_INT (1 << 7)
266#define FLD_GPIO6_INT (1 << 6)
267#define FLD_GPIO5_INT (1 << 5)
268#define FLD_GPIO4_INT (1 << 4)
269#define FLD_GPIO3_INT (1 << 3)
270#define FLD_GPIO2_INT (1 << 2)
271#define FLD_GPIO1_INT (1 << 1)
272#define FLD_GPIO0_INT (1 << 0)
273
274//*****************************************************************************
275#define TC_REQ 0x040090 // Rider PCI Express traFFic class request
276
277//*****************************************************************************
278#define TC_REQ_SET 0x040094 // Rider PCI Express traFFic class request set
279
280//*****************************************************************************
281// Rider
282//*****************************************************************************
283
284// PCI Compatible Header
285//*****************************************************************************
286#define RDR_CFG0 0x050000
287#define RDR_VENDOR_DEVICE_ID_CFG 0x050000
288
289//*****************************************************************************
290#define RDR_CFG1 0x050004
291
292//*****************************************************************************
293#define RDR_CFG2 0x050008
294
295//*****************************************************************************
296#define RDR_CFG3 0x05000C
297
298//*****************************************************************************
299#define RDR_CFG4 0x050010
300
301//*****************************************************************************
302#define RDR_CFG5 0x050014
303
304//*****************************************************************************
305#define RDR_CFG6 0x050018
306
307//*****************************************************************************
308#define RDR_CFG7 0x05001C
309
310//*****************************************************************************
311#define RDR_CFG8 0x050020
312
313//*****************************************************************************
314#define RDR_CFG9 0x050024
315
316//*****************************************************************************
317#define RDR_CFGA 0x050028
318
319//*****************************************************************************
320#define RDR_CFGB 0x05002C
321#define RDR_SUSSYSTEM_ID_CFG 0x05002C
322
323//*****************************************************************************
324#define RDR_CFGC 0x050030
325
326//*****************************************************************************
327#define RDR_CFGD 0x050034
328
329//*****************************************************************************
330#define RDR_CFGE 0x050038
331
332//*****************************************************************************
333#define RDR_CFGF 0x05003C
334
335//*****************************************************************************
336// PCI-Express Capabilities
337//*****************************************************************************
338#define RDR_PECAP 0x050040
339
340//*****************************************************************************
341#define RDR_PEDEVCAP 0x050044
342
343//*****************************************************************************
344#define RDR_PEDEVSC 0x050048
345
346//*****************************************************************************
347#define RDR_PELINKCAP 0x05004C
348
349//*****************************************************************************
350#define RDR_PELINKSC 0x050050
351
352//*****************************************************************************
353#define RDR_PMICAP 0x050080
354
355//*****************************************************************************
356#define RDR_PMCSR 0x050084
357
358//*****************************************************************************
359#define RDR_VPDCAP 0x050090
360
361//*****************************************************************************
362#define RDR_VPDDATA 0x050094
363
364//*****************************************************************************
365#define RDR_MSICAP 0x0500A0
366
367//*****************************************************************************
368#define RDR_MSIARL 0x0500A4
369
370//*****************************************************************************
371#define RDR_MSIARU 0x0500A8
372
373//*****************************************************************************
374#define RDR_MSIDATA 0x0500AC
375
376//*****************************************************************************
377// PCI Express Extended Capabilities
378//*****************************************************************************
379#define RDR_AERXCAP 0x050100
380
381//*****************************************************************************
382#define RDR_AERUESTA 0x050104
383
384//*****************************************************************************
385#define RDR_AERUEMSK 0x050108
386
387//*****************************************************************************
388#define RDR_AERUESEV 0x05010C
389
390//*****************************************************************************
391#define RDR_AERCESTA 0x050110
392
393//*****************************************************************************
394#define RDR_AERCEMSK 0x050114
395
396//*****************************************************************************
397#define RDR_AERCC 0x050118
398
399//*****************************************************************************
400#define RDR_AERHL0 0x05011C
401
402//*****************************************************************************
403#define RDR_AERHL1 0x050120
404
405//*****************************************************************************
406#define RDR_AERHL2 0x050124
407
408//*****************************************************************************
409#define RDR_AERHL3 0x050128
410
411//*****************************************************************************
412#define RDR_VCXCAP 0x050200
413
414//*****************************************************************************
415#define RDR_VCCAP1 0x050204
416
417//*****************************************************************************
418#define RDR_VCCAP2 0x050208
419
420//*****************************************************************************
421#define RDR_VCSC 0x05020C
422
423//*****************************************************************************
424#define RDR_VCR0_CAP 0x050210
425
426//*****************************************************************************
427#define RDR_VCR0_CTRL 0x050214
428
429//*****************************************************************************
430#define RDR_VCR0_STAT 0x050218
431
432//*****************************************************************************
433#define RDR_VCR1_CAP 0x05021C
434
435//*****************************************************************************
436#define RDR_VCR1_CTRL 0x050220
437
438//*****************************************************************************
439#define RDR_VCR1_STAT 0x050224
440
441//*****************************************************************************
442#define RDR_VCR2_CAP 0x050228
443
444//*****************************************************************************
445#define RDR_VCR2_CTRL 0x05022C
446
447//*****************************************************************************
448#define RDR_VCR2_STAT 0x050230
449
450//*****************************************************************************
451#define RDR_VCR3_CAP 0x050234
452
453//*****************************************************************************
454#define RDR_VCR3_CTRL 0x050238
455
456//*****************************************************************************
457#define RDR_VCR3_STAT 0x05023C
458
459//*****************************************************************************
460#define RDR_VCARB0 0x050240
461
462//*****************************************************************************
463#define RDR_VCARB1 0x050244
464
465//*****************************************************************************
466#define RDR_VCARB2 0x050248
467
468//*****************************************************************************
469#define RDR_VCARB3 0x05024C
470
471//*****************************************************************************
472#define RDR_VCARB4 0x050250
473
474//*****************************************************************************
475#define RDR_VCARB5 0x050254
476
477//*****************************************************************************
478#define RDR_VCARB6 0x050258
479
480//*****************************************************************************
481#define RDR_VCARB7 0x05025C
482
483//*****************************************************************************
484#define RDR_RDRSTAT0 0x050300
485
486//*****************************************************************************
487#define RDR_RDRSTAT1 0x050304
488
489//*****************************************************************************
490#define RDR_RDRCTL0 0x050308
491
492//*****************************************************************************
493#define RDR_RDRCTL1 0x05030C
494
495//*****************************************************************************
496// Transaction Layer Registers
497//*****************************************************************************
498#define RDR_TLSTAT0 0x050310
499
500//*****************************************************************************
501#define RDR_TLSTAT1 0x050314
502
503//*****************************************************************************
504#define RDR_TLCTL0 0x050318
505#define FLD_CFG_UR_CPL_MODE 0x00000040
506#define FLD_CFG_CORR_ERR_QUITE 0x00000020
507#define FLD_CFG_RCB_CK_EN 0x00000010
508#define FLD_CFG_BNDRY_CK_EN 0x00000008
509#define FLD_CFG_BYTE_EN_CK_EN 0x00000004
510#define FLD_CFG_RELAX_ORDER_MSK 0x00000002
511#define FLD_CFG_TAG_ORDER_EN 0x00000001
512
513//*****************************************************************************
514#define RDR_TLCTL1 0x05031C
515
516//*****************************************************************************
517#define RDR_REQRCAL 0x050320
518
519//*****************************************************************************
520#define RDR_REQRCAU 0x050324
521
522//*****************************************************************************
523#define RDR_REQEPA 0x050328
524
525//*****************************************************************************
526#define RDR_REQCTRL 0x05032C
527
528//*****************************************************************************
529#define RDR_REQSTAT 0x050330
530
531//*****************************************************************************
532#define RDR_TL_TEST 0x050334
533
534//*****************************************************************************
535#define RDR_VCR01_CTL 0x050348
536
537//*****************************************************************************
538#define RDR_VCR23_CTL 0x05034C
539
540//*****************************************************************************
541#define RDR_RX_VCR0_FC 0x050350
542
543//*****************************************************************************
544#define RDR_RX_VCR1_FC 0x050354
545
546//*****************************************************************************
547#define RDR_RX_VCR2_FC 0x050358
548
549//*****************************************************************************
550#define RDR_RX_VCR3_FC 0x05035C
551
552//*****************************************************************************
553// Data Link Layer Registers
554//*****************************************************************************
555#define RDR_DLLSTAT 0x050360
556
557//*****************************************************************************
558#define RDR_DLLCTRL 0x050364
559
560//*****************************************************************************
561#define RDR_REPLAYTO 0x050368
562
563//*****************************************************************************
564#define RDR_ACKLATTO 0x05036C
565
566//*****************************************************************************
567// MAC Layer Registers
568//*****************************************************************************
569#define RDR_MACSTAT0 0x050380
570
571//*****************************************************************************
572#define RDR_MACSTAT1 0x050384
573
574//*****************************************************************************
575#define RDR_MACCTRL0 0x050388
576
577//*****************************************************************************
578#define RDR_MACCTRL1 0x05038C
579
580//*****************************************************************************
581#define RDR_MACCTRL2 0x050390
582
583//*****************************************************************************
584#define RDR_MAC_LB_DATA 0x050394
585
586//*****************************************************************************
587#define RDR_L0S_EXIT_LAT 0x050398
588
589//*****************************************************************************
590// DMAC
591//*****************************************************************************
592#define DMA1_PTR1 0x100000 // DMA Current Ptr : Ch#1
593
594//*****************************************************************************
595#define DMA2_PTR1 0x100004 // DMA Current Ptr : Ch#2
596
597//*****************************************************************************
598#define DMA3_PTR1 0x100008 // DMA Current Ptr : Ch#3
599
600//*****************************************************************************
601#define DMA4_PTR1 0x10000C // DMA Current Ptr : Ch#4
602
603//*****************************************************************************
604#define DMA5_PTR1 0x100010 // DMA Current Ptr : Ch#5
605
606//*****************************************************************************
607#define DMA6_PTR1 0x100014 // DMA Current Ptr : Ch#6
608
609//*****************************************************************************
610#define DMA7_PTR1 0x100018 // DMA Current Ptr : Ch#7
611
612//*****************************************************************************
613#define DMA8_PTR1 0x10001C // DMA Current Ptr : Ch#8
614
615//*****************************************************************************
616#define DMA9_PTR1 0x100020 // DMA Current Ptr : Ch#9
617
618//*****************************************************************************
619#define DMA10_PTR1 0x100024 // DMA Current Ptr : Ch#10
620
621//*****************************************************************************
622#define DMA11_PTR1 0x100028 // DMA Current Ptr : Ch#11
623
624//*****************************************************************************
625#define DMA12_PTR1 0x10002C // DMA Current Ptr : Ch#12
626
627//*****************************************************************************
628#define DMA13_PTR1 0x100030 // DMA Current Ptr : Ch#13
629
630//*****************************************************************************
631#define DMA14_PTR1 0x100034 // DMA Current Ptr : Ch#14
632
633//*****************************************************************************
634#define DMA15_PTR1 0x100038 // DMA Current Ptr : Ch#15
635
636//*****************************************************************************
637#define DMA16_PTR1 0x10003C // DMA Current Ptr : Ch#16
638
639//*****************************************************************************
640#define DMA17_PTR1 0x100040 // DMA Current Ptr : Ch#17
641
642//*****************************************************************************
643#define DMA18_PTR1 0x100044 // DMA Current Ptr : Ch#18
644
645//*****************************************************************************
646#define DMA19_PTR1 0x100048 // DMA Current Ptr : Ch#19
647
648//*****************************************************************************
649#define DMA20_PTR1 0x10004C // DMA Current Ptr : Ch#20
650
651//*****************************************************************************
652#define DMA21_PTR1 0x100050 // DMA Current Ptr : Ch#21
653
654//*****************************************************************************
655#define DMA22_PTR1 0x100054 // DMA Current Ptr : Ch#22
656
657//*****************************************************************************
658#define DMA23_PTR1 0x100058 // DMA Current Ptr : Ch#23
659
660//*****************************************************************************
661#define DMA24_PTR1 0x10005C // DMA Current Ptr : Ch#24
662
663//*****************************************************************************
664#define DMA25_PTR1 0x100060 // DMA Current Ptr : Ch#25
665
666//*****************************************************************************
667#define DMA26_PTR1 0x100064 // DMA Current Ptr : Ch#26
668
669//*****************************************************************************
670#define DMA1_PTR2 0x100080 // DMA Tab Ptr : Ch#1
671
672//*****************************************************************************
673#define DMA2_PTR2 0x100084 // DMA Tab Ptr : Ch#2
674
675//*****************************************************************************
676#define DMA3_PTR2 0x100088 // DMA Tab Ptr : Ch#3
677
678//*****************************************************************************
679#define DMA4_PTR2 0x10008C // DMA Tab Ptr : Ch#4
680
681//*****************************************************************************
682#define DMA5_PTR2 0x100090 // DMA Tab Ptr : Ch#5
683
684//*****************************************************************************
685#define DMA6_PTR2 0x100094 // DMA Tab Ptr : Ch#6
686
687//*****************************************************************************
688#define DMA7_PTR2 0x100098 // DMA Tab Ptr : Ch#7
689
690//*****************************************************************************
691#define DMA8_PTR2 0x10009C // DMA Tab Ptr : Ch#8
692
693//*****************************************************************************
694#define DMA9_PTR2 0x1000A0 // DMA Tab Ptr : Ch#9
695
696//*****************************************************************************
697#define DMA10_PTR2 0x1000A4 // DMA Tab Ptr : Ch#10
698
699//*****************************************************************************
700#define DMA11_PTR2 0x1000A8 // DMA Tab Ptr : Ch#11
701
702//*****************************************************************************
703#define DMA12_PTR2 0x1000AC // DMA Tab Ptr : Ch#12
704
705//*****************************************************************************
706#define DMA13_PTR2 0x1000B0 // DMA Tab Ptr : Ch#13
707
708//*****************************************************************************
709#define DMA14_PTR2 0x1000B4 // DMA Tab Ptr : Ch#14
710
711//*****************************************************************************
712#define DMA15_PTR2 0x1000B8 // DMA Tab Ptr : Ch#15
713
714//*****************************************************************************
715#define DMA16_PTR2 0x1000BC // DMA Tab Ptr : Ch#16
716
717//*****************************************************************************
718#define DMA17_PTR2 0x1000C0 // DMA Tab Ptr : Ch#17
719
720//*****************************************************************************
721#define DMA18_PTR2 0x1000C4 // DMA Tab Ptr : Ch#18
722
723//*****************************************************************************
724#define DMA19_PTR2 0x1000C8 // DMA Tab Ptr : Ch#19
725
726//*****************************************************************************
727#define DMA20_PTR2 0x1000CC // DMA Tab Ptr : Ch#20
728
729//*****************************************************************************
730#define DMA21_PTR2 0x1000D0 // DMA Tab Ptr : Ch#21
731
732//*****************************************************************************
733#define DMA22_PTR2 0x1000D4 // DMA Tab Ptr : Ch#22
734
735//*****************************************************************************
736#define DMA23_PTR2 0x1000D8 // DMA Tab Ptr : Ch#23
737
738//*****************************************************************************
739#define DMA24_PTR2 0x1000DC // DMA Tab Ptr : Ch#24
740
741//*****************************************************************************
742#define DMA25_PTR2 0x1000E0 // DMA Tab Ptr : Ch#25
743
744//*****************************************************************************
745#define DMA26_PTR2 0x1000E4 // DMA Tab Ptr : Ch#26
746
747//*****************************************************************************
748#define DMA1_CNT1 0x100100 // DMA BuFFer Size : Ch#1
749
750//*****************************************************************************
751#define DMA2_CNT1 0x100104 // DMA BuFFer Size : Ch#2
752
753//*****************************************************************************
754#define DMA3_CNT1 0x100108 // DMA BuFFer Size : Ch#3
755
756//*****************************************************************************
757#define DMA4_CNT1 0x10010C // DMA BuFFer Size : Ch#4
758
759//*****************************************************************************
760#define DMA5_CNT1 0x100110 // DMA BuFFer Size : Ch#5
761
762//*****************************************************************************
763#define DMA6_CNT1 0x100114 // DMA BuFFer Size : Ch#6
764
765//*****************************************************************************
766#define DMA7_CNT1 0x100118 // DMA BuFFer Size : Ch#7
767
768//*****************************************************************************
769#define DMA8_CNT1 0x10011C // DMA BuFFer Size : Ch#8
770
771//*****************************************************************************
772#define DMA9_CNT1 0x100120 // DMA BuFFer Size : Ch#9
773
774//*****************************************************************************
775#define DMA10_CNT1 0x100124 // DMA BuFFer Size : Ch#10
776
777//*****************************************************************************
778#define DMA11_CNT1 0x100128 // DMA BuFFer Size : Ch#11
779
780//*****************************************************************************
781#define DMA12_CNT1 0x10012C // DMA BuFFer Size : Ch#12
782
783//*****************************************************************************
784#define DMA13_CNT1 0x100130 // DMA BuFFer Size : Ch#13
785
786//*****************************************************************************
787#define DMA14_CNT1 0x100134 // DMA BuFFer Size : Ch#14
788
789//*****************************************************************************
790#define DMA15_CNT1 0x100138 // DMA BuFFer Size : Ch#15
791
792//*****************************************************************************
793#define DMA16_CNT1 0x10013C // DMA BuFFer Size : Ch#16
794
795//*****************************************************************************
796#define DMA17_CNT1 0x100140 // DMA BuFFer Size : Ch#17
797
798//*****************************************************************************
799#define DMA18_CNT1 0x100144 // DMA BuFFer Size : Ch#18
800
801//*****************************************************************************
802#define DMA19_CNT1 0x100148 // DMA BuFFer Size : Ch#19
803
804//*****************************************************************************
805#define DMA20_CNT1 0x10014C // DMA BuFFer Size : Ch#20
806
807//*****************************************************************************
808#define DMA21_CNT1 0x100150 // DMA BuFFer Size : Ch#21
809
810//*****************************************************************************
811#define DMA22_CNT1 0x100154 // DMA BuFFer Size : Ch#22
812
813//*****************************************************************************
814#define DMA23_CNT1 0x100158 // DMA BuFFer Size : Ch#23
815
816//*****************************************************************************
817#define DMA24_CNT1 0x10015C // DMA BuFFer Size : Ch#24
818
819//*****************************************************************************
820#define DMA25_CNT1 0x100160 // DMA BuFFer Size : Ch#25
821
822//*****************************************************************************
823#define DMA26_CNT1 0x100164 // DMA BuFFer Size : Ch#26
824
825//*****************************************************************************
826#define DMA1_CNT2 0x100180 // DMA Table Size : Ch#1
827
828//*****************************************************************************
829#define DMA2_CNT2 0x100184 // DMA Table Size : Ch#2
830
831//*****************************************************************************
832#define DMA3_CNT2 0x100188 // DMA Table Size : Ch#3
833
834//*****************************************************************************
835#define DMA4_CNT2 0x10018C // DMA Table Size : Ch#4
836
837//*****************************************************************************
838#define DMA5_CNT2 0x100190 // DMA Table Size : Ch#5
839
840//*****************************************************************************
841#define DMA6_CNT2 0x100194 // DMA Table Size : Ch#6
842
843//*****************************************************************************
844#define DMA7_CNT2 0x100198 // DMA Table Size : Ch#7
845
846//*****************************************************************************
847#define DMA8_CNT2 0x10019C // DMA Table Size : Ch#8
848
849//*****************************************************************************
850#define DMA9_CNT2 0x1001A0 // DMA Table Size : Ch#9
851
852//*****************************************************************************
853#define DMA10_CNT2 0x1001A4 // DMA Table Size : Ch#10
854
855//*****************************************************************************
856#define DMA11_CNT2 0x1001A8 // DMA Table Size : Ch#11
857
858//*****************************************************************************
859#define DMA12_CNT2 0x1001AC // DMA Table Size : Ch#12
860
861//*****************************************************************************
862#define DMA13_CNT2 0x1001B0 // DMA Table Size : Ch#13
863
864//*****************************************************************************
865#define DMA14_CNT2 0x1001B4 // DMA Table Size : Ch#14
866
867//*****************************************************************************
868#define DMA15_CNT2 0x1001B8 // DMA Table Size : Ch#15
869
870//*****************************************************************************
871#define DMA16_CNT2 0x1001BC // DMA Table Size : Ch#16
872
873//*****************************************************************************
874#define DMA17_CNT2 0x1001C0 // DMA Table Size : Ch#17
875
876//*****************************************************************************
877#define DMA18_CNT2 0x1001C4 // DMA Table Size : Ch#18
878
879//*****************************************************************************
880#define DMA19_CNT2 0x1001C8 // DMA Table Size : Ch#19
881
882//*****************************************************************************
883#define DMA20_CNT2 0x1001CC // DMA Table Size : Ch#20
884
885//*****************************************************************************
886#define DMA21_CNT2 0x1001D0 // DMA Table Size : Ch#21
887
888//*****************************************************************************
889#define DMA22_CNT2 0x1001D4 // DMA Table Size : Ch#22
890
891//*****************************************************************************
892#define DMA23_CNT2 0x1001D8 // DMA Table Size : Ch#23
893
894//*****************************************************************************
895#define DMA24_CNT2 0x1001DC // DMA Table Size : Ch#24
896
897//*****************************************************************************
898#define DMA25_CNT2 0x1001E0 // DMA Table Size : Ch#25
899
900//*****************************************************************************
901#define DMA26_CNT2 0x1001E4 // DMA Table Size : Ch#26
902
903//*****************************************************************************
904 // ITG
905//*****************************************************************************
906#define TM_CNT_LDW 0x110000 // Timer : Counter low
907
908//*****************************************************************************
909#define TM_CNT_UW 0x110004 // Timer : Counter high word
910
911//*****************************************************************************
912#define TM_LMT_LDW 0x110008 // Timer : Limit low
913
914//*****************************************************************************
915#define TM_LMT_UW 0x11000C // Timer : Limit high word
916
917//*****************************************************************************
918#define GP0_IO 0x110010 // GPIO output enables data I/O
919#define FLD_GP_OE 0x00FF0000 // GPIO: GP_OE output enable
920#define FLD_GP_IN 0x0000FF00 // GPIO: GP_IN status
921#define FLD_GP_OUT 0x000000FF // GPIO: GP_OUT control
922
923//*****************************************************************************
924#define GPIO_ISM 0x110014 // GPIO interrupt sensitivity mode
925#define FLD_GP_ISM_SNS 0x00000070
926#define FLD_GP_ISM_POL 0x00000007
927
928//*****************************************************************************
929#define SOFT_RESET 0x11001C // Output system reset reg
930#define FLD_PECOS_SOFT_RESET 0x00000001
931
932//*****************************************************************************
933#define MC416_RWD 0x110020 // MC416 GPIO[18:3] pin
934#define MC416_OEN 0x110024 // Output enable of GPIO[18:3]
935#define MC416_CTL 0x110028
936
937//*****************************************************************************
938#define ALT_PIN_OUT_SEL 0x11002C // Alternate GPIO output select
939
940#define FLD_ALT_GPIO_OUT_SEL 0xF0000000
941// 0 Disabled <-- default
942// 1 GPIO[0]
943// 2 GPIO[10]
944// 3 VIP_656_DATA_VAL
945// 4 VIP_656_DATA[0]
946// 5 VIP_656_CLK
947// 6 VIP_656_DATA_EXT[1]
948// 7 VIP_656_DATA_EXT[0]
949// 8 ATT_IF
950
951#define FLD_AUX_PLL_CLK_ALT_SEL 0x0F000000
952// 0 AUX_PLL_CLK<-- default
953// 1 GPIO[2]
954// 2 GPIO[10]
955// 3 VIP_656_DATA_VAL
956// 4 VIP_656_DATA[0]
957// 5 VIP_656_CLK
958// 6 VIP_656_DATA_EXT[1]
959// 7 VIP_656_DATA_EXT[0]
960
961#define FLD_IR_TX_ALT_SEL 0x00F00000
962// 0 IR_TX <-- default
963// 1 GPIO[1]
964// 2 GPIO[10]
965// 3 VIP_656_DATA_VAL
966// 4 VIP_656_DATA[0]
967// 5 VIP_656_CLK
968// 6 VIP_656_DATA_EXT[1]
969// 7 VIP_656_DATA_EXT[0]
970
971#define FLD_IR_RX_ALT_SEL 0x000F0000
972// 0 IR_RX <-- default
973// 1 GPIO[0]
974// 2 GPIO[10]
975// 3 VIP_656_DATA_VAL
976// 4 VIP_656_DATA[0]
977// 5 VIP_656_CLK
978// 6 VIP_656_DATA_EXT[1]
979// 7 VIP_656_DATA_EXT[0]
980
981#define FLD_GPIO10_ALT_SEL 0x0000F000
982// 0 GPIO[10] <-- default
983// 1 GPIO[0]
984// 2 GPIO[10]
985// 3 VIP_656_DATA_VAL
986// 4 VIP_656_DATA[0]
987// 5 VIP_656_CLK
988// 6 VIP_656_DATA_EXT[1]
989// 7 VIP_656_DATA_EXT[0]
990
991#define FLD_GPIO2_ALT_SEL 0x00000F00
992// 0 GPIO[2] <-- default
993// 1 GPIO[1]
994// 2 GPIO[10]
995// 3 VIP_656_DATA_VAL
996// 4 VIP_656_DATA[0]
997// 5 VIP_656_CLK
998// 6 VIP_656_DATA_EXT[1]
999// 7 VIP_656_DATA_EXT[0]
1000
1001#define FLD_GPIO1_ALT_SEL 0x000000F0
1002// 0 GPIO[1] <-- default
1003// 1 GPIO[0]
1004// 2 GPIO[10]
1005// 3 VIP_656_DATA_VAL
1006// 4 VIP_656_DATA[0]
1007// 5 VIP_656_CLK
1008// 6 VIP_656_DATA_EXT[1]
1009// 7 VIP_656_DATA_EXT[0]
1010
1011#define FLD_GPIO0_ALT_SEL 0x0000000F
1012// 0 GPIO[0] <-- default
1013// 1 GPIO[1]
1014// 2 GPIO[10]
1015// 3 VIP_656_DATA_VAL
1016// 4 VIP_656_DATA[0]
1017// 5 VIP_656_CLK
1018// 6 VIP_656_DATA_EXT[1]
1019// 7 VIP_656_DATA_EXT[0]
1020
1021#define ALT_PIN_IN_SEL 0x110030 // Alternate GPIO input select
1022
1023#define FLD_GPIO10_ALT_IN_SEL 0x0000F000
1024// 0 GPIO[10] <-- default
1025// 1 IR_RX
1026// 2 IR_TX
1027// 3 AUX_PLL_CLK
1028// 4 IF_ATT_SEL
1029// 5 GPIO[0]
1030// 6 GPIO[1]
1031// 7 GPIO[2]
1032
1033#define FLD_GPIO2_ALT_IN_SEL 0x00000F00
1034// 0 GPIO[2] <-- default
1035// 1 IR_RX
1036// 2 IR_TX
1037// 3 AUX_PLL_CLK
1038// 4 IF_ATT_SEL
1039
1040#define FLD_GPIO1_ALT_IN_SEL 0x000000F0
1041// 0 GPIO[1] <-- default
1042// 1 IR_RX
1043// 2 IR_TX
1044// 3 AUX_PLL_CLK
1045// 4 IF_ATT_SEL
1046
1047#define FLD_GPIO0_ALT_IN_SEL 0x0000000F
1048// 0 GPIO[0] <-- default
1049// 1 IR_RX
1050// 2 IR_TX
1051// 3 AUX_PLL_CLK
1052// 4 IF_ATT_SEL
1053
1054//*****************************************************************************
1055#define TEST_BUS_CTL1 0x110040 // Test bus control register #1
1056
1057//*****************************************************************************
1058#define TEST_BUS_CTL2 0x110044 // Test bus control register #2
1059
1060//*****************************************************************************
1061#define CLK_DELAY 0x110048 // Clock delay
1062#define FLD_MOE_CLK_DIS 0x80000000 // Disable MoE clock
1063
1064//*****************************************************************************
1065#define PAD_CTRL 0x110068 // Pad drive strength control
1066
1067//*****************************************************************************
1068#define MBIST_CTRL 0x110050 // SRAM memory built-in self test control
1069
1070//*****************************************************************************
1071#define MBIST_STAT 0x110054 // SRAM memory built-in self test status
1072
1073//*****************************************************************************
1074// PLL registers
1075//*****************************************************************************
1076#define PLL_A_INT_FRAC 0x110088
1077#define PLL_A_POST_STAT_BIST 0x11008C
1078#define PLL_B_INT_FRAC 0x110090
1079#define PLL_B_POST_STAT_BIST 0x110094
1080#define PLL_C_INT_FRAC 0x110098
1081#define PLL_C_POST_STAT_BIST 0x11009C
1082#define PLL_D_INT_FRAC 0x1100A0
1083#define PLL_D_POST_STAT_BIST 0x1100A4
1084
1085#define CLK_RST 0x11002C
1086#define FLD_VID_I_CLK_NOE 0x00001000
1087#define FLD_VID_J_CLK_NOE 0x00002000
1088#define FLD_USE_ALT_PLL_REF 0x00004000
1089
1090#define VID_CH_MODE_SEL 0x110078
1091#define VID_CH_CLK_SEL 0x11007C
1092
1093//*****************************************************************************
1094#define VBI_A_DMA 0x130008 // VBI A DMA data port
1095
1096//*****************************************************************************
1097#define VID_A_VIP_CTL 0x130080 // Video A VIP format control
1098#define FLD_VIP_MODE 0x00000001
1099
1100//*****************************************************************************
1101#define VID_A_PIXEL_FRMT 0x130084 // Video A pixel format
1102#define FLD_VID_A_GAMMA_DIS 0x00000008
1103#define FLD_VID_A_FORMAT 0x00000007
1104#define FLD_VID_A_GAMMA_FACTOR 0x00000010
1105
1106//*****************************************************************************
1107#define VID_A_VBI_CTL 0x130088 // Video A VBI miscellaneous control
1108#define FLD_VID_A_VIP_EXT 0x00000003
1109
1110//*****************************************************************************
1111#define VID_B_DMA 0x130100 // Video B DMA data port
1112
1113//*****************************************************************************
1114#define VBI_B_DMA 0x130108 // VBI B DMA data port
1115
1116//*****************************************************************************
1117#define VID_B_SRC_SEL 0x130144 // Video B source select
1118#define FLD_VID_B_SRC_SEL 0x00000000
1119
1120//*****************************************************************************
1121#define VID_B_LNGTH 0x130150 // Video B line length
1122#define FLD_VID_B_LN_LNGTH 0x00000FFF
1123
1124//*****************************************************************************
1125#define VID_B_VIP_CTL 0x130180 // Video B VIP format control
1126
1127//*****************************************************************************
1128#define VID_B_PIXEL_FRMT 0x130184 // Video B pixel format
1129#define FLD_VID_B_GAMMA_DIS 0x00000008
1130#define FLD_VID_B_FORMAT 0x00000007
1131#define FLD_VID_B_GAMMA_FACTOR 0x00000010
1132
1133//*****************************************************************************
1134#define VID_C_DMA 0x130200 // Video C DMA data port
1135
1136//*****************************************************************************
1137#define VID_C_LNGTH 0x130250 // Video C line length
1138#define FLD_VID_C_LN_LNGTH 0x00000FFF
1139
1140//*****************************************************************************
1141// Video Destination Channels
1142//*****************************************************************************
1143
1144#define VID_DST_A_GPCNT 0x130020 // Video A general purpose counter
1145#define VID_DST_B_GPCNT 0x130120 // Video B general purpose counter
1146#define VID_DST_C_GPCNT 0x130220 // Video C general purpose counter
1147#define VID_DST_D_GPCNT 0x130320 // Video D general purpose counter
1148#define VID_DST_E_GPCNT 0x130420 // Video E general purpose counter
1149#define VID_DST_F_GPCNT 0x130520 // Video F general purpose counter
1150#define VID_DST_G_GPCNT 0x130620 // Video G general purpose counter
1151#define VID_DST_H_GPCNT 0x130720 // Video H general purpose counter
1152
1153//*****************************************************************************
1154
1155#define VID_DST_A_GPCNT_CTL 0x130030 // Video A general purpose control
1156#define VID_DST_B_GPCNT_CTL 0x130130 // Video B general purpose control
1157#define VID_DST_C_GPCNT_CTL 0x130230 // Video C general purpose control
1158#define VID_DST_D_GPCNT_CTL 0x130330 // Video D general purpose control
1159#define VID_DST_E_GPCNT_CTL 0x130430 // Video E general purpose control
1160#define VID_DST_F_GPCNT_CTL 0x130530 // Video F general purpose control
1161#define VID_DST_G_GPCNT_CTL 0x130630 // Video G general purpose control
1162#define VID_DST_H_GPCNT_CTL 0x130730 // Video H general purpose control
1163
1164//*****************************************************************************
1165
1166#define VID_DST_A_DMA_CTL 0x130040 // Video A DMA control
1167#define VID_DST_B_DMA_CTL 0x130140 // Video B DMA control
1168#define VID_DST_C_DMA_CTL 0x130240 // Video C DMA control
1169#define VID_DST_D_DMA_CTL 0x130340 // Video D DMA control
1170#define VID_DST_E_DMA_CTL 0x130440 // Video E DMA control
1171#define VID_DST_F_DMA_CTL 0x130540 // Video F DMA control
1172#define VID_DST_G_DMA_CTL 0x130640 // Video G DMA control
1173#define VID_DST_H_DMA_CTL 0x130740 // Video H DMA control
1174
1175#define FLD_VID_RISC_EN 0x00000010
1176#define FLD_VID_FIFO_EN 0x00000001
1177
1178//*****************************************************************************
1179
1180#define VID_DST_A_VIP_CTL 0x130080 // Video A VIP control
1181#define VID_DST_B_VIP_CTL 0x130180 // Video B VIP control
1182#define VID_DST_C_VIP_CTL 0x130280 // Video C VIP control
1183#define VID_DST_D_VIP_CTL 0x130380 // Video D VIP control
1184#define VID_DST_E_VIP_CTL 0x130480 // Video E VIP control
1185#define VID_DST_F_VIP_CTL 0x130580 // Video F VIP control
1186#define VID_DST_G_VIP_CTL 0x130680 // Video G VIP control
1187#define VID_DST_H_VIP_CTL 0x130780 // Video H VIP control
1188
1189//*****************************************************************************
1190
1191#define VID_DST_A_PIX_FRMT 0x130084 // Video A Pixel format
1192#define VID_DST_B_PIX_FRMT 0x130184 // Video B Pixel format
1193#define VID_DST_C_PIX_FRMT 0x130284 // Video C Pixel format
1194#define VID_DST_D_PIX_FRMT 0x130384 // Video D Pixel format
1195#define VID_DST_E_PIX_FRMT 0x130484 // Video E Pixel format
1196#define VID_DST_F_PIX_FRMT 0x130584 // Video F Pixel format
1197#define VID_DST_G_PIX_FRMT 0x130684 // Video G Pixel format
1198#define VID_DST_H_PIX_FRMT 0x130784 // Video H Pixel format
1199
1200//*****************************************************************************
1201// Video Source Channels
1202//*****************************************************************************
1203
1204#define VID_SRC_A_GPCNT_CTL 0x130804 // Video A general purpose control
1205#define VID_SRC_B_GPCNT_CTL 0x130904 // Video B general purpose control
1206#define VID_SRC_C_GPCNT_CTL 0x130A04 // Video C general purpose control
1207#define VID_SRC_D_GPCNT_CTL 0x130B04 // Video D general purpose control
1208#define VID_SRC_E_GPCNT_CTL 0x130C04 // Video E general purpose control
1209#define VID_SRC_F_GPCNT_CTL 0x130D04 // Video F general purpose control
1210#define VID_SRC_I_GPCNT_CTL 0x130E04 // Video I general purpose control
1211#define VID_SRC_J_GPCNT_CTL 0x130F04 // Video J general purpose control
1212
1213//*****************************************************************************
1214
1215#define VID_SRC_A_GPCNT 0x130808 // Video A general purpose counter
1216#define VID_SRC_B_GPCNT 0x130908 // Video B general purpose counter
1217#define VID_SRC_C_GPCNT 0x130A08 // Video C general purpose counter
1218#define VID_SRC_D_GPCNT 0x130B08 // Video D general purpose counter
1219#define VID_SRC_E_GPCNT 0x130C08 // Video E general purpose counter
1220#define VID_SRC_F_GPCNT 0x130D08 // Video F general purpose counter
1221#define VID_SRC_I_GPCNT 0x130E08 // Video I general purpose counter
1222#define VID_SRC_J_GPCNT 0x130F08 // Video J general purpose counter
1223
1224//*****************************************************************************
1225
1226#define VID_SRC_A_DMA_CTL 0x13080C // Video A DMA control
1227#define VID_SRC_B_DMA_CTL 0x13090C // Video B DMA control
1228#define VID_SRC_C_DMA_CTL 0x130A0C // Video C DMA control
1229#define VID_SRC_D_DMA_CTL 0x130B0C // Video D DMA control
1230#define VID_SRC_E_DMA_CTL 0x130C0C // Video E DMA control
1231#define VID_SRC_F_DMA_CTL 0x130D0C // Video F DMA control
1232#define VID_SRC_I_DMA_CTL 0x130E0C // Video I DMA control
1233#define VID_SRC_J_DMA_CTL 0x130F0C // Video J DMA control
1234
1235#define FLD_APB_RISC_EN 0x00000010
1236#define FLD_APB_FIFO_EN 0x00000001
1237
1238//*****************************************************************************
1239
1240#define VID_SRC_A_FMT_CTL 0x130810 // Video A format control
1241#define VID_SRC_B_FMT_CTL 0x130910 // Video B format control
1242#define VID_SRC_C_FMT_CTL 0x130A10 // Video C format control
1243#define VID_SRC_D_FMT_CTL 0x130B10 // Video D format control
1244#define VID_SRC_E_FMT_CTL 0x130C10 // Video E format control
1245#define VID_SRC_F_FMT_CTL 0x130D10 // Video F format control
1246#define VID_SRC_I_FMT_CTL 0x130E10 // Video I format control
1247#define VID_SRC_J_FMT_CTL 0x130F10 // Video J format control
1248
1249//*****************************************************************************
1250
1251#define VID_SRC_A_ACTIVE_CTL1 0x130814 // Video A active control 1
1252#define VID_SRC_B_ACTIVE_CTL1 0x130914 // Video B active control 1
1253#define VID_SRC_C_ACTIVE_CTL1 0x130A14 // Video C active control 1
1254#define VID_SRC_D_ACTIVE_CTL1 0x130B14 // Video D active control 1
1255#define VID_SRC_E_ACTIVE_CTL1 0x130C14 // Video E active control 1
1256#define VID_SRC_F_ACTIVE_CTL1 0x130D14 // Video F active control 1
1257#define VID_SRC_I_ACTIVE_CTL1 0x130E14 // Video I active control 1
1258#define VID_SRC_J_ACTIVE_CTL1 0x130F14 // Video J active control 1
1259
1260//*****************************************************************************
1261
1262#define VID_SRC_A_ACTIVE_CTL2 0x130818 // Video A active control 2
1263#define VID_SRC_B_ACTIVE_CTL2 0x130918 // Video B active control 2
1264#define VID_SRC_C_ACTIVE_CTL2 0x130A18 // Video C active control 2
1265#define VID_SRC_D_ACTIVE_CTL2 0x130B18 // Video D active control 2
1266#define VID_SRC_E_ACTIVE_CTL2 0x130C18 // Video E active control 2
1267#define VID_SRC_F_ACTIVE_CTL2 0x130D18 // Video F active control 2
1268#define VID_SRC_I_ACTIVE_CTL2 0x130E18 // Video I active control 2
1269#define VID_SRC_J_ACTIVE_CTL2 0x130F18 // Video J active control 2
1270
1271//*****************************************************************************
1272
1273#define VID_SRC_A_CDT_SZ 0x13081C // Video A CDT size
1274#define VID_SRC_B_CDT_SZ 0x13091C // Video B CDT size
1275#define VID_SRC_C_CDT_SZ 0x130A1C // Video C CDT size
1276#define VID_SRC_D_CDT_SZ 0x130B1C // Video D CDT size
1277#define VID_SRC_E_CDT_SZ 0x130C1C // Video E CDT size
1278#define VID_SRC_F_CDT_SZ 0x130D1C // Video F CDT size
1279#define VID_SRC_I_CDT_SZ 0x130E1C // Video I CDT size
1280#define VID_SRC_J_CDT_SZ 0x130F1C // Video J CDT size
1281
1282//*****************************************************************************
1283// Audio I/F
1284//*****************************************************************************
1285#define AUD_DST_A_DMA 0x140000 // Audio Int A DMA data port
1286#define AUD_SRC_A_DMA 0x140008 // Audio Int A DMA data port
1287
1288#define AUD_A_GPCNT 0x140010 // Audio Int A gp counter
1289#define FLD_AUD_A_GP_CNT 0x0000FFFF
1290
1291#define AUD_A_GPCNT_CTL 0x140014 // Audio Int A gp control
1292
1293#define AUD_A_LNGTH 0x140018 // Audio Int A line length
1294
1295#define AUD_A_CFG 0x14001C // Audio Int A configuration
1296
1297//*****************************************************************************
1298#define AUD_DST_B_DMA 0x140100 // Audio Int B DMA data port
1299#define AUD_SRC_B_DMA 0x140108 // Audio Int B DMA data port
1300
1301#define AUD_B_GPCNT 0x140110 // Audio Int B gp counter
1302#define FLD_AUD_B_GP_CNT 0x0000FFFF
1303
1304#define AUD_B_GPCNT_CTL 0x140114 // Audio Int B gp control
1305
1306#define AUD_B_LNGTH 0x140118 // Audio Int B line length
1307
1308#define AUD_B_CFG 0x14011C // Audio Int B configuration
1309
1310//*****************************************************************************
1311#define AUD_DST_C_DMA 0x140200 // Audio Int C DMA data port
1312#define AUD_SRC_C_DMA 0x140208 // Audio Int C DMA data port
1313
1314#define AUD_C_GPCNT 0x140210 // Audio Int C gp counter
1315#define FLD_AUD_C_GP_CNT 0x0000FFFF
1316
1317#define AUD_C_GPCNT_CTL 0x140214 // Audio Int C gp control
1318
1319#define AUD_C_LNGTH 0x140218 // Audio Int C line length
1320
1321#define AUD_C_CFG 0x14021C // Audio Int C configuration
1322
1323//*****************************************************************************
1324#define AUD_DST_D_DMA 0x140300 // Audio Int D DMA data port
1325#define AUD_SRC_D_DMA 0x140308 // Audio Int D DMA data port
1326
1327#define AUD_D_GPCNT 0x140310 // Audio Int D gp counter
1328#define FLD_AUD_D_GP_CNT 0x0000FFFF
1329
1330#define AUD_D_GPCNT_CTL 0x140314 // Audio Int D gp control
1331
1332#define AUD_D_LNGTH 0x140318 // Audio Int D line length
1333
1334#define AUD_D_CFG 0x14031C // Audio Int D configuration
1335
1336//*****************************************************************************
1337#define AUD_SRC_E_DMA 0x140400 // Audio Int E DMA data port
1338
1339#define AUD_E_GPCNT 0x140410 // Audio Int E gp counter
1340#define FLD_AUD_E_GP_CNT 0x0000FFFF
1341
1342#define AUD_E_GPCNT_CTL 0x140414 // Audio Int E gp control
1343
1344#define AUD_E_CFG 0x14041C // Audio Int E configuration
1345
1346//*****************************************************************************
1347
1348#define FLD_AUD_DST_LN_LNGTH 0x00000FFF
1349
1350#define FLD_AUD_DST_PK_MODE 0x00004000
1351
1352#define FLD_AUD_CLK_ENABLE 0x00000200
1353
1354#define FLD_AUD_MASTER_MODE 0x00000002
1355
1356#define FLD_AUD_SONY_MODE 0x00000001
1357
1358#define FLD_AUD_CLK_SELECT_PLL_D 0x00001800
1359
1360#define FLD_AUD_DST_ENABLE 0x00020000
1361
1362#define FLD_AUD_SRC_ENABLE 0x00010000
1363
1364//*****************************************************************************
1365#define AUD_INT_DMA_CTL 0x140500 // Audio Int DMA control
1366
1367#define FLD_AUD_SRC_E_RISC_EN 0x00008000
1368#define FLD_AUD_SRC_C_RISC_EN 0x00004000
1369#define FLD_AUD_SRC_B_RISC_EN 0x00002000
1370#define FLD_AUD_SRC_A_RISC_EN 0x00001000
1371
1372#define FLD_AUD_DST_D_RISC_EN 0x00000800
1373#define FLD_AUD_DST_C_RISC_EN 0x00000400
1374#define FLD_AUD_DST_B_RISC_EN 0x00000200
1375#define FLD_AUD_DST_A_RISC_EN 0x00000100
1376
1377#define FLD_AUD_SRC_E_FIFO_EN 0x00000080
1378#define FLD_AUD_SRC_C_FIFO_EN 0x00000040
1379#define FLD_AUD_SRC_B_FIFO_EN 0x00000020
1380#define FLD_AUD_SRC_A_FIFO_EN 0x00000010
1381
1382#define FLD_AUD_DST_D_FIFO_EN 0x00000008
1383#define FLD_AUD_DST_C_FIFO_EN 0x00000004
1384#define FLD_AUD_DST_B_FIFO_EN 0x00000002
1385#define FLD_AUD_DST_A_FIFO_EN 0x00000001
1386
1387//*****************************************************************************
1388//
1389// Mobilygen Interface Registers
1390//
1391//*****************************************************************************
1392// Mobilygen Interface A
1393//*****************************************************************************
1394#define MB_IF_A_DMA 0x150000 // MBIF A DMA data port
1395#define MB_IF_A_GPCN 0x150008 // MBIF A GP counter
1396#define MB_IF_A_GPCN_CTRL 0x15000C
1397#define MB_IF_A_DMA_CTRL 0x150010
1398#define MB_IF_A_LENGTH 0x150014
1399#define MB_IF_A_HDMA_XFER_SZ 0x150018
1400#define MB_IF_A_HCMD 0x15001C
1401#define MB_IF_A_HCONFIG 0x150020
1402#define MB_IF_A_DATA_STRUCT_0 0x150024
1403#define MB_IF_A_DATA_STRUCT_1 0x150028
1404#define MB_IF_A_DATA_STRUCT_2 0x15002C
1405#define MB_IF_A_DATA_STRUCT_3 0x150030
1406#define MB_IF_A_DATA_STRUCT_4 0x150034
1407#define MB_IF_A_DATA_STRUCT_5 0x150038
1408#define MB_IF_A_DATA_STRUCT_6 0x15003C
1409#define MB_IF_A_DATA_STRUCT_7 0x150040
1410#define MB_IF_A_DATA_STRUCT_8 0x150044
1411#define MB_IF_A_DATA_STRUCT_9 0x150048
1412#define MB_IF_A_DATA_STRUCT_A 0x15004C
1413#define MB_IF_A_DATA_STRUCT_B 0x150050
1414#define MB_IF_A_DATA_STRUCT_C 0x150054
1415#define MB_IF_A_DATA_STRUCT_D 0x150058
1416#define MB_IF_A_DATA_STRUCT_E 0x15005C
1417#define MB_IF_A_DATA_STRUCT_F 0x150060
1418//*****************************************************************************
1419// Mobilygen Interface B
1420//*****************************************************************************
1421#define MB_IF_B_DMA 0x160000 // MBIF A DMA data port
1422#define MB_IF_B_GPCN 0x160008 // MBIF A GP counter
1423#define MB_IF_B_GPCN_CTRL 0x16000C
1424#define MB_IF_B_DMA_CTRL 0x160010
1425#define MB_IF_B_LENGTH 0x160014
1426#define MB_IF_B_HDMA_XFER_SZ 0x160018
1427#define MB_IF_B_HCMD 0x16001C
1428#define MB_IF_B_HCONFIG 0x160020
1429#define MB_IF_B_DATA_STRUCT_0 0x160024
1430#define MB_IF_B_DATA_STRUCT_1 0x160028
1431#define MB_IF_B_DATA_STRUCT_2 0x16002C
1432#define MB_IF_B_DATA_STRUCT_3 0x160030
1433#define MB_IF_B_DATA_STRUCT_4 0x160034
1434#define MB_IF_B_DATA_STRUCT_5 0x160038
1435#define MB_IF_B_DATA_STRUCT_6 0x16003C
1436#define MB_IF_B_DATA_STRUCT_7 0x160040
1437#define MB_IF_B_DATA_STRUCT_8 0x160044
1438#define MB_IF_B_DATA_STRUCT_9 0x160048
1439#define MB_IF_B_DATA_STRUCT_A 0x16004C
1440#define MB_IF_B_DATA_STRUCT_B 0x160050
1441#define MB_IF_B_DATA_STRUCT_C 0x160054
1442#define MB_IF_B_DATA_STRUCT_D 0x160058
1443#define MB_IF_B_DATA_STRUCT_E 0x16005C
1444#define MB_IF_B_DATA_STRUCT_F 0x160060
1445
1446// MB_DMA_CTRL
1447#define FLD_MB_IF_RISC_EN 0x00000010
1448#define FLD_MB_IF_FIFO_EN 0x00000001
1449
1450// MB_LENGTH
1451#define FLD_MB_IF_LN_LNGTH 0x00000FFF
1452
1453// MB_HCMD register
1454#define FLD_MB_HCMD_H_GO 0x80000000
1455#define FLD_MB_HCMD_H_BUSY 0x40000000
1456#define FLD_MB_HCMD_H_DMA_HOLD 0x10000000
1457#define FLD_MB_HCMD_H_DMA_BUSY 0x08000000
1458#define FLD_MB_HCMD_H_DMA_TYPE 0x04000000
1459#define FLD_MB_HCMD_H_DMA_XACT 0x02000000
1460#define FLD_MB_HCMD_H_RW_N 0x01000000
1461#define FLD_MB_HCMD_H_ADDR 0x00FF0000
1462#define FLD_MB_HCMD_H_DATA 0x0000FFFF
1463
1464//*****************************************************************************
1465// I2C #1
1466//*****************************************************************************
1467#define I2C1_ADDR 0x180000 // I2C #1 address
1468#define FLD_I2C_DADDR 0xfe000000 // RW [31:25] I2C Device Address
1469 // RO [24] reserved
1470//*****************************************************************************
1471#define FLD_I2C_SADDR 0x00FFFFFF // RW [23:0] I2C Sub-address
1472
1473//*****************************************************************************
1474#define I2C1_WDATA 0x180004 // I2C #1 write data
1475#define FLD_I2C_WDATA 0xFFFFFFFF // RW [31:0]
1476
1477//*****************************************************************************
1478#define I2C1_CTRL 0x180008 // I2C #1 control
1479#define FLD_I2C_PERIOD 0xFF000000 // RW [31:24]
1480#define FLD_I2C_SCL_IN 0x00200000 // RW [21]
1481#define FLD_I2C_SDA_IN 0x00100000 // RW [20]
1482 // RO [19:18] reserved
1483#define FLD_I2C_SCL_OUT 0x00020000 // RW [17]
1484#define FLD_I2C_SDA_OUT 0x00010000 // RW [16]
1485 // RO [15] reserved
1486#define FLD_I2C_DATA_LEN 0x00007000 // RW [14:12]
1487#define FLD_I2C_SADDR_INC 0x00000800 // RW [11]
1488 // RO [10:9] reserved
1489#define FLD_I2C_SADDR_LEN 0x00000300 // RW [9:8]
1490 // RO [7:6] reserved
1491#define FLD_I2C_SOFT 0x00000020 // RW [5]
1492#define FLD_I2C_NOSTOP 0x00000010 // RW [4]
1493#define FLD_I2C_EXTEND 0x00000008 // RW [3]
1494#define FLD_I2C_SYNC 0x00000004 // RW [2]
1495#define FLD_I2C_READ_SA 0x00000002 // RW [1]
1496#define FLD_I2C_READ_WRN 0x00000001 // RW [0]
1497
1498//*****************************************************************************
1499#define I2C1_RDATA 0x18000C // I2C #1 read data
1500#define FLD_I2C_RDATA 0xFFFFFFFF // RO [31:0]
1501
1502//*****************************************************************************
1503#define I2C1_STAT 0x180010 // I2C #1 status
1504#define FLD_I2C_XFER_IN_PROG 0x00000002 // RO [1]
1505#define FLD_I2C_RACK 0x00000001 // RO [0]
1506
1507//*****************************************************************************
1508// I2C #2
1509//*****************************************************************************
1510#define I2C2_ADDR 0x190000 // I2C #2 address
1511
1512//*****************************************************************************
1513#define I2C2_WDATA 0x190004 // I2C #2 write data
1514
1515//*****************************************************************************
1516#define I2C2_CTRL 0x190008 // I2C #2 control
1517
1518//*****************************************************************************
1519#define I2C2_RDATA 0x19000C // I2C #2 read data
1520
1521//*****************************************************************************
1522#define I2C2_STAT 0x190010 // I2C #2 status
1523
1524//*****************************************************************************
1525// I2C #3
1526//*****************************************************************************
1527#define I2C3_ADDR 0x1A0000 // I2C #3 address
1528
1529//*****************************************************************************
1530#define I2C3_WDATA 0x1A0004 // I2C #3 write data
1531
1532//*****************************************************************************
1533#define I2C3_CTRL 0x1A0008 // I2C #3 control
1534
1535//*****************************************************************************
1536#define I2C3_RDATA 0x1A000C // I2C #3 read data
1537
1538//*****************************************************************************
1539#define I2C3_STAT 0x1A0010 // I2C #3 status
1540
1541//*****************************************************************************
1542// UART
1543//*****************************************************************************
1544#define UART_CTL 0x1B0000 // UART Control Register
1545#define FLD_LOOP_BACK_EN (1 << 7) // RW field - default 0
1546#define FLD_RX_TRG_SZ (3 << 2) // RW field - default 0
1547#define FLD_RX_EN (1 << 1) // RW field - default 0
1548#define FLD_TX_EN (1 << 0) // RW field - default 0
1549
1550//*****************************************************************************
1551#define UART_BRD 0x1B0004 // UART Baud Rate Divisor
1552#define FLD_BRD 0x0000FFFF // RW field - default 0x197
1553
1554//*****************************************************************************
1555#define UART_DBUF 0x1B0008 // UART Tx/Rx Data BuFFer
1556#define FLD_DB 0xFFFFFFFF // RW field - default 0
1557
1558//*****************************************************************************
1559#define UART_ISR 0x1B000C // UART Interrupt Status
1560#define FLD_RXD_TIMEOUT_EN (1 << 7) // RW field - default 0
1561#define FLD_FRM_ERR_EN (1 << 6) // RW field - default 0
1562#define FLD_RXD_RDY_EN (1 << 5) // RW field - default 0
1563#define FLD_TXD_EMPTY_EN (1 << 4) // RW field - default 0
1564#define FLD_RXD_OVERFLOW (1 << 3) // RW field - default 0
1565#define FLD_FRM_ERR (1 << 2) // RW field - default 0
1566#define FLD_RXD_RDY (1 << 1) // RW field - default 0
1567#define FLD_TXD_EMPTY (1 << 0) // RW field - default 0
1568
1569//*****************************************************************************
1570#define UART_CNT 0x1B0010 // UART Tx/Rx FIFO Byte Count
1571#define FLD_TXD_CNT (0x1F << 8) // RW field - default 0
1572#define FLD_RXD_CNT (0x1F << 0) // RW field - default 0
1573
1574//*****************************************************************************
1575// Motion Detection
1576#define MD_CH0_GRID_BLOCK_YCNT 0x170014
1577#define MD_CH1_GRID_BLOCK_YCNT 0x170094
1578#define MD_CH2_GRID_BLOCK_YCNT 0x170114
1579#define MD_CH3_GRID_BLOCK_YCNT 0x170194
1580#define MD_CH4_GRID_BLOCK_YCNT 0x170214
1581#define MD_CH5_GRID_BLOCK_YCNT 0x170294
1582#define MD_CH6_GRID_BLOCK_YCNT 0x170314
1583#define MD_CH7_GRID_BLOCK_YCNT 0x170394
1584
1585#define PIXEL_FRMT_422 4
1586#define PIXEL_FRMT_411 5
1587#define PIXEL_FRMT_Y8 6
1588
1589#define PIXEL_ENGINE_VIP1 0
1590#define PIXEL_ENGINE_VIP2 1
1591
1592#endif //Athena_REGISTERS
diff --git a/drivers/staging/cx25821/cx25821-sram.h b/drivers/staging/cx25821/cx25821-sram.h
new file mode 100644
index 000000000000..bd677ee22996
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-sram.h
@@ -0,0 +1,261 @@
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//#define TX_SRAM_POOL_FREE_SIZE = 704; // Start of available TX SRAM
51//#define TX_SRAM_END_SIZE = 0; // End of TX SRAM
52
53// Receive SRAM
54#define RX_SRAM_START 0x10000
55#define VID_A_DOWN_CMDS 0x10000
56#define VID_B_DOWN_CMDS 0x10050
57#define VID_C_DOWN_CMDS 0x100A0
58#define VID_D_DOWN_CMDS 0x100F0
59#define VID_E_DOWN_CMDS 0x10140
60#define VID_F_DOWN_CMDS 0x10190
61#define VID_G_DOWN_CMDS 0x101E0
62#define VID_H_DOWN_CMDS 0x10230
63#define VID_A_UP_CMDS 0x10280
64#define VID_B_UP_CMDS 0x102D0
65#define VID_C_UP_CMDS 0x10320
66#define VID_D_UP_CMDS 0x10370
67#define VID_E_UP_CMDS 0x103C0
68#define VID_F_UP_CMDS 0x10410
69#define VID_I_UP_CMDS 0x10460
70#define VID_J_UP_CMDS 0x104B0
71#define AUD_A_DOWN_CMDS 0x10500
72#define AUD_B_DOWN_CMDS 0x10550
73#define AUD_C_DOWN_CMDS 0x105A0
74#define AUD_D_DOWN_CMDS 0x105F0
75#define AUD_A_UP_CMDS 0x10640
76#define AUD_B_UP_CMDS 0x10690
77#define AUD_C_UP_CMDS 0x106E0
78#define AUD_E_UP_CMDS 0x10730
79#define MBIF_A_DOWN_CMDS 0x10780
80#define MBIF_B_DOWN_CMDS 0x107D0
81#define DMA_SCRATCH_PAD 0x10820 // Scratch pad area from 0x10820 to 0x10B40
82
83//#define RX_SRAM_POOL_START = 0x105B0;
84
85#define VID_A_IQ 0x11000
86#define VID_B_IQ 0x11040
87#define VID_C_IQ 0x11080
88#define VID_D_IQ 0x110C0
89#define VID_E_IQ 0x11100
90#define VID_F_IQ 0x11140
91#define VID_G_IQ 0x11180
92#define VID_H_IQ 0x111C0
93#define VID_I_IQ 0x11200
94#define VID_J_IQ 0x11240
95#define AUD_A_IQ 0x11280
96#define AUD_B_IQ 0x112C0
97#define AUD_C_IQ 0x11300
98#define AUD_D_IQ 0x11340
99#define AUD_E_IQ 0x11380
100#define MBIF_A_IQ 0x11000
101#define MBIF_B_IQ 0x110C0
102
103#define VID_A_CDT 0x10C00
104#define VID_B_CDT 0x10C40
105#define VID_C_CDT 0x10C80
106#define VID_D_CDT 0x10CC0
107#define VID_E_CDT 0x10D00
108#define VID_F_CDT 0x10D40
109#define VID_G_CDT 0x10D80
110#define VID_H_CDT 0x10DC0
111#define VID_I_CDT 0x10E00
112#define VID_J_CDT 0x10E40
113#define AUD_A_CDT 0x10E80
114#define AUD_B_CDT 0x10EB0
115#define AUD_C_CDT 0x10EE0
116#define AUD_D_CDT 0x10F10
117#define AUD_E_CDT 0x10F40
118#define MBIF_A_CDT 0x10C00
119#define MBIF_B_CDT 0x10CC0
120
121// Cluster Buffer for RX
122#define VID_A_UP_CLUSTER_1 0x11400
123#define VID_A_UP_CLUSTER_2 0x119A0
124#define VID_A_UP_CLUSTER_3 0x11F40
125#define VID_A_UP_CLUSTER_4 0x124E0
126
127#define VID_B_UP_CLUSTER_1 0x12A80
128#define VID_B_UP_CLUSTER_2 0x13020
129#define VID_B_UP_CLUSTER_3 0x135C0
130#define VID_B_UP_CLUSTER_4 0x13B60
131
132#define VID_C_UP_CLUSTER_1 0x14100
133#define VID_C_UP_CLUSTER_2 0x146A0
134#define VID_C_UP_CLUSTER_3 0x14C40
135#define VID_C_UP_CLUSTER_4 0x151E0
136
137#define VID_D_UP_CLUSTER_1 0x15780
138#define VID_D_UP_CLUSTER_2 0x15D20
139#define VID_D_UP_CLUSTER_3 0x162C0
140#define VID_D_UP_CLUSTER_4 0x16860
141
142#define VID_E_UP_CLUSTER_1 0x16E00
143#define VID_E_UP_CLUSTER_2 0x173A0
144#define VID_E_UP_CLUSTER_3 0x17940
145#define VID_E_UP_CLUSTER_4 0x17EE0
146
147#define VID_F_UP_CLUSTER_1 0x18480
148#define VID_F_UP_CLUSTER_2 0x18A20
149#define VID_F_UP_CLUSTER_3 0x18FC0
150#define VID_F_UP_CLUSTER_4 0x19560
151
152#define VID_I_UP_CLUSTER_1 0x19B00
153#define VID_I_UP_CLUSTER_2 0x1A0A0
154#define VID_I_UP_CLUSTER_3 0x1A640
155#define VID_I_UP_CLUSTER_4 0x1ABE0
156
157#define VID_J_UP_CLUSTER_1 0x1B180
158#define VID_J_UP_CLUSTER_2 0x1B720
159#define VID_J_UP_CLUSTER_3 0x1BCC0
160#define VID_J_UP_CLUSTER_4 0x1C260
161
162#define AUD_A_UP_CLUSTER_1 0x1C800
163#define AUD_A_UP_CLUSTER_2 0x1C880
164#define AUD_A_UP_CLUSTER_3 0x1C900
165
166#define AUD_B_UP_CLUSTER_1 0x1C980
167#define AUD_B_UP_CLUSTER_2 0x1CA00
168#define AUD_B_UP_CLUSTER_3 0x1CA80
169
170#define AUD_C_UP_CLUSTER_1 0x1CB00
171#define AUD_C_UP_CLUSTER_2 0x1CB80
172#define AUD_C_UP_CLUSTER_3 0x1CC00
173
174#define AUD_E_UP_CLUSTER_1 0x1CC80
175#define AUD_E_UP_CLUSTER_2 0x1CD00
176#define AUD_E_UP_CLUSTER_3 0x1CD80
177
178#define RX_SRAM_POOL_FREE 0x1CE00
179#define RX_SRAM_END 0x1D000
180
181// Free Receive SRAM 144 Bytes
182
183// Transmit SRAM
184#define TX_SRAM_POOL_START 0x00000
185
186#define VID_A_DOWN_CLUSTER_1 0x00040
187#define VID_A_DOWN_CLUSTER_2 0x005E0
188#define VID_A_DOWN_CLUSTER_3 0x00B80
189#define VID_A_DOWN_CLUSTER_4 0x01120
190
191#define VID_B_DOWN_CLUSTER_1 0x016C0
192#define VID_B_DOWN_CLUSTER_2 0x01C60
193#define VID_B_DOWN_CLUSTER_3 0x02200
194#define VID_B_DOWN_CLUSTER_4 0x027A0
195
196#define VID_C_DOWN_CLUSTER_1 0x02D40
197#define VID_C_DOWN_CLUSTER_2 0x032E0
198#define VID_C_DOWN_CLUSTER_3 0x03880
199#define VID_C_DOWN_CLUSTER_4 0x03E20
200
201#define VID_D_DOWN_CLUSTER_1 0x043C0
202#define VID_D_DOWN_CLUSTER_2 0x04960
203#define VID_D_DOWN_CLUSTER_3 0x04F00
204#define VID_D_DOWN_CLUSTER_4 0x054A0
205
206#define VID_E_DOWN_CLUSTER_1 0x05a40
207#define VID_E_DOWN_CLUSTER_2 0x05FE0
208#define VID_E_DOWN_CLUSTER_3 0x06580
209#define VID_E_DOWN_CLUSTER_4 0x06B20
210
211#define VID_F_DOWN_CLUSTER_1 0x070C0
212#define VID_F_DOWN_CLUSTER_2 0x07660
213#define VID_F_DOWN_CLUSTER_3 0x07C00
214#define VID_F_DOWN_CLUSTER_4 0x081A0
215
216#define VID_G_DOWN_CLUSTER_1 0x08740
217#define VID_G_DOWN_CLUSTER_2 0x08CE0
218#define VID_G_DOWN_CLUSTER_3 0x09280
219#define VID_G_DOWN_CLUSTER_4 0x09820
220
221#define VID_H_DOWN_CLUSTER_1 0x09DC0
222#define VID_H_DOWN_CLUSTER_2 0x0A360
223#define VID_H_DOWN_CLUSTER_3 0x0A900
224#define VID_H_DOWN_CLUSTER_4 0x0AEA0
225
226#define AUD_A_DOWN_CLUSTER_1 0x0B500
227#define AUD_A_DOWN_CLUSTER_2 0x0B580
228#define AUD_A_DOWN_CLUSTER_3 0x0B600
229
230#define AUD_B_DOWN_CLUSTER_1 0x0B680
231#define AUD_B_DOWN_CLUSTER_2 0x0B700
232#define AUD_B_DOWN_CLUSTER_3 0x0B780
233
234#define AUD_C_DOWN_CLUSTER_1 0x0B800
235#define AUD_C_DOWN_CLUSTER_2 0x0B880
236#define AUD_C_DOWN_CLUSTER_3 0x0B900
237
238#define AUD_D_DOWN_CLUSTER_1 0x0B980
239#define AUD_D_DOWN_CLUSTER_2 0x0BA00
240#define AUD_D_DOWN_CLUSTER_3 0x0BA80
241
242#define TX_SRAM_POOL_FREE 0x0BB00
243#define TX_SRAM_END 0x0C000
244
245#define BYTES_TO_DWORDS(bcount) ((bcount) >> 2)
246#define BYTES_TO_QWORDS(bcount) ((bcount) >> 3)
247#define BYTES_TO_OWORDS(bcount) ((bcount) >> 4)
248
249#define VID_IQ_SIZE_DW BYTES_TO_DWORDS(VID_IQ_SIZE)
250#define VID_CDT_SIZE_QW BYTES_TO_QWORDS(VID_CDT_SIZE)
251#define VID_CLUSTER_SIZE_OW BYTES_TO_OWORDS(VID_CLUSTER_SIZE)
252
253#define AUDIO_IQ_SIZE_DW BYTES_TO_DWORDS(AUDIO_IQ_SIZE)
254#define AUDIO_CDT_SIZE_QW BYTES_TO_QWORDS(AUDIO_CDT_SIZE)
255#define AUDIO_CLUSTER_SIZE_QW BYTES_TO_QWORDS(AUDIO_CLUSTER_SIZE)
256
257#define MBIF_IQ_SIZE_DW BYTES_TO_DWORDS(MBIF_IQ_SIZE)
258#define MBIF_CDT_SIZE_QW BYTES_TO_QWORDS(MBIF_CDT_SIZE)
259#define MBIF_CLUSTER_SIZE_OW BYTES_TO_OWORDS(MBIF_CLUSTER_SIZE)
260
261#endif
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 000000000000..c8905e0ac509
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -0,0 +1,835 @@
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 "cx25821-video.h"
24#include "cx25821-video-upstream-ch2.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <asm/uaccess.h>
35
36MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
37MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
38MODULE_LICENSE("GPL");
39
40static int _intr_msk =
41 FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
42
43static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev,
44 __le32 * rp, unsigned int offset,
45 unsigned int bpl, u32 sync_line,
46 unsigned int lines,
47 int fifo_enable, int field_type)
48{
49 unsigned int line, i;
50 int dist_betwn_starts = bpl * 2;
51
52 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
53
54 if (USE_RISC_NOOP_VIDEO) {
55 for (i = 0; i < NUM_NO_OPS; i++) {
56 *(rp++) = cpu_to_le32(RISC_NOOP);
57 }
58 }
59
60 /* scan lines */
61 for (line = 0; line < lines; line++) {
62 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
63 *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset);
64 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
65
66 if ((lines <= NTSC_FIELD_HEIGHT)
67 || (line < (NTSC_FIELD_HEIGHT - 1))
68 || !(dev->_isNTSC_ch2)) {
69 offset += dist_betwn_starts;
70 }
71 }
72
73 return rp;
74}
75
76static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev,
77 __le32 * rp,
78 dma_addr_t databuf_phys_addr,
79 unsigned int offset,
80 u32 sync_line, unsigned int bpl,
81 unsigned int lines,
82 int fifo_enable, int field_type)
83{
84 unsigned int line, i;
85 struct sram_channel *sram_ch =
86 &dev->sram_channels[dev->_channel2_upstream_select];
87 int dist_betwn_starts = bpl * 2;
88
89 /* sync instruction */
90 if (sync_line != NO_SYNC_LINE) {
91 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
92 }
93
94 if (USE_RISC_NOOP_VIDEO) {
95 for (i = 0; i < NUM_NO_OPS; i++) {
96 *(rp++) = cpu_to_le32(RISC_NOOP);
97 }
98 }
99
100 /* scan lines */
101 for (line = 0; line < lines; line++) {
102 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
103 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
104 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
105
106 if ((lines <= NTSC_FIELD_HEIGHT)
107 || (line < (NTSC_FIELD_HEIGHT - 1))
108 || !(dev->_isNTSC_ch2)) {
109 offset += dist_betwn_starts;
110 }
111
112 // check if we need to enable the FIFO after the first 4 lines
113 // For the upstream video channel, the risc engine will enable the FIFO.
114 if (fifo_enable && line == 3) {
115 *(rp++) = RISC_WRITECR;
116 *(rp++) = sram_ch->dma_ctl;
117 *(rp++) = FLD_VID_FIFO_EN;
118 *(rp++) = 0x00000001;
119 }
120 }
121
122 return rp;
123}
124
125int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
126 struct pci_dev *pci,
127 unsigned int top_offset, unsigned int bpl,
128 unsigned int lines)
129{
130 __le32 *rp;
131 int fifo_enable = 0;
132 int singlefield_lines = lines >> 1; //get line count for single field
133 int odd_num_lines = singlefield_lines;
134 int frame = 0;
135 int frame_size = 0;
136 int databuf_offset = 0;
137 int risc_program_size = 0;
138 int risc_flag = RISC_CNT_RESET;
139 unsigned int bottom_offset = bpl;
140 dma_addr_t risc_phys_jump_addr;
141
142 if (dev->_isNTSC_ch2) {
143 odd_num_lines = singlefield_lines + 1;
144 risc_program_size = FRAME1_VID_PROG_SIZE;
145 frame_size =
146 (bpl ==
147 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
148 FRAME_SIZE_NTSC_Y422;
149 } else {
150 risc_program_size = PAL_VID_PROG_SIZE;
151 frame_size =
152 (bpl ==
153 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
154 }
155
156 /* Virtual address of Risc buffer program */
157 rp = dev->_dma_virt_addr_ch2;
158
159 for (frame = 0; frame < NUM_FRAMES; frame++) {
160 databuf_offset = frame_size * frame;
161
162 if (UNSET != top_offset) {
163 fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
164 rp = cx25821_risc_field_upstream_ch2(dev, rp,
165 dev->
166 _data_buf_phys_addr_ch2
167 + databuf_offset,
168 top_offset, 0, bpl,
169 odd_num_lines,
170 fifo_enable,
171 ODD_FIELD);
172 }
173
174 fifo_enable = FIFO_DISABLE;
175
176 //Even field
177 rp = cx25821_risc_field_upstream_ch2(dev, rp,
178 dev->
179 _data_buf_phys_addr_ch2 +
180 databuf_offset,
181 bottom_offset, 0x200, bpl,
182 singlefield_lines,
183 fifo_enable, EVEN_FIELD);
184
185 if (frame == 0) {
186 risc_flag = RISC_CNT_RESET;
187 risc_phys_jump_addr =
188 dev->_dma_phys_start_addr_ch2 + risc_program_size;
189 } else {
190 risc_flag = RISC_CNT_INC;
191 risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2;
192 }
193
194 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
195 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
196 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
197 *(rp++) = cpu_to_le32(0);
198 }
199
200 return 0;
201}
202
203void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
204{
205 struct sram_channel *sram_ch =
206 &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_J];
207 u32 tmp = 0;
208
209 if (!dev->_is_running_ch2) {
210 printk
211 ("cx25821: No video file is currently running so return!\n");
212 return;
213 }
214 //Disable RISC interrupts
215 tmp = cx_read(sram_ch->int_msk);
216 cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
217
218 //Turn OFF risc and fifo
219 tmp = cx_read(sram_ch->dma_ctl);
220 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
221
222 //Clear data buffer memory
223 if (dev->_data_buf_virt_addr_ch2)
224 memset(dev->_data_buf_virt_addr_ch2, 0,
225 dev->_data_buf_size_ch2);
226
227 dev->_is_running_ch2 = 0;
228 dev->_is_first_frame_ch2 = 0;
229 dev->_frame_count_ch2 = 0;
230 dev->_file_status_ch2 = END_OF_FILE;
231
232 if (dev->_irq_queues_ch2) {
233 kfree(dev->_irq_queues_ch2);
234 dev->_irq_queues_ch2 = NULL;
235 }
236
237 if (dev->_filename_ch2 != NULL)
238 kfree(dev->_filename_ch2);
239
240 tmp = cx_read(VID_CH_MODE_SEL);
241 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
242}
243
244void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev)
245{
246 if (dev->_is_running_ch2) {
247 cx25821_stop_upstream_video_ch2(dev);
248 }
249
250 if (dev->_dma_virt_addr_ch2) {
251 pci_free_consistent(dev->pci, dev->_risc_size_ch2,
252 dev->_dma_virt_addr_ch2,
253 dev->_dma_phys_addr_ch2);
254 dev->_dma_virt_addr_ch2 = NULL;
255 }
256
257 if (dev->_data_buf_virt_addr_ch2) {
258 pci_free_consistent(dev->pci, dev->_data_buf_size_ch2,
259 dev->_data_buf_virt_addr_ch2,
260 dev->_data_buf_phys_addr_ch2);
261 dev->_data_buf_virt_addr_ch2 = NULL;
262 }
263}
264
265int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
266{
267 struct file *myfile;
268 int frame_index_temp = dev->_frame_index_ch2;
269 int i = 0;
270 int line_size =
271 (dev->_pixel_format_ch2 ==
272 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
273 int frame_size = 0;
274 int frame_offset = 0;
275 ssize_t vfs_read_retval = 0;
276 char mybuf[line_size];
277 loff_t file_offset;
278 loff_t pos;
279 mm_segment_t old_fs;
280
281 if (dev->_file_status_ch2 == END_OF_FILE)
282 return 0;
283
284 if (dev->_isNTSC_ch2) {
285 frame_size =
286 (line_size ==
287 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
288 FRAME_SIZE_NTSC_Y422;
289 } else {
290 frame_size =
291 (line_size ==
292 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
293 }
294
295 frame_offset = (frame_index_temp > 0) ? frame_size : 0;
296 file_offset = dev->_frame_count_ch2 * frame_size;
297
298 myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
299
300 if (IS_ERR(myfile)) {
301 const int open_errno = -PTR_ERR(myfile);
302 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
303 __func__, dev->_filename_ch2, open_errno);
304 return PTR_ERR(myfile);
305 } else {
306 if (!(myfile->f_op)) {
307 printk("%s: File has no file operations registered!",
308 __func__);
309 filp_close(myfile, NULL);
310 return -EIO;
311 }
312
313 if (!myfile->f_op->read) {
314 printk("%s: File has no READ operations registered!",
315 __func__);
316 filp_close(myfile, NULL);
317 return -EIO;
318 }
319
320 pos = myfile->f_pos;
321 old_fs = get_fs();
322 set_fs(KERNEL_DS);
323
324 for (i = 0; i < dev->_lines_count_ch2; i++) {
325 pos = file_offset;
326
327 vfs_read_retval =
328 vfs_read(myfile, mybuf, line_size, &pos);
329
330 if (vfs_read_retval > 0 && vfs_read_retval == line_size
331 && dev->_data_buf_virt_addr_ch2 != NULL) {
332 memcpy((void *)(dev->_data_buf_virt_addr_ch2 +
333 frame_offset / 4), mybuf,
334 vfs_read_retval);
335 }
336
337 file_offset += vfs_read_retval;
338 frame_offset += vfs_read_retval;
339
340 if (vfs_read_retval < line_size) {
341 printk(KERN_INFO
342 "Done: exit %s() since no more bytes to read from Video file.\n",
343 __func__);
344 break;
345 }
346 }
347
348 if (i > 0)
349 dev->_frame_count_ch2++;
350
351 dev->_file_status_ch2 =
352 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
353
354 set_fs(old_fs);
355 filp_close(myfile, NULL);
356 }
357
358 return 0;
359}
360
361static void cx25821_vidups_handler_ch2(struct work_struct *work)
362{
363 struct cx25821_dev *dev =
364 container_of(work, struct cx25821_dev, _irq_work_entry_ch2);
365
366 if (!dev) {
367 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
368 __func__);
369 return;
370 }
371
372 cx25821_get_frame_ch2(dev,
373 &dev->sram_channels[dev->
374 _channel2_upstream_select]);
375}
376
377int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
378{
379 struct file *myfile;
380 int i = 0, j = 0;
381 int line_size =
382 (dev->_pixel_format_ch2 ==
383 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
384 ssize_t vfs_read_retval = 0;
385 char mybuf[line_size];
386 loff_t pos;
387 loff_t offset = (unsigned long)0;
388 mm_segment_t old_fs;
389
390 myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
391
392 if (IS_ERR(myfile)) {
393 const int open_errno = -PTR_ERR(myfile);
394 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
395 __func__, dev->_filename_ch2, open_errno);
396 return PTR_ERR(myfile);
397 } else {
398 if (!(myfile->f_op)) {
399 printk("%s: File has no file operations registered!",
400 __func__);
401 filp_close(myfile, NULL);
402 return -EIO;
403 }
404
405 if (!myfile->f_op->read) {
406 printk
407 ("%s: File has no READ operations registered! Returning.",
408 __func__);
409 filp_close(myfile, NULL);
410 return -EIO;
411 }
412
413 pos = myfile->f_pos;
414 old_fs = get_fs();
415 set_fs(KERNEL_DS);
416
417 for (j = 0; j < NUM_FRAMES; j++) {
418 for (i = 0; i < dev->_lines_count_ch2; i++) {
419 pos = offset;
420
421 vfs_read_retval =
422 vfs_read(myfile, mybuf, line_size, &pos);
423
424 if (vfs_read_retval > 0
425 && vfs_read_retval == line_size
426 && dev->_data_buf_virt_addr_ch2 != NULL) {
427 memcpy((void *)(dev->
428 _data_buf_virt_addr_ch2
429 + offset / 4), mybuf,
430 vfs_read_retval);
431 }
432
433 offset += vfs_read_retval;
434
435 if (vfs_read_retval < line_size) {
436 printk(KERN_INFO
437 "Done: exit %s() since no more bytes to read from Video file.\n",
438 __func__);
439 break;
440 }
441 }
442
443 if (i > 0)
444 dev->_frame_count_ch2++;
445
446 if (vfs_read_retval < line_size) {
447 break;
448 }
449 }
450
451 dev->_file_status_ch2 =
452 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
453
454 set_fs(old_fs);
455 myfile->f_pos = 0;
456 filp_close(myfile, NULL);
457 }
458
459 return 0;
460}
461
462static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
463 struct sram_channel *sram_ch,
464 int bpl)
465{
466 int ret = 0;
467 dma_addr_t dma_addr;
468 dma_addr_t data_dma_addr;
469
470 if (dev->_dma_virt_addr_ch2 != NULL) {
471 pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
472 dev->_dma_virt_addr_ch2,
473 dev->_dma_phys_addr_ch2);
474 }
475
476 dev->_dma_virt_addr_ch2 =
477 pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
478 &dma_addr);
479 dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2;
480 dev->_dma_phys_start_addr_ch2 = dma_addr;
481 dev->_dma_phys_addr_ch2 = dma_addr;
482 dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;
483
484 if (!dev->_dma_virt_addr_ch2) {
485 printk
486 ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
487 return -ENOMEM;
488 }
489
490 //Iniitize at this address until n bytes to 0
491 memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2);
492
493 if (dev->_data_buf_virt_addr_ch2 != NULL) {
494 pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2,
495 dev->_data_buf_virt_addr_ch2,
496 dev->_data_buf_phys_addr_ch2);
497 }
498 //For Video Data buffer allocation
499 dev->_data_buf_virt_addr_ch2 =
500 pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2,
501 &data_dma_addr);
502 dev->_data_buf_phys_addr_ch2 = data_dma_addr;
503 dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
504
505 if (!dev->_data_buf_virt_addr_ch2) {
506 printk
507 ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
508 return -ENOMEM;
509 }
510
511 //Initialize at this address until n bytes to 0
512 memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2);
513
514 ret = cx25821_openfile_ch2(dev, sram_ch);
515 if (ret < 0)
516 return ret;
517
518 //Creating RISC programs
519 ret =
520 cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
521 dev->_lines_count_ch2);
522 if (ret < 0) {
523 printk(KERN_INFO
524 "cx25821: Failed creating Video Upstream Risc programs! \n");
525 goto error;
526 }
527
528 return 0;
529
530 error:
531 return ret;
532}
533
534int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
535 u32 status)
536{
537 u32 int_msk_tmp;
538 struct sram_channel *channel = &dev->sram_channels[chan_num];
539 int singlefield_lines = NTSC_FIELD_HEIGHT;
540 int line_size_in_bytes = Y422_LINE_SZ;
541 int odd_risc_prog_size = 0;
542 dma_addr_t risc_phys_jump_addr;
543 __le32 *rp;
544
545 if (status & FLD_VID_SRC_RISC1) {
546 // We should only process one program per call
547 u32 prog_cnt = cx_read(channel->gpcnt);
548
549 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
550 int_msk_tmp = cx_read(channel->int_msk);
551 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
552 cx_write(channel->int_stat, _intr_msk);
553
554 spin_lock(&dev->slock);
555
556 dev->_frame_index_ch2 = prog_cnt;
557
558 queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2);
559
560 if (dev->_is_first_frame_ch2) {
561 dev->_is_first_frame_ch2 = 0;
562
563 if (dev->_isNTSC_ch2) {
564 singlefield_lines += 1;
565 odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
566 } else {
567 singlefield_lines = PAL_FIELD_HEIGHT;
568 odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
569 }
570
571 if (dev->_dma_virt_start_addr_ch2 != NULL) {
572 line_size_in_bytes =
573 (dev->_pixel_format_ch2 ==
574 PIXEL_FRMT_411) ? Y411_LINE_SZ :
575 Y422_LINE_SZ;
576 risc_phys_jump_addr =
577 dev->_dma_phys_start_addr_ch2 +
578 odd_risc_prog_size;
579
580 rp = cx25821_update_riscprogram_ch2(dev,
581 dev->
582 _dma_virt_start_addr_ch2,
583 TOP_OFFSET,
584 line_size_in_bytes,
585 0x0,
586 singlefield_lines,
587 FIFO_DISABLE,
588 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 if (dev->_file_status_ch2 == END_OF_FILE) {
601 printk("cx25821: EOF Channel 2 Framecount = %d\n",
602 dev->_frame_count_ch2);
603 return -1;
604 }
605 //ElSE, set the interrupt mask register, re-enable irq.
606 int_msk_tmp = cx_read(channel->int_msk);
607 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
608
609 return 0;
610}
611
612static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
613{
614 struct cx25821_dev *dev = dev_id;
615 u32 msk_stat, vid_status;
616 int handled = 0;
617 int channel_num = 0;
618 struct sram_channel *sram_ch;
619
620 if (!dev)
621 return -1;
622
623 channel_num = VID_UPSTREAM_SRAM_CHANNEL_J;
624
625 sram_ch = &dev->sram_channels[channel_num];
626
627 msk_stat = cx_read(sram_ch->int_mstat);
628 vid_status = cx_read(sram_ch->int_stat);
629
630 // Only deal with our interrupt
631 if (vid_status) {
632 handled =
633 cx25821_video_upstream_irq_ch2(dev, channel_num,
634 vid_status);
635 }
636
637 if (handled < 0) {
638 cx25821_stop_upstream_video_ch2(dev);
639 } else {
640 handled += handled;
641 }
642
643 return IRQ_RETVAL(handled);
644}
645
646static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
647 struct sram_channel *ch, int pix_format)
648{
649 int width = WIDTH_D1;
650 int height = dev->_lines_count_ch2;
651 int num_lines, odd_num_lines;
652 u32 value;
653 int vip_mode = PIXEL_ENGINE_VIP1;
654
655 value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
656 value &= 0xFFFFFFEF;
657 value |= dev->_isNTSC_ch2 ? 0 : 0x10;
658 cx_write(ch->vid_fmt_ctl, value);
659
660 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
661 cx_write(ch->vid_active_ctl1, width);
662
663 num_lines = (height / 2) & 0x3FF;
664 odd_num_lines = num_lines;
665
666 if (dev->_isNTSC_ch2) {
667 odd_num_lines += 1;
668 }
669
670 value = (num_lines << 16) | odd_num_lines;
671
672 // set number of active lines in field 0 (top) and field 1 (bottom)
673 cx_write(ch->vid_active_ctl2, value);
674
675 cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
676}
677
678int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
679 struct sram_channel *sram_ch)
680{
681 u32 tmp = 0;
682 int err = 0;
683
684 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
685 tmp = cx_read(VID_CH_MODE_SEL);
686 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
687
688 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
689 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2);
690 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
691
692 /* reset counter */
693 cx_write(sram_ch->gpcnt_ctl, 3);
694
695 // Clear our bits from the interrupt status register.
696 cx_write(sram_ch->int_stat, _intr_msk);
697
698 //Set the interrupt mask register, enable irq.
699 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
700 tmp = cx_read(sram_ch->int_msk);
701 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
702
703 err =
704 request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
705 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
706 if (err < 0) {
707 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
708 dev->pci->irq);
709 goto fail_irq;
710 }
711 // Start the DMA engine
712 tmp = cx_read(sram_ch->dma_ctl);
713 cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
714
715 dev->_is_running_ch2 = 1;
716 dev->_is_first_frame_ch2 = 1;
717
718 return 0;
719
720 fail_irq:
721 cx25821_dev_unregister(dev);
722 return err;
723}
724
725int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
726 int pixel_format)
727{
728 struct sram_channel *sram_ch;
729 u32 tmp;
730 int retval = 0;
731 int err = 0;
732 int data_frame_size = 0;
733 int risc_buffer_size = 0;
734 int str_length = 0;
735
736 if (dev->_is_running_ch2) {
737 printk("Video Channel is still running so return!\n");
738 return 0;
739 }
740
741 dev->_channel2_upstream_select = channel_select;
742 sram_ch = &dev->sram_channels[channel_select];
743
744 INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2);
745 dev->_irq_queues_ch2 =
746 create_singlethread_workqueue("cx25821_workqueue2");
747
748 if (!dev->_irq_queues_ch2) {
749 printk
750 ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
751 return -ENOMEM;
752 }
753 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
754 tmp = cx_read(VID_CH_MODE_SEL);
755 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
756
757 dev->_is_running_ch2 = 0;
758 dev->_frame_count_ch2 = 0;
759 dev->_file_status_ch2 = RESET_STATUS;
760 dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576;
761 dev->_pixel_format_ch2 = pixel_format;
762 dev->_line_size_ch2 =
763 (dev->_pixel_format_ch2 ==
764 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
765 data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
766 risc_buffer_size =
767 dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
768
769 if (dev->input_filename_ch2) {
770 str_length = strlen(dev->input_filename_ch2);
771 dev->_filename_ch2 =
772 (char *)kmalloc(str_length + 1, GFP_KERNEL);
773
774 if (!dev->_filename_ch2)
775 goto error;
776
777 memcpy(dev->_filename_ch2, dev->input_filename_ch2,
778 str_length + 1);
779 } else {
780 str_length = strlen(dev->_defaultname_ch2);
781 dev->_filename_ch2 =
782 (char *)kmalloc(str_length + 1, GFP_KERNEL);
783
784 if (!dev->_filename_ch2)
785 goto error;
786
787 memcpy(dev->_filename_ch2, dev->_defaultname_ch2,
788 str_length + 1);
789 }
790
791 //Default if filename is empty string
792 if (strcmp(dev->input_filename_ch2, "") == 0) {
793 if (dev->_isNTSC_ch2) {
794 dev->_filename_ch2 =
795 (dev->_pixel_format_ch2 ==
796 PIXEL_FRMT_411) ? "/root/vid411.yuv" :
797 "/root/vidtest.yuv";
798 } else {
799 dev->_filename_ch2 =
800 (dev->_pixel_format_ch2 ==
801 PIXEL_FRMT_411) ? "/root/pal411.yuv" :
802 "/root/pal422.yuv";
803 }
804 }
805
806 retval =
807 cx25821_sram_channel_setup_upstream(dev, sram_ch,
808 dev->_line_size_ch2, 0);
809
810 /* setup fifo + format */
811 cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2);
812
813 dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2;
814 dev->upstream_databuf_size_ch2 = data_frame_size * 2;
815
816 //Allocating buffers and prepare RISC program
817 retval =
818 cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
819 dev->_line_size_ch2);
820 if (retval < 0) {
821 printk(KERN_ERR
822 "%s: Failed to set up Video upstream buffers!\n",
823 dev->name);
824 goto error;
825 }
826
827 cx25821_start_video_dma_upstream_ch2(dev, sram_ch);
828
829 return 0;
830
831 error:
832 cx25821_dev_unregister(dev);
833
834 return err;
835}
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 000000000000..73feea114c1c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
@@ -0,0 +1,101 @@
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 OPEN_FILE_1 0
27#define NUM_PROGS 8
28#define NUM_FRAMES 2
29#define ODD_FIELD 0
30#define EVEN_FIELD 1
31#define TOP_OFFSET 0
32#define FIFO_DISABLE 0
33#define FIFO_ENABLE 1
34#define TEST_FRAMES 5
35#define END_OF_FILE 0
36#define IN_PROGRESS 1
37#define RESET_STATUS -1
38#define NUM_NO_OPS 5
39
40// PAL and NTSC line sizes and number of lines.
41#define WIDTH_D1 720
42#define NTSC_LINES_PER_FRAME 480
43#define PAL_LINES_PER_FRAME 576
44#define PAL_LINE_SZ 1440
45#define Y422_LINE_SZ 1440
46#define Y411_LINE_SZ 1080
47#define NTSC_FIELD_HEIGHT 240
48#define NTSC_ODD_FLD_LINES 241
49#define PAL_FIELD_HEIGHT 288
50
51#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
52#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
53#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
54#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
55
56#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
57#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
58
59#define RISC_WRITECR_INSTRUCTION_SIZE 16
60#define RISC_SYNC_INSTRUCTION_SIZE 4
61#define JUMP_INSTRUCTION_SIZE 12
62#define MAXSIZE_NO_OPS 36
63#define DWORD_SIZE 4
64
65#define USE_RISC_NOOP_VIDEO 1
66
67#ifdef USE_RISC_NOOP_VIDEO
68#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
69 RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
70
71#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
72
73#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
74 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
75
76#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
77 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
78
79#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
80 JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
81
82#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
83
84#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
85 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
86#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
87 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
88#endif
89
90#ifndef USE_RISC_NOOP_VIDEO
91#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
92#define PAL_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE) )
93#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
94 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
95#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
96#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
97#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
98#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
99#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
100 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
101#endif
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
new file mode 100644
index 000000000000..3d7dd3f66541
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -0,0 +1,894 @@
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 "cx25821-video.h"
24#include "cx25821-video-upstream.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <asm/uaccess.h>
35
36MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
37MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
38MODULE_LICENSE("GPL");
39
40static int _intr_msk =
41 FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
42
43int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
44 struct sram_channel *ch,
45 unsigned int bpl, u32 risc)
46{
47 unsigned int i, lines;
48 u32 cdt;
49
50 if (ch->cmds_start == 0) {
51 cx_write(ch->ptr1_reg, 0);
52 cx_write(ch->ptr2_reg, 0);
53 cx_write(ch->cnt2_reg, 0);
54 cx_write(ch->cnt1_reg, 0);
55 return 0;
56 }
57
58 bpl = (bpl + 7) & ~7; /* alignment */
59 cdt = ch->cdt;
60 lines = ch->fifo_size / bpl;
61
62 if (lines > 4) {
63 lines = 4;
64 }
65
66 BUG_ON(lines < 2);
67
68 /* write CDT */
69 for (i = 0; i < lines; i++) {
70 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
71 cx_write(cdt + 16 * i + 4, 0);
72 cx_write(cdt + 16 * i + 8, 0);
73 cx_write(cdt + 16 * i + 12, 0);
74 }
75
76 /* write CMDS */
77 cx_write(ch->cmds_start + 0, risc);
78
79 cx_write(ch->cmds_start + 4, 0);
80 cx_write(ch->cmds_start + 8, cdt);
81 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
82 cx_write(ch->cmds_start + 16, ch->ctrl_start);
83
84 cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);
85
86 for (i = 24; i < 80; i += 4)
87 cx_write(ch->cmds_start + i, 0);
88
89 /* fill registers */
90 cx_write(ch->ptr1_reg, ch->fifo_start);
91 cx_write(ch->ptr2_reg, cdt);
92 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
93 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
94
95 return 0;
96}
97
98static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
99 __le32 * rp, unsigned int offset,
100 unsigned int bpl, u32 sync_line,
101 unsigned int lines, int fifo_enable,
102 int field_type)
103{
104 unsigned int line, i;
105 int dist_betwn_starts = bpl * 2;
106
107 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
108
109 if (USE_RISC_NOOP_VIDEO) {
110 for (i = 0; i < NUM_NO_OPS; i++) {
111 *(rp++) = cpu_to_le32(RISC_NOOP);
112 }
113 }
114
115 /* scan lines */
116 for (line = 0; line < lines; line++) {
117 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
118 *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset);
119 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
120
121 if ((lines <= NTSC_FIELD_HEIGHT)
122 || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
123 offset += dist_betwn_starts;
124 }
125 }
126
127 return rp;
128}
129
130static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
131 dma_addr_t databuf_phys_addr,
132 unsigned int offset, u32 sync_line,
133 unsigned int bpl, unsigned int lines,
134 int fifo_enable, int field_type)
135{
136 unsigned int line, i;
137 struct sram_channel *sram_ch =
138 &dev->sram_channels[dev->_channel_upstream_select];
139 int dist_betwn_starts = bpl * 2;
140
141 /* sync instruction */
142 if (sync_line != NO_SYNC_LINE) {
143 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
144 }
145
146 if (USE_RISC_NOOP_VIDEO) {
147 for (i = 0; i < NUM_NO_OPS; i++) {
148 *(rp++) = cpu_to_le32(RISC_NOOP);
149 }
150 }
151
152 /* scan lines */
153 for (line = 0; line < lines; line++) {
154 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
155 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
156 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
157
158 if ((lines <= NTSC_FIELD_HEIGHT)
159 || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
160 offset += dist_betwn_starts; //to skip the other field line
161 }
162
163 // check if we need to enable the FIFO after the first 4 lines
164 // For the upstream video channel, the risc engine will enable the FIFO.
165 if (fifo_enable && line == 3) {
166 *(rp++) = RISC_WRITECR;
167 *(rp++) = sram_ch->dma_ctl;
168 *(rp++) = FLD_VID_FIFO_EN;
169 *(rp++) = 0x00000001;
170 }
171 }
172
173 return rp;
174}
175
176int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
177 struct pci_dev *pci,
178 unsigned int top_offset,
179 unsigned int bpl, unsigned int lines)
180{
181 __le32 *rp;
182 int fifo_enable = 0;
183 int singlefield_lines = lines >> 1; //get line count for single field
184 int odd_num_lines = singlefield_lines;
185 int frame = 0;
186 int frame_size = 0;
187 int databuf_offset = 0;
188 int risc_program_size = 0;
189 int risc_flag = RISC_CNT_RESET;
190 unsigned int bottom_offset = bpl;
191 dma_addr_t risc_phys_jump_addr;
192
193 if (dev->_isNTSC) {
194 odd_num_lines = singlefield_lines + 1;
195 risc_program_size = FRAME1_VID_PROG_SIZE;
196 frame_size =
197 (bpl ==
198 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
199 FRAME_SIZE_NTSC_Y422;
200 } else {
201 risc_program_size = PAL_VID_PROG_SIZE;
202 frame_size =
203 (bpl ==
204 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
205 }
206
207 /* Virtual address of Risc buffer program */
208 rp = dev->_dma_virt_addr;
209
210 for (frame = 0; frame < NUM_FRAMES; frame++) {
211 databuf_offset = frame_size * frame;
212
213 if (UNSET != top_offset) {
214 fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
215 rp = cx25821_risc_field_upstream(dev, rp,
216 dev->
217 _data_buf_phys_addr +
218 databuf_offset,
219 top_offset, 0, bpl,
220 odd_num_lines,
221 fifo_enable,
222 ODD_FIELD);
223 }
224
225 fifo_enable = FIFO_DISABLE;
226
227 //Even Field
228 rp = cx25821_risc_field_upstream(dev, rp,
229 dev->_data_buf_phys_addr +
230 databuf_offset, bottom_offset,
231 0x200, bpl, singlefield_lines,
232 fifo_enable, EVEN_FIELD);
233
234 if (frame == 0) {
235 risc_flag = RISC_CNT_RESET;
236 risc_phys_jump_addr =
237 dev->_dma_phys_start_addr + risc_program_size;
238 } else {
239 risc_phys_jump_addr = dev->_dma_phys_start_addr;
240 risc_flag = RISC_CNT_INC;
241 }
242
243 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
244 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
245 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
246 *(rp++) = cpu_to_le32(0);
247 }
248
249 return 0;
250}
251
252void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
253{
254 struct sram_channel *sram_ch =
255 &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_I];
256 u32 tmp = 0;
257
258 if (!dev->_is_running) {
259 printk
260 ("cx25821: No video file is currently running so return!\n");
261 return;
262 }
263 //Disable RISC interrupts
264 tmp = cx_read(sram_ch->int_msk);
265 cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
266
267 //Turn OFF risc and fifo enable
268 tmp = cx_read(sram_ch->dma_ctl);
269 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
270
271 //Clear data buffer memory
272 if (dev->_data_buf_virt_addr)
273 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
274
275 dev->_is_running = 0;
276 dev->_is_first_frame = 0;
277 dev->_frame_count = 0;
278 dev->_file_status = END_OF_FILE;
279
280 if (dev->_irq_queues) {
281 kfree(dev->_irq_queues);
282 dev->_irq_queues = NULL;
283 }
284
285 if (dev->_filename != NULL)
286 kfree(dev->_filename);
287
288 tmp = cx_read(VID_CH_MODE_SEL);
289 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
290}
291
292void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
293{
294 if (dev->_is_running) {
295 cx25821_stop_upstream_video_ch1(dev);
296 }
297
298 if (dev->_dma_virt_addr) {
299 pci_free_consistent(dev->pci, dev->_risc_size,
300 dev->_dma_virt_addr, dev->_dma_phys_addr);
301 dev->_dma_virt_addr = NULL;
302 }
303
304 if (dev->_data_buf_virt_addr) {
305 pci_free_consistent(dev->pci, dev->_data_buf_size,
306 dev->_data_buf_virt_addr,
307 dev->_data_buf_phys_addr);
308 dev->_data_buf_virt_addr = NULL;
309 }
310}
311
312int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
313{
314 struct file *myfile;
315 int frame_index_temp = dev->_frame_index;
316 int i = 0;
317 int line_size =
318 (dev->_pixel_format ==
319 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
320 int frame_size = 0;
321 int frame_offset = 0;
322 ssize_t vfs_read_retval = 0;
323 char mybuf[line_size];
324 loff_t file_offset;
325 loff_t pos;
326 mm_segment_t old_fs;
327
328 if (dev->_file_status == END_OF_FILE)
329 return 0;
330
331 if (dev->_isNTSC) {
332 frame_size =
333 (line_size ==
334 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
335 FRAME_SIZE_NTSC_Y422;
336 } else {
337 frame_size =
338 (line_size ==
339 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
340 }
341
342 frame_offset = (frame_index_temp > 0) ? frame_size : 0;
343 file_offset = dev->_frame_count * frame_size;
344
345 myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
346
347 if (IS_ERR(myfile)) {
348 const int open_errno = -PTR_ERR(myfile);
349 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
350 __func__, dev->_filename, open_errno);
351 return PTR_ERR(myfile);
352 } else {
353 if (!(myfile->f_op)) {
354 printk("%s: File has no file operations registered!",
355 __func__);
356 filp_close(myfile, NULL);
357 return -EIO;
358 }
359
360 if (!myfile->f_op->read) {
361 printk("%s: File has no READ operations registered!",
362 __func__);
363 filp_close(myfile, NULL);
364 return -EIO;
365 }
366
367 pos = myfile->f_pos;
368 old_fs = get_fs();
369 set_fs(KERNEL_DS);
370
371 for (i = 0; i < dev->_lines_count; i++) {
372 pos = file_offset;
373
374 vfs_read_retval =
375 vfs_read(myfile, mybuf, line_size, &pos);
376
377 if (vfs_read_retval > 0 && vfs_read_retval == line_size
378 && dev->_data_buf_virt_addr != NULL) {
379 memcpy((void *)(dev->_data_buf_virt_addr +
380 frame_offset / 4), mybuf,
381 vfs_read_retval);
382 }
383
384 file_offset += vfs_read_retval;
385 frame_offset += vfs_read_retval;
386
387 if (vfs_read_retval < line_size) {
388 printk(KERN_INFO
389 "Done: exit %s() since no more bytes to read from Video file.\n",
390 __func__);
391 break;
392 }
393 }
394
395 if (i > 0)
396 dev->_frame_count++;
397
398 dev->_file_status =
399 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
400
401 set_fs(old_fs);
402 filp_close(myfile, NULL);
403 }
404
405 return 0;
406}
407
408static void cx25821_vidups_handler(struct work_struct *work)
409{
410 struct cx25821_dev *dev =
411 container_of(work, struct cx25821_dev, _irq_work_entry);
412
413 if (!dev) {
414 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
415 __func__);
416 return;
417 }
418
419 cx25821_get_frame(dev,
420 &dev->sram_channels[dev->_channel_upstream_select]);
421}
422
423int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
424{
425 struct file *myfile;
426 int i = 0, j = 0;
427 int line_size =
428 (dev->_pixel_format ==
429 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
430 ssize_t vfs_read_retval = 0;
431 char mybuf[line_size];
432 loff_t pos;
433 loff_t offset = (unsigned long)0;
434 mm_segment_t old_fs;
435
436 myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
437
438 if (IS_ERR(myfile)) {
439 const int open_errno = -PTR_ERR(myfile);
440 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
441 __func__, dev->_filename, open_errno);
442 return PTR_ERR(myfile);
443 } else {
444 if (!(myfile->f_op)) {
445 printk("%s: File has no file operations registered!",
446 __func__);
447 filp_close(myfile, NULL);
448 return -EIO;
449 }
450
451 if (!myfile->f_op->read) {
452 printk
453 ("%s: File has no READ operations registered! Returning.",
454 __func__);
455 filp_close(myfile, NULL);
456 return -EIO;
457 }
458
459 pos = myfile->f_pos;
460 old_fs = get_fs();
461 set_fs(KERNEL_DS);
462
463 for (j = 0; j < NUM_FRAMES; j++) {
464 for (i = 0; i < dev->_lines_count; i++) {
465 pos = offset;
466
467 vfs_read_retval =
468 vfs_read(myfile, mybuf, line_size, &pos);
469
470 if (vfs_read_retval > 0
471 && vfs_read_retval == line_size
472 && dev->_data_buf_virt_addr != NULL) {
473 memcpy((void *)(dev->
474 _data_buf_virt_addr +
475 offset / 4), mybuf,
476 vfs_read_retval);
477 }
478
479 offset += vfs_read_retval;
480
481 if (vfs_read_retval < line_size) {
482 printk(KERN_INFO
483 "Done: exit %s() since no more bytes to read from Video file.\n",
484 __func__);
485 break;
486 }
487 }
488
489 if (i > 0)
490 dev->_frame_count++;
491
492 if (vfs_read_retval < line_size) {
493 break;
494 }
495 }
496
497 dev->_file_status =
498 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
499
500 set_fs(old_fs);
501 myfile->f_pos = 0;
502 filp_close(myfile, NULL);
503 }
504
505 return 0;
506}
507
508int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
509 struct sram_channel *sram_ch, int bpl)
510{
511 int ret = 0;
512 dma_addr_t dma_addr;
513 dma_addr_t data_dma_addr;
514
515 if (dev->_dma_virt_addr != NULL) {
516 pci_free_consistent(dev->pci, dev->upstream_riscbuf_size,
517 dev->_dma_virt_addr, dev->_dma_phys_addr);
518 }
519
520 dev->_dma_virt_addr =
521 pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size,
522 &dma_addr);
523 dev->_dma_virt_start_addr = dev->_dma_virt_addr;
524 dev->_dma_phys_start_addr = dma_addr;
525 dev->_dma_phys_addr = dma_addr;
526 dev->_risc_size = dev->upstream_riscbuf_size;
527
528 if (!dev->_dma_virt_addr) {
529 printk
530 ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
531 return -ENOMEM;
532 }
533
534 //Clear memory at address
535 memset(dev->_dma_virt_addr, 0, dev->_risc_size);
536
537 if (dev->_data_buf_virt_addr != NULL) {
538 pci_free_consistent(dev->pci, dev->upstream_databuf_size,
539 dev->_data_buf_virt_addr,
540 dev->_data_buf_phys_addr);
541 }
542 //For Video Data buffer allocation
543 dev->_data_buf_virt_addr =
544 pci_alloc_consistent(dev->pci, dev->upstream_databuf_size,
545 &data_dma_addr);
546 dev->_data_buf_phys_addr = data_dma_addr;
547 dev->_data_buf_size = dev->upstream_databuf_size;
548
549 if (!dev->_data_buf_virt_addr) {
550 printk
551 ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
552 return -ENOMEM;
553 }
554
555 //Clear memory at address
556 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
557
558 ret = cx25821_openfile(dev, sram_ch);
559 if (ret < 0)
560 return ret;
561
562 //Create RISC programs
563 ret =
564 cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
565 dev->_lines_count);
566 if (ret < 0) {
567 printk(KERN_INFO
568 "cx25821: Failed creating Video Upstream Risc programs! \n");
569 goto error;
570 }
571
572 return 0;
573
574 error:
575 return ret;
576}
577
578int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
579 u32 status)
580{
581 u32 int_msk_tmp;
582 struct sram_channel *channel = &dev->sram_channels[chan_num];
583 int singlefield_lines = NTSC_FIELD_HEIGHT;
584 int line_size_in_bytes = Y422_LINE_SZ;
585 int odd_risc_prog_size = 0;
586 dma_addr_t risc_phys_jump_addr;
587 __le32 *rp;
588
589 if (status & FLD_VID_SRC_RISC1) {
590 // We should only process one program per call
591 u32 prog_cnt = cx_read(channel->gpcnt);
592
593 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
594 int_msk_tmp = cx_read(channel->int_msk);
595 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
596 cx_write(channel->int_stat, _intr_msk);
597
598 spin_lock(&dev->slock);
599
600 dev->_frame_index = prog_cnt;
601
602 queue_work(dev->_irq_queues, &dev->_irq_work_entry);
603
604 if (dev->_is_first_frame) {
605 dev->_is_first_frame = 0;
606
607 if (dev->_isNTSC) {
608 singlefield_lines += 1;
609 odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
610 } else {
611 singlefield_lines = PAL_FIELD_HEIGHT;
612 odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
613 }
614
615 if (dev->_dma_virt_start_addr != NULL) {
616 line_size_in_bytes =
617 (dev->_pixel_format ==
618 PIXEL_FRMT_411) ? Y411_LINE_SZ :
619 Y422_LINE_SZ;
620 risc_phys_jump_addr =
621 dev->_dma_phys_start_addr +
622 odd_risc_prog_size;
623
624 rp = cx25821_update_riscprogram(dev,
625 dev->
626 _dma_virt_start_addr,
627 TOP_OFFSET,
628 line_size_in_bytes,
629 0x0,
630 singlefield_lines,
631 FIFO_DISABLE,
632 ODD_FIELD);
633
634 // Jump to Even Risc program of 1st Frame
635 *(rp++) = cpu_to_le32(RISC_JUMP);
636 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
637 *(rp++) = cpu_to_le32(0);
638 }
639 }
640
641 spin_unlock(&dev->slock);
642 } else {
643 if (status & FLD_VID_SRC_UF)
644 printk
645 ("%s: Video Received Underflow Error Interrupt!\n",
646 __func__);
647
648 if (status & FLD_VID_SRC_SYNC)
649 printk("%s: Video Received Sync Error Interrupt!\n",
650 __func__);
651
652 if (status & FLD_VID_SRC_OPC_ERR)
653 printk("%s: Video Received OpCode Error Interrupt!\n",
654 __func__);
655 }
656
657 if (dev->_file_status == END_OF_FILE) {
658 printk("cx25821: EOF Channel 1 Framecount = %d\n",
659 dev->_frame_count);
660 return -1;
661 }
662 //ElSE, set the interrupt mask register, re-enable irq.
663 int_msk_tmp = cx_read(channel->int_msk);
664 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
665
666 return 0;
667}
668
669static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
670{
671 struct cx25821_dev *dev = dev_id;
672 u32 msk_stat, vid_status;
673 int handled = 0;
674 int channel_num = 0;
675 struct sram_channel *sram_ch;
676
677 if (!dev)
678 return -1;
679
680 channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;
681
682 sram_ch = &dev->sram_channels[channel_num];
683
684 msk_stat = cx_read(sram_ch->int_mstat);
685 vid_status = cx_read(sram_ch->int_stat);
686
687 // Only deal with our interrupt
688 if (vid_status) {
689 handled =
690 cx25821_video_upstream_irq(dev, channel_num, vid_status);
691 }
692
693 if (handled < 0) {
694 cx25821_stop_upstream_video_ch1(dev);
695 } else {
696 handled += handled;
697 }
698
699 return IRQ_RETVAL(handled);
700}
701
702void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
703 int pix_format)
704{
705 int width = WIDTH_D1;
706 int height = dev->_lines_count;
707 int num_lines, odd_num_lines;
708 u32 value;
709 int vip_mode = OUTPUT_FRMT_656;
710
711 value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
712 value &= 0xFFFFFFEF;
713 value |= dev->_isNTSC ? 0 : 0x10;
714 cx_write(ch->vid_fmt_ctl, value);
715
716 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
717 cx_write(ch->vid_active_ctl1, width);
718
719 num_lines = (height / 2) & 0x3FF;
720 odd_num_lines = num_lines;
721
722 if (dev->_isNTSC) {
723 odd_num_lines += 1;
724 }
725
726 value = (num_lines << 16) | odd_num_lines;
727
728 // set number of active lines in field 0 (top) and field 1 (bottom)
729 cx_write(ch->vid_active_ctl2, value);
730
731 cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
732}
733
734int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
735 struct sram_channel *sram_ch)
736{
737 u32 tmp = 0;
738 int err = 0;
739
740 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
741 tmp = cx_read(VID_CH_MODE_SEL);
742 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
743
744 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
745 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
746 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
747
748 /* reset counter */
749 cx_write(sram_ch->gpcnt_ctl, 3);
750
751 // Clear our bits from the interrupt status register.
752 cx_write(sram_ch->int_stat, _intr_msk);
753
754 //Set the interrupt mask register, enable irq.
755 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
756 tmp = cx_read(sram_ch->int_msk);
757 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
758
759 err =
760 request_irq(dev->pci->irq, cx25821_upstream_irq,
761 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
762 if (err < 0) {
763 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
764 dev->pci->irq);
765 goto fail_irq;
766 }
767
768 // Start the DMA engine
769 tmp = cx_read(sram_ch->dma_ctl);
770 cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
771
772 dev->_is_running = 1;
773 dev->_is_first_frame = 1;
774
775 return 0;
776
777 fail_irq:
778 cx25821_dev_unregister(dev);
779 return err;
780}
781
782int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
783 int pixel_format)
784{
785 struct sram_channel *sram_ch;
786 u32 tmp;
787 int retval = 0;
788 int err = 0;
789 int data_frame_size = 0;
790 int risc_buffer_size = 0;
791 int str_length = 0;
792
793 if (dev->_is_running) {
794 printk("Video Channel is still running so return!\n");
795 return 0;
796 }
797
798 dev->_channel_upstream_select = channel_select;
799 sram_ch = &dev->sram_channels[channel_select];
800
801 INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
802 dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
803
804 if (!dev->_irq_queues) {
805 printk
806 ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
807 return -ENOMEM;
808 }
809 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
810 tmp = cx_read(VID_CH_MODE_SEL);
811 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
812
813 dev->_is_running = 0;
814 dev->_frame_count = 0;
815 dev->_file_status = RESET_STATUS;
816 dev->_lines_count = dev->_isNTSC ? 480 : 576;
817 dev->_pixel_format = pixel_format;
818 dev->_line_size =
819 (dev->_pixel_format ==
820 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
821 data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
822 risc_buffer_size =
823 dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
824
825 if (dev->input_filename) {
826 str_length = strlen(dev->input_filename);
827 dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL);
828
829 if (!dev->_filename)
830 goto error;
831
832 memcpy(dev->_filename, dev->input_filename, str_length + 1);
833 } else {
834 str_length = strlen(dev->_defaultname);
835 dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL);
836
837 if (!dev->_filename)
838 goto error;
839
840 memcpy(dev->_filename, dev->_defaultname, str_length + 1);
841 }
842
843 //Default if filename is empty string
844 if (strcmp(dev->input_filename, "") == 0) {
845 if (dev->_isNTSC) {
846 dev->_filename =
847 (dev->_pixel_format ==
848 PIXEL_FRMT_411) ? "/root/vid411.yuv" :
849 "/root/vidtest.yuv";
850 } else {
851 dev->_filename =
852 (dev->_pixel_format ==
853 PIXEL_FRMT_411) ? "/root/pal411.yuv" :
854 "/root/pal422.yuv";
855 }
856 }
857
858 dev->_is_running = 0;
859 dev->_frame_count = 0;
860 dev->_file_status = RESET_STATUS;
861 dev->_lines_count = dev->_isNTSC ? 480 : 576;
862 dev->_pixel_format = pixel_format;
863 dev->_line_size =
864 (dev->_pixel_format ==
865 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
866
867 retval =
868 cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size,
869 0);
870
871 /* setup fifo + format */
872 cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);
873
874 dev->upstream_riscbuf_size = risc_buffer_size * 2;
875 dev->upstream_databuf_size = data_frame_size * 2;
876
877 //Allocating buffers and prepare RISC program
878 retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
879 if (retval < 0) {
880 printk(KERN_ERR
881 "%s: Failed to set up Video upstream buffers!\n",
882 dev->name);
883 goto error;
884 }
885
886 cx25821_start_video_dma_upstream(dev, sram_ch);
887
888 return 0;
889
890 error:
891 cx25821_dev_unregister(dev);
892
893 return err;
894}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/staging/cx25821/cx25821-video-upstream.h
new file mode 100644
index 000000000000..cc9f93842514
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.h
@@ -0,0 +1,109 @@
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// PAL and NTSC line sizes and number of lines.
42#define WIDTH_D1 720
43#define NTSC_LINES_PER_FRAME 480
44#define PAL_LINES_PER_FRAME 576
45#define PAL_LINE_SZ 1440
46#define Y422_LINE_SZ 1440
47#define Y411_LINE_SZ 1080
48#define NTSC_FIELD_HEIGHT 240
49#define NTSC_ODD_FLD_LINES 241
50#define PAL_FIELD_HEIGHT 288
51
52#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
53#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
54#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
55#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
56
57#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
58#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
59
60#define RISC_WRITECR_INSTRUCTION_SIZE 16
61#define RISC_SYNC_INSTRUCTION_SIZE 4
62#define JUMP_INSTRUCTION_SIZE 12
63#define MAXSIZE_NO_OPS 36
64#define DWORD_SIZE 4
65
66#define USE_RISC_NOOP_VIDEO 1
67
68#ifdef USE_RISC_NOOP_VIDEO
69#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
70 RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
71
72#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
73
74#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
75 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
76
77#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
78 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
79
80#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
81 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
82
83#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
84 JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
85
86#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
87
88#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
89 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
90
91#endif
92
93#ifndef USE_RISC_NOOP_VIDEO
94#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
95 RISC_SYNC_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
96
97#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
98
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
102#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
103#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
104
105#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
106#define NTSC_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
107#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
108 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
109#endif
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
new file mode 100644
index 000000000000..8834bc80a5ab
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -0,0 +1,1299 @@
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
84int get_format_size(void)
85{
86 return ARRAY_SIZE(formats);
87}
88
89struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
90{
91 unsigned int i;
92
93 if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) {
94 return formats + 1;
95 }
96
97 for (i = 0; i < ARRAY_SIZE(formats); i++)
98 if (formats[i].fourcc == fourcc)
99 return formats + i;
100
101 printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
102 return NULL;
103}
104
105void dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q)
106{
107 struct cx25821_buffer *buf;
108 struct list_head *item;
109 dprintk(1, "%s()\n", __func__);
110
111 if (!list_empty(&q->active)) {
112 list_for_each(item, &q->active)
113 buf = list_entry(item, struct cx25821_buffer, vb.queue);
114 }
115
116 if (!list_empty(&q->queued)) {
117 list_for_each(item, &q->queued)
118 buf = list_entry(item, struct cx25821_buffer, vb.queue);
119 }
120
121}
122
123void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
124 u32 count)
125{
126 struct cx25821_buffer *buf;
127 int bc;
128
129 for (bc = 0;; bc++) {
130 if (list_empty(&q->active)) {
131 dprintk(1, "bc=%d (=0: active empty)\n", bc);
132 break;
133 }
134
135 buf =
136 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
137
138 /* count comes from the hw and it is 16bit wide --
139 * this trick handles wrap-arounds correctly for
140 * up to 32767 buffers in flight... */
141 if ((s16) (count - buf->count) < 0) {
142 break;
143 }
144
145 do_gettimeofday(&buf->vb.ts);
146 buf->vb.state = VIDEOBUF_DONE;
147 list_del(&buf->vb.queue);
148 wake_up(&buf->vb.done);
149 }
150
151 if (list_empty(&q->active))
152 del_timer(&q->timeout);
153 else
154 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
155 if (bc != 1)
156 printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
157 __func__, bc);
158}
159
160#ifdef TUNER_FLAG
161int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
162{
163 dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
164 (unsigned int)norm, v4l2_norm_to_name(norm));
165
166 dev->tvnorm = norm;
167
168 /* Tell the internal A/V decoder */
169 cx25821_call_all(dev, core, s_std, norm);
170
171 return 0;
172}
173#endif
174
175struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
176 struct pci_dev *pci,
177 struct video_device *template,
178 char *type)
179{
180 struct video_device *vfd;
181 dprintk(1, "%s()\n", __func__);
182
183 vfd = video_device_alloc();
184 if (NULL == vfd)
185 return NULL;
186 *vfd = *template;
187 vfd->minor = -1;
188 vfd->v4l2_dev = &dev->v4l2_dev;
189 vfd->release = video_device_release;
190 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
191 cx25821_boards[dev->board].name);
192 return vfd;
193}
194
195/*
196static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
197{
198 int i;
199
200 if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
201 return -EINVAL;
202 for (i = 0; i < CX25821_CTLS; i++)
203 if (cx25821_ctls[i].v.id == qctrl->id)
204 break;
205 if (i == CX25821_CTLS) {
206 *qctrl = no_ctl;
207 return 0;
208 }
209 *qctrl = cx25821_ctls[i].v;
210 return 0;
211}
212*/
213
214// resource management
215int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
216{
217 dprintk(1, "%s()\n", __func__);
218 if (fh->resources & bit)
219 /* have it already allocated */
220 return 1;
221
222 /* is it free? */
223 mutex_lock(&dev->lock);
224 if (dev->resources & bit) {
225 /* no, someone else uses it */
226 mutex_unlock(&dev->lock);
227 return 0;
228 }
229 /* it's free, grab it */
230 fh->resources |= bit;
231 dev->resources |= bit;
232 dprintk(1, "res: get %d\n", bit);
233 mutex_unlock(&dev->lock);
234 return 1;
235}
236
237int res_check(struct cx25821_fh *fh, unsigned int bit)
238{
239 return fh->resources & bit;
240}
241
242int res_locked(struct cx25821_dev *dev, unsigned int bit)
243{
244 return dev->resources & bit;
245}
246
247void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
248{
249 BUG_ON((fh->resources & bits) != bits);
250 dprintk(1, "%s()\n", __func__);
251
252 mutex_lock(&dev->lock);
253 fh->resources &= ~bits;
254 dev->resources &= ~bits;
255 dprintk(1, "res: put %d\n", bits);
256 mutex_unlock(&dev->lock);
257}
258
259int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
260{
261 struct v4l2_routing route;
262 memset(&route, 0, sizeof(route));
263
264 dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
265 __func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
266 INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
267 dev->input = input;
268
269 route.input = INPUT(input)->vmux;
270
271 /* Tell the internal A/V decoder */
272 cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
273
274 return 0;
275}
276
277int cx25821_start_video_dma(struct cx25821_dev *dev,
278 struct cx25821_dmaqueue *q,
279 struct cx25821_buffer *buf,
280 struct sram_channel *channel)
281{
282 int tmp = 0;
283
284 /* setup fifo + format */
285 cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
286
287 /* reset counter */
288 cx_write(channel->gpcnt_ctl, 3);
289 q->count = 1;
290
291 /* enable irq */
292 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
293 cx_set(channel->int_msk, 0x11);
294
295 /* start dma */
296 cx_write(channel->dma_ctl, 0x11); /* FIFO and RISC enable */
297
298 /* make sure upstream setting if any is reversed */
299 tmp = cx_read(VID_CH_MODE_SEL);
300 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
301
302 return 0;
303}
304
305int cx25821_restart_video_queue(struct cx25821_dev *dev,
306 struct cx25821_dmaqueue *q,
307 struct sram_channel *channel)
308{
309 struct cx25821_buffer *buf, *prev;
310 struct list_head *item;
311
312 if (!list_empty(&q->active)) {
313 buf =
314 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
315
316 cx25821_start_video_dma(dev, q, buf, channel);
317
318 list_for_each(item, &q->active) {
319 buf = list_entry(item, struct cx25821_buffer, vb.queue);
320 buf->count = q->count++;
321 }
322
323 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
324 return 0;
325 }
326
327 prev = NULL;
328 for (;;) {
329 if (list_empty(&q->queued))
330 return 0;
331
332 buf =
333 list_entry(q->queued.next, struct cx25821_buffer, vb.queue);
334
335 if (NULL == prev) {
336 list_move_tail(&buf->vb.queue, &q->active);
337 cx25821_start_video_dma(dev, q, buf, channel);
338 buf->vb.state = VIDEOBUF_ACTIVE;
339 buf->count = q->count++;
340 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
341 } else if (prev->vb.width == buf->vb.width &&
342 prev->vb.height == buf->vb.height &&
343 prev->fmt == buf->fmt) {
344 list_move_tail(&buf->vb.queue, &q->active);
345 buf->vb.state = VIDEOBUF_ACTIVE;
346 buf->count = q->count++;
347 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
348 prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
349 } else {
350 return 0;
351 }
352 prev = buf;
353 }
354}
355
356void cx25821_vid_timeout(unsigned long data)
357{
358 struct cx25821_data *timeout_data = (struct cx25821_data *)data;
359 struct cx25821_dev *dev = timeout_data->dev;
360 struct sram_channel *channel = timeout_data->channel;
361 struct cx25821_dmaqueue *q = &dev->vidq[channel->i];
362 struct cx25821_buffer *buf;
363 unsigned long flags;
364
365 //cx25821_sram_channel_dump(dev, channel);
366 cx_clear(channel->dma_ctl, 0x11);
367
368 spin_lock_irqsave(&dev->slock, flags);
369 while (!list_empty(&q->active)) {
370 buf =
371 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
372 list_del(&buf->vb.queue);
373
374 buf->vb.state = VIDEOBUF_ERROR;
375 wake_up(&buf->vb.done);
376 }
377
378 cx25821_restart_video_queue(dev, q, channel);
379 spin_unlock_irqrestore(&dev->slock, flags);
380}
381
382int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
383{
384 u32 count = 0;
385 int handled = 0;
386 u32 mask;
387 struct sram_channel *channel = &dev->sram_channels[chan_num];
388
389 mask = cx_read(channel->int_msk);
390 if (0 == (status & mask))
391 return handled;
392
393 cx_write(channel->int_stat, status);
394
395 /* risc op code error */
396 if (status & (1 << 16)) {
397 printk(KERN_WARNING "%s, %s: video risc op code error\n",
398 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],
417 channel);
418 spin_unlock(&dev->slock);
419 handled++;
420 }
421 return handled;
422}
423
424void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
425{
426 if (dev->ioctl_dev) {
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
455int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
456 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 =
475 (unsigned long)&dev->timeout_data[chan_num];
476 init_timer(&dev->vidq[chan_num].timeout);
477 cx25821_risc_stopper(dev->pci, &dev->vidq[chan_num].stopper,
478 dev->sram_channels[chan_num].dma_ctl, 0x11, 0);
479
480 /* register v4l devices */
481 dev->video_dev[chan_num] =
482 cx25821_vdev_init(dev, dev->pci, video_template, "video");
483 err =
484 video_register_device(dev->video_dev[chan_num], VFL_TYPE_GRABBER,
485 video_nr[dev->nr]);
486
487 if (err < 0) {
488 goto fail_unreg;
489 }
490 //set PCI interrupt
491 cx_set(PCI_INT_MSK, 0xff);
492
493 /* initial device configuration */
494 mutex_lock(&dev->lock);
495#ifdef TUNER_FLAG
496 cx25821_set_tvnorm(dev, dev->tvnorm);
497#endif
498 mutex_unlock(&dev->lock);
499
500 init_controls(dev, chan_num);
501
502 return 0;
503
504 fail_unreg:
505 cx25821_video_unregister(dev, chan_num);
506 return err;
507}
508
509int buffer_setup(struct videobuf_queue *q, unsigned int *count,
510 unsigned int *size)
511{
512 struct cx25821_fh *fh = q->priv_data;
513
514 *size = fh->fmt->depth * fh->width * fh->height >> 3;
515
516 if (0 == *count)
517 *count = 32;
518
519 while (*size * *count > vid_limit * 1024 * 1024)
520 (*count)--;
521
522 return 0;
523}
524
525int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
526 enum v4l2_field field)
527{
528 struct cx25821_fh *fh = q->priv_data;
529 struct cx25821_dev *dev = fh->dev;
530 struct cx25821_buffer *buf =
531 container_of(vb, struct cx25821_buffer, vb);
532 int rc, init_buffer = 0;
533 u32 line0_offset, line1_offset;
534 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
535 int bpl_local = LINE_SIZE_D1;
536 int channel_opened = 0;
537
538 BUG_ON(NULL == fh->fmt);
539 if (fh->width < 48 || fh->width > 720 ||
540 fh->height < 32 || fh->height > 576)
541 return -EINVAL;
542
543 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
544
545 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
546 return -EINVAL;
547
548 if (buf->fmt != fh->fmt ||
549 buf->vb.width != fh->width ||
550 buf->vb.height != fh->height || buf->vb.field != field) {
551 buf->fmt = fh->fmt;
552 buf->vb.width = fh->width;
553 buf->vb.height = fh->height;
554 buf->vb.field = field;
555 init_buffer = 1;
556 }
557
558 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
559 init_buffer = 1;
560 rc = videobuf_iolock(q, &buf->vb, NULL);
561 if (0 != rc) {
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
573 || channel_opened > 7) ? 7 : channel_opened;
574
575 if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411)
576 buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
577 else
578 buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
579
580 if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411) {
581 bpl_local = buf->bpl;
582 } else {
583 bpl_local = buf->bpl; //Default
584
585 if (channel_opened >= 0 && channel_opened <= 7) {
586 if (dev->use_cif_resolution[channel_opened]) {
587 if (dev->tvnorm & V4L2_STD_PAL_BG
588 || dev->tvnorm & V4L2_STD_PAL_DK)
589 bpl_local = 352 << 1;
590 else
591 bpl_local =
592 dev->
593 cif_width[channel_opened] <<
594 1;
595 }
596 }
597 }
598
599 switch (buf->vb.field) {
600 case V4L2_FIELD_TOP:
601 cx25821_risc_buffer(dev->pci, &buf->risc,
602 dma->sglist, 0, UNSET,
603 buf->bpl, 0, buf->vb.height);
604 break;
605 case V4L2_FIELD_BOTTOM:
606 cx25821_risc_buffer(dev->pci, &buf->risc,
607 dma->sglist, UNSET, 0,
608 buf->bpl, 0, buf->vb.height);
609 break;
610 case V4L2_FIELD_INTERLACED:
611 /* All other formats are top field first */
612 line0_offset = 0;
613 line1_offset = buf->bpl;
614 dprintk(1, "top field first\n");
615
616 cx25821_risc_buffer(dev->pci, &buf->risc,
617 dma->sglist, line0_offset,
618 bpl_local, bpl_local, bpl_local,
619 buf->vb.height >> 1);
620 break;
621 case V4L2_FIELD_SEQ_TB:
622 cx25821_risc_buffer(dev->pci, &buf->risc,
623 dma->sglist,
624 0, buf->bpl * (buf->vb.height >> 1),
625 buf->bpl, 0, buf->vb.height >> 1);
626 break;
627 case V4L2_FIELD_SEQ_BT:
628 cx25821_risc_buffer(dev->pci, &buf->risc,
629 dma->sglist,
630 buf->bpl * (buf->vb.height >> 1), 0,
631 buf->bpl, 0, buf->vb.height >> 1);
632 break;
633 default:
634 BUG();
635 }
636 }
637
638 dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
639 buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth,
640 fh->fmt->name, (unsigned long)buf->risc.dma);
641
642 buf->vb.state = VIDEOBUF_PREPARED;
643
644 return 0;
645
646 fail:
647 cx25821_free_buffer(q, buf);
648 return rc;
649}
650
651void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
652{
653 struct cx25821_buffer *buf =
654 container_of(vb, struct cx25821_buffer, vb);
655
656 cx25821_free_buffer(q, buf);
657}
658
659struct videobuf_queue *get_queue(struct cx25821_fh *fh)
660{
661 switch (fh->type) {
662 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
663 return &fh->vidq;
664 default:
665 BUG();
666 return NULL;
667 }
668}
669
670int get_resource(struct cx25821_fh *fh, int resource)
671{
672 switch (fh->type) {
673 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
674 return resource;
675 default:
676 BUG();
677 return 0;
678 }
679}
680
681int video_mmap(struct file *file, struct vm_area_struct *vma)
682{
683 struct cx25821_fh *fh = file->private_data;
684
685 return videobuf_mmap_mapper(get_queue(fh), vma);
686}
687
688/* VIDEO IOCTLS */
689int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
690{
691 struct cx25821_fh *fh = priv;
692
693 f->fmt.pix.width = fh->width;
694 f->fmt.pix.height = fh->height;
695 f->fmt.pix.field = fh->vidq.field;
696 f->fmt.pix.pixelformat = fh->fmt->fourcc;
697 f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
698 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
699
700 return 0;
701}
702
703int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
704{
705 struct cx25821_fmt *fmt;
706 enum v4l2_field field;
707 unsigned int maxw, maxh;
708
709 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
710 if (NULL == fmt)
711 return -EINVAL;
712
713 field = f->fmt.pix.field;
714 maxw = 720;
715 maxh = 576;
716
717 if (V4L2_FIELD_ANY == field) {
718 field = (f->fmt.pix.height > maxh / 2)
719 ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
720 }
721
722 switch (field) {
723 case V4L2_FIELD_TOP:
724 case V4L2_FIELD_BOTTOM:
725 maxh = maxh / 2;
726 break;
727 case V4L2_FIELD_INTERLACED:
728 break;
729 default:
730 return -EINVAL;
731 }
732
733 f->fmt.pix.field = field;
734 if (f->fmt.pix.height < 32)
735 f->fmt.pix.height = 32;
736 if (f->fmt.pix.height > maxh)
737 f->fmt.pix.height = maxh;
738 if (f->fmt.pix.width < 48)
739 f->fmt.pix.width = 48;
740 if (f->fmt.pix.width > maxw)
741 f->fmt.pix.width = maxw;
742 f->fmt.pix.width &= ~0x03;
743 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
744 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
745
746 return 0;
747}
748
749int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
750{
751 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
752
753 strcpy(cap->driver, "cx25821");
754 strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
755 sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
756 cap->version = CX25821_VERSION_CODE;
757 cap->capabilities =
758 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
759 if (UNSET != dev->tuner_type)
760 cap->capabilities |= V4L2_CAP_TUNER;
761 return 0;
762}
763
764int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
765 struct v4l2_fmtdesc *f)
766{
767 if (unlikely(f->index >= ARRAY_SIZE(formats)))
768 return -EINVAL;
769
770 strlcpy(f->description, formats[f->index].name, sizeof(f->description));
771 f->pixelformat = formats[f->index].fourcc;
772
773 return 0;
774}
775
776#ifdef CONFIG_VIDEO_V4L1_COMPAT
777int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
778{
779 struct cx25821_fh *fh = priv;
780 struct videobuf_queue *q;
781 struct v4l2_requestbuffers req;
782 unsigned int i;
783 int err;
784
785 q = get_queue(fh);
786 memset(&req, 0, sizeof(req));
787 req.type = q->type;
788 req.count = 8;
789 req.memory = V4L2_MEMORY_MMAP;
790 err = videobuf_reqbufs(q, &req);
791 if (err < 0)
792 return err;
793
794 mbuf->frames = req.count;
795 mbuf->size = 0;
796 for (i = 0; i < mbuf->frames; i++) {
797 mbuf->offsets[i] = q->bufs[i]->boff;
798 mbuf->size += q->bufs[i]->bsize;
799 }
800 return 0;
801}
802#endif
803
804int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
805{
806 struct cx25821_fh *fh = priv;
807 return videobuf_reqbufs(get_queue(fh), p);
808}
809
810int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
811{
812 struct cx25821_fh *fh = priv;
813 return videobuf_querybuf(get_queue(fh), p);
814}
815
816int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
817{
818 struct cx25821_fh *fh = priv;
819 return videobuf_qbuf(get_queue(fh), p);
820}
821
822int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
823{
824 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
825
826 *p = v4l2_prio_max(&dev->prio);
827
828 return 0;
829}
830
831int vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio)
832{
833 struct cx25821_fh *fh = f;
834 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
835
836 return v4l2_prio_change(&dev->prio, &fh->prio, prio);
837}
838
839#ifdef TUNER_FLAG
840int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
841{
842 struct cx25821_fh *fh = priv;
843 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
844 int err;
845
846 dprintk(1, "%s()\n", __func__);
847
848 if (fh) {
849 err = v4l2_prio_check(&dev->prio, &fh->prio);
850 if (0 != err)
851 return err;
852 }
853
854 if (dev->tvnorm == *tvnorms) {
855 return 0;
856 }
857
858 mutex_lock(&dev->lock);
859 cx25821_set_tvnorm(dev, *tvnorms);
860 mutex_unlock(&dev->lock);
861
862 medusa_set_videostandard(dev);
863
864 return 0;
865}
866#endif
867
868int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
869{
870 static const char *iname[] = {
871 [CX25821_VMUX_COMPOSITE] = "Composite",
872 [CX25821_VMUX_SVIDEO] = "S-Video",
873 [CX25821_VMUX_DEBUG] = "for debug only",
874 };
875 unsigned int n;
876 dprintk(1, "%s()\n", __func__);
877
878 n = i->index;
879 if (n > 2)
880 return -EINVAL;
881
882 if (0 == INPUT(n)->type)
883 return -EINVAL;
884
885 memset(i, 0, sizeof(*i));
886 i->index = n;
887 i->type = V4L2_INPUT_TYPE_CAMERA;
888 strcpy(i->name, iname[INPUT(n)->type]);
889
890 i->std = CX25821_NORMS;
891 return 0;
892}
893
894int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
895{
896 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
897 dprintk(1, "%s()\n", __func__);
898 return cx25821_enum_input(dev, i);
899}
900
901int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
902{
903 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
904
905 *i = dev->input;
906 dprintk(1, "%s() returns %d\n", __func__, *i);
907 return 0;
908}
909
910int vidioc_s_input(struct file *file, void *priv, unsigned int i)
911{
912 struct cx25821_fh *fh = priv;
913 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
914 int err;
915
916 dprintk(1, "%s(%d)\n", __func__, i);
917
918 if (fh) {
919 err = v4l2_prio_check(&dev->prio, &fh->prio);
920 if (0 != err)
921 return err;
922 }
923
924 if (i > 2) {
925 dprintk(1, "%s() -EINVAL\n", __func__);
926 return -EINVAL;
927 }
928
929 mutex_lock(&dev->lock);
930 cx25821_video_mux(dev, i);
931 mutex_unlock(&dev->lock);
932 return 0;
933}
934
935#ifdef TUNER_FLAG
936int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
937{
938 struct cx25821_fh *fh = priv;
939 struct cx25821_dev *dev = fh->dev;
940
941 f->frequency = dev->freq;
942
943 cx25821_call_all(dev, tuner, g_frequency, f);
944
945 return 0;
946}
947
948int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
949{
950 mutex_lock(&dev->lock);
951 dev->freq = f->frequency;
952
953 cx25821_call_all(dev, tuner, s_frequency, f);
954
955 /* When changing channels it is required to reset TVAUDIO */
956 msleep(10);
957
958 mutex_unlock(&dev->lock);
959
960 return 0;
961}
962
963int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
964{
965 struct cx25821_fh *fh = priv;
966 struct cx25821_dev *dev = fh->dev;
967 int err;
968
969 if (fh) {
970 err = v4l2_prio_check(&dev->prio, &fh->prio);
971 if (0 != err)
972 return err;
973 }
974
975 return cx25821_set_freq(dev, f);
976}
977#endif
978
979#ifdef CONFIG_VIDEO_ADV_DEBUG
980int vidioc_g_register(struct file *file, void *fh,
981 struct v4l2_dbg_register *reg)
982{
983 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
984
985 if (!v4l2_chip_match_host(&reg->match))
986 return -EINVAL;
987
988 cx25821_call_all(dev, core, g_register, reg);
989
990 return 0;
991}
992
993int vidioc_s_register(struct file *file, void *fh,
994 struct v4l2_dbg_register *reg)
995{
996 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
997
998 if (!v4l2_chip_match_host(&reg->match))
999 return -EINVAL;
1000
1001 cx25821_call_all(dev, core, s_register, reg);
1002
1003 return 0;
1004}
1005
1006#endif
1007
1008#ifdef TUNER_FLAG
1009int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1010{
1011 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1012
1013 if (unlikely(UNSET == dev->tuner_type))
1014 return -EINVAL;
1015 if (0 != t->index)
1016 return -EINVAL;
1017
1018 strcpy(t->name, "Television");
1019 t->type = V4L2_TUNER_ANALOG_TV;
1020 t->capability = V4L2_TUNER_CAP_NORM;
1021 t->rangehigh = 0xffffffffUL;
1022
1023 t->signal = 0xffff; /* LOCKED */
1024 return 0;
1025}
1026
1027int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1028{
1029 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1030 struct cx25821_fh *fh = priv;
1031 int err;
1032
1033 if (fh) {
1034 err = v4l2_prio_check(&dev->prio, &fh->prio);
1035 if (0 != err)
1036 return err;
1037 }
1038
1039 dprintk(1, "%s()\n", __func__);
1040 if (UNSET == dev->tuner_type)
1041 return -EINVAL;
1042 if (0 != t->index)
1043 return -EINVAL;
1044
1045 return 0;
1046}
1047
1048#endif
1049// ******************************************************************************************
1050static const struct v4l2_queryctrl no_ctl = {
1051 .name = "42",
1052 .flags = V4L2_CTRL_FLAG_DISABLED,
1053};
1054
1055static struct v4l2_queryctrl cx25821_ctls[] = {
1056 /* --- video --- */
1057 {
1058 .id = V4L2_CID_BRIGHTNESS,
1059 .name = "Brightness",
1060 .minimum = 0,
1061 .maximum = 10000,
1062 .step = 1,
1063 .default_value = 6200,
1064 .type = V4L2_CTRL_TYPE_INTEGER,
1065 }, {
1066 .id = V4L2_CID_CONTRAST,
1067 .name = "Contrast",
1068 .minimum = 0,
1069 .maximum = 10000,
1070 .step = 1,
1071 .default_value = 5000,
1072 .type = V4L2_CTRL_TYPE_INTEGER,
1073 }, {
1074 .id = V4L2_CID_SATURATION,
1075 .name = "Saturation",
1076 .minimum = 0,
1077 .maximum = 10000,
1078 .step = 1,
1079 .default_value = 5000,
1080 .type = V4L2_CTRL_TYPE_INTEGER,
1081 }, {
1082 .id = V4L2_CID_HUE,
1083 .name = "Hue",
1084 .minimum = 0,
1085 .maximum = 10000,
1086 .step = 1,
1087 .default_value = 5000,
1088 .type = V4L2_CTRL_TYPE_INTEGER,
1089 }
1090};
1091static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
1092
1093static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
1094{
1095 int i;
1096
1097 if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
1098 return -EINVAL;
1099 for (i = 0; i < CX25821_CTLS; i++)
1100 if (cx25821_ctls[i].id == qctrl->id)
1101 break;
1102 if (i == CX25821_CTLS) {
1103 *qctrl = no_ctl;
1104 return 0;
1105 }
1106 *qctrl = cx25821_ctls[i];
1107 return 0;
1108}
1109
1110int vidioc_queryctrl(struct file *file, void *priv,
1111 struct v4l2_queryctrl *qctrl)
1112{
1113 return cx25821_ctrl_query(qctrl);
1114}
1115
1116/* ------------------------------------------------------------------ */
1117/* VIDEO CTRL IOCTLS */
1118
1119static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
1120{
1121 unsigned int i;
1122
1123 for (i = 0; i < CX25821_CTLS; i++)
1124 if (cx25821_ctls[i].id == id)
1125 return cx25821_ctls + i;
1126 return NULL;
1127}
1128
1129int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl)
1130{
1131 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1132
1133 const struct v4l2_queryctrl *ctrl;
1134
1135 ctrl = ctrl_by_id(ctl->id);
1136
1137 if (NULL == ctrl)
1138 return -EINVAL;
1139 switch (ctl->id) {
1140 case V4L2_CID_BRIGHTNESS:
1141 ctl->value = dev->ctl_bright;
1142 break;
1143 case V4L2_CID_HUE:
1144 ctl->value = dev->ctl_hue;
1145 break;
1146 case V4L2_CID_CONTRAST:
1147 ctl->value = dev->ctl_contrast;
1148 break;
1149 case V4L2_CID_SATURATION:
1150 ctl->value = dev->ctl_saturation;
1151 break;
1152 }
1153 return 0;
1154}
1155
1156int cx25821_set_control(struct cx25821_dev *dev,
1157 struct v4l2_control *ctl, int chan_num)
1158{
1159 int err;
1160 const struct v4l2_queryctrl *ctrl;
1161
1162 err = -EINVAL;
1163
1164 ctrl = ctrl_by_id(ctl->id);
1165
1166 if (NULL == ctrl)
1167 return err;
1168
1169 switch (ctrl->type) {
1170 case V4L2_CTRL_TYPE_BOOLEAN:
1171 case V4L2_CTRL_TYPE_MENU:
1172 case V4L2_CTRL_TYPE_INTEGER:
1173 if (ctl->value < ctrl->minimum)
1174 ctl->value = ctrl->minimum;
1175 if (ctl->value > ctrl->maximum)
1176 ctl->value = ctrl->maximum;
1177 break;
1178 default:
1179 /* nothing */ ;
1180 };
1181
1182 switch (ctl->id) {
1183 case V4L2_CID_BRIGHTNESS:
1184 dev->ctl_bright = ctl->value;
1185 medusa_set_brightness(dev, ctl->value, chan_num);
1186 break;
1187 case V4L2_CID_HUE:
1188 dev->ctl_hue = ctl->value;
1189 medusa_set_hue(dev, ctl->value, chan_num);
1190 break;
1191 case V4L2_CID_CONTRAST:
1192 dev->ctl_contrast = ctl->value;
1193 medusa_set_contrast(dev, ctl->value, chan_num);
1194 break;
1195 case V4L2_CID_SATURATION:
1196 dev->ctl_saturation = ctl->value;
1197 medusa_set_saturation(dev, ctl->value, chan_num);
1198 break;
1199 }
1200
1201 err = 0;
1202
1203 return err;
1204}
1205
1206static void init_controls(struct cx25821_dev *dev, int chan_num)
1207{
1208 struct v4l2_control ctrl;
1209 int i;
1210 for (i = 0; i < CX25821_CTLS; i++) {
1211 ctrl.id = cx25821_ctls[i].id;
1212 ctrl.value = cx25821_ctls[i].default_value;
1213
1214 cx25821_set_control(dev, &ctrl, chan_num);
1215 }
1216}
1217
1218int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap)
1219{
1220 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1221
1222 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1223 return -EINVAL;
1224 cropcap->bounds.top = cropcap->bounds.left = 0;
1225 cropcap->bounds.width = 720;
1226 cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
1227 cropcap->pixelaspect.numerator =
1228 dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
1229 cropcap->pixelaspect.denominator =
1230 dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
1231 cropcap->defrect = cropcap->bounds;
1232 return 0;
1233}
1234
1235int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1236{
1237 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1238 struct cx25821_fh *fh = priv;
1239 int err;
1240
1241 if (fh) {
1242 err = v4l2_prio_check(&dev->prio, &fh->prio);
1243 if (0 != err)
1244 return err;
1245 }
1246 // vidioc_s_crop not supported
1247 return -EINVAL;
1248}
1249
1250int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1251{
1252 // vidioc_g_crop not supported
1253 return -EINVAL;
1254}
1255
1256int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
1257{
1258 // medusa does not support video standard sensing of current input
1259 *norm = CX25821_NORMS;
1260
1261 return 0;
1262}
1263
1264int is_valid_width(u32 width, v4l2_std_id tvnorm)
1265{
1266 if (tvnorm == V4L2_STD_PAL_BG) {
1267 if (width == 352 || width == 720)
1268 return 1;
1269 else
1270 return 0;
1271 }
1272
1273 if (tvnorm == V4L2_STD_NTSC_M) {
1274 if (width == 320 || width == 352 || width == 720)
1275 return 1;
1276 else
1277 return 0;
1278 }
1279 return 0;
1280}
1281
1282int is_valid_height(u32 height, v4l2_std_id tvnorm)
1283{
1284 if (tvnorm == V4L2_STD_PAL_BG) {
1285 if (height == 576 || height == 288)
1286 return 1;
1287 else
1288 return 0;
1289 }
1290
1291 if (tvnorm == V4L2_STD_NTSC_M) {
1292 if (height == 480 || height == 240)
1293 return 1;
1294 else
1295 return 0;
1296 }
1297
1298 return 0;
1299}
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
new file mode 100644
index 000000000000..4417ff5d90d4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -0,0 +1,194 @@
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#include <linux/init.h>
28#include <linux/list.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/kmod.h>
32#include <linux/kernel.h>
33#include <linux/slab.h>
34#include <linux/interrupt.h>
35#include <linux/delay.h>
36#include <linux/kthread.h>
37#include <asm/div64.h>
38
39#include "cx25821.h"
40#include <media/v4l2-common.h>
41#include <media/v4l2-ioctl.h>
42
43#ifdef CONFIG_VIDEO_V4L1_COMPAT
44/* Include V4L1 specific functions. Should be removed soon */
45#include <linux/videodev.h>
46#endif
47
48#define TUNER_FLAG
49
50#define VIDEO_DEBUG 0
51
52#define dprintk(level, fmt, arg...)\
53 do { if (VIDEO_DEBUG >= level)\
54 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
55 } while (0)
56
57//For IOCTL to identify running upstream
58#define UPSTREAM_START_VIDEO 700
59#define UPSTREAM_STOP_VIDEO 701
60#define UPSTREAM_START_AUDIO 702
61#define UPSTREAM_STOP_AUDIO 703
62#define UPSTREAM_DUMP_REGISTERS 702
63#define SET_VIDEO_STD 800
64#define SET_PIXEL_FORMAT 1000
65#define ENABLE_CIF_RESOLUTION 1001
66
67#define REG_READ 900
68#define REG_WRITE 901
69#define MEDUSA_READ 910
70#define MEDUSA_WRITE 911
71
72extern struct sram_channel *channel0;
73extern struct sram_channel *channel1;
74extern struct sram_channel *channel2;
75extern struct sram_channel *channel3;
76extern struct sram_channel *channel4;
77extern struct sram_channel *channel5;
78extern struct sram_channel *channel6;
79extern struct sram_channel *channel7;
80extern struct sram_channel *channel9;
81extern struct sram_channel *channel10;
82extern struct sram_channel *channel11;
83extern struct video_device cx25821_video_template0;
84extern struct video_device cx25821_video_template1;
85extern struct video_device cx25821_video_template2;
86extern struct video_device cx25821_video_template3;
87extern struct video_device cx25821_video_template4;
88extern struct video_device cx25821_video_template5;
89extern struct video_device cx25821_video_template6;
90extern struct video_device cx25821_video_template7;
91extern struct video_device cx25821_video_template9;
92extern struct video_device cx25821_video_template10;
93extern struct video_device cx25821_video_template11;
94extern struct video_device cx25821_videoioctl_template;
95//extern const u32 *ctrl_classes[];
96
97extern unsigned int vid_limit;
98
99#define FORMAT_FLAGS_PACKED 0x01
100extern struct cx25821_fmt formats[];
101extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc);
102extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
103
104extern void dump_video_queue(struct cx25821_dev *dev,
105 struct cx25821_dmaqueue *q);
106extern void cx25821_video_wakeup(struct cx25821_dev *dev,
107 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
113extern int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
114 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,
118 unsigned int bits);
119extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);
120extern int cx25821_start_video_dma(struct cx25821_dev *dev,
121 struct cx25821_dmaqueue *q,
122 struct cx25821_buffer *buf,
123 struct sram_channel *channel);
124
125extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width,
126 unsigned int height, enum v4l2_field field);
127extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);
128extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);
129extern int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
130 struct video_device *video_template);
131extern int get_format_size(void);
132
133extern int buffer_setup(struct videobuf_queue *q, unsigned int *count,
134 unsigned int *size);
135extern int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
136 enum v4l2_field field);
137extern void buffer_release(struct videobuf_queue *q,
138 struct videobuf_buffer *vb);
139extern struct videobuf_queue *get_queue(struct cx25821_fh *fh);
140extern int get_resource(struct cx25821_fh *fh, int resource);
141extern int video_mmap(struct file *file, struct vm_area_struct *vma);
142extern int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
143 struct v4l2_format *f);
144extern int vidioc_querycap(struct file *file, void *priv,
145 struct v4l2_capability *cap);
146extern int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
147 struct v4l2_fmtdesc *f);
148extern int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf);
149extern int vidioc_reqbufs(struct file *file, void *priv,
150 struct v4l2_requestbuffers *p);
151extern int vidioc_querybuf(struct file *file, void *priv,
152 struct v4l2_buffer *p);
153extern int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
154extern int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms);
155extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i);
156extern int vidioc_enum_input(struct file *file, void *priv,
157 struct v4l2_input *i);
158extern int vidioc_g_input(struct file *file, void *priv, unsigned int *i);
159extern int vidioc_s_input(struct file *file, void *priv, unsigned int i);
160extern int vidioc_g_ctrl(struct file *file, void *priv,
161 struct v4l2_control *ctl);
162extern int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
163 struct v4l2_format *f);
164extern int vidioc_g_frequency(struct file *file, void *priv,
165 struct v4l2_frequency *f);
166extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f);
167extern int vidioc_s_frequency(struct file *file, void *priv,
168 struct v4l2_frequency *f);
169extern int vidioc_g_register(struct file *file, void *fh,
170 struct v4l2_dbg_register *reg);
171extern int vidioc_s_register(struct file *file, void *fh,
172 struct v4l2_dbg_register *reg);
173extern int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
174extern int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
175
176extern int is_valid_width(u32 width, v4l2_std_id tvnorm);
177extern int is_valid_height(u32 height, v4l2_std_id tvnorm);
178
179extern int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p);
180extern int vidioc_s_priority(struct file *file, void *f,
181 enum v4l2_priority prio);
182
183extern int vidioc_queryctrl(struct file *file, void *priv,
184 struct v4l2_queryctrl *qctrl);
185extern int cx25821_set_control(struct cx25821_dev *dev,
186 struct v4l2_control *ctrl, int chan_num);
187
188extern int vidioc_cropcap(struct file *file, void *fh,
189 struct v4l2_cropcap *cropcap);
190extern int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop);
191extern int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop);
192
193extern int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm);
194#endif
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c
new file mode 100644
index 000000000000..950fac1d7003
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video0.c
@@ -0,0 +1,451 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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,
46 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,
51 &dev->sram_channels[SRAM_CH00]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH00]
109 && h->video_dev[SRAM_CH00]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128
129 file->private_data = fh;
130 fh->dev = dev;
131 fh->type = type;
132 fh->width = 720;
133
134 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
135 fh->height = 576;
136 else
137 fh->height = 480;
138
139 dev->channel_opened = SRAM_CH00;
140 pix_format =
141 (dev->pixel_formats[dev->channel_opened] ==
142 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
143 fh->fmt = format_by_fourcc(pix_format);
144
145 v4l2_prio_open(&dev->prio, &fh->prio);
146
147 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
148 &dev->pci->dev, &dev->slock,
149 V4L2_BUF_TYPE_VIDEO_CAPTURE,
150 V4L2_FIELD_INTERLACED,
151 sizeof(struct cx25821_buffer), fh);
152
153 dprintk(1, "post videobuf_queue_init()\n");
154 unlock_kernel();
155
156 return 0;
157}
158
159static ssize_t video_read(struct file *file, char __user * data, size_t count,
160 loff_t * ppos)
161{
162 struct cx25821_fh *fh = file->private_data;
163
164 switch (fh->type) {
165 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
166 if (res_locked(fh->dev, RESOURCE_VIDEO0))
167 return -EBUSY;
168
169 return videobuf_read_one(&fh->vidq, data, count, ppos,
170 file->f_flags & O_NONBLOCK);
171
172 default:
173 BUG();
174 return 0;
175 }
176}
177
178static unsigned int video_poll(struct file *file,
179 struct poll_table_struct *wait)
180{
181 struct cx25821_fh *fh = file->private_data;
182 struct cx25821_buffer *buf;
183
184 if (res_check(fh, RESOURCE_VIDEO0)) {
185 /* streaming capture */
186 if (list_empty(&fh->vidq.stream))
187 return POLLERR;
188 buf = list_entry(fh->vidq.stream.next,
189 struct cx25821_buffer, vb.stream);
190 } else {
191 /* read() capture */
192 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
193 if (NULL == buf)
194 return POLLERR;
195 }
196
197 poll_wait(file, &buf->vb.done, wait);
198 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
199 if (buf->vb.state == VIDEOBUF_DONE) {
200 struct cx25821_dev *dev = fh->dev;
201
202 if (dev && dev->use_cif_resolution[SRAM_CH00]) {
203 u8 cam_id = *((char *)buf->vb.baddr + 3);
204 memcpy((char *)buf->vb.baddr,
205 (char *)buf->vb.baddr + (fh->width * 2),
206 (fh->width * 2));
207 *((char *)buf->vb.baddr + 3) = cam_id;
208 }
209 }
210
211 return POLLIN | POLLRDNORM;
212 }
213
214 return 0;
215}
216
217static int video_release(struct file *file)
218{
219 struct cx25821_fh *fh = file->private_data;
220 struct cx25821_dev *dev = fh->dev;
221
222 //stop the risc engine and fifo
223 cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
224
225 /* stop video capture */
226 if (res_check(fh, RESOURCE_VIDEO0)) {
227 videobuf_queue_cancel(&fh->vidq);
228 res_free(dev, fh, RESOURCE_VIDEO0);
229 }
230
231 if (fh->vidq.read_buf) {
232 buffer_release(&fh->vidq, fh->vidq.read_buf);
233 kfree(fh->vidq.read_buf);
234 }
235
236 videobuf_mmap_free(&fh->vidq);
237
238 v4l2_prio_close(&dev->prio, &fh->prio);
239 file->private_data = NULL;
240 kfree(fh);
241
242 return 0;
243}
244
245static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
246{
247 struct cx25821_fh *fh = priv;
248 struct cx25821_dev *dev = fh->dev;
249
250 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
251 return -EINVAL;
252 }
253
254 if (unlikely(i != fh->type)) {
255 return -EINVAL;
256 }
257
258 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO0)))) {
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
284static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
285 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 err = v4l2_prio_check(&dev->prio, &fh->prio);
294 if (0 != err)
295 return err;
296 }
297
298 dprintk(2, "%s()\n", __func__);
299 err = vidioc_try_fmt_vid_cap(file, priv, f);
300
301 if (0 != err)
302 return err;
303
304 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
305 fh->vidq.field = f->fmt.pix.field;
306
307 // check if width and height is valid based on set standard
308 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
309 fh->width = f->fmt.pix.width;
310 }
311
312 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
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_CH00, pix_format);
324
325 // check if cif resolution
326 if (fh->width == 320 || fh->width == 352) {
327 dev->use_cif_resolution[SRAM_CH00] = 1;
328 } else {
329 dev->use_cif_resolution[SRAM_CH00] = 0;
330 }
331 dev->cif_width[SRAM_CH00] = fh->width;
332 medusa_set_resolution(dev, fh->width, SRAM_CH00);
333
334 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
335 fh->height, fh->vidq.field);
336 cx25821_call_all(dev, video, s_fmt, f);
337
338 return 0;
339}
340
341static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
342{
343 int ret_val = 0;
344 struct cx25821_fh *fh = priv;
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346
347 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
348
349 p->sequence = dev->vidq[SRAM_CH00].count;
350
351 return ret_val;
352}
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_CH00];
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 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 0 is %s\n",
368 (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_CH00);
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_template0 = {
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};
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c
new file mode 100644
index 000000000000..a4dddc684adf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video1.c
@@ -0,0 +1,451 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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 /* 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,
46 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,
51 &dev->sram_channels[SRAM_CH01]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH01]
109 && h->video_dev[SRAM_CH01]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128
129 file->private_data = fh;
130 fh->dev = dev;
131 fh->type = type;
132 fh->width = 720;
133
134 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
135 fh->height = 576;
136 else
137 fh->height = 480;
138
139 dev->channel_opened = SRAM_CH01;
140 pix_format =
141 (dev->pixel_formats[dev->channel_opened] ==
142 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
143 fh->fmt = format_by_fourcc(pix_format);
144
145 v4l2_prio_open(&dev->prio, &fh->prio);
146
147 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
148 &dev->pci->dev, &dev->slock,
149 V4L2_BUF_TYPE_VIDEO_CAPTURE,
150 V4L2_FIELD_INTERLACED,
151 sizeof(struct cx25821_buffer), fh);
152
153 dprintk(1, "post videobuf_queue_init()\n");
154 unlock_kernel();
155
156 return 0;
157}
158
159static ssize_t video_read(struct file *file, char __user * data, size_t count,
160 loff_t * ppos)
161{
162 struct cx25821_fh *fh = file->private_data;
163
164 switch (fh->type) {
165 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
166 if (res_locked(fh->dev, RESOURCE_VIDEO1))
167 return -EBUSY;
168
169 return videobuf_read_one(&fh->vidq, data, count, ppos,
170 file->f_flags & O_NONBLOCK);
171
172 default:
173 BUG();
174 return 0;
175 }
176}
177
178static unsigned int video_poll(struct file *file,
179 struct poll_table_struct *wait)
180{
181 struct cx25821_fh *fh = file->private_data;
182 struct cx25821_buffer *buf;
183
184 if (res_check(fh, RESOURCE_VIDEO1)) {
185 /* streaming capture */
186 if (list_empty(&fh->vidq.stream))
187 return POLLERR;
188 buf = list_entry(fh->vidq.stream.next,
189 struct cx25821_buffer, vb.stream);
190 } else {
191 /* read() capture */
192 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
193 if (NULL == buf)
194 return POLLERR;
195 }
196
197 poll_wait(file, &buf->vb.done, wait);
198 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
199 if (buf->vb.state == VIDEOBUF_DONE) {
200 struct cx25821_dev *dev = fh->dev;
201
202 if (dev && dev->use_cif_resolution[SRAM_CH01]) {
203 u8 cam_id = *((char *)buf->vb.baddr + 3);
204 memcpy((char *)buf->vb.baddr,
205 (char *)buf->vb.baddr + (fh->width * 2),
206 (fh->width * 2));
207 *((char *)buf->vb.baddr + 3) = cam_id;
208 }
209 }
210
211 return POLLIN | POLLRDNORM;
212 }
213
214 return 0;
215}
216
217static int video_release(struct file *file)
218{
219 struct cx25821_fh *fh = file->private_data;
220 struct cx25821_dev *dev = fh->dev;
221
222 //stop the risc engine and fifo
223 cx_write(channel1->dma_ctl, 0); /* FIFO and RISC disable */
224
225 /* stop video capture */
226 if (res_check(fh, RESOURCE_VIDEO1)) {
227 videobuf_queue_cancel(&fh->vidq);
228 res_free(dev, fh, RESOURCE_VIDEO1);
229 }
230
231 if (fh->vidq.read_buf) {
232 buffer_release(&fh->vidq, fh->vidq.read_buf);
233 kfree(fh->vidq.read_buf);
234 }
235
236 videobuf_mmap_free(&fh->vidq);
237
238 v4l2_prio_close(&dev->prio, &fh->prio);
239 file->private_data = NULL;
240 kfree(fh);
241
242 return 0;
243}
244
245static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
246{
247 struct cx25821_fh *fh = priv;
248 struct cx25821_dev *dev = fh->dev;
249
250 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
251 return -EINVAL;
252 }
253
254 if (unlikely(i != fh->type)) {
255 return -EINVAL;
256 }
257
258 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO1)))) {
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_VIDEO1);
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
284static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
285 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 err = v4l2_prio_check(&dev->prio, &fh->prio);
294 if (0 != err)
295 return err;
296 }
297
298 dprintk(2, "%s()\n", __func__);
299 err = vidioc_try_fmt_vid_cap(file, priv, f);
300
301 if (0 != err)
302 return err;
303
304 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
305 fh->vidq.field = f->fmt.pix.field;
306
307 // check if width and height is valid based on set standard
308 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
309 fh->width = f->fmt.pix.width;
310 }
311
312 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
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_CH01, pix_format);
324
325 // check if cif resolution
326 if (fh->width == 320 || fh->width == 352) {
327 dev->use_cif_resolution[SRAM_CH01] = 1;
328 } else {
329 dev->use_cif_resolution[SRAM_CH01] = 0;
330 }
331 dev->cif_width[SRAM_CH01] = fh->width;
332 medusa_set_resolution(dev, fh->width, SRAM_CH01);
333
334 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
335 fh->height, fh->vidq.field);
336 cx25821_call_all(dev, video, s_fmt, f);
337
338 return 0;
339}
340
341static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
342{
343 int ret_val = 0;
344 struct cx25821_fh *fh = priv;
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346
347 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
348
349 p->sequence = dev->vidq[SRAM_CH01].count;
350
351 return ret_val;
352}
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_CH01];
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 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 1 is %s\n",
368 (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_CH01);
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_template1 = {
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};
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c
new file mode 100644
index 000000000000..8e04e253f5d9
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video2.c
@@ -0,0 +1,452 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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 /* 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,
46 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,
51 &dev->sram_channels[SRAM_CH02]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH02]
109 && h->video_dev[SRAM_CH02]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH02;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO2))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO2)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH02]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel2->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO2)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO2);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO2)))) {
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
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
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 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH02, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH02] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH02] = 0;
329 }
330 dev->cif_width[SRAM_CH02] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH02);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH02].count;
349
350 return ret_val;
351}
352
353static int vidioc_log_status(struct file *file, void *priv)
354{
355 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
356 char name[32 + 2];
357
358 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH02];
359 u32 tmp = 0;
360
361 snprintf(name, sizeof(name), "%s/2", dev->name);
362 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
363 dev->name);
364
365 cx25821_call_all(dev, core, log_status);
366
367 tmp = cx_read(sram_ch->dma_ctl);
368 printk(KERN_INFO "Video input 2 is %s\n",
369 (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_CH02);
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_template2 = {
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};
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c
new file mode 100644
index 000000000000..8801a8ead904
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video3.c
@@ -0,0 +1,451 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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 /* 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,
46 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,
51 &dev->sram_channels[SRAM_CH03]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH03]
109 && h->video_dev[SRAM_CH03]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH03;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO3))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO3)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH03]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel3->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO3)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO3);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO3)))) {
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
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
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 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH03, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH03] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH03] = 0;
329 }
330 dev->cif_width[SRAM_CH03] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH03);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH03].count;
349
350 return ret_val;
351}
352
353static int vidioc_log_status(struct file *file, void *priv)
354{
355 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
356 char name[32 + 2];
357
358 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH03];
359 u32 tmp = 0;
360
361 snprintf(name, sizeof(name), "%s/2", dev->name);
362 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
363 dev->name);
364 cx25821_call_all(dev, core, log_status);
365
366 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 3 is %s\n",
368 (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_CH03);
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_template3 = {
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};
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c
new file mode 100644
index 000000000000..ab0d747138ad
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video4.c
@@ -0,0 +1,450 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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,
46 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,
51 &dev->sram_channels[SRAM_CH04]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH04]
109 && h->video_dev[SRAM_CH04]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH04;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
146 &dev->pci->dev, &dev->slock,
147 V4L2_BUF_TYPE_VIDEO_CAPTURE,
148 V4L2_FIELD_INTERLACED,
149 sizeof(struct cx25821_buffer), fh);
150
151 dprintk(1, "post videobuf_queue_init()\n");
152 unlock_kernel();
153
154 return 0;
155}
156
157static ssize_t video_read(struct file *file, char __user * data, size_t count,
158 loff_t * ppos)
159{
160 struct cx25821_fh *fh = file->private_data;
161
162 switch (fh->type) {
163 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
164 if (res_locked(fh->dev, RESOURCE_VIDEO4))
165 return -EBUSY;
166
167 return videobuf_read_one(&fh->vidq, data, count, ppos,
168 file->f_flags & O_NONBLOCK);
169
170 default:
171 BUG();
172 return 0;
173 }
174}
175
176static unsigned int video_poll(struct file *file,
177 struct poll_table_struct *wait)
178{
179 struct cx25821_fh *fh = file->private_data;
180 struct cx25821_buffer *buf;
181
182 if (res_check(fh, RESOURCE_VIDEO4)) {
183 /* streaming capture */
184 if (list_empty(&fh->vidq.stream))
185 return POLLERR;
186 buf = list_entry(fh->vidq.stream.next,
187 struct cx25821_buffer, vb.stream);
188 } else {
189 /* read() capture */
190 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
191 if (NULL == buf)
192 return POLLERR;
193 }
194
195 poll_wait(file, &buf->vb.done, wait);
196 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
197 if (buf->vb.state == VIDEOBUF_DONE) {
198 struct cx25821_dev *dev = fh->dev;
199
200 if (dev && dev->use_cif_resolution[SRAM_CH04]) {
201 u8 cam_id = *((char *)buf->vb.baddr + 3);
202 memcpy((char *)buf->vb.baddr,
203 (char *)buf->vb.baddr + (fh->width * 2),
204 (fh->width * 2));
205 *((char *)buf->vb.baddr + 3) = cam_id;
206 }
207 }
208
209 return POLLIN | POLLRDNORM;
210 }
211
212 return 0;
213}
214
215static int video_release(struct file *file)
216{
217 struct cx25821_fh *fh = file->private_data;
218 struct cx25821_dev *dev = fh->dev;
219
220 //stop the risc engine and fifo
221 cx_write(channel4->dma_ctl, 0); /* FIFO and RISC disable */
222
223 /* stop video capture */
224 if (res_check(fh, RESOURCE_VIDEO4)) {
225 videobuf_queue_cancel(&fh->vidq);
226 res_free(dev, fh, RESOURCE_VIDEO4);
227 }
228
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO4)))) {
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_VIDEO4);
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
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 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 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
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 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH04, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH04] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH04] = 0;
328 }
329 dev->cif_width[SRAM_CH04] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH04);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH04].count;
348
349 return ret_val;
350}
351
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH04];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 4 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH04);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template4 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c
new file mode 100644
index 000000000000..7ef0b971f5cf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video5.c
@@ -0,0 +1,450 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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,
46 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,
51 &dev->sram_channels[SRAM_CH05]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH05]
109 && h->video_dev[SRAM_CH05]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH05;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO5))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO5)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH05]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel5->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO5)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO5);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO5)))) {
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_VIDEO5);
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
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
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 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH05, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH05] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH05] = 0;
329 }
330 dev->cif_width[SRAM_CH05] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH05);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH05].count;
349
350 return ret_val;
351}
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH05];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 5 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH05);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template5 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c
new file mode 100644
index 000000000000..3c41b49e2ea9
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video6.c
@@ -0,0 +1,450 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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,
46 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,
51 &dev->sram_channels[SRAM_CH06]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH06]
109 && h->video_dev[SRAM_CH06]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH06;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO6))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO6)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH06]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel6->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO6)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO6);
228 }
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO6)))) {
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_VIDEO6);
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
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 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 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 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH06, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH06] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH06] = 0;
328 }
329 dev->cif_width[SRAM_CH06] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH06);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH06].count;
348
349 return ret_val;
350}
351
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH06];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 6 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH06);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template6 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c
new file mode 100644
index 000000000000..625c9b78a9cf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video7.c
@@ -0,0 +1,449 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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,
45 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,
50 &dev->sram_channels[SRAM_CH07]);
51 buf->vb.state = VIDEOBUF_ACTIVE;
52 buf->count = q->count++;
53 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
54 dprintk(2,
55 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
56 buf, buf->vb.i, buf->count, q->count);
57 } else {
58 prev =
59 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
60 if (prev->vb.width == buf->vb.width
61 && prev->vb.height == buf->vb.height
62 && prev->fmt == buf->fmt) {
63 list_add_tail(&buf->vb.queue, &q->active);
64 buf->vb.state = VIDEOBUF_ACTIVE;
65 buf->count = q->count++;
66 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
67
68 /* 64 bit bits 63-32 */
69 prev->risc.jmp[2] = cpu_to_le32(0);
70 dprintk(2,
71 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
72 buf, buf->vb.i, buf->count);
73
74 } else {
75 list_add_tail(&buf->vb.queue, &q->queued);
76 buf->vb.state = VIDEOBUF_QUEUED;
77 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
78 buf->vb.i);
79 }
80 }
81
82 if (list_empty(&q->active)) {
83 dprintk(2, "active queue empty!\n");
84 }
85}
86
87static struct videobuf_queue_ops cx25821_video_qops = {
88 .buf_setup = buffer_setup,
89 .buf_prepare = buffer_prepare,
90 .buf_queue = buffer_queue,
91 .buf_release = buffer_release,
92};
93
94static int video_open(struct file *file)
95{
96 int minor = video_devdata(file)->minor;
97 struct cx25821_dev *h, *dev = NULL;
98 struct cx25821_fh *fh;
99 struct list_head *list;
100 enum v4l2_buf_type type = 0;
101 u32 pix_format;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH07]
108 && h->video_dev[SRAM_CH07]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127 file->private_data = fh;
128 fh->dev = dev;
129 fh->type = type;
130 fh->width = 720;
131
132 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
133 fh->height = 576;
134 else
135 fh->height = 480;
136
137 dev->channel_opened = SRAM_CH07;
138 pix_format =
139 (dev->pixel_formats[dev->channel_opened] ==
140 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
141 fh->fmt = format_by_fourcc(pix_format);
142
143 v4l2_prio_open(&dev->prio, &fh->prio);
144
145 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
146 &dev->pci->dev, &dev->slock,
147 V4L2_BUF_TYPE_VIDEO_CAPTURE,
148 V4L2_FIELD_INTERLACED,
149 sizeof(struct cx25821_buffer), fh);
150
151 dprintk(1, "post videobuf_queue_init()\n");
152 unlock_kernel();
153
154 return 0;
155}
156
157static ssize_t video_read(struct file *file, char __user * data, size_t count,
158 loff_t * ppos)
159{
160 struct cx25821_fh *fh = file->private_data;
161
162 switch (fh->type) {
163 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
164 if (res_locked(fh->dev, RESOURCE_VIDEO7))
165 return -EBUSY;
166
167 return videobuf_read_one(&fh->vidq, data, count, ppos,
168 file->f_flags & O_NONBLOCK);
169
170 default:
171 BUG();
172 return 0;
173 }
174}
175
176static unsigned int video_poll(struct file *file,
177 struct poll_table_struct *wait)
178{
179 struct cx25821_fh *fh = file->private_data;
180 struct cx25821_buffer *buf;
181
182 if (res_check(fh, RESOURCE_VIDEO7)) {
183 /* streaming capture */
184 if (list_empty(&fh->vidq.stream))
185 return POLLERR;
186 buf = list_entry(fh->vidq.stream.next,
187 struct cx25821_buffer, vb.stream);
188 } else {
189 /* read() capture */
190 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
191 if (NULL == buf)
192 return POLLERR;
193 }
194
195 poll_wait(file, &buf->vb.done, wait);
196 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
197 if (buf->vb.state == VIDEOBUF_DONE) {
198 struct cx25821_dev *dev = fh->dev;
199
200 if (dev && dev->use_cif_resolution[SRAM_CH07]) {
201 u8 cam_id = *((char *)buf->vb.baddr + 3);
202 memcpy((char *)buf->vb.baddr,
203 (char *)buf->vb.baddr + (fh->width * 2),
204 (fh->width * 2));
205 *((char *)buf->vb.baddr + 3) = cam_id;
206 }
207 }
208
209 return POLLIN | POLLRDNORM;
210 }
211
212 return 0;
213}
214
215static int video_release(struct file *file)
216{
217 struct cx25821_fh *fh = file->private_data;
218 struct cx25821_dev *dev = fh->dev;
219
220 //stop the risc engine and fifo
221 cx_write(channel7->dma_ctl, 0); /* FIFO and RISC disable */
222
223 /* stop video capture */
224 if (res_check(fh, RESOURCE_VIDEO7)) {
225 videobuf_queue_cancel(&fh->vidq);
226 res_free(dev, fh, RESOURCE_VIDEO7);
227 }
228
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO7)))) {
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_VIDEO7);
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
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 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 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 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH07, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH07] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH07] = 0;
328 }
329 dev->cif_width[SRAM_CH07] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH07);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH07].count;
348
349 return ret_val;
350}
351static int vidioc_log_status(struct file *file, void *priv)
352{
353 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
354 char name[32 + 2];
355
356 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH07];
357 u32 tmp = 0;
358
359 snprintf(name, sizeof(name), "%s/2", dev->name);
360 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
361 dev->name);
362 cx25821_call_all(dev, core, log_status);
363
364 tmp = cx_read(sram_ch->dma_ctl);
365 printk(KERN_INFO "Video input 7 is %s\n",
366 (tmp & 0x11) ? "streaming" : "stopped");
367 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
368 dev->name);
369 return 0;
370}
371
372static int vidioc_s_ctrl(struct file *file, void *priv,
373 struct v4l2_control *ctl)
374{
375 struct cx25821_fh *fh = priv;
376 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
377 int err;
378
379 if (fh) {
380 err = v4l2_prio_check(&dev->prio, &fh->prio);
381 if (0 != err)
382 return err;
383 }
384
385 return cx25821_set_control(dev, ctl, SRAM_CH07);
386}
387
388// exported stuff
389static const struct v4l2_file_operations video_fops = {
390 .owner = THIS_MODULE,
391 .open = video_open,
392 .release = video_release,
393 .read = video_read,
394 .poll = video_poll,
395 .mmap = video_mmap,
396 .ioctl = video_ioctl2,
397};
398
399static const struct v4l2_ioctl_ops video_ioctl_ops = {
400 .vidioc_querycap = vidioc_querycap,
401 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
402 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
403 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
404 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
405 .vidioc_reqbufs = vidioc_reqbufs,
406 .vidioc_querybuf = vidioc_querybuf,
407 .vidioc_qbuf = vidioc_qbuf,
408 .vidioc_dqbuf = vidioc_dqbuf,
409#ifdef TUNER_FLAG
410 .vidioc_s_std = vidioc_s_std,
411 .vidioc_querystd = vidioc_querystd,
412#endif
413 .vidioc_cropcap = vidioc_cropcap,
414 .vidioc_s_crop = vidioc_s_crop,
415 .vidioc_g_crop = vidioc_g_crop,
416 .vidioc_enum_input = vidioc_enum_input,
417 .vidioc_g_input = vidioc_g_input,
418 .vidioc_s_input = vidioc_s_input,
419 .vidioc_g_ctrl = vidioc_g_ctrl,
420 .vidioc_s_ctrl = vidioc_s_ctrl,
421 .vidioc_queryctrl = vidioc_queryctrl,
422 .vidioc_streamon = vidioc_streamon,
423 .vidioc_streamoff = vidioc_streamoff,
424 .vidioc_log_status = vidioc_log_status,
425 .vidioc_g_priority = vidioc_g_priority,
426 .vidioc_s_priority = vidioc_s_priority,
427#ifdef CONFIG_VIDEO_V4L1_COMPAT
428 .vidiocgmbuf = vidiocgmbuf,
429#endif
430#ifdef TUNER_FLAG
431 .vidioc_g_tuner = vidioc_g_tuner,
432 .vidioc_s_tuner = vidioc_s_tuner,
433 .vidioc_g_frequency = vidioc_g_frequency,
434 .vidioc_s_frequency = vidioc_s_frequency,
435#endif
436#ifdef CONFIG_VIDEO_ADV_DEBUG
437 .vidioc_g_register = vidioc_g_register,
438 .vidioc_s_register = vidioc_s_register,
439#endif
440};
441
442struct video_device cx25821_video_template7 = {
443 .name = "cx25821-video",
444 .fops = &video_fops,
445 .minor = -1,
446 .ioctl_ops = &video_ioctl_ops,
447 .tvnorms = CX25821_NORMS,
448 .current_norm = V4L2_STD_NTSC_M,
449};
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c
new file mode 100644
index 000000000000..2a312ce78c63
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-videoioctl.c
@@ -0,0 +1,496 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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,
46 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,
51 &dev->sram_channels[VIDEO_IOCTL_CH]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->ioctl_dev && h->ioctl_dev->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = VIDEO_IOCTL_CH;
139 pix_format = V4L2_PIX_FMT_YUYV;
140 fh->fmt = format_by_fourcc(pix_format);
141
142 v4l2_prio_open(&dev->prio, &fh->prio);
143
144 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
145 &dev->pci->dev, &dev->slock,
146 V4L2_BUF_TYPE_VIDEO_CAPTURE,
147 V4L2_FIELD_INTERLACED,
148 sizeof(struct cx25821_buffer), fh);
149
150 dprintk(1, "post videobuf_queue_init()\n");
151 unlock_kernel();
152
153 return 0;
154}
155
156static ssize_t video_read(struct file *file, char __user * data, size_t count,
157 loff_t * ppos)
158{
159 struct cx25821_fh *fh = file->private_data;
160
161 switch (fh->type) {
162 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
163 if (res_locked(fh->dev, RESOURCE_VIDEO_IOCTL))
164 return -EBUSY;
165
166 return videobuf_read_one(&fh->vidq, data, count, ppos,
167 file->f_flags & O_NONBLOCK);
168
169 default:
170 BUG();
171 return 0;
172 }
173}
174
175static unsigned int video_poll(struct file *file,
176 struct poll_table_struct *wait)
177{
178 struct cx25821_fh *fh = file->private_data;
179 struct cx25821_buffer *buf;
180
181 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
182 /* streaming capture */
183 if (list_empty(&fh->vidq.stream))
184 return POLLERR;
185 buf = list_entry(fh->vidq.stream.next,
186 struct cx25821_buffer, vb.stream);
187 } else {
188 /* read() capture */
189 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
190 if (NULL == buf)
191 return POLLERR;
192 }
193
194 poll_wait(file, &buf->vb.done, wait);
195 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
196 return POLLIN | POLLRDNORM;
197
198 return 0;
199}
200
201static int video_release(struct file *file)
202{
203 struct cx25821_fh *fh = file->private_data;
204 struct cx25821_dev *dev = fh->dev;
205
206 /* stop video capture */
207 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
208 videobuf_queue_cancel(&fh->vidq);
209 res_free(dev, fh, RESOURCE_VIDEO_IOCTL);
210 }
211
212 if (fh->vidq.read_buf) {
213 buffer_release(&fh->vidq, fh->vidq.read_buf);
214 kfree(fh->vidq.read_buf);
215 }
216
217 videobuf_mmap_free(&fh->vidq);
218
219 v4l2_prio_close(&dev->prio, &fh->prio);
220
221 file->private_data = NULL;
222 kfree(fh);
223
224 return 0;
225}
226
227static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
228{
229 struct cx25821_fh *fh = priv;
230 struct cx25821_dev *dev = fh->dev;
231
232 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
233 return -EINVAL;
234 }
235
236 if (unlikely(i != fh->type)) {
237 return -EINVAL;
238 }
239
240 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO_IOCTL)))) {
241 return -EBUSY;
242 }
243
244 return videobuf_streamon(get_queue(fh));
245}
246
247static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
248{
249 struct cx25821_fh *fh = priv;
250 struct cx25821_dev *dev = fh->dev;
251 int err, res;
252
253 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
254 return -EINVAL;
255 if (i != fh->type)
256 return -EINVAL;
257
258 res = get_resource(fh, RESOURCE_VIDEO_IOCTL);
259 err = videobuf_streamoff(get_queue(fh));
260 if (err < 0)
261 return err;
262 res_free(dev, fh, res);
263 return 0;
264}
265
266static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
267 struct v4l2_format *f)
268{
269 struct cx25821_fh *fh = priv;
270 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
271 int err;
272
273 if (fh) {
274 err = v4l2_prio_check(&dev->prio, &fh->prio);
275 if (0 != err)
276 return err;
277 }
278
279 dprintk(2, "%s()\n", __func__);
280 err = vidioc_try_fmt_vid_cap(file, priv, f);
281
282 if (0 != err)
283 return err;
284 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
285 fh->width = f->fmt.pix.width;
286 fh->height = f->fmt.pix.height;
287 fh->vidq.field = f->fmt.pix.field;
288 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
289 fh->height, fh->vidq.field);
290 cx25821_call_all(dev, video, s_fmt, f);
291 return 0;
292}
293
294static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
295{
296 struct cx25821_fh *fh = priv;
297 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
298}
299
300static long video_ioctl_set(struct file *file, unsigned int cmd,
301 unsigned long arg)
302{
303 struct cx25821_fh *fh = file->private_data;
304 struct cx25821_dev *dev = fh->dev;
305 struct downstream_user_struct *data_from_user;
306 int command;
307 int width = 720;
308 int selected_channel = 0, pix_format = 0, i = 0;
309 int cif_enable = 0, cif_width = 0;
310 u32 value = 0;
311
312 data_from_user = (struct downstream_user_struct *)arg;
313
314 if (!data_from_user) {
315 printk("cx25821 in %s(): User data is INVALID. Returning.\n",
316 __func__);
317 return 0;
318 }
319
320 command = data_from_user->command;
321
322 if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
323 && command != ENABLE_CIF_RESOLUTION && command != REG_READ
324 && command != REG_WRITE && command != MEDUSA_READ
325 && command != MEDUSA_WRITE) {
326 return 0;
327 }
328
329 switch (command) {
330 case SET_VIDEO_STD:
331 dev->tvnorm =
332 !strcmp(data_from_user->vid_stdname,
333 "PAL") ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
334 medusa_set_videostandard(dev);
335 break;
336
337 case SET_PIXEL_FORMAT:
338 selected_channel = data_from_user->decoder_select;
339 pix_format = data_from_user->pixel_format;
340
341 if (!(selected_channel <= 7 && selected_channel >= 0)) {
342 selected_channel -= 4;
343 selected_channel = selected_channel % 8;
344 }
345
346 if (selected_channel >= 0)
347 cx25821_set_pixel_format(dev, selected_channel,
348 pix_format);
349
350 break;
351
352 case ENABLE_CIF_RESOLUTION:
353 selected_channel = data_from_user->decoder_select;
354 cif_enable = data_from_user->cif_resolution_enable;
355 cif_width = data_from_user->cif_width;
356
357 if (cif_enable) {
358 if (dev->tvnorm & V4L2_STD_PAL_BG
359 || dev->tvnorm & V4L2_STD_PAL_DK)
360 width = 352;
361 else
362 width = (cif_width == 320
363 || cif_width == 352) ? cif_width : 320;
364 }
365
366 if (!(selected_channel <= 7 && selected_channel >= 0)) {
367 selected_channel -= 4;
368 selected_channel = selected_channel % 8;
369 }
370
371 if (selected_channel <= 7 && selected_channel >= 0) {
372 dev->use_cif_resolution[selected_channel] = cif_enable;
373 dev->cif_width[selected_channel] = width;
374 } else {
375 for (i = 0; i < VID_CHANNEL_NUM; i++) {
376 dev->use_cif_resolution[i] = cif_enable;
377 dev->cif_width[i] = width;
378 }
379 }
380
381 medusa_set_resolution(dev, width, selected_channel);
382 break;
383 case REG_READ:
384 data_from_user->reg_data = cx_read(data_from_user->reg_address);
385 break;
386 case REG_WRITE:
387 cx_write(data_from_user->reg_address, data_from_user->reg_data);
388 break;
389 case MEDUSA_READ:
390 value =
391 cx25821_i2c_read(&dev->i2c_bus[0],
392 (u16) data_from_user->reg_address,
393 &data_from_user->reg_data);
394 break;
395 case MEDUSA_WRITE:
396 cx25821_i2c_write(&dev->i2c_bus[0],
397 (u16) data_from_user->reg_address,
398 data_from_user->reg_data);
399 break;
400 }
401
402 return 0;
403}
404
405static int vidioc_log_status(struct file *file, void *priv)
406{
407 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
408 char name[32 + 2];
409
410 snprintf(name, sizeof(name), "%s/2", dev->name);
411 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
412 dev->name);
413 cx25821_call_all(dev, core, log_status);
414 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
415 dev->name);
416 return 0;
417}
418
419static int vidioc_s_ctrl(struct file *file, void *priv,
420 struct v4l2_control *ctl)
421{
422 struct cx25821_fh *fh = priv;
423 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
424 int err;
425
426 if (fh) {
427 err = v4l2_prio_check(&dev->prio, &fh->prio);
428 if (0 != err)
429 return err;
430 }
431
432 return 0;
433}
434
435// exported stuff
436static const struct v4l2_file_operations video_fops = {
437 .owner = THIS_MODULE,
438 .open = video_open,
439 .release = video_release,
440 .read = video_read,
441 .poll = video_poll,
442 .mmap = video_mmap,
443 .ioctl = video_ioctl_set,
444};
445
446static const struct v4l2_ioctl_ops video_ioctl_ops = {
447 .vidioc_querycap = vidioc_querycap,
448 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
449 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
450 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
451 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
452 .vidioc_reqbufs = vidioc_reqbufs,
453 .vidioc_querybuf = vidioc_querybuf,
454 .vidioc_qbuf = vidioc_qbuf,
455 .vidioc_dqbuf = vidioc_dqbuf,
456#ifdef TUNER_FLAG
457 .vidioc_s_std = vidioc_s_std,
458 .vidioc_querystd = vidioc_querystd,
459#endif
460 .vidioc_cropcap = vidioc_cropcap,
461 .vidioc_s_crop = vidioc_s_crop,
462 .vidioc_g_crop = vidioc_g_crop,
463 .vidioc_enum_input = vidioc_enum_input,
464 .vidioc_g_input = vidioc_g_input,
465 .vidioc_s_input = vidioc_s_input,
466 .vidioc_g_ctrl = vidioc_g_ctrl,
467 .vidioc_s_ctrl = vidioc_s_ctrl,
468 .vidioc_queryctrl = vidioc_queryctrl,
469 .vidioc_streamon = vidioc_streamon,
470 .vidioc_streamoff = vidioc_streamoff,
471 .vidioc_log_status = vidioc_log_status,
472 .vidioc_g_priority = vidioc_g_priority,
473 .vidioc_s_priority = vidioc_s_priority,
474#ifdef CONFIG_VIDEO_V4L1_COMPAT
475 .vidiocgmbuf = vidiocgmbuf,
476#endif
477#ifdef TUNER_FLAG
478 .vidioc_g_tuner = vidioc_g_tuner,
479 .vidioc_s_tuner = vidioc_s_tuner,
480 .vidioc_g_frequency = vidioc_g_frequency,
481 .vidioc_s_frequency = vidioc_s_frequency,
482#endif
483#ifdef CONFIG_VIDEO_ADV_DEBUG
484 .vidioc_g_register = vidioc_g_register,
485 .vidioc_s_register = vidioc_s_register,
486#endif
487};
488
489struct video_device cx25821_videoioctl_template = {
490 .name = "cx25821-videoioctl",
491 .fops = &video_fops,
492 .minor = -1,
493 .ioctl_ops = &video_ioctl_ops,
494 .tvnorms = CX25821_NORMS,
495 .current_norm = V4L2_STD_NTSC_M,
496};
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c
new file mode 100644
index 000000000000..77b63b060405
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups10.c
@@ -0,0 +1,435 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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 /* 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,
46 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,
51 &dev->sram_channels[SRAM_CH10]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH10]
108 && h->video_dev[SRAM_CH10]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 9;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), 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,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO10))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO10)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
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 the risc engine and fifo
205 //cx_write(channel10->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO10)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO10);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO10)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO10);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
268 unsigned long arg)
269{
270 struct cx25821_fh *fh = file->private_data;
271 struct cx25821_dev *dev = fh->dev;
272 int command = 0;
273 struct upstream_user_struct *data_from_user;
274
275 data_from_user = (struct upstream_user_struct *)arg;
276
277 if (!data_from_user) {
278 printk
279 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
280 __func__);
281 return 0;
282 }
283
284 command = data_from_user->command;
285
286 if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
287 return 0;
288 }
289
290 dev->input_filename_ch2 = data_from_user->input_filename;
291 dev->input_audiofilename = data_from_user->input_filename;
292 dev->vid_stdname_ch2 = data_from_user->vid_stdname;
293 dev->pixel_format_ch2 = data_from_user->pixel_format;
294 dev->channel_select_ch2 = data_from_user->channel_select;
295 dev->command_ch2 = data_from_user->command;
296
297 switch (command) {
298 case UPSTREAM_START_VIDEO:
299 cx25821_start_upstream_video_ch2(dev, data_from_user);
300 break;
301
302 case UPSTREAM_STOP_VIDEO:
303 cx25821_stop_upstream_video_ch2(dev);
304 break;
305 }
306
307 return 0;
308}
309
310static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
311 struct v4l2_format *f)
312{
313 struct cx25821_fh *fh = priv;
314 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
315 int err;
316
317 if (fh) {
318 err = v4l2_prio_check(&dev->prio, &fh->prio);
319 if (0 != err)
320 return err;
321 }
322
323 dprintk(2, "%s()\n", __func__);
324 err = vidioc_try_fmt_vid_cap(file, priv, f);
325
326 if (0 != err)
327 return err;
328 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
329 fh->width = f->fmt.pix.width;
330 fh->height = f->fmt.pix.height;
331 fh->vidq.field = f->fmt.pix.field;
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343
344static int vidioc_log_status(struct file *file, void *priv)
345{
346 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
347 char name[32 + 2];
348
349 snprintf(name, sizeof(name), "%s/2", dev->name);
350 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
351 dev->name);
352 cx25821_call_all(dev, core, log_status);
353 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
354 dev->name);
355 return 0;
356}
357
358static int vidioc_s_ctrl(struct file *file, void *priv,
359 struct v4l2_control *ctl)
360{
361 struct cx25821_fh *fh = priv;
362 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
363 int err;
364
365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio);
367 if (0 != err)
368 return err;
369 }
370
371 return 0;
372}
373
374//exported stuff
375static const struct v4l2_file_operations video_fops = {
376 .owner = THIS_MODULE,
377 .open = video_open,
378 .release = video_release,
379 .read = video_read,
380 .poll = video_poll,
381 .mmap = video_mmap,
382 .ioctl = video_ioctl_upstream10,
383};
384
385static const struct v4l2_ioctl_ops video_ioctl_ops = {
386 .vidioc_querycap = vidioc_querycap,
387 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
388 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
389 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
391 .vidioc_reqbufs = vidioc_reqbufs,
392 .vidioc_querybuf = vidioc_querybuf,
393 .vidioc_qbuf = vidioc_qbuf,
394 .vidioc_dqbuf = vidioc_dqbuf,
395#ifdef TUNER_FLAG
396 .vidioc_s_std = vidioc_s_std,
397 .vidioc_querystd = vidioc_querystd,
398#endif
399 .vidioc_cropcap = vidioc_cropcap,
400 .vidioc_s_crop = vidioc_s_crop,
401 .vidioc_g_crop = vidioc_g_crop,
402 .vidioc_enum_input = vidioc_enum_input,
403 .vidioc_g_input = vidioc_g_input,
404 .vidioc_s_input = vidioc_s_input,
405 .vidioc_g_ctrl = vidioc_g_ctrl,
406 .vidioc_s_ctrl = vidioc_s_ctrl,
407 .vidioc_queryctrl = vidioc_queryctrl,
408 .vidioc_streamon = vidioc_streamon,
409 .vidioc_streamoff = vidioc_streamoff,
410 .vidioc_log_status = vidioc_log_status,
411 .vidioc_g_priority = vidioc_g_priority,
412 .vidioc_s_priority = vidioc_s_priority,
413#ifdef CONFIG_VIDEO_V4L1_COMPAT
414 .vidiocgmbuf = vidiocgmbuf,
415#endif
416#ifdef TUNER_FLAG
417 .vidioc_g_tuner = vidioc_g_tuner,
418 .vidioc_s_tuner = vidioc_s_tuner,
419 .vidioc_g_frequency = vidioc_g_frequency,
420 .vidioc_s_frequency = vidioc_s_frequency,
421#endif
422#ifdef CONFIG_VIDEO_ADV_DEBUG
423 .vidioc_g_register = vidioc_g_register,
424 .vidioc_s_register = vidioc_s_register,
425#endif
426};
427
428struct video_device cx25821_video_template10 = {
429 .name = "cx25821-upstream10",
430 .fops = &video_fops,
431 .minor = -1,
432 .ioctl_ops = &video_ioctl_ops,
433 .tvnorms = CX25821_NORMS,
434 .current_norm = V4L2_STD_NTSC_M,
435};
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c
new file mode 100644
index 000000000000..75c8c1eed2da
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups9.c
@@ -0,0 +1,433 @@
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
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 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,
46 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,
51 &dev->sram_channels[SRAM_CH09]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH09]
108 && h->video_dev[SRAM_CH09]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 8;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), 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,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO9))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO9)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
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 the risc engine and fifo
205 //cx_write(channel9->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO9)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO9);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO9)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO9);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
268 unsigned long arg)
269{
270 struct cx25821_fh *fh = file->private_data;
271 struct cx25821_dev *dev = fh->dev;
272 int command = 0;
273 struct upstream_user_struct *data_from_user;
274
275 data_from_user = (struct upstream_user_struct *)arg;
276
277 if (!data_from_user) {
278 printk
279 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
280 __func__);
281 return 0;
282 }
283
284 command = data_from_user->command;
285
286 if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
287 return 0;
288 }
289
290 dev->input_filename = data_from_user->input_filename;
291 dev->input_audiofilename = data_from_user->input_filename;
292 dev->vid_stdname = data_from_user->vid_stdname;
293 dev->pixel_format = data_from_user->pixel_format;
294 dev->channel_select = data_from_user->channel_select;
295 dev->command = data_from_user->command;
296
297 switch (command) {
298 case UPSTREAM_START_VIDEO:
299 cx25821_start_upstream_video_ch1(dev, data_from_user);
300 break;
301
302 case UPSTREAM_STOP_VIDEO:
303 cx25821_stop_upstream_video_ch1(dev);
304 break;
305 }
306
307 return 0;
308}
309
310static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
311 struct v4l2_format *f)
312{
313 struct cx25821_fh *fh = priv;
314 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
315 int err;
316
317 if (fh) {
318 err = v4l2_prio_check(&dev->prio, &fh->prio);
319 if (0 != err)
320 return err;
321 }
322
323 dprintk(2, "%s()\n", __func__);
324 err = vidioc_try_fmt_vid_cap(file, priv, f);
325
326 if (0 != err)
327 return err;
328 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
329 fh->width = f->fmt.pix.width;
330 fh->height = f->fmt.pix.height;
331 fh->vidq.field = f->fmt.pix.field;
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343static int vidioc_log_status(struct file *file, void *priv)
344{
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346 char name[32 + 2];
347
348 snprintf(name, sizeof(name), "%s/2", dev->name);
349 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
350 dev->name);
351 cx25821_call_all(dev, core, log_status);
352 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
353 dev->name);
354 return 0;
355}
356
357static int vidioc_s_ctrl(struct file *file, void *priv,
358 struct v4l2_control *ctl)
359{
360 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
361 struct cx25821_fh *fh = priv;
362 int err;
363 if (fh) {
364 err = v4l2_prio_check(&dev->prio, &fh->prio);
365 if (0 != err)
366 return err;
367 }
368
369 return 0;
370}
371
372// exported stuff
373static const struct v4l2_file_operations video_fops = {
374 .owner = THIS_MODULE,
375 .open = video_open,
376 .release = video_release,
377 .read = video_read,
378 .poll = video_poll,
379 .mmap = video_mmap,
380 .ioctl = video_ioctl_upstream9,
381};
382
383static const struct v4l2_ioctl_ops video_ioctl_ops = {
384 .vidioc_querycap = vidioc_querycap,
385 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
386 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
387 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
388 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
389 .vidioc_reqbufs = vidioc_reqbufs,
390 .vidioc_querybuf = vidioc_querybuf,
391 .vidioc_qbuf = vidioc_qbuf,
392 .vidioc_dqbuf = vidioc_dqbuf,
393#ifdef TUNER_FLAG
394 .vidioc_s_std = vidioc_s_std,
395 .vidioc_querystd = vidioc_querystd,
396#endif
397 .vidioc_cropcap = vidioc_cropcap,
398 .vidioc_s_crop = vidioc_s_crop,
399 .vidioc_g_crop = vidioc_g_crop,
400 .vidioc_enum_input = vidioc_enum_input,
401 .vidioc_g_input = vidioc_g_input,
402 .vidioc_s_input = vidioc_s_input,
403 .vidioc_g_ctrl = vidioc_g_ctrl,
404 .vidioc_s_ctrl = vidioc_s_ctrl,
405 .vidioc_queryctrl = vidioc_queryctrl,
406 .vidioc_streamon = vidioc_streamon,
407 .vidioc_streamoff = vidioc_streamoff,
408 .vidioc_log_status = vidioc_log_status,
409 .vidioc_g_priority = vidioc_g_priority,
410 .vidioc_s_priority = vidioc_s_priority,
411#ifdef CONFIG_VIDEO_V4L1_COMPAT
412 .vidiocgmbuf = vidiocgmbuf,
413#endif
414#ifdef TUNER_FLAG
415 .vidioc_g_tuner = vidioc_g_tuner,
416 .vidioc_s_tuner = vidioc_s_tuner,
417 .vidioc_g_frequency = vidioc_g_frequency,
418 .vidioc_s_frequency = vidioc_s_frequency,
419#endif
420#ifdef CONFIG_VIDEO_ADV_DEBUG
421 .vidioc_g_register = vidioc_g_register,
422 .vidioc_s_register = vidioc_s_register,
423#endif
424};
425
426struct video_device cx25821_video_template9 = {
427 .name = "cx25821-upstream9",
428 .fops = &video_fops,
429 .minor = -1,
430 .ioctl_ops = &video_ioctl_ops,
431 .tvnorms = CX25821_NORMS,
432 .current_norm = V4L2_STD_NTSC_M,
433};
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
new file mode 100644
index 000000000000..cf2286d83b6a
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821.h
@@ -0,0 +1,602 @@
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_H_
25#define CX25821_H_
26
27#include <linux/pci.h>
28#include <linux/i2c.h>
29#include <linux/i2c-algo-bit.h>
30#include <linux/interrupt.h>
31#include <linux/delay.h>
32#include <linux/sched.h>
33#include <linux/kdev_t.h>
34#include <linux/smp_lock.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#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
88
89#define UNKNOWN_BOARD 0
90#define CX25821_BOARD 1
91
92/* Currently supported by the driver */
93#define CX25821_NORMS (\
94 V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \
95 V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
96 V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_H | \
97 V4L2_STD_PAL_Nc )
98
99#define CX25821_BOARD_CONEXANT_ATHENA10 1
100#define MAX_VID_CHANNEL_NUM 12
101#define VID_CHANNEL_NUM 8
102
103struct cx25821_fmt {
104 char *name;
105 u32 fourcc; /* v4l2 format id */
106 int depth;
107 int flags;
108 u32 cxformat;
109};
110
111struct cx25821_ctrl {
112 struct v4l2_queryctrl v;
113 u32 off;
114 u32 reg;
115 u32 mask;
116 u32 shift;
117};
118
119struct cx25821_tvnorm {
120 char *name;
121 v4l2_std_id id;
122 u32 cxiformat;
123 u32 cxoformat;
124};
125
126struct cx25821_fh {
127 struct cx25821_dev *dev;
128 enum v4l2_buf_type type;
129 int radio;
130 u32 resources;
131
132 enum v4l2_priority prio;
133
134 /* video overlay */
135 struct v4l2_window win;
136 struct v4l2_clip *clips;
137 unsigned int nclips;
138
139 /* video capture */
140 struct cx25821_fmt *fmt;
141 unsigned int width, height;
142
143 /* vbi capture */
144 struct videobuf_queue vidq;
145 struct videobuf_queue vbiq;
146
147 /* H264 Encoder specifics ONLY */
148 struct videobuf_queue mpegq;
149 atomic_t v4l_reading;
150};
151
152enum cx25821_itype {
153 CX25821_VMUX_COMPOSITE = 1,
154 CX25821_VMUX_SVIDEO,
155 CX25821_VMUX_DEBUG,
156 CX25821_RADIO,
157};
158
159enum cx25821_src_sel_type {
160 CX25821_SRC_SEL_EXT_656_VIDEO = 0,
161 CX25821_SRC_SEL_PARALLEL_MPEG_VIDEO
162};
163
164/* buffer for one video frame */
165struct cx25821_buffer {
166 /* common v4l buffer stuff -- must be first */
167 struct videobuf_buffer vb;
168
169 /* cx25821 specific */
170 unsigned int bpl;
171 struct btcx_riscmem risc;
172 struct cx25821_fmt *fmt;
173 u32 count;
174};
175
176struct cx25821_input {
177 enum cx25821_itype type;
178 unsigned int vmux;
179 u32 gpio0, gpio1, gpio2, gpio3;
180};
181
182typedef enum {
183 CX25821_UNDEFINED = 0,
184 CX25821_RAW,
185 CX25821_264
186} port_t;
187
188struct cx25821_board {
189 char *name;
190 port_t porta, portb, portc;
191 unsigned int tuner_type;
192 unsigned int radio_type;
193 unsigned char tuner_addr;
194 unsigned char radio_addr;
195
196 u32 clk_freq;
197 struct cx25821_input input[2];
198};
199
200struct cx25821_subid {
201 u16 subvendor;
202 u16 subdevice;
203 u32 card;
204};
205
206struct cx25821_i2c {
207 struct cx25821_dev *dev;
208
209 int nr;
210
211 /* i2c i/o */
212 struct i2c_adapter i2c_adap;
213 struct i2c_algo_bit_data i2c_algo;
214 struct i2c_client i2c_client;
215 u32 i2c_rc;
216
217 /* cx25821 registers used for raw addess */
218 u32 i2c_period;
219 u32 reg_ctrl;
220 u32 reg_stat;
221 u32 reg_addr;
222 u32 reg_rdata;
223 u32 reg_wdata;
224};
225
226struct cx25821_dmaqueue {
227 struct list_head active;
228 struct list_head queued;
229 struct timer_list timeout;
230 struct btcx_riscmem stopper;
231 u32 count;
232};
233
234struct cx25821_data {
235 struct cx25821_dev *dev;
236 struct sram_channel *channel;
237};
238
239struct cx25821_dev {
240 struct list_head devlist;
241 atomic_t refcount;
242 struct v4l2_device v4l2_dev;
243
244 struct v4l2_prio_state prio;
245
246 /* pci stuff */
247 struct pci_dev *pci;
248 unsigned char pci_rev, pci_lat;
249 int pci_bus, pci_slot;
250 u32 base_io_addr;
251 u32 __iomem *lmmio;
252 u8 __iomem *bmmio;
253 int pci_irqmask;
254 int hwrevision;
255
256 u32 clk_freq;
257
258 /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
259 struct cx25821_i2c i2c_bus[3];
260
261 int nr;
262 struct mutex lock;
263
264 /* board details */
265 unsigned int board;
266 char name[32];
267
268 /* sram configuration */
269 struct sram_channel *sram_channels;
270
271 /* Analog video */
272 u32 resources;
273 unsigned int input;
274 u32 tvaudio;
275 v4l2_std_id tvnorm;
276 unsigned int tuner_type;
277 unsigned char tuner_addr;
278 unsigned int radio_type;
279 unsigned char radio_addr;
280 unsigned int has_radio;
281 unsigned int videc_type;
282 unsigned char videc_addr;
283 unsigned short _max_num_decoders;
284
285 int ctl_bright;
286 int ctl_contrast;
287 int ctl_hue;
288 int ctl_saturation;
289
290 struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
291
292 /* Analog Audio Upstream */
293 int _audio_is_running;
294 int _audiopixel_format;
295 int _is_first_audio_frame;
296 int _audiofile_status;
297 int _audio_lines_count;
298 int _audioframe_count;
299 int _audio_upstream_channel_select;
300 int _last_index_irq; //The last interrupt index processed.
301
302 __le32 *_risc_audio_jmp_addr;
303 __le32 *_risc_virt_start_addr;
304 __le32 *_risc_virt_addr;
305 dma_addr_t _risc_phys_addr;
306 dma_addr_t _risc_phys_start_addr;
307
308 unsigned int _audiorisc_size;
309 unsigned int _audiodata_buf_size;
310 __le32 *_audiodata_buf_virt_addr;
311 dma_addr_t _audiodata_buf_phys_addr;
312 char *_audiofilename;
313
314 /* V4l */
315 u32 freq;
316 struct video_device *video_dev[MAX_VID_CHANNEL_NUM];
317 struct video_device *vbi_dev;
318 struct video_device *radio_dev;
319 struct video_device *ioctl_dev;
320
321 struct cx25821_dmaqueue vidq[MAX_VID_CHANNEL_NUM];
322 spinlock_t slock;
323
324 /* Video Upstream */
325 int _line_size;
326 int _prog_cnt;
327 int _pixel_format;
328 int _is_first_frame;
329 int _is_running;
330 int _file_status;
331 int _lines_count;
332 int _frame_count;
333 int _channel_upstream_select;
334 unsigned int _risc_size;
335
336 __le32 *_dma_virt_start_addr;
337 __le32 *_dma_virt_addr;
338 dma_addr_t _dma_phys_addr;
339 dma_addr_t _dma_phys_start_addr;
340
341 unsigned int _data_buf_size;
342 __le32 *_data_buf_virt_addr;
343 dma_addr_t _data_buf_phys_addr;
344 char *_filename;
345 char *_defaultname;
346
347 int _line_size_ch2;
348 int _prog_cnt_ch2;
349 int _pixel_format_ch2;
350 int _is_first_frame_ch2;
351 int _is_running_ch2;
352 int _file_status_ch2;
353 int _lines_count_ch2;
354 int _frame_count_ch2;
355 int _channel2_upstream_select;
356 unsigned int _risc_size_ch2;
357
358 __le32 *_dma_virt_start_addr_ch2;
359 __le32 *_dma_virt_addr_ch2;
360 dma_addr_t _dma_phys_addr_ch2;
361 dma_addr_t _dma_phys_start_addr_ch2;
362
363 unsigned int _data_buf_size_ch2;
364 __le32 *_data_buf_virt_addr_ch2;
365 dma_addr_t _data_buf_phys_addr_ch2;
366 char *_filename_ch2;
367 char *_defaultname_ch2;
368
369 /* MPEG Encoder ONLY settings */
370 u32 cx23417_mailbox;
371 struct cx2341x_mpeg_params mpeg_params;
372 struct video_device *v4l_device;
373 atomic_t v4l_reader_count;
374 struct cx25821_tvnorm encodernorm;
375
376 u32 upstream_riscbuf_size;
377 u32 upstream_databuf_size;
378 u32 upstream_riscbuf_size_ch2;
379 u32 upstream_databuf_size_ch2;
380 u32 audio_upstream_riscbuf_size;
381 u32 audio_upstream_databuf_size;
382 int _isNTSC;
383 int _frame_index;
384 int _audioframe_index;
385 struct workqueue_struct *_irq_queues;
386 struct work_struct _irq_work_entry;
387 struct workqueue_struct *_irq_queues_ch2;
388 struct work_struct _irq_work_entry_ch2;
389 struct workqueue_struct *_irq_audio_queues;
390 struct work_struct _audio_work_entry;
391 char *input_filename;
392 char *input_filename_ch2;
393 int _frame_index_ch2;
394 int _isNTSC_ch2;
395 char *vid_stdname_ch2;
396 int pixel_format_ch2;
397 int channel_select_ch2;
398 int command_ch2;
399 char *input_audiofilename;
400 char *vid_stdname;
401 int pixel_format;
402 int channel_select;
403 int command;
404 int pixel_formats[VID_CHANNEL_NUM];
405 int use_cif_resolution[VID_CHANNEL_NUM];
406 int cif_width[VID_CHANNEL_NUM];
407 int channel_opened;
408};
409
410struct upstream_user_struct {
411 char *input_filename;
412 char *vid_stdname;
413 int pixel_format;
414 int channel_select;
415 int command;
416};
417
418struct downstream_user_struct {
419 char *vid_stdname;
420 int pixel_format;
421 int cif_resolution_enable;
422 int cif_width;
423 int decoder_select;
424 int command;
425 int reg_address;
426 int reg_data;
427};
428
429extern struct upstream_user_struct *up_data;
430
431static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)
432{
433 return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev);
434}
435
436#define cx25821_call_all(dev, o, f, args...) \
437 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
438
439extern struct list_head cx25821_devlist;
440extern struct cx25821_board cx25821_boards[];
441extern struct cx25821_subid cx25821_subids[];
442
443#define SRAM_CH00 0 /* Video A */
444#define SRAM_CH01 1 /* Video B */
445#define SRAM_CH02 2 /* Video C */
446#define SRAM_CH03 3 /* Video D */
447#define SRAM_CH04 4 /* Video E */
448#define SRAM_CH05 5 /* Video F */
449#define SRAM_CH06 6 /* Video G */
450#define SRAM_CH07 7 /* Video H */
451
452#define SRAM_CH08 8 /* Audio A */
453#define SRAM_CH09 9 /* Video Upstream I */
454#define SRAM_CH10 10 /* Video Upstream J */
455#define SRAM_CH11 11 /* Audio Upstream AUD_CHANNEL_B */
456
457#define VID_UPSTREAM_SRAM_CHANNEL_I SRAM_CH09
458#define VID_UPSTREAM_SRAM_CHANNEL_J SRAM_CH10
459#define AUDIO_UPSTREAM_SRAM_CHANNEL_B SRAM_CH11
460#define VIDEO_IOCTL_CH 11
461
462struct sram_channel {
463 char *name;
464 u32 i;
465 u32 cmds_start;
466 u32 ctrl_start;
467 u32 cdt;
468 u32 fifo_start;
469 u32 fifo_size;
470 u32 ptr1_reg;
471 u32 ptr2_reg;
472 u32 cnt1_reg;
473 u32 cnt2_reg;
474 u32 int_msk;
475 u32 int_stat;
476 u32 int_mstat;
477 u32 dma_ctl;
478 u32 gpcnt_ctl;
479 u32 gpcnt;
480 u32 aud_length;
481 u32 aud_cfg;
482 u32 fld_aud_fifo_en;
483 u32 fld_aud_risc_en;
484
485 //For Upstream Video
486 u32 vid_fmt_ctl;
487 u32 vid_active_ctl1;
488 u32 vid_active_ctl2;
489 u32 vid_cdt_size;
490
491 u32 vip_ctl;
492 u32 pix_frmt;
493 u32 jumponly;
494 u32 irq_bit;
495};
496extern struct sram_channel cx25821_sram_channels[];
497
498#define STATUS_SUCCESS 0
499#define STATUS_UNSUCCESSFUL -1
500
501#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
502#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2))
503
504#define cx_andor(reg, mask, value) \
505 writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
506 ((value) & (mask)), dev->lmmio+((reg)>>2))
507
508#define cx_set(reg, bit) cx_andor((reg), (bit), (bit))
509#define cx_clear(reg, bit) cx_andor((reg), (bit), 0)
510
511#define Set_GPIO_Bit(Bit) (1 << Bit)
512#define Clear_GPIO_Bit(Bit) (~(1 << Bit))
513
514#define CX25821_ERR(fmt, args...) printk(KERN_ERR "cx25821(%d): " fmt, dev->board, ## args)
515#define CX25821_WARN(fmt, args...) printk(KERN_WARNING "cx25821(%d): " fmt, dev->board , ## args)
516#define CX25821_INFO(fmt, args...) printk(KERN_INFO "cx25821(%d): " fmt, dev->board , ## args)
517
518extern int cx25821_i2c_register(struct cx25821_i2c *bus);
519extern void cx25821_card_setup(struct cx25821_dev *dev);
520extern int cx25821_ir_init(struct cx25821_dev *dev);
521extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value);
522extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value);
523extern int cx25821_i2c_unregister(struct cx25821_i2c *bus);
524extern void cx25821_gpio_init(struct cx25821_dev *dev);
525extern void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
526 int pin_number, int pin_logic_value);
527
528extern int medusa_video_init(struct cx25821_dev *dev);
529extern int medusa_set_videostandard(struct cx25821_dev *dev);
530extern void medusa_set_resolution(struct cx25821_dev *dev, int width,
531 int decoder_select);
532extern int medusa_set_brightness(struct cx25821_dev *dev, int brightness,
533 int decoder);
534extern int medusa_set_contrast(struct cx25821_dev *dev, int contrast,
535 int decoder);
536extern int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder);
537extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation,
538 int decoder);
539
540extern int cx25821_sram_channel_setup(struct cx25821_dev *dev,
541 struct sram_channel *ch, unsigned int bpl,
542 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, unsigned int lines);
550extern int cx25821_risc_databuffer_audio(struct pci_dev *pci,
551 struct btcx_riscmem *risc,
552 struct scatterlist *sglist,
553 unsigned int bpl,
554 unsigned int lines, unsigned int lpi);
555extern void cx25821_free_buffer(struct videobuf_queue *q,
556 struct cx25821_buffer *buf);
557extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
558 u32 reg, u32 mask, u32 value);
559extern void cx25821_sram_channel_dump(struct cx25821_dev *dev,
560 struct sram_channel *ch);
561extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
562 struct sram_channel *ch);
563
564extern struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci);
565extern void cx25821_print_irqbits(char *name, char *tag, char **strings,
566 int len, u32 bits, u32 mask);
567extern void cx25821_dev_unregister(struct cx25821_dev *dev);
568extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
569 struct sram_channel *ch,
570 unsigned int bpl, u32 risc);
571
572extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev,
573 int channel_select, int pixel_format);
574extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev,
575 int channel_select, int pixel_format);
576extern int cx25821_audio_upstream_init(struct cx25821_dev *dev,
577 int channel_select);
578extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev);
579extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev);
580extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev);
581extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
582 struct upstream_user_struct
583 *up_data);
584extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
585 struct upstream_user_struct
586 *up_data);
587extern void cx25821_start_upstream_audio(struct cx25821_dev *dev,
588 struct upstream_user_struct *up_data);
589extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev);
590extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev);
591extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev);
592extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
593 struct sram_channel *ch,
594 unsigned int bpl, u32 risc);
595extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel,
596 u32 format);
597extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev);
598extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
599 struct pci_dev *pci,
600 struct video_device *template,
601 char *type);
602#endif
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index ca6ade6c4b47..e47f683a323e 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -1,5 +1,5 @@
1config VIDEO_GO7007 1config VIDEO_GO7007
2 tristate "Go 7007 support" 2 tristate "WIS GO7007 MPEG encoder support"
3 depends on VIDEO_DEV && PCI && I2C && INPUT 3 depends on VIDEO_DEV && PCI && I2C && INPUT
4 depends on SND 4 depends on SND
5 select VIDEOBUF_DMA_SG 5 select VIDEOBUF_DMA_SG
@@ -10,17 +10,19 @@ config VIDEO_GO7007
10 select CRC32 10 select CRC32
11 default N 11 default N
12 ---help--- 12 ---help---
13 This is a video4linux driver for some weird device... 13 This is a video4linux driver for the WIS GO7007 MPEG
14 encoder chip.
14 15
15 To compile this driver as a module, choose M here: the 16 To compile this driver as a module, choose M here: the
16 module will be called go7007 17 module will be called go7007
17 18
18config VIDEO_GO7007_USB 19config VIDEO_GO7007_USB
19 tristate "Go 7007 USB support" 20 tristate "WIS GO7007 USB support"
20 depends on VIDEO_GO7007 && USB 21 depends on VIDEO_GO7007 && USB
21 default N 22 default N
22 ---help--- 23 ---help---
23 This is a video4linux driver for some weird device... 24 This is a video4linux driver for the WIS GO7007 MPEG
25 encoder chip over USB.
24 26
25 To compile this driver as a module, choose M here: the 27 To compile this driver as a module, choose M here: the
26 module will be called go7007-usb 28 module will be called go7007-usb
@@ -30,8 +32,78 @@ config VIDEO_GO7007_USB_S2250_BOARD
30 depends on VIDEO_GO7007_USB && DVB_USB 32 depends on VIDEO_GO7007_USB && DVB_USB
31 default N 33 default N
32 ---help--- 34 ---help---
33 This is a video4linux driver for the Sensoray 2250/2251 device 35 This is a video4linux driver for the Sensoray 2250/2251 device.
34 36
35 To compile this driver as a module, choose M here: the 37 To compile this driver as a module, choose M here: the
36 module will be called s2250-board 38 module will be called s2250
39
40config VIDEO_GO7007_OV7640
41 tristate "OV7640 subdev support"
42 depends on VIDEO_GO7007
43 default N
44 ---help---
45 This is a video4linux driver for the OV7640 sub-device.
46
47 To compile this driver as a module, choose M here: the
48 module will be called wis-ov7640
49
50config VIDEO_GO7007_SAA7113
51 tristate "SAA7113 subdev support"
52 depends on VIDEO_GO7007
53 default N
54 ---help---
55 This is a video4linux driver for the SAA7113 sub-device.
56
57 To compile this driver as a module, choose M here: the
58 module will be called wis-saa7113
59
60config VIDEO_GO7007_SAA7115
61 tristate "SAA7115 subdev support"
62 depends on VIDEO_GO7007
63 default N
64 ---help---
65 This is a video4linux driver for the SAA7115 sub-device.
66
67 To compile this driver as a module, choose M here: the
68 module will be called wis-saa7115
69
70config VIDEO_GO7007_TW9903
71 tristate "TW9903 subdev support"
72 depends on VIDEO_GO7007
73 default N
74 ---help---
75 This is a video4linux driver for the TW9903 sub-device.
76
77 To compile this driver as a module, choose M here: the
78 module will be called wis-tw9903
79
80config VIDEO_GO7007_UDA1342
81 tristate "UDA1342 subdev support"
82 depends on VIDEO_GO7007
83 default N
84 ---help---
85 This is a video4linux driver for the UDA1342 sub-device.
86
87 To compile this driver as a module, choose M here: the
88 module will be called wis-uda1342
89
90config VIDEO_GO7007_SONY_TUNER
91 tristate "Sony tuner subdev support"
92 depends on VIDEO_GO7007
93 default N
94 ---help---
95 This is a video4linux driver for the Sony Tuner sub-device.
96
97 To compile this driver as a module, choose M here: the
98 module will be called wis-sony-tuner
99
100config VIDEO_GO7007_TW2804
101 tristate "TW2804 subdev support"
102 depends on VIDEO_GO7007
103 default N
104 ---help---
105 This is a video4linux driver for the TW2804 sub-device.
106
107 To compile this driver as a module, choose M here: the
108 module will be called wis-tw2804
37 109
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
index e514b4af6d06..d14ea84a01f6 100644
--- a/drivers/staging/go7007/Makefile
+++ b/drivers/staging/go7007/Makefile
@@ -6,22 +6,34 @@
6obj-$(CONFIG_VIDEO_GO7007) += go7007.o 6obj-$(CONFIG_VIDEO_GO7007) += go7007.o
7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o 7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o 8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o
9obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o
10obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o
11obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o
12obj-$(CONFIG_VIDEO_GO7007_TW9903) += wis-tw9903.o
13obj-$(CONFIG_VIDEO_GO7007_UDA1342) += wis-uda1342.o
14obj-$(CONFIG_VIDEO_GO7007_SONY_TUNER) += wis-sony-tuner.o
15obj-$(CONFIG_VIDEO_GO7007_TW2804) += wis-tw2804.o
9 16
10go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \ 17go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
11 snd-go7007.o wis-saa7113.o 18 snd-go7007.o
12 19
13s2250-objs += s2250-board.o s2250-loader.o 20s2250-objs += s2250-board.o s2250-loader.o
14 21
15# Uncompile when the saa7134 patches get into upstream 22# Uncomment when the saa7134 patches get into upstream
16#ifneq ($(CONFIG_VIDEO_SAA7134),) 23#ifneq ($(CONFIG_VIDEO_SAA7134),)
17#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o 24#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
18#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 25#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
19#endif 26#endif
20 27
28# S2250 needs cypress ezusb loader from dvb-usb
21ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),) 29ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),)
22EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb 30EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb
23endif 31endif
24 32
25EXTRA_CFLAGS += -Idrivers/staging/saa7134
26EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 33EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
27EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 34EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
35
36# Ubuntu 8.04 has CONFIG_SND undefined, so include lum sound/config.h too
37ifeq ($(CONFIG_SND),)
38EXTRA_CFLAGS += -include sound/config.h
39endif
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index 77b1e769ac92..472f4bb08fdc 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -27,7 +27,7 @@
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/firmware.h> 29#include <linux/firmware.h>
30#include <linux/semaphore.h> 30#include <linux/mutex.h>
31#include <linux/uaccess.h> 31#include <linux/uaccess.h>
32#include <asm/system.h> 32#include <asm/system.h>
33#include <linux/videodev2.h> 33#include <linux/videodev2.h>
@@ -49,7 +49,7 @@ int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
49 go->hpi_ops->read_interrupt(go); 49 go->hpi_ops->read_interrupt(go);
50 if (wait_event_timeout(go->interrupt_waitq, 50 if (wait_event_timeout(go->interrupt_waitq,
51 go->interrupt_available, 5*HZ) < 0) { 51 go->interrupt_available, 5*HZ) < 0) {
52 printk(KERN_ERR "go7007: timeout waiting for read interrupt\n"); 52 v4l2_err(go->video_dev, "timeout waiting for read interrupt\n");
53 return -1; 53 return -1;
54 } 54 }
55 if (!go->interrupt_available) 55 if (!go->interrupt_available)
@@ -97,13 +97,12 @@ static int go7007_load_encoder(struct go7007 *go)
97 u16 intr_val, intr_data; 97 u16 intr_val, intr_data;
98 98
99 if (request_firmware(&fw_entry, fw_name, go->dev)) { 99 if (request_firmware(&fw_entry, fw_name, go->dev)) {
100 printk(KERN_ERR 100 v4l2_err(go, "unable to load firmware from file "
101 "go7007: unable to load firmware from file \"%s\"\n", 101 "\"%s\"\n", fw_name);
102 fw_name);
103 return -1; 102 return -1;
104 } 103 }
105 if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { 104 if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
106 printk(KERN_ERR "go7007: file \"%s\" does not appear to be " 105 v4l2_err(go, "file \"%s\" does not appear to be "
107 "go7007 firmware\n", fw_name); 106 "go7007 firmware\n", fw_name);
108 release_firmware(fw_entry); 107 release_firmware(fw_entry);
109 return -1; 108 return -1;
@@ -111,7 +110,7 @@ static int go7007_load_encoder(struct go7007 *go)
111 fw_len = fw_entry->size - 16; 110 fw_len = fw_entry->size - 16;
112 bounce = kmalloc(fw_len, GFP_KERNEL); 111 bounce = kmalloc(fw_len, GFP_KERNEL);
113 if (bounce == NULL) { 112 if (bounce == NULL) {
114 printk(KERN_ERR "go7007: unable to allocate %d bytes for " 113 v4l2_err(go, "unable to allocate %d bytes for "
115 "firmware transfer\n", fw_len); 114 "firmware transfer\n", fw_len);
116 release_firmware(fw_entry); 115 release_firmware(fw_entry);
117 return -1; 116 return -1;
@@ -122,7 +121,7 @@ static int go7007_load_encoder(struct go7007 *go)
122 go7007_send_firmware(go, bounce, fw_len) < 0 || 121 go7007_send_firmware(go, bounce, fw_len) < 0 ||
123 go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || 122 go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
124 (intr_val & ~0x1) != 0x5a5a) { 123 (intr_val & ~0x1) != 0x5a5a) {
125 printk(KERN_ERR "go7007: error transferring firmware\n"); 124 v4l2_err(go, "error transferring firmware\n");
126 rv = -1; 125 rv = -1;
127 } 126 }
128 kfree(bounce); 127 kfree(bounce);
@@ -140,9 +139,9 @@ int go7007_boot_encoder(struct go7007 *go, int init_i2c)
140{ 139{
141 int ret; 140 int ret;
142 141
143 down(&go->hw_lock); 142 mutex_lock(&go->hw_lock);
144 ret = go7007_load_encoder(go); 143 ret = go7007_load_encoder(go);
145 up(&go->hw_lock); 144 mutex_unlock(&go->hw_lock);
146 if (ret < 0) 145 if (ret < 0)
147 return -1; 146 return -1;
148 if (!init_i2c) 147 if (!init_i2c)
@@ -257,9 +256,9 @@ int go7007_register_encoder(struct go7007 *go)
257 256
258 printk(KERN_INFO "go7007: registering new %s\n", go->name); 257 printk(KERN_INFO "go7007: registering new %s\n", go->name);
259 258
260 down(&go->hw_lock); 259 mutex_lock(&go->hw_lock);
261 ret = go7007_init_encoder(go); 260 ret = go7007_init_encoder(go);
262 up(&go->hw_lock); 261 mutex_unlock(&go->hw_lock);
263 if (ret < 0) 262 if (ret < 0)
264 return -1; 263 return -1;
265 264
@@ -316,7 +315,7 @@ int go7007_start_encoder(struct go7007 *go)
316 315
317 if (go7007_send_firmware(go, fw, fw_len) < 0 || 316 if (go7007_send_firmware(go, fw, fw_len) < 0 ||
318 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) { 317 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
319 printk(KERN_ERR "go7007: error transferring firmware\n"); 318 v4l2_err(go->video_dev, "error transferring firmware\n");
320 rv = -1; 319 rv = -1;
321 goto start_error; 320 goto start_error;
322 } 321 }
@@ -325,7 +324,7 @@ int go7007_start_encoder(struct go7007 *go)
325 go->parse_length = 0; 324 go->parse_length = 0;
326 go->seen_frame = 0; 325 go->seen_frame = 0;
327 if (go7007_stream_start(go) < 0) { 326 if (go7007_stream_start(go) < 0) {
328 printk(KERN_ERR "go7007: error starting stream transfer\n"); 327 v4l2_err(go->video_dev, "error starting stream transfer\n");
329 rv = -1; 328 rv = -1;
330 goto start_error; 329 goto start_error;
331 } 330 }
@@ -421,7 +420,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
421 for (i = 0; i < length; ++i) { 420 for (i = 0; i < length; ++i) {
422 if (go->active_buf != NULL && 421 if (go->active_buf != NULL &&
423 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) { 422 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
424 printk(KERN_DEBUG "go7007: dropping oversized frame\n"); 423 v4l2_info(go->video_dev, "dropping oversized frame\n");
425 go->active_buf->offset -= go->active_buf->bytesused; 424 go->active_buf->offset -= go->active_buf->bytesused;
426 go->active_buf->bytesused = 0; 425 go->active_buf->bytesused = 0;
427 go->active_buf->modet_active = 0; 426 go->active_buf->modet_active = 0;
@@ -604,7 +603,7 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
604 go->tuner_type = -1; 603 go->tuner_type = -1;
605 go->channel_number = 0; 604 go->channel_number = 0;
606 go->name[0] = 0; 605 go->name[0] = 0;
607 init_MUTEX(&go->hw_lock); 606 mutex_init(&go->hw_lock);
608 init_waitqueue_head(&go->frame_waitq); 607 init_waitqueue_head(&go->frame_waitq);
609 spin_lock_init(&go->spinlock); 608 spin_lock_init(&go->spinlock);
610 go->video_dev = NULL; 609 go->video_dev = NULL;
@@ -669,8 +668,8 @@ void go7007_remove(struct go7007 *go)
669 if (i2c_del_adapter(&go->i2c_adapter) == 0) 668 if (i2c_del_adapter(&go->i2c_adapter) == 0)
670 go->i2c_adapter_online = 0; 669 go->i2c_adapter_online = 0;
671 else 670 else
672 printk(KERN_ERR 671 v4l2_err(go->video_dev,
673 "go7007: error removing I2C adapter!\n"); 672 "error removing I2C adapter!\n");
674 } 673 }
675 674
676 if (go->audio_enabled) 675 if (go->audio_enabled)
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c
index 871ed43e4e05..a8bb264e0074 100644
--- a/drivers/staging/go7007/go7007-fw.c
+++ b/drivers/staging/go7007/go7007-fw.c
@@ -1034,7 +1034,8 @@ static int brctrl_to_package(struct go7007 *go,
1034 0xBF1B, framelen[7], 1034 0xBF1B, framelen[7],
1035 0, 0, 1035 0, 0,
1036 1036
1037#if 0 /* Remove once we don't care about matching */ 1037#if 0
1038 /* Remove once we don't care about matching */
1038 0x200e, 0x0000, 1039 0x200e, 0x0000,
1039 0xBF56, 4, 1040 0xBF56, 4,
1040 0xBF57, 0, 1041 0xBF57, 0,
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
index c82867fdd28d..b8cfa1a6eaeb 100644
--- a/drivers/staging/go7007/go7007-i2c.c
+++ b/drivers/staging/go7007/go7007-i2c.c
@@ -24,7 +24,7 @@
24#include <linux/time.h> 24#include <linux/time.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/semaphore.h> 27#include <linux/mutex.h>
28#include <linux/uaccess.h> 28#include <linux/uaccess.h>
29#include <asm/system.h> 29#include <asm/system.h>
30 30
@@ -48,7 +48,7 @@
48 48
49/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs 49/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
50 * on the Adlink PCI-MPG24, so access is shared between all of them. */ 50 * on the Adlink PCI-MPG24, so access is shared between all of them. */
51static DECLARE_MUTEX(adlink_mpg24_i2c_lock); 51static DEFINE_MUTEX(adlink_mpg24_i2c_lock);
52 52
53static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read, 53static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
54 u16 command, int flags, u8 *data) 54 u16 command, int flags, u8 *data)
@@ -69,11 +69,11 @@ static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
69 *data, command, addr); 69 *data, command, addr);
70#endif 70#endif
71 71
72 down(&go->hw_lock); 72 mutex_lock(&go->hw_lock);
73 73
74 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) { 74 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
75 /* Bridge the I2C port on this GO7007 to the shared bus */ 75 /* Bridge the I2C port on this GO7007 to the shared bus */
76 down(&adlink_mpg24_i2c_lock); 76 mutex_lock(&adlink_mpg24_i2c_lock);
77 go7007_write_addr(go, 0x3c82, 0x0020); 77 go7007_write_addr(go, 0x3c82, 0x0020);
78 } 78 }
79 79
@@ -134,9 +134,9 @@ i2c_done:
134 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) { 134 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
135 /* Isolate the I2C port on this GO7007 from the shared bus */ 135 /* Isolate the I2C port on this GO7007 from the shared bus */
136 go7007_write_addr(go, 0x3c82, 0x0000); 136 go7007_write_addr(go, 0x3c82, 0x0000);
137 up(&adlink_mpg24_i2c_lock); 137 mutex_unlock(&adlink_mpg24_i2c_lock);
138 } 138 }
139 up(&go->hw_lock); 139 mutex_unlock(&go->hw_lock);
140 return ret; 140 return ret;
141} 141}
142 142
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
index 178d18119faa..ce9307e3e186 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -132,7 +132,7 @@ struct go7007_buffer {
132 132
133struct go7007_file { 133struct go7007_file {
134 struct go7007 *go; 134 struct go7007 *go;
135 struct semaphore lock; 135 struct mutex lock;
136 int buf_count; 136 int buf_count;
137 struct go7007_buffer *bufs; 137 struct go7007_buffer *bufs;
138}; 138};
@@ -170,7 +170,7 @@ struct go7007 {
170 int ref_count; 170 int ref_count;
171 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status; 171 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
172 spinlock_t spinlock; 172 spinlock_t spinlock;
173 struct semaphore hw_lock; 173 struct mutex hw_lock;
174 int streaming; 174 int streaming;
175 int in_use; 175 int in_use;
176 int audio_enabled; 176 int audio_enabled;
@@ -240,7 +240,7 @@ struct go7007 {
240 unsigned short interrupt_data; 240 unsigned short interrupt_data;
241}; 241};
242 242
243/* All of these must be called with the hpi_lock semaphore held! */ 243/* All of these must be called with the hpi_lock mutex held! */
244#define go7007_interface_reset(go) \ 244#define go7007_interface_reset(go) \
245 ((go)->hpi_ops->interface_reset(go)) 245 ((go)->hpi_ops->interface_reset(go))
246#define go7007_write_interrupt(go, x, y) \ 246#define go7007_write_interrupt(go, x, y) \
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index aa4a9e0b9954..ecaa3c989cf4 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -33,7 +33,8 @@
33 33
34static unsigned int assume_endura; 34static unsigned int assume_endura;
35module_param(assume_endura, int, 0644); 35module_param(assume_endura, int, 0644);
36MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura"); 36MODULE_PARM_DESC(assume_endura, "when probing fails, "
37 "hardware is a Pelco Endura");
37 38
38/* #define GO7007_USB_DEBUG */ 39/* #define GO7007_USB_DEBUG */
39/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */ 40/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
@@ -44,12 +45,12 @@ MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura"
44 45
45/* 46/*
46 * Pipes on EZ-USB interface: 47 * Pipes on EZ-USB interface:
47 * 0 snd - Control 48 * 0 snd - Control
48 * 0 rcv - Control 49 * 0 rcv - Control
49 * 2 snd - Download firmware (control) 50 * 2 snd - Download firmware (control)
50 * 4 rcv - Read Interrupt (interrupt) 51 * 4 rcv - Read Interrupt (interrupt)
51 * 6 rcv - Read Video (bulk) 52 * 6 rcv - Read Video (bulk)
52 * 8 rcv - Read Audio (bulk) 53 * 8 rcv - Read Audio (bulk)
53 */ 54 */
54 55
55#define GO7007_USB_EZUSB (1<<0) 56#define GO7007_USB_EZUSB (1<<0)
@@ -62,7 +63,7 @@ struct go7007_usb_board {
62 63
63struct go7007_usb { 64struct go7007_usb {
64 struct go7007_usb_board *board; 65 struct go7007_usb_board *board;
65 struct semaphore i2c_lock; 66 struct mutex i2c_lock;
66 struct usb_device *usbdev; 67 struct usb_device *usbdev;
67 struct urb *video_urbs[8]; 68 struct urb *video_urbs[8];
68 struct urb *audio_urbs[8]; 69 struct urb *audio_urbs[8];
@@ -97,7 +98,7 @@ static struct go7007_usb_board board_matrix_ii = {
97 }, 98 },
98 }, 99 },
99 .num_inputs = 2, 100 .num_inputs = 2,
100 .inputs = { 101 .inputs = {
101 { 102 {
102 .video_input = 0, 103 .video_input = 0,
103 .name = "Composite", 104 .name = "Composite",
@@ -134,7 +135,7 @@ static struct go7007_usb_board board_matrix_reload = {
134 }, 135 },
135 }, 136 },
136 .num_inputs = 2, 137 .num_inputs = 2,
137 .inputs = { 138 .inputs = {
138 { 139 {
139 .video_input = 0, 140 .video_input = 0,
140 .name = "Composite", 141 .name = "Composite",
@@ -172,7 +173,7 @@ static struct go7007_usb_board board_star_trek = {
172 }, 173 },
173 }, 174 },
174 .num_inputs = 2, 175 .num_inputs = 2,
175 .inputs = { 176 .inputs = {
176 { 177 {
177 .video_input = 1, 178 .video_input = 1,
178 /* .audio_input = AUDIO_EXTERN, */ 179 /* .audio_input = AUDIO_EXTERN, */
@@ -228,7 +229,7 @@ static struct go7007_usb_board board_px_tv402u = {
228 }, 229 },
229 }, 230 },
230 .num_inputs = 3, 231 .num_inputs = 3,
231 .inputs = { 232 .inputs = {
232 { 233 {
233 .video_input = 1, 234 .video_input = 1,
234 .audio_input = TVAUDIO_INPUT_EXTERN, 235 .audio_input = TVAUDIO_INPUT_EXTERN,
@@ -276,7 +277,7 @@ static struct go7007_usb_board board_xmen = {
276 }, 277 },
277 }, 278 },
278 .num_inputs = 1, 279 .num_inputs = 1,
279 .inputs = { 280 .inputs = {
280 { 281 {
281 .name = "Camera", 282 .name = "Camera",
282 }, 283 },
@@ -309,7 +310,7 @@ static struct go7007_usb_board board_matrix_revolution = {
309 }, 310 },
310 }, 311 },
311 .num_inputs = 2, 312 .num_inputs = 2,
312 .inputs = { 313 .inputs = {
313 { 314 {
314 .video_input = 2, 315 .video_input = 2,
315 .name = "Composite", 316 .name = "Composite",
@@ -341,7 +342,7 @@ static struct go7007_usb_board board_lifeview_lr192 = {
341 GO7007_SENSOR_SCALING, 342 GO7007_SENSOR_SCALING,
342 .num_i2c_devs = 0, 343 .num_i2c_devs = 0,
343 .num_inputs = 1, 344 .num_inputs = 1,
344 .inputs = { 345 .inputs = {
345 { 346 {
346 .video_input = 0, 347 .video_input = 0,
347 .name = "Composite", 348 .name = "Composite",
@@ -367,7 +368,7 @@ static struct go7007_usb_board board_endura = {
367 .sensor_h_offset = 8, 368 .sensor_h_offset = 8,
368 .num_i2c_devs = 0, 369 .num_i2c_devs = 0,
369 .num_inputs = 1, 370 .num_inputs = 1,
370 .inputs = { 371 .inputs = {
371 { 372 {
372 .name = "Camera", 373 .name = "Camera",
373 }, 374 },
@@ -399,7 +400,7 @@ static struct go7007_usb_board board_adlink_mpg24 = {
399 }, 400 },
400 }, 401 },
401 .num_inputs = 1, 402 .num_inputs = 1,
402 .inputs = { 403 .inputs = {
403 { 404 {
404 .name = "Composite", 405 .name = "Composite",
405 }, 406 },
@@ -430,7 +431,7 @@ static struct go7007_usb_board board_sensoray_2250 = {
430 }, 431 },
431 }, 432 },
432 .num_inputs = 2, 433 .num_inputs = 2,
433 .inputs = { 434 .inputs = {
434 { 435 {
435 .video_input = 0, 436 .video_input = 0,
436 .name = "Composite", 437 .name = "Composite",
@@ -734,14 +735,15 @@ static int go7007_usb_read_interrupt(struct go7007 *go)
734static void go7007_usb_read_video_pipe_complete(struct urb *urb) 735static void go7007_usb_read_video_pipe_complete(struct urb *urb)
735{ 736{
736 struct go7007 *go = (struct go7007 *)urb->context; 737 struct go7007 *go = (struct go7007 *)urb->context;
737 int r, status = urb-> status; 738 int r, status = urb->status;
738 739
739 if (!go->streaming) { 740 if (!go->streaming) {
740 wake_up_interruptible(&go->frame_waitq); 741 wake_up_interruptible(&go->frame_waitq);
741 return; 742 return;
742 } 743 }
743 if (status) { 744 if (status) {
744 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", status); 745 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
746 status);
745 return; 747 return;
746 } 748 }
747 if (urb->actual_length != urb->transfer_buffer_length) { 749 if (urb->actual_length != urb->transfer_buffer_length) {
@@ -762,7 +764,8 @@ static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
762 if (!go->streaming) 764 if (!go->streaming)
763 return; 765 return;
764 if (status) { 766 if (status) {
765 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", status); 767 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
768 status);
766 return; 769 return;
767 } 770 }
768 if (urb->actual_length != urb->transfer_buffer_length) { 771 if (urb->actual_length != urb->transfer_buffer_length) {
@@ -877,7 +880,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
877 if (go->status == STATUS_SHUTDOWN) 880 if (go->status == STATUS_SHUTDOWN)
878 return -1; 881 return -1;
879 882
880 down(&usb->i2c_lock); 883 mutex_lock(&usb->i2c_lock);
881 884
882 for (i = 0; i < num; ++i) { 885 for (i = 0; i < num; ++i) {
883 /* The hardware command is "write some bytes then read some 886 /* The hardware command is "write some bytes then read some
@@ -935,7 +938,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
935 ret = 0; 938 ret = 0;
936 939
937i2c_done: 940i2c_done:
938 up(&usb->i2c_lock); 941 mutex_unlock(&usb->i2c_lock);
939 return ret; 942 return ret;
940} 943}
941 944
@@ -1017,7 +1020,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1017 break; 1020 break;
1018 case GO7007_BOARDID_SENSORAY_2250: 1021 case GO7007_BOARDID_SENSORAY_2250:
1019 printk(KERN_INFO "Sensoray 2250 found\n"); 1022 printk(KERN_INFO "Sensoray 2250 found\n");
1020 name = "Sensoray 2250/2251\n"; 1023 name = "Sensoray 2250/2251";
1021 board = &board_sensoray_2250; 1024 board = &board_sensoray_2250;
1022 break; 1025 break;
1023 default: 1026 default:
@@ -1065,7 +1068,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1065 if (board->flags & GO7007_USB_EZUSB_I2C) { 1068 if (board->flags & GO7007_USB_EZUSB_I2C) {
1066 memcpy(&go->i2c_adapter, &go7007_usb_adap_templ, 1069 memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
1067 sizeof(go7007_usb_adap_templ)); 1070 sizeof(go7007_usb_adap_templ));
1068 init_MUTEX(&usb->i2c_lock); 1071 mutex_init(&usb->i2c_lock);
1069 go->i2c_adapter.dev.parent = go->dev; 1072 go->i2c_adapter.dev.parent = go->dev;
1070 i2c_set_adapdata(&go->i2c_adapter, go); 1073 i2c_set_adapdata(&go->i2c_adapter, go);
1071 if (i2c_add_adapter(&go->i2c_adapter) < 0) { 1074 if (i2c_add_adapter(&go->i2c_adapter) < 0) {
@@ -1096,7 +1099,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1096 usb->board = board = &board_endura; 1099 usb->board = board = &board_endura;
1097 go->board_info = &board->main_info; 1100 go->board_info = &board->main_info;
1098 strncpy(go->name, "Pelco Endura", 1101 strncpy(go->name, "Pelco Endura",
1099 sizeof(go->name)); 1102 sizeof(go->name));
1100 } else { 1103 } else {
1101 u16 channel; 1104 u16 channel;
1102 1105
@@ -1154,8 +1157,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1154 * to the EZ-USB GPIO output pins */ 1157 * to the EZ-USB GPIO output pins */
1155 if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0, 1158 if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
1156 NULL, 0, 0) < 0) { 1159 NULL, 0, 0) < 0) {
1157 printk(KERN_ERR 1160 printk(KERN_ERR "go7007-usb: GPIO write failed!\n");
1158 "go7007-usb: GPIO write failed!\n");
1159 goto initfail; 1161 goto initfail;
1160 } 1162 }
1161 } 1163 }
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 06cacd37bbd8..4bd353afa596 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -30,7 +30,7 @@
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
32#include <linux/i2c.h> 32#include <linux/i2c.h>
33#include <linux/semaphore.h> 33#include <linux/mutex.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35#include <asm/system.h> 35#include <asm/system.h>
36 36
@@ -75,7 +75,7 @@ static int go7007_streamoff(struct go7007 *go)
75 int retval = -EINVAL; 75 int retval = -EINVAL;
76 unsigned long flags; 76 unsigned long flags;
77 77
78 down(&go->hw_lock); 78 mutex_lock(&go->hw_lock);
79 if (go->streaming) { 79 if (go->streaming) {
80 go->streaming = 0; 80 go->streaming = 0;
81 go7007_stream_stop(go); 81 go7007_stream_stop(go);
@@ -85,7 +85,7 @@ static int go7007_streamoff(struct go7007 *go)
85 go7007_reset_encoder(go); 85 go7007_reset_encoder(go);
86 retval = 0; 86 retval = 0;
87 } 87 }
88 up(&go->hw_lock); 88 mutex_unlock(&go->hw_lock);
89 return 0; 89 return 0;
90} 90}
91 91
@@ -101,7 +101,7 @@ static int go7007_open(struct file *file)
101 return -ENOMEM; 101 return -ENOMEM;
102 ++go->ref_count; 102 ++go->ref_count;
103 gofh->go = go; 103 gofh->go = go;
104 init_MUTEX(&gofh->lock); 104 mutex_init(&gofh->lock);
105 gofh->buf_count = 0; 105 gofh->buf_count = 0;
106 file->private_data = gofh; 106 file->private_data = gofh;
107 return 0; 107 return 0;
@@ -383,13 +383,10 @@ static int clip_to_modet_map(struct go7007 *go, int region,
383 } 383 }
384 return 0; 384 return 0;
385} 385}
386#endif
386 387
387static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl) 388static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl)
388{ 389{
389 static const u32 user_ctrls[] = {
390 V4L2_CID_USER_CLASS,
391 0
392 };
393 static const u32 mpeg_ctrls[] = { 390 static const u32 mpeg_ctrls[] = {
394 V4L2_CID_MPEG_CLASS, 391 V4L2_CID_MPEG_CLASS,
395 V4L2_CID_MPEG_STREAM_TYPE, 392 V4L2_CID_MPEG_STREAM_TYPE,
@@ -401,26 +398,15 @@ static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
401 0 398 0
402 }; 399 };
403 static const u32 *ctrl_classes[] = { 400 static const u32 *ctrl_classes[] = {
404 user_ctrls,
405 mpeg_ctrls, 401 mpeg_ctrls,
406 NULL 402 NULL
407 }; 403 };
408 404
409 /* The ctrl may already contain the queried i2c controls, 405 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
410 * query the mpeg controls if the existing ctrl id is
411 * greater than the next mpeg ctrl id.
412 */
413 id = v4l2_ctrl_next(ctrl_classes, id);
414 if (id >= ctrl->id && ctrl->name[0])
415 return 0;
416
417 memset(ctrl, 0, sizeof(*ctrl));
418 ctrl->id = id;
419 406
420 switch (ctrl->id) { 407 switch (ctrl->id) {
421 case V4L2_CID_USER_CLASS:
422 case V4L2_CID_MPEG_CLASS: 408 case V4L2_CID_MPEG_CLASS:
423 return v4l2_ctrl_query_fill_std(ctrl); 409 return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
424 case V4L2_CID_MPEG_STREAM_TYPE: 410 case V4L2_CID_MPEG_STREAM_TYPE:
425 return v4l2_ctrl_query_fill(ctrl, 411 return v4l2_ctrl_query_fill(ctrl,
426 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD, 412 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
@@ -437,20 +423,21 @@ static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
437 V4L2_MPEG_VIDEO_ASPECT_16x9, 1, 423 V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
438 V4L2_MPEG_VIDEO_ASPECT_1x1); 424 V4L2_MPEG_VIDEO_ASPECT_1x1);
439 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 425 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
426 return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
440 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 427 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
441 return v4l2_ctrl_query_fill_std(ctrl); 428 return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
442 case V4L2_CID_MPEG_VIDEO_BITRATE: 429 case V4L2_CID_MPEG_VIDEO_BITRATE:
443 return v4l2_ctrl_query_fill(ctrl, 430 return v4l2_ctrl_query_fill(ctrl,
444 64000, 431 64000,
445 10000000, 1, 432 10000000, 1,
446 9800000); 433 1500000);
447 default: 434 default:
448 break; 435 return -EINVAL;
449 } 436 }
450 return -EINVAL; 437 return 0;
451} 438}
452 439
453static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go) 440static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
454{ 441{
455 /* pretty sure we can't change any of these while streaming */ 442 /* pretty sure we can't change any of these while streaming */
456 if (go->streaming) 443 if (go->streaming)
@@ -528,6 +515,8 @@ static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
528 } 515 }
529 break; 516 break;
530 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 517 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
518 if (ctrl->value < 0 || ctrl->value > 34)
519 return -EINVAL;
531 go->gop_size = ctrl->value; 520 go->gop_size = ctrl->value;
532 break; 521 break;
533 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 522 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
@@ -547,7 +536,7 @@ static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
547 return 0; 536 return 0;
548} 537}
549 538
550static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go) 539static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
551{ 540{
552 switch (ctrl->id) { 541 switch (ctrl->id) {
553 case V4L2_CID_MPEG_STREAM_TYPE: 542 case V4L2_CID_MPEG_STREAM_TYPE:
@@ -600,13 +589,11 @@ static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go)
600 } 589 }
601 return 0; 590 return 0;
602} 591}
603#endif
604 592
605static int vidioc_querycap(struct file *file, void *priv, 593static int vidioc_querycap(struct file *file, void *priv,
606 struct v4l2_capability *cap) 594 struct v4l2_capability *cap)
607{ 595{
608 struct go7007_file *gofh = priv; 596 struct go7007 *go = ((struct go7007_file *) priv)->go;
609 struct go7007 *go = gofh->go;
610 597
611 strlcpy(cap->driver, "go7007", sizeof(cap->driver)); 598 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
612 strlcpy(cap->card, go->name, sizeof(cap->card)); 599 strlcpy(cap->card, go->name, sizeof(cap->card));
@@ -653,8 +640,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
653static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 640static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
654 struct v4l2_format *fmt) 641 struct v4l2_format *fmt)
655{ 642{
656 struct go7007_file *gofh = priv; 643 struct go7007 *go = ((struct go7007_file *) priv)->go;
657 struct go7007 *go = gofh->go;
658 644
659 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 645 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
660 fmt->fmt.pix.width = go->width; 646 fmt->fmt.pix.width = go->width;
@@ -672,8 +658,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
672static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 658static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
673 struct v4l2_format *fmt) 659 struct v4l2_format *fmt)
674{ 660{
675 struct go7007_file *gofh = priv; 661 struct go7007 *go = ((struct go7007_file *) priv)->go;
676 struct go7007 *go = gofh->go;
677 662
678 return set_capture_size(go, fmt, 1); 663 return set_capture_size(go, fmt, 1);
679} 664}
@@ -681,8 +666,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
681static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 666static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
682 struct v4l2_format *fmt) 667 struct v4l2_format *fmt)
683{ 668{
684 struct go7007_file *gofh = priv; 669 struct go7007 *go = ((struct go7007_file *) priv)->go;
685 struct go7007 *go = gofh->go;
686 670
687 if (go->streaming) 671 if (go->streaming)
688 return -EBUSY; 672 return -EBUSY;
@@ -705,14 +689,14 @@ static int vidioc_reqbufs(struct file *file, void *priv,
705 req->memory != V4L2_MEMORY_MMAP) 689 req->memory != V4L2_MEMORY_MMAP)
706 return -EINVAL; 690 return -EINVAL;
707 691
708 down(&gofh->lock); 692 mutex_lock(&gofh->lock);
709 for (i = 0; i < gofh->buf_count; ++i) 693 for (i = 0; i < gofh->buf_count; ++i)
710 if (gofh->bufs[i].mapped > 0) 694 if (gofh->bufs[i].mapped > 0)
711 goto unlock_and_return; 695 goto unlock_and_return;
712 696
713 down(&go->hw_lock); 697 mutex_lock(&go->hw_lock);
714 if (go->in_use > 0 && gofh->buf_count == 0) { 698 if (go->in_use > 0 && gofh->buf_count == 0) {
715 up(&go->hw_lock); 699 mutex_unlock(&go->hw_lock);
716 goto unlock_and_return; 700 goto unlock_and_return;
717 } 701 }
718 702
@@ -731,7 +715,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
731 GFP_KERNEL); 715 GFP_KERNEL);
732 716
733 if (!gofh->bufs) { 717 if (!gofh->bufs) {
734 up(&go->hw_lock); 718 mutex_unlock(&go->hw_lock);
735 goto unlock_and_return; 719 goto unlock_and_return;
736 } 720 }
737 721
@@ -750,8 +734,8 @@ static int vidioc_reqbufs(struct file *file, void *priv,
750 } 734 }
751 735
752 gofh->buf_count = count; 736 gofh->buf_count = count;
753 up(&go->hw_lock); 737 mutex_unlock(&go->hw_lock);
754 up(&gofh->lock); 738 mutex_unlock(&gofh->lock);
755 739
756 memset(req, 0, sizeof(*req)); 740 memset(req, 0, sizeof(*req));
757 741
@@ -762,7 +746,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
762 return 0; 746 return 0;
763 747
764unlock_and_return: 748unlock_and_return:
765 up(&gofh->lock); 749 mutex_unlock(&gofh->lock);
766 return retval; 750 return retval;
767} 751}
768 752
@@ -778,7 +762,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
778 762
779 index = buf->index; 763 index = buf->index;
780 764
781 down(&gofh->lock); 765 mutex_lock(&gofh->lock);
782 if (index >= gofh->buf_count) 766 if (index >= gofh->buf_count)
783 goto unlock_and_return; 767 goto unlock_and_return;
784 768
@@ -802,12 +786,12 @@ static int vidioc_querybuf(struct file *file, void *priv,
802 buf->memory = V4L2_MEMORY_MMAP; 786 buf->memory = V4L2_MEMORY_MMAP;
803 buf->m.offset = index * GO7007_BUF_SIZE; 787 buf->m.offset = index * GO7007_BUF_SIZE;
804 buf->length = GO7007_BUF_SIZE; 788 buf->length = GO7007_BUF_SIZE;
805 up(&gofh->lock); 789 mutex_unlock(&gofh->lock);
806 790
807 return 0; 791 return 0;
808 792
809unlock_and_return: 793unlock_and_return:
810 up(&gofh->lock); 794 mutex_unlock(&gofh->lock);
811 return retval; 795 return retval;
812} 796}
813 797
@@ -824,7 +808,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
824 buf->memory != V4L2_MEMORY_MMAP) 808 buf->memory != V4L2_MEMORY_MMAP)
825 return retval; 809 return retval;
826 810
827 down(&gofh->lock); 811 mutex_lock(&gofh->lock);
828 if (buf->index < 0 || buf->index >= gofh->buf_count) 812 if (buf->index < 0 || buf->index >= gofh->buf_count)
829 goto unlock_and_return; 813 goto unlock_and_return;
830 814
@@ -865,12 +849,12 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
865 spin_lock_irqsave(&go->spinlock, flags); 849 spin_lock_irqsave(&go->spinlock, flags);
866 list_add_tail(&gobuf->stream, &go->stream); 850 list_add_tail(&gobuf->stream, &go->stream);
867 spin_unlock_irqrestore(&go->spinlock, flags); 851 spin_unlock_irqrestore(&go->spinlock, flags);
868 up(&gofh->lock); 852 mutex_unlock(&gofh->lock);
869 853
870 return 0; 854 return 0;
871 855
872unlock_and_return: 856unlock_and_return:
873 up(&gofh->lock); 857 mutex_unlock(&gofh->lock);
874 return retval; 858 return retval;
875} 859}
876 860
@@ -890,7 +874,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
890 if (buf->memory != V4L2_MEMORY_MMAP) 874 if (buf->memory != V4L2_MEMORY_MMAP)
891 return retval; 875 return retval;
892 876
893 down(&gofh->lock); 877 mutex_lock(&gofh->lock);
894 if (list_empty(&go->stream)) 878 if (list_empty(&go->stream))
895 goto unlock_and_return; 879 goto unlock_and_return;
896 gobuf = list_entry(go->stream.next, 880 gobuf = list_entry(go->stream.next,
@@ -934,11 +918,11 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
934 buf->length = GO7007_BUF_SIZE; 918 buf->length = GO7007_BUF_SIZE;
935 buf->reserved = gobuf->modet_active; 919 buf->reserved = gobuf->modet_active;
936 920
937 up(&gofh->lock); 921 mutex_unlock(&gofh->lock);
938 return 0; 922 return 0;
939 923
940unlock_and_return: 924unlock_and_return:
941 up(&gofh->lock); 925 mutex_unlock(&gofh->lock);
942 return retval; 926 return retval;
943} 927}
944 928
@@ -952,8 +936,8 @@ static int vidioc_streamon(struct file *file, void *priv,
952 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 936 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
953 return -EINVAL; 937 return -EINVAL;
954 938
955 down(&gofh->lock); 939 mutex_lock(&gofh->lock);
956 down(&go->hw_lock); 940 mutex_lock(&go->hw_lock);
957 941
958 if (!go->streaming) { 942 if (!go->streaming) {
959 go->streaming = 1; 943 go->streaming = 1;
@@ -964,8 +948,8 @@ static int vidioc_streamon(struct file *file, void *priv,
964 else 948 else
965 retval = 0; 949 retval = 0;
966 } 950 }
967 up(&go->hw_lock); 951 mutex_unlock(&go->hw_lock);
968 up(&gofh->lock); 952 mutex_unlock(&gofh->lock);
969 953
970 return retval; 954 return retval;
971} 955}
@@ -978,9 +962,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
978 962
979 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 963 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
980 return -EINVAL; 964 return -EINVAL;
981 down(&gofh->lock); 965 mutex_lock(&gofh->lock);
982 go7007_streamoff(go); 966 go7007_streamoff(go);
983 up(&gofh->lock); 967 mutex_unlock(&gofh->lock);
984 968
985 return 0; 969 return 0;
986} 970}
@@ -988,22 +972,20 @@ static int vidioc_streamoff(struct file *file, void *priv,
988static int vidioc_queryctrl(struct file *file, void *priv, 972static int vidioc_queryctrl(struct file *file, void *priv,
989 struct v4l2_queryctrl *query) 973 struct v4l2_queryctrl *query)
990{ 974{
991 struct go7007_file *gofh = priv; 975 struct go7007 *go = ((struct go7007_file *) priv)->go;
992 struct go7007 *go = gofh->go;
993 976
994 if (!go->i2c_adapter_online) 977 if (!go->i2c_adapter_online)
995 return -EIO; 978 return -EIO;
996 979
997 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query); 980 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
998 981
999 return (!query->name[0]) ? -EINVAL : 0; 982 return (!query->name[0]) ? mpeg_queryctrl(query) : 0;
1000} 983}
1001 984
1002static int vidioc_g_ctrl(struct file *file, void *priv, 985static int vidioc_g_ctrl(struct file *file, void *priv,
1003 struct v4l2_control *ctrl) 986 struct v4l2_control *ctrl)
1004{ 987{
1005 struct go7007_file *gofh = priv; 988 struct go7007 *go = ((struct go7007_file *) priv)->go;
1006 struct go7007 *go = gofh->go;
1007 struct v4l2_queryctrl query; 989 struct v4l2_queryctrl query;
1008 990
1009 if (!go->i2c_adapter_online) 991 if (!go->i2c_adapter_online)
@@ -1013,7 +995,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1013 query.id = ctrl->id; 995 query.id = ctrl->id;
1014 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); 996 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1015 if (query.name[0] == 0) 997 if (query.name[0] == 0)
1016 return -EINVAL; 998 return mpeg_g_ctrl(ctrl, go);
1017 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl); 999 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl);
1018 1000
1019 return 0; 1001 return 0;
@@ -1022,8 +1004,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1022static int vidioc_s_ctrl(struct file *file, void *priv, 1004static int vidioc_s_ctrl(struct file *file, void *priv,
1023 struct v4l2_control *ctrl) 1005 struct v4l2_control *ctrl)
1024{ 1006{
1025 struct go7007_file *gofh = priv; 1007 struct go7007 *go = ((struct go7007_file *) priv)->go;
1026 struct go7007 *go = gofh->go;
1027 struct v4l2_queryctrl query; 1008 struct v4l2_queryctrl query;
1028 1009
1029 if (!go->i2c_adapter_online) 1010 if (!go->i2c_adapter_online)
@@ -1033,7 +1014,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1033 query.id = ctrl->id; 1014 query.id = ctrl->id;
1034 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); 1015 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1035 if (query.name[0] == 0) 1016 if (query.name[0] == 0)
1036 return -EINVAL; 1017 return mpeg_s_ctrl(ctrl, go);
1037 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl); 1018 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl);
1038 1019
1039 return 0; 1020 return 0;
@@ -1042,8 +1023,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1042static int vidioc_g_parm(struct file *filp, void *priv, 1023static int vidioc_g_parm(struct file *filp, void *priv,
1043 struct v4l2_streamparm *parm) 1024 struct v4l2_streamparm *parm)
1044{ 1025{
1045 struct go7007_file *gofh = priv; 1026 struct go7007 *go = ((struct go7007_file *) priv)->go;
1046 struct go7007 *go = gofh->go;
1047 struct v4l2_fract timeperframe = { 1027 struct v4l2_fract timeperframe = {
1048 .numerator = 1001 * go->fps_scale, 1028 .numerator = 1001 * go->fps_scale,
1049 .denominator = go->sensor_framerate, 1029 .denominator = go->sensor_framerate,
@@ -1061,8 +1041,7 @@ static int vidioc_g_parm(struct file *filp, void *priv,
1061static int vidioc_s_parm(struct file *filp, void *priv, 1041static int vidioc_s_parm(struct file *filp, void *priv,
1062 struct v4l2_streamparm *parm) 1042 struct v4l2_streamparm *parm)
1063{ 1043{
1064 struct go7007_file *gofh = priv; 1044 struct go7007 *go = ((struct go7007_file *) priv)->go;
1065 struct go7007 *go = gofh->go;
1066 unsigned int n, d; 1045 unsigned int n, d;
1067 1046
1068 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1047 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1094,8 +1073,7 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1094static int vidioc_enum_framesizes(struct file *filp, void *priv, 1073static int vidioc_enum_framesizes(struct file *filp, void *priv,
1095 struct v4l2_frmsizeenum *fsize) 1074 struct v4l2_frmsizeenum *fsize)
1096{ 1075{
1097 struct go7007_file *gofh = priv; 1076 struct go7007 *go = ((struct go7007_file *) priv)->go;
1098 struct go7007 *go = gofh->go;
1099 1077
1100 /* Return -EINVAL, if it is a TV board */ 1078 /* Return -EINVAL, if it is a TV board */
1101 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || 1079 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
@@ -1115,8 +1093,7 @@ static int vidioc_enum_framesizes(struct file *filp, void *priv,
1115static int vidioc_enum_frameintervals(struct file *filp, void *priv, 1093static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1116 struct v4l2_frmivalenum *fival) 1094 struct v4l2_frmivalenum *fival)
1117{ 1095{
1118 struct go7007_file *gofh = priv; 1096 struct go7007 *go = ((struct go7007_file *) priv)->go;
1119 struct go7007 *go = gofh->go;
1120 1097
1121 /* Return -EINVAL, if it is a TV board */ 1098 /* Return -EINVAL, if it is a TV board */
1122 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || 1099 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
@@ -1133,10 +1110,27 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1133 return 0; 1110 return 0;
1134} 1111}
1135 1112
1113static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1114{
1115 struct go7007 *go = ((struct go7007_file *) priv)->go;
1116
1117 switch (go->standard) {
1118 case GO7007_STD_NTSC:
1119 *std = V4L2_STD_NTSC;
1120 break;
1121 case GO7007_STD_PAL:
1122 *std = V4L2_STD_PAL;
1123 break;
1124 default:
1125 return -EINVAL;
1126 }
1127
1128 return 0;
1129}
1130
1136static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) 1131static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1137{ 1132{
1138 struct go7007_file *gofh = priv; 1133 struct go7007 *go = ((struct go7007_file *) priv)->go;
1139 struct go7007 *go = gofh->go;
1140 1134
1141 if (go->streaming) 1135 if (go->streaming)
1142 return -EBUSY; 1136 return -EBUSY;
@@ -1178,30 +1172,27 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1178 return 0; 1172 return 0;
1179} 1173}
1180 1174
1181#if 0 1175static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1182 case VIDIOC_QUERYSTD: 1176{
1183 { 1177 struct go7007 *go = ((struct go7007_file *) priv)->go;
1184 v4l2_std_id *std = arg;
1185 1178
1186 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && 1179 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1187 go->input == go->board_info->num_inputs - 1) { 1180 go->input == go->board_info->num_inputs - 1) {
1188 if (!go->i2c_adapter_online) 1181 if (!go->i2c_adapter_online)
1189 return -EIO; 1182 return -EIO;
1190 i2c_clients_command(&go->i2c_adapter, 1183 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYSTD, std);
1191 VIDIOC_QUERYSTD, arg); 1184 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1192 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) 1185 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1193 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; 1186 else
1194 else 1187 *std = 0;
1195 *std = 0; 1188
1196 return 0; 1189 return 0;
1197 } 1190}
1198#endif
1199 1191
1200static int vidioc_enum_input(struct file *file, void *priv, 1192static int vidioc_enum_input(struct file *file, void *priv,
1201 struct v4l2_input *inp) 1193 struct v4l2_input *inp)
1202{ 1194{
1203 struct go7007_file *gofh = priv; 1195 struct go7007 *go = ((struct go7007_file *) priv)->go;
1204 struct go7007 *go = gofh->go;
1205 1196
1206 if (inp->index >= go->board_info->num_inputs) 1197 if (inp->index >= go->board_info->num_inputs)
1207 return -EINVAL; 1198 return -EINVAL;
@@ -1230,8 +1221,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
1230 1221
1231static int vidioc_g_input(struct file *file, void *priv, unsigned int *input) 1222static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1232{ 1223{
1233 struct go7007_file *gofh = priv; 1224 struct go7007 *go = ((struct go7007_file *) priv)->go;
1234 struct go7007 *go = gofh->go;
1235 1225
1236 *input = go->input; 1226 *input = go->input;
1237 1227
@@ -1240,8 +1230,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1240 1230
1241static int vidioc_s_input(struct file *file, void *priv, unsigned int input) 1231static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1242{ 1232{
1243 struct go7007_file *gofh = priv; 1233 struct go7007 *go = ((struct go7007_file *) priv)->go;
1244 struct go7007 *go = gofh->go;
1245 1234
1246 if (input >= go->board_info->num_inputs) 1235 if (input >= go->board_info->num_inputs)
1247 return -EINVAL; 1236 return -EINVAL;
@@ -1262,8 +1251,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1262static int vidioc_g_tuner(struct file *file, void *priv, 1251static int vidioc_g_tuner(struct file *file, void *priv,
1263 struct v4l2_tuner *t) 1252 struct v4l2_tuner *t)
1264{ 1253{
1265 struct go7007_file *gofh = priv; 1254 struct go7007 *go = ((struct go7007_file *) priv)->go;
1266 struct go7007 *go = gofh->go;
1267 1255
1268 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1256 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1269 return -EINVAL; 1257 return -EINVAL;
@@ -1281,8 +1269,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
1281static int vidioc_s_tuner(struct file *file, void *priv, 1269static int vidioc_s_tuner(struct file *file, void *priv,
1282 struct v4l2_tuner *t) 1270 struct v4l2_tuner *t)
1283{ 1271{
1284 struct go7007_file *gofh = priv; 1272 struct go7007 *go = ((struct go7007_file *) priv)->go;
1285 struct go7007 *go = gofh->go;
1286 1273
1287 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1274 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1288 return -EINVAL; 1275 return -EINVAL;
@@ -1308,8 +1295,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
1308static int vidioc_g_frequency(struct file *file, void *priv, 1295static int vidioc_g_frequency(struct file *file, void *priv,
1309 struct v4l2_frequency *f) 1296 struct v4l2_frequency *f)
1310{ 1297{
1311 struct go7007_file *gofh = priv; 1298 struct go7007 *go = ((struct go7007_file *) priv)->go;
1312 struct go7007 *go = gofh->go;
1313 1299
1314 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1300 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1315 return -EINVAL; 1301 return -EINVAL;
@@ -1324,8 +1310,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1324static int vidioc_s_frequency(struct file *file, void *priv, 1310static int vidioc_s_frequency(struct file *file, void *priv,
1325 struct v4l2_frequency *f) 1311 struct v4l2_frequency *f)
1326{ 1312{
1327 struct go7007_file *gofh = priv; 1313 struct go7007 *go = ((struct go7007_file *) priv)->go;
1328 struct go7007 *go = gofh->go;
1329 1314
1330 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1315 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1331 return -EINVAL; 1316 return -EINVAL;
@@ -1340,8 +1325,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1340static int vidioc_cropcap(struct file *file, void *priv, 1325static int vidioc_cropcap(struct file *file, void *priv,
1341 struct v4l2_cropcap *cropcap) 1326 struct v4l2_cropcap *cropcap)
1342{ 1327{
1343 struct go7007_file *gofh = priv; 1328 struct go7007 *go = ((struct go7007_file *) priv)->go;
1344 struct go7007 *go = gofh->go;
1345 1329
1346 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1330 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1347 return -EINVAL; 1331 return -EINVAL;
@@ -1385,8 +1369,7 @@ static int vidioc_cropcap(struct file *file, void *priv,
1385 1369
1386static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) 1370static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1387{ 1371{
1388 struct go7007_file *gofh = priv; 1372 struct go7007 *go = ((struct go7007_file *) priv)->go;
1389 struct go7007 *go = gofh->go;
1390 1373
1391 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1374 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1392 return -EINVAL; 1375 return -EINVAL;
@@ -1734,18 +1717,18 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1734 return -EINVAL; /* only support VM_SHARED mapping */ 1717 return -EINVAL; /* only support VM_SHARED mapping */
1735 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE) 1718 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1736 return -EINVAL; /* must map exactly one full buffer */ 1719 return -EINVAL; /* must map exactly one full buffer */
1737 down(&gofh->lock); 1720 mutex_lock(&gofh->lock);
1738 index = vma->vm_pgoff / GO7007_BUF_PAGES; 1721 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1739 if (index >= gofh->buf_count) { 1722 if (index >= gofh->buf_count) {
1740 up(&gofh->lock); 1723 mutex_unlock(&gofh->lock);
1741 return -EINVAL; /* trying to map beyond requested buffers */ 1724 return -EINVAL; /* trying to map beyond requested buffers */
1742 } 1725 }
1743 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) { 1726 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1744 up(&gofh->lock); 1727 mutex_unlock(&gofh->lock);
1745 return -EINVAL; /* offset is not aligned on buffer boundary */ 1728 return -EINVAL; /* offset is not aligned on buffer boundary */
1746 } 1729 }
1747 if (gofh->bufs[index].mapped > 0) { 1730 if (gofh->bufs[index].mapped > 0) {
1748 up(&gofh->lock); 1731 mutex_unlock(&gofh->lock);
1749 return -EBUSY; 1732 return -EBUSY;
1750 } 1733 }
1751 gofh->bufs[index].mapped = 1; 1734 gofh->bufs[index].mapped = 1;
@@ -1754,7 +1737,7 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1754 vma->vm_flags |= VM_DONTEXPAND; 1737 vma->vm_flags |= VM_DONTEXPAND;
1755 vma->vm_flags &= ~VM_IO; 1738 vma->vm_flags &= ~VM_IO;
1756 vma->vm_private_data = &gofh->bufs[index]; 1739 vma->vm_private_data = &gofh->bufs[index];
1757 up(&gofh->lock); 1740 mutex_unlock(&gofh->lock);
1758 return 0; 1741 return 0;
1759} 1742}
1760 1743
@@ -1801,7 +1784,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1801 .vidioc_querybuf = vidioc_querybuf, 1784 .vidioc_querybuf = vidioc_querybuf,
1802 .vidioc_qbuf = vidioc_qbuf, 1785 .vidioc_qbuf = vidioc_qbuf,
1803 .vidioc_dqbuf = vidioc_dqbuf, 1786 .vidioc_dqbuf = vidioc_dqbuf,
1787 .vidioc_g_std = vidioc_g_std,
1804 .vidioc_s_std = vidioc_s_std, 1788 .vidioc_s_std = vidioc_s_std,
1789 .vidioc_querystd = vidioc_querystd,
1805 .vidioc_enum_input = vidioc_enum_input, 1790 .vidioc_enum_input = vidioc_enum_input,
1806 .vidioc_g_input = vidioc_g_input, 1791 .vidioc_g_input = vidioc_g_input,
1807 .vidioc_s_input = vidioc_s_input, 1792 .vidioc_s_input = vidioc_s_input,
@@ -1862,7 +1847,7 @@ void go7007_v4l2_remove(struct go7007 *go)
1862{ 1847{
1863 unsigned long flags; 1848 unsigned long flags;
1864 1849
1865 down(&go->hw_lock); 1850 mutex_lock(&go->hw_lock);
1866 if (go->streaming) { 1851 if (go->streaming) {
1867 go->streaming = 0; 1852 go->streaming = 0;
1868 go7007_stream_stop(go); 1853 go7007_stream_stop(go);
@@ -1870,7 +1855,7 @@ void go7007_v4l2_remove(struct go7007 *go)
1870 abort_queued(go); 1855 abort_queued(go);
1871 spin_unlock_irqrestore(&go->spinlock, flags); 1856 spin_unlock_irqrestore(&go->spinlock, flags);
1872 } 1857 }
1873 up(&go->hw_lock); 1858 mutex_unlock(&go->hw_lock);
1874 if (go->video_dev) 1859 if (go->video_dev)
1875 video_unregister_device(go->video_dev); 1860 video_unregister_device(go->video_dev);
1876} 1861}
diff --git a/drivers/staging/go7007/go7007.txt b/drivers/staging/go7007/go7007.txt
index 1c2907c1dc81..06a76da32128 100644
--- a/drivers/staging/go7007/go7007.txt
+++ b/drivers/staging/go7007/go7007.txt
@@ -2,7 +2,7 @@ This is a driver for the WIS GO7007SB multi-format video encoder.
2 2
3Pete Eberlein <pete@sensoray.com> 3Pete Eberlein <pete@sensoray.com>
4 4
5The driver was originally released under the GPL and is currently hosted at: 5The driver was orignally released under the GPL and is currently hosted at:
6http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver 6http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver
7The go7007 firmware can be acquired from the package on the site above. 7The go7007 firmware can be acquired from the package on the site above.
8 8
@@ -24,10 +24,10 @@ These should be used instead of the non-standard GO7007 ioctls described
24below. 24below.
25 25
26 26
27The README files from the original package appears below: 27The README files from the orignal package appear below:
28 28
29--------------------------------------------------------------------------- 29---------------------------------------------------------------------------
30 WIS GO7007SB Public Linux Driver 30 WIS GO7007SB Public Linux Driver
31--------------------------------------------------------------------------- 31---------------------------------------------------------------------------
32 32
33 33
@@ -78,23 +78,23 @@ All vendor-built kernels should already be configured properly. However,
78for custom-built kernels, the following options need to be enabled in the 78for custom-built kernels, the following options need to be enabled in the
79kernel as built-in or modules: 79kernel as built-in or modules:
80 80
81 CONFIG_HOTPLUG - Support for hot-pluggable devices 81 CONFIG_HOTPLUG - Support for hot-pluggable devices
82 CONFIG_MODULES - Enable loadable module support 82 CONFIG_MODULES - Enable loadable module support
83 CONFIG_KMOD - Automatic kernel module loading 83 CONFIG_KMOD - Automatic kernel module loading
84 CONFIG_FW_LOADER - Hotplug firmware loading support 84 CONFIG_FW_LOADER - Hotplug firmware loading support
85 CONFIG_I2C - I2C support 85 CONFIG_I2C - I2C support
86 CONFIG_VIDEO_DEV - Video For Linux 86 CONFIG_VIDEO_DEV - Video For Linux
87 CONFIG_SOUND - Sound card support 87 CONFIG_SOUND - Sound card support
88 CONFIG_SND - Advanced Linux Sound Architecture 88 CONFIG_SND - Advanced Linux Sound Architecture
89 CONFIG_USB - Support for Host-side USB 89 CONFIG_USB - Support for Host-side USB
90 CONFIG_USB_DEVICEFS - USB device filesystem 90 CONFIG_USB_DEVICEFS - USB device filesystem
91 CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support 91 CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support
92 92
93Additionally, to use the example application, the following options need to 93Additionally, to use the example application, the following options need to
94be enabled in the ALSA section: 94be enabled in the ALSA section:
95 95
96 CONFIG_SND_MIXER_OSS - OSS Mixer API 96 CONFIG_SND_MIXER_OSS - OSS Mixer API
97 CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API 97 CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API
98 98
99The hotplug scripts, along with the fxload utility, must also be installed. 99The hotplug scripts, along with the fxload utility, must also be installed.
100These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>. 100These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>.
@@ -107,7 +107,7 @@ fxload and for loading firmware into the driver using the firmware agent.
107 107
108Most users should be able to compile the driver by simply running: 108Most users should be able to compile the driver by simply running:
109 109
110 $ make 110 $ make
111 111
112in the top-level directory of the driver kit. First the kernel modules 112in the top-level directory of the driver kit. First the kernel modules
113will be built, followed by the example applications. 113will be built, followed by the example applications.
@@ -117,12 +117,12 @@ currently-running kernel, or if the module should be built for a kernel
117other than the currently-running kernel, an additional parameter will need 117other than the currently-running kernel, an additional parameter will need
118to be passed to make to specify the appropriate kernel source directory: 118to be passed to make to specify the appropriate kernel source directory:
119 119
120 $ make KERNELSRC=/usr/src/linux-2.6.10-custom3 120 $ make KERNELSRC=/usr/src/linux-2.6.10-custom3
121 121
122Once the compile completes, the driver and firmware files should be 122Once the compile completes, the driver and firmware files should be
123installed by running: 123installed by running:
124 124
125 $ make install 125 $ make install
126 126
127The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra" 127The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra"
128and the firmware files will be placed in the appropriate hotplug firmware 128and the firmware files will be placed in the appropriate hotplug firmware
@@ -200,7 +200,7 @@ stereo audio broadcasts on the A2 carrier.
200To verify that the configuration has been placed in the correct location, 200To verify that the configuration has been placed in the correct location,
201execute: 201execute:
202 202
203 $ modprobe -c | grep wis-sony-tuner 203 $ modprobe -c | grep wis-sony-tuner
204 204
205If the configuration line appears, then modprobe will pass the parameters 205If the configuration line appears, then modprobe will pass the parameters
206correctly the next time the wis-sony-tuner module is loaded into the 206correctly the next time the wis-sony-tuner module is loaded into the
@@ -223,7 +223,7 @@ This application will auto-detect the V4L2 and ALSA/OSS device names of the
223hardware and will record video and audio to an AVI file for a specified 223hardware and will record video and audio to an AVI file for a specified
224number of seconds. For example: 224number of seconds. For example:
225 225
226 $ apps/gorecord -duration 60 capture.avi 226 $ apps/gorecord -duration 60 capture.avi
227 227
228If this application does not successfully record an AVI file, the error 228If this application does not successfully record an AVI file, the error
229messages produced by gorecord and recorded in the system log (usually in 229messages produced by gorecord and recorded in the system log (usually in
@@ -286,35 +286,35 @@ features of the GO7007SB encoder, which are described below:
286 286
287 Fields in struct go7007_comp_params: 287 Fields in struct go7007_comp_params:
288 288
289 __u32 The maximum number of frames in each 289 __u32 The maximum number of frames in each
290 gop_size Group Of Pictures; i.e. the maximum 290 gop_size Group Of Pictures; i.e. the maximum
291 number of frames minus one between 291 number of frames minus one between
292 each key frame. 292 each key frame.
293 293
294 __u32 The maximum number of sequential 294 __u32 The maximum number of sequential
295 max_b_frames bidirectionally-predicted frames. 295 max_b_frames bidirectionally-predicted frames.
296 (B-frames are not yet supported.) 296 (B-frames are not yet supported.)
297 297
298 enum go7007_aspect_ratio The aspect ratio to be encoded in the 298 enum go7007_aspect_ratio The aspect ratio to be encoded in the
299 aspect_ratio meta-data of the compressed format. 299 aspect_ratio meta-data of the compressed format.
300 300
301 Choices are: 301 Choices are:
302 GO7007_ASPECT_RATIO_1_1 302 GO7007_ASPECT_RATIO_1_1
303 GO7007_ASPECT_RATIO_4_3_NTSC 303 GO7007_ASPECT_RATIO_4_3_NTSC
304 GO7007_ASPECT_RATIO_4_3_PAL 304 GO7007_ASPECT_RATIO_4_3_PAL
305 GO7007_ASPECT_RATIO_16_9_NTSC 305 GO7007_ASPECT_RATIO_16_9_NTSC
306 GO7007_ASPECT_RATIO_16_9_PAL 306 GO7007_ASPECT_RATIO_16_9_PAL
307 307
308 __u32 Bit-wise OR of control flags (below) 308 __u32 Bit-wise OR of control flags (below)
309 flags 309 flags
310 310
311 Flags in struct go7007_comp_params: 311 Flags in struct go7007_comp_params:
312 312
313 GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used 313 GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used
314 to produce streams appropriate for 314 to produce streams appropriate for
315 random seeking. 315 random seeking.
316 316
317 GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header. 317 GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header.
318 318
319 319
320 GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS 320 GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS
@@ -337,56 +337,56 @@ features of the GO7007SB encoder, which are described below:
337 337
338 Fields in struct go7007_mpeg_params: 338 Fields in struct go7007_mpeg_params:
339 339
340 enum go7007_mpeg_video_standard 340 enum go7007_mpeg_video_standard
341 mpeg_video_standard The MPEG video standard in which to 341 mpeg_video_standard The MPEG video standard in which to
342 compress the video. 342 compress the video.
343 343
344 Choices are: 344 Choices are:
345 GO7007_MPEG_VIDEO_MPEG1 345 GO7007_MPEG_VIDEO_MPEG1
346 GO7007_MPEG_VIDEO_MPEG2 346 GO7007_MPEG_VIDEO_MPEG2
347 GO7007_MPEG_VIDEO_MPEG4 347 GO7007_MPEG_VIDEO_MPEG4
348 348
349 __u32 Bit-wise OR of control flags (below) 349 __u32 Bit-wise OR of control flags (below)
350 flags 350 flags
351 351
352 __u32 The profile and level indication to be 352 __u32 The profile and level indication to be
353 pali stored in the sequence header. This 353 pali stored in the sequence header. This
354 is only used as an indicator to the 354 is only used as an indicator to the
355 decoder, and does not affect the MPEG 355 decoder, and does not affect the MPEG
356 features used in the video stream. 356 features used in the video stream.
357 Not valid for MPEG1. 357 Not valid for MPEG1.
358 358
359 Choices for MPEG2 are: 359 Choices for MPEG2 are:
360 GO7007_MPEG2_PROFILE_MAIN_MAIN 360 GO7007_MPEG2_PROFILE_MAIN_MAIN
361 361
362 Choices for MPEG4 are: 362 Choices for MPEG4 are:
363 GO7007_MPEG4_PROFILE_S_L0 363 GO7007_MPEG4_PROFILE_S_L0
364 GO7007_MPEG4_PROFILE_S_L1 364 GO7007_MPEG4_PROFILE_S_L1
365 GO7007_MPEG4_PROFILE_S_L2 365 GO7007_MPEG4_PROFILE_S_L2
366 GO7007_MPEG4_PROFILE_S_L3 366 GO7007_MPEG4_PROFILE_S_L3
367 GO7007_MPEG4_PROFILE_ARTS_L1 367 GO7007_MPEG4_PROFILE_ARTS_L1
368 GO7007_MPEG4_PROFILE_ARTS_L2 368 GO7007_MPEG4_PROFILE_ARTS_L2
369 GO7007_MPEG4_PROFILE_ARTS_L3 369 GO7007_MPEG4_PROFILE_ARTS_L3
370 GO7007_MPEG4_PROFILE_ARTS_L4 370 GO7007_MPEG4_PROFILE_ARTS_L4
371 GO7007_MPEG4_PROFILE_AS_L0 371 GO7007_MPEG4_PROFILE_AS_L0
372 GO7007_MPEG4_PROFILE_AS_L1 372 GO7007_MPEG4_PROFILE_AS_L1
373 GO7007_MPEG4_PROFILE_AS_L2 373 GO7007_MPEG4_PROFILE_AS_L2
374 GO7007_MPEG4_PROFILE_AS_L3 374 GO7007_MPEG4_PROFILE_AS_L3
375 GO7007_MPEG4_PROFILE_AS_L4 375 GO7007_MPEG4_PROFILE_AS_L4
376 GO7007_MPEG4_PROFILE_AS_L5 376 GO7007_MPEG4_PROFILE_AS_L5
377 377
378 Flags in struct go7007_mpeg_params: 378 Flags in struct go7007_mpeg_params:
379 379
380 GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and 380 GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and
381 bitrate control settings to comply 381 bitrate control settings to comply
382 with DVD MPEG2 stream requirements. 382 with DVD MPEG2 stream requirements.
383 This overrides most compression and 383 This overrides most compression and
384 bitrate settings! 384 bitrate settings!
385 385
386 GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header. 386 GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header.
387 387
388 GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at 388 GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
389 the start of each GOP. 389 the start of each GOP.
390 390
391 391
392 GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE 392 GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE
@@ -404,7 +404,7 @@ features of the GO7007SB encoder, which are described below:
404 404
405 405
406---------------------------------------------------------------------------- 406----------------------------------------------------------------------------
407 Installing the WIS PCI Voyager Driver 407 Installing the WIS PCI Voyager Driver
408--------------------------------------------------------------------------- 408---------------------------------------------------------------------------
409 409
410The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x 410The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index 1706fbf06847..8c85a9c3665a 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -21,12 +21,10 @@
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/videodev2.h> 22#include <linux/videodev2.h>
23#include <media/v4l2-common.h> 23#include <media/v4l2-common.h>
24#include "s2250-loader.h"
24#include "go7007-priv.h" 25#include "go7007-priv.h"
25#include "wis-i2c.h" 26#include "wis-i2c.h"
26 27
27extern int s2250loader_init(void);
28extern void s2250loader_cleanup(void);
29
30#define TLV320_ADDRESS 0x34 28#define TLV320_ADDRESS 0x34
31#define VPX322_ADDR_ANALOGCONTROL1 0x02 29#define VPX322_ADDR_ANALOGCONTROL1 0x02
32#define VPX322_ADDR_BRIGHTNESS0 0x0127 30#define VPX322_ADDR_BRIGHTNESS0 0x0127
@@ -34,7 +32,7 @@ extern void s2250loader_cleanup(void);
34#define VPX322_ADDR_CONTRAST0 0x0128 32#define VPX322_ADDR_CONTRAST0 0x0128
35#define VPX322_ADDR_CONTRAST1 0x0132 33#define VPX322_ADDR_CONTRAST1 0x0132
36#define VPX322_ADDR_HUE 0x00dc 34#define VPX322_ADDR_HUE 0x00dc
37#define VPX322_ADDR_SAT 0x0030 35#define VPX322_ADDR_SAT 0x0030
38 36
39struct go7007_usb_board { 37struct go7007_usb_board {
40 unsigned int flags; 38 unsigned int flags;
@@ -43,7 +41,7 @@ struct go7007_usb_board {
43 41
44struct go7007_usb { 42struct go7007_usb {
45 struct go7007_usb_board *board; 43 struct go7007_usb_board *board;
46 struct semaphore i2c_lock; 44 struct mutex i2c_lock;
47 struct usb_device *usbdev; 45 struct usb_device *usbdev;
48 struct urb *video_urbs[8]; 46 struct urb *video_urbs[8];
49 struct urb *audio_urbs[8]; 47 struct urb *audio_urbs[8];
@@ -114,7 +112,7 @@ static u16 vid_regs_fp_pal[] =
114}; 112};
115 113
116struct s2250 { 114struct s2250 {
117 int std; 115 v4l2_std_id std;
118 int input; 116 int input;
119 int brightness; 117 int brightness;
120 int contrast; 118 int contrast;
@@ -165,7 +163,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
165 return -ENOMEM; 163 return -ENOMEM;
166 164
167 usb = go->hpi_context; 165 usb = go->hpi_context;
168 if (down_interruptible(&usb->i2c_lock) != 0) { 166 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
169 printk(KERN_INFO "i2c lock failed\n"); 167 printk(KERN_INFO "i2c lock failed\n");
170 kfree(buf); 168 kfree(buf);
171 return -EINTR; 169 return -EINTR;
@@ -175,7 +173,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
175 buf, 173 buf,
176 16, 1); 174 16, 1);
177 175
178 up(&usb->i2c_lock); 176 mutex_unlock(&usb->i2c_lock);
179 kfree(buf); 177 kfree(buf);
180 return rc; 178 return rc;
181} 179}
@@ -203,19 +201,23 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
203 memset(buf, 0xcd, 6); 201 memset(buf, 0xcd, 6);
204 202
205 usb = go->hpi_context; 203 usb = go->hpi_context;
206 if (down_interruptible(&usb->i2c_lock) != 0) { 204 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
207 printk(KERN_INFO "i2c lock failed\n"); 205 printk(KERN_INFO "i2c lock failed\n");
206 kfree(buf);
208 return -EINTR; 207 return -EINTR;
209 } 208 }
210 if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) 209 if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) {
210 kfree(buf);
211 return -EFAULT; 211 return -EFAULT;
212 }
212 213
213 up(&usb->i2c_lock); 214 mutex_unlock(&usb->i2c_lock);
214 if (buf[0] == 0) { 215 if (buf[0] == 0) {
215 unsigned int subaddr, val_read; 216 unsigned int subaddr, val_read;
216 217
217 subaddr = (buf[4] << 8) + buf[5]; 218 subaddr = (buf[4] << 8) + buf[5];
218 val_read = (buf[2] << 8) + buf[3]; 219 val_read = (buf[2] << 8) + buf[3];
220 kfree(buf);
219 if (val_read != val) { 221 if (val_read != val) {
220 printk(KERN_INFO "invalid fp write %x %x\n", 222 printk(KERN_INFO "invalid fp write %x %x\n",
221 val_read, val); 223 val_read, val);
@@ -226,8 +228,10 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
226 subaddr, addr); 228 subaddr, addr);
227 return -EFAULT; 229 return -EFAULT;
228 } 230 }
229 } else 231 } else {
232 kfree(buf);
230 return -EFAULT; 233 return -EFAULT;
234 }
231 235
232 /* save last 12b value */ 236 /* save last 12b value */
233 if (addr == 0x12b) 237 if (addr == 0x12b)
@@ -236,6 +240,45 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
236 return 0; 240 return 0;
237} 241}
238 242
243static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
244{
245 struct go7007 *go = i2c_get_adapdata(client->adapter);
246 struct go7007_usb *usb;
247 u8 *buf;
248
249 if (go == NULL)
250 return -ENODEV;
251
252 if (go->status == STATUS_SHUTDOWN)
253 return -EBUSY;
254
255 buf = kzalloc(16, GFP_KERNEL);
256
257 if (buf == NULL)
258 return -ENOMEM;
259
260
261
262 memset(buf, 0xcd, 6);
263 usb = go->hpi_context;
264 if (down_interruptible(&usb->i2c_lock) != 0) {
265 printk(KERN_INFO "i2c lock failed\n");
266 kfree(buf);
267 return -EINTR;
268 }
269 if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) {
270 kfree(buf);
271 return -EFAULT;
272 }
273 up(&usb->i2c_lock);
274
275 *val = (buf[0] << 8) | buf[1];
276 kfree(buf);
277
278 return 0;
279}
280
281
239static int write_regs(struct i2c_client *client, u8 *regs) 282static int write_regs(struct i2c_client *client, u8 *regs)
240{ 283{
241 int i; 284 int i;
@@ -350,14 +393,42 @@ static int s2250_command(struct i2c_client *client,
350 { 393 {
351 struct v4l2_control *ctrl = arg; 394 struct v4l2_control *ctrl = arg;
352 int value1; 395 int value1;
396 u16 oldvalue;
353 397
354 switch (ctrl->id) { 398 switch (ctrl->id) {
355 case V4L2_CID_BRIGHTNESS: 399 case V4L2_CID_BRIGHTNESS:
356 printk(KERN_INFO "s2250: future setting\n"); 400 if (ctrl->value > 100)
357 return -EINVAL; 401 dec->brightness = 100;
402 else if (ctrl->value < 0)
403 dec->brightness = 0;
404 else
405 dec->brightness = ctrl->value;
406 value1 = (dec->brightness - 50) * 255 / 100;
407 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
408 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
409 value1 | (oldvalue & ~0xff));
410 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
411 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
412 value1 | (oldvalue & ~0xff));
413 write_reg_fp(client, 0x140, 0x60);
414 break;
358 case V4L2_CID_CONTRAST: 415 case V4L2_CID_CONTRAST:
359 printk(KERN_INFO "s2250: future setting\n"); 416 if (ctrl->value > 100)
360 return -EINVAL; 417 dec->contrast = 100;
418 else if (ctrl->value < 0)
419 dec->contrast = 0;
420 else
421 dec->contrast = ctrl->value;
422 value1 = dec->contrast * 0x40 / 100;
423 if (value1 > 0x3f)
424 value1 = 0x3f; /* max */
425 read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
426 write_reg_fp(client, VPX322_ADDR_CONTRAST0,
427 value1 | (oldvalue & ~0x3f));
428 read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
429 write_reg_fp(client, VPX322_ADDR_CONTRAST1,
430 value1 | (oldvalue & ~0x3f));
431 write_reg_fp(client, 0x140, 0x60);
361 break; 432 break;
362 case V4L2_CID_SATURATION: 433 case V4L2_CID_SATURATION:
363 if (ctrl->value > 127) 434 if (ctrl->value > 127)
@@ -541,7 +612,7 @@ static int s2250_probe(struct i2c_client *client,
541 dec->audio_input = 0; 612 dec->audio_input = 0;
542 write_reg(client, 0x08, 0x02); /* Line In */ 613 write_reg(client, 0x08, 0x02); /* Line In */
543 614
544 if (down_interruptible(&usb->i2c_lock) == 0) { 615 if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
545 data = kzalloc(16, GFP_KERNEL); 616 data = kzalloc(16, GFP_KERNEL);
546 if (data != NULL) { 617 if (data != NULL) {
547 int rc; 618 int rc;
@@ -560,7 +631,7 @@ static int s2250_probe(struct i2c_client *client,
560 } 631 }
561 kfree(data); 632 kfree(data);
562 } 633 }
563 up(&usb->i2c_lock); 634 mutex_unlock(&usb->i2c_lock);
564 } 635 }
565 636
566 printk("s2250: initialized successfully\n"); 637 printk("s2250: initialized successfully\n");
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
index bb22347af60e..d7bf82983274 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -35,7 +35,7 @@ typedef struct device_extension_s {
35#define MAX_DEVICES 256 35#define MAX_DEVICES 256
36 36
37static pdevice_extension_t s2250_dev_table[MAX_DEVICES]; 37static pdevice_extension_t s2250_dev_table[MAX_DEVICES];
38static DECLARE_MUTEX(s2250_dev_table_mutex); 38static DEFINE_MUTEX(s2250_dev_table_mutex);
39 39
40#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref) 40#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref)
41static void s2250loader_delete(struct kref *kref) 41static void s2250loader_delete(struct kref *kref)
@@ -67,7 +67,7 @@ static int s2250loader_probe(struct usb_interface *interface,
67 printk(KERN_ERR "can't handle multiple config\n"); 67 printk(KERN_ERR "can't handle multiple config\n");
68 return -1; 68 return -1;
69 } 69 }
70 down(&s2250_dev_table_mutex); 70 mutex_lock(&s2250_dev_table_mutex);
71 71
72 for (minor = 0; minor < MAX_DEVICES; minor++) { 72 for (minor = 0; minor < MAX_DEVICES; minor++) {
73 if (s2250_dev_table[minor] == NULL) 73 if (s2250_dev_table[minor] == NULL)
@@ -96,7 +96,7 @@ static int s2250loader_probe(struct usb_interface *interface,
96 96
97 kref_init(&(s->kref)); 97 kref_init(&(s->kref));
98 98
99 up(&s2250_dev_table_mutex); 99 mutex_unlock(&s2250_dev_table_mutex);
100 100
101 if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) { 101 if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
102 printk(KERN_ERR 102 printk(KERN_ERR
@@ -128,7 +128,7 @@ static int s2250loader_probe(struct usb_interface *interface,
128 return 0; 128 return 0;
129 129
130failed: 130failed:
131 up(&s2250_dev_table_mutex); 131 mutex_unlock(&s2250_dev_table_mutex);
132failed2: 132failed2:
133 if (s) 133 if (s)
134 kref_put(&(s->kref), s2250loader_delete); 134 kref_put(&(s->kref), s2250loader_delete);
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
index cd19be6c00e0..03c4dfc138a1 100644
--- a/drivers/staging/go7007/snd-go7007.c
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -26,7 +26,7 @@
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/semaphore.h> 29#include <linux/mutex.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <asm/system.h> 31#include <asm/system.h>
32#include <sound/core.h> 32#include <sound/core.h>
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
index 6c3427bb6f4c..506dca6e942e 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -111,7 +111,8 @@ static int wis_tw9903_command(struct i2c_client *client,
111 i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1)); 111 i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
112 break; 112 break;
113 } 113 }
114#if 0 /* The scaler on this thing seems to be horribly broken */ 114#if 0
115 /* The scaler on this thing seems to be horribly broken */
115 case DECODER_SET_RESOLUTION: 116 case DECODER_SET_RESOLUTION:
116 { 117 {
117 struct video_decoder_resolution *res = arg; 118 struct video_decoder_resolution *res = arg;