aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSteven Toth <stoth@hauppauge.com>2007-03-11 19:44:05 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:07:56 -0400
commitd19770e5178a4bc49641711246360c25781d20a4 (patch)
treea8984db06c4344b00718e958c12ee403eb339278 /drivers
parent275511a0aca8483c03df1c6e3a33a27cee334709 (diff)
V4L/DVB (6150): Add CX23885/CX23887 PCIe bridge driver
This is a new framework to support boards based on the CX23885/7 PCIe bridge. The framework supports digital (no analog yet) Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/cx23885/Kconfig17
-rw-r--r--drivers/media/video/cx23885/Makefile9
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c198
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c1601
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c199
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c375
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h429
-rw-r--r--drivers/media/video/cx23885/cx23885.h295
9 files changed, 3124 insertions, 0 deletions
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 00699c36ec1a..9e99d2e1c1bd 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -124,5 +124,6 @@ obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
124obj-$(CONFIG_VIDEO_IVTV) += ivtv/ 124obj-$(CONFIG_VIDEO_IVTV) += ivtv/
125 125
126obj-$(CONFIG_VIDEO_VIVI) += vivi.o 126obj-$(CONFIG_VIDEO_VIVI) += vivi.o
127obj-$(CONFIG_VIDEO_CX23885) += cx23885/
127 128
128EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 129EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
new file mode 100644
index 000000000000..ea53466dacbe
--- /dev/null
+++ b/drivers/media/video/cx23885/Kconfig
@@ -0,0 +1,17 @@
1config VIDEO_CX23885
2 tristate "Conexant cx23885 (2388x successor) support"
3 depends on VIDEO_DEV && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_BTCX
7 select VIDEO_BUF
8 select VIDEO_TUNER
9 select VIDEO_TVEEPROM
10 select VIDEO_IR
11 ---help---
12 This is a video4linux driver for Conexant 23885 based
13 TV cards.
14
15 To compile this driver as a module, choose M here: the
16 module will be called cx23885
17
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
new file mode 100644
index 000000000000..665067022d2a
--- /dev/null
+++ b/drivers/media/video/cx23885/Makefile
@@ -0,0 +1,9 @@
1cx23885-objs := cx23885-cards.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o
2
3obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
4
5EXTRA_CFLAGS += -Idrivers/media/video
6EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
7EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
8
9EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
new file mode 100644
index 000000000000..9344fb5d95f6
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -0,0 +1,198 @@
1/*
2 * Driver for the Conexant CX23885 PCIe bridge
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/pci.h>
25#include <linux/delay.h>
26
27#include "cx23885.h"
28
29/* ------------------------------------------------------------------ */
30/* board config info */
31
32struct cx23885_board cx23885_boards[] = {
33 [CX23885_BOARD_UNKNOWN] = {
34 .name = "UNKNOWN/GENERIC",
35 .bridge = CX23885_BRIDGE_UNDEFINED,
36 .input = {{
37 .type = CX23885_VMUX_COMPOSITE1,
38 .vmux = 0,
39 },{
40 .type = CX23885_VMUX_COMPOSITE2,
41 .vmux = 1,
42 },{
43 .type = CX23885_VMUX_COMPOSITE3,
44 .vmux = 2,
45 },{
46 .type = CX23885_VMUX_COMPOSITE4,
47 .vmux = 3,
48 }},
49 },
50 [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = {
51 .name = "Hauppauge WinTV-HVR1800lp",
52 .bridge = CX23885_BRIDGE_885,
53 .portc = CX23885_MPEG_DVB,
54 .input = {{
55 .type = CX23885_VMUX_TELEVISION,
56 .vmux = 0,
57 .gpio0 = 0xff00,
58 },{
59 .type = CX23885_VMUX_DEBUG,
60 .vmux = 0,
61 .gpio0 = 0xff01,
62 },{
63 .type = CX23885_VMUX_COMPOSITE1,
64 .vmux = 1,
65 .gpio0 = 0xff02,
66 },{
67 .type = CX23885_VMUX_SVIDEO,
68 .vmux = 2,
69 .gpio0 = 0xff02,
70 }},
71 },
72 [CX23885_BOARD_HAUPPAUGE_HVR1800] = {
73 .name = "Hauppauge WinTV-HVR1800",
74 .bridge = CX23885_BRIDGE_887,
75 .portc = CX23885_MPEG_DVB,
76 .input = {{
77 .type = CX23885_VMUX_TELEVISION,
78 .vmux = 0,
79 .gpio0 = 0xff00,
80 },{
81 .type = CX23885_VMUX_DEBUG,
82 .vmux = 0,
83 .gpio0 = 0xff01,
84 },{
85 .type = CX23885_VMUX_COMPOSITE1,
86 .vmux = 1,
87 .gpio0 = 0xff02,
88 },{
89 .type = CX23885_VMUX_SVIDEO,
90 .vmux = 2,
91 .gpio0 = 0xff02,
92 }},
93 },
94};
95const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
96
97/* ------------------------------------------------------------------ */
98/* PCI subsystem IDs */
99
100struct cx23885_subid cx23885_subids[] = {
101 {
102 .subvendor = 0x0070,
103 .subdevice = 0x3400,
104 .card = CX23885_BOARD_UNKNOWN,
105 },{
106 .subvendor = 0x0070,
107 .subdevice = 0x7600,
108 .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp,
109 },{
110 .subvendor = 0x0070,
111 .subdevice = 0x7800,
112 .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
113 },{
114 .subvendor = 0x0070,
115 .subdevice = 0x7801,
116 .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
117 },
118};
119const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
120
121void cx23885_card_list(struct cx23885_dev *dev)
122{
123 int i;
124
125 if (0 == dev->pci->subsystem_vendor &&
126 0 == dev->pci->subsystem_device) {
127 printk("%s: Your board has no valid PCIe Subsystem ID and thus can't\n"
128 "%s: be autodetected. Please pass card=<n> insmod option to\n"
129 "%s: workaround that. Redirect complaints to the vendor of\n"
130 "%s: the TV card. Best regards,\n"
131 "%s: -- tux\n",
132 dev->name, dev->name, dev->name, dev->name, dev->name);
133 } else {
134 printk("%s: Your board isn't known (yet) to the driver. You can\n"
135 "%s: try to pick one of the existing card configs via\n"
136 "%s: card=<n> insmod option. Updating to the latest\n"
137 "%s: version might help as well.\n",
138 dev->name, dev->name, dev->name, dev->name);
139 }
140 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
141 dev->name);
142 for (i = 0; i < cx23885_bcount; i++)
143 printk("%s: card=%d -> %s\n",
144 dev->name, i, cx23885_boards[i].name);
145}
146
147static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
148{
149 struct tveeprom tv;
150
151 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data);
152
153
154 /* Make sure we support the board model */
155 switch (tv.model)
156 {
157 case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
158 case 77001: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
159 case 78501: /* WinTV-HVR1800 (PCIe, Retail, IR, Dual channel ATSC and MPEG2 HW Encoder */
160 case 78521: /* WinTV-HVR1800 (PCIe, Retail, IR, Dual channel ATSC and MPEG2 HW Encoder */
161 break;
162 default:
163 printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model);
164 break;
165 }
166
167 printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n",
168 dev->name, tv.model);
169}
170
171void cx23885_card_setup(struct cx23885_dev *dev)
172{
173 static u8 eeprom[256];
174
175 if (dev->i2c_bus[0].i2c_rc == 0) {
176 dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
177 tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom));
178 }
179
180 switch (dev->board) {
181 case CX23885_BOARD_HAUPPAUGE_HVR1800:
182 case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
183 if (dev->i2c_bus[0].i2c_rc == 0)
184 hauppauge_eeprom(dev, eeprom+0x80);
185 break;
186 }
187}
188
189/* ------------------------------------------------------------------ */
190
191EXPORT_SYMBOL(cx23885_boards);
192
193/*
194 * Local variables:
195 * c-basic-offset: 8
196 * End:
197 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
198 */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
new file mode 100644
index 000000000000..876d396fb7a3
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -0,0 +1,1601 @@
1/*
2 * Driver for the Conexant CX23885 PCIe bridge
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/init.h>
23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/kmod.h>
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h>
30#include <linux/delay.h>
31#include <asm/div64.h>
32
33#include "cx23885.h"
34
35MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
36MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>");
37MODULE_LICENSE("GPL");
38
39static unsigned int debug = 0;
40module_param(debug,int,0644);
41MODULE_PARM_DESC(debug,"enable debug messages");
42
43static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
44module_param_array(card, int, NULL, 0444);
45MODULE_PARM_DESC(card,"card type");
46
47#define dprintk(level,fmt, arg...) if (debug >= level) \
48 printk(KERN_DEBUG "%s/0: " fmt, dev->name , ## arg)
49
50static unsigned int cx23885_devcount;
51
52static DEFINE_MUTEX(devlist);
53static LIST_HEAD(cx23885_devlist);
54
55#define NO_SYNC_LINE (-1U)
56
57/*
58 * CX23885 Assumptions
59 * 1 line = 16 bytes of CDT
60 * cmds size = 80
61 * cdt size = 16 * linesize
62 * iqsize = 64
63 * maxlines = 6
64 *
65 * Address Space:
66 * 0x00000000 0x00008fff FIFO clusters
67 * 0x00010000 0x000104af Channel Management Data Structures
68 * 0x000104b0 0x000104ff Free
69 * 0x00010500 0x000108bf 15 channels * iqsize
70 * 0x000108c0 0x000108ff Free
71 * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables
72 * 15 channels * (iqsize + (maxlines * linesize))
73 * 0x00010ea0 0x00010xxx Free
74 */
75
76struct sram_channel cx23885_sram_channels[] = {
77 [SRAM_CH01] = {
78 .name = "test ch1",
79 .cmds_start = 0x10000,
80 .ctrl_start = 0x10500,
81 .cdt = 0x10900,
82 .fifo_start = 0x3000,
83 .fifo_size = 0x1000,
84 .ptr1_reg = DMA1_PTR1,
85 .ptr2_reg = DMA1_PTR2,
86 .cnt1_reg = DMA1_CNT1,
87 .cnt2_reg = DMA1_CNT2,
88 .jumponly = 1,
89 },
90 [SRAM_CH02] = {
91 .name = "ch2",
92 .cmds_start = 0x0,
93 .ctrl_start = 0x0,
94 .cdt = 0x0,
95 .fifo_start = 0x0,
96 .fifo_size = 0x0,
97 .ptr1_reg = DMA2_PTR1,
98 .ptr2_reg = DMA2_PTR2,
99 .cnt1_reg = DMA2_CNT1,
100 .cnt2_reg = DMA2_CNT2,
101 },
102 [SRAM_CH03] = {
103 .name = "ch3",
104 .cmds_start = 0x0,
105 .ctrl_start = 0x0,
106 .cdt = 0x0,
107 .fifo_start = 0x0,
108 .fifo_size = 0x0,
109 .ptr1_reg = DMA3_PTR1,
110 .ptr2_reg = DMA3_PTR2,
111 .cnt1_reg = DMA3_CNT1,
112 .cnt2_reg = DMA3_CNT2,
113 },
114 [SRAM_CH04] = {
115 .name = "ch4",
116 .cmds_start = 0x0,
117 .ctrl_start = 0x0,
118 .cdt = 0x0,
119 .fifo_start = 0x0,
120 .fifo_size = 0x0,
121 .ptr1_reg = DMA4_PTR1,
122 .ptr2_reg = DMA4_PTR2,
123 .cnt1_reg = DMA4_CNT1,
124 .cnt2_reg = DMA4_CNT2,
125 },
126 [SRAM_CH05] = {
127 .name = "ch5",
128 .cmds_start = 0x0,
129 .ctrl_start = 0x0,
130 .cdt = 0x0,
131 .fifo_start = 0x0,
132 .fifo_size = 0x0,
133 .ptr1_reg = DMA5_PTR1,
134 .ptr2_reg = DMA5_PTR2,
135 .cnt1_reg = DMA5_CNT1,
136 .cnt2_reg = DMA5_CNT2,
137 },
138 [SRAM_CH06] = {
139 .name = "TS2 C",
140 .cmds_start = 0x10140,
141 .ctrl_start = 0x10680,
142 .cdt = 0x10480,
143 .fifo_start = 0x6000,
144 .fifo_size = 0x1000,
145 .ptr1_reg = DMA5_PTR1,
146 .ptr2_reg = DMA5_PTR2,
147 .cnt1_reg = DMA5_CNT1,
148 .cnt2_reg = DMA5_CNT2,
149 },
150 [SRAM_CH07] = {
151 .name = "ch7",
152 .cmds_start = 0x0,
153 .ctrl_start = 0x0,
154 .cdt = 0x0,
155 .fifo_start = 0x0,
156 .fifo_size = 0x0,
157 .ptr1_reg = DMA6_PTR1,
158 .ptr2_reg = DMA6_PTR2,
159 .cnt1_reg = DMA6_CNT1,
160 .cnt2_reg = DMA6_CNT2,
161 },
162 [SRAM_CH08] = {
163 .name = "ch8",
164 .cmds_start = 0x0,
165 .ctrl_start = 0x0,
166 .cdt = 0x0,
167 .fifo_start = 0x0,
168 .fifo_size = 0x0,
169 .ptr1_reg = DMA7_PTR1,
170 .ptr2_reg = DMA7_PTR2,
171 .cnt1_reg = DMA7_CNT1,
172 .cnt2_reg = DMA7_CNT2,
173 },
174 [SRAM_CH09] = {
175 .name = "ch9",
176 .cmds_start = 0x0,
177 .ctrl_start = 0x0,
178 .cdt = 0x0,
179 .fifo_start = 0x0,
180 .fifo_size = 0x0,
181 .ptr1_reg = DMA8_PTR1,
182 .ptr2_reg = DMA8_PTR2,
183 .cnt1_reg = DMA8_CNT1,
184 .cnt2_reg = DMA8_CNT2,
185 },
186};
187
188/* FIXME, these allocations will change when
189 * analog arrives. The be reviewed.
190 * CX23887 Assumptions
191 * 1 line = 16 bytes of CDT
192 * cmds size = 80
193 * cdt size = 16 * linesize
194 * iqsize = 64
195 * maxlines = 6
196 *
197 * Address Space:
198 * 0x00000000 0x00008fff FIFO clusters
199 * 0x00010000 0x000104af Channel Management Data Structures
200 * 0x000104b0 0x000104ff Free
201 * 0x00010500 0x000108bf 15 channels * iqsize
202 * 0x000108c0 0x000108ff Free
203 * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables
204 * 15 channels * (iqsize + (maxlines * linesize))
205 * 0x00010ea0 0x00010xxx Free
206 */
207
208struct sram_channel cx23887_sram_channels[] = {
209 [SRAM_CH01] = {
210 .name = "test ch1",
211 .cmds_start = 0x0,
212 .ctrl_start = 0x0,
213 .cdt = 0x0,
214 .fifo_start = 0x0,
215 .fifo_size = 0x0,
216 .ptr1_reg = DMA1_PTR1,
217 .ptr2_reg = DMA1_PTR2,
218 .cnt1_reg = DMA1_CNT1,
219 .cnt2_reg = DMA1_CNT2,
220 },
221 [SRAM_CH02] = {
222 .name = "ch2",
223 .cmds_start = 0x0,
224 .ctrl_start = 0x0,
225 .cdt = 0x0,
226 .fifo_start = 0x0,
227 .fifo_size = 0x0,
228 .ptr1_reg = DMA2_PTR1,
229 .ptr2_reg = DMA2_PTR2,
230 .cnt1_reg = DMA2_CNT1,
231 .cnt2_reg = DMA2_CNT2,
232 },
233 [SRAM_CH03] = {
234 .name = "ch3",
235 .cmds_start = 0x0,
236 .ctrl_start = 0x0,
237 .cdt = 0x0,
238 .fifo_start = 0x0,
239 .fifo_size = 0x0,
240 .ptr1_reg = DMA3_PTR1,
241 .ptr2_reg = DMA3_PTR2,
242 .cnt1_reg = DMA3_CNT1,
243 .cnt2_reg = DMA3_CNT2,
244 },
245 [SRAM_CH04] = {
246 .name = "ch4",
247 .cmds_start = 0x0,
248 .ctrl_start = 0x0,
249 .cdt = 0x0,
250 .fifo_start = 0x0,
251 .fifo_size = 0x0,
252 .ptr1_reg = DMA4_PTR1,
253 .ptr2_reg = DMA4_PTR2,
254 .cnt1_reg = DMA4_CNT1,
255 .cnt2_reg = DMA4_CNT2,
256 },
257 [SRAM_CH05] = {
258 .name = "ch5",
259 .cmds_start = 0x0,
260 .ctrl_start = 0x0,
261 .cdt = 0x0,
262 .fifo_start = 0x0,
263 .fifo_size = 0x0,
264 .ptr1_reg = DMA5_PTR1,
265 .ptr2_reg = DMA5_PTR2,
266 .cnt1_reg = DMA5_CNT1,
267 .cnt2_reg = DMA5_CNT2,
268 },
269 [SRAM_CH06] = {
270 .name = "TS2 C",
271 .cmds_start = 0x10140,
272 .ctrl_start = 0x10680,
273 .cdt = 0x10480,
274 .fifo_start = 0x6000,
275 .fifo_size = 0x1000,
276 .ptr1_reg = DMA5_PTR1,
277 .ptr2_reg = DMA5_PTR2,
278 .cnt1_reg = DMA5_CNT1,
279 .cnt2_reg = DMA5_CNT2,
280 },
281 [SRAM_CH07] = {
282 .name = "ch7",
283 .cmds_start = 0x0,
284 .ctrl_start = 0x0,
285 .cdt = 0x0,
286 .fifo_start = 0x0,
287 .fifo_size = 0x0,
288 .ptr1_reg = DMA6_PTR1,
289 .ptr2_reg = DMA6_PTR2,
290 .cnt1_reg = DMA6_CNT1,
291 .cnt2_reg = DMA6_CNT2,
292 },
293 [SRAM_CH08] = {
294 .name = "ch8",
295 .cmds_start = 0x0,
296 .ctrl_start = 0x0,
297 .cdt = 0x0,
298 .fifo_start = 0x0,
299 .fifo_size = 0x0,
300 .ptr1_reg = DMA7_PTR1,
301 .ptr2_reg = DMA7_PTR2,
302 .cnt1_reg = DMA7_CNT1,
303 .cnt2_reg = DMA7_CNT2,
304 },
305 [SRAM_CH09] = {
306 .name = "ch9",
307 .cmds_start = 0x0,
308 .ctrl_start = 0x0,
309 .cdt = 0x0,
310 .fifo_start = 0x0,
311 .fifo_size = 0x0,
312 .ptr1_reg = DMA8_PTR1,
313 .ptr2_reg = DMA8_PTR2,
314 .cnt1_reg = DMA8_CNT1,
315 .cnt2_reg = DMA8_CNT2,
316 },
317};
318
319static int cx23885_risc_decode(u32 risc)
320{
321 static char *instr[16] = {
322 [ RISC_SYNC >> 28 ] = "sync",
323 [ RISC_WRITE >> 28 ] = "write",
324 [ RISC_WRITEC >> 28 ] = "writec",
325 [ RISC_READ >> 28 ] = "read",
326 [ RISC_READC >> 28 ] = "readc",
327 [ RISC_JUMP >> 28 ] = "jump",
328 [ RISC_SKIP >> 28 ] = "skip",
329 [ RISC_WRITERM >> 28 ] = "writerm",
330 [ RISC_WRITECM >> 28 ] = "writecm",
331 [ RISC_WRITECR >> 28 ] = "writecr",
332 };
333 static int incr[16] = {
334 [ RISC_WRITE >> 28 ] = 3, // 2
335 [ RISC_JUMP >> 28 ] = 3, // 2
336 [ RISC_SKIP >> 28 ] = 1,
337 [ RISC_SYNC >> 28 ] = 1,
338 [ RISC_WRITERM >> 28 ] = 3,
339 [ RISC_WRITECM >> 28 ] = 3,
340 [ RISC_WRITECR >> 28 ] = 4,
341 };
342 static char *bits[] = {
343 "12", "13", "14", "resync",
344 "cnt0", "cnt1", "18", "19",
345 "20", "21", "22", "23",
346 "irq1", "irq2", "eol", "sol",
347 };
348 int i;
349
350 printk("0x%08x [ %s", risc,
351 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
352 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
353 if (risc & (1 << (i + 12)))
354 printk(" %s",bits[i]);
355 printk(" count=%d ]\n", risc & 0xfff);
356 return incr[risc >> 28] ? incr[risc >> 28] : 1;
357}
358
359void cx23885_wakeup(struct cx23885_tsport *port,
360 struct cx23885_dmaqueue *q, u32 count)
361{
362 struct cx23885_dev *dev = port->dev;
363 struct cx23885_buffer *buf;
364 int bc;
365
366 for (bc = 0;; bc++) {
367 if (list_empty(&q->active))
368 break;
369 buf = list_entry(q->active.next,
370 struct cx23885_buffer, vb.queue);
371 /* count comes from the hw and is is 16bit wide --
372 * this trick handles wrap-arounds correctly for
373 * up to 32767 buffers in flight... */
374 if ((s16) (count - buf->count) < 0)
375 break;
376 do_gettimeofday(&buf->vb.ts);
377 dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
378 count, buf->count);
379 buf->vb.state = STATE_DONE;
380 list_del(&buf->vb.queue);
381 wake_up(&buf->vb.done);
382 }
383 if (list_empty(&q->active)) {
384 del_timer(&q->timeout);
385 } else {
386 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
387 }
388 if (bc != 1)
389 printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
390}
391void cx23885_sram_channel_dump(struct cx23885_dev *dev,
392 struct sram_channel *ch);
393
394int cx23885_sram_channel_setup(struct cx23885_dev *dev,
395 struct sram_channel *ch,
396 unsigned int bpl, u32 risc)
397{
398 unsigned int i,lines;
399 u32 cdt;
400
401 if (ch->cmds_start == 0)
402 {
403 dprintk(1, "%s() Erasing channel [%s]\n",__FUNCTION__, ch->name);
404 cx_write(ch->ptr1_reg, 0);
405 cx_write(ch->ptr2_reg, 0);
406 cx_write(ch->cnt2_reg, 0);
407 cx_write(ch->cnt1_reg, 0);
408 return 0;
409 } else {
410 dprintk(1, "%s() Configuring channel [%s]\n",__FUNCTION__, ch->name);
411 }
412
413 bpl = (bpl + 7) & ~7; /* alignment */
414 cdt = ch->cdt;
415 lines = ch->fifo_size / bpl;
416 if (lines > 6)
417 lines = 6;
418 BUG_ON(lines < 2);
419
420 cx_write(8+0, cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC) );
421 cx_write(8+4, cpu_to_le32(8) );
422 cx_write(8+8, cpu_to_le32(0) );
423
424 /* write CDT */
425 for (i = 0; i < lines; i++) {
426 dprintk(2, "%s() 0x%08x <- 0x%08x\n", __FUNCTION__, cdt + 16*i, ch->fifo_start + bpl*i);
427 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
428 cx_write(cdt + 16*i + 4, 0);
429 cx_write(cdt + 16*i + 8, 0);
430 cx_write(cdt + 16*i + 12, 0);
431 }
432
433 /* write CMDS */
434 if (ch->jumponly)
435 cx_write(ch->cmds_start + 0, 8);
436 else
437 cx_write(ch->cmds_start + 0, risc);
438 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
439 cx_write(ch->cmds_start + 8, cdt);
440 cx_write(ch->cmds_start + 12, (lines*16) >> 3);
441 cx_write(ch->cmds_start + 16, ch->ctrl_start);
442 if (ch->jumponly)
443 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2) );
444 else
445 cx_write(ch->cmds_start + 20, 64 >> 2);
446 for (i = 24; i < 80; i += 4)
447 cx_write(ch->cmds_start + i, 0);
448
449 /* fill registers */
450 cx_write(ch->ptr1_reg, ch->fifo_start);
451 cx_write(ch->ptr2_reg, cdt);
452 cx_write(ch->cnt2_reg, (lines*16) >> 3);
453 cx_write(ch->cnt1_reg, (bpl >> 3) -1);
454
455 dprintk(2,"[bridged %d] sram setup %s: bpl=%d lines=%d\n",
456 cx23885_boards[dev->board].bridge,
457 ch->name,
458 bpl,
459 lines);
460
461 return 0;
462}
463
464void cx23885_sram_channel_dump(struct cx23885_dev *dev,
465 struct sram_channel *ch)
466{
467 static char *name[] = {
468 "init risc lo",
469 "init risc hi",
470 "cdt base",
471 "cdt size",
472 "iq base",
473 "iq size",
474 "risc pc lo",
475 "risc pc hi",
476 "iq wr ptr",
477 "iq rd ptr",
478 "cdt current",
479 "pci target lo",
480 "pci target hi",
481 "line / byte",
482 };
483 u32 risc;
484 unsigned int i,j,n;
485
486 printk("%s: %s - dma channel status dump\n",
487 dev->name, ch->name);
488 for (i = 0; i < ARRAY_SIZE(name); i++)
489 printk("%s: cmds: %-15s: 0x%08x\n",
490 dev->name, name[i],
491 cx_read(ch->cmds_start + 4*i));
492
493 for (i = 0; i < 4; i++) {
494 risc = cx_read(ch->cmds_start + 4 * (i+14));
495 printk("%s: risc%d: ", dev->name, i);
496 cx23885_risc_decode(risc);
497 }
498 for (i = 0; i < (64 >> 2); i += n) {
499 risc = cx_read(ch->ctrl_start + 4 * i); /* No consideration for bits 63-32 */
500 printk("%s: (0x%08x) iq %x: ", dev->name, ch->ctrl_start + 4 * i, i);
501 n = cx23885_risc_decode(risc);
502 for (j = 1; j < n; j++) {
503 risc = cx_read(ch->ctrl_start + 4 * (i+j));
504 printk("%s: iq %x: 0x%08x [ arg #%d ]\n",
505 dev->name, i+j, risc, j);
506 }
507 }
508
509 printk("%s: fifo: 0x%08x -> 0x%x\n",
510 dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
511 printk("%s: ctrl: 0x%08x -> 0x%x\n",
512 dev->name, ch->ctrl_start, ch->ctrl_start+6*16);
513 printk("%s: ptr1_reg: 0x%08x\n",
514 dev->name, cx_read(ch->ptr1_reg));
515 printk("%s: ptr2_reg: 0x%08x\n",
516 dev->name, cx_read(ch->ptr2_reg));
517 printk("%s: cnt1_reg: 0x%08x\n",
518 dev->name, cx_read(ch->cnt1_reg));
519 printk("%s: cnt2_reg: 0x%08x\n",
520 dev->name, cx_read(ch->cnt2_reg));
521}
522
523void cx23885_risc_disasm(struct cx23885_tsport *port, struct btcx_riscmem *risc)
524{
525 struct cx23885_dev *dev = port->dev;
526 unsigned int i,j,n;
527
528 printk("%s: risc disasm: %p [dma=0x%08lx]\n",
529 dev->name, risc->cpu, (unsigned long)risc->dma);
530 for (i = 0; i < (risc->size >> 2); i += n) {
531 printk("%s: %04d: ", dev->name, i);
532 n = cx23885_risc_decode(risc->cpu[i]);
533 for (j = 1; j < n; j++)
534 printk("%s: %04d: 0x%08x [ arg #%d ]\n",
535 dev->name, i+j, risc->cpu[i+j], j);
536 if (risc->cpu[i] == RISC_JUMP)
537 break;
538 }
539}
540
541void cx23885_shutdown(struct cx23885_dev *dev)
542{
543 /* disable RISC controller */
544 cx_write(DEV_CNTRL2, 0);
545
546 /* Disable all IR activity */
547 cx_write(IR_CNTRL_REG, 0);
548
549 /* Disable Video A/B activity */
550 cx_write(VID_A_DMA_CTL, 0);
551 cx_write(VID_B_DMA_CTL, 0);
552 cx_write(VID_C_DMA_CTL, 0);
553
554 /* Disable Audio activity */
555 cx_write(AUD_INT_DMA_CTL, 0);
556 cx_write(AUD_EXT_DMA_CTL, 0);
557
558 /* Disable Serial port */
559 cx_write(UART_CTL, 0);
560
561 /* Disable Interrupts */
562 cx_write(PCI_INT_MSK, 0);
563 cx_write(VID_A_INT_MSK, 0);
564 cx_write(VID_B_INT_MSK, 0);
565 cx_write(VID_C_INT_MSK, 0);
566 cx_write(AUDIO_INT_INT_MSK, 0);
567 cx_write(AUDIO_EXT_INT_MSK, 0);
568
569}
570
571void cx23885_reset(struct cx23885_dev *dev)
572{
573 dprintk(1, "%s()\n", __FUNCTION__);
574
575 cx23885_shutdown(dev);
576
577 cx_write(PCI_INT_STAT, 0xffffffff);
578 cx_write(VID_A_INT_STAT, 0xffffffff);
579 cx_write(VID_B_INT_STAT, 0xffffffff);
580 cx_write(VID_C_INT_STAT, 0xffffffff);
581 cx_write(AUDIO_INT_INT_STAT, 0xffffffff);
582 cx_write(AUDIO_EXT_INT_STAT, 0xffffffff);
583 cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
584
585 mdelay(100);
586
587#if SRAM
588 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH01 ], 188*4, 0);
589 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH02 ], 128, 0);
590 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH03 ], 128, 0);
591 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH04 ], 128, 0);
592 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH05 ], 128, 0);
593 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH06 ], 188*4, 0);
594 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH07 ], 128, 0);
595 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH08 ], 128, 0);
596 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH09 ], 128, 0);
597
598#else
599 // FIXME: Put a pointer to the sram_channel table in cx23885_dev
600 // and stop all this ugly switch/if code
601 switch(cx23885_boards[dev->board].bridge) {
602 case CX23885_BRIDGE_885:
603 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH01 ], 188*4, 0);
604 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH02 ], 128, 0);
605 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH03 ], 128, 0);
606 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH04 ], 128, 0);
607 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH05 ], 128, 0);
608 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH06 ], 188*4, 0);
609 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH07 ], 128, 0);
610 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH08 ], 128, 0);
611 cx23885_sram_channel_setup(dev, &cx23885_sram_channels[ SRAM_CH09 ], 128, 0);
612 break;
613 case CX23885_BRIDGE_887:
614 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH01 ], 188*4, 0);
615 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH02 ], 128, 0);
616 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH03 ], 128, 0);
617 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH04 ], 128, 0);
618 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH05 ], 128, 0);
619 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH06 ], 188*4, 0);
620 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH07 ], 128, 0);
621 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH08 ], 128, 0);
622 cx23885_sram_channel_setup(dev, &cx23887_sram_channels[ SRAM_CH09 ], 128, 0);
623 break;
624 default:
625 printk(KERN_ERR "%s() error, default case", __FUNCTION__ );
626 }
627#endif
628
629 switch(dev->board) {
630 case CX23885_BOARD_HAUPPAUGE_HVR1800:
631 /* GPIO-0 656_CLK */
632 /* GPIO-1 656_D0 */
633 /* GPIO-2 8295A Reset */
634 /* GPIO-3-10 cx23417 data0-7 */
635 /* GPIO-11-14 cx23417 addr0-3 */
636 /* GPIO-15-18 cx23417 READY, CS, RD, WR */
637 /* GPIO-19 IR_RX */
638 dprintk( 1, "%s() Configuring HVR1800 GPIO's\n", __FUNCTION__);
639 // FIXME: Analog requires the tuner is brought out of reset
640 break;
641 }
642}
643
644
645static int cx23885_pci_quirks(struct cx23885_dev *dev)
646{
647 dprintk(1, "%s()\n", __FUNCTION__);
648
649 switch(dev->board) {
650 case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
651 cx_clear(RDR_TLCTL0, 1 << 4);
652 break;
653 }
654 return 0;
655}
656
657static int get_resources(struct cx23885_dev *dev)
658{
659 if (request_mem_region(pci_resource_start(dev->pci,0),
660 pci_resource_len(dev->pci,0),
661 dev->name))
662 return 0;
663
664 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
665 dev->name, (unsigned long long)pci_resource_start(dev->pci,0));
666
667 return -EBUSY;
668}
669
670static void cx23885_timeout(unsigned long data);
671int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
672 u32 reg, u32 mask, u32 value);
673
674static int cx23885_ir_init(struct cx23885_dev *dev)
675{
676 dprintk(1, "%s()\n", __FUNCTION__);
677
678 switch (dev->board) {
679 case CX23885_BOARD_HAUPPAUGE_HVR1800:
680 dprintk(1, "%s() FIXME - Implement IR support\n", __FUNCTION__);
681 break;
682 }
683
684 return 0;
685}
686
687static int cx23885_dev_setup(struct cx23885_dev *dev)
688{
689 int i;
690
691 mutex_init(&dev->lock);
692
693 atomic_inc(&dev->refcount);
694
695 dev->nr = cx23885_devcount++;
696 dev->pci_bus = dev->pci->bus->number;
697 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
698 dev->pci_irqmask = 0x001f00;
699
700 /* External Master 1 Bus */
701 dev->i2c_bus[0].nr = 0;
702 dev->i2c_bus[0].dev = dev;
703 dev->i2c_bus[0].reg_stat = I2C1_STAT;
704 dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
705 dev->i2c_bus[0].reg_addr = I2C1_ADDR;
706 dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
707 dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
708 dev->i2c_bus[0].i2c_period = (0x9d << 24); /* 100kHz */
709
710 /* External Master 2 Bus */
711 dev->i2c_bus[1].nr = 1;
712 dev->i2c_bus[1].dev = dev;
713 dev->i2c_bus[1].reg_stat = I2C2_STAT;
714 dev->i2c_bus[1].reg_ctrl = I2C2_CTRL;
715 dev->i2c_bus[1].reg_addr = I2C2_ADDR;
716 dev->i2c_bus[1].reg_rdata = I2C2_RDATA;
717 dev->i2c_bus[1].reg_wdata = I2C2_WDATA;
718 dev->i2c_bus[1].i2c_period = (0x9d << 24); /* 100kHz */
719
720 /* Internal Master 3 Bus */
721 dev->i2c_bus[2].nr = 2;
722 dev->i2c_bus[2].dev = dev;
723 dev->i2c_bus[2].reg_stat = I2C3_STAT;
724 dev->i2c_bus[2].reg_ctrl = I2C3_CTRL;
725 dev->i2c_bus[2].reg_addr = I2C2_ADDR;
726 dev->i2c_bus[2].reg_rdata = I2C3_RDATA;
727 dev->i2c_bus[2].reg_wdata = I2C3_WDATA;
728 dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */
729
730 /* Transport bus init dma queue */
731 spin_lock_init(&dev->ts2.slock);
732 dev->ts2.dev = dev;
733 dev->ts2.nr = 2;
734 dev->ts2.sram_chno = SRAM_CH06;
735 INIT_LIST_HEAD(&dev->ts2.mpegq.active);
736 INIT_LIST_HEAD(&dev->ts2.mpegq.queued);
737 dev->ts2.mpegq.timeout.function = cx23885_timeout;
738 dev->ts2.mpegq.timeout.data = (unsigned long)&dev->ts2;
739 init_timer(&dev->ts2.mpegq.timeout);
740
741 dev->ts2.reg_gpcnt = VID_C_GPCNT;
742 dev->ts2.reg_gpcnt_ctl = VID_C_GPCNT_CTL;
743 dev->ts2.reg_dma_ctl = VID_C_DMA_CTL;
744 dev->ts2.reg_lngth = VID_C_LNGTH;
745 dev->ts2.reg_hw_sop_ctrl = VID_C_HW_SOP_CTL;
746 dev->ts2.reg_gen_ctrl = VID_C_GEN_CTL;
747 dev->ts2.reg_bd_pkt_status = VID_C_BD_PKT_STATUS;
748 dev->ts2.reg_sop_status = VID_C_SOP_STATUS;
749 dev->ts2.reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT;
750 dev->ts2.reg_vld_misc = VID_C_VLD_MISC;
751 dev->ts2.reg_ts_clk_en = VID_C_TS_CLK_EN;
752 dev->ts2.reg_ts_int_msk = VID_C_INT_MSK;
753
754 // FIXME: Make this board specific
755 dev->ts2.pci_irqmask = 0x04; /* TS Port 2 bit */
756 dev->ts2.dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */
757 dev->ts2.ts_int_msk_val = 0x1111; /* TS port bits for RISC */
758 dev->ts2.gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
759 dev->ts2.ts_clk_en_val = 0x1; /* Enable TS_CLK */
760
761 cx23885_risc_stopper(dev->pci, &dev->ts2.mpegq.stopper, dev->ts2.reg_dma_ctl, dev->ts2.dma_ctl_val, 0x00);
762
763 sprintf(dev->name,"cx23885[%d]", dev->nr);
764
765 if (get_resources(dev) < 0) {
766 printk(KERN_ERR "CORE %s No more PCIe resources for "
767 "subsystem: %04x:%04x\n",
768 dev->name, dev->pci->subsystem_vendor,
769 dev->pci->subsystem_device);
770
771 cx23885_devcount--;
772 goto fail_free;
773 }
774
775 mutex_lock(&devlist);
776 list_add_tail(&dev->devlist, &cx23885_devlist);
777 mutex_unlock(&devlist);
778
779 /* PCIe stuff */
780 dev->lmmio = ioremap(pci_resource_start(dev->pci,0),
781 pci_resource_len(dev->pci,0));
782
783 dev->bmmio = (u8 __iomem *)dev->lmmio;
784
785 cx23885_pci_quirks(dev);
786
787 /* board config */
788 dev->board = UNSET;
789 if (card[dev->nr] < cx23885_bcount)
790 dev->board = card[dev->nr];
791 for (i = 0; UNSET == dev->board && i < cx23885_idcount; i++)
792 if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor &&
793 dev->pci->subsystem_device == cx23885_subids[i].subdevice)
794 dev->board = cx23885_subids[i].card;
795 if (UNSET == dev->board) {
796 dev->board = CX23885_BOARD_UNKNOWN;
797 cx23885_card_list(dev);
798 }
799 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
800 dev->name, dev->pci->subsystem_vendor,
801 dev->pci->subsystem_device, cx23885_boards[dev->board].name,
802 dev->board, card[dev->nr] == dev->board ?
803 "insmod option" : "autodetected");
804
805 /* Configure the hardware internal memory for fifos */
806 switch(cx23885_boards[dev->board].bridge) {
807 case CX23885_BRIDGE_UNDEFINED:
808 case CX23885_BRIDGE_885:
809 dev->sram_channels = cx23885_sram_channels;
810 break;
811 case CX23885_BRIDGE_887:
812 dev->sram_channels = cx23887_sram_channels;
813 break;
814 default:
815 printk(KERN_ERR "%s() error, default case", __FUNCTION__ );
816 }
817
818 /* init hardware */
819 cx23885_reset(dev);
820
821 cx23885_i2c_register(&dev->i2c_bus[0]);
822 cx23885_i2c_register(&dev->i2c_bus[1]);
823 cx23885_i2c_register(&dev->i2c_bus[2]);
824 cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
825
826 cx23885_card_setup(dev);
827 cx23885_ir_init(dev);
828
829 if (cx23885_dvb_register(&dev->ts2) < 0) {
830 printk(KERN_ERR "%s() Failed to register dvb adapters\n", __FUNCTION__);
831 }
832
833 return 0;
834
835fail_free:
836 kfree(dev);
837 return -ENODEV;
838}
839
840void cx23885_dev_unregister(struct cx23885_dev *dev)
841{
842 release_mem_region(pci_resource_start(dev->pci,0),
843 pci_resource_len(dev->pci,0));
844
845 if (!atomic_dec_and_test(&dev->refcount))
846 return;
847
848 cx23885_dvb_unregister(&dev->ts2);
849 cx23885_i2c_unregister(&dev->i2c_bus[2]);
850 cx23885_i2c_unregister(&dev->i2c_bus[1]);
851 cx23885_i2c_unregister(&dev->i2c_bus[0]);
852
853 iounmap(dev->lmmio);
854}
855
856static u32* cx23885_risc_field(u32 *rp, struct scatterlist *sglist,
857 unsigned int offset, u32 sync_line,
858 unsigned int bpl, unsigned int padding,
859 unsigned int lines)
860{
861 struct scatterlist *sg;
862 unsigned int line,todo;
863
864 /* sync instruction */
865 if (sync_line != NO_SYNC_LINE)
866 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
867
868 /* scan lines */
869 sg = sglist;
870 for (line = 0; line < lines; line++) {
871 while (offset && offset >= sg_dma_len(sg)) {
872 offset -= sg_dma_len(sg);
873 sg++;
874 }
875 if (bpl <= sg_dma_len(sg)-offset) {
876 /* fits into current chunk */
877 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
878 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
879 *(rp++)=cpu_to_le32(0); /* bits 63-32 */
880 offset+=bpl;
881 } else {
882 /* scanline needs to be split */
883 todo = bpl;
884 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
885 (sg_dma_len(sg)-offset));
886 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
887 *(rp++)=cpu_to_le32(0); /* bits 63-32 */
888 todo -= (sg_dma_len(sg)-offset);
889 offset = 0;
890 sg++;
891 while (todo > sg_dma_len(sg)) {
892 *(rp++)=cpu_to_le32(RISC_WRITE|
893 sg_dma_len(sg));
894 *(rp++)=cpu_to_le32(sg_dma_address(sg));
895 *(rp++)=cpu_to_le32(0); /* bits 63-32 */
896 todo -= sg_dma_len(sg);
897 sg++;
898 }
899 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
900 *(rp++)=cpu_to_le32(sg_dma_address(sg));
901 *(rp++)=cpu_to_le32(0); /* bits 63-32 */
902 offset += todo;
903 }
904 offset += padding;
905 }
906
907 return rp;
908}
909
910int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
911 struct scatterlist *sglist,
912 unsigned int top_offset, unsigned int bottom_offset,
913 unsigned int bpl, unsigned int padding, unsigned int lines)
914{
915 u32 instructions,fields;
916 u32 *rp;
917 int rc;
918
919 fields = 0;
920 if (UNSET != top_offset)
921 fields++;
922 if (UNSET != bottom_offset)
923 fields++;
924
925 /* estimate risc mem: worst case is one write per page border +
926 one write per scan line + syncs + jump (all 2 dwords). Padding
927 can cause next bpl to start close to a page border. First DMA
928 region may be smaller than PAGE_SIZE */
929 /* write and jump need and extra dword */
930 instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
931 instructions += 2;
932 //if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
933 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
934 return rc;
935
936 /* write risc instructions */
937 rp = risc->cpu;
938 if (UNSET != top_offset)
939 rp = cx23885_risc_field(rp, sglist, top_offset, 0,
940 bpl, padding, lines);
941 if (UNSET != bottom_offset)
942 rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
943 bpl, padding, lines);
944
945 /* save pointer to jmp instruction address */
946 risc->jmp = rp;
947 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
948 return 0;
949}
950
951int cx23885_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
952 struct scatterlist *sglist, unsigned int bpl,
953 unsigned int lines)
954{
955 u32 instructions;
956 u32 *rp;
957 int rc;
958
959 /* estimate risc mem: worst case is one write per page border +
960 one write per scan line + syncs + jump (all 2 dwords). Here
961 there is no padding and no sync. First DMA region may be smaller
962 than PAGE_SIZE */
963 /* Jump and write need an extra dword */
964 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
965 instructions += 1;
966
967 //if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
968 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
969 return rc;
970
971 /* write risc instructions */
972 rp = risc->cpu;
973 rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
974
975 /* save pointer to jmp instruction address */
976 risc->jmp = rp;
977 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
978 return 0;
979}
980
981int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
982 u32 reg, u32 mask, u32 value)
983{
984 u32 *rp;
985 int rc;
986
987 if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
988 return rc;
989
990 /* write risc instructions */
991 rp = risc->cpu;
992 //*(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2 | RISC_IMM);
993 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2);
994 *(rp++) = cpu_to_le32(reg);
995 *(rp++) = cpu_to_le32(value);
996 *(rp++) = cpu_to_le32(mask);
997 *(rp++) = cpu_to_le32(RISC_JUMP);
998 *(rp++) = cpu_to_le32(risc->dma);
999 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1000 return 0;
1001}
1002
1003void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
1004{
1005 BUG_ON(in_interrupt());
1006 videobuf_waiton(&buf->vb,0,0);
1007 videobuf_dma_unmap(q, &buf->vb.dma);
1008 videobuf_dma_free(&buf->vb.dma);
1009 btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
1010 buf->vb.state = STATE_NEEDS_INIT;
1011}
1012
1013static int cx23885_start_dma(struct cx23885_tsport *port,
1014 struct cx23885_dmaqueue *q,
1015 struct cx23885_buffer *buf)
1016{
1017 struct cx23885_dev *dev = port->dev;
1018
1019 dprintk(1, "%s() w: %d, h: %d, f: %d\n", __FUNCTION__,
1020 buf->vb.width, buf->vb.height, buf->vb.field);
1021
1022#if SRAM
1023 /* setup fifo + format */
1024 cx23885_sram_channel_setup(dev,
1025 &dev->sram_channels[ port->sram_chno ],
1026 port->ts_packet_size, buf->risc.dma);
1027 if(debug > 5)
1028 cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ] );
1029#else
1030 // FIXME: Put a pointer to the sram_channel table in cx23885_dev
1031 // and stop all this ugly switch/if code
1032 switch(cx23885_boards[dev->board].bridge) {
1033 case CX23885_BRIDGE_885:
1034 cx23885_sram_channel_setup(dev,
1035 &cx23885_sram_channels[ port->sram_chno ],
1036 port->ts_packet_size, buf->risc.dma);
1037 if(debug > 5)
1038 cx23885_sram_channel_dump(dev, &cx23885_sram_channels[ port->sram_chno ] );
1039 break;
1040 case CX23885_BRIDGE_887:
1041 cx23885_sram_channel_setup(dev,
1042 &cx23887_sram_channels[ port->sram_chno ],
1043 port->ts_packet_size, buf->risc.dma);
1044 if(debug > 5)
1045 cx23885_sram_channel_dump(dev, &cx23887_sram_channels[ port->sram_chno ] );
1046 break;
1047 default:
1048 printk(KERN_ERR "%s() error, default case", __FUNCTION__ );
1049 }
1050#endif
1051
1052 if(debug > 5)
1053 cx23885_risc_disasm(port, &buf->risc);
1054
1055 /* write TS length to chip */
1056 cx_write(port->reg_lngth, buf->vb.width);
1057
1058 if (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) {
1059 printk( "%s() Failed. Unsupported value in .portc (0x%08x)\n", __FUNCTION__,
1060 cx23885_boards[dev->board].portc );
1061 return -EINVAL;
1062 }
1063
1064 // FIXME: review the need for these two lines
1065 dprintk( 1, "%s() doing .dvb\n", __FUNCTION__);
1066 udelay(100);
1067
1068 cx_write(port->reg_hw_sop_ctrl, 0x47 << 16 | 188 << 4);
1069 cx_write(port->reg_ts_clk_en, port->ts_clk_en_val);
1070
1071 // FIXME: review the need for this
1072 cx_write(GPIO2, 0x00);
1073
1074 switch (dev->board) {
1075 case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
1076 case CX23885_BOARD_HAUPPAUGE_HVR1800:
1077 cx_write(port->reg_vld_misc, 0x00);
1078 dprintk(1, "%s() Configuring HVR1800/lp/1500 board\n", __FUNCTION__);
1079 break;
1080 default:
1081 // FIXME
1082 printk(KERN_ERR "%s() error, default case", __FUNCTION__ );
1083 }
1084
1085 cx_write(port->reg_gen_ctrl, port->gen_ctrl_val);
1086 udelay(100);
1087
1088 /* reset counter to zero */
1089 cx_write(port->reg_gpcnt_ctl, 3);
1090 q->count = 1;
1091
1092 /* A bug in the current 887 implementation, causes an NMI assert during
1093 * starting or stopping interrupts or dma. Avoid the bug for the time being,
1094 * enabling the developer to work on the demod/tuner locking work.
1095 */
1096 switch(cx23885_boards[dev->board].bridge) {
1097 case CX23885_BRIDGE_885:
1098 /* enable irqs */
1099 dprintk(1, "%s() enabling TS int's and DMA\n", __FUNCTION__ );
1100 cx_set(port->reg_ts_int_msk, port->ts_int_msk_val);
1101 cx_set(port->reg_dma_ctl, port->dma_ctl_val);
1102 cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask);
1103 break;
1104 case CX23885_BRIDGE_887:
1105 // FIXME
1106 dprintk(1, "%s() NOT enabling TS int's and DMA, NMI bug\n", __FUNCTION__ );
1107 break;
1108 default:
1109 // FIXME: generate a sensible switch-default message
1110 printk(KERN_ERR "%s() error, default case", __FUNCTION__ );
1111 }
1112
1113 dprintk(1, "%s() Register Dump\n", __FUNCTION__);
1114 dprintk(1, "%s() set port ts_int_msk, now %x\n", __FUNCTION__, cx_read(port->reg_ts_int_msk) );
1115 dprintk(1, "%s() DEV_CNTRL2 0x%08x\n", __FUNCTION__, cx_read(DEV_CNTRL2) );
1116 dprintk(1, "%s() PCI_INT_MSK 0x%08x\n", __FUNCTION__, cx_read(PCI_INT_MSK) );
1117 dprintk(1, "%s() VID_A_INT_MSK 0x%08x\n", __FUNCTION__, cx_read(VID_A_INT_MSK) );
1118 dprintk(1, "%s() VID_B_INT_MSK 0x%08x\n", __FUNCTION__, cx_read(VID_B_INT_MSK) );
1119 dprintk(1, "%s() VID_C_INT_MSK 0x%08x\n", __FUNCTION__, cx_read(VID_C_INT_MSK) );
1120 dprintk(1, "%s() VID_A_DMA_CTL 0x%08x\n", __FUNCTION__, cx_read(VID_A_DMA_CTL) );
1121 dprintk(1, "%s() VID_B_DMA_CTL 0x%08x\n", __FUNCTION__, cx_read(VID_B_DMA_CTL) );
1122 dprintk(1, "%s() VID_C_DMA_CTL 0x%08x\n", __FUNCTION__, cx_read(VID_C_DMA_CTL) );
1123 dprintk(1, "%s() AUD_INT_INT_MSK 0x%08x\n", __FUNCTION__, cx_read(AUDIO_INT_INT_MSK) );
1124 dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08x\n", __FUNCTION__, cx_read(AUD_INT_DMA_CTL) );
1125 dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08x\n", __FUNCTION__, cx_read(AUDIO_EXT_INT_MSK) );
1126 dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08x\n", __FUNCTION__, cx_read(AUD_EXT_DMA_CTL) );
1127
1128 cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */
1129
1130 dprintk(1, "%s() set dev_cntrl2, now %x\n", __FUNCTION__, cx_read(DEV_CNTRL2) );
1131 dprintk(1, "%s() VID_C_DMA_CTL , now %x\n", __FUNCTION__, cx_read(port->reg_dma_ctl) );
1132 dprintk(1, "%s() VID_C_DMA_CTL , now %x\n", __FUNCTION__, cx_read(VID_C_DMA_CTL) );
1133 dprintk(1, "%s() PAD_CTRL %x\n", __FUNCTION__, cx_read(PAD_CTRL) );
1134 dprintk(1, "%s() GPIO2 %x\n", __FUNCTION__, cx_read(GPIO2) );
1135 dprintk(1, "%s() VID_C_LN_LNGTH , now %x\n", __FUNCTION__, cx_read(port->reg_lngth) );
1136 dprintk(1, "%s() VID_C_HW_SOP_CTL, now %x\n", __FUNCTION__, cx_read(port->reg_hw_sop_ctrl) );
1137 dprintk(1, "%s() VID_C_GEN_CTL , now %x\n", __FUNCTION__, cx_read(port->reg_gen_ctrl) );
1138 dprintk(1, "%s() VID_C_SOP_STATUS, now %x\n", __FUNCTION__, cx_read(VID_C_SOP_STATUS) );
1139 dprintk(1, "%s() VID_C_TS_CLK_EN , now %x\n", __FUNCTION__, cx_read(VID_C_TS_CLK_EN) );
1140 dprintk(1, "%s() VID_C_FIFO_OVLST, now %x\n", __FUNCTION__, cx_read(VID_C_FIFO_OVFL_STAT) );
1141 dprintk(1, "%s() VID_C_INT_MSTAT , now 0x%08x\n", __FUNCTION__, cx_read(VID_C_INT_MSTAT) );
1142 return 0;
1143}
1144
1145static int cx23885_stop_dma(struct cx23885_tsport *port)
1146{
1147 struct cx23885_dev *dev = port->dev;
1148 dprintk(1, "%s()\n", __FUNCTION__);
1149
1150 /* Stop interrupts and DMA */
1151 cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val);
1152 cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
1153
1154 return 0;
1155}
1156
1157static int cx23885_restart_queue(struct cx23885_tsport *port,
1158 struct cx23885_dmaqueue *q)
1159{
1160 struct cx23885_dev *dev = port->dev;
1161 struct cx23885_buffer *buf;
1162 struct list_head *item;
1163
1164 dprintk(5, "%s()\n", __FUNCTION__);
1165 if (list_empty(&q->active))
1166 {
1167 struct cx23885_buffer *prev;
1168 prev = NULL;
1169
1170 dprintk(5, "%s() queue is empty\n", __FUNCTION__);
1171
1172 for (;;) {
1173 if (list_empty(&q->queued))
1174 return 0;
1175 buf = list_entry(q->queued.next, struct cx23885_buffer, vb.queue);
1176 if (NULL == prev) {
1177 list_del(&buf->vb.queue);
1178 list_add_tail(&buf->vb.queue,&q->active);
1179 cx23885_start_dma(port, q, buf);
1180 buf->vb.state = STATE_ACTIVE;
1181 buf->count = q->count++;
1182 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
1183 dprintk(5,"[%p/%d] restart_queue - first active\n",
1184 buf,buf->vb.i);
1185
1186 } else if (prev->vb.width == buf->vb.width &&
1187 prev->vb.height == buf->vb.height &&
1188 prev->fmt == buf->fmt) {
1189 list_del(&buf->vb.queue);
1190 list_add_tail(&buf->vb.queue,&q->active);
1191 buf->vb.state = STATE_ACTIVE;
1192 buf->count = q->count++;
1193 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
1194 prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
1195 dprintk(5,"[%p/%d] restart_queue - move to active\n",
1196 buf,buf->vb.i);
1197 } else {
1198 return 0;
1199 }
1200 prev = buf;
1201 }
1202 return 0;
1203 }
1204
1205 buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
1206 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
1207 buf, buf->vb.i);
1208 cx23885_start_dma(port, q, buf);
1209 list_for_each(item,&q->active) {
1210 buf = list_entry(item, struct cx23885_buffer, vb.queue);
1211 buf->count = q->count++;
1212 }
1213 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
1214 return 0;
1215}
1216
1217/* ------------------------------------------------------------------ */
1218
1219int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
1220 struct cx23885_buffer *buf, enum v4l2_field field)
1221{
1222 struct cx23885_dev *dev = port->dev;
1223 int size = port->ts_packet_size * port->ts_packet_count;
1224 int rc;
1225
1226 dprintk(1, "%s: %p\n", __FUNCTION__, buf);
1227 if (0 != buf->vb.baddr && buf->vb.bsize < size)
1228 return -EINVAL;
1229
1230 if (STATE_NEEDS_INIT == buf->vb.state) {
1231 buf->vb.width = port->ts_packet_size;
1232 buf->vb.height = port->ts_packet_count;
1233 buf->vb.size = size;
1234 buf->vb.field = field /*V4L2_FIELD_TOP*/;
1235
1236 if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
1237 goto fail;
1238 cx23885_risc_databuffer(dev->pci, &buf->risc,
1239 buf->vb.dma.sglist,
1240 buf->vb.width, buf->vb.height);
1241 }
1242 buf->vb.state = STATE_PREPARED;
1243 return 0;
1244
1245 fail:
1246 cx23885_free_buffer(q,buf);
1247 return rc;
1248}
1249
1250void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
1251{
1252 struct cx23885_buffer *prev;
1253 struct cx23885_dev *dev = port->dev;
1254 struct cx23885_dmaqueue *cx88q = &port->mpegq;
1255
1256 /* add jump to stopper */
1257 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
1258 buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
1259 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
1260
1261 if (list_empty(&cx88q->active)) {
1262 dprintk( 1, "queue is empty - first active\n" );
1263 list_add_tail(&buf->vb.queue,&cx88q->active);
1264 cx23885_start_dma(port, cx88q, buf);
1265 buf->vb.state = STATE_ACTIVE;
1266 buf->count = cx88q->count++;
1267 mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
1268 dprintk(1,"[%p/%d] %s - first active\n",
1269 buf, buf->vb.i, __FUNCTION__);
1270
1271 } else {
1272 dprintk( 1, "queue is not empty - append to active\n" );
1273 prev = list_entry(cx88q->active.prev, struct cx23885_buffer, vb.queue);
1274 list_add_tail(&buf->vb.queue,&cx88q->active);
1275 buf->vb.state = STATE_ACTIVE;
1276 buf->count = cx88q->count++;
1277 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
1278 prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
1279 dprintk( 1, "[%p/%d] %s - append to active\n",
1280 buf, buf->vb.i, __FUNCTION__);
1281 }
1282}
1283
1284/* ----------------------------------------------------------- */
1285
1286static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, int restart)
1287{
1288 struct cx23885_dev *dev = port->dev;
1289 struct cx23885_dmaqueue *q = &port->mpegq;
1290 struct cx23885_buffer *buf;
1291 unsigned long flags;
1292
1293 spin_lock_irqsave(&port->slock,flags);
1294 while (!list_empty(&q->active)) {
1295 buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
1296 list_del(&buf->vb.queue);
1297 buf->vb.state = STATE_ERROR;
1298 wake_up(&buf->vb.done);
1299 dprintk(1,"[%p/%d] %s - dma=0x%08lx\n",
1300 buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
1301 }
1302 if (restart)
1303 {
1304 dprintk(1, "restarting queue\n" );
1305 cx23885_restart_queue(port, q);
1306 }
1307 spin_unlock_irqrestore(&port->slock,flags);
1308}
1309
1310void cx23885_cancel_buffers(struct cx23885_tsport *port)
1311{
1312 struct cx23885_dev *dev = port->dev;
1313 struct cx23885_dmaqueue *q = &port->mpegq;
1314
1315 dprintk(1, "%s()\n", __FUNCTION__ );
1316 del_timer_sync(&q->timeout);
1317 cx23885_stop_dma(port);
1318 do_cancel_buffers(port, "cancel", 0);
1319}
1320
1321static void cx23885_timeout(unsigned long data)
1322{
1323 struct cx23885_tsport *port = (struct cx23885_tsport *)data;
1324 struct cx23885_dev *dev = port->dev;
1325
1326 dprintk(1, "%s()\n",__FUNCTION__);
1327
1328 if (debug > 5)
1329#if SRAM
1330 cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]);
1331#else
1332 {
1333 // FIXME: Put a pointer to the sram_channel table in cx23885_dev
1334 // and stop all this ugly switch/if code
1335 if(cx23885_boards[dev->board].bridge == CX23885_BRIDGE_885)
1336 cx23885_sram_channel_dump(dev, &cx23885_sram_channels[ port->sram_chno ]);
1337 if(cx23885_boards[dev->board].bridge == CX23885_BRIDGE_887)
1338 cx23885_sram_channel_dump(dev, &cx23887_sram_channels[ port->sram_chno ]);
1339 }
1340#endif
1341 cx23885_stop_dma(port);
1342 do_cancel_buffers(port, "timeout", 1);
1343}
1344
1345#define PCI_MSK_APB_DMA (1 << 12)
1346#define PCI_MSK_AL_WR (1 << 11)
1347#define PCI_MSK_AL_RD (1 << 10)
1348#define PCI_MSK_RISC_WR (1 << 9)
1349#define PCI_MSK_RISC_RD (1 << 8)
1350
1351#define PCI_MSK_AUD_EXT (1 << 4)
1352#define PCI_MSK_AUD_INT (1 << 3)
1353#define PCI_MSK_VID_C (1 << 2)
1354#define PCI_MSK_VID_B (1 << 1)
1355#define PCI_MSK_VID_A 1
1356
1357#define VID_C_MSK_BAD_PKT (1 << 20)
1358#define VID_C_MSK_OPC_ERR (1 << 16)
1359#define VID_C_MSK_SYNC (1 << 12)
1360#define VID_C_MSK_OF (1 << 8)
1361#define VID_C_MSK_RISCI2 (1 << 4)
1362#define VID_C_MSK_RISCI1 1
1363
1364static irqreturn_t cx23885_irq(int irq, void *dev_id, struct pt_regs *regs)
1365{
1366 struct cx23885_dev *dev = dev_id;
1367 struct cx23885_tsport *port = &dev->ts2;
1368 u32 pci_status, pci_mask;
1369 u32 ts2_status, ts2_mask;
1370 int count = 0, handled = 0;
1371
1372 pci_status = cx_read(PCI_INT_STAT);
1373 pci_mask = cx_read(PCI_INT_MSK);
1374
1375 ts2_status = cx_read(VID_C_INT_STAT);
1376 ts2_mask = cx_read(VID_C_INT_MSK);
1377
1378 if ( (pci_status == 0) && (ts2_status == 0) )
1379 goto out;
1380
1381 count = cx_read(port->reg_gpcnt);
1382 dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n", pci_status, pci_mask );
1383 dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", ts2_status, ts2_mask, count );
1384
1385 if ( (pci_status & PCI_MSK_RISC_RD) ||
1386 (pci_status & PCI_MSK_RISC_WR) ||
1387 (pci_status & PCI_MSK_AL_RD) ||
1388 (pci_status & PCI_MSK_AL_WR) ||
1389 (pci_status & PCI_MSK_APB_DMA) ||
1390 (pci_status & PCI_MSK_VID_C) ||
1391 (pci_status & PCI_MSK_VID_B) ||
1392 (pci_status & PCI_MSK_VID_A) ||
1393 (pci_status & PCI_MSK_AUD_INT) ||
1394 (pci_status & PCI_MSK_AUD_EXT) )
1395 {
1396
1397 if (pci_status & PCI_MSK_RISC_RD)
1398 dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", PCI_MSK_RISC_RD);
1399 if (pci_status & PCI_MSK_RISC_WR)
1400 dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", PCI_MSK_RISC_WR);
1401 if (pci_status & PCI_MSK_AL_RD)
1402 dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", PCI_MSK_AL_RD);
1403 if (pci_status & PCI_MSK_AL_WR)
1404 dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", PCI_MSK_AL_WR);
1405 if (pci_status & PCI_MSK_APB_DMA)
1406 dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", PCI_MSK_APB_DMA);
1407 if (pci_status & PCI_MSK_VID_C)
1408 dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", PCI_MSK_VID_C);
1409 if (pci_status & PCI_MSK_VID_B)
1410 dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", PCI_MSK_VID_B);
1411 if (pci_status & PCI_MSK_VID_A)
1412 dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", PCI_MSK_VID_A);
1413 if (pci_status & PCI_MSK_AUD_INT)
1414 dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", PCI_MSK_AUD_INT);
1415 if (pci_status & PCI_MSK_AUD_EXT)
1416 dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", PCI_MSK_AUD_EXT);
1417
1418 }
1419
1420 if ( (ts2_status & VID_C_MSK_OPC_ERR) ||
1421 (ts2_status & VID_C_MSK_BAD_PKT) ||
1422 (ts2_status & VID_C_MSK_SYNC) ||
1423 (ts2_status & VID_C_MSK_OF))
1424 {
1425 if (ts2_status & VID_C_MSK_OPC_ERR)
1426 dprintk(7, " (VID_C_MSK_OPC_ERR 0x%08x)\n", VID_C_MSK_OPC_ERR);
1427 if (ts2_status & VID_C_MSK_BAD_PKT)
1428 dprintk(7, " (VID_C_MSK_BAD_PKT 0x%08x)\n", VID_C_MSK_BAD_PKT);
1429 if (ts2_status & VID_C_MSK_SYNC)
1430 dprintk(7, " (VID_C_MSK_SYNC 0x%08x)\n", VID_C_MSK_SYNC);
1431 if (ts2_status & VID_C_MSK_OF)
1432 dprintk(7, " (VID_C_MSK_OF 0x%08x)\n", VID_C_MSK_OF);
1433
1434 printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name);
1435
1436 cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
1437#if SRAM
1438 cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]);
1439#else
1440 cx23885_sram_channel_dump(dev, &cx23885_sram_channels[ port->sram_chno ]);
1441#endif
1442
1443
1444 } else if (ts2_status & VID_C_MSK_RISCI1) {
1445
1446 dprintk(7, " (RISCI1 0x%08x)\n", VID_C_MSK_RISCI1);
1447
1448 spin_lock(&port->slock);
1449 count = cx_read(port->reg_gpcnt);
1450 cx23885_wakeup(port, &port->mpegq, count);
1451 spin_unlock(&port->slock);
1452
1453 } else if (ts2_status & VID_C_MSK_RISCI2) {
1454
1455 dprintk(7, " (RISCI2 0x%08x)\n", VID_C_MSK_RISCI2);
1456
1457 spin_lock(&port->slock);
1458 cx23885_restart_queue(port, &port->mpegq);
1459 spin_unlock(&port->slock);
1460
1461 }
1462
1463 cx_write(VID_C_INT_STAT, ts2_status);
1464 cx_write(PCI_INT_STAT, pci_status);
1465 handled = 1;
1466out:
1467 return IRQ_RETVAL(handled);
1468}
1469
1470static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
1471 const struct pci_device_id *pci_id)
1472{
1473 struct cx23885_dev *dev;
1474 int err;
1475
1476 dev = kzalloc(sizeof(*dev),GFP_KERNEL);
1477 if (NULL == dev)
1478 return -ENOMEM;
1479
1480 /* pci init */
1481 dev->pci = pci_dev;
1482 if (pci_enable_device(pci_dev)) {
1483 err = -EIO;
1484 goto fail_free;
1485 }
1486
1487 if (cx23885_dev_setup(dev) < 0) {
1488 err = -EINVAL;
1489 goto fail_free;
1490 }
1491
1492 /* print pci info */
1493 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1494 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1495 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1496 "latency: %d, mmio: 0x%llx\n", dev->name,
1497 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1498 dev->pci_lat, (unsigned long long)pci_resource_start(pci_dev,0));
1499
1500 pci_set_master(pci_dev);
1501 if (!pci_dma_supported(pci_dev, 0xffffffff)) {
1502 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
1503 err = -EIO;
1504 goto fail_irq;
1505 }
1506
1507 err = request_irq(pci_dev->irq, cx23885_irq
1508 , IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
1509 if (err < 0) {
1510 printk(KERN_ERR "%s: can't get IRQ %d\n",
1511 dev->name, pci_dev->irq);
1512 goto fail_irq;
1513 }
1514
1515 pci_set_drvdata(pci_dev, dev);
1516 return 0;
1517
1518fail_irq:
1519 cx23885_dev_unregister(dev);
1520fail_free:
1521 kfree(dev);
1522 return err;
1523}
1524
1525static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
1526{
1527 struct cx23885_dev *dev = pci_get_drvdata(pci_dev);
1528
1529 cx23885_shutdown(dev);
1530
1531 pci_disable_device(pci_dev);
1532
1533 /* unregister stuff */
1534 free_irq(pci_dev->irq, dev);
1535 pci_set_drvdata(pci_dev, NULL);
1536
1537 mutex_lock(&devlist);
1538 list_del(&dev->devlist);
1539 mutex_unlock(&devlist);
1540
1541 cx23885_dev_unregister(dev);
1542 kfree(dev);
1543}
1544
1545static struct pci_device_id cx23885_pci_tbl[] = {
1546 {
1547 /* CX23885 */
1548 .vendor = 0x14f1,
1549 .device = 0x8852,
1550 .subvendor = PCI_ANY_ID,
1551 .subdevice = PCI_ANY_ID,
1552 },{
1553 /* CX23887 Rev 2 */
1554 .vendor = 0x14f1,
1555 .device = 0x8880,
1556 .subvendor = PCI_ANY_ID,
1557 .subdevice = PCI_ANY_ID,
1558 },{
1559 /* --- end of list --- */
1560 }
1561};
1562MODULE_DEVICE_TABLE(pci, cx23885_pci_tbl);
1563
1564static struct pci_driver cx23885_pci_driver = {
1565 .name = "cx23885",
1566 .id_table = cx23885_pci_tbl,
1567 .probe = cx23885_initdev,
1568 .remove = __devexit_p(cx23885_finidev),
1569 /* TODO */
1570 .suspend = NULL,
1571 .resume = NULL,
1572};
1573
1574static int cx23885_init(void)
1575{
1576 printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n",
1577 (CX88_VERSION_CODE >> 16) & 0xff,
1578 (CX88_VERSION_CODE >> 8) & 0xff,
1579 CX88_VERSION_CODE & 0xff);
1580#ifdef SNAPSHOT
1581 printk(KERN_INFO "cx23885: snapshot date %04d-%02d-%02d\n",
1582 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1583#endif
1584 return pci_register_driver(&cx23885_pci_driver);
1585}
1586
1587static void cx23885_fini(void)
1588{
1589 pci_unregister_driver(&cx23885_pci_driver);
1590}
1591
1592module_init(cx23885_init);
1593module_exit(cx23885_fini);
1594
1595/* ----------------------------------------------------------- */
1596/*
1597 * Local variables:
1598 * c-basic-offset: 8
1599 * End:
1600 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
1601 */
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
new file mode 100644
index 000000000000..4ff85f75f9f7
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -0,0 +1,199 @@
1/*
2 * Driver for the Conexant CX23885 PCIe bridge
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/device.h>
25#include <linux/fs.h>
26#include <linux/kthread.h>
27#include <linux/file.h>
28#include <linux/suspend.h>
29
30#include "cx23885.h"
31#include "dvb-pll.h"
32#include <media/v4l2-common.h>
33
34#include "s5h1409.h"
35#include "mt2131.h"
36
37static unsigned int debug = 2;
38
39#define dprintk(level,fmt, arg...) if (debug >= level) \
40 printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg)
41
42/* ------------------------------------------------------------------ */
43
44static int dvb_buf_setup(struct videobuf_queue *q,
45 unsigned int *count, unsigned int *size)
46{
47 struct cx23885_tsport *port = q->priv_data;
48
49 port->ts_packet_size = 188 * 4;
50 port->ts_packet_count = 32;
51
52 *size = port->ts_packet_size * port->ts_packet_count;
53 *count = 32;
54 return 0;
55}
56
57static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
58 enum v4l2_field field)
59{
60 struct cx23885_tsport *port = q->priv_data;
61 return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb,field);
62}
63
64static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
65{
66 struct cx23885_tsport *port = q->priv_data;
67 cx23885_buf_queue(port, (struct cx23885_buffer*)vb);
68}
69
70static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
71{
72 cx23885_free_buffer(q, (struct cx23885_buffer*)vb);
73}
74
75static struct videobuf_queue_ops dvb_qops = {
76 .buf_setup = dvb_buf_setup,
77 .buf_prepare = dvb_buf_prepare,
78 .buf_queue = dvb_buf_queue,
79 .buf_release = dvb_buf_release,
80};
81
82static struct s5h1409_config hauppauge_hvr1800lp_config = {
83 .demod_address = 0x32 >> 1,
84 .output_mode = S5H1409_SERIAL_OUTPUT,
85 .gpio = S5H1409_GPIO_OFF,
86 .if_freq = 44000,
87 .inversion = S5H1409_INVERSION_OFF
88};
89
90static struct s5h1409_config hauppauge_hvr1800_config = {
91 .demod_address = 0x32 >> 1,
92 .output_mode = S5H1409_SERIAL_OUTPUT,
93 .gpio = S5H1409_GPIO_ON,
94 .if_freq = 44000,
95 .inversion = S5H1409_INVERSION_OFF
96};
97
98
99static struct mt2131_config hauppauge_hvr1800lp_rev2_tunerconfig = {
100 0x61
101};
102
103static struct mt2131_config hauppauge_hvr1800_tunerconfig = {
104 0x61
105};
106
107static int dvb_register(struct cx23885_tsport *port)
108{
109 struct cx23885_dev *dev = port->dev;
110
111 /* init struct videobuf_dvb */
112 port->dvb.name = dev->name;
113
114 /* init frontend */
115 switch (dev->board) {
116 case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
117 port->dvb.frontend = dvb_attach(s5h1409_attach,
118 &hauppauge_hvr1800lp_config,
119 &dev->i2c_bus[0].i2c_adap);
120 if (port->dvb.frontend != NULL) {
121 dvb_attach(mt2131_attach,
122 port->dvb.frontend,
123 &dev->i2c_bus[0].i2c_adap,
124 &hauppauge_hvr1800lp_rev2_tunerconfig,
125 0);
126 }
127 break;
128 case CX23885_BOARD_HAUPPAUGE_HVR1800:
129 port->dvb.frontend = dvb_attach(s5h1409_attach,
130 &hauppauge_hvr1800_config,
131 &dev->i2c_bus[0].i2c_adap);
132 if (port->dvb.frontend != NULL) {
133 dvb_attach(mt2131_attach,
134 port->dvb.frontend,
135 &dev->i2c_bus[0].i2c_adap,
136 &hauppauge_hvr1800_tunerconfig,
137 0);
138 }
139 break;
140 default:
141 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
142 dev->name);
143 break;
144 }
145 if (NULL == port->dvb.frontend) {
146 printk("%s: frontend initialization failed\n", dev->name);
147 return -1;
148 }
149
150 /* Put the analog decoder in standby to keep it quiet */
151 cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
152
153 /* register everything */
154 return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, &dev->pci->dev);
155}
156
157int cx23885_dvb_register(struct cx23885_tsport *port)
158{
159 struct cx23885_dev *dev = port->dev;
160 int err;
161
162 dprintk( 1, "%s\n", __FUNCTION__);
163 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
164 dev->board,
165 dev->name,
166 dev->pci_bus,
167 dev->pci_slot);
168
169 err = -ENODEV;
170 if (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))
171 goto fail_core;
172
173 /* dvb stuff */
174 printk("%s: cx23885 based dvb card\n", dev->name);
175 videobuf_queue_init(
176 &port->dvb.dvbq,
177 &dvb_qops,
178 dev->pci,
179 &port->slock,
180 V4L2_BUF_TYPE_VIDEO_CAPTURE,
181 V4L2_FIELD_TOP,
182 sizeof(struct cx23885_buffer),
183 port);
184 err = dvb_register(port);
185 if (err != 0)
186 printk("%s() dvb_register failed err = %d\n", __FUNCTION__, err);
187
188 fail_core:
189 return err;
190}
191
192int cx23885_dvb_unregister(struct cx23885_tsport *port)
193{
194 /* dvb */
195 if(port->dvb.frontend)
196 videobuf_dvb_unregister(&port->dvb);
197
198 return 0;
199}
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
new file mode 100644
index 000000000000..6f5e207c11a6
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -0,0 +1,375 @@
1/*
2 * Driver for the Conexant CX23885 PCIe bridge
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <asm/io.h>
27
28#include "cx23885.h"
29
30#include <media/v4l2-common.h>
31
32static unsigned int i2c_debug = 2;
33module_param(i2c_debug, int, 0644);
34MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
35
36static unsigned int i2c_scan = 0;
37module_param(i2c_scan, int, 0444);
38MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
39
40#define dprintk(level,fmt, arg...) if (i2c_debug >= level) \
41 printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg)
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
49static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
50{
51 struct cx23885_i2c *bus = i2c_adap->algo_data;
52 struct cx23885_dev *dev = bus->dev;
53 return cx_read(bus->reg_stat) & 0x01;
54}
55
56static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
57{
58 struct cx23885_i2c *bus = i2c_adap->algo_data;
59 struct cx23885_dev *dev = bus->dev;
60 return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
61}
62
63static 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
79static int i2c_sendbytes(struct i2c_adapter *i2c_adap, const struct i2c_msg *msg, int last)
80{
81 struct cx23885_i2c *bus = i2c_adap->algo_data;
82 struct cx23885_dev *dev = bus->dev;
83 u32 wdata, addr, ctrl;
84 int retval, cnt;
85
86 dprintk(1, "%s()\n", __FUNCTION__);
87 /* Deal with i2c probe functions with zero payload */
88 if (msg->len == 0) {
89 cx_write(bus->reg_addr, msg->addr << 25);
90 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
91 if (!i2c_wait_done(i2c_adap))
92 return -EIO;
93 if (!i2c_slave_did_ack(i2c_adap))
94 return -EIO;
95
96 dprintk(1, "%s() returns 0\n", __FUNCTION__);
97 return 0;
98 }
99
100
101 /* dev, reg + first byte */
102 addr = (msg->addr << 25) | msg->buf[0];
103 wdata = msg->buf[0];
104 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
105
106 if (msg->len > 1)
107 ctrl |= I2C_NOSTOP | I2C_EXTEND;
108
109 cx_write(bus->reg_addr, addr);
110 cx_write(bus->reg_wdata, wdata);
111 cx_write(bus->reg_ctrl, ctrl);
112
113 retval = i2c_wait_done(i2c_adap);
114 if (retval < 0)
115 goto err;
116 if (retval == 0)
117 goto eio;
118 if (i2c_debug) {
119 printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]);
120 if (!(ctrl & I2C_NOSTOP))
121 printk(" >\n");
122 }
123
124 for (cnt = 1; cnt < msg->len; cnt++ ) {
125 /* following bytes */
126 wdata = msg->buf[cnt];
127 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
128
129 if (cnt < msg->len-1 || !last)
130 ctrl |= I2C_NOSTOP | I2C_EXTEND;
131
132 //printk("addr = 0x%08x wdata = 0x%08x ctrl = 0x%08x\n", addr, wdata, ctrl);
133 cx_write(bus->reg_addr, addr);
134 cx_write(bus->reg_wdata, wdata);
135 cx_write(bus->reg_ctrl, ctrl);
136
137 retval = i2c_wait_done(i2c_adap);
138 if (retval < 0)
139 goto err;
140 if (retval == 0)
141 goto eio;
142 if (i2c_debug) {
143 printk(" %02x", msg->buf[cnt]);
144 if (!(ctrl & I2C_NOSTOP))
145 printk(" >\n");
146 }
147 }
148 return msg->len;
149
150 eio:
151 retval = -EIO;
152 err:
153 printk(" ERR: %d\n",retval);
154 return retval;
155}
156
157static int i2c_readbytes(struct i2c_adapter *i2c_adap, const struct i2c_msg *msg, int last)
158{
159 struct cx23885_i2c *bus = i2c_adap->algo_data;
160 struct cx23885_dev *dev = bus->dev;
161 u32 ctrl, cnt;
162 int retval;
163
164 dprintk(1, "%s()\n", __FUNCTION__);
165
166 /* Deal with i2c probe functions with zero payload */
167 if (msg->len == 0) {
168 cx_write(bus->reg_addr, msg->addr << 25);
169 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
170 if (!i2c_wait_done(i2c_adap))
171 return -EIO;
172 if (!i2c_slave_did_ack(i2c_adap))
173 return -EIO;
174
175
176 dprintk(1, "%s() returns 0\n", __FUNCTION__);
177 return 0;
178 }
179
180 for(cnt = 0; cnt < msg->len; cnt++) {
181
182 ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
183
184 if (cnt < msg->len-1 || !last)
185 ctrl |= I2C_NOSTOP | I2C_EXTEND;
186
187 cx_write(bus->reg_addr, msg->addr << 25);
188 cx_write(bus->reg_ctrl, ctrl);
189
190 retval = i2c_wait_done(i2c_adap);
191 if (retval < 0)
192 goto err;
193 if (retval == 0)
194 goto eio;
195 msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
196 if (i2c_debug) {
197 if (!(ctrl & I2C_NOSTOP))
198 printk(" <R %02x", (msg->addr << 1) +1);
199 printk(" =%02x", msg->buf[cnt]);
200 if (!(ctrl & I2C_NOSTOP))
201 printk(" >\n");
202 }
203 }
204 return msg->len;
205
206 eio:
207 retval = -EIO;
208 err:
209 printk(" ERR: %d\n",retval);
210 return retval;
211}
212
213static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
214{
215 struct cx23885_i2c *bus = i2c_adap->algo_data;
216 struct cx23885_dev *dev = bus->dev;
217 int i, retval = 0;
218
219 dprintk(1, "%s(num = %d)\n", __FUNCTION__, num);
220
221 for (i = 0 ; i < num; i++) {
222 dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n"
223 , __FUNCTION__, num, msgs[i].addr, msgs[i].len);
224 if (msgs[i].flags & I2C_M_RD) {
225 /* read */
226 retval = i2c_readbytes(i2c_adap, &msgs[i], i+1 == num);
227 if (retval < 0)
228 goto err;
229 } else {
230 /* write */
231 retval = i2c_sendbytes(i2c_adap, &msgs[i], i+1 == num);
232 if (retval < 0)
233 goto err;
234 }
235 }
236 return num;
237
238 err:
239 return retval;
240}
241
242static int attach_inform(struct i2c_client *client)
243{
244 struct cx23885_dev *dev = i2c_get_adapdata(client->adapter);
245
246 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
247 client->driver->driver.name, client->addr, client->name);
248
249 if (!client->driver->command)
250 return 0;
251
252 return 0;
253}
254
255static int detach_inform(struct i2c_client *client)
256{
257 struct cx23885_dev *dev = i2c_get_adapdata(client->adapter);
258
259 dprintk(1, "i2c detach [client=%s]\n", client->name);
260
261 return 0;
262}
263
264void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd, void *arg)
265{
266// struct cx23885_dev *dev = bus->dev;
267
268 if (bus->i2c_rc != 0)
269 return;
270
271 i2c_clients_command(&bus->i2c_adap, cmd, arg);
272}
273
274static int cx23885_algo_control(struct i2c_adapter *adap,
275 unsigned int cmd, unsigned long arg)
276{
277 return 0;
278}
279
280static u32 cx23885_functionality(struct i2c_adapter *adap)
281{
282 return I2C_FUNC_SMBUS_EMUL;
283}
284
285static struct i2c_algorithm cx23885_i2c_algo_template = {
286 .master_xfer = i2c_xfer,
287 .algo_control = cx23885_algo_control,
288 .functionality = cx23885_functionality,
289};
290
291/* ----------------------------------------------------------------------- */
292
293static struct i2c_adapter cx23885_i2c_adap_template = {
294 .name = "cx23885",
295 .owner = THIS_MODULE,
296 .id = I2C_HW_B_CX23885,
297 .algo = &cx23885_i2c_algo_template,
298// .class = I2C_CLASS_TV_ANALOG,
299 .client_register = attach_inform,
300 .client_unregister = detach_inform,
301};
302
303static struct i2c_client cx23885_i2c_client_template = {
304 .name = "cx23885 internal",
305};
306
307static char *i2c_devs[128] = {
308 [ 0x32 >> 1 ] = "cx24227",
309 [ 0x88 >> 1 ] = "cx25837",
310 [ 0x84 >> 1 ] = "tda8295",
311 [ 0xa0 >> 1 ] = "eeprom",
312 [ 0xc0 >> 1 ] = "mt2131/tda8275",
313 [ 0xc2 >> 1 ] = "mt2131/tda8275",
314};
315
316static void do_i2c_scan(char *name, struct i2c_client *c)
317{
318 unsigned char buf;
319 int i,rc;
320
321 for (i = 0; i < 128; i++) {
322 c->addr = i;
323 rc = i2c_master_recv(c,&buf,0);
324 if (rc < 0)
325 continue;
326 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
327 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
328 }
329}
330
331/* init + register i2c algo-bit adapter */
332int cx23885_i2c_register(struct cx23885_i2c *bus)
333{
334 struct cx23885_dev *dev = bus->dev;
335
336 dprintk(1, "%s(bus = %d)\n", __FUNCTION__, bus->nr);
337
338 memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template, sizeof(bus->i2c_adap));
339 memcpy(&bus->i2c_algo, &cx23885_i2c_algo_template, sizeof(bus->i2c_algo));
340 memcpy(&bus->i2c_client, &cx23885_i2c_client_template, sizeof(bus->i2c_client));
341
342 bus->i2c_adap.dev.parent = &dev->pci->dev;
343
344 strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
345 bus->i2c_algo.data = bus;
346 bus->i2c_adap.algo_data = bus;
347 i2c_add_adapter(&bus->i2c_adap);
348
349 bus->i2c_client.adapter = &bus->i2c_adap;
350
351 if (0 == bus->i2c_rc) {
352 printk("%s: i2c bus %d registered\n", dev->name, bus->nr);
353 if (i2c_scan)
354 do_i2c_scan(dev->name, &bus->i2c_client);
355 } else
356 printk("%s: i2c bus %d register FAILED\n", dev->name, bus->nr);
357
358 return bus->i2c_rc;
359}
360
361int cx23885_i2c_unregister(struct cx23885_i2c *bus)
362{
363 i2c_del_adapter(&bus->i2c_adap);
364 return 0;
365}
366
367/* ----------------------------------------------------------------------- */
368
369EXPORT_SYMBOL(cx23885_call_i2c_clients);
370
371/*
372 * Local variables:
373 * c-basic-offset: 8
374 * End:
375 */
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
new file mode 100644
index 000000000000..5cb692f20d28
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -0,0 +1,429 @@
1/*
2 * Driver for the Conexant CX23885 PCIe bridge
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef _CX23885_REG_H_
23#define _CX23885_REG_H_
24
25
26/*
27Address Map
280x00000000 -> 0x00009000 TX SRAM (Fifos)
290x00010000 -> 0x00013c00 RX SRAM CMDS + CDT
30
31EACH CMDS struct is 0x80 bytes long
32
33DMAx_PTR1 = 0x03040 address of first cluster
34DMAx_PTR2 = 0x10600 address of the CDT
35DMAx_CNT1 = cluster size in (bytes >> 4) -1
36DMAx_CNT2 = total cdt size for all entries >> 3
37
38Cluster Descriptor entry = 4 DWORDS
39 DWORD 0 -> ptr to cluster
40 DWORD 1 Reserved
41 DWORD 2 Reserved
42 DWORD 3 Reserved
43
44Channel manager Data Structure entry = 20 DWORD
45 0 IntialProgramCounterLow
46 1 IntialProgramCounterHigh
47 2 ClusterDescriptorTableBase
48 3 ClusterDescriptorTableSize
49 4 InstructionQueueBase
50 5 InstructionQueueSize
51... Reserved
52 19 Reserved
53
54
55*/
56
57/* Risc Instructions */
58#define RISC_CNT_INC 0x00010000
59#define RISC_CNT_RESET 0x00030000
60#define RISC_IRQ1 0x01000000
61#define RISC_IRQ2 0x02000000
62#define RISC_EOL 0x04000000
63#define RISC_SOL 0x08000000
64#define RISC_WRITE 0x10000000
65#define RISC_SKIP 0x20000000
66#define RISC_JUMP 0x70000000
67#define RISC_SYNC 0x80000000
68#define RISC_RESYNC 0x80008000
69#define RISC_READ 0x90000000
70#define RISC_WRITERM 0xB0000000
71#define RISC_WRITECM 0xC0000000
72#define RISC_WRITECR 0xD0000000
73
74//#define RISC_SYNC_ODD 0x80000000
75//#define RISC_SYNC_EVEN 0x80000200
76//#define RISC_RESYNC_ODD 0x80008000
77//#define RISC_RESYNC_EVEN 0x80008200
78
79// Do we need these?
80#define RISC_WRITEC 0x50000000
81#define RISC_READC 0xA0000000
82
83// Is this used?
84#define RISC_IMM 0x00000001
85
86//#define RISC_CNT_NONE 0x00000000
87//#define RISC_CNT_RSVR 0x00020000
88//#define RISC_JMP_SRP 0x01
89
90/* Audio and Video Core */
91#define HOST_REG1 0x00000000
92#define HOST_REG2 0x00000001
93#define HOST_REG3 0x00000002
94
95/* Chip Configuration Registers */
96#define CHIP_CTRL 0x00000100
97#define AFE_CTRL 0x00000104
98#define VID_PLL_INT_POST 0x00000108
99#define VID_PLL_FRAC 0x0000010C
100#define AUX_PLL_INT_POST 0x00000110
101#define AUX_PLL_FRAC 0x00000114
102#define SYS_PLL_INT_POST 0x00000118
103#define SYS_PLL_FRAC 0x0000011C
104#define PIN_CTRL 0x00000120
105#define AUD_IO_CTRL 0x00000124
106#define AUD_LOCK1 0x00000128
107#define AUD_LOCK2 0x0000012C
108#define POWER_CTRL 0x00000130
109#define AFE_DIAG_CTRL1 0x00000134
110#define AFE_DIAG_CTRL3 0x0000013C
111#define PLL_DIAG_CTRL 0x00000140
112#define AFE_CLK_OUT_CTRL 0x00000144
113#define DLL1_DIAG_CTRL 0x0000015C
114
115/* GPIO[23:19] Output Enable */
116#define GPIO2_OUT_EN_REG 0x00000160
117/* GPIO[23:19] Data Registers */
118#define GPIO2 0x00000164
119
120#define IFADC_CTRL 0x00000180
121
122/* Infrared Remote Registers */
123#define IR_CNTRL_REG 0x00000200
124#define IR_TXCLK_REG 0x00000204
125#define IR_RXCLK_REG 0x00000208
126#define IR_CDUTY_REG 0x0000020C
127#define IR_STAT_REG 0x00000210
128#define IR_IRQEN_REG 0x00000214
129#define IR_FILTR_REG 0x00000218
130#define IR_FIFO_REG 0x0000023C
131
132/* Video Decoder Registers */
133#define MODE_CTRL 0x00000400
134#define OUT_CTRL1 0x00000404
135#define OUT_CTRL2 0x00000408
136#define GEN_STAT 0x0000040C
137#define INT_STAT_MASK 0x00000410
138#define LUMA_CTRL 0x00000414
139#define HSCALE_CTRL 0x00000418
140#define VSCALE_CTRL 0x0000041C
141#define CHROMA_CTRL 0x00000420
142#define VBI_LINE_CTRL1 0x00000424
143#define VBI_LINE_CTRL2 0x00000428
144#define VBI_LINE_CTRL3 0x0000042C
145#define VBI_LINE_CTRL4 0x00000430
146#define VBI_LINE_CTRL5 0x00000434
147#define VBI_FC_CFG 0x00000438
148#define VBI_MISC_CFG1 0x0000043C
149#define VBI_MISC_CFG2 0x00000440
150#define VBI_PAY1 0x00000444
151#define VBI_PAY2 0x00000448
152#define VBI_CUST1_CFG1 0x0000044C
153#define VBI_CUST1_CFG2 0x00000450
154#define VBI_CUST1_CFG3 0x00000454
155#define VBI_CUST2_CFG1 0x00000458
156#define VBI_CUST2_CFG2 0x0000045C
157#define VBI_CUST2_CFG3 0x00000460
158#define VBI_CUST3_CFG1 0x00000464
159#define VBI_CUST3_CFG2 0x00000468
160#define VBI_CUST3_CFG3 0x0000046C
161#define HORIZ_TIM_CTRL 0x00000470
162#define VERT_TIM_CTRL 0x00000474
163#define SRC_COMB_CFG 0x00000478
164#define CHROMA_VBIOFF_CFG 0x0000047C
165#define FIELD_COUNT 0x00000480
166#define MISC_TIM_CTRL 0x00000484
167#define DFE_CTRL1 0x00000488
168#define DFE_CTRL2 0x0000048C
169#define DFE_CTRL3 0x00000490
170#define PLL_CTRL 0x00000494
171#define HTL_CTRL 0x00000498
172#define COMB_CTRL 0x0000049C
173#define CRUSH_CTRL 0x000004A0
174#define SOFT_RST_CTRL 0x000004A4
175#define CX885_VERSION 0x000004B4
176#define VBI_PASS_CTRL 0x000004BC
177
178/* Audio Decoder Registers */
179/* 8051 Configuration */
180#define DL_CTL 0x00000800
181#define STD_DET_STATUS 0x00000804
182#define STD_DET_CTL 0x00000808
183#define DW8051_INT 0x0000080C
184#define GENERAL_CTL 0x00000810
185#define AAGC_CTL 0x00000814
186#define DEMATRIX_CTL 0x000008CC
187#define PATH1_CTL1 0x000008D0
188#define PATH1_VOL_CTL 0x000008D4
189#define PATH1_EQ_CTL 0x000008D8
190#define PATH1_SC_CTL 0x000008DC
191#define PATH2_CTL1 0x000008E0
192#define PATH2_VOL_CTL 0x000008E4
193#define PATH2_EQ_CTL 0x000008E8
194#define PATH2_SC_CTL 0x000008EC
195
196/* Sample Rate Converter */
197#define SRC_CTL 0x000008F0
198#define SRC_LF_COEF 0x000008F4
199#define SRC1_CTL 0x000008F8
200#define SRC2_CTL 0x000008FC
201#define SRC3_CTL 0x00000900
202#define SRC4_CTL 0x00000904
203#define SRC5_CTL 0x00000908
204#define SRC6_CTL 0x0000090C
205#define BAND_OUT_SEL 0x00000910
206#define I2S_N_CTL 0x00000914
207#define I2S_OUT_CTL 0x00000918
208#define AUTOCONFIG_REG 0x000009C4
209
210/* Audio ADC Registers */
211#define DSM_CTRL1 0x00000000
212#define DSM_CTRL2 0x00000001
213#define CHP_EN_CTRL 0x00000002
214#define CHP_CLK_CTRL1 0x00000004
215#define CHP_CLK_CTRL2 0x00000005
216#define BG_REF_CTRL 0x00000006
217#define SD2_SW_CTRL1 0x00000008
218#define SD2_SW_CTRL2 0x00000009
219#define SD2_BIAS_CTRL 0x0000000A
220#define AMP_BIAS_CTRL 0x0000000C
221#define CH_PWR_CTRL1 0x0000000E
222#define CH_PWR_CTRL2 0x0000000F
223#define DSM_STATUS1 0x00000010
224#define DSM_STATUS2 0x00000011
225#define DIG_CTL1 0x00000012
226#define DIG_CTL2 0x00000013
227#define I2S_TX_CFG 0x0000001A
228
229#define DEV_CNTRL2 0x00040000
230#define PCI_INT_MSK 0x00040010
231#define PCI_MSK_APB_DMA (1 << 12)
232#define PCI_MSK_AL_WR (1 << 11)
233#define PCI_MSK_AL_RD (1 << 10)
234#define PCI_MSK_RISC_WR (1 << 9)
235#define PCI_MSK_RISC_RD (1 << 8)
236#define PCI_MSK_AUD_EXT (1 << 4)
237#define PCI_MSK_AUD_INT (1 << 3)
238#define PCI_MSK_VID_C (1 << 2)
239#define PCI_MSK_VID_B (1 << 1)
240#define PCI_MSK_VID_A 1
241#define PCI_INT_STAT 0x00040014
242#define PCI_INT_MSTAT 0x00040018
243
244#define VID_A_INT_MSK 0x00040020
245#define VID_A_INT_STAT 0x00040024
246#define VID_A_INT_MSTAT 0x00040028
247#define VID_A_INT_SSTAT 0x0004002C
248
249#define VID_B_INT_MSK 0x00040030
250#define VID_B_INT_STAT 0x00040034
251#define VID_B_INT_MSTAT 0x00040038
252#define VID_B_INT_SSTAT 0x0004003C
253
254#define VID_C_INT_MSK 0x00040040
255#define VID_C_MSK_BAD_PKT (1 << 20)
256#define VID_C_MSK_OPC_ERR (1 << 16)
257#define VID_C_MSK_SYNC (1 << 12)
258#define VID_C_MSK_OF (1 << 8)
259#define VID_C_MSK_RISCI2 (1 << 4)
260#define VID_C_MSK_RISCI1 1
261#define VID_C_INT_STAT 0x00040044
262#define VID_C_INT_MSTAT 0x00040048
263#define VID_C_INT_SSTAT 0x0004004C
264
265#define AUDIO_INT_INT_MSK 0x00040050
266#define AUDIO_INT_INT_STAT 0x00040054
267#define AUDIO_INT_INT_MSTAT 0x00040058
268#define AUDIO_INT_INT_SSTAT 0x0004005C
269
270#define AUDIO_EXT_INT_MSK 0x00040060
271#define AUDIO_EXT_INT_STAT 0x00040064
272#define AUDIO_EXT_INT_MSTAT 0x00040068
273#define AUDIO_EXT_INT_SSTAT 0x0004006C
274
275#define RDR_CFG0 0x00050000
276#define RDR_CFG1 0x00050004
277#define RDR_TLCTL0 0x00050318
278
279/* APB DMAC Current Buffer Pointer */
280#define DMA1_PTR1 0x00100000
281#define DMA2_PTR1 0x00100004
282#define DMA3_PTR1 0x00100008
283#define DMA4_PTR1 0x0010000C
284#define DMA5_PTR1 0x00100010
285#define DMA6_PTR1 0x00100014
286#define DMA7_PTR1 0x00100018
287#define DMA8_PTR1 0x0010001C
288
289/* APB DMAC Current Table Pointer */
290#define DMA1_PTR2 0x00100040
291#define DMA2_PTR2 0x00100044
292#define DMA3_PTR2 0x00100048
293#define DMA4_PTR2 0x0010004C
294#define DMA5_PTR2 0x00100050
295#define DMA6_PTR2 0x00100054
296#define DMA7_PTR2 0x00100058
297#define DMA8_PTR2 0x0010005C
298
299/* APB DMAC Buffer Limit */
300#define DMA1_CNT1 0x00100080
301#define DMA2_CNT1 0x00100084
302#define DMA3_CNT1 0x00100088
303#define DMA4_CNT1 0x0010008C
304#define DMA5_CNT1 0x00100090
305#define DMA6_CNT1 0x00100094
306#define DMA7_CNT1 0x00100098
307#define DMA8_CNT1 0x0010009C
308
309/* APB DMAC Table Size */
310#define DMA1_CNT2 0x001000C0
311#define DMA2_CNT2 0x001000C4
312#define DMA3_CNT2 0x001000C8
313#define DMA4_CNT2 0x001000CC
314#define DMA5_CNT2 0x001000D0
315#define DMA6_CNT2 0x001000D4
316#define DMA7_CNT2 0x001000D8
317#define DMA8_CNT2 0x001000DC
318
319/* Timer Counters */
320#define TM_CNT_LDW 0x00110000
321#define TM_CNT_UW 0x00110004
322#define TM_LMT_LDW 0x00110008
323#define TM_LMT_UW 0x0011000C
324
325/* GPIO */
326#define GP0_IO 0x00110010
327#define GPIO_ISM 0x00110014
328#define SOFT_RESET 0x0011001C
329
330/* GPIO (417 Microsoftcontroller) RW Data */
331#define MC417_RWD 0x00110020
332
333/* GPIO (417 Microsoftcontroller) Output Enable, Low Active */
334#define MC417_OEN 0x00110024
335#define MC417_CTL 0x00110028
336#define CLK_DELAY 0x00110048
337#define PAD_CTRL 0x0011004C
338
339/* Video A Interface */
340#define VID_A_GPCNT 0x00130020
341#define VBI_A_GPCNT 0x00130024
342#define VID_A_GPCNT_CTL 0x00130030
343#define VBI_A_GPCNT_CTL 0x00130034
344#define VID_A_DMA_CTL 0x00130040
345#define VID_A_VIP_CTRL 0x00130080
346#define VID_A_PIXEL_FRMT 0x00130084
347#define VID_A_VBI_CTRL 0x00130088
348
349/* Video B Interface */
350#define VID_B_DMA 0x00130100
351#define VBI_B_DMA 0x00130108
352#define VID_B_GPCNT 0x00130120
353#define VBI_B_GPCNT 0x00130124
354#define VID_B_GPCNT_CTL 0x00130130
355#define VBI_B_GPCNT_CTL 0x00130134
356#define VID_B_DMA_CTL 0x00130140
357#define VID_B_SRC_SEL 0x00130144
358#define VID_B_LNGTH 0x00130150
359#define VID_B_HW_SOP_CTL 0x00130154
360#define VID_B_GEN_CTL 0x00130158
361#define VID_B_BD_PKT_STATUS 0x0013015C
362#define VID_B_SOP_STATUS 0x00130160
363#define VID_B_FIFO_OVFL_STAT 0x00130164
364#define VID_B_VLD_MISC 0x00130168
365#define VID_B_TS_CLK_EN 0x0013016C
366#define VID_B_VIP_CTRL 0x00130180
367#define VID_B_PIXEL_FRMT 0x00130184
368
369/* Video C Interface */
370#define VID_C_GPCNT 0x00130220
371#define VID_C_GPCNT_CTL 0x00130230
372#define VBI_C_GPCNT_CTL 0x00130234
373#define VID_C_DMA_CTL 0x00130240
374#define VID_C_LNGTH 0x00130250
375#define VID_C_HW_SOP_CTL 0x00130254
376#define VID_C_GEN_CTL 0x00130258
377#define VID_C_BD_PKT_STATUS 0x0013025C
378#define VID_C_SOP_STATUS 0x00130260
379#define VID_C_FIFO_OVFL_STAT 0x00130264
380#define VID_C_VLD_MISC 0x00130268
381#define VID_C_TS_CLK_EN 0x0013026C
382
383/* Internal Audio Interface */
384#define AUD_INT_A_GPCNT 0x00140020
385#define AUD_INT_B_GPCNT 0x00140024
386#define AUD_INT_A_GPCNT_CTL 0x00140030
387#define AUD_INT_B_GPCNT_CTL 0x00140034
388#define AUD_INT_DMA_CTL 0x00140040
389#define AUD_INT_A_LNGTH 0x00140050
390#define AUD_INT_B_LNGTH 0x00140054
391#define AUD_INT_A_MODE 0x00140058
392#define AUD_INT_B_MODE 0x0014005C
393
394/* External Audio Interface */
395#define AUD_EXT_DMA 0x00140100
396#define AUD_EXT_GPCNT 0x00140120
397#define AUD_EXT_GPCNT_CTL 0x00140130
398#define AUD_EXT_DMA_CTL 0x00140140
399#define AUD_EXT_LNGTH 0x00140150
400#define AUD_EXT_A_MODE 0x00140158
401
402/* I2C Bus 1 */
403#define I2C1_ADDR 0x00180000
404#define I2C1_WDATA 0x00180004
405#define I2C1_CTRL 0x00180008
406#define I2C1_RDATA 0x0018000C
407#define I2C1_STAT 0x00180010
408
409/* I2C Bus 2 */
410#define I2C2_ADDR 0x00190000
411#define I2C2_WDATA 0x00190004
412#define I2C2_CTRL 0x00190008
413#define I2C2_RDATA 0x0019000C
414#define I2C2_STAT 0x00190010
415
416/* I2C Bus 3 */
417#define I2C3_ADDR 0x001A0000
418#define I2C3_WDATA 0x001A0004
419#define I2C3_CTRL 0x001A0008
420#define I2C3_RDATA 0x001A000C
421#define I2C3_STAT 0x001A0010
422
423/* UART */
424#define UART_CTL 0x001B0000
425#define UART_BRD 0x001B0004
426#define UART_ISR 0x001B000C
427#define UART_CNT 0x001B0010
428
429#endif /* _CX23885_REG_H_ */
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
new file mode 100644
index 000000000000..f58ab86bd532
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -0,0 +1,295 @@
1/*
2 * Driver for the Conexant CX23885 PCIe bridge
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/pci.h>
23#include <linux/i2c.h>
24#include <linux/i2c-algo-bit.h>
25#include <linux/kdev_t.h>
26
27#include <media/v4l2-common.h>
28#include <media/tuner.h>
29#include <media/tveeprom.h>
30#include <media/video-buf.h>
31#include <media/video-buf-dvb.h>
32
33#include "btcx-risc.h"
34#include "cx23885-reg.h"
35
36#include <linux/version.h>
37#include <linux/mutex.h>
38
39#define CX88_VERSION_CODE KERNEL_VERSION(0,0,6)
40
41#define UNSET (-1U)
42
43#define CX23885_MAXBOARDS 8
44
45#define SRAM 0
46
47/* Max number of inputs by card */
48#define MAX_CX23885_INPUT 8
49
50//#define SHADOW_MAX 3
51
52#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
53
54#define CX23885_BOARD_NOAUTO UNSET
55#define CX23885_BOARD_UNKNOWN 0
56#define CX23885_BOARD_HAUPPAUGE_HVR1800lp 1
57#define CX23885_BOARD_HAUPPAUGE_HVR1800 2
58
59enum cx23885_itype {
60 CX23885_VMUX_COMPOSITE1 = 1,
61 CX23885_VMUX_COMPOSITE2,
62 CX23885_VMUX_COMPOSITE3,
63 CX23885_VMUX_COMPOSITE4,
64 CX23885_VMUX_SVIDEO,
65 CX23885_VMUX_TELEVISION,
66 CX23885_VMUX_CABLE,
67 CX23885_VMUX_DVB,
68 CX23885_VMUX_DEBUG,
69 CX23885_RADIO,
70};
71
72struct cx23885_fmt {
73 char *name;
74 u32 fourcc; /* v4l2 format id */
75 int depth;
76 int flags;
77 u32 cxformat;
78};
79
80/* buffer for one video frame */
81struct cx23885_buffer {
82 /* common v4l buffer stuff -- must be first */
83 struct videobuf_buffer vb;
84
85 /* cx23885 specific */
86 unsigned int bpl;
87 struct btcx_riscmem risc;
88 struct cx23885_fmt *fmt;
89 u32 count;
90};
91
92struct cx23885_input {
93 enum cx23885_itype type;
94 unsigned int vmux;
95 u32 gpio0, gpio1, gpio2, gpio3;
96};
97
98struct cx23885_board {
99 char *name;
100 enum {
101 CX23885_MPEG_UNDEFINED = 0,
102 CX23885_MPEG_DVB
103 } portc;
104 enum {
105 CX23885_BRIDGE_UNDEFINED = 0,
106 CX23885_BRIDGE_885 = 885,
107 CX23885_BRIDGE_887 = 887,
108 } bridge;
109 struct cx23885_input input[MAX_CX23885_INPUT];
110};
111
112struct cx23885_subid {
113 u16 subvendor;
114 u16 subdevice;
115 u32 card;
116};
117
118struct cx23885_i2c {
119 struct cx23885_dev *dev;
120
121 int nr;
122
123 /* i2c i/o */
124 struct i2c_adapter i2c_adap;
125 struct i2c_algo_bit_data i2c_algo;
126 struct i2c_client i2c_client;
127 u32 i2c_rc;
128
129 /* 885 registers used for raw addess */
130 u32 i2c_period;
131 u32 reg_ctrl;
132 u32 reg_stat;
133 u32 reg_addr;
134 u32 reg_rdata;
135 u32 reg_wdata;
136};
137
138struct cx23885_dmaqueue {
139 struct list_head active;
140 struct list_head queued;
141 struct timer_list timeout;
142 struct btcx_riscmem stopper;
143 u32 count;
144};
145
146struct cx23885_tsport {
147 struct cx23885_dev *dev;
148
149 int nr;
150 int sram_chno;
151
152 struct videobuf_dvb dvb;
153
154 /* dma queues */
155 struct cx23885_dmaqueue mpegq;
156 u32 ts_packet_size;
157 u32 ts_packet_count;
158
159 int width;
160 int height;
161
162 spinlock_t slock;
163
164 /* registers */
165 u32 reg_gpcnt;
166 u32 reg_gpcnt_ctl;
167 u32 reg_dma_ctl;
168 u32 reg_lngth;
169 u32 reg_hw_sop_ctrl;
170 u32 reg_gen_ctrl;
171 u32 reg_bd_pkt_status;
172 u32 reg_sop_status;
173 u32 reg_fifo_ovfl_stat;
174 u32 reg_vld_misc;
175 u32 reg_ts_clk_en;
176 u32 reg_ts_int_msk;
177
178 /* Default register vals */
179 int pci_irqmask;
180 u32 dma_ctl_val;
181 u32 ts_int_msk_val;
182 u32 gen_ctrl_val;
183 u32 ts_clk_en_val;
184};
185
186struct cx23885_dev {
187 struct list_head devlist;
188 atomic_t refcount;
189
190 /* pci stuff */
191 struct pci_dev *pci;
192 unsigned char pci_rev, pci_lat;
193 int pci_bus, pci_slot;
194 u32 __iomem *lmmio;
195 u8 __iomem *bmmio;
196 //u32 shadow[SHADOW_MAX];
197 int pci_irqmask;
198
199 /* I2C adapters: Master 1 and 2 (External) and Master 3 (Internal only) */
200 struct cx23885_i2c i2c_bus[3];
201
202 int nr;
203 struct mutex lock;
204
205 /* board details */
206 unsigned int board;
207 char name[32];
208
209 struct cx23885_tsport ts2;
210
211 /* sram configuration */
212 struct sram_channel *sram_channels;
213};
214
215#define SRAM_CH01 0 /* Video A */
216#define SRAM_CH02 1 /* VBI A */
217#define SRAM_CH03 2 /* Video B */
218#define SRAM_CH04 3 /* Transport via B */
219#define SRAM_CH05 4 /* VBI B */
220#define SRAM_CH06 5 /* Video C */
221#define SRAM_CH07 6 /* Transport via C */
222#define SRAM_CH08 7 /* Audio Internal A */
223#define SRAM_CH09 8 /* Audio Internal B */
224#define SRAM_CH10 9 /* Audio External */
225#define SRAM_CH11 10 /* COMB_3D_N */
226#define SRAM_CH12 11 /* Comb 3D N1 */
227#define SRAM_CH13 12 /* Comb 3D N2 */
228#define SRAM_CH14 13 /* MOE Vid */
229#define SRAM_CH15 14 /* MOE RSLT */
230
231struct sram_channel {
232 char *name;
233 u32 cmds_start;
234 u32 ctrl_start;
235 u32 cdt;
236 u32 fifo_start;;
237 u32 fifo_size;
238 u32 ptr1_reg;
239 u32 ptr2_reg;
240 u32 cnt1_reg;
241 u32 cnt2_reg;
242 u32 jumponly;
243};
244
245/* ----------------------------------------------------------- */
246
247#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
248#define cx_write(reg,value) writel((value), dev->lmmio + ((reg)>>2))
249
250#define cx_andor(reg,mask,value) \
251 writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
252 ((value) & (mask)), dev->lmmio+((reg)>>2))
253
254#define cx_set(reg,bit) cx_andor((reg),(bit),(bit))
255#define cx_clear(reg,bit) cx_andor((reg),(bit),0)
256
257
258extern int cx23885_sram_channel_setup(struct cx23885_dev *dev,
259 struct sram_channel *ch,
260 unsigned int bpl, u32 risc);
261
262/* ----------------------------------------------------------- */
263/* cx23885-cards.c */
264
265extern struct cx23885_board cx23885_boards[];
266extern const unsigned int cx23885_bcount;
267
268extern struct cx23885_subid cx23885_subids[];
269extern const unsigned int cx23885_idcount;
270
271extern void cx23885_card_list(struct cx23885_dev *dev);
272extern void cx23885_card_setup(struct cx23885_dev *dev);
273extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
274
275extern int cx23885_dvb_register(struct cx23885_tsport *port);
276extern int cx23885_dvb_unregister(struct cx23885_tsport *port);
277
278extern int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
279 struct cx23885_buffer *buf, enum v4l2_field field);
280
281extern void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf);
282extern void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf);
283
284/* ----------------------------------------------------------- */
285/* cx23885-i2c.c */
286extern int cx23885_i2c_register(struct cx23885_i2c *bus);
287extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
288extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd, void *arg);
289
290/*
291 * Local variables:
292 * c-basic-offset: 8
293 * End:
294 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
295 */