1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
/*
* Driver for the Conexant CX23885 PCIe bridge
*
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/pci.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/kdev_t.h>
#include <media/v4l2-common.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
#include <media/videobuf-dvb.h>
#include "btcx-risc.h"
#include "cx23885-reg.h"
#include <linux/version.h>
#include <linux/mutex.h>
#define CX23885_VERSION_CODE KERNEL_VERSION(0,0,1)
#define UNSET (-1U)
#define CX23885_MAXBOARDS 8
/* Max number of inputs by card */
#define MAX_CX23885_INPUT 8
#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
#define CX23885_BOARD_NOAUTO UNSET
#define CX23885_BOARD_UNKNOWN 0
#define CX23885_BOARD_HAUPPAUGE_HVR1800lp 1
#define CX23885_BOARD_HAUPPAUGE_HVR1800 2
#define CX23885_BOARD_HAUPPAUGE_HVR1250 3
#define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP 4
enum cx23885_itype {
CX23885_VMUX_COMPOSITE1 = 1,
CX23885_VMUX_COMPOSITE2,
CX23885_VMUX_COMPOSITE3,
CX23885_VMUX_COMPOSITE4,
CX23885_VMUX_SVIDEO,
CX23885_VMUX_TELEVISION,
CX23885_VMUX_CABLE,
CX23885_VMUX_DVB,
CX23885_VMUX_DEBUG,
CX23885_RADIO,
};
enum cx23885_src_sel_type {
CX23885_SRC_SEL_EXT_656_VIDEO = 0,
CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO
};
/* buffer for one video frame */
struct cx23885_buffer {
/* common v4l buffer stuff -- must be first */
struct videobuf_buffer vb;
/* cx23885 specific */
unsigned int bpl;
struct btcx_riscmem risc;
struct cx23885_fmt *fmt;
u32 count;
};
struct cx23885_input {
enum cx23885_itype type;
unsigned int vmux;
u32 gpio0, gpio1, gpio2, gpio3;
};
typedef enum {
CX23885_MPEG_UNDEFINED = 0,
CX23885_MPEG_DVB
} port_t;
struct cx23885_board {
char *name;
port_t portb, portc;
struct cx23885_input input[MAX_CX23885_INPUT];
};
struct cx23885_subid {
u16 subvendor;
u16 subdevice;
u32 card;
};
struct cx23885_i2c {
struct cx23885_dev *dev;
int nr;
/* i2c i/o */
struct i2c_adapter i2c_adap;
struct i2c_algo_bit_data i2c_algo;
struct i2c_client i2c_client;
u32 i2c_rc;
/* 885 registers used for raw addess */
u32 i2c_period;
u32 reg_ctrl;
u32 reg_stat;
u32 reg_addr;
u32 reg_rdata;
u32 reg_wdata;
};
struct cx23885_dmaqueue {
struct list_head active;
struct list_head queued;
struct timer_list timeout;
struct btcx_riscmem stopper;
u32 count;
};
struct cx23885_tsport {
struct cx23885_dev *dev;
int nr;
int sram_chno;
struct videobuf_dvb dvb;
/* dma queues */
struct cx23885_dmaqueue mpegq;
u32 ts_packet_size;
u32 ts_packet_count;
int width;
int height;
spinlock_t slock;
/* registers */
u32 reg_gpcnt;
u32 reg_gpcnt_ctl;
u32 reg_dma_ctl;
u32 reg_lngth;
u32 reg_hw_sop_ctrl;
u32 reg_gen_ctrl;
u32 reg_bd_pkt_status;
u32 reg_sop_status;
u32 reg_fifo_ovfl_stat;
u32 reg_vld_misc;
u32 reg_ts_clk_en;
u32 reg_ts_int_msk;
u32 reg_ts_int_stat;
u32 reg_src_sel;
/* Default register vals */
int pci_irqmask;
u32 dma_ctl_val;
u32 ts_int_msk_val;
u32 gen_ctrl_val;
u32 ts_clk_en_val;
u32 src_sel_val;
};
struct cx23885_dev {
struct list_head devlist;
atomic_t refcount;
/* pci stuff */
struct pci_dev *pci;
unsigned char pci_rev, pci_lat;
int pci_bus, pci_slot;
u32 __iomem *lmmio;
u8 __iomem *bmmio;
int pci_irqmask;
/* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
struct cx23885_i2c i2c_bus[3];
int nr;
struct mutex lock;
/* board details */
unsigned int board;
char name[32];
struct cx23885_tsport ts1, ts2;
/* sram configuration */
struct sram_channel *sram_channels;
enum {
CX23885_BRIDGE_UNDEFINED = 0,
CX23885_BRIDGE_885 = 885,
CX23885_BRIDGE_887 = 887,
} bridge;
};
#define SRAM_CH01 0 /* Video A */
#define SRAM_CH02 1 /* VBI A */
#define SRAM_CH03 2 /* Video B */
#define SRAM_CH04 3 /* Transport via B */
#define SRAM_CH05 4 /* VBI B */
#define SRAM_CH06 5 /* Video C */
#define SRAM_CH07 6 /* Transport via C */
#define SRAM_CH08 7 /* Audio Internal A */
#define SRAM_CH09 8 /* Audio Internal B */
#define SRAM_CH10 9 /* Audio External */
#define SRAM_CH11 10 /* COMB_3D_N */
#define SRAM_CH12 11 /* Comb 3D N1 */
#define SRAM_CH13 12 /* Comb 3D N2 */
#define SRAM_CH14 13 /* MOE Vid */
#define SRAM_CH15 14 /* MOE RSLT */
struct sram_channel {
char *name;
u32 cmds_start;
u32 ctrl_start;
u32 cdt;
u32 fifo_start;;
u32 fifo_size;
u32 ptr1_reg;
u32 ptr2_reg;
u32 cnt1_reg;
u32 cnt2_reg;
u32 jumponly;
};
/* ----------------------------------------------------------- */
#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
#define cx_write(reg,value) writel((value), dev->lmmio + ((reg)>>2))
#define cx_andor(reg,mask,value) \
writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
((value) & (mask)), dev->lmmio+((reg)>>2))
#define cx_set(reg,bit) cx_andor((reg),(bit),(bit))
#define cx_clear(reg,bit) cx_andor((reg),(bit),0)
/* ----------------------------------------------------------- */
/* cx23885-cards.c */
extern struct cx23885_board cx23885_boards[];
extern const unsigned int cx23885_bcount;
extern struct cx23885_subid cx23885_subids[];
extern const unsigned int cx23885_idcount;
extern void cx23885_card_list(struct cx23885_dev *dev);
extern int cx23885_ir_init(struct cx23885_dev *dev);
extern void cx23885_gpio_setup(struct cx23885_dev *dev);
extern void cx23885_card_setup(struct cx23885_dev *dev);
extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
extern int cx23885_dvb_register(struct cx23885_tsport *port);
extern int cx23885_dvb_unregister(struct cx23885_tsport *port);
extern int cx23885_buf_prepare(struct videobuf_queue *q,
struct cx23885_tsport *port,
struct cx23885_buffer *buf,
enum v4l2_field field);
extern void cx23885_buf_queue(struct cx23885_tsport *port,
struct cx23885_buffer *buf);
extern void cx23885_free_buffer(struct videobuf_queue *q,
struct cx23885_buffer *buf);
/* ----------------------------------------------------------- */
/* cx23885-i2c.c */
extern int cx23885_i2c_register(struct cx23885_i2c *bus);
extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
void *arg);
/*
* Local variables:
* c-basic-offset: 8
* End:
* 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
*/
|