1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Driver for the NXP SAA7164 PCIe bridge
4 *
5 * Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
6 */
7
8 #include <linux/wait.h>
9 #include <linux/slab.h>
10
11 #include "saa7164.h"
12
saa7164_api_get_load_info(struct saa7164_dev * dev,struct tmFwInfoStruct * i)13 int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i)
14 {
15 int ret;
16
17 if (!(saa_debug & DBGLVL_CPU))
18 return 0;
19
20 dprintk(DBGLVL_API, "%s()\n", __func__);
21
22 i->deviceinst = 0;
23 i->devicespec = 0;
24 i->mode = 0;
25 i->status = 0;
26
27 ret = saa7164_cmd_send(dev, 0, GET_CUR,
28 GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i);
29 if (ret != SAA_OK)
30 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
31
32 printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad);
33
34 return ret;
35 }
36
saa7164_api_collect_debug(struct saa7164_dev * dev)37 int saa7164_api_collect_debug(struct saa7164_dev *dev)
38 {
39 struct tmComResDebugGetData d;
40 u8 more = 255;
41 int ret;
42
43 dprintk(DBGLVL_API, "%s()\n", __func__);
44
45 while (more--) {
46
47 memset(&d, 0, sizeof(d));
48
49 ret = saa7164_cmd_send(dev, 0, GET_CUR,
50 GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
51 if (ret != SAA_OK)
52 printk(KERN_ERR "%s() error, ret = 0x%x\n",
53 __func__, ret);
54
55 if (d.dwResult != SAA_OK)
56 break;
57
58 printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr,
59 d.ucDebugData);
60 }
61
62 return 0;
63 }
64
saa7164_api_set_debug(struct saa7164_dev * dev,u8 level)65 int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
66 {
67 struct tmComResDebugSetLevel lvl;
68 int ret;
69
70 dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level);
71
72 /* Retrieve current state */
73 ret = saa7164_cmd_send(dev, 0, GET_CUR,
74 SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
75 if (ret != SAA_OK)
76 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
77
78 dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
79
80 lvl.dwDebugLevel = level;
81
82 /* set new state */
83 ret = saa7164_cmd_send(dev, 0, SET_CUR,
84 SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
85 if (ret != SAA_OK)
86 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
87
88 return ret;
89 }
90
saa7164_api_set_vbi_format(struct saa7164_port * port)91 int saa7164_api_set_vbi_format(struct saa7164_port *port)
92 {
93 struct saa7164_dev *dev = port->dev;
94 struct tmComResProbeCommit fmt, rsp;
95 int ret;
96
97 dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__,
98 port->nr, port->hwcfg.unitid);
99
100 fmt.bmHint = 0;
101 fmt.bFormatIndex = 1;
102 fmt.bFrameIndex = 1;
103
104 /* Probe, see if it can support this format */
105 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
106 SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt);
107 if (ret != SAA_OK)
108 printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret);
109
110 /* See of the format change was successful */
111 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
112 GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp);
113 if (ret != SAA_OK) {
114 printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret);
115 } else {
116 /* Compare requested vs received, should be same */
117 if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
118 dprintk(DBGLVL_API, "SET/PROBE Verified\n");
119
120 /* Ask the device to select the negotiated format */
121 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
122 SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
123 if (ret != SAA_OK)
124 printk(KERN_ERR "%s() commit error, ret = 0x%x\n",
125 __func__, ret);
126
127 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
128 GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp);
129 if (ret != SAA_OK)
130 printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
131 __func__, ret);
132
133 if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) {
134 printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
135 __func__, ret);
136 } else
137 dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
138
139 dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
140 dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n",
141 rsp.bFormatIndex);
142 dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n",
143 rsp.bFrameIndex);
144 } else
145 printk(KERN_ERR "%s() compare failed\n", __func__);
146 }
147
148 if (ret == SAA_OK)
149 dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr);
150
151 return ret;
152 }
153
saa7164_api_set_gop_size(struct saa7164_port * port)154 static int saa7164_api_set_gop_size(struct saa7164_port *port)
155 {
156 struct saa7164_dev *dev = port->dev;
157 struct tmComResEncVideoGopStructure gs;
158 int ret;
159
160 dprintk(DBGLVL_ENC, "%s()\n", __func__);
161
162 gs.ucRefFrameDist = port->encoder_params.refdist;
163 gs.ucGOPSize = port->encoder_params.gop_size;
164 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
165 EU_VIDEO_GOP_STRUCTURE_CONTROL,
166 sizeof(gs), &gs);
167 if (ret != SAA_OK)
168 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
169
170 return ret;
171 }
172
saa7164_api_set_encoder(struct saa7164_port * port)173 int saa7164_api_set_encoder(struct saa7164_port *port)
174 {
175 struct saa7164_dev *dev = port->dev;
176 struct tmComResEncVideoBitRate vb;
177 struct tmComResEncAudioBitRate ab;
178 int ret;
179
180 dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
181 port->hwcfg.sourceid);
182
183 if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
184 port->encoder_profile = EU_PROFILE_PS_DVD;
185 else
186 port->encoder_profile = EU_PROFILE_TS_HQ;
187
188 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
189 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
190 if (ret != SAA_OK)
191 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
192
193 /* Resolution */
194 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
195 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
196 if (ret != SAA_OK)
197 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
198
199 /* Establish video bitrates */
200 if (port->encoder_params.bitrate_mode ==
201 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
202 vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT;
203 else
204 vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK;
205 vb.dwVideoBitRate = port->encoder_params.bitrate;
206 vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak;
207 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
208 EU_VIDEO_BIT_RATE_CONTROL,
209 sizeof(struct tmComResEncVideoBitRate),
210 &vb);
211 if (ret != SAA_OK)
212 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
213
214 /* Establish audio bitrates */
215 ab.ucAudioBitRateMode = 0;
216 ab.dwAudioBitRate = 384000;
217 ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
218 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
219 EU_AUDIO_BIT_RATE_CONTROL,
220 sizeof(struct tmComResEncAudioBitRate),
221 &ab);
222 if (ret != SAA_OK)
223 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
224 ret);
225
226 saa7164_api_set_aspect_ratio(port);
227 saa7164_api_set_gop_size(port);
228
229 return ret;
230 }
231
saa7164_api_get_encoder(struct saa7164_port * port)232 int saa7164_api_get_encoder(struct saa7164_port *port)
233 {
234 struct saa7164_dev *dev = port->dev;
235 struct tmComResEncVideoBitRate v;
236 struct tmComResEncAudioBitRate a;
237 struct tmComResEncVideoInputAspectRatio ar;
238 int ret;
239
240 dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
241 port->hwcfg.sourceid);
242
243 port->encoder_profile = 0;
244 port->video_format = 0;
245 port->video_resolution = 0;
246 port->audio_format = 0;
247
248 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
249 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
250 if (ret != SAA_OK)
251 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
252
253 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
254 EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8),
255 &port->video_resolution);
256 if (ret != SAA_OK)
257 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
258
259 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
260 EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format);
261 if (ret != SAA_OK)
262 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
263
264 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
265 EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v);
266 if (ret != SAA_OK)
267 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
268
269 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
270 EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format);
271 if (ret != SAA_OK)
272 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
273
274 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
275 EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a);
276 if (ret != SAA_OK)
277 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
278
279 /* Aspect Ratio */
280 ar.width = 0;
281 ar.height = 0;
282 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
283 EU_VIDEO_INPUT_ASPECT_CONTROL,
284 sizeof(struct tmComResEncVideoInputAspectRatio), &ar);
285 if (ret != SAA_OK)
286 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
287
288 dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile);
289 dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format);
290 dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format);
291 dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
292 dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n",
293 v.ucVideoBitRateMode);
294 dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n",
295 v.dwVideoBitRate);
296 dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n",
297 v.dwVideoBitRatePeak);
298 dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n",
299 a.ucAudioBitRateMode);
300 dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n",
301 a.dwAudioBitRate);
302 dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n",
303 a.dwAudioBitRatePeak);
304 dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n",
305 ar.width, ar.height);
306
307 return ret;
308 }
309
saa7164_api_set_aspect_ratio(struct saa7164_port * port)310 int saa7164_api_set_aspect_ratio(struct saa7164_port *port)
311 {
312 struct saa7164_dev *dev = port->dev;
313 struct tmComResEncVideoInputAspectRatio ar;
314 int ret;
315
316 dprintk(DBGLVL_ENC, "%s(%d)\n", __func__,
317 port->encoder_params.ctl_aspect);
318
319 switch (port->encoder_params.ctl_aspect) {
320 case V4L2_MPEG_VIDEO_ASPECT_1x1:
321 ar.width = 1;
322 ar.height = 1;
323 break;
324 case V4L2_MPEG_VIDEO_ASPECT_4x3:
325 ar.width = 4;
326 ar.height = 3;
327 break;
328 case V4L2_MPEG_VIDEO_ASPECT_16x9:
329 ar.width = 16;
330 ar.height = 9;
331 break;
332 case V4L2_MPEG_VIDEO_ASPECT_221x100:
333 ar.width = 221;
334 ar.height = 100;
335 break;
336 default:
337 BUG();
338 }
339
340 dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__,
341 port->encoder_params.ctl_aspect,
342 ar.width, ar.height);
343
344 /* Aspect Ratio */
345 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
346 EU_VIDEO_INPUT_ASPECT_CONTROL,
347 sizeof(struct tmComResEncVideoInputAspectRatio), &ar);
348 if (ret != SAA_OK)
349 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
350
351 return ret;
352 }
353
saa7164_api_set_usercontrol(struct saa7164_port * port,u8 ctl)354 int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl)
355 {
356 struct saa7164_dev *dev = port->dev;
357 int ret;
358 u16 val;
359
360 if (ctl == PU_BRIGHTNESS_CONTROL)
361 val = port->ctl_brightness;
362 else
363 if (ctl == PU_CONTRAST_CONTROL)
364 val = port->ctl_contrast;
365 else
366 if (ctl == PU_HUE_CONTROL)
367 val = port->ctl_hue;
368 else
369 if (ctl == PU_SATURATION_CONTROL)
370 val = port->ctl_saturation;
371 else
372 if (ctl == PU_SHARPNESS_CONTROL)
373 val = port->ctl_sharpness;
374 else
375 return -EINVAL;
376
377 dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n",
378 __func__, port->encunit.vsourceid, ctl, val);
379
380 ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR,
381 ctl, sizeof(u16), &val);
382 if (ret != SAA_OK)
383 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
384
385 return ret;
386 }
387
saa7164_api_get_usercontrol(struct saa7164_port * port,u8 ctl)388 int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl)
389 {
390 struct saa7164_dev *dev = port->dev;
391 int ret;
392 u16 val;
393
394 ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR,
395 ctl, sizeof(u16), &val);
396 if (ret != SAA_OK) {
397 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
398 return ret;
399 }
400
401 dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n",
402 __func__, ctl, val);
403
404 if (ctl == PU_BRIGHTNESS_CONTROL)
405 port->ctl_brightness = val;
406 else
407 if (ctl == PU_CONTRAST_CONTROL)
408 port->ctl_contrast = val;
409 else
410 if (ctl == PU_HUE_CONTROL)
411 port->ctl_hue = val;
412 else
413 if (ctl == PU_SATURATION_CONTROL)
414 port->ctl_saturation = val;
415 else
416 if (ctl == PU_SHARPNESS_CONTROL)
417 port->ctl_sharpness = val;
418
419 return ret;
420 }
421
saa7164_api_set_videomux(struct saa7164_port * port)422 int saa7164_api_set_videomux(struct saa7164_port *port)
423 {
424 struct saa7164_dev *dev = port->dev;
425 u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 };
426 int ret;
427
428 dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n",
429 __func__, port->mux_input, inputs[port->mux_input - 1]);
430
431 /* Audio Mute */
432 ret = saa7164_api_audio_mute(port, 1);
433 if (ret != SAA_OK)
434 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
435
436 /* Video Mux */
437 ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR,
438 SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
439 if (ret != SAA_OK)
440 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
441
442 /* Audio Mux */
443 ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
444 SU_INPUT_SELECT_CONTROL, sizeof(u8),
445 &inputs[port->mux_input - 1]);
446 if (ret != SAA_OK)
447 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
448
449 /* Audio UnMute */
450 ret = saa7164_api_audio_mute(port, 0);
451 if (ret != SAA_OK)
452 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
453
454 return ret;
455 }
456
saa7164_api_audio_mute(struct saa7164_port * port,int mute)457 int saa7164_api_audio_mute(struct saa7164_port *port, int mute)
458 {
459 struct saa7164_dev *dev = port->dev;
460 u8 v = mute;
461 int ret;
462
463 dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute);
464
465 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
466 MUTE_CONTROL, sizeof(u8), &v);
467 if (ret != SAA_OK)
468 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
469
470 return ret;
471 }
472
473 /* 0 = silence, 0xff = full */
saa7164_api_set_audio_volume(struct saa7164_port * port,s8 level)474 int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
475 {
476 struct saa7164_dev *dev = port->dev;
477 s16 v, min, max;
478 int ret;
479
480 dprintk(DBGLVL_API, "%s(%d)\n", __func__, level);
481
482 /* Obtain the min/max ranges */
483 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN,
484 VOLUME_CONTROL, sizeof(u16), &min);
485 if (ret != SAA_OK)
486 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
487
488 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX,
489 VOLUME_CONTROL, sizeof(u16), &max);
490 if (ret != SAA_OK)
491 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
492
493 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
494 (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
495 if (ret != SAA_OK)
496 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
497
498 dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
499 level, min, max, v);
500
501 v = level;
502 if (v < min)
503 v = min;
504 if (v > max)
505 v = max;
506
507 /* Left */
508 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
509 (0x01 << 8) | VOLUME_CONTROL, sizeof(s16), &v);
510 if (ret != SAA_OK)
511 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
512
513 /* Right */
514 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
515 (0x02 << 8) | VOLUME_CONTROL, sizeof(s16), &v);
516 if (ret != SAA_OK)
517 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
518
519 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
520 (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
521 if (ret != SAA_OK)
522 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
523
524 dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
525 level, min, max, v);
526
527 return ret;
528 }
529
saa7164_api_set_audio_std(struct saa7164_port * port)530 int saa7164_api_set_audio_std(struct saa7164_port *port)
531 {
532 struct saa7164_dev *dev = port->dev;
533 struct tmComResAudioDefaults lvl;
534 struct tmComResTunerStandard tvaudio;
535 int ret;
536
537 dprintk(DBGLVL_API, "%s()\n", __func__);
538
539 /* Establish default levels */
540 lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT;
541 lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT;
542 lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT;
543 lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT;
544 lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
545 lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
546 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
547 AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults),
548 &lvl);
549 if (ret != SAA_OK)
550 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
551
552 /* Manually select the appropriate TV audio standard */
553 if (port->encodernorm.id & V4L2_STD_NTSC) {
554 tvaudio.std = TU_STANDARD_NTSC_M;
555 tvaudio.country = 1;
556 } else {
557 tvaudio.std = TU_STANDARD_PAL_I;
558 tvaudio.country = 44;
559 }
560
561 ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
562 TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
563 if (ret != SAA_OK)
564 printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n",
565 __func__, ret);
566 return ret;
567 }
568
saa7164_api_set_audio_detection(struct saa7164_port * port,int autodetect)569 int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
570 {
571 struct saa7164_dev *dev = port->dev;
572 struct tmComResTunerStandardAuto p;
573 int ret;
574
575 dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect);
576
577 /* Disable TV Audio autodetect if not already set (buggy) */
578 if (autodetect)
579 p.mode = TU_STANDARD_AUTO;
580 else
581 p.mode = TU_STANDARD_MANUAL;
582 ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
583 TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
584 if (ret != SAA_OK)
585 printk(KERN_ERR
586 "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n",
587 __func__, ret);
588
589 return ret;
590 }
591
saa7164_api_get_videomux(struct saa7164_port * port)592 int saa7164_api_get_videomux(struct saa7164_port *port)
593 {
594 struct saa7164_dev *dev = port->dev;
595 int ret;
596
597 ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR,
598 SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
599 if (ret != SAA_OK)
600 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
601
602 dprintk(DBGLVL_ENC, "%s() v_mux=%d\n",
603 __func__, port->mux_input);
604
605 return ret;
606 }
607
saa7164_api_set_dif(struct saa7164_port * port,u8 reg,u8 val)608 static int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
609 {
610 struct saa7164_dev *dev = port->dev;
611
612 u16 len = 0;
613 u8 buf[256];
614 int ret;
615 u8 mas;
616
617 dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__,
618 port->nr, port->type, val);
619
620 if (port->nr == 0)
621 mas = 0xd0;
622 else
623 mas = 0xe0;
624
625 memset(buf, 0, sizeof(buf));
626
627 buf[0x00] = 0x04;
628 buf[0x01] = 0x00;
629 buf[0x02] = 0x00;
630 buf[0x03] = 0x00;
631
632 buf[0x04] = 0x04;
633 buf[0x05] = 0x00;
634 buf[0x06] = 0x00;
635 buf[0x07] = 0x00;
636
637 buf[0x08] = reg;
638 buf[0x09] = 0x26;
639 buf[0x0a] = mas;
640 buf[0x0b] = 0xb0;
641
642 buf[0x0c] = val;
643 buf[0x0d] = 0x00;
644 buf[0x0e] = 0x00;
645 buf[0x0f] = 0x00;
646
647 ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN,
648 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
649 if (ret != SAA_OK) {
650 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
651 return -EIO;
652 }
653
654 ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR,
655 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
656 if (ret != SAA_OK)
657 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
658 #if 0
659 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, 16,
660 false);
661 #endif
662 return ret == SAA_OK ? 0 : -EIO;
663 }
664
665 /* Disable the IF block AGC controls */
saa7164_api_configure_dif(struct saa7164_port * port,u32 std)666 int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
667 {
668 struct saa7164_dev *dev = port->dev;
669 u8 agc_disable;
670
671 dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std);
672
673 if (std & V4L2_STD_NTSC) {
674 dprintk(DBGLVL_API, " NTSC\n");
675 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
676 agc_disable = 0;
677 } else if (std & V4L2_STD_PAL_I) {
678 dprintk(DBGLVL_API, " PAL-I\n");
679 saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */
680 agc_disable = 0;
681 } else if (std & V4L2_STD_PAL_M) {
682 dprintk(DBGLVL_API, " PAL-M\n");
683 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
684 agc_disable = 0;
685 } else if (std & V4L2_STD_PAL_N) {
686 dprintk(DBGLVL_API, " PAL-N\n");
687 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
688 agc_disable = 0;
689 } else if (std & V4L2_STD_PAL_Nc) {
690 dprintk(DBGLVL_API, " PAL-Nc\n");
691 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
692 agc_disable = 0;
693 } else if (std & V4L2_STD_PAL_B) {
694 dprintk(DBGLVL_API, " PAL-B\n");
695 saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */
696 agc_disable = 0;
697 } else if (std & V4L2_STD_PAL_DK) {
698 dprintk(DBGLVL_API, " PAL-DK\n");
699 saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */
700 agc_disable = 0;
701 } else if (std & V4L2_STD_SECAM_L) {
702 dprintk(DBGLVL_API, " SECAM-L\n");
703 saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */
704 agc_disable = 0;
705 } else {
706 /* Unknown standard, assume DTV */
707 dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
708 /* Undefinded Video Standard */
709 saa7164_api_set_dif(port, 0x00, 0x80);
710 agc_disable = 1;
711 }
712
713 saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */
714 saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */
715 saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */
716 saa7164_api_set_dif(port, 0x04, 0x01); /* Active */
717 msleep(100);
718 saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */
719 msleep(100);
720
721 return 0;
722 }
723
724 /* Ensure the dif is in the correct state for the operating mode
725 * (analog / dtv). We only configure the diff through the analog encoder
726 * so when we're in digital mode we need to find the appropriate encoder
727 * and use it to configure the DIF.
728 */
saa7164_api_initialize_dif(struct saa7164_port * port)729 int saa7164_api_initialize_dif(struct saa7164_port *port)
730 {
731 struct saa7164_dev *dev = port->dev;
732 struct saa7164_port *p = NULL;
733 int ret = -EINVAL;
734 u32 std = 0;
735
736 dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__,
737 port->nr, port->type);
738
739 if (port->type == SAA7164_MPEG_ENCODER) {
740 /* Pick any analog standard to init the diff.
741 * we'll come back during encoder_init'
742 * and set the correct standard if required.
743 */
744 std = V4L2_STD_NTSC;
745 } else
746 if (port->type == SAA7164_MPEG_DVB) {
747 if (port->nr == SAA7164_PORT_TS1)
748 p = &dev->ports[SAA7164_PORT_ENC1];
749 else
750 p = &dev->ports[SAA7164_PORT_ENC2];
751 } else
752 if (port->type == SAA7164_MPEG_VBI) {
753 std = V4L2_STD_NTSC;
754 if (port->nr == SAA7164_PORT_VBI1)
755 p = &dev->ports[SAA7164_PORT_ENC1];
756 else
757 p = &dev->ports[SAA7164_PORT_ENC2];
758 } else
759 BUG();
760
761 if (p)
762 ret = saa7164_api_configure_dif(p, std);
763
764 return ret;
765 }
766
saa7164_api_transition_port(struct saa7164_port * port,u8 mode)767 int saa7164_api_transition_port(struct saa7164_port *port, u8 mode)
768 {
769 struct saa7164_dev *dev = port->dev;
770
771 int ret;
772
773 dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n",
774 __func__, port->nr, port->hwcfg.unitid, mode);
775
776 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
777 SAA_STATE_CONTROL, sizeof(mode), &mode);
778 if (ret != SAA_OK)
779 printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n",
780 __func__, port->nr, port->hwcfg.unitid, ret);
781
782 return ret;
783 }
784
saa7164_api_get_fw_version(struct saa7164_dev * dev,u32 * version)785 int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
786 {
787 int ret;
788
789 ret = saa7164_cmd_send(dev, 0, GET_CUR,
790 GET_FW_VERSION_CONTROL, sizeof(u32), version);
791 if (ret != SAA_OK)
792 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
793
794 return ret;
795 }
796
saa7164_api_read_eeprom(struct saa7164_dev * dev,u8 * buf,int buflen)797 int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
798 {
799 u8 reg[] = { 0x0f, 0x00 };
800
801 if (buflen < 128)
802 return -ENOMEM;
803
804 /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
805 /* TODO: Pull the details from the boards struct */
806 return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
807 ®[0], 128, buf);
808 }
809
saa7164_api_configure_port_vbi(struct saa7164_dev * dev,struct saa7164_port * port)810 static int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
811 struct saa7164_port *port)
812 {
813 struct tmComResVBIFormatDescrHeader *fmt = &port->vbi_fmt_ntsc;
814
815 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
816 dprintk(DBGLVL_API, " VideoStandard = 0x%x\n", fmt->VideoStandard);
817 dprintk(DBGLVL_API, " StartLine = %d\n", fmt->StartLine);
818 dprintk(DBGLVL_API, " EndLine = %d\n", fmt->EndLine);
819 dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate);
820 dprintk(DBGLVL_API, " bNumLines = %d\n", fmt->bNumLines);
821
822 /* Cache the hardware configuration in the port */
823
824 port->bufcounter = port->hwcfg.BARLocation;
825 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
826 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
827 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
828 port->bufptr32l = port->hwcfg.BARLocation +
829 (4 * sizeof(u32)) +
830 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
831 port->bufptr32h = port->hwcfg.BARLocation +
832 (4 * sizeof(u32)) +
833 (sizeof(u32) * port->hwcfg.buffercount);
834 port->bufptr64 = port->hwcfg.BARLocation +
835 (4 * sizeof(u32)) +
836 (sizeof(u32) * port->hwcfg.buffercount);
837 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
838 port->hwcfg.BARLocation);
839
840 dprintk(DBGLVL_API, " = VS_FORMAT_VBI (becomes dev->en[%d])\n",
841 port->nr);
842
843 return 0;
844 }
845
846 static int
saa7164_api_configure_port_mpeg2ts(struct saa7164_dev * dev,struct saa7164_port * port,struct tmComResTSFormatDescrHeader * tsfmt)847 saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
848 struct saa7164_port *port,
849 struct tmComResTSFormatDescrHeader *tsfmt)
850 {
851 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
852 dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
853 dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
854 dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
855 dprintk(DBGLVL_API, " bguid = (....)\n");
856
857 /* Cache the hardware configuration in the port */
858
859 port->bufcounter = port->hwcfg.BARLocation;
860 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
861 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
862 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
863 port->bufptr32l = port->hwcfg.BARLocation +
864 (4 * sizeof(u32)) +
865 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
866 port->bufptr32h = port->hwcfg.BARLocation +
867 (4 * sizeof(u32)) +
868 (sizeof(u32) * port->hwcfg.buffercount);
869 port->bufptr64 = port->hwcfg.BARLocation +
870 (4 * sizeof(u32)) +
871 (sizeof(u32) * port->hwcfg.buffercount);
872 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
873 port->hwcfg.BARLocation);
874
875 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
876 port->nr);
877
878 return 0;
879 }
880
881 static int
saa7164_api_configure_port_mpeg2ps(struct saa7164_dev * dev,struct saa7164_port * port,struct tmComResPSFormatDescrHeader * fmt)882 saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
883 struct saa7164_port *port,
884 struct tmComResPSFormatDescrHeader *fmt)
885 {
886 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
887 dprintk(DBGLVL_API, " wPacketLength= 0x%x\n", fmt->wPacketLength);
888 dprintk(DBGLVL_API, " wPackLength= 0x%x\n", fmt->wPackLength);
889 dprintk(DBGLVL_API, " bPackDataType= 0x%x\n", fmt->bPackDataType);
890
891 /* Cache the hardware configuration in the port */
892 /* TODO: CHECK THIS in the port config */
893 port->bufcounter = port->hwcfg.BARLocation;
894 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
895 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
896 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
897 port->bufptr32l = port->hwcfg.BARLocation +
898 (4 * sizeof(u32)) +
899 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
900 port->bufptr32h = port->hwcfg.BARLocation +
901 (4 * sizeof(u32)) +
902 (sizeof(u32) * port->hwcfg.buffercount);
903 port->bufptr64 = port->hwcfg.BARLocation +
904 (4 * sizeof(u32)) +
905 (sizeof(u32) * port->hwcfg.buffercount);
906 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
907 port->hwcfg.BARLocation);
908
909 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n",
910 port->nr);
911
912 return 0;
913 }
914
saa7164_api_dump_subdevs(struct saa7164_dev * dev,u8 * buf,int len)915 static int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
916 {
917 struct saa7164_port *tsport = NULL;
918 struct saa7164_port *encport = NULL;
919 struct saa7164_port *vbiport = NULL;
920 u32 idx, next_offset;
921 int i;
922 struct tmComResDescrHeader *hdr, *t;
923 struct tmComResExtDevDescrHeader *exthdr;
924 struct tmComResPathDescrHeader *pathhdr;
925 struct tmComResAntTermDescrHeader *anttermhdr;
926 struct tmComResTunerDescrHeader *tunerunithdr;
927 struct tmComResDMATermDescrHeader *vcoutputtermhdr;
928 struct tmComResTSFormatDescrHeader *tsfmt;
929 struct tmComResPSFormatDescrHeader *psfmt;
930 struct tmComResSelDescrHeader *psel;
931 struct tmComResProcDescrHeader *pdh;
932 struct tmComResAFeatureDescrHeader *afd;
933 struct tmComResEncoderDescrHeader *edh;
934 struct tmComResVBIFormatDescrHeader *vbifmt;
935 u32 currpath = 0;
936
937 dprintk(DBGLVL_API,
938 "%s(?,?,%d) sizeof(struct tmComResDescrHeader) = %d bytes\n",
939 __func__, len, (u32)sizeof(struct tmComResDescrHeader));
940
941 for (idx = 0; idx < (len - sizeof(struct tmComResDescrHeader));) {
942
943 hdr = (struct tmComResDescrHeader *)(buf + idx);
944
945 if (hdr->type != CS_INTERFACE)
946 return SAA_ERR_NOT_SUPPORTED;
947
948 dprintk(DBGLVL_API, "@ 0x%x =\n", idx);
949 switch (hdr->subtype) {
950 case GENERAL_REQUEST:
951 dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
952 break;
953 case VC_TUNER_PATH:
954 dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
955 pathhdr = (struct tmComResPathDescrHeader *)(buf + idx);
956 dprintk(DBGLVL_API, " pathid = 0x%x\n",
957 pathhdr->pathid);
958 currpath = pathhdr->pathid;
959 break;
960 case VC_INPUT_TERMINAL:
961 dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
962 anttermhdr =
963 (struct tmComResAntTermDescrHeader *)(buf + idx);
964 dprintk(DBGLVL_API, " terminalid = 0x%x\n",
965 anttermhdr->terminalid);
966 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
967 anttermhdr->terminaltype);
968 switch (anttermhdr->terminaltype) {
969 case ITT_ANTENNA:
970 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
971 break;
972 case LINE_CONNECTOR:
973 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
974 break;
975 case SPDIF_CONNECTOR:
976 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
977 break;
978 case COMPOSITE_CONNECTOR:
979 dprintk(DBGLVL_API,
980 " = COMPOSITE_CONNECTOR\n");
981 break;
982 case SVIDEO_CONNECTOR:
983 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
984 break;
985 case COMPONENT_CONNECTOR:
986 dprintk(DBGLVL_API,
987 " = COMPONENT_CONNECTOR\n");
988 break;
989 case STANDARD_DMA:
990 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
991 break;
992 default:
993 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
994 anttermhdr->terminaltype);
995 }
996 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
997 anttermhdr->assocterminal);
998 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
999 anttermhdr->iterminal);
1000 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1001 anttermhdr->controlsize);
1002 break;
1003 case VC_OUTPUT_TERMINAL:
1004 dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
1005 vcoutputtermhdr =
1006 (struct tmComResDMATermDescrHeader *)(buf + idx);
1007 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1008 vcoutputtermhdr->unitid);
1009 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
1010 vcoutputtermhdr->terminaltype);
1011 switch (vcoutputtermhdr->terminaltype) {
1012 case ITT_ANTENNA:
1013 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
1014 break;
1015 case LINE_CONNECTOR:
1016 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
1017 break;
1018 case SPDIF_CONNECTOR:
1019 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
1020 break;
1021 case COMPOSITE_CONNECTOR:
1022 dprintk(DBGLVL_API,
1023 " = COMPOSITE_CONNECTOR\n");
1024 break;
1025 case SVIDEO_CONNECTOR:
1026 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
1027 break;
1028 case COMPONENT_CONNECTOR:
1029 dprintk(DBGLVL_API,
1030 " = COMPONENT_CONNECTOR\n");
1031 break;
1032 case STANDARD_DMA:
1033 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
1034 break;
1035 default:
1036 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
1037 vcoutputtermhdr->terminaltype);
1038 }
1039 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
1040 vcoutputtermhdr->assocterminal);
1041 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1042 vcoutputtermhdr->sourceid);
1043 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
1044 vcoutputtermhdr->iterminal);
1045 dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
1046 vcoutputtermhdr->BARLocation);
1047 dprintk(DBGLVL_API, " flags = 0x%x\n",
1048 vcoutputtermhdr->flags);
1049 dprintk(DBGLVL_API, " interruptid = 0x%x\n",
1050 vcoutputtermhdr->interruptid);
1051 dprintk(DBGLVL_API, " buffercount = 0x%x\n",
1052 vcoutputtermhdr->buffercount);
1053 dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
1054 vcoutputtermhdr->metadatasize);
1055 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1056 vcoutputtermhdr->controlsize);
1057 dprintk(DBGLVL_API, " numformats = 0x%x\n",
1058 vcoutputtermhdr->numformats);
1059
1060 t = (struct tmComResDescrHeader *)
1061 ((struct tmComResDMATermDescrHeader *)(buf + idx));
1062 next_offset = idx + (vcoutputtermhdr->len);
1063 for (i = 0; i < vcoutputtermhdr->numformats; i++) {
1064 t = (struct tmComResDescrHeader *)
1065 (buf + next_offset);
1066 switch (t->subtype) {
1067 case VS_FORMAT_MPEG2TS:
1068 tsfmt =
1069 (struct tmComResTSFormatDescrHeader *)t;
1070 if (currpath == 1)
1071 tsport = &dev->ports[SAA7164_PORT_TS1];
1072 else
1073 tsport = &dev->ports[SAA7164_PORT_TS2];
1074 memcpy(&tsport->hwcfg, vcoutputtermhdr,
1075 sizeof(*vcoutputtermhdr));
1076 saa7164_api_configure_port_mpeg2ts(dev,
1077 tsport, tsfmt);
1078 break;
1079 case VS_FORMAT_MPEG2PS:
1080 psfmt =
1081 (struct tmComResPSFormatDescrHeader *)t;
1082 if (currpath == 1)
1083 encport = &dev->ports[SAA7164_PORT_ENC1];
1084 else
1085 encport = &dev->ports[SAA7164_PORT_ENC2];
1086 memcpy(&encport->hwcfg, vcoutputtermhdr,
1087 sizeof(*vcoutputtermhdr));
1088 saa7164_api_configure_port_mpeg2ps(dev,
1089 encport, psfmt);
1090 break;
1091 case VS_FORMAT_VBI:
1092 vbifmt =
1093 (struct tmComResVBIFormatDescrHeader *)t;
1094 if (currpath == 1)
1095 vbiport = &dev->ports[SAA7164_PORT_VBI1];
1096 else
1097 vbiport = &dev->ports[SAA7164_PORT_VBI2];
1098 memcpy(&vbiport->hwcfg, vcoutputtermhdr,
1099 sizeof(*vcoutputtermhdr));
1100 memcpy(&vbiport->vbi_fmt_ntsc, vbifmt,
1101 sizeof(*vbifmt));
1102 saa7164_api_configure_port_vbi(dev,
1103 vbiport);
1104 break;
1105 case VS_FORMAT_RDS:
1106 dprintk(DBGLVL_API,
1107 " = VS_FORMAT_RDS\n");
1108 break;
1109 case VS_FORMAT_UNCOMPRESSED:
1110 dprintk(DBGLVL_API,
1111 " = VS_FORMAT_UNCOMPRESSED\n");
1112 break;
1113 case VS_FORMAT_TYPE:
1114 dprintk(DBGLVL_API,
1115 " = VS_FORMAT_TYPE\n");
1116 break;
1117 default:
1118 dprintk(DBGLVL_API,
1119 " = undefined (0x%x)\n",
1120 t->subtype);
1121 }
1122 next_offset += t->len;
1123 }
1124
1125 break;
1126 case TUNER_UNIT:
1127 dprintk(DBGLVL_API, " TUNER_UNIT\n");
1128 tunerunithdr =
1129 (struct tmComResTunerDescrHeader *)(buf + idx);
1130 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1131 tunerunithdr->unitid);
1132 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1133 tunerunithdr->sourceid);
1134 dprintk(DBGLVL_API, " iunit = 0x%x\n",
1135 tunerunithdr->iunit);
1136 dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
1137 tunerunithdr->tuningstandards);
1138 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1139 tunerunithdr->controlsize);
1140 dprintk(DBGLVL_API, " controls = 0x%x\n",
1141 tunerunithdr->controls);
1142
1143 if (tunerunithdr->unitid == tunerunithdr->iunit) {
1144 if (currpath == 1)
1145 encport = &dev->ports[SAA7164_PORT_ENC1];
1146 else
1147 encport = &dev->ports[SAA7164_PORT_ENC2];
1148 memcpy(&encport->tunerunit, tunerunithdr,
1149 sizeof(struct tmComResTunerDescrHeader));
1150 dprintk(DBGLVL_API,
1151 " (becomes dev->enc[%d] tuner)\n",
1152 encport->nr);
1153 }
1154 break;
1155 case VC_SELECTOR_UNIT:
1156 psel = (struct tmComResSelDescrHeader *)(buf + idx);
1157 dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
1158 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1159 psel->unitid);
1160 dprintk(DBGLVL_API, " nrinpins = 0x%x\n",
1161 psel->nrinpins);
1162 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1163 psel->sourceid);
1164 break;
1165 case VC_PROCESSING_UNIT:
1166 pdh = (struct tmComResProcDescrHeader *)(buf + idx);
1167 dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
1168 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1169 pdh->unitid);
1170 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1171 pdh->sourceid);
1172 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1173 pdh->controlsize);
1174 if (pdh->controlsize == 0x04) {
1175 if (currpath == 1)
1176 encport = &dev->ports[SAA7164_PORT_ENC1];
1177 else
1178 encport = &dev->ports[SAA7164_PORT_ENC2];
1179 memcpy(&encport->vidproc, pdh,
1180 sizeof(struct tmComResProcDescrHeader));
1181 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
1182 encport->nr);
1183 }
1184 break;
1185 case FEATURE_UNIT:
1186 afd = (struct tmComResAFeatureDescrHeader *)(buf + idx);
1187 dprintk(DBGLVL_API, " FEATURE_UNIT\n");
1188 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1189 afd->unitid);
1190 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1191 afd->sourceid);
1192 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1193 afd->controlsize);
1194 if (currpath == 1)
1195 encport = &dev->ports[SAA7164_PORT_ENC1];
1196 else
1197 encport = &dev->ports[SAA7164_PORT_ENC2];
1198 memcpy(&encport->audfeat, afd,
1199 sizeof(struct tmComResAFeatureDescrHeader));
1200 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
1201 encport->nr);
1202 break;
1203 case ENCODER_UNIT:
1204 edh = (struct tmComResEncoderDescrHeader *)(buf + idx);
1205 dprintk(DBGLVL_API, " ENCODER_UNIT\n");
1206 dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype);
1207 dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid);
1208 dprintk(DBGLVL_API, " vsourceid = 0x%x\n",
1209 edh->vsourceid);
1210 dprintk(DBGLVL_API, " asourceid = 0x%x\n",
1211 edh->asourceid);
1212 dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit);
1213 if (edh->iunit == edh->unitid) {
1214 if (currpath == 1)
1215 encport = &dev->ports[SAA7164_PORT_ENC1];
1216 else
1217 encport = &dev->ports[SAA7164_PORT_ENC2];
1218 memcpy(&encport->encunit, edh,
1219 sizeof(struct tmComResEncoderDescrHeader));
1220 dprintk(DBGLVL_API,
1221 " (becomes dev->enc[%d])\n",
1222 encport->nr);
1223 }
1224 break;
1225 case EXTENSION_UNIT:
1226 dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
1227 exthdr = (struct tmComResExtDevDescrHeader *)(buf + idx);
1228 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1229 exthdr->unitid);
1230 dprintk(DBGLVL_API, " deviceid = 0x%x\n",
1231 exthdr->deviceid);
1232 dprintk(DBGLVL_API, " devicetype = 0x%x\n",
1233 exthdr->devicetype);
1234 if (exthdr->devicetype & 0x1)
1235 dprintk(DBGLVL_API, " = Decoder Device\n");
1236 if (exthdr->devicetype & 0x2)
1237 dprintk(DBGLVL_API, " = GPIO Source\n");
1238 if (exthdr->devicetype & 0x4)
1239 dprintk(DBGLVL_API, " = Video Decoder\n");
1240 if (exthdr->devicetype & 0x8)
1241 dprintk(DBGLVL_API, " = Audio Decoder\n");
1242 if (exthdr->devicetype & 0x20)
1243 dprintk(DBGLVL_API, " = Crossbar\n");
1244 if (exthdr->devicetype & 0x40)
1245 dprintk(DBGLVL_API, " = Tuner\n");
1246 if (exthdr->devicetype & 0x80)
1247 dprintk(DBGLVL_API, " = IF PLL\n");
1248 if (exthdr->devicetype & 0x100)
1249 dprintk(DBGLVL_API, " = Demodulator\n");
1250 if (exthdr->devicetype & 0x200)
1251 dprintk(DBGLVL_API, " = RDS Decoder\n");
1252 if (exthdr->devicetype & 0x400)
1253 dprintk(DBGLVL_API, " = Encoder\n");
1254 if (exthdr->devicetype & 0x800)
1255 dprintk(DBGLVL_API, " = IR Decoder\n");
1256 if (exthdr->devicetype & 0x1000)
1257 dprintk(DBGLVL_API, " = EEPROM\n");
1258 if (exthdr->devicetype & 0x2000)
1259 dprintk(DBGLVL_API,
1260 " = VBI Decoder\n");
1261 if (exthdr->devicetype & 0x10000)
1262 dprintk(DBGLVL_API,
1263 " = Streaming Device\n");
1264 if (exthdr->devicetype & 0x20000)
1265 dprintk(DBGLVL_API,
1266 " = DRM Device\n");
1267 if (exthdr->devicetype & 0x40000000)
1268 dprintk(DBGLVL_API,
1269 " = Generic Device\n");
1270 if (exthdr->devicetype & 0x80000000)
1271 dprintk(DBGLVL_API,
1272 " = Config Space Device\n");
1273 dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
1274 exthdr->numgpiopins);
1275 dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
1276 exthdr->numgpiogroups);
1277 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1278 exthdr->controlsize);
1279 if (exthdr->devicetype & 0x80) {
1280 if (currpath == 1)
1281 encport = &dev->ports[SAA7164_PORT_ENC1];
1282 else
1283 encport = &dev->ports[SAA7164_PORT_ENC2];
1284 memcpy(&encport->ifunit, exthdr,
1285 sizeof(struct tmComResExtDevDescrHeader));
1286 dprintk(DBGLVL_API,
1287 " (becomes dev->enc[%d])\n",
1288 encport->nr);
1289 }
1290 break;
1291 case PVC_INFRARED_UNIT:
1292 dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
1293 break;
1294 case DRM_UNIT:
1295 dprintk(DBGLVL_API, " DRM_UNIT\n");
1296 break;
1297 default:
1298 dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
1299 }
1300
1301 dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
1302 dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
1303 dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
1304 dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
1305
1306 idx += hdr->len;
1307 }
1308
1309 return 0;
1310 }
1311
saa7164_api_enum_subdevs(struct saa7164_dev * dev)1312 int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
1313 {
1314 int ret;
1315 u32 buflen = 0;
1316 u8 *buf;
1317
1318 dprintk(DBGLVL_API, "%s()\n", __func__);
1319
1320 /* Get the total descriptor length */
1321 ret = saa7164_cmd_send(dev, 0, GET_LEN,
1322 GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
1323 if (ret != SAA_OK)
1324 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1325
1326 dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
1327 __func__, buflen);
1328
1329 /* Allocate enough storage for all of the descs */
1330 buf = kzalloc(buflen, GFP_KERNEL);
1331 if (!buf)
1332 return SAA_ERR_NO_RESOURCES;
1333
1334 /* Retrieve them */
1335 ret = saa7164_cmd_send(dev, 0, GET_CUR,
1336 GET_DESCRIPTORS_CONTROL, buflen, buf);
1337 if (ret != SAA_OK) {
1338 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1339 goto out;
1340 }
1341
1342 if (saa_debug & DBGLVL_API)
1343 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf,
1344 buflen & ~15, false);
1345
1346 saa7164_api_dump_subdevs(dev, buf, buflen);
1347
1348 out:
1349 kfree(buf);
1350 return ret;
1351 }
1352
saa7164_api_i2c_read(struct saa7164_i2c * bus,u8 addr,u32 reglen,u8 * reg,u32 datalen,u8 * data)1353 int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
1354 u32 datalen, u8 *data)
1355 {
1356 struct saa7164_dev *dev = bus->dev;
1357 u16 len = 0;
1358 int unitid;
1359 u8 buf[256];
1360 int ret;
1361
1362 dprintk(DBGLVL_API, "%s() addr=%x reglen=%d datalen=%d\n",
1363 __func__, addr, reglen, datalen);
1364
1365 if (reglen > 4)
1366 return -EIO;
1367
1368 /* Prepare the send buffer */
1369 /* Bytes 00-03 source register length
1370 * 04-07 source bytes to read
1371 * 08... register address
1372 */
1373 memset(buf, 0, sizeof(buf));
1374 memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
1375 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1376 *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
1377
1378 unitid = saa7164_i2caddr_to_unitid(bus, addr);
1379 if (unitid < 0) {
1380 printk(KERN_ERR
1381 "%s() error, cannot translate regaddr 0x%x to unitid\n",
1382 __func__, addr);
1383 return -EIO;
1384 }
1385
1386 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
1387 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
1388 if (ret != SAA_OK) {
1389 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1390 return -EIO;
1391 }
1392
1393 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
1394
1395 if (saa_debug & DBGLVL_I2C)
1396 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf,
1397 32, false);
1398
1399 ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
1400 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
1401 if (ret != SAA_OK)
1402 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1403 else {
1404 if (saa_debug & DBGLVL_I2C)
1405 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
1406 buf, sizeof(buf), false);
1407 memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
1408 }
1409
1410 return ret == SAA_OK ? 0 : -EIO;
1411 }
1412
1413 /* For a given 8 bit i2c address device, write the buffer */
saa7164_api_i2c_write(struct saa7164_i2c * bus,u8 addr,u32 datalen,u8 * data)1414 int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
1415 u8 *data)
1416 {
1417 struct saa7164_dev *dev = bus->dev;
1418 u16 len = 0;
1419 int unitid;
1420 int reglen;
1421 u8 buf[256];
1422 int ret;
1423
1424 dprintk(DBGLVL_API, "%s() addr=0x%2x len=0x%x\n",
1425 __func__, addr, datalen);
1426
1427 if ((datalen == 0) || (datalen > 232))
1428 return -EIO;
1429
1430 memset(buf, 0, sizeof(buf));
1431
1432 unitid = saa7164_i2caddr_to_unitid(bus, addr);
1433 if (unitid < 0) {
1434 printk(KERN_ERR
1435 "%s() error, cannot translate regaddr 0x%x to unitid\n",
1436 __func__, addr);
1437 return -EIO;
1438 }
1439
1440 reglen = saa7164_i2caddr_to_reglen(bus, addr);
1441 if (reglen < 0) {
1442 printk(KERN_ERR
1443 "%s() error, cannot translate regaddr to reglen\n",
1444 __func__);
1445 return -EIO;
1446 }
1447
1448 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
1449 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
1450 if (ret != SAA_OK) {
1451 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1452 return -EIO;
1453 }
1454
1455 dprintk(DBGLVL_API, "%s() len = %d bytes unitid=0x%x\n", __func__,
1456 len, unitid);
1457
1458 /* Prepare the send buffer */
1459 /* Bytes 00-03 dest register length
1460 * 04-07 dest bytes to write
1461 * 08... register address
1462 */
1463 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1464 *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
1465 memcpy((buf + 2 * sizeof(u32)), data, datalen);
1466
1467 if (saa_debug & DBGLVL_I2C)
1468 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
1469 buf, sizeof(buf), false);
1470
1471 ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
1472 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
1473 if (ret != SAA_OK)
1474 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1475
1476 return ret == SAA_OK ? 0 : -EIO;
1477 }
1478
saa7164_api_modify_gpio(struct saa7164_dev * dev,u8 unitid,u8 pin,u8 state)1479 static int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
1480 u8 pin, u8 state)
1481 {
1482 int ret;
1483 struct tmComResGPIO t;
1484
1485 dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
1486 __func__, unitid, pin, state);
1487
1488 if ((pin > 7) || (state > 2))
1489 return SAA_ERR_BAD_PARAMETER;
1490
1491 t.pin = pin;
1492 t.state = state;
1493
1494 ret = saa7164_cmd_send(dev, unitid, SET_CUR,
1495 EXU_GPIO_CONTROL, sizeof(t), &t);
1496 if (ret != SAA_OK)
1497 printk(KERN_ERR "%s() error, ret = 0x%x\n",
1498 __func__, ret);
1499
1500 return ret;
1501 }
1502
saa7164_api_set_gpiobit(struct saa7164_dev * dev,u8 unitid,u8 pin)1503 int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
1504 u8 pin)
1505 {
1506 return saa7164_api_modify_gpio(dev, unitid, pin, 1);
1507 }
1508
saa7164_api_clear_gpiobit(struct saa7164_dev * dev,u8 unitid,u8 pin)1509 int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
1510 u8 pin)
1511 {
1512 return saa7164_api_modify_gpio(dev, unitid, pin, 0);
1513 }
1514
1515