]>
Commit | Line | Data |
---|---|---|
c942fddf | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
1da177e4 | 2 | /* |
1da177e4 LT |
3 | * v4l2 device driver for cx2388x based TV cards |
4 | * | |
5 | * (c) 2003,04 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs] | |
1da177e4 LT |
6 | */ |
7 | ||
65bc2fe8 MCC |
8 | #ifndef CX88_H |
9 | #define CX88_H | |
10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
12 | ||
1da177e4 LT |
13 | #include <linux/pci.h> |
14 | #include <linux/i2c.h> | |
15 | #include <linux/i2c-algo-bit.h> | |
98f30ed0 | 16 | #include <linux/videodev2.h> |
1da177e4 | 17 | #include <linux/kdev_t.h> |
a8d8e38a | 18 | #include <linux/refcount.h> |
1da177e4 | 19 | |
9467fe12 | 20 | #include <media/v4l2-device.h> |
88bb42fb | 21 | #include <media/v4l2-fh.h> |
1da177e4 LT |
22 | #include <media/tuner.h> |
23 | #include <media/tveeprom.h> | |
0b6b6302 | 24 | #include <media/videobuf2-dma-sg.h> |
d647f0b7 | 25 | #include <media/drv-intf/cx2341x.h> |
0b6b6302 | 26 | #include <media/videobuf2-dvb.h> |
b5dcee22 MCC |
27 | #include <media/i2c/ir-kbd-i2c.h> |
28 | #include <media/i2c/wm8775.h> | |
1da177e4 | 29 | |
1da177e4 | 30 | #include "cx88-reg.h" |
99e09eac | 31 | #include "tuner-xc2028.h" |
1da177e4 | 32 | |
3593cab5 | 33 | #include <linux/mutex.h> |
1990d50b | 34 | |
0b6b6302 | 35 | #define CX88_VERSION "1.0.0" |
1da177e4 | 36 | |
1da177e4 LT |
37 | #define UNSET (-1U) |
38 | ||
39 | #define CX88_MAXBOARDS 8 | |
40 | ||
e52e98a7 MCC |
41 | /* Max number of inputs by card */ |
42 | #define MAX_CX88_INPUT 8 | |
43 | ||
1da177e4 LT |
44 | /* ----------------------------------------------------------- */ |
45 | /* defines and enums */ | |
46 | ||
5910e820 | 47 | /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM/LC */ |
7b61ba8f | 48 | #define CX88_NORMS (V4L2_STD_ALL \ |
5910e820 MCC |
49 | & ~V4L2_STD_PAL_H \ |
50 | & ~V4L2_STD_NTSC_M_KR \ | |
51 | & ~V4L2_STD_SECAM_LC) | |
63ab1bdc | 52 | |
1da177e4 LT |
53 | #define FORMAT_FLAGS_PACKED 0x01 |
54 | #define FORMAT_FLAGS_PLANAR 0x02 | |
55 | ||
c0d5b5fb HV |
56 | #define VBI_LINE_PAL_COUNT 18 |
57 | #define VBI_LINE_NTSC_COUNT 12 | |
1da177e4 LT |
58 | #define VBI_LINE_LENGTH 2048 |
59 | ||
e878cf3a MB |
60 | #define AUD_RDS_LINES 4 |
61 | ||
1da177e4 LT |
62 | /* need "shadow" registers for some write-only ones ... */ |
63 | #define SHADOW_AUD_VOL_CTL 1 | |
64 | #define SHADOW_AUD_BAL_CTL 2 | |
cef4e7af | 65 | #define SHADOW_MAX 3 |
1da177e4 | 66 | |
b45009b0 MCC |
67 | /* FM Radio deemphasis type */ |
68 | enum cx88_deemph_type { | |
69 | FM_NO_DEEMPH = 0, | |
70 | FM_DEEMPH_50, | |
71 | FM_DEEMPH_75 | |
72 | }; | |
73 | ||
3a5ba52a ST |
74 | enum cx88_board_type { |
75 | CX88_BOARD_NONE = 0, | |
48d5e803 MK |
76 | CX88_MPEG_DVB, |
77 | CX88_MPEG_BLACKBIRD | |
3a5ba52a ST |
78 | }; |
79 | ||
6c5be74c ST |
80 | enum cx8802_board_access { |
81 | CX8802_DRVCTL_SHARED = 1, | |
82 | CX8802_DRVCTL_EXCLUSIVE = 2, | |
83 | }; | |
84 | ||
1da177e4 LT |
85 | /* ----------------------------------------------------------- */ |
86 | /* tv norms */ | |
87 | ||
34206439 | 88 | static inline unsigned int norm_maxw(v4l2_std_id norm) |
1da177e4 | 89 | { |
0b6b6302 | 90 | return 720; |
1da177e4 LT |
91 | } |
92 | ||
34206439 | 93 | static inline unsigned int norm_maxh(v4l2_std_id norm) |
1da177e4 | 94 | { |
0b6b6302 | 95 | return (norm & V4L2_STD_525_60) ? 480 : 576; |
1da177e4 LT |
96 | } |
97 | ||
98 | /* ----------------------------------------------------------- */ | |
99 | /* static data */ | |
100 | ||
101 | struct cx8800_fmt { | |
2e4e98e7 | 102 | const char *name; |
1da177e4 LT |
103 | u32 fourcc; /* v4l2 format id */ |
104 | int depth; | |
105 | int flags; | |
106 | u32 cxformat; | |
107 | }; | |
108 | ||
1da177e4 LT |
109 | /* ----------------------------------------------------------- */ |
110 | /* SRAM memory management data (see cx88-core.c) */ | |
111 | ||
112 | #define SRAM_CH21 0 /* video */ | |
113 | #define SRAM_CH22 1 | |
114 | #define SRAM_CH23 2 | |
115 | #define SRAM_CH24 3 /* vbi */ | |
116 | #define SRAM_CH25 4 /* audio */ | |
117 | #define SRAM_CH26 5 | |
118 | #define SRAM_CH28 6 /* mpeg */ | |
e878cf3a | 119 | #define SRAM_CH27 7 /* audio rds */ |
1da177e4 LT |
120 | /* more */ |
121 | ||
122 | struct sram_channel { | |
2e4e98e7 | 123 | const char *name; |
1da177e4 LT |
124 | u32 cmds_start; |
125 | u32 ctrl_start; | |
126 | u32 cdt; | |
127 | u32 fifo_start; | |
128 | u32 fifo_size; | |
129 | u32 ptr1_reg; | |
130 | u32 ptr2_reg; | |
131 | u32 cnt1_reg; | |
132 | u32 cnt2_reg; | |
133 | }; | |
399426ca | 134 | |
d9bc8510 | 135 | extern const struct sram_channel cx88_sram_channels[]; |
1da177e4 LT |
136 | |
137 | /* ----------------------------------------------------------- */ | |
138 | /* card configuration */ | |
139 | ||
140 | #define CX88_BOARD_NOAUTO UNSET | |
141 | #define CX88_BOARD_UNKNOWN 0 | |
142 | #define CX88_BOARD_HAUPPAUGE 1 | |
143 | #define CX88_BOARD_GDI 2 | |
144 | #define CX88_BOARD_PIXELVIEW 3 | |
145 | #define CX88_BOARD_ATI_WONDER_PRO 4 | |
146 | #define CX88_BOARD_WINFAST2000XP_EXPERT 5 | |
7418f346 | 147 | #define CX88_BOARD_AVERTV_STUDIO_303 6 |
1da177e4 LT |
148 | #define CX88_BOARD_MSI_TVANYWHERE_MASTER 7 |
149 | #define CX88_BOARD_WINFAST_DV2000 8 | |
150 | #define CX88_BOARD_LEADTEK_PVR2000 9 | |
151 | #define CX88_BOARD_IODATA_GVVCP3PCI 10 | |
152 | #define CX88_BOARD_PROLINK_PLAYTVPVR 11 | |
153 | #define CX88_BOARD_ASUS_PVR_416 12 | |
154 | #define CX88_BOARD_MSI_TVANYWHERE 13 | |
155 | #define CX88_BOARD_KWORLD_DVB_T 14 | |
156 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 15 | |
157 | #define CX88_BOARD_KWORLD_LTV883 16 | |
a82decf6 | 158 | #define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q 17 |
1da177e4 LT |
159 | #define CX88_BOARD_HAUPPAUGE_DVB_T1 18 |
160 | #define CX88_BOARD_CONEXANT_DVB_T1 19 | |
161 | #define CX88_BOARD_PROVIDEO_PV259 20 | |
162 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS 21 | |
163 | #define CX88_BOARD_PCHDTV_HD3000 22 | |
164 | #define CX88_BOARD_DNTV_LIVE_DVB_T 23 | |
165 | #define CX88_BOARD_HAUPPAUGE_ROSLYN 24 | |
a82decf6 | 166 | #define CX88_BOARD_DIGITALLOGIC_MEC 25 |
1da177e4 | 167 | #define CX88_BOARD_IODATA_GVBCTV7E 26 |
239df2e2 | 168 | #define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27 |
b45009b0 | 169 | #define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28 |
a82decf6 | 170 | #define CX88_BOARD_ADSTECH_DVB_T_PCI 29 |
e057ee11 | 171 | #define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 |
9fef07ca | 172 | #define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31 |
d45170ed | 173 | #define CX88_BOARD_AVERMEDIA_ULTRATV_MC_550 32 |
0bcc37c3 | 174 | #define CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD 33 |
e976f937 | 175 | #define CX88_BOARD_ATI_HDTVWONDER 34 |
2b5200a7 | 176 | #define CX88_BOARD_WINFAST_DTV1000 35 |
7418f346 | 177 | #define CX88_BOARD_AVERTV_303 36 |
0fa14aa6 ST |
178 | #define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37 |
179 | #define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38 | |
0e0351e3 | 180 | #define CX88_BOARD_KWORLD_DVBS_100 39 |
611900c1 ST |
181 | #define CX88_BOARD_HAUPPAUGE_HVR1100 40 |
182 | #define CX88_BOARD_HAUPPAUGE_HVR1100LP 41 | |
fc40b261 | 183 | #define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42 |
f39624fd | 184 | #define CX88_BOARD_KWORLD_DVB_T_CX22702 43 |
43eabb4e | 185 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 |
44256de1 | 186 | #define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45 |
780dfef3 | 187 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46 |
da215d22 | 188 | #define CX88_BOARD_PCHDTV_HD5500 47 |
b3038304 | 189 | #define CX88_BOARD_KWORLD_MCE200_DELUXE 48 |
a3124622 | 190 | #define CX88_BOARD_PIXELVIEW_PLAYTV_P7000 49 |
be4f4519 | 191 | #define CX88_BOARD_NPGTECH_REALTV_TOP10FM 50 |
4bd6e9d9 | 192 | #define CX88_BOARD_WINFAST_DTV2000H 51 |
c02a34f4 | 193 | #define CX88_BOARD_GENIATECH_DVBS 52 |
ad10c930 | 194 | #define CX88_BOARD_HAUPPAUGE_HVR3000 53 |
d1009bd7 | 195 | #define CX88_BOARD_NORWOOD_MICRO 54 |
2acadefa | 196 | #define CX88_BOARD_TE_DTV_250_OEM_SWANN 55 |
aa481a65 | 197 | #define CX88_BOARD_HAUPPAUGE_HVR1300 56 |
7cb47a14 | 198 | #define CX88_BOARD_ADSTECH_PTV_390 57 |
60464da8 | 199 | #define CX88_BOARD_PINNACLE_PCTV_HD_800i 58 |
5c00fac0 | 200 | #define CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO 59 |
9507901e MCC |
201 | #define CX88_BOARD_PINNACLE_HYBRID_PCTV 60 |
202 | #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL 61 | |
203 | #define CX88_BOARD_POWERCOLOR_REAL_ANGEL 62 | |
204 | #define CX88_BOARD_GENIATECH_X8000_MT 63 | |
b3fb91d2 | 205 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO 64 |
1117d6ba | 206 | #define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65 |
2422a9b3 | 207 | #define CX88_BOARD_PROLINK_PV_8000GT 66 |
99e09eac | 208 | #define CX88_BOARD_KWORLD_ATSC_120 67 |
5bd1b663 ST |
209 | #define CX88_BOARD_HAUPPAUGE_HVR4000 68 |
210 | #define CX88_BOARD_HAUPPAUGE_HVR4000LITE 69 | |
af832623 | 211 | #define CX88_BOARD_TEVII_S460 70 |
4cd7fb87 | 212 | #define CX88_BOARD_OMICOM_SS4_PCI 71 |
ee73042c | 213 | #define CX88_BOARD_TBS_8920 72 |
e4aab64c | 214 | #define CX88_BOARD_TEVII_S420 73 |
a31d2bb7 | 215 | #define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74 |
57f51dbc | 216 | #define CX88_BOARD_PROF_7300 75 |
4b29631d IL |
217 | #define CX88_BOARD_SATTRADE_ST4200 76 |
218 | #define CX88_BOARD_TBS_8910 77 | |
cd3cde12 | 219 | #define CX88_BOARD_PROF_6200 78 |
70101a27 | 220 | #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 |
501d8cd4 | 221 | #define CX88_BOARD_HAUPPAUGE_IRONLY 80 |
3047a176 | 222 | #define CX88_BOARD_WINFAST_DTV1800H 81 |
4d14c833 | 223 | #define CX88_BOARD_WINFAST_DTV2000H_J 82 |
b699c271 | 224 | #define CX88_BOARD_PROF_7301 83 |
4f3ca2f1 | 225 | #define CX88_BOARD_SAMSUNG_SMT_7020 84 |
111ac84a | 226 | #define CX88_BOARD_TWINHAN_VP1027_DVBS 85 |
0cb73639 | 227 | #define CX88_BOARD_TEVII_S464 86 |
f271a3af | 228 | #define CX88_BOARD_WINFAST_DTV2000H_PLUS 87 |
8eb79c0b | 229 | #define CX88_BOARD_WINFAST_DTV1800H_XC4000 88 |
84463d5f IV |
230 | #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36 89 |
231 | #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43 90 | |
1da177e4 LT |
232 | |
233 | enum cx88_itype { | |
234 | CX88_VMUX_COMPOSITE1 = 1, | |
235 | CX88_VMUX_COMPOSITE2, | |
236 | CX88_VMUX_COMPOSITE3, | |
237 | CX88_VMUX_COMPOSITE4, | |
238 | CX88_VMUX_SVIDEO, | |
239 | CX88_VMUX_TELEVISION, | |
240 | CX88_VMUX_CABLE, | |
241 | CX88_VMUX_DVB, | |
242 | CX88_VMUX_DEBUG, | |
243 | CX88_RADIO, | |
244 | }; | |
245 | ||
246 | struct cx88_input { | |
247 | enum cx88_itype type; | |
1da177e4 | 248 | u32 gpio0, gpio1, gpio2, gpio3; |
c252b051 | 249 | unsigned int vmux:2; |
923ac7f7 | 250 | unsigned int audioroute:4; |
1da177e4 LT |
251 | }; |
252 | ||
facd2366 | 253 | enum cx88_audio_chip { |
f66b2a1c | 254 | CX88_AUDIO_WM8775 = 1, |
facd2366 HV |
255 | CX88_AUDIO_TVAUDIO, |
256 | }; | |
257 | ||
1da177e4 | 258 | struct cx88_board { |
2e4e98e7 | 259 | const char *name; |
1da177e4 | 260 | unsigned int tuner_type; |
b45009b0 MCC |
261 | unsigned int radio_type; |
262 | unsigned char tuner_addr; | |
263 | unsigned char radio_addr; | |
1da177e4 | 264 | int tda9887_conf; |
e52e98a7 | 265 | struct cx88_input input[MAX_CX88_INPUT]; |
1da177e4 | 266 | struct cx88_input radio; |
3a5ba52a | 267 | enum cx88_board_type mpeg; |
facd2366 | 268 | enum cx88_audio_chip audio_chip; |
363c35fc | 269 | int num_frontends; |
6951803c LR |
270 | |
271 | /* Used for I2S devices */ | |
272 | int i2sinputcntl; | |
1da177e4 LT |
273 | }; |
274 | ||
275 | struct cx88_subid { | |
276 | u16 subvendor; | |
277 | u16 subdevice; | |
278 | u32 card; | |
279 | }; | |
280 | ||
d06b49ed | 281 | enum cx88_tvaudio { |
282 | WW_NONE = 1, | |
283 | WW_BTSC, | |
284 | WW_BG, | |
285 | WW_DK, | |
286 | WW_I, | |
287 | WW_L, | |
288 | WW_EIAJ, | |
289 | WW_I2SPT, | |
290 | WW_FM, | |
291 | WW_I2SADC, | |
292 | WW_M | |
293 | }; | |
294 | ||
6a59d64c | 295 | #define INPUT(nr) (core->board.input[nr]) |
1da177e4 LT |
296 | |
297 | /* ----------------------------------------------------------- */ | |
298 | /* device / file handle status */ | |
299 | ||
300 | #define RESOURCE_OVERLAY 1 | |
301 | #define RESOURCE_VIDEO 2 | |
302 | #define RESOURCE_VBI 4 | |
303 | ||
d044189d | 304 | #define BUFFER_TIMEOUT msecs_to_jiffies(2000) |
1da177e4 | 305 | |
5e7045e3 HV |
306 | struct cx88_riscmem { |
307 | unsigned int size; | |
308 | __le32 *cpu; | |
309 | __le32 *jmp; | |
310 | dma_addr_t dma; | |
311 | }; | |
312 | ||
1da177e4 LT |
313 | /* buffer for one video frame */ |
314 | struct cx88_buffer { | |
315 | /* common v4l buffer stuff -- must be first */ | |
2d700715 | 316 | struct vb2_v4l2_buffer vb; |
0b6b6302 | 317 | struct list_head list; |
1da177e4 LT |
318 | |
319 | /* cx88 specific */ | |
320 | unsigned int bpl; | |
5e7045e3 | 321 | struct cx88_riscmem risc; |
1da177e4 LT |
322 | }; |
323 | ||
324 | struct cx88_dmaqueue { | |
325 | struct list_head active; | |
1da177e4 LT |
326 | u32 count; |
327 | }; | |
328 | ||
078859a3 HV |
329 | struct cx8800_dev; |
330 | struct cx8802_dev; | |
331 | ||
1da177e4 LT |
332 | struct cx88_core { |
333 | struct list_head devlist; | |
a8d8e38a | 334 | refcount_t refcount; |
1da177e4 LT |
335 | |
336 | /* board name */ | |
337 | int nr; | |
338 | char name[32]; | |
48a8a03b | 339 | u32 model; |
1da177e4 LT |
340 | |
341 | /* pci stuff */ | |
342 | int pci_bus; | |
343 | int pci_slot; | |
4ac97914 MCC |
344 | u32 __iomem *lmmio; |
345 | u8 __iomem *bmmio; | |
1da177e4 LT |
346 | u32 shadow[SHADOW_MAX]; |
347 | int pci_irqmask; | |
348 | ||
349 | /* i2c i/o */ | |
350 | struct i2c_adapter i2c_adap; | |
351 | struct i2c_algo_bit_data i2c_algo; | |
352 | struct i2c_client i2c_client; | |
353 | u32 i2c_state, i2c_rc; | |
354 | ||
355 | /* config info -- analog */ | |
7b61ba8f | 356 | struct v4l2_device v4l2_dev; |
8c7cb12a HV |
357 | struct v4l2_ctrl_handler video_hdl; |
358 | struct v4l2_ctrl *chroma_agc; | |
359 | struct v4l2_ctrl_handler audio_hdl; | |
bac63981 | 360 | struct v4l2_subdev *sd_wm8775; |
7b61ba8f | 361 | struct i2c_client *i2c_rtc; |
6a59d64c TP |
362 | unsigned int boardnr; |
363 | struct cx88_board board; | |
1da177e4 | 364 | |
0345c387 ST |
365 | /* Supported V4L _STD_ tuner formats */ |
366 | unsigned int tuner_formats; | |
367 | ||
1da177e4 | 368 | /* config info -- dvb */ |
8268979a | 369 | #if IS_ENABLED(CONFIG_VIDEO_CX88_DVB) |
0df289a2 MCC |
370 | int (*prev_set_voltage)(struct dvb_frontend *fe, |
371 | enum fe_sec_voltage voltage); | |
05ad3907 | 372 | #endif |
0df289a2 | 373 | void (*gate_ctrl)(struct cx88_core *core, int open); |
1da177e4 LT |
374 | |
375 | /* state info */ | |
376 | struct task_struct *kthread; | |
63ab1bdc | 377 | v4l2_std_id tvnorm; |
399426ca MCC |
378 | unsigned int width, height; |
379 | unsigned int field; | |
d06b49ed | 380 | enum cx88_tvaudio tvaudio; |
1da177e4 LT |
381 | u32 audiomode_manual; |
382 | u32 audiomode_current; | |
383 | u32 input; | |
243bf1a2 | 384 | u32 last_analog_input; |
1da177e4 | 385 | u32 astat; |
b1706b91 | 386 | u32 use_nicam; |
e878cf3a | 387 | unsigned long last_change; |
1da177e4 LT |
388 | |
389 | /* IR remote control state */ | |
390 | struct cx88_IR *ir; | |
e52e98a7 | 391 | |
44243fc2 MCC |
392 | /* I2C remote data */ |
393 | struct IR_i2c_init_data init_data; | |
6951803c | 394 | struct wm8775_platform_data wm8775_data; |
44243fc2 | 395 | |
3593cab5 | 396 | struct mutex lock; |
e52e98a7 MCC |
397 | /* various v4l controls */ |
398 | u32 freq; | |
611900c1 | 399 | |
078859a3 HV |
400 | /* |
401 | * cx88-video needs to access cx8802 for hybrid tuner pll access and | |
402 | * for vb2_is_busy() checks. | |
403 | */ | |
611900c1 | 404 | struct cx8802_dev *dvbdev; |
078859a3 HV |
405 | /* cx88-blackbird needs to access cx8800 for vb2_is_busy() checks */ |
406 | struct cx8800_dev *v4ldev; | |
6c5be74c | 407 | enum cx88_board_type active_type_id; |
27d0fe18 | 408 | int active_ref; |
363c35fc | 409 | int active_fe_id; |
1da177e4 LT |
410 | }; |
411 | ||
9467fe12 HV |
412 | static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) |
413 | { | |
414 | return container_of(v4l2_dev, struct cx88_core, v4l2_dev); | |
415 | } | |
416 | ||
6951803c | 417 | #define call_hw(core, grpid, o, f, args...) \ |
b8341e1d HV |
418 | do { \ |
419 | if (!core->i2c_rc) { \ | |
420 | if (core->gate_ctrl) \ | |
421 | core->gate_ctrl(core, 1); \ | |
399426ca MCC |
422 | v4l2_device_call_all(&core->v4l2_dev, \ |
423 | grpid, o, f, ##args); \ | |
b8341e1d HV |
424 | if (core->gate_ctrl) \ |
425 | core->gate_ctrl(core, 0); \ | |
426 | } \ | |
427 | } while (0) | |
428 | ||
6951803c LR |
429 | #define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args) |
430 | ||
bac63981 HV |
431 | #define WM8775_GID (1 << 0) |
432 | ||
433 | #define wm8775_s_ctrl(core, id, val) \ | |
399426ca MCC |
434 | do { \ |
435 | struct v4l2_ctrl *ctrl_ = \ | |
436 | v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id);\ | |
437 | if (ctrl_ && !core->i2c_rc) { \ | |
438 | if (core->gate_ctrl) \ | |
439 | core->gate_ctrl(core, 1); \ | |
440 | v4l2_ctrl_s_ctrl(ctrl_, val); \ | |
441 | if (core->gate_ctrl) \ | |
442 | core->gate_ctrl(core, 0); \ | |
443 | } \ | |
bac63981 HV |
444 | } while (0) |
445 | ||
446 | #define wm8775_g_ctrl(core, id) \ | |
399426ca MCC |
447 | ({ \ |
448 | struct v4l2_ctrl *ctrl_ = \ | |
449 | v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id);\ | |
450 | s32 val = 0; \ | |
451 | if (ctrl_ && !core->i2c_rc) { \ | |
452 | if (core->gate_ctrl) \ | |
453 | core->gate_ctrl(core, 1); \ | |
454 | val = v4l2_ctrl_g_ctrl(ctrl_); \ | |
455 | if (core->gate_ctrl) \ | |
456 | core->gate_ctrl(core, 0); \ | |
457 | } \ | |
458 | val; \ | |
bac63981 HV |
459 | }) |
460 | ||
1da177e4 LT |
461 | /* ----------------------------------------------------------- */ |
462 | /* function 0: video stuff */ | |
463 | ||
1da177e4 LT |
464 | struct cx8800_suspend_state { |
465 | int disabled; | |
466 | }; | |
467 | ||
468 | struct cx8800_dev { | |
469 | struct cx88_core *core; | |
e52e98a7 | 470 | spinlock_t slock; |
1da177e4 LT |
471 | |
472 | /* various device info */ | |
473 | unsigned int resources; | |
34080bc2 HV |
474 | struct video_device video_dev; |
475 | struct video_device vbi_dev; | |
476 | struct video_device radio_dev; | |
1da177e4 LT |
477 | |
478 | /* pci i/o */ | |
479 | struct pci_dev *pci; | |
7b61ba8f | 480 | unsigned char pci_rev, pci_lat; |
1da177e4 | 481 | |
c5a86144 | 482 | const struct cx8800_fmt *fmt; |
1da177e4 LT |
483 | |
484 | /* capture queues */ | |
485 | struct cx88_dmaqueue vidq; | |
0b6b6302 | 486 | struct vb2_queue vb2_vidq; |
1da177e4 | 487 | struct cx88_dmaqueue vbiq; |
0b6b6302 | 488 | struct vb2_queue vb2_vbiq; |
1da177e4 LT |
489 | |
490 | /* various v4l controls */ | |
1da177e4 LT |
491 | |
492 | /* other global state info */ | |
493 | struct cx8800_suspend_state state; | |
494 | }; | |
495 | ||
496 | /* ----------------------------------------------------------- */ | |
497 | /* function 1: audio/alsa stuff */ | |
e52e98a7 | 498 | /* =============> moved to cx88-alsa.c <====================== */ |
1da177e4 | 499 | |
1da177e4 LT |
500 | /* ----------------------------------------------------------- */ |
501 | /* function 2: mpeg stuff */ | |
502 | ||
1da177e4 LT |
503 | struct cx8802_suspend_state { |
504 | int disabled; | |
505 | }; | |
506 | ||
6c5be74c ST |
507 | struct cx8802_driver { |
508 | struct cx88_core *core; | |
081c2fc8 TP |
509 | |
510 | /* List of drivers attached to device */ | |
511 | struct list_head drvlist; | |
6c5be74c ST |
512 | |
513 | /* Type of driver and access required */ | |
514 | enum cx88_board_type type_id; | |
515 | enum cx8802_board_access hw_access; | |
516 | ||
517 | /* MPEG 8802 internal only */ | |
518 | int (*suspend)(struct pci_dev *pci_dev, pm_message_t state); | |
519 | int (*resume)(struct pci_dev *pci_dev); | |
520 | ||
1fe70e96 JN |
521 | /* Callers to the following functions must hold core->lock */ |
522 | ||
1d6213ab JN |
523 | /* MPEG 8802 -> mini driver - Driver probe and configuration */ |
524 | int (*probe)(struct cx8802_driver *drv); | |
6c5be74c ST |
525 | int (*remove)(struct cx8802_driver *drv); |
526 | ||
527 | /* MPEG 8802 -> mini driver - Access for hardware control */ | |
528 | int (*advise_acquire)(struct cx8802_driver *drv); | |
529 | int (*advise_release)(struct cx8802_driver *drv); | |
530 | ||
531 | /* MPEG 8802 <- mini driver - Access for hardware control */ | |
532 | int (*request_acquire)(struct cx8802_driver *drv); | |
533 | int (*request_release)(struct cx8802_driver *drv); | |
534 | }; | |
535 | ||
1da177e4 LT |
536 | struct cx8802_dev { |
537 | struct cx88_core *core; | |
e52e98a7 | 538 | spinlock_t slock; |
1da177e4 LT |
539 | |
540 | /* pci i/o */ | |
541 | struct pci_dev *pci; | |
7b61ba8f | 542 | unsigned char pci_rev, pci_lat; |
1da177e4 LT |
543 | |
544 | /* dma queues */ | |
545 | struct cx88_dmaqueue mpegq; | |
0b6b6302 | 546 | struct vb2_queue vb2_mpegq; |
1da177e4 LT |
547 | u32 ts_packet_size; |
548 | u32 ts_packet_count; | |
549 | ||
550 | /* other global state info */ | |
551 | struct cx8802_suspend_state state; | |
552 | ||
553 | /* for blackbird only */ | |
554 | struct list_head devlist; | |
8268979a | 555 | #if IS_ENABLED(CONFIG_VIDEO_CX88_BLACKBIRD) |
34080bc2 | 556 | struct video_device mpeg_dev; |
1da177e4 | 557 | u32 mailbox; |
1da177e4 | 558 | |
7717cbed | 559 | /* mpeg params */ |
7bb34c8e | 560 | struct cx2341x_handler cxhdl; |
399426ca | 561 | |
7717cbed TP |
562 | #endif |
563 | ||
8268979a | 564 | #if IS_ENABLED(CONFIG_VIDEO_CX88_DVB) |
1da177e4 | 565 | /* for dvb only */ |
0b6b6302 | 566 | struct vb2_dvb_frontends frontends; |
f0ad9097 | 567 | #endif |
fc40b261 | 568 | |
8268979a | 569 | #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054) |
f0ad9097 TP |
570 | /* For VP3045 secondary I2C bus support */ |
571 | struct vp3054_i2c_state *vp3054; | |
05ad3907 | 572 | #endif |
1da177e4 LT |
573 | /* for switching modulation types */ |
574 | unsigned char ts_gen_cntrl; | |
31629424 | 575 | |
8a317a87 | 576 | /* List of attached drivers; must hold core->lock to access */ |
081c2fc8 | 577 | struct list_head drvlist; |
8a317a87 | 578 | |
081c2fc8 | 579 | struct work_struct request_module_wk; |
1da177e4 LT |
580 | }; |
581 | ||
582 | /* ----------------------------------------------------------- */ | |
583 | ||
399426ca MCC |
584 | #define cx_read(reg) readl(core->lmmio + ((reg) >> 2)) |
585 | #define cx_write(reg, value) writel((value), core->lmmio + ((reg) >> 2)) | |
586 | #define cx_writeb(reg, value) writeb((value), core->bmmio + (reg)) | |
1da177e4 | 587 | |
7b61ba8f | 588 | #define cx_andor(reg, mask, value) \ |
399426ca MCC |
589 | writel((readl(core->lmmio + ((reg) >> 2)) & ~(mask)) |\ |
590 | ((value) & (mask)), core->lmmio + ((reg) >> 2)) | |
591 | #define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) | |
592 | #define cx_clear(reg, bit) cx_andor((reg), (bit), 0) | |
1da177e4 LT |
593 | |
594 | #define cx_wait(d) { if (need_resched()) schedule(); else udelay(d); } | |
595 | ||
596 | /* shadow registers */ | |
597 | #define cx_sread(sreg) (core->shadow[sreg]) | |
7b61ba8f | 598 | #define cx_swrite(sreg, reg, value) \ |
399426ca MCC |
599 | (core->shadow[sreg] = value, \ |
600 | writel(core->shadow[sreg], core->lmmio + ((reg) >> 2))) | |
7b61ba8f | 601 | #define cx_sandor(sreg, reg, mask, value) \ |
399426ca MCC |
602 | (core->shadow[sreg] = (core->shadow[sreg] & ~(mask)) | \ |
603 | ((value) & (mask)), \ | |
604 | writel(core->shadow[sreg], \ | |
605 | core->lmmio + ((reg) >> 2))) | |
1da177e4 LT |
606 | |
607 | /* ----------------------------------------------------------- */ | |
608 | /* cx88-core.c */ | |
609 | ||
02615ed5 MCC |
610 | extern unsigned int cx88_core_debug; |
611 | ||
399426ca MCC |
612 | void cx88_print_irqbits(const char *tag, const char *strings[], |
613 | int len, u32 bits, u32 mask); | |
1da177e4 | 614 | |
399426ca MCC |
615 | int cx88_core_irq(struct cx88_core *core, u32 status); |
616 | void cx88_wakeup(struct cx88_core *core, | |
617 | struct cx88_dmaqueue *q, u32 count); | |
618 | void cx88_shutdown(struct cx88_core *core); | |
619 | int cx88_reset(struct cx88_core *core); | |
1da177e4 LT |
620 | |
621 | extern int | |
5e7045e3 | 622 | cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, |
1da177e4 LT |
623 | struct scatterlist *sglist, |
624 | unsigned int top_offset, unsigned int bottom_offset, | |
625 | unsigned int bpl, unsigned int padding, unsigned int lines); | |
626 | extern int | |
5e7045e3 | 627 | cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, |
1da177e4 | 628 | struct scatterlist *sglist, unsigned int bpl, |
05b27233 | 629 | unsigned int lines, unsigned int lpi); |
1da177e4 | 630 | |
399426ca MCC |
631 | void cx88_risc_disasm(struct cx88_core *core, |
632 | struct cx88_riscmem *risc); | |
633 | int cx88_sram_channel_setup(struct cx88_core *core, | |
634 | const struct sram_channel *ch, | |
635 | unsigned int bpl, u32 risc); | |
636 | void cx88_sram_channel_dump(struct cx88_core *core, | |
637 | const struct sram_channel *ch); | |
638 | ||
639 | int cx88_set_scale(struct cx88_core *core, unsigned int width, | |
640 | unsigned int height, enum v4l2_field field); | |
641 | int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm); | |
642 | ||
643 | void cx88_vdev_init(struct cx88_core *core, | |
644 | struct pci_dev *pci, | |
645 | struct video_device *vfd, | |
646 | const struct video_device *template_, | |
647 | const char *type); | |
648 | struct cx88_core *cx88_core_get(struct pci_dev *pci); | |
649 | void cx88_core_put(struct cx88_core *core, | |
650 | struct pci_dev *pci); | |
651 | ||
652 | int cx88_start_audio_dma(struct cx88_core *core); | |
653 | int cx88_stop_audio_dma(struct cx88_core *core); | |
6f502b8a | 654 | |
1da177e4 LT |
655 | /* ----------------------------------------------------------- */ |
656 | /* cx88-vbi.c */ | |
657 | ||
8d87cb9f | 658 | /* Can be used as g_vbi_fmt, try_vbi_fmt and s_vbi_fmt */ |
7b61ba8f | 659 | int cx8800_vbi_fmt(struct file *file, void *priv, |
399426ca | 660 | struct v4l2_format *f); |
8d87cb9f | 661 | |
0b6b6302 HV |
662 | void cx8800_stop_vbi_dma(struct cx8800_dev *dev); |
663 | int cx8800_restart_vbi_queue(struct cx8800_dev *dev, struct cx88_dmaqueue *q); | |
1da177e4 | 664 | |
0b6b6302 | 665 | extern const struct vb2_ops cx8800_vbi_qops; |
1da177e4 LT |
666 | |
667 | /* ----------------------------------------------------------- */ | |
668 | /* cx88-i2c.c */ | |
669 | ||
399426ca | 670 | int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci); |
1da177e4 LT |
671 | |
672 | /* ----------------------------------------------------------- */ | |
673 | /* cx88-cards.c */ | |
674 | ||
399426ca MCC |
675 | int cx88_tuner_callback(void *dev, int component, int command, int arg); |
676 | int cx88_get_resources(const struct cx88_core *core, | |
677 | struct pci_dev *pci); | |
678 | struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); | |
679 | void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); | |
1da177e4 LT |
680 | |
681 | /* ----------------------------------------------------------- */ | |
682 | /* cx88-tvaudio.c */ | |
683 | ||
1da177e4 LT |
684 | void cx88_set_tvaudio(struct cx88_core *core); |
685 | void cx88_newstation(struct cx88_core *core); | |
686 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); | |
687 | void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); | |
688 | int cx88_audio_thread(void *data); | |
689 | ||
6c5be74c ST |
690 | int cx8802_register_driver(struct cx8802_driver *drv); |
691 | int cx8802_unregister_driver(struct cx8802_driver *drv); | |
8a317a87 JN |
692 | |
693 | /* Caller must hold core->lock */ | |
7b61ba8f MCC |
694 | struct cx8802_driver *cx8802_get_driver(struct cx8802_dev *dev, |
695 | enum cx88_board_type btype); | |
6c5be74c | 696 | |
e878cf3a MB |
697 | /* ----------------------------------------------------------- */ |
698 | /* cx88-dsp.c */ | |
699 | ||
700 | s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core); | |
701 | ||
1da177e4 LT |
702 | /* ----------------------------------------------------------- */ |
703 | /* cx88-input.c */ | |
704 | ||
705 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); | |
706 | int cx88_ir_fini(struct cx88_core *core); | |
707 | void cx88_ir_irq(struct cx88_core *core); | |
92f4fc10 MCC |
708 | int cx88_ir_start(struct cx88_core *core); |
709 | void cx88_ir_stop(struct cx88_core *core); | |
399426ca | 710 | void cx88_i2c_init_ir(struct cx88_core *core); |
1da177e4 LT |
711 | |
712 | /* ----------------------------------------------------------- */ | |
713 | /* cx88-mpeg.c */ | |
714 | ||
0b6b6302 | 715 | int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, |
399426ca | 716 | struct cx88_buffer *buf); |
1da177e4 LT |
717 | void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); |
718 | void cx8802_cancel_buffers(struct cx8802_dev *dev); | |
0b6b6302 | 719 | int cx8802_start_dma(struct cx8802_dev *dev, |
399426ca MCC |
720 | struct cx88_dmaqueue *q, |
721 | struct cx88_buffer *buf); | |
1da177e4 | 722 | |
e52e98a7 | 723 | /* ----------------------------------------------------------- */ |
54da49f5 | 724 | /* cx88-video.c*/ |
0b6b6302 | 725 | int cx88_enum_input(struct cx88_core *core, struct v4l2_input *i); |
b530a447 | 726 | int cx88_set_freq(struct cx88_core *core, const struct v4l2_frequency *f); |
54da49f5 | 727 | int cx88_video_mux(struct cx88_core *core, unsigned int input); |
4839c58f MCC |
728 | int cx88_querycap(struct file *file, struct cx88_core *core, |
729 | struct v4l2_capability *cap); | |
65bc2fe8 MCC |
730 | |
731 | #endif |