aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx18/Makefile2
-rw-r--r--drivers/media/video/cx18/cx18-audio.c5
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c12
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c7
-rw-r--r--drivers/media/video/cx18/cx18-driver.c7
-rw-r--r--drivers/media/video/cx18/cx18-driver.h43
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c5
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c140
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c15
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c47
-rw-r--r--drivers/media/video/cx18/cx18-io.c142
-rw-r--r--drivers/media/video/cx18/cx18-io.h69
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c5
-rw-r--r--drivers/media/video/cx18/cx18-irq.c43
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c44
-rw-r--r--drivers/media/video/cx18/cx18-queue.c2
-rw-r--r--drivers/media/video/cx18/cx18-queue.h2
-rw-r--r--drivers/media/video/cx18/cx18-scb.c131
-rw-r--r--drivers/media/video/cx18/cx18-streams.c10
19 files changed, 468 insertions, 263 deletions
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile
index b23d2e26120f..f7bf0edf93f9 100644
--- a/drivers/media/video/cx18/Makefile
+++ b/drivers/media/video/cx18/Makefile
@@ -2,7 +2,7 @@ cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.
2 cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \ 2 cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \ 3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \ 4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
5 cx18-dvb.o 5 cx18-dvb.o cx18-io.o
6 6
7obj-$(CONFIG_VIDEO_CX18) += cx18.o 7obj-$(CONFIG_VIDEO_CX18) += cx18.o
8 8
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 6d5b94fc7087..57beddf0af4d 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include "cx18-driver.h" 24#include "cx18-driver.h"
25#include "cx18-io.h"
25#include "cx18-i2c.h" 26#include "cx18-i2c.h"
26#include "cx18-cards.h" 27#include "cx18-cards.h"
27#include "cx18-audio.h" 28#include "cx18-audio.h"
@@ -60,10 +61,10 @@ int cx18_audio_set_io(struct cx18 *cx)
60 if (err) 61 if (err)
61 return err; 62 return err;
62 63
63 val = read_reg(CX18_AUDIO_ENABLE) & ~0x30; 64 val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
64 val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : 65 val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
65 (audio_input << 4); 66 (audio_input << 4);
66 write_reg(val | 0xb00, CX18_AUDIO_ENABLE); 67 cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE);
67 cx18_vapi(cx, CX18_APU_RESETAI, 1, 0); 68 cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
68 return 0; 69 return 0;
69} 70}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 3b0a2c450605..d8626e354651 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -22,27 +22,29 @@
22 */ 22 */
23 23
24#include "cx18-driver.h" 24#include "cx18-driver.h"
25#include "cx18-io.h"
25 26
26int cx18_av_write(struct cx18 *cx, u16 addr, u8 value) 27int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
27{ 28{
28 u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3)); 29 u32 reg = 0xc40000 + (addr & ~3);
29 u32 mask = 0xff; 30 u32 mask = 0xff;
30 int shift = (addr & 3) * 8; 31 int shift = (addr & 3) * 8;
32 u32 x = cx18_read_reg(cx, reg);
31 33
32 x = (x & ~(mask << shift)) | ((u32)value << shift); 34 x = (x & ~(mask << shift)) | ((u32)value << shift);
33 writel(x, cx->reg_mem + 0xc40000 + (addr & ~3)); 35 cx18_write_reg(cx, x, reg);
34 return 0; 36 return 0;
35} 37}
36 38
37int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value) 39int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
38{ 40{
39 writel(value, cx->reg_mem + 0xc40000 + addr); 41 cx18_write_reg(cx, value, 0xc40000 + addr);
40 return 0; 42 return 0;
41} 43}
42 44
43u8 cx18_av_read(struct cx18 *cx, u16 addr) 45u8 cx18_av_read(struct cx18 *cx, u16 addr)
44{ 46{
45 u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3)); 47 u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3));
46 int shift = (addr & 3) * 8; 48 int shift = (addr & 3) * 8;
47 49
48 return (x >> shift) & 0xff; 50 return (x >> shift) & 0xff;
@@ -50,7 +52,7 @@ u8 cx18_av_read(struct cx18 *cx, u16 addr)
50 52
51u32 cx18_av_read4(struct cx18 *cx, u16 addr) 53u32 cx18_av_read4(struct cx18 *cx, u16 addr)
52{ 54{
53 return readl(cx->reg_mem + 0xc40000 + addr); 55 return cx18_read_reg(cx, 0xc40000 + addr);
54} 56}
55 57
56int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask, 58int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index e996a4e3123a..0488b6297704 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include "cx18-driver.h" 22#include "cx18-driver.h"
23#include "cx18-io.h"
23#include <linux/firmware.h> 24#include <linux/firmware.h>
24 25
25#define CX18_AUDIO_ENABLE 0xc72014 26#define CX18_AUDIO_ENABLE 0xc72014
@@ -119,10 +120,10 @@ int cx18_av_loadfw(struct cx18 *cx)
119 have a name in the spec. */ 120 have a name in the spec. */
120 cx18_av_write4(cx, 0x09CC, 1); 121 cx18_av_write4(cx, 0x09CC, 1);
121 122
122 v = read_reg(CX18_AUDIO_ENABLE); 123 v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
123 /* If bit 11 is 1 */ 124 /* If bit 11 is 1, clear bit 10 */
124 if (v & 0x800) 125 if (v & 0x800)
125 write_reg(v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); /* Clear bit 10 */ 126 cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE);
126 127
127 /* Enable WW auto audio standard detection */ 128 /* Enable WW auto audio standard detection */
128 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); 129 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 3dfceb360b50..d31e1ec8d14c 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include "cx18-driver.h" 24#include "cx18-driver.h"
25#include "cx18-io.h"
25#include "cx18-version.h" 26#include "cx18-version.h"
26#include "cx18-cards.h" 27#include "cx18-cards.h"
27#include "cx18-i2c.h" 28#include "cx18-i2c.h"
@@ -651,7 +652,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
651 goto free_mem; 652 goto free_mem;
652 } 653 }
653 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET; 654 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
654 devtype = read_reg(0xC72028); 655 devtype = cx18_read_reg(cx, 0xC72028);
655 switch (devtype & 0xff000000) { 656 switch (devtype & 0xff000000) {
656 case 0xff000000: 657 case 0xff000000:
657 CX18_INFO("cx23418 revision %08x (A)\n", devtype); 658 CX18_INFO("cx23418 revision %08x (A)\n", devtype);
@@ -897,8 +898,8 @@ static void cx18_remove(struct pci_dev *pci_dev)
897 cx18_stop_all_captures(cx); 898 cx18_stop_all_captures(cx);
898 899
899 /* Interrupts */ 900 /* Interrupts */
900 sw1_irq_disable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); 901 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
901 sw2_irq_disable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); 902 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
902 903
903 cx18_halt_firmware(cx); 904 cx18_halt_firmware(cx);
904 905
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 7bdd2fcdf200..2cfdbe445820 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -457,47 +457,4 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
457/* First-open initialization: load firmware, etc. */ 457/* First-open initialization: load firmware, etc. */
458int cx18_init_on_first_open(struct cx18 *cx); 458int cx18_init_on_first_open(struct cx18 *cx);
459 459
460/* This is a PCI post thing, where if the pci register is not read, then
461 the write doesn't always take effect right away. By reading back the
462 register any pending PCI writes will be performed (in order), and so
463 you can be sure that the writes are guaranteed to be done.
464
465 Rarely needed, only in some timing sensitive cases.
466 Apparently if this is not done some motherboards seem
467 to kill the firmware and get into the broken state until computer is
468 rebooted. */
469#define write_sync(val, reg) \
470 do { writel(val, reg); readl(reg); } while (0)
471
472#define read_reg(reg) readl(cx->reg_mem + (reg))
473#define write_reg(val, reg) writel(val, cx->reg_mem + (reg))
474#define write_reg_sync(val, reg) \
475 do { write_reg(val, reg); read_reg(reg); } while (0)
476
477#define read_enc(addr) readl(cx->enc_mem + (u32)(addr))
478#define write_enc(val, addr) writel(val, cx->enc_mem + (u32)(addr))
479#define write_enc_sync(val, addr) \
480 do { write_enc(val, addr); read_enc(addr); } while (0)
481
482#define sw1_irq_enable(val) do { \
483 write_reg(val, SW1_INT_STATUS); \
484 write_reg(read_reg(SW1_INT_ENABLE_PCI) | (val), SW1_INT_ENABLE_PCI); \
485} while (0)
486
487#define sw1_irq_disable(val) \
488 write_reg(read_reg(SW1_INT_ENABLE_PCI) & ~(val), SW1_INT_ENABLE_PCI);
489
490#define sw2_irq_enable(val) do { \
491 write_reg(val, SW2_INT_STATUS); \
492 write_reg(read_reg(SW2_INT_ENABLE_PCI) | (val), SW2_INT_ENABLE_PCI); \
493} while (0)
494
495#define sw2_irq_disable(val) \
496 write_reg(read_reg(SW2_INT_ENABLE_PCI) & ~(val), SW2_INT_ENABLE_PCI);
497
498#define setup_page(addr) do { \
499 u32 val = read_reg(0xD000F8) & ~0x1f00; \
500 write_reg(val | (((addr) >> 17) & 0x1f00), 0xD000F8); \
501} while (0)
502
503#endif /* CX18_DRIVER_H */ 460#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 1e420a804fc9..afc694e7bdb2 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -21,6 +21,7 @@
21 21
22#include "cx18-version.h" 22#include "cx18-version.h"
23#include "cx18-dvb.h" 23#include "cx18-dvb.h"
24#include "cx18-io.h"
24#include "cx18-streams.h" 25#include "cx18-streams.h"
25#include "cx18-cards.h" 26#include "cx18-cards.h"
26#include "s5h1409.h" 27#include "s5h1409.h"
@@ -87,13 +88,13 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
87 switch (cx->card->type) { 88 switch (cx->card->type) {
88 case CX18_CARD_HVR_1600_ESMT: 89 case CX18_CARD_HVR_1600_ESMT:
89 case CX18_CARD_HVR_1600_SAMSUNG: 90 case CX18_CARD_HVR_1600_SAMSUNG:
90 v = read_reg(CX18_REG_DMUX_NUM_PORT_0_CONTROL); 91 v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
91 v |= 0x00400000; /* Serial Mode */ 92 v |= 0x00400000; /* Serial Mode */
92 v |= 0x00002000; /* Data Length - Byte */ 93 v |= 0x00002000; /* Data Length - Byte */
93 v |= 0x00010000; /* Error - Polarity */ 94 v |= 0x00010000; /* Error - Polarity */
94 v |= 0x00020000; /* Error - Passthru */ 95 v |= 0x00020000; /* Error - Passthru */
95 v |= 0x000c0000; /* Error - Ignore */ 96 v |= 0x000c0000; /* Error - Ignore */
96 write_reg(v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); 97 cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
97 break; 98 break;
98 99
99 default: 100 default:
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 78fadd2ada5d..51534428cd00 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include "cx18-driver.h" 22#include "cx18-driver.h"
23#include "cx18-io.h"
23#include "cx18-scb.h" 24#include "cx18-scb.h"
24#include "cx18-irq.h" 25#include "cx18-irq.h"
25#include "cx18-firmware.h" 26#include "cx18-firmware.h"
@@ -113,11 +114,11 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
113 src = (const u32 *)fw->data; 114 src = (const u32 *)fw->data;
114 115
115 for (i = 0; i < fw->size; i += 4096) { 116 for (i = 0; i < fw->size; i += 4096) {
116 setup_page(i); 117 cx18_setup_page(cx, i);
117 for (j = i; j < fw->size && j < i + 4096; j += 4) { 118 for (j = i; j < fw->size && j < i + 4096; j += 4) {
118 /* no need for endianness conversion on the ppc */ 119 /* no need for endianness conversion on the ppc */
119 __raw_writel(*src, dst); 120 cx18_raw_writel(cx, *src, dst);
120 if (__raw_readl(dst) != *src) { 121 if (cx18_raw_readl(cx, dst) != *src) {
121 CX18_ERR("Mismatch at offset %x\n", i); 122 CX18_ERR("Mismatch at offset %x\n", i);
122 release_firmware(fw); 123 release_firmware(fw);
123 return -EIO; 124 return -EIO;
@@ -170,12 +171,15 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
170 if (offset + seghdr.size > sz) 171 if (offset + seghdr.size > sz)
171 break; 172 break;
172 for (i = 0; i < seghdr.size; i += 4096) { 173 for (i = 0; i < seghdr.size; i += 4096) {
173 setup_page(offset + i); 174 cx18_setup_page(cx, offset + i);
174 for (j = i; j < seghdr.size && j < i + 4096; j += 4) { 175 for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
175 /* no need for endianness conversion on the ppc */ 176 /* no need for endianness conversion on the ppc */
176 __raw_writel(src[(offset + j) / 4], dst + seghdr.addr + j); 177 cx18_raw_writel(cx, src[(offset + j) / 4],
177 if (__raw_readl(dst + seghdr.addr + j) != src[(offset + j) / 4]) { 178 dst + seghdr.addr + j);
178 CX18_ERR("Mismatch at offset %x\n", offset + j); 179 if (cx18_raw_readl(cx, dst + seghdr.addr + j)
180 != src[(offset + j) / 4]) {
181 CX18_ERR("Mismatch at offset %x\n",
182 offset + j);
179 release_firmware(fw); 183 release_firmware(fw);
180 return -EIO; 184 return -EIO;
181 } 185 }
@@ -189,43 +193,45 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
189 size = fw->size; 193 size = fw->size;
190 release_firmware(fw); 194 release_firmware(fw);
191 /* Clear bit0 for APU to start from 0 */ 195 /* Clear bit0 for APU to start from 0 */
192 write_reg(read_reg(0xc72030) & ~1, 0xc72030); 196 cx18_write_reg(cx, cx18_read_reg(cx, 0xc72030) & ~1, 0xc72030);
193 return size; 197 return size;
194} 198}
195 199
196void cx18_halt_firmware(struct cx18 *cx) 200void cx18_halt_firmware(struct cx18 *cx)
197{ 201{
198 CX18_DEBUG_INFO("Preparing for firmware halt.\n"); 202 CX18_DEBUG_INFO("Preparing for firmware halt.\n");
199 write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ 203 cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
200 write_reg(0x00020002, CX18_ADEC_CONTROL); 204 cx18_write_reg(cx, 0x00020002, CX18_ADEC_CONTROL);
201} 205}
202 206
203void cx18_init_power(struct cx18 *cx, int lowpwr) 207void cx18_init_power(struct cx18 *cx, int lowpwr)
204{ 208{
205 /* power-down Spare and AOM PLLs */ 209 /* power-down Spare and AOM PLLs */
206 /* power-up fast, slow and mpeg PLLs */ 210 /* power-up fast, slow and mpeg PLLs */
207 write_reg(0x00000008, CX18_PLL_POWER_DOWN); 211 cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
208 212
209 /* ADEC out of sleep */ 213 /* ADEC out of sleep */
210 write_reg(0x00020000, CX18_ADEC_CONTROL); 214 cx18_write_reg(cx, 0x00020000, CX18_ADEC_CONTROL);
211 215
212 /* The fast clock is at 200/245 MHz */ 216 /* The fast clock is at 200/245 MHz */
213 write_reg(lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT); 217 cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
214 write_reg(lowpwr ? 0x1EFBF37 : 0x038E3D7, CX18_FAST_CLOCK_PLL_FRAC); 218 cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
219 CX18_FAST_CLOCK_PLL_FRAC);
215 220
216 write_reg(2, CX18_FAST_CLOCK_PLL_POST); 221 cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST);
217 write_reg(1, CX18_FAST_CLOCK_PLL_PRESCALE); 222 cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE);
218 write_reg(4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH); 223 cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
219 224
220 /* set slow clock to 125/120 MHz */ 225 /* set slow clock to 125/120 MHz */
221 write_reg(lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT); 226 cx18_write_reg(cx, lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT);
222 write_reg(lowpwr ? 0xEBAF05 : 0x18618A8, CX18_SLOW_CLOCK_PLL_FRAC); 227 cx18_write_reg(cx, lowpwr ? 0xEBAF05 : 0x18618A8,
223 write_reg(4, CX18_SLOW_CLOCK_PLL_POST); 228 CX18_SLOW_CLOCK_PLL_FRAC);
229 cx18_write_reg(cx, 4, CX18_SLOW_CLOCK_PLL_POST);
224 230
225 /* mpeg clock pll 54MHz */ 231 /* mpeg clock pll 54MHz */
226 write_reg(0xF, CX18_MPEG_CLOCK_PLL_INT); 232 cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
227 write_reg(0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC); 233 cx18_write_reg(cx, 0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC);
228 write_reg(8, CX18_MPEG_CLOCK_PLL_POST); 234 cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
229 235
230 /* Defaults */ 236 /* Defaults */
231 /* APU = SC or SC/2 = 125/62.5 */ 237 /* APU = SC or SC/2 = 125/62.5 */
@@ -242,81 +248,84 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
242 /* VFC = disabled */ 248 /* VFC = disabled */
243 /* USB = disabled */ 249 /* USB = disabled */
244 250
245 write_reg(lowpwr ? 0xFFFF0020 : 0x00060004, CX18_CLOCK_SELECT1); 251 cx18_write_reg(cx, lowpwr ? 0xFFFF0020 : 0x00060004,
246 write_reg(lowpwr ? 0xFFFF0004 : 0x00060006, CX18_CLOCK_SELECT2); 252 CX18_CLOCK_SELECT1);
253 cx18_write_reg(cx, lowpwr ? 0xFFFF0004 : 0x00060006,
254 CX18_CLOCK_SELECT2);
247 255
248 write_reg(0xFFFF0002, CX18_HALF_CLOCK_SELECT1); 256 cx18_write_reg(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1);
249 write_reg(0xFFFF0104, CX18_HALF_CLOCK_SELECT2); 257 cx18_write_reg(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2);
250 258
251 write_reg(0xFFFF9026, CX18_CLOCK_ENABLE1); 259 cx18_write_reg(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1);
252 write_reg(0xFFFF3105, CX18_CLOCK_ENABLE2); 260 cx18_write_reg(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2);
253} 261}
254 262
255void cx18_init_memory(struct cx18 *cx) 263void cx18_init_memory(struct cx18 *cx)
256{ 264{
257 cx18_msleep_timeout(10, 0); 265 cx18_msleep_timeout(10, 0);
258 write_reg(0x10000, CX18_DDR_SOFT_RESET); 266 cx18_write_reg(cx, 0x10000, CX18_DDR_SOFT_RESET);
259 cx18_msleep_timeout(10, 0); 267 cx18_msleep_timeout(10, 0);
260 268
261 write_reg(cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG); 269 cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
262 270
263 cx18_msleep_timeout(10, 0); 271 cx18_msleep_timeout(10, 0);
264 272
265 write_reg(cx->card->ddr.refresh, CX18_DDR_REFRESH); 273 cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH);
266 write_reg(cx->card->ddr.timing1, CX18_DDR_TIMING1); 274 cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1);
267 write_reg(cx->card->ddr.timing2, CX18_DDR_TIMING2); 275 cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2);
268 276
269 cx18_msleep_timeout(10, 0); 277 cx18_msleep_timeout(10, 0);
270 278
271 /* Initialize DQS pad time */ 279 /* Initialize DQS pad time */
272 write_reg(cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE); 280 cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
273 write_reg(cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS); 281 cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
274 282
275 cx18_msleep_timeout(10, 0); 283 cx18_msleep_timeout(10, 0);
276 284
277 write_reg(0x20000, CX18_DDR_SOFT_RESET); 285 cx18_write_reg(cx, 0x20000, CX18_DDR_SOFT_RESET);
278 cx18_msleep_timeout(10, 0); 286 cx18_msleep_timeout(10, 0);
279 287
280 /* use power-down mode when idle */ 288 /* use power-down mode when idle */
281 write_reg(0x00000010, CX18_DDR_POWER_REG); 289 cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
282 290
283 write_reg(0x10001, CX18_REG_BUS_TIMEOUT_EN); 291 cx18_write_reg(cx, 0x10001, CX18_REG_BUS_TIMEOUT_EN);
284 292
285 write_reg(0x48, CX18_DDR_MB_PER_ROW_7); 293 cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
286 write_reg(0xE0000, CX18_DDR_BASE_63_ADDR); 294 cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
287 295
288 write_reg(0x00000101, CX18_WMB_CLIENT02); /* AO */ 296 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */
289 write_reg(0x00000101, CX18_WMB_CLIENT09); /* AI2 */ 297 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */
290 write_reg(0x00000101, CX18_WMB_CLIENT05); /* VIM1 */ 298 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
291 write_reg(0x00000101, CX18_WMB_CLIENT06); /* AI1 */ 299 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */
292 write_reg(0x00000101, CX18_WMB_CLIENT07); /* 3D comb */ 300 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
293 write_reg(0x00000101, CX18_WMB_CLIENT10); /* ME */ 301 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */
294 write_reg(0x00000101, CX18_WMB_CLIENT12); /* ENC */ 302 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */
295 write_reg(0x00000101, CX18_WMB_CLIENT13); /* PK */ 303 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */
296 write_reg(0x00000101, CX18_WMB_CLIENT11); /* RC */ 304 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */
297 write_reg(0x00000101, CX18_WMB_CLIENT14); /* AVO */ 305 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */
298} 306}
299 307
300int cx18_firmware_init(struct cx18 *cx) 308int cx18_firmware_init(struct cx18 *cx)
301{ 309{
302 /* Allow chip to control CLKRUN */ 310 /* Allow chip to control CLKRUN */
303 write_reg(0x5, CX18_DSP0_INTERRUPT_MASK); 311 cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
304 312
305 write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ 313 cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
306 314
307 cx18_msleep_timeout(1, 0); 315 cx18_msleep_timeout(1, 0);
308 316
309 sw1_irq_enable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); 317 cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
310 sw2_irq_enable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); 318 cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
311 319
312 /* Only if the processor is not running */ 320 /* Only if the processor is not running */
313 if (read_reg(CX18_PROC_SOFT_RESET) & 8) { 321 if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) {
314 int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", 322 int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
315 cx->enc_mem, cx); 323 cx->enc_mem, cx);
316 324
317 write_enc(0xE51FF004, 0); 325 cx18_write_enc(cx, 0xE51FF004, 0);
318 write_enc(0xa00000, 4); /* todo: not hardcoded */ 326 cx18_write_enc(cx, 0xa00000, 4); /* todo: not hardcoded */
319 write_reg(0x00010000, CX18_PROC_SOFT_RESET); /* Start APU */ 327 /* Start APU */
328 cx18_write_reg(cx, 0x00010000, CX18_PROC_SOFT_RESET);
320 cx18_msleep_timeout(500, 0); 329 cx18_msleep_timeout(500, 0);
321 330
322 sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", 331 sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
@@ -326,9 +335,10 @@ int cx18_firmware_init(struct cx18 *cx)
326 int retries = 0; 335 int retries = 0;
327 336
328 /* start the CPU */ 337 /* start the CPU */
329 write_reg(0x00080000, CX18_PROC_SOFT_RESET); 338 cx18_write_reg(cx, 0x00080000, CX18_PROC_SOFT_RESET);
330 while (retries++ < 50) { /* Loop for max 500mS */ 339 while (retries++ < 50) { /* Loop for max 500mS */
331 if ((read_reg(CX18_PROC_SOFT_RESET) & 1) == 0) 340 if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET)
341 & 1) == 0)
332 break; 342 break;
333 cx18_msleep_timeout(10, 0); 343 cx18_msleep_timeout(10, 0);
334 } 344 }
@@ -342,6 +352,6 @@ int cx18_firmware_init(struct cx18 *cx)
342 return -EIO; 352 return -EIO;
343 } 353 }
344 /* initialize GPIO */ 354 /* initialize GPIO */
345 write_reg(0x14001400, 0xC78110); 355 cx18_write_reg(cx, 0x14001400, 0xC78110);
346 return 0; 356 return 0;
347} 357}
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 3d495dba4983..3bdffbf7a96d 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include "cx18-driver.h" 24#include "cx18-driver.h"
25#include "cx18-io.h"
25#include "cx18-cards.h" 26#include "cx18-cards.h"
26#include "cx18-gpio.h" 27#include "cx18-gpio.h"
27#include "tuner-xc2028.h" 28#include "tuner-xc2028.h"
@@ -49,11 +50,11 @@ static void gpio_write(struct cx18 *cx)
49 u32 dir = cx->gpio_dir; 50 u32 dir = cx->gpio_dir;
50 u32 val = cx->gpio_val; 51 u32 val = cx->gpio_val;
51 52
52 write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); 53 cx18_write_reg(cx, (dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
53 write_reg(((dir & 0xffff) << 16) | (val & 0xffff), 54 cx18_write_reg(cx, ((dir & 0xffff) << 16) | (val & 0xffff),
54 CX18_REG_GPIO_OUT1); 55 CX18_REG_GPIO_OUT1);
55 write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); 56 cx18_write_reg(cx, dir & 0xffff0000, CX18_REG_GPIO_DIR2);
56 write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), 57 cx18_write_reg_sync(cx, (dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
57 CX18_REG_GPIO_OUT2); 58 CX18_REG_GPIO_OUT2);
58} 59}
59 60
@@ -141,8 +142,10 @@ void cx18_gpio_init(struct cx18 *cx)
141 } 142 }
142 143
143 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", 144 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
144 read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), 145 cx18_read_reg(cx, CX18_REG_GPIO_DIR1),
145 read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); 146 cx18_read_reg(cx, CX18_REG_GPIO_DIR2),
147 cx18_read_reg(cx, CX18_REG_GPIO_OUT1),
148 cx18_read_reg(cx, CX18_REG_GPIO_OUT2));
146 149
147 gpio_write(cx); 150 gpio_write(cx);
148 mutex_unlock(&cx->gpio_lock); 151 mutex_unlock(&cx->gpio_lock);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 7d8fb25baae8..aa09e557b195 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include "cx18-driver.h" 24#include "cx18-driver.h"
25#include "cx18-io.h"
25#include "cx18-cards.h" 26#include "cx18-cards.h"
26#include "cx18-gpio.h" 27#include "cx18-gpio.h"
27#include "cx18-av-core.h" 28#include "cx18-av-core.h"
@@ -156,12 +157,12 @@ static void cx18_setscl(void *data, int state)
156 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; 157 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
157 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; 158 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
158 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR; 159 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
159 u32 r = read_reg(addr); 160 u32 r = cx18_read_reg(cx, addr);
160 161
161 if (state) 162 if (state)
162 write_reg_sync(r | SETSCL_BIT, addr); 163 cx18_write_reg_sync(cx, r | SETSCL_BIT, addr);
163 else 164 else
164 write_reg_sync(r & ~SETSCL_BIT, addr); 165 cx18_write_reg_sync(cx, r & ~SETSCL_BIT, addr);
165} 166}
166 167
167static void cx18_setsda(void *data, int state) 168static void cx18_setsda(void *data, int state)
@@ -169,12 +170,12 @@ static void cx18_setsda(void *data, int state)
169 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; 170 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
170 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; 171 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
171 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR; 172 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
172 u32 r = read_reg(addr); 173 u32 r = cx18_read_reg(cx, addr);
173 174
174 if (state) 175 if (state)
175 write_reg_sync(r | SETSDL_BIT, addr); 176 cx18_write_reg_sync(cx, r | SETSDL_BIT, addr);
176 else 177 else
177 write_reg_sync(r & ~SETSDL_BIT, addr); 178 cx18_write_reg_sync(cx, r & ~SETSDL_BIT, addr);
178} 179}
179 180
180static int cx18_getscl(void *data) 181static int cx18_getscl(void *data)
@@ -183,7 +184,7 @@ static int cx18_getscl(void *data)
183 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; 184 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
184 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD; 185 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
185 186
186 return read_reg(addr) & GETSCL_BIT; 187 return cx18_read_reg(cx, addr) & GETSCL_BIT;
187} 188}
188 189
189static int cx18_getsda(void *data) 190static int cx18_getsda(void *data)
@@ -192,7 +193,7 @@ static int cx18_getsda(void *data)
192 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; 193 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
193 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD; 194 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
194 195
195 return read_reg(addr) & GETSDL_BIT; 196 return cx18_read_reg(cx, addr) & GETSDL_BIT;
196} 197}
197 198
198/* template for i2c-bit-algo */ 199/* template for i2c-bit-algo */
@@ -392,29 +393,33 @@ int init_cx18_i2c(struct cx18 *cx)
392 cx->i2c_adap[i].dev.parent = &cx->dev->dev; 393 cx->i2c_adap[i].dev.parent = &cx->dev->dev;
393 } 394 }
394 395
395 if (read_reg(CX18_REG_I2C_2_WR) != 0x0003c02f) { 396 if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
396 /* Reset/Unreset I2C hardware block */ 397 /* Reset/Unreset I2C hardware block */
397 write_reg(0x10000000, 0xc71004); /* Clock select 220MHz */ 398 /* Clock select 220MHz */
398 write_reg_sync(0x10001000, 0xc71024); /* Clock Enable */ 399 cx18_write_reg(cx, 0x10000000, 0xc71004);
400 /* Clock Enable */
401 cx18_write_reg_sync(cx, 0x10001000, 0xc71024);
399 } 402 }
400 /* courtesy of Steven Toth <stoth@hauppauge.com> */ 403 /* courtesy of Steven Toth <stoth@hauppauge.com> */
401 write_reg_sync(0x00c00000, 0xc7001c); 404 cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c);
402 mdelay(10); 405 mdelay(10);
403 write_reg_sync(0x00c000c0, 0xc7001c); 406 cx18_write_reg_sync(cx, 0x00c000c0, 0xc7001c);
404 mdelay(10); 407 mdelay(10);
405 write_reg_sync(0x00c00000, 0xc7001c); 408 cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c);
406 mdelay(10); 409 mdelay(10);
407 410
408 write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */ 411 /* Set to edge-triggered intrs. */
409 write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */ 412 cx18_write_reg_sync(cx, 0x00c00000, 0xc730c8);
413 /* Clear any stale intrs */
414 cx18_write_reg_sync(cx, 0x00c00000, 0xc730c4);
410 415
411 /* Hw I2C1 Clock Freq ~100kHz */ 416 /* Hw I2C1 Clock Freq ~100kHz */
412 write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_1_WR); 417 cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
413 cx18_setscl(&cx->i2c_algo_cb_data[0], 1); 418 cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
414 cx18_setsda(&cx->i2c_algo_cb_data[0], 1); 419 cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
415 420
416 /* Hw I2C2 Clock Freq ~100kHz */ 421 /* Hw I2C2 Clock Freq ~100kHz */
417 write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_2_WR); 422 cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
418 cx18_setscl(&cx->i2c_algo_cb_data[1], 1); 423 cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
419 cx18_setsda(&cx->i2c_algo_cb_data[1], 1); 424 cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
420 425
@@ -428,8 +433,10 @@ void exit_cx18_i2c(struct cx18 *cx)
428{ 433{
429 int i; 434 int i;
430 CX18_DEBUG_I2C("i2c exit\n"); 435 CX18_DEBUG_I2C("i2c exit\n");
431 write_reg(read_reg(CX18_REG_I2C_1_WR) | 4, CX18_REG_I2C_1_WR); 436 cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4,
432 write_reg(read_reg(CX18_REG_I2C_2_WR) | 4, CX18_REG_I2C_2_WR); 437 CX18_REG_I2C_1_WR);
438 cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4,
439 CX18_REG_I2C_2_WR);
433 440
434 for (i = 0; i < 2; i++) { 441 for (i = 0; i < 2; i++) {
435 i2c_del_adapter(&cx->i2c_adap[i]); 442 i2c_del_adapter(&cx->i2c_adap[i]);
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
new file mode 100644
index 000000000000..c53d9b6e5e46
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-io.c
@@ -0,0 +1,142 @@
1/*
2 * cx18 driver PCI memory mapped IO access routines
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
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 * 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
20 * 02111-1307 USA
21 */
22
23#include "cx18-driver.h"
24#include "cx18-irq.h"
25
26void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
27{
28 __raw_writel(val, addr);
29}
30
31u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
32{
33 return __raw_readl(addr);
34}
35
36u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr)
37{
38 writel(val, addr);
39 return readl(addr);
40}
41
42void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
43{
44 writel(val, addr);
45}
46
47u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
48{
49 return readl(addr);
50}
51
52
53/* Access "register" region of CX23418 memory mapped I/O */
54u32 cx18_read_reg(struct cx18 *cx, u32 reg)
55{
56 return readl(cx->reg_mem + reg);
57}
58
59void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
60{
61 writel(val, cx->reg_mem + reg);
62}
63
64u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg)
65{
66 return cx18_write_sync(cx, val, cx->reg_mem + reg);
67}
68
69/* Access "encoder memory" region of CX23418 memory mapped I/O */
70u32 cx18_read_enc(struct cx18 *cx, u32 addr)
71{
72 return readl(cx->enc_mem + addr);
73}
74
75void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
76{
77 writel(val, cx->enc_mem + addr);
78}
79
80u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr)
81{
82 return cx18_write_sync(cx, val, cx->enc_mem + addr);
83}
84
85void cx18_memcpy_fromio(struct cx18 *cx, void *to,
86 const void __iomem *from, unsigned int len)
87{
88 memcpy_fromio(to, from, len);
89}
90
91void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
92{
93 memset_io(addr, val, count);
94}
95
96void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
97{
98 u32 r;
99 cx18_write_reg(cx, val, SW1_INT_STATUS);
100 r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
101 cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI);
102}
103
104void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
105{
106 u32 r;
107 r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
108 cx18_write_reg(cx, r & ~val, SW1_INT_ENABLE_PCI);
109}
110
111void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
112{
113 u32 r;
114 cx18_write_reg(cx, val, SW2_INT_STATUS);
115 r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
116 cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI);
117}
118
119void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
120{
121 u32 r;
122 r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
123 cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_PCI);
124}
125
126void cx18_setup_page(struct cx18 *cx, u32 addr)
127{
128 u32 val;
129 val = cx18_read_reg(cx, 0xD000F8);
130 val = (val & ~0x1f00) | ((addr >> 17) & 0x1f00);
131 cx18_write_reg(cx, val, 0xD000F8);
132}
133
134/* Tries to recover from the CX23418 responding improperly on the PCI bus */
135int cx18_pci_try_recover(struct cx18 *cx)
136{
137 u16 status;
138
139 pci_read_config_word(cx->dev, PCI_STATUS, &status);
140 pci_write_config_word(cx->dev, PCI_STATUS, status);
141 return 0;
142}
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
new file mode 100644
index 000000000000..7c08c0add490
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-io.h
@@ -0,0 +1,69 @@
1/*
2 * cx18 driver PCI memory mapped IO access routines
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
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 * 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
20 * 02111-1307 USA
21 */
22
23#ifndef CX18_IO_H
24#define CX18_IO_H
25
26#include "cx18-driver.h"
27
28/* This is a PCI post thing, where if the pci register is not read, then
29 the write doesn't always take effect right away. By reading back the
30 register any pending PCI writes will be performed (in order), and so
31 you can be sure that the writes are guaranteed to be done.
32
33 Rarely needed, only in some timing sensitive cases.
34 Apparently if this is not done some motherboards seem
35 to kill the firmware and get into the broken state until computer is
36 rebooted. */
37u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr);
38
39void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr);
40u32 cx18_readl(struct cx18 *cx, const void __iomem *addr);
41
42/* No endiannes conversion calls */
43void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr);
44u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr);
45
46/* Access "register" region of CX23418 memory mapped I/O */
47u32 cx18_read_reg(struct cx18 *cx, u32 reg);
48void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg);
49u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg);
50
51/* Access "encoder memory" region of CX23418 memory mapped I/O */
52u32 cx18_read_enc(struct cx18 *cx, u32 addr);
53void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr);
54u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr);
55
56void cx18_memcpy_fromio(struct cx18 *cx, void *to,
57 const void __iomem *from, unsigned int len);
58void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
59
60void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
61void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
62void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
63void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
64void cx18_setup_page(struct cx18 *cx, u32 addr);
65
66/* Tries to recover from the CX23418 responding improperly on the PCI bus */
67int cx18_pci_try_recover(struct cx18 *cx);
68
69#endif /* CX18_IO_H */
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 84507a39f2b8..8b26b3fefb1e 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include "cx18-driver.h" 24#include "cx18-driver.h"
25#include "cx18-io.h"
25#include "cx18-version.h" 26#include "cx18-version.h"
26#include "cx18-mailbox.h" 27#include "cx18-mailbox.h"
27#include "cx18-i2c.h" 28#include "cx18-i2c.h"
@@ -286,9 +287,9 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
286 287
287 spin_lock_irqsave(&cx18_cards_lock, flags); 288 spin_lock_irqsave(&cx18_cards_lock, flags);
288 if (cmd == VIDIOC_DBG_G_REGISTER) 289 if (cmd == VIDIOC_DBG_G_REGISTER)
289 regs->val = read_enc(regs->reg); 290 regs->val = cx18_read_enc(cx, regs->reg);
290 else 291 else
291 write_enc(regs->val, regs->reg); 292 cx18_write_enc(cx, regs->val, regs->reg);
292 spin_unlock_irqrestore(&cx18_cards_lock, flags); 293 spin_unlock_irqrestore(&cx18_cards_lock, flags);
293 return 0; 294 return 0;
294} 295}
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
index ab218315c84b..55a50a2b048d 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include "cx18-driver.h" 22#include "cx18-driver.h"
23#include "cx18-io.h"
23#include "cx18-firmware.h" 24#include "cx18-firmware.h"
24#include "cx18-fileops.h" 25#include "cx18-fileops.h"
25#include "cx18-queue.h" 26#include "cx18-queue.h"
@@ -60,8 +61,8 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
60 if (mb->args[2] != 1) 61 if (mb->args[2] != 1)
61 CX18_WARN("Ack struct = %d for %s\n", 62 CX18_WARN("Ack struct = %d for %s\n",
62 mb->args[2], s->name); 63 mb->args[2], s->name);
63 id = read_enc(off); 64 id = cx18_read_enc(cx, off);
64 buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4)); 65 buf = cx18_queue_get_buf_irq(s, id, cx18_read_enc(cx, off + 4));
65 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); 66 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
66 if (buf) { 67 if (buf) {
67 cx18_buf_sync_for_cpu(s, buf); 68 cx18_buf_sync_for_cpu(s, buf);
@@ -81,7 +82,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
81 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); 82 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
82 } else { 83 } else {
83 CX18_WARN("Could not find buf %d for stream %s\n", 84 CX18_WARN("Could not find buf %d for stream %s\n",
84 read_enc(off), s->name); 85 cx18_read_enc(cx, off), s->name);
85 } 86 }
86 mb->error = 0; 87 mb->error = 0;
87 mb->cmd = 0; 88 mb->cmd = 0;
@@ -97,8 +98,8 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb)
97 char *p; 98 char *p;
98 99
99 if (mb->args[1]) { 100 if (mb->args[1]) {
100 setup_page(mb->args[1]); 101 cx18_setup_page(cx, mb->args[1]);
101 memcpy_fromio(str, cx->enc_mem + mb->args[1], 252); 102 cx18_memcpy_fromio(cx, str, cx->enc_mem + mb->args[1], 252);
102 str[252] = 0; 103 str[252] = 0;
103 } 104 }
104 cx18_mb_ack(cx, mb); 105 cx18_mb_ack(cx, mb);
@@ -113,7 +114,7 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1)
113 struct cx18_mailbox mb; 114 struct cx18_mailbox mb;
114 115
115 if (sw1 & IRQ_CPU_TO_EPU) { 116 if (sw1 & IRQ_CPU_TO_EPU) {
116 memcpy_fromio(&mb, &cx->scb->cpu2epu_mb, sizeof(mb)); 117 cx18_memcpy_fromio(cx, &mb, &cx->scb->cpu2epu_mb, sizeof(mb));
117 mb.error = 0; 118 mb.error = 0;
118 119
119 switch (mb.cmd) { 120 switch (mb.cmd) {
@@ -141,16 +142,16 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
141 142
142 spin_lock(&cx->dma_reg_lock); 143 spin_lock(&cx->dma_reg_lock);
143 144
144 hw2_mask = read_reg(HW2_INT_MASK5_PCI); 145 hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI);
145 hw2 = read_reg(HW2_INT_CLR_STATUS) & hw2_mask; 146 hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask;
146 sw2_mask = read_reg(SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK; 147 sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK;
147 sw2 = read_reg(SW2_INT_STATUS) & sw2_mask; 148 sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask;
148 sw1_mask = read_reg(SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU; 149 sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU;
149 sw1 = read_reg(SW1_INT_STATUS) & sw1_mask; 150 sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask;
150 151
151 write_reg(sw2&sw2_mask, SW2_INT_STATUS); 152 cx18_write_reg(cx, sw2&sw2_mask, SW2_INT_STATUS);
152 write_reg(sw1&sw1_mask, SW1_INT_STATUS); 153 cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS);
153 write_reg(hw2&hw2_mask, HW2_INT_CLR_STATUS); 154 cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS);
154 155
155 if (sw1 || sw2 || hw2) 156 if (sw1 || sw2 || hw2)
156 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); 157 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
@@ -161,15 +162,15 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
161 */ 162 */
162 163
163 if (sw2) { 164 if (sw2) {
164 if (sw2 & (readl(&cx->scb->cpu2hpu_irq_ack) | 165 if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) |
165 readl(&cx->scb->cpu2epu_irq_ack))) 166 cx18_readl(cx, &cx->scb->cpu2epu_irq_ack)))
166 wake_up(&cx->mb_cpu_waitq); 167 wake_up(&cx->mb_cpu_waitq);
167 if (sw2 & (readl(&cx->scb->apu2hpu_irq_ack) | 168 if (sw2 & (cx18_readl(cx, &cx->scb->apu2hpu_irq_ack) |
168 readl(&cx->scb->apu2epu_irq_ack))) 169 cx18_readl(cx, &cx->scb->apu2epu_irq_ack)))
169 wake_up(&cx->mb_apu_waitq); 170 wake_up(&cx->mb_apu_waitq);
170 if (sw2 & readl(&cx->scb->epu2hpu_irq_ack)) 171 if (sw2 & cx18_readl(cx, &cx->scb->epu2hpu_irq_ack))
171 wake_up(&cx->mb_epu_waitq); 172 wake_up(&cx->mb_epu_waitq);
172 if (sw2 & readl(&cx->scb->hpu2epu_irq_ack)) 173 if (sw2 & cx18_readl(cx, &cx->scb->hpu2epu_irq_ack))
173 wake_up(&cx->mb_hpu_waitq); 174 wake_up(&cx->mb_hpu_waitq);
174 } 175 }
175 176
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 1b9fbf9a6bc5..9d18dd22de76 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -22,6 +22,7 @@
22#include <stdarg.h> 22#include <stdarg.h>
23 23
24#include "cx18-driver.h" 24#include "cx18-driver.h"
25#include "cx18-io.h"
25#include "cx18-scb.h" 26#include "cx18-scb.h"
26#include "cx18-irq.h" 27#include "cx18-irq.h"
27#include "cx18-mailbox.h" 28#include "cx18-mailbox.h"
@@ -106,20 +107,20 @@ static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu
106 switch (rpu) { 107 switch (rpu) {
107 case APU: 108 case APU:
108 mb = &cx->scb->epu2apu_mb; 109 mb = &cx->scb->epu2apu_mb;
109 *state = readl(&cx->scb->apu_state); 110 *state = cx18_readl(cx, &cx->scb->apu_state);
110 *irq = readl(&cx->scb->epu2apu_irq); 111 *irq = cx18_readl(cx, &cx->scb->epu2apu_irq);
111 break; 112 break;
112 113
113 case CPU: 114 case CPU:
114 mb = &cx->scb->epu2cpu_mb; 115 mb = &cx->scb->epu2cpu_mb;
115 *state = readl(&cx->scb->cpu_state); 116 *state = cx18_readl(cx, &cx->scb->cpu_state);
116 *irq = readl(&cx->scb->epu2cpu_irq); 117 *irq = cx18_readl(cx, &cx->scb->epu2cpu_irq);
117 break; 118 break;
118 119
119 case HPU: 120 case HPU:
120 mb = &cx->scb->epu2hpu_mb; 121 mb = &cx->scb->epu2hpu_mb;
121 *state = readl(&cx->scb->hpu_state); 122 *state = cx18_readl(cx, &cx->scb->hpu_state);
122 *irq = readl(&cx->scb->epu2hpu_irq); 123 *irq = cx18_readl(cx, &cx->scb->epu2hpu_irq);
123 break; 124 break;
124 } 125 }
125 126
@@ -127,8 +128,8 @@ static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu
127 return mb; 128 return mb;
128 129
129 do { 130 do {
130 *req = readl(&mb->request); 131 *req = cx18_readl(cx, &mb->request);
131 ack = readl(&mb->ack); 132 ack = cx18_readl(cx, &mb->ack);
132 wait_count++; 133 wait_count++;
133 } while (*req != ack && wait_count < 600); 134 } while (*req != ack && wait_count < 600);
134 135
@@ -173,9 +174,9 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb)
173 return -EINVAL; 174 return -EINVAL;
174 } 175 }
175 176
176 setup_page(SCB_OFFSET); 177 cx18_setup_page(cx, SCB_OFFSET);
177 write_sync(mb->request, &ack_mb->ack); 178 cx18_write_sync(cx, mb->request, &ack_mb->ack);
178 write_reg(ack_irq, SW2_INT_SET); 179 cx18_write_reg(cx, ack_irq, SW2_INT_SET);
179 return 0; 180 return 0;
180} 181}
181 182
@@ -200,7 +201,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
200 CX18_DEBUG_HI_API("%s\n", info->name); 201 CX18_DEBUG_HI_API("%s\n", info->name);
201 else 202 else
202 CX18_DEBUG_API("%s\n", info->name); 203 CX18_DEBUG_API("%s\n", info->name);
203 setup_page(SCB_OFFSET); 204 cx18_setup_page(cx, SCB_OFFSET);
204 mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req); 205 mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req);
205 206
206 if (mb == NULL) { 207 if (mb == NULL) {
@@ -209,11 +210,11 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
209 } 210 }
210 211
211 oldreq = req - 1; 212 oldreq = req - 1;
212 writel(cmd, &mb->cmd); 213 cx18_writel(cx, cmd, &mb->cmd);
213 for (i = 0; i < args; i++) 214 for (i = 0; i < args; i++)
214 writel(data[i], &mb->args[i]); 215 cx18_writel(cx, data[i], &mb->args[i]);
215 writel(0, &mb->error); 216 cx18_writel(cx, 0, &mb->error);
216 writel(req, &mb->request); 217 cx18_writel(cx, req, &mb->request);
217 218
218 switch (info->rpu) { 219 switch (info->rpu) {
219 case APU: waitq = &cx->mb_apu_waitq; break; 220 case APU: waitq = &cx->mb_apu_waitq; break;
@@ -224,9 +225,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
224 } 225 }
225 if (info->flags & API_FAST) 226 if (info->flags & API_FAST)
226 timeout /= 2; 227 timeout /= 2;
227 write_reg(irq, SW1_INT_SET); 228 cx18_write_reg(cx, irq, SW1_INT_SET);
228 229
229 while (!sig && readl(&mb->ack) != readl(&mb->request) && cnt < 660) { 230 while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request)
231 && cnt < 660) {
230 if (cnt > 200 && !in_atomic()) 232 if (cnt > 200 && !in_atomic())
231 sig = cx18_msleep_timeout(10, 1); 233 sig = cx18_msleep_timeout(10, 1);
232 cnt++; 234 cnt++;
@@ -234,13 +236,13 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
234 if (sig) 236 if (sig)
235 return -EINTR; 237 return -EINTR;
236 if (cnt == 660) { 238 if (cnt == 660) {
237 writel(oldreq, &mb->request); 239 cx18_writel(cx, oldreq, &mb->request);
238 CX18_ERR("mb %s failed\n", info->name); 240 CX18_ERR("mb %s failed\n", info->name);
239 return -EINVAL; 241 return -EINVAL;
240 } 242 }
241 for (i = 0; i < MAX_MB_ARGUMENTS; i++) 243 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
242 data[i] = readl(&mb->args[i]); 244 data[i] = cx18_readl(cx, &mb->args[i]);
243 err = readl(&mb->error); 245 err = cx18_readl(cx, &mb->error);
244 if (!in_atomic() && (info->flags & API_SLOW)) 246 if (!in_atomic() && (info->flags & API_SLOW))
245 cx18_msleep_timeout(300, 0); 247 cx18_msleep_timeout(300, 0);
246 if (err) 248 if (err)
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index a33ba04a2686..48976833e238 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -170,6 +170,7 @@ int cx18_stream_alloc(struct cx18_stream *s)
170 } 170 }
171 buf->id = cx->buffer_id++; 171 buf->id = cx->buffer_id++;
172 INIT_LIST_HEAD(&buf->list); 172 INIT_LIST_HEAD(&buf->list);
173 /* FIXME - check for mmio */
173 buf->dma_handle = pci_map_single(s->cx->dev, 174 buf->dma_handle = pci_map_single(s->cx->dev,
174 buf->buf, s->buf_size, s->dma); 175 buf->buf, s->buf_size, s->dma);
175 cx18_buf_sync_for_cpu(s, buf); 176 cx18_buf_sync_for_cpu(s, buf);
@@ -193,6 +194,7 @@ void cx18_stream_free(struct cx18_stream *s)
193 194
194 /* empty q_free */ 195 /* empty q_free */
195 while ((buf = cx18_dequeue(s, &s->q_free))) { 196 while ((buf = cx18_dequeue(s, &s->q_free))) {
197 /* FIXME - check for mmio */
196 pci_unmap_single(s->cx->dev, buf->dma_handle, 198 pci_unmap_single(s->cx->dev, buf->dma_handle,
197 s->buf_size, s->dma); 199 s->buf_size, s->dma);
198 kfree(buf->buf); 200 kfree(buf->buf);
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 7f93bb13c09f..0c7df932d176 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -28,6 +28,7 @@
28static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s, 28static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
29 struct cx18_buffer *buf) 29 struct cx18_buffer *buf)
30{ 30{
31 /* FIXME check IO transfers */
31 pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle, 32 pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
32 s->buf_size, s->dma); 33 s->buf_size, s->dma);
33} 34}
@@ -35,6 +36,7 @@ static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
35static inline void cx18_buf_sync_for_device(struct cx18_stream *s, 36static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
36 struct cx18_buffer *buf) 37 struct cx18_buffer *buf)
37{ 38{
39 /* FIXME check IO transfers */
38 pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle, 40 pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
39 s->buf_size, s->dma); 41 s->buf_size, s->dma);
40} 42}
diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c
index 30bc803e30da..f56d3772aa67 100644
--- a/drivers/media/video/cx18/cx18-scb.c
+++ b/drivers/media/video/cx18/cx18-scb.c
@@ -20,102 +20,103 @@
20 */ 20 */
21 21
22#include "cx18-driver.h" 22#include "cx18-driver.h"
23#include "cx18-io.h"
23#include "cx18-scb.h" 24#include "cx18-scb.h"
24 25
25void cx18_init_scb(struct cx18 *cx) 26void cx18_init_scb(struct cx18 *cx)
26{ 27{
27 setup_page(SCB_OFFSET); 28 cx18_setup_page(cx, SCB_OFFSET);
28 memset_io(cx->scb, 0, 0x10000); 29 cx18_memset_io(cx, cx->scb, 0, 0x10000);
29 30
30 writel(IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq); 31 cx18_writel(cx, IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
31 writel(IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack); 32 cx18_writel(cx, IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
32 writel(IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq); 33 cx18_writel(cx, IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
33 writel(IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack); 34 cx18_writel(cx, IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
34 writel(IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq); 35 cx18_writel(cx, IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
35 writel(IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack); 36 cx18_writel(cx, IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
36 writel(IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq); 37 cx18_writel(cx, IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
37 writel(IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack); 38 cx18_writel(cx, IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
38 39
39 writel(IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq); 40 cx18_writel(cx, IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
40 writel(IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack); 41 cx18_writel(cx, IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
41 writel(IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq); 42 cx18_writel(cx, IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
42 writel(IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack); 43 cx18_writel(cx, IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
43 writel(IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq); 44 cx18_writel(cx, IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
44 writel(IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack); 45 cx18_writel(cx, IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
45 writel(IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq); 46 cx18_writel(cx, IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
46 writel(IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack); 47 cx18_writel(cx, IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
47 48
48 writel(IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq); 49 cx18_writel(cx, IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
49 writel(IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack); 50 cx18_writel(cx, IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
50 writel(IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq); 51 cx18_writel(cx, IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
51 writel(IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack); 52 cx18_writel(cx, IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
52 writel(IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq); 53 cx18_writel(cx, IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
53 writel(IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack); 54 cx18_writel(cx, IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
54 writel(IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq); 55 cx18_writel(cx, IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
55 writel(IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack); 56 cx18_writel(cx, IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
56 57
57 writel(IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq); 58 cx18_writel(cx, IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
58 writel(IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack); 59 cx18_writel(cx, IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
59 writel(IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq); 60 cx18_writel(cx, IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
60 writel(IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack); 61 cx18_writel(cx, IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
61 writel(IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq); 62 cx18_writel(cx, IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
62 writel(IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack); 63 cx18_writel(cx, IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
63 writel(IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq); 64 cx18_writel(cx, IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
64 writel(IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack); 65 cx18_writel(cx, IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
65 66
66 writel(IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq); 67 cx18_writel(cx, IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
67 writel(IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack); 68 cx18_writel(cx, IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
68 writel(IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq); 69 cx18_writel(cx, IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
69 writel(IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack); 70 cx18_writel(cx, IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
70 writel(IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq); 71 cx18_writel(cx, IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
71 writel(IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack); 72 cx18_writel(cx, IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
72 writel(IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq); 73 cx18_writel(cx, IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
73 writel(IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack); 74 cx18_writel(cx, IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
74 75
75 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb), 76 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
76 &cx->scb->apu2cpu_mb_offset); 77 &cx->scb->apu2cpu_mb_offset);
77 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb), 78 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
78 &cx->scb->hpu2cpu_mb_offset); 79 &cx->scb->hpu2cpu_mb_offset);
79 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb), 80 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
80 &cx->scb->ppu2cpu_mb_offset); 81 &cx->scb->ppu2cpu_mb_offset);
81 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb), 82 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
82 &cx->scb->epu2cpu_mb_offset); 83 &cx->scb->epu2cpu_mb_offset);
83 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb), 84 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
84 &cx->scb->cpu2apu_mb_offset); 85 &cx->scb->cpu2apu_mb_offset);
85 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb), 86 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
86 &cx->scb->hpu2apu_mb_offset); 87 &cx->scb->hpu2apu_mb_offset);
87 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb), 88 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
88 &cx->scb->ppu2apu_mb_offset); 89 &cx->scb->ppu2apu_mb_offset);
89 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb), 90 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
90 &cx->scb->epu2apu_mb_offset); 91 &cx->scb->epu2apu_mb_offset);
91 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb), 92 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
92 &cx->scb->cpu2hpu_mb_offset); 93 &cx->scb->cpu2hpu_mb_offset);
93 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb), 94 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
94 &cx->scb->apu2hpu_mb_offset); 95 &cx->scb->apu2hpu_mb_offset);
95 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb), 96 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
96 &cx->scb->ppu2hpu_mb_offset); 97 &cx->scb->ppu2hpu_mb_offset);
97 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb), 98 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
98 &cx->scb->epu2hpu_mb_offset); 99 &cx->scb->epu2hpu_mb_offset);
99 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb), 100 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
100 &cx->scb->cpu2ppu_mb_offset); 101 &cx->scb->cpu2ppu_mb_offset);
101 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb), 102 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
102 &cx->scb->apu2ppu_mb_offset); 103 &cx->scb->apu2ppu_mb_offset);
103 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb), 104 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
104 &cx->scb->hpu2ppu_mb_offset); 105 &cx->scb->hpu2ppu_mb_offset);
105 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb), 106 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
106 &cx->scb->epu2ppu_mb_offset); 107 &cx->scb->epu2ppu_mb_offset);
107 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb), 108 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
108 &cx->scb->cpu2epu_mb_offset); 109 &cx->scb->cpu2epu_mb_offset);
109 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb), 110 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
110 &cx->scb->apu2epu_mb_offset); 111 &cx->scb->apu2epu_mb_offset);
111 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb), 112 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
112 &cx->scb->hpu2epu_mb_offset); 113 &cx->scb->hpu2epu_mb_offset);
113 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb), 114 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
114 &cx->scb->ppu2epu_mb_offset); 115 &cx->scb->ppu2epu_mb_offset);
115 116
116 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu_state), 117 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
117 &cx->scb->ipc_offset); 118 &cx->scb->ipc_offset);
118 119
119 writel(1, &cx->scb->hpu_state); 120 cx18_writel(cx, 1, &cx->scb->hpu_state);
120 writel(1, &cx->scb->epu_state); 121 cx18_writel(cx, 1, &cx->scb->epu_state);
121} 122}
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 4d5b446895cb..c752a6a4dbd3 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include "cx18-driver.h" 24#include "cx18-driver.h"
25#include "cx18-io.h"
25#include "cx18-fileops.h" 26#include "cx18-fileops.h"
26#include "cx18-mailbox.h" 27#include "cx18-mailbox.h"
27#include "cx18-i2c.h" 28#include "cx18-i2c.h"
@@ -469,7 +470,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
469 470
470 if (atomic_read(&cx->tot_capturing) == 0) { 471 if (atomic_read(&cx->tot_capturing) == 0) {
471 clear_bit(CX18_F_I_EOS, &cx->i_flags); 472 clear_bit(CX18_F_I_EOS, &cx->i_flags);
472 write_reg(7, CX18_DSP0_INTERRUPT_MASK); 473 cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
473 } 474 }
474 475
475 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle, 476 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
@@ -479,8 +480,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
479 list_for_each(p, &s->q_free.list) { 480 list_for_each(p, &s->q_free.list) {
480 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); 481 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list);
481 482
482 writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr); 483 cx18_writel(cx, buf->dma_handle,
483 writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length); 484 &cx->scb->cpu_mdl[buf->id].paddr);
485 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
484 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 486 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
485 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 487 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
486 1, buf->id, s->buf_size); 488 1, buf->id, s->buf_size);
@@ -563,7 +565,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
563 if (atomic_read(&cx->tot_capturing) > 0) 565 if (atomic_read(&cx->tot_capturing) > 0)
564 return 0; 566 return 0;
565 567
566 write_reg(5, CX18_DSP0_INTERRUPT_MASK); 568 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
567 wake_up(&s->waitq); 569 wake_up(&s->waitq);
568 570
569 return 0; 571 return 0;