aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7164
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/saa7164')
-rw-r--r--drivers/media/video/saa7164/Kconfig18
-rw-r--r--drivers/media/video/saa7164/Makefile12
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c1533
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c322
-rw-r--r--drivers/media/video/saa7164/saa7164-bus.c475
-rw-r--r--drivers/media/video/saa7164/saa7164-cards.c715
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c589
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c1526
-rw-r--r--drivers/media/video/saa7164/saa7164-dvb.c555
-rw-r--r--drivers/media/video/saa7164/saa7164-encoder.c1506
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c613
-rw-r--r--drivers/media/video/saa7164/saa7164-i2c.c141
-rw-r--r--drivers/media/video/saa7164/saa7164-reg.h219
-rw-r--r--drivers/media/video/saa7164/saa7164-types.h442
-rw-r--r--drivers/media/video/saa7164/saa7164-vbi.c1380
-rw-r--r--drivers/media/video/saa7164/saa7164.h623
16 files changed, 10669 insertions, 0 deletions
diff --git a/drivers/media/video/saa7164/Kconfig b/drivers/media/video/saa7164/Kconfig
new file mode 100644
index 00000000000..35326372517
--- /dev/null
+++ b/drivers/media/video/saa7164/Kconfig
@@ -0,0 +1,18 @@
1config VIDEO_SAA7164
2 tristate "NXP SAA7164 support"
3 depends on DVB_CORE && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_TUNER
7 select VIDEO_TVEEPROM
8 select VIDEOBUF_DVB
9 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
10 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
11 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
12 ---help---
13 This is a video4linux driver for NXP SAA7164 based
14 TV cards.
15
16 To compile this driver as a module, choose M here: the
17 module will be called saa7164
18
diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile
new file mode 100644
index 00000000000..6303a8e60ea
--- /dev/null
+++ b/drivers/media/video/saa7164/Makefile
@@ -0,0 +1,12 @@
1saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
2 saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \
3 saa7164-buffer.o saa7164-encoder.o saa7164-vbi.o
4
5obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
6
7EXTRA_CFLAGS += -Idrivers/media/video
8EXTRA_CFLAGS += -Idrivers/media/common/tuners
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
11
12EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
new file mode 100644
index 00000000000..8a98ab68239
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -0,0 +1,1533 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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/wait.h>
23#include <linux/slab.h>
24
25#include "saa7164.h"
26
27int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i)
28{
29 int ret;
30
31 if (!(saa_debug & DBGLVL_CPU))
32 return 0;
33
34 dprintk(DBGLVL_API, "%s()\n", __func__);
35
36 i->deviceinst = 0;
37 i->devicespec = 0;
38 i->mode = 0;
39 i->status = 0;
40
41 ret = saa7164_cmd_send(dev, 0, GET_CUR,
42 GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i);
43 if (ret != SAA_OK)
44 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
45
46 printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad);
47
48 return ret;
49}
50
51int saa7164_api_collect_debug(struct saa7164_dev *dev)
52{
53 struct tmComResDebugGetData d;
54 u8 more = 255;
55 int ret;
56
57 dprintk(DBGLVL_API, "%s()\n", __func__);
58
59 while (more--) {
60
61 memset(&d, 0, sizeof(d));
62
63 ret = saa7164_cmd_send(dev, 0, GET_CUR,
64 GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
65 if (ret != SAA_OK)
66 printk(KERN_ERR "%s() error, ret = 0x%x\n",
67 __func__, ret);
68
69 if (d.dwResult != SAA_OK)
70 break;
71
72 printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr,
73 d.ucDebugData);
74 }
75
76 return 0;
77}
78
79int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
80{
81 struct tmComResDebugSetLevel lvl;
82 int ret;
83
84 dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level);
85
86 /* Retrieve current state */
87 ret = saa7164_cmd_send(dev, 0, GET_CUR,
88 SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
89 if (ret != SAA_OK)
90 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
91
92 dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
93
94 lvl.dwDebugLevel = level;
95
96 /* set new state */
97 ret = saa7164_cmd_send(dev, 0, SET_CUR,
98 SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
99 if (ret != SAA_OK)
100 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
101
102 return ret;
103}
104
105int saa7164_api_set_vbi_format(struct saa7164_port *port)
106{
107 struct saa7164_dev *dev = port->dev;
108 struct tmComResProbeCommit fmt, rsp;
109 int ret;
110
111 dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__,
112 port->nr, port->hwcfg.unitid);
113
114 fmt.bmHint = 0;
115 fmt.bFormatIndex = 1;
116 fmt.bFrameIndex = 1;
117
118 /* Probe, see if it can support this format */
119 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
120 SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt);
121 if (ret != SAA_OK)
122 printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret);
123
124 /* See of the format change was successful */
125 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
126 GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp);
127 if (ret != SAA_OK) {
128 printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret);
129 } else {
130 /* Compare requested vs received, should be same */
131 if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
132 dprintk(DBGLVL_API, "SET/PROBE Verified\n");
133
134 /* Ask the device to select the negotiated format */
135 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
136 SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
137 if (ret != SAA_OK)
138 printk(KERN_ERR "%s() commit error, ret = 0x%x\n",
139 __func__, ret);
140
141 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
142 GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp);
143 if (ret != SAA_OK)
144 printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
145 __func__, ret);
146
147 if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) {
148 printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
149 __func__, ret);
150 } else
151 dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
152
153 dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
154 dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n",
155 rsp.bFormatIndex);
156 dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n",
157 rsp.bFrameIndex);
158 } else
159 printk(KERN_ERR "%s() compare failed\n", __func__);
160 }
161
162 if (ret == SAA_OK)
163 dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr);
164
165 return ret;
166}
167
168int saa7164_api_set_gop_size(struct saa7164_port *port)
169{
170 struct saa7164_dev *dev = port->dev;
171 struct tmComResEncVideoGopStructure gs;
172 int ret;
173
174 dprintk(DBGLVL_ENC, "%s()\n", __func__);
175
176 gs.ucRefFrameDist = port->encoder_params.refdist;
177 gs.ucGOPSize = port->encoder_params.gop_size;
178 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
179 EU_VIDEO_GOP_STRUCTURE_CONTROL,
180 sizeof(gs), &gs);
181 if (ret != SAA_OK)
182 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
183
184 return ret;
185}
186
187int saa7164_api_set_encoder(struct saa7164_port *port)
188{
189 struct saa7164_dev *dev = port->dev;
190 struct tmComResEncVideoBitRate vb;
191 struct tmComResEncAudioBitRate ab;
192 int ret;
193
194 dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
195 port->hwcfg.sourceid);
196
197 if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
198 port->encoder_profile = EU_PROFILE_PS_DVD;
199 else
200 port->encoder_profile = EU_PROFILE_TS_HQ;
201
202 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
203 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
204 if (ret != SAA_OK)
205 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
206
207 /* Resolution */
208 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
209 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
210 if (ret != SAA_OK)
211 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
212
213 /* Establish video bitrates */
214 if (port->encoder_params.bitrate_mode ==
215 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
216 vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT;
217 else
218 vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK;
219 vb.dwVideoBitRate = port->encoder_params.bitrate;
220 vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak;
221 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
222 EU_VIDEO_BIT_RATE_CONTROL,
223 sizeof(struct tmComResEncVideoBitRate),
224 &vb);
225 if (ret != SAA_OK)
226 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
227
228 /* Establish audio bitrates */
229 ab.ucAudioBitRateMode = 0;
230 ab.dwAudioBitRate = 384000;
231 ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
232 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
233 EU_AUDIO_BIT_RATE_CONTROL,
234 sizeof(struct tmComResEncAudioBitRate),
235 &ab);
236 if (ret != SAA_OK)
237 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
238 ret);
239
240 saa7164_api_set_aspect_ratio(port);
241 saa7164_api_set_gop_size(port);
242
243 return ret;
244}
245
246int saa7164_api_get_encoder(struct saa7164_port *port)
247{
248 struct saa7164_dev *dev = port->dev;
249 struct tmComResEncVideoBitRate v;
250 struct tmComResEncAudioBitRate a;
251 struct tmComResEncVideoInputAspectRatio ar;
252 int ret;
253
254 dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
255 port->hwcfg.sourceid);
256
257 port->encoder_profile = 0;
258 port->video_format = 0;
259 port->video_resolution = 0;
260 port->audio_format = 0;
261
262 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
263 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
264 if (ret != SAA_OK)
265 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
266
267 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
268 EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8),
269 &port->video_resolution);
270 if (ret != SAA_OK)
271 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
272
273 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
274 EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format);
275 if (ret != SAA_OK)
276 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
277
278 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
279 EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v);
280 if (ret != SAA_OK)
281 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
282
283 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
284 EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format);
285 if (ret != SAA_OK)
286 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
287
288 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
289 EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a);
290 if (ret != SAA_OK)
291 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
292
293 /* Aspect Ratio */
294 ar.width = 0;
295 ar.height = 0;
296 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
297 EU_VIDEO_INPUT_ASPECT_CONTROL,
298 sizeof(struct tmComResEncVideoInputAspectRatio), &ar);
299 if (ret != SAA_OK)
300 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
301
302 dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile);
303 dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format);
304 dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format);
305 dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
306 dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n",
307 v.ucVideoBitRateMode);
308 dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n",
309 v.dwVideoBitRate);
310 dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n",
311 v.dwVideoBitRatePeak);
312 dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n",
313 a.ucAudioBitRateMode);
314 dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n",
315 a.dwAudioBitRate);
316 dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n",
317 a.dwAudioBitRatePeak);
318 dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n",
319 ar.width, ar.height);
320
321 return ret;
322}
323
324int saa7164_api_set_aspect_ratio(struct saa7164_port *port)
325{
326 struct saa7164_dev *dev = port->dev;
327 struct tmComResEncVideoInputAspectRatio ar;
328 int ret;
329
330 dprintk(DBGLVL_ENC, "%s(%d)\n", __func__,
331 port->encoder_params.ctl_aspect);
332
333 switch (port->encoder_params.ctl_aspect) {
334 case V4L2_MPEG_VIDEO_ASPECT_1x1:
335 ar.width = 1;
336 ar.height = 1;
337 break;
338 case V4L2_MPEG_VIDEO_ASPECT_4x3:
339 ar.width = 4;
340 ar.height = 3;
341 break;
342 case V4L2_MPEG_VIDEO_ASPECT_16x9:
343 ar.width = 16;
344 ar.height = 9;
345 break;
346 case V4L2_MPEG_VIDEO_ASPECT_221x100:
347 ar.width = 221;
348 ar.height = 100;
349 break;
350 default:
351 BUG();
352 }
353
354 dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__,
355 port->encoder_params.ctl_aspect,
356 ar.width, ar.height);
357
358 /* Aspect Ratio */
359 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
360 EU_VIDEO_INPUT_ASPECT_CONTROL,
361 sizeof(struct tmComResEncVideoInputAspectRatio), &ar);
362 if (ret != SAA_OK)
363 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
364
365 return ret;
366}
367
368int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl)
369{
370 struct saa7164_dev *dev = port->dev;
371 int ret;
372 u16 val;
373
374 if (ctl == PU_BRIGHTNESS_CONTROL)
375 val = port->ctl_brightness;
376 else
377 if (ctl == PU_CONTRAST_CONTROL)
378 val = port->ctl_contrast;
379 else
380 if (ctl == PU_HUE_CONTROL)
381 val = port->ctl_hue;
382 else
383 if (ctl == PU_SATURATION_CONTROL)
384 val = port->ctl_saturation;
385 else
386 if (ctl == PU_SHARPNESS_CONTROL)
387 val = port->ctl_sharpness;
388 else
389 return -EINVAL;
390
391 dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n",
392 __func__, port->encunit.vsourceid, ctl, val);
393
394 ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR,
395 ctl, sizeof(u16), &val);
396 if (ret != SAA_OK)
397 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
398
399 return ret;
400}
401
402int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl)
403{
404 struct saa7164_dev *dev = port->dev;
405 int ret;
406 u16 val;
407
408 ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR,
409 ctl, sizeof(u16), &val);
410 if (ret != SAA_OK) {
411 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
412 return ret;
413 }
414
415 dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n",
416 __func__, ctl, val);
417
418 if (ctl == PU_BRIGHTNESS_CONTROL)
419 port->ctl_brightness = val;
420 else
421 if (ctl == PU_CONTRAST_CONTROL)
422 port->ctl_contrast = val;
423 else
424 if (ctl == PU_HUE_CONTROL)
425 port->ctl_hue = val;
426 else
427 if (ctl == PU_SATURATION_CONTROL)
428 port->ctl_saturation = val;
429 else
430 if (ctl == PU_SHARPNESS_CONTROL)
431 port->ctl_sharpness = val;
432
433 return ret;
434}
435
436int saa7164_api_set_videomux(struct saa7164_port *port)
437{
438 struct saa7164_dev *dev = port->dev;
439 u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 };
440 int ret;
441
442 dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n",
443 __func__, port->mux_input, inputs[port->mux_input - 1]);
444
445 /* Audio Mute */
446 ret = saa7164_api_audio_mute(port, 1);
447 if (ret != SAA_OK)
448 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
449
450 /* Video Mux */
451 ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR,
452 SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
453 if (ret != SAA_OK)
454 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
455
456 /* Audio Mux */
457 ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
458 SU_INPUT_SELECT_CONTROL, sizeof(u8),
459 &inputs[port->mux_input - 1]);
460 if (ret != SAA_OK)
461 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
462
463 /* Audio UnMute */
464 ret = saa7164_api_audio_mute(port, 0);
465 if (ret != SAA_OK)
466 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
467
468 return ret;
469}
470
471int saa7164_api_audio_mute(struct saa7164_port *port, int mute)
472{
473 struct saa7164_dev *dev = port->dev;
474 u8 v = mute;
475 int ret;
476
477 dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute);
478
479 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
480 MUTE_CONTROL, sizeof(u8), &v);
481 if (ret != SAA_OK)
482 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
483
484 return ret;
485}
486
487/* 0 = silence, 0xff = full */
488int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
489{
490 struct saa7164_dev *dev = port->dev;
491 s16 v, min, max;
492 int ret;
493
494 dprintk(DBGLVL_API, "%s(%d)\n", __func__, level);
495
496 /* Obtain the min/max ranges */
497 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN,
498 VOLUME_CONTROL, sizeof(u16), &min);
499 if (ret != SAA_OK)
500 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
501
502 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX,
503 VOLUME_CONTROL, sizeof(u16), &max);
504 if (ret != SAA_OK)
505 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
506
507 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
508 (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
509 if (ret != SAA_OK)
510 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
511
512 dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
513 level, min, max, v);
514
515 v = level;
516 if (v < min)
517 v = min;
518 if (v > max)
519 v = max;
520
521 /* Left */
522 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
523 (0x01 << 8) | VOLUME_CONTROL, sizeof(s16), &v);
524 if (ret != SAA_OK)
525 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
526
527 /* Right */
528 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
529 (0x02 << 8) | VOLUME_CONTROL, sizeof(s16), &v);
530 if (ret != SAA_OK)
531 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
532
533 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
534 (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
535 if (ret != SAA_OK)
536 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
537
538 dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
539 level, min, max, v);
540
541 return ret;
542}
543
544int saa7164_api_set_audio_std(struct saa7164_port *port)
545{
546 struct saa7164_dev *dev = port->dev;
547 struct tmComResAudioDefaults lvl;
548 struct tmComResTunerStandard tvaudio;
549 int ret;
550
551 dprintk(DBGLVL_API, "%s()\n", __func__);
552
553 /* Establish default levels */
554 lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT;
555 lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT;
556 lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT;
557 lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT;
558 lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
559 lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
560 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
561 AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults),
562 &lvl);
563 if (ret != SAA_OK)
564 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
565
566 /* Manually select the appropriate TV audio standard */
567 if (port->encodernorm.id & V4L2_STD_NTSC) {
568 tvaudio.std = TU_STANDARD_NTSC_M;
569 tvaudio.country = 1;
570 } else {
571 tvaudio.std = TU_STANDARD_PAL_I;
572 tvaudio.country = 44;
573 }
574
575 ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
576 TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
577 if (ret != SAA_OK)
578 printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n",
579 __func__, ret);
580 return ret;
581}
582
583int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
584{
585 struct saa7164_dev *dev = port->dev;
586 struct tmComResTunerStandardAuto p;
587 int ret;
588
589 dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect);
590
591 /* Disable TV Audio autodetect if not already set (buggy) */
592 if (autodetect)
593 p.mode = TU_STANDARD_AUTO;
594 else
595 p.mode = TU_STANDARD_MANUAL;
596 ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
597 TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
598 if (ret != SAA_OK)
599 printk(KERN_ERR
600 "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n",
601 __func__, ret);
602
603 return ret;
604}
605
606int saa7164_api_get_videomux(struct saa7164_port *port)
607{
608 struct saa7164_dev *dev = port->dev;
609 int ret;
610
611 ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR,
612 SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
613 if (ret != SAA_OK)
614 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
615
616 dprintk(DBGLVL_ENC, "%s() v_mux=%d\n",
617 __func__, port->mux_input);
618
619 return ret;
620}
621
622int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
623{
624 struct saa7164_dev *dev = port->dev;
625
626 u16 len = 0;
627 u8 buf[256];
628 int ret;
629 u8 mas;
630
631 dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__,
632 port->nr, port->type, val);
633
634 if (port->nr == 0)
635 mas = 0xd0;
636 else
637 mas = 0xe0;
638
639 memset(buf, 0, sizeof(buf));
640
641 buf[0x00] = 0x04;
642 buf[0x01] = 0x00;
643 buf[0x02] = 0x00;
644 buf[0x03] = 0x00;
645
646 buf[0x04] = 0x04;
647 buf[0x05] = 0x00;
648 buf[0x06] = 0x00;
649 buf[0x07] = 0x00;
650
651 buf[0x08] = reg;
652 buf[0x09] = 0x26;
653 buf[0x0a] = mas;
654 buf[0x0b] = 0xb0;
655
656 buf[0x0c] = val;
657 buf[0x0d] = 0x00;
658 buf[0x0e] = 0x00;
659 buf[0x0f] = 0x00;
660
661 ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN,
662 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
663 if (ret != SAA_OK) {
664 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
665 return -EIO;
666 }
667
668 ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR,
669 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
670 if (ret != SAA_OK)
671 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
672#if 0
673 saa7164_dumphex16(dev, buf, 16);
674#endif
675 return ret == SAA_OK ? 0 : -EIO;
676}
677
678/* Disable the IF block AGC controls */
679int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
680{
681 struct saa7164_dev *dev = port->dev;
682 int ret = 0;
683 u8 agc_disable;
684
685 dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std);
686
687 if (std & V4L2_STD_NTSC) {
688 dprintk(DBGLVL_API, " NTSC\n");
689 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
690 agc_disable = 0;
691 } else if (std & V4L2_STD_PAL_I) {
692 dprintk(DBGLVL_API, " PAL-I\n");
693 saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */
694 agc_disable = 0;
695 } else if (std & V4L2_STD_PAL_M) {
696 dprintk(DBGLVL_API, " PAL-M\n");
697 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
698 agc_disable = 0;
699 } else if (std & V4L2_STD_PAL_N) {
700 dprintk(DBGLVL_API, " PAL-N\n");
701 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
702 agc_disable = 0;
703 } else if (std & V4L2_STD_PAL_Nc) {
704 dprintk(DBGLVL_API, " PAL-Nc\n");
705 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
706 agc_disable = 0;
707 } else if (std & V4L2_STD_PAL_B) {
708 dprintk(DBGLVL_API, " PAL-B\n");
709 saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */
710 agc_disable = 0;
711 } else if (std & V4L2_STD_PAL_DK) {
712 dprintk(DBGLVL_API, " PAL-DK\n");
713 saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */
714 agc_disable = 0;
715 } else if (std & V4L2_STD_SECAM_L) {
716 dprintk(DBGLVL_API, " SECAM-L\n");
717 saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */
718 agc_disable = 0;
719 } else {
720 /* Unknown standard, assume DTV */
721 dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
722 /* Undefinded Video Standard */
723 saa7164_api_set_dif(port, 0x00, 0x80);
724 agc_disable = 1;
725 }
726
727 saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */
728 saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */
729 saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */
730 saa7164_api_set_dif(port, 0x04, 0x01); /* Active */
731 msleep(100);
732 saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */
733 msleep(100);
734
735 return ret;
736}
737
738/* Ensure the dif is in the correct state for the operating mode
739 * (analog / dtv). We only configure the diff through the analog encoder
740 * so when we're in digital mode we need to find the appropriate encoder
741 * and use it to configure the DIF.
742 */
743int saa7164_api_initialize_dif(struct saa7164_port *port)
744{
745 struct saa7164_dev *dev = port->dev;
746 struct saa7164_port *p = NULL;
747 int ret = -EINVAL;
748 u32 std = 0;
749
750 dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__,
751 port->nr, port->type);
752
753 if (port->type == SAA7164_MPEG_ENCODER) {
754 /* Pick any analog standard to init the diff.
755 * we'll come back during encoder_init'
756 * and set the correct standard if requried.
757 */
758 std = V4L2_STD_NTSC;
759 } else
760 if (port->type == SAA7164_MPEG_DVB) {
761 if (port->nr == SAA7164_PORT_TS1)
762 p = &dev->ports[SAA7164_PORT_ENC1];
763 else
764 p = &dev->ports[SAA7164_PORT_ENC2];
765 } else
766 if (port->type == SAA7164_MPEG_VBI) {
767 std = V4L2_STD_NTSC;
768 if (port->nr == SAA7164_PORT_VBI1)
769 p = &dev->ports[SAA7164_PORT_ENC1];
770 else
771 p = &dev->ports[SAA7164_PORT_ENC2];
772 } else
773 BUG();
774
775 if (p)
776 ret = saa7164_api_configure_dif(p, std);
777
778 return ret;
779}
780
781int saa7164_api_transition_port(struct saa7164_port *port, u8 mode)
782{
783 struct saa7164_dev *dev = port->dev;
784
785 int ret;
786
787 dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n",
788 __func__, port->nr, port->hwcfg.unitid, mode);
789
790 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
791 SAA_STATE_CONTROL, sizeof(mode), &mode);
792 if (ret != SAA_OK)
793 printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n",
794 __func__, port->nr, port->hwcfg.unitid, ret);
795
796 return ret;
797}
798
799int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
800{
801 int ret;
802
803 ret = saa7164_cmd_send(dev, 0, GET_CUR,
804 GET_FW_VERSION_CONTROL, sizeof(u32), version);
805 if (ret != SAA_OK)
806 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
807
808 return ret;
809}
810
811int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
812{
813 u8 reg[] = { 0x0f, 0x00 };
814
815 if (buflen < 128)
816 return -ENOMEM;
817
818 /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
819 /* TODO: Pull the details from the boards struct */
820 return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
821 &reg[0], 128, buf);
822}
823
824int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
825 struct saa7164_port *port)
826{
827 struct tmComResVBIFormatDescrHeader *fmt = &port->vbi_fmt_ntsc;
828
829 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
830 dprintk(DBGLVL_API, " VideoStandard = 0x%x\n", fmt->VideoStandard);
831 dprintk(DBGLVL_API, " StartLine = %d\n", fmt->StartLine);
832 dprintk(DBGLVL_API, " EndLine = %d\n", fmt->EndLine);
833 dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate);
834 dprintk(DBGLVL_API, " bNumLines = %d\n", fmt->bNumLines);
835
836 /* Cache the hardware configuration in the port */
837
838 port->bufcounter = port->hwcfg.BARLocation;
839 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
840 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
841 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
842 port->bufptr32l = port->hwcfg.BARLocation +
843 (4 * sizeof(u32)) +
844 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
845 port->bufptr32h = port->hwcfg.BARLocation +
846 (4 * sizeof(u32)) +
847 (sizeof(u32) * port->hwcfg.buffercount);
848 port->bufptr64 = port->hwcfg.BARLocation +
849 (4 * sizeof(u32)) +
850 (sizeof(u32) * port->hwcfg.buffercount);
851 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
852 port->hwcfg.BARLocation);
853
854 dprintk(DBGLVL_API, " = VS_FORMAT_VBI (becomes dev->en[%d])\n",
855 port->nr);
856
857 return 0;
858}
859
860int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
861 struct saa7164_port *port,
862 struct tmComResTSFormatDescrHeader *tsfmt)
863{
864 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
865 dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
866 dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
867 dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
868 dprintk(DBGLVL_API, " bguid = (....)\n");
869
870 /* Cache the hardware configuration in the port */
871
872 port->bufcounter = port->hwcfg.BARLocation;
873 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
874 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
875 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
876 port->bufptr32l = port->hwcfg.BARLocation +
877 (4 * sizeof(u32)) +
878 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
879 port->bufptr32h = port->hwcfg.BARLocation +
880 (4 * sizeof(u32)) +
881 (sizeof(u32) * port->hwcfg.buffercount);
882 port->bufptr64 = port->hwcfg.BARLocation +
883 (4 * sizeof(u32)) +
884 (sizeof(u32) * port->hwcfg.buffercount);
885 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
886 port->hwcfg.BARLocation);
887
888 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
889 port->nr);
890
891 return 0;
892}
893
894int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
895 struct saa7164_port *port,
896 struct tmComResPSFormatDescrHeader *fmt)
897{
898 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
899 dprintk(DBGLVL_API, " wPacketLength= 0x%x\n", fmt->wPacketLength);
900 dprintk(DBGLVL_API, " wPackLength= 0x%x\n", fmt->wPackLength);
901 dprintk(DBGLVL_API, " bPackDataType= 0x%x\n", fmt->bPackDataType);
902
903 /* Cache the hardware configuration in the port */
904 /* TODO: CHECK THIS in the port config */
905 port->bufcounter = port->hwcfg.BARLocation;
906 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
907 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
908 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
909 port->bufptr32l = port->hwcfg.BARLocation +
910 (4 * sizeof(u32)) +
911 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
912 port->bufptr32h = port->hwcfg.BARLocation +
913 (4 * sizeof(u32)) +
914 (sizeof(u32) * port->hwcfg.buffercount);
915 port->bufptr64 = port->hwcfg.BARLocation +
916 (4 * sizeof(u32)) +
917 (sizeof(u32) * port->hwcfg.buffercount);
918 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
919 port->hwcfg.BARLocation);
920
921 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n",
922 port->nr);
923
924 return 0;
925}
926
927int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
928{
929 struct saa7164_port *tsport = NULL;
930 struct saa7164_port *encport = NULL;
931 struct saa7164_port *vbiport = NULL;
932 u32 idx, next_offset;
933 int i;
934 struct tmComResDescrHeader *hdr, *t;
935 struct tmComResExtDevDescrHeader *exthdr;
936 struct tmComResPathDescrHeader *pathhdr;
937 struct tmComResAntTermDescrHeader *anttermhdr;
938 struct tmComResTunerDescrHeader *tunerunithdr;
939 struct tmComResDMATermDescrHeader *vcoutputtermhdr;
940 struct tmComResTSFormatDescrHeader *tsfmt;
941 struct tmComResPSFormatDescrHeader *psfmt;
942 struct tmComResSelDescrHeader *psel;
943 struct tmComResProcDescrHeader *pdh;
944 struct tmComResAFeatureDescrHeader *afd;
945 struct tmComResEncoderDescrHeader *edh;
946 struct tmComResVBIFormatDescrHeader *vbifmt;
947 u32 currpath = 0;
948
949 dprintk(DBGLVL_API,
950 "%s(?,?,%d) sizeof(struct tmComResDescrHeader) = %d bytes\n",
951 __func__, len, (u32)sizeof(struct tmComResDescrHeader));
952
953 for (idx = 0; idx < (len - sizeof(struct tmComResDescrHeader));) {
954
955 hdr = (struct tmComResDescrHeader *)(buf + idx);
956
957 if (hdr->type != CS_INTERFACE)
958 return SAA_ERR_NOT_SUPPORTED;
959
960 dprintk(DBGLVL_API, "@ 0x%x =\n", idx);
961 switch (hdr->subtype) {
962 case GENERAL_REQUEST:
963 dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
964 break;
965 case VC_TUNER_PATH:
966 dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
967 pathhdr = (struct tmComResPathDescrHeader *)(buf + idx);
968 dprintk(DBGLVL_API, " pathid = 0x%x\n",
969 pathhdr->pathid);
970 currpath = pathhdr->pathid;
971 break;
972 case VC_INPUT_TERMINAL:
973 dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
974 anttermhdr =
975 (struct tmComResAntTermDescrHeader *)(buf + idx);
976 dprintk(DBGLVL_API, " terminalid = 0x%x\n",
977 anttermhdr->terminalid);
978 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
979 anttermhdr->terminaltype);
980 switch (anttermhdr->terminaltype) {
981 case ITT_ANTENNA:
982 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
983 break;
984 case LINE_CONNECTOR:
985 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
986 break;
987 case SPDIF_CONNECTOR:
988 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
989 break;
990 case COMPOSITE_CONNECTOR:
991 dprintk(DBGLVL_API,
992 " = COMPOSITE_CONNECTOR\n");
993 break;
994 case SVIDEO_CONNECTOR:
995 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
996 break;
997 case COMPONENT_CONNECTOR:
998 dprintk(DBGLVL_API,
999 " = COMPONENT_CONNECTOR\n");
1000 break;
1001 case STANDARD_DMA:
1002 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
1003 break;
1004 default:
1005 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
1006 anttermhdr->terminaltype);
1007 }
1008 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
1009 anttermhdr->assocterminal);
1010 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
1011 anttermhdr->iterminal);
1012 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1013 anttermhdr->controlsize);
1014 break;
1015 case VC_OUTPUT_TERMINAL:
1016 dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
1017 vcoutputtermhdr =
1018 (struct tmComResDMATermDescrHeader *)(buf + idx);
1019 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1020 vcoutputtermhdr->unitid);
1021 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
1022 vcoutputtermhdr->terminaltype);
1023 switch (vcoutputtermhdr->terminaltype) {
1024 case ITT_ANTENNA:
1025 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
1026 break;
1027 case LINE_CONNECTOR:
1028 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
1029 break;
1030 case SPDIF_CONNECTOR:
1031 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
1032 break;
1033 case COMPOSITE_CONNECTOR:
1034 dprintk(DBGLVL_API,
1035 " = COMPOSITE_CONNECTOR\n");
1036 break;
1037 case SVIDEO_CONNECTOR:
1038 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
1039 break;
1040 case COMPONENT_CONNECTOR:
1041 dprintk(DBGLVL_API,
1042 " = COMPONENT_CONNECTOR\n");
1043 break;
1044 case STANDARD_DMA:
1045 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
1046 break;
1047 default:
1048 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
1049 vcoutputtermhdr->terminaltype);
1050 }
1051 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
1052 vcoutputtermhdr->assocterminal);
1053 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1054 vcoutputtermhdr->sourceid);
1055 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
1056 vcoutputtermhdr->iterminal);
1057 dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
1058 vcoutputtermhdr->BARLocation);
1059 dprintk(DBGLVL_API, " flags = 0x%x\n",
1060 vcoutputtermhdr->flags);
1061 dprintk(DBGLVL_API, " interruptid = 0x%x\n",
1062 vcoutputtermhdr->interruptid);
1063 dprintk(DBGLVL_API, " buffercount = 0x%x\n",
1064 vcoutputtermhdr->buffercount);
1065 dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
1066 vcoutputtermhdr->metadatasize);
1067 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1068 vcoutputtermhdr->controlsize);
1069 dprintk(DBGLVL_API, " numformats = 0x%x\n",
1070 vcoutputtermhdr->numformats);
1071
1072 t = (struct tmComResDescrHeader *)
1073 ((struct tmComResDMATermDescrHeader *)(buf + idx));
1074 next_offset = idx + (vcoutputtermhdr->len);
1075 for (i = 0; i < vcoutputtermhdr->numformats; i++) {
1076 t = (struct tmComResDescrHeader *)
1077 (buf + next_offset);
1078 switch (t->subtype) {
1079 case VS_FORMAT_MPEG2TS:
1080 tsfmt =
1081 (struct tmComResTSFormatDescrHeader *)t;
1082 if (currpath == 1)
1083 tsport = &dev->ports[SAA7164_PORT_TS1];
1084 else
1085 tsport = &dev->ports[SAA7164_PORT_TS2];
1086 memcpy(&tsport->hwcfg, vcoutputtermhdr,
1087 sizeof(*vcoutputtermhdr));
1088 saa7164_api_configure_port_mpeg2ts(dev,
1089 tsport, tsfmt);
1090 break;
1091 case VS_FORMAT_MPEG2PS:
1092 psfmt =
1093 (struct tmComResPSFormatDescrHeader *)t;
1094 if (currpath == 1)
1095 encport = &dev->ports[SAA7164_PORT_ENC1];
1096 else
1097 encport = &dev->ports[SAA7164_PORT_ENC2];
1098 memcpy(&encport->hwcfg, vcoutputtermhdr,
1099 sizeof(*vcoutputtermhdr));
1100 saa7164_api_configure_port_mpeg2ps(dev,
1101 encport, psfmt);
1102 break;
1103 case VS_FORMAT_VBI:
1104 vbifmt =
1105 (struct tmComResVBIFormatDescrHeader *)t;
1106 if (currpath == 1)
1107 vbiport = &dev->ports[SAA7164_PORT_VBI1];
1108 else
1109 vbiport = &dev->ports[SAA7164_PORT_VBI2];
1110 memcpy(&vbiport->hwcfg, vcoutputtermhdr,
1111 sizeof(*vcoutputtermhdr));
1112 memcpy(&vbiport->vbi_fmt_ntsc, vbifmt,
1113 sizeof(*vbifmt));
1114 saa7164_api_configure_port_vbi(dev,
1115 vbiport);
1116 break;
1117 case VS_FORMAT_RDS:
1118 dprintk(DBGLVL_API,
1119 " = VS_FORMAT_RDS\n");
1120 break;
1121 case VS_FORMAT_UNCOMPRESSED:
1122 dprintk(DBGLVL_API,
1123 " = VS_FORMAT_UNCOMPRESSED\n");
1124 break;
1125 case VS_FORMAT_TYPE:
1126 dprintk(DBGLVL_API,
1127 " = VS_FORMAT_TYPE\n");
1128 break;
1129 default:
1130 dprintk(DBGLVL_API,
1131 " = undefined (0x%x)\n",
1132 t->subtype);
1133 }
1134 next_offset += t->len;
1135 }
1136
1137 break;
1138 case TUNER_UNIT:
1139 dprintk(DBGLVL_API, " TUNER_UNIT\n");
1140 tunerunithdr =
1141 (struct tmComResTunerDescrHeader *)(buf + idx);
1142 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1143 tunerunithdr->unitid);
1144 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1145 tunerunithdr->sourceid);
1146 dprintk(DBGLVL_API, " iunit = 0x%x\n",
1147 tunerunithdr->iunit);
1148 dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
1149 tunerunithdr->tuningstandards);
1150 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1151 tunerunithdr->controlsize);
1152 dprintk(DBGLVL_API, " controls = 0x%x\n",
1153 tunerunithdr->controls);
1154
1155 if (tunerunithdr->unitid == tunerunithdr->iunit) {
1156 if (currpath == 1)
1157 encport = &dev->ports[SAA7164_PORT_ENC1];
1158 else
1159 encport = &dev->ports[SAA7164_PORT_ENC2];
1160 memcpy(&encport->tunerunit, tunerunithdr,
1161 sizeof(struct tmComResTunerDescrHeader));
1162 dprintk(DBGLVL_API,
1163 " (becomes dev->enc[%d] tuner)\n",
1164 encport->nr);
1165 }
1166 break;
1167 case VC_SELECTOR_UNIT:
1168 psel = (struct tmComResSelDescrHeader *)(buf + idx);
1169 dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
1170 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1171 psel->unitid);
1172 dprintk(DBGLVL_API, " nrinpins = 0x%x\n",
1173 psel->nrinpins);
1174 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1175 psel->sourceid);
1176 break;
1177 case VC_PROCESSING_UNIT:
1178 pdh = (struct tmComResProcDescrHeader *)(buf + idx);
1179 dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
1180 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1181 pdh->unitid);
1182 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1183 pdh->sourceid);
1184 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1185 pdh->controlsize);
1186 if (pdh->controlsize == 0x04) {
1187 if (currpath == 1)
1188 encport = &dev->ports[SAA7164_PORT_ENC1];
1189 else
1190 encport = &dev->ports[SAA7164_PORT_ENC2];
1191 memcpy(&encport->vidproc, pdh,
1192 sizeof(struct tmComResProcDescrHeader));
1193 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
1194 encport->nr);
1195 }
1196 break;
1197 case FEATURE_UNIT:
1198 afd = (struct tmComResAFeatureDescrHeader *)(buf + idx);
1199 dprintk(DBGLVL_API, " FEATURE_UNIT\n");
1200 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1201 afd->unitid);
1202 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1203 afd->sourceid);
1204 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1205 afd->controlsize);
1206 if (currpath == 1)
1207 encport = &dev->ports[SAA7164_PORT_ENC1];
1208 else
1209 encport = &dev->ports[SAA7164_PORT_ENC2];
1210 memcpy(&encport->audfeat, afd,
1211 sizeof(struct tmComResAFeatureDescrHeader));
1212 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
1213 encport->nr);
1214 break;
1215 case ENCODER_UNIT:
1216 edh = (struct tmComResEncoderDescrHeader *)(buf + idx);
1217 dprintk(DBGLVL_API, " ENCODER_UNIT\n");
1218 dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype);
1219 dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid);
1220 dprintk(DBGLVL_API, " vsourceid = 0x%x\n",
1221 edh->vsourceid);
1222 dprintk(DBGLVL_API, " asourceid = 0x%x\n",
1223 edh->asourceid);
1224 dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit);
1225 if (edh->iunit == edh->unitid) {
1226 if (currpath == 1)
1227 encport = &dev->ports[SAA7164_PORT_ENC1];
1228 else
1229 encport = &dev->ports[SAA7164_PORT_ENC2];
1230 memcpy(&encport->encunit, edh,
1231 sizeof(struct tmComResEncoderDescrHeader));
1232 dprintk(DBGLVL_API,
1233 " (becomes dev->enc[%d])\n",
1234 encport->nr);
1235 }
1236 break;
1237 case EXTENSION_UNIT:
1238 dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
1239 exthdr = (struct tmComResExtDevDescrHeader *)(buf + idx);
1240 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1241 exthdr->unitid);
1242 dprintk(DBGLVL_API, " deviceid = 0x%x\n",
1243 exthdr->deviceid);
1244 dprintk(DBGLVL_API, " devicetype = 0x%x\n",
1245 exthdr->devicetype);
1246 if (exthdr->devicetype & 0x1)
1247 dprintk(DBGLVL_API, " = Decoder Device\n");
1248 if (exthdr->devicetype & 0x2)
1249 dprintk(DBGLVL_API, " = GPIO Source\n");
1250 if (exthdr->devicetype & 0x4)
1251 dprintk(DBGLVL_API, " = Video Decoder\n");
1252 if (exthdr->devicetype & 0x8)
1253 dprintk(DBGLVL_API, " = Audio Decoder\n");
1254 if (exthdr->devicetype & 0x20)
1255 dprintk(DBGLVL_API, " = Crossbar\n");
1256 if (exthdr->devicetype & 0x40)
1257 dprintk(DBGLVL_API, " = Tuner\n");
1258 if (exthdr->devicetype & 0x80)
1259 dprintk(DBGLVL_API, " = IF PLL\n");
1260 if (exthdr->devicetype & 0x100)
1261 dprintk(DBGLVL_API, " = Demodulator\n");
1262 if (exthdr->devicetype & 0x200)
1263 dprintk(DBGLVL_API, " = RDS Decoder\n");
1264 if (exthdr->devicetype & 0x400)
1265 dprintk(DBGLVL_API, " = Encoder\n");
1266 if (exthdr->devicetype & 0x800)
1267 dprintk(DBGLVL_API, " = IR Decoder\n");
1268 if (exthdr->devicetype & 0x1000)
1269 dprintk(DBGLVL_API, " = EEPROM\n");
1270 if (exthdr->devicetype & 0x2000)
1271 dprintk(DBGLVL_API,
1272 " = VBI Decoder\n");
1273 if (exthdr->devicetype & 0x10000)
1274 dprintk(DBGLVL_API,
1275 " = Streaming Device\n");
1276 if (exthdr->devicetype & 0x20000)
1277 dprintk(DBGLVL_API,
1278 " = DRM Device\n");
1279 if (exthdr->devicetype & 0x40000000)
1280 dprintk(DBGLVL_API,
1281 " = Generic Device\n");
1282 if (exthdr->devicetype & 0x80000000)
1283 dprintk(DBGLVL_API,
1284 " = Config Space Device\n");
1285 dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
1286 exthdr->numgpiopins);
1287 dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
1288 exthdr->numgpiogroups);
1289 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1290 exthdr->controlsize);
1291 if (exthdr->devicetype & 0x80) {
1292 if (currpath == 1)
1293 encport = &dev->ports[SAA7164_PORT_ENC1];
1294 else
1295 encport = &dev->ports[SAA7164_PORT_ENC2];
1296 memcpy(&encport->ifunit, exthdr,
1297 sizeof(struct tmComResExtDevDescrHeader));
1298 dprintk(DBGLVL_API,
1299 " (becomes dev->enc[%d])\n",
1300 encport->nr);
1301 }
1302 break;
1303 case PVC_INFRARED_UNIT:
1304 dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
1305 break;
1306 case DRM_UNIT:
1307 dprintk(DBGLVL_API, " DRM_UNIT\n");
1308 break;
1309 default:
1310 dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
1311 }
1312
1313 dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
1314 dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
1315 dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
1316 dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
1317
1318 idx += hdr->len;
1319 }
1320
1321 return 0;
1322}
1323
1324int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
1325{
1326 int ret;
1327 u32 buflen = 0;
1328 u8 *buf;
1329
1330 dprintk(DBGLVL_API, "%s()\n", __func__);
1331
1332 /* Get the total descriptor length */
1333 ret = saa7164_cmd_send(dev, 0, GET_LEN,
1334 GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
1335 if (ret != SAA_OK)
1336 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1337
1338 dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
1339 __func__, buflen);
1340
1341 /* Allocate enough storage for all of the descs */
1342 buf = kzalloc(buflen, GFP_KERNEL);
1343 if (!buf)
1344 return SAA_ERR_NO_RESOURCES;
1345
1346 /* Retrieve them */
1347 ret = saa7164_cmd_send(dev, 0, GET_CUR,
1348 GET_DESCRIPTORS_CONTROL, buflen, buf);
1349 if (ret != SAA_OK) {
1350 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1351 goto out;
1352 }
1353
1354 if (saa_debug & DBGLVL_API)
1355 saa7164_dumphex16(dev, buf, (buflen/16)*16);
1356
1357 saa7164_api_dump_subdevs(dev, buf, buflen);
1358
1359out:
1360 kfree(buf);
1361 return ret;
1362}
1363
1364int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
1365 u32 datalen, u8 *data)
1366{
1367 struct saa7164_dev *dev = bus->dev;
1368 u16 len = 0;
1369 int unitid;
1370 u32 regval;
1371 u8 buf[256];
1372 int ret;
1373
1374 dprintk(DBGLVL_API, "%s()\n", __func__);
1375
1376 if (reglen > 4)
1377 return -EIO;
1378
1379 if (reglen == 1)
1380 regval = *(reg);
1381 else
1382 if (reglen == 2)
1383 regval = ((*(reg) << 8) || *(reg+1));
1384 else
1385 if (reglen == 3)
1386 regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
1387 else
1388 if (reglen == 4)
1389 regval = ((*(reg) << 24) | (*(reg+1) << 16) |
1390 (*(reg+2) << 8) | *(reg+3));
1391
1392 /* Prepare the send buffer */
1393 /* Bytes 00-03 source register length
1394 * 04-07 source bytes to read
1395 * 08... register address
1396 */
1397 memset(buf, 0, sizeof(buf));
1398 memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
1399 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1400 *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
1401
1402 unitid = saa7164_i2caddr_to_unitid(bus, addr);
1403 if (unitid < 0) {
1404 printk(KERN_ERR
1405 "%s() error, cannot translate regaddr 0x%x to unitid\n",
1406 __func__, addr);
1407 return -EIO;
1408 }
1409
1410 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
1411 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
1412 if (ret != SAA_OK) {
1413 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1414 return -EIO;
1415 }
1416
1417 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
1418
1419 if (saa_debug & DBGLVL_I2C)
1420 saa7164_dumphex16(dev, buf, 2 * 16);
1421
1422 ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
1423 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
1424 if (ret != SAA_OK)
1425 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1426 else {
1427 if (saa_debug & DBGLVL_I2C)
1428 saa7164_dumphex16(dev, buf, sizeof(buf));
1429 memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
1430 }
1431
1432 return ret == SAA_OK ? 0 : -EIO;
1433}
1434
1435/* For a given 8 bit i2c address device, write the buffer */
1436int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
1437 u8 *data)
1438{
1439 struct saa7164_dev *dev = bus->dev;
1440 u16 len = 0;
1441 int unitid;
1442 int reglen;
1443 u8 buf[256];
1444 int ret;
1445
1446 dprintk(DBGLVL_API, "%s()\n", __func__);
1447
1448 if ((datalen == 0) || (datalen > 232))
1449 return -EIO;
1450
1451 memset(buf, 0, sizeof(buf));
1452
1453 unitid = saa7164_i2caddr_to_unitid(bus, addr);
1454 if (unitid < 0) {
1455 printk(KERN_ERR
1456 "%s() error, cannot translate regaddr 0x%x to unitid\n",
1457 __func__, addr);
1458 return -EIO;
1459 }
1460
1461 reglen = saa7164_i2caddr_to_reglen(bus, addr);
1462 if (reglen < 0) {
1463 printk(KERN_ERR
1464 "%s() error, cannot translate regaddr to reglen\n",
1465 __func__);
1466 return -EIO;
1467 }
1468
1469 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
1470 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
1471 if (ret != SAA_OK) {
1472 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1473 return -EIO;
1474 }
1475
1476 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
1477
1478 /* Prepare the send buffer */
1479 /* Bytes 00-03 dest register length
1480 * 04-07 dest bytes to write
1481 * 08... register address
1482 */
1483 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1484 *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
1485 memcpy((buf + 2 * sizeof(u32)), data, datalen);
1486
1487 if (saa_debug & DBGLVL_I2C)
1488 saa7164_dumphex16(dev, buf, sizeof(buf));
1489
1490 ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
1491 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
1492 if (ret != SAA_OK)
1493 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1494
1495 return ret == SAA_OK ? 0 : -EIO;
1496}
1497
1498int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
1499 u8 pin, u8 state)
1500{
1501 int ret;
1502 struct tmComResGPIO t;
1503
1504 dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
1505 __func__, unitid, pin, state);
1506
1507 if ((pin > 7) || (state > 2))
1508 return SAA_ERR_BAD_PARAMETER;
1509
1510 t.pin = pin;
1511 t.state = state;
1512
1513 ret = saa7164_cmd_send(dev, unitid, SET_CUR,
1514 EXU_GPIO_CONTROL, sizeof(t), &t);
1515 if (ret != SAA_OK)
1516 printk(KERN_ERR "%s() error, ret = 0x%x\n",
1517 __func__, ret);
1518
1519 return ret;
1520}
1521
1522int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
1523 u8 pin)
1524{
1525 return saa7164_api_modify_gpio(dev, unitid, pin, 1);
1526}
1527
1528int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
1529 u8 pin)
1530{
1531 return saa7164_api_modify_gpio(dev, unitid, pin, 0);
1532}
1533
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
new file mode 100644
index 00000000000..66696fa8341
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -0,0 +1,322 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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/slab.h>
23
24#include "saa7164.h"
25
26/* The PCI address space for buffer handling looks like this:
27 *
28 * +-u32 wide-------------+
29 * | +
30 * +-u64 wide------------------------------------+
31 * + +
32 * +----------------------+
33 * | CurrentBufferPtr + Pointer to current PCI buffer >-+
34 * +----------------------+ |
35 * | Unused + |
36 * +----------------------+ |
37 * | Pitch + = 188 (bytes) |
38 * +----------------------+ |
39 * | PCI buffer size + = pitch * number of lines (312) |
40 * +----------------------+ |
41 * |0| Buf0 Write Offset + |
42 * +----------------------+ v
43 * |1| Buf1 Write Offset + |
44 * +----------------------+ |
45 * |2| Buf2 Write Offset + |
46 * +----------------------+ |
47 * |3| Buf3 Write Offset + |
48 * +----------------------+ |
49 * ... More write offsets |
50 * +---------------------------------------------+ |
51 * +0| set of ptrs to PCI pagetables + |
52 * +---------------------------------------------+ |
53 * +1| set of ptrs to PCI pagetables + <--------+
54 * +---------------------------------------------+
55 * +2| set of ptrs to PCI pagetables +
56 * +---------------------------------------------+
57 * +3| set of ptrs to PCI pagetables + >--+
58 * +---------------------------------------------+ |
59 * ... More buffer pointers | +----------------+
60 * +->| pt[0] TS data |
61 * | +----------------+
62 * |
63 * | +----------------+
64 * +->| pt[1] TS data |
65 * | +----------------+
66 * | etc
67 */
68
69void saa7164_buffer_display(struct saa7164_buffer *buf)
70{
71 struct saa7164_dev *dev = buf->port->dev;
72 int i;
73
74 dprintk(DBGLVL_BUF, "%s() buffer @ 0x%p nr=%d\n",
75 __func__, buf, buf->idx);
76 dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08llx len = 0x%x\n",
77 buf->cpu, (long long)buf->dma, buf->pci_size);
78 dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08llx len = 0x%x\n",
79 buf->pt_cpu, (long long)buf->pt_dma, buf->pt_size);
80
81 /* Format the Page Table Entries to point into the data buffer */
82 for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
83
84 dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
85 i, buf->pt_cpu, (u64)*(buf->pt_cpu));
86
87 }
88}
89/* Allocate a new buffer structure and associated PCI space in bytes.
90 * len must be a multiple of sizeof(u64)
91 */
92struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
93 u32 len)
94{
95 struct tmHWStreamParameters *params = &port->hw_streamingparams;
96 struct saa7164_buffer *buf = NULL;
97 struct saa7164_dev *dev = port->dev;
98 int i;
99
100 if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
101 log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
102 goto ret;
103 }
104
105 buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
106 if (!buf) {
107 log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
108 goto ret;
109 }
110
111 buf->idx = -1;
112 buf->port = port;
113 buf->flags = SAA7164_BUFFER_FREE;
114 buf->pos = 0;
115 buf->actual_size = params->pitch * params->numberoflines;
116 buf->crc = 0;
117 /* TODO: arg len is being ignored */
118 buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
119 buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
120
121 /* Allocate contiguous memory */
122 buf->cpu = pci_alloc_consistent(port->dev->pci, buf->pci_size,
123 &buf->dma);
124 if (!buf->cpu)
125 goto fail1;
126
127 buf->pt_cpu = pci_alloc_consistent(port->dev->pci, buf->pt_size,
128 &buf->pt_dma);
129 if (!buf->pt_cpu)
130 goto fail2;
131
132 /* init the buffers to a known pattern, easier during debugging */
133 memset_io(buf->cpu, 0xff, buf->pci_size);
134 buf->crc = crc32(0, buf->cpu, buf->actual_size);
135 memset_io(buf->pt_cpu, 0xff, buf->pt_size);
136
137 dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n",
138 __func__, buf, params->numpagetables);
139 dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n",
140 buf->cpu, (long)buf->dma, buf->pci_size);
141 dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
142 buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
143
144 /* Format the Page Table Entries to point into the data buffer */
145 for (i = 0 ; i < params->numpagetables; i++) {
146
147 *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
148 dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
149 i, buf->pt_cpu, (u64)*(buf->pt_cpu));
150
151 }
152
153 goto ret;
154
155fail2:
156 pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
157fail1:
158 kfree(buf);
159
160 buf = NULL;
161ret:
162 return buf;
163}
164
165int saa7164_buffer_dealloc(struct saa7164_buffer *buf)
166{
167 struct saa7164_dev *dev;
168
169 if (!buf || !buf->port)
170 return SAA_ERR_BAD_PARAMETER;
171 dev = buf->port->dev;
172
173 dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n",
174 __func__, buf);
175
176 if (buf->flags != SAA7164_BUFFER_FREE)
177 log_warn(" freeing a non-free buffer\n");
178
179 pci_free_consistent(dev->pci, buf->pci_size, buf->cpu, buf->dma);
180 pci_free_consistent(dev->pci, buf->pt_size, buf->pt_cpu, buf->pt_dma);
181
182 kfree(buf);
183
184 return SAA_OK;
185}
186
187int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i)
188{
189 struct saa7164_dev *dev = port->dev;
190
191 if ((i < 0) || (i >= port->hwcfg.buffercount))
192 return -EINVAL;
193
194 dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
195
196 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
197
198 return 0;
199}
200
201/* Write a buffer into the hardware */
202int saa7164_buffer_activate(struct saa7164_buffer *buf, int i)
203{
204 struct saa7164_port *port = buf->port;
205 struct saa7164_dev *dev = port->dev;
206
207 if ((i < 0) || (i >= port->hwcfg.buffercount))
208 return -EINVAL;
209
210 dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
211
212 buf->idx = i; /* Note of which buffer list index position we occupy */
213 buf->flags = SAA7164_BUFFER_BUSY;
214 buf->pos = 0;
215
216 /* TODO: Review this in light of 32v64 assignments */
217 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
218 saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma);
219 saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
220
221 dprintk(DBGLVL_BUF, " buf[%d] offset 0x%llx (0x%x) "
222 "buf 0x%llx/%llx (0x%x/%x) nr=%d\n",
223 buf->idx,
224 (u64)port->bufoffset + (i * sizeof(u32)),
225 saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
226 (u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
227 (u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
228 saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) * 2)),
229 saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) * 2)),
230 buf->idx);
231
232 return 0;
233}
234
235int saa7164_buffer_cfg_port(struct saa7164_port *port)
236{
237 struct tmHWStreamParameters *params = &port->hw_streamingparams;
238 struct saa7164_dev *dev = port->dev;
239 struct saa7164_buffer *buf;
240 struct list_head *c, *n;
241 int i = 0;
242
243 dprintk(DBGLVL_BUF, "%s(port=%d)\n", __func__, port->nr);
244
245 saa7164_writel(port->bufcounter, 0);
246 saa7164_writel(port->pitch, params->pitch);
247 saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
248
249 dprintk(DBGLVL_BUF, " configured:\n");
250 dprintk(DBGLVL_BUF, " lmmio 0x%p\n", dev->lmmio);
251 dprintk(DBGLVL_BUF, " bufcounter 0x%x = 0x%x\n", port->bufcounter,
252 saa7164_readl(port->bufcounter));
253
254 dprintk(DBGLVL_BUF, " pitch 0x%x = %d\n", port->pitch,
255 saa7164_readl(port->pitch));
256
257 dprintk(DBGLVL_BUF, " bufsize 0x%x = %d\n", port->bufsize,
258 saa7164_readl(port->bufsize));
259
260 dprintk(DBGLVL_BUF, " buffercount = %d\n", port->hwcfg.buffercount);
261 dprintk(DBGLVL_BUF, " bufoffset = 0x%x\n", port->bufoffset);
262 dprintk(DBGLVL_BUF, " bufptr32h = 0x%x\n", port->bufptr32h);
263 dprintk(DBGLVL_BUF, " bufptr32l = 0x%x\n", port->bufptr32l);
264
265 /* Poke the buffers and offsets into PCI space */
266 mutex_lock(&port->dmaqueue_lock);
267 list_for_each_safe(c, n, &port->dmaqueue.list) {
268 buf = list_entry(c, struct saa7164_buffer, list);
269
270 if (buf->flags != SAA7164_BUFFER_FREE)
271 BUG();
272
273 /* Place the buffer in the h/w queue */
274 saa7164_buffer_activate(buf, i);
275
276 /* Don't exceed the device maximum # bufs */
277 if (i++ > port->hwcfg.buffercount)
278 BUG();
279
280 }
281 mutex_unlock(&port->dmaqueue_lock);
282
283 return 0;
284}
285
286struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
287 u32 len)
288{
289 struct saa7164_user_buffer *buf;
290
291 buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL);
292 if (!buf)
293 return NULL;
294
295 buf->data = kzalloc(len, GFP_KERNEL);
296
297 if (!buf->data) {
298 kfree(buf);
299 return NULL;
300 }
301
302 buf->actual_size = len;
303 buf->pos = 0;
304 buf->crc = 0;
305
306 dprintk(DBGLVL_BUF, "%s() allocated user buffer @ 0x%p\n",
307 __func__, buf);
308
309 return buf;
310}
311
312void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
313{
314 if (!buf)
315 return;
316
317 kfree(buf->data);
318 buf->data = NULL;
319
320 kfree(buf);
321}
322
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
new file mode 100644
index 00000000000..466e1b02f91
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -0,0 +1,475 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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 "saa7164.h"
23
24/* The message bus to/from the firmware is a ring buffer in PCI address
25 * space. Establish the defaults.
26 */
27int saa7164_bus_setup(struct saa7164_dev *dev)
28{
29 struct tmComResBusInfo *b = &dev->bus;
30
31 mutex_init(&b->lock);
32
33 b->Type = TYPE_BUS_PCIe;
34 b->m_wMaxReqSize = SAA_DEVICE_MAXREQUESTSIZE;
35
36 b->m_pdwSetRing = (u8 *)(dev->bmmio +
37 ((u32)dev->busdesc.CommandRing));
38
39 b->m_dwSizeSetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
40
41 b->m_pdwGetRing = (u8 *)(dev->bmmio +
42 ((u32)dev->busdesc.ResponseRing));
43
44 b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
45
46 b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) +
47 (2 * sizeof(u64));
48 b->m_dwSetReadPos = b->m_dwSetWritePos + (1 * sizeof(u32));
49
50 b->m_dwGetWritePos = b->m_dwSetWritePos + (2 * sizeof(u32));
51 b->m_dwGetReadPos = b->m_dwSetWritePos + (3 * sizeof(u32));
52
53 return 0;
54}
55
56void saa7164_bus_dump(struct saa7164_dev *dev)
57{
58 struct tmComResBusInfo *b = &dev->bus;
59
60 dprintk(DBGLVL_BUS, "Dumping the bus structure:\n");
61 dprintk(DBGLVL_BUS, " .type = %d\n", b->Type);
62 dprintk(DBGLVL_BUS, " .dev->bmmio = 0x%p\n", dev->bmmio);
63 dprintk(DBGLVL_BUS, " .m_wMaxReqSize = 0x%x\n", b->m_wMaxReqSize);
64 dprintk(DBGLVL_BUS, " .m_pdwSetRing = 0x%p\n", b->m_pdwSetRing);
65 dprintk(DBGLVL_BUS, " .m_dwSizeSetRing = 0x%x\n", b->m_dwSizeSetRing);
66 dprintk(DBGLVL_BUS, " .m_pdwGetRing = 0x%p\n", b->m_pdwGetRing);
67 dprintk(DBGLVL_BUS, " .m_dwSizeGetRing = 0x%x\n", b->m_dwSizeGetRing);
68
69 dprintk(DBGLVL_BUS, " .m_dwSetReadPos = 0x%x (0x%08x)\n",
70 b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
71
72 dprintk(DBGLVL_BUS, " .m_dwSetWritePos = 0x%x (0x%08x)\n",
73 b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
74
75 dprintk(DBGLVL_BUS, " .m_dwGetReadPos = 0x%x (0x%08x)\n",
76 b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
77
78 dprintk(DBGLVL_BUS, " .m_dwGetWritePos = 0x%x (0x%08x)\n",
79 b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
80
81}
82
83/* Intensionally throw a BUG() if the state of the message bus looks corrupt */
84void saa7164_bus_verify(struct saa7164_dev *dev)
85{
86 struct tmComResBusInfo *b = &dev->bus;
87 int bug = 0;
88
89 if (saa7164_readl(b->m_dwSetReadPos) > b->m_dwSizeSetRing)
90 bug++;
91
92 if (saa7164_readl(b->m_dwSetWritePos) > b->m_dwSizeSetRing)
93 bug++;
94
95 if (saa7164_readl(b->m_dwGetReadPos) > b->m_dwSizeGetRing)
96 bug++;
97
98 if (saa7164_readl(b->m_dwGetWritePos) > b->m_dwSizeGetRing)
99 bug++;
100
101 if (bug) {
102 saa_debug = 0xffff; /* Ensure we get the bus dump */
103 saa7164_bus_dump(dev);
104 saa_debug = 1024; /* Ensure we get the bus dump */
105 BUG();
106 }
107}
108
109void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m,
110 void *buf)
111{
112 dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
113 dprintk(DBGLVL_BUS, " .id = %d\n", m->id);
114 dprintk(DBGLVL_BUS, " .flags = 0x%x\n", m->flags);
115 dprintk(DBGLVL_BUS, " .size = 0x%x\n", m->size);
116 dprintk(DBGLVL_BUS, " .command = 0x%x\n", m->command);
117 dprintk(DBGLVL_BUS, " .controlselector = 0x%x\n", m->controlselector);
118 dprintk(DBGLVL_BUS, " .seqno = %d\n", m->seqno);
119 if (buf)
120 dprintk(DBGLVL_BUS, " .buffer (ignored)\n");
121}
122
123/*
124 * Places a command or a response on the bus. The implementation does not
125 * know if it is a command or a response it just places the data on the
126 * bus depending on the bus information given in the struct tmComResBusInfo
127 * structure. If the command or response does not fit into the bus ring
128 * buffer it will be refused.
129 *
130 * Return Value:
131 * SAA_OK The function executed successfully.
132 * < 0 One or more members are not initialized.
133 */
134int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
135 void *buf)
136{
137 struct tmComResBusInfo *bus = &dev->bus;
138 u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp;
139 u32 new_swp, space_rem;
140 int ret = SAA_ERR_BAD_PARAMETER;
141
142 if (!msg) {
143 printk(KERN_ERR "%s() !msg\n", __func__);
144 return SAA_ERR_BAD_PARAMETER;
145 }
146
147 dprintk(DBGLVL_BUS, "%s()\n", __func__);
148
149 saa7164_bus_verify(dev);
150
151 msg->size = cpu_to_le16(msg->size);
152 msg->command = cpu_to_le16(msg->command);
153 msg->controlselector = cpu_to_le16(msg->controlselector);
154
155 if (msg->size > dev->bus.m_wMaxReqSize) {
156 printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
157 __func__);
158 return SAA_ERR_BAD_PARAMETER;
159 }
160
161 if ((msg->size > 0) && (buf == NULL)) {
162 printk(KERN_ERR "%s() Missing message buffer\n", __func__);
163 return SAA_ERR_BAD_PARAMETER;
164 }
165
166 /* Lock the bus from any other access */
167 mutex_lock(&bus->lock);
168
169 bytes_to_write = sizeof(*msg) + msg->size;
170 free_write_space = 0;
171 timeout = SAA_BUS_TIMEOUT;
172 curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos));
173 curr_swp = le32_to_cpu(saa7164_readl(bus->m_dwSetWritePos));
174
175 /* Deal with ring wrapping issues */
176 if (curr_srp > curr_swp)
177 /* Deal with the wrapped ring */
178 free_write_space = curr_srp - curr_swp;
179 else
180 /* The ring has not wrapped yet */
181 free_write_space = (curr_srp + bus->m_dwSizeSetRing) - curr_swp;
182
183 dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__,
184 bytes_to_write);
185
186 dprintk(DBGLVL_BUS, "%s() free_write_space = %d\n", __func__,
187 free_write_space);
188
189 dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp);
190 dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp);
191
192 /* Process the msg and write the content onto the bus */
193 while (bytes_to_write >= free_write_space) {
194
195 if (timeout-- == 0) {
196 printk(KERN_ERR "%s() bus timeout\n", __func__);
197 ret = SAA_ERR_NO_RESOURCES;
198 goto out;
199 }
200
201 /* TODO: Review this delay, efficient? */
202 /* Wait, allowing the hardware fetch time */
203 mdelay(1);
204
205 /* Check the space usage again */
206 curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos));
207
208 /* Deal with ring wrapping issues */
209 if (curr_srp > curr_swp)
210 /* Deal with the wrapped ring */
211 free_write_space = curr_srp - curr_swp;
212 else
213 /* Read didn't wrap around the buffer */
214 free_write_space = (curr_srp + bus->m_dwSizeSetRing) -
215 curr_swp;
216
217 }
218
219 /* Calculate the new write position */
220 new_swp = curr_swp + bytes_to_write;
221
222 dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
223 dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__,
224 bus->m_dwSizeSetRing);
225
226 /* Mental Note: line 462 tmmhComResBusPCIe.cpp */
227
228 /* Check if we're going to wrap again */
229 if (new_swp > bus->m_dwSizeSetRing) {
230
231 /* Ring wraps */
232 new_swp -= bus->m_dwSizeSetRing;
233
234 space_rem = bus->m_dwSizeSetRing - curr_swp;
235
236 dprintk(DBGLVL_BUS, "%s() space_rem = %x\n", __func__,
237 space_rem);
238
239 dprintk(DBGLVL_BUS, "%s() sizeof(*msg) = %d\n", __func__,
240 (u32)sizeof(*msg));
241
242 if (space_rem < sizeof(*msg)) {
243 dprintk(DBGLVL_BUS, "%s() tr4\n", __func__);
244
245 /* Split the msg into pieces as the ring wraps */
246 memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem);
247 memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem,
248 sizeof(*msg) - space_rem);
249
250 memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem,
251 buf, msg->size);
252
253 } else if (space_rem == sizeof(*msg)) {
254 dprintk(DBGLVL_BUS, "%s() tr5\n", __func__);
255
256 /* Additional data at the beginning of the ring */
257 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
258 memcpy(bus->m_pdwSetRing, buf, msg->size);
259
260 } else {
261 /* Additional data wraps around the ring */
262 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
263 if (msg->size > 0) {
264 memcpy(bus->m_pdwSetRing + curr_swp +
265 sizeof(*msg), buf, space_rem -
266 sizeof(*msg));
267 memcpy(bus->m_pdwSetRing, (u8 *)buf +
268 space_rem - sizeof(*msg),
269 bytes_to_write - space_rem);
270 }
271
272 }
273
274 } /* (new_swp > bus->m_dwSizeSetRing) */
275 else {
276 dprintk(DBGLVL_BUS, "%s() tr6\n", __func__);
277
278 /* The ring buffer doesn't wrap, two simple copies */
279 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
280 memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf,
281 msg->size);
282 }
283
284 dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
285
286 /* Update the bus write position */
287 saa7164_writel(bus->m_dwSetWritePos, cpu_to_le32(new_swp));
288 ret = SAA_OK;
289
290out:
291 saa7164_bus_dump(dev);
292 mutex_unlock(&bus->lock);
293 saa7164_bus_verify(dev);
294 return ret;
295}
296
297/*
298 * Receive a command or a response from the bus. The implementation does not
299 * know if it is a command or a response it simply dequeues the data,
300 * depending on the bus information given in the struct tmComResBusInfo
301 * structure.
302 *
303 * Return Value:
304 * 0 The function executed successfully.
305 * < 0 One or more members are not initialized.
306 */
307int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
308 void *buf, int peekonly)
309{
310 struct tmComResBusInfo *bus = &dev->bus;
311 u32 bytes_to_read, write_distance, curr_grp, curr_gwp,
312 new_grp, buf_size, space_rem;
313 struct tmComResInfo msg_tmp;
314 int ret = SAA_ERR_BAD_PARAMETER;
315
316 saa7164_bus_verify(dev);
317
318 if (msg == NULL)
319 return ret;
320
321 if (msg->size > dev->bus.m_wMaxReqSize) {
322 printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
323 __func__);
324 return ret;
325 }
326
327 if ((peekonly == 0) && (msg->size > 0) && (buf == NULL)) {
328 printk(KERN_ERR
329 "%s() Missing msg buf, size should be %d bytes\n",
330 __func__, msg->size);
331 return ret;
332 }
333
334 mutex_lock(&bus->lock);
335
336 /* Peek the bus to see if a msg exists, if it's not what we're expecting
337 * then return cleanly else read the message from the bus.
338 */
339 curr_gwp = le32_to_cpu(saa7164_readl(bus->m_dwGetWritePos));
340 curr_grp = le32_to_cpu(saa7164_readl(bus->m_dwGetReadPos));
341
342 if (curr_gwp == curr_grp) {
343 ret = SAA_ERR_EMPTY;
344 goto out;
345 }
346
347 bytes_to_read = sizeof(*msg);
348
349 /* Calculate write distance to current read position */
350 write_distance = 0;
351 if (curr_gwp >= curr_grp)
352 /* Write doesn't wrap around the ring */
353 write_distance = curr_gwp - curr_grp;
354 else
355 /* Write wraps around the ring */
356 write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
357
358 if (bytes_to_read > write_distance) {
359 printk(KERN_ERR "%s() No message/response found\n", __func__);
360 ret = SAA_ERR_INVALID_COMMAND;
361 goto out;
362 }
363
364 /* Calculate the new read position */
365 new_grp = curr_grp + bytes_to_read;
366 if (new_grp > bus->m_dwSizeGetRing) {
367
368 /* Ring wraps */
369 new_grp -= bus->m_dwSizeGetRing;
370 space_rem = bus->m_dwSizeGetRing - curr_grp;
371
372 memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem);
373 memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing,
374 bytes_to_read - space_rem);
375
376 } else {
377 /* No wrapping */
378 memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read);
379 }
380
381 /* No need to update the read positions, because this was a peek */
382 /* If the caller specifically want to peek, return */
383 if (peekonly) {
384 memcpy(msg, &msg_tmp, sizeof(*msg));
385 goto peekout;
386 }
387
388 /* Check if the command/response matches what is expected */
389 if ((msg_tmp.id != msg->id) || (msg_tmp.command != msg->command) ||
390 (msg_tmp.controlselector != msg->controlselector) ||
391 (msg_tmp.seqno != msg->seqno) || (msg_tmp.size != msg->size)) {
392
393 printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__);
394 saa7164_bus_dumpmsg(dev, msg, buf);
395 saa7164_bus_dumpmsg(dev, &msg_tmp, NULL);
396 ret = SAA_ERR_INVALID_COMMAND;
397 goto out;
398 }
399
400 /* Get the actual command and response from the bus */
401 buf_size = msg->size;
402
403 bytes_to_read = sizeof(*msg) + msg->size;
404 /* Calculate write distance to current read position */
405 write_distance = 0;
406 if (curr_gwp >= curr_grp)
407 /* Write doesn't wrap around the ring */
408 write_distance = curr_gwp - curr_grp;
409 else
410 /* Write wraps around the ring */
411 write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
412
413 if (bytes_to_read > write_distance) {
414 printk(KERN_ERR "%s() Invalid bus state, missing msg "
415 "or mangled ring, faulty H/W / bad code?\n", __func__);
416 ret = SAA_ERR_INVALID_COMMAND;
417 goto out;
418 }
419
420 /* Calculate the new read position */
421 new_grp = curr_grp + bytes_to_read;
422 if (new_grp > bus->m_dwSizeGetRing) {
423
424 /* Ring wraps */
425 new_grp -= bus->m_dwSizeGetRing;
426 space_rem = bus->m_dwSizeGetRing - curr_grp;
427
428 if (space_rem < sizeof(*msg)) {
429 /* msg wraps around the ring */
430 memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem);
431 memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing,
432 sizeof(*msg) - space_rem);
433 if (buf)
434 memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) -
435 space_rem, buf_size);
436
437 } else if (space_rem == sizeof(*msg)) {
438 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
439 if (buf)
440 memcpy(buf, bus->m_pdwGetRing, buf_size);
441 } else {
442 /* Additional data wraps around the ring */
443 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
444 if (buf) {
445 memcpy(buf, bus->m_pdwGetRing + curr_grp +
446 sizeof(*msg), space_rem - sizeof(*msg));
447 memcpy(buf + space_rem - sizeof(*msg),
448 bus->m_pdwGetRing, bytes_to_read -
449 space_rem);
450 }
451
452 }
453
454 } else {
455 /* No wrapping */
456 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
457 if (buf)
458 memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg),
459 buf_size);
460 }
461
462 /* Update the read positions, adjusting the ring */
463 saa7164_writel(bus->m_dwGetReadPos, cpu_to_le32(new_grp));
464
465peekout:
466 msg->size = le16_to_cpu(msg->size);
467 msg->command = le16_to_cpu(msg->command);
468 msg->controlselector = le16_to_cpu(msg->controlselector);
469 ret = SAA_OK;
470out:
471 mutex_unlock(&bus->lock);
472 saa7164_bus_verify(dev);
473 return ret;
474}
475
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c
new file mode 100644
index 00000000000..c71369173fa
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-cards.c
@@ -0,0 +1,715 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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 "saa7164.h"
28
29/* The Bridge API needs to understand register widths (in bytes) for the
30 * attached I2C devices, so we can simplify the virtual i2c mechansms
31 * and keep the -i2c.c implementation clean.
32 */
33#define REGLEN_8bit 1
34#define REGLEN_16bit 2
35
36struct saa7164_board saa7164_boards[] = {
37 [SAA7164_BOARD_UNKNOWN] = {
38 /* Bridge will not load any firmware, without knowing
39 * the rev this would be fatal. */
40 .name = "Unknown",
41 },
42 [SAA7164_BOARD_UNKNOWN_REV2] = {
43 /* Bridge will load the v2 f/w and dump descriptors */
44 /* Required during new board bringup */
45 .name = "Generic Rev2",
46 .chiprev = SAA7164_CHIP_REV2,
47 },
48 [SAA7164_BOARD_UNKNOWN_REV3] = {
49 /* Bridge will load the v2 f/w and dump descriptors */
50 /* Required during new board bringup */
51 .name = "Generic Rev3",
52 .chiprev = SAA7164_CHIP_REV3,
53 },
54 [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
55 .name = "Hauppauge WinTV-HVR2200",
56 .porta = SAA7164_MPEG_DVB,
57 .portb = SAA7164_MPEG_DVB,
58 .portc = SAA7164_MPEG_ENCODER,
59 .portd = SAA7164_MPEG_ENCODER,
60 .porte = SAA7164_MPEG_VBI,
61 .portf = SAA7164_MPEG_VBI,
62 .chiprev = SAA7164_CHIP_REV3,
63 .unit = {{
64 .id = 0x1d,
65 .type = SAA7164_UNIT_EEPROM,
66 .name = "4K EEPROM",
67 .i2c_bus_nr = SAA7164_I2C_BUS_0,
68 .i2c_bus_addr = 0xa0 >> 1,
69 .i2c_reg_len = REGLEN_8bit,
70 }, {
71 .id = 0x04,
72 .type = SAA7164_UNIT_TUNER,
73 .name = "TDA18271-1",
74 .i2c_bus_nr = SAA7164_I2C_BUS_1,
75 .i2c_bus_addr = 0xc0 >> 1,
76 .i2c_reg_len = REGLEN_8bit,
77 }, {
78 .id = 0x1b,
79 .type = SAA7164_UNIT_TUNER,
80 .name = "TDA18271-2",
81 .i2c_bus_nr = SAA7164_I2C_BUS_2,
82 .i2c_bus_addr = 0xc0 >> 1,
83 .i2c_reg_len = REGLEN_8bit,
84 }, {
85 .id = 0x1e,
86 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
87 .name = "TDA10048-1",
88 .i2c_bus_nr = SAA7164_I2C_BUS_1,
89 .i2c_bus_addr = 0x10 >> 1,
90 .i2c_reg_len = REGLEN_8bit,
91 }, {
92 .id = 0x1f,
93 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
94 .name = "TDA10048-2",
95 .i2c_bus_nr = SAA7164_I2C_BUS_2,
96 .i2c_bus_addr = 0x12 >> 1,
97 .i2c_reg_len = REGLEN_8bit,
98 } },
99 },
100 [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
101 .name = "Hauppauge WinTV-HVR2200",
102 .porta = SAA7164_MPEG_DVB,
103 .portb = SAA7164_MPEG_DVB,
104 .portc = SAA7164_MPEG_ENCODER,
105 .portd = SAA7164_MPEG_ENCODER,
106 .porte = SAA7164_MPEG_VBI,
107 .portf = SAA7164_MPEG_VBI,
108 .chiprev = SAA7164_CHIP_REV2,
109 .unit = {{
110 .id = 0x06,
111 .type = SAA7164_UNIT_EEPROM,
112 .name = "4K EEPROM",
113 .i2c_bus_nr = SAA7164_I2C_BUS_0,
114 .i2c_bus_addr = 0xa0 >> 1,
115 .i2c_reg_len = REGLEN_8bit,
116 }, {
117 .id = 0x04,
118 .type = SAA7164_UNIT_TUNER,
119 .name = "TDA18271-1",
120 .i2c_bus_nr = SAA7164_I2C_BUS_1,
121 .i2c_bus_addr = 0xc0 >> 1,
122 .i2c_reg_len = REGLEN_8bit,
123 }, {
124 .id = 0x05,
125 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
126 .name = "TDA10048-1",
127 .i2c_bus_nr = SAA7164_I2C_BUS_1,
128 .i2c_bus_addr = 0x10 >> 1,
129 .i2c_reg_len = REGLEN_8bit,
130 }, {
131 .id = 0x1e,
132 .type = SAA7164_UNIT_TUNER,
133 .name = "TDA18271-2",
134 .i2c_bus_nr = SAA7164_I2C_BUS_2,
135 .i2c_bus_addr = 0xc0 >> 1,
136 .i2c_reg_len = REGLEN_8bit,
137 }, {
138 .id = 0x1f,
139 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
140 .name = "TDA10048-2",
141 .i2c_bus_nr = SAA7164_I2C_BUS_2,
142 .i2c_bus_addr = 0x12 >> 1,
143 .i2c_reg_len = REGLEN_8bit,
144 } },
145 },
146 [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
147 .name = "Hauppauge WinTV-HVR2200",
148 .porta = SAA7164_MPEG_DVB,
149 .portb = SAA7164_MPEG_DVB,
150 .portc = SAA7164_MPEG_ENCODER,
151 .portd = SAA7164_MPEG_ENCODER,
152 .porte = SAA7164_MPEG_VBI,
153 .portf = SAA7164_MPEG_VBI,
154 .chiprev = SAA7164_CHIP_REV2,
155 .unit = {{
156 .id = 0x1d,
157 .type = SAA7164_UNIT_EEPROM,
158 .name = "4K EEPROM",
159 .i2c_bus_nr = SAA7164_I2C_BUS_0,
160 .i2c_bus_addr = 0xa0 >> 1,
161 .i2c_reg_len = REGLEN_8bit,
162 }, {
163 .id = 0x04,
164 .type = SAA7164_UNIT_TUNER,
165 .name = "TDA18271-1",
166 .i2c_bus_nr = SAA7164_I2C_BUS_1,
167 .i2c_bus_addr = 0xc0 >> 1,
168 .i2c_reg_len = REGLEN_8bit,
169 }, {
170 .id = 0x05,
171 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
172 .name = "TDA8290-1",
173 .i2c_bus_nr = SAA7164_I2C_BUS_1,
174 .i2c_bus_addr = 0x84 >> 1,
175 .i2c_reg_len = REGLEN_8bit,
176 }, {
177 .id = 0x1b,
178 .type = SAA7164_UNIT_TUNER,
179 .name = "TDA18271-2",
180 .i2c_bus_nr = SAA7164_I2C_BUS_2,
181 .i2c_bus_addr = 0xc0 >> 1,
182 .i2c_reg_len = REGLEN_8bit,
183 }, {
184 .id = 0x1c,
185 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
186 .name = "TDA8290-2",
187 .i2c_bus_nr = SAA7164_I2C_BUS_2,
188 .i2c_bus_addr = 0x84 >> 1,
189 .i2c_reg_len = REGLEN_8bit,
190 }, {
191 .id = 0x1e,
192 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
193 .name = "TDA10048-1",
194 .i2c_bus_nr = SAA7164_I2C_BUS_1,
195 .i2c_bus_addr = 0x10 >> 1,
196 .i2c_reg_len = REGLEN_8bit,
197 }, {
198 .id = 0x1f,
199 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
200 .name = "TDA10048-2",
201 .i2c_bus_nr = SAA7164_I2C_BUS_2,
202 .i2c_bus_addr = 0x12 >> 1,
203 .i2c_reg_len = REGLEN_8bit,
204 } },
205 },
206 [SAA7164_BOARD_HAUPPAUGE_HVR2200_4] = {
207 .name = "Hauppauge WinTV-HVR2200",
208 .porta = SAA7164_MPEG_DVB,
209 .portb = SAA7164_MPEG_DVB,
210 .portc = SAA7164_MPEG_ENCODER,
211 .portd = SAA7164_MPEG_ENCODER,
212 .porte = SAA7164_MPEG_VBI,
213 .portf = SAA7164_MPEG_VBI,
214 .chiprev = SAA7164_CHIP_REV3,
215 .unit = {{
216 .id = 0x1d,
217 .type = SAA7164_UNIT_EEPROM,
218 .name = "4K EEPROM",
219 .i2c_bus_nr = SAA7164_I2C_BUS_0,
220 .i2c_bus_addr = 0xa0 >> 1,
221 .i2c_reg_len = REGLEN_8bit,
222 }, {
223 .id = 0x04,
224 .type = SAA7164_UNIT_TUNER,
225 .name = "TDA18271-1",
226 .i2c_bus_nr = SAA7164_I2C_BUS_1,
227 .i2c_bus_addr = 0xc0 >> 1,
228 .i2c_reg_len = REGLEN_8bit,
229 }, {
230 .id = 0x05,
231 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
232 .name = "TDA8290-1",
233 .i2c_bus_nr = SAA7164_I2C_BUS_1,
234 .i2c_bus_addr = 0x84 >> 1,
235 .i2c_reg_len = REGLEN_8bit,
236 }, {
237 .id = 0x1b,
238 .type = SAA7164_UNIT_TUNER,
239 .name = "TDA18271-2",
240 .i2c_bus_nr = SAA7164_I2C_BUS_2,
241 .i2c_bus_addr = 0xc0 >> 1,
242 .i2c_reg_len = REGLEN_8bit,
243 }, {
244 .id = 0x1c,
245 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
246 .name = "TDA8290-2",
247 .i2c_bus_nr = SAA7164_I2C_BUS_2,
248 .i2c_bus_addr = 0x84 >> 1,
249 .i2c_reg_len = REGLEN_8bit,
250 }, {
251 .id = 0x1e,
252 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
253 .name = "TDA10048-1",
254 .i2c_bus_nr = SAA7164_I2C_BUS_1,
255 .i2c_bus_addr = 0x10 >> 1,
256 .i2c_reg_len = REGLEN_8bit,
257 }, {
258 .id = 0x1f,
259 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
260 .name = "TDA10048-2",
261 .i2c_bus_nr = SAA7164_I2C_BUS_2,
262 .i2c_bus_addr = 0x12 >> 1,
263 .i2c_reg_len = REGLEN_8bit,
264 } },
265 },
266 [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
267 .name = "Hauppauge WinTV-HVR2250",
268 .porta = SAA7164_MPEG_DVB,
269 .portb = SAA7164_MPEG_DVB,
270 .portc = SAA7164_MPEG_ENCODER,
271 .portd = SAA7164_MPEG_ENCODER,
272 .portc = SAA7164_MPEG_ENCODER,
273 .portd = SAA7164_MPEG_ENCODER,
274 .porte = SAA7164_MPEG_VBI,
275 .portf = SAA7164_MPEG_VBI,
276 .chiprev = SAA7164_CHIP_REV3,
277 .unit = {{
278 .id = 0x22,
279 .type = SAA7164_UNIT_EEPROM,
280 .name = "4K EEPROM",
281 .i2c_bus_nr = SAA7164_I2C_BUS_0,
282 .i2c_bus_addr = 0xa0 >> 1,
283 .i2c_reg_len = REGLEN_8bit,
284 }, {
285 .id = 0x04,
286 .type = SAA7164_UNIT_TUNER,
287 .name = "TDA18271-1",
288 .i2c_bus_nr = SAA7164_I2C_BUS_1,
289 .i2c_bus_addr = 0xc0 >> 1,
290 .i2c_reg_len = REGLEN_8bit,
291 }, {
292 .id = 0x07,
293 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
294 .name = "CX24228/S5H1411-1 (TOP)",
295 .i2c_bus_nr = SAA7164_I2C_BUS_1,
296 .i2c_bus_addr = 0x32 >> 1,
297 .i2c_reg_len = REGLEN_8bit,
298 }, {
299 .id = 0x08,
300 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
301 .name = "CX24228/S5H1411-1 (QAM)",
302 .i2c_bus_nr = SAA7164_I2C_BUS_1,
303 .i2c_bus_addr = 0x34 >> 1,
304 .i2c_reg_len = REGLEN_8bit,
305 }, {
306 .id = 0x1e,
307 .type = SAA7164_UNIT_TUNER,
308 .name = "TDA18271-2",
309 .i2c_bus_nr = SAA7164_I2C_BUS_2,
310 .i2c_bus_addr = 0xc0 >> 1,
311 .i2c_reg_len = REGLEN_8bit,
312 }, {
313 .id = 0x20,
314 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
315 .name = "CX24228/S5H1411-2 (TOP)",
316 .i2c_bus_nr = SAA7164_I2C_BUS_2,
317 .i2c_bus_addr = 0x32 >> 1,
318 .i2c_reg_len = REGLEN_8bit,
319 }, {
320 .id = 0x23,
321 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
322 .name = "CX24228/S5H1411-2 (QAM)",
323 .i2c_bus_nr = SAA7164_I2C_BUS_2,
324 .i2c_bus_addr = 0x34 >> 1,
325 .i2c_reg_len = REGLEN_8bit,
326 } },
327 },
328 [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
329 .name = "Hauppauge WinTV-HVR2250",
330 .porta = SAA7164_MPEG_DVB,
331 .portb = SAA7164_MPEG_DVB,
332 .portc = SAA7164_MPEG_ENCODER,
333 .portd = SAA7164_MPEG_ENCODER,
334 .porte = SAA7164_MPEG_VBI,
335 .portf = SAA7164_MPEG_VBI,
336 .porte = SAA7164_MPEG_VBI,
337 .portf = SAA7164_MPEG_VBI,
338 .chiprev = SAA7164_CHIP_REV3,
339 .unit = {{
340 .id = 0x28,
341 .type = SAA7164_UNIT_EEPROM,
342 .name = "4K EEPROM",
343 .i2c_bus_nr = SAA7164_I2C_BUS_0,
344 .i2c_bus_addr = 0xa0 >> 1,
345 .i2c_reg_len = REGLEN_8bit,
346 }, {
347 .id = 0x04,
348 .type = SAA7164_UNIT_TUNER,
349 .name = "TDA18271-1",
350 .i2c_bus_nr = SAA7164_I2C_BUS_1,
351 .i2c_bus_addr = 0xc0 >> 1,
352 .i2c_reg_len = REGLEN_8bit,
353 }, {
354 .id = 0x07,
355 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
356 .name = "CX24228/S5H1411-1 (TOP)",
357 .i2c_bus_nr = SAA7164_I2C_BUS_1,
358 .i2c_bus_addr = 0x32 >> 1,
359 .i2c_reg_len = REGLEN_8bit,
360 }, {
361 .id = 0x08,
362 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
363 .name = "CX24228/S5H1411-1 (QAM)",
364 .i2c_bus_nr = SAA7164_I2C_BUS_1,
365 .i2c_bus_addr = 0x34 >> 1,
366 .i2c_reg_len = REGLEN_8bit,
367 }, {
368 .id = 0x24,
369 .type = SAA7164_UNIT_TUNER,
370 .name = "TDA18271-2",
371 .i2c_bus_nr = SAA7164_I2C_BUS_2,
372 .i2c_bus_addr = 0xc0 >> 1,
373 .i2c_reg_len = REGLEN_8bit,
374 }, {
375 .id = 0x26,
376 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
377 .name = "CX24228/S5H1411-2 (TOP)",
378 .i2c_bus_nr = SAA7164_I2C_BUS_2,
379 .i2c_bus_addr = 0x32 >> 1,
380 .i2c_reg_len = REGLEN_8bit,
381 }, {
382 .id = 0x29,
383 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
384 .name = "CX24228/S5H1411-2 (QAM)",
385 .i2c_bus_nr = SAA7164_I2C_BUS_2,
386 .i2c_bus_addr = 0x34 >> 1,
387 .i2c_reg_len = REGLEN_8bit,
388 } },
389 },
390 [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
391 .name = "Hauppauge WinTV-HVR2250",
392 .porta = SAA7164_MPEG_DVB,
393 .portb = SAA7164_MPEG_DVB,
394 .portc = SAA7164_MPEG_ENCODER,
395 .portd = SAA7164_MPEG_ENCODER,
396 .porte = SAA7164_MPEG_VBI,
397 .portf = SAA7164_MPEG_VBI,
398 .chiprev = SAA7164_CHIP_REV3,
399 .unit = {{
400 .id = 0x26,
401 .type = SAA7164_UNIT_EEPROM,
402 .name = "4K EEPROM",
403 .i2c_bus_nr = SAA7164_I2C_BUS_0,
404 .i2c_bus_addr = 0xa0 >> 1,
405 .i2c_reg_len = REGLEN_8bit,
406 }, {
407 .id = 0x04,
408 .type = SAA7164_UNIT_TUNER,
409 .name = "TDA18271-1",
410 .i2c_bus_nr = SAA7164_I2C_BUS_1,
411 .i2c_bus_addr = 0xc0 >> 1,
412 .i2c_reg_len = REGLEN_8bit,
413 }, {
414 .id = 0x07,
415 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
416 .name = "CX24228/S5H1411-1 (TOP)",
417 .i2c_bus_nr = SAA7164_I2C_BUS_1,
418 .i2c_bus_addr = 0x32 >> 1,
419 .i2c_reg_len = REGLEN_8bit,
420 }, {
421 .id = 0x08,
422 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
423 .name = "CX24228/S5H1411-1 (QAM)",
424 .i2c_bus_nr = SAA7164_I2C_BUS_1,
425 .i2c_bus_addr = 0x34 >> 1,
426 .i2c_reg_len = REGLEN_8bit,
427 }, {
428 .id = 0x22,
429 .type = SAA7164_UNIT_TUNER,
430 .name = "TDA18271-2",
431 .i2c_bus_nr = SAA7164_I2C_BUS_2,
432 .i2c_bus_addr = 0xc0 >> 1,
433 .i2c_reg_len = REGLEN_8bit,
434 }, {
435 .id = 0x24,
436 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
437 .name = "CX24228/S5H1411-2 (TOP)",
438 .i2c_bus_nr = SAA7164_I2C_BUS_2,
439 .i2c_bus_addr = 0x32 >> 1,
440 .i2c_reg_len = REGLEN_8bit,
441 }, {
442 .id = 0x27,
443 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
444 .name = "CX24228/S5H1411-2 (QAM)",
445 .i2c_bus_nr = SAA7164_I2C_BUS_2,
446 .i2c_bus_addr = 0x34 >> 1,
447 .i2c_reg_len = REGLEN_8bit,
448 } },
449 },
450};
451const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
452
453/* ------------------------------------------------------------------ */
454/* PCI subsystem IDs */
455
456struct saa7164_subid saa7164_subids[] = {
457 {
458 .subvendor = 0x0070,
459 .subdevice = 0x8880,
460 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
461 }, {
462 .subvendor = 0x0070,
463 .subdevice = 0x8810,
464 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
465 }, {
466 .subvendor = 0x0070,
467 .subdevice = 0x8980,
468 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200,
469 }, {
470 .subvendor = 0x0070,
471 .subdevice = 0x8900,
472 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
473 }, {
474 .subvendor = 0x0070,
475 .subdevice = 0x8901,
476 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
477 }, {
478 .subvendor = 0x0070,
479 .subdevice = 0x88A1,
480 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
481 }, {
482 .subvendor = 0x0070,
483 .subdevice = 0x8891,
484 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
485 }, {
486 .subvendor = 0x0070,
487 .subdevice = 0x8851,
488 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
489 }, {
490 .subvendor = 0x0070,
491 .subdevice = 0x8940,
492 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
493 },
494};
495const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
496
497void saa7164_card_list(struct saa7164_dev *dev)
498{
499 int i;
500
501 if (0 == dev->pci->subsystem_vendor &&
502 0 == dev->pci->subsystem_device) {
503 printk(KERN_ERR
504 "%s: Board has no valid PCIe Subsystem ID and can't\n"
505 "%s: be autodetected. Pass card=<n> insmod option to\n"
506 "%s: workaround that. Send complaints to the vendor\n"
507 "%s: of the TV card. Best regards,\n"
508 "%s: -- tux\n",
509 dev->name, dev->name, dev->name, dev->name, dev->name);
510 } else {
511 printk(KERN_ERR
512 "%s: Your board isn't known (yet) to the driver.\n"
513 "%s: Try to pick one of the existing card configs via\n"
514 "%s: card=<n> insmod option. Updating to the latest\n"
515 "%s: version might help as well.\n",
516 dev->name, dev->name, dev->name, dev->name);
517 }
518
519 printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
520 "option:\n", dev->name);
521
522 for (i = 0; i < saa7164_bcount; i++)
523 printk(KERN_ERR "%s: card=%d -> %s\n",
524 dev->name, i, saa7164_boards[i].name);
525}
526
527/* TODO: clean this define up into the -cards.c structs */
528#define PCIEBRIDGE_UNITID 2
529
530void saa7164_gpio_setup(struct saa7164_dev *dev)
531{
532 switch (dev->board) {
533 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
534 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
535 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
536 case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
537 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
538 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
539 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
540 /*
541 GPIO 2: s5h1411 / tda10048-1 demod reset
542 GPIO 3: s5h1411 / tda10048-2 demod reset
543 GPIO 7: IRBlaster Zilog reset
544 */
545
546 /* Reset parts by going in and out of reset */
547 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
548 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
549
550 msleep(20);
551
552 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
553 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
554 break;
555 }
556}
557
558static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
559{
560 struct tveeprom tv;
561
562 /* TODO: Assumption: eeprom on bus 0 */
563 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
564 eeprom_data);
565
566 /* Make sure we support the board model */
567 switch (tv.model) {
568 case 88001:
569 /* Development board - Limit circulation */
570 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
571 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
572 case 88021:
573 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
574 * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
575 break;
576 case 88041:
577 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
578 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
579 break;
580 case 88061:
581 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
582 * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
583 break;
584 case 89519:
585 case 89609:
586 /* WinTV-HVR2200 (PCIe, Retail, full-height)
587 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
588 break;
589 case 89619:
590 /* WinTV-HVR2200 (PCIe, Retail, half-height)
591 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
592 break;
593 default:
594 printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
595 dev->name, tv.model);
596 break;
597 }
598
599 printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
600 tv.model);
601}
602
603void saa7164_card_setup(struct saa7164_dev *dev)
604{
605 static u8 eeprom[256];
606
607 if (dev->i2c_bus[0].i2c_rc == 0) {
608 if (saa7164_api_read_eeprom(dev, &eeprom[0],
609 sizeof(eeprom)) < 0)
610 return;
611 }
612
613 switch (dev->board) {
614 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
615 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
616 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
617 case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
618 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
619 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
620 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
621 hauppauge_eeprom(dev, &eeprom[0]);
622 break;
623 }
624}
625
626/* With most other drivers, the kernel expects to communicate with subdrivers
627 * through i2c. This bridge does not allow that, it does not expose any direct
628 * access to I2C. Instead we have to communicate through the device f/w for
629 * register access to 'processing units'. Each unit has a unique
630 * id, regardless of how the physical implementation occurs across
631 * the three physical i2c busses. The being said if we want leverge of
632 * the existing kernel drivers for tuners and demods we have to 'speak i2c',
633 * to this bridge implements 3 virtual i2c buses. This is a helper function
634 * for those.
635 *
636 * Description: Translate the kernels notion of an i2c address and bus into
637 * the appropriate unitid.
638 */
639int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
640{
641 /* For a given bus and i2c device address, return the saa7164 unique
642 * unitid. < 0 on error */
643
644 struct saa7164_dev *dev = bus->dev;
645 struct saa7164_unit *unit;
646 int i;
647
648 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
649 unit = &saa7164_boards[dev->board].unit[i];
650
651 if (unit->type == SAA7164_UNIT_UNDEFINED)
652 continue;
653 if ((bus->nr == unit->i2c_bus_nr) &&
654 (addr == unit->i2c_bus_addr))
655 return unit->id;
656 }
657
658 return -1;
659}
660
661/* The 7164 API needs to know the i2c register length in advance.
662 * this is a helper function. Based on a specific chip addr and bus return the
663 * reg length.
664 */
665int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
666{
667 /* For a given bus and i2c device address, return the
668 * saa7164 registry address width. < 0 on error
669 */
670
671 struct saa7164_dev *dev = bus->dev;
672 struct saa7164_unit *unit;
673 int i;
674
675 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
676 unit = &saa7164_boards[dev->board].unit[i];
677
678 if (unit->type == SAA7164_UNIT_UNDEFINED)
679 continue;
680
681 if ((bus->nr == unit->i2c_bus_nr) &&
682 (addr == unit->i2c_bus_addr))
683 return unit->i2c_reg_len;
684 }
685
686 return -1;
687}
688/* TODO: implement a 'findeeprom' functio like the above and fix any other
689 * eeprom related todo's in -api.c.
690 */
691
692/* Translate a unitid into a x readable device name, for display purposes. */
693char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
694{
695 char *undefed = "UNDEFINED";
696 char *bridge = "BRIDGE";
697 struct saa7164_unit *unit;
698 int i;
699
700 if (unitid == 0)
701 return bridge;
702
703 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
704 unit = &saa7164_boards[dev->board].unit[i];
705
706 if (unit->type == SAA7164_UNIT_UNDEFINED)
707 continue;
708
709 if (unitid == unit->id)
710 return unit->name;
711 }
712
713 return undefed;
714}
715
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
new file mode 100644
index 00000000000..62fac7f9d04
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -0,0 +1,589 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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/wait.h>
23
24#include "saa7164.h"
25
26int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
27{
28 int i, ret = -1;
29
30 mutex_lock(&dev->lock);
31 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
32 if (dev->cmds[i].inuse == 0) {
33 dev->cmds[i].inuse = 1;
34 dev->cmds[i].signalled = 0;
35 dev->cmds[i].timeout = 0;
36 ret = dev->cmds[i].seqno;
37 break;
38 }
39 }
40 mutex_unlock(&dev->lock);
41
42 return ret;
43}
44
45void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
46{
47 mutex_lock(&dev->lock);
48 if ((dev->cmds[seqno].inuse == 1) &&
49 (dev->cmds[seqno].seqno == seqno)) {
50 dev->cmds[seqno].inuse = 0;
51 dev->cmds[seqno].signalled = 0;
52 dev->cmds[seqno].timeout = 0;
53 }
54 mutex_unlock(&dev->lock);
55}
56
57void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
58{
59 mutex_lock(&dev->lock);
60 if ((dev->cmds[seqno].inuse == 1) &&
61 (dev->cmds[seqno].seqno == seqno)) {
62 dev->cmds[seqno].timeout = 1;
63 }
64 mutex_unlock(&dev->lock);
65}
66
67u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
68{
69 int ret = 0;
70
71 mutex_lock(&dev->lock);
72 if ((dev->cmds[seqno].inuse == 1) &&
73 (dev->cmds[seqno].seqno == seqno)) {
74 ret = dev->cmds[seqno].timeout;
75 }
76 mutex_unlock(&dev->lock);
77
78 return ret;
79}
80
81/* Commands to the f/w get marshelled to/from this code then onto the PCI
82 * -bus/c running buffer. */
83int saa7164_irq_dequeue(struct saa7164_dev *dev)
84{
85 int ret = SAA_OK, i = 0;
86 u32 timeout;
87 wait_queue_head_t *q = NULL;
88 u8 tmp[512];
89 dprintk(DBGLVL_CMD, "%s()\n", __func__);
90
91 /* While any outstand message on the bus exists... */
92 do {
93
94 /* Peek the msg bus */
95 struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 };
96 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
97 if (ret != SAA_OK)
98 break;
99
100 q = &dev->cmds[tRsp.seqno].wait;
101 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
102 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
103 if (!timeout) {
104 dprintk(DBGLVL_CMD,
105 "%s() signalled seqno(%d) (for dequeue)\n",
106 __func__, tRsp.seqno);
107 dev->cmds[tRsp.seqno].signalled = 1;
108 wake_up(q);
109 } else {
110 printk(KERN_ERR
111 "%s() found timed out command on the bus\n",
112 __func__);
113
114 /* Clean the bus */
115 ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
116 printk(KERN_ERR "%s() ret = %x\n", __func__, ret);
117 if (ret == SAA_ERR_EMPTY)
118 /* Someone else already fetched the response */
119 return SAA_OK;
120
121 if (ret != SAA_OK)
122 return ret;
123 }
124
125 /* It's unlikely to have more than 4 or 5 pending messages,
126 * ensure we exit at some point regardless.
127 */
128 } while (i++ < 32);
129
130 return ret;
131}
132
133/* Commands to the f/w get marshelled to/from this code then onto the PCI
134 * -bus/c running buffer. */
135int saa7164_cmd_dequeue(struct saa7164_dev *dev)
136{
137 int loop = 1;
138 int ret;
139 u32 timeout;
140 wait_queue_head_t *q = NULL;
141 u8 tmp[512];
142 dprintk(DBGLVL_CMD, "%s()\n", __func__);
143
144 while (loop) {
145
146 struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 };
147 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
148 if (ret == SAA_ERR_EMPTY)
149 return SAA_OK;
150
151 if (ret != SAA_OK)
152 return ret;
153
154 q = &dev->cmds[tRsp.seqno].wait;
155 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
156 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
157 if (timeout) {
158 printk(KERN_ERR "found timed out command on the bus\n");
159
160 /* Clean the bus */
161 ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
162 printk(KERN_ERR "ret = %x\n", ret);
163 if (ret == SAA_ERR_EMPTY)
164 /* Someone else already fetched the response */
165 return SAA_OK;
166
167 if (ret != SAA_OK)
168 return ret;
169
170 if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
171 printk(KERN_ERR "split response\n");
172 else
173 saa7164_cmd_free_seqno(dev, tRsp.seqno);
174
175 printk(KERN_ERR " timeout continue\n");
176 continue;
177 }
178
179 dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
180 __func__, tRsp.seqno);
181 dev->cmds[tRsp.seqno].signalled = 1;
182 wake_up(q);
183 return SAA_OK;
184 }
185
186 return SAA_OK;
187}
188
189int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg,
190 void *buf)
191{
192 struct tmComResBusInfo *bus = &dev->bus;
193 u8 cmd_sent;
194 u16 size, idx;
195 u32 cmds;
196 void *tmp;
197 int ret = -1;
198
199 if (!msg) {
200 printk(KERN_ERR "%s() !msg\n", __func__);
201 return SAA_ERR_BAD_PARAMETER;
202 }
203
204 mutex_lock(&dev->cmds[msg->id].lock);
205
206 size = msg->size;
207 idx = 0;
208 cmds = size / bus->m_wMaxReqSize;
209 if (size % bus->m_wMaxReqSize == 0)
210 cmds -= 1;
211
212 cmd_sent = 0;
213
214 /* Split the request into smaller chunks */
215 for (idx = 0; idx < cmds; idx++) {
216
217 msg->flags |= SAA_CMDFLAG_CONTINUE;
218 msg->size = bus->m_wMaxReqSize;
219 tmp = buf + idx * bus->m_wMaxReqSize;
220
221 ret = saa7164_bus_set(dev, msg, tmp);
222 if (ret != SAA_OK) {
223 printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
224
225 if (cmd_sent) {
226 ret = SAA_ERR_BUSY;
227 goto out;
228 }
229 ret = SAA_ERR_OVERFLOW;
230 goto out;
231 }
232 cmd_sent = 1;
233 }
234
235 /* If not the last command... */
236 if (idx != 0)
237 msg->flags &= ~SAA_CMDFLAG_CONTINUE;
238
239 msg->size = size - idx * bus->m_wMaxReqSize;
240
241 ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
242 if (ret != SAA_OK) {
243 printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
244
245 if (cmd_sent) {
246 ret = SAA_ERR_BUSY;
247 goto out;
248 }
249 ret = SAA_ERR_OVERFLOW;
250 goto out;
251 }
252 ret = SAA_OK;
253
254out:
255 mutex_unlock(&dev->cmds[msg->id].lock);
256 return ret;
257}
258
259/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
260 * the event never occurred, or SAA_OK if it was signaled during the wait.
261 */
262int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
263{
264 wait_queue_head_t *q = NULL;
265 int ret = SAA_BUS_TIMEOUT;
266 unsigned long stamp;
267 int r;
268
269 if (saa_debug >= 4)
270 saa7164_bus_dump(dev);
271
272 dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
273
274 mutex_lock(&dev->lock);
275 if ((dev->cmds[seqno].inuse == 1) &&
276 (dev->cmds[seqno].seqno == seqno)) {
277 q = &dev->cmds[seqno].wait;
278 }
279 mutex_unlock(&dev->lock);
280
281 if (q) {
282 /* If we haven't been signalled we need to wait */
283 if (dev->cmds[seqno].signalled == 0) {
284 stamp = jiffies;
285 dprintk(DBGLVL_CMD,
286 "%s(seqno=%d) Waiting (signalled=%d)\n",
287 __func__, seqno, dev->cmds[seqno].signalled);
288
289 /* Wait for signalled to be flagged or timeout */
290 /* In a highly stressed system this can easily extend
291 * into multiple seconds before the deferred worker
292 * is scheduled, and we're woken up via signal.
293 * We typically are signalled in < 50ms but it can
294 * take MUCH longer.
295 */
296 wait_event_timeout(*q, dev->cmds[seqno].signalled,
297 (HZ * waitsecs));
298 r = time_before(jiffies, stamp + (HZ * waitsecs));
299 if (r)
300 ret = SAA_OK;
301 else
302 saa7164_cmd_timeout_seqno(dev, seqno);
303
304 dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
305 "(signalled=%d)\n", __func__, seqno, r,
306 dev->cmds[seqno].signalled);
307 } else
308 ret = SAA_OK;
309 } else
310 printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
311 __func__, seqno);
312
313 return ret;
314}
315
316void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
317{
318 int i;
319 dprintk(DBGLVL_CMD, "%s()\n", __func__);
320
321 mutex_lock(&dev->lock);
322 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
323 if (dev->cmds[i].inuse == 1) {
324 dprintk(DBGLVL_CMD,
325 "seqno %d inuse, sig = %d, t/out = %d\n",
326 dev->cmds[i].seqno,
327 dev->cmds[i].signalled,
328 dev->cmds[i].timeout);
329 }
330 }
331
332 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
333 if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
334 (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
335 dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
336 __func__, i);
337 dev->cmds[i].signalled = 1;
338 wake_up(&dev->cmds[i].wait);
339 }
340 }
341 mutex_unlock(&dev->lock);
342}
343
344int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
345 u16 controlselector, u16 size, void *buf)
346{
347 struct tmComResInfo command_t, *pcommand_t;
348 struct tmComResInfo response_t, *presponse_t;
349 u8 errdata[256];
350 u16 resp_dsize;
351 u16 data_recd;
352 u32 loop;
353 int ret;
354 int safety = 0;
355
356 dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
357 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
358 command, controlselector);
359
360 if ((size == 0) || (buf == NULL)) {
361 printk(KERN_ERR "%s() Invalid param\n", __func__);
362 return SAA_ERR_BAD_PARAMETER;
363 }
364
365 /* Prepare some basic command/response structures */
366 memset(&command_t, 0, sizeof(command_t));
367 memset(&response_t, 0, sizeof(response_t));
368 pcommand_t = &command_t;
369 presponse_t = &response_t;
370 command_t.id = id;
371 command_t.command = command;
372 command_t.controlselector = controlselector;
373 command_t.size = size;
374
375 /* Allocate a unique sequence number */
376 ret = saa7164_cmd_alloc_seqno(dev);
377 if (ret < 0) {
378 printk(KERN_ERR "%s() No free sequences\n", __func__);
379 ret = SAA_ERR_NO_RESOURCES;
380 goto out;
381 }
382
383 command_t.seqno = (u8)ret;
384
385 /* Send Command */
386 resp_dsize = size;
387 pcommand_t->size = size;
388
389 dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
390 __func__, pcommand_t->seqno);
391
392 dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
393 __func__, pcommand_t->size);
394
395 ret = saa7164_cmd_set(dev, pcommand_t, buf);
396 if (ret != SAA_OK) {
397 printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
398
399 if (ret != SAA_ERR_BUSY)
400 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
401 else
402 /* Flag a timeout, because at least one
403 * command was sent */
404 saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
405
406 goto out;
407 }
408
409 /* With split responses we have to collect the msgs piece by piece */
410 data_recd = 0;
411 loop = 1;
412 while (loop) {
413 dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
414
415 ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
416 dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
417
418 /* if power is down and this is not a power command ... */
419
420 if (ret == SAA_BUS_TIMEOUT) {
421 printk(KERN_ERR "Event timed out\n");
422 saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
423 return ret;
424 }
425
426 if (ret != SAA_OK) {
427 printk(KERN_ERR "spurious error\n");
428 return ret;
429 }
430
431 /* Peek response */
432 ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
433 if (ret == SAA_ERR_EMPTY) {
434 dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
435 continue;
436 }
437 if (ret != SAA_OK) {
438 printk(KERN_ERR "peek failed\n");
439 return ret;
440 }
441
442 dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
443 __func__, presponse_t->seqno);
444
445 dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
446 __func__, presponse_t->flags);
447
448 dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
449 __func__, presponse_t->size);
450
451 /* Check if the response was for our command */
452 if (presponse_t->seqno != pcommand_t->seqno) {
453
454 dprintk(DBGLVL_CMD,
455 "wrong event: seqno = %d, "
456 "expected seqno = %d, "
457 "will dequeue regardless\n",
458 presponse_t->seqno, pcommand_t->seqno);
459
460 ret = saa7164_cmd_dequeue(dev);
461 if (ret != SAA_OK) {
462 printk(KERN_ERR "dequeue failed, ret = %d\n",
463 ret);
464 if (safety++ > 16) {
465 printk(KERN_ERR
466 "dequeue exceeded, safety exit\n");
467 return SAA_ERR_BUSY;
468 }
469 }
470
471 continue;
472 }
473
474 if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
475
476 memset(&errdata[0], 0, sizeof(errdata));
477
478 ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
479 if (ret != SAA_OK) {
480 printk(KERN_ERR "get error(2)\n");
481 return ret;
482 }
483
484 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
485
486 dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
487 __func__, errdata[0], errdata[1], errdata[2],
488 errdata[3]);
489
490 /* Map error codes */
491 dprintk(DBGLVL_CMD, "%s() cmd, error code = 0x%x\n",
492 __func__, errdata[0]);
493
494 switch (errdata[0]) {
495 case PVC_ERRORCODE_INVALID_COMMAND:
496 dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
497 __func__);
498 ret = SAA_ERR_INVALID_COMMAND;
499 break;
500 case PVC_ERRORCODE_INVALID_DATA:
501 dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
502 __func__);
503 ret = SAA_ERR_BAD_PARAMETER;
504 break;
505 case PVC_ERRORCODE_TIMEOUT:
506 dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
507 ret = SAA_ERR_TIMEOUT;
508 break;
509 case PVC_ERRORCODE_NAK:
510 dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
511 ret = SAA_ERR_NULL_PACKET;
512 break;
513 case PVC_ERRORCODE_UNKNOWN:
514 case PVC_ERRORCODE_INVALID_CONTROL:
515 dprintk(DBGLVL_CMD,
516 "%s() UNKNOWN OR INVALID CONTROL\n",
517 __func__);
518 default:
519 dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
520 ret = SAA_ERR_NOT_SUPPORTED;
521 }
522
523 /* See of other commands are on the bus */
524 if (saa7164_cmd_dequeue(dev) != SAA_OK)
525 printk(KERN_ERR "dequeue(2) failed\n");
526
527 return ret;
528 }
529
530 /* If response is invalid */
531 if ((presponse_t->id != pcommand_t->id) ||
532 (presponse_t->command != pcommand_t->command) ||
533 (presponse_t->controlselector !=
534 pcommand_t->controlselector) ||
535 (((resp_dsize - data_recd) != presponse_t->size) &&
536 !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
537 ((resp_dsize - data_recd) < presponse_t->size)) {
538
539 /* Invalid */
540 dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
541 ret = saa7164_bus_get(dev, presponse_t, NULL, 0);
542 if (ret != SAA_OK) {
543 printk(KERN_ERR "get failed\n");
544 return ret;
545 }
546
547 /* See of other commands are on the bus */
548 if (saa7164_cmd_dequeue(dev) != SAA_OK)
549 printk(KERN_ERR "dequeue(3) failed\n");
550 continue;
551 }
552
553 /* OK, now we're actually getting out correct response */
554 ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
555 if (ret != SAA_OK) {
556 printk(KERN_ERR "get failed\n");
557 return ret;
558 }
559
560 data_recd = presponse_t->size + data_recd;
561 if (resp_dsize == data_recd) {
562 dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
563 break;
564 }
565
566 /* See of other commands are on the bus */
567 if (saa7164_cmd_dequeue(dev) != SAA_OK)
568 printk(KERN_ERR "dequeue(3) failed\n");
569
570 continue;
571
572 } /* (loop) */
573
574 /* Release the sequence number allocation */
575 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
576
577 /* if powerdown signal all pending commands */
578
579 dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
580
581 /* See of other commands are on the bus */
582 if (saa7164_cmd_dequeue(dev) != SAA_OK)
583 printk(KERN_ERR "dequeue(4) failed\n");
584
585 ret = SAA_OK;
586out:
587 return ret;
588}
589
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
new file mode 100644
index 00000000000..3b7d7b4e303
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -0,0 +1,1526 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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#ifdef CONFIG_PROC_FS
34#include <linux/proc_fs.h>
35#endif
36#include "saa7164.h"
37
38MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
39MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
40MODULE_LICENSE("GPL");
41
42/*
43 * 1 Basic
44 * 2
45 * 4 i2c
46 * 8 api
47 * 16 cmd
48 * 32 bus
49 */
50
51unsigned int saa_debug;
52module_param_named(debug, saa_debug, int, 0644);
53MODULE_PARM_DESC(debug, "enable debug messages");
54
55unsigned int fw_debug;
56module_param(fw_debug, int, 0644);
57MODULE_PARM_DESC(fw_debug, "Firware debug level def:2");
58
59unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS;
60module_param(encoder_buffers, int, 0644);
61MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64");
62
63unsigned int vbi_buffers = SAA7164_MAX_VBI_BUFFERS;
64module_param(vbi_buffers, int, 0644);
65MODULE_PARM_DESC(vbi_buffers, "Total buffers in read queue 16-512 def:64");
66
67unsigned int waitsecs = 10;
68module_param(waitsecs, int, 0644);
69MODULE_PARM_DESC(waitsecs, "timeout on firmware messages");
70
71static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
72module_param_array(card, int, NULL, 0444);
73MODULE_PARM_DESC(card, "card type");
74
75unsigned int print_histogram = 64;
76module_param(print_histogram, int, 0644);
77MODULE_PARM_DESC(print_histogram, "print histogram values once");
78
79unsigned int crc_checking = 1;
80module_param(crc_checking, int, 0644);
81MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers");
82
83unsigned int guard_checking = 1;
84module_param(guard_checking, int, 0644);
85MODULE_PARM_DESC(guard_checking,
86 "enable dma sanity checking for buffer overruns");
87
88static unsigned int saa7164_devcount;
89
90static DEFINE_MUTEX(devlist);
91LIST_HEAD(saa7164_devlist);
92
93#define INT_SIZE 16
94
95void saa7164_dumphex16FF(struct saa7164_dev *dev, u8 *buf, int len)
96{
97 int i;
98 u8 tmp[16];
99 memset(&tmp[0], 0xff, sizeof(tmp));
100
101 printk(KERN_INFO "--------------------> "
102 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
103
104 for (i = 0; i < len; i += 16) {
105 if (memcmp(&tmp, buf + i, sizeof(tmp)) != 0) {
106 printk(KERN_INFO " [0x%08x] "
107 "%02x %02x %02x %02x %02x %02x %02x %02x "
108 "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
109 *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
110 *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
111 *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
112 *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
113 }
114 }
115}
116
117static void saa7164_pack_verifier(struct saa7164_buffer *buf)
118{
119 u8 *p = (u8 *)buf->cpu;
120 int i;
121
122 for (i = 0; i < buf->actual_size; i += 2048) {
123
124 if ((*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) ||
125 (*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) {
126 printk(KERN_ERR "No pack at 0x%x\n", i);
127#if 0
128 saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
129#endif
130 }
131 }
132}
133
134#define FIXED_VIDEO_PID 0xf1
135#define FIXED_AUDIO_PID 0xf2
136
137static void saa7164_ts_verifier(struct saa7164_buffer *buf)
138{
139 struct saa7164_port *port = buf->port;
140 u32 i;
141 u8 cc, a;
142 u16 pid;
143 u8 __iomem *bufcpu = (u8 *)buf->cpu;
144
145 port->sync_errors = 0;
146 port->v_cc_errors = 0;
147 port->a_cc_errors = 0;
148
149 for (i = 0; i < buf->actual_size; i += 188) {
150 if (*(bufcpu + i) != 0x47)
151 port->sync_errors++;
152
153 /* TODO: Query pid lower 8 bits, ignoring upper bits intensionally */
154 pid = ((*(bufcpu + i + 1) & 0x1f) << 8) | *(bufcpu + i + 2);
155 cc = *(bufcpu + i + 3) & 0x0f;
156
157 if (pid == FIXED_VIDEO_PID) {
158 a = ((port->last_v_cc + 1) & 0x0f);
159 if (a != cc) {
160 printk(KERN_ERR "video cc last = %x current = %x i = %d\n",
161 port->last_v_cc, cc, i);
162 port->v_cc_errors++;
163 }
164
165 port->last_v_cc = cc;
166 } else
167 if (pid == FIXED_AUDIO_PID) {
168 a = ((port->last_a_cc + 1) & 0x0f);
169 if (a != cc) {
170 printk(KERN_ERR "audio cc last = %x current = %x i = %d\n",
171 port->last_a_cc, cc, i);
172 port->a_cc_errors++;
173 }
174
175 port->last_a_cc = cc;
176 }
177
178 }
179
180 /* Only report errors if we've been through this function atleast
181 * once already and the cached cc values are primed. First time through
182 * always generates errors.
183 */
184 if (port->v_cc_errors && (port->done_first_interrupt > 1))
185 printk(KERN_ERR "video pid cc, %d errors\n", port->v_cc_errors);
186
187 if (port->a_cc_errors && (port->done_first_interrupt > 1))
188 printk(KERN_ERR "audio pid cc, %d errors\n", port->a_cc_errors);
189
190 if (port->sync_errors && (port->done_first_interrupt > 1))
191 printk(KERN_ERR "sync_errors = %d\n", port->sync_errors);
192
193 if (port->done_first_interrupt == 1)
194 port->done_first_interrupt++;
195}
196
197static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name)
198{
199 int i;
200
201 memset(hg, 0, sizeof(struct saa7164_histogram));
202 strcpy(hg->name, name);
203
204 /* First 30ms x 1ms */
205 for (i = 0; i < 30; i++)
206 hg->counter1[0 + i].val = i;
207
208 /* 30 - 200ms x 10ms */
209 for (i = 0; i < 18; i++)
210 hg->counter1[30 + i].val = 30 + (i * 10);
211
212 /* 200 - 2000ms x 100ms */
213 for (i = 0; i < 15; i++)
214 hg->counter1[48 + i].val = 200 + (i * 200);
215
216 /* Catch all massive value (2secs) */
217 hg->counter1[55].val = 2000;
218
219 /* Catch all massive value (4secs) */
220 hg->counter1[56].val = 4000;
221
222 /* Catch all massive value (8secs) */
223 hg->counter1[57].val = 8000;
224
225 /* Catch all massive value (15secs) */
226 hg->counter1[58].val = 15000;
227
228 /* Catch all massive value (30secs) */
229 hg->counter1[59].val = 30000;
230
231 /* Catch all massive value (60secs) */
232 hg->counter1[60].val = 60000;
233
234 /* Catch all massive value (5mins) */
235 hg->counter1[61].val = 300000;
236
237 /* Catch all massive value (15mins) */
238 hg->counter1[62].val = 900000;
239
240 /* Catch all massive values (1hr) */
241 hg->counter1[63].val = 3600000;
242}
243
244void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val)
245{
246 int i;
247 for (i = 0; i < 64; i++) {
248 if (val <= hg->counter1[i].val) {
249 hg->counter1[i].count++;
250 hg->counter1[i].update_time = jiffies;
251 break;
252 }
253 }
254}
255
256static void saa7164_histogram_print(struct saa7164_port *port,
257 struct saa7164_histogram *hg)
258{
259 u32 entries = 0;
260 int i;
261
262 printk(KERN_ERR "Histogram named %s (ms, count, last_update_jiffy)\n", hg->name);
263 for (i = 0; i < 64; i++) {
264 if (hg->counter1[i].count == 0)
265 continue;
266
267 printk(KERN_ERR " %4d %12d %Ld\n",
268 hg->counter1[i].val,
269 hg->counter1[i].count,
270 hg->counter1[i].update_time);
271
272 entries++;
273 }
274 printk(KERN_ERR "Total: %d\n", entries);
275}
276
277static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
278{
279 struct saa7164_dev *dev = port->dev;
280 struct saa7164_buffer *buf = NULL;
281 struct saa7164_user_buffer *ubuf = NULL;
282 struct list_head *c, *n;
283 int i = 0;
284 u8 __iomem *p;
285
286 mutex_lock(&port->dmaqueue_lock);
287 list_for_each_safe(c, n, &port->dmaqueue.list) {
288
289 buf = list_entry(c, struct saa7164_buffer, list);
290 if (i++ > port->hwcfg.buffercount) {
291 printk(KERN_ERR "%s() illegal i count %d\n",
292 __func__, i);
293 break;
294 }
295
296 if (buf->idx == bufnr) {
297
298 /* Found the buffer, deal with it */
299 dprintk(DBGLVL_IRQ, "%s() bufnr: %d\n", __func__, bufnr);
300
301 if (crc_checking) {
302 /* Throw a new checksum on the dma buffer */
303 buf->crc = crc32(0, buf->cpu, buf->actual_size);
304 }
305
306 if (guard_checking) {
307 p = (u8 *)buf->cpu;
308 if ((*(p + buf->actual_size + 0) != 0xff) ||
309 (*(p + buf->actual_size + 1) != 0xff) ||
310 (*(p + buf->actual_size + 2) != 0xff) ||
311 (*(p + buf->actual_size + 3) != 0xff) ||
312 (*(p + buf->actual_size + 0x10) != 0xff) ||
313 (*(p + buf->actual_size + 0x11) != 0xff) ||
314 (*(p + buf->actual_size + 0x12) != 0xff) ||
315 (*(p + buf->actual_size + 0x13) != 0xff)) {
316 printk(KERN_ERR "%s() buf %p guard buffer breach\n",
317 __func__, buf);
318#if 0
319 saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
320#endif
321 }
322 }
323
324 if ((port->nr != SAA7164_PORT_VBI1) && (port->nr != SAA7164_PORT_VBI2)) {
325 /* Validate the incoming buffer content */
326 if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
327 saa7164_ts_verifier(buf);
328 else if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
329 saa7164_pack_verifier(buf);
330 }
331
332 /* find a free user buffer and clone to it */
333 if (!list_empty(&port->list_buf_free.list)) {
334
335 /* Pull the first buffer from the used list */
336 ubuf = list_first_entry(&port->list_buf_free.list,
337 struct saa7164_user_buffer, list);
338
339 if (buf->actual_size <= ubuf->actual_size) {
340
341 memcpy_fromio(ubuf->data, buf->cpu,
342 ubuf->actual_size);
343
344 if (crc_checking) {
345 /* Throw a new checksum on the read buffer */
346 ubuf->crc = crc32(0, ubuf->data, ubuf->actual_size);
347 }
348
349 /* Requeue the buffer on the free list */
350 ubuf->pos = 0;
351
352 list_move_tail(&ubuf->list,
353 &port->list_buf_used.list);
354
355 /* Flag any userland waiters */
356 wake_up_interruptible(&port->wait_read);
357
358 } else {
359 printk(KERN_ERR "buf %p bufsize fails match\n", buf);
360 }
361
362 } else
363 printk(KERN_ERR "encirq no free buffers, increase param encoder_buffers\n");
364
365 /* Ensure offset into buffer remains 0, fill buffer
366 * with known bad data. We check for this data at a later point
367 * in time. */
368 saa7164_buffer_zero_offsets(port, bufnr);
369 memset_io(buf->cpu, 0xff, buf->pci_size);
370 if (crc_checking) {
371 /* Throw yet aanother new checksum on the dma buffer */
372 buf->crc = crc32(0, buf->cpu, buf->actual_size);
373 }
374
375 break;
376 }
377 }
378 mutex_unlock(&port->dmaqueue_lock);
379}
380
381static void saa7164_work_enchandler(struct work_struct *w)
382{
383 struct saa7164_port *port =
384 container_of(w, struct saa7164_port, workenc);
385 struct saa7164_dev *dev = port->dev;
386
387 u32 wp, mcb, rp, cnt = 0;
388
389 port->last_svc_msecs_diff = port->last_svc_msecs;
390 port->last_svc_msecs = jiffies_to_msecs(jiffies);
391
392 port->last_svc_msecs_diff = port->last_svc_msecs -
393 port->last_svc_msecs_diff;
394
395 saa7164_histogram_update(&port->svc_interval,
396 port->last_svc_msecs_diff);
397
398 port->last_irq_svc_msecs_diff = port->last_svc_msecs -
399 port->last_irq_msecs;
400
401 saa7164_histogram_update(&port->irq_svc_interval,
402 port->last_irq_svc_msecs_diff);
403
404 dprintk(DBGLVL_IRQ,
405 "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
406 __func__,
407 port->last_svc_msecs_diff,
408 port->last_irq_svc_msecs_diff,
409 port->last_svc_wp,
410 port->last_svc_rp
411 );
412
413 /* Current write position */
414 wp = saa7164_readl(port->bufcounter);
415 if (wp > (port->hwcfg.buffercount - 1)) {
416 printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
417 return;
418 }
419
420 /* Most current complete buffer */
421 if (wp == 0)
422 mcb = (port->hwcfg.buffercount - 1);
423 else
424 mcb = wp - 1;
425
426 while (1) {
427 if (port->done_first_interrupt == 0) {
428 port->done_first_interrupt++;
429 rp = mcb;
430 } else
431 rp = (port->last_svc_rp + 1) % 8;
432
433 if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
434 printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
435 break;
436 }
437
438 saa7164_work_enchandler_helper(port, rp);
439 port->last_svc_rp = rp;
440 cnt++;
441
442 if (rp == mcb)
443 break;
444 }
445
446 /* TODO: Convert this into a /proc/saa7164 style readable file */
447 if (print_histogram == port->nr) {
448 saa7164_histogram_print(port, &port->irq_interval);
449 saa7164_histogram_print(port, &port->svc_interval);
450 saa7164_histogram_print(port, &port->irq_svc_interval);
451 saa7164_histogram_print(port, &port->read_interval);
452 saa7164_histogram_print(port, &port->poll_interval);
453 /* TODO: fix this to preserve any previous state */
454 print_histogram = 64 + port->nr;
455 }
456}
457
458static void saa7164_work_vbihandler(struct work_struct *w)
459{
460 struct saa7164_port *port =
461 container_of(w, struct saa7164_port, workenc);
462 struct saa7164_dev *dev = port->dev;
463
464 u32 wp, mcb, rp, cnt = 0;
465
466 port->last_svc_msecs_diff = port->last_svc_msecs;
467 port->last_svc_msecs = jiffies_to_msecs(jiffies);
468 port->last_svc_msecs_diff = port->last_svc_msecs -
469 port->last_svc_msecs_diff;
470
471 saa7164_histogram_update(&port->svc_interval,
472 port->last_svc_msecs_diff);
473
474 port->last_irq_svc_msecs_diff = port->last_svc_msecs -
475 port->last_irq_msecs;
476
477 saa7164_histogram_update(&port->irq_svc_interval,
478 port->last_irq_svc_msecs_diff);
479
480 dprintk(DBGLVL_IRQ,
481 "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
482 __func__,
483 port->last_svc_msecs_diff,
484 port->last_irq_svc_msecs_diff,
485 port->last_svc_wp,
486 port->last_svc_rp
487 );
488
489 /* Current write position */
490 wp = saa7164_readl(port->bufcounter);
491 if (wp > (port->hwcfg.buffercount - 1)) {
492 printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
493 return;
494 }
495
496 /* Most current complete buffer */
497 if (wp == 0)
498 mcb = (port->hwcfg.buffercount - 1);
499 else
500 mcb = wp - 1;
501
502 while (1) {
503 if (port->done_first_interrupt == 0) {
504 port->done_first_interrupt++;
505 rp = mcb;
506 } else
507 rp = (port->last_svc_rp + 1) % 8;
508
509 if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
510 printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
511 break;
512 }
513
514 saa7164_work_enchandler_helper(port, rp);
515 port->last_svc_rp = rp;
516 cnt++;
517
518 if (rp == mcb)
519 break;
520 }
521
522 /* TODO: Convert this into a /proc/saa7164 style readable file */
523 if (print_histogram == port->nr) {
524 saa7164_histogram_print(port, &port->irq_interval);
525 saa7164_histogram_print(port, &port->svc_interval);
526 saa7164_histogram_print(port, &port->irq_svc_interval);
527 saa7164_histogram_print(port, &port->read_interval);
528 saa7164_histogram_print(port, &port->poll_interval);
529 /* TODO: fix this to preserve any previous state */
530 print_histogram = 64 + port->nr;
531 }
532}
533
534static void saa7164_work_cmdhandler(struct work_struct *w)
535{
536 struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
537
538 /* Wake up any complete commands */
539 saa7164_irq_dequeue(dev);
540}
541
542static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
543{
544 struct saa7164_port *port = buf->port;
545
546 /* Feed the transport payload into the kernel demux */
547 dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu,
548 SAA7164_TS_NUMBER_OF_LINES);
549
550}
551
552static irqreturn_t saa7164_irq_vbi(struct saa7164_port *port)
553{
554 struct saa7164_dev *dev = port->dev;
555
556 /* Store old time */
557 port->last_irq_msecs_diff = port->last_irq_msecs;
558
559 /* Collect new stats */
560 port->last_irq_msecs = jiffies_to_msecs(jiffies);
561
562 /* Calculate stats */
563 port->last_irq_msecs_diff = port->last_irq_msecs -
564 port->last_irq_msecs_diff;
565
566 saa7164_histogram_update(&port->irq_interval,
567 port->last_irq_msecs_diff);
568
569 dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,
570 port->last_irq_msecs_diff);
571
572 /* Tis calls the vbi irq handler */
573 schedule_work(&port->workenc);
574 return 0;
575}
576
577static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port)
578{
579 struct saa7164_dev *dev = port->dev;
580
581 /* Store old time */
582 port->last_irq_msecs_diff = port->last_irq_msecs;
583
584 /* Collect new stats */
585 port->last_irq_msecs = jiffies_to_msecs(jiffies);
586
587 /* Calculate stats */
588 port->last_irq_msecs_diff = port->last_irq_msecs -
589 port->last_irq_msecs_diff;
590
591 saa7164_histogram_update(&port->irq_interval,
592 port->last_irq_msecs_diff);
593
594 dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,
595 port->last_irq_msecs_diff);
596
597 schedule_work(&port->workenc);
598 return 0;
599}
600
601static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
602{
603 struct saa7164_dev *dev = port->dev;
604 struct saa7164_buffer *buf;
605 struct list_head *c, *n;
606 int wp, i = 0, rp;
607
608 /* Find the current write point from the hardware */
609 wp = saa7164_readl(port->bufcounter);
610 if (wp > (port->hwcfg.buffercount - 1))
611 BUG();
612
613 /* Find the previous buffer to the current write point */
614 if (wp == 0)
615 rp = (port->hwcfg.buffercount - 1);
616 else
617 rp = wp - 1;
618
619 /* Lookup the WP in the buffer list */
620 /* TODO: turn this into a worker thread */
621 list_for_each_safe(c, n, &port->dmaqueue.list) {
622 buf = list_entry(c, struct saa7164_buffer, list);
623 if (i++ > port->hwcfg.buffercount)
624 BUG();
625
626 if (buf->idx == rp) {
627 /* Found the buffer, deal with it */
628 dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
629 __func__, wp, rp);
630 saa7164_buffer_deliver(buf);
631 break;
632 }
633
634 }
635 return 0;
636}
637
638/* Primary IRQ handler and dispatch mechanism */
639static irqreturn_t saa7164_irq(int irq, void *dev_id)
640{
641 struct saa7164_dev *dev = dev_id;
642 struct saa7164_port *porta = &dev->ports[SAA7164_PORT_TS1];
643 struct saa7164_port *portb = &dev->ports[SAA7164_PORT_TS2];
644 struct saa7164_port *portc = &dev->ports[SAA7164_PORT_ENC1];
645 struct saa7164_port *portd = &dev->ports[SAA7164_PORT_ENC2];
646 struct saa7164_port *porte = &dev->ports[SAA7164_PORT_VBI1];
647 struct saa7164_port *portf = &dev->ports[SAA7164_PORT_VBI2];
648
649 u32 intid, intstat[INT_SIZE/4];
650 int i, handled = 0, bit;
651
652 if (dev == NULL) {
653 printk(KERN_ERR "%s() No device specified\n", __func__);
654 handled = 0;
655 goto out;
656 }
657
658 /* Check that the hardware is accessible. If the status bytes are
659 * 0xFF then the device is not accessible, the the IRQ belongs
660 * to another driver.
661 * 4 x u32 interrupt registers.
662 */
663 for (i = 0; i < INT_SIZE/4; i++) {
664
665 /* TODO: Convert into saa7164_readl() */
666 /* Read the 4 hardware interrupt registers */
667 intstat[i] = saa7164_readl(dev->int_status + (i * 4));
668
669 if (intstat[i])
670 handled = 1;
671 }
672 if (handled == 0)
673 goto out;
674
675 /* For each of the HW interrupt registers */
676 for (i = 0; i < INT_SIZE/4; i++) {
677
678 if (intstat[i]) {
679 /* Each function of the board has it's own interruptid.
680 * Find the function that triggered then call
681 * it's handler.
682 */
683 for (bit = 0; bit < 32; bit++) {
684
685 if (((intstat[i] >> bit) & 0x00000001) == 0)
686 continue;
687
688 /* Calculate the interrupt id (0x00 to 0x7f) */
689
690 intid = (i * 32) + bit;
691 if (intid == dev->intfdesc.bInterruptId) {
692 /* A response to an cmd/api call */
693 schedule_work(&dev->workcmd);
694 } else if (intid == porta->hwcfg.interruptid) {
695
696 /* Transport path 1 */
697 saa7164_irq_ts(porta);
698
699 } else if (intid == portb->hwcfg.interruptid) {
700
701 /* Transport path 2 */
702 saa7164_irq_ts(portb);
703
704 } else if (intid == portc->hwcfg.interruptid) {
705
706 /* Encoder path 1 */
707 saa7164_irq_encoder(portc);
708
709 } else if (intid == portd->hwcfg.interruptid) {
710
711 /* Encoder path 2 */
712 saa7164_irq_encoder(portd);
713
714 } else if (intid == porte->hwcfg.interruptid) {
715
716 /* VBI path 1 */
717 saa7164_irq_vbi(porte);
718
719 } else if (intid == portf->hwcfg.interruptid) {
720
721 /* VBI path 2 */
722 saa7164_irq_vbi(portf);
723
724 } else {
725 /* Find the function */
726 dprintk(DBGLVL_IRQ,
727 "%s() unhandled interrupt "
728 "reg 0x%x bit 0x%x "
729 "intid = 0x%x\n",
730 __func__, i, bit, intid);
731 }
732 }
733
734 /* Ack it */
735 saa7164_writel(dev->int_ack + (i * 4), intstat[i]);
736
737 }
738 }
739out:
740 return IRQ_RETVAL(handled);
741}
742
743void saa7164_getfirmwarestatus(struct saa7164_dev *dev)
744{
745 struct saa7164_fw_status *s = &dev->fw_status;
746
747 dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS);
748 dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE);
749 dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC);
750 dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST);
751 dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD);
752 dev->fw_status.remainheap =
753 saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP);
754
755 dprintk(1, "Firmware status:\n");
756 dprintk(1, " .status = 0x%08x\n", s->status);
757 dprintk(1, " .mode = 0x%08x\n", s->mode);
758 dprintk(1, " .spec = 0x%08x\n", s->spec);
759 dprintk(1, " .inst = 0x%08x\n", s->inst);
760 dprintk(1, " .cpuload = 0x%08x\n", s->cpuload);
761 dprintk(1, " .remainheap = 0x%08x\n", s->remainheap);
762}
763
764u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
765{
766 u32 reg;
767
768 reg = saa7164_readl(SAA_DEVICE_VERSION);
769 dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n",
770 (reg & 0x0000fc00) >> 10,
771 (reg & 0x000003e0) >> 5,
772 (reg & 0x0000001f),
773 (reg & 0xffff0000) >> 16,
774 reg);
775
776 return reg;
777}
778
779/* TODO: Debugging func, remove */
780void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
781{
782 int i;
783
784 printk(KERN_INFO "--------------------> "
785 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
786
787 for (i = 0; i < len; i += 16)
788 printk(KERN_INFO " [0x%08x] "
789 "%02x %02x %02x %02x %02x %02x %02x %02x "
790 "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
791 *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
792 *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
793 *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
794 *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
795}
796
797/* TODO: Debugging func, remove */
798void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
799{
800 int i;
801
802 dprintk(1, "--------------------> "
803 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
804
805 for (i = 0; i < 0x100; i += 16)
806 dprintk(1, "region0[0x%08x] = "
807 "%02x %02x %02x %02x %02x %02x %02x %02x"
808 " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
809 (u8)saa7164_readb(addr + i + 0),
810 (u8)saa7164_readb(addr + i + 1),
811 (u8)saa7164_readb(addr + i + 2),
812 (u8)saa7164_readb(addr + i + 3),
813 (u8)saa7164_readb(addr + i + 4),
814 (u8)saa7164_readb(addr + i + 5),
815 (u8)saa7164_readb(addr + i + 6),
816 (u8)saa7164_readb(addr + i + 7),
817 (u8)saa7164_readb(addr + i + 8),
818 (u8)saa7164_readb(addr + i + 9),
819 (u8)saa7164_readb(addr + i + 10),
820 (u8)saa7164_readb(addr + i + 11),
821 (u8)saa7164_readb(addr + i + 12),
822 (u8)saa7164_readb(addr + i + 13),
823 (u8)saa7164_readb(addr + i + 14),
824 (u8)saa7164_readb(addr + i + 15)
825 );
826}
827
828static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
829{
830 dprintk(1, "@0x%p hwdesc sizeof(struct tmComResHWDescr) = %d bytes\n",
831 &dev->hwdesc, (u32)sizeof(struct tmComResHWDescr));
832
833 dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength);
834 dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType);
835 dprintk(1, " .bDescriptorSubtype = 0x%x\n",
836 dev->hwdesc.bDescriptorSubtype);
837
838 dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion);
839 dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency);
840 dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes);
841 dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities);
842 dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n",
843 dev->hwdesc.dwDeviceRegistersLocation);
844
845 dprintk(1, " .dwHostMemoryRegion = 0x%x\n",
846 dev->hwdesc.dwHostMemoryRegion);
847
848 dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n",
849 dev->hwdesc.dwHostMemoryRegionSize);
850
851 dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n",
852 dev->hwdesc.dwHostHibernatMemRegion);
853
854 dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n",
855 dev->hwdesc.dwHostHibernatMemRegionSize);
856}
857
858static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
859{
860 dprintk(1, "@0x%p intfdesc "
861 "sizeof(struct tmComResInterfaceDescr) = %d bytes\n",
862 &dev->intfdesc, (u32)sizeof(struct tmComResInterfaceDescr));
863
864 dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
865 dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType);
866 dprintk(1, " .bDescriptorSubtype = 0x%x\n",
867 dev->intfdesc.bDescriptorSubtype);
868
869 dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags);
870 dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType);
871 dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId);
872 dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface);
873 dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId);
874 dprintk(1, " .bDebugInterruptId = 0x%x\n",
875 dev->intfdesc.bDebugInterruptId);
876
877 dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation);
878}
879
880static void saa7164_dump_busdesc(struct saa7164_dev *dev)
881{
882 dprintk(1, "@0x%p busdesc sizeof(struct tmComResBusDescr) = %d bytes\n",
883 &dev->busdesc, (u32)sizeof(struct tmComResBusDescr));
884
885 dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing);
886 dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing);
887 dprintk(1, " .CommandWrite = 0x%x\n", dev->busdesc.CommandWrite);
888 dprintk(1, " .CommandRead = 0x%x\n", dev->busdesc.CommandRead);
889 dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite);
890 dprintk(1, " .ResponseRead = 0x%x\n", dev->busdesc.ResponseRead);
891}
892
893/* Much of the hardware configuration and PCI registers are configured
894 * dynamically depending on firmware. We have to cache some initial
895 * structures then use these to locate other important structures
896 * from PCI space.
897 */
898static void saa7164_get_descriptors(struct saa7164_dev *dev)
899{
900 memcpy_fromio(&dev->hwdesc, dev->bmmio, sizeof(struct tmComResHWDescr));
901 memcpy_fromio(&dev->intfdesc, dev->bmmio + sizeof(struct tmComResHWDescr),
902 sizeof(struct tmComResInterfaceDescr));
903 memcpy_fromio(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
904 sizeof(struct tmComResBusDescr));
905
906 if (dev->hwdesc.bLength != sizeof(struct tmComResHWDescr)) {
907 printk(KERN_ERR "Structure struct tmComResHWDescr is mangled\n");
908 printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength,
909 (u32)sizeof(struct tmComResHWDescr));
910 } else
911 saa7164_dump_hwdesc(dev);
912
913 if (dev->intfdesc.bLength != sizeof(struct tmComResInterfaceDescr)) {
914 printk(KERN_ERR "struct struct tmComResInterfaceDescr is mangled\n");
915 printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength,
916 (u32)sizeof(struct tmComResInterfaceDescr));
917 } else
918 saa7164_dump_intfdesc(dev);
919
920 saa7164_dump_busdesc(dev);
921}
922
923static int saa7164_pci_quirks(struct saa7164_dev *dev)
924{
925 return 0;
926}
927
928static int get_resources(struct saa7164_dev *dev)
929{
930 if (request_mem_region(pci_resource_start(dev->pci, 0),
931 pci_resource_len(dev->pci, 0), dev->name)) {
932
933 if (request_mem_region(pci_resource_start(dev->pci, 2),
934 pci_resource_len(dev->pci, 2), dev->name))
935 return 0;
936 }
937
938 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n",
939 dev->name,
940 (u64)pci_resource_start(dev->pci, 0),
941 (u64)pci_resource_start(dev->pci, 2));
942
943 return -EBUSY;
944}
945
946static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
947{
948 struct saa7164_port *port = NULL;
949
950 if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS))
951 BUG();
952
953 port = &dev->ports[portnr];
954
955 port->dev = dev;
956 port->nr = portnr;
957
958 if ((portnr == SAA7164_PORT_TS1) || (portnr == SAA7164_PORT_TS2))
959 port->type = SAA7164_MPEG_DVB;
960 else
961 if ((portnr == SAA7164_PORT_ENC1) || (portnr == SAA7164_PORT_ENC2)) {
962 port->type = SAA7164_MPEG_ENCODER;
963
964 /* We need a deferred interrupt handler for cmd handling */
965 INIT_WORK(&port->workenc, saa7164_work_enchandler);
966 } else if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) {
967 port->type = SAA7164_MPEG_VBI;
968
969 /* We need a deferred interrupt handler for cmd handling */
970 INIT_WORK(&port->workenc, saa7164_work_vbihandler);
971 } else
972 BUG();
973
974 /* Init all the critical resources */
975 mutex_init(&port->dvb.lock);
976 INIT_LIST_HEAD(&port->dmaqueue.list);
977 mutex_init(&port->dmaqueue_lock);
978
979 INIT_LIST_HEAD(&port->list_buf_used.list);
980 INIT_LIST_HEAD(&port->list_buf_free.list);
981 init_waitqueue_head(&port->wait_read);
982
983
984 saa7164_histogram_reset(&port->irq_interval, "irq intervals");
985 saa7164_histogram_reset(&port->svc_interval, "deferred intervals");
986 saa7164_histogram_reset(&port->irq_svc_interval,
987 "irq to deferred intervals");
988 saa7164_histogram_reset(&port->read_interval,
989 "encoder/vbi read() intervals");
990 saa7164_histogram_reset(&port->poll_interval,
991 "encoder/vbi poll() intervals");
992
993 return 0;
994}
995
996static int saa7164_dev_setup(struct saa7164_dev *dev)
997{
998 int i;
999
1000 mutex_init(&dev->lock);
1001 atomic_inc(&dev->refcount);
1002 dev->nr = saa7164_devcount++;
1003
1004 snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr);
1005
1006 mutex_lock(&devlist);
1007 list_add_tail(&dev->devlist, &saa7164_devlist);
1008 mutex_unlock(&devlist);
1009
1010 /* board config */
1011 dev->board = UNSET;
1012 if (card[dev->nr] < saa7164_bcount)
1013 dev->board = card[dev->nr];
1014
1015 for (i = 0; UNSET == dev->board && i < saa7164_idcount; i++)
1016 if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor &&
1017 dev->pci->subsystem_device ==
1018 saa7164_subids[i].subdevice)
1019 dev->board = saa7164_subids[i].card;
1020
1021 if (UNSET == dev->board) {
1022 dev->board = SAA7164_BOARD_UNKNOWN;
1023 saa7164_card_list(dev);
1024 }
1025
1026 dev->pci_bus = dev->pci->bus->number;
1027 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
1028
1029 /* I2C Defaults / setup */
1030 dev->i2c_bus[0].dev = dev;
1031 dev->i2c_bus[0].nr = 0;
1032 dev->i2c_bus[1].dev = dev;
1033 dev->i2c_bus[1].nr = 1;
1034 dev->i2c_bus[2].dev = dev;
1035 dev->i2c_bus[2].nr = 2;
1036
1037 /* Transport + Encoder ports 1, 2, 3, 4 - Defaults / setup */
1038 saa7164_port_init(dev, SAA7164_PORT_TS1);
1039 saa7164_port_init(dev, SAA7164_PORT_TS2);
1040 saa7164_port_init(dev, SAA7164_PORT_ENC1);
1041 saa7164_port_init(dev, SAA7164_PORT_ENC2);
1042 saa7164_port_init(dev, SAA7164_PORT_VBI1);
1043 saa7164_port_init(dev, SAA7164_PORT_VBI2);
1044
1045 if (get_resources(dev) < 0) {
1046 printk(KERN_ERR "CORE %s No more PCIe resources for "
1047 "subsystem: %04x:%04x\n",
1048 dev->name, dev->pci->subsystem_vendor,
1049 dev->pci->subsystem_device);
1050
1051 saa7164_devcount--;
1052 return -ENODEV;
1053 }
1054
1055 /* PCI/e allocations */
1056 dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
1057 pci_resource_len(dev->pci, 0));
1058
1059 dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
1060 pci_resource_len(dev->pci, 2));
1061
1062 dev->bmmio = (u8 __iomem *)dev->lmmio;
1063 dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
1064
1065 /* Inerrupt and ack register locations offset of bmmio */
1066 dev->int_status = 0x183000 + 0xf80;
1067 dev->int_ack = 0x183000 + 0xf90;
1068
1069 printk(KERN_INFO
1070 "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1071 dev->name, dev->pci->subsystem_vendor,
1072 dev->pci->subsystem_device, saa7164_boards[dev->board].name,
1073 dev->board, card[dev->nr] == dev->board ?
1074 "insmod option" : "autodetected");
1075
1076 saa7164_pci_quirks(dev);
1077
1078 return 0;
1079}
1080
1081static void saa7164_dev_unregister(struct saa7164_dev *dev)
1082{
1083 dprintk(1, "%s()\n", __func__);
1084
1085 release_mem_region(pci_resource_start(dev->pci, 0),
1086 pci_resource_len(dev->pci, 0));
1087
1088 release_mem_region(pci_resource_start(dev->pci, 2),
1089 pci_resource_len(dev->pci, 2));
1090
1091 if (!atomic_dec_and_test(&dev->refcount))
1092 return;
1093
1094 iounmap(dev->lmmio);
1095 iounmap(dev->lmmio2);
1096
1097 return;
1098}
1099
1100#ifdef CONFIG_PROC_FS
1101static int saa7164_proc_show(struct seq_file *m, void *v)
1102{
1103 struct saa7164_dev *dev;
1104 struct tmComResBusInfo *b;
1105 struct list_head *list;
1106 int i, c;
1107
1108 if (saa7164_devcount == 0)
1109 return 0;
1110
1111 list_for_each(list, &saa7164_devlist) {
1112 dev = list_entry(list, struct saa7164_dev, devlist);
1113 seq_printf(m, "%s = %p\n", dev->name, dev);
1114
1115 /* Lock the bus from any other access */
1116 b = &dev->bus;
1117 mutex_lock(&b->lock);
1118
1119 seq_printf(m, " .m_pdwSetWritePos = 0x%x (0x%08x)\n",
1120 b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
1121
1122 seq_printf(m, " .m_pdwSetReadPos = 0x%x (0x%08x)\n",
1123 b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
1124
1125 seq_printf(m, " .m_pdwGetWritePos = 0x%x (0x%08x)\n",
1126 b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
1127
1128 seq_printf(m, " .m_pdwGetReadPos = 0x%x (0x%08x)\n",
1129 b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
1130 c = 0;
1131 seq_printf(m, "\n Set Ring:\n");
1132 seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
1133 for (i = 0; i < b->m_dwSizeSetRing; i++) {
1134 if (c == 0)
1135 seq_printf(m, " %04x:", i);
1136
1137 seq_printf(m, " %02x", *(b->m_pdwSetRing + i));
1138
1139 if (++c == 16) {
1140 seq_printf(m, "\n");
1141 c = 0;
1142 }
1143 }
1144
1145 c = 0;
1146 seq_printf(m, "\n Get Ring:\n");
1147 seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
1148 for (i = 0; i < b->m_dwSizeGetRing; i++) {
1149 if (c == 0)
1150 seq_printf(m, " %04x:", i);
1151
1152 seq_printf(m, " %02x", *(b->m_pdwGetRing + i));
1153
1154 if (++c == 16) {
1155 seq_printf(m, "\n");
1156 c = 0;
1157 }
1158 }
1159
1160 mutex_unlock(&b->lock);
1161
1162 }
1163
1164 return 0;
1165}
1166
1167static int saa7164_proc_open(struct inode *inode, struct file *filp)
1168{
1169 return single_open(filp, saa7164_proc_show, NULL);
1170}
1171
1172static const struct file_operations saa7164_proc_fops = {
1173 .open = saa7164_proc_open,
1174 .read = seq_read,
1175 .llseek = seq_lseek,
1176 .release = single_release,
1177};
1178
1179static int saa7164_proc_create(void)
1180{
1181 struct proc_dir_entry *pe;
1182
1183 pe = proc_create("saa7164", S_IRUGO, NULL, &saa7164_proc_fops);
1184 if (!pe)
1185 return -ENOMEM;
1186
1187 return 0;
1188}
1189#endif
1190
1191static int saa7164_thread_function(void *data)
1192{
1193 struct saa7164_dev *dev = data;
1194 struct tmFwInfoStruct fwinfo;
1195 u64 last_poll_time = 0;
1196
1197 dprintk(DBGLVL_THR, "thread started\n");
1198
1199 set_freezable();
1200
1201 while (1) {
1202 msleep_interruptible(100);
1203 if (kthread_should_stop())
1204 break;
1205 try_to_freeze();
1206
1207 dprintk(DBGLVL_THR, "thread running\n");
1208
1209 /* Dump the firmware debug message to console */
1210 /* Polling this costs us 1-2% of the arm CPU */
1211 /* convert this into a respnde to interrupt 0x7a */
1212 saa7164_api_collect_debug(dev);
1213
1214 /* Monitor CPU load every 1 second */
1215 if ((last_poll_time + 1000 /* ms */) < jiffies_to_msecs(jiffies)) {
1216 saa7164_api_get_load_info(dev, &fwinfo);
1217 last_poll_time = jiffies_to_msecs(jiffies);
1218 }
1219
1220 }
1221
1222 dprintk(DBGLVL_THR, "thread exiting\n");
1223 return 0;
1224}
1225
1226static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
1227 const struct pci_device_id *pci_id)
1228{
1229 struct saa7164_dev *dev;
1230 int err, i;
1231 u32 version;
1232
1233 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1234 if (NULL == dev)
1235 return -ENOMEM;
1236
1237 /* pci init */
1238 dev->pci = pci_dev;
1239 if (pci_enable_device(pci_dev)) {
1240 err = -EIO;
1241 goto fail_free;
1242 }
1243
1244 if (saa7164_dev_setup(dev) < 0) {
1245 err = -EINVAL;
1246 goto fail_free;
1247 }
1248
1249 /* print pci info */
1250 dev->pci_rev = pci_dev->revision;
1251 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1252 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1253 "latency: %d, mmio: 0x%llx\n", dev->name,
1254 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1255 dev->pci_lat,
1256 (unsigned long long)pci_resource_start(pci_dev, 0));
1257
1258 pci_set_master(pci_dev);
1259 /* TODO */
1260 if (!pci_dma_supported(pci_dev, 0xffffffff)) {
1261 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
1262 err = -EIO;
1263 goto fail_irq;
1264 }
1265
1266 err = request_irq(pci_dev->irq, saa7164_irq,
1267 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
1268 if (err < 0) {
1269 printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
1270 pci_dev->irq);
1271 err = -EIO;
1272 goto fail_irq;
1273 }
1274
1275 pci_set_drvdata(pci_dev, dev);
1276
1277 /* Init the internal command list */
1278 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
1279 dev->cmds[i].seqno = i;
1280 dev->cmds[i].inuse = 0;
1281 mutex_init(&dev->cmds[i].lock);
1282 init_waitqueue_head(&dev->cmds[i].wait);
1283 }
1284
1285 /* We need a deferred interrupt handler for cmd handling */
1286 INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler);
1287
1288 /* Only load the firmware if we know the board */
1289 if (dev->board != SAA7164_BOARD_UNKNOWN) {
1290
1291 err = saa7164_downloadfirmware(dev);
1292 if (err < 0) {
1293 printk(KERN_ERR
1294 "Failed to boot firmware, no features "
1295 "registered\n");
1296 goto fail_fw;
1297 }
1298
1299 saa7164_get_descriptors(dev);
1300 saa7164_dumpregs(dev, 0);
1301 saa7164_getcurrentfirmwareversion(dev);
1302 saa7164_getfirmwarestatus(dev);
1303 err = saa7164_bus_setup(dev);
1304 if (err < 0)
1305 printk(KERN_ERR
1306 "Failed to setup the bus, will continue\n");
1307 saa7164_bus_dump(dev);
1308
1309 /* Ping the running firmware via the command bus and get the
1310 * firmware version, this checks the bus is running OK.
1311 */
1312 version = 0;
1313 if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
1314 dprintk(1, "Bus is operating correctly using "
1315 "version %d.%d.%d.%d (0x%x)\n",
1316 (version & 0x0000fc00) >> 10,
1317 (version & 0x000003e0) >> 5,
1318 (version & 0x0000001f),
1319 (version & 0xffff0000) >> 16,
1320 version);
1321 else
1322 printk(KERN_ERR
1323 "Failed to communicate with the firmware\n");
1324
1325 /* Bring up the I2C buses */
1326 saa7164_i2c_register(&dev->i2c_bus[0]);
1327 saa7164_i2c_register(&dev->i2c_bus[1]);
1328 saa7164_i2c_register(&dev->i2c_bus[2]);
1329 saa7164_gpio_setup(dev);
1330 saa7164_card_setup(dev);
1331
1332 /* Parse the dynamic device configuration, find various
1333 * media endpoints (MPEG, WMV, PS, TS) and cache their
1334 * configuration details into the driver, so we can
1335 * reference them later during simething_register() func,
1336 * interrupt handlers, deferred work handlers etc.
1337 */
1338 saa7164_api_enum_subdevs(dev);
1339
1340 /* Begin to create the video sub-systems and register funcs */
1341 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
1342 if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS1]) < 0) {
1343 printk(KERN_ERR "%s() Failed to register "
1344 "dvb adapters on porta\n",
1345 __func__);
1346 }
1347 }
1348
1349 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
1350 if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS2]) < 0) {
1351 printk(KERN_ERR"%s() Failed to register "
1352 "dvb adapters on portb\n",
1353 __func__);
1354 }
1355 }
1356
1357 if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) {
1358 if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC1]) < 0) {
1359 printk(KERN_ERR"%s() Failed to register "
1360 "mpeg encoder\n", __func__);
1361 }
1362 }
1363
1364 if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) {
1365 if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC2]) < 0) {
1366 printk(KERN_ERR"%s() Failed to register "
1367 "mpeg encoder\n", __func__);
1368 }
1369 }
1370
1371 if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) {
1372 if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI1]) < 0) {
1373 printk(KERN_ERR"%s() Failed to register "
1374 "vbi device\n", __func__);
1375 }
1376 }
1377
1378 if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) {
1379 if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI2]) < 0) {
1380 printk(KERN_ERR"%s() Failed to register "
1381 "vbi device\n", __func__);
1382 }
1383 }
1384 saa7164_api_set_debug(dev, fw_debug);
1385
1386 if (fw_debug) {
1387 dev->kthread = kthread_run(saa7164_thread_function, dev,
1388 "saa7164 debug");
1389 if (!dev->kthread)
1390 printk(KERN_ERR "%s() Failed to create "
1391 "debug kernel thread\n", __func__);
1392 }
1393
1394 } /* != BOARD_UNKNOWN */
1395 else
1396 printk(KERN_ERR "%s() Unsupported board detected, "
1397 "registering without firmware\n", __func__);
1398
1399 dprintk(1, "%s() parameter debug = %d\n", __func__, saa_debug);
1400 dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
1401
1402fail_fw:
1403 return 0;
1404
1405fail_irq:
1406 saa7164_dev_unregister(dev);
1407fail_free:
1408 kfree(dev);
1409 return err;
1410}
1411
1412static void saa7164_shutdown(struct saa7164_dev *dev)
1413{
1414 dprintk(1, "%s()\n", __func__);
1415}
1416
1417static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
1418{
1419 struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
1420
1421 if (dev->board != SAA7164_BOARD_UNKNOWN) {
1422 if (fw_debug && dev->kthread) {
1423 kthread_stop(dev->kthread);
1424 dev->kthread = NULL;
1425 }
1426 if (dev->firmwareloaded)
1427 saa7164_api_set_debug(dev, 0x00);
1428 }
1429
1430 saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
1431 &dev->ports[SAA7164_PORT_ENC1].irq_interval);
1432 saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
1433 &dev->ports[SAA7164_PORT_ENC1].svc_interval);
1434 saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
1435 &dev->ports[SAA7164_PORT_ENC1].irq_svc_interval);
1436 saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
1437 &dev->ports[SAA7164_PORT_ENC1].read_interval);
1438 saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
1439 &dev->ports[SAA7164_PORT_ENC1].poll_interval);
1440 saa7164_histogram_print(&dev->ports[SAA7164_PORT_VBI1],
1441 &dev->ports[SAA7164_PORT_VBI1].read_interval);
1442 saa7164_histogram_print(&dev->ports[SAA7164_PORT_VBI2],
1443 &dev->ports[SAA7164_PORT_VBI2].poll_interval);
1444
1445 saa7164_shutdown(dev);
1446
1447 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
1448 saa7164_dvb_unregister(&dev->ports[SAA7164_PORT_TS1]);
1449
1450 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
1451 saa7164_dvb_unregister(&dev->ports[SAA7164_PORT_TS2]);
1452
1453 if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER)
1454 saa7164_encoder_unregister(&dev->ports[SAA7164_PORT_ENC1]);
1455
1456 if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER)
1457 saa7164_encoder_unregister(&dev->ports[SAA7164_PORT_ENC2]);
1458
1459 if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI)
1460 saa7164_vbi_unregister(&dev->ports[SAA7164_PORT_VBI1]);
1461
1462 if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI)
1463 saa7164_vbi_unregister(&dev->ports[SAA7164_PORT_VBI2]);
1464
1465 saa7164_i2c_unregister(&dev->i2c_bus[0]);
1466 saa7164_i2c_unregister(&dev->i2c_bus[1]);
1467 saa7164_i2c_unregister(&dev->i2c_bus[2]);
1468
1469 pci_disable_device(pci_dev);
1470
1471 /* unregister stuff */
1472 free_irq(pci_dev->irq, dev);
1473 pci_set_drvdata(pci_dev, NULL);
1474
1475 mutex_lock(&devlist);
1476 list_del(&dev->devlist);
1477 mutex_unlock(&devlist);
1478
1479 saa7164_dev_unregister(dev);
1480 kfree(dev);
1481}
1482
1483static struct pci_device_id saa7164_pci_tbl[] = {
1484 {
1485 /* SAA7164 */
1486 .vendor = 0x1131,
1487 .device = 0x7164,
1488 .subvendor = PCI_ANY_ID,
1489 .subdevice = PCI_ANY_ID,
1490 }, {
1491 /* --- end of list --- */
1492 }
1493};
1494MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl);
1495
1496static struct pci_driver saa7164_pci_driver = {
1497 .name = "saa7164",
1498 .id_table = saa7164_pci_tbl,
1499 .probe = saa7164_initdev,
1500 .remove = __devexit_p(saa7164_finidev),
1501 /* TODO */
1502 .suspend = NULL,
1503 .resume = NULL,
1504};
1505
1506static int __init saa7164_init(void)
1507{
1508 printk(KERN_INFO "saa7164 driver loaded\n");
1509
1510#ifdef CONFIG_PROC_FS
1511 saa7164_proc_create();
1512#endif
1513 return pci_register_driver(&saa7164_pci_driver);
1514}
1515
1516static void __exit saa7164_fini(void)
1517{
1518#ifdef CONFIG_PROC_FS
1519 remove_proc_entry("saa7164", NULL);
1520#endif
1521 pci_unregister_driver(&saa7164_pci_driver);
1522}
1523
1524module_init(saa7164_init);
1525module_exit(saa7164_fini);
1526
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
new file mode 100644
index 00000000000..d3779379197
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -0,0 +1,555 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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 "saa7164.h"
23
24#include "tda10048.h"
25#include "tda18271.h"
26#include "s5h1411.h"
27
28#define DRIVER_NAME "saa7164"
29
30DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
31
32/* addr is in the card struct, get it from there */
33static struct tda10048_config hauppauge_hvr2200_1_config = {
34 .demod_address = 0x10 >> 1,
35 .output_mode = TDA10048_SERIAL_OUTPUT,
36 .fwbulkwritelen = TDA10048_BULKWRITE_200,
37 .inversion = TDA10048_INVERSION_ON,
38 .dtv6_if_freq_khz = TDA10048_IF_3300,
39 .dtv7_if_freq_khz = TDA10048_IF_3500,
40 .dtv8_if_freq_khz = TDA10048_IF_4000,
41 .clk_freq_khz = TDA10048_CLK_16000,
42};
43static struct tda10048_config hauppauge_hvr2200_2_config = {
44 .demod_address = 0x12 >> 1,
45 .output_mode = TDA10048_SERIAL_OUTPUT,
46 .fwbulkwritelen = TDA10048_BULKWRITE_200,
47 .inversion = TDA10048_INVERSION_ON,
48 .dtv6_if_freq_khz = TDA10048_IF_3300,
49 .dtv7_if_freq_khz = TDA10048_IF_3500,
50 .dtv8_if_freq_khz = TDA10048_IF_4000,
51 .clk_freq_khz = TDA10048_CLK_16000,
52};
53
54static struct tda18271_std_map hauppauge_tda18271_std_map = {
55 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
56 .if_lvl = 6, .rfagc_top = 0x37 },
57 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
58 .if_lvl = 6, .rfagc_top = 0x37 },
59};
60
61static struct tda18271_config hauppauge_hvr22x0_tuner_config = {
62 .std_map = &hauppauge_tda18271_std_map,
63 .gate = TDA18271_GATE_ANALOG,
64 .role = TDA18271_MASTER,
65};
66
67static struct tda18271_config hauppauge_hvr22x0s_tuner_config = {
68 .std_map = &hauppauge_tda18271_std_map,
69 .gate = TDA18271_GATE_ANALOG,
70 .role = TDA18271_SLAVE,
71 .output_opt = TDA18271_OUTPUT_LT_OFF,
72 .rf_cal_on_startup = 1
73};
74
75static struct s5h1411_config hauppauge_s5h1411_config = {
76 .output_mode = S5H1411_SERIAL_OUTPUT,
77 .gpio = S5H1411_GPIO_ON,
78 .qam_if = S5H1411_IF_4000,
79 .vsb_if = S5H1411_IF_3250,
80 .inversion = S5H1411_INVERSION_ON,
81 .status_mode = S5H1411_DEMODLOCKING,
82 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
83};
84
85static int saa7164_dvb_stop_port(struct saa7164_port *port)
86{
87 struct saa7164_dev *dev = port->dev;
88 int ret;
89
90 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
91 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
92 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
93 __func__, ret);
94 ret = -EIO;
95 } else {
96 dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__);
97 ret = 0;
98 }
99
100 return ret;
101}
102
103static int saa7164_dvb_acquire_port(struct saa7164_port *port)
104{
105 struct saa7164_dev *dev = port->dev;
106 int ret;
107
108 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
109 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
110 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
111 __func__, ret);
112 ret = -EIO;
113 } else {
114 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
115 ret = 0;
116 }
117
118 return ret;
119}
120
121static int saa7164_dvb_pause_port(struct saa7164_port *port)
122{
123 struct saa7164_dev *dev = port->dev;
124 int ret;
125
126 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
127 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
128 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
129 __func__, ret);
130 ret = -EIO;
131 } else {
132 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
133 ret = 0;
134 }
135
136 return ret;
137}
138
139/* Firmware is very windows centric, meaning you have to transition
140 * the part through AVStream / KS Windows stages, forwards or backwards.
141 * States are: stopped, acquired (h/w), paused, started.
142 */
143static int saa7164_dvb_stop_streaming(struct saa7164_port *port)
144{
145 struct saa7164_dev *dev = port->dev;
146 struct saa7164_buffer *buf;
147 struct list_head *p, *q;
148 int ret;
149
150 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
151
152 ret = saa7164_dvb_pause_port(port);
153 ret = saa7164_dvb_acquire_port(port);
154 ret = saa7164_dvb_stop_port(port);
155
156 /* Mark the hardware buffers as free */
157 mutex_lock(&port->dmaqueue_lock);
158 list_for_each_safe(p, q, &port->dmaqueue.list) {
159 buf = list_entry(p, struct saa7164_buffer, list);
160 buf->flags = SAA7164_BUFFER_FREE;
161 }
162 mutex_unlock(&port->dmaqueue_lock);
163
164 return ret;
165}
166
167static int saa7164_dvb_start_port(struct saa7164_port *port)
168{
169 struct saa7164_dev *dev = port->dev;
170 int ret = 0, result;
171
172 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
173
174 saa7164_buffer_cfg_port(port);
175
176 /* Acquire the hardware */
177 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
178 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
179 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
180 __func__, result);
181
182 /* Stop the hardware, regardless */
183 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
184 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
185 printk(KERN_ERR "%s() acquire/forced stop transition "
186 "failed, res = 0x%x\n", __func__, result);
187 }
188 ret = -EIO;
189 goto out;
190 } else
191 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
192
193 /* Pause the hardware */
194 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
195 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
196 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
197 __func__, result);
198
199 /* Stop the hardware, regardless */
200 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
201 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
202 printk(KERN_ERR "%s() pause/forced stop transition "
203 "failed, res = 0x%x\n", __func__, result);
204 }
205
206 ret = -EIO;
207 goto out;
208 } else
209 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
210
211 /* Start the hardware */
212 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
213 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
214 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
215 __func__, result);
216
217 /* Stop the hardware, regardless */
218 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
219 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
220 printk(KERN_ERR "%s() run/forced stop transition "
221 "failed, res = 0x%x\n", __func__, result);
222 }
223
224 ret = -EIO;
225 } else
226 dprintk(DBGLVL_DVB, "%s() Running\n", __func__);
227
228out:
229 return ret;
230}
231
232static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
233{
234 struct dvb_demux *demux = feed->demux;
235 struct saa7164_port *port = (struct saa7164_port *) demux->priv;
236 struct saa7164_dvb *dvb = &port->dvb;
237 struct saa7164_dev *dev = port->dev;
238 int ret = 0;
239
240 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
241
242 if (!demux->dmx.frontend)
243 return -EINVAL;
244
245 if (dvb) {
246 mutex_lock(&dvb->lock);
247 if (dvb->feeding++ == 0) {
248 /* Start transport */
249 ret = saa7164_dvb_start_port(port);
250 }
251 mutex_unlock(&dvb->lock);
252 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
253 __func__, port->nr, dvb->feeding);
254 }
255
256 return ret;
257}
258
259static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
260{
261 struct dvb_demux *demux = feed->demux;
262 struct saa7164_port *port = (struct saa7164_port *) demux->priv;
263 struct saa7164_dvb *dvb = &port->dvb;
264 struct saa7164_dev *dev = port->dev;
265 int ret = 0;
266
267 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
268
269 if (dvb) {
270 mutex_lock(&dvb->lock);
271 if (--dvb->feeding == 0) {
272 /* Stop transport */
273 ret = saa7164_dvb_stop_streaming(port);
274 }
275 mutex_unlock(&dvb->lock);
276 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
277 __func__, port->nr, dvb->feeding);
278 }
279
280 return ret;
281}
282
283static int dvb_register(struct saa7164_port *port)
284{
285 struct saa7164_dvb *dvb = &port->dvb;
286 struct saa7164_dev *dev = port->dev;
287 struct saa7164_buffer *buf;
288 int result, i;
289
290 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
291
292 if (port->type != SAA7164_MPEG_DVB)
293 BUG();
294
295 /* Sanity check that the PCI configuration space is active */
296 if (port->hwcfg.BARLocation == 0) {
297 result = -ENOMEM;
298 printk(KERN_ERR "%s: dvb_register_adapter failed "
299 "(errno = %d), NO PCI configuration\n",
300 DRIVER_NAME, result);
301 goto fail_adapter;
302 }
303
304 /* Init and establish defaults */
305 port->hw_streamingparams.bitspersample = 8;
306 port->hw_streamingparams.samplesperline = 188;
307 port->hw_streamingparams.numberoflines =
308 (SAA7164_TS_NUMBER_OF_LINES * 188) / 188;
309
310 port->hw_streamingparams.pitch = 188;
311 port->hw_streamingparams.linethreshold = 0;
312 port->hw_streamingparams.pagetablelistvirt = NULL;
313 port->hw_streamingparams.pagetablelistphys = NULL;
314 port->hw_streamingparams.numpagetables = 2 +
315 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
316
317 port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
318
319 /* Allocate the PCI resources */
320 for (i = 0; i < port->hwcfg.buffercount; i++) {
321 buf = saa7164_buffer_alloc(port,
322 port->hw_streamingparams.numberoflines *
323 port->hw_streamingparams.pitch);
324
325 if (!buf) {
326 result = -ENOMEM;
327 printk(KERN_ERR "%s: dvb_register_adapter failed "
328 "(errno = %d), unable to allocate buffers\n",
329 DRIVER_NAME, result);
330 goto fail_adapter;
331 }
332
333 mutex_lock(&port->dmaqueue_lock);
334 list_add_tail(&buf->list, &port->dmaqueue.list);
335 mutex_unlock(&port->dmaqueue_lock);
336 }
337
338 /* register adapter */
339 result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
340 &dev->pci->dev, adapter_nr);
341 if (result < 0) {
342 printk(KERN_ERR "%s: dvb_register_adapter failed "
343 "(errno = %d)\n", DRIVER_NAME, result);
344 goto fail_adapter;
345 }
346 dvb->adapter.priv = port;
347
348 /* register frontend */
349 result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
350 if (result < 0) {
351 printk(KERN_ERR "%s: dvb_register_frontend failed "
352 "(errno = %d)\n", DRIVER_NAME, result);
353 goto fail_frontend;
354 }
355
356 /* register demux stuff */
357 dvb->demux.dmx.capabilities =
358 DMX_TS_FILTERING | DMX_SECTION_FILTERING |
359 DMX_MEMORY_BASED_FILTERING;
360 dvb->demux.priv = port;
361 dvb->demux.filternum = 256;
362 dvb->demux.feednum = 256;
363 dvb->demux.start_feed = saa7164_dvb_start_feed;
364 dvb->demux.stop_feed = saa7164_dvb_stop_feed;
365 result = dvb_dmx_init(&dvb->demux);
366 if (result < 0) {
367 printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
368 DRIVER_NAME, result);
369 goto fail_dmx;
370 }
371
372 dvb->dmxdev.filternum = 256;
373 dvb->dmxdev.demux = &dvb->demux.dmx;
374 dvb->dmxdev.capabilities = 0;
375 result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
376 if (result < 0) {
377 printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
378 DRIVER_NAME, result);
379 goto fail_dmxdev;
380 }
381
382 dvb->fe_hw.source = DMX_FRONTEND_0;
383 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
384 if (result < 0) {
385 printk(KERN_ERR "%s: add_frontend failed "
386 "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
387 goto fail_fe_hw;
388 }
389
390 dvb->fe_mem.source = DMX_MEMORY_FE;
391 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
392 if (result < 0) {
393 printk(KERN_ERR "%s: add_frontend failed "
394 "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
395 goto fail_fe_mem;
396 }
397
398 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
399 if (result < 0) {
400 printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
401 DRIVER_NAME, result);
402 goto fail_fe_conn;
403 }
404
405 /* register network adapter */
406 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
407 return 0;
408
409fail_fe_conn:
410 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
411fail_fe_mem:
412 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
413fail_fe_hw:
414 dvb_dmxdev_release(&dvb->dmxdev);
415fail_dmxdev:
416 dvb_dmx_release(&dvb->demux);
417fail_dmx:
418 dvb_unregister_frontend(dvb->frontend);
419fail_frontend:
420 dvb_frontend_detach(dvb->frontend);
421 dvb_unregister_adapter(&dvb->adapter);
422fail_adapter:
423 return result;
424}
425
426int saa7164_dvb_unregister(struct saa7164_port *port)
427{
428 struct saa7164_dvb *dvb = &port->dvb;
429 struct saa7164_dev *dev = port->dev;
430 struct saa7164_buffer *b;
431 struct list_head *c, *n;
432
433 dprintk(DBGLVL_DVB, "%s()\n", __func__);
434
435 if (port->type != SAA7164_MPEG_DVB)
436 BUG();
437
438 /* Remove any allocated buffers */
439 mutex_lock(&port->dmaqueue_lock);
440 list_for_each_safe(c, n, &port->dmaqueue.list) {
441 b = list_entry(c, struct saa7164_buffer, list);
442 list_del(c);
443 saa7164_buffer_dealloc(b);
444 }
445 mutex_unlock(&port->dmaqueue_lock);
446
447 if (dvb->frontend == NULL)
448 return 0;
449
450 dvb_net_release(&dvb->net);
451 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
452 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
453 dvb_dmxdev_release(&dvb->dmxdev);
454 dvb_dmx_release(&dvb->demux);
455 dvb_unregister_frontend(dvb->frontend);
456 dvb_frontend_detach(dvb->frontend);
457 dvb_unregister_adapter(&dvb->adapter);
458 return 0;
459}
460
461/* All the DVB attach calls go here, this function get's modified
462 * for each new card.
463 */
464int saa7164_dvb_register(struct saa7164_port *port)
465{
466 struct saa7164_dev *dev = port->dev;
467 struct saa7164_dvb *dvb = &port->dvb;
468 struct saa7164_i2c *i2c_bus = NULL;
469 int ret;
470
471 dprintk(DBGLVL_DVB, "%s()\n", __func__);
472
473 /* init frontend */
474 switch (dev->board) {
475 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
476 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
477 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
478 case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
479 i2c_bus = &dev->i2c_bus[port->nr + 1];
480 switch (port->nr) {
481 case 0:
482 port->dvb.frontend = dvb_attach(tda10048_attach,
483 &hauppauge_hvr2200_1_config,
484 &i2c_bus->i2c_adap);
485
486 if (port->dvb.frontend != NULL) {
487 /* TODO: addr is in the card struct */
488 dvb_attach(tda18271_attach, port->dvb.frontend,
489 0xc0 >> 1, &i2c_bus->i2c_adap,
490 &hauppauge_hvr22x0_tuner_config);
491 }
492
493 break;
494 case 1:
495 port->dvb.frontend = dvb_attach(tda10048_attach,
496 &hauppauge_hvr2200_2_config,
497 &i2c_bus->i2c_adap);
498
499 if (port->dvb.frontend != NULL) {
500 /* TODO: addr is in the card struct */
501 dvb_attach(tda18271_attach, port->dvb.frontend,
502 0xc0 >> 1, &i2c_bus->i2c_adap,
503 &hauppauge_hvr22x0s_tuner_config);
504 }
505
506 break;
507 }
508 break;
509 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
510 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
511 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
512 i2c_bus = &dev->i2c_bus[port->nr + 1];
513
514 port->dvb.frontend = dvb_attach(s5h1411_attach,
515 &hauppauge_s5h1411_config,
516 &i2c_bus->i2c_adap);
517
518 if (port->dvb.frontend != NULL) {
519 if (port->nr == 0) {
520 /* Master TDA18271 */
521 /* TODO: addr is in the card struct */
522 dvb_attach(tda18271_attach, port->dvb.frontend,
523 0xc0 >> 1, &i2c_bus->i2c_adap,
524 &hauppauge_hvr22x0_tuner_config);
525 } else {
526 /* Slave TDA18271 */
527 dvb_attach(tda18271_attach, port->dvb.frontend,
528 0xc0 >> 1, &i2c_bus->i2c_adap,
529 &hauppauge_hvr22x0s_tuner_config);
530 }
531 }
532
533 break;
534 default:
535 printk(KERN_ERR "%s: The frontend isn't supported\n",
536 dev->name);
537 break;
538 }
539 if (NULL == dvb->frontend) {
540 printk(KERN_ERR "%s() Frontend initialization failed\n",
541 __func__);
542 return -1;
543 }
544
545 /* register everything */
546 ret = dvb_register(port);
547 if (ret < 0) {
548 if (dvb->frontend->ops.release)
549 dvb->frontend->ops.release(dvb->frontend);
550 return ret;
551 }
552
553 return 0;
554}
555
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
new file mode 100644
index 00000000000..2fd38a01887
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-encoder.c
@@ -0,0 +1,1506 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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 "saa7164.h"
23
24#define ENCODER_MAX_BITRATE 6500000
25#define ENCODER_MIN_BITRATE 1000000
26#define ENCODER_DEF_BITRATE 5000000
27
28static struct saa7164_tvnorm saa7164_tvnorms[] = {
29 {
30 .name = "NTSC-M",
31 .id = V4L2_STD_NTSC_M,
32 }, {
33 .name = "NTSC-JP",
34 .id = V4L2_STD_NTSC_M_JP,
35 }
36};
37
38static const u32 saa7164_v4l2_ctrls[] = {
39 V4L2_CID_BRIGHTNESS,
40 V4L2_CID_CONTRAST,
41 V4L2_CID_SATURATION,
42 V4L2_CID_HUE,
43 V4L2_CID_AUDIO_VOLUME,
44 V4L2_CID_SHARPNESS,
45 V4L2_CID_MPEG_STREAM_TYPE,
46 V4L2_CID_MPEG_VIDEO_ASPECT,
47 V4L2_CID_MPEG_VIDEO_B_FRAMES,
48 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
49 V4L2_CID_MPEG_AUDIO_MUTE,
50 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
51 V4L2_CID_MPEG_VIDEO_BITRATE,
52 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
53 0
54};
55
56/* Take the encoder configuration form the port struct and
57 * flush it to the hardware.
58 */
59static void saa7164_encoder_configure(struct saa7164_port *port)
60{
61 struct saa7164_dev *dev = port->dev;
62 dprintk(DBGLVL_ENC, "%s()\n", __func__);
63
64 port->encoder_params.width = port->width;
65 port->encoder_params.height = port->height;
66 port->encoder_params.is_50hz =
67 (port->encodernorm.id & V4L2_STD_625_50) != 0;
68
69 /* Set up the DIF (enable it) for analog mode by default */
70 saa7164_api_initialize_dif(port);
71
72 /* Configure the correct video standard */
73 saa7164_api_configure_dif(port, port->encodernorm.id);
74
75 /* Ensure the audio decoder is correct configured */
76 saa7164_api_set_audio_std(port);
77}
78
79static int saa7164_encoder_buffers_dealloc(struct saa7164_port *port)
80{
81 struct list_head *c, *n, *p, *q, *l, *v;
82 struct saa7164_dev *dev = port->dev;
83 struct saa7164_buffer *buf;
84 struct saa7164_user_buffer *ubuf;
85
86 /* Remove any allocated buffers */
87 mutex_lock(&port->dmaqueue_lock);
88
89 dprintk(DBGLVL_ENC, "%s(port=%d) dmaqueue\n", __func__, port->nr);
90 list_for_each_safe(c, n, &port->dmaqueue.list) {
91 buf = list_entry(c, struct saa7164_buffer, list);
92 list_del(c);
93 saa7164_buffer_dealloc(buf);
94 }
95
96 dprintk(DBGLVL_ENC, "%s(port=%d) used\n", __func__, port->nr);
97 list_for_each_safe(p, q, &port->list_buf_used.list) {
98 ubuf = list_entry(p, struct saa7164_user_buffer, list);
99 list_del(p);
100 saa7164_buffer_dealloc_user(ubuf);
101 }
102
103 dprintk(DBGLVL_ENC, "%s(port=%d) free\n", __func__, port->nr);
104 list_for_each_safe(l, v, &port->list_buf_free.list) {
105 ubuf = list_entry(l, struct saa7164_user_buffer, list);
106 list_del(l);
107 saa7164_buffer_dealloc_user(ubuf);
108 }
109
110 mutex_unlock(&port->dmaqueue_lock);
111 dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
112
113 return 0;
114}
115
116/* Dynamic buffer switch at encoder start time */
117static int saa7164_encoder_buffers_alloc(struct saa7164_port *port)
118{
119 struct saa7164_dev *dev = port->dev;
120 struct saa7164_buffer *buf;
121 struct saa7164_user_buffer *ubuf;
122 struct tmHWStreamParameters *params = &port->hw_streamingparams;
123 int result = -ENODEV, i;
124 int len = 0;
125
126 dprintk(DBGLVL_ENC, "%s()\n", __func__);
127
128 if (port->encoder_params.stream_type ==
129 V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
130 dprintk(DBGLVL_ENC,
131 "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n",
132 __func__);
133 params->samplesperline = 128;
134 params->numberoflines = 256;
135 params->pitch = 128;
136 params->numpagetables = 2 +
137 ((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE);
138 } else
139 if (port->encoder_params.stream_type ==
140 V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
141 dprintk(DBGLVL_ENC,
142 "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n",
143 __func__);
144 params->samplesperline = 188;
145 params->numberoflines = 312;
146 params->pitch = 188;
147 params->numpagetables = 2 +
148 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
149 } else
150 BUG();
151
152 /* Init and establish defaults */
153 params->bitspersample = 8;
154 params->linethreshold = 0;
155 params->pagetablelistvirt = NULL;
156 params->pagetablelistphys = NULL;
157 params->numpagetableentries = port->hwcfg.buffercount;
158
159 /* Allocate the PCI resources, buffers (hard) */
160 for (i = 0; i < port->hwcfg.buffercount; i++) {
161 buf = saa7164_buffer_alloc(port,
162 params->numberoflines *
163 params->pitch);
164
165 if (!buf) {
166 printk(KERN_ERR "%s() failed "
167 "(errno = %d), unable to allocate buffer\n",
168 __func__, result);
169 result = -ENOMEM;
170 goto failed;
171 } else {
172
173 mutex_lock(&port->dmaqueue_lock);
174 list_add_tail(&buf->list, &port->dmaqueue.list);
175 mutex_unlock(&port->dmaqueue_lock);
176
177 }
178 }
179
180 /* Allocate some kernel buffers for copying
181 * to userpsace.
182 */
183 len = params->numberoflines * params->pitch;
184
185 if (encoder_buffers < 16)
186 encoder_buffers = 16;
187 if (encoder_buffers > 512)
188 encoder_buffers = 512;
189
190 for (i = 0; i < encoder_buffers; i++) {
191
192 ubuf = saa7164_buffer_alloc_user(dev, len);
193 if (ubuf) {
194 mutex_lock(&port->dmaqueue_lock);
195 list_add_tail(&ubuf->list, &port->list_buf_free.list);
196 mutex_unlock(&port->dmaqueue_lock);
197 }
198
199 }
200
201 result = 0;
202
203failed:
204 return result;
205}
206
207static int saa7164_encoder_initialize(struct saa7164_port *port)
208{
209 saa7164_encoder_configure(port);
210 return 0;
211}
212
213/* -- V4L2 --------------------------------------------------------- */
214static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
215{
216 struct saa7164_encoder_fh *fh = file->private_data;
217 struct saa7164_port *port = fh->port;
218 struct saa7164_dev *dev = port->dev;
219 unsigned int i;
220
221 dprintk(DBGLVL_ENC, "%s(id=0x%x)\n", __func__, (u32)*id);
222
223 for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
224 if (*id & saa7164_tvnorms[i].id)
225 break;
226 }
227 if (i == ARRAY_SIZE(saa7164_tvnorms))
228 return -EINVAL;
229
230 port->encodernorm = saa7164_tvnorms[i];
231
232 /* Update the audio decoder while is not running in
233 * auto detect mode.
234 */
235 saa7164_api_set_audio_std(port);
236
237 dprintk(DBGLVL_ENC, "%s(id=0x%x) OK\n", __func__, (u32)*id);
238
239 return 0;
240}
241
242static int vidioc_enum_input(struct file *file, void *priv,
243 struct v4l2_input *i)
244{
245 int n;
246
247 char *inputs[] = { "tuner", "composite", "svideo", "aux",
248 "composite 2", "svideo 2", "aux 2" };
249
250 if (i->index >= 7)
251 return -EINVAL;
252
253 strcpy(i->name, inputs[i->index]);
254
255 if (i->index == 0)
256 i->type = V4L2_INPUT_TYPE_TUNER;
257 else
258 i->type = V4L2_INPUT_TYPE_CAMERA;
259
260 for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
261 i->std |= saa7164_tvnorms[n].id;
262
263 return 0;
264}
265
266static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
267{
268 struct saa7164_encoder_fh *fh = file->private_data;
269 struct saa7164_port *port = fh->port;
270 struct saa7164_dev *dev = port->dev;
271
272 if (saa7164_api_get_videomux(port) != SAA_OK)
273 return -EIO;
274
275 *i = (port->mux_input - 1);
276
277 dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, *i);
278
279 return 0;
280}
281
282static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
283{
284 struct saa7164_encoder_fh *fh = file->private_data;
285 struct saa7164_port *port = fh->port;
286 struct saa7164_dev *dev = port->dev;
287
288 dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, i);
289
290 if (i >= 7)
291 return -EINVAL;
292
293 port->mux_input = i + 1;
294
295 if (saa7164_api_set_videomux(port) != SAA_OK)
296 return -EIO;
297
298 return 0;
299}
300
301static int vidioc_g_tuner(struct file *file, void *priv,
302 struct v4l2_tuner *t)
303{
304 struct saa7164_encoder_fh *fh = file->private_data;
305 struct saa7164_port *port = fh->port;
306 struct saa7164_dev *dev = port->dev;
307
308 if (0 != t->index)
309 return -EINVAL;
310
311 strcpy(t->name, "tuner");
312 t->type = V4L2_TUNER_ANALOG_TV;
313 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
314
315 dprintk(DBGLVL_ENC, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
316
317 return 0;
318}
319
320static int vidioc_s_tuner(struct file *file, void *priv,
321 struct v4l2_tuner *t)
322{
323 /* Update the A/V core */
324 return 0;
325}
326
327static int vidioc_g_frequency(struct file *file, void *priv,
328 struct v4l2_frequency *f)
329{
330 struct saa7164_encoder_fh *fh = file->private_data;
331 struct saa7164_port *port = fh->port;
332
333 f->type = V4L2_TUNER_ANALOG_TV;
334 f->frequency = port->freq;
335
336 return 0;
337}
338
339static int vidioc_s_frequency(struct file *file, void *priv,
340 struct v4l2_frequency *f)
341{
342 struct saa7164_encoder_fh *fh = file->private_data;
343 struct saa7164_port *port = fh->port;
344 struct saa7164_dev *dev = port->dev;
345 struct saa7164_port *tsport;
346 struct dvb_frontend *fe;
347
348 /* TODO: Pull this for the std */
349 struct analog_parameters params = {
350 .mode = V4L2_TUNER_ANALOG_TV,
351 .audmode = V4L2_TUNER_MODE_STEREO,
352 .std = port->encodernorm.id,
353 .frequency = f->frequency
354 };
355
356 /* Stop the encoder */
357 dprintk(DBGLVL_ENC, "%s() frequency=%d tuner=%d\n", __func__,
358 f->frequency, f->tuner);
359
360 if (f->tuner != 0)
361 return -EINVAL;
362
363 if (f->type != V4L2_TUNER_ANALOG_TV)
364 return -EINVAL;
365
366 port->freq = f->frequency;
367
368 /* Update the hardware */
369 if (port->nr == SAA7164_PORT_ENC1)
370 tsport = &dev->ports[SAA7164_PORT_TS1];
371 else
372 if (port->nr == SAA7164_PORT_ENC2)
373 tsport = &dev->ports[SAA7164_PORT_TS2];
374 else
375 BUG();
376
377 fe = tsport->dvb.frontend;
378
379 if (fe && fe->ops.tuner_ops.set_analog_params)
380 fe->ops.tuner_ops.set_analog_params(fe, &params);
381 else
382 printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
383
384 saa7164_encoder_initialize(port);
385
386 return 0;
387}
388
389static int vidioc_g_ctrl(struct file *file, void *priv,
390 struct v4l2_control *ctl)
391{
392 struct saa7164_encoder_fh *fh = file->private_data;
393 struct saa7164_port *port = fh->port;
394 struct saa7164_dev *dev = port->dev;
395
396 dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
397 ctl->id, ctl->value);
398
399 switch (ctl->id) {
400 case V4L2_CID_BRIGHTNESS:
401 ctl->value = port->ctl_brightness;
402 break;
403 case V4L2_CID_CONTRAST:
404 ctl->value = port->ctl_contrast;
405 break;
406 case V4L2_CID_SATURATION:
407 ctl->value = port->ctl_saturation;
408 break;
409 case V4L2_CID_HUE:
410 ctl->value = port->ctl_hue;
411 break;
412 case V4L2_CID_SHARPNESS:
413 ctl->value = port->ctl_sharpness;
414 break;
415 case V4L2_CID_AUDIO_VOLUME:
416 ctl->value = port->ctl_volume;
417 break;
418 default:
419 return -EINVAL;
420 }
421
422 return 0;
423}
424
425static int vidioc_s_ctrl(struct file *file, void *priv,
426 struct v4l2_control *ctl)
427{
428 struct saa7164_encoder_fh *fh = file->private_data;
429 struct saa7164_port *port = fh->port;
430 struct saa7164_dev *dev = port->dev;
431 int ret = 0;
432
433 dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
434 ctl->id, ctl->value);
435
436 switch (ctl->id) {
437 case V4L2_CID_BRIGHTNESS:
438 if ((ctl->value >= 0) && (ctl->value <= 255)) {
439 port->ctl_brightness = ctl->value;
440 saa7164_api_set_usercontrol(port,
441 PU_BRIGHTNESS_CONTROL);
442 } else
443 ret = -EINVAL;
444 break;
445 case V4L2_CID_CONTRAST:
446 if ((ctl->value >= 0) && (ctl->value <= 255)) {
447 port->ctl_contrast = ctl->value;
448 saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
449 } else
450 ret = -EINVAL;
451 break;
452 case V4L2_CID_SATURATION:
453 if ((ctl->value >= 0) && (ctl->value <= 255)) {
454 port->ctl_saturation = ctl->value;
455 saa7164_api_set_usercontrol(port,
456 PU_SATURATION_CONTROL);
457 } else
458 ret = -EINVAL;
459 break;
460 case V4L2_CID_HUE:
461 if ((ctl->value >= 0) && (ctl->value <= 255)) {
462 port->ctl_hue = ctl->value;
463 saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
464 } else
465 ret = -EINVAL;
466 break;
467 case V4L2_CID_SHARPNESS:
468 if ((ctl->value >= 0) && (ctl->value <= 255)) {
469 port->ctl_sharpness = ctl->value;
470 saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
471 } else
472 ret = -EINVAL;
473 break;
474 case V4L2_CID_AUDIO_VOLUME:
475 if ((ctl->value >= -83) && (ctl->value <= 24)) {
476 port->ctl_volume = ctl->value;
477 saa7164_api_set_audio_volume(port, port->ctl_volume);
478 } else
479 ret = -EINVAL;
480 break;
481 default:
482 ret = -EINVAL;
483 }
484
485 return ret;
486}
487
488static int saa7164_get_ctrl(struct saa7164_port *port,
489 struct v4l2_ext_control *ctrl)
490{
491 struct saa7164_encoder_params *params = &port->encoder_params;
492
493 switch (ctrl->id) {
494 case V4L2_CID_MPEG_VIDEO_BITRATE:
495 ctrl->value = params->bitrate;
496 break;
497 case V4L2_CID_MPEG_STREAM_TYPE:
498 ctrl->value = params->stream_type;
499 break;
500 case V4L2_CID_MPEG_AUDIO_MUTE:
501 ctrl->value = params->ctl_mute;
502 break;
503 case V4L2_CID_MPEG_VIDEO_ASPECT:
504 ctrl->value = params->ctl_aspect;
505 break;
506 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
507 ctrl->value = params->bitrate_mode;
508 break;
509 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
510 ctrl->value = params->refdist;
511 break;
512 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
513 ctrl->value = params->bitrate_peak;
514 break;
515 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
516 ctrl->value = params->gop_size;
517 break;
518 default:
519 return -EINVAL;
520 }
521 return 0;
522}
523
524static int vidioc_g_ext_ctrls(struct file *file, void *priv,
525 struct v4l2_ext_controls *ctrls)
526{
527 struct saa7164_encoder_fh *fh = file->private_data;
528 struct saa7164_port *port = fh->port;
529 int i, err = 0;
530
531 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
532 for (i = 0; i < ctrls->count; i++) {
533 struct v4l2_ext_control *ctrl = ctrls->controls + i;
534
535 err = saa7164_get_ctrl(port, ctrl);
536 if (err) {
537 ctrls->error_idx = i;
538 break;
539 }
540 }
541 return err;
542
543 }
544
545 return -EINVAL;
546}
547
548static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
549{
550 int ret = -EINVAL;
551
552 switch (ctrl->id) {
553 case V4L2_CID_MPEG_VIDEO_BITRATE:
554 if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
555 (ctrl->value <= ENCODER_MAX_BITRATE))
556 ret = 0;
557 break;
558 case V4L2_CID_MPEG_STREAM_TYPE:
559 if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
560 (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
561 ret = 0;
562 break;
563 case V4L2_CID_MPEG_AUDIO_MUTE:
564 if ((ctrl->value >= 0) &&
565 (ctrl->value <= 1))
566 ret = 0;
567 break;
568 case V4L2_CID_MPEG_VIDEO_ASPECT:
569 if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
570 (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
571 ret = 0;
572 break;
573 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
574 if ((ctrl->value >= 0) &&
575 (ctrl->value <= 255))
576 ret = 0;
577 break;
578 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
579 if ((ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ||
580 (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))
581 ret = 0;
582 break;
583 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
584 if ((ctrl->value >= 1) &&
585 (ctrl->value <= 3))
586 ret = 0;
587 break;
588 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
589 if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
590 (ctrl->value <= ENCODER_MAX_BITRATE))
591 ret = 0;
592 break;
593 default:
594 ret = -EINVAL;
595 }
596
597 return ret;
598}
599
600static int vidioc_try_ext_ctrls(struct file *file, void *priv,
601 struct v4l2_ext_controls *ctrls)
602{
603 int i, err = 0;
604
605 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
606 for (i = 0; i < ctrls->count; i++) {
607 struct v4l2_ext_control *ctrl = ctrls->controls + i;
608
609 err = saa7164_try_ctrl(ctrl, 0);
610 if (err) {
611 ctrls->error_idx = i;
612 break;
613 }
614 }
615 return err;
616 }
617
618 return -EINVAL;
619}
620
621static int saa7164_set_ctrl(struct saa7164_port *port,
622 struct v4l2_ext_control *ctrl)
623{
624 struct saa7164_encoder_params *params = &port->encoder_params;
625 int ret = 0;
626
627 switch (ctrl->id) {
628 case V4L2_CID_MPEG_VIDEO_BITRATE:
629 params->bitrate = ctrl->value;
630 break;
631 case V4L2_CID_MPEG_STREAM_TYPE:
632 params->stream_type = ctrl->value;
633 break;
634 case V4L2_CID_MPEG_AUDIO_MUTE:
635 params->ctl_mute = ctrl->value;
636 ret = saa7164_api_audio_mute(port, params->ctl_mute);
637 if (ret != SAA_OK) {
638 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
639 ret);
640 ret = -EIO;
641 }
642 break;
643 case V4L2_CID_MPEG_VIDEO_ASPECT:
644 params->ctl_aspect = ctrl->value;
645 ret = saa7164_api_set_aspect_ratio(port);
646 if (ret != SAA_OK) {
647 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
648 ret);
649 ret = -EIO;
650 }
651 break;
652 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
653 params->bitrate_mode = ctrl->value;
654 break;
655 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
656 params->refdist = ctrl->value;
657 break;
658 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
659 params->bitrate_peak = ctrl->value;
660 break;
661 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
662 params->gop_size = ctrl->value;
663 break;
664 default:
665 return -EINVAL;
666 }
667
668 /* TODO: Update the hardware */
669
670 return ret;
671}
672
673static int vidioc_s_ext_ctrls(struct file *file, void *priv,
674 struct v4l2_ext_controls *ctrls)
675{
676 struct saa7164_encoder_fh *fh = file->private_data;
677 struct saa7164_port *port = fh->port;
678 int i, err = 0;
679
680 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
681 for (i = 0; i < ctrls->count; i++) {
682 struct v4l2_ext_control *ctrl = ctrls->controls + i;
683
684 err = saa7164_try_ctrl(ctrl, 0);
685 if (err) {
686 ctrls->error_idx = i;
687 break;
688 }
689 err = saa7164_set_ctrl(port, ctrl);
690 if (err) {
691 ctrls->error_idx = i;
692 break;
693 }
694 }
695 return err;
696
697 }
698
699 return -EINVAL;
700}
701
702static int vidioc_querycap(struct file *file, void *priv,
703 struct v4l2_capability *cap)
704{
705 struct saa7164_encoder_fh *fh = file->private_data;
706 struct saa7164_port *port = fh->port;
707 struct saa7164_dev *dev = port->dev;
708
709 strcpy(cap->driver, dev->name);
710 strlcpy(cap->card, saa7164_boards[dev->board].name,
711 sizeof(cap->card));
712 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
713
714 cap->capabilities =
715 V4L2_CAP_VIDEO_CAPTURE |
716 V4L2_CAP_READWRITE |
717 0;
718
719 cap->capabilities |= V4L2_CAP_TUNER;
720 cap->version = 0;
721
722 return 0;
723}
724
725static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
726 struct v4l2_fmtdesc *f)
727{
728 if (f->index != 0)
729 return -EINVAL;
730
731 strlcpy(f->description, "MPEG", sizeof(f->description));
732 f->pixelformat = V4L2_PIX_FMT_MPEG;
733
734 return 0;
735}
736
737static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
738 struct v4l2_format *f)
739{
740 struct saa7164_encoder_fh *fh = file->private_data;
741 struct saa7164_port *port = fh->port;
742 struct saa7164_dev *dev = port->dev;
743
744 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
745 f->fmt.pix.bytesperline = 0;
746 f->fmt.pix.sizeimage =
747 port->ts_packet_size * port->ts_packet_count;
748 f->fmt.pix.colorspace = 0;
749 f->fmt.pix.width = port->width;
750 f->fmt.pix.height = port->height;
751
752 dprintk(DBGLVL_ENC, "VIDIOC_G_FMT: w: %d, h: %d\n",
753 port->width, port->height);
754
755 return 0;
756}
757
758static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
759 struct v4l2_format *f)
760{
761 struct saa7164_encoder_fh *fh = file->private_data;
762 struct saa7164_port *port = fh->port;
763 struct saa7164_dev *dev = port->dev;
764
765 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
766 f->fmt.pix.bytesperline = 0;
767 f->fmt.pix.sizeimage =
768 port->ts_packet_size * port->ts_packet_count;
769 f->fmt.pix.colorspace = 0;
770 dprintk(DBGLVL_ENC, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
771 port->width, port->height);
772 return 0;
773}
774
775static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
776 struct v4l2_format *f)
777{
778 struct saa7164_encoder_fh *fh = file->private_data;
779 struct saa7164_port *port = fh->port;
780 struct saa7164_dev *dev = port->dev;
781
782 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
783 f->fmt.pix.bytesperline = 0;
784 f->fmt.pix.sizeimage =
785 port->ts_packet_size * port->ts_packet_count;
786 f->fmt.pix.colorspace = 0;
787
788 dprintk(DBGLVL_ENC, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
789 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
790
791 return 0;
792}
793
794static int vidioc_log_status(struct file *file, void *priv)
795{
796 return 0;
797}
798
799static int fill_queryctrl(struct saa7164_encoder_params *params,
800 struct v4l2_queryctrl *c)
801{
802 switch (c->id) {
803 case V4L2_CID_BRIGHTNESS:
804 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
805 case V4L2_CID_CONTRAST:
806 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
807 case V4L2_CID_SATURATION:
808 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
809 case V4L2_CID_HUE:
810 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
811 case V4L2_CID_SHARPNESS:
812 return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
813 case V4L2_CID_MPEG_AUDIO_MUTE:
814 return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
815 case V4L2_CID_AUDIO_VOLUME:
816 return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
817 case V4L2_CID_MPEG_VIDEO_BITRATE:
818 return v4l2_ctrl_query_fill(c,
819 ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
820 100000, ENCODER_DEF_BITRATE);
821 case V4L2_CID_MPEG_STREAM_TYPE:
822 return v4l2_ctrl_query_fill(c,
823 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
824 V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
825 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
826 case V4L2_CID_MPEG_VIDEO_ASPECT:
827 return v4l2_ctrl_query_fill(c,
828 V4L2_MPEG_VIDEO_ASPECT_1x1,
829 V4L2_MPEG_VIDEO_ASPECT_221x100,
830 1, V4L2_MPEG_VIDEO_ASPECT_4x3);
831 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
832 return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
833 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
834 return v4l2_ctrl_query_fill(c,
835 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
836 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
837 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
838 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
839 return v4l2_ctrl_query_fill(c,
840 1, 3, 1, 1);
841 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
842 return v4l2_ctrl_query_fill(c,
843 ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
844 100000, ENCODER_DEF_BITRATE);
845 default:
846 return -EINVAL;
847 }
848}
849
850static int vidioc_queryctrl(struct file *file, void *priv,
851 struct v4l2_queryctrl *c)
852{
853 struct saa7164_encoder_fh *fh = priv;
854 struct saa7164_port *port = fh->port;
855 int i, next;
856 u32 id = c->id;
857
858 memset(c, 0, sizeof(*c));
859
860 next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
861 c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
862
863 for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
864 if (next) {
865 if (c->id < saa7164_v4l2_ctrls[i])
866 c->id = saa7164_v4l2_ctrls[i];
867 else
868 continue;
869 }
870
871 if (c->id == saa7164_v4l2_ctrls[i])
872 return fill_queryctrl(&port->encoder_params, c);
873
874 if (c->id < saa7164_v4l2_ctrls[i])
875 break;
876 }
877
878 return -EINVAL;
879}
880
881static int saa7164_encoder_stop_port(struct saa7164_port *port)
882{
883 struct saa7164_dev *dev = port->dev;
884 int ret;
885
886 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
887 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
888 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
889 __func__, ret);
890 ret = -EIO;
891 } else {
892 dprintk(DBGLVL_ENC, "%s() Stopped\n", __func__);
893 ret = 0;
894 }
895
896 return ret;
897}
898
899static int saa7164_encoder_acquire_port(struct saa7164_port *port)
900{
901 struct saa7164_dev *dev = port->dev;
902 int ret;
903
904 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
905 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
906 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
907 __func__, ret);
908 ret = -EIO;
909 } else {
910 dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__);
911 ret = 0;
912 }
913
914 return ret;
915}
916
917static int saa7164_encoder_pause_port(struct saa7164_port *port)
918{
919 struct saa7164_dev *dev = port->dev;
920 int ret;
921
922 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
923 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
924 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
925 __func__, ret);
926 ret = -EIO;
927 } else {
928 dprintk(DBGLVL_ENC, "%s() Paused\n", __func__);
929 ret = 0;
930 }
931
932 return ret;
933}
934
935/* Firmware is very windows centric, meaning you have to transition
936 * the part through AVStream / KS Windows stages, forwards or backwards.
937 * States are: stopped, acquired (h/w), paused, started.
938 * We have to leave here will all of the soft buffers on the free list,
939 * else the cfg_post() func won't have soft buffers to correctly configure.
940 */
941static int saa7164_encoder_stop_streaming(struct saa7164_port *port)
942{
943 struct saa7164_dev *dev = port->dev;
944 struct saa7164_buffer *buf;
945 struct saa7164_user_buffer *ubuf;
946 struct list_head *c, *n;
947 int ret;
948
949 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
950
951 ret = saa7164_encoder_pause_port(port);
952 ret = saa7164_encoder_acquire_port(port);
953 ret = saa7164_encoder_stop_port(port);
954
955 dprintk(DBGLVL_ENC, "%s(port=%d) Hardware stopped\n", __func__,
956 port->nr);
957
958 /* Reset the state of any allocated buffer resources */
959 mutex_lock(&port->dmaqueue_lock);
960
961 /* Reset the hard and soft buffer state */
962 list_for_each_safe(c, n, &port->dmaqueue.list) {
963 buf = list_entry(c, struct saa7164_buffer, list);
964 buf->flags = SAA7164_BUFFER_FREE;
965 buf->pos = 0;
966 }
967
968 list_for_each_safe(c, n, &port->list_buf_used.list) {
969 ubuf = list_entry(c, struct saa7164_user_buffer, list);
970 ubuf->pos = 0;
971 list_move_tail(&ubuf->list, &port->list_buf_free.list);
972 }
973
974 mutex_unlock(&port->dmaqueue_lock);
975
976 /* Free any allocated resources */
977 saa7164_encoder_buffers_dealloc(port);
978
979 dprintk(DBGLVL_ENC, "%s(port=%d) Released\n", __func__, port->nr);
980
981 return ret;
982}
983
984static int saa7164_encoder_start_streaming(struct saa7164_port *port)
985{
986 struct saa7164_dev *dev = port->dev;
987 int result, ret = 0;
988
989 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
990
991 port->done_first_interrupt = 0;
992
993 /* allocate all of the PCIe DMA buffer resources on the fly,
994 * allowing switching between TS and PS payloads without
995 * requiring a complete driver reload.
996 */
997 saa7164_encoder_buffers_alloc(port);
998
999 /* Configure the encoder with any cache values */
1000 saa7164_api_set_encoder(port);
1001 saa7164_api_get_encoder(port);
1002
1003 /* Place the empty buffers on the hardware */
1004 saa7164_buffer_cfg_port(port);
1005
1006 /* Acquire the hardware */
1007 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
1008 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
1009 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
1010 __func__, result);
1011
1012 /* Stop the hardware, regardless */
1013 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
1014 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
1015 printk(KERN_ERR "%s() acquire/forced stop transition "
1016 "failed, res = 0x%x\n", __func__, result);
1017 }
1018 ret = -EIO;
1019 goto out;
1020 } else
1021 dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__);
1022
1023 /* Pause the hardware */
1024 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
1025 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
1026 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
1027 __func__, result);
1028
1029 /* Stop the hardware, regardless */
1030 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
1031 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
1032 printk(KERN_ERR "%s() pause/forced stop transition "
1033 "failed, res = 0x%x\n", __func__, result);
1034 }
1035
1036 ret = -EIO;
1037 goto out;
1038 } else
1039 dprintk(DBGLVL_ENC, "%s() Paused\n", __func__);
1040
1041 /* Start the hardware */
1042 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
1043 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
1044 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
1045 __func__, result);
1046
1047 /* Stop the hardware, regardless */
1048 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
1049 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
1050 printk(KERN_ERR "%s() run/forced stop transition "
1051 "failed, res = 0x%x\n", __func__, result);
1052 }
1053
1054 ret = -EIO;
1055 } else
1056 dprintk(DBGLVL_ENC, "%s() Running\n", __func__);
1057
1058out:
1059 return ret;
1060}
1061
1062static int fops_open(struct file *file)
1063{
1064 struct saa7164_dev *dev;
1065 struct saa7164_port *port;
1066 struct saa7164_encoder_fh *fh;
1067
1068 port = (struct saa7164_port *)video_get_drvdata(video_devdata(file));
1069 if (!port)
1070 return -ENODEV;
1071
1072 dev = port->dev;
1073
1074 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1075
1076 /* allocate + initialize per filehandle data */
1077 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1078 if (NULL == fh)
1079 return -ENOMEM;
1080
1081 file->private_data = fh;
1082 fh->port = port;
1083
1084 return 0;
1085}
1086
1087static int fops_release(struct file *file)
1088{
1089 struct saa7164_encoder_fh *fh = file->private_data;
1090 struct saa7164_port *port = fh->port;
1091 struct saa7164_dev *dev = port->dev;
1092
1093 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1094
1095 /* Shut device down on last close */
1096 if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
1097 if (atomic_dec_return(&port->v4l_reader_count) == 0) {
1098 /* stop mpeg capture then cancel buffers */
1099 saa7164_encoder_stop_streaming(port);
1100 }
1101 }
1102
1103 file->private_data = NULL;
1104 kfree(fh);
1105
1106 return 0;
1107}
1108
1109struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
1110{
1111 struct saa7164_user_buffer *ubuf = NULL;
1112 struct saa7164_dev *dev = port->dev;
1113 u32 crc;
1114
1115 mutex_lock(&port->dmaqueue_lock);
1116 if (!list_empty(&port->list_buf_used.list)) {
1117 ubuf = list_first_entry(&port->list_buf_used.list,
1118 struct saa7164_user_buffer, list);
1119
1120 if (crc_checking) {
1121 crc = crc32(0, ubuf->data, ubuf->actual_size);
1122 if (crc != ubuf->crc) {
1123 printk(KERN_ERR
1124 "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
1125 __func__,
1126 ubuf, ubuf->crc, crc);
1127 }
1128 }
1129
1130 }
1131 mutex_unlock(&port->dmaqueue_lock);
1132
1133 dprintk(DBGLVL_ENC, "%s() returns %p\n", __func__, ubuf);
1134
1135 return ubuf;
1136}
1137
1138static ssize_t fops_read(struct file *file, char __user *buffer,
1139 size_t count, loff_t *pos)
1140{
1141 struct saa7164_encoder_fh *fh = file->private_data;
1142 struct saa7164_port *port = fh->port;
1143 struct saa7164_user_buffer *ubuf = NULL;
1144 struct saa7164_dev *dev = port->dev;
1145 int ret = 0;
1146 int rem, cnt;
1147 u8 *p;
1148
1149 port->last_read_msecs_diff = port->last_read_msecs;
1150 port->last_read_msecs = jiffies_to_msecs(jiffies);
1151 port->last_read_msecs_diff = port->last_read_msecs -
1152 port->last_read_msecs_diff;
1153
1154 saa7164_histogram_update(&port->read_interval,
1155 port->last_read_msecs_diff);
1156
1157 if (*pos) {
1158 printk(KERN_ERR "%s() ESPIPE\n", __func__);
1159 return -ESPIPE;
1160 }
1161
1162 if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1163 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1164
1165 if (saa7164_encoder_initialize(port) < 0) {
1166 printk(KERN_ERR "%s() EINVAL\n", __func__);
1167 return -EINVAL;
1168 }
1169
1170 saa7164_encoder_start_streaming(port);
1171 msleep(200);
1172 }
1173 }
1174
1175 /* blocking wait for buffer */
1176 if ((file->f_flags & O_NONBLOCK) == 0) {
1177 if (wait_event_interruptible(port->wait_read,
1178 saa7164_enc_next_buf(port))) {
1179 printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
1180 return -ERESTARTSYS;
1181 }
1182 }
1183
1184 /* Pull the first buffer from the used list */
1185 ubuf = saa7164_enc_next_buf(port);
1186
1187 while ((count > 0) && ubuf) {
1188
1189 /* set remaining bytes to copy */
1190 rem = ubuf->actual_size - ubuf->pos;
1191 cnt = rem > count ? count : rem;
1192
1193 p = ubuf->data + ubuf->pos;
1194
1195 dprintk(DBGLVL_ENC,
1196 "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
1197 __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
1198
1199 if (copy_to_user(buffer, p, cnt)) {
1200 printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
1201 if (!ret) {
1202 printk(KERN_ERR "%s() EFAULT\n", __func__);
1203 ret = -EFAULT;
1204 }
1205 goto err;
1206 }
1207
1208 ubuf->pos += cnt;
1209 count -= cnt;
1210 buffer += cnt;
1211 ret += cnt;
1212
1213 if (ubuf->pos > ubuf->actual_size)
1214 printk(KERN_ERR "read() pos > actual, huh?\n");
1215
1216 if (ubuf->pos == ubuf->actual_size) {
1217
1218 /* finished with current buffer, take next buffer */
1219
1220 /* Requeue the buffer on the free list */
1221 ubuf->pos = 0;
1222
1223 mutex_lock(&port->dmaqueue_lock);
1224 list_move_tail(&ubuf->list, &port->list_buf_free.list);
1225 mutex_unlock(&port->dmaqueue_lock);
1226
1227 /* Dequeue next */
1228 if ((file->f_flags & O_NONBLOCK) == 0) {
1229 if (wait_event_interruptible(port->wait_read,
1230 saa7164_enc_next_buf(port))) {
1231 break;
1232 }
1233 }
1234 ubuf = saa7164_enc_next_buf(port);
1235 }
1236 }
1237err:
1238 if (!ret && !ubuf)
1239 ret = -EAGAIN;
1240
1241 return ret;
1242}
1243
1244static unsigned int fops_poll(struct file *file, poll_table *wait)
1245{
1246 struct saa7164_encoder_fh *fh =
1247 (struct saa7164_encoder_fh *)file->private_data;
1248 struct saa7164_port *port = fh->port;
1249 unsigned int mask = 0;
1250
1251 port->last_poll_msecs_diff = port->last_poll_msecs;
1252 port->last_poll_msecs = jiffies_to_msecs(jiffies);
1253 port->last_poll_msecs_diff = port->last_poll_msecs -
1254 port->last_poll_msecs_diff;
1255
1256 saa7164_histogram_update(&port->poll_interval,
1257 port->last_poll_msecs_diff);
1258
1259 if (!video_is_registered(port->v4l_device))
1260 return -EIO;
1261
1262 if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1263 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1264 if (saa7164_encoder_initialize(port) < 0)
1265 return -EINVAL;
1266 saa7164_encoder_start_streaming(port);
1267 msleep(200);
1268 }
1269 }
1270
1271 /* blocking wait for buffer */
1272 if ((file->f_flags & O_NONBLOCK) == 0) {
1273 if (wait_event_interruptible(port->wait_read,
1274 saa7164_enc_next_buf(port))) {
1275 return -ERESTARTSYS;
1276 }
1277 }
1278
1279 /* Pull the first buffer from the used list */
1280 if (!list_empty(&port->list_buf_used.list))
1281 mask |= POLLIN | POLLRDNORM;
1282
1283 return mask;
1284}
1285
1286static const struct v4l2_file_operations mpeg_fops = {
1287 .owner = THIS_MODULE,
1288 .open = fops_open,
1289 .release = fops_release,
1290 .read = fops_read,
1291 .poll = fops_poll,
1292 .unlocked_ioctl = video_ioctl2,
1293};
1294
1295int saa7164_g_chip_ident(struct file *file, void *fh,
1296 struct v4l2_dbg_chip_ident *chip)
1297{
1298 struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
1299 struct saa7164_dev *dev = port->dev;
1300 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1301
1302 return 0;
1303}
1304
1305int saa7164_g_register(struct file *file, void *fh,
1306 struct v4l2_dbg_register *reg)
1307{
1308 struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
1309 struct saa7164_dev *dev = port->dev;
1310 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1311
1312 if (!capable(CAP_SYS_ADMIN))
1313 return -EPERM;
1314
1315 return 0;
1316}
1317
1318int saa7164_s_register(struct file *file, void *fh,
1319 struct v4l2_dbg_register *reg)
1320{
1321 struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
1322 struct saa7164_dev *dev = port->dev;
1323 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1324
1325 if (!capable(CAP_SYS_ADMIN))
1326 return -EPERM;
1327
1328 return 0;
1329}
1330
1331static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
1332 .vidioc_s_std = vidioc_s_std,
1333 .vidioc_enum_input = vidioc_enum_input,
1334 .vidioc_g_input = vidioc_g_input,
1335 .vidioc_s_input = vidioc_s_input,
1336 .vidioc_g_tuner = vidioc_g_tuner,
1337 .vidioc_s_tuner = vidioc_s_tuner,
1338 .vidioc_g_frequency = vidioc_g_frequency,
1339 .vidioc_s_frequency = vidioc_s_frequency,
1340 .vidioc_s_ctrl = vidioc_s_ctrl,
1341 .vidioc_g_ctrl = vidioc_g_ctrl,
1342 .vidioc_querycap = vidioc_querycap,
1343 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1344 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1345 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1346 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1347 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
1348 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
1349 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
1350 .vidioc_log_status = vidioc_log_status,
1351 .vidioc_queryctrl = vidioc_queryctrl,
1352 .vidioc_g_chip_ident = saa7164_g_chip_ident,
1353#ifdef CONFIG_VIDEO_ADV_DEBUG
1354 .vidioc_g_register = saa7164_g_register,
1355 .vidioc_s_register = saa7164_s_register,
1356#endif
1357};
1358
1359static struct video_device saa7164_mpeg_template = {
1360 .name = "saa7164",
1361 .fops = &mpeg_fops,
1362 .ioctl_ops = &mpeg_ioctl_ops,
1363 .minor = -1,
1364 .tvnorms = SAA7164_NORMS,
1365 .current_norm = V4L2_STD_NTSC_M,
1366};
1367
1368static struct video_device *saa7164_encoder_alloc(
1369 struct saa7164_port *port,
1370 struct pci_dev *pci,
1371 struct video_device *template,
1372 char *type)
1373{
1374 struct video_device *vfd;
1375 struct saa7164_dev *dev = port->dev;
1376
1377 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1378
1379 vfd = video_device_alloc();
1380 if (NULL == vfd)
1381 return NULL;
1382
1383 *vfd = *template;
1384 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
1385 type, saa7164_boards[dev->board].name);
1386
1387 vfd->parent = &pci->dev;
1388 vfd->release = video_device_release;
1389 return vfd;
1390}
1391
1392int saa7164_encoder_register(struct saa7164_port *port)
1393{
1394 struct saa7164_dev *dev = port->dev;
1395 int result = -ENODEV;
1396
1397 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1398
1399 if (port->type != SAA7164_MPEG_ENCODER)
1400 BUG();
1401
1402 /* Sanity check that the PCI configuration space is active */
1403 if (port->hwcfg.BARLocation == 0) {
1404 printk(KERN_ERR "%s() failed "
1405 "(errno = %d), NO PCI configuration\n",
1406 __func__, result);
1407 result = -ENOMEM;
1408 goto failed;
1409 }
1410
1411 /* Establish encoder defaults here */
1412 /* Set default TV standard */
1413 port->encodernorm = saa7164_tvnorms[0];
1414 port->width = 720;
1415 port->mux_input = 1; /* Composite */
1416 port->video_format = EU_VIDEO_FORMAT_MPEG_2;
1417 port->audio_format = 0;
1418 port->video_resolution = 0;
1419 port->ctl_brightness = 127;
1420 port->ctl_contrast = 66;
1421 port->ctl_hue = 128;
1422 port->ctl_saturation = 62;
1423 port->ctl_sharpness = 8;
1424 port->encoder_params.bitrate = ENCODER_DEF_BITRATE;
1425 port->encoder_params.bitrate_peak = ENCODER_DEF_BITRATE;
1426 port->encoder_params.bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
1427 port->encoder_params.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
1428 port->encoder_params.ctl_mute = 0;
1429 port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
1430 port->encoder_params.refdist = 1;
1431 port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE;
1432
1433 if (port->encodernorm.id & V4L2_STD_525_60)
1434 port->height = 480;
1435 else
1436 port->height = 576;
1437
1438 /* Allocate and register the video device node */
1439 port->v4l_device = saa7164_encoder_alloc(port,
1440 dev->pci, &saa7164_mpeg_template, "mpeg");
1441
1442 if (!port->v4l_device) {
1443 printk(KERN_INFO "%s: can't allocate mpeg device\n",
1444 dev->name);
1445 result = -ENOMEM;
1446 goto failed;
1447 }
1448
1449 video_set_drvdata(port->v4l_device, port);
1450 result = video_register_device(port->v4l_device,
1451 VFL_TYPE_GRABBER, -1);
1452 if (result < 0) {
1453 printk(KERN_INFO "%s: can't register mpeg device\n",
1454 dev->name);
1455 /* TODO: We're going to leak here if we don't dealloc
1456 The buffers above. The unreg function can't deal wit it.
1457 */
1458 goto failed;
1459 }
1460
1461 printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
1462 dev->name, port->v4l_device->num);
1463
1464 /* Configure the hardware defaults */
1465 saa7164_api_set_videomux(port);
1466 saa7164_api_set_usercontrol(port, PU_BRIGHTNESS_CONTROL);
1467 saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
1468 saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
1469 saa7164_api_set_usercontrol(port, PU_SATURATION_CONTROL);
1470 saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
1471 saa7164_api_audio_mute(port, 0);
1472 saa7164_api_set_audio_volume(port, 20);
1473 saa7164_api_set_aspect_ratio(port);
1474
1475 /* Disable audio standard detection, it's buggy */
1476 saa7164_api_set_audio_detection(port, 0);
1477
1478 saa7164_api_set_encoder(port);
1479 saa7164_api_get_encoder(port);
1480
1481 result = 0;
1482failed:
1483 return result;
1484}
1485
1486void saa7164_encoder_unregister(struct saa7164_port *port)
1487{
1488 struct saa7164_dev *dev = port->dev;
1489
1490 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
1491
1492 if (port->type != SAA7164_MPEG_ENCODER)
1493 BUG();
1494
1495 if (port->v4l_device) {
1496 if (port->v4l_device->minor != -1)
1497 video_unregister_device(port->v4l_device);
1498 else
1499 video_device_release(port->v4l_device);
1500
1501 port->v4l_device = NULL;
1502 }
1503
1504 dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
1505}
1506
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
new file mode 100644
index 00000000000..a266bf0169e
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -0,0 +1,613 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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/firmware.h>
23#include <linux/slab.h>
24
25#include "saa7164.h"
26
27#define SAA7164_REV2_FIRMWARE "NXP7164-2010-03-10.1.fw"
28#define SAA7164_REV2_FIRMWARE_SIZE 4019072
29
30#define SAA7164_REV3_FIRMWARE "NXP7164-2010-03-10.1.fw"
31#define SAA7164_REV3_FIRMWARE_SIZE 4019072
32
33struct fw_header {
34 u32 firmwaresize;
35 u32 bslsize;
36 u32 reserved;
37 u32 version;
38};
39
40int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
41{
42 u32 timeout = SAA_DEVICE_TIMEOUT;
43 while ((saa7164_readl(reg) & 0x01) == 0) {
44 timeout -= 10;
45 if (timeout == 0) {
46 printk(KERN_ERR "%s() timeout (no d/l ack)\n",
47 __func__);
48 return -EBUSY;
49 }
50 msleep(100);
51 }
52
53 return 0;
54}
55
56int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
57{
58 u32 timeout = SAA_DEVICE_TIMEOUT;
59 while (saa7164_readl(reg) & 0x01) {
60 timeout -= 10;
61 if (timeout == 0) {
62 printk(KERN_ERR "%s() timeout (no d/l clr)\n",
63 __func__);
64 return -EBUSY;
65 }
66 msleep(100);
67 }
68
69 return 0;
70}
71
72/* TODO: move dlflags into dev-> and change to write/readl/b */
73/* TODO: Excessive levels of debug */
74int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
75 u32 dlflags, u8 *dst, u32 dstsize)
76{
77 u32 reg, timeout, offset;
78 u8 *srcbuf = NULL;
79 int ret;
80
81 u32 dlflag = dlflags;
82 u32 dlflag_ack = dlflag + 4;
83 u32 drflag = dlflag_ack + 4;
84 u32 drflag_ack = drflag + 4;
85 u32 bleflag = drflag_ack + 4;
86
87 dprintk(DBGLVL_FW,
88 "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
89 __func__, src, srcsize, dlflags, dst, dstsize);
90
91 if ((src == NULL) || (dst == NULL)) {
92 ret = -EIO;
93 goto out;
94 }
95
96 srcbuf = kzalloc(4 * 1048576, GFP_KERNEL);
97 if (NULL == srcbuf) {
98 ret = -ENOMEM;
99 goto out;
100 }
101
102 if (srcsize > (4*1048576)) {
103 ret = -ENOMEM;
104 goto out;
105 }
106
107 memcpy(srcbuf, src, srcsize);
108
109 dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag);
110 dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack);
111 dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag);
112 dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack);
113 dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag);
114
115 reg = saa7164_readl(dlflag);
116 dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg);
117 if (reg == 1)
118 dprintk(DBGLVL_FW,
119 "%s() Download flag already set, please reboot\n",
120 __func__);
121
122 /* Indicate download start */
123 saa7164_writel(dlflag, 1);
124 ret = saa7164_dl_wait_ack(dev, dlflag_ack);
125 if (ret < 0)
126 goto out;
127
128 /* Ack download start, then wait for wait */
129 saa7164_writel(dlflag, 0);
130 ret = saa7164_dl_wait_clr(dev, dlflag_ack);
131 if (ret < 0)
132 goto out;
133
134 /* Deal with the raw firmware, in the appropriate chunk size */
135 for (offset = 0; srcsize > dstsize;
136 srcsize -= dstsize, offset += dstsize) {
137
138 dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize);
139 memcpy(dst, srcbuf + offset, dstsize);
140
141 /* Flag the data as ready */
142 saa7164_writel(drflag, 1);
143 ret = saa7164_dl_wait_ack(dev, drflag_ack);
144 if (ret < 0)
145 goto out;
146
147 /* Wait for indication data was received */
148 saa7164_writel(drflag, 0);
149 ret = saa7164_dl_wait_clr(dev, drflag_ack);
150 if (ret < 0)
151 goto out;
152
153 }
154
155 dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize);
156 /* Write last block to the device */
157 memcpy(dst, srcbuf+offset, srcsize);
158
159 /* Flag the data as ready */
160 saa7164_writel(drflag, 1);
161 ret = saa7164_dl_wait_ack(dev, drflag_ack);
162 if (ret < 0)
163 goto out;
164
165 saa7164_writel(drflag, 0);
166 timeout = 0;
167 while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) {
168 if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) {
169 printk(KERN_ERR "%s() image corrupt\n", __func__);
170 ret = -EBUSY;
171 goto out;
172 }
173
174 if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) {
175 printk(KERN_ERR "%s() device memory corrupt\n",
176 __func__);
177 ret = -EBUSY;
178 goto out;
179 }
180
181 msleep(10); /* Checkpatch throws a < 20ms warning */
182 if (timeout++ > 60)
183 break;
184 }
185
186 printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__);
187
188 ret = saa7164_dl_wait_clr(dev, drflag_ack);
189 if (ret < 0)
190 goto out;
191
192 printk(KERN_INFO "%s() Image booted successfully.\n", __func__);
193 ret = 0;
194
195out:
196 kfree(srcbuf);
197 return ret;
198}
199
200/* TODO: Excessive debug */
201/* Load the firmware. Optionally it can be in ROM or newer versions
202 * can be on disk, saving the expense of the ROM hardware. */
203int saa7164_downloadfirmware(struct saa7164_dev *dev)
204{
205 /* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */
206 u32 tmp, filesize, version, err_flags, first_timeout, fwlength;
207 u32 second_timeout, updatebootloader = 1, bootloadersize = 0;
208 const struct firmware *fw = NULL;
209 struct fw_header *hdr, *boothdr = NULL, *fwhdr;
210 u32 bootloaderversion = 0, fwloadersize;
211 u8 *bootloaderoffset = NULL, *fwloaderoffset;
212 char *fwname;
213 int ret;
214
215 dprintk(DBGLVL_FW, "%s()\n", __func__);
216
217 if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) {
218 fwname = SAA7164_REV2_FIRMWARE;
219 fwlength = SAA7164_REV2_FIRMWARE_SIZE;
220 } else {
221 fwname = SAA7164_REV3_FIRMWARE;
222 fwlength = SAA7164_REV3_FIRMWARE_SIZE;
223 }
224
225 version = saa7164_getcurrentfirmwareversion(dev);
226
227 if (version == 0x00) {
228
229 second_timeout = 100;
230 first_timeout = 100;
231 err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
232 dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
233 __func__, err_flags);
234
235 while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
236 dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
237 __func__, err_flags);
238 msleep(10); /* Checkpatch throws a < 20ms warning */
239
240 if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
241 printk(KERN_ERR "%s() firmware corrupt\n",
242 __func__);
243 break;
244 }
245 if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
246 printk(KERN_ERR "%s() device memory corrupt\n",
247 __func__);
248 break;
249 }
250 if (err_flags & SAA_DEVICE_NO_IMAGE) {
251 printk(KERN_ERR "%s() no first image\n",
252 __func__);
253 break;
254 }
255 if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
256 first_timeout -= 10;
257 if (first_timeout == 0) {
258 printk(KERN_ERR
259 "%s() no first image\n",
260 __func__);
261 break;
262 }
263 } else if (err_flags & SAA_DEVICE_IMAGE_LOADING) {
264 second_timeout -= 10;
265 if (second_timeout == 0) {
266 printk(KERN_ERR
267 "%s() FW load time exceeded\n",
268 __func__);
269 break;
270 }
271 } else {
272 second_timeout -= 10;
273 if (second_timeout == 0) {
274 printk(KERN_ERR
275 "%s() Unknown bootloader flags 0x%x\n",
276 __func__, err_flags);
277 break;
278 }
279 }
280
281 err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
282 } /* While != Booting */
283
284 if (err_flags == SAA_DEVICE_IMAGE_BOOTING) {
285 dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n",
286 __func__);
287 first_timeout = SAA_DEVICE_TIMEOUT;
288 second_timeout = 60 * SAA_DEVICE_TIMEOUT;
289 second_timeout = 100;
290
291 err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
292 dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
293 __func__, err_flags);
294 while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
295 dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
296 __func__, err_flags);
297 msleep(10); /* Checkpatch throws a < 20ms warning */
298
299 if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
300 printk(KERN_ERR
301 "%s() firmware corrupt\n",
302 __func__);
303 break;
304 }
305 if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
306 printk(KERN_ERR
307 "%s() device memory corrupt\n",
308 __func__);
309 break;
310 }
311 if (err_flags & SAA_DEVICE_NO_IMAGE) {
312 printk(KERN_ERR "%s() no first image\n",
313 __func__);
314 break;
315 }
316 if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
317 first_timeout -= 10;
318 if (first_timeout == 0) {
319 printk(KERN_ERR
320 "%s() no second image\n",
321 __func__);
322 break;
323 }
324 } else if (err_flags &
325 SAA_DEVICE_IMAGE_LOADING) {
326 second_timeout -= 10;
327 if (second_timeout == 0) {
328 printk(KERN_ERR
329 "%s() FW load time exceeded\n",
330 __func__);
331 break;
332 }
333 } else {
334 second_timeout -= 10;
335 if (second_timeout == 0) {
336 printk(KERN_ERR
337 "%s() Unknown bootloader flags 0x%x\n",
338 __func__, err_flags);
339 break;
340 }
341 }
342
343 err_flags =
344 saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
345 } /* err_flags != SAA_DEVICE_IMAGE_BOOTING */
346
347 dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n",
348 __func__,
349 saa7164_readl(SAA_BOOTLOADERERROR_FLAGS),
350 saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS));
351
352 } /* err_flags == SAA_DEVICE_IMAGE_BOOTING */
353
354 /* It's possible for both firmwares to have booted,
355 * but that doesn't mean they've finished booting yet.
356 */
357 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
358 SAA_DEVICE_IMAGE_BOOTING) &&
359 (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
360 SAA_DEVICE_IMAGE_BOOTING)) {
361
362
363 dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n",
364 __func__);
365
366 first_timeout = SAA_DEVICE_TIMEOUT;
367 while (first_timeout) {
368 msleep(10); /* Checkpatch throws a < 20ms warning */
369
370 version =
371 saa7164_getcurrentfirmwareversion(dev);
372 if (version) {
373 dprintk(DBGLVL_FW,
374 "%s() All f/w loaded successfully\n",
375 __func__);
376 break;
377 } else {
378 first_timeout -= 10;
379 if (first_timeout == 0) {
380 printk(KERN_ERR
381 "%s() FW did not boot\n",
382 __func__);
383 break;
384 }
385 }
386 }
387 }
388 version = saa7164_getcurrentfirmwareversion(dev);
389 } /* version == 0 */
390
391 /* Has the firmware really booted? */
392 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
393 SAA_DEVICE_IMAGE_BOOTING) &&
394 (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
395 SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) {
396
397 printk(KERN_ERR
398 "%s() The firmware hung, probably bad firmware\n",
399 __func__);
400
401 /* Tell the second stage loader we have a deadlock */
402 saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET,
403 SAA_DEVICE_DEADLOCK_DETECTED);
404
405 saa7164_getfirmwarestatus(dev);
406
407 return -ENOMEM;
408 }
409
410 dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n",
411 (version & 0x0000fc00) >> 10,
412 (version & 0x000003e0) >> 5,
413 (version & 0x0000001f),
414 (version & 0xffff0000) >> 16);
415
416 /* Load the firmwware from the disk if required */
417 if (version == 0) {
418
419 printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n",
420 __func__, fwname);
421
422 ret = request_firmware(&fw, fwname, &dev->pci->dev);
423 if (ret) {
424 printk(KERN_ERR "%s() Upload failed. "
425 "(file not found?)\n", __func__);
426 return -ENOMEM;
427 }
428
429 printk(KERN_INFO "%s() firmware read %Zu bytes.\n",
430 __func__, fw->size);
431
432 if (fw->size != fwlength) {
433 printk(KERN_ERR "xc5000: firmware incorrect size\n");
434 ret = -ENOMEM;
435 goto out;
436 }
437
438 printk(KERN_INFO "%s() firmware loaded.\n", __func__);
439
440 hdr = (struct fw_header *)fw->data;
441 printk(KERN_INFO "Firmware file header part 1:\n");
442 printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize);
443 printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize);
444 printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved);
445 printk(KERN_INFO " .Version = 0x%x\n", hdr->version);
446
447 /* Retrieve bootloader if reqd */
448 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0))
449 /* Second bootloader in the firmware file */
450 filesize = hdr->reserved * 16;
451 else
452 filesize = (hdr->firmwaresize + hdr->bslsize) *
453 16 + sizeof(struct fw_header);
454
455 printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n",
456 __func__, filesize);
457
458 /* Get bootloader (if reqd) and firmware header */
459 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
460 /* Second boot loader is required */
461
462 /* Get the loader header */
463 boothdr = (struct fw_header *)(fw->data +
464 sizeof(struct fw_header));
465
466 bootloaderversion =
467 saa7164_readl(SAA_DEVICE_2ND_VERSION);
468 dprintk(DBGLVL_FW, "Onboard BootLoader:\n");
469 dprintk(DBGLVL_FW, "->Flag 0x%x\n",
470 saa7164_readl(SAA_BOOTLOADERERROR_FLAGS));
471 dprintk(DBGLVL_FW, "->Ack 0x%x\n",
472 saa7164_readl(SAA_DATAREADY_FLAG_ACK));
473 dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version);
474 dprintk(DBGLVL_FW, "->Loader Version 0x%x\n",
475 bootloaderversion);
476
477 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
478 0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK)
479 == 0x00) && (version == 0x00)) {
480
481 dprintk(DBGLVL_FW, "BootLoader version in "
482 "rom %d.%d.%d.%d\n",
483 (bootloaderversion & 0x0000fc00) >> 10,
484 (bootloaderversion & 0x000003e0) >> 5,
485 (bootloaderversion & 0x0000001f),
486 (bootloaderversion & 0xffff0000) >> 16
487 );
488 dprintk(DBGLVL_FW, "BootLoader version "
489 "in file %d.%d.%d.%d\n",
490 (boothdr->version & 0x0000fc00) >> 10,
491 (boothdr->version & 0x000003e0) >> 5,
492 (boothdr->version & 0x0000001f),
493 (boothdr->version & 0xffff0000) >> 16
494 );
495
496 if (bootloaderversion == boothdr->version)
497 updatebootloader = 0;
498 }
499
500 /* Calculate offset to firmware header */
501 tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 +
502 (sizeof(struct fw_header) +
503 sizeof(struct fw_header));
504
505 fwhdr = (struct fw_header *)(fw->data+tmp);
506 } else {
507 /* No second boot loader */
508 fwhdr = hdr;
509 }
510
511 dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n",
512 (fwhdr->version & 0x0000fc00) >> 10,
513 (fwhdr->version & 0x000003e0) >> 5,
514 (fwhdr->version & 0x0000001f),
515 (fwhdr->version & 0xffff0000) >> 16
516 );
517
518 if (version == fwhdr->version) {
519 /* No download, firmware already on board */
520 ret = 0;
521 goto out;
522 }
523
524 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
525 if (updatebootloader) {
526 /* Get ready to upload the bootloader */
527 bootloadersize = (boothdr->firmwaresize +
528 boothdr->bslsize) * 16 +
529 sizeof(struct fw_header);
530
531 bootloaderoffset = (u8 *)(fw->data +
532 sizeof(struct fw_header));
533
534 dprintk(DBGLVL_FW, "bootloader d/l starts.\n");
535 printk(KERN_INFO "%s() FirmwareSize = 0x%x\n",
536 __func__, boothdr->firmwaresize);
537 printk(KERN_INFO "%s() BSLSize = 0x%x\n",
538 __func__, boothdr->bslsize);
539 printk(KERN_INFO "%s() Reserved = 0x%x\n",
540 __func__, boothdr->reserved);
541 printk(KERN_INFO "%s() Version = 0x%x\n",
542 __func__, boothdr->version);
543 ret = saa7164_downloadimage(
544 dev,
545 bootloaderoffset,
546 bootloadersize,
547 SAA_DOWNLOAD_FLAGS,
548 dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
549 SAA_DEVICE_BUFFERBLOCKSIZE);
550 if (ret < 0) {
551 printk(KERN_ERR
552 "bootloader d/l has failed\n");
553 goto out;
554 }
555 dprintk(DBGLVL_FW,
556 "bootloader download complete.\n");
557
558 }
559
560 printk(KERN_ERR "starting firmware download(2)\n");
561 bootloadersize = (boothdr->firmwaresize +
562 boothdr->bslsize) * 16 +
563 sizeof(struct fw_header);
564
565 bootloaderoffset =
566 (u8 *)(fw->data + sizeof(struct fw_header));
567
568 fwloaderoffset = bootloaderoffset + bootloadersize;
569
570 /* TODO: fix this bounds overrun here with old f/ws */
571 fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) *
572 16 + sizeof(struct fw_header);
573
574 ret = saa7164_downloadimage(
575 dev,
576 fwloaderoffset,
577 fwloadersize,
578 SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET,
579 dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET,
580 SAA_DEVICE_2ND_BUFFERBLOCKSIZE);
581 if (ret < 0) {
582 printk(KERN_ERR "firmware download failed\n");
583 goto out;
584 }
585 printk(KERN_ERR "firmware download complete.\n");
586
587 } else {
588
589 /* No bootloader update reqd, download firmware only */
590 printk(KERN_ERR "starting firmware download(3)\n");
591
592 ret = saa7164_downloadimage(
593 dev,
594 (u8 *)fw->data,
595 fw->size,
596 SAA_DOWNLOAD_FLAGS,
597 dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
598 SAA_DEVICE_BUFFERBLOCKSIZE);
599 if (ret < 0) {
600 printk(KERN_ERR "firmware download failed\n");
601 goto out;
602 }
603 printk(KERN_ERR "firmware download complete.\n");
604 }
605 }
606
607 dev->firmwareloaded = 1;
608 ret = 0;
609
610out:
611 release_firmware(fw);
612 return ret;
613}
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c
new file mode 100644
index 00000000000..26148f76cba
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-i2c.c
@@ -0,0 +1,141 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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 <linux/io.h>
27
28#include "saa7164.h"
29
30static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
31{
32 struct saa7164_i2c *bus = i2c_adap->algo_data;
33 struct saa7164_dev *dev = bus->dev;
34 int i, retval = 0;
35
36 dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num);
37
38 for (i = 0 ; i < num; i++) {
39 dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
40 __func__, num, msgs[i].addr, msgs[i].len);
41 if (msgs[i].flags & I2C_M_RD) {
42 /* Unsupported - Yet*/
43 printk(KERN_ERR "%s() Unsupported - Yet\n", __func__);
44 continue;
45 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
46 msgs[i].addr == msgs[i + 1].addr) {
47 /* write then read from same address */
48
49 retval = saa7164_api_i2c_read(bus, msgs[i].addr,
50 msgs[i].len, msgs[i].buf,
51 msgs[i+1].len, msgs[i+1].buf
52 );
53
54 i++;
55
56 if (retval < 0)
57 goto err;
58 } else {
59 /* write */
60 retval = saa7164_api_i2c_write(bus, msgs[i].addr,
61 msgs[i].len, msgs[i].buf);
62 }
63 if (retval < 0)
64 goto err;
65 }
66 return num;
67
68err:
69 return retval;
70}
71
72void saa7164_call_i2c_clients(struct saa7164_i2c *bus, unsigned int cmd,
73 void *arg)
74{
75 if (bus->i2c_rc != 0)
76 return;
77
78 i2c_clients_command(&bus->i2c_adap, cmd, arg);
79}
80
81static u32 saa7164_functionality(struct i2c_adapter *adap)
82{
83 return I2C_FUNC_I2C;
84}
85
86static struct i2c_algorithm saa7164_i2c_algo_template = {
87 .master_xfer = i2c_xfer,
88 .functionality = saa7164_functionality,
89};
90
91/* ----------------------------------------------------------------------- */
92
93static struct i2c_adapter saa7164_i2c_adap_template = {
94 .name = "saa7164",
95 .owner = THIS_MODULE,
96 .algo = &saa7164_i2c_algo_template,
97};
98
99static struct i2c_client saa7164_i2c_client_template = {
100 .name = "saa7164 internal",
101};
102
103int saa7164_i2c_register(struct saa7164_i2c *bus)
104{
105 struct saa7164_dev *dev = bus->dev;
106
107 dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr);
108
109 memcpy(&bus->i2c_adap, &saa7164_i2c_adap_template,
110 sizeof(bus->i2c_adap));
111
112 memcpy(&bus->i2c_algo, &saa7164_i2c_algo_template,
113 sizeof(bus->i2c_algo));
114
115 memcpy(&bus->i2c_client, &saa7164_i2c_client_template,
116 sizeof(bus->i2c_client));
117
118 bus->i2c_adap.dev.parent = &dev->pci->dev;
119
120 strlcpy(bus->i2c_adap.name, bus->dev->name,
121 sizeof(bus->i2c_adap.name));
122
123 bus->i2c_algo.data = bus;
124 bus->i2c_adap.algo_data = bus;
125 i2c_set_adapdata(&bus->i2c_adap, bus);
126 i2c_add_adapter(&bus->i2c_adap);
127
128 bus->i2c_client.adapter = &bus->i2c_adap;
129
130 if (0 != bus->i2c_rc)
131 printk(KERN_ERR "%s: i2c bus %d register FAILED\n",
132 dev->name, bus->nr);
133
134 return bus->i2c_rc;
135}
136
137int saa7164_i2c_unregister(struct saa7164_i2c *bus)
138{
139 i2c_del_adapter(&bus->i2c_adap);
140 return 0;
141}
diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/video/saa7164/saa7164-reg.h
new file mode 100644
index 00000000000..2bbf81583d3
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-reg.h
@@ -0,0 +1,219 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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/* TODO: Retest the driver with errors expressed as negatives */
23
24/* Result codes */
25#define SAA_OK 0
26#define SAA_ERR_BAD_PARAMETER 0x09
27#define SAA_ERR_NO_RESOURCES 0x0c
28#define SAA_ERR_NOT_SUPPORTED 0x13
29#define SAA_ERR_BUSY 0x15
30#define SAA_ERR_READ 0x17
31#define SAA_ERR_TIMEOUT 0x1f
32#define SAA_ERR_OVERFLOW 0x20
33#define SAA_ERR_EMPTY 0x22
34#define SAA_ERR_NOT_STARTED 0x23
35#define SAA_ERR_ALREADY_STARTED 0x24
36#define SAA_ERR_NOT_STOPPED 0x25
37#define SAA_ERR_ALREADY_STOPPED 0x26
38#define SAA_ERR_INVALID_COMMAND 0x3e
39#define SAA_ERR_NULL_PACKET 0x59
40
41/* Errors and flags from the silicon */
42#define PVC_ERRORCODE_UNKNOWN 0x00
43#define PVC_ERRORCODE_INVALID_COMMAND 0x01
44#define PVC_ERRORCODE_INVALID_CONTROL 0x02
45#define PVC_ERRORCODE_INVALID_DATA 0x03
46#define PVC_ERRORCODE_TIMEOUT 0x04
47#define PVC_ERRORCODE_NAK 0x05
48#define PVC_RESPONSEFLAG_ERROR 0x01
49#define PVC_RESPONSEFLAG_OVERFLOW 0x02
50#define PVC_RESPONSEFLAG_RESET 0x04
51#define PVC_RESPONSEFLAG_INTERFACE 0x08
52#define PVC_RESPONSEFLAG_CONTINUED 0x10
53#define PVC_CMDFLAG_INTERRUPT 0x02
54#define PVC_CMDFLAG_INTERFACE 0x04
55#define PVC_CMDFLAG_SERIALIZE 0x08
56#define PVC_CMDFLAG_CONTINUE 0x10
57
58/* Silicon Commands */
59#define GET_DESCRIPTORS_CONTROL 0x01
60#define GET_STRING_CONTROL 0x03
61#define GET_LANGUAGE_CONTROL 0x05
62#define SET_POWER_CONTROL 0x07
63#define GET_FW_STATUS_CONTROL 0x08
64#define GET_FW_VERSION_CONTROL 0x09
65#define SET_DEBUG_LEVEL_CONTROL 0x0B
66#define GET_DEBUG_DATA_CONTROL 0x0C
67#define GET_PRODUCTION_INFO_CONTROL 0x0D
68
69/* cmd defines */
70#define SAA_CMDFLAG_CONTINUE 0x10
71#define SAA_CMD_MAX_MSG_UNITS 256
72
73/* Some defines */
74#define SAA_BUS_TIMEOUT 50
75#define SAA_DEVICE_TIMEOUT 5000
76#define SAA_DEVICE_MAXREQUESTSIZE 256
77
78/* Register addresses */
79#define SAA_DEVICE_VERSION 0x30
80#define SAA_DOWNLOAD_FLAGS 0x34
81#define SAA_DOWNLOAD_FLAG 0x34
82#define SAA_DOWNLOAD_FLAG_ACK 0x38
83#define SAA_DATAREADY_FLAG 0x3C
84#define SAA_DATAREADY_FLAG_ACK 0x40
85
86/* Boot loader register and bit definitions */
87#define SAA_BOOTLOADERERROR_FLAGS 0x44
88#define SAA_DEVICE_IMAGE_SEARCHING 0x01
89#define SAA_DEVICE_IMAGE_LOADING 0x02
90#define SAA_DEVICE_IMAGE_BOOTING 0x03
91#define SAA_DEVICE_IMAGE_CORRUPT 0x04
92#define SAA_DEVICE_MEMORY_CORRUPT 0x08
93#define SAA_DEVICE_NO_IMAGE 0x10
94
95/* Register addresses */
96#define SAA_DEVICE_2ND_VERSION 0x50
97#define SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET 0x54
98
99/* Register addresses */
100#define SAA_SECONDSTAGEERROR_FLAGS 0x64
101
102/* Bootloader regs and flags */
103#define SAA_DEVICE_DEADLOCK_DETECTED_OFFSET 0x6C
104#define SAA_DEVICE_DEADLOCK_DETECTED 0xDEADDEAD
105
106/* Basic firmware status registers */
107#define SAA_DEVICE_SYSINIT_STATUS_OFFSET 0x70
108#define SAA_DEVICE_SYSINIT_STATUS 0x70
109#define SAA_DEVICE_SYSINIT_MODE 0x74
110#define SAA_DEVICE_SYSINIT_SPEC 0x78
111#define SAA_DEVICE_SYSINIT_INST 0x7C
112#define SAA_DEVICE_SYSINIT_CPULOAD 0x80
113#define SAA_DEVICE_SYSINIT_REMAINHEAP 0x84
114
115#define SAA_DEVICE_DOWNLOAD_OFFSET 0x1000
116#define SAA_DEVICE_BUFFERBLOCKSIZE 0x1000
117
118#define SAA_DEVICE_2ND_BUFFERBLOCKSIZE 0x100000
119#define SAA_DEVICE_2ND_DOWNLOAD_OFFSET 0x200000
120
121/* Descriptors */
122#define CS_INTERFACE 0x24
123
124/* Descriptor subtypes */
125#define VC_INPUT_TERMINAL 0x02
126#define VC_OUTPUT_TERMINAL 0x03
127#define VC_SELECTOR_UNIT 0x04
128#define VC_PROCESSING_UNIT 0x05
129#define FEATURE_UNIT 0x06
130#define TUNER_UNIT 0x09
131#define ENCODER_UNIT 0x0A
132#define EXTENSION_UNIT 0x0B
133#define VC_TUNER_PATH 0xF0
134#define PVC_HARDWARE_DESCRIPTOR 0xF1
135#define PVC_INTERFACE_DESCRIPTOR 0xF2
136#define PVC_INFRARED_UNIT 0xF3
137#define DRM_UNIT 0xF4
138#define GENERAL_REQUEST 0xF5
139
140/* Format Types */
141#define VS_FORMAT_TYPE 0x02
142#define VS_FORMAT_TYPE_I 0x01
143#define VS_FORMAT_UNCOMPRESSED 0x04
144#define VS_FRAME_UNCOMPRESSED 0x05
145#define VS_FORMAT_MPEG2PS 0x09
146#define VS_FORMAT_MPEG2TS 0x0A
147#define VS_FORMAT_MPEG4SL 0x0B
148#define VS_FORMAT_WM9 0x0C
149#define VS_FORMAT_DIVX 0x0D
150#define VS_FORMAT_VBI 0x0E
151#define VS_FORMAT_RDS 0x0F
152
153/* Device extension commands */
154#define EXU_REGISTER_ACCESS_CONTROL 0x00
155#define EXU_GPIO_CONTROL 0x01
156#define EXU_GPIO_GROUP_CONTROL 0x02
157#define EXU_INTERRUPT_CONTROL 0x03
158
159/* State Transition and args */
160#define SAA_PROBE_CONTROL 0x01
161#define SAA_COMMIT_CONTROL 0x02
162#define SAA_STATE_CONTROL 0x03
163#define SAA_DMASTATE_STOP 0x00
164#define SAA_DMASTATE_ACQUIRE 0x01
165#define SAA_DMASTATE_PAUSE 0x02
166#define SAA_DMASTATE_RUN 0x03
167
168/* A/V Mux Input Selector */
169#define SU_INPUT_SELECT_CONTROL 0x01
170
171/* Encoder Profiles */
172#define EU_PROFILE_PS_DVD 0x06
173#define EU_PROFILE_TS_HQ 0x09
174#define EU_VIDEO_FORMAT_MPEG_2 0x02
175
176/* Tuner */
177#define TU_AUDIO_MODE_CONTROL 0x17
178
179/* Video Formats */
180#define TU_STANDARD_CONTROL 0x00
181#define TU_STANDARD_AUTO_CONTROL 0x01
182#define TU_STANDARD_NONE 0x00
183#define TU_STANDARD_NTSC_M 0x01
184#define TU_STANDARD_PAL_I 0x08
185#define TU_STANDARD_MANUAL 0x00
186#define TU_STANDARD_AUTO 0x01
187
188/* Video Controls */
189#define PU_BRIGHTNESS_CONTROL 0x02
190#define PU_CONTRAST_CONTROL 0x03
191#define PU_HUE_CONTROL 0x06
192#define PU_SATURATION_CONTROL 0x07
193#define PU_SHARPNESS_CONTROL 0x08
194
195/* Audio Controls */
196#define MUTE_CONTROL 0x01
197#define VOLUME_CONTROL 0x02
198#define AUDIO_DEFAULT_CONTROL 0x0D
199
200/* Default Volume Levels */
201#define TMHW_LEV_ADJ_DECLEV_DEFAULT 0x00
202#define TMHW_LEV_ADJ_MONOLEV_DEFAULT 0x00
203#define TMHW_LEV_ADJ_NICLEV_DEFAULT 0x00
204#define TMHW_LEV_ADJ_SAPLEV_DEFAULT 0x00
205#define TMHW_LEV_ADJ_ADCLEV_DEFAULT 0x00
206
207/* Encoder Related Commands */
208#define EU_PROFILE_CONTROL 0x00
209#define EU_VIDEO_FORMAT_CONTROL 0x01
210#define EU_VIDEO_BIT_RATE_CONTROL 0x02
211#define EU_VIDEO_RESOLUTION_CONTROL 0x03
212#define EU_VIDEO_GOP_STRUCTURE_CONTROL 0x04
213#define EU_VIDEO_INPUT_ASPECT_CONTROL 0x0A
214#define EU_AUDIO_FORMAT_CONTROL 0x0C
215#define EU_AUDIO_BIT_RATE_CONTROL 0x0D
216
217/* Firmware Debugging */
218#define SET_DEBUG_LEVEL_CONTROL 0x0B
219#define GET_DEBUG_DATA_CONTROL 0x0C
diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h
new file mode 100644
index 00000000000..1d2140a3eb3
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-types.h
@@ -0,0 +1,442 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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/* TODO: Cleanup and shorten the namespace */
23
24/* Some structues are passed directly to/from the firmware and
25 * have strict alignment requirements. This is one of them.
26 */
27struct tmComResHWDescr {
28 u8 bLength;
29 u8 bDescriptorType;
30 u8 bDescriptorSubtype;
31 u16 bcdSpecVersion;
32 u32 dwClockFrequency;
33 u32 dwClockUpdateRes;
34 u8 bCapabilities;
35 u32 dwDeviceRegistersLocation;
36 u32 dwHostMemoryRegion;
37 u32 dwHostMemoryRegionSize;
38 u32 dwHostHibernatMemRegion;
39 u32 dwHostHibernatMemRegionSize;
40} __attribute__((packed));
41
42/* This is DWORD aligned on windows but I can't find the right
43 * gcc syntax to match the binary data from the device.
44 * I've manually padded with Reserved[3] bytes to match the hardware,
45 * but this could break if GCC decies to pack in a different way.
46 */
47struct tmComResInterfaceDescr {
48 u8 bLength;
49 u8 bDescriptorType;
50 u8 bDescriptorSubtype;
51 u8 bFlags;
52 u8 bInterfaceType;
53 u8 bInterfaceId;
54 u8 bBaseInterface;
55 u8 bInterruptId;
56 u8 bDebugInterruptId;
57 u8 BARLocation;
58 u8 Reserved[3];
59};
60
61struct tmComResBusDescr {
62 u64 CommandRing;
63 u64 ResponseRing;
64 u32 CommandWrite;
65 u32 CommandRead;
66 u32 ResponseWrite;
67 u32 ResponseRead;
68};
69
70enum tmBusType {
71 NONE = 0,
72 TYPE_BUS_PCI = 1,
73 TYPE_BUS_PCIe = 2,
74 TYPE_BUS_USB = 3,
75 TYPE_BUS_I2C = 4
76};
77
78struct tmComResBusInfo {
79 enum tmBusType Type;
80 u16 m_wMaxReqSize;
81 u8 *m_pdwSetRing;
82 u32 m_dwSizeSetRing;
83 u8 *m_pdwGetRing;
84 u32 m_dwSizeGetRing;
85 u32 m_dwSetWritePos;
86 u32 m_dwSetReadPos;
87 u32 m_dwGetWritePos;
88 u32 m_dwGetReadPos;
89
90 /* All access is protected */
91 struct mutex lock;
92
93};
94
95struct tmComResInfo {
96 u8 id;
97 u8 flags;
98 u16 size;
99 u32 command;
100 u16 controlselector;
101 u8 seqno;
102} __attribute__((packed));
103
104enum tmComResCmd {
105 SET_CUR = 0x01,
106 GET_CUR = 0x81,
107 GET_MIN = 0x82,
108 GET_MAX = 0x83,
109 GET_RES = 0x84,
110 GET_LEN = 0x85,
111 GET_INFO = 0x86,
112 GET_DEF = 0x87
113};
114
115struct cmd {
116 u8 seqno;
117 u32 inuse;
118 u32 timeout;
119 u32 signalled;
120 struct mutex lock;
121 wait_queue_head_t wait;
122};
123
124struct tmDescriptor {
125 u32 pathid;
126 u32 size;
127 void *descriptor;
128};
129
130struct tmComResDescrHeader {
131 u8 len;
132 u8 type;
133 u8 subtype;
134 u8 unitid;
135} __attribute__((packed));
136
137struct tmComResExtDevDescrHeader {
138 u8 len;
139 u8 type;
140 u8 subtype;
141 u8 unitid;
142 u32 devicetype;
143 u16 deviceid;
144 u32 numgpiopins;
145 u8 numgpiogroups;
146 u8 controlsize;
147} __attribute__((packed));
148
149struct tmComResGPIO {
150 u32 pin;
151 u8 state;
152} __attribute__((packed));
153
154struct tmComResPathDescrHeader {
155 u8 len;
156 u8 type;
157 u8 subtype;
158 u8 pathid;
159} __attribute__((packed));
160
161/* terminaltype */
162enum tmComResTermType {
163 ITT_ANTENNA = 0x0203,
164 LINE_CONNECTOR = 0x0603,
165 SPDIF_CONNECTOR = 0x0605,
166 COMPOSITE_CONNECTOR = 0x0401,
167 SVIDEO_CONNECTOR = 0x0402,
168 COMPONENT_CONNECTOR = 0x0403,
169 STANDARD_DMA = 0xF101
170};
171
172struct tmComResAntTermDescrHeader {
173 u8 len;
174 u8 type;
175 u8 subtype;
176 u8 terminalid;
177 u16 terminaltype;
178 u8 assocterminal;
179 u8 iterminal;
180 u8 controlsize;
181} __attribute__((packed));
182
183struct tmComResTunerDescrHeader {
184 u8 len;
185 u8 type;
186 u8 subtype;
187 u8 unitid;
188 u8 sourceid;
189 u8 iunit;
190 u32 tuningstandards;
191 u8 controlsize;
192 u32 controls;
193} __attribute__((packed));
194
195enum tmBufferFlag {
196 /* the buffer does not contain any valid data */
197 TM_BUFFER_FLAG_EMPTY,
198
199 /* the buffer is filled with valid data */
200 TM_BUFFER_FLAG_DONE,
201
202 /* the buffer is the dummy buffer - TODO??? */
203 TM_BUFFER_FLAG_DUMMY_BUFFER
204};
205
206struct tmBuffer {
207 u64 *pagetablevirt;
208 u64 pagetablephys;
209 u16 offset;
210 u8 *context;
211 u64 timestamp;
212 enum tmBufferFlag BufferFlag;
213 u32 lostbuffers;
214 u32 validbuffers;
215 u64 *dummypagevirt;
216 u64 dummypagephys;
217 u64 *addressvirt;
218};
219
220struct tmHWStreamParameters {
221 u32 bitspersample;
222 u32 samplesperline;
223 u32 numberoflines;
224 u32 pitch;
225 u32 linethreshold;
226 u64 **pagetablelistvirt;
227 u64 *pagetablelistphys;
228 u32 numpagetables;
229 u32 numpagetableentries;
230};
231
232struct tmStreamParameters {
233 struct tmHWStreamParameters HWStreamParameters;
234 u64 qwDummyPageTablePhys;
235 u64 *pDummyPageTableVirt;
236};
237
238struct tmComResDMATermDescrHeader {
239 u8 len;
240 u8 type;
241 u8 subtyle;
242 u8 unitid;
243 u16 terminaltype;
244 u8 assocterminal;
245 u8 sourceid;
246 u8 iterminal;
247 u32 BARLocation;
248 u8 flags;
249 u8 interruptid;
250 u8 buffercount;
251 u8 metadatasize;
252 u8 numformats;
253 u8 controlsize;
254} __attribute__((packed));
255
256/*
257 *
258 * Description:
259 * This is the transport stream format header.
260 *
261 * Settings:
262 * bLength - The size of this descriptor in bytes.
263 * bDescriptorType - CS_INTERFACE.
264 * bDescriptorSubtype - VS_FORMAT_MPEG2TS descriptor subtype.
265 * bFormatIndex - A non-zero constant that uniquely identifies the
266 * format.
267 * bDataOffset - Offset to TSP packet within MPEG-2 TS transport
268 * stride, in bytes.
269 * bPacketLength - Length of TSP packet, in bytes (typically 188).
270 * bStrideLength - Length of MPEG-2 TS transport stride.
271 * guidStrideFormat - A Globally Unique Identifier indicating the
272 * format of the stride data (if any). Set to zeros
273 * if there is no Stride Data, or if the Stride
274 * Data is to be ignored by the application.
275 *
276 */
277struct tmComResTSFormatDescrHeader {
278 u8 len;
279 u8 type;
280 u8 subtype;
281 u8 bFormatIndex;
282 u8 bDataOffset;
283 u8 bPacketLength;
284 u8 bStrideLength;
285 u8 guidStrideFormat[16];
286} __attribute__((packed));
287
288/* Encoder related structures */
289
290/* A/V Mux Selector */
291struct tmComResSelDescrHeader {
292 u8 len;
293 u8 type;
294 u8 subtype;
295 u8 unitid;
296 u8 nrinpins;
297 u8 sourceid;
298} __attribute__((packed));
299
300/* A/V Audio processor definitions */
301struct tmComResProcDescrHeader {
302 u8 len;
303 u8 type;
304 u8 subtype;
305 u8 unitid;
306 u8 sourceid;
307 u16 wreserved;
308 u8 controlsize;
309} __attribute__((packed));
310
311/* Video bitrate control message */
312#define EU_VIDEO_BIT_RATE_MODE_CONSTANT (0)
313#define EU_VIDEO_BIT_RATE_MODE_VARIABLE_AVERAGE (1)
314#define EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK (2)
315struct tmComResEncVideoBitRate {
316 u8 ucVideoBitRateMode;
317 u32 dwVideoBitRate;
318 u32 dwVideoBitRatePeak;
319} __attribute__((packed));
320
321/* Video Encoder Aspect Ratio message */
322struct tmComResEncVideoInputAspectRatio {
323 u8 width;
324 u8 height;
325} __attribute__((packed));
326
327/* Video Encoder GOP IBP message */
328/* 1. IPPPPPPPPPPPPPP */
329/* 2. IBPBPBPBPBPBPBP */
330/* 3. IBBPBBPBBPBBP */
331#define SAA7164_ENCODER_DEFAULT_GOP_DIST (1)
332#define SAA7164_ENCODER_DEFAULT_GOP_SIZE (15)
333struct tmComResEncVideoGopStructure {
334 u8 ucGOPSize; /* GOP Size 12, 15 */
335 u8 ucRefFrameDist; /* Reference Frame Distance */
336} __attribute__((packed));
337
338/* Encoder processor definition */
339struct tmComResEncoderDescrHeader {
340 u8 len;
341 u8 type;
342 u8 subtype;
343 u8 unitid;
344 u8 vsourceid;
345 u8 asourceid;
346 u8 iunit;
347 u32 dwmControlCap;
348 u32 dwmProfileCap;
349 u32 dwmVidFormatCap;
350 u8 bmVidBitrateCap;
351 u16 wmVidResolutionsCap;
352 u16 wmVidFrmRateCap;
353 u32 dwmAudFormatCap;
354 u8 bmAudBitrateCap;
355} __attribute__((packed));
356
357/* Audio processor definition */
358struct tmComResAFeatureDescrHeader {
359 u8 len;
360 u8 type;
361 u8 subtype;
362 u8 unitid;
363 u8 sourceid;
364 u8 controlsize;
365} __attribute__((packed));
366
367/* Audio control messages */
368struct tmComResAudioDefaults {
369 u8 ucDecoderLevel;
370 u8 ucDecoderFM_Level;
371 u8 ucMonoLevel;
372 u8 ucNICAM_Level;
373 u8 ucSAP_Level;
374 u8 ucADC_Level;
375} __attribute__((packed));
376
377/* Audio bitrate control message */
378struct tmComResEncAudioBitRate {
379 u8 ucAudioBitRateMode;
380 u32 dwAudioBitRate;
381 u32 dwAudioBitRatePeak;
382} __attribute__((packed));
383
384/* Tuner / AV Decoder messages */
385struct tmComResTunerStandard {
386 u8 std;
387 u32 country;
388} __attribute__((packed));
389
390struct tmComResTunerStandardAuto {
391 u8 mode;
392} __attribute__((packed));
393
394/* EEPROM definition for PS stream types */
395struct tmComResPSFormatDescrHeader {
396 u8 len;
397 u8 type;
398 u8 subtype;
399 u8 bFormatIndex;
400 u16 wPacketLength;
401 u16 wPackLength;
402 u8 bPackDataType;
403} __attribute__((packed));
404
405/* VBI control structure */
406struct tmComResVBIFormatDescrHeader {
407 u8 len;
408 u8 type;
409 u8 subtype; /* VS_FORMAT_VBI */
410 u8 bFormatIndex;
411 u32 VideoStandard; /* See KS_AnalogVideoStandard, NTSC = 1 */
412 u8 StartLine; /* NTSC Start = 10 */
413 u8 EndLine; /* NTSC = 21 */
414 u8 FieldRate; /* 60 for NTSC */
415 u8 bNumLines; /* Unused - scheduled for removal */
416} __attribute__((packed));
417
418struct tmComResProbeCommit {
419 u16 bmHint;
420 u8 bFormatIndex;
421 u8 bFrameIndex;
422} __attribute__((packed));
423
424struct tmComResDebugSetLevel {
425 u32 dwDebugLevel;
426} __attribute__((packed));
427
428struct tmComResDebugGetData {
429 u32 dwResult;
430 u8 ucDebugData[256];
431} __attribute__((packed));
432
433struct tmFwInfoStruct {
434 u32 status;
435 u32 mode;
436 u32 devicespec;
437 u32 deviceinst;
438 u32 CPULoad;
439 u32 RemainHeap;
440 u32 CPUClock;
441 u32 RAMSpeed;
442} __attribute__((packed));
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
new file mode 100644
index 00000000000..e2e03415871
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-vbi.c
@@ -0,0 +1,1380 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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 "saa7164.h"
23
24static struct saa7164_tvnorm saa7164_tvnorms[] = {
25 {
26 .name = "NTSC-M",
27 .id = V4L2_STD_NTSC_M,
28 }, {
29 .name = "NTSC-JP",
30 .id = V4L2_STD_NTSC_M_JP,
31 }
32};
33
34static const u32 saa7164_v4l2_ctrls[] = {
35 0
36};
37
38/* Take the encoder configuration from the port struct and
39 * flush it to the hardware.
40 */
41static void saa7164_vbi_configure(struct saa7164_port *port)
42{
43 struct saa7164_dev *dev = port->dev;
44 dprintk(DBGLVL_VBI, "%s()\n", __func__);
45
46 port->vbi_params.width = port->width;
47 port->vbi_params.height = port->height;
48 port->vbi_params.is_50hz =
49 (port->encodernorm.id & V4L2_STD_625_50) != 0;
50
51 /* Set up the DIF (enable it) for analog mode by default */
52 saa7164_api_initialize_dif(port);
53
54 /* Configure the correct video standard */
55#if 0
56 saa7164_api_configure_dif(port, port->encodernorm.id);
57#endif
58
59#if 0
60 /* Ensure the audio decoder is correct configured */
61 saa7164_api_set_audio_std(port);
62#endif
63 dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
64}
65
66static int saa7164_vbi_buffers_dealloc(struct saa7164_port *port)
67{
68 struct list_head *c, *n, *p, *q, *l, *v;
69 struct saa7164_dev *dev = port->dev;
70 struct saa7164_buffer *buf;
71 struct saa7164_user_buffer *ubuf;
72
73 /* Remove any allocated buffers */
74 mutex_lock(&port->dmaqueue_lock);
75
76 dprintk(DBGLVL_VBI, "%s(port=%d) dmaqueue\n", __func__, port->nr);
77 list_for_each_safe(c, n, &port->dmaqueue.list) {
78 buf = list_entry(c, struct saa7164_buffer, list);
79 list_del(c);
80 saa7164_buffer_dealloc(buf);
81 }
82
83 dprintk(DBGLVL_VBI, "%s(port=%d) used\n", __func__, port->nr);
84 list_for_each_safe(p, q, &port->list_buf_used.list) {
85 ubuf = list_entry(p, struct saa7164_user_buffer, list);
86 list_del(p);
87 saa7164_buffer_dealloc_user(ubuf);
88 }
89
90 dprintk(DBGLVL_VBI, "%s(port=%d) free\n", __func__, port->nr);
91 list_for_each_safe(l, v, &port->list_buf_free.list) {
92 ubuf = list_entry(l, struct saa7164_user_buffer, list);
93 list_del(l);
94 saa7164_buffer_dealloc_user(ubuf);
95 }
96
97 mutex_unlock(&port->dmaqueue_lock);
98 dprintk(DBGLVL_VBI, "%s(port=%d) done\n", __func__, port->nr);
99
100 return 0;
101}
102
103/* Dynamic buffer switch at vbi start time */
104static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
105{
106 struct saa7164_dev *dev = port->dev;
107 struct saa7164_buffer *buf;
108 struct saa7164_user_buffer *ubuf;
109 struct tmHWStreamParameters *params = &port->hw_streamingparams;
110 int result = -ENODEV, i;
111 int len = 0;
112
113 dprintk(DBGLVL_VBI, "%s()\n", __func__);
114
115 /* TODO: NTSC SPECIFIC */
116 /* Init and establish defaults */
117 params->samplesperline = 1440;
118 params->numberoflines = 12;
119 params->numberoflines = 18;
120 params->pitch = 1600;
121 params->pitch = 1440;
122 params->numpagetables = 2 +
123 ((params->numberoflines * params->pitch) / PAGE_SIZE);
124 params->bitspersample = 8;
125 params->linethreshold = 0;
126 params->pagetablelistvirt = NULL;
127 params->pagetablelistphys = NULL;
128 params->numpagetableentries = port->hwcfg.buffercount;
129
130 /* Allocate the PCI resources, buffers (hard) */
131 for (i = 0; i < port->hwcfg.buffercount; i++) {
132 buf = saa7164_buffer_alloc(port,
133 params->numberoflines *
134 params->pitch);
135
136 if (!buf) {
137 printk(KERN_ERR "%s() failed "
138 "(errno = %d), unable to allocate buffer\n",
139 __func__, result);
140 result = -ENOMEM;
141 goto failed;
142 } else {
143
144 mutex_lock(&port->dmaqueue_lock);
145 list_add_tail(&buf->list, &port->dmaqueue.list);
146 mutex_unlock(&port->dmaqueue_lock);
147
148 }
149 }
150
151 /* Allocate some kernel buffers for copying
152 * to userpsace.
153 */
154 len = params->numberoflines * params->pitch;
155
156 if (vbi_buffers < 16)
157 vbi_buffers = 16;
158 if (vbi_buffers > 512)
159 vbi_buffers = 512;
160
161 for (i = 0; i < vbi_buffers; i++) {
162
163 ubuf = saa7164_buffer_alloc_user(dev, len);
164 if (ubuf) {
165 mutex_lock(&port->dmaqueue_lock);
166 list_add_tail(&ubuf->list, &port->list_buf_free.list);
167 mutex_unlock(&port->dmaqueue_lock);
168 }
169
170 }
171
172 result = 0;
173
174failed:
175 return result;
176}
177
178
179static int saa7164_vbi_initialize(struct saa7164_port *port)
180{
181 saa7164_vbi_configure(port);
182 return 0;
183}
184
185/* -- V4L2 --------------------------------------------------------- */
186static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
187{
188 struct saa7164_vbi_fh *fh = file->private_data;
189 struct saa7164_port *port = fh->port;
190 struct saa7164_dev *dev = port->dev;
191 unsigned int i;
192
193 dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)*id);
194
195 for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
196 if (*id & saa7164_tvnorms[i].id)
197 break;
198 }
199 if (i == ARRAY_SIZE(saa7164_tvnorms))
200 return -EINVAL;
201
202 port->encodernorm = saa7164_tvnorms[i];
203
204 /* Update the audio decoder while is not running in
205 * auto detect mode.
206 */
207 saa7164_api_set_audio_std(port);
208
209 dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)*id);
210
211 return 0;
212}
213
214static int vidioc_enum_input(struct file *file, void *priv,
215 struct v4l2_input *i)
216{
217 int n;
218
219 char *inputs[] = { "tuner", "composite", "svideo", "aux",
220 "composite 2", "svideo 2", "aux 2" };
221
222 if (i->index >= 7)
223 return -EINVAL;
224
225 strcpy(i->name, inputs[i->index]);
226
227 if (i->index == 0)
228 i->type = V4L2_INPUT_TYPE_TUNER;
229 else
230 i->type = V4L2_INPUT_TYPE_CAMERA;
231
232 for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
233 i->std |= saa7164_tvnorms[n].id;
234
235 return 0;
236}
237
238static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
239{
240 struct saa7164_vbi_fh *fh = file->private_data;
241 struct saa7164_port *port = fh->port;
242 struct saa7164_dev *dev = port->dev;
243
244 if (saa7164_api_get_videomux(port) != SAA_OK)
245 return -EIO;
246
247 *i = (port->mux_input - 1);
248
249 dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i);
250
251 return 0;
252}
253
254static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
255{
256 struct saa7164_vbi_fh *fh = file->private_data;
257 struct saa7164_port *port = fh->port;
258 struct saa7164_dev *dev = port->dev;
259
260 dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i);
261
262 if (i >= 7)
263 return -EINVAL;
264
265 port->mux_input = i + 1;
266
267 if (saa7164_api_set_videomux(port) != SAA_OK)
268 return -EIO;
269
270 return 0;
271}
272
273static int vidioc_g_tuner(struct file *file, void *priv,
274 struct v4l2_tuner *t)
275{
276 struct saa7164_vbi_fh *fh = file->private_data;
277 struct saa7164_port *port = fh->port;
278 struct saa7164_dev *dev = port->dev;
279
280 if (0 != t->index)
281 return -EINVAL;
282
283 strcpy(t->name, "tuner");
284 t->type = V4L2_TUNER_ANALOG_TV;
285 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
286
287 dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
288
289 return 0;
290}
291
292static int vidioc_s_tuner(struct file *file, void *priv,
293 struct v4l2_tuner *t)
294{
295 /* Update the A/V core */
296 return 0;
297}
298
299static int vidioc_g_frequency(struct file *file, void *priv,
300 struct v4l2_frequency *f)
301{
302 struct saa7164_vbi_fh *fh = file->private_data;
303 struct saa7164_port *port = fh->port;
304
305 f->type = V4L2_TUNER_ANALOG_TV;
306 f->frequency = port->freq;
307
308 return 0;
309}
310
311static int vidioc_s_frequency(struct file *file, void *priv,
312 struct v4l2_frequency *f)
313{
314 struct saa7164_vbi_fh *fh = file->private_data;
315 struct saa7164_port *port = fh->port;
316 struct saa7164_dev *dev = port->dev;
317 struct saa7164_port *tsport;
318 struct dvb_frontend *fe;
319
320 /* TODO: Pull this for the std */
321 struct analog_parameters params = {
322 .mode = V4L2_TUNER_ANALOG_TV,
323 .audmode = V4L2_TUNER_MODE_STEREO,
324 .std = port->encodernorm.id,
325 .frequency = f->frequency
326 };
327
328 /* Stop the encoder */
329 dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__,
330 f->frequency, f->tuner);
331
332 if (f->tuner != 0)
333 return -EINVAL;
334
335 if (f->type != V4L2_TUNER_ANALOG_TV)
336 return -EINVAL;
337
338 port->freq = f->frequency;
339
340 /* Update the hardware */
341 if (port->nr == SAA7164_PORT_VBI1)
342 tsport = &dev->ports[SAA7164_PORT_TS1];
343 else
344 if (port->nr == SAA7164_PORT_VBI2)
345 tsport = &dev->ports[SAA7164_PORT_TS2];
346 else
347 BUG();
348
349 fe = tsport->dvb.frontend;
350
351 if (fe && fe->ops.tuner_ops.set_analog_params)
352 fe->ops.tuner_ops.set_analog_params(fe, &params);
353 else
354 printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
355
356 saa7164_vbi_initialize(port);
357
358 return 0;
359}
360
361static int vidioc_g_ctrl(struct file *file, void *priv,
362 struct v4l2_control *ctl)
363{
364 struct saa7164_vbi_fh *fh = file->private_data;
365 struct saa7164_port *port = fh->port;
366 struct saa7164_dev *dev = port->dev;
367
368 dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
369 ctl->id, ctl->value);
370
371 switch (ctl->id) {
372 case V4L2_CID_BRIGHTNESS:
373 ctl->value = port->ctl_brightness;
374 break;
375 case V4L2_CID_CONTRAST:
376 ctl->value = port->ctl_contrast;
377 break;
378 case V4L2_CID_SATURATION:
379 ctl->value = port->ctl_saturation;
380 break;
381 case V4L2_CID_HUE:
382 ctl->value = port->ctl_hue;
383 break;
384 case V4L2_CID_SHARPNESS:
385 ctl->value = port->ctl_sharpness;
386 break;
387 case V4L2_CID_AUDIO_VOLUME:
388 ctl->value = port->ctl_volume;
389 break;
390 default:
391 return -EINVAL;
392 }
393
394 return 0;
395}
396
397static int vidioc_s_ctrl(struct file *file, void *priv,
398 struct v4l2_control *ctl)
399{
400 struct saa7164_vbi_fh *fh = file->private_data;
401 struct saa7164_port *port = fh->port;
402 struct saa7164_dev *dev = port->dev;
403 int ret = 0;
404
405 dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
406 ctl->id, ctl->value);
407
408 switch (ctl->id) {
409 case V4L2_CID_BRIGHTNESS:
410 if ((ctl->value >= 0) && (ctl->value <= 255)) {
411 port->ctl_brightness = ctl->value;
412 saa7164_api_set_usercontrol(port,
413 PU_BRIGHTNESS_CONTROL);
414 } else
415 ret = -EINVAL;
416 break;
417 case V4L2_CID_CONTRAST:
418 if ((ctl->value >= 0) && (ctl->value <= 255)) {
419 port->ctl_contrast = ctl->value;
420 saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
421 } else
422 ret = -EINVAL;
423 break;
424 case V4L2_CID_SATURATION:
425 if ((ctl->value >= 0) && (ctl->value <= 255)) {
426 port->ctl_saturation = ctl->value;
427 saa7164_api_set_usercontrol(port,
428 PU_SATURATION_CONTROL);
429 } else
430 ret = -EINVAL;
431 break;
432 case V4L2_CID_HUE:
433 if ((ctl->value >= 0) && (ctl->value <= 255)) {
434 port->ctl_hue = ctl->value;
435 saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
436 } else
437 ret = -EINVAL;
438 break;
439 case V4L2_CID_SHARPNESS:
440 if ((ctl->value >= 0) && (ctl->value <= 255)) {
441 port->ctl_sharpness = ctl->value;
442 saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
443 } else
444 ret = -EINVAL;
445 break;
446 case V4L2_CID_AUDIO_VOLUME:
447 if ((ctl->value >= -83) && (ctl->value <= 24)) {
448 port->ctl_volume = ctl->value;
449 saa7164_api_set_audio_volume(port, port->ctl_volume);
450 } else
451 ret = -EINVAL;
452 break;
453 default:
454 ret = -EINVAL;
455 }
456
457 return ret;
458}
459
460static int saa7164_get_ctrl(struct saa7164_port *port,
461 struct v4l2_ext_control *ctrl)
462{
463 struct saa7164_vbi_params *params = &port->vbi_params;
464
465 switch (ctrl->id) {
466 case V4L2_CID_MPEG_STREAM_TYPE:
467 ctrl->value = params->stream_type;
468 break;
469 case V4L2_CID_MPEG_AUDIO_MUTE:
470 ctrl->value = params->ctl_mute;
471 break;
472 case V4L2_CID_MPEG_VIDEO_ASPECT:
473 ctrl->value = params->ctl_aspect;
474 break;
475 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
476 ctrl->value = params->refdist;
477 break;
478 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
479 ctrl->value = params->gop_size;
480 break;
481 default:
482 return -EINVAL;
483 }
484 return 0;
485}
486
487static int vidioc_g_ext_ctrls(struct file *file, void *priv,
488 struct v4l2_ext_controls *ctrls)
489{
490 struct saa7164_vbi_fh *fh = file->private_data;
491 struct saa7164_port *port = fh->port;
492 int i, err = 0;
493
494 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
495 for (i = 0; i < ctrls->count; i++) {
496 struct v4l2_ext_control *ctrl = ctrls->controls + i;
497
498 err = saa7164_get_ctrl(port, ctrl);
499 if (err) {
500 ctrls->error_idx = i;
501 break;
502 }
503 }
504 return err;
505
506 }
507
508 return -EINVAL;
509}
510
511static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
512{
513 int ret = -EINVAL;
514
515 switch (ctrl->id) {
516 case V4L2_CID_MPEG_STREAM_TYPE:
517 if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
518 (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
519 ret = 0;
520 break;
521 case V4L2_CID_MPEG_AUDIO_MUTE:
522 if ((ctrl->value >= 0) &&
523 (ctrl->value <= 1))
524 ret = 0;
525 break;
526 case V4L2_CID_MPEG_VIDEO_ASPECT:
527 if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
528 (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
529 ret = 0;
530 break;
531 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
532 if ((ctrl->value >= 0) &&
533 (ctrl->value <= 255))
534 ret = 0;
535 break;
536 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
537 if ((ctrl->value >= 1) &&
538 (ctrl->value <= 3))
539 ret = 0;
540 break;
541 default:
542 ret = -EINVAL;
543 }
544
545 return ret;
546}
547
548static int vidioc_try_ext_ctrls(struct file *file, void *priv,
549 struct v4l2_ext_controls *ctrls)
550{
551 int i, err = 0;
552
553 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
554 for (i = 0; i < ctrls->count; i++) {
555 struct v4l2_ext_control *ctrl = ctrls->controls + i;
556
557 err = saa7164_try_ctrl(ctrl, 0);
558 if (err) {
559 ctrls->error_idx = i;
560 break;
561 }
562 }
563 return err;
564 }
565
566 return -EINVAL;
567}
568
569static int saa7164_set_ctrl(struct saa7164_port *port,
570 struct v4l2_ext_control *ctrl)
571{
572 struct saa7164_vbi_params *params = &port->vbi_params;
573 int ret = 0;
574
575 switch (ctrl->id) {
576 case V4L2_CID_MPEG_STREAM_TYPE:
577 params->stream_type = ctrl->value;
578 break;
579 case V4L2_CID_MPEG_AUDIO_MUTE:
580 params->ctl_mute = ctrl->value;
581 ret = saa7164_api_audio_mute(port, params->ctl_mute);
582 if (ret != SAA_OK) {
583 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
584 ret);
585 ret = -EIO;
586 }
587 break;
588 case V4L2_CID_MPEG_VIDEO_ASPECT:
589 params->ctl_aspect = ctrl->value;
590 ret = saa7164_api_set_aspect_ratio(port);
591 if (ret != SAA_OK) {
592 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
593 ret);
594 ret = -EIO;
595 }
596 break;
597 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
598 params->refdist = ctrl->value;
599 break;
600 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
601 params->gop_size = ctrl->value;
602 break;
603 default:
604 return -EINVAL;
605 }
606
607 /* TODO: Update the hardware */
608
609 return ret;
610}
611
612static int vidioc_s_ext_ctrls(struct file *file, void *priv,
613 struct v4l2_ext_controls *ctrls)
614{
615 struct saa7164_vbi_fh *fh = file->private_data;
616 struct saa7164_port *port = fh->port;
617 int i, err = 0;
618
619 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
620 for (i = 0; i < ctrls->count; i++) {
621 struct v4l2_ext_control *ctrl = ctrls->controls + i;
622
623 err = saa7164_try_ctrl(ctrl, 0);
624 if (err) {
625 ctrls->error_idx = i;
626 break;
627 }
628 err = saa7164_set_ctrl(port, ctrl);
629 if (err) {
630 ctrls->error_idx = i;
631 break;
632 }
633 }
634 return err;
635
636 }
637
638 return -EINVAL;
639}
640
641static int vidioc_querycap(struct file *file, void *priv,
642 struct v4l2_capability *cap)
643{
644 struct saa7164_vbi_fh *fh = file->private_data;
645 struct saa7164_port *port = fh->port;
646 struct saa7164_dev *dev = port->dev;
647
648 strcpy(cap->driver, dev->name);
649 strlcpy(cap->card, saa7164_boards[dev->board].name,
650 sizeof(cap->card));
651 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
652
653 cap->capabilities =
654 V4L2_CAP_VBI_CAPTURE |
655 V4L2_CAP_READWRITE |
656 0;
657
658 cap->capabilities |= V4L2_CAP_TUNER;
659 cap->version = 0;
660
661 return 0;
662}
663
664static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
665 struct v4l2_fmtdesc *f)
666{
667 if (f->index != 0)
668 return -EINVAL;
669
670 strlcpy(f->description, "VBI", sizeof(f->description));
671 f->pixelformat = V4L2_PIX_FMT_MPEG;
672
673 return 0;
674}
675
676static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
677 struct v4l2_format *f)
678{
679 struct saa7164_vbi_fh *fh = file->private_data;
680 struct saa7164_port *port = fh->port;
681 struct saa7164_dev *dev = port->dev;
682
683 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
684 f->fmt.pix.bytesperline = 0;
685 f->fmt.pix.sizeimage =
686 port->ts_packet_size * port->ts_packet_count;
687 f->fmt.pix.colorspace = 0;
688 f->fmt.pix.width = port->width;
689 f->fmt.pix.height = port->height;
690
691 dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n",
692 port->width, port->height);
693
694 return 0;
695}
696
697static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
698 struct v4l2_format *f)
699{
700 struct saa7164_vbi_fh *fh = file->private_data;
701 struct saa7164_port *port = fh->port;
702 struct saa7164_dev *dev = port->dev;
703
704 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
705 f->fmt.pix.bytesperline = 0;
706 f->fmt.pix.sizeimage =
707 port->ts_packet_size * port->ts_packet_count;
708 f->fmt.pix.colorspace = 0;
709 dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
710 port->width, port->height);
711 return 0;
712}
713
714static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
715 struct v4l2_format *f)
716{
717 struct saa7164_vbi_fh *fh = file->private_data;
718 struct saa7164_port *port = fh->port;
719 struct saa7164_dev *dev = port->dev;
720
721 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
722 f->fmt.pix.bytesperline = 0;
723 f->fmt.pix.sizeimage =
724 port->ts_packet_size * port->ts_packet_count;
725 f->fmt.pix.colorspace = 0;
726
727 dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
728 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
729
730 return 0;
731}
732
733static int vidioc_log_status(struct file *file, void *priv)
734{
735 return 0;
736}
737
738static int fill_queryctrl(struct saa7164_vbi_params *params,
739 struct v4l2_queryctrl *c)
740{
741 switch (c->id) {
742 case V4L2_CID_BRIGHTNESS:
743 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
744 case V4L2_CID_CONTRAST:
745 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
746 case V4L2_CID_SATURATION:
747 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
748 case V4L2_CID_HUE:
749 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
750 case V4L2_CID_SHARPNESS:
751 return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
752 case V4L2_CID_MPEG_AUDIO_MUTE:
753 return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
754 case V4L2_CID_AUDIO_VOLUME:
755 return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
756 case V4L2_CID_MPEG_STREAM_TYPE:
757 return v4l2_ctrl_query_fill(c,
758 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
759 V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
760 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
761 case V4L2_CID_MPEG_VIDEO_ASPECT:
762 return v4l2_ctrl_query_fill(c,
763 V4L2_MPEG_VIDEO_ASPECT_1x1,
764 V4L2_MPEG_VIDEO_ASPECT_221x100,
765 1, V4L2_MPEG_VIDEO_ASPECT_4x3);
766 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
767 return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
768 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
769 return v4l2_ctrl_query_fill(c,
770 1, 3, 1, 1);
771 default:
772 return -EINVAL;
773 }
774}
775
776static int vidioc_queryctrl(struct file *file, void *priv,
777 struct v4l2_queryctrl *c)
778{
779 struct saa7164_vbi_fh *fh = priv;
780 struct saa7164_port *port = fh->port;
781 int i, next;
782 u32 id = c->id;
783
784 memset(c, 0, sizeof(*c));
785
786 next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
787 c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
788
789 for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
790 if (next) {
791 if (c->id < saa7164_v4l2_ctrls[i])
792 c->id = saa7164_v4l2_ctrls[i];
793 else
794 continue;
795 }
796
797 if (c->id == saa7164_v4l2_ctrls[i])
798 return fill_queryctrl(&port->vbi_params, c);
799
800 if (c->id < saa7164_v4l2_ctrls[i])
801 break;
802 }
803
804 return -EINVAL;
805}
806
807static int saa7164_vbi_stop_port(struct saa7164_port *port)
808{
809 struct saa7164_dev *dev = port->dev;
810 int ret;
811
812 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
813 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
814 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
815 __func__, ret);
816 ret = -EIO;
817 } else {
818 dprintk(DBGLVL_VBI, "%s() Stopped\n", __func__);
819 ret = 0;
820 }
821
822 return ret;
823}
824
825static int saa7164_vbi_acquire_port(struct saa7164_port *port)
826{
827 struct saa7164_dev *dev = port->dev;
828 int ret;
829
830 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
831 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
832 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
833 __func__, ret);
834 ret = -EIO;
835 } else {
836 dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
837 ret = 0;
838 }
839
840 return ret;
841}
842
843static int saa7164_vbi_pause_port(struct saa7164_port *port)
844{
845 struct saa7164_dev *dev = port->dev;
846 int ret;
847
848 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
849 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
850 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
851 __func__, ret);
852 ret = -EIO;
853 } else {
854 dprintk(DBGLVL_VBI, "%s() Paused\n", __func__);
855 ret = 0;
856 }
857
858 return ret;
859}
860
861/* Firmware is very windows centric, meaning you have to transition
862 * the part through AVStream / KS Windows stages, forwards or backwards.
863 * States are: stopped, acquired (h/w), paused, started.
864 * We have to leave here will all of the soft buffers on the free list,
865 * else the cfg_post() func won't have soft buffers to correctly configure.
866 */
867static int saa7164_vbi_stop_streaming(struct saa7164_port *port)
868{
869 struct saa7164_dev *dev = port->dev;
870 struct saa7164_buffer *buf;
871 struct saa7164_user_buffer *ubuf;
872 struct list_head *c, *n;
873 int ret;
874
875 dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
876
877 ret = saa7164_vbi_pause_port(port);
878 ret = saa7164_vbi_acquire_port(port);
879 ret = saa7164_vbi_stop_port(port);
880
881 dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__,
882 port->nr);
883
884 /* Reset the state of any allocated buffer resources */
885 mutex_lock(&port->dmaqueue_lock);
886
887 /* Reset the hard and soft buffer state */
888 list_for_each_safe(c, n, &port->dmaqueue.list) {
889 buf = list_entry(c, struct saa7164_buffer, list);
890 buf->flags = SAA7164_BUFFER_FREE;
891 buf->pos = 0;
892 }
893
894 list_for_each_safe(c, n, &port->list_buf_used.list) {
895 ubuf = list_entry(c, struct saa7164_user_buffer, list);
896 ubuf->pos = 0;
897 list_move_tail(&ubuf->list, &port->list_buf_free.list);
898 }
899
900 mutex_unlock(&port->dmaqueue_lock);
901
902 /* Free any allocated resources */
903 saa7164_vbi_buffers_dealloc(port);
904
905 dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr);
906
907 return ret;
908}
909
910static int saa7164_vbi_start_streaming(struct saa7164_port *port)
911{
912 struct saa7164_dev *dev = port->dev;
913 int result, ret = 0;
914
915 dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
916
917 port->done_first_interrupt = 0;
918
919 /* allocate all of the PCIe DMA buffer resources on the fly,
920 * allowing switching between TS and PS payloads without
921 * requiring a complete driver reload.
922 */
923 saa7164_vbi_buffers_alloc(port);
924
925 /* Configure the encoder with any cache values */
926#if 0
927 saa7164_api_set_encoder(port);
928 saa7164_api_get_encoder(port);
929#endif
930
931 /* Place the empty buffers on the hardware */
932 saa7164_buffer_cfg_port(port);
933
934 /* Negotiate format */
935 if (saa7164_api_set_vbi_format(port) != SAA_OK) {
936 printk(KERN_ERR "%s() No supported VBI format\n", __func__);
937 ret = -EIO;
938 goto out;
939 }
940
941 /* Acquire the hardware */
942 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
943 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
944 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
945 __func__, result);
946
947 ret = -EIO;
948 goto out;
949 } else
950 dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
951
952 /* Pause the hardware */
953 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
954 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
955 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
956 __func__, result);
957
958 /* Stop the hardware, regardless */
959 result = saa7164_vbi_stop_port(port);
960 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
961 printk(KERN_ERR "%s() pause/forced stop transition "
962 "failed, res = 0x%x\n", __func__, result);
963 }
964
965 ret = -EIO;
966 goto out;
967 } else
968 dprintk(DBGLVL_VBI, "%s() Paused\n", __func__);
969
970 /* Start the hardware */
971 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
972 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
973 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
974 __func__, result);
975
976 /* Stop the hardware, regardless */
977 result = saa7164_vbi_acquire_port(port);
978 result = saa7164_vbi_stop_port(port);
979 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
980 printk(KERN_ERR "%s() run/forced stop transition "
981 "failed, res = 0x%x\n", __func__, result);
982 }
983
984 ret = -EIO;
985 } else
986 dprintk(DBGLVL_VBI, "%s() Running\n", __func__);
987
988out:
989 return ret;
990}
991
992int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f)
993{
994 /* ntsc */
995 f->fmt.vbi.samples_per_line = 1600;
996 f->fmt.vbi.samples_per_line = 1440;
997 f->fmt.vbi.sampling_rate = 27000000;
998 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
999 f->fmt.vbi.offset = 0;
1000 f->fmt.vbi.flags = 0;
1001 f->fmt.vbi.start[0] = 10;
1002 f->fmt.vbi.count[0] = 18;
1003 f->fmt.vbi.start[1] = 263 + 10 + 1;
1004 f->fmt.vbi.count[1] = 18;
1005 return 0;
1006}
1007
1008static int fops_open(struct file *file)
1009{
1010 struct saa7164_dev *dev;
1011 struct saa7164_port *port;
1012 struct saa7164_vbi_fh *fh;
1013
1014 port = (struct saa7164_port *)video_get_drvdata(video_devdata(file));
1015 if (!port)
1016 return -ENODEV;
1017
1018 dev = port->dev;
1019
1020 dprintk(DBGLVL_VBI, "%s()\n", __func__);
1021
1022 /* allocate + initialize per filehandle data */
1023 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1024 if (NULL == fh)
1025 return -ENOMEM;
1026
1027 file->private_data = fh;
1028 fh->port = port;
1029
1030 return 0;
1031}
1032
1033static int fops_release(struct file *file)
1034{
1035 struct saa7164_vbi_fh *fh = file->private_data;
1036 struct saa7164_port *port = fh->port;
1037 struct saa7164_dev *dev = port->dev;
1038
1039 dprintk(DBGLVL_VBI, "%s()\n", __func__);
1040
1041 /* Shut device down on last close */
1042 if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
1043 if (atomic_dec_return(&port->v4l_reader_count) == 0) {
1044 /* stop vbi capture then cancel buffers */
1045 saa7164_vbi_stop_streaming(port);
1046 }
1047 }
1048
1049 file->private_data = NULL;
1050 kfree(fh);
1051
1052 return 0;
1053}
1054
1055struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
1056{
1057 struct saa7164_user_buffer *ubuf = NULL;
1058 struct saa7164_dev *dev = port->dev;
1059 u32 crc;
1060
1061 mutex_lock(&port->dmaqueue_lock);
1062 if (!list_empty(&port->list_buf_used.list)) {
1063 ubuf = list_first_entry(&port->list_buf_used.list,
1064 struct saa7164_user_buffer, list);
1065
1066 if (crc_checking) {
1067 crc = crc32(0, ubuf->data, ubuf->actual_size);
1068 if (crc != ubuf->crc) {
1069 printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
1070 __func__,
1071 ubuf, ubuf->crc, crc);
1072 }
1073 }
1074
1075 }
1076 mutex_unlock(&port->dmaqueue_lock);
1077
1078 dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf);
1079
1080 return ubuf;
1081}
1082
1083static ssize_t fops_read(struct file *file, char __user *buffer,
1084 size_t count, loff_t *pos)
1085{
1086 struct saa7164_vbi_fh *fh = file->private_data;
1087 struct saa7164_port *port = fh->port;
1088 struct saa7164_user_buffer *ubuf = NULL;
1089 struct saa7164_dev *dev = port->dev;
1090 int ret = 0;
1091 int rem, cnt;
1092 u8 *p;
1093
1094 port->last_read_msecs_diff = port->last_read_msecs;
1095 port->last_read_msecs = jiffies_to_msecs(jiffies);
1096 port->last_read_msecs_diff = port->last_read_msecs -
1097 port->last_read_msecs_diff;
1098
1099 saa7164_histogram_update(&port->read_interval,
1100 port->last_read_msecs_diff);
1101
1102 if (*pos) {
1103 printk(KERN_ERR "%s() ESPIPE\n", __func__);
1104 return -ESPIPE;
1105 }
1106
1107 if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1108 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1109
1110 if (saa7164_vbi_initialize(port) < 0) {
1111 printk(KERN_ERR "%s() EINVAL\n", __func__);
1112 return -EINVAL;
1113 }
1114
1115 saa7164_vbi_start_streaming(port);
1116 msleep(200);
1117 }
1118 }
1119
1120 /* blocking wait for buffer */
1121 if ((file->f_flags & O_NONBLOCK) == 0) {
1122 if (wait_event_interruptible(port->wait_read,
1123 saa7164_vbi_next_buf(port))) {
1124 printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
1125 return -ERESTARTSYS;
1126 }
1127 }
1128
1129 /* Pull the first buffer from the used list */
1130 ubuf = saa7164_vbi_next_buf(port);
1131
1132 while ((count > 0) && ubuf) {
1133
1134 /* set remaining bytes to copy */
1135 rem = ubuf->actual_size - ubuf->pos;
1136 cnt = rem > count ? count : rem;
1137
1138 p = ubuf->data + ubuf->pos;
1139
1140 dprintk(DBGLVL_VBI,
1141 "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
1142 __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
1143
1144 if (copy_to_user(buffer, p, cnt)) {
1145 printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
1146 if (!ret) {
1147 printk(KERN_ERR "%s() EFAULT\n", __func__);
1148 ret = -EFAULT;
1149 }
1150 goto err;
1151 }
1152
1153 ubuf->pos += cnt;
1154 count -= cnt;
1155 buffer += cnt;
1156 ret += cnt;
1157
1158 if (ubuf->pos > ubuf->actual_size)
1159 printk(KERN_ERR "read() pos > actual, huh?\n");
1160
1161 if (ubuf->pos == ubuf->actual_size) {
1162
1163 /* finished with current buffer, take next buffer */
1164
1165 /* Requeue the buffer on the free list */
1166 ubuf->pos = 0;
1167
1168 mutex_lock(&port->dmaqueue_lock);
1169 list_move_tail(&ubuf->list, &port->list_buf_free.list);
1170 mutex_unlock(&port->dmaqueue_lock);
1171
1172 /* Dequeue next */
1173 if ((file->f_flags & O_NONBLOCK) == 0) {
1174 if (wait_event_interruptible(port->wait_read,
1175 saa7164_vbi_next_buf(port))) {
1176 break;
1177 }
1178 }
1179 ubuf = saa7164_vbi_next_buf(port);
1180 }
1181 }
1182err:
1183 if (!ret && !ubuf) {
1184 printk(KERN_ERR "%s() EAGAIN\n", __func__);
1185 ret = -EAGAIN;
1186 }
1187
1188 return ret;
1189}
1190
1191static unsigned int fops_poll(struct file *file, poll_table *wait)
1192{
1193 struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data;
1194 struct saa7164_port *port = fh->port;
1195 unsigned int mask = 0;
1196
1197 port->last_poll_msecs_diff = port->last_poll_msecs;
1198 port->last_poll_msecs = jiffies_to_msecs(jiffies);
1199 port->last_poll_msecs_diff = port->last_poll_msecs -
1200 port->last_poll_msecs_diff;
1201
1202 saa7164_histogram_update(&port->poll_interval,
1203 port->last_poll_msecs_diff);
1204
1205 if (!video_is_registered(port->v4l_device))
1206 return -EIO;
1207
1208 if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1209 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1210 if (saa7164_vbi_initialize(port) < 0)
1211 return -EINVAL;
1212 saa7164_vbi_start_streaming(port);
1213 msleep(200);
1214 }
1215 }
1216
1217 /* blocking wait for buffer */
1218 if ((file->f_flags & O_NONBLOCK) == 0) {
1219 if (wait_event_interruptible(port->wait_read,
1220 saa7164_vbi_next_buf(port))) {
1221 return -ERESTARTSYS;
1222 }
1223 }
1224
1225 /* Pull the first buffer from the used list */
1226 if (!list_empty(&port->list_buf_used.list))
1227 mask |= POLLIN | POLLRDNORM;
1228
1229 return mask;
1230}
1231static const struct v4l2_file_operations vbi_fops = {
1232 .owner = THIS_MODULE,
1233 .open = fops_open,
1234 .release = fops_release,
1235 .read = fops_read,
1236 .poll = fops_poll,
1237 .unlocked_ioctl = video_ioctl2,
1238};
1239
1240static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
1241 .vidioc_s_std = vidioc_s_std,
1242 .vidioc_enum_input = vidioc_enum_input,
1243 .vidioc_g_input = vidioc_g_input,
1244 .vidioc_s_input = vidioc_s_input,
1245 .vidioc_g_tuner = vidioc_g_tuner,
1246 .vidioc_s_tuner = vidioc_s_tuner,
1247 .vidioc_g_frequency = vidioc_g_frequency,
1248 .vidioc_s_frequency = vidioc_s_frequency,
1249 .vidioc_s_ctrl = vidioc_s_ctrl,
1250 .vidioc_g_ctrl = vidioc_g_ctrl,
1251 .vidioc_querycap = vidioc_querycap,
1252 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1253 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1254 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1255 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1256 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
1257 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
1258 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
1259 .vidioc_log_status = vidioc_log_status,
1260 .vidioc_queryctrl = vidioc_queryctrl,
1261#if 0
1262 .vidioc_g_chip_ident = saa7164_g_chip_ident,
1263#endif
1264#ifdef CONFIG_VIDEO_ADV_DEBUG
1265#if 0
1266 .vidioc_g_register = saa7164_g_register,
1267 .vidioc_s_register = saa7164_s_register,
1268#endif
1269#endif
1270 .vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt,
1271 .vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt,
1272 .vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt,
1273};
1274
1275static struct video_device saa7164_vbi_template = {
1276 .name = "saa7164",
1277 .fops = &vbi_fops,
1278 .ioctl_ops = &vbi_ioctl_ops,
1279 .minor = -1,
1280 .tvnorms = SAA7164_NORMS,
1281 .current_norm = V4L2_STD_NTSC_M,
1282};
1283
1284static struct video_device *saa7164_vbi_alloc(
1285 struct saa7164_port *port,
1286 struct pci_dev *pci,
1287 struct video_device *template,
1288 char *type)
1289{
1290 struct video_device *vfd;
1291 struct saa7164_dev *dev = port->dev;
1292
1293 dprintk(DBGLVL_VBI, "%s()\n", __func__);
1294
1295 vfd = video_device_alloc();
1296 if (NULL == vfd)
1297 return NULL;
1298
1299 *vfd = *template;
1300 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
1301 type, saa7164_boards[dev->board].name);
1302
1303 vfd->parent = &pci->dev;
1304 vfd->release = video_device_release;
1305 return vfd;
1306}
1307
1308int saa7164_vbi_register(struct saa7164_port *port)
1309{
1310 struct saa7164_dev *dev = port->dev;
1311 int result = -ENODEV;
1312
1313 dprintk(DBGLVL_VBI, "%s()\n", __func__);
1314
1315 if (port->type != SAA7164_MPEG_VBI)
1316 BUG();
1317
1318 /* Sanity check that the PCI configuration space is active */
1319 if (port->hwcfg.BARLocation == 0) {
1320 printk(KERN_ERR "%s() failed "
1321 "(errno = %d), NO PCI configuration\n",
1322 __func__, result);
1323 result = -ENOMEM;
1324 goto failed;
1325 }
1326
1327 /* Establish VBI defaults here */
1328
1329 /* Allocate and register the video device node */
1330 port->v4l_device = saa7164_vbi_alloc(port,
1331 dev->pci, &saa7164_vbi_template, "vbi");
1332
1333 if (!port->v4l_device) {
1334 printk(KERN_INFO "%s: can't allocate vbi device\n",
1335 dev->name);
1336 result = -ENOMEM;
1337 goto failed;
1338 }
1339
1340 video_set_drvdata(port->v4l_device, port);
1341 result = video_register_device(port->v4l_device,
1342 VFL_TYPE_VBI, -1);
1343 if (result < 0) {
1344 printk(KERN_INFO "%s: can't register vbi device\n",
1345 dev->name);
1346 /* TODO: We're going to leak here if we don't dealloc
1347 The buffers above. The unreg function can't deal wit it.
1348 */
1349 goto failed;
1350 }
1351
1352 printk(KERN_INFO "%s: registered device vbi%d [vbi]\n",
1353 dev->name, port->v4l_device->num);
1354
1355 /* Configure the hardware defaults */
1356
1357 result = 0;
1358failed:
1359 return result;
1360}
1361
1362void saa7164_vbi_unregister(struct saa7164_port *port)
1363{
1364 struct saa7164_dev *dev = port->dev;
1365
1366 dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
1367
1368 if (port->type != SAA7164_MPEG_VBI)
1369 BUG();
1370
1371 if (port->v4l_device) {
1372 if (port->v4l_device->minor != -1)
1373 video_unregister_device(port->v4l_device);
1374 else
1375 video_device_release(port->v4l_device);
1376
1377 port->v4l_device = NULL;
1378 }
1379
1380}
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
new file mode 100644
index 00000000000..35b64306ba9
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -0,0 +1,623 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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/*
23 Driver architecture
24 *******************
25
26 saa7164_core.c/buffer.c/cards.c/i2c.c/dvb.c
27 | : Standard Linux driver framework for creating
28 | : exposing and managing interfaces to the rest
29 | : of the kernel or userland. Also uses _fw.c to load
30 | : firmware direct into the PCIe bus, bypassing layers.
31 V
32 saa7164_api..() : Translate kernel specific functions/features
33 | : into command buffers.
34 V
35 saa7164_cmd..() : Manages the flow of command packets on/off,
36 | : the bus. Deal with bus errors, timeouts etc.
37 V
38 saa7164_bus..() : Manage a read/write memory ring buffer in the
39 | : PCIe Address space.
40 |
41 | saa7164_fw...() : Load any frimware
42 | | : direct into the device
43 V V
44 <- ----------------- PCIe address space -------------------- ->
45*/
46
47#include <linux/pci.h>
48#include <linux/i2c.h>
49#include <linux/i2c-algo-bit.h>
50#include <linux/kdev_t.h>
51#include <linux/mutex.h>
52#include <linux/crc32.h>
53#include <linux/kthread.h>
54#include <linux/freezer.h>
55
56#include <media/tuner.h>
57#include <media/tveeprom.h>
58#include <media/videobuf-dma-sg.h>
59#include <media/videobuf-dvb.h>
60#include <dvb_demux.h>
61#include <dvb_frontend.h>
62#include <dvb_net.h>
63#include <dvbdev.h>
64#include <dmxdev.h>
65#include <media/v4l2-common.h>
66#include <media/v4l2-ioctl.h>
67#include <media/v4l2-chip-ident.h>
68
69#include "saa7164-reg.h"
70#include "saa7164-types.h"
71
72#define SAA7164_MAXBOARDS 8
73
74#define UNSET (-1U)
75#define SAA7164_BOARD_NOAUTO UNSET
76#define SAA7164_BOARD_UNKNOWN 0
77#define SAA7164_BOARD_UNKNOWN_REV2 1
78#define SAA7164_BOARD_UNKNOWN_REV3 2
79#define SAA7164_BOARD_HAUPPAUGE_HVR2250 3
80#define SAA7164_BOARD_HAUPPAUGE_HVR2200 4
81#define SAA7164_BOARD_HAUPPAUGE_HVR2200_2 5
82#define SAA7164_BOARD_HAUPPAUGE_HVR2200_3 6
83#define SAA7164_BOARD_HAUPPAUGE_HVR2250_2 7
84#define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8
85#define SAA7164_BOARD_HAUPPAUGE_HVR2200_4 9
86
87#define SAA7164_MAX_UNITS 8
88#define SAA7164_TS_NUMBER_OF_LINES 312
89#define SAA7164_PS_NUMBER_OF_LINES 256
90#define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */
91#define SAA7164_MAX_ENCODER_BUFFERS 64 /* max 5secs of latency at 6Mbps */
92#define SAA7164_MAX_VBI_BUFFERS 64
93
94/* Port related defines */
95#define SAA7164_PORT_TS1 (0)
96#define SAA7164_PORT_TS2 (SAA7164_PORT_TS1 + 1)
97#define SAA7164_PORT_ENC1 (SAA7164_PORT_TS2 + 1)
98#define SAA7164_PORT_ENC2 (SAA7164_PORT_ENC1 + 1)
99#define SAA7164_PORT_VBI1 (SAA7164_PORT_ENC2 + 1)
100#define SAA7164_PORT_VBI2 (SAA7164_PORT_VBI1 + 1)
101#define SAA7164_MAX_PORTS (SAA7164_PORT_VBI2 + 1)
102
103#define DBGLVL_FW 4
104#define DBGLVL_DVB 8
105#define DBGLVL_I2C 16
106#define DBGLVL_API 32
107#define DBGLVL_CMD 64
108#define DBGLVL_BUS 128
109#define DBGLVL_IRQ 256
110#define DBGLVL_BUF 512
111#define DBGLVL_ENC 1024
112#define DBGLVL_VBI 2048
113#define DBGLVL_THR 4096
114#define DBGLVL_CPU 8192
115
116#define SAA7164_NORMS \
117 (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443)
118
119enum port_t {
120 SAA7164_MPEG_UNDEFINED = 0,
121 SAA7164_MPEG_DVB,
122 SAA7164_MPEG_ENCODER,
123 SAA7164_MPEG_VBI,
124};
125
126enum saa7164_i2c_bus_nr {
127 SAA7164_I2C_BUS_0 = 0,
128 SAA7164_I2C_BUS_1,
129 SAA7164_I2C_BUS_2,
130};
131
132enum saa7164_buffer_flags {
133 SAA7164_BUFFER_UNDEFINED = 0,
134 SAA7164_BUFFER_FREE,
135 SAA7164_BUFFER_BUSY,
136 SAA7164_BUFFER_FULL
137};
138
139enum saa7164_unit_type {
140 SAA7164_UNIT_UNDEFINED = 0,
141 SAA7164_UNIT_DIGITAL_DEMODULATOR,
142 SAA7164_UNIT_ANALOG_DEMODULATOR,
143 SAA7164_UNIT_TUNER,
144 SAA7164_UNIT_EEPROM,
145 SAA7164_UNIT_ZILOG_IRBLASTER,
146 SAA7164_UNIT_ENCODER,
147};
148
149/* The PCIe bridge doesn't grant direct access to i2c.
150 * Instead, you address i2c devices using a uniqely
151 * allocated 'unitid' value via a messaging API. This
152 * is a problem. The kernel and existing demod/tuner
153 * drivers expect to talk 'i2c', so we have to maintain
154 * a translation layer, and a series of functions to
155 * convert i2c bus + device address into a unit id.
156 */
157struct saa7164_unit {
158 enum saa7164_unit_type type;
159 u8 id;
160 char *name;
161 enum saa7164_i2c_bus_nr i2c_bus_nr;
162 u8 i2c_bus_addr;
163 u8 i2c_reg_len;
164};
165
166struct saa7164_board {
167 char *name;
168 enum port_t porta, portb, portc,
169 portd, porte, portf;
170 enum {
171 SAA7164_CHIP_UNDEFINED = 0,
172 SAA7164_CHIP_REV2,
173 SAA7164_CHIP_REV3,
174 } chiprev;
175 struct saa7164_unit unit[SAA7164_MAX_UNITS];
176};
177
178struct saa7164_subid {
179 u16 subvendor;
180 u16 subdevice;
181 u32 card;
182};
183
184struct saa7164_encoder_fh {
185 struct saa7164_port *port;
186 atomic_t v4l_reading;
187};
188
189struct saa7164_vbi_fh {
190 struct saa7164_port *port;
191 atomic_t v4l_reading;
192};
193
194struct saa7164_histogram_bucket {
195 u32 val;
196 u32 count;
197 u64 update_time;
198};
199
200struct saa7164_histogram {
201 char name[32];
202 struct saa7164_histogram_bucket counter1[64];
203};
204
205struct saa7164_user_buffer {
206 struct list_head list;
207
208 /* Attributes */
209 u8 *data;
210 u32 pos;
211 u32 actual_size;
212
213 u32 crc;
214};
215
216struct saa7164_fw_status {
217
218 /* RISC Core details */
219 u32 status;
220 u32 mode;
221 u32 spec;
222 u32 inst;
223 u32 cpuload;
224 u32 remainheap;
225
226 /* Firmware version */
227 u32 version;
228 u32 major;
229 u32 sub;
230 u32 rel;
231 u32 buildnr;
232};
233
234struct saa7164_dvb {
235 struct mutex lock;
236 struct dvb_adapter adapter;
237 struct dvb_frontend *frontend;
238 struct dvb_demux demux;
239 struct dmxdev dmxdev;
240 struct dmx_frontend fe_hw;
241 struct dmx_frontend fe_mem;
242 struct dvb_net net;
243 int feeding;
244};
245
246struct saa7164_i2c {
247 struct saa7164_dev *dev;
248
249 enum saa7164_i2c_bus_nr nr;
250
251 /* I2C I/O */
252 struct i2c_adapter i2c_adap;
253 struct i2c_algo_bit_data i2c_algo;
254 struct i2c_client i2c_client;
255 u32 i2c_rc;
256};
257
258struct saa7164_ctrl {
259 struct v4l2_queryctrl v;
260};
261
262struct saa7164_tvnorm {
263 char *name;
264 v4l2_std_id id;
265};
266
267struct saa7164_encoder_params {
268 struct saa7164_tvnorm encodernorm;
269 u32 height;
270 u32 width;
271 u32 is_50hz;
272 u32 bitrate; /* bps */
273 u32 bitrate_peak; /* bps */
274 u32 bitrate_mode;
275 u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */
276
277 u32 audio_sampling_freq;
278 u32 ctl_mute;
279 u32 ctl_aspect;
280 u32 refdist;
281 u32 gop_size;
282};
283
284struct saa7164_vbi_params {
285 struct saa7164_tvnorm encodernorm;
286 u32 height;
287 u32 width;
288 u32 is_50hz;
289 u32 bitrate; /* bps */
290 u32 bitrate_peak; /* bps */
291 u32 bitrate_mode;
292 u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */
293
294 u32 audio_sampling_freq;
295 u32 ctl_mute;
296 u32 ctl_aspect;
297 u32 refdist;
298 u32 gop_size;
299};
300
301struct saa7164_port;
302
303struct saa7164_buffer {
304 struct list_head list;
305
306 /* Note of which h/w buffer list index position we occupy */
307 int idx;
308
309 struct saa7164_port *port;
310
311 /* Hardware Specific */
312 /* PCI Memory allocations */
313 enum saa7164_buffer_flags flags; /* Free, Busy, Full */
314
315 /* A block of page align PCI memory */
316 u32 pci_size; /* PCI allocation size in bytes */
317 u64 __iomem *cpu; /* Virtual address */
318 dma_addr_t dma; /* Physical address */
319 u32 crc; /* Checksum for the entire buffer data */
320
321 /* A page table that splits the block into a number of entries */
322 u32 pt_size; /* PCI allocation size in bytes */
323 u64 __iomem *pt_cpu; /* Virtual address */
324 dma_addr_t pt_dma; /* Physical address */
325
326 /* Encoder fops */
327 u32 pos;
328 u32 actual_size;
329};
330
331struct saa7164_port {
332
333 struct saa7164_dev *dev;
334 enum port_t type;
335 int nr;
336
337 /* --- Generic port attributes --- */
338
339 /* HW stream parameters */
340 struct tmHWStreamParameters hw_streamingparams;
341
342 /* DMA configuration values, is seeded during initialization */
343 struct tmComResDMATermDescrHeader hwcfg;
344
345 /* hardware specific registers */
346 u32 bufcounter;
347 u32 pitch;
348 u32 bufsize;
349 u32 bufoffset;
350 u32 bufptr32l;
351 u32 bufptr32h;
352 u64 bufptr64;
353
354 u32 numpte; /* Number of entries in array, only valid in head */
355
356 struct mutex dmaqueue_lock;
357 struct saa7164_buffer dmaqueue;
358
359 u64 last_irq_msecs, last_svc_msecs;
360 u64 last_irq_msecs_diff, last_svc_msecs_diff;
361 u32 last_svc_wp;
362 u32 last_svc_rp;
363 u64 last_irq_svc_msecs_diff;
364 u64 last_read_msecs, last_read_msecs_diff;
365 u64 last_poll_msecs, last_poll_msecs_diff;
366
367 struct saa7164_histogram irq_interval;
368 struct saa7164_histogram svc_interval;
369 struct saa7164_histogram irq_svc_interval;
370 struct saa7164_histogram read_interval;
371 struct saa7164_histogram poll_interval;
372
373 /* --- DVB Transport Specific --- */
374 struct saa7164_dvb dvb;
375
376 /* --- Encoder/V4L related attributes --- */
377 /* Encoder */
378 /* Defaults established in saa7164-encoder.c */
379 struct saa7164_tvnorm encodernorm;
380 u32 height;
381 u32 width;
382 u32 freq;
383 u32 ts_packet_size;
384 u32 ts_packet_count;
385 u8 mux_input;
386 u8 encoder_profile;
387 u8 video_format;
388 u8 audio_format;
389 u8 video_resolution;
390 u16 ctl_brightness;
391 u16 ctl_contrast;
392 u16 ctl_hue;
393 u16 ctl_saturation;
394 u16 ctl_sharpness;
395 s8 ctl_volume;
396
397 struct tmComResAFeatureDescrHeader audfeat;
398 struct tmComResEncoderDescrHeader encunit;
399 struct tmComResProcDescrHeader vidproc;
400 struct tmComResExtDevDescrHeader ifunit;
401 struct tmComResTunerDescrHeader tunerunit;
402
403 struct work_struct workenc;
404
405 /* V4L Encoder Video */
406 struct saa7164_encoder_params encoder_params;
407 struct video_device *v4l_device;
408 atomic_t v4l_reader_count;
409
410 struct saa7164_buffer list_buf_used;
411 struct saa7164_buffer list_buf_free;
412 wait_queue_head_t wait_read;
413
414 /* V4L VBI */
415 struct tmComResVBIFormatDescrHeader vbi_fmt_ntsc;
416 struct saa7164_vbi_params vbi_params;
417
418 /* Debug */
419 u32 sync_errors;
420 u32 v_cc_errors;
421 u32 a_cc_errors;
422 u8 last_v_cc;
423 u8 last_a_cc;
424 u32 done_first_interrupt;
425};
426
427struct saa7164_dev {
428 struct list_head devlist;
429 atomic_t refcount;
430
431 /* pci stuff */
432 struct pci_dev *pci;
433 unsigned char pci_rev, pci_lat;
434 int pci_bus, pci_slot;
435 u32 __iomem *lmmio;
436 u8 __iomem *bmmio;
437 u32 __iomem *lmmio2;
438 u8 __iomem *bmmio2;
439 int pci_irqmask;
440
441 /* board details */
442 int nr;
443 int hwrevision;
444 u32 board;
445 char name[16];
446
447 /* firmware status */
448 struct saa7164_fw_status fw_status;
449 u32 firmwareloaded;
450
451 struct tmComResHWDescr hwdesc;
452 struct tmComResInterfaceDescr intfdesc;
453 struct tmComResBusDescr busdesc;
454
455 struct tmComResBusInfo bus;
456
457 /* Interrupt status and ack registers */
458 u32 int_status;
459 u32 int_ack;
460
461 struct cmd cmds[SAA_CMD_MAX_MSG_UNITS];
462 struct mutex lock;
463
464 /* I2c related */
465 struct saa7164_i2c i2c_bus[3];
466
467 /* Transport related */
468 struct saa7164_port ports[SAA7164_MAX_PORTS];
469
470 /* Deferred command/api interrupts handling */
471 struct work_struct workcmd;
472
473 /* A kernel thread to monitor the firmware log, used
474 * only in debug mode.
475 */
476 struct task_struct *kthread;
477
478};
479
480extern struct list_head saa7164_devlist;
481extern unsigned int waitsecs;
482extern unsigned int encoder_buffers;
483extern unsigned int vbi_buffers;
484
485/* ----------------------------------------------------------- */
486/* saa7164-core.c */
487void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr);
488void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len);
489void saa7164_getfirmwarestatus(struct saa7164_dev *dev);
490u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev);
491void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val);
492
493/* ----------------------------------------------------------- */
494/* saa7164-fw.c */
495int saa7164_downloadfirmware(struct saa7164_dev *dev);
496
497/* ----------------------------------------------------------- */
498/* saa7164-i2c.c */
499extern int saa7164_i2c_register(struct saa7164_i2c *bus);
500extern int saa7164_i2c_unregister(struct saa7164_i2c *bus);
501extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus,
502 unsigned int cmd, void *arg);
503
504/* ----------------------------------------------------------- */
505/* saa7164-bus.c */
506int saa7164_bus_setup(struct saa7164_dev *dev);
507void saa7164_bus_dump(struct saa7164_dev *dev);
508int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
509 void *buf);
510int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
511 void *buf, int peekonly);
512
513/* ----------------------------------------------------------- */
514/* saa7164-cmd.c */
515int saa7164_cmd_send(struct saa7164_dev *dev,
516 u8 id, enum tmComResCmd command, u16 controlselector,
517 u16 size, void *buf);
518void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
519int saa7164_irq_dequeue(struct saa7164_dev *dev);
520
521/* ----------------------------------------------------------- */
522/* saa7164-api.c */
523int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version);
524int saa7164_api_enum_subdevs(struct saa7164_dev *dev);
525int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
526 u32 datalen, u8 *data);
527int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr,
528 u32 datalen, u8 *data);
529int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr,
530 u32 datalen, u8 *data);
531int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen);
532int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
533int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
534int saa7164_api_transition_port(struct saa7164_port *port, u8 mode);
535int saa7164_api_initialize_dif(struct saa7164_port *port);
536int saa7164_api_configure_dif(struct saa7164_port *port, u32 std);
537int saa7164_api_set_encoder(struct saa7164_port *port);
538int saa7164_api_get_encoder(struct saa7164_port *port);
539int saa7164_api_set_aspect_ratio(struct saa7164_port *port);
540int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl);
541int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl);
542int saa7164_api_set_videomux(struct saa7164_port *port);
543int saa7164_api_audio_mute(struct saa7164_port *port, int mute);
544int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level);
545int saa7164_api_set_audio_std(struct saa7164_port *port);
546int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect);
547int saa7164_api_get_videomux(struct saa7164_port *port);
548int saa7164_api_set_vbi_format(struct saa7164_port *port);
549int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level);
550int saa7164_api_collect_debug(struct saa7164_dev *dev);
551int saa7164_api_get_load_info(struct saa7164_dev *dev,
552 struct tmFwInfoStruct *i);
553
554/* ----------------------------------------------------------- */
555/* saa7164-cards.c */
556extern struct saa7164_board saa7164_boards[];
557extern const unsigned int saa7164_bcount;
558
559extern struct saa7164_subid saa7164_subids[];
560extern const unsigned int saa7164_idcount;
561
562extern void saa7164_card_list(struct saa7164_dev *dev);
563extern void saa7164_gpio_setup(struct saa7164_dev *dev);
564extern void saa7164_card_setup(struct saa7164_dev *dev);
565
566extern int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr);
567extern int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr);
568extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid);
569
570/* ----------------------------------------------------------- */
571/* saa7164-dvb.c */
572extern int saa7164_dvb_register(struct saa7164_port *port);
573extern int saa7164_dvb_unregister(struct saa7164_port *port);
574
575/* ----------------------------------------------------------- */
576/* saa7164-buffer.c */
577extern struct saa7164_buffer *saa7164_buffer_alloc(
578 struct saa7164_port *port, u32 len);
579extern int saa7164_buffer_dealloc(struct saa7164_buffer *buf);
580extern void saa7164_buffer_display(struct saa7164_buffer *buf);
581extern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i);
582extern int saa7164_buffer_cfg_port(struct saa7164_port *port);
583extern struct saa7164_user_buffer *saa7164_buffer_alloc_user(
584 struct saa7164_dev *dev, u32 len);
585extern void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf);
586extern int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i);
587
588/* ----------------------------------------------------------- */
589/* saa7164-encoder.c */
590int saa7164_encoder_register(struct saa7164_port *port);
591void saa7164_encoder_unregister(struct saa7164_port *port);
592
593/* ----------------------------------------------------------- */
594/* saa7164-vbi.c */
595int saa7164_vbi_register(struct saa7164_port *port);
596void saa7164_vbi_unregister(struct saa7164_port *port);
597
598/* ----------------------------------------------------------- */
599
600extern unsigned int crc_checking;
601
602extern unsigned int saa_debug;
603#define dprintk(level, fmt, arg...)\
604 do { if (saa_debug & level)\
605 printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
606 } while (0)
607
608#define log_warn(fmt, arg...)\
609 do { \
610 printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\
611 } while (0)
612
613#define log_err(fmt, arg...)\
614 do { \
615 printk(KERN_ERROR "%s: " fmt, dev->name, ## arg);\
616 } while (0)
617
618#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2))
619#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
620
621#define saa7164_readb(reg) readl(dev->bmmio + (reg))
622#define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg))
623