diff options
Diffstat (limited to 'drivers/media/pci/cx25821')
24 files changed, 11778 insertions, 0 deletions
diff --git a/drivers/media/pci/cx25821/Kconfig b/drivers/media/pci/cx25821/Kconfig new file mode 100644 index 000000000000..5f6b54213713 --- /dev/null +++ b/drivers/media/pci/cx25821/Kconfig | |||
@@ -0,0 +1,34 @@ | |||
1 | config VIDEO_CX25821 | ||
2 | tristate "Conexant cx25821 support" | ||
3 | depends on DVB_CORE && VIDEO_DEV && PCI && I2C | ||
4 | select I2C_ALGOBIT | ||
5 | select VIDEO_BTCX | ||
6 | select VIDEO_TVEEPROM | ||
7 | depends on RC_CORE | ||
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 | |||
19 | config 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/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile new file mode 100644 index 000000000000..1434e8094803 --- /dev/null +++ b/drivers/media/pci/cx25821/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | cx25821-y := cx25821-core.o cx25821-cards.o cx25821-i2c.o \ | ||
2 | cx25821-gpio.o cx25821-medusa-video.o \ | ||
3 | cx25821-video.o cx25821-video-upstream.o \ | ||
4 | cx25821-video-upstream-ch2.o \ | ||
5 | cx25821-audio-upstream.o | ||
6 | |||
7 | obj-$(CONFIG_VIDEO_CX25821) += cx25821.o | ||
8 | obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o | ||
9 | |||
10 | ccflags-y := -Idrivers/media/video | ||
11 | ccflags-y += -Idrivers/media/tuners | ||
12 | ccflags-y += -Idrivers/media/dvb-core | ||
13 | ccflags-y += -Idrivers/media/dvb-frontends | ||
diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c new file mode 100644 index 000000000000..1858a45dd081 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-alsa.c | |||
@@ -0,0 +1,784 @@ | |||
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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/device.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/vmalloc.h> | ||
30 | #include <linux/dma-mapping.h> | ||
31 | #include <linux/pci.h> | ||
32 | #include <linux/slab.h> | ||
33 | |||
34 | #include <linux/delay.h> | ||
35 | #include <sound/core.h> | ||
36 | #include <sound/pcm.h> | ||
37 | #include <sound/pcm_params.h> | ||
38 | #include <sound/control.h> | ||
39 | #include <sound/initval.h> | ||
40 | #include <sound/tlv.h> | ||
41 | |||
42 | #include "cx25821.h" | ||
43 | #include "cx25821-reg.h" | ||
44 | |||
45 | #define AUDIO_SRAM_CHANNEL SRAM_CH08 | ||
46 | |||
47 | #define dprintk(level, fmt, arg...) \ | ||
48 | do { \ | ||
49 | if (debug >= level) \ | ||
50 | pr_info("%s/1: " fmt, chip->dev->name, ##arg); \ | ||
51 | } while (0) | ||
52 | #define dprintk_core(level, fmt, arg...) \ | ||
53 | do { \ | ||
54 | if (debug >= level) \ | ||
55 | printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name, ##arg); \ | ||
56 | } while (0) | ||
57 | |||
58 | /**************************************************************************** | ||
59 | Data type declarations - Can be moded to a header file later | ||
60 | ****************************************************************************/ | ||
61 | |||
62 | static struct snd_card *snd_cx25821_cards[SNDRV_CARDS]; | ||
63 | static int devno; | ||
64 | |||
65 | struct cx25821_audio_buffer { | ||
66 | unsigned int bpl; | ||
67 | struct btcx_riscmem risc; | ||
68 | struct videobuf_dmabuf dma; | ||
69 | }; | ||
70 | |||
71 | struct cx25821_audio_dev { | ||
72 | struct cx25821_dev *dev; | ||
73 | struct cx25821_dmaqueue q; | ||
74 | |||
75 | /* pci i/o */ | ||
76 | struct pci_dev *pci; | ||
77 | |||
78 | /* audio controls */ | ||
79 | int irq; | ||
80 | |||
81 | struct snd_card *card; | ||
82 | |||
83 | unsigned long iobase; | ||
84 | spinlock_t reg_lock; | ||
85 | atomic_t count; | ||
86 | |||
87 | unsigned int dma_size; | ||
88 | unsigned int period_size; | ||
89 | unsigned int num_periods; | ||
90 | |||
91 | struct videobuf_dmabuf *dma_risc; | ||
92 | |||
93 | struct cx25821_audio_buffer *buf; | ||
94 | |||
95 | struct snd_pcm_substream *substream; | ||
96 | }; | ||
97 | |||
98 | |||
99 | /**************************************************************************** | ||
100 | Module global static vars | ||
101 | ****************************************************************************/ | ||
102 | |||
103 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | ||
104 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | ||
105 | static bool enable[SNDRV_CARDS] = { 1, [1 ... (SNDRV_CARDS - 1)] = 1 }; | ||
106 | |||
107 | module_param_array(enable, bool, NULL, 0444); | ||
108 | MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled."); | ||
109 | |||
110 | module_param_array(index, int, NULL, 0444); | ||
111 | MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s)."); | ||
112 | |||
113 | /**************************************************************************** | ||
114 | Module macros | ||
115 | ****************************************************************************/ | ||
116 | |||
117 | MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards"); | ||
118 | MODULE_AUTHOR("Hiep Huynh"); | ||
119 | MODULE_LICENSE("GPL"); | ||
120 | MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); /* "{{Conexant,23881}," */ | ||
121 | |||
122 | static unsigned int debug; | ||
123 | module_param(debug, int, 0644); | ||
124 | MODULE_PARM_DESC(debug, "enable debug messages"); | ||
125 | |||
126 | /**************************************************************************** | ||
127 | Module specific funtions | ||
128 | ****************************************************************************/ | ||
129 | /* Constants taken from cx88-reg.h */ | ||
130 | #define AUD_INT_DN_RISCI1 (1 << 0) | ||
131 | #define AUD_INT_UP_RISCI1 (1 << 1) | ||
132 | #define AUD_INT_RDS_DN_RISCI1 (1 << 2) | ||
133 | #define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */ | ||
134 | #define AUD_INT_UP_RISCI2 (1 << 5) | ||
135 | #define AUD_INT_RDS_DN_RISCI2 (1 << 6) | ||
136 | #define AUD_INT_DN_SYNC (1 << 12) | ||
137 | #define AUD_INT_UP_SYNC (1 << 13) | ||
138 | #define AUD_INT_RDS_DN_SYNC (1 << 14) | ||
139 | #define AUD_INT_OPC_ERR (1 << 16) | ||
140 | #define AUD_INT_BER_IRQ (1 << 20) | ||
141 | #define AUD_INT_MCHG_IRQ (1 << 21) | ||
142 | #define GP_COUNT_CONTROL_RESET 0x3 | ||
143 | |||
144 | #define PCI_MSK_AUD_EXT (1 << 4) | ||
145 | #define PCI_MSK_AUD_INT (1 << 3) | ||
146 | /* | ||
147 | * BOARD Specific: Sets audio DMA | ||
148 | */ | ||
149 | |||
150 | static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip) | ||
151 | { | ||
152 | struct cx25821_audio_buffer *buf = chip->buf; | ||
153 | struct cx25821_dev *dev = chip->dev; | ||
154 | struct sram_channel *audio_ch = | ||
155 | &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]; | ||
156 | u32 tmp = 0; | ||
157 | |||
158 | /* enable output on the GPIO 0 for the MCLK ADC (Audio) */ | ||
159 | cx25821_set_gpiopin_direction(chip->dev, 0, 0); | ||
160 | |||
161 | /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ | ||
162 | cx_clear(AUD_INT_DMA_CTL, | ||
163 | FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN); | ||
164 | |||
165 | /* setup fifo + format - out channel */ | ||
166 | cx25821_sram_channel_setup_audio(chip->dev, audio_ch, buf->bpl, | ||
167 | buf->risc.dma); | ||
168 | |||
169 | /* sets bpl size */ | ||
170 | cx_write(AUD_A_LNGTH, buf->bpl); | ||
171 | |||
172 | /* reset counter */ | ||
173 | /* GP_COUNT_CONTROL_RESET = 0x3 */ | ||
174 | cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); | ||
175 | atomic_set(&chip->count, 0); | ||
176 | |||
177 | /* Set the input mode to 16-bit */ | ||
178 | tmp = cx_read(AUD_A_CFG); | ||
179 | cx_write(AUD_A_CFG, tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE | | ||
180 | FLD_AUD_CLK_ENABLE); | ||
181 | |||
182 | /* | ||
183 | pr_info("DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d byte buffer\n", | ||
184 | buf->bpl, audio_ch->cmds_start, | ||
185 | cx_read(audio_ch->cmds_start + 12)>>1, | ||
186 | chip->num_periods, buf->bpl * chip->num_periods); | ||
187 | */ | ||
188 | |||
189 | /* Enables corresponding bits at AUD_INT_STAT */ | ||
190 | cx_write(AUD_A_INT_MSK, FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | | ||
191 | FLD_AUD_DST_SYNC | FLD_AUD_DST_OPC_ERR); | ||
192 | |||
193 | /* Clean any pending interrupt bits already set */ | ||
194 | cx_write(AUD_A_INT_STAT, ~0); | ||
195 | |||
196 | /* enable audio irqs */ | ||
197 | cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT); | ||
198 | |||
199 | /* Turn on audio downstream fifo and risc enable 0x101 */ | ||
200 | tmp = cx_read(AUD_INT_DMA_CTL); | ||
201 | cx_set(AUD_INT_DMA_CTL, tmp | | ||
202 | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN)); | ||
203 | |||
204 | mdelay(100); | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * BOARD Specific: Resets audio DMA | ||
210 | */ | ||
211 | static int _cx25821_stop_audio_dma(struct cx25821_audio_dev *chip) | ||
212 | { | ||
213 | struct cx25821_dev *dev = chip->dev; | ||
214 | |||
215 | /* stop dma */ | ||
216 | cx_clear(AUD_INT_DMA_CTL, | ||
217 | FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN); | ||
218 | |||
219 | /* disable irqs */ | ||
220 | cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT); | ||
221 | cx_clear(AUD_A_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | | ||
222 | AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | #define MAX_IRQ_LOOP 50 | ||
228 | |||
229 | /* | ||
230 | * BOARD Specific: IRQ dma bits | ||
231 | */ | ||
232 | static char *cx25821_aud_irqs[32] = { | ||
233 | "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ | ||
234 | NULL, /* reserved */ | ||
235 | "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ | ||
236 | NULL, /* reserved */ | ||
237 | "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */ | ||
238 | NULL, /* reserved */ | ||
239 | "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */ | ||
240 | NULL, /* reserved */ | ||
241 | "opc_err", "par_err", "rip_err", /* 16-18 */ | ||
242 | "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */ | ||
243 | }; | ||
244 | |||
245 | /* | ||
246 | * BOARD Specific: Threats IRQ audio specific calls | ||
247 | */ | ||
248 | static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status, | ||
249 | u32 mask) | ||
250 | { | ||
251 | struct cx25821_dev *dev = chip->dev; | ||
252 | |||
253 | if (0 == (status & mask)) | ||
254 | return; | ||
255 | |||
256 | cx_write(AUD_A_INT_STAT, status); | ||
257 | if (debug > 1 || (status & mask & ~0xff)) | ||
258 | cx25821_print_irqbits(dev->name, "irq aud", cx25821_aud_irqs, | ||
259 | ARRAY_SIZE(cx25821_aud_irqs), status, mask); | ||
260 | |||
261 | /* risc op code error */ | ||
262 | if (status & AUD_INT_OPC_ERR) { | ||
263 | pr_warn("WARNING %s/1: Audio risc op code error\n", dev->name); | ||
264 | |||
265 | cx_clear(AUD_INT_DMA_CTL, | ||
266 | FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN); | ||
267 | cx25821_sram_channel_dump_audio(dev, | ||
268 | &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]); | ||
269 | } | ||
270 | if (status & AUD_INT_DN_SYNC) { | ||
271 | pr_warn("WARNING %s: Downstream sync error!\n", dev->name); | ||
272 | cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); | ||
273 | return; | ||
274 | } | ||
275 | |||
276 | /* risc1 downstream */ | ||
277 | if (status & AUD_INT_DN_RISCI1) { | ||
278 | atomic_set(&chip->count, cx_read(AUD_A_GPCNT)); | ||
279 | snd_pcm_period_elapsed(chip->substream); | ||
280 | } | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * BOARD Specific: Handles IRQ calls | ||
285 | */ | ||
286 | static irqreturn_t cx25821_irq(int irq, void *dev_id) | ||
287 | { | ||
288 | struct cx25821_audio_dev *chip = dev_id; | ||
289 | struct cx25821_dev *dev = chip->dev; | ||
290 | u32 status, pci_status; | ||
291 | u32 audint_status, audint_mask; | ||
292 | int loop, handled = 0; | ||
293 | |||
294 | audint_status = cx_read(AUD_A_INT_STAT); | ||
295 | audint_mask = cx_read(AUD_A_INT_MSK); | ||
296 | status = cx_read(PCI_INT_STAT); | ||
297 | |||
298 | for (loop = 0; loop < 1; loop++) { | ||
299 | status = cx_read(PCI_INT_STAT); | ||
300 | if (0 == status) { | ||
301 | status = cx_read(PCI_INT_STAT); | ||
302 | audint_status = cx_read(AUD_A_INT_STAT); | ||
303 | audint_mask = cx_read(AUD_A_INT_MSK); | ||
304 | |||
305 | if (status) { | ||
306 | handled = 1; | ||
307 | cx_write(PCI_INT_STAT, status); | ||
308 | |||
309 | cx25821_aud_irq(chip, audint_status, | ||
310 | audint_mask); | ||
311 | break; | ||
312 | } else { | ||
313 | goto out; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | handled = 1; | ||
318 | cx_write(PCI_INT_STAT, status); | ||
319 | |||
320 | cx25821_aud_irq(chip, audint_status, audint_mask); | ||
321 | } | ||
322 | |||
323 | pci_status = cx_read(PCI_INT_STAT); | ||
324 | |||
325 | if (handled) | ||
326 | cx_write(PCI_INT_STAT, pci_status); | ||
327 | |||
328 | out: | ||
329 | return IRQ_RETVAL(handled); | ||
330 | } | ||
331 | |||
332 | static int dsp_buffer_free(struct cx25821_audio_dev *chip) | ||
333 | { | ||
334 | BUG_ON(!chip->dma_size); | ||
335 | |||
336 | dprintk(2, "Freeing buffer\n"); | ||
337 | videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc); | ||
338 | videobuf_dma_free(chip->dma_risc); | ||
339 | btcx_riscmem_free(chip->pci, &chip->buf->risc); | ||
340 | kfree(chip->buf); | ||
341 | |||
342 | chip->dma_risc = NULL; | ||
343 | chip->dma_size = 0; | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | /**************************************************************************** | ||
349 | ALSA PCM Interface | ||
350 | ****************************************************************************/ | ||
351 | |||
352 | /* | ||
353 | * Digital hardware definition | ||
354 | */ | ||
355 | #define DEFAULT_FIFO_SIZE 384 | ||
356 | static struct snd_pcm_hardware snd_cx25821_digital_hw = { | ||
357 | .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | ||
358 | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID, | ||
359 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
360 | |||
361 | .rates = SNDRV_PCM_RATE_48000, | ||
362 | .rate_min = 48000, | ||
363 | .rate_max = 48000, | ||
364 | .channels_min = 2, | ||
365 | .channels_max = 2, | ||
366 | /* Analog audio output will be full of clicks and pops if there | ||
367 | are not exactly four lines in the SRAM FIFO buffer. */ | ||
368 | .period_bytes_min = DEFAULT_FIFO_SIZE / 3, | ||
369 | .period_bytes_max = DEFAULT_FIFO_SIZE / 3, | ||
370 | .periods_min = 1, | ||
371 | .periods_max = AUDIO_LINE_SIZE, | ||
372 | /* 128 * 128 = 16384 = 1024 * 16 */ | ||
373 | .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE), | ||
374 | }; | ||
375 | |||
376 | /* | ||
377 | * audio pcm capture open callback | ||
378 | */ | ||
379 | static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream) | ||
380 | { | ||
381 | struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream); | ||
382 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
383 | int err; | ||
384 | unsigned int bpl = 0; | ||
385 | |||
386 | if (!chip) { | ||
387 | pr_err("DEBUG: cx25821 can't find device struct. Can't proceed with open\n"); | ||
388 | return -ENODEV; | ||
389 | } | ||
390 | |||
391 | err = snd_pcm_hw_constraint_pow2(runtime, 0, | ||
392 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
393 | if (err < 0) | ||
394 | goto _error; | ||
395 | |||
396 | chip->substream = substream; | ||
397 | |||
398 | runtime->hw = snd_cx25821_digital_hw; | ||
399 | |||
400 | if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size != | ||
401 | DEFAULT_FIFO_SIZE) { | ||
402 | /* since there are 3 audio Clusters */ | ||
403 | bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3; | ||
404 | bpl &= ~7; /* must be multiple of 8 */ | ||
405 | |||
406 | if (bpl > AUDIO_LINE_SIZE) | ||
407 | bpl = AUDIO_LINE_SIZE; | ||
408 | |||
409 | runtime->hw.period_bytes_min = bpl; | ||
410 | runtime->hw.period_bytes_max = bpl; | ||
411 | } | ||
412 | |||
413 | return 0; | ||
414 | _error: | ||
415 | dprintk(1, "Error opening PCM!\n"); | ||
416 | return err; | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * audio close callback | ||
421 | */ | ||
422 | static int snd_cx25821_close(struct snd_pcm_substream *substream) | ||
423 | { | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | * hw_params callback | ||
429 | */ | ||
430 | static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, | ||
431 | struct snd_pcm_hw_params *hw_params) | ||
432 | { | ||
433 | struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream); | ||
434 | struct videobuf_dmabuf *dma; | ||
435 | |||
436 | struct cx25821_audio_buffer *buf; | ||
437 | int ret; | ||
438 | |||
439 | if (substream->runtime->dma_area) { | ||
440 | dsp_buffer_free(chip); | ||
441 | substream->runtime->dma_area = NULL; | ||
442 | } | ||
443 | |||
444 | chip->period_size = params_period_bytes(hw_params); | ||
445 | chip->num_periods = params_periods(hw_params); | ||
446 | chip->dma_size = chip->period_size * params_periods(hw_params); | ||
447 | |||
448 | BUG_ON(!chip->dma_size); | ||
449 | BUG_ON(chip->num_periods & (chip->num_periods - 1)); | ||
450 | |||
451 | buf = kzalloc(sizeof(*buf), GFP_KERNEL); | ||
452 | if (NULL == buf) | ||
453 | return -ENOMEM; | ||
454 | |||
455 | if (chip->period_size > AUDIO_LINE_SIZE) | ||
456 | chip->period_size = AUDIO_LINE_SIZE; | ||
457 | |||
458 | buf->bpl = chip->period_size; | ||
459 | |||
460 | dma = &buf->dma; | ||
461 | videobuf_dma_init(dma); | ||
462 | ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, | ||
463 | (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); | ||
464 | if (ret < 0) | ||
465 | goto error; | ||
466 | |||
467 | ret = videobuf_dma_map(&chip->pci->dev, dma); | ||
468 | if (ret < 0) | ||
469 | goto error; | ||
470 | |||
471 | ret = cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist, | ||
472 | chip->period_size, chip->num_periods, 1); | ||
473 | if (ret < 0) { | ||
474 | pr_info("DEBUG: ERROR after cx25821_risc_databuffer_audio()\n"); | ||
475 | goto error; | ||
476 | } | ||
477 | |||
478 | /* Loop back to start of program */ | ||
479 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | ||
480 | buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | ||
481 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | ||
482 | |||
483 | chip->buf = buf; | ||
484 | chip->dma_risc = dma; | ||
485 | |||
486 | substream->runtime->dma_area = chip->dma_risc->vaddr; | ||
487 | substream->runtime->dma_bytes = chip->dma_size; | ||
488 | substream->runtime->dma_addr = 0; | ||
489 | |||
490 | return 0; | ||
491 | |||
492 | error: | ||
493 | kfree(buf); | ||
494 | return ret; | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * hw free callback | ||
499 | */ | ||
500 | static int snd_cx25821_hw_free(struct snd_pcm_substream *substream) | ||
501 | { | ||
502 | struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream); | ||
503 | |||
504 | if (substream->runtime->dma_area) { | ||
505 | dsp_buffer_free(chip); | ||
506 | substream->runtime->dma_area = NULL; | ||
507 | } | ||
508 | |||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | /* | ||
513 | * prepare callback | ||
514 | */ | ||
515 | static int snd_cx25821_prepare(struct snd_pcm_substream *substream) | ||
516 | { | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | /* | ||
521 | * trigger callback | ||
522 | */ | ||
523 | static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream, | ||
524 | int cmd) | ||
525 | { | ||
526 | struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream); | ||
527 | int err = 0; | ||
528 | |||
529 | /* Local interrupts are already disabled by ALSA */ | ||
530 | spin_lock(&chip->reg_lock); | ||
531 | |||
532 | switch (cmd) { | ||
533 | case SNDRV_PCM_TRIGGER_START: | ||
534 | err = _cx25821_start_audio_dma(chip); | ||
535 | break; | ||
536 | case SNDRV_PCM_TRIGGER_STOP: | ||
537 | err = _cx25821_stop_audio_dma(chip); | ||
538 | break; | ||
539 | default: | ||
540 | err = -EINVAL; | ||
541 | break; | ||
542 | } | ||
543 | |||
544 | spin_unlock(&chip->reg_lock); | ||
545 | |||
546 | return err; | ||
547 | } | ||
548 | |||
549 | /* | ||
550 | * pointer callback | ||
551 | */ | ||
552 | static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream | ||
553 | *substream) | ||
554 | { | ||
555 | struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream); | ||
556 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
557 | u16 count; | ||
558 | |||
559 | count = atomic_read(&chip->count); | ||
560 | |||
561 | return runtime->period_size * (count & (runtime->periods - 1)); | ||
562 | } | ||
563 | |||
564 | /* | ||
565 | * page callback (needed for mmap) | ||
566 | */ | ||
567 | static struct page *snd_cx25821_page(struct snd_pcm_substream *substream, | ||
568 | unsigned long offset) | ||
569 | { | ||
570 | void *pageptr = substream->runtime->dma_area + offset; | ||
571 | |||
572 | return vmalloc_to_page(pageptr); | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * operators | ||
577 | */ | ||
578 | static struct snd_pcm_ops snd_cx25821_pcm_ops = { | ||
579 | .open = snd_cx25821_pcm_open, | ||
580 | .close = snd_cx25821_close, | ||
581 | .ioctl = snd_pcm_lib_ioctl, | ||
582 | .hw_params = snd_cx25821_hw_params, | ||
583 | .hw_free = snd_cx25821_hw_free, | ||
584 | .prepare = snd_cx25821_prepare, | ||
585 | .trigger = snd_cx25821_card_trigger, | ||
586 | .pointer = snd_cx25821_pointer, | ||
587 | .page = snd_cx25821_page, | ||
588 | }; | ||
589 | |||
590 | /* | ||
591 | * ALSA create a PCM device: Called when initializing the board. | ||
592 | * Sets up the name and hooks up the callbacks | ||
593 | */ | ||
594 | static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device, | ||
595 | char *name) | ||
596 | { | ||
597 | struct snd_pcm *pcm; | ||
598 | int err; | ||
599 | |||
600 | err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); | ||
601 | if (err < 0) { | ||
602 | pr_info("ERROR: FAILED snd_pcm_new() in %s\n", __func__); | ||
603 | return err; | ||
604 | } | ||
605 | pcm->private_data = chip; | ||
606 | pcm->info_flags = 0; | ||
607 | strcpy(pcm->name, name); | ||
608 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx25821_pcm_ops); | ||
609 | |||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | /**************************************************************************** | ||
614 | Basic Flow for Sound Devices | ||
615 | ****************************************************************************/ | ||
616 | |||
617 | /* | ||
618 | * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio | ||
619 | * Only boards with eeprom and byte 1 at eeprom=1 have it | ||
620 | */ | ||
621 | |||
622 | static DEFINE_PCI_DEVICE_TABLE(cx25821_audio_pci_tbl) = { | ||
623 | {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
624 | {0,} | ||
625 | }; | ||
626 | |||
627 | MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl); | ||
628 | |||
629 | /* | ||
630 | * Not used in the function snd_cx25821_dev_free so removing | ||
631 | * from the file. | ||
632 | */ | ||
633 | /* | ||
634 | static int snd_cx25821_free(struct cx25821_audio_dev *chip) | ||
635 | { | ||
636 | if (chip->irq >= 0) | ||
637 | free_irq(chip->irq, chip); | ||
638 | |||
639 | cx25821_dev_unregister(chip->dev); | ||
640 | pci_disable_device(chip->pci); | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | */ | ||
645 | |||
646 | /* | ||
647 | * Component Destructor | ||
648 | */ | ||
649 | static void snd_cx25821_dev_free(struct snd_card *card) | ||
650 | { | ||
651 | struct cx25821_audio_dev *chip = card->private_data; | ||
652 | |||
653 | /* snd_cx25821_free(chip); */ | ||
654 | snd_card_free(chip->card); | ||
655 | } | ||
656 | |||
657 | /* | ||
658 | * Alsa Constructor - Component probe | ||
659 | */ | ||
660 | static int cx25821_audio_initdev(struct cx25821_dev *dev) | ||
661 | { | ||
662 | struct snd_card *card; | ||
663 | struct cx25821_audio_dev *chip; | ||
664 | int err; | ||
665 | |||
666 | if (devno >= SNDRV_CARDS) { | ||
667 | pr_info("DEBUG ERROR: devno >= SNDRV_CARDS %s\n", __func__); | ||
668 | return -ENODEV; | ||
669 | } | ||
670 | |||
671 | if (!enable[devno]) { | ||
672 | ++devno; | ||
673 | pr_info("DEBUG ERROR: !enable[devno] %s\n", __func__); | ||
674 | return -ENOENT; | ||
675 | } | ||
676 | |||
677 | err = snd_card_create(index[devno], id[devno], THIS_MODULE, | ||
678 | sizeof(struct cx25821_audio_dev), &card); | ||
679 | if (err < 0) { | ||
680 | pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n", | ||
681 | __func__); | ||
682 | return err; | ||
683 | } | ||
684 | |||
685 | strcpy(card->driver, "cx25821"); | ||
686 | |||
687 | /* Card "creation" */ | ||
688 | card->private_free = snd_cx25821_dev_free; | ||
689 | chip = card->private_data; | ||
690 | spin_lock_init(&chip->reg_lock); | ||
691 | |||
692 | chip->dev = dev; | ||
693 | chip->card = card; | ||
694 | chip->pci = dev->pci; | ||
695 | chip->iobase = pci_resource_start(dev->pci, 0); | ||
696 | |||
697 | chip->irq = dev->pci->irq; | ||
698 | |||
699 | err = request_irq(dev->pci->irq, cx25821_irq, | ||
700 | IRQF_SHARED, chip->dev->name, chip); | ||
701 | |||
702 | if (err < 0) { | ||
703 | pr_err("ERROR %s: can't get IRQ %d for ALSA\n", chip->dev->name, | ||
704 | dev->pci->irq); | ||
705 | goto error; | ||
706 | } | ||
707 | |||
708 | err = snd_cx25821_pcm(chip, 0, "cx25821 Digital"); | ||
709 | if (err < 0) { | ||
710 | pr_info("DEBUG ERROR: cannot create snd_cx25821_pcm %s\n", | ||
711 | __func__); | ||
712 | goto error; | ||
713 | } | ||
714 | |||
715 | snd_card_set_dev(card, &chip->pci->dev); | ||
716 | |||
717 | strcpy(card->shortname, "cx25821"); | ||
718 | sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name, | ||
719 | chip->iobase, chip->irq); | ||
720 | strcpy(card->mixername, "CX25821"); | ||
721 | |||
722 | pr_info("%s/%i: ALSA support for cx25821 boards\n", card->driver, | ||
723 | devno); | ||
724 | |||
725 | err = snd_card_register(card); | ||
726 | if (err < 0) { | ||
727 | pr_info("DEBUG ERROR: cannot register sound card %s\n", | ||
728 | __func__); | ||
729 | goto error; | ||
730 | } | ||
731 | |||
732 | snd_cx25821_cards[devno] = card; | ||
733 | |||
734 | devno++; | ||
735 | return 0; | ||
736 | |||
737 | error: | ||
738 | snd_card_free(card); | ||
739 | return err; | ||
740 | } | ||
741 | |||
742 | /**************************************************************************** | ||
743 | LINUX MODULE INIT | ||
744 | ****************************************************************************/ | ||
745 | static void cx25821_audio_fini(void) | ||
746 | { | ||
747 | snd_card_free(snd_cx25821_cards[0]); | ||
748 | } | ||
749 | |||
750 | /* | ||
751 | * Module initializer | ||
752 | * | ||
753 | * Loops through present saa7134 cards, and assigns an ALSA device | ||
754 | * to each one | ||
755 | * | ||
756 | */ | ||
757 | static int cx25821_alsa_init(void) | ||
758 | { | ||
759 | struct cx25821_dev *dev = NULL; | ||
760 | struct list_head *list; | ||
761 | |||
762 | mutex_lock(&cx25821_devlist_mutex); | ||
763 | list_for_each(list, &cx25821_devlist) { | ||
764 | dev = list_entry(list, struct cx25821_dev, devlist); | ||
765 | cx25821_audio_initdev(dev); | ||
766 | } | ||
767 | mutex_unlock(&cx25821_devlist_mutex); | ||
768 | |||
769 | if (dev == NULL) | ||
770 | pr_info("ERROR ALSA: no cx25821 cards found\n"); | ||
771 | |||
772 | return 0; | ||
773 | |||
774 | } | ||
775 | |||
776 | late_initcall(cx25821_alsa_init); | ||
777 | module_exit(cx25821_audio_fini); | ||
778 | |||
779 | /* ----------------------------------------------------------- */ | ||
780 | /* | ||
781 | * Local variables: | ||
782 | * c-basic-offset: 8 | ||
783 | * End: | ||
784 | */ | ||
diff --git a/drivers/media/pci/cx25821/cx25821-audio-upstream.c b/drivers/media/pci/cx25821/cx25821-audio-upstream.c new file mode 100644 index 000000000000..8b2a99975c23 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.c | |||
@@ -0,0 +1,778 @@ | |||
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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
25 | #include "cx25821-video.h" | ||
26 | #include "cx25821-audio-upstream.h" | ||
27 | |||
28 | #include <linux/fs.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/syscalls.h> | ||
34 | #include <linux/file.h> | ||
35 | #include <linux/fcntl.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/uaccess.h> | ||
39 | |||
40 | MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); | ||
41 | MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); | ||
42 | MODULE_LICENSE("GPL"); | ||
43 | |||
44 | static int _intr_msk = FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | | ||
45 | FLD_AUD_SRC_SYNC | FLD_AUD_SRC_OPC_ERR; | ||
46 | |||
47 | int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev, | ||
48 | struct sram_channel *ch, | ||
49 | unsigned int bpl, u32 risc) | ||
50 | { | ||
51 | unsigned int i, lines; | ||
52 | u32 cdt; | ||
53 | |||
54 | if (ch->cmds_start == 0) { | ||
55 | cx_write(ch->ptr1_reg, 0); | ||
56 | cx_write(ch->ptr2_reg, 0); | ||
57 | cx_write(ch->cnt2_reg, 0); | ||
58 | cx_write(ch->cnt1_reg, 0); | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | bpl = (bpl + 7) & ~7; /* alignment */ | ||
63 | cdt = ch->cdt; | ||
64 | lines = ch->fifo_size / bpl; | ||
65 | |||
66 | if (lines > 3) | ||
67 | lines = 3; | ||
68 | |||
69 | BUG_ON(lines < 2); | ||
70 | |||
71 | /* write CDT */ | ||
72 | for (i = 0; i < lines; i++) { | ||
73 | cx_write(cdt + 16 * i, ch->fifo_start + bpl * i); | ||
74 | cx_write(cdt + 16 * i + 4, 0); | ||
75 | cx_write(cdt + 16 * i + 8, 0); | ||
76 | cx_write(cdt + 16 * i + 12, 0); | ||
77 | } | ||
78 | |||
79 | /* write CMDS */ | ||
80 | cx_write(ch->cmds_start + 0, risc); | ||
81 | |||
82 | cx_write(ch->cmds_start + 4, 0); | ||
83 | cx_write(ch->cmds_start + 8, cdt); | ||
84 | cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW); | ||
85 | cx_write(ch->cmds_start + 16, ch->ctrl_start); | ||
86 | |||
87 | /* IQ size */ | ||
88 | cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW); | ||
89 | |||
90 | for (i = 24; i < 80; i += 4) | ||
91 | cx_write(ch->cmds_start + i, 0); | ||
92 | |||
93 | /* fill registers */ | ||
94 | cx_write(ch->ptr1_reg, ch->fifo_start); | ||
95 | cx_write(ch->ptr2_reg, cdt); | ||
96 | cx_write(ch->cnt2_reg, AUDIO_CDT_SIZE_QW); | ||
97 | cx_write(ch->cnt1_reg, AUDIO_CLUSTER_SIZE_QW - 1); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev, | ||
103 | __le32 *rp, | ||
104 | dma_addr_t databuf_phys_addr, | ||
105 | unsigned int bpl, | ||
106 | int fifo_enable) | ||
107 | { | ||
108 | unsigned int line; | ||
109 | struct sram_channel *sram_ch = | ||
110 | dev->channels[dev->_audio_upstream_channel].sram_channels; | ||
111 | int offset = 0; | ||
112 | |||
113 | /* scan lines */ | ||
114 | for (line = 0; line < LINES_PER_AUDIO_BUFFER; line++) { | ||
115 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); | ||
116 | *(rp++) = cpu_to_le32(databuf_phys_addr + offset); | ||
117 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
118 | |||
119 | /* Check if we need to enable the FIFO | ||
120 | * after the first 3 lines. | ||
121 | * For the upstream audio channel, | ||
122 | * the risc engine will enable the FIFO */ | ||
123 | if (fifo_enable && line == 2) { | ||
124 | *(rp++) = RISC_WRITECR; | ||
125 | *(rp++) = sram_ch->dma_ctl; | ||
126 | *(rp++) = sram_ch->fld_aud_fifo_en; | ||
127 | *(rp++) = 0x00000020; | ||
128 | } | ||
129 | |||
130 | offset += AUDIO_LINE_SIZE; | ||
131 | } | ||
132 | |||
133 | return rp; | ||
134 | } | ||
135 | |||
136 | int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev, | ||
137 | struct pci_dev *pci, | ||
138 | unsigned int bpl, unsigned int lines) | ||
139 | { | ||
140 | __le32 *rp; | ||
141 | int fifo_enable = 0; | ||
142 | int frame = 0, i = 0; | ||
143 | int frame_size = AUDIO_DATA_BUF_SZ; | ||
144 | int databuf_offset = 0; | ||
145 | int risc_flag = RISC_CNT_INC; | ||
146 | dma_addr_t risc_phys_jump_addr; | ||
147 | |||
148 | /* Virtual address of Risc buffer program */ | ||
149 | rp = dev->_risc_virt_addr; | ||
150 | |||
151 | /* sync instruction */ | ||
152 | *(rp++) = cpu_to_le32(RISC_RESYNC | AUDIO_SYNC_LINE); | ||
153 | |||
154 | for (frame = 0; frame < NUM_AUDIO_FRAMES; frame++) { | ||
155 | databuf_offset = frame_size * frame; | ||
156 | |||
157 | if (frame == 0) { | ||
158 | fifo_enable = 1; | ||
159 | risc_flag = RISC_CNT_RESET; | ||
160 | } else { | ||
161 | fifo_enable = 0; | ||
162 | risc_flag = RISC_CNT_INC; | ||
163 | } | ||
164 | |||
165 | /* Calculate physical jump address */ | ||
166 | if ((frame + 1) == NUM_AUDIO_FRAMES) { | ||
167 | risc_phys_jump_addr = | ||
168 | dev->_risc_phys_start_addr + | ||
169 | RISC_SYNC_INSTRUCTION_SIZE; | ||
170 | } else { | ||
171 | risc_phys_jump_addr = | ||
172 | dev->_risc_phys_start_addr + | ||
173 | RISC_SYNC_INSTRUCTION_SIZE + | ||
174 | AUDIO_RISC_DMA_BUF_SIZE * (frame + 1); | ||
175 | } | ||
176 | |||
177 | rp = cx25821_risc_field_upstream_audio(dev, rp, | ||
178 | dev->_audiodata_buf_phys_addr + databuf_offset, | ||
179 | bpl, fifo_enable); | ||
180 | |||
181 | if (USE_RISC_NOOP_AUDIO) { | ||
182 | for (i = 0; i < NUM_NO_OPS; i++) | ||
183 | *(rp++) = cpu_to_le32(RISC_NOOP); | ||
184 | } | ||
185 | |||
186 | /* Loop to (Nth)FrameRISC or to Start of Risc program & | ||
187 | * generate IRQ */ | ||
188 | *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); | ||
189 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | ||
190 | *(rp++) = cpu_to_le32(0); | ||
191 | |||
192 | /* Recalculate virtual address based on frame index */ | ||
193 | rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 + | ||
194 | (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4); | ||
195 | } | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | void cx25821_free_memory_audio(struct cx25821_dev *dev) | ||
201 | { | ||
202 | if (dev->_risc_virt_addr) { | ||
203 | pci_free_consistent(dev->pci, dev->_audiorisc_size, | ||
204 | dev->_risc_virt_addr, dev->_risc_phys_addr); | ||
205 | dev->_risc_virt_addr = NULL; | ||
206 | } | ||
207 | |||
208 | if (dev->_audiodata_buf_virt_addr) { | ||
209 | pci_free_consistent(dev->pci, dev->_audiodata_buf_size, | ||
210 | dev->_audiodata_buf_virt_addr, | ||
211 | dev->_audiodata_buf_phys_addr); | ||
212 | dev->_audiodata_buf_virt_addr = NULL; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | void cx25821_stop_upstream_audio(struct cx25821_dev *dev) | ||
217 | { | ||
218 | struct sram_channel *sram_ch = | ||
219 | dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels; | ||
220 | u32 tmp = 0; | ||
221 | |||
222 | if (!dev->_audio_is_running) { | ||
223 | printk(KERN_DEBUG | ||
224 | pr_fmt("No audio file is currently running so return!\n")); | ||
225 | return; | ||
226 | } | ||
227 | /* Disable RISC interrupts */ | ||
228 | cx_write(sram_ch->int_msk, 0); | ||
229 | |||
230 | /* Turn OFF risc and fifo enable in AUD_DMA_CNTRL */ | ||
231 | tmp = cx_read(sram_ch->dma_ctl); | ||
232 | cx_write(sram_ch->dma_ctl, | ||
233 | tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en)); | ||
234 | |||
235 | /* Clear data buffer memory */ | ||
236 | if (dev->_audiodata_buf_virt_addr) | ||
237 | memset(dev->_audiodata_buf_virt_addr, 0, | ||
238 | dev->_audiodata_buf_size); | ||
239 | |||
240 | dev->_audio_is_running = 0; | ||
241 | dev->_is_first_audio_frame = 0; | ||
242 | dev->_audioframe_count = 0; | ||
243 | dev->_audiofile_status = END_OF_FILE; | ||
244 | |||
245 | kfree(dev->_irq_audio_queues); | ||
246 | dev->_irq_audio_queues = NULL; | ||
247 | |||
248 | kfree(dev->_audiofilename); | ||
249 | } | ||
250 | |||
251 | void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev) | ||
252 | { | ||
253 | if (dev->_audio_is_running) | ||
254 | cx25821_stop_upstream_audio(dev); | ||
255 | |||
256 | cx25821_free_memory_audio(dev); | ||
257 | } | ||
258 | |||
259 | int cx25821_get_audio_data(struct cx25821_dev *dev, | ||
260 | struct sram_channel *sram_ch) | ||
261 | { | ||
262 | struct file *myfile; | ||
263 | int frame_index_temp = dev->_audioframe_index; | ||
264 | int i = 0; | ||
265 | int line_size = AUDIO_LINE_SIZE; | ||
266 | int frame_size = AUDIO_DATA_BUF_SZ; | ||
267 | int frame_offset = frame_size * frame_index_temp; | ||
268 | ssize_t vfs_read_retval = 0; | ||
269 | char mybuf[line_size]; | ||
270 | loff_t file_offset = dev->_audioframe_count * frame_size; | ||
271 | loff_t pos; | ||
272 | mm_segment_t old_fs; | ||
273 | |||
274 | if (dev->_audiofile_status == END_OF_FILE) | ||
275 | return 0; | ||
276 | |||
277 | myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0); | ||
278 | |||
279 | if (IS_ERR(myfile)) { | ||
280 | const int open_errno = -PTR_ERR(myfile); | ||
281 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | ||
282 | __func__, dev->_audiofilename, open_errno); | ||
283 | return PTR_ERR(myfile); | ||
284 | } else { | ||
285 | if (!(myfile->f_op)) { | ||
286 | pr_err("%s(): File has no file operations registered!\n", | ||
287 | __func__); | ||
288 | filp_close(myfile, NULL); | ||
289 | return -EIO; | ||
290 | } | ||
291 | |||
292 | if (!myfile->f_op->read) { | ||
293 | pr_err("%s(): File has no READ operations registered!\n", | ||
294 | __func__); | ||
295 | filp_close(myfile, NULL); | ||
296 | return -EIO; | ||
297 | } | ||
298 | |||
299 | pos = myfile->f_pos; | ||
300 | old_fs = get_fs(); | ||
301 | set_fs(KERNEL_DS); | ||
302 | |||
303 | for (i = 0; i < dev->_audio_lines_count; i++) { | ||
304 | pos = file_offset; | ||
305 | |||
306 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, | ||
307 | &pos); | ||
308 | |||
309 | if (vfs_read_retval > 0 && vfs_read_retval == line_size | ||
310 | && dev->_audiodata_buf_virt_addr != NULL) { | ||
311 | memcpy((void *)(dev->_audiodata_buf_virt_addr + | ||
312 | frame_offset / 4), mybuf, | ||
313 | vfs_read_retval); | ||
314 | } | ||
315 | |||
316 | file_offset += vfs_read_retval; | ||
317 | frame_offset += vfs_read_retval; | ||
318 | |||
319 | if (vfs_read_retval < line_size) { | ||
320 | pr_info("Done: exit %s() since no more bytes to read from Audio file\n", | ||
321 | __func__); | ||
322 | break; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | if (i > 0) | ||
327 | dev->_audioframe_count++; | ||
328 | |||
329 | dev->_audiofile_status = (vfs_read_retval == line_size) ? | ||
330 | IN_PROGRESS : END_OF_FILE; | ||
331 | |||
332 | set_fs(old_fs); | ||
333 | filp_close(myfile, NULL); | ||
334 | } | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static void cx25821_audioups_handler(struct work_struct *work) | ||
340 | { | ||
341 | struct cx25821_dev *dev = container_of(work, struct cx25821_dev, | ||
342 | _audio_work_entry); | ||
343 | |||
344 | if (!dev) { | ||
345 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", | ||
346 | __func__); | ||
347 | return; | ||
348 | } | ||
349 | |||
350 | cx25821_get_audio_data(dev, dev->channels[dev->_audio_upstream_channel]. | ||
351 | sram_channels); | ||
352 | } | ||
353 | |||
354 | int cx25821_openfile_audio(struct cx25821_dev *dev, | ||
355 | struct sram_channel *sram_ch) | ||
356 | { | ||
357 | struct file *myfile; | ||
358 | int i = 0, j = 0; | ||
359 | int line_size = AUDIO_LINE_SIZE; | ||
360 | ssize_t vfs_read_retval = 0; | ||
361 | char mybuf[line_size]; | ||
362 | loff_t pos; | ||
363 | loff_t offset = (unsigned long)0; | ||
364 | mm_segment_t old_fs; | ||
365 | |||
366 | myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0); | ||
367 | |||
368 | if (IS_ERR(myfile)) { | ||
369 | const int open_errno = -PTR_ERR(myfile); | ||
370 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | ||
371 | __func__, dev->_audiofilename, open_errno); | ||
372 | return PTR_ERR(myfile); | ||
373 | } else { | ||
374 | if (!(myfile->f_op)) { | ||
375 | pr_err("%s(): File has no file operations registered!\n", | ||
376 | __func__); | ||
377 | filp_close(myfile, NULL); | ||
378 | return -EIO; | ||
379 | } | ||
380 | |||
381 | if (!myfile->f_op->read) { | ||
382 | pr_err("%s(): File has no READ operations registered!\n", | ||
383 | __func__); | ||
384 | filp_close(myfile, NULL); | ||
385 | return -EIO; | ||
386 | } | ||
387 | |||
388 | pos = myfile->f_pos; | ||
389 | old_fs = get_fs(); | ||
390 | set_fs(KERNEL_DS); | ||
391 | |||
392 | for (j = 0; j < NUM_AUDIO_FRAMES; j++) { | ||
393 | for (i = 0; i < dev->_audio_lines_count; i++) { | ||
394 | pos = offset; | ||
395 | |||
396 | vfs_read_retval = vfs_read(myfile, mybuf, | ||
397 | line_size, &pos); | ||
398 | |||
399 | if (vfs_read_retval > 0 && | ||
400 | vfs_read_retval == line_size && | ||
401 | dev->_audiodata_buf_virt_addr != NULL) { | ||
402 | memcpy((void *)(dev-> | ||
403 | _audiodata_buf_virt_addr | ||
404 | + offset / 4), mybuf, | ||
405 | vfs_read_retval); | ||
406 | } | ||
407 | |||
408 | offset += vfs_read_retval; | ||
409 | |||
410 | if (vfs_read_retval < line_size) { | ||
411 | pr_info("Done: exit %s() since no more bytes to read from Audio file\n", | ||
412 | __func__); | ||
413 | break; | ||
414 | } | ||
415 | } | ||
416 | |||
417 | if (i > 0) | ||
418 | dev->_audioframe_count++; | ||
419 | |||
420 | if (vfs_read_retval < line_size) | ||
421 | break; | ||
422 | } | ||
423 | |||
424 | dev->_audiofile_status = (vfs_read_retval == line_size) ? | ||
425 | IN_PROGRESS : END_OF_FILE; | ||
426 | |||
427 | set_fs(old_fs); | ||
428 | myfile->f_pos = 0; | ||
429 | filp_close(myfile, NULL); | ||
430 | } | ||
431 | |||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, | ||
436 | struct sram_channel *sram_ch, | ||
437 | int bpl) | ||
438 | { | ||
439 | int ret = 0; | ||
440 | dma_addr_t dma_addr; | ||
441 | dma_addr_t data_dma_addr; | ||
442 | |||
443 | cx25821_free_memory_audio(dev); | ||
444 | |||
445 | dev->_risc_virt_addr = pci_alloc_consistent(dev->pci, | ||
446 | dev->audio_upstream_riscbuf_size, &dma_addr); | ||
447 | dev->_risc_virt_start_addr = dev->_risc_virt_addr; | ||
448 | dev->_risc_phys_start_addr = dma_addr; | ||
449 | dev->_risc_phys_addr = dma_addr; | ||
450 | dev->_audiorisc_size = dev->audio_upstream_riscbuf_size; | ||
451 | |||
452 | if (!dev->_risc_virt_addr) { | ||
453 | printk(KERN_DEBUG | ||
454 | pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n")); | ||
455 | return -ENOMEM; | ||
456 | } | ||
457 | /* Clear out memory at address */ | ||
458 | memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size); | ||
459 | |||
460 | /* For Audio Data buffer allocation */ | ||
461 | dev->_audiodata_buf_virt_addr = pci_alloc_consistent(dev->pci, | ||
462 | dev->audio_upstream_databuf_size, &data_dma_addr); | ||
463 | dev->_audiodata_buf_phys_addr = data_dma_addr; | ||
464 | dev->_audiodata_buf_size = dev->audio_upstream_databuf_size; | ||
465 | |||
466 | if (!dev->_audiodata_buf_virt_addr) { | ||
467 | printk(KERN_DEBUG | ||
468 | pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n")); | ||
469 | return -ENOMEM; | ||
470 | } | ||
471 | /* Clear out memory at address */ | ||
472 | memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size); | ||
473 | |||
474 | ret = cx25821_openfile_audio(dev, sram_ch); | ||
475 | if (ret < 0) | ||
476 | return ret; | ||
477 | |||
478 | /* Creating RISC programs */ | ||
479 | ret = cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl, | ||
480 | dev->_audio_lines_count); | ||
481 | if (ret < 0) { | ||
482 | printk(KERN_DEBUG | ||
483 | pr_fmt("ERROR creating audio upstream RISC programs!\n")); | ||
484 | goto error; | ||
485 | } | ||
486 | |||
487 | return 0; | ||
488 | |||
489 | error: | ||
490 | return ret; | ||
491 | } | ||
492 | |||
493 | int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num, | ||
494 | u32 status) | ||
495 | { | ||
496 | int i = 0; | ||
497 | u32 int_msk_tmp; | ||
498 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; | ||
499 | dma_addr_t risc_phys_jump_addr; | ||
500 | __le32 *rp; | ||
501 | |||
502 | if (status & FLD_AUD_SRC_RISCI1) { | ||
503 | /* Get interrupt_index of the program that interrupted */ | ||
504 | u32 prog_cnt = cx_read(channel->gpcnt); | ||
505 | |||
506 | /* Since we've identified our IRQ, clear our bits from the | ||
507 | * interrupt mask and interrupt status registers */ | ||
508 | cx_write(channel->int_msk, 0); | ||
509 | cx_write(channel->int_stat, cx_read(channel->int_stat)); | ||
510 | |||
511 | spin_lock(&dev->slock); | ||
512 | |||
513 | while (prog_cnt != dev->_last_index_irq) { | ||
514 | /* Update _last_index_irq */ | ||
515 | if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1)) | ||
516 | dev->_last_index_irq++; | ||
517 | else | ||
518 | dev->_last_index_irq = 0; | ||
519 | |||
520 | dev->_audioframe_index = dev->_last_index_irq; | ||
521 | |||
522 | queue_work(dev->_irq_audio_queues, | ||
523 | &dev->_audio_work_entry); | ||
524 | } | ||
525 | |||
526 | if (dev->_is_first_audio_frame) { | ||
527 | dev->_is_first_audio_frame = 0; | ||
528 | |||
529 | if (dev->_risc_virt_start_addr != NULL) { | ||
530 | risc_phys_jump_addr = | ||
531 | dev->_risc_phys_start_addr + | ||
532 | RISC_SYNC_INSTRUCTION_SIZE + | ||
533 | AUDIO_RISC_DMA_BUF_SIZE; | ||
534 | |||
535 | rp = cx25821_risc_field_upstream_audio(dev, | ||
536 | dev->_risc_virt_start_addr + 1, | ||
537 | dev->_audiodata_buf_phys_addr, | ||
538 | AUDIO_LINE_SIZE, FIFO_DISABLE); | ||
539 | |||
540 | if (USE_RISC_NOOP_AUDIO) { | ||
541 | for (i = 0; i < NUM_NO_OPS; i++) { | ||
542 | *(rp++) = | ||
543 | cpu_to_le32(RISC_NOOP); | ||
544 | } | ||
545 | } | ||
546 | /* Jump to 2nd Audio Frame */ | ||
547 | *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | | ||
548 | RISC_CNT_RESET); | ||
549 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | ||
550 | *(rp++) = cpu_to_le32(0); | ||
551 | } | ||
552 | } | ||
553 | |||
554 | spin_unlock(&dev->slock); | ||
555 | } else { | ||
556 | if (status & FLD_AUD_SRC_OF) | ||
557 | pr_warn("%s(): Audio Received Overflow Error Interrupt!\n", | ||
558 | __func__); | ||
559 | |||
560 | if (status & FLD_AUD_SRC_SYNC) | ||
561 | pr_warn("%s(): Audio Received Sync Error Interrupt!\n", | ||
562 | __func__); | ||
563 | |||
564 | if (status & FLD_AUD_SRC_OPC_ERR) | ||
565 | pr_warn("%s(): Audio Received OpCode Error Interrupt!\n", | ||
566 | __func__); | ||
567 | |||
568 | /* Read and write back the interrupt status register to clear | ||
569 | * our bits */ | ||
570 | cx_write(channel->int_stat, cx_read(channel->int_stat)); | ||
571 | } | ||
572 | |||
573 | if (dev->_audiofile_status == END_OF_FILE) { | ||
574 | pr_warn("EOF Channel Audio Framecount = %d\n", | ||
575 | dev->_audioframe_count); | ||
576 | return -1; | ||
577 | } | ||
578 | /* ElSE, set the interrupt mask register, re-enable irq. */ | ||
579 | int_msk_tmp = cx_read(channel->int_msk); | ||
580 | cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); | ||
581 | |||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id) | ||
586 | { | ||
587 | struct cx25821_dev *dev = dev_id; | ||
588 | u32 audio_status; | ||
589 | int handled = 0; | ||
590 | struct sram_channel *sram_ch; | ||
591 | |||
592 | if (!dev) | ||
593 | return -1; | ||
594 | |||
595 | sram_ch = dev->channels[dev->_audio_upstream_channel].sram_channels; | ||
596 | |||
597 | audio_status = cx_read(sram_ch->int_stat); | ||
598 | |||
599 | /* Only deal with our interrupt */ | ||
600 | if (audio_status) { | ||
601 | handled = cx25821_audio_upstream_irq(dev, | ||
602 | dev->_audio_upstream_channel, audio_status); | ||
603 | } | ||
604 | |||
605 | if (handled < 0) | ||
606 | cx25821_stop_upstream_audio(dev); | ||
607 | else | ||
608 | handled += handled; | ||
609 | |||
610 | return IRQ_RETVAL(handled); | ||
611 | } | ||
612 | |||
613 | static void cx25821_wait_fifo_enable(struct cx25821_dev *dev, | ||
614 | struct sram_channel *sram_ch) | ||
615 | { | ||
616 | int count = 0; | ||
617 | u32 tmp; | ||
618 | |||
619 | do { | ||
620 | /* Wait 10 microsecond before checking to see if the FIFO is | ||
621 | * turned ON. */ | ||
622 | udelay(10); | ||
623 | |||
624 | tmp = cx_read(sram_ch->dma_ctl); | ||
625 | |||
626 | /* 10 millisecond timeout */ | ||
627 | if (count++ > 1000) { | ||
628 | pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n", | ||
629 | __func__); | ||
630 | return; | ||
631 | } | ||
632 | |||
633 | } while (!(tmp & sram_ch->fld_aud_fifo_en)); | ||
634 | |||
635 | } | ||
636 | |||
637 | int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, | ||
638 | struct sram_channel *sram_ch) | ||
639 | { | ||
640 | u32 tmp = 0; | ||
641 | int err = 0; | ||
642 | |||
643 | /* Set the physical start address of the RISC program in the initial | ||
644 | * program counter(IPC) member of the CMDS. */ | ||
645 | cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr); | ||
646 | /* Risc IPC High 64 bits 63-32 */ | ||
647 | cx_write(sram_ch->cmds_start + 4, 0); | ||
648 | |||
649 | /* reset counter */ | ||
650 | cx_write(sram_ch->gpcnt_ctl, 3); | ||
651 | |||
652 | /* Set the line length (It looks like we do not need to set the | ||
653 | * line length) */ | ||
654 | cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH); | ||
655 | |||
656 | /* Set the input mode to 16-bit */ | ||
657 | tmp = cx_read(sram_ch->aud_cfg); | ||
658 | tmp |= FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | | ||
659 | FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | | ||
660 | FLD_AUD_SONY_MODE; | ||
661 | cx_write(sram_ch->aud_cfg, tmp); | ||
662 | |||
663 | /* Read and write back the interrupt status register to clear it */ | ||
664 | tmp = cx_read(sram_ch->int_stat); | ||
665 | cx_write(sram_ch->int_stat, tmp); | ||
666 | |||
667 | /* Clear our bits from the interrupt status register. */ | ||
668 | cx_write(sram_ch->int_stat, _intr_msk); | ||
669 | |||
670 | /* Set the interrupt mask register, enable irq. */ | ||
671 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); | ||
672 | tmp = cx_read(sram_ch->int_msk); | ||
673 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | ||
674 | |||
675 | err = request_irq(dev->pci->irq, cx25821_upstream_irq_audio, | ||
676 | IRQF_SHARED, dev->name, dev); | ||
677 | if (err < 0) { | ||
678 | pr_err("%s: can't get upstream IRQ %d\n", dev->name, | ||
679 | dev->pci->irq); | ||
680 | goto fail_irq; | ||
681 | } | ||
682 | |||
683 | /* Start the DMA engine */ | ||
684 | tmp = cx_read(sram_ch->dma_ctl); | ||
685 | cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en); | ||
686 | |||
687 | dev->_audio_is_running = 1; | ||
688 | dev->_is_first_audio_frame = 1; | ||
689 | |||
690 | /* The fifo_en bit turns on by the first Risc program */ | ||
691 | cx25821_wait_fifo_enable(dev, sram_ch); | ||
692 | |||
693 | return 0; | ||
694 | |||
695 | fail_irq: | ||
696 | cx25821_dev_unregister(dev); | ||
697 | return err; | ||
698 | } | ||
699 | |||
700 | int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) | ||
701 | { | ||
702 | struct sram_channel *sram_ch; | ||
703 | int retval = 0; | ||
704 | int err = 0; | ||
705 | int str_length = 0; | ||
706 | |||
707 | if (dev->_audio_is_running) { | ||
708 | pr_warn("Audio Channel is still running so return!\n"); | ||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | dev->_audio_upstream_channel = channel_select; | ||
713 | sram_ch = dev->channels[channel_select].sram_channels; | ||
714 | |||
715 | /* Work queue */ | ||
716 | INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler); | ||
717 | dev->_irq_audio_queues = | ||
718 | create_singlethread_workqueue("cx25821_audioworkqueue"); | ||
719 | |||
720 | if (!dev->_irq_audio_queues) { | ||
721 | printk(KERN_DEBUG | ||
722 | pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n")); | ||
723 | return -ENOMEM; | ||
724 | } | ||
725 | |||
726 | dev->_last_index_irq = 0; | ||
727 | dev->_audio_is_running = 0; | ||
728 | dev->_audioframe_count = 0; | ||
729 | dev->_audiofile_status = RESET_STATUS; | ||
730 | dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER; | ||
731 | _line_size = AUDIO_LINE_SIZE; | ||
732 | |||
733 | if (dev->input_audiofilename) { | ||
734 | str_length = strlen(dev->input_audiofilename); | ||
735 | dev->_audiofilename = kmemdup(dev->input_audiofilename, | ||
736 | str_length + 1, GFP_KERNEL); | ||
737 | |||
738 | if (!dev->_audiofilename) | ||
739 | goto error; | ||
740 | |||
741 | /* Default if filename is empty string */ | ||
742 | if (strcmp(dev->input_audiofilename, "") == 0) | ||
743 | dev->_audiofilename = "/root/audioGOOD.wav"; | ||
744 | } else { | ||
745 | str_length = strlen(_defaultAudioName); | ||
746 | dev->_audiofilename = kmemdup(_defaultAudioName, | ||
747 | str_length + 1, GFP_KERNEL); | ||
748 | |||
749 | if (!dev->_audiofilename) | ||
750 | goto error; | ||
751 | } | ||
752 | |||
753 | retval = cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, | ||
754 | _line_size, 0); | ||
755 | |||
756 | dev->audio_upstream_riscbuf_size = | ||
757 | AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS + | ||
758 | RISC_SYNC_INSTRUCTION_SIZE; | ||
759 | dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS; | ||
760 | |||
761 | /* Allocating buffers and prepare RISC program */ | ||
762 | retval = cx25821_audio_upstream_buffer_prepare(dev, sram_ch, | ||
763 | _line_size); | ||
764 | if (retval < 0) { | ||
765 | pr_err("%s: Failed to set up Audio upstream buffers!\n", | ||
766 | dev->name); | ||
767 | goto error; | ||
768 | } | ||
769 | /* Start RISC engine */ | ||
770 | cx25821_start_audio_dma_upstream(dev, sram_ch); | ||
771 | |||
772 | return 0; | ||
773 | |||
774 | error: | ||
775 | cx25821_dev_unregister(dev); | ||
776 | |||
777 | return err; | ||
778 | } | ||
diff --git a/drivers/media/pci/cx25821/cx25821-audio-upstream.h b/drivers/media/pci/cx25821/cx25821-audio-upstream.h new file mode 100644 index 000000000000..af2ae7c5815a --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Driver for the Conexant CX25821 PCIe bridge | ||
3 | * | ||
4 | * Copyright (C) 2009 Conexant Systems Inc. | ||
5 | * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/mutex.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | |||
26 | #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 \ | ||
50 | (LINES_PER_AUDIO_BUFFER * RISC_READ_INSTRUCTION_SIZE + \ | ||
51 | RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS * DWORD_SIZE + \ | ||
52 | RISC_JUMP_INSTRUCTION_SIZE) | ||
53 | #endif | ||
54 | |||
55 | #ifndef USE_RISC_NOOP_AUDIO | ||
56 | #define AUDIO_RISC_DMA_BUF_SIZE \ | ||
57 | (LINES_PER_AUDIO_BUFFER * RISC_READ_INSTRUCTION_SIZE + \ | ||
58 | RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE) | ||
59 | #endif | ||
60 | |||
61 | static int _line_size; | ||
62 | char *_defaultAudioName = "/root/audioGOOD.wav"; | ||
diff --git a/drivers/media/pci/cx25821/cx25821-audio.h b/drivers/media/pci/cx25821/cx25821-audio.h new file mode 100644 index 000000000000..1fc2d24f5110 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-audio.h | |||
@@ -0,0 +1,62 @@ | |||
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 | /* | ||
34 | * Max size of the RISC program for a buffer. - worst case is 2 writes per line | ||
35 | * Space is also added for the 4 no-op instructions added on the end. | ||
36 | */ | ||
37 | #ifndef USE_RISC_NOOP | ||
38 | #define MAX_BUFFER_PROGRAM_SIZE \ | ||
39 | (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ | ||
40 | RISC_WRITECR_INSTRUCTION_SIZE * 4) | ||
41 | #endif | ||
42 | |||
43 | /* MAE 12 July 2005 Try to use NOOP RISC instruction instead */ | ||
44 | #ifdef USE_RISC_NOOP | ||
45 | #define MAX_BUFFER_PROGRAM_SIZE \ | ||
46 | (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ | ||
47 | RISC_NOOP_INSTRUCTION_SIZE * 4) | ||
48 | #endif | ||
49 | |||
50 | /* Sizes of various instructions in bytes. Used when adding instructions. */ | ||
51 | #define RISC_WRITE_INSTRUCTION_SIZE 12 | ||
52 | #define RISC_JUMP_INSTRUCTION_SIZE 12 | ||
53 | #define RISC_SKIP_INSTRUCTION_SIZE 4 | ||
54 | #define RISC_SYNC_INSTRUCTION_SIZE 4 | ||
55 | #define RISC_WRITECR_INSTRUCTION_SIZE 16 | ||
56 | #define RISC_NOOP_INSTRUCTION_SIZE 4 | ||
57 | |||
58 | #define MAX_AUDIO_DMA_BUFFER_SIZE \ | ||
59 | (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + \ | ||
60 | RISC_SYNC_INSTRUCTION_SIZE) | ||
61 | |||
62 | #endif | ||
diff --git a/drivers/media/pci/cx25821/cx25821-biffuncs.h b/drivers/media/pci/cx25821/cx25821-biffuncs.h new file mode 100644 index 000000000000..9326a7c729ec --- /dev/null +++ b/drivers/media/pci/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 | |||
28 | inline u8 getBit(u32 sample, u8 index) | ||
29 | { | ||
30 | return (u8) ((sample >> index) & 1); | ||
31 | } | ||
32 | |||
33 | inline u32 clearBitAtPos(u32 value, u8 bit) | ||
34 | { | ||
35 | return value & ~(1 << bit); | ||
36 | } | ||
37 | |||
38 | inline u32 setBitAtPos(u32 sample, u8 bit) | ||
39 | { | ||
40 | sample |= (1 << bit); | ||
41 | return sample; | ||
42 | |||
43 | } | ||
44 | |||
45 | #endif | ||
diff --git a/drivers/media/pci/cx25821/cx25821-cards.c b/drivers/media/pci/cx25821/cx25821-cards.c new file mode 100644 index 000000000000..99988c988095 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-cards.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Driver for the Conexant CX25821 PCIe bridge | ||
3 | * | ||
4 | * Copyright (C) 2009 Conexant Systems Inc. | ||
5 | * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com> | ||
6 | * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
25 | |||
26 | #include <linux/init.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <media/cx25840.h> | ||
31 | |||
32 | #include "cx25821.h" | ||
33 | #include "tuner-xc2028.h" | ||
34 | |||
35 | /* board config info */ | ||
36 | |||
37 | struct cx25821_board cx25821_boards[] = { | ||
38 | [UNKNOWN_BOARD] = { | ||
39 | .name = "UNKNOWN/GENERIC", | ||
40 | /* Ensure safe default for unknown boards */ | ||
41 | .clk_freq = 0, | ||
42 | }, | ||
43 | |||
44 | [CX25821_BOARD] = { | ||
45 | .name = "CX25821", | ||
46 | .portb = CX25821_RAW, | ||
47 | .portc = CX25821_264, | ||
48 | .input[0].type = CX25821_VMUX_COMPOSITE, | ||
49 | }, | ||
50 | |||
51 | }; | ||
52 | |||
53 | const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards); | ||
54 | |||
55 | struct cx25821_subid cx25821_subids[] = { | ||
56 | { | ||
57 | .subvendor = 0x14f1, | ||
58 | .subdevice = 0x0920, | ||
59 | .card = CX25821_BOARD, | ||
60 | }, | ||
61 | }; | ||
62 | |||
63 | void cx25821_card_setup(struct cx25821_dev *dev) | ||
64 | { | ||
65 | static u8 eeprom[256]; | ||
66 | |||
67 | if (dev->i2c_bus[0].i2c_rc == 0) { | ||
68 | dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; | ||
69 | tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, | ||
70 | sizeof(eeprom)); | ||
71 | } | ||
72 | } | ||
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c new file mode 100644 index 000000000000..f11f6f07e915 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-core.c | |||
@@ -0,0 +1,1502 @@ | |||
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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
25 | |||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include "cx25821.h" | ||
29 | #include "cx25821-sram.h" | ||
30 | #include "cx25821-video.h" | ||
31 | |||
32 | MODULE_DESCRIPTION("Driver for Athena cards"); | ||
33 | MODULE_AUTHOR("Shu Lin - Hiep Huynh"); | ||
34 | MODULE_LICENSE("GPL"); | ||
35 | |||
36 | static unsigned int debug; | ||
37 | module_param(debug, int, 0644); | ||
38 | MODULE_PARM_DESC(debug, "enable debug messages"); | ||
39 | |||
40 | static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET }; | ||
41 | module_param_array(card, int, NULL, 0444); | ||
42 | MODULE_PARM_DESC(card, "card type"); | ||
43 | |||
44 | static unsigned int cx25821_devcount; | ||
45 | |||
46 | DEFINE_MUTEX(cx25821_devlist_mutex); | ||
47 | EXPORT_SYMBOL(cx25821_devlist_mutex); | ||
48 | LIST_HEAD(cx25821_devlist); | ||
49 | EXPORT_SYMBOL(cx25821_devlist); | ||
50 | |||
51 | struct sram_channel cx25821_sram_channels[] = { | ||
52 | [SRAM_CH00] = { | ||
53 | .i = SRAM_CH00, | ||
54 | .name = "VID A", | ||
55 | .cmds_start = VID_A_DOWN_CMDS, | ||
56 | .ctrl_start = VID_A_IQ, | ||
57 | .cdt = VID_A_CDT, | ||
58 | .fifo_start = VID_A_DOWN_CLUSTER_1, | ||
59 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
60 | .ptr1_reg = DMA1_PTR1, | ||
61 | .ptr2_reg = DMA1_PTR2, | ||
62 | .cnt1_reg = DMA1_CNT1, | ||
63 | .cnt2_reg = DMA1_CNT2, | ||
64 | .int_msk = VID_A_INT_MSK, | ||
65 | .int_stat = VID_A_INT_STAT, | ||
66 | .int_mstat = VID_A_INT_MSTAT, | ||
67 | .dma_ctl = VID_DST_A_DMA_CTL, | ||
68 | .gpcnt_ctl = VID_DST_A_GPCNT_CTL, | ||
69 | .gpcnt = VID_DST_A_GPCNT, | ||
70 | .vip_ctl = VID_DST_A_VIP_CTL, | ||
71 | .pix_frmt = VID_DST_A_PIX_FRMT, | ||
72 | }, | ||
73 | |||
74 | [SRAM_CH01] = { | ||
75 | .i = SRAM_CH01, | ||
76 | .name = "VID B", | ||
77 | .cmds_start = VID_B_DOWN_CMDS, | ||
78 | .ctrl_start = VID_B_IQ, | ||
79 | .cdt = VID_B_CDT, | ||
80 | .fifo_start = VID_B_DOWN_CLUSTER_1, | ||
81 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
82 | .ptr1_reg = DMA2_PTR1, | ||
83 | .ptr2_reg = DMA2_PTR2, | ||
84 | .cnt1_reg = DMA2_CNT1, | ||
85 | .cnt2_reg = DMA2_CNT2, | ||
86 | .int_msk = VID_B_INT_MSK, | ||
87 | .int_stat = VID_B_INT_STAT, | ||
88 | .int_mstat = VID_B_INT_MSTAT, | ||
89 | .dma_ctl = VID_DST_B_DMA_CTL, | ||
90 | .gpcnt_ctl = VID_DST_B_GPCNT_CTL, | ||
91 | .gpcnt = VID_DST_B_GPCNT, | ||
92 | .vip_ctl = VID_DST_B_VIP_CTL, | ||
93 | .pix_frmt = VID_DST_B_PIX_FRMT, | ||
94 | }, | ||
95 | |||
96 | [SRAM_CH02] = { | ||
97 | .i = SRAM_CH02, | ||
98 | .name = "VID C", | ||
99 | .cmds_start = VID_C_DOWN_CMDS, | ||
100 | .ctrl_start = VID_C_IQ, | ||
101 | .cdt = VID_C_CDT, | ||
102 | .fifo_start = VID_C_DOWN_CLUSTER_1, | ||
103 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
104 | .ptr1_reg = DMA3_PTR1, | ||
105 | .ptr2_reg = DMA3_PTR2, | ||
106 | .cnt1_reg = DMA3_CNT1, | ||
107 | .cnt2_reg = DMA3_CNT2, | ||
108 | .int_msk = VID_C_INT_MSK, | ||
109 | .int_stat = VID_C_INT_STAT, | ||
110 | .int_mstat = VID_C_INT_MSTAT, | ||
111 | .dma_ctl = VID_DST_C_DMA_CTL, | ||
112 | .gpcnt_ctl = VID_DST_C_GPCNT_CTL, | ||
113 | .gpcnt = VID_DST_C_GPCNT, | ||
114 | .vip_ctl = VID_DST_C_VIP_CTL, | ||
115 | .pix_frmt = VID_DST_C_PIX_FRMT, | ||
116 | }, | ||
117 | |||
118 | [SRAM_CH03] = { | ||
119 | .i = SRAM_CH03, | ||
120 | .name = "VID D", | ||
121 | .cmds_start = VID_D_DOWN_CMDS, | ||
122 | .ctrl_start = VID_D_IQ, | ||
123 | .cdt = VID_D_CDT, | ||
124 | .fifo_start = VID_D_DOWN_CLUSTER_1, | ||
125 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
126 | .ptr1_reg = DMA4_PTR1, | ||
127 | .ptr2_reg = DMA4_PTR2, | ||
128 | .cnt1_reg = DMA4_CNT1, | ||
129 | .cnt2_reg = DMA4_CNT2, | ||
130 | .int_msk = VID_D_INT_MSK, | ||
131 | .int_stat = VID_D_INT_STAT, | ||
132 | .int_mstat = VID_D_INT_MSTAT, | ||
133 | .dma_ctl = VID_DST_D_DMA_CTL, | ||
134 | .gpcnt_ctl = VID_DST_D_GPCNT_CTL, | ||
135 | .gpcnt = VID_DST_D_GPCNT, | ||
136 | .vip_ctl = VID_DST_D_VIP_CTL, | ||
137 | .pix_frmt = VID_DST_D_PIX_FRMT, | ||
138 | }, | ||
139 | |||
140 | [SRAM_CH04] = { | ||
141 | .i = SRAM_CH04, | ||
142 | .name = "VID E", | ||
143 | .cmds_start = VID_E_DOWN_CMDS, | ||
144 | .ctrl_start = VID_E_IQ, | ||
145 | .cdt = VID_E_CDT, | ||
146 | .fifo_start = VID_E_DOWN_CLUSTER_1, | ||
147 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
148 | .ptr1_reg = DMA5_PTR1, | ||
149 | .ptr2_reg = DMA5_PTR2, | ||
150 | .cnt1_reg = DMA5_CNT1, | ||
151 | .cnt2_reg = DMA5_CNT2, | ||
152 | .int_msk = VID_E_INT_MSK, | ||
153 | .int_stat = VID_E_INT_STAT, | ||
154 | .int_mstat = VID_E_INT_MSTAT, | ||
155 | .dma_ctl = VID_DST_E_DMA_CTL, | ||
156 | .gpcnt_ctl = VID_DST_E_GPCNT_CTL, | ||
157 | .gpcnt = VID_DST_E_GPCNT, | ||
158 | .vip_ctl = VID_DST_E_VIP_CTL, | ||
159 | .pix_frmt = VID_DST_E_PIX_FRMT, | ||
160 | }, | ||
161 | |||
162 | [SRAM_CH05] = { | ||
163 | .i = SRAM_CH05, | ||
164 | .name = "VID F", | ||
165 | .cmds_start = VID_F_DOWN_CMDS, | ||
166 | .ctrl_start = VID_F_IQ, | ||
167 | .cdt = VID_F_CDT, | ||
168 | .fifo_start = VID_F_DOWN_CLUSTER_1, | ||
169 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
170 | .ptr1_reg = DMA6_PTR1, | ||
171 | .ptr2_reg = DMA6_PTR2, | ||
172 | .cnt1_reg = DMA6_CNT1, | ||
173 | .cnt2_reg = DMA6_CNT2, | ||
174 | .int_msk = VID_F_INT_MSK, | ||
175 | .int_stat = VID_F_INT_STAT, | ||
176 | .int_mstat = VID_F_INT_MSTAT, | ||
177 | .dma_ctl = VID_DST_F_DMA_CTL, | ||
178 | .gpcnt_ctl = VID_DST_F_GPCNT_CTL, | ||
179 | .gpcnt = VID_DST_F_GPCNT, | ||
180 | .vip_ctl = VID_DST_F_VIP_CTL, | ||
181 | .pix_frmt = VID_DST_F_PIX_FRMT, | ||
182 | }, | ||
183 | |||
184 | [SRAM_CH06] = { | ||
185 | .i = SRAM_CH06, | ||
186 | .name = "VID G", | ||
187 | .cmds_start = VID_G_DOWN_CMDS, | ||
188 | .ctrl_start = VID_G_IQ, | ||
189 | .cdt = VID_G_CDT, | ||
190 | .fifo_start = VID_G_DOWN_CLUSTER_1, | ||
191 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
192 | .ptr1_reg = DMA7_PTR1, | ||
193 | .ptr2_reg = DMA7_PTR2, | ||
194 | .cnt1_reg = DMA7_CNT1, | ||
195 | .cnt2_reg = DMA7_CNT2, | ||
196 | .int_msk = VID_G_INT_MSK, | ||
197 | .int_stat = VID_G_INT_STAT, | ||
198 | .int_mstat = VID_G_INT_MSTAT, | ||
199 | .dma_ctl = VID_DST_G_DMA_CTL, | ||
200 | .gpcnt_ctl = VID_DST_G_GPCNT_CTL, | ||
201 | .gpcnt = VID_DST_G_GPCNT, | ||
202 | .vip_ctl = VID_DST_G_VIP_CTL, | ||
203 | .pix_frmt = VID_DST_G_PIX_FRMT, | ||
204 | }, | ||
205 | |||
206 | [SRAM_CH07] = { | ||
207 | .i = SRAM_CH07, | ||
208 | .name = "VID H", | ||
209 | .cmds_start = VID_H_DOWN_CMDS, | ||
210 | .ctrl_start = VID_H_IQ, | ||
211 | .cdt = VID_H_CDT, | ||
212 | .fifo_start = VID_H_DOWN_CLUSTER_1, | ||
213 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
214 | .ptr1_reg = DMA8_PTR1, | ||
215 | .ptr2_reg = DMA8_PTR2, | ||
216 | .cnt1_reg = DMA8_CNT1, | ||
217 | .cnt2_reg = DMA8_CNT2, | ||
218 | .int_msk = VID_H_INT_MSK, | ||
219 | .int_stat = VID_H_INT_STAT, | ||
220 | .int_mstat = VID_H_INT_MSTAT, | ||
221 | .dma_ctl = VID_DST_H_DMA_CTL, | ||
222 | .gpcnt_ctl = VID_DST_H_GPCNT_CTL, | ||
223 | .gpcnt = VID_DST_H_GPCNT, | ||
224 | .vip_ctl = VID_DST_H_VIP_CTL, | ||
225 | .pix_frmt = VID_DST_H_PIX_FRMT, | ||
226 | }, | ||
227 | |||
228 | [SRAM_CH08] = { | ||
229 | .name = "audio from", | ||
230 | .cmds_start = AUD_A_DOWN_CMDS, | ||
231 | .ctrl_start = AUD_A_IQ, | ||
232 | .cdt = AUD_A_CDT, | ||
233 | .fifo_start = AUD_A_DOWN_CLUSTER_1, | ||
234 | .fifo_size = AUDIO_CLUSTER_SIZE * 3, | ||
235 | .ptr1_reg = DMA17_PTR1, | ||
236 | .ptr2_reg = DMA17_PTR2, | ||
237 | .cnt1_reg = DMA17_CNT1, | ||
238 | .cnt2_reg = DMA17_CNT2, | ||
239 | }, | ||
240 | |||
241 | [SRAM_CH09] = { | ||
242 | .i = SRAM_CH09, | ||
243 | .name = "VID Upstream I", | ||
244 | .cmds_start = VID_I_UP_CMDS, | ||
245 | .ctrl_start = VID_I_IQ, | ||
246 | .cdt = VID_I_CDT, | ||
247 | .fifo_start = VID_I_UP_CLUSTER_1, | ||
248 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
249 | .ptr1_reg = DMA15_PTR1, | ||
250 | .ptr2_reg = DMA15_PTR2, | ||
251 | .cnt1_reg = DMA15_CNT1, | ||
252 | .cnt2_reg = DMA15_CNT2, | ||
253 | .int_msk = VID_I_INT_MSK, | ||
254 | .int_stat = VID_I_INT_STAT, | ||
255 | .int_mstat = VID_I_INT_MSTAT, | ||
256 | .dma_ctl = VID_SRC_I_DMA_CTL, | ||
257 | .gpcnt_ctl = VID_SRC_I_GPCNT_CTL, | ||
258 | .gpcnt = VID_SRC_I_GPCNT, | ||
259 | |||
260 | .vid_fmt_ctl = VID_SRC_I_FMT_CTL, | ||
261 | .vid_active_ctl1 = VID_SRC_I_ACTIVE_CTL1, | ||
262 | .vid_active_ctl2 = VID_SRC_I_ACTIVE_CTL2, | ||
263 | .vid_cdt_size = VID_SRC_I_CDT_SZ, | ||
264 | .irq_bit = 8, | ||
265 | }, | ||
266 | |||
267 | [SRAM_CH10] = { | ||
268 | .i = SRAM_CH10, | ||
269 | .name = "VID Upstream J", | ||
270 | .cmds_start = VID_J_UP_CMDS, | ||
271 | .ctrl_start = VID_J_IQ, | ||
272 | .cdt = VID_J_CDT, | ||
273 | .fifo_start = VID_J_UP_CLUSTER_1, | ||
274 | .fifo_size = (VID_CLUSTER_SIZE << 2), | ||
275 | .ptr1_reg = DMA16_PTR1, | ||
276 | .ptr2_reg = DMA16_PTR2, | ||
277 | .cnt1_reg = DMA16_CNT1, | ||
278 | .cnt2_reg = DMA16_CNT2, | ||
279 | .int_msk = VID_J_INT_MSK, | ||
280 | .int_stat = VID_J_INT_STAT, | ||
281 | .int_mstat = VID_J_INT_MSTAT, | ||
282 | .dma_ctl = VID_SRC_J_DMA_CTL, | ||
283 | .gpcnt_ctl = VID_SRC_J_GPCNT_CTL, | ||
284 | .gpcnt = VID_SRC_J_GPCNT, | ||
285 | |||
286 | .vid_fmt_ctl = VID_SRC_J_FMT_CTL, | ||
287 | .vid_active_ctl1 = VID_SRC_J_ACTIVE_CTL1, | ||
288 | .vid_active_ctl2 = VID_SRC_J_ACTIVE_CTL2, | ||
289 | .vid_cdt_size = VID_SRC_J_CDT_SZ, | ||
290 | .irq_bit = 9, | ||
291 | }, | ||
292 | |||
293 | [SRAM_CH11] = { | ||
294 | .i = SRAM_CH11, | ||
295 | .name = "Audio Upstream Channel B", | ||
296 | .cmds_start = AUD_B_UP_CMDS, | ||
297 | .ctrl_start = AUD_B_IQ, | ||
298 | .cdt = AUD_B_CDT, | ||
299 | .fifo_start = AUD_B_UP_CLUSTER_1, | ||
300 | .fifo_size = (AUDIO_CLUSTER_SIZE * 3), | ||
301 | .ptr1_reg = DMA22_PTR1, | ||
302 | .ptr2_reg = DMA22_PTR2, | ||
303 | .cnt1_reg = DMA22_CNT1, | ||
304 | .cnt2_reg = DMA22_CNT2, | ||
305 | .int_msk = AUD_B_INT_MSK, | ||
306 | .int_stat = AUD_B_INT_STAT, | ||
307 | .int_mstat = AUD_B_INT_MSTAT, | ||
308 | .dma_ctl = AUD_INT_DMA_CTL, | ||
309 | .gpcnt_ctl = AUD_B_GPCNT_CTL, | ||
310 | .gpcnt = AUD_B_GPCNT, | ||
311 | .aud_length = AUD_B_LNGTH, | ||
312 | .aud_cfg = AUD_B_CFG, | ||
313 | .fld_aud_fifo_en = FLD_AUD_SRC_B_FIFO_EN, | ||
314 | .fld_aud_risc_en = FLD_AUD_SRC_B_RISC_EN, | ||
315 | .irq_bit = 11, | ||
316 | }, | ||
317 | }; | ||
318 | EXPORT_SYMBOL(cx25821_sram_channels); | ||
319 | |||
320 | struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00]; | ||
321 | struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01]; | ||
322 | struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02]; | ||
323 | struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03]; | ||
324 | struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04]; | ||
325 | struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05]; | ||
326 | struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06]; | ||
327 | struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07]; | ||
328 | struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09]; | ||
329 | struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10]; | ||
330 | struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11]; | ||
331 | |||
332 | struct cx25821_dmaqueue mpegq; | ||
333 | |||
334 | static int cx25821_risc_decode(u32 risc) | ||
335 | { | ||
336 | static const char * const instr[16] = { | ||
337 | [RISC_SYNC >> 28] = "sync", | ||
338 | [RISC_WRITE >> 28] = "write", | ||
339 | [RISC_WRITEC >> 28] = "writec", | ||
340 | [RISC_READ >> 28] = "read", | ||
341 | [RISC_READC >> 28] = "readc", | ||
342 | [RISC_JUMP >> 28] = "jump", | ||
343 | [RISC_SKIP >> 28] = "skip", | ||
344 | [RISC_WRITERM >> 28] = "writerm", | ||
345 | [RISC_WRITECM >> 28] = "writecm", | ||
346 | [RISC_WRITECR >> 28] = "writecr", | ||
347 | }; | ||
348 | static const int incr[16] = { | ||
349 | [RISC_WRITE >> 28] = 3, | ||
350 | [RISC_JUMP >> 28] = 3, | ||
351 | [RISC_SKIP >> 28] = 1, | ||
352 | [RISC_SYNC >> 28] = 1, | ||
353 | [RISC_WRITERM >> 28] = 3, | ||
354 | [RISC_WRITECM >> 28] = 3, | ||
355 | [RISC_WRITECR >> 28] = 4, | ||
356 | }; | ||
357 | static const char * const bits[] = { | ||
358 | "12", "13", "14", "resync", | ||
359 | "cnt0", "cnt1", "18", "19", | ||
360 | "20", "21", "22", "23", | ||
361 | "irq1", "irq2", "eol", "sol", | ||
362 | }; | ||
363 | int i; | ||
364 | |||
365 | pr_cont("0x%08x [ %s", | ||
366 | risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); | ||
367 | for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) { | ||
368 | if (risc & (1 << (i + 12))) | ||
369 | pr_cont(" %s", bits[i]); | ||
370 | } | ||
371 | pr_cont(" count=%d ]\n", risc & 0xfff); | ||
372 | return incr[risc >> 28] ? incr[risc >> 28] : 1; | ||
373 | } | ||
374 | |||
375 | static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap) | ||
376 | { | ||
377 | struct cx25821_i2c *bus = i2c_adap->algo_data; | ||
378 | struct cx25821_dev *dev = bus->dev; | ||
379 | return cx_read(bus->reg_stat) & 0x01; | ||
380 | } | ||
381 | |||
382 | static void cx25821_registers_init(struct cx25821_dev *dev) | ||
383 | { | ||
384 | u32 tmp; | ||
385 | |||
386 | /* enable RUN_RISC in Pecos */ | ||
387 | cx_write(DEV_CNTRL2, 0x20); | ||
388 | |||
389 | /* Set the master PCI interrupt masks to enable video, audio, MBIF, | ||
390 | * and GPIO interrupts | ||
391 | * I2C interrupt masking is handled by the I2C objects themselves. */ | ||
392 | cx_write(PCI_INT_MSK, 0x2001FFFF); | ||
393 | |||
394 | tmp = cx_read(RDR_TLCTL0); | ||
395 | tmp &= ~FLD_CFG_RCB_CK_EN; /* Clear the RCB_CK_EN bit */ | ||
396 | cx_write(RDR_TLCTL0, tmp); | ||
397 | |||
398 | /* PLL-A setting for the Audio Master Clock */ | ||
399 | cx_write(PLL_A_INT_FRAC, 0x9807A58B); | ||
400 | |||
401 | /* PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1 */ | ||
402 | cx_write(PLL_A_POST_STAT_BIST, 0x8000019C); | ||
403 | |||
404 | /* clear reset bit [31] */ | ||
405 | tmp = cx_read(PLL_A_INT_FRAC); | ||
406 | cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF); | ||
407 | |||
408 | /* PLL-B setting for Mobilygen Host Bus Interface */ | ||
409 | cx_write(PLL_B_INT_FRAC, 0x9883A86F); | ||
410 | |||
411 | /* PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0 */ | ||
412 | cx_write(PLL_B_POST_STAT_BIST, 0x8000018D); | ||
413 | |||
414 | /* clear reset bit [31] */ | ||
415 | tmp = cx_read(PLL_B_INT_FRAC); | ||
416 | cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF); | ||
417 | |||
418 | /* PLL-C setting for video upstream channel */ | ||
419 | cx_write(PLL_C_INT_FRAC, 0x96A0EA3F); | ||
420 | |||
421 | /* PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0 */ | ||
422 | cx_write(PLL_C_POST_STAT_BIST, 0x80000103); | ||
423 | |||
424 | /* clear reset bit [31] */ | ||
425 | tmp = cx_read(PLL_C_INT_FRAC); | ||
426 | cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF); | ||
427 | |||
428 | /* PLL-D setting for audio upstream channel */ | ||
429 | cx_write(PLL_D_INT_FRAC, 0x98757F5B); | ||
430 | |||
431 | /* PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0 */ | ||
432 | cx_write(PLL_D_POST_STAT_BIST, 0x80000113); | ||
433 | |||
434 | /* clear reset bit [31] */ | ||
435 | tmp = cx_read(PLL_D_INT_FRAC); | ||
436 | cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF); | ||
437 | |||
438 | /* This selects the PLL C clock source for the video upstream channel | ||
439 | * I and J */ | ||
440 | tmp = cx_read(VID_CH_CLK_SEL); | ||
441 | cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000); | ||
442 | |||
443 | /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for | ||
444 | * channel A-C | ||
445 | * select 656/VIP DST for downstream Channel A - C */ | ||
446 | tmp = cx_read(VID_CH_MODE_SEL); | ||
447 | /* cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF); */ | ||
448 | cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); | ||
449 | |||
450 | /* enables 656 port I and J as output */ | ||
451 | tmp = cx_read(CLK_RST); | ||
452 | /* use external ALT_PLL_REF pin as its reference clock instead */ | ||
453 | tmp |= FLD_USE_ALT_PLL_REF; | ||
454 | cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE)); | ||
455 | |||
456 | mdelay(100); | ||
457 | } | ||
458 | |||
459 | int 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 | BUG_ON(lines < 2); | ||
482 | |||
483 | cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | ||
484 | cx_write(8 + 4, 8); | ||
485 | cx_write(8 + 8, 0); | ||
486 | |||
487 | /* write CDT */ | ||
488 | for (i = 0; i < lines; i++) { | ||
489 | cx_write(cdt + 16 * i, ch->fifo_start + bpl * i); | ||
490 | cx_write(cdt + 16 * i + 4, 0); | ||
491 | cx_write(cdt + 16 * i + 8, 0); | ||
492 | cx_write(cdt + 16 * i + 12, 0); | ||
493 | } | ||
494 | |||
495 | /* init the first cdt buffer */ | ||
496 | for (i = 0; i < 128; i++) | ||
497 | cx_write(ch->fifo_start + 4 * i, i); | ||
498 | |||
499 | /* write CMDS */ | ||
500 | if (ch->jumponly) | ||
501 | cx_write(ch->cmds_start + 0, 8); | ||
502 | else | ||
503 | cx_write(ch->cmds_start + 0, risc); | ||
504 | |||
505 | cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ | ||
506 | cx_write(ch->cmds_start + 8, cdt); | ||
507 | cx_write(ch->cmds_start + 12, (lines * 16) >> 3); | ||
508 | cx_write(ch->cmds_start + 16, ch->ctrl_start); | ||
509 | |||
510 | if (ch->jumponly) | ||
511 | cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2)); | ||
512 | else | ||
513 | cx_write(ch->cmds_start + 20, 64 >> 2); | ||
514 | |||
515 | for (i = 24; i < 80; i += 4) | ||
516 | cx_write(ch->cmds_start + i, 0); | ||
517 | |||
518 | /* fill registers */ | ||
519 | cx_write(ch->ptr1_reg, ch->fifo_start); | ||
520 | cx_write(ch->ptr2_reg, cdt); | ||
521 | cx_write(ch->cnt2_reg, (lines * 16) >> 3); | ||
522 | cx_write(ch->cnt1_reg, (bpl >> 3) - 1); | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | EXPORT_SYMBOL(cx25821_sram_channel_setup); | ||
527 | |||
528 | int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, | ||
529 | struct sram_channel *ch, | ||
530 | unsigned int bpl, u32 risc) | ||
531 | { | ||
532 | unsigned int i, lines; | ||
533 | u32 cdt; | ||
534 | |||
535 | if (ch->cmds_start == 0) { | ||
536 | cx_write(ch->ptr1_reg, 0); | ||
537 | cx_write(ch->ptr2_reg, 0); | ||
538 | cx_write(ch->cnt2_reg, 0); | ||
539 | cx_write(ch->cnt1_reg, 0); | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | bpl = (bpl + 7) & ~7; /* alignment */ | ||
544 | cdt = ch->cdt; | ||
545 | lines = ch->fifo_size / bpl; | ||
546 | |||
547 | if (lines > 3) | ||
548 | lines = 3; /* for AUDIO */ | ||
549 | |||
550 | BUG_ON(lines < 2); | ||
551 | |||
552 | cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | ||
553 | cx_write(8 + 4, 8); | ||
554 | cx_write(8 + 8, 0); | ||
555 | |||
556 | /* write CDT */ | ||
557 | for (i = 0; i < lines; i++) { | ||
558 | cx_write(cdt + 16 * i, ch->fifo_start + bpl * i); | ||
559 | cx_write(cdt + 16 * i + 4, 0); | ||
560 | cx_write(cdt + 16 * i + 8, 0); | ||
561 | cx_write(cdt + 16 * i + 12, 0); | ||
562 | } | ||
563 | |||
564 | /* write CMDS */ | ||
565 | if (ch->jumponly) | ||
566 | cx_write(ch->cmds_start + 0, 8); | ||
567 | else | ||
568 | cx_write(ch->cmds_start + 0, risc); | ||
569 | |||
570 | cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ | ||
571 | cx_write(ch->cmds_start + 8, cdt); | ||
572 | cx_write(ch->cmds_start + 12, (lines * 16) >> 3); | ||
573 | cx_write(ch->cmds_start + 16, ch->ctrl_start); | ||
574 | |||
575 | /* IQ size */ | ||
576 | if (ch->jumponly) | ||
577 | cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2)); | ||
578 | else | ||
579 | cx_write(ch->cmds_start + 20, 64 >> 2); | ||
580 | |||
581 | /* zero out */ | ||
582 | for (i = 24; i < 80; i += 4) | ||
583 | cx_write(ch->cmds_start + i, 0); | ||
584 | |||
585 | /* fill registers */ | ||
586 | cx_write(ch->ptr1_reg, ch->fifo_start); | ||
587 | cx_write(ch->ptr2_reg, cdt); | ||
588 | cx_write(ch->cnt2_reg, (lines * 16) >> 3); | ||
589 | cx_write(ch->cnt1_reg, (bpl >> 3) - 1); | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | EXPORT_SYMBOL(cx25821_sram_channel_setup_audio); | ||
594 | |||
595 | void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch) | ||
596 | { | ||
597 | static char *name[] = { | ||
598 | "init risc lo", | ||
599 | "init risc hi", | ||
600 | "cdt base", | ||
601 | "cdt size", | ||
602 | "iq base", | ||
603 | "iq size", | ||
604 | "risc pc lo", | ||
605 | "risc pc hi", | ||
606 | "iq wr ptr", | ||
607 | "iq rd ptr", | ||
608 | "cdt current", | ||
609 | "pci target lo", | ||
610 | "pci target hi", | ||
611 | "line / byte", | ||
612 | }; | ||
613 | u32 risc; | ||
614 | unsigned int i, j, n; | ||
615 | |||
616 | pr_warn("%s: %s - dma channel status dump\n", dev->name, ch->name); | ||
617 | for (i = 0; i < ARRAY_SIZE(name); i++) | ||
618 | pr_warn("cmds + 0x%2x: %-15s: 0x%08x\n", | ||
619 | i * 4, name[i], cx_read(ch->cmds_start + 4 * i)); | ||
620 | |||
621 | j = i * 4; | ||
622 | for (i = 0; i < 4;) { | ||
623 | risc = cx_read(ch->cmds_start + 4 * (i + 14)); | ||
624 | pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i); | ||
625 | i += cx25821_risc_decode(risc); | ||
626 | } | ||
627 | |||
628 | for (i = 0; i < (64 >> 2); i += n) { | ||
629 | risc = cx_read(ch->ctrl_start + 4 * i); | ||
630 | /* No consideration for bits 63-32 */ | ||
631 | |||
632 | pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ", | ||
633 | i * 4, ch->ctrl_start + 4 * i, i); | ||
634 | n = cx25821_risc_decode(risc); | ||
635 | for (j = 1; j < n; j++) { | ||
636 | risc = cx_read(ch->ctrl_start + 4 * (i + j)); | ||
637 | pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n", | ||
638 | 4 * (i + j), i + j, risc, j); | ||
639 | } | ||
640 | } | ||
641 | |||
642 | pr_warn(" : fifo: 0x%08x -> 0x%x\n", | ||
643 | ch->fifo_start, ch->fifo_start + ch->fifo_size); | ||
644 | pr_warn(" : ctrl: 0x%08x -> 0x%x\n", | ||
645 | ch->ctrl_start, ch->ctrl_start + 6 * 16); | ||
646 | pr_warn(" : ptr1_reg: 0x%08x\n", | ||
647 | cx_read(ch->ptr1_reg)); | ||
648 | pr_warn(" : ptr2_reg: 0x%08x\n", | ||
649 | cx_read(ch->ptr2_reg)); | ||
650 | pr_warn(" : cnt1_reg: 0x%08x\n", | ||
651 | cx_read(ch->cnt1_reg)); | ||
652 | pr_warn(" : cnt2_reg: 0x%08x\n", | ||
653 | cx_read(ch->cnt2_reg)); | ||
654 | } | ||
655 | EXPORT_SYMBOL(cx25821_sram_channel_dump); | ||
656 | |||
657 | void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, | ||
658 | struct sram_channel *ch) | ||
659 | { | ||
660 | static const char * const name[] = { | ||
661 | "init risc lo", | ||
662 | "init risc hi", | ||
663 | "cdt base", | ||
664 | "cdt size", | ||
665 | "iq base", | ||
666 | "iq size", | ||
667 | "risc pc lo", | ||
668 | "risc pc hi", | ||
669 | "iq wr ptr", | ||
670 | "iq rd ptr", | ||
671 | "cdt current", | ||
672 | "pci target lo", | ||
673 | "pci target hi", | ||
674 | "line / byte", | ||
675 | }; | ||
676 | |||
677 | u32 risc, value, tmp; | ||
678 | unsigned int i, j, n; | ||
679 | |||
680 | pr_info("\n%s: %s - dma Audio channel status dump\n", | ||
681 | dev->name, ch->name); | ||
682 | |||
683 | for (i = 0; i < ARRAY_SIZE(name); i++) | ||
684 | pr_info("%s: cmds + 0x%2x: %-15s: 0x%08x\n", | ||
685 | dev->name, i * 4, name[i], | ||
686 | cx_read(ch->cmds_start + 4 * i)); | ||
687 | |||
688 | j = i * 4; | ||
689 | for (i = 0; i < 4;) { | ||
690 | risc = cx_read(ch->cmds_start + 4 * (i + 14)); | ||
691 | pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i); | ||
692 | i += cx25821_risc_decode(risc); | ||
693 | } | ||
694 | |||
695 | for (i = 0; i < (64 >> 2); i += n) { | ||
696 | risc = cx_read(ch->ctrl_start + 4 * i); | ||
697 | /* No consideration for bits 63-32 */ | ||
698 | |||
699 | pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ", | ||
700 | i * 4, ch->ctrl_start + 4 * i, i); | ||
701 | n = cx25821_risc_decode(risc); | ||
702 | |||
703 | for (j = 1; j < n; j++) { | ||
704 | risc = cx_read(ch->ctrl_start + 4 * (i + j)); | ||
705 | pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n", | ||
706 | 4 * (i + j), i + j, risc, j); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | pr_warn(" : fifo: 0x%08x -> 0x%x\n", | ||
711 | ch->fifo_start, ch->fifo_start + ch->fifo_size); | ||
712 | pr_warn(" : ctrl: 0x%08x -> 0x%x\n", | ||
713 | ch->ctrl_start, ch->ctrl_start + 6 * 16); | ||
714 | pr_warn(" : ptr1_reg: 0x%08x\n", | ||
715 | cx_read(ch->ptr1_reg)); | ||
716 | pr_warn(" : ptr2_reg: 0x%08x\n", | ||
717 | cx_read(ch->ptr2_reg)); | ||
718 | pr_warn(" : cnt1_reg: 0x%08x\n", | ||
719 | cx_read(ch->cnt1_reg)); | ||
720 | pr_warn(" : cnt2_reg: 0x%08x\n", | ||
721 | cx_read(ch->cnt2_reg)); | ||
722 | |||
723 | for (i = 0; i < 4; i++) { | ||
724 | risc = cx_read(ch->cmds_start + 56 + (i * 4)); | ||
725 | pr_warn("instruction %d = 0x%x\n", i, risc); | ||
726 | } | ||
727 | |||
728 | /* read data from the first cdt buffer */ | ||
729 | risc = cx_read(AUD_A_CDT); | ||
730 | pr_warn("\nread cdt loc=0x%x\n", risc); | ||
731 | for (i = 0; i < 8; i++) { | ||
732 | n = cx_read(risc + i * 4); | ||
733 | pr_cont("0x%x ", n); | ||
734 | } | ||
735 | pr_cont("\n\n"); | ||
736 | |||
737 | value = cx_read(CLK_RST); | ||
738 | CX25821_INFO(" CLK_RST = 0x%x\n\n", value); | ||
739 | |||
740 | value = cx_read(PLL_A_POST_STAT_BIST); | ||
741 | CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x\n\n", value); | ||
742 | value = cx_read(PLL_A_INT_FRAC); | ||
743 | CX25821_INFO(" PLL_A_INT_FRAC = 0x%x\n\n", value); | ||
744 | |||
745 | value = cx_read(PLL_B_POST_STAT_BIST); | ||
746 | CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x\n\n", value); | ||
747 | value = cx_read(PLL_B_INT_FRAC); | ||
748 | CX25821_INFO(" PLL_B_INT_FRAC = 0x%x\n\n", value); | ||
749 | |||
750 | value = cx_read(PLL_C_POST_STAT_BIST); | ||
751 | CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x\n\n", value); | ||
752 | value = cx_read(PLL_C_INT_FRAC); | ||
753 | CX25821_INFO(" PLL_C_INT_FRAC = 0x%x\n\n", value); | ||
754 | |||
755 | value = cx_read(PLL_D_POST_STAT_BIST); | ||
756 | CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x\n\n", value); | ||
757 | value = cx_read(PLL_D_INT_FRAC); | ||
758 | CX25821_INFO(" PLL_D_INT_FRAC = 0x%x\n\n", value); | ||
759 | |||
760 | value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); | ||
761 | CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x\n\n", value); | ||
762 | } | ||
763 | EXPORT_SYMBOL(cx25821_sram_channel_dump_audio); | ||
764 | |||
765 | static void cx25821_shutdown(struct cx25821_dev *dev) | ||
766 | { | ||
767 | int i; | ||
768 | |||
769 | /* disable RISC controller */ | ||
770 | cx_write(DEV_CNTRL2, 0); | ||
771 | |||
772 | /* Disable Video A/B activity */ | ||
773 | for (i = 0; i < VID_CHANNEL_NUM; i++) { | ||
774 | cx_write(dev->channels[i].sram_channels->dma_ctl, 0); | ||
775 | cx_write(dev->channels[i].sram_channels->int_msk, 0); | ||
776 | } | ||
777 | |||
778 | for (i = VID_UPSTREAM_SRAM_CHANNEL_I; | ||
779 | i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) { | ||
780 | cx_write(dev->channels[i].sram_channels->dma_ctl, 0); | ||
781 | cx_write(dev->channels[i].sram_channels->int_msk, 0); | ||
782 | } | ||
783 | |||
784 | /* Disable Audio activity */ | ||
785 | cx_write(AUD_INT_DMA_CTL, 0); | ||
786 | |||
787 | /* Disable Serial port */ | ||
788 | cx_write(UART_CTL, 0); | ||
789 | |||
790 | /* Disable Interrupts */ | ||
791 | cx_write(PCI_INT_MSK, 0); | ||
792 | cx_write(AUD_A_INT_MSK, 0); | ||
793 | } | ||
794 | |||
795 | void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select, | ||
796 | u32 format) | ||
797 | { | ||
798 | if (channel_select <= 7 && channel_select >= 0) { | ||
799 | cx_write(dev->channels[channel_select].sram_channels->pix_frmt, | ||
800 | format); | ||
801 | dev->channels[channel_select].pixel_formats = format; | ||
802 | } | ||
803 | } | ||
804 | |||
805 | static void cx25821_set_vip_mode(struct cx25821_dev *dev, | ||
806 | struct sram_channel *ch) | ||
807 | { | ||
808 | cx_write(ch->pix_frmt, PIXEL_FRMT_422); | ||
809 | cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1); | ||
810 | } | ||
811 | |||
812 | static void cx25821_initialize(struct cx25821_dev *dev) | ||
813 | { | ||
814 | int i; | ||
815 | |||
816 | dprintk(1, "%s()\n", __func__); | ||
817 | |||
818 | cx25821_shutdown(dev); | ||
819 | cx_write(PCI_INT_STAT, 0xffffffff); | ||
820 | |||
821 | for (i = 0; i < VID_CHANNEL_NUM; i++) | ||
822 | cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); | ||
823 | |||
824 | cx_write(AUD_A_INT_STAT, 0xffffffff); | ||
825 | cx_write(AUD_B_INT_STAT, 0xffffffff); | ||
826 | cx_write(AUD_C_INT_STAT, 0xffffffff); | ||
827 | cx_write(AUD_D_INT_STAT, 0xffffffff); | ||
828 | cx_write(AUD_E_INT_STAT, 0xffffffff); | ||
829 | |||
830 | cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); | ||
831 | cx_write(PAD_CTRL, 0x12); /* for I2C */ | ||
832 | cx25821_registers_init(dev); /* init Pecos registers */ | ||
833 | mdelay(100); | ||
834 | |||
835 | for (i = 0; i < VID_CHANNEL_NUM; i++) { | ||
836 | cx25821_set_vip_mode(dev, dev->channels[i].sram_channels); | ||
837 | cx25821_sram_channel_setup(dev, dev->channels[i].sram_channels, | ||
838 | 1440, 0); | ||
839 | dev->channels[i].pixel_formats = PIXEL_FRMT_422; | ||
840 | dev->channels[i].use_cif_resolution = FALSE; | ||
841 | } | ||
842 | |||
843 | /* Probably only affect Downstream */ | ||
844 | for (i = VID_UPSTREAM_SRAM_CHANNEL_I; | ||
845 | i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) { | ||
846 | cx25821_set_vip_mode(dev, dev->channels[i].sram_channels); | ||
847 | } | ||
848 | |||
849 | cx25821_sram_channel_setup_audio(dev, | ||
850 | dev->channels[SRAM_CH08].sram_channels, 128, 0); | ||
851 | |||
852 | cx25821_gpio_init(dev); | ||
853 | } | ||
854 | |||
855 | static int cx25821_get_resources(struct cx25821_dev *dev) | ||
856 | { | ||
857 | if (request_mem_region(pci_resource_start(dev->pci, 0), | ||
858 | pci_resource_len(dev->pci, 0), dev->name)) | ||
859 | return 0; | ||
860 | |||
861 | pr_err("%s: can't get MMIO memory @ 0x%llx\n", | ||
862 | dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); | ||
863 | |||
864 | return -EBUSY; | ||
865 | } | ||
866 | |||
867 | static void cx25821_dev_checkrevision(struct cx25821_dev *dev) | ||
868 | { | ||
869 | dev->hwrevision = cx_read(RDR_CFG2) & 0xff; | ||
870 | |||
871 | pr_info("%s(): Hardware revision = 0x%02x\n", | ||
872 | __func__, dev->hwrevision); | ||
873 | } | ||
874 | |||
875 | static void cx25821_iounmap(struct cx25821_dev *dev) | ||
876 | { | ||
877 | if (dev == NULL) | ||
878 | return; | ||
879 | |||
880 | /* Releasing IO memory */ | ||
881 | if (dev->lmmio != NULL) { | ||
882 | CX25821_INFO("Releasing lmmio.\n"); | ||
883 | iounmap(dev->lmmio); | ||
884 | dev->lmmio = NULL; | ||
885 | } | ||
886 | } | ||
887 | |||
888 | static int cx25821_dev_setup(struct cx25821_dev *dev) | ||
889 | { | ||
890 | int i; | ||
891 | |||
892 | pr_info("\n***********************************\n"); | ||
893 | pr_info("cx25821 set up\n"); | ||
894 | pr_info("***********************************\n\n"); | ||
895 | |||
896 | mutex_init(&dev->lock); | ||
897 | |||
898 | atomic_inc(&dev->refcount); | ||
899 | |||
900 | dev->nr = ++cx25821_devcount; | ||
901 | sprintf(dev->name, "cx25821[%d]", dev->nr); | ||
902 | |||
903 | mutex_lock(&cx25821_devlist_mutex); | ||
904 | list_add_tail(&dev->devlist, &cx25821_devlist); | ||
905 | mutex_unlock(&cx25821_devlist_mutex); | ||
906 | |||
907 | if (dev->pci->device != 0x8210) { | ||
908 | pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", | ||
909 | __func__, dev->pci->device); | ||
910 | return -1; | ||
911 | } else { | ||
912 | pr_info("Athena Hardware device = 0x%02x\n", dev->pci->device); | ||
913 | } | ||
914 | |||
915 | /* Apply a sensible clock frequency for the PCIe bridge */ | ||
916 | dev->clk_freq = 28000000; | ||
917 | for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) | ||
918 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; | ||
919 | |||
920 | if (dev->nr > 1) | ||
921 | CX25821_INFO("dev->nr > 1!"); | ||
922 | |||
923 | /* board config */ | ||
924 | dev->board = 1; /* card[dev->nr]; */ | ||
925 | dev->_max_num_decoders = MAX_DECODERS; | ||
926 | |||
927 | dev->pci_bus = dev->pci->bus->number; | ||
928 | dev->pci_slot = PCI_SLOT(dev->pci->devfn); | ||
929 | dev->pci_irqmask = 0x001f00; | ||
930 | |||
931 | /* External Master 1 Bus */ | ||
932 | dev->i2c_bus[0].nr = 0; | ||
933 | dev->i2c_bus[0].dev = dev; | ||
934 | dev->i2c_bus[0].reg_stat = I2C1_STAT; | ||
935 | dev->i2c_bus[0].reg_ctrl = I2C1_CTRL; | ||
936 | dev->i2c_bus[0].reg_addr = I2C1_ADDR; | ||
937 | dev->i2c_bus[0].reg_rdata = I2C1_RDATA; | ||
938 | dev->i2c_bus[0].reg_wdata = I2C1_WDATA; | ||
939 | dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */ | ||
940 | |||
941 | if (cx25821_get_resources(dev) < 0) { | ||
942 | pr_err("%s: No more PCIe resources for subsystem: %04x:%04x\n", | ||
943 | dev->name, dev->pci->subsystem_vendor, | ||
944 | dev->pci->subsystem_device); | ||
945 | |||
946 | cx25821_devcount--; | ||
947 | return -EBUSY; | ||
948 | } | ||
949 | |||
950 | /* PCIe stuff */ | ||
951 | dev->base_io_addr = pci_resource_start(dev->pci, 0); | ||
952 | |||
953 | if (!dev->base_io_addr) { | ||
954 | CX25821_ERR("No PCI Memory resources, exiting!\n"); | ||
955 | return -ENODEV; | ||
956 | } | ||
957 | |||
958 | dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0)); | ||
959 | |||
960 | if (!dev->lmmio) { | ||
961 | CX25821_ERR("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n"); | ||
962 | cx25821_iounmap(dev); | ||
963 | return -ENOMEM; | ||
964 | } | ||
965 | |||
966 | dev->bmmio = (u8 __iomem *) dev->lmmio; | ||
967 | |||
968 | pr_info("%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", | ||
969 | dev->name, dev->pci->subsystem_vendor, | ||
970 | dev->pci->subsystem_device, cx25821_boards[dev->board].name, | ||
971 | dev->board, card[dev->nr] == dev->board ? | ||
972 | "insmod option" : "autodetected"); | ||
973 | |||
974 | /* init hardware */ | ||
975 | cx25821_initialize(dev); | ||
976 | |||
977 | cx25821_i2c_register(&dev->i2c_bus[0]); | ||
978 | /* cx25821_i2c_register(&dev->i2c_bus[1]); | ||
979 | * cx25821_i2c_register(&dev->i2c_bus[2]); */ | ||
980 | |||
981 | CX25821_INFO("i2c register! bus->i2c_rc = %d\n", | ||
982 | dev->i2c_bus[0].i2c_rc); | ||
983 | |||
984 | cx25821_card_setup(dev); | ||
985 | |||
986 | if (medusa_video_init(dev) < 0) | ||
987 | CX25821_ERR("%s(): Failed to initialize medusa!\n", __func__); | ||
988 | |||
989 | cx25821_video_register(dev); | ||
990 | |||
991 | /* register IOCTL device */ | ||
992 | dev->ioctl_dev = cx25821_vdev_init(dev, dev->pci, | ||
993 | &cx25821_videoioctl_template, "video"); | ||
994 | |||
995 | if (video_register_device | ||
996 | (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) { | ||
997 | cx25821_videoioctl_unregister(dev); | ||
998 | pr_err("%s(): Failed to register video adapter for IOCTL, so unregistering videoioctl device\n", | ||
999 | __func__); | ||
1000 | } | ||
1001 | |||
1002 | cx25821_dev_checkrevision(dev); | ||
1003 | CX25821_INFO("setup done!\n"); | ||
1004 | |||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, | ||
1009 | struct upstream_user_struct *up_data) | ||
1010 | { | ||
1011 | dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0; | ||
1012 | |||
1013 | dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M; | ||
1014 | medusa_set_videostandard(dev); | ||
1015 | |||
1016 | cx25821_vidupstream_init_ch1(dev, dev->channel_select, | ||
1017 | dev->pixel_format); | ||
1018 | } | ||
1019 | |||
1020 | void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, | ||
1021 | struct upstream_user_struct *up_data) | ||
1022 | { | ||
1023 | dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0; | ||
1024 | |||
1025 | dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M; | ||
1026 | medusa_set_videostandard(dev); | ||
1027 | |||
1028 | cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2, | ||
1029 | dev->pixel_format_ch2); | ||
1030 | } | ||
1031 | |||
1032 | void cx25821_start_upstream_audio(struct cx25821_dev *dev, | ||
1033 | struct upstream_user_struct *up_data) | ||
1034 | { | ||
1035 | cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B); | ||
1036 | } | ||
1037 | |||
1038 | void cx25821_dev_unregister(struct cx25821_dev *dev) | ||
1039 | { | ||
1040 | int i; | ||
1041 | |||
1042 | if (!dev->base_io_addr) | ||
1043 | return; | ||
1044 | |||
1045 | cx25821_free_mem_upstream_ch1(dev); | ||
1046 | cx25821_free_mem_upstream_ch2(dev); | ||
1047 | cx25821_free_mem_upstream_audio(dev); | ||
1048 | |||
1049 | release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0)); | ||
1050 | |||
1051 | if (!atomic_dec_and_test(&dev->refcount)) | ||
1052 | return; | ||
1053 | |||
1054 | for (i = 0; i < VID_CHANNEL_NUM; i++) | ||
1055 | cx25821_video_unregister(dev, i); | ||
1056 | |||
1057 | for (i = VID_UPSTREAM_SRAM_CHANNEL_I; | ||
1058 | i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) { | ||
1059 | cx25821_video_unregister(dev, i); | ||
1060 | } | ||
1061 | |||
1062 | cx25821_videoioctl_unregister(dev); | ||
1063 | |||
1064 | cx25821_i2c_unregister(&dev->i2c_bus[0]); | ||
1065 | cx25821_iounmap(dev); | ||
1066 | } | ||
1067 | EXPORT_SYMBOL(cx25821_dev_unregister); | ||
1068 | |||
1069 | static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, | ||
1070 | unsigned int offset, u32 sync_line, | ||
1071 | unsigned int bpl, unsigned int padding, | ||
1072 | unsigned int lines) | ||
1073 | { | ||
1074 | struct scatterlist *sg; | ||
1075 | unsigned int line, todo; | ||
1076 | |||
1077 | /* sync instruction */ | ||
1078 | if (sync_line != NO_SYNC_LINE) | ||
1079 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | ||
1080 | |||
1081 | /* scan lines */ | ||
1082 | sg = sglist; | ||
1083 | for (line = 0; line < lines; line++) { | ||
1084 | while (offset && offset >= sg_dma_len(sg)) { | ||
1085 | offset -= sg_dma_len(sg); | ||
1086 | sg++; | ||
1087 | } | ||
1088 | if (bpl <= sg_dma_len(sg) - offset) { | ||
1089 | /* fits into current chunk */ | ||
1090 | *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | | ||
1091 | bpl); | ||
1092 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); | ||
1093 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1094 | offset += bpl; | ||
1095 | } else { | ||
1096 | /* scanline needs to be split */ | ||
1097 | todo = bpl; | ||
1098 | *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | | ||
1099 | (sg_dma_len(sg) - offset)); | ||
1100 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); | ||
1101 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1102 | todo -= (sg_dma_len(sg) - offset); | ||
1103 | offset = 0; | ||
1104 | sg++; | ||
1105 | while (todo > sg_dma_len(sg)) { | ||
1106 | *(rp++) = cpu_to_le32(RISC_WRITE | | ||
1107 | sg_dma_len(sg)); | ||
1108 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); | ||
1109 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1110 | todo -= sg_dma_len(sg); | ||
1111 | sg++; | ||
1112 | } | ||
1113 | *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo); | ||
1114 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); | ||
1115 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1116 | offset += todo; | ||
1117 | } | ||
1118 | |||
1119 | offset += padding; | ||
1120 | } | ||
1121 | |||
1122 | return rp; | ||
1123 | } | ||
1124 | |||
1125 | int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | ||
1126 | struct scatterlist *sglist, unsigned int top_offset, | ||
1127 | unsigned int bottom_offset, unsigned int bpl, | ||
1128 | unsigned int padding, unsigned int lines) | ||
1129 | { | ||
1130 | u32 instructions; | ||
1131 | u32 fields; | ||
1132 | __le32 *rp; | ||
1133 | int rc; | ||
1134 | |||
1135 | fields = 0; | ||
1136 | if (UNSET != top_offset) | ||
1137 | fields++; | ||
1138 | if (UNSET != bottom_offset) | ||
1139 | fields++; | ||
1140 | |||
1141 | /* estimate risc mem: worst case is one write per page border + | ||
1142 | one write per scan line + syncs + jump (all 2 dwords). Padding | ||
1143 | can cause next bpl to start close to a page border. First DMA | ||
1144 | region may be smaller than PAGE_SIZE */ | ||
1145 | /* write and jump need and extra dword */ | ||
1146 | instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + | ||
1147 | lines); | ||
1148 | instructions += 2; | ||
1149 | rc = btcx_riscmem_alloc(pci, risc, instructions * 12); | ||
1150 | |||
1151 | if (rc < 0) | ||
1152 | return rc; | ||
1153 | |||
1154 | /* write risc instructions */ | ||
1155 | rp = risc->cpu; | ||
1156 | |||
1157 | if (UNSET != top_offset) { | ||
1158 | rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding, | ||
1159 | lines); | ||
1160 | } | ||
1161 | |||
1162 | if (UNSET != bottom_offset) { | ||
1163 | rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl, | ||
1164 | padding, lines); | ||
1165 | } | ||
1166 | |||
1167 | /* save pointer to jmp instruction address */ | ||
1168 | risc->jmp = rp; | ||
1169 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); | ||
1170 | |||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1174 | static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, | ||
1175 | unsigned int offset, u32 sync_line, | ||
1176 | unsigned int bpl, unsigned int padding, | ||
1177 | unsigned int lines, unsigned int lpi) | ||
1178 | { | ||
1179 | struct scatterlist *sg; | ||
1180 | unsigned int line, todo, sol; | ||
1181 | |||
1182 | /* sync instruction */ | ||
1183 | if (sync_line != NO_SYNC_LINE) | ||
1184 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | ||
1185 | |||
1186 | /* scan lines */ | ||
1187 | sg = sglist; | ||
1188 | for (line = 0; line < lines; line++) { | ||
1189 | while (offset && offset >= sg_dma_len(sg)) { | ||
1190 | offset -= sg_dma_len(sg); | ||
1191 | sg++; | ||
1192 | } | ||
1193 | |||
1194 | if (lpi && line > 0 && !(line % lpi)) | ||
1195 | sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC; | ||
1196 | else | ||
1197 | sol = RISC_SOL; | ||
1198 | |||
1199 | if (bpl <= sg_dma_len(sg) - offset) { | ||
1200 | /* fits into current chunk */ | ||
1201 | *(rp++) = cpu_to_le32(RISC_WRITE | sol | RISC_EOL | | ||
1202 | bpl); | ||
1203 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); | ||
1204 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1205 | offset += bpl; | ||
1206 | } else { | ||
1207 | /* scanline needs to be split */ | ||
1208 | todo = bpl; | ||
1209 | *(rp++) = cpu_to_le32(RISC_WRITE | sol | | ||
1210 | (sg_dma_len(sg) - offset)); | ||
1211 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); | ||
1212 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1213 | todo -= (sg_dma_len(sg) - offset); | ||
1214 | offset = 0; | ||
1215 | sg++; | ||
1216 | while (todo > sg_dma_len(sg)) { | ||
1217 | *(rp++) = cpu_to_le32(RISC_WRITE | | ||
1218 | sg_dma_len(sg)); | ||
1219 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); | ||
1220 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1221 | todo -= sg_dma_len(sg); | ||
1222 | sg++; | ||
1223 | } | ||
1224 | *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo); | ||
1225 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); | ||
1226 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1227 | offset += todo; | ||
1228 | } | ||
1229 | offset += padding; | ||
1230 | } | ||
1231 | |||
1232 | return rp; | ||
1233 | } | ||
1234 | |||
1235 | int cx25821_risc_databuffer_audio(struct pci_dev *pci, | ||
1236 | struct btcx_riscmem *risc, | ||
1237 | struct scatterlist *sglist, | ||
1238 | unsigned int bpl, | ||
1239 | unsigned int lines, unsigned int lpi) | ||
1240 | { | ||
1241 | u32 instructions; | ||
1242 | __le32 *rp; | ||
1243 | int rc; | ||
1244 | |||
1245 | /* estimate risc mem: worst case is one write per page border + | ||
1246 | one write per scan line + syncs + jump (all 2 dwords). Here | ||
1247 | there is no padding and no sync. First DMA region may be smaller | ||
1248 | than PAGE_SIZE */ | ||
1249 | /* Jump and write need an extra dword */ | ||
1250 | instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; | ||
1251 | instructions += 1; | ||
1252 | |||
1253 | rc = btcx_riscmem_alloc(pci, risc, instructions * 12); | ||
1254 | if (rc < 0) | ||
1255 | return rc; | ||
1256 | |||
1257 | /* write risc instructions */ | ||
1258 | rp = risc->cpu; | ||
1259 | rp = cx25821_risc_field_audio(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, | ||
1260 | lines, lpi); | ||
1261 | |||
1262 | /* save pointer to jmp instruction address */ | ||
1263 | risc->jmp = rp; | ||
1264 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); | ||
1265 | return 0; | ||
1266 | } | ||
1267 | EXPORT_SYMBOL(cx25821_risc_databuffer_audio); | ||
1268 | |||
1269 | int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | ||
1270 | u32 reg, u32 mask, u32 value) | ||
1271 | { | ||
1272 | __le32 *rp; | ||
1273 | int rc; | ||
1274 | |||
1275 | rc = btcx_riscmem_alloc(pci, risc, 4 * 16); | ||
1276 | |||
1277 | if (rc < 0) | ||
1278 | return rc; | ||
1279 | |||
1280 | /* write risc instructions */ | ||
1281 | rp = risc->cpu; | ||
1282 | |||
1283 | *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ1); | ||
1284 | *(rp++) = cpu_to_le32(reg); | ||
1285 | *(rp++) = cpu_to_le32(value); | ||
1286 | *(rp++) = cpu_to_le32(mask); | ||
1287 | *(rp++) = cpu_to_le32(RISC_JUMP); | ||
1288 | *(rp++) = cpu_to_le32(risc->dma); | ||
1289 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1290 | return 0; | ||
1291 | } | ||
1292 | |||
1293 | void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf) | ||
1294 | { | ||
1295 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | ||
1296 | |||
1297 | BUG_ON(in_interrupt()); | ||
1298 | videobuf_waiton(q, &buf->vb, 0, 0); | ||
1299 | videobuf_dma_unmap(q->dev, dma); | ||
1300 | videobuf_dma_free(dma); | ||
1301 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); | ||
1302 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
1303 | } | ||
1304 | |||
1305 | static irqreturn_t cx25821_irq(int irq, void *dev_id) | ||
1306 | { | ||
1307 | struct cx25821_dev *dev = dev_id; | ||
1308 | u32 pci_status; | ||
1309 | u32 vid_status; | ||
1310 | int i, handled = 0; | ||
1311 | u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; | ||
1312 | |||
1313 | pci_status = cx_read(PCI_INT_STAT); | ||
1314 | |||
1315 | if (pci_status == 0) | ||
1316 | goto out; | ||
1317 | |||
1318 | for (i = 0; i < VID_CHANNEL_NUM; i++) { | ||
1319 | if (pci_status & mask[i]) { | ||
1320 | vid_status = cx_read(dev->channels[i]. | ||
1321 | sram_channels->int_stat); | ||
1322 | |||
1323 | if (vid_status) | ||
1324 | handled += cx25821_video_irq(dev, i, | ||
1325 | vid_status); | ||
1326 | |||
1327 | cx_write(PCI_INT_STAT, mask[i]); | ||
1328 | } | ||
1329 | } | ||
1330 | |||
1331 | out: | ||
1332 | return IRQ_RETVAL(handled); | ||
1333 | } | ||
1334 | |||
1335 | void cx25821_print_irqbits(char *name, char *tag, char **strings, | ||
1336 | int len, u32 bits, u32 mask) | ||
1337 | { | ||
1338 | unsigned int i; | ||
1339 | |||
1340 | printk(KERN_DEBUG pr_fmt("%s: %s [0x%x]"), name, tag, bits); | ||
1341 | |||
1342 | for (i = 0; i < len; i++) { | ||
1343 | if (!(bits & (1 << i))) | ||
1344 | continue; | ||
1345 | if (strings[i]) | ||
1346 | pr_cont(" %s", strings[i]); | ||
1347 | else | ||
1348 | pr_cont(" %d", i); | ||
1349 | if (!(mask & (1 << i))) | ||
1350 | continue; | ||
1351 | pr_cont("*"); | ||
1352 | } | ||
1353 | pr_cont("\n"); | ||
1354 | } | ||
1355 | EXPORT_SYMBOL(cx25821_print_irqbits); | ||
1356 | |||
1357 | struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci) | ||
1358 | { | ||
1359 | struct cx25821_dev *dev = pci_get_drvdata(pci); | ||
1360 | return dev; | ||
1361 | } | ||
1362 | EXPORT_SYMBOL(cx25821_dev_get); | ||
1363 | |||
1364 | static int __devinit cx25821_initdev(struct pci_dev *pci_dev, | ||
1365 | const struct pci_device_id *pci_id) | ||
1366 | { | ||
1367 | struct cx25821_dev *dev; | ||
1368 | int err = 0; | ||
1369 | |||
1370 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
1371 | if (NULL == dev) | ||
1372 | return -ENOMEM; | ||
1373 | |||
1374 | err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev); | ||
1375 | if (err < 0) | ||
1376 | goto fail_free; | ||
1377 | |||
1378 | /* pci init */ | ||
1379 | dev->pci = pci_dev; | ||
1380 | if (pci_enable_device(pci_dev)) { | ||
1381 | err = -EIO; | ||
1382 | |||
1383 | pr_info("pci enable failed!\n"); | ||
1384 | |||
1385 | goto fail_unregister_device; | ||
1386 | } | ||
1387 | |||
1388 | pr_info("Athena pci enable !\n"); | ||
1389 | |||
1390 | err = cx25821_dev_setup(dev); | ||
1391 | if (err) { | ||
1392 | if (err == -EBUSY) | ||
1393 | goto fail_unregister_device; | ||
1394 | else | ||
1395 | goto fail_unregister_pci; | ||
1396 | } | ||
1397 | |||
1398 | /* print pci info */ | ||
1399 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); | ||
1400 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); | ||
1401 | pr_info("%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", | ||
1402 | dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | ||
1403 | dev->pci_lat, (unsigned long long)dev->base_io_addr); | ||
1404 | |||
1405 | pci_set_master(pci_dev); | ||
1406 | if (!pci_dma_supported(pci_dev, 0xffffffff)) { | ||
1407 | pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); | ||
1408 | err = -EIO; | ||
1409 | goto fail_irq; | ||
1410 | } | ||
1411 | |||
1412 | err = request_irq(pci_dev->irq, cx25821_irq, | ||
1413 | IRQF_SHARED, dev->name, dev); | ||
1414 | |||
1415 | if (err < 0) { | ||
1416 | pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); | ||
1417 | goto fail_irq; | ||
1418 | } | ||
1419 | |||
1420 | return 0; | ||
1421 | |||
1422 | fail_irq: | ||
1423 | pr_info("cx25821_initdev() can't get IRQ !\n"); | ||
1424 | cx25821_dev_unregister(dev); | ||
1425 | |||
1426 | fail_unregister_pci: | ||
1427 | pci_disable_device(pci_dev); | ||
1428 | fail_unregister_device: | ||
1429 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1430 | |||
1431 | fail_free: | ||
1432 | kfree(dev); | ||
1433 | return err; | ||
1434 | } | ||
1435 | |||
1436 | static void __devexit cx25821_finidev(struct pci_dev *pci_dev) | ||
1437 | { | ||
1438 | struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); | ||
1439 | struct cx25821_dev *dev = get_cx25821(v4l2_dev); | ||
1440 | |||
1441 | cx25821_shutdown(dev); | ||
1442 | pci_disable_device(pci_dev); | ||
1443 | |||
1444 | /* unregister stuff */ | ||
1445 | if (pci_dev->irq) | ||
1446 | free_irq(pci_dev->irq, dev); | ||
1447 | |||
1448 | mutex_lock(&cx25821_devlist_mutex); | ||
1449 | list_del(&dev->devlist); | ||
1450 | mutex_unlock(&cx25821_devlist_mutex); | ||
1451 | |||
1452 | cx25821_dev_unregister(dev); | ||
1453 | v4l2_device_unregister(v4l2_dev); | ||
1454 | kfree(dev); | ||
1455 | } | ||
1456 | |||
1457 | static DEFINE_PCI_DEVICE_TABLE(cx25821_pci_tbl) = { | ||
1458 | { | ||
1459 | /* CX25821 Athena */ | ||
1460 | .vendor = 0x14f1, | ||
1461 | .device = 0x8210, | ||
1462 | .subvendor = 0x14f1, | ||
1463 | .subdevice = 0x0920, | ||
1464 | }, { | ||
1465 | /* CX25821 No Brand */ | ||
1466 | .vendor = 0x14f1, | ||
1467 | .device = 0x8210, | ||
1468 | .subvendor = 0x0000, | ||
1469 | .subdevice = 0x0000, | ||
1470 | }, { | ||
1471 | /* --- end of list --- */ | ||
1472 | } | ||
1473 | }; | ||
1474 | |||
1475 | MODULE_DEVICE_TABLE(pci, cx25821_pci_tbl); | ||
1476 | |||
1477 | static struct pci_driver cx25821_pci_driver = { | ||
1478 | .name = "cx25821", | ||
1479 | .id_table = cx25821_pci_tbl, | ||
1480 | .probe = cx25821_initdev, | ||
1481 | .remove = __devexit_p(cx25821_finidev), | ||
1482 | /* TODO */ | ||
1483 | .suspend = NULL, | ||
1484 | .resume = NULL, | ||
1485 | }; | ||
1486 | |||
1487 | static int __init cx25821_init(void) | ||
1488 | { | ||
1489 | pr_info("driver version %d.%d.%d loaded\n", | ||
1490 | (CX25821_VERSION_CODE >> 16) & 0xff, | ||
1491 | (CX25821_VERSION_CODE >> 8) & 0xff, | ||
1492 | CX25821_VERSION_CODE & 0xff); | ||
1493 | return pci_register_driver(&cx25821_pci_driver); | ||
1494 | } | ||
1495 | |||
1496 | static void __exit cx25821_fini(void) | ||
1497 | { | ||
1498 | pci_unregister_driver(&cx25821_pci_driver); | ||
1499 | } | ||
1500 | |||
1501 | module_init(cx25821_init); | ||
1502 | module_exit(cx25821_fini); | ||
diff --git a/drivers/media/pci/cx25821/cx25821-gpio.c b/drivers/media/pci/cx25821/cx25821-gpio.c new file mode 100644 index 000000000000..29e43b03c85e --- /dev/null +++ b/drivers/media/pci/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 *********************/ | ||
26 | void 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 | ||
43 | * rest as is */ | ||
44 | gpio_register = cx_read(gpio_oe_reg); | ||
45 | |||
46 | if (pin_logic_value == 1) | ||
47 | value = gpio_register | Set_GPIO_Bit(bit); | ||
48 | else | ||
49 | value = gpio_register & Clear_GPIO_Bit(bit); | ||
50 | |||
51 | cx_write(gpio_oe_reg, value); | ||
52 | } | ||
53 | EXPORT_SYMBOL(cx25821_set_gpiopin_direction); | ||
54 | |||
55 | static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev, | ||
56 | int pin_number, int pin_logic_value) | ||
57 | { | ||
58 | int bit = pin_number; | ||
59 | u32 gpio_reg = GPIO_LO; | ||
60 | u32 value = 0; | ||
61 | |||
62 | /* Check for valid pinNumber */ | ||
63 | if (pin_number >= 47) | ||
64 | return; | ||
65 | |||
66 | /* change to output direction */ | ||
67 | cx25821_set_gpiopin_direction(dev, pin_number, 0); | ||
68 | |||
69 | if (pin_number > 31) { | ||
70 | bit = pin_number - 31; | ||
71 | gpio_reg = GPIO_HI; | ||
72 | } | ||
73 | |||
74 | value = cx_read(gpio_reg); | ||
75 | |||
76 | if (pin_logic_value == 0) | ||
77 | value &= Clear_GPIO_Bit(bit); | ||
78 | else | ||
79 | value |= Set_GPIO_Bit(bit); | ||
80 | |||
81 | cx_write(gpio_reg, value); | ||
82 | } | ||
83 | |||
84 | void cx25821_gpio_init(struct cx25821_dev *dev) | ||
85 | { | ||
86 | if (dev == NULL) | ||
87 | return; | ||
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/media/pci/cx25821/cx25821-i2c.c b/drivers/media/pci/cx25821/cx25821-i2c.c new file mode 100644 index 000000000000..9844549764c9 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-i2c.c | |||
@@ -0,0 +1,416 @@ | |||
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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
25 | |||
26 | #include "cx25821.h" | ||
27 | #include <linux/i2c.h> | ||
28 | |||
29 | static unsigned int i2c_debug; | ||
30 | module_param(i2c_debug, int, 0644); | ||
31 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | ||
32 | |||
33 | static unsigned int i2c_scan; | ||
34 | module_param(i2c_scan, int, 0444); | ||
35 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | ||
36 | |||
37 | #define dprintk(level, fmt, arg...) \ | ||
38 | do { \ | ||
39 | if (i2c_debug >= level) \ | ||
40 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \ | ||
41 | } while (0) | ||
42 | |||
43 | #define I2C_WAIT_DELAY 32 | ||
44 | #define I2C_WAIT_RETRY 64 | ||
45 | |||
46 | #define I2C_EXTEND (1 << 3) | ||
47 | #define I2C_NOSTOP (1 << 4) | ||
48 | |||
49 | static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap) | ||
50 | { | ||
51 | struct cx25821_i2c *bus = i2c_adap->algo_data; | ||
52 | struct cx25821_dev *dev = bus->dev; | ||
53 | return cx_read(bus->reg_stat) & 0x01; | ||
54 | } | ||
55 | |||
56 | static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) | ||
57 | { | ||
58 | struct cx25821_i2c *bus = i2c_adap->algo_data; | ||
59 | struct cx25821_dev *dev = bus->dev; | ||
60 | return cx_read(bus->reg_stat) & 0x02 ? 1 : 0; | ||
61 | } | ||
62 | |||
63 | static int i2c_wait_done(struct i2c_adapter *i2c_adap) | ||
64 | { | ||
65 | int count; | ||
66 | |||
67 | for (count = 0; count < I2C_WAIT_RETRY; count++) { | ||
68 | if (!i2c_is_busy(i2c_adap)) | ||
69 | break; | ||
70 | udelay(I2C_WAIT_DELAY); | ||
71 | } | ||
72 | |||
73 | if (I2C_WAIT_RETRY == count) | ||
74 | return 0; | ||
75 | |||
76 | return 1; | ||
77 | } | ||
78 | |||
79 | static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | ||
80 | const struct i2c_msg *msg, int joined_rlen) | ||
81 | { | ||
82 | struct cx25821_i2c *bus = i2c_adap->algo_data; | ||
83 | struct cx25821_dev *dev = bus->dev; | ||
84 | u32 wdata, addr, ctrl; | ||
85 | int retval, cnt; | ||
86 | |||
87 | if (joined_rlen) | ||
88 | dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, | ||
89 | msg->len, joined_rlen); | ||
90 | else | ||
91 | dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); | ||
92 | |||
93 | /* Deal with i2c probe functions with zero payload */ | ||
94 | if (msg->len == 0) { | ||
95 | cx_write(bus->reg_addr, msg->addr << 25); | ||
96 | cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2)); | ||
97 | |||
98 | if (!i2c_wait_done(i2c_adap)) | ||
99 | return -EIO; | ||
100 | |||
101 | if (!i2c_slave_did_ack(i2c_adap)) | ||
102 | return -EIO; | ||
103 | |||
104 | dprintk(1, "%s(): returns 0\n", __func__); | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | /* dev, reg + first byte */ | ||
109 | addr = (msg->addr << 25) | msg->buf[0]; | ||
110 | wdata = msg->buf[0]; | ||
111 | |||
112 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2); | ||
113 | |||
114 | if (msg->len > 1) | ||
115 | ctrl |= I2C_NOSTOP | I2C_EXTEND; | ||
116 | else if (joined_rlen) | ||
117 | ctrl |= I2C_NOSTOP; | ||
118 | |||
119 | cx_write(bus->reg_addr, addr); | ||
120 | cx_write(bus->reg_wdata, wdata); | ||
121 | cx_write(bus->reg_ctrl, ctrl); | ||
122 | |||
123 | retval = i2c_wait_done(i2c_adap); | ||
124 | if (retval < 0) | ||
125 | goto err; | ||
126 | |||
127 | if (retval == 0) | ||
128 | goto eio; | ||
129 | |||
130 | if (i2c_debug) { | ||
131 | if (!(ctrl & I2C_NOSTOP)) | ||
132 | printk(" >\n"); | ||
133 | } | ||
134 | |||
135 | for (cnt = 1; cnt < msg->len; cnt++) { | ||
136 | /* following bytes */ | ||
137 | wdata = msg->buf[cnt]; | ||
138 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2); | ||
139 | |||
140 | if (cnt < msg->len - 1) | ||
141 | ctrl |= I2C_NOSTOP | I2C_EXTEND; | ||
142 | else if (joined_rlen) | ||
143 | ctrl |= I2C_NOSTOP; | ||
144 | |||
145 | cx_write(bus->reg_addr, addr); | ||
146 | cx_write(bus->reg_wdata, wdata); | ||
147 | cx_write(bus->reg_ctrl, ctrl); | ||
148 | |||
149 | retval = i2c_wait_done(i2c_adap); | ||
150 | if (retval < 0) | ||
151 | goto err; | ||
152 | |||
153 | if (retval == 0) | ||
154 | goto eio; | ||
155 | |||
156 | if (i2c_debug) { | ||
157 | dprintk(1, " %02x", msg->buf[cnt]); | ||
158 | if (!(ctrl & I2C_NOSTOP)) | ||
159 | dprintk(1, " >\n"); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | return msg->len; | ||
164 | |||
165 | eio: | ||
166 | retval = -EIO; | ||
167 | err: | ||
168 | if (i2c_debug) | ||
169 | pr_err(" ERR: %d\n", retval); | ||
170 | return retval; | ||
171 | } | ||
172 | |||
173 | static int i2c_readbytes(struct i2c_adapter *i2c_adap, | ||
174 | const struct i2c_msg *msg, int joined) | ||
175 | { | ||
176 | struct cx25821_i2c *bus = i2c_adap->algo_data; | ||
177 | struct cx25821_dev *dev = bus->dev; | ||
178 | u32 ctrl, cnt; | ||
179 | int retval; | ||
180 | |||
181 | if (i2c_debug && !joined) | ||
182 | dprintk(1, "6-%s(msg->len=%d)\n", __func__, msg->len); | ||
183 | |||
184 | /* Deal with i2c probe functions with zero payload */ | ||
185 | if (msg->len == 0) { | ||
186 | cx_write(bus->reg_addr, msg->addr << 25); | ||
187 | cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1); | ||
188 | if (!i2c_wait_done(i2c_adap)) | ||
189 | return -EIO; | ||
190 | if (!i2c_slave_did_ack(i2c_adap)) | ||
191 | return -EIO; | ||
192 | |||
193 | dprintk(1, "%s(): returns 0\n", __func__); | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | if (i2c_debug) { | ||
198 | if (joined) | ||
199 | dprintk(1, " R"); | ||
200 | else | ||
201 | dprintk(1, " <R %02x", (msg->addr << 1) + 1); | ||
202 | } | ||
203 | |||
204 | for (cnt = 0; cnt < msg->len; cnt++) { | ||
205 | |||
206 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; | ||
207 | |||
208 | if (cnt < msg->len - 1) | ||
209 | ctrl |= I2C_NOSTOP | I2C_EXTEND; | ||
210 | |||
211 | cx_write(bus->reg_addr, msg->addr << 25); | ||
212 | cx_write(bus->reg_ctrl, ctrl); | ||
213 | |||
214 | retval = i2c_wait_done(i2c_adap); | ||
215 | if (retval < 0) | ||
216 | goto err; | ||
217 | if (retval == 0) | ||
218 | goto eio; | ||
219 | msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; | ||
220 | |||
221 | if (i2c_debug) { | ||
222 | dprintk(1, " %02x", msg->buf[cnt]); | ||
223 | if (!(ctrl & I2C_NOSTOP)) | ||
224 | dprintk(1, " >\n"); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | return msg->len; | ||
229 | eio: | ||
230 | retval = -EIO; | ||
231 | err: | ||
232 | if (i2c_debug) | ||
233 | pr_err(" ERR: %d\n", retval); | ||
234 | return retval; | ||
235 | } | ||
236 | |||
237 | static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) | ||
238 | { | ||
239 | struct cx25821_i2c *bus = i2c_adap->algo_data; | ||
240 | struct cx25821_dev *dev = bus->dev; | ||
241 | int i, retval = 0; | ||
242 | |||
243 | dprintk(1, "%s(num = %d)\n", __func__, num); | ||
244 | |||
245 | for (i = 0; i < num; i++) { | ||
246 | dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", | ||
247 | __func__, num, msgs[i].addr, msgs[i].len); | ||
248 | |||
249 | if (msgs[i].flags & I2C_M_RD) { | ||
250 | /* read */ | ||
251 | retval = i2c_readbytes(i2c_adap, &msgs[i], 0); | ||
252 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && | ||
253 | msgs[i].addr == msgs[i + 1].addr) { | ||
254 | /* write then read from same address */ | ||
255 | retval = i2c_sendbytes(i2c_adap, &msgs[i], | ||
256 | msgs[i + 1].len); | ||
257 | |||
258 | if (retval < 0) | ||
259 | goto err; | ||
260 | i++; | ||
261 | retval = i2c_readbytes(i2c_adap, &msgs[i], 1); | ||
262 | } else { | ||
263 | /* write */ | ||
264 | retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); | ||
265 | } | ||
266 | |||
267 | if (retval < 0) | ||
268 | goto err; | ||
269 | } | ||
270 | return num; | ||
271 | |||
272 | err: | ||
273 | return retval; | ||
274 | } | ||
275 | |||
276 | |||
277 | static u32 cx25821_functionality(struct i2c_adapter *adap) | ||
278 | { | ||
279 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WORD_DATA | | ||
280 | I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA; | ||
281 | } | ||
282 | |||
283 | static struct i2c_algorithm cx25821_i2c_algo_template = { | ||
284 | .master_xfer = i2c_xfer, | ||
285 | .functionality = cx25821_functionality, | ||
286 | #ifdef NEED_ALGO_CONTROL | ||
287 | .algo_control = dummy_algo_control, | ||
288 | #endif | ||
289 | }; | ||
290 | |||
291 | static struct i2c_adapter cx25821_i2c_adap_template = { | ||
292 | .name = "cx25821", | ||
293 | .owner = THIS_MODULE, | ||
294 | .algo = &cx25821_i2c_algo_template, | ||
295 | }; | ||
296 | |||
297 | static struct i2c_client cx25821_i2c_client_template = { | ||
298 | .name = "cx25821 internal", | ||
299 | }; | ||
300 | |||
301 | /* init + register i2c adapter */ | ||
302 | int cx25821_i2c_register(struct cx25821_i2c *bus) | ||
303 | { | ||
304 | struct cx25821_dev *dev = bus->dev; | ||
305 | |||
306 | dprintk(1, "%s(bus = %d)\n", __func__, bus->nr); | ||
307 | |||
308 | bus->i2c_adap = cx25821_i2c_adap_template; | ||
309 | bus->i2c_client = cx25821_i2c_client_template; | ||
310 | bus->i2c_adap.dev.parent = &dev->pci->dev; | ||
311 | |||
312 | strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name)); | ||
313 | |||
314 | bus->i2c_adap.algo_data = bus; | ||
315 | i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); | ||
316 | i2c_add_adapter(&bus->i2c_adap); | ||
317 | |||
318 | bus->i2c_client.adapter = &bus->i2c_adap; | ||
319 | |||
320 | /* set up the I2c */ | ||
321 | bus->i2c_client.addr = (0x88 >> 1); | ||
322 | |||
323 | return bus->i2c_rc; | ||
324 | } | ||
325 | |||
326 | int cx25821_i2c_unregister(struct cx25821_i2c *bus) | ||
327 | { | ||
328 | i2c_del_adapter(&bus->i2c_adap); | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | void cx25821_av_clk(struct cx25821_dev *dev, int enable) | ||
333 | { | ||
334 | /* write 0 to bus 2 addr 0x144 via i2x_xfer() */ | ||
335 | char buffer[3]; | ||
336 | struct i2c_msg msg; | ||
337 | dprintk(1, "%s(enabled = %d)\n", __func__, enable); | ||
338 | |||
339 | /* Register 0x144 */ | ||
340 | buffer[0] = 0x01; | ||
341 | buffer[1] = 0x44; | ||
342 | if (enable == 1) | ||
343 | buffer[2] = 0x05; | ||
344 | else | ||
345 | buffer[2] = 0x00; | ||
346 | |||
347 | msg.addr = 0x44; | ||
348 | msg.flags = I2C_M_TEN; | ||
349 | msg.len = 3; | ||
350 | msg.buf = buffer; | ||
351 | |||
352 | i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1); | ||
353 | } | ||
354 | |||
355 | int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value) | ||
356 | { | ||
357 | struct i2c_client *client = &bus->i2c_client; | ||
358 | int v = 0; | ||
359 | u8 addr[2] = { 0, 0 }; | ||
360 | u8 buf[4] = { 0, 0, 0, 0 }; | ||
361 | |||
362 | struct i2c_msg msgs[2] = { | ||
363 | { | ||
364 | .addr = client->addr, | ||
365 | .flags = 0, | ||
366 | .len = 2, | ||
367 | .buf = addr, | ||
368 | }, { | ||
369 | .addr = client->addr, | ||
370 | .flags = I2C_M_RD, | ||
371 | .len = 4, | ||
372 | .buf = buf, | ||
373 | } | ||
374 | }; | ||
375 | |||
376 | addr[0] = (reg_addr >> 8); | ||
377 | addr[1] = (reg_addr & 0xff); | ||
378 | msgs[0].addr = 0x44; | ||
379 | msgs[1].addr = 0x44; | ||
380 | |||
381 | i2c_xfer(client->adapter, msgs, 2); | ||
382 | |||
383 | v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
384 | *value = v; | ||
385 | |||
386 | return v; | ||
387 | } | ||
388 | |||
389 | int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value) | ||
390 | { | ||
391 | struct i2c_client *client = &bus->i2c_client; | ||
392 | int retval = 0; | ||
393 | u8 buf[6] = { 0, 0, 0, 0, 0, 0 }; | ||
394 | |||
395 | struct i2c_msg msgs[1] = { | ||
396 | { | ||
397 | .addr = client->addr, | ||
398 | .flags = 0, | ||
399 | .len = 6, | ||
400 | .buf = buf, | ||
401 | } | ||
402 | }; | ||
403 | |||
404 | buf[0] = reg_addr >> 8; | ||
405 | buf[1] = reg_addr & 0xff; | ||
406 | buf[5] = (value >> 24) & 0xff; | ||
407 | buf[4] = (value >> 16) & 0xff; | ||
408 | buf[3] = (value >> 8) & 0xff; | ||
409 | buf[2] = value & 0xff; | ||
410 | client->flags = 0; | ||
411 | msgs[0].addr = 0x44; | ||
412 | |||
413 | retval = i2c_xfer(client->adapter, msgs, 1); | ||
414 | |||
415 | return retval; | ||
416 | } | ||
diff --git a/drivers/media/pci/cx25821/cx25821-medusa-defines.h b/drivers/media/pci/cx25821/cx25821-medusa-defines.h new file mode 100644 index 000000000000..7a9e6470ba22 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-medusa-defines.h | |||
@@ -0,0 +1,42 @@ | |||
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 decoder 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 | /* end of display sequence */ | ||
37 | #define END_OF_SEQ 0xF; | ||
38 | |||
39 | /* registry string size */ | ||
40 | #define MAX_REGISTRY_SZ 40; | ||
41 | |||
42 | #endif | ||
diff --git a/drivers/media/pci/cx25821/cx25821-medusa-reg.h b/drivers/media/pci/cx25821/cx25821-medusa-reg.h new file mode 100644 index 000000000000..c98ac946b277 --- /dev/null +++ b/drivers/media/pci/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/media/pci/cx25821/cx25821-medusa-video.c b/drivers/media/pci/cx25821/cx25821-medusa-video.c new file mode 100644 index 000000000000..6a92e5c70c2a --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-medusa-video.c | |||
@@ -0,0 +1,787 @@ | |||
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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
25 | #include "cx25821.h" | ||
26 | #include "cx25821-medusa-video.h" | ||
27 | #include "cx25821-biffuncs.h" | ||
28 | |||
29 | /* | ||
30 | * medusa_enable_bluefield_output() | ||
31 | * | ||
32 | * Enable the generation of blue filed output if no video | ||
33 | * | ||
34 | */ | ||
35 | static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel, | ||
36 | int enable) | ||
37 | { | ||
38 | u32 value = 0; | ||
39 | u32 tmp = 0; | ||
40 | int out_ctrl = OUT_CTRL1; | ||
41 | int out_ctrl_ns = OUT_CTRL_NS; | ||
42 | |||
43 | switch (channel) { | ||
44 | default: | ||
45 | case VDEC_A: | ||
46 | break; | ||
47 | case VDEC_B: | ||
48 | out_ctrl = VDEC_B_OUT_CTRL1; | ||
49 | out_ctrl_ns = VDEC_B_OUT_CTRL_NS; | ||
50 | break; | ||
51 | case VDEC_C: | ||
52 | out_ctrl = VDEC_C_OUT_CTRL1; | ||
53 | out_ctrl_ns = VDEC_C_OUT_CTRL_NS; | ||
54 | break; | ||
55 | case VDEC_D: | ||
56 | out_ctrl = VDEC_D_OUT_CTRL1; | ||
57 | out_ctrl_ns = VDEC_D_OUT_CTRL_NS; | ||
58 | break; | ||
59 | case VDEC_E: | ||
60 | out_ctrl = VDEC_E_OUT_CTRL1; | ||
61 | out_ctrl_ns = VDEC_E_OUT_CTRL_NS; | ||
62 | return; | ||
63 | case VDEC_F: | ||
64 | out_ctrl = VDEC_F_OUT_CTRL1; | ||
65 | out_ctrl_ns = VDEC_F_OUT_CTRL_NS; | ||
66 | return; | ||
67 | case VDEC_G: | ||
68 | out_ctrl = VDEC_G_OUT_CTRL1; | ||
69 | out_ctrl_ns = VDEC_G_OUT_CTRL_NS; | ||
70 | return; | ||
71 | case VDEC_H: | ||
72 | out_ctrl = VDEC_H_OUT_CTRL1; | ||
73 | out_ctrl_ns = VDEC_H_OUT_CTRL_NS; | ||
74 | return; | ||
75 | } | ||
76 | |||
77 | value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp); | ||
78 | value &= 0xFFFFFF7F; /* clear BLUE_FIELD_EN */ | ||
79 | if (enable) | ||
80 | value |= 0x00000080; /* set BLUE_FIELD_EN */ | ||
81 | cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value); | ||
82 | |||
83 | value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp); | ||
84 | value &= 0xFFFFFF7F; | ||
85 | if (enable) | ||
86 | value |= 0x00000080; /* set BLUE_FIELD_EN */ | ||
87 | cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value); | ||
88 | } | ||
89 | |||
90 | static int medusa_initialize_ntsc(struct cx25821_dev *dev) | ||
91 | { | ||
92 | int ret_val = 0; | ||
93 | int i = 0; | ||
94 | u32 value = 0; | ||
95 | u32 tmp = 0; | ||
96 | |||
97 | mutex_lock(&dev->lock); | ||
98 | |||
99 | for (i = 0; i < MAX_DECODERS; i++) { | ||
100 | /* set video format NTSC-M */ | ||
101 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
102 | MODE_CTRL + (0x200 * i), &tmp); | ||
103 | value &= 0xFFFFFFF0; | ||
104 | /* enable the fast locking mode bit[16] */ | ||
105 | value |= 0x10001; | ||
106 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
107 | MODE_CTRL + (0x200 * i), value); | ||
108 | |||
109 | /* resolution NTSC 720x480 */ | ||
110 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
111 | HORIZ_TIM_CTRL + (0x200 * i), &tmp); | ||
112 | value &= 0x00C00C00; | ||
113 | value |= 0x612D0074; | ||
114 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
115 | HORIZ_TIM_CTRL + (0x200 * i), value); | ||
116 | |||
117 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
118 | VERT_TIM_CTRL + (0x200 * i), &tmp); | ||
119 | value &= 0x00C00C00; | ||
120 | value |= 0x1C1E001A; /* vblank_cnt + 2 to get camera ID */ | ||
121 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
122 | VERT_TIM_CTRL + (0x200 * i), value); | ||
123 | |||
124 | /* chroma subcarrier step size */ | ||
125 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
126 | SC_STEP_SIZE + (0x200 * i), 0x43E00000); | ||
127 | |||
128 | /* enable VIP optional active */ | ||
129 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
130 | OUT_CTRL_NS + (0x200 * i), &tmp); | ||
131 | value &= 0xFFFBFFFF; | ||
132 | value |= 0x00040000; | ||
133 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
134 | OUT_CTRL_NS + (0x200 * i), value); | ||
135 | |||
136 | /* enable VIP optional active (VIP_OPT_AL) for direct output. */ | ||
137 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
138 | OUT_CTRL1 + (0x200 * i), &tmp); | ||
139 | value &= 0xFFFBFFFF; | ||
140 | value |= 0x00040000; | ||
141 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
142 | OUT_CTRL1 + (0x200 * i), value); | ||
143 | |||
144 | /* | ||
145 | * clear VPRES_VERT_EN bit, fixes the chroma run away problem | ||
146 | * when the input switching rate < 16 fields | ||
147 | */ | ||
148 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
149 | MISC_TIM_CTRL + (0x200 * i), &tmp); | ||
150 | /* disable special play detection */ | ||
151 | value = setBitAtPos(value, 14); | ||
152 | value = clearBitAtPos(value, 15); | ||
153 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
154 | MISC_TIM_CTRL + (0x200 * i), value); | ||
155 | |||
156 | /* set vbi_gate_en to 0 */ | ||
157 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
158 | DFE_CTRL1 + (0x200 * i), &tmp); | ||
159 | value = clearBitAtPos(value, 29); | ||
160 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
161 | DFE_CTRL1 + (0x200 * i), value); | ||
162 | |||
163 | /* Enable the generation of blue field output if no video */ | ||
164 | medusa_enable_bluefield_output(dev, i, 1); | ||
165 | } | ||
166 | |||
167 | for (i = 0; i < MAX_ENCODERS; i++) { | ||
168 | /* NTSC hclock */ | ||
169 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
170 | DENC_A_REG_1 + (0x100 * i), &tmp); | ||
171 | value &= 0xF000FC00; | ||
172 | value |= 0x06B402D0; | ||
173 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
174 | DENC_A_REG_1 + (0x100 * i), value); | ||
175 | |||
176 | /* burst begin and burst end */ | ||
177 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
178 | DENC_A_REG_2 + (0x100 * i), &tmp); | ||
179 | value &= 0xFF000000; | ||
180 | value |= 0x007E9054; | ||
181 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
182 | DENC_A_REG_2 + (0x100 * i), value); | ||
183 | |||
184 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
185 | DENC_A_REG_3 + (0x100 * i), &tmp); | ||
186 | value &= 0xFC00FE00; | ||
187 | value |= 0x00EC00F0; | ||
188 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
189 | DENC_A_REG_3 + (0x100 * i), value); | ||
190 | |||
191 | /* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */ | ||
192 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
193 | DENC_A_REG_4 + (0x100 * i), &tmp); | ||
194 | value &= 0x00FCFFFF; | ||
195 | value |= 0x13020000; | ||
196 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
197 | DENC_A_REG_4 + (0x100 * i), value); | ||
198 | |||
199 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
200 | DENC_A_REG_5 + (0x100 * i), &tmp); | ||
201 | value &= 0xFFFF0000; | ||
202 | value |= 0x0000E575; | ||
203 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
204 | DENC_A_REG_5 + (0x100 * i), value); | ||
205 | |||
206 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
207 | DENC_A_REG_6 + (0x100 * i), 0x009A89C1); | ||
208 | |||
209 | /* Subcarrier Increment */ | ||
210 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
211 | DENC_A_REG_7 + (0x100 * i), 0x21F07C1F); | ||
212 | } | ||
213 | |||
214 | /* set picture resolutions */ | ||
215 | /* 0 - 720 */ | ||
216 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); | ||
217 | /* 0 - 480 */ | ||
218 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); | ||
219 | |||
220 | /* set Bypass input format to NTSC 525 lines */ | ||
221 | value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); | ||
222 | value |= 0x00080200; | ||
223 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); | ||
224 | |||
225 | mutex_unlock(&dev->lock); | ||
226 | |||
227 | return ret_val; | ||
228 | } | ||
229 | |||
230 | static int medusa_PALCombInit(struct cx25821_dev *dev, int dec) | ||
231 | { | ||
232 | int ret_val = -1; | ||
233 | u32 value = 0, tmp = 0; | ||
234 | |||
235 | /* Setup for 2D threshold */ | ||
236 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
237 | COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861); | ||
238 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
239 | COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861); | ||
240 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
241 | COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023); | ||
242 | |||
243 | /* Setup flat chroma and luma thresholds */ | ||
244 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
245 | COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp); | ||
246 | value &= 0x06230000; | ||
247 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
248 | COMB_FLAT_THRESH_CTRL + (0x200 * dec), value); | ||
249 | |||
250 | /* set comb 2D blend */ | ||
251 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
252 | COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F); | ||
253 | |||
254 | /* COMB MISC CONTROL */ | ||
255 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
256 | COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F); | ||
257 | |||
258 | return ret_val; | ||
259 | } | ||
260 | |||
261 | static int medusa_initialize_pal(struct cx25821_dev *dev) | ||
262 | { | ||
263 | int ret_val = 0; | ||
264 | int i = 0; | ||
265 | u32 value = 0; | ||
266 | u32 tmp = 0; | ||
267 | |||
268 | mutex_lock(&dev->lock); | ||
269 | |||
270 | for (i = 0; i < MAX_DECODERS; i++) { | ||
271 | /* set video format PAL-BDGHI */ | ||
272 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
273 | MODE_CTRL + (0x200 * i), &tmp); | ||
274 | value &= 0xFFFFFFF0; | ||
275 | /* enable the fast locking mode bit[16] */ | ||
276 | value |= 0x10004; | ||
277 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
278 | MODE_CTRL + (0x200 * i), value); | ||
279 | |||
280 | /* resolution PAL 720x576 */ | ||
281 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
282 | HORIZ_TIM_CTRL + (0x200 * i), &tmp); | ||
283 | value &= 0x00C00C00; | ||
284 | value |= 0x632D007D; | ||
285 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
286 | HORIZ_TIM_CTRL + (0x200 * i), value); | ||
287 | |||
288 | /* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */ | ||
289 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
290 | VERT_TIM_CTRL + (0x200 * i), &tmp); | ||
291 | value &= 0x00C00C00; | ||
292 | value |= 0x28240026; /* vblank_cnt + 2 to get camera ID */ | ||
293 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
294 | VERT_TIM_CTRL + (0x200 * i), value); | ||
295 | |||
296 | /* chroma subcarrier step size */ | ||
297 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
298 | SC_STEP_SIZE + (0x200 * i), 0x5411E2D0); | ||
299 | |||
300 | /* enable VIP optional active */ | ||
301 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
302 | OUT_CTRL_NS + (0x200 * i), &tmp); | ||
303 | value &= 0xFFFBFFFF; | ||
304 | value |= 0x00040000; | ||
305 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
306 | OUT_CTRL_NS + (0x200 * i), value); | ||
307 | |||
308 | /* enable VIP optional active (VIP_OPT_AL) for direct output. */ | ||
309 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
310 | OUT_CTRL1 + (0x200 * i), &tmp); | ||
311 | value &= 0xFFFBFFFF; | ||
312 | value |= 0x00040000; | ||
313 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
314 | OUT_CTRL1 + (0x200 * i), value); | ||
315 | |||
316 | /* | ||
317 | * clear VPRES_VERT_EN bit, fixes the chroma run away problem | ||
318 | * when the input switching rate < 16 fields | ||
319 | */ | ||
320 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
321 | MISC_TIM_CTRL + (0x200 * i), &tmp); | ||
322 | /* disable special play detection */ | ||
323 | value = setBitAtPos(value, 14); | ||
324 | value = clearBitAtPos(value, 15); | ||
325 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
326 | MISC_TIM_CTRL + (0x200 * i), value); | ||
327 | |||
328 | /* set vbi_gate_en to 0 */ | ||
329 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
330 | DFE_CTRL1 + (0x200 * i), &tmp); | ||
331 | value = clearBitAtPos(value, 29); | ||
332 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
333 | DFE_CTRL1 + (0x200 * i), value); | ||
334 | |||
335 | medusa_PALCombInit(dev, i); | ||
336 | |||
337 | /* Enable the generation of blue field output if no video */ | ||
338 | medusa_enable_bluefield_output(dev, i, 1); | ||
339 | } | ||
340 | |||
341 | for (i = 0; i < MAX_ENCODERS; i++) { | ||
342 | /* PAL hclock */ | ||
343 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
344 | DENC_A_REG_1 + (0x100 * i), &tmp); | ||
345 | value &= 0xF000FC00; | ||
346 | value |= 0x06C002D0; | ||
347 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
348 | DENC_A_REG_1 + (0x100 * i), value); | ||
349 | |||
350 | /* burst begin and burst end */ | ||
351 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
352 | DENC_A_REG_2 + (0x100 * i), &tmp); | ||
353 | value &= 0xFF000000; | ||
354 | value |= 0x007E9754; | ||
355 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
356 | DENC_A_REG_2 + (0x100 * i), value); | ||
357 | |||
358 | /* hblank and vactive */ | ||
359 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
360 | DENC_A_REG_3 + (0x100 * i), &tmp); | ||
361 | value &= 0xFC00FE00; | ||
362 | value |= 0x00FC0120; | ||
363 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
364 | DENC_A_REG_3 + (0x100 * i), value); | ||
365 | |||
366 | /* set PAL vblank, phase alternation, 0 IRE pedestal */ | ||
367 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
368 | DENC_A_REG_4 + (0x100 * i), &tmp); | ||
369 | value &= 0x00FCFFFF; | ||
370 | value |= 0x14010000; | ||
371 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
372 | DENC_A_REG_4 + (0x100 * i), value); | ||
373 | |||
374 | value = cx25821_i2c_read(&dev->i2c_bus[0], | ||
375 | DENC_A_REG_5 + (0x100 * i), &tmp); | ||
376 | value &= 0xFFFF0000; | ||
377 | value |= 0x0000F078; | ||
378 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
379 | DENC_A_REG_5 + (0x100 * i), value); | ||
380 | |||
381 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
382 | DENC_A_REG_6 + (0x100 * i), 0x00A493CF); | ||
383 | |||
384 | /* Subcarrier Increment */ | ||
385 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], | ||
386 | DENC_A_REG_7 + (0x100 * i), 0x2A098ACB); | ||
387 | } | ||
388 | |||
389 | /* set picture resolutions */ | ||
390 | /* 0 - 720 */ | ||
391 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); | ||
392 | /* 0 - 576 */ | ||
393 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); | ||
394 | |||
395 | /* set Bypass input format to PAL 625 lines */ | ||
396 | value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); | ||
397 | value &= 0xFFF7FDFF; | ||
398 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); | ||
399 | |||
400 | mutex_unlock(&dev->lock); | ||
401 | |||
402 | return ret_val; | ||
403 | } | ||
404 | |||
405 | int medusa_set_videostandard(struct cx25821_dev *dev) | ||
406 | { | ||
407 | int status = STATUS_SUCCESS; | ||
408 | u32 value = 0, tmp = 0; | ||
409 | |||
410 | if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) | ||
411 | status = medusa_initialize_pal(dev); | ||
412 | else | ||
413 | status = medusa_initialize_ntsc(dev); | ||
414 | |||
415 | /* Enable DENC_A output */ | ||
416 | value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp); | ||
417 | value = setBitAtPos(value, 4); | ||
418 | status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value); | ||
419 | |||
420 | /* Enable DENC_B output */ | ||
421 | value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp); | ||
422 | value = setBitAtPos(value, 4); | ||
423 | status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value); | ||
424 | |||
425 | return status; | ||
426 | } | ||
427 | |||
428 | void medusa_set_resolution(struct cx25821_dev *dev, int width, | ||
429 | int decoder_select) | ||
430 | { | ||
431 | int decoder = 0; | ||
432 | int decoder_count = 0; | ||
433 | u32 hscale = 0x0; | ||
434 | u32 vscale = 0x0; | ||
435 | const int MAX_WIDTH = 720; | ||
436 | |||
437 | mutex_lock(&dev->lock); | ||
438 | |||
439 | /* validate the width */ | ||
440 | if (width > MAX_WIDTH) { | ||
441 | pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n", | ||
442 | __func__, width, MAX_WIDTH); | ||
443 | width = MAX_WIDTH; | ||
444 | } | ||
445 | |||
446 | if (decoder_select <= 7 && decoder_select >= 0) { | ||
447 | decoder = decoder_select; | ||
448 | decoder_count = decoder_select + 1; | ||
449 | } else { | ||
450 | decoder = 0; | ||
451 | decoder_count = _num_decoders; | ||
452 | } | ||
453 | |||
454 | switch (width) { | ||
455 | case 320: | ||
456 | hscale = 0x13E34B; | ||
457 | vscale = 0x0; | ||
458 | break; | ||
459 | |||
460 | case 352: | ||
461 | hscale = 0x10A273; | ||
462 | vscale = 0x0; | ||
463 | break; | ||
464 | |||
465 | case 176: | ||
466 | hscale = 0x3115B2; | ||
467 | vscale = 0x1E00; | ||
468 | break; | ||
469 | |||
470 | case 160: | ||
471 | hscale = 0x378D84; | ||
472 | vscale = 0x1E00; | ||
473 | break; | ||
474 | |||
475 | default: /* 720 */ | ||
476 | hscale = 0x0; | ||
477 | vscale = 0x0; | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | for (; decoder < decoder_count; decoder++) { | ||
482 | /* write scaling values for each decoder */ | ||
483 | cx25821_i2c_write(&dev->i2c_bus[0], | ||
484 | HSCALE_CTRL + (0x200 * decoder), hscale); | ||
485 | cx25821_i2c_write(&dev->i2c_bus[0], | ||
486 | VSCALE_CTRL + (0x200 * decoder), vscale); | ||
487 | } | ||
488 | |||
489 | mutex_unlock(&dev->lock); | ||
490 | } | ||
491 | |||
492 | static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, | ||
493 | int duration) | ||
494 | { | ||
495 | u32 fld_cnt = 0; | ||
496 | u32 tmp = 0; | ||
497 | u32 disp_cnt_reg = DISP_AB_CNT; | ||
498 | |||
499 | mutex_lock(&dev->lock); | ||
500 | |||
501 | /* no support */ | ||
502 | if (decoder < VDEC_A || decoder > VDEC_H) { | ||
503 | mutex_unlock(&dev->lock); | ||
504 | return; | ||
505 | } | ||
506 | |||
507 | switch (decoder) { | ||
508 | default: | ||
509 | break; | ||
510 | case VDEC_C: | ||
511 | case VDEC_D: | ||
512 | disp_cnt_reg = DISP_CD_CNT; | ||
513 | break; | ||
514 | case VDEC_E: | ||
515 | case VDEC_F: | ||
516 | disp_cnt_reg = DISP_EF_CNT; | ||
517 | break; | ||
518 | case VDEC_G: | ||
519 | case VDEC_H: | ||
520 | disp_cnt_reg = DISP_GH_CNT; | ||
521 | break; | ||
522 | } | ||
523 | |||
524 | _display_field_cnt[decoder] = duration; | ||
525 | |||
526 | /* update hardware */ | ||
527 | fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp); | ||
528 | |||
529 | if (!(decoder % 2)) { /* EVEN decoder */ | ||
530 | fld_cnt &= 0xFFFF0000; | ||
531 | fld_cnt |= duration; | ||
532 | } else { | ||
533 | fld_cnt &= 0x0000FFFF; | ||
534 | fld_cnt |= ((u32) duration) << 16; | ||
535 | } | ||
536 | |||
537 | cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt); | ||
538 | |||
539 | mutex_unlock(&dev->lock); | ||
540 | } | ||
541 | |||
542 | /* Map to Medusa register setting */ | ||
543 | static int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax, | ||
544 | int *dstVal) | ||
545 | { | ||
546 | int numerator; | ||
547 | int denominator; | ||
548 | int quotient; | ||
549 | |||
550 | if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax)) | ||
551 | return -1; | ||
552 | /* | ||
553 | * This is the overall expression used: | ||
554 | * *dstVal = | ||
555 | * (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin; | ||
556 | * but we need to account for rounding so below we use the modulus | ||
557 | * operator to find the remainder and increment if necessary. | ||
558 | */ | ||
559 | numerator = (srcVal - srcMin) * (dstMax - dstMin); | ||
560 | denominator = srcMax - srcMin; | ||
561 | quotient = numerator / denominator; | ||
562 | |||
563 | if (2 * (numerator % denominator) >= denominator) | ||
564 | quotient++; | ||
565 | |||
566 | *dstVal = quotient + dstMin; | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | static unsigned long convert_to_twos(long numeric, unsigned long bits_len) | ||
572 | { | ||
573 | unsigned char temp; | ||
574 | |||
575 | if (numeric >= 0) | ||
576 | return numeric; | ||
577 | else { | ||
578 | temp = ~(abs(numeric) & 0xFF); | ||
579 | temp += 1; | ||
580 | return temp; | ||
581 | } | ||
582 | } | ||
583 | |||
584 | int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder) | ||
585 | { | ||
586 | int ret_val = 0; | ||
587 | int value = 0; | ||
588 | u32 val = 0, tmp = 0; | ||
589 | |||
590 | mutex_lock(&dev->lock); | ||
591 | if ((brightness > VIDEO_PROCAMP_MAX) || | ||
592 | (brightness < VIDEO_PROCAMP_MIN)) { | ||
593 | mutex_unlock(&dev->lock); | ||
594 | return -1; | ||
595 | } | ||
596 | ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, | ||
597 | SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); | ||
598 | value = convert_to_twos(value, 8); | ||
599 | val = cx25821_i2c_read(&dev->i2c_bus[0], | ||
600 | VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp); | ||
601 | val &= 0xFFFFFF00; | ||
602 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], | ||
603 | VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value); | ||
604 | mutex_unlock(&dev->lock); | ||
605 | return ret_val; | ||
606 | } | ||
607 | |||
608 | int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder) | ||
609 | { | ||
610 | int ret_val = 0; | ||
611 | int value = 0; | ||
612 | u32 val = 0, tmp = 0; | ||
613 | |||
614 | mutex_lock(&dev->lock); | ||
615 | |||
616 | if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) { | ||
617 | mutex_unlock(&dev->lock); | ||
618 | return -1; | ||
619 | } | ||
620 | |||
621 | ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast, | ||
622 | UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); | ||
623 | val = cx25821_i2c_read(&dev->i2c_bus[0], | ||
624 | VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp); | ||
625 | val &= 0xFFFFFF00; | ||
626 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], | ||
627 | VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value); | ||
628 | |||
629 | mutex_unlock(&dev->lock); | ||
630 | return ret_val; | ||
631 | } | ||
632 | |||
633 | int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder) | ||
634 | { | ||
635 | int ret_val = 0; | ||
636 | int value = 0; | ||
637 | u32 val = 0, tmp = 0; | ||
638 | |||
639 | mutex_lock(&dev->lock); | ||
640 | |||
641 | if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) { | ||
642 | mutex_unlock(&dev->lock); | ||
643 | return -1; | ||
644 | } | ||
645 | |||
646 | ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, | ||
647 | SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); | ||
648 | |||
649 | value = convert_to_twos(value, 8); | ||
650 | val = cx25821_i2c_read(&dev->i2c_bus[0], | ||
651 | VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp); | ||
652 | val &= 0xFFFFFF00; | ||
653 | |||
654 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], | ||
655 | VDEC_A_HUE_CTRL + (0x200 * decoder), val | value); | ||
656 | |||
657 | mutex_unlock(&dev->lock); | ||
658 | return ret_val; | ||
659 | } | ||
660 | |||
661 | int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) | ||
662 | { | ||
663 | int ret_val = 0; | ||
664 | int value = 0; | ||
665 | u32 val = 0, tmp = 0; | ||
666 | |||
667 | mutex_lock(&dev->lock); | ||
668 | |||
669 | if ((saturation > VIDEO_PROCAMP_MAX) || | ||
670 | (saturation < VIDEO_PROCAMP_MIN)) { | ||
671 | mutex_unlock(&dev->lock); | ||
672 | return -1; | ||
673 | } | ||
674 | |||
675 | ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation, | ||
676 | UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); | ||
677 | |||
678 | val = cx25821_i2c_read(&dev->i2c_bus[0], | ||
679 | VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp); | ||
680 | val &= 0xFFFFFF00; | ||
681 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], | ||
682 | VDEC_A_USAT_CTRL + (0x200 * decoder), val | value); | ||
683 | |||
684 | val = cx25821_i2c_read(&dev->i2c_bus[0], | ||
685 | VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp); | ||
686 | val &= 0xFFFFFF00; | ||
687 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], | ||
688 | VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value); | ||
689 | |||
690 | mutex_unlock(&dev->lock); | ||
691 | return ret_val; | ||
692 | } | ||
693 | |||
694 | /* Program the display sequence and monitor output. */ | ||
695 | |||
696 | int medusa_video_init(struct cx25821_dev *dev) | ||
697 | { | ||
698 | u32 value = 0, tmp = 0; | ||
699 | int ret_val = 0; | ||
700 | int i = 0; | ||
701 | |||
702 | mutex_lock(&dev->lock); | ||
703 | |||
704 | _num_decoders = dev->_max_num_decoders; | ||
705 | |||
706 | /* disable Auto source selection on all video decoders */ | ||
707 | value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); | ||
708 | value &= 0xFFFFF0FF; | ||
709 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value); | ||
710 | |||
711 | if (ret_val < 0) | ||
712 | goto error; | ||
713 | |||
714 | /* Turn off Master source switch enable */ | ||
715 | value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); | ||
716 | value &= 0xFFFFFFDF; | ||
717 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value); | ||
718 | |||
719 | if (ret_val < 0) | ||
720 | goto error; | ||
721 | |||
722 | mutex_unlock(&dev->lock); | ||
723 | |||
724 | for (i = 0; i < _num_decoders; i++) | ||
725 | medusa_set_decoderduration(dev, i, _display_field_cnt[i]); | ||
726 | |||
727 | mutex_lock(&dev->lock); | ||
728 | |||
729 | /* Select monitor as DENC A input, power up the DAC */ | ||
730 | value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp); | ||
731 | value &= 0xFF70FF70; | ||
732 | value |= 0x00090008; /* set en_active */ | ||
733 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value); | ||
734 | |||
735 | if (ret_val < 0) | ||
736 | goto error; | ||
737 | |||
738 | /* enable input is VIP/656 */ | ||
739 | value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); | ||
740 | value |= 0x00040100; /* enable VIP */ | ||
741 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); | ||
742 | |||
743 | if (ret_val < 0) | ||
744 | goto error; | ||
745 | |||
746 | /* select AFE clock to output mode */ | ||
747 | value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); | ||
748 | value &= 0x83FFFFFF; | ||
749 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, | ||
750 | value | 0x10000000); | ||
751 | |||
752 | if (ret_val < 0) | ||
753 | goto error; | ||
754 | |||
755 | /* Turn on all of the data out and control output pins. */ | ||
756 | value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp); | ||
757 | value &= 0xFEF0FE00; | ||
758 | if (_num_decoders == MAX_DECODERS) { | ||
759 | /* | ||
760 | * Note: The octal board does not support control pins(bit16-19) | ||
761 | * These bits are ignored in the octal board. | ||
762 | * | ||
763 | * disable VDEC A-C port, default to Mobilygen Interface | ||
764 | */ | ||
765 | value |= 0x010001F8; | ||
766 | } else { | ||
767 | /* disable VDEC A-C port, default to Mobilygen Interface */ | ||
768 | value |= 0x010F0108; | ||
769 | } | ||
770 | |||
771 | value |= 7; | ||
772 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value); | ||
773 | |||
774 | if (ret_val < 0) | ||
775 | goto error; | ||
776 | |||
777 | |||
778 | mutex_unlock(&dev->lock); | ||
779 | |||
780 | ret_val = medusa_set_videostandard(dev); | ||
781 | |||
782 | return ret_val; | ||
783 | |||
784 | error: | ||
785 | mutex_unlock(&dev->lock); | ||
786 | return ret_val; | ||
787 | } | ||
diff --git a/drivers/media/pci/cx25821/cx25821-medusa-video.h b/drivers/media/pci/cx25821/cx25821-medusa-video.h new file mode 100644 index 000000000000..6175e0961855 --- /dev/null +++ b/drivers/media/pci/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 | |||
43 | unsigned short _num_decoders; | ||
44 | unsigned short _num_cameras; | ||
45 | |||
46 | unsigned int _video_standard; | ||
47 | int _display_field_cnt[MAX_DECODERS]; | ||
48 | |||
49 | #endif | ||
diff --git a/drivers/media/pci/cx25821/cx25821-reg.h b/drivers/media/pci/cx25821/cx25821-reg.h new file mode 100644 index 000000000000..a3fc25a4dc0b --- /dev/null +++ b/drivers/media/pci/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/media/pci/cx25821/cx25821-sram.h b/drivers/media/pci/cx25821/cx25821-sram.h new file mode 100644 index 000000000000..5f05d153bc4d --- /dev/null +++ b/drivers/media/pci/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/media/pci/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c new file mode 100644 index 000000000000..c8c94fbf5d8d --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c | |||
@@ -0,0 +1,802 @@ | |||
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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
25 | #include "cx25821-video.h" | ||
26 | #include "cx25821-video-upstream-ch2.h" | ||
27 | |||
28 | #include <linux/fs.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/syscalls.h> | ||
34 | #include <linux/file.h> | ||
35 | #include <linux/fcntl.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | |||
39 | MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); | ||
40 | MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); | ||
41 | MODULE_LICENSE("GPL"); | ||
42 | |||
43 | static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | | ||
44 | FLD_VID_SRC_OPC_ERR; | ||
45 | |||
46 | static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, | ||
47 | __le32 *rp, unsigned int offset, | ||
48 | unsigned int bpl, u32 sync_line, | ||
49 | unsigned int lines, | ||
50 | int fifo_enable, int field_type) | ||
51 | { | ||
52 | unsigned int line, i; | ||
53 | int dist_betwn_starts = bpl * 2; | ||
54 | |||
55 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | ||
56 | |||
57 | if (USE_RISC_NOOP_VIDEO) { | ||
58 | for (i = 0; i < NUM_NO_OPS; i++) | ||
59 | *(rp++) = cpu_to_le32(RISC_NOOP); | ||
60 | } | ||
61 | |||
62 | /* scan lines */ | ||
63 | for (line = 0; line < lines; line++) { | ||
64 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); | ||
65 | *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset); | ||
66 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
67 | |||
68 | if ((lines <= NTSC_FIELD_HEIGHT) || | ||
69 | (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { | ||
70 | offset += dist_betwn_starts; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | return rp; | ||
75 | } | ||
76 | |||
77 | static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, | ||
78 | __le32 *rp, | ||
79 | dma_addr_t databuf_phys_addr, | ||
80 | unsigned int offset, | ||
81 | u32 sync_line, unsigned int bpl, | ||
82 | unsigned int lines, | ||
83 | int fifo_enable, int field_type) | ||
84 | { | ||
85 | unsigned int line, i; | ||
86 | struct sram_channel *sram_ch = | ||
87 | dev->channels[dev->_channel2_upstream_select].sram_channels; | ||
88 | int dist_betwn_starts = bpl * 2; | ||
89 | |||
90 | /* sync instruction */ | ||
91 | if (sync_line != NO_SYNC_LINE) | ||
92 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | ||
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 | /* scan lines */ | ||
100 | for (line = 0; line < lines; line++) { | ||
101 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); | ||
102 | *(rp++) = cpu_to_le32(databuf_phys_addr + offset); | ||
103 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
104 | |||
105 | if ((lines <= NTSC_FIELD_HEIGHT) || | ||
106 | (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { | ||
107 | offset += dist_betwn_starts; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | check if we need to enable the FIFO after the first 4 lines | ||
112 | For the upstream video channel, the risc engine will enable | ||
113 | the FIFO. | ||
114 | */ | ||
115 | if (fifo_enable && line == 3) { | ||
116 | *(rp++) = RISC_WRITECR; | ||
117 | *(rp++) = sram_ch->dma_ctl; | ||
118 | *(rp++) = FLD_VID_FIFO_EN; | ||
119 | *(rp++) = 0x00000001; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | return rp; | ||
124 | } | ||
125 | |||
126 | int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, | ||
127 | struct pci_dev *pci, | ||
128 | unsigned int top_offset, unsigned int bpl, | ||
129 | unsigned int lines) | ||
130 | { | ||
131 | __le32 *rp; | ||
132 | int fifo_enable = 0; | ||
133 | int singlefield_lines = lines >> 1; /*get line count for single field */ | ||
134 | int odd_num_lines = singlefield_lines; | ||
135 | int frame = 0; | ||
136 | int frame_size = 0; | ||
137 | int databuf_offset = 0; | ||
138 | int risc_program_size = 0; | ||
139 | int risc_flag = RISC_CNT_RESET; | ||
140 | unsigned int bottom_offset = bpl; | ||
141 | dma_addr_t risc_phys_jump_addr; | ||
142 | |||
143 | if (dev->_isNTSC_ch2) { | ||
144 | odd_num_lines = singlefield_lines + 1; | ||
145 | risc_program_size = FRAME1_VID_PROG_SIZE; | ||
146 | if (bpl == Y411_LINE_SZ) | ||
147 | frame_size = FRAME_SIZE_NTSC_Y411; | ||
148 | else | ||
149 | frame_size = FRAME_SIZE_NTSC_Y422; | ||
150 | } else { | ||
151 | risc_program_size = PAL_VID_PROG_SIZE; | ||
152 | if (bpl == Y411_LINE_SZ) | ||
153 | frame_size = FRAME_SIZE_PAL_Y411; | ||
154 | else | ||
155 | frame_size = FRAME_SIZE_PAL_Y422; | ||
156 | } | ||
157 | |||
158 | /* Virtual address of Risc buffer program */ | ||
159 | rp = dev->_dma_virt_addr_ch2; | ||
160 | |||
161 | for (frame = 0; frame < NUM_FRAMES; frame++) { | ||
162 | databuf_offset = frame_size * frame; | ||
163 | |||
164 | if (UNSET != top_offset) { | ||
165 | fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; | ||
166 | rp = cx25821_risc_field_upstream_ch2(dev, rp, | ||
167 | dev->_data_buf_phys_addr_ch2 + databuf_offset, | ||
168 | top_offset, 0, bpl, odd_num_lines, fifo_enable, | ||
169 | ODD_FIELD); | ||
170 | } | ||
171 | |||
172 | fifo_enable = FIFO_DISABLE; | ||
173 | |||
174 | /* Even field */ | ||
175 | rp = cx25821_risc_field_upstream_ch2(dev, rp, | ||
176 | dev->_data_buf_phys_addr_ch2 + databuf_offset, | ||
177 | bottom_offset, 0x200, bpl, singlefield_lines, | ||
178 | fifo_enable, EVEN_FIELD); | ||
179 | |||
180 | if (frame == 0) { | ||
181 | risc_flag = RISC_CNT_RESET; | ||
182 | risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2 + | ||
183 | risc_program_size; | ||
184 | } else { | ||
185 | risc_flag = RISC_CNT_INC; | ||
186 | risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2; | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * Loop to 2ndFrameRISC or to Start of | ||
191 | * Risc program & generate IRQ | ||
192 | */ | ||
193 | *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); | ||
194 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | ||
195 | *(rp++) = cpu_to_le32(0); | ||
196 | } | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) | ||
202 | { | ||
203 | struct sram_channel *sram_ch = | ||
204 | dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; | ||
205 | u32 tmp = 0; | ||
206 | |||
207 | if (!dev->_is_running_ch2) { | ||
208 | pr_info("No video file is currently running so return!\n"); | ||
209 | return; | ||
210 | } | ||
211 | /* Disable RISC interrupts */ | ||
212 | tmp = cx_read(sram_ch->int_msk); | ||
213 | cx_write(sram_ch->int_msk, tmp & ~_intr_msk); | ||
214 | |||
215 | /* Turn OFF risc and fifo */ | ||
216 | tmp = cx_read(sram_ch->dma_ctl); | ||
217 | cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); | ||
218 | |||
219 | /* Clear data buffer memory */ | ||
220 | if (dev->_data_buf_virt_addr_ch2) | ||
221 | memset(dev->_data_buf_virt_addr_ch2, 0, | ||
222 | dev->_data_buf_size_ch2); | ||
223 | |||
224 | dev->_is_running_ch2 = 0; | ||
225 | dev->_is_first_frame_ch2 = 0; | ||
226 | dev->_frame_count_ch2 = 0; | ||
227 | dev->_file_status_ch2 = END_OF_FILE; | ||
228 | |||
229 | kfree(dev->_irq_queues_ch2); | ||
230 | dev->_irq_queues_ch2 = NULL; | ||
231 | |||
232 | kfree(dev->_filename_ch2); | ||
233 | |||
234 | tmp = cx_read(VID_CH_MODE_SEL); | ||
235 | cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); | ||
236 | } | ||
237 | |||
238 | void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev) | ||
239 | { | ||
240 | if (dev->_is_running_ch2) | ||
241 | cx25821_stop_upstream_video_ch2(dev); | ||
242 | |||
243 | if (dev->_dma_virt_addr_ch2) { | ||
244 | pci_free_consistent(dev->pci, dev->_risc_size_ch2, | ||
245 | dev->_dma_virt_addr_ch2, | ||
246 | dev->_dma_phys_addr_ch2); | ||
247 | dev->_dma_virt_addr_ch2 = NULL; | ||
248 | } | ||
249 | |||
250 | if (dev->_data_buf_virt_addr_ch2) { | ||
251 | pci_free_consistent(dev->pci, dev->_data_buf_size_ch2, | ||
252 | dev->_data_buf_virt_addr_ch2, | ||
253 | dev->_data_buf_phys_addr_ch2); | ||
254 | dev->_data_buf_virt_addr_ch2 = NULL; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | ||
259 | { | ||
260 | struct file *myfile; | ||
261 | int frame_index_temp = dev->_frame_index_ch2; | ||
262 | int i = 0; | ||
263 | int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? | ||
264 | Y411_LINE_SZ : Y422_LINE_SZ; | ||
265 | int frame_size = 0; | ||
266 | int frame_offset = 0; | ||
267 | ssize_t vfs_read_retval = 0; | ||
268 | char mybuf[line_size]; | ||
269 | loff_t file_offset; | ||
270 | loff_t pos; | ||
271 | mm_segment_t old_fs; | ||
272 | |||
273 | if (dev->_file_status_ch2 == END_OF_FILE) | ||
274 | return 0; | ||
275 | |||
276 | if (dev->_isNTSC_ch2) { | ||
277 | frame_size = (line_size == Y411_LINE_SZ) ? | ||
278 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; | ||
279 | } else { | ||
280 | frame_size = (line_size == Y411_LINE_SZ) ? | ||
281 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; | ||
282 | } | ||
283 | |||
284 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; | ||
285 | file_offset = dev->_frame_count_ch2 * frame_size; | ||
286 | |||
287 | myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); | ||
288 | if (IS_ERR(myfile)) { | ||
289 | const int open_errno = -PTR_ERR(myfile); | ||
290 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | ||
291 | __func__, dev->_filename_ch2, open_errno); | ||
292 | return PTR_ERR(myfile); | ||
293 | } else { | ||
294 | if (!(myfile->f_op)) { | ||
295 | pr_err("%s(): File has no file operations registered!\n", | ||
296 | __func__); | ||
297 | filp_close(myfile, NULL); | ||
298 | return -EIO; | ||
299 | } | ||
300 | |||
301 | if (!myfile->f_op->read) { | ||
302 | pr_err("%s(): File has no READ operations registered!\n", | ||
303 | __func__); | ||
304 | filp_close(myfile, NULL); | ||
305 | return -EIO; | ||
306 | } | ||
307 | |||
308 | pos = myfile->f_pos; | ||
309 | old_fs = get_fs(); | ||
310 | set_fs(KERNEL_DS); | ||
311 | |||
312 | for (i = 0; i < dev->_lines_count_ch2; i++) { | ||
313 | pos = file_offset; | ||
314 | |||
315 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, | ||
316 | &pos); | ||
317 | |||
318 | if (vfs_read_retval > 0 && vfs_read_retval == line_size | ||
319 | && dev->_data_buf_virt_addr_ch2 != NULL) { | ||
320 | memcpy((void *)(dev->_data_buf_virt_addr_ch2 + | ||
321 | frame_offset / 4), mybuf, | ||
322 | vfs_read_retval); | ||
323 | } | ||
324 | |||
325 | file_offset += vfs_read_retval; | ||
326 | frame_offset += vfs_read_retval; | ||
327 | |||
328 | if (vfs_read_retval < line_size) { | ||
329 | pr_info("Done: exit %s() since no more bytes to read from Video file\n", | ||
330 | __func__); | ||
331 | break; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | if (i > 0) | ||
336 | dev->_frame_count_ch2++; | ||
337 | |||
338 | dev->_file_status_ch2 = (vfs_read_retval == line_size) ? | ||
339 | IN_PROGRESS : END_OF_FILE; | ||
340 | |||
341 | set_fs(old_fs); | ||
342 | filp_close(myfile, NULL); | ||
343 | } | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static void cx25821_vidups_handler_ch2(struct work_struct *work) | ||
349 | { | ||
350 | struct cx25821_dev *dev = container_of(work, struct cx25821_dev, | ||
351 | _irq_work_entry_ch2); | ||
352 | |||
353 | if (!dev) { | ||
354 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", | ||
355 | __func__); | ||
356 | return; | ||
357 | } | ||
358 | |||
359 | cx25821_get_frame_ch2(dev, dev->channels[dev-> | ||
360 | _channel2_upstream_select].sram_channels); | ||
361 | } | ||
362 | |||
363 | int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | ||
364 | { | ||
365 | struct file *myfile; | ||
366 | int i = 0, j = 0; | ||
367 | int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? | ||
368 | Y411_LINE_SZ : Y422_LINE_SZ; | ||
369 | ssize_t vfs_read_retval = 0; | ||
370 | char mybuf[line_size]; | ||
371 | loff_t pos; | ||
372 | loff_t offset = (unsigned long)0; | ||
373 | mm_segment_t old_fs; | ||
374 | |||
375 | myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); | ||
376 | |||
377 | if (IS_ERR(myfile)) { | ||
378 | const int open_errno = -PTR_ERR(myfile); | ||
379 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | ||
380 | __func__, dev->_filename_ch2, open_errno); | ||
381 | return PTR_ERR(myfile); | ||
382 | } else { | ||
383 | if (!(myfile->f_op)) { | ||
384 | pr_err("%s(): File has no file operations registered!\n", | ||
385 | __func__); | ||
386 | filp_close(myfile, NULL); | ||
387 | return -EIO; | ||
388 | } | ||
389 | |||
390 | if (!myfile->f_op->read) { | ||
391 | pr_err("%s(): File has no READ operations registered! Returning\n", | ||
392 | __func__); | ||
393 | filp_close(myfile, NULL); | ||
394 | return -EIO; | ||
395 | } | ||
396 | |||
397 | pos = myfile->f_pos; | ||
398 | old_fs = get_fs(); | ||
399 | set_fs(KERNEL_DS); | ||
400 | |||
401 | for (j = 0; j < NUM_FRAMES; j++) { | ||
402 | for (i = 0; i < dev->_lines_count_ch2; i++) { | ||
403 | pos = offset; | ||
404 | |||
405 | vfs_read_retval = vfs_read(myfile, mybuf, | ||
406 | line_size, &pos); | ||
407 | |||
408 | if (vfs_read_retval > 0 && | ||
409 | vfs_read_retval == line_size && | ||
410 | dev->_data_buf_virt_addr_ch2 != NULL) { | ||
411 | memcpy((void *)(dev-> | ||
412 | _data_buf_virt_addr_ch2 | ||
413 | + offset / 4), mybuf, | ||
414 | vfs_read_retval); | ||
415 | } | ||
416 | |||
417 | offset += vfs_read_retval; | ||
418 | |||
419 | if (vfs_read_retval < line_size) { | ||
420 | pr_info("Done: exit %s() since no more bytes to read from Video file\n", | ||
421 | __func__); | ||
422 | break; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | if (i > 0) | ||
427 | dev->_frame_count_ch2++; | ||
428 | |||
429 | if (vfs_read_retval < line_size) | ||
430 | break; | ||
431 | } | ||
432 | |||
433 | dev->_file_status_ch2 = (vfs_read_retval == line_size) ? | ||
434 | IN_PROGRESS : END_OF_FILE; | ||
435 | |||
436 | set_fs(old_fs); | ||
437 | myfile->f_pos = 0; | ||
438 | filp_close(myfile, NULL); | ||
439 | } | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, | ||
445 | struct sram_channel *sram_ch, | ||
446 | int bpl) | ||
447 | { | ||
448 | int ret = 0; | ||
449 | dma_addr_t dma_addr; | ||
450 | dma_addr_t data_dma_addr; | ||
451 | |||
452 | if (dev->_dma_virt_addr_ch2 != NULL) { | ||
453 | pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2, | ||
454 | dev->_dma_virt_addr_ch2, | ||
455 | dev->_dma_phys_addr_ch2); | ||
456 | } | ||
457 | |||
458 | dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci, | ||
459 | dev->upstream_riscbuf_size_ch2, &dma_addr); | ||
460 | dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2; | ||
461 | dev->_dma_phys_start_addr_ch2 = dma_addr; | ||
462 | dev->_dma_phys_addr_ch2 = dma_addr; | ||
463 | dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2; | ||
464 | |||
465 | if (!dev->_dma_virt_addr_ch2) { | ||
466 | pr_err("FAILED to allocate memory for Risc buffer! Returning\n"); | ||
467 | return -ENOMEM; | ||
468 | } | ||
469 | |||
470 | /* Iniitize at this address until n bytes to 0 */ | ||
471 | memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2); | ||
472 | |||
473 | if (dev->_data_buf_virt_addr_ch2 != NULL) { | ||
474 | pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2, | ||
475 | dev->_data_buf_virt_addr_ch2, | ||
476 | dev->_data_buf_phys_addr_ch2); | ||
477 | } | ||
478 | /* For Video Data buffer allocation */ | ||
479 | dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci, | ||
480 | dev->upstream_databuf_size_ch2, &data_dma_addr); | ||
481 | dev->_data_buf_phys_addr_ch2 = data_dma_addr; | ||
482 | dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2; | ||
483 | |||
484 | if (!dev->_data_buf_virt_addr_ch2) { | ||
485 | pr_err("FAILED to allocate memory for data buffer! Returning\n"); | ||
486 | return -ENOMEM; | ||
487 | } | ||
488 | |||
489 | /* Initialize at this address until n bytes to 0 */ | ||
490 | memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2); | ||
491 | |||
492 | ret = cx25821_openfile_ch2(dev, sram_ch); | ||
493 | if (ret < 0) | ||
494 | return ret; | ||
495 | |||
496 | /* Creating RISC programs */ | ||
497 | ret = cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl, | ||
498 | dev->_lines_count_ch2); | ||
499 | if (ret < 0) { | ||
500 | pr_info("Failed creating Video Upstream Risc programs!\n"); | ||
501 | goto error; | ||
502 | } | ||
503 | |||
504 | return 0; | ||
505 | |||
506 | error: | ||
507 | return ret; | ||
508 | } | ||
509 | |||
510 | int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num, | ||
511 | u32 status) | ||
512 | { | ||
513 | u32 int_msk_tmp; | ||
514 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; | ||
515 | int singlefield_lines = NTSC_FIELD_HEIGHT; | ||
516 | int line_size_in_bytes = Y422_LINE_SZ; | ||
517 | int odd_risc_prog_size = 0; | ||
518 | dma_addr_t risc_phys_jump_addr; | ||
519 | __le32 *rp; | ||
520 | |||
521 | if (status & FLD_VID_SRC_RISC1) { | ||
522 | /* We should only process one program per call */ | ||
523 | u32 prog_cnt = cx_read(channel->gpcnt); | ||
524 | |||
525 | /* | ||
526 | * Since we've identified our IRQ, clear our bits from the | ||
527 | * interrupt mask and interrupt status registers | ||
528 | */ | ||
529 | int_msk_tmp = cx_read(channel->int_msk); | ||
530 | cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); | ||
531 | cx_write(channel->int_stat, _intr_msk); | ||
532 | |||
533 | spin_lock(&dev->slock); | ||
534 | |||
535 | dev->_frame_index_ch2 = prog_cnt; | ||
536 | |||
537 | queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2); | ||
538 | |||
539 | if (dev->_is_first_frame_ch2) { | ||
540 | dev->_is_first_frame_ch2 = 0; | ||
541 | |||
542 | if (dev->_isNTSC_ch2) { | ||
543 | singlefield_lines += 1; | ||
544 | odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; | ||
545 | } else { | ||
546 | singlefield_lines = PAL_FIELD_HEIGHT; | ||
547 | odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; | ||
548 | } | ||
549 | |||
550 | if (dev->_dma_virt_start_addr_ch2 != NULL) { | ||
551 | if (dev->_pixel_format_ch2 == PIXEL_FRMT_411) | ||
552 | line_size_in_bytes = Y411_LINE_SZ; | ||
553 | else | ||
554 | line_size_in_bytes = Y422_LINE_SZ; | ||
555 | risc_phys_jump_addr = | ||
556 | dev->_dma_phys_start_addr_ch2 + | ||
557 | odd_risc_prog_size; | ||
558 | |||
559 | rp = cx25821_update_riscprogram_ch2(dev, | ||
560 | dev->_dma_virt_start_addr_ch2, | ||
561 | TOP_OFFSET, line_size_in_bytes, | ||
562 | 0x0, singlefield_lines, | ||
563 | FIFO_DISABLE, ODD_FIELD); | ||
564 | |||
565 | /* Jump to Even Risc program of 1st Frame */ | ||
566 | *(rp++) = cpu_to_le32(RISC_JUMP); | ||
567 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | ||
568 | *(rp++) = cpu_to_le32(0); | ||
569 | } | ||
570 | } | ||
571 | |||
572 | spin_unlock(&dev->slock); | ||
573 | } | ||
574 | |||
575 | if (dev->_file_status_ch2 == END_OF_FILE) { | ||
576 | pr_info("EOF Channel 2 Framecount = %d\n", | ||
577 | dev->_frame_count_ch2); | ||
578 | return -1; | ||
579 | } | ||
580 | /* ElSE, set the interrupt mask register, re-enable irq. */ | ||
581 | int_msk_tmp = cx_read(channel->int_msk); | ||
582 | cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) | ||
588 | { | ||
589 | struct cx25821_dev *dev = dev_id; | ||
590 | u32 vid_status; | ||
591 | int handled = 0; | ||
592 | int channel_num = 0; | ||
593 | struct sram_channel *sram_ch; | ||
594 | |||
595 | if (!dev) | ||
596 | return -1; | ||
597 | |||
598 | channel_num = VID_UPSTREAM_SRAM_CHANNEL_J; | ||
599 | sram_ch = dev->channels[channel_num].sram_channels; | ||
600 | |||
601 | vid_status = cx_read(sram_ch->int_stat); | ||
602 | |||
603 | /* Only deal with our interrupt */ | ||
604 | if (vid_status) | ||
605 | handled = cx25821_video_upstream_irq_ch2(dev, channel_num, | ||
606 | vid_status); | ||
607 | |||
608 | if (handled < 0) | ||
609 | cx25821_stop_upstream_video_ch2(dev); | ||
610 | else | ||
611 | handled += handled; | ||
612 | |||
613 | return IRQ_RETVAL(handled); | ||
614 | } | ||
615 | |||
616 | static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev, | ||
617 | struct sram_channel *ch, int pix_format) | ||
618 | { | ||
619 | int width = WIDTH_D1; | ||
620 | int height = dev->_lines_count_ch2; | ||
621 | int num_lines, odd_num_lines; | ||
622 | u32 value; | ||
623 | int vip_mode = PIXEL_ENGINE_VIP1; | ||
624 | |||
625 | value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7); | ||
626 | value &= 0xFFFFFFEF; | ||
627 | value |= dev->_isNTSC_ch2 ? 0 : 0x10; | ||
628 | cx_write(ch->vid_fmt_ctl, value); | ||
629 | |||
630 | /* | ||
631 | * set number of active pixels in each line. Default is 720 | ||
632 | * pixels in both NTSC and PAL format | ||
633 | */ | ||
634 | cx_write(ch->vid_active_ctl1, width); | ||
635 | |||
636 | num_lines = (height / 2) & 0x3FF; | ||
637 | odd_num_lines = num_lines; | ||
638 | |||
639 | if (dev->_isNTSC_ch2) | ||
640 | odd_num_lines += 1; | ||
641 | |||
642 | value = (num_lines << 16) | odd_num_lines; | ||
643 | |||
644 | /* set number of active lines in field 0 (top) and field 1 (bottom) */ | ||
645 | cx_write(ch->vid_active_ctl2, value); | ||
646 | |||
647 | cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); | ||
648 | } | ||
649 | |||
650 | int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, | ||
651 | struct sram_channel *sram_ch) | ||
652 | { | ||
653 | u32 tmp = 0; | ||
654 | int err = 0; | ||
655 | |||
656 | /* | ||
657 | * 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface | ||
658 | * for channel A-C | ||
659 | */ | ||
660 | tmp = cx_read(VID_CH_MODE_SEL); | ||
661 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | ||
662 | |||
663 | /* | ||
664 | * Set the physical start address of the RISC program in the initial | ||
665 | * program counter(IPC) member of the cmds. | ||
666 | */ | ||
667 | cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2); | ||
668 | cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ | ||
669 | |||
670 | /* reset counter */ | ||
671 | cx_write(sram_ch->gpcnt_ctl, 3); | ||
672 | |||
673 | /* Clear our bits from the interrupt status register. */ | ||
674 | cx_write(sram_ch->int_stat, _intr_msk); | ||
675 | |||
676 | /* Set the interrupt mask register, enable irq. */ | ||
677 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); | ||
678 | tmp = cx_read(sram_ch->int_msk); | ||
679 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | ||
680 | |||
681 | err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, | ||
682 | IRQF_SHARED, dev->name, dev); | ||
683 | if (err < 0) { | ||
684 | pr_err("%s: can't get upstream IRQ %d\n", | ||
685 | dev->name, dev->pci->irq); | ||
686 | goto fail_irq; | ||
687 | } | ||
688 | /* Start the DMA engine */ | ||
689 | tmp = cx_read(sram_ch->dma_ctl); | ||
690 | cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); | ||
691 | |||
692 | dev->_is_running_ch2 = 1; | ||
693 | dev->_is_first_frame_ch2 = 1; | ||
694 | |||
695 | return 0; | ||
696 | |||
697 | fail_irq: | ||
698 | cx25821_dev_unregister(dev); | ||
699 | return err; | ||
700 | } | ||
701 | |||
702 | int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, | ||
703 | int pixel_format) | ||
704 | { | ||
705 | struct sram_channel *sram_ch; | ||
706 | u32 tmp; | ||
707 | int retval = 0; | ||
708 | int err = 0; | ||
709 | int data_frame_size = 0; | ||
710 | int risc_buffer_size = 0; | ||
711 | int str_length = 0; | ||
712 | |||
713 | if (dev->_is_running_ch2) { | ||
714 | pr_info("Video Channel is still running so return!\n"); | ||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | dev->_channel2_upstream_select = channel_select; | ||
719 | sram_ch = dev->channels[channel_select].sram_channels; | ||
720 | |||
721 | INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2); | ||
722 | dev->_irq_queues_ch2 = | ||
723 | create_singlethread_workqueue("cx25821_workqueue2"); | ||
724 | |||
725 | if (!dev->_irq_queues_ch2) { | ||
726 | pr_err("create_singlethread_workqueue() for Video FAILED!\n"); | ||
727 | return -ENOMEM; | ||
728 | } | ||
729 | /* | ||
730 | * 656/VIP SRC Upstream Channel I & J and 7 - | ||
731 | * Host Bus Interface for channel A-C | ||
732 | */ | ||
733 | tmp = cx_read(VID_CH_MODE_SEL); | ||
734 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | ||
735 | |||
736 | dev->_is_running_ch2 = 0; | ||
737 | dev->_frame_count_ch2 = 0; | ||
738 | dev->_file_status_ch2 = RESET_STATUS; | ||
739 | dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576; | ||
740 | dev->_pixel_format_ch2 = pixel_format; | ||
741 | dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ? | ||
742 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | ||
743 | data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; | ||
744 | risc_buffer_size = dev->_isNTSC_ch2 ? | ||
745 | NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; | ||
746 | |||
747 | if (dev->input_filename_ch2) { | ||
748 | str_length = strlen(dev->input_filename_ch2); | ||
749 | dev->_filename_ch2 = kmemdup(dev->input_filename_ch2, | ||
750 | str_length + 1, GFP_KERNEL); | ||
751 | |||
752 | if (!dev->_filename_ch2) | ||
753 | goto error; | ||
754 | } else { | ||
755 | str_length = strlen(dev->_defaultname_ch2); | ||
756 | dev->_filename_ch2 = kmemdup(dev->_defaultname_ch2, | ||
757 | str_length + 1, GFP_KERNEL); | ||
758 | |||
759 | if (!dev->_filename_ch2) | ||
760 | goto error; | ||
761 | } | ||
762 | |||
763 | /* Default if filename is empty string */ | ||
764 | if (strcmp(dev->input_filename_ch2, "") == 0) { | ||
765 | if (dev->_isNTSC_ch2) { | ||
766 | dev->_filename_ch2 = (dev->_pixel_format_ch2 == | ||
767 | PIXEL_FRMT_411) ? "/root/vid411.yuv" : | ||
768 | "/root/vidtest.yuv"; | ||
769 | } else { | ||
770 | dev->_filename_ch2 = (dev->_pixel_format_ch2 == | ||
771 | PIXEL_FRMT_411) ? "/root/pal411.yuv" : | ||
772 | "/root/pal422.yuv"; | ||
773 | } | ||
774 | } | ||
775 | |||
776 | retval = cx25821_sram_channel_setup_upstream(dev, sram_ch, | ||
777 | dev->_line_size_ch2, 0); | ||
778 | |||
779 | /* setup fifo + format */ | ||
780 | cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2); | ||
781 | |||
782 | dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2; | ||
783 | dev->upstream_databuf_size_ch2 = data_frame_size * 2; | ||
784 | |||
785 | /* Allocating buffers and prepare RISC program */ | ||
786 | retval = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch, | ||
787 | dev->_line_size_ch2); | ||
788 | if (retval < 0) { | ||
789 | pr_err("%s: Failed to set up Video upstream buffers!\n", | ||
790 | dev->name); | ||
791 | goto error; | ||
792 | } | ||
793 | |||
794 | cx25821_start_video_dma_upstream_ch2(dev, sram_ch); | ||
795 | |||
796 | return 0; | ||
797 | |||
798 | error: | ||
799 | cx25821_dev_unregister(dev); | ||
800 | |||
801 | return err; | ||
802 | } | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h new file mode 100644 index 000000000000..d42dab59b663 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h | |||
@@ -0,0 +1,138 @@ | |||
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 \ | ||
69 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
70 | RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \ | ||
71 | NUM_NO_OPS * DWORD_SIZE) | ||
72 | |||
73 | #define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE) | ||
74 | |||
75 | #define PAL_VID_PROG_SIZE \ | ||
76 | ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \ | ||
77 | 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
78 | JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE) | ||
79 | |||
80 | #define ODD_FLD_PAL_PROG_SIZE \ | ||
81 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
82 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
83 | NUM_NO_OPS * DWORD_SIZE) | ||
84 | |||
85 | #define NTSC_US_VID_PROG_SIZE \ | ||
86 | ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \ | ||
87 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \ | ||
88 | NUM_NO_OPS * DWORD_SIZE) | ||
89 | |||
90 | #define NTSC_RISC_BUF_SIZE \ | ||
91 | (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) | ||
92 | |||
93 | #define FRAME1_VID_PROG_SIZE \ | ||
94 | ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * \ | ||
95 | 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE + \ | ||
96 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \ | ||
97 | 2 * NUM_NO_OPS * DWORD_SIZE) | ||
98 | |||
99 | #define ODD_FLD_NTSC_PROG_SIZE \ | ||
100 | (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \ | ||
101 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
102 | NUM_NO_OPS * DWORD_SIZE) | ||
103 | #endif | ||
104 | |||
105 | #ifndef USE_RISC_NOOP_VIDEO | ||
106 | #define PAL_US_VID_PROG_SIZE \ | ||
107 | ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + \ | ||
108 | RISC_WRITECR_INSTRUCTION_SIZE) | ||
109 | |||
110 | #define PAL_RISC_BUF_SIZE \ | ||
111 | (2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE)) | ||
112 | |||
113 | #define PAL_VID_PROG_SIZE \ | ||
114 | ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \ | ||
115 | 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
116 | JUMP_INSTRUCTION_SIZE) | ||
117 | |||
118 | #define ODD_FLD_PAL_PROG_SIZE \ | ||
119 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
120 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) | ||
121 | |||
122 | #define ODD_FLD_NTSC_PROG_SIZE \ | ||
123 | (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \ | ||
124 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) | ||
125 | |||
126 | #define NTSC_US_VID_PROG_SIZE \ | ||
127 | ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \ | ||
128 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) | ||
129 | |||
130 | #define NTSC_RISC_BUF_SIZE \ | ||
131 | (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) | ||
132 | |||
133 | #define FRAME1_VID_PROG_SIZE \ | ||
134 | ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * \ | ||
135 | 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE + \ | ||
136 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) | ||
137 | |||
138 | #endif | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c new file mode 100644 index 000000000000..52c13e0b6492 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c | |||
@@ -0,0 +1,856 @@ | |||
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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
25 | #include "cx25821-video.h" | ||
26 | #include "cx25821-video-upstream.h" | ||
27 | |||
28 | #include <linux/fs.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/syscalls.h> | ||
34 | #include <linux/file.h> | ||
35 | #include <linux/fcntl.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | |||
39 | MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); | ||
40 | MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); | ||
41 | MODULE_LICENSE("GPL"); | ||
42 | |||
43 | static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | | ||
44 | FLD_VID_SRC_OPC_ERR; | ||
45 | |||
46 | int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, | ||
47 | struct sram_channel *ch, | ||
48 | unsigned int bpl, u32 risc) | ||
49 | { | ||
50 | unsigned int i, lines; | ||
51 | u32 cdt; | ||
52 | |||
53 | if (ch->cmds_start == 0) { | ||
54 | cx_write(ch->ptr1_reg, 0); | ||
55 | cx_write(ch->ptr2_reg, 0); | ||
56 | cx_write(ch->cnt2_reg, 0); | ||
57 | cx_write(ch->cnt1_reg, 0); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | bpl = (bpl + 7) & ~7; /* alignment */ | ||
62 | cdt = ch->cdt; | ||
63 | lines = ch->fifo_size / bpl; | ||
64 | |||
65 | if (lines > 4) | ||
66 | lines = 4; | ||
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, (lines * 16) >> 3); | ||
84 | cx_write(ch->cmds_start + 16, ch->ctrl_start); | ||
85 | |||
86 | cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW); | ||
87 | |||
88 | for (i = 24; i < 80; i += 4) | ||
89 | cx_write(ch->cmds_start + i, 0); | ||
90 | |||
91 | /* fill registers */ | ||
92 | cx_write(ch->ptr1_reg, ch->fifo_start); | ||
93 | cx_write(ch->ptr2_reg, cdt); | ||
94 | cx_write(ch->cnt2_reg, (lines * 16) >> 3); | ||
95 | cx_write(ch->cnt1_reg, (bpl >> 3) - 1); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, | ||
101 | __le32 *rp, unsigned int offset, | ||
102 | unsigned int bpl, u32 sync_line, | ||
103 | unsigned int lines, int fifo_enable, | ||
104 | int field_type) | ||
105 | { | ||
106 | unsigned int line, i; | ||
107 | int dist_betwn_starts = bpl * 2; | ||
108 | |||
109 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | ||
110 | |||
111 | if (USE_RISC_NOOP_VIDEO) { | ||
112 | for (i = 0; i < NUM_NO_OPS; i++) | ||
113 | *(rp++) = cpu_to_le32(RISC_NOOP); | ||
114 | } | ||
115 | |||
116 | /* scan lines */ | ||
117 | for (line = 0; line < lines; line++) { | ||
118 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); | ||
119 | *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset); | ||
120 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
121 | |||
122 | if ((lines <= NTSC_FIELD_HEIGHT) | ||
123 | || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) { | ||
124 | offset += dist_betwn_starts; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | return rp; | ||
129 | } | ||
130 | |||
131 | static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, | ||
132 | dma_addr_t databuf_phys_addr, | ||
133 | unsigned int offset, u32 sync_line, | ||
134 | unsigned int bpl, unsigned int lines, | ||
135 | int fifo_enable, int field_type) | ||
136 | { | ||
137 | unsigned int line, i; | ||
138 | struct sram_channel *sram_ch = | ||
139 | dev->channels[dev->_channel_upstream_select].sram_channels; | ||
140 | int dist_betwn_starts = bpl * 2; | ||
141 | |||
142 | /* sync instruction */ | ||
143 | if (sync_line != NO_SYNC_LINE) | ||
144 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | ||
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 | /* scan lines */ | ||
152 | for (line = 0; line < lines; line++) { | ||
153 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); | ||
154 | *(rp++) = cpu_to_le32(databuf_phys_addr + offset); | ||
155 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
156 | |||
157 | if ((lines <= NTSC_FIELD_HEIGHT) | ||
158 | || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) | ||
159 | /* to skip the other field line */ | ||
160 | offset += dist_betwn_starts; | ||
161 | |||
162 | /* check if we need to enable the FIFO after the first 4 lines | ||
163 | * For the upstream video channel, the risc engine will enable | ||
164 | * 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 | |||
176 | int 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 | /* get line count for single field */ | ||
184 | int singlefield_lines = lines >> 1; | ||
185 | int odd_num_lines = singlefield_lines; | ||
186 | int frame = 0; | ||
187 | int frame_size = 0; | ||
188 | int databuf_offset = 0; | ||
189 | int risc_program_size = 0; | ||
190 | int risc_flag = RISC_CNT_RESET; | ||
191 | unsigned int bottom_offset = bpl; | ||
192 | dma_addr_t risc_phys_jump_addr; | ||
193 | |||
194 | if (dev->_isNTSC) { | ||
195 | odd_num_lines = singlefield_lines + 1; | ||
196 | risc_program_size = FRAME1_VID_PROG_SIZE; | ||
197 | frame_size = (bpl == Y411_LINE_SZ) ? | ||
198 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; | ||
199 | } else { | ||
200 | risc_program_size = PAL_VID_PROG_SIZE; | ||
201 | frame_size = (bpl == Y411_LINE_SZ) ? | ||
202 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; | ||
203 | } | ||
204 | |||
205 | /* Virtual address of Risc buffer program */ | ||
206 | rp = dev->_dma_virt_addr; | ||
207 | |||
208 | for (frame = 0; frame < NUM_FRAMES; frame++) { | ||
209 | databuf_offset = frame_size * frame; | ||
210 | |||
211 | if (UNSET != top_offset) { | ||
212 | fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; | ||
213 | rp = cx25821_risc_field_upstream(dev, rp, | ||
214 | dev->_data_buf_phys_addr + | ||
215 | databuf_offset, top_offset, 0, bpl, | ||
216 | odd_num_lines, fifo_enable, ODD_FIELD); | ||
217 | } | ||
218 | |||
219 | fifo_enable = FIFO_DISABLE; | ||
220 | |||
221 | /* Even Field */ | ||
222 | rp = cx25821_risc_field_upstream(dev, rp, | ||
223 | dev->_data_buf_phys_addr + | ||
224 | databuf_offset, bottom_offset, | ||
225 | 0x200, bpl, singlefield_lines, | ||
226 | fifo_enable, EVEN_FIELD); | ||
227 | |||
228 | if (frame == 0) { | ||
229 | risc_flag = RISC_CNT_RESET; | ||
230 | risc_phys_jump_addr = dev->_dma_phys_start_addr + | ||
231 | risc_program_size; | ||
232 | } else { | ||
233 | risc_phys_jump_addr = dev->_dma_phys_start_addr; | ||
234 | risc_flag = RISC_CNT_INC; | ||
235 | } | ||
236 | |||
237 | /* Loop to 2ndFrameRISC or to Start of Risc | ||
238 | * program & generate IRQ | ||
239 | */ | ||
240 | *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); | ||
241 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | ||
242 | *(rp++) = cpu_to_le32(0); | ||
243 | } | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) | ||
249 | { | ||
250 | struct sram_channel *sram_ch = | ||
251 | dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; | ||
252 | u32 tmp = 0; | ||
253 | |||
254 | if (!dev->_is_running) { | ||
255 | pr_info("No video file is currently running so return!\n"); | ||
256 | return; | ||
257 | } | ||
258 | /* Disable RISC interrupts */ | ||
259 | tmp = cx_read(sram_ch->int_msk); | ||
260 | cx_write(sram_ch->int_msk, tmp & ~_intr_msk); | ||
261 | |||
262 | /* Turn OFF risc and fifo enable */ | ||
263 | tmp = cx_read(sram_ch->dma_ctl); | ||
264 | cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); | ||
265 | |||
266 | /* Clear data buffer memory */ | ||
267 | if (dev->_data_buf_virt_addr) | ||
268 | memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); | ||
269 | |||
270 | dev->_is_running = 0; | ||
271 | dev->_is_first_frame = 0; | ||
272 | dev->_frame_count = 0; | ||
273 | dev->_file_status = END_OF_FILE; | ||
274 | |||
275 | kfree(dev->_irq_queues); | ||
276 | dev->_irq_queues = NULL; | ||
277 | |||
278 | kfree(dev->_filename); | ||
279 | |||
280 | tmp = cx_read(VID_CH_MODE_SEL); | ||
281 | cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); | ||
282 | } | ||
283 | |||
284 | void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev) | ||
285 | { | ||
286 | if (dev->_is_running) | ||
287 | cx25821_stop_upstream_video_ch1(dev); | ||
288 | |||
289 | if (dev->_dma_virt_addr) { | ||
290 | pci_free_consistent(dev->pci, dev->_risc_size, | ||
291 | dev->_dma_virt_addr, dev->_dma_phys_addr); | ||
292 | dev->_dma_virt_addr = NULL; | ||
293 | } | ||
294 | |||
295 | if (dev->_data_buf_virt_addr) { | ||
296 | pci_free_consistent(dev->pci, dev->_data_buf_size, | ||
297 | dev->_data_buf_virt_addr, | ||
298 | dev->_data_buf_phys_addr); | ||
299 | dev->_data_buf_virt_addr = NULL; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) | ||
304 | { | ||
305 | struct file *myfile; | ||
306 | int frame_index_temp = dev->_frame_index; | ||
307 | int i = 0; | ||
308 | int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? | ||
309 | Y411_LINE_SZ : Y422_LINE_SZ; | ||
310 | int frame_size = 0; | ||
311 | int frame_offset = 0; | ||
312 | ssize_t vfs_read_retval = 0; | ||
313 | char mybuf[line_size]; | ||
314 | loff_t file_offset; | ||
315 | loff_t pos; | ||
316 | mm_segment_t old_fs; | ||
317 | |||
318 | if (dev->_file_status == END_OF_FILE) | ||
319 | return 0; | ||
320 | |||
321 | if (dev->_isNTSC) | ||
322 | frame_size = (line_size == Y411_LINE_SZ) ? | ||
323 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; | ||
324 | else | ||
325 | frame_size = (line_size == Y411_LINE_SZ) ? | ||
326 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; | ||
327 | |||
328 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; | ||
329 | file_offset = dev->_frame_count * frame_size; | ||
330 | |||
331 | myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0); | ||
332 | |||
333 | if (IS_ERR(myfile)) { | ||
334 | const int open_errno = -PTR_ERR(myfile); | ||
335 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | ||
336 | __func__, dev->_filename, open_errno); | ||
337 | return PTR_ERR(myfile); | ||
338 | } else { | ||
339 | if (!(myfile->f_op)) { | ||
340 | pr_err("%s(): File has no file operations registered!\n", | ||
341 | __func__); | ||
342 | filp_close(myfile, NULL); | ||
343 | return -EIO; | ||
344 | } | ||
345 | |||
346 | if (!myfile->f_op->read) { | ||
347 | pr_err("%s(): File has no READ operations registered!\n", | ||
348 | __func__); | ||
349 | filp_close(myfile, NULL); | ||
350 | return -EIO; | ||
351 | } | ||
352 | |||
353 | pos = myfile->f_pos; | ||
354 | old_fs = get_fs(); | ||
355 | set_fs(KERNEL_DS); | ||
356 | |||
357 | for (i = 0; i < dev->_lines_count; i++) { | ||
358 | pos = file_offset; | ||
359 | |||
360 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, | ||
361 | &pos); | ||
362 | |||
363 | if (vfs_read_retval > 0 && vfs_read_retval == line_size | ||
364 | && dev->_data_buf_virt_addr != NULL) { | ||
365 | memcpy((void *)(dev->_data_buf_virt_addr + | ||
366 | frame_offset / 4), mybuf, | ||
367 | vfs_read_retval); | ||
368 | } | ||
369 | |||
370 | file_offset += vfs_read_retval; | ||
371 | frame_offset += vfs_read_retval; | ||
372 | |||
373 | if (vfs_read_retval < line_size) { | ||
374 | pr_info("Done: exit %s() since no more bytes to read from Video file\n", | ||
375 | __func__); | ||
376 | break; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | if (i > 0) | ||
381 | dev->_frame_count++; | ||
382 | |||
383 | dev->_file_status = (vfs_read_retval == line_size) ? | ||
384 | IN_PROGRESS : END_OF_FILE; | ||
385 | |||
386 | set_fs(old_fs); | ||
387 | filp_close(myfile, NULL); | ||
388 | } | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static void cx25821_vidups_handler(struct work_struct *work) | ||
394 | { | ||
395 | struct cx25821_dev *dev = container_of(work, struct cx25821_dev, | ||
396 | _irq_work_entry); | ||
397 | |||
398 | if (!dev) { | ||
399 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", | ||
400 | __func__); | ||
401 | return; | ||
402 | } | ||
403 | |||
404 | cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select]. | ||
405 | sram_channels); | ||
406 | } | ||
407 | |||
408 | int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) | ||
409 | { | ||
410 | struct file *myfile; | ||
411 | int i = 0, j = 0; | ||
412 | int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? | ||
413 | Y411_LINE_SZ : Y422_LINE_SZ; | ||
414 | ssize_t vfs_read_retval = 0; | ||
415 | char mybuf[line_size]; | ||
416 | loff_t pos; | ||
417 | loff_t offset = (unsigned long)0; | ||
418 | mm_segment_t old_fs; | ||
419 | |||
420 | myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0); | ||
421 | |||
422 | if (IS_ERR(myfile)) { | ||
423 | const int open_errno = -PTR_ERR(myfile); | ||
424 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | ||
425 | __func__, dev->_filename, open_errno); | ||
426 | return PTR_ERR(myfile); | ||
427 | } else { | ||
428 | if (!(myfile->f_op)) { | ||
429 | pr_err("%s(): File has no file operations registered!\n", | ||
430 | __func__); | ||
431 | filp_close(myfile, NULL); | ||
432 | return -EIO; | ||
433 | } | ||
434 | |||
435 | if (!myfile->f_op->read) { | ||
436 | pr_err("%s(): File has no READ operations registered! Returning\n", | ||
437 | __func__); | ||
438 | filp_close(myfile, NULL); | ||
439 | return -EIO; | ||
440 | } | ||
441 | |||
442 | pos = myfile->f_pos; | ||
443 | old_fs = get_fs(); | ||
444 | set_fs(KERNEL_DS); | ||
445 | |||
446 | for (j = 0; j < NUM_FRAMES; j++) { | ||
447 | for (i = 0; i < dev->_lines_count; i++) { | ||
448 | pos = offset; | ||
449 | |||
450 | vfs_read_retval = vfs_read(myfile, mybuf, | ||
451 | line_size, &pos); | ||
452 | |||
453 | if (vfs_read_retval > 0 | ||
454 | && vfs_read_retval == line_size | ||
455 | && dev->_data_buf_virt_addr != NULL) { | ||
456 | memcpy((void *)(dev-> | ||
457 | _data_buf_virt_addr + | ||
458 | offset / 4), mybuf, | ||
459 | vfs_read_retval); | ||
460 | } | ||
461 | |||
462 | offset += vfs_read_retval; | ||
463 | |||
464 | if (vfs_read_retval < line_size) { | ||
465 | pr_info("Done: exit %s() since no more bytes to read from Video file\n", | ||
466 | __func__); | ||
467 | break; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | if (i > 0) | ||
472 | dev->_frame_count++; | ||
473 | |||
474 | if (vfs_read_retval < line_size) | ||
475 | break; | ||
476 | } | ||
477 | |||
478 | dev->_file_status = (vfs_read_retval == line_size) ? | ||
479 | IN_PROGRESS : END_OF_FILE; | ||
480 | |||
481 | set_fs(old_fs); | ||
482 | myfile->f_pos = 0; | ||
483 | filp_close(myfile, NULL); | ||
484 | } | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, | ||
490 | struct sram_channel *sram_ch, int bpl) | ||
491 | { | ||
492 | int ret = 0; | ||
493 | dma_addr_t dma_addr; | ||
494 | dma_addr_t data_dma_addr; | ||
495 | |||
496 | if (dev->_dma_virt_addr != NULL) | ||
497 | pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, | ||
498 | dev->_dma_virt_addr, dev->_dma_phys_addr); | ||
499 | |||
500 | dev->_dma_virt_addr = pci_alloc_consistent(dev->pci, | ||
501 | dev->upstream_riscbuf_size, &dma_addr); | ||
502 | dev->_dma_virt_start_addr = dev->_dma_virt_addr; | ||
503 | dev->_dma_phys_start_addr = dma_addr; | ||
504 | dev->_dma_phys_addr = dma_addr; | ||
505 | dev->_risc_size = dev->upstream_riscbuf_size; | ||
506 | |||
507 | if (!dev->_dma_virt_addr) { | ||
508 | pr_err("FAILED to allocate memory for Risc buffer! Returning\n"); | ||
509 | return -ENOMEM; | ||
510 | } | ||
511 | |||
512 | /* Clear memory at address */ | ||
513 | memset(dev->_dma_virt_addr, 0, dev->_risc_size); | ||
514 | |||
515 | if (dev->_data_buf_virt_addr != NULL) | ||
516 | pci_free_consistent(dev->pci, dev->upstream_databuf_size, | ||
517 | dev->_data_buf_virt_addr, | ||
518 | dev->_data_buf_phys_addr); | ||
519 | /* For Video Data buffer allocation */ | ||
520 | dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, | ||
521 | dev->upstream_databuf_size, &data_dma_addr); | ||
522 | dev->_data_buf_phys_addr = data_dma_addr; | ||
523 | dev->_data_buf_size = dev->upstream_databuf_size; | ||
524 | |||
525 | if (!dev->_data_buf_virt_addr) { | ||
526 | pr_err("FAILED to allocate memory for data buffer! Returning\n"); | ||
527 | return -ENOMEM; | ||
528 | } | ||
529 | |||
530 | /* Clear memory at address */ | ||
531 | memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); | ||
532 | |||
533 | ret = cx25821_openfile(dev, sram_ch); | ||
534 | if (ret < 0) | ||
535 | return ret; | ||
536 | |||
537 | /* Create RISC programs */ | ||
538 | ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, | ||
539 | dev->_lines_count); | ||
540 | if (ret < 0) { | ||
541 | pr_info("Failed creating Video Upstream Risc programs!\n"); | ||
542 | goto error; | ||
543 | } | ||
544 | |||
545 | return 0; | ||
546 | |||
547 | error: | ||
548 | return ret; | ||
549 | } | ||
550 | |||
551 | int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, | ||
552 | u32 status) | ||
553 | { | ||
554 | u32 int_msk_tmp; | ||
555 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; | ||
556 | int singlefield_lines = NTSC_FIELD_HEIGHT; | ||
557 | int line_size_in_bytes = Y422_LINE_SZ; | ||
558 | int odd_risc_prog_size = 0; | ||
559 | dma_addr_t risc_phys_jump_addr; | ||
560 | __le32 *rp; | ||
561 | |||
562 | if (status & FLD_VID_SRC_RISC1) { | ||
563 | /* We should only process one program per call */ | ||
564 | u32 prog_cnt = cx_read(channel->gpcnt); | ||
565 | |||
566 | /* Since we've identified our IRQ, clear our bits from the | ||
567 | * interrupt mask and interrupt status registers */ | ||
568 | int_msk_tmp = cx_read(channel->int_msk); | ||
569 | cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); | ||
570 | cx_write(channel->int_stat, _intr_msk); | ||
571 | |||
572 | spin_lock(&dev->slock); | ||
573 | |||
574 | dev->_frame_index = prog_cnt; | ||
575 | |||
576 | queue_work(dev->_irq_queues, &dev->_irq_work_entry); | ||
577 | |||
578 | if (dev->_is_first_frame) { | ||
579 | dev->_is_first_frame = 0; | ||
580 | |||
581 | if (dev->_isNTSC) { | ||
582 | singlefield_lines += 1; | ||
583 | odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; | ||
584 | } else { | ||
585 | singlefield_lines = PAL_FIELD_HEIGHT; | ||
586 | odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; | ||
587 | } | ||
588 | |||
589 | if (dev->_dma_virt_start_addr != NULL) { | ||
590 | line_size_in_bytes = | ||
591 | (dev->_pixel_format == | ||
592 | PIXEL_FRMT_411) ? Y411_LINE_SZ : | ||
593 | Y422_LINE_SZ; | ||
594 | risc_phys_jump_addr = | ||
595 | dev->_dma_phys_start_addr + | ||
596 | odd_risc_prog_size; | ||
597 | |||
598 | rp = cx25821_update_riscprogram(dev, | ||
599 | dev->_dma_virt_start_addr, TOP_OFFSET, | ||
600 | line_size_in_bytes, 0x0, | ||
601 | singlefield_lines, FIFO_DISABLE, | ||
602 | ODD_FIELD); | ||
603 | |||
604 | /* Jump to Even Risc program of 1st Frame */ | ||
605 | *(rp++) = cpu_to_le32(RISC_JUMP); | ||
606 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | ||
607 | *(rp++) = cpu_to_le32(0); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | spin_unlock(&dev->slock); | ||
612 | } else { | ||
613 | if (status & FLD_VID_SRC_UF) | ||
614 | pr_err("%s(): Video Received Underflow Error Interrupt!\n", | ||
615 | __func__); | ||
616 | |||
617 | if (status & FLD_VID_SRC_SYNC) | ||
618 | pr_err("%s(): Video Received Sync Error Interrupt!\n", | ||
619 | __func__); | ||
620 | |||
621 | if (status & FLD_VID_SRC_OPC_ERR) | ||
622 | pr_err("%s(): Video Received OpCode Error Interrupt!\n", | ||
623 | __func__); | ||
624 | } | ||
625 | |||
626 | if (dev->_file_status == END_OF_FILE) { | ||
627 | pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count); | ||
628 | return -1; | ||
629 | } | ||
630 | /* ElSE, set the interrupt mask register, re-enable irq. */ | ||
631 | int_msk_tmp = cx_read(channel->int_msk); | ||
632 | cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); | ||
633 | |||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) | ||
638 | { | ||
639 | struct cx25821_dev *dev = dev_id; | ||
640 | u32 vid_status; | ||
641 | int handled = 0; | ||
642 | int channel_num = 0; | ||
643 | struct sram_channel *sram_ch; | ||
644 | |||
645 | if (!dev) | ||
646 | return -1; | ||
647 | |||
648 | channel_num = VID_UPSTREAM_SRAM_CHANNEL_I; | ||
649 | |||
650 | sram_ch = dev->channels[channel_num].sram_channels; | ||
651 | |||
652 | vid_status = cx_read(sram_ch->int_stat); | ||
653 | |||
654 | /* Only deal with our interrupt */ | ||
655 | if (vid_status) | ||
656 | handled = cx25821_video_upstream_irq(dev, channel_num, | ||
657 | vid_status); | ||
658 | |||
659 | if (handled < 0) | ||
660 | cx25821_stop_upstream_video_ch1(dev); | ||
661 | else | ||
662 | handled += handled; | ||
663 | |||
664 | return IRQ_RETVAL(handled); | ||
665 | } | ||
666 | |||
667 | void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch, | ||
668 | int pix_format) | ||
669 | { | ||
670 | int width = WIDTH_D1; | ||
671 | int height = dev->_lines_count; | ||
672 | int num_lines, odd_num_lines; | ||
673 | u32 value; | ||
674 | int vip_mode = OUTPUT_FRMT_656; | ||
675 | |||
676 | value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7); | ||
677 | value &= 0xFFFFFFEF; | ||
678 | value |= dev->_isNTSC ? 0 : 0x10; | ||
679 | cx_write(ch->vid_fmt_ctl, value); | ||
680 | |||
681 | /* set number of active pixels in each line. | ||
682 | * Default is 720 pixels in both NTSC and PAL format */ | ||
683 | cx_write(ch->vid_active_ctl1, width); | ||
684 | |||
685 | num_lines = (height / 2) & 0x3FF; | ||
686 | odd_num_lines = num_lines; | ||
687 | |||
688 | if (dev->_isNTSC) | ||
689 | odd_num_lines += 1; | ||
690 | |||
691 | value = (num_lines << 16) | odd_num_lines; | ||
692 | |||
693 | /* set number of active lines in field 0 (top) and field 1 (bottom) */ | ||
694 | cx_write(ch->vid_active_ctl2, value); | ||
695 | |||
696 | cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); | ||
697 | } | ||
698 | |||
699 | int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, | ||
700 | struct sram_channel *sram_ch) | ||
701 | { | ||
702 | u32 tmp = 0; | ||
703 | int err = 0; | ||
704 | |||
705 | /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for | ||
706 | * channel A-C | ||
707 | */ | ||
708 | tmp = cx_read(VID_CH_MODE_SEL); | ||
709 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | ||
710 | |||
711 | /* Set the physical start address of the RISC program in the initial | ||
712 | * program counter(IPC) member of the cmds. | ||
713 | */ | ||
714 | cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr); | ||
715 | /* Risc IPC High 64 bits 63-32 */ | ||
716 | cx_write(sram_ch->cmds_start + 4, 0); | ||
717 | |||
718 | /* reset counter */ | ||
719 | cx_write(sram_ch->gpcnt_ctl, 3); | ||
720 | |||
721 | /* Clear our bits from the interrupt status register. */ | ||
722 | cx_write(sram_ch->int_stat, _intr_msk); | ||
723 | |||
724 | /* Set the interrupt mask register, enable irq. */ | ||
725 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); | ||
726 | tmp = cx_read(sram_ch->int_msk); | ||
727 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | ||
728 | |||
729 | err = request_irq(dev->pci->irq, cx25821_upstream_irq, | ||
730 | IRQF_SHARED, dev->name, dev); | ||
731 | if (err < 0) { | ||
732 | pr_err("%s: can't get upstream IRQ %d\n", | ||
733 | dev->name, dev->pci->irq); | ||
734 | goto fail_irq; | ||
735 | } | ||
736 | |||
737 | /* Start the DMA engine */ | ||
738 | tmp = cx_read(sram_ch->dma_ctl); | ||
739 | cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); | ||
740 | |||
741 | dev->_is_running = 1; | ||
742 | dev->_is_first_frame = 1; | ||
743 | |||
744 | return 0; | ||
745 | |||
746 | fail_irq: | ||
747 | cx25821_dev_unregister(dev); | ||
748 | return err; | ||
749 | } | ||
750 | |||
751 | int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, | ||
752 | int pixel_format) | ||
753 | { | ||
754 | struct sram_channel *sram_ch; | ||
755 | u32 tmp; | ||
756 | int retval = 0; | ||
757 | int err = 0; | ||
758 | int data_frame_size = 0; | ||
759 | int risc_buffer_size = 0; | ||
760 | int str_length = 0; | ||
761 | |||
762 | if (dev->_is_running) { | ||
763 | pr_info("Video Channel is still running so return!\n"); | ||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | dev->_channel_upstream_select = channel_select; | ||
768 | sram_ch = dev->channels[channel_select].sram_channels; | ||
769 | |||
770 | INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler); | ||
771 | dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); | ||
772 | |||
773 | if (!dev->_irq_queues) { | ||
774 | pr_err("create_singlethread_workqueue() for Video FAILED!\n"); | ||
775 | return -ENOMEM; | ||
776 | } | ||
777 | /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for | ||
778 | * channel A-C | ||
779 | */ | ||
780 | tmp = cx_read(VID_CH_MODE_SEL); | ||
781 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | ||
782 | |||
783 | dev->_is_running = 0; | ||
784 | dev->_frame_count = 0; | ||
785 | dev->_file_status = RESET_STATUS; | ||
786 | dev->_lines_count = dev->_isNTSC ? 480 : 576; | ||
787 | dev->_pixel_format = pixel_format; | ||
788 | dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? | ||
789 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | ||
790 | data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; | ||
791 | risc_buffer_size = dev->_isNTSC ? | ||
792 | NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; | ||
793 | |||
794 | if (dev->input_filename) { | ||
795 | str_length = strlen(dev->input_filename); | ||
796 | dev->_filename = kmemdup(dev->input_filename, str_length + 1, | ||
797 | GFP_KERNEL); | ||
798 | |||
799 | if (!dev->_filename) | ||
800 | goto error; | ||
801 | } else { | ||
802 | str_length = strlen(dev->_defaultname); | ||
803 | dev->_filename = kmemdup(dev->_defaultname, str_length + 1, | ||
804 | GFP_KERNEL); | ||
805 | |||
806 | if (!dev->_filename) | ||
807 | goto error; | ||
808 | } | ||
809 | |||
810 | /* Default if filename is empty string */ | ||
811 | if (strcmp(dev->input_filename, "") == 0) { | ||
812 | if (dev->_isNTSC) { | ||
813 | dev->_filename = | ||
814 | (dev->_pixel_format == PIXEL_FRMT_411) ? | ||
815 | "/root/vid411.yuv" : "/root/vidtest.yuv"; | ||
816 | } else { | ||
817 | dev->_filename = | ||
818 | (dev->_pixel_format == PIXEL_FRMT_411) ? | ||
819 | "/root/pal411.yuv" : "/root/pal422.yuv"; | ||
820 | } | ||
821 | } | ||
822 | |||
823 | dev->_is_running = 0; | ||
824 | dev->_frame_count = 0; | ||
825 | dev->_file_status = RESET_STATUS; | ||
826 | dev->_lines_count = dev->_isNTSC ? 480 : 576; | ||
827 | dev->_pixel_format = pixel_format; | ||
828 | dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? | ||
829 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | ||
830 | |||
831 | retval = cx25821_sram_channel_setup_upstream(dev, sram_ch, | ||
832 | dev->_line_size, 0); | ||
833 | |||
834 | /* setup fifo + format */ | ||
835 | cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format); | ||
836 | |||
837 | dev->upstream_riscbuf_size = risc_buffer_size * 2; | ||
838 | dev->upstream_databuf_size = data_frame_size * 2; | ||
839 | |||
840 | /* Allocating buffers and prepare RISC program */ | ||
841 | retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size); | ||
842 | if (retval < 0) { | ||
843 | pr_err("%s: Failed to set up Video upstream buffers!\n", | ||
844 | dev->name); | ||
845 | goto error; | ||
846 | } | ||
847 | |||
848 | cx25821_start_video_dma_upstream(dev, sram_ch); | ||
849 | |||
850 | return 0; | ||
851 | |||
852 | error: | ||
853 | cx25821_dev_unregister(dev); | ||
854 | |||
855 | return err; | ||
856 | } | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.h b/drivers/media/pci/cx25821/cx25821-video-upstream.h new file mode 100644 index 000000000000..268ec8aa6a61 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.h | |||
@@ -0,0 +1,139 @@ | |||
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 \ | ||
70 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
71 | RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \ | ||
72 | NUM_NO_OPS * DWORD_SIZE) | ||
73 | |||
74 | #define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE) | ||
75 | |||
76 | #define PAL_VID_PROG_SIZE \ | ||
77 | ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \ | ||
78 | 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
79 | JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE) | ||
80 | |||
81 | #define ODD_FLD_PAL_PROG_SIZE \ | ||
82 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
83 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
84 | NUM_NO_OPS * DWORD_SIZE) | ||
85 | |||
86 | #define ODD_FLD_NTSC_PROG_SIZE \ | ||
87 | (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \ | ||
88 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
89 | NUM_NO_OPS * DWORD_SIZE) | ||
90 | |||
91 | #define NTSC_US_VID_PROG_SIZE \ | ||
92 | ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \ | ||
93 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \ | ||
94 | NUM_NO_OPS * DWORD_SIZE) | ||
95 | |||
96 | #define NTSC_RISC_BUF_SIZE \ | ||
97 | (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) | ||
98 | |||
99 | #define FRAME1_VID_PROG_SIZE \ | ||
100 | ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + \ | ||
101 | 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
102 | JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE) | ||
103 | |||
104 | #endif | ||
105 | |||
106 | #ifndef USE_RISC_NOOP_VIDEO | ||
107 | #define PAL_US_VID_PROG_SIZE \ | ||
108 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
109 | RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \ | ||
110 | JUMP_INSTRUCTION_SIZE) | ||
111 | |||
112 | #define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE) | ||
113 | |||
114 | #define PAL_VID_PROG_SIZE \ | ||
115 | ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \ | ||
116 | 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
117 | JUMP_INSTRUCTION_SIZE) | ||
118 | |||
119 | #define ODD_FLD_PAL_PROG_SIZE \ | ||
120 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
121 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) | ||
122 | |||
123 | #define ODD_FLD_NTSC_PROG_SIZE \ | ||
124 | (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \ | ||
125 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) | ||
126 | |||
127 | #define NTSC_US_VID_PROG_SIZE \ | ||
128 | ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \ | ||
129 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) | ||
130 | |||
131 | #define NTSC_RISC_BUF_SIZE \ | ||
132 | (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) | ||
133 | |||
134 | #define FRAME1_VID_PROG_SIZE \ | ||
135 | ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + \ | ||
136 | 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
137 | JUMP_INSTRUCTION_SIZE) | ||
138 | |||
139 | #endif | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c new file mode 100644 index 000000000000..b38d4379cc36 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-video.c | |||
@@ -0,0 +1,1990 @@ | |||
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 | * Parts adapted/taken from Eduardo Moscoso Rubino | ||
8 | * Copyright (C) 2009 Eduardo Moscoso Rubino <moscoso@TopoLogica.com> | ||
9 | * | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | |||
27 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
28 | |||
29 | #include "cx25821-video.h" | ||
30 | |||
31 | MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); | ||
32 | MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | |||
35 | static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET }; | ||
36 | static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET }; | ||
37 | |||
38 | module_param_array(video_nr, int, NULL, 0444); | ||
39 | module_param_array(radio_nr, int, NULL, 0444); | ||
40 | |||
41 | MODULE_PARM_DESC(video_nr, "video device numbers"); | ||
42 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); | ||
43 | |||
44 | static unsigned int video_debug = VIDEO_DEBUG; | ||
45 | module_param(video_debug, int, 0644); | ||
46 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); | ||
47 | |||
48 | static unsigned int irq_debug; | ||
49 | module_param(irq_debug, int, 0644); | ||
50 | MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); | ||
51 | |||
52 | unsigned int vid_limit = 16; | ||
53 | module_param(vid_limit, int, 0644); | ||
54 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); | ||
55 | |||
56 | static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num); | ||
57 | |||
58 | static const struct v4l2_file_operations video_fops; | ||
59 | static const struct v4l2_ioctl_ops video_ioctl_ops; | ||
60 | |||
61 | #define FORMAT_FLAGS_PACKED 0x01 | ||
62 | |||
63 | struct cx25821_fmt formats[] = { | ||
64 | { | ||
65 | .name = "8 bpp, gray", | ||
66 | .fourcc = V4L2_PIX_FMT_GREY, | ||
67 | .depth = 8, | ||
68 | .flags = FORMAT_FLAGS_PACKED, | ||
69 | }, { | ||
70 | .name = "4:1:1, packed, Y41P", | ||
71 | .fourcc = V4L2_PIX_FMT_Y41P, | ||
72 | .depth = 12, | ||
73 | .flags = FORMAT_FLAGS_PACKED, | ||
74 | }, { | ||
75 | .name = "4:2:2, packed, YUYV", | ||
76 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
77 | .depth = 16, | ||
78 | .flags = FORMAT_FLAGS_PACKED, | ||
79 | }, { | ||
80 | .name = "4:2:2, packed, UYVY", | ||
81 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
82 | .depth = 16, | ||
83 | .flags = FORMAT_FLAGS_PACKED, | ||
84 | }, { | ||
85 | .name = "4:2:0, YUV", | ||
86 | .fourcc = V4L2_PIX_FMT_YUV420, | ||
87 | .depth = 12, | ||
88 | .flags = FORMAT_FLAGS_PACKED, | ||
89 | }, | ||
90 | }; | ||
91 | |||
92 | int cx25821_get_format_size(void) | ||
93 | { | ||
94 | return ARRAY_SIZE(formats); | ||
95 | } | ||
96 | |||
97 | struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc) | ||
98 | { | ||
99 | unsigned int i; | ||
100 | |||
101 | if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) | ||
102 | return formats + 1; | ||
103 | |||
104 | for (i = 0; i < ARRAY_SIZE(formats); i++) | ||
105 | if (formats[i].fourcc == fourcc) | ||
106 | return formats + i; | ||
107 | |||
108 | pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc); | ||
109 | return NULL; | ||
110 | } | ||
111 | |||
112 | void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, | ||
113 | u32 count) | ||
114 | { | ||
115 | struct cx25821_buffer *buf; | ||
116 | int bc; | ||
117 | |||
118 | for (bc = 0;; bc++) { | ||
119 | if (list_empty(&q->active)) { | ||
120 | dprintk(1, "bc=%d (=0: active empty)\n", bc); | ||
121 | break; | ||
122 | } | ||
123 | |||
124 | buf = list_entry(q->active.next, struct cx25821_buffer, | ||
125 | vb.queue); | ||
126 | |||
127 | /* count comes from the hw and it is 16bit wide -- | ||
128 | * this trick handles wrap-arounds correctly for | ||
129 | * up to 32767 buffers in flight... */ | ||
130 | if ((s16) (count - buf->count) < 0) | ||
131 | break; | ||
132 | |||
133 | do_gettimeofday(&buf->vb.ts); | ||
134 | buf->vb.state = VIDEOBUF_DONE; | ||
135 | list_del(&buf->vb.queue); | ||
136 | wake_up(&buf->vb.done); | ||
137 | } | ||
138 | |||
139 | if (list_empty(&q->active)) | ||
140 | del_timer(&q->timeout); | ||
141 | else | ||
142 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | ||
143 | if (bc != 1) | ||
144 | pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc); | ||
145 | } | ||
146 | |||
147 | #ifdef TUNER_FLAG | ||
148 | int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) | ||
149 | { | ||
150 | dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", | ||
151 | __func__, (unsigned int)norm, v4l2_norm_to_name(norm)); | ||
152 | |||
153 | dev->tvnorm = norm; | ||
154 | |||
155 | /* Tell the internal A/V decoder */ | ||
156 | cx25821_call_all(dev, core, s_std, norm); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | #endif | ||
161 | |||
162 | struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, | ||
163 | struct pci_dev *pci, | ||
164 | struct video_device *template, | ||
165 | char *type) | ||
166 | { | ||
167 | struct video_device *vfd; | ||
168 | dprintk(1, "%s()\n", __func__); | ||
169 | |||
170 | vfd = video_device_alloc(); | ||
171 | if (NULL == vfd) | ||
172 | return NULL; | ||
173 | *vfd = *template; | ||
174 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
175 | vfd->release = video_device_release; | ||
176 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, | ||
177 | cx25821_boards[dev->board].name); | ||
178 | video_set_drvdata(vfd, dev); | ||
179 | return vfd; | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) | ||
184 | { | ||
185 | int i; | ||
186 | |||
187 | if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1) | ||
188 | return -EINVAL; | ||
189 | for (i = 0; i < CX25821_CTLS; i++) | ||
190 | if (cx25821_ctls[i].v.id == qctrl->id) | ||
191 | break; | ||
192 | if (i == CX25821_CTLS) { | ||
193 | *qctrl = no_ctl; | ||
194 | return 0; | ||
195 | } | ||
196 | *qctrl = cx25821_ctls[i].v; | ||
197 | return 0; | ||
198 | } | ||
199 | */ | ||
200 | |||
201 | /* resource management */ | ||
202 | int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, | ||
203 | unsigned int bit) | ||
204 | { | ||
205 | dprintk(1, "%s()\n", __func__); | ||
206 | if (fh->resources & bit) | ||
207 | /* have it already allocated */ | ||
208 | return 1; | ||
209 | |||
210 | /* is it free? */ | ||
211 | mutex_lock(&dev->lock); | ||
212 | if (dev->channels[fh->channel_id].resources & bit) { | ||
213 | /* no, someone else uses it */ | ||
214 | mutex_unlock(&dev->lock); | ||
215 | return 0; | ||
216 | } | ||
217 | /* it's free, grab it */ | ||
218 | fh->resources |= bit; | ||
219 | dev->channels[fh->channel_id].resources |= bit; | ||
220 | dprintk(1, "res: get %d\n", bit); | ||
221 | mutex_unlock(&dev->lock); | ||
222 | return 1; | ||
223 | } | ||
224 | |||
225 | int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit) | ||
226 | { | ||
227 | return fh->resources & bit; | ||
228 | } | ||
229 | |||
230 | int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit) | ||
231 | { | ||
232 | return fh->dev->channels[fh->channel_id].resources & bit; | ||
233 | } | ||
234 | |||
235 | void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, | ||
236 | unsigned int bits) | ||
237 | { | ||
238 | BUG_ON((fh->resources & bits) != bits); | ||
239 | dprintk(1, "%s()\n", __func__); | ||
240 | |||
241 | mutex_lock(&dev->lock); | ||
242 | fh->resources &= ~bits; | ||
243 | dev->channels[fh->channel_id].resources &= ~bits; | ||
244 | dprintk(1, "res: put %d\n", bits); | ||
245 | mutex_unlock(&dev->lock); | ||
246 | } | ||
247 | |||
248 | int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) | ||
249 | { | ||
250 | struct v4l2_routing route; | ||
251 | memset(&route, 0, sizeof(route)); | ||
252 | |||
253 | dprintk(1, "%s(): video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", | ||
254 | __func__, input, INPUT(input)->vmux, INPUT(input)->gpio0, | ||
255 | INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3); | ||
256 | dev->input = input; | ||
257 | |||
258 | route.input = INPUT(input)->vmux; | ||
259 | |||
260 | /* Tell the internal A/V decoder */ | ||
261 | cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | int cx25821_start_video_dma(struct cx25821_dev *dev, | ||
267 | struct cx25821_dmaqueue *q, | ||
268 | struct cx25821_buffer *buf, | ||
269 | struct sram_channel *channel) | ||
270 | { | ||
271 | int tmp = 0; | ||
272 | |||
273 | /* setup fifo + format */ | ||
274 | cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma); | ||
275 | |||
276 | /* reset counter */ | ||
277 | cx_write(channel->gpcnt_ctl, 3); | ||
278 | q->count = 1; | ||
279 | |||
280 | /* enable irq */ | ||
281 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i)); | ||
282 | cx_set(channel->int_msk, 0x11); | ||
283 | |||
284 | /* start dma */ | ||
285 | cx_write(channel->dma_ctl, 0x11); /* FIFO and RISC enable */ | ||
286 | |||
287 | /* make sure upstream setting if any is reversed */ | ||
288 | tmp = cx_read(VID_CH_MODE_SEL); | ||
289 | cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | int cx25821_restart_video_queue(struct cx25821_dev *dev, | ||
295 | struct cx25821_dmaqueue *q, | ||
296 | struct sram_channel *channel) | ||
297 | { | ||
298 | struct cx25821_buffer *buf, *prev; | ||
299 | struct list_head *item; | ||
300 | |||
301 | if (!list_empty(&q->active)) { | ||
302 | buf = list_entry(q->active.next, struct cx25821_buffer, | ||
303 | vb.queue); | ||
304 | |||
305 | cx25821_start_video_dma(dev, q, buf, channel); | ||
306 | |||
307 | list_for_each(item, &q->active) { | ||
308 | buf = list_entry(item, struct cx25821_buffer, vb.queue); | ||
309 | buf->count = q->count++; | ||
310 | } | ||
311 | |||
312 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | prev = NULL; | ||
317 | for (;;) { | ||
318 | if (list_empty(&q->queued)) | ||
319 | return 0; | ||
320 | |||
321 | buf = list_entry(q->queued.next, struct cx25821_buffer, | ||
322 | vb.queue); | ||
323 | |||
324 | if (NULL == prev) { | ||
325 | list_move_tail(&buf->vb.queue, &q->active); | ||
326 | cx25821_start_video_dma(dev, q, buf, channel); | ||
327 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
328 | buf->count = q->count++; | ||
329 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | ||
330 | } else if (prev->vb.width == buf->vb.width && | ||
331 | prev->vb.height == buf->vb.height && | ||
332 | prev->fmt == buf->fmt) { | ||
333 | list_move_tail(&buf->vb.queue, &q->active); | ||
334 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
335 | buf->count = q->count++; | ||
336 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | ||
337 | prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */ | ||
338 | } else { | ||
339 | return 0; | ||
340 | } | ||
341 | prev = buf; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | void cx25821_vid_timeout(unsigned long data) | ||
346 | { | ||
347 | struct cx25821_data *timeout_data = (struct cx25821_data *)data; | ||
348 | struct cx25821_dev *dev = timeout_data->dev; | ||
349 | struct sram_channel *channel = timeout_data->channel; | ||
350 | struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq; | ||
351 | struct cx25821_buffer *buf; | ||
352 | unsigned long flags; | ||
353 | |||
354 | /* cx25821_sram_channel_dump(dev, channel); */ | ||
355 | cx_clear(channel->dma_ctl, 0x11); | ||
356 | |||
357 | spin_lock_irqsave(&dev->slock, flags); | ||
358 | while (!list_empty(&q->active)) { | ||
359 | buf = list_entry(q->active.next, struct cx25821_buffer, | ||
360 | vb.queue); | ||
361 | list_del(&buf->vb.queue); | ||
362 | |||
363 | buf->vb.state = VIDEOBUF_ERROR; | ||
364 | wake_up(&buf->vb.done); | ||
365 | } | ||
366 | |||
367 | cx25821_restart_video_queue(dev, q, channel); | ||
368 | spin_unlock_irqrestore(&dev->slock, flags); | ||
369 | } | ||
370 | |||
371 | int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) | ||
372 | { | ||
373 | u32 count = 0; | ||
374 | int handled = 0; | ||
375 | u32 mask; | ||
376 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; | ||
377 | |||
378 | mask = cx_read(channel->int_msk); | ||
379 | if (0 == (status & mask)) | ||
380 | return handled; | ||
381 | |||
382 | cx_write(channel->int_stat, status); | ||
383 | |||
384 | /* risc op code error */ | ||
385 | if (status & (1 << 16)) { | ||
386 | pr_warn("%s, %s: video risc op code error\n", | ||
387 | dev->name, channel->name); | ||
388 | cx_clear(channel->dma_ctl, 0x11); | ||
389 | cx25821_sram_channel_dump(dev, channel); | ||
390 | } | ||
391 | |||
392 | /* risc1 y */ | ||
393 | if (status & FLD_VID_DST_RISC1) { | ||
394 | spin_lock(&dev->slock); | ||
395 | count = cx_read(channel->gpcnt); | ||
396 | cx25821_video_wakeup(dev, &dev->channels[channel->i].vidq, | ||
397 | count); | ||
398 | spin_unlock(&dev->slock); | ||
399 | handled++; | ||
400 | } | ||
401 | |||
402 | /* risc2 y */ | ||
403 | if (status & 0x10) { | ||
404 | dprintk(2, "stopper video\n"); | ||
405 | spin_lock(&dev->slock); | ||
406 | cx25821_restart_video_queue(dev, | ||
407 | &dev->channels[channel->i].vidq, channel); | ||
408 | spin_unlock(&dev->slock); | ||
409 | handled++; | ||
410 | } | ||
411 | return handled; | ||
412 | } | ||
413 | |||
414 | void cx25821_videoioctl_unregister(struct cx25821_dev *dev) | ||
415 | { | ||
416 | if (dev->ioctl_dev) { | ||
417 | if (video_is_registered(dev->ioctl_dev)) | ||
418 | video_unregister_device(dev->ioctl_dev); | ||
419 | else | ||
420 | video_device_release(dev->ioctl_dev); | ||
421 | |||
422 | dev->ioctl_dev = NULL; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) | ||
427 | { | ||
428 | cx_clear(PCI_INT_MSK, 1); | ||
429 | |||
430 | if (dev->channels[chan_num].video_dev) { | ||
431 | if (video_is_registered(dev->channels[chan_num].video_dev)) | ||
432 | video_unregister_device( | ||
433 | dev->channels[chan_num].video_dev); | ||
434 | else | ||
435 | video_device_release( | ||
436 | dev->channels[chan_num].video_dev); | ||
437 | |||
438 | dev->channels[chan_num].video_dev = NULL; | ||
439 | |||
440 | btcx_riscmem_free(dev->pci, | ||
441 | &dev->channels[chan_num].vidq.stopper); | ||
442 | |||
443 | pr_warn("device %d released!\n", chan_num); | ||
444 | } | ||
445 | |||
446 | } | ||
447 | |||
448 | int cx25821_video_register(struct cx25821_dev *dev) | ||
449 | { | ||
450 | int err; | ||
451 | int i; | ||
452 | |||
453 | struct video_device cx25821_video_device = { | ||
454 | .name = "cx25821-video", | ||
455 | .fops = &video_fops, | ||
456 | .minor = -1, | ||
457 | .ioctl_ops = &video_ioctl_ops, | ||
458 | .tvnorms = CX25821_NORMS, | ||
459 | .current_norm = V4L2_STD_NTSC_M, | ||
460 | }; | ||
461 | |||
462 | spin_lock_init(&dev->slock); | ||
463 | |||
464 | for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) { | ||
465 | cx25821_init_controls(dev, i); | ||
466 | |||
467 | cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, | ||
468 | dev->channels[i].sram_channels->dma_ctl, 0x11, 0); | ||
469 | |||
470 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; | ||
471 | dev->channels[i].video_dev = NULL; | ||
472 | dev->channels[i].resources = 0; | ||
473 | |||
474 | cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); | ||
475 | |||
476 | INIT_LIST_HEAD(&dev->channels[i].vidq.active); | ||
477 | INIT_LIST_HEAD(&dev->channels[i].vidq.queued); | ||
478 | |||
479 | dev->channels[i].timeout_data.dev = dev; | ||
480 | dev->channels[i].timeout_data.channel = | ||
481 | &cx25821_sram_channels[i]; | ||
482 | dev->channels[i].vidq.timeout.function = cx25821_vid_timeout; | ||
483 | dev->channels[i].vidq.timeout.data = | ||
484 | (unsigned long)&dev->channels[i].timeout_data; | ||
485 | init_timer(&dev->channels[i].vidq.timeout); | ||
486 | |||
487 | /* register v4l devices */ | ||
488 | dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci, | ||
489 | &cx25821_video_device, "video"); | ||
490 | |||
491 | err = video_register_device(dev->channels[i].video_dev, | ||
492 | VFL_TYPE_GRABBER, video_nr[dev->nr]); | ||
493 | |||
494 | if (err < 0) | ||
495 | goto fail_unreg; | ||
496 | |||
497 | } | ||
498 | |||
499 | /* set PCI interrupt */ | ||
500 | cx_set(PCI_INT_MSK, 0xff); | ||
501 | |||
502 | /* initial device configuration */ | ||
503 | mutex_lock(&dev->lock); | ||
504 | #ifdef TUNER_FLAG | ||
505 | dev->tvnorm = cx25821_video_device.current_norm; | ||
506 | cx25821_set_tvnorm(dev, dev->tvnorm); | ||
507 | #endif | ||
508 | mutex_unlock(&dev->lock); | ||
509 | |||
510 | return 0; | ||
511 | |||
512 | fail_unreg: | ||
513 | cx25821_video_unregister(dev, i); | ||
514 | return err; | ||
515 | } | ||
516 | |||
517 | int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, | ||
518 | unsigned int *size) | ||
519 | { | ||
520 | struct cx25821_fh *fh = q->priv_data; | ||
521 | |||
522 | *size = fh->fmt->depth * fh->width * fh->height >> 3; | ||
523 | |||
524 | if (0 == *count) | ||
525 | *count = 32; | ||
526 | |||
527 | if (*size * *count > vid_limit * 1024 * 1024) | ||
528 | *count = (vid_limit * 1024 * 1024) / *size; | ||
529 | |||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | ||
534 | enum v4l2_field field) | ||
535 | { | ||
536 | struct cx25821_fh *fh = q->priv_data; | ||
537 | struct cx25821_dev *dev = fh->dev; | ||
538 | struct cx25821_buffer *buf = | ||
539 | container_of(vb, struct cx25821_buffer, vb); | ||
540 | int rc, init_buffer = 0; | ||
541 | u32 line0_offset; | ||
542 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | ||
543 | int bpl_local = LINE_SIZE_D1; | ||
544 | int channel_opened = fh->channel_id; | ||
545 | |||
546 | BUG_ON(NULL == fh->fmt); | ||
547 | if (fh->width < 48 || fh->width > 720 || | ||
548 | fh->height < 32 || fh->height > 576) | ||
549 | return -EINVAL; | ||
550 | |||
551 | buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; | ||
552 | |||
553 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
554 | return -EINVAL; | ||
555 | |||
556 | if (buf->fmt != fh->fmt || | ||
557 | buf->vb.width != fh->width || | ||
558 | buf->vb.height != fh->height || buf->vb.field != field) { | ||
559 | buf->fmt = fh->fmt; | ||
560 | buf->vb.width = fh->width; | ||
561 | buf->vb.height = fh->height; | ||
562 | buf->vb.field = field; | ||
563 | init_buffer = 1; | ||
564 | } | ||
565 | |||
566 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
567 | init_buffer = 1; | ||
568 | rc = videobuf_iolock(q, &buf->vb, NULL); | ||
569 | if (0 != rc) { | ||
570 | printk(KERN_DEBUG pr_fmt("videobuf_iolock failed!\n")); | ||
571 | goto fail; | ||
572 | } | ||
573 | } | ||
574 | |||
575 | dprintk(1, "init_buffer=%d\n", init_buffer); | ||
576 | |||
577 | if (init_buffer) { | ||
578 | |||
579 | channel_opened = dev->channel_opened; | ||
580 | if (channel_opened < 0 || channel_opened > 7) | ||
581 | channel_opened = 7; | ||
582 | |||
583 | if (dev->channels[channel_opened].pixel_formats == | ||
584 | PIXEL_FRMT_411) | ||
585 | buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3; | ||
586 | else | ||
587 | buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width); | ||
588 | |||
589 | if (dev->channels[channel_opened].pixel_formats == | ||
590 | PIXEL_FRMT_411) { | ||
591 | bpl_local = buf->bpl; | ||
592 | } else { | ||
593 | bpl_local = buf->bpl; /* Default */ | ||
594 | |||
595 | if (channel_opened >= 0 && channel_opened <= 7) { | ||
596 | if (dev->channels[channel_opened] | ||
597 | .use_cif_resolution) { | ||
598 | if (dev->tvnorm & V4L2_STD_PAL_BG || | ||
599 | dev->tvnorm & V4L2_STD_PAL_DK) | ||
600 | bpl_local = 352 << 1; | ||
601 | else | ||
602 | bpl_local = dev->channels[ | ||
603 | channel_opened]. | ||
604 | cif_width << 1; | ||
605 | } | ||
606 | } | ||
607 | } | ||
608 | |||
609 | switch (buf->vb.field) { | ||
610 | case V4L2_FIELD_TOP: | ||
611 | cx25821_risc_buffer(dev->pci, &buf->risc, | ||
612 | dma->sglist, 0, UNSET, | ||
613 | buf->bpl, 0, buf->vb.height); | ||
614 | break; | ||
615 | case V4L2_FIELD_BOTTOM: | ||
616 | cx25821_risc_buffer(dev->pci, &buf->risc, | ||
617 | dma->sglist, UNSET, 0, | ||
618 | buf->bpl, 0, buf->vb.height); | ||
619 | break; | ||
620 | case V4L2_FIELD_INTERLACED: | ||
621 | /* All other formats are top field first */ | ||
622 | line0_offset = 0; | ||
623 | dprintk(1, "top field first\n"); | ||
624 | |||
625 | cx25821_risc_buffer(dev->pci, &buf->risc, | ||
626 | dma->sglist, line0_offset, | ||
627 | bpl_local, bpl_local, bpl_local, | ||
628 | buf->vb.height >> 1); | ||
629 | break; | ||
630 | case V4L2_FIELD_SEQ_TB: | ||
631 | cx25821_risc_buffer(dev->pci, &buf->risc, | ||
632 | dma->sglist, | ||
633 | 0, buf->bpl * (buf->vb.height >> 1), | ||
634 | buf->bpl, 0, buf->vb.height >> 1); | ||
635 | break; | ||
636 | case V4L2_FIELD_SEQ_BT: | ||
637 | cx25821_risc_buffer(dev->pci, &buf->risc, | ||
638 | dma->sglist, | ||
639 | buf->bpl * (buf->vb.height >> 1), 0, | ||
640 | buf->bpl, 0, buf->vb.height >> 1); | ||
641 | break; | ||
642 | default: | ||
643 | BUG(); | ||
644 | } | ||
645 | } | ||
646 | |||
647 | dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", | ||
648 | buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth, | ||
649 | fh->fmt->name, (unsigned long)buf->risc.dma); | ||
650 | |||
651 | buf->vb.state = VIDEOBUF_PREPARED; | ||
652 | |||
653 | return 0; | ||
654 | |||
655 | fail: | ||
656 | cx25821_free_buffer(q, buf); | ||
657 | return rc; | ||
658 | } | ||
659 | |||
660 | void cx25821_buffer_release(struct videobuf_queue *q, | ||
661 | struct videobuf_buffer *vb) | ||
662 | { | ||
663 | struct cx25821_buffer *buf = | ||
664 | container_of(vb, struct cx25821_buffer, vb); | ||
665 | |||
666 | cx25821_free_buffer(q, buf); | ||
667 | } | ||
668 | |||
669 | struct videobuf_queue *get_queue(struct cx25821_fh *fh) | ||
670 | { | ||
671 | switch (fh->type) { | ||
672 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
673 | return &fh->vidq; | ||
674 | default: | ||
675 | BUG(); | ||
676 | return NULL; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | int cx25821_get_resource(struct cx25821_fh *fh, int resource) | ||
681 | { | ||
682 | switch (fh->type) { | ||
683 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
684 | return resource; | ||
685 | default: | ||
686 | BUG(); | ||
687 | return 0; | ||
688 | } | ||
689 | } | ||
690 | |||
691 | int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) | ||
692 | { | ||
693 | struct cx25821_fh *fh = file->private_data; | ||
694 | |||
695 | return videobuf_mmap_mapper(get_queue(fh), vma); | ||
696 | } | ||
697 | |||
698 | |||
699 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
700 | { | ||
701 | struct cx25821_buffer *buf = | ||
702 | container_of(vb, struct cx25821_buffer, vb); | ||
703 | struct cx25821_buffer *prev; | ||
704 | struct cx25821_fh *fh = vq->priv_data; | ||
705 | struct cx25821_dev *dev = fh->dev; | ||
706 | struct cx25821_dmaqueue *q = &dev->channels[fh->channel_id].vidq; | ||
707 | |||
708 | /* add jump to stopper */ | ||
709 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | ||
710 | buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); | ||
711 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | ||
712 | |||
713 | dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]); | ||
714 | |||
715 | if (!list_empty(&q->queued)) { | ||
716 | list_add_tail(&buf->vb.queue, &q->queued); | ||
717 | buf->vb.state = VIDEOBUF_QUEUED; | ||
718 | dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf, | ||
719 | buf->vb.i); | ||
720 | |||
721 | } else if (list_empty(&q->active)) { | ||
722 | list_add_tail(&buf->vb.queue, &q->active); | ||
723 | cx25821_start_video_dma(dev, q, buf, | ||
724 | dev->channels[fh->channel_id].sram_channels); | ||
725 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
726 | buf->count = q->count++; | ||
727 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | ||
728 | dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n", | ||
729 | buf, buf->vb.i, buf->count, q->count); | ||
730 | } else { | ||
731 | prev = list_entry(q->active.prev, struct cx25821_buffer, | ||
732 | vb.queue); | ||
733 | if (prev->vb.width == buf->vb.width | ||
734 | && prev->vb.height == buf->vb.height | ||
735 | && prev->fmt == buf->fmt) { | ||
736 | list_add_tail(&buf->vb.queue, &q->active); | ||
737 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
738 | buf->count = q->count++; | ||
739 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | ||
740 | |||
741 | /* 64 bit bits 63-32 */ | ||
742 | prev->risc.jmp[2] = cpu_to_le32(0); | ||
743 | dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n", | ||
744 | buf, buf->vb.i, buf->count); | ||
745 | |||
746 | } else { | ||
747 | list_add_tail(&buf->vb.queue, &q->queued); | ||
748 | buf->vb.state = VIDEOBUF_QUEUED; | ||
749 | dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf, | ||
750 | buf->vb.i); | ||
751 | } | ||
752 | } | ||
753 | |||
754 | if (list_empty(&q->active)) | ||
755 | dprintk(2, "active queue empty!\n"); | ||
756 | } | ||
757 | |||
758 | static struct videobuf_queue_ops cx25821_video_qops = { | ||
759 | .buf_setup = cx25821_buffer_setup, | ||
760 | .buf_prepare = cx25821_buffer_prepare, | ||
761 | .buf_queue = buffer_queue, | ||
762 | .buf_release = cx25821_buffer_release, | ||
763 | }; | ||
764 | |||
765 | static int video_open(struct file *file) | ||
766 | { | ||
767 | struct video_device *vdev = video_devdata(file); | ||
768 | struct cx25821_dev *h, *dev = video_drvdata(file); | ||
769 | struct cx25821_fh *fh; | ||
770 | struct list_head *list; | ||
771 | int minor = video_devdata(file)->minor; | ||
772 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
773 | u32 pix_format; | ||
774 | int ch_id = 0; | ||
775 | int i; | ||
776 | |||
777 | dprintk(1, "open dev=%s type=%s\n", video_device_node_name(vdev), | ||
778 | v4l2_type_names[type]); | ||
779 | |||
780 | /* allocate + initialize per filehandle data */ | ||
781 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
782 | if (NULL == fh) | ||
783 | return -ENOMEM; | ||
784 | |||
785 | mutex_lock(&cx25821_devlist_mutex); | ||
786 | |||
787 | list_for_each(list, &cx25821_devlist) | ||
788 | { | ||
789 | h = list_entry(list, struct cx25821_dev, devlist); | ||
790 | |||
791 | for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { | ||
792 | if (h->channels[i].video_dev && | ||
793 | h->channels[i].video_dev->minor == minor) { | ||
794 | dev = h; | ||
795 | ch_id = i; | ||
796 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
797 | } | ||
798 | } | ||
799 | } | ||
800 | |||
801 | if (NULL == dev) { | ||
802 | mutex_unlock(&cx25821_devlist_mutex); | ||
803 | kfree(fh); | ||
804 | return -ENODEV; | ||
805 | } | ||
806 | |||
807 | file->private_data = fh; | ||
808 | fh->dev = dev; | ||
809 | fh->type = type; | ||
810 | fh->width = 720; | ||
811 | fh->channel_id = ch_id; | ||
812 | |||
813 | if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) | ||
814 | fh->height = 576; | ||
815 | else | ||
816 | fh->height = 480; | ||
817 | |||
818 | dev->channel_opened = fh->channel_id; | ||
819 | if (dev->channels[ch_id].pixel_formats == PIXEL_FRMT_411) | ||
820 | pix_format = V4L2_PIX_FMT_Y41P; | ||
821 | else | ||
822 | pix_format = V4L2_PIX_FMT_YUYV; | ||
823 | fh->fmt = cx25821_format_by_fourcc(pix_format); | ||
824 | |||
825 | v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); | ||
826 | |||
827 | videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev, | ||
828 | &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
829 | V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), | ||
830 | fh, NULL); | ||
831 | |||
832 | dprintk(1, "post videobuf_queue_init()\n"); | ||
833 | mutex_unlock(&cx25821_devlist_mutex); | ||
834 | |||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | static ssize_t video_read(struct file *file, char __user * data, size_t count, | ||
839 | loff_t *ppos) | ||
840 | { | ||
841 | struct cx25821_fh *fh = file->private_data; | ||
842 | |||
843 | switch (fh->type) { | ||
844 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
845 | if (cx25821_res_locked(fh, RESOURCE_VIDEO0)) | ||
846 | return -EBUSY; | ||
847 | |||
848 | return videobuf_read_one(&fh->vidq, data, count, ppos, | ||
849 | file->f_flags & O_NONBLOCK); | ||
850 | |||
851 | default: | ||
852 | BUG(); | ||
853 | return 0; | ||
854 | } | ||
855 | } | ||
856 | |||
857 | static unsigned int video_poll(struct file *file, | ||
858 | struct poll_table_struct *wait) | ||
859 | { | ||
860 | struct cx25821_fh *fh = file->private_data; | ||
861 | struct cx25821_buffer *buf; | ||
862 | |||
863 | if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { | ||
864 | /* streaming capture */ | ||
865 | if (list_empty(&fh->vidq.stream)) | ||
866 | return POLLERR; | ||
867 | buf = list_entry(fh->vidq.stream.next, | ||
868 | struct cx25821_buffer, vb.stream); | ||
869 | } else { | ||
870 | /* read() capture */ | ||
871 | buf = (struct cx25821_buffer *)fh->vidq.read_buf; | ||
872 | if (NULL == buf) | ||
873 | return POLLERR; | ||
874 | } | ||
875 | |||
876 | poll_wait(file, &buf->vb.done, wait); | ||
877 | if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) { | ||
878 | if (buf->vb.state == VIDEOBUF_DONE) { | ||
879 | struct cx25821_dev *dev = fh->dev; | ||
880 | |||
881 | if (dev && dev->channels[fh->channel_id] | ||
882 | .use_cif_resolution) { | ||
883 | u8 cam_id = *((char *)buf->vb.baddr + 3); | ||
884 | memcpy((char *)buf->vb.baddr, | ||
885 | (char *)buf->vb.baddr + (fh->width * 2), | ||
886 | (fh->width * 2)); | ||
887 | *((char *)buf->vb.baddr + 3) = cam_id; | ||
888 | } | ||
889 | } | ||
890 | |||
891 | return POLLIN | POLLRDNORM; | ||
892 | } | ||
893 | |||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | static int video_release(struct file *file) | ||
898 | { | ||
899 | struct cx25821_fh *fh = file->private_data; | ||
900 | struct cx25821_dev *dev = fh->dev; | ||
901 | |||
902 | /* stop the risc engine and fifo */ | ||
903 | cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */ | ||
904 | |||
905 | /* stop video capture */ | ||
906 | if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { | ||
907 | videobuf_queue_cancel(&fh->vidq); | ||
908 | cx25821_res_free(dev, fh, RESOURCE_VIDEO0); | ||
909 | } | ||
910 | |||
911 | if (fh->vidq.read_buf) { | ||
912 | cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf); | ||
913 | kfree(fh->vidq.read_buf); | ||
914 | } | ||
915 | |||
916 | videobuf_mmap_free(&fh->vidq); | ||
917 | |||
918 | v4l2_prio_close(&dev->channels[fh->channel_id].prio, fh->prio); | ||
919 | file->private_data = NULL; | ||
920 | kfree(fh); | ||
921 | |||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | ||
926 | { | ||
927 | struct cx25821_fh *fh = priv; | ||
928 | struct cx25821_dev *dev = fh->dev; | ||
929 | |||
930 | if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) | ||
931 | return -EINVAL; | ||
932 | |||
933 | if (unlikely(i != fh->type)) | ||
934 | return -EINVAL; | ||
935 | |||
936 | if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, | ||
937 | RESOURCE_VIDEO0)))) | ||
938 | return -EBUSY; | ||
939 | |||
940 | return videobuf_streamon(get_queue(fh)); | ||
941 | } | ||
942 | |||
943 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | ||
944 | { | ||
945 | struct cx25821_fh *fh = priv; | ||
946 | struct cx25821_dev *dev = fh->dev; | ||
947 | int err, res; | ||
948 | |||
949 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
950 | return -EINVAL; | ||
951 | if (i != fh->type) | ||
952 | return -EINVAL; | ||
953 | |||
954 | res = cx25821_get_resource(fh, RESOURCE_VIDEO0); | ||
955 | err = videobuf_streamoff(get_queue(fh)); | ||
956 | if (err < 0) | ||
957 | return err; | ||
958 | cx25821_res_free(dev, fh, res); | ||
959 | return 0; | ||
960 | } | ||
961 | |||
962 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | ||
963 | struct v4l2_format *f) | ||
964 | { | ||
965 | struct cx25821_fh *fh = priv; | ||
966 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
967 | struct v4l2_mbus_framefmt mbus_fmt; | ||
968 | int err; | ||
969 | int pix_format = PIXEL_FRMT_422; | ||
970 | |||
971 | if (fh) { | ||
972 | err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, | ||
973 | fh->prio); | ||
974 | if (0 != err) | ||
975 | return err; | ||
976 | } | ||
977 | |||
978 | dprintk(2, "%s()\n", __func__); | ||
979 | err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f); | ||
980 | |||
981 | if (0 != err) | ||
982 | return err; | ||
983 | |||
984 | fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); | ||
985 | fh->vidq.field = f->fmt.pix.field; | ||
986 | |||
987 | /* check if width and height is valid based on set standard */ | ||
988 | if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) | ||
989 | fh->width = f->fmt.pix.width; | ||
990 | |||
991 | if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) | ||
992 | fh->height = f->fmt.pix.height; | ||
993 | |||
994 | if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P) | ||
995 | pix_format = PIXEL_FRMT_411; | ||
996 | else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) | ||
997 | pix_format = PIXEL_FRMT_422; | ||
998 | else | ||
999 | return -EINVAL; | ||
1000 | |||
1001 | cx25821_set_pixel_format(dev, SRAM_CH00, pix_format); | ||
1002 | |||
1003 | /* check if cif resolution */ | ||
1004 | if (fh->width == 320 || fh->width == 352) | ||
1005 | dev->channels[fh->channel_id].use_cif_resolution = 1; | ||
1006 | else | ||
1007 | dev->channels[fh->channel_id].use_cif_resolution = 0; | ||
1008 | |||
1009 | dev->channels[fh->channel_id].cif_width = fh->width; | ||
1010 | medusa_set_resolution(dev, fh->width, SRAM_CH00); | ||
1011 | |||
1012 | dprintk(2, "%s(): width=%d height=%d field=%d\n", __func__, fh->width, | ||
1013 | fh->height, fh->vidq.field); | ||
1014 | v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); | ||
1015 | cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt); | ||
1016 | |||
1017 | return 0; | ||
1018 | } | ||
1019 | |||
1020 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) | ||
1021 | { | ||
1022 | int ret_val = 0; | ||
1023 | struct cx25821_fh *fh = priv; | ||
1024 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1025 | |||
1026 | ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK); | ||
1027 | |||
1028 | p->sequence = dev->channels[fh->channel_id].vidq.count; | ||
1029 | |||
1030 | return ret_val; | ||
1031 | } | ||
1032 | |||
1033 | static int vidioc_log_status(struct file *file, void *priv) | ||
1034 | { | ||
1035 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1036 | struct cx25821_fh *fh = priv; | ||
1037 | char name[32 + 2]; | ||
1038 | |||
1039 | struct sram_channel *sram_ch = dev->channels[fh->channel_id] | ||
1040 | .sram_channels; | ||
1041 | u32 tmp = 0; | ||
1042 | |||
1043 | snprintf(name, sizeof(name), "%s/2", dev->name); | ||
1044 | pr_info("%s/2: ============ START LOG STATUS ============\n", | ||
1045 | dev->name); | ||
1046 | cx25821_call_all(dev, core, log_status); | ||
1047 | tmp = cx_read(sram_ch->dma_ctl); | ||
1048 | pr_info("Video input 0 is %s\n", | ||
1049 | (tmp & 0x11) ? "streaming" : "stopped"); | ||
1050 | pr_info("%s/2: ============= END LOG STATUS =============\n", | ||
1051 | dev->name); | ||
1052 | return 0; | ||
1053 | } | ||
1054 | |||
1055 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
1056 | struct v4l2_control *ctl) | ||
1057 | { | ||
1058 | struct cx25821_fh *fh = priv; | ||
1059 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1060 | int err; | ||
1061 | |||
1062 | if (fh) { | ||
1063 | err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, | ||
1064 | fh->prio); | ||
1065 | if (0 != err) | ||
1066 | return err; | ||
1067 | } | ||
1068 | |||
1069 | return cx25821_set_control(dev, ctl, fh->channel_id); | ||
1070 | } | ||
1071 | |||
1072 | /* VIDEO IOCTLS */ | ||
1073 | int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
1074 | struct v4l2_format *f) | ||
1075 | { | ||
1076 | struct cx25821_fh *fh = priv; | ||
1077 | |||
1078 | f->fmt.pix.width = fh->width; | ||
1079 | f->fmt.pix.height = fh->height; | ||
1080 | f->fmt.pix.field = fh->vidq.field; | ||
1081 | f->fmt.pix.pixelformat = fh->fmt->fourcc; | ||
1082 | f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3; | ||
1083 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
1084 | |||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, | ||
1089 | struct v4l2_format *f) | ||
1090 | { | ||
1091 | struct cx25821_fmt *fmt; | ||
1092 | enum v4l2_field field; | ||
1093 | unsigned int maxw, maxh; | ||
1094 | |||
1095 | fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); | ||
1096 | if (NULL == fmt) | ||
1097 | return -EINVAL; | ||
1098 | |||
1099 | field = f->fmt.pix.field; | ||
1100 | maxw = 720; | ||
1101 | maxh = 576; | ||
1102 | |||
1103 | if (V4L2_FIELD_ANY == field) { | ||
1104 | if (f->fmt.pix.height > maxh / 2) | ||
1105 | field = V4L2_FIELD_INTERLACED; | ||
1106 | else | ||
1107 | field = V4L2_FIELD_TOP; | ||
1108 | } | ||
1109 | |||
1110 | switch (field) { | ||
1111 | case V4L2_FIELD_TOP: | ||
1112 | case V4L2_FIELD_BOTTOM: | ||
1113 | maxh = maxh / 2; | ||
1114 | break; | ||
1115 | case V4L2_FIELD_INTERLACED: | ||
1116 | break; | ||
1117 | default: | ||
1118 | return -EINVAL; | ||
1119 | } | ||
1120 | |||
1121 | f->fmt.pix.field = field; | ||
1122 | if (f->fmt.pix.height < 32) | ||
1123 | f->fmt.pix.height = 32; | ||
1124 | if (f->fmt.pix.height > maxh) | ||
1125 | f->fmt.pix.height = maxh; | ||
1126 | if (f->fmt.pix.width < 48) | ||
1127 | f->fmt.pix.width = 48; | ||
1128 | if (f->fmt.pix.width > maxw) | ||
1129 | f->fmt.pix.width = maxw; | ||
1130 | f->fmt.pix.width &= ~0x03; | ||
1131 | f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; | ||
1132 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
1133 | |||
1134 | return 0; | ||
1135 | } | ||
1136 | |||
1137 | int cx25821_vidioc_querycap(struct file *file, void *priv, | ||
1138 | struct v4l2_capability *cap) | ||
1139 | { | ||
1140 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1141 | |||
1142 | strcpy(cap->driver, "cx25821"); | ||
1143 | strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card)); | ||
1144 | sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); | ||
1145 | cap->version = CX25821_VERSION_CODE; | ||
1146 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | | ||
1147 | V4L2_CAP_STREAMING; | ||
1148 | if (UNSET != dev->tuner_type) | ||
1149 | cap->capabilities |= V4L2_CAP_TUNER; | ||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | ||
1154 | struct v4l2_fmtdesc *f) | ||
1155 | { | ||
1156 | if (unlikely(f->index >= ARRAY_SIZE(formats))) | ||
1157 | return -EINVAL; | ||
1158 | |||
1159 | strlcpy(f->description, formats[f->index].name, sizeof(f->description)); | ||
1160 | f->pixelformat = formats[f->index].fourcc; | ||
1161 | |||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | int cx25821_vidioc_reqbufs(struct file *file, void *priv, | ||
1166 | struct v4l2_requestbuffers *p) | ||
1167 | { | ||
1168 | struct cx25821_fh *fh = priv; | ||
1169 | return videobuf_reqbufs(get_queue(fh), p); | ||
1170 | } | ||
1171 | |||
1172 | int cx25821_vidioc_querybuf(struct file *file, void *priv, | ||
1173 | struct v4l2_buffer *p) | ||
1174 | { | ||
1175 | struct cx25821_fh *fh = priv; | ||
1176 | return videobuf_querybuf(get_queue(fh), p); | ||
1177 | } | ||
1178 | |||
1179 | int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) | ||
1180 | { | ||
1181 | struct cx25821_fh *fh = priv; | ||
1182 | return videobuf_qbuf(get_queue(fh), p); | ||
1183 | } | ||
1184 | |||
1185 | int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) | ||
1186 | { | ||
1187 | struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; | ||
1188 | struct cx25821_fh *fh = f; | ||
1189 | |||
1190 | *p = v4l2_prio_max(&dev->channels[fh->channel_id].prio); | ||
1191 | |||
1192 | return 0; | ||
1193 | } | ||
1194 | |||
1195 | int cx25821_vidioc_s_priority(struct file *file, void *f, | ||
1196 | enum v4l2_priority prio) | ||
1197 | { | ||
1198 | struct cx25821_fh *fh = f; | ||
1199 | struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; | ||
1200 | |||
1201 | return v4l2_prio_change(&dev->channels[fh->channel_id].prio, &fh->prio, | ||
1202 | prio); | ||
1203 | } | ||
1204 | |||
1205 | #ifdef TUNER_FLAG | ||
1206 | int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms) | ||
1207 | { | ||
1208 | struct cx25821_fh *fh = priv; | ||
1209 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1210 | int err; | ||
1211 | |||
1212 | dprintk(1, "%s()\n", __func__); | ||
1213 | |||
1214 | if (fh) { | ||
1215 | err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, | ||
1216 | fh->prio); | ||
1217 | if (0 != err) | ||
1218 | return err; | ||
1219 | } | ||
1220 | |||
1221 | if (dev->tvnorm == *tvnorms) | ||
1222 | return 0; | ||
1223 | |||
1224 | mutex_lock(&dev->lock); | ||
1225 | cx25821_set_tvnorm(dev, *tvnorms); | ||
1226 | mutex_unlock(&dev->lock); | ||
1227 | |||
1228 | medusa_set_videostandard(dev); | ||
1229 | |||
1230 | return 0; | ||
1231 | } | ||
1232 | #endif | ||
1233 | |||
1234 | int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i) | ||
1235 | { | ||
1236 | static const char * const iname[] = { | ||
1237 | [CX25821_VMUX_COMPOSITE] = "Composite", | ||
1238 | [CX25821_VMUX_SVIDEO] = "S-Video", | ||
1239 | [CX25821_VMUX_DEBUG] = "for debug only", | ||
1240 | }; | ||
1241 | unsigned int n; | ||
1242 | dprintk(1, "%s()\n", __func__); | ||
1243 | |||
1244 | n = i->index; | ||
1245 | if (n >= 2) | ||
1246 | return -EINVAL; | ||
1247 | |||
1248 | if (0 == INPUT(n)->type) | ||
1249 | return -EINVAL; | ||
1250 | |||
1251 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
1252 | strcpy(i->name, iname[INPUT(n)->type]); | ||
1253 | |||
1254 | i->std = CX25821_NORMS; | ||
1255 | return 0; | ||
1256 | } | ||
1257 | |||
1258 | int cx25821_vidioc_enum_input(struct file *file, void *priv, | ||
1259 | struct v4l2_input *i) | ||
1260 | { | ||
1261 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1262 | dprintk(1, "%s()\n", __func__); | ||
1263 | return cx25821_enum_input(dev, i); | ||
1264 | } | ||
1265 | |||
1266 | int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i) | ||
1267 | { | ||
1268 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1269 | |||
1270 | *i = dev->input; | ||
1271 | dprintk(1, "%s(): returns %d\n", __func__, *i); | ||
1272 | return 0; | ||
1273 | } | ||
1274 | |||
1275 | int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
1276 | { | ||
1277 | struct cx25821_fh *fh = priv; | ||
1278 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1279 | int err; | ||
1280 | |||
1281 | dprintk(1, "%s(%d)\n", __func__, i); | ||
1282 | |||
1283 | if (fh) { | ||
1284 | err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, | ||
1285 | fh->prio); | ||
1286 | if (0 != err) | ||
1287 | return err; | ||
1288 | } | ||
1289 | |||
1290 | if (i >= CX25821_NR_INPUT) { | ||
1291 | dprintk(1, "%s(): -EINVAL\n", __func__); | ||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | |||
1295 | mutex_lock(&dev->lock); | ||
1296 | cx25821_video_mux(dev, i); | ||
1297 | mutex_unlock(&dev->lock); | ||
1298 | return 0; | ||
1299 | } | ||
1300 | |||
1301 | #ifdef TUNER_FLAG | ||
1302 | int cx25821_vidioc_g_frequency(struct file *file, void *priv, | ||
1303 | struct v4l2_frequency *f) | ||
1304 | { | ||
1305 | struct cx25821_fh *fh = priv; | ||
1306 | struct cx25821_dev *dev = fh->dev; | ||
1307 | |||
1308 | f->frequency = dev->freq; | ||
1309 | |||
1310 | cx25821_call_all(dev, tuner, g_frequency, f); | ||
1311 | |||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f) | ||
1316 | { | ||
1317 | mutex_lock(&dev->lock); | ||
1318 | dev->freq = f->frequency; | ||
1319 | |||
1320 | cx25821_call_all(dev, tuner, s_frequency, f); | ||
1321 | |||
1322 | /* When changing channels it is required to reset TVAUDIO */ | ||
1323 | msleep(10); | ||
1324 | |||
1325 | mutex_unlock(&dev->lock); | ||
1326 | |||
1327 | return 0; | ||
1328 | } | ||
1329 | |||
1330 | int cx25821_vidioc_s_frequency(struct file *file, void *priv, | ||
1331 | struct v4l2_frequency *f) | ||
1332 | { | ||
1333 | struct cx25821_fh *fh = priv; | ||
1334 | struct cx25821_dev *dev; | ||
1335 | int err; | ||
1336 | |||
1337 | if (fh) { | ||
1338 | dev = fh->dev; | ||
1339 | err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, | ||
1340 | fh->prio); | ||
1341 | if (0 != err) | ||
1342 | return err; | ||
1343 | } else { | ||
1344 | pr_err("Invalid fh pointer!\n"); | ||
1345 | return -EINVAL; | ||
1346 | } | ||
1347 | |||
1348 | return cx25821_set_freq(dev, f); | ||
1349 | } | ||
1350 | #endif | ||
1351 | |||
1352 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1353 | int cx25821_vidioc_g_register(struct file *file, void *fh, | ||
1354 | struct v4l2_dbg_register *reg) | ||
1355 | { | ||
1356 | struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev; | ||
1357 | |||
1358 | if (!v4l2_chip_match_host(®->match)) | ||
1359 | return -EINVAL; | ||
1360 | |||
1361 | cx25821_call_all(dev, core, g_register, reg); | ||
1362 | |||
1363 | return 0; | ||
1364 | } | ||
1365 | |||
1366 | int cx25821_vidioc_s_register(struct file *file, void *fh, | ||
1367 | struct v4l2_dbg_register *reg) | ||
1368 | { | ||
1369 | struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev; | ||
1370 | |||
1371 | if (!v4l2_chip_match_host(®->match)) | ||
1372 | return -EINVAL; | ||
1373 | |||
1374 | cx25821_call_all(dev, core, s_register, reg); | ||
1375 | |||
1376 | return 0; | ||
1377 | } | ||
1378 | |||
1379 | #endif | ||
1380 | |||
1381 | #ifdef TUNER_FLAG | ||
1382 | int cx25821_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | ||
1383 | { | ||
1384 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1385 | |||
1386 | if (unlikely(UNSET == dev->tuner_type)) | ||
1387 | return -EINVAL; | ||
1388 | if (0 != t->index) | ||
1389 | return -EINVAL; | ||
1390 | |||
1391 | strcpy(t->name, "Television"); | ||
1392 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1393 | t->capability = V4L2_TUNER_CAP_NORM; | ||
1394 | t->rangehigh = 0xffffffffUL; | ||
1395 | |||
1396 | t->signal = 0xffff; /* LOCKED */ | ||
1397 | return 0; | ||
1398 | } | ||
1399 | |||
1400 | int cx25821_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | ||
1401 | { | ||
1402 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1403 | struct cx25821_fh *fh = priv; | ||
1404 | int err; | ||
1405 | |||
1406 | if (fh) { | ||
1407 | err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, | ||
1408 | fh->prio); | ||
1409 | if (0 != err) | ||
1410 | return err; | ||
1411 | } | ||
1412 | |||
1413 | dprintk(1, "%s()\n", __func__); | ||
1414 | if (UNSET == dev->tuner_type) | ||
1415 | return -EINVAL; | ||
1416 | if (0 != t->index) | ||
1417 | return -EINVAL; | ||
1418 | |||
1419 | return 0; | ||
1420 | } | ||
1421 | |||
1422 | #endif | ||
1423 | /*****************************************************************************/ | ||
1424 | static const struct v4l2_queryctrl no_ctl = { | ||
1425 | .name = "42", | ||
1426 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
1427 | }; | ||
1428 | |||
1429 | static struct v4l2_queryctrl cx25821_ctls[] = { | ||
1430 | /* --- video --- */ | ||
1431 | { | ||
1432 | .id = V4L2_CID_BRIGHTNESS, | ||
1433 | .name = "Brightness", | ||
1434 | .minimum = 0, | ||
1435 | .maximum = 10000, | ||
1436 | .step = 1, | ||
1437 | .default_value = 6200, | ||
1438 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1439 | }, { | ||
1440 | .id = V4L2_CID_CONTRAST, | ||
1441 | .name = "Contrast", | ||
1442 | .minimum = 0, | ||
1443 | .maximum = 10000, | ||
1444 | .step = 1, | ||
1445 | .default_value = 5000, | ||
1446 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1447 | }, { | ||
1448 | .id = V4L2_CID_SATURATION, | ||
1449 | .name = "Saturation", | ||
1450 | .minimum = 0, | ||
1451 | .maximum = 10000, | ||
1452 | .step = 1, | ||
1453 | .default_value = 5000, | ||
1454 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1455 | }, { | ||
1456 | .id = V4L2_CID_HUE, | ||
1457 | .name = "Hue", | ||
1458 | .minimum = 0, | ||
1459 | .maximum = 10000, | ||
1460 | .step = 1, | ||
1461 | .default_value = 5000, | ||
1462 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1463 | } | ||
1464 | }; | ||
1465 | static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls); | ||
1466 | |||
1467 | static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) | ||
1468 | { | ||
1469 | int i; | ||
1470 | |||
1471 | if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1) | ||
1472 | return -EINVAL; | ||
1473 | for (i = 0; i < CX25821_CTLS; i++) | ||
1474 | if (cx25821_ctls[i].id == qctrl->id) | ||
1475 | break; | ||
1476 | if (i == CX25821_CTLS) { | ||
1477 | *qctrl = no_ctl; | ||
1478 | return 0; | ||
1479 | } | ||
1480 | *qctrl = cx25821_ctls[i]; | ||
1481 | return 0; | ||
1482 | } | ||
1483 | |||
1484 | int cx25821_vidioc_queryctrl(struct file *file, void *priv, | ||
1485 | struct v4l2_queryctrl *qctrl) | ||
1486 | { | ||
1487 | return cx25821_ctrl_query(qctrl); | ||
1488 | } | ||
1489 | |||
1490 | /* ------------------------------------------------------------------ */ | ||
1491 | /* VIDEO CTRL IOCTLS */ | ||
1492 | |||
1493 | static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id) | ||
1494 | { | ||
1495 | unsigned int i; | ||
1496 | |||
1497 | for (i = 0; i < CX25821_CTLS; i++) | ||
1498 | if (cx25821_ctls[i].id == id) | ||
1499 | return cx25821_ctls + i; | ||
1500 | return NULL; | ||
1501 | } | ||
1502 | |||
1503 | int cx25821_vidioc_g_ctrl(struct file *file, void *priv, | ||
1504 | struct v4l2_control *ctl) | ||
1505 | { | ||
1506 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1507 | struct cx25821_fh *fh = priv; | ||
1508 | |||
1509 | const struct v4l2_queryctrl *ctrl; | ||
1510 | |||
1511 | ctrl = ctrl_by_id(ctl->id); | ||
1512 | |||
1513 | if (NULL == ctrl) | ||
1514 | return -EINVAL; | ||
1515 | switch (ctl->id) { | ||
1516 | case V4L2_CID_BRIGHTNESS: | ||
1517 | ctl->value = dev->channels[fh->channel_id].ctl_bright; | ||
1518 | break; | ||
1519 | case V4L2_CID_HUE: | ||
1520 | ctl->value = dev->channels[fh->channel_id].ctl_hue; | ||
1521 | break; | ||
1522 | case V4L2_CID_CONTRAST: | ||
1523 | ctl->value = dev->channels[fh->channel_id].ctl_contrast; | ||
1524 | break; | ||
1525 | case V4L2_CID_SATURATION: | ||
1526 | ctl->value = dev->channels[fh->channel_id].ctl_saturation; | ||
1527 | break; | ||
1528 | } | ||
1529 | return 0; | ||
1530 | } | ||
1531 | |||
1532 | int cx25821_set_control(struct cx25821_dev *dev, | ||
1533 | struct v4l2_control *ctl, int chan_num) | ||
1534 | { | ||
1535 | int err; | ||
1536 | const struct v4l2_queryctrl *ctrl; | ||
1537 | |||
1538 | err = -EINVAL; | ||
1539 | |||
1540 | ctrl = ctrl_by_id(ctl->id); | ||
1541 | |||
1542 | if (NULL == ctrl) | ||
1543 | return err; | ||
1544 | |||
1545 | switch (ctrl->type) { | ||
1546 | case V4L2_CTRL_TYPE_BOOLEAN: | ||
1547 | case V4L2_CTRL_TYPE_MENU: | ||
1548 | case V4L2_CTRL_TYPE_INTEGER: | ||
1549 | if (ctl->value < ctrl->minimum) | ||
1550 | ctl->value = ctrl->minimum; | ||
1551 | if (ctl->value > ctrl->maximum) | ||
1552 | ctl->value = ctrl->maximum; | ||
1553 | break; | ||
1554 | default: | ||
1555 | /* nothing */ ; | ||
1556 | } | ||
1557 | |||
1558 | switch (ctl->id) { | ||
1559 | case V4L2_CID_BRIGHTNESS: | ||
1560 | dev->channels[chan_num].ctl_bright = ctl->value; | ||
1561 | medusa_set_brightness(dev, ctl->value, chan_num); | ||
1562 | break; | ||
1563 | case V4L2_CID_HUE: | ||
1564 | dev->channels[chan_num].ctl_hue = ctl->value; | ||
1565 | medusa_set_hue(dev, ctl->value, chan_num); | ||
1566 | break; | ||
1567 | case V4L2_CID_CONTRAST: | ||
1568 | dev->channels[chan_num].ctl_contrast = ctl->value; | ||
1569 | medusa_set_contrast(dev, ctl->value, chan_num); | ||
1570 | break; | ||
1571 | case V4L2_CID_SATURATION: | ||
1572 | dev->channels[chan_num].ctl_saturation = ctl->value; | ||
1573 | medusa_set_saturation(dev, ctl->value, chan_num); | ||
1574 | break; | ||
1575 | } | ||
1576 | |||
1577 | err = 0; | ||
1578 | |||
1579 | return err; | ||
1580 | } | ||
1581 | |||
1582 | static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num) | ||
1583 | { | ||
1584 | struct v4l2_control ctrl; | ||
1585 | int i; | ||
1586 | for (i = 0; i < CX25821_CTLS; i++) { | ||
1587 | ctrl.id = cx25821_ctls[i].id; | ||
1588 | ctrl.value = cx25821_ctls[i].default_value; | ||
1589 | |||
1590 | cx25821_set_control(dev, &ctrl, chan_num); | ||
1591 | } | ||
1592 | } | ||
1593 | |||
1594 | int cx25821_vidioc_cropcap(struct file *file, void *priv, | ||
1595 | struct v4l2_cropcap *cropcap) | ||
1596 | { | ||
1597 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1598 | |||
1599 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1600 | return -EINVAL; | ||
1601 | cropcap->bounds.top = 0; | ||
1602 | cropcap->bounds.left = 0; | ||
1603 | cropcap->bounds.width = 720; | ||
1604 | cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480; | ||
1605 | cropcap->pixelaspect.numerator = | ||
1606 | dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10; | ||
1607 | cropcap->pixelaspect.denominator = | ||
1608 | dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11; | ||
1609 | cropcap->defrect = cropcap->bounds; | ||
1610 | return 0; | ||
1611 | } | ||
1612 | |||
1613 | int cx25821_vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop) | ||
1614 | { | ||
1615 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1616 | struct cx25821_fh *fh = priv; | ||
1617 | int err; | ||
1618 | |||
1619 | if (fh) { | ||
1620 | err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, | ||
1621 | fh->prio); | ||
1622 | if (0 != err) | ||
1623 | return err; | ||
1624 | } | ||
1625 | /* cx25821_vidioc_s_crop not supported */ | ||
1626 | return -EINVAL; | ||
1627 | } | ||
1628 | |||
1629 | int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) | ||
1630 | { | ||
1631 | /* cx25821_vidioc_g_crop not supported */ | ||
1632 | return -EINVAL; | ||
1633 | } | ||
1634 | |||
1635 | int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm) | ||
1636 | { | ||
1637 | /* medusa does not support video standard sensing of current input */ | ||
1638 | *norm = CX25821_NORMS; | ||
1639 | |||
1640 | return 0; | ||
1641 | } | ||
1642 | |||
1643 | int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) | ||
1644 | { | ||
1645 | if (tvnorm == V4L2_STD_PAL_BG) { | ||
1646 | if (width == 352 || width == 720) | ||
1647 | return 1; | ||
1648 | else | ||
1649 | return 0; | ||
1650 | } | ||
1651 | |||
1652 | if (tvnorm == V4L2_STD_NTSC_M) { | ||
1653 | if (width == 320 || width == 352 || width == 720) | ||
1654 | return 1; | ||
1655 | else | ||
1656 | return 0; | ||
1657 | } | ||
1658 | return 0; | ||
1659 | } | ||
1660 | |||
1661 | int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm) | ||
1662 | { | ||
1663 | if (tvnorm == V4L2_STD_PAL_BG) { | ||
1664 | if (height == 576 || height == 288) | ||
1665 | return 1; | ||
1666 | else | ||
1667 | return 0; | ||
1668 | } | ||
1669 | |||
1670 | if (tvnorm == V4L2_STD_NTSC_M) { | ||
1671 | if (height == 480 || height == 240) | ||
1672 | return 1; | ||
1673 | else | ||
1674 | return 0; | ||
1675 | } | ||
1676 | |||
1677 | return 0; | ||
1678 | } | ||
1679 | |||
1680 | static long video_ioctl_upstream9(struct file *file, unsigned int cmd, | ||
1681 | unsigned long arg) | ||
1682 | { | ||
1683 | struct cx25821_fh *fh = file->private_data; | ||
1684 | struct cx25821_dev *dev = fh->dev; | ||
1685 | int command = 0; | ||
1686 | struct upstream_user_struct *data_from_user; | ||
1687 | |||
1688 | data_from_user = (struct upstream_user_struct *)arg; | ||
1689 | |||
1690 | if (!data_from_user) { | ||
1691 | pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); | ||
1692 | return 0; | ||
1693 | } | ||
1694 | |||
1695 | command = data_from_user->command; | ||
1696 | |||
1697 | if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) | ||
1698 | return 0; | ||
1699 | |||
1700 | dev->input_filename = data_from_user->input_filename; | ||
1701 | dev->input_audiofilename = data_from_user->input_filename; | ||
1702 | dev->vid_stdname = data_from_user->vid_stdname; | ||
1703 | dev->pixel_format = data_from_user->pixel_format; | ||
1704 | dev->channel_select = data_from_user->channel_select; | ||
1705 | dev->command = data_from_user->command; | ||
1706 | |||
1707 | switch (command) { | ||
1708 | case UPSTREAM_START_VIDEO: | ||
1709 | cx25821_start_upstream_video_ch1(dev, data_from_user); | ||
1710 | break; | ||
1711 | |||
1712 | case UPSTREAM_STOP_VIDEO: | ||
1713 | cx25821_stop_upstream_video_ch1(dev); | ||
1714 | break; | ||
1715 | } | ||
1716 | |||
1717 | return 0; | ||
1718 | } | ||
1719 | |||
1720 | static long video_ioctl_upstream10(struct file *file, unsigned int cmd, | ||
1721 | unsigned long arg) | ||
1722 | { | ||
1723 | struct cx25821_fh *fh = file->private_data; | ||
1724 | struct cx25821_dev *dev = fh->dev; | ||
1725 | int command = 0; | ||
1726 | struct upstream_user_struct *data_from_user; | ||
1727 | |||
1728 | data_from_user = (struct upstream_user_struct *)arg; | ||
1729 | |||
1730 | if (!data_from_user) { | ||
1731 | pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); | ||
1732 | return 0; | ||
1733 | } | ||
1734 | |||
1735 | command = data_from_user->command; | ||
1736 | |||
1737 | if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) | ||
1738 | return 0; | ||
1739 | |||
1740 | dev->input_filename_ch2 = data_from_user->input_filename; | ||
1741 | dev->input_audiofilename = data_from_user->input_filename; | ||
1742 | dev->vid_stdname_ch2 = data_from_user->vid_stdname; | ||
1743 | dev->pixel_format_ch2 = data_from_user->pixel_format; | ||
1744 | dev->channel_select_ch2 = data_from_user->channel_select; | ||
1745 | dev->command_ch2 = data_from_user->command; | ||
1746 | |||
1747 | switch (command) { | ||
1748 | case UPSTREAM_START_VIDEO: | ||
1749 | cx25821_start_upstream_video_ch2(dev, data_from_user); | ||
1750 | break; | ||
1751 | |||
1752 | case UPSTREAM_STOP_VIDEO: | ||
1753 | cx25821_stop_upstream_video_ch2(dev); | ||
1754 | break; | ||
1755 | } | ||
1756 | |||
1757 | return 0; | ||
1758 | } | ||
1759 | |||
1760 | static long video_ioctl_upstream11(struct file *file, unsigned int cmd, | ||
1761 | unsigned long arg) | ||
1762 | { | ||
1763 | struct cx25821_fh *fh = file->private_data; | ||
1764 | struct cx25821_dev *dev = fh->dev; | ||
1765 | int command = 0; | ||
1766 | struct upstream_user_struct *data_from_user; | ||
1767 | |||
1768 | data_from_user = (struct upstream_user_struct *)arg; | ||
1769 | |||
1770 | if (!data_from_user) { | ||
1771 | pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); | ||
1772 | return 0; | ||
1773 | } | ||
1774 | |||
1775 | command = data_from_user->command; | ||
1776 | |||
1777 | if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) | ||
1778 | return 0; | ||
1779 | |||
1780 | dev->input_filename = data_from_user->input_filename; | ||
1781 | dev->input_audiofilename = data_from_user->input_filename; | ||
1782 | dev->vid_stdname = data_from_user->vid_stdname; | ||
1783 | dev->pixel_format = data_from_user->pixel_format; | ||
1784 | dev->channel_select = data_from_user->channel_select; | ||
1785 | dev->command = data_from_user->command; | ||
1786 | |||
1787 | switch (command) { | ||
1788 | case UPSTREAM_START_AUDIO: | ||
1789 | cx25821_start_upstream_audio(dev, data_from_user); | ||
1790 | break; | ||
1791 | |||
1792 | case UPSTREAM_STOP_AUDIO: | ||
1793 | cx25821_stop_upstream_audio(dev); | ||
1794 | break; | ||
1795 | } | ||
1796 | |||
1797 | return 0; | ||
1798 | } | ||
1799 | |||
1800 | static long video_ioctl_set(struct file *file, unsigned int cmd, | ||
1801 | unsigned long arg) | ||
1802 | { | ||
1803 | struct cx25821_fh *fh = file->private_data; | ||
1804 | struct cx25821_dev *dev = fh->dev; | ||
1805 | struct downstream_user_struct *data_from_user; | ||
1806 | int command; | ||
1807 | int width = 720; | ||
1808 | int selected_channel = 0; | ||
1809 | int pix_format = 0; | ||
1810 | int i = 0; | ||
1811 | int cif_enable = 0; | ||
1812 | int cif_width = 0; | ||
1813 | |||
1814 | data_from_user = (struct downstream_user_struct *)arg; | ||
1815 | |||
1816 | if (!data_from_user) { | ||
1817 | pr_err("%s(): User data is INVALID. Returning\n", __func__); | ||
1818 | return 0; | ||
1819 | } | ||
1820 | |||
1821 | command = data_from_user->command; | ||
1822 | |||
1823 | if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT | ||
1824 | && command != ENABLE_CIF_RESOLUTION && command != REG_READ | ||
1825 | && command != REG_WRITE && command != MEDUSA_READ | ||
1826 | && command != MEDUSA_WRITE) { | ||
1827 | return 0; | ||
1828 | } | ||
1829 | |||
1830 | switch (command) { | ||
1831 | case SET_VIDEO_STD: | ||
1832 | if (!strcmp(data_from_user->vid_stdname, "PAL")) | ||
1833 | dev->tvnorm = V4L2_STD_PAL_BG; | ||
1834 | else | ||
1835 | dev->tvnorm = V4L2_STD_NTSC_M; | ||
1836 | medusa_set_videostandard(dev); | ||
1837 | break; | ||
1838 | |||
1839 | case SET_PIXEL_FORMAT: | ||
1840 | selected_channel = data_from_user->decoder_select; | ||
1841 | pix_format = data_from_user->pixel_format; | ||
1842 | |||
1843 | if (!(selected_channel <= 7 && selected_channel >= 0)) { | ||
1844 | selected_channel -= 4; | ||
1845 | selected_channel = selected_channel % 8; | ||
1846 | } | ||
1847 | |||
1848 | if (selected_channel >= 0) | ||
1849 | cx25821_set_pixel_format(dev, selected_channel, | ||
1850 | pix_format); | ||
1851 | |||
1852 | break; | ||
1853 | |||
1854 | case ENABLE_CIF_RESOLUTION: | ||
1855 | selected_channel = data_from_user->decoder_select; | ||
1856 | cif_enable = data_from_user->cif_resolution_enable; | ||
1857 | cif_width = data_from_user->cif_width; | ||
1858 | |||
1859 | if (cif_enable) { | ||
1860 | if (dev->tvnorm & V4L2_STD_PAL_BG | ||
1861 | || dev->tvnorm & V4L2_STD_PAL_DK) { | ||
1862 | width = 352; | ||
1863 | } else { | ||
1864 | width = cif_width; | ||
1865 | if (cif_width != 320 && cif_width != 352) | ||
1866 | width = 320; | ||
1867 | } | ||
1868 | } | ||
1869 | |||
1870 | if (!(selected_channel <= 7 && selected_channel >= 0)) { | ||
1871 | selected_channel -= 4; | ||
1872 | selected_channel = selected_channel % 8; | ||
1873 | } | ||
1874 | |||
1875 | if (selected_channel <= 7 && selected_channel >= 0) { | ||
1876 | dev->channels[selected_channel].use_cif_resolution = | ||
1877 | cif_enable; | ||
1878 | dev->channels[selected_channel].cif_width = width; | ||
1879 | } else { | ||
1880 | for (i = 0; i < VID_CHANNEL_NUM; i++) { | ||
1881 | dev->channels[i].use_cif_resolution = | ||
1882 | cif_enable; | ||
1883 | dev->channels[i].cif_width = width; | ||
1884 | } | ||
1885 | } | ||
1886 | |||
1887 | medusa_set_resolution(dev, width, selected_channel); | ||
1888 | break; | ||
1889 | case REG_READ: | ||
1890 | data_from_user->reg_data = cx_read(data_from_user->reg_address); | ||
1891 | break; | ||
1892 | case REG_WRITE: | ||
1893 | cx_write(data_from_user->reg_address, data_from_user->reg_data); | ||
1894 | break; | ||
1895 | case MEDUSA_READ: | ||
1896 | cx25821_i2c_read(&dev->i2c_bus[0], | ||
1897 | (u16) data_from_user->reg_address, | ||
1898 | &data_from_user->reg_data); | ||
1899 | break; | ||
1900 | case MEDUSA_WRITE: | ||
1901 | cx25821_i2c_write(&dev->i2c_bus[0], | ||
1902 | (u16) data_from_user->reg_address, | ||
1903 | data_from_user->reg_data); | ||
1904 | break; | ||
1905 | } | ||
1906 | |||
1907 | return 0; | ||
1908 | } | ||
1909 | |||
1910 | static long cx25821_video_ioctl(struct file *file, | ||
1911 | unsigned int cmd, unsigned long arg) | ||
1912 | { | ||
1913 | int ret = 0; | ||
1914 | |||
1915 | struct cx25821_fh *fh = file->private_data; | ||
1916 | |||
1917 | /* check to see if it's the video upstream */ | ||
1918 | if (fh->channel_id == SRAM_CH09) { | ||
1919 | ret = video_ioctl_upstream9(file, cmd, arg); | ||
1920 | return ret; | ||
1921 | } else if (fh->channel_id == SRAM_CH10) { | ||
1922 | ret = video_ioctl_upstream10(file, cmd, arg); | ||
1923 | return ret; | ||
1924 | } else if (fh->channel_id == SRAM_CH11) { | ||
1925 | ret = video_ioctl_upstream11(file, cmd, arg); | ||
1926 | ret = video_ioctl_set(file, cmd, arg); | ||
1927 | return ret; | ||
1928 | } | ||
1929 | |||
1930 | return video_ioctl2(file, cmd, arg); | ||
1931 | } | ||
1932 | |||
1933 | /* exported stuff */ | ||
1934 | static const struct v4l2_file_operations video_fops = { | ||
1935 | .owner = THIS_MODULE, | ||
1936 | .open = video_open, | ||
1937 | .release = video_release, | ||
1938 | .read = video_read, | ||
1939 | .poll = video_poll, | ||
1940 | .mmap = cx25821_video_mmap, | ||
1941 | .ioctl = cx25821_video_ioctl, | ||
1942 | }; | ||
1943 | |||
1944 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | ||
1945 | .vidioc_querycap = cx25821_vidioc_querycap, | ||
1946 | .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap, | ||
1947 | .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap, | ||
1948 | .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap, | ||
1949 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
1950 | .vidioc_reqbufs = cx25821_vidioc_reqbufs, | ||
1951 | .vidioc_querybuf = cx25821_vidioc_querybuf, | ||
1952 | .vidioc_qbuf = cx25821_vidioc_qbuf, | ||
1953 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1954 | #ifdef TUNER_FLAG | ||
1955 | .vidioc_s_std = cx25821_vidioc_s_std, | ||
1956 | .vidioc_querystd = cx25821_vidioc_querystd, | ||
1957 | #endif | ||
1958 | .vidioc_cropcap = cx25821_vidioc_cropcap, | ||
1959 | .vidioc_s_crop = cx25821_vidioc_s_crop, | ||
1960 | .vidioc_g_crop = cx25821_vidioc_g_crop, | ||
1961 | .vidioc_enum_input = cx25821_vidioc_enum_input, | ||
1962 | .vidioc_g_input = cx25821_vidioc_g_input, | ||
1963 | .vidioc_s_input = cx25821_vidioc_s_input, | ||
1964 | .vidioc_g_ctrl = cx25821_vidioc_g_ctrl, | ||
1965 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1966 | .vidioc_queryctrl = cx25821_vidioc_queryctrl, | ||
1967 | .vidioc_streamon = vidioc_streamon, | ||
1968 | .vidioc_streamoff = vidioc_streamoff, | ||
1969 | .vidioc_log_status = vidioc_log_status, | ||
1970 | .vidioc_g_priority = cx25821_vidioc_g_priority, | ||
1971 | .vidioc_s_priority = cx25821_vidioc_s_priority, | ||
1972 | #ifdef TUNER_FLAG | ||
1973 | .vidioc_g_tuner = cx25821_vidioc_g_tuner, | ||
1974 | .vidioc_s_tuner = cx25821_vidioc_s_tuner, | ||
1975 | .vidioc_g_frequency = cx25821_vidioc_g_frequency, | ||
1976 | .vidioc_s_frequency = cx25821_vidioc_s_frequency, | ||
1977 | #endif | ||
1978 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1979 | .vidioc_g_register = cx25821_vidioc_g_register, | ||
1980 | .vidioc_s_register = cx25821_vidioc_s_register, | ||
1981 | #endif | ||
1982 | }; | ||
1983 | |||
1984 | struct video_device cx25821_videoioctl_template = { | ||
1985 | .name = "cx25821-videoioctl", | ||
1986 | .fops = &video_fops, | ||
1987 | .ioctl_ops = &video_ioctl_ops, | ||
1988 | .tvnorms = CX25821_NORMS, | ||
1989 | .current_norm = V4L2_STD_NTSC_M, | ||
1990 | }; | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h new file mode 100644 index 000000000000..9652a5e35ba2 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821-video.h | |||
@@ -0,0 +1,186 @@ | |||
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 | #define TUNER_FLAG | ||
44 | |||
45 | #define VIDEO_DEBUG 0 | ||
46 | |||
47 | #define dprintk(level, fmt, arg...) \ | ||
48 | do { \ | ||
49 | if (VIDEO_DEBUG >= level) \ | ||
50 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \ | ||
51 | } while (0) | ||
52 | |||
53 | /* For IOCTL to identify running upstream */ | ||
54 | #define UPSTREAM_START_VIDEO 700 | ||
55 | #define UPSTREAM_STOP_VIDEO 701 | ||
56 | #define UPSTREAM_START_AUDIO 702 | ||
57 | #define UPSTREAM_STOP_AUDIO 703 | ||
58 | #define UPSTREAM_DUMP_REGISTERS 702 | ||
59 | #define SET_VIDEO_STD 800 | ||
60 | #define SET_PIXEL_FORMAT 1000 | ||
61 | #define ENABLE_CIF_RESOLUTION 1001 | ||
62 | |||
63 | #define REG_READ 900 | ||
64 | #define REG_WRITE 901 | ||
65 | #define MEDUSA_READ 910 | ||
66 | #define MEDUSA_WRITE 911 | ||
67 | |||
68 | extern struct sram_channel *channel0; | ||
69 | extern struct sram_channel *channel1; | ||
70 | extern struct sram_channel *channel2; | ||
71 | extern struct sram_channel *channel3; | ||
72 | extern struct sram_channel *channel4; | ||
73 | extern struct sram_channel *channel5; | ||
74 | extern struct sram_channel *channel6; | ||
75 | extern struct sram_channel *channel7; | ||
76 | extern struct sram_channel *channel9; | ||
77 | extern struct sram_channel *channel10; | ||
78 | extern struct sram_channel *channel11; | ||
79 | extern struct video_device cx25821_videoioctl_template; | ||
80 | /* extern const u32 *ctrl_classes[]; */ | ||
81 | |||
82 | extern unsigned int vid_limit; | ||
83 | |||
84 | #define FORMAT_FLAGS_PACKED 0x01 | ||
85 | extern struct cx25821_fmt formats[]; | ||
86 | extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc); | ||
87 | extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; | ||
88 | |||
89 | extern void cx25821_video_wakeup(struct cx25821_dev *dev, | ||
90 | struct cx25821_dmaqueue *q, u32 count); | ||
91 | |||
92 | #ifdef TUNER_FLAG | ||
93 | extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm); | ||
94 | #endif | ||
95 | |||
96 | extern int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, | ||
97 | unsigned int bit); | ||
98 | extern int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit); | ||
99 | extern int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit); | ||
100 | extern void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, | ||
101 | unsigned int bits); | ||
102 | extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input); | ||
103 | extern int cx25821_start_video_dma(struct cx25821_dev *dev, | ||
104 | struct cx25821_dmaqueue *q, | ||
105 | struct cx25821_buffer *buf, | ||
106 | struct sram_channel *channel); | ||
107 | |||
108 | extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width, | ||
109 | unsigned int height, enum v4l2_field field); | ||
110 | extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status); | ||
111 | extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num); | ||
112 | extern int cx25821_video_register(struct cx25821_dev *dev); | ||
113 | extern int cx25821_get_format_size(void); | ||
114 | |||
115 | extern int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, | ||
116 | unsigned int *size); | ||
117 | extern int cx25821_buffer_prepare(struct videobuf_queue *q, | ||
118 | struct videobuf_buffer *vb, | ||
119 | enum v4l2_field field); | ||
120 | extern void cx25821_buffer_release(struct videobuf_queue *q, | ||
121 | struct videobuf_buffer *vb); | ||
122 | extern struct videobuf_queue *get_queue(struct cx25821_fh *fh); | ||
123 | extern int cx25821_get_resource(struct cx25821_fh *fh, int resource); | ||
124 | extern int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma); | ||
125 | extern int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, | ||
126 | struct v4l2_format *f); | ||
127 | extern int cx25821_vidioc_querycap(struct file *file, void *priv, | ||
128 | struct v4l2_capability *cap); | ||
129 | extern int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | ||
130 | struct v4l2_fmtdesc *f); | ||
131 | extern int cx25821_vidioc_reqbufs(struct file *file, void *priv, | ||
132 | struct v4l2_requestbuffers *p); | ||
133 | extern int cx25821_vidioc_querybuf(struct file *file, void *priv, | ||
134 | struct v4l2_buffer *p); | ||
135 | extern int cx25821_vidioc_qbuf(struct file *file, void *priv, | ||
136 | struct v4l2_buffer *p); | ||
137 | extern int cx25821_vidioc_s_std(struct file *file, void *priv, | ||
138 | v4l2_std_id *tvnorms); | ||
139 | extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i); | ||
140 | extern int cx25821_vidioc_enum_input(struct file *file, void *priv, | ||
141 | struct v4l2_input *i); | ||
142 | extern int cx25821_vidioc_g_input(struct file *file, void *priv, | ||
143 | unsigned int *i); | ||
144 | extern int cx25821_vidioc_s_input(struct file *file, void *priv, | ||
145 | unsigned int i); | ||
146 | extern int cx25821_vidioc_g_ctrl(struct file *file, void *priv, | ||
147 | struct v4l2_control *ctl); | ||
148 | extern int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
149 | struct v4l2_format *f); | ||
150 | extern int cx25821_vidioc_g_frequency(struct file *file, void *priv, | ||
151 | struct v4l2_frequency *f); | ||
152 | extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f); | ||
153 | extern int cx25821_vidioc_s_frequency(struct file *file, void *priv, | ||
154 | struct v4l2_frequency *f); | ||
155 | extern int cx25821_vidioc_g_register(struct file *file, void *fh, | ||
156 | struct v4l2_dbg_register *reg); | ||
157 | extern int cx25821_vidioc_s_register(struct file *file, void *fh, | ||
158 | struct v4l2_dbg_register *reg); | ||
159 | extern int cx25821_vidioc_g_tuner(struct file *file, void *priv, | ||
160 | struct v4l2_tuner *t); | ||
161 | extern int cx25821_vidioc_s_tuner(struct file *file, void *priv, | ||
162 | struct v4l2_tuner *t); | ||
163 | |||
164 | extern int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm); | ||
165 | extern int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm); | ||
166 | |||
167 | extern int cx25821_vidioc_g_priority(struct file *file, void *f, | ||
168 | enum v4l2_priority *p); | ||
169 | extern int cx25821_vidioc_s_priority(struct file *file, void *f, | ||
170 | enum v4l2_priority prio); | ||
171 | |||
172 | extern int cx25821_vidioc_queryctrl(struct file *file, void *priv, | ||
173 | struct v4l2_queryctrl *qctrl); | ||
174 | extern int cx25821_set_control(struct cx25821_dev *dev, | ||
175 | struct v4l2_control *ctrl, int chan_num); | ||
176 | |||
177 | extern int cx25821_vidioc_cropcap(struct file *file, void *fh, | ||
178 | struct v4l2_cropcap *cropcap); | ||
179 | extern int cx25821_vidioc_s_crop(struct file *file, void *priv, | ||
180 | struct v4l2_crop *crop); | ||
181 | extern int cx25821_vidioc_g_crop(struct file *file, void *priv, | ||
182 | struct v4l2_crop *crop); | ||
183 | |||
184 | extern int cx25821_vidioc_querystd(struct file *file, void *priv, | ||
185 | v4l2_std_id *norm); | ||
186 | #endif | ||
diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h new file mode 100644 index 000000000000..8a9c0c869412 --- /dev/null +++ b/drivers/media/pci/cx25821/cx25821.h | |||
@@ -0,0 +1,615 @@ | |||
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/interrupt.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/sched.h> | ||
32 | #include <linux/kdev_t.h> | ||
33 | |||
34 | #include <media/v4l2-common.h> | ||
35 | #include <media/v4l2-device.h> | ||
36 | #include <media/tuner.h> | ||
37 | #include <media/tveeprom.h> | ||
38 | #include <media/videobuf-dma-sg.h> | ||
39 | #include <media/videobuf-dvb.h> | ||
40 | |||
41 | #include "btcx-risc.h" | ||
42 | #include "cx25821-reg.h" | ||
43 | #include "cx25821-medusa-reg.h" | ||
44 | #include "cx25821-sram.h" | ||
45 | #include "cx25821-audio.h" | ||
46 | #include "media/cx2341x.h" | ||
47 | |||
48 | #include <linux/version.h> | ||
49 | #include <linux/mutex.h> | ||
50 | |||
51 | #define CX25821_VERSION_CODE KERNEL_VERSION(0, 0, 106) | ||
52 | |||
53 | #define UNSET (-1U) | ||
54 | #define NO_SYNC_LINE (-1U) | ||
55 | |||
56 | #define CX25821_MAXBOARDS 2 | ||
57 | |||
58 | #define TRUE 1 | ||
59 | #define FALSE 0 | ||
60 | #define LINE_SIZE_D1 1440 | ||
61 | |||
62 | /* Number of decoders and encoders */ | ||
63 | #define MAX_DECODERS 8 | ||
64 | #define MAX_ENCODERS 2 | ||
65 | #define QUAD_DECODERS 4 | ||
66 | #define MAX_CAMERAS 16 | ||
67 | |||
68 | /* Max number of inputs by card */ | ||
69 | #define MAX_CX25821_INPUT 8 | ||
70 | #define INPUT(nr) (&cx25821_boards[dev->board].input[nr]) | ||
71 | #define RESOURCE_VIDEO0 1 | ||
72 | #define RESOURCE_VIDEO1 2 | ||
73 | #define RESOURCE_VIDEO2 4 | ||
74 | #define RESOURCE_VIDEO3 8 | ||
75 | #define RESOURCE_VIDEO4 16 | ||
76 | #define RESOURCE_VIDEO5 32 | ||
77 | #define RESOURCE_VIDEO6 64 | ||
78 | #define RESOURCE_VIDEO7 128 | ||
79 | #define RESOURCE_VIDEO8 256 | ||
80 | #define RESOURCE_VIDEO9 512 | ||
81 | #define RESOURCE_VIDEO10 1024 | ||
82 | #define RESOURCE_VIDEO11 2048 | ||
83 | #define RESOURCE_VIDEO_IOCTL 4096 | ||
84 | |||
85 | #define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ | ||
86 | |||
87 | #define UNKNOWN_BOARD 0 | ||
88 | #define CX25821_BOARD 1 | ||
89 | |||
90 | /* Currently supported by the driver */ | ||
91 | #define CX25821_NORMS (\ | ||
92 | V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \ | ||
93 | V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \ | ||
94 | V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_H | \ | ||
95 | V4L2_STD_PAL_Nc) | ||
96 | |||
97 | #define CX25821_BOARD_CONEXANT_ATHENA10 1 | ||
98 | #define MAX_VID_CHANNEL_NUM 12 | ||
99 | #define VID_CHANNEL_NUM 8 | ||
100 | #define CX25821_NR_INPUT 2 | ||
101 | |||
102 | struct cx25821_fmt { | ||
103 | char *name; | ||
104 | u32 fourcc; /* v4l2 format id */ | ||
105 | int depth; | ||
106 | int flags; | ||
107 | u32 cxformat; | ||
108 | }; | ||
109 | |||
110 | struct cx25821_ctrl { | ||
111 | struct v4l2_queryctrl v; | ||
112 | u32 off; | ||
113 | u32 reg; | ||
114 | u32 mask; | ||
115 | u32 shift; | ||
116 | }; | ||
117 | |||
118 | struct cx25821_tvnorm { | ||
119 | char *name; | ||
120 | v4l2_std_id id; | ||
121 | u32 cxiformat; | ||
122 | u32 cxoformat; | ||
123 | }; | ||
124 | |||
125 | struct cx25821_fh { | ||
126 | struct cx25821_dev *dev; | ||
127 | enum v4l2_buf_type type; | ||
128 | int radio; | ||
129 | u32 resources; | ||
130 | |||
131 | enum v4l2_priority prio; | ||
132 | |||
133 | /* video overlay */ | ||
134 | struct v4l2_window win; | ||
135 | struct v4l2_clip *clips; | ||
136 | unsigned int nclips; | ||
137 | |||
138 | /* video capture */ | ||
139 | struct cx25821_fmt *fmt; | ||
140 | unsigned int width, height; | ||
141 | int channel_id; | ||
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 | |||
152 | enum cx25821_itype { | ||
153 | CX25821_VMUX_COMPOSITE = 1, | ||
154 | CX25821_VMUX_SVIDEO, | ||
155 | CX25821_VMUX_DEBUG, | ||
156 | CX25821_RADIO, | ||
157 | }; | ||
158 | |||
159 | enum 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 */ | ||
165 | struct 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 | |||
176 | struct cx25821_input { | ||
177 | enum cx25821_itype type; | ||
178 | unsigned int vmux; | ||
179 | u32 gpio0, gpio1, gpio2, gpio3; | ||
180 | }; | ||
181 | |||
182 | enum port { | ||
183 | CX25821_UNDEFINED = 0, | ||
184 | CX25821_RAW, | ||
185 | CX25821_264 | ||
186 | }; | ||
187 | |||
188 | struct cx25821_board { | ||
189 | const char *name; | ||
190 | enum port porta; | ||
191 | enum port portb; | ||
192 | enum port portc; | ||
193 | unsigned int tuner_type; | ||
194 | unsigned int radio_type; | ||
195 | unsigned char tuner_addr; | ||
196 | unsigned char radio_addr; | ||
197 | |||
198 | u32 clk_freq; | ||
199 | struct cx25821_input input[CX25821_NR_INPUT]; | ||
200 | }; | ||
201 | |||
202 | struct cx25821_subid { | ||
203 | u16 subvendor; | ||
204 | u16 subdevice; | ||
205 | u32 card; | ||
206 | }; | ||
207 | |||
208 | struct cx25821_i2c { | ||
209 | struct cx25821_dev *dev; | ||
210 | |||
211 | int nr; | ||
212 | |||
213 | /* i2c i/o */ | ||
214 | struct i2c_adapter i2c_adap; | ||
215 | struct i2c_client i2c_client; | ||
216 | u32 i2c_rc; | ||
217 | |||
218 | /* cx25821 registers used for raw addess */ | ||
219 | u32 i2c_period; | ||
220 | u32 reg_ctrl; | ||
221 | u32 reg_stat; | ||
222 | u32 reg_addr; | ||
223 | u32 reg_rdata; | ||
224 | u32 reg_wdata; | ||
225 | }; | ||
226 | |||
227 | struct cx25821_dmaqueue { | ||
228 | struct list_head active; | ||
229 | struct list_head queued; | ||
230 | struct timer_list timeout; | ||
231 | struct btcx_riscmem stopper; | ||
232 | u32 count; | ||
233 | }; | ||
234 | |||
235 | struct cx25821_data { | ||
236 | struct cx25821_dev *dev; | ||
237 | struct sram_channel *channel; | ||
238 | }; | ||
239 | |||
240 | struct cx25821_channel { | ||
241 | struct v4l2_prio_state prio; | ||
242 | |||
243 | int ctl_bright; | ||
244 | int ctl_contrast; | ||
245 | int ctl_hue; | ||
246 | int ctl_saturation; | ||
247 | struct cx25821_data timeout_data; | ||
248 | |||
249 | struct video_device *video_dev; | ||
250 | struct cx25821_dmaqueue vidq; | ||
251 | |||
252 | struct sram_channel *sram_channels; | ||
253 | |||
254 | struct mutex lock; | ||
255 | int resources; | ||
256 | |||
257 | int pixel_formats; | ||
258 | int use_cif_resolution; | ||
259 | int cif_width; | ||
260 | }; | ||
261 | |||
262 | struct cx25821_dev { | ||
263 | struct list_head devlist; | ||
264 | atomic_t refcount; | ||
265 | struct v4l2_device v4l2_dev; | ||
266 | |||
267 | /* pci stuff */ | ||
268 | struct pci_dev *pci; | ||
269 | unsigned char pci_rev, pci_lat; | ||
270 | int pci_bus, pci_slot; | ||
271 | u32 base_io_addr; | ||
272 | u32 __iomem *lmmio; | ||
273 | u8 __iomem *bmmio; | ||
274 | int pci_irqmask; | ||
275 | int hwrevision; | ||
276 | |||
277 | u32 clk_freq; | ||
278 | |||
279 | /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ | ||
280 | struct cx25821_i2c i2c_bus[3]; | ||
281 | |||
282 | int nr; | ||
283 | struct mutex lock; | ||
284 | |||
285 | struct cx25821_channel channels[MAX_VID_CHANNEL_NUM]; | ||
286 | |||
287 | /* board details */ | ||
288 | unsigned int board; | ||
289 | char name[32]; | ||
290 | |||
291 | /* Analog video */ | ||
292 | u32 resources; | ||
293 | unsigned int input; | ||
294 | u32 tvaudio; | ||
295 | v4l2_std_id tvnorm; | ||
296 | unsigned int tuner_type; | ||
297 | unsigned char tuner_addr; | ||
298 | unsigned int radio_type; | ||
299 | unsigned char radio_addr; | ||
300 | unsigned int has_radio; | ||
301 | unsigned int videc_type; | ||
302 | unsigned char videc_addr; | ||
303 | unsigned short _max_num_decoders; | ||
304 | |||
305 | /* Analog Audio Upstream */ | ||
306 | int _audio_is_running; | ||
307 | int _audiopixel_format; | ||
308 | int _is_first_audio_frame; | ||
309 | int _audiofile_status; | ||
310 | int _audio_lines_count; | ||
311 | int _audioframe_count; | ||
312 | int _audio_upstream_channel; | ||
313 | int _last_index_irq; /* The last interrupt index processed. */ | ||
314 | |||
315 | __le32 *_risc_audio_jmp_addr; | ||
316 | __le32 *_risc_virt_start_addr; | ||
317 | __le32 *_risc_virt_addr; | ||
318 | dma_addr_t _risc_phys_addr; | ||
319 | dma_addr_t _risc_phys_start_addr; | ||
320 | |||
321 | unsigned int _audiorisc_size; | ||
322 | unsigned int _audiodata_buf_size; | ||
323 | __le32 *_audiodata_buf_virt_addr; | ||
324 | dma_addr_t _audiodata_buf_phys_addr; | ||
325 | char *_audiofilename; | ||
326 | |||
327 | /* V4l */ | ||
328 | u32 freq; | ||
329 | struct video_device *vbi_dev; | ||
330 | struct video_device *radio_dev; | ||
331 | struct video_device *ioctl_dev; | ||
332 | |||
333 | spinlock_t slock; | ||
334 | |||
335 | /* Video Upstream */ | ||
336 | int _line_size; | ||
337 | int _prog_cnt; | ||
338 | int _pixel_format; | ||
339 | int _is_first_frame; | ||
340 | int _is_running; | ||
341 | int _file_status; | ||
342 | int _lines_count; | ||
343 | int _frame_count; | ||
344 | int _channel_upstream_select; | ||
345 | unsigned int _risc_size; | ||
346 | |||
347 | __le32 *_dma_virt_start_addr; | ||
348 | __le32 *_dma_virt_addr; | ||
349 | dma_addr_t _dma_phys_addr; | ||
350 | dma_addr_t _dma_phys_start_addr; | ||
351 | |||
352 | unsigned int _data_buf_size; | ||
353 | __le32 *_data_buf_virt_addr; | ||
354 | dma_addr_t _data_buf_phys_addr; | ||
355 | char *_filename; | ||
356 | char *_defaultname; | ||
357 | |||
358 | int _line_size_ch2; | ||
359 | int _prog_cnt_ch2; | ||
360 | int _pixel_format_ch2; | ||
361 | int _is_first_frame_ch2; | ||
362 | int _is_running_ch2; | ||
363 | int _file_status_ch2; | ||
364 | int _lines_count_ch2; | ||
365 | int _frame_count_ch2; | ||
366 | int _channel2_upstream_select; | ||
367 | unsigned int _risc_size_ch2; | ||
368 | |||
369 | __le32 *_dma_virt_start_addr_ch2; | ||
370 | __le32 *_dma_virt_addr_ch2; | ||
371 | dma_addr_t _dma_phys_addr_ch2; | ||
372 | dma_addr_t _dma_phys_start_addr_ch2; | ||
373 | |||
374 | unsigned int _data_buf_size_ch2; | ||
375 | __le32 *_data_buf_virt_addr_ch2; | ||
376 | dma_addr_t _data_buf_phys_addr_ch2; | ||
377 | char *_filename_ch2; | ||
378 | char *_defaultname_ch2; | ||
379 | |||
380 | /* MPEG Encoder ONLY settings */ | ||
381 | u32 cx23417_mailbox; | ||
382 | struct cx2341x_mpeg_params mpeg_params; | ||
383 | struct video_device *v4l_device; | ||
384 | atomic_t v4l_reader_count; | ||
385 | struct cx25821_tvnorm encodernorm; | ||
386 | |||
387 | u32 upstream_riscbuf_size; | ||
388 | u32 upstream_databuf_size; | ||
389 | u32 upstream_riscbuf_size_ch2; | ||
390 | u32 upstream_databuf_size_ch2; | ||
391 | u32 audio_upstream_riscbuf_size; | ||
392 | u32 audio_upstream_databuf_size; | ||
393 | int _isNTSC; | ||
394 | int _frame_index; | ||
395 | int _audioframe_index; | ||
396 | struct workqueue_struct *_irq_queues; | ||
397 | struct work_struct _irq_work_entry; | ||
398 | struct workqueue_struct *_irq_queues_ch2; | ||
399 | struct work_struct _irq_work_entry_ch2; | ||
400 | struct workqueue_struct *_irq_audio_queues; | ||
401 | struct work_struct _audio_work_entry; | ||
402 | char *input_filename; | ||
403 | char *input_filename_ch2; | ||
404 | int _frame_index_ch2; | ||
405 | int _isNTSC_ch2; | ||
406 | char *vid_stdname_ch2; | ||
407 | int pixel_format_ch2; | ||
408 | int channel_select_ch2; | ||
409 | int command_ch2; | ||
410 | char *input_audiofilename; | ||
411 | char *vid_stdname; | ||
412 | int pixel_format; | ||
413 | int channel_select; | ||
414 | int command; | ||
415 | int channel_opened; | ||
416 | }; | ||
417 | |||
418 | struct upstream_user_struct { | ||
419 | char *input_filename; | ||
420 | char *vid_stdname; | ||
421 | int pixel_format; | ||
422 | int channel_select; | ||
423 | int command; | ||
424 | }; | ||
425 | |||
426 | struct downstream_user_struct { | ||
427 | char *vid_stdname; | ||
428 | int pixel_format; | ||
429 | int cif_resolution_enable; | ||
430 | int cif_width; | ||
431 | int decoder_select; | ||
432 | int command; | ||
433 | int reg_address; | ||
434 | int reg_data; | ||
435 | }; | ||
436 | |||
437 | extern struct upstream_user_struct *up_data; | ||
438 | |||
439 | static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) | ||
440 | { | ||
441 | return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev); | ||
442 | } | ||
443 | |||
444 | #define cx25821_call_all(dev, o, f, args...) \ | ||
445 | v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) | ||
446 | |||
447 | extern struct list_head cx25821_devlist; | ||
448 | extern struct mutex cx25821_devlist_mutex; | ||
449 | |||
450 | extern struct cx25821_board cx25821_boards[]; | ||
451 | extern struct cx25821_subid cx25821_subids[]; | ||
452 | |||
453 | #define SRAM_CH00 0 /* Video A */ | ||
454 | #define SRAM_CH01 1 /* Video B */ | ||
455 | #define SRAM_CH02 2 /* Video C */ | ||
456 | #define SRAM_CH03 3 /* Video D */ | ||
457 | #define SRAM_CH04 4 /* Video E */ | ||
458 | #define SRAM_CH05 5 /* Video F */ | ||
459 | #define SRAM_CH06 6 /* Video G */ | ||
460 | #define SRAM_CH07 7 /* Video H */ | ||
461 | |||
462 | #define SRAM_CH08 8 /* Audio A */ | ||
463 | #define SRAM_CH09 9 /* Video Upstream I */ | ||
464 | #define SRAM_CH10 10 /* Video Upstream J */ | ||
465 | #define SRAM_CH11 11 /* Audio Upstream AUD_CHANNEL_B */ | ||
466 | |||
467 | #define VID_UPSTREAM_SRAM_CHANNEL_I SRAM_CH09 | ||
468 | #define VID_UPSTREAM_SRAM_CHANNEL_J SRAM_CH10 | ||
469 | #define AUDIO_UPSTREAM_SRAM_CHANNEL_B SRAM_CH11 | ||
470 | #define VIDEO_IOCTL_CH 11 | ||
471 | |||
472 | struct sram_channel { | ||
473 | char *name; | ||
474 | u32 i; | ||
475 | u32 cmds_start; | ||
476 | u32 ctrl_start; | ||
477 | u32 cdt; | ||
478 | u32 fifo_start; | ||
479 | u32 fifo_size; | ||
480 | u32 ptr1_reg; | ||
481 | u32 ptr2_reg; | ||
482 | u32 cnt1_reg; | ||
483 | u32 cnt2_reg; | ||
484 | u32 int_msk; | ||
485 | u32 int_stat; | ||
486 | u32 int_mstat; | ||
487 | u32 dma_ctl; | ||
488 | u32 gpcnt_ctl; | ||
489 | u32 gpcnt; | ||
490 | u32 aud_length; | ||
491 | u32 aud_cfg; | ||
492 | u32 fld_aud_fifo_en; | ||
493 | u32 fld_aud_risc_en; | ||
494 | |||
495 | /* For Upstream Video */ | ||
496 | u32 vid_fmt_ctl; | ||
497 | u32 vid_active_ctl1; | ||
498 | u32 vid_active_ctl2; | ||
499 | u32 vid_cdt_size; | ||
500 | |||
501 | u32 vip_ctl; | ||
502 | u32 pix_frmt; | ||
503 | u32 jumponly; | ||
504 | u32 irq_bit; | ||
505 | }; | ||
506 | extern struct sram_channel cx25821_sram_channels[]; | ||
507 | |||
508 | #define STATUS_SUCCESS 0 | ||
509 | #define STATUS_UNSUCCESSFUL -1 | ||
510 | |||
511 | #define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) | ||
512 | #define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) | ||
513 | |||
514 | #define cx_andor(reg, mask, value) \ | ||
515 | writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ | ||
516 | ((value) & (mask)), dev->lmmio+((reg)>>2)) | ||
517 | |||
518 | #define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) | ||
519 | #define cx_clear(reg, bit) cx_andor((reg), (bit), 0) | ||
520 | |||
521 | #define Set_GPIO_Bit(Bit) (1 << Bit) | ||
522 | #define Clear_GPIO_Bit(Bit) (~(1 << Bit)) | ||
523 | |||
524 | #define CX25821_ERR(fmt, args...) \ | ||
525 | pr_err("(%d): " fmt, dev->board, ##args) | ||
526 | #define CX25821_WARN(fmt, args...) \ | ||
527 | pr_warn("(%d): " fmt, dev->board, ##args) | ||
528 | #define CX25821_INFO(fmt, args...) \ | ||
529 | pr_info("(%d): " fmt, dev->board, ##args) | ||
530 | |||
531 | extern int cx25821_i2c_register(struct cx25821_i2c *bus); | ||
532 | extern void cx25821_card_setup(struct cx25821_dev *dev); | ||
533 | extern int cx25821_ir_init(struct cx25821_dev *dev); | ||
534 | extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value); | ||
535 | extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value); | ||
536 | extern int cx25821_i2c_unregister(struct cx25821_i2c *bus); | ||
537 | extern void cx25821_gpio_init(struct cx25821_dev *dev); | ||
538 | extern void cx25821_set_gpiopin_direction(struct cx25821_dev *dev, | ||
539 | int pin_number, int pin_logic_value); | ||
540 | |||
541 | extern int medusa_video_init(struct cx25821_dev *dev); | ||
542 | extern int medusa_set_videostandard(struct cx25821_dev *dev); | ||
543 | extern void medusa_set_resolution(struct cx25821_dev *dev, int width, | ||
544 | int decoder_select); | ||
545 | extern int medusa_set_brightness(struct cx25821_dev *dev, int brightness, | ||
546 | int decoder); | ||
547 | extern int medusa_set_contrast(struct cx25821_dev *dev, int contrast, | ||
548 | int decoder); | ||
549 | extern int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder); | ||
550 | extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation, | ||
551 | int decoder); | ||
552 | |||
553 | extern int cx25821_sram_channel_setup(struct cx25821_dev *dev, | ||
554 | struct sram_channel *ch, unsigned int bpl, | ||
555 | u32 risc); | ||
556 | |||
557 | extern int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | ||
558 | struct scatterlist *sglist, | ||
559 | unsigned int top_offset, | ||
560 | unsigned int bottom_offset, | ||
561 | unsigned int bpl, | ||
562 | unsigned int padding, unsigned int lines); | ||
563 | extern int cx25821_risc_databuffer_audio(struct pci_dev *pci, | ||
564 | struct btcx_riscmem *risc, | ||
565 | struct scatterlist *sglist, | ||
566 | unsigned int bpl, | ||
567 | unsigned int lines, unsigned int lpi); | ||
568 | extern void cx25821_free_buffer(struct videobuf_queue *q, | ||
569 | struct cx25821_buffer *buf); | ||
570 | extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | ||
571 | u32 reg, u32 mask, u32 value); | ||
572 | extern void cx25821_sram_channel_dump(struct cx25821_dev *dev, | ||
573 | struct sram_channel *ch); | ||
574 | extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, | ||
575 | struct sram_channel *ch); | ||
576 | |||
577 | extern struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci); | ||
578 | extern void cx25821_print_irqbits(char *name, char *tag, char **strings, | ||
579 | int len, u32 bits, u32 mask); | ||
580 | extern void cx25821_dev_unregister(struct cx25821_dev *dev); | ||
581 | extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, | ||
582 | struct sram_channel *ch, | ||
583 | unsigned int bpl, u32 risc); | ||
584 | |||
585 | extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, | ||
586 | int channel_select, int pixel_format); | ||
587 | extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, | ||
588 | int channel_select, int pixel_format); | ||
589 | extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, | ||
590 | int channel_select); | ||
591 | extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev); | ||
592 | extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev); | ||
593 | extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); | ||
594 | extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, | ||
595 | struct upstream_user_struct | ||
596 | *up_data); | ||
597 | extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, | ||
598 | struct upstream_user_struct | ||
599 | *up_data); | ||
600 | extern void cx25821_start_upstream_audio(struct cx25821_dev *dev, | ||
601 | struct upstream_user_struct *up_data); | ||
602 | extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); | ||
603 | extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); | ||
604 | extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); | ||
605 | extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, | ||
606 | struct sram_channel *ch, | ||
607 | unsigned int bpl, u32 risc); | ||
608 | extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel, | ||
609 | u32 format); | ||
610 | extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev); | ||
611 | extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, | ||
612 | struct pci_dev *pci, | ||
613 | struct video_device *template, | ||
614 | char *type); | ||
615 | #endif | ||