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
13int 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, id: 0, command: GET_CUR,
28 GET_FW_STATUS_CONTROL, size: sizeof(struct tmFwInfoStruct), buf: 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
37int 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, id: 0, command: GET_CUR,
50 GET_DEBUG_DATA_CONTROL, size: sizeof(d), buf: &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
65int 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, id: 0, command: GET_CUR,
74 SET_DEBUG_LEVEL_CONTROL, size: sizeof(lvl), buf: &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, id: 0, command: SET_CUR,
84 SET_DEBUG_LEVEL_CONTROL, size: sizeof(lvl), buf: &lvl);
85 if (ret != SAA_OK)
86 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
87
88 return ret;
89}
90
91int 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(dev: port->dev, id: port->hwcfg.unitid,
106 command: SET_CUR, SAA_PROBE_CONTROL, size: sizeof(fmt), buf: &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(dev: port->dev, id: port->hwcfg.unitid,
112 command: GET_CUR, SAA_PROBE_CONTROL, size: sizeof(rsp), buf: &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(p: &fmt, q: &rsp, size: 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(dev: port->dev, id: port->hwcfg.unitid,
122 command: SET_CUR, SAA_COMMIT_CONTROL, size: sizeof(fmt), buf: &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(dev: port->dev, id: port->hwcfg.unitid,
128 command: GET_CUR, SAA_COMMIT_CONTROL, size: sizeof(rsp), buf: &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(p: &fmt, q: &rsp, size: 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
154static 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(dev: port->dev, id: port->hwcfg.sourceid, command: SET_CUR,
165 EU_VIDEO_GOP_STRUCTURE_CONTROL,
166 size: sizeof(gs), buf: &gs);
167 if (ret != SAA_OK)
168 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
169
170 return ret;
171}
172
173int 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(dev: port->dev, id: port->hwcfg.sourceid, command: SET_CUR,
189 EU_PROFILE_CONTROL, size: sizeof(u8), buf: &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(dev: port->dev, id: port->hwcfg.sourceid, command: SET_CUR,
195 EU_PROFILE_CONTROL, size: sizeof(u8), buf: &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(dev: port->dev, id: port->hwcfg.sourceid, command: SET_CUR,
208 EU_VIDEO_BIT_RATE_CONTROL,
209 size: sizeof(struct tmComResEncVideoBitRate),
210 buf: &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(dev: port->dev, id: port->hwcfg.sourceid, command: SET_CUR,
219 EU_AUDIO_BIT_RATE_CONTROL,
220 size: sizeof(struct tmComResEncAudioBitRate),
221 buf: &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
232int 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(dev: port->dev, id: port->hwcfg.sourceid, command: GET_CUR,
249 EU_PROFILE_CONTROL, size: sizeof(u8), buf: &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(dev: port->dev, id: port->hwcfg.sourceid, command: GET_CUR,
254 EU_VIDEO_RESOLUTION_CONTROL, size: sizeof(u8),
255 buf: &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(dev: port->dev, id: port->hwcfg.sourceid, command: GET_CUR,
260 EU_VIDEO_FORMAT_CONTROL, size: sizeof(u8), buf: &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(dev: port->dev, id: port->hwcfg.sourceid, command: GET_CUR,
265 EU_VIDEO_BIT_RATE_CONTROL, size: sizeof(v), buf: &v);
266 if (ret != SAA_OK)
267 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
268
269 ret = saa7164_cmd_send(dev: port->dev, id: port->hwcfg.sourceid, command: GET_CUR,
270 EU_AUDIO_FORMAT_CONTROL, size: sizeof(u8), buf: &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(dev: port->dev, id: port->hwcfg.sourceid, command: GET_CUR,
275 EU_AUDIO_BIT_RATE_CONTROL, size: sizeof(a), buf: &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(dev: port->dev, id: port->hwcfg.sourceid, command: GET_CUR,
283 EU_VIDEO_INPUT_ASPECT_CONTROL,
284 size: sizeof(struct tmComResEncVideoInputAspectRatio), buf: &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
310int 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(dev: port->dev, id: port->hwcfg.sourceid, command: SET_CUR,
346 EU_VIDEO_INPUT_ASPECT_CONTROL,
347 size: sizeof(struct tmComResEncVideoInputAspectRatio), buf: &ar);
348 if (ret != SAA_OK)
349 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
350
351 return ret;
352}
353
354int 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(dev: port->dev, id: port->encunit.vsourceid, command: SET_CUR,
381 controlselector: ctl, size: sizeof(u16), buf: &val);
382 if (ret != SAA_OK)
383 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
384
385 return ret;
386}
387
388int 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(dev: port->dev, id: port->encunit.vsourceid, command: GET_CUR,
395 controlselector: ctl, size: sizeof(u16), buf: &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
422int 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, mute: 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(dev: port->dev, id: port->vidproc.sourceid, command: SET_CUR,
438 SU_INPUT_SELECT_CONTROL, size: sizeof(u8), buf: &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(dev: port->dev, id: port->audfeat.sourceid, command: SET_CUR,
444 SU_INPUT_SELECT_CONTROL, size: sizeof(u8),
445 buf: &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, mute: 0);
451 if (ret != SAA_OK)
452 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
453
454 return ret;
455}
456
457int 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(dev: port->dev, id: port->audfeat.unitid, command: SET_CUR,
466 MUTE_CONTROL, size: sizeof(u8), buf: &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 */
474int 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(dev: port->dev, id: port->audfeat.unitid, command: GET_MIN,
484 VOLUME_CONTROL, size: sizeof(u16), buf: &min);
485 if (ret != SAA_OK)
486 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
487
488 ret = saa7164_cmd_send(dev: port->dev, id: port->audfeat.unitid, command: GET_MAX,
489 VOLUME_CONTROL, size: sizeof(u16), buf: &max);
490 if (ret != SAA_OK)
491 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
492
493 ret = saa7164_cmd_send(dev: port->dev, id: port->audfeat.unitid, command: GET_CUR,
494 controlselector: (0x01 << 8) | VOLUME_CONTROL, size: sizeof(u16), buf: &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(dev: port->dev, id: port->audfeat.unitid, command: SET_CUR,
509 controlselector: (0x01 << 8) | VOLUME_CONTROL, size: sizeof(s16), buf: &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(dev: port->dev, id: port->audfeat.unitid, command: SET_CUR,
515 controlselector: (0x02 << 8) | VOLUME_CONTROL, size: sizeof(s16), buf: &v);
516 if (ret != SAA_OK)
517 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
518
519 ret = saa7164_cmd_send(dev: port->dev, id: port->audfeat.unitid, command: GET_CUR,
520 controlselector: (0x01 << 8) | VOLUME_CONTROL, size: sizeof(u16), buf: &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
530int 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(dev: port->dev, id: port->audfeat.unitid, command: SET_CUR,
547 AUDIO_DEFAULT_CONTROL, size: sizeof(struct tmComResAudioDefaults),
548 buf: &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(dev: port->dev, id: port->tunerunit.unitid, command: SET_CUR,
562 TU_STANDARD_CONTROL, size: sizeof(tvaudio), buf: &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
569int 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(dev: port->dev, id: port->tunerunit.unitid, command: SET_CUR,
583 TU_STANDARD_AUTO_CONTROL, size: sizeof(p), buf: &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
592int 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(dev: port->dev, id: port->vidproc.sourceid, command: GET_CUR,
598 SU_INPUT_SELECT_CONTROL, size: sizeof(u8), buf: &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
608static 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, id: port->ifunit.unitid, command: GET_LEN,
648 EXU_REGISTER_ACCESS_CONTROL, size: sizeof(len), buf: &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, id: port->ifunit.unitid, command: SET_CUR,
655 EXU_REGISTER_ACCESS_CONTROL, size: len, buf: &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 */
666int 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, reg: 0x00, val: 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, reg: 0x00, val: 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, reg: 0x00, val: 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, reg: 0x00, val: 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, reg: 0x00, val: 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, reg: 0x00, val: 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, reg: 0x00, val: 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, reg: 0x00, val: 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, reg: 0x00, val: 0x80);
710 agc_disable = 1;
711 }
712
713 saa7164_api_set_dif(port, reg: 0x48, val: 0xa0); /* AGC Functions 1 */
714 saa7164_api_set_dif(port, reg: 0xc0, val: agc_disable); /* AGC Output Disable */
715 saa7164_api_set_dif(port, reg: 0x7c, val: 0x04); /* CVBS EQ */
716 saa7164_api_set_dif(port, reg: 0x04, val: 0x01); /* Active */
717 msleep(msecs: 100);
718 saa7164_api_set_dif(port, reg: 0x04, val: 0x00); /* Active (again) */
719 msleep(msecs: 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 */
729int 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(port: p, std);
763
764 return ret;
765}
766
767int 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(dev: port->dev, id: port->hwcfg.unitid, command: SET_CUR,
777 SAA_STATE_CONTROL, size: sizeof(mode), buf: &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
785int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
786{
787 int ret;
788
789 ret = saa7164_cmd_send(dev, id: 0, command: GET_CUR,
790 GET_FW_VERSION_CONTROL, size: sizeof(u32), buf: version);
791 if (ret != SAA_OK)
792 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
793
794 return ret;
795}
796
797int 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 bus 0 */
805 /* TODO: Pull the details from the boards struct */
806 return saa7164_api_i2c_read(bus: &dev->i2c_bus[0], addr: 0xa0 >> 1, reglen: sizeof(reg),
807 reg: &reg[0], datalen: 128, data: buf);
808}
809
810static 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
846static int
847saa7164_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
881static int
882saa7164_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
915static 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 next_offset = idx + (vcoutputtermhdr->len);
1061 for (i = 0; i < vcoutputtermhdr->numformats; i++) {
1062 t = (struct tmComResDescrHeader *)
1063 (buf + next_offset);
1064 switch (t->subtype) {
1065 case VS_FORMAT_MPEG2TS:
1066 tsfmt =
1067 (struct tmComResTSFormatDescrHeader *)t;
1068 if (currpath == 1)
1069 tsport = &dev->ports[SAA7164_PORT_TS1];
1070 else
1071 tsport = &dev->ports[SAA7164_PORT_TS2];
1072 memcpy(&tsport->hwcfg, vcoutputtermhdr,
1073 sizeof(*vcoutputtermhdr));
1074 saa7164_api_configure_port_mpeg2ts(dev,
1075 port: tsport, tsfmt);
1076 break;
1077 case VS_FORMAT_MPEG2PS:
1078 psfmt =
1079 (struct tmComResPSFormatDescrHeader *)t;
1080 if (currpath == 1)
1081 encport = &dev->ports[SAA7164_PORT_ENC1];
1082 else
1083 encport = &dev->ports[SAA7164_PORT_ENC2];
1084 memcpy(&encport->hwcfg, vcoutputtermhdr,
1085 sizeof(*vcoutputtermhdr));
1086 saa7164_api_configure_port_mpeg2ps(dev,
1087 port: encport, fmt: psfmt);
1088 break;
1089 case VS_FORMAT_VBI:
1090 vbifmt =
1091 (struct tmComResVBIFormatDescrHeader *)t;
1092 if (currpath == 1)
1093 vbiport = &dev->ports[SAA7164_PORT_VBI1];
1094 else
1095 vbiport = &dev->ports[SAA7164_PORT_VBI2];
1096 memcpy(&vbiport->hwcfg, vcoutputtermhdr,
1097 sizeof(*vcoutputtermhdr));
1098 memcpy(&vbiport->vbi_fmt_ntsc, vbifmt,
1099 sizeof(*vbifmt));
1100 saa7164_api_configure_port_vbi(dev,
1101 port: vbiport);
1102 break;
1103 case VS_FORMAT_RDS:
1104 dprintk(DBGLVL_API,
1105 " = VS_FORMAT_RDS\n");
1106 break;
1107 case VS_FORMAT_UNCOMPRESSED:
1108 dprintk(DBGLVL_API,
1109 " = VS_FORMAT_UNCOMPRESSED\n");
1110 break;
1111 case VS_FORMAT_TYPE:
1112 dprintk(DBGLVL_API,
1113 " = VS_FORMAT_TYPE\n");
1114 break;
1115 default:
1116 dprintk(DBGLVL_API,
1117 " = undefined (0x%x)\n",
1118 t->subtype);
1119 }
1120 next_offset += t->len;
1121 }
1122
1123 break;
1124 case TUNER_UNIT:
1125 dprintk(DBGLVL_API, " TUNER_UNIT\n");
1126 tunerunithdr =
1127 (struct tmComResTunerDescrHeader *)(buf + idx);
1128 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1129 tunerunithdr->unitid);
1130 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1131 tunerunithdr->sourceid);
1132 dprintk(DBGLVL_API, " iunit = 0x%x\n",
1133 tunerunithdr->iunit);
1134 dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
1135 tunerunithdr->tuningstandards);
1136 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1137 tunerunithdr->controlsize);
1138 dprintk(DBGLVL_API, " controls = 0x%x\n",
1139 tunerunithdr->controls);
1140
1141 if (tunerunithdr->unitid == tunerunithdr->iunit) {
1142 if (currpath == 1)
1143 encport = &dev->ports[SAA7164_PORT_ENC1];
1144 else
1145 encport = &dev->ports[SAA7164_PORT_ENC2];
1146 memcpy(&encport->tunerunit, tunerunithdr,
1147 sizeof(struct tmComResTunerDescrHeader));
1148 dprintk(DBGLVL_API,
1149 " (becomes dev->enc[%d] tuner)\n",
1150 encport->nr);
1151 }
1152 break;
1153 case VC_SELECTOR_UNIT:
1154 psel = (struct tmComResSelDescrHeader *)(buf + idx);
1155 dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
1156 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1157 psel->unitid);
1158 dprintk(DBGLVL_API, " nrinpins = 0x%x\n",
1159 psel->nrinpins);
1160 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1161 psel->sourceid);
1162 break;
1163 case VC_PROCESSING_UNIT:
1164 pdh = (struct tmComResProcDescrHeader *)(buf + idx);
1165 dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
1166 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1167 pdh->unitid);
1168 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1169 pdh->sourceid);
1170 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1171 pdh->controlsize);
1172 if (pdh->controlsize == 0x04) {
1173 if (currpath == 1)
1174 encport = &dev->ports[SAA7164_PORT_ENC1];
1175 else
1176 encport = &dev->ports[SAA7164_PORT_ENC2];
1177 memcpy(&encport->vidproc, pdh,
1178 sizeof(struct tmComResProcDescrHeader));
1179 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
1180 encport->nr);
1181 }
1182 break;
1183 case FEATURE_UNIT:
1184 afd = (struct tmComResAFeatureDescrHeader *)(buf + idx);
1185 dprintk(DBGLVL_API, " FEATURE_UNIT\n");
1186 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1187 afd->unitid);
1188 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1189 afd->sourceid);
1190 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1191 afd->controlsize);
1192 if (currpath == 1)
1193 encport = &dev->ports[SAA7164_PORT_ENC1];
1194 else
1195 encport = &dev->ports[SAA7164_PORT_ENC2];
1196 memcpy(&encport->audfeat, afd,
1197 sizeof(struct tmComResAFeatureDescrHeader));
1198 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
1199 encport->nr);
1200 break;
1201 case ENCODER_UNIT:
1202 edh = (struct tmComResEncoderDescrHeader *)(buf + idx);
1203 dprintk(DBGLVL_API, " ENCODER_UNIT\n");
1204 dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype);
1205 dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid);
1206 dprintk(DBGLVL_API, " vsourceid = 0x%x\n",
1207 edh->vsourceid);
1208 dprintk(DBGLVL_API, " asourceid = 0x%x\n",
1209 edh->asourceid);
1210 dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit);
1211 if (edh->iunit == edh->unitid) {
1212 if (currpath == 1)
1213 encport = &dev->ports[SAA7164_PORT_ENC1];
1214 else
1215 encport = &dev->ports[SAA7164_PORT_ENC2];
1216 memcpy(&encport->encunit, edh,
1217 sizeof(struct tmComResEncoderDescrHeader));
1218 dprintk(DBGLVL_API,
1219 " (becomes dev->enc[%d])\n",
1220 encport->nr);
1221 }
1222 break;
1223 case EXTENSION_UNIT:
1224 dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
1225 exthdr = (struct tmComResExtDevDescrHeader *)(buf + idx);
1226 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1227 exthdr->unitid);
1228 dprintk(DBGLVL_API, " deviceid = 0x%x\n",
1229 exthdr->deviceid);
1230 dprintk(DBGLVL_API, " devicetype = 0x%x\n",
1231 exthdr->devicetype);
1232 if (exthdr->devicetype & 0x1)
1233 dprintk(DBGLVL_API, " = Decoder Device\n");
1234 if (exthdr->devicetype & 0x2)
1235 dprintk(DBGLVL_API, " = GPIO Source\n");
1236 if (exthdr->devicetype & 0x4)
1237 dprintk(DBGLVL_API, " = Video Decoder\n");
1238 if (exthdr->devicetype & 0x8)
1239 dprintk(DBGLVL_API, " = Audio Decoder\n");
1240 if (exthdr->devicetype & 0x20)
1241 dprintk(DBGLVL_API, " = Crossbar\n");
1242 if (exthdr->devicetype & 0x40)
1243 dprintk(DBGLVL_API, " = Tuner\n");
1244 if (exthdr->devicetype & 0x80)
1245 dprintk(DBGLVL_API, " = IF PLL\n");
1246 if (exthdr->devicetype & 0x100)
1247 dprintk(DBGLVL_API, " = Demodulator\n");
1248 if (exthdr->devicetype & 0x200)
1249 dprintk(DBGLVL_API, " = RDS Decoder\n");
1250 if (exthdr->devicetype & 0x400)
1251 dprintk(DBGLVL_API, " = Encoder\n");
1252 if (exthdr->devicetype & 0x800)
1253 dprintk(DBGLVL_API, " = IR Decoder\n");
1254 if (exthdr->devicetype & 0x1000)
1255 dprintk(DBGLVL_API, " = EEPROM\n");
1256 if (exthdr->devicetype & 0x2000)
1257 dprintk(DBGLVL_API,
1258 " = VBI Decoder\n");
1259 if (exthdr->devicetype & 0x10000)
1260 dprintk(DBGLVL_API,
1261 " = Streaming Device\n");
1262 if (exthdr->devicetype & 0x20000)
1263 dprintk(DBGLVL_API,
1264 " = DRM Device\n");
1265 if (exthdr->devicetype & 0x40000000)
1266 dprintk(DBGLVL_API,
1267 " = Generic Device\n");
1268 if (exthdr->devicetype & 0x80000000)
1269 dprintk(DBGLVL_API,
1270 " = Config Space Device\n");
1271 dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
1272 exthdr->numgpiopins);
1273 dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
1274 exthdr->numgpiogroups);
1275 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1276 exthdr->controlsize);
1277 if (exthdr->devicetype & 0x80) {
1278 if (currpath == 1)
1279 encport = &dev->ports[SAA7164_PORT_ENC1];
1280 else
1281 encport = &dev->ports[SAA7164_PORT_ENC2];
1282 memcpy(&encport->ifunit, exthdr,
1283 sizeof(struct tmComResExtDevDescrHeader));
1284 dprintk(DBGLVL_API,
1285 " (becomes dev->enc[%d])\n",
1286 encport->nr);
1287 }
1288 break;
1289 case PVC_INFRARED_UNIT:
1290 dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
1291 break;
1292 case DRM_UNIT:
1293 dprintk(DBGLVL_API, " DRM_UNIT\n");
1294 break;
1295 default:
1296 dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
1297 }
1298
1299 dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
1300 dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
1301 dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
1302 dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
1303
1304 idx += hdr->len;
1305 }
1306
1307 return 0;
1308}
1309
1310int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
1311{
1312 int ret;
1313 u32 buflen = 0;
1314 u8 *buf;
1315
1316 dprintk(DBGLVL_API, "%s()\n", __func__);
1317
1318 /* Get the total descriptor length */
1319 ret = saa7164_cmd_send(dev, id: 0, command: GET_LEN,
1320 GET_DESCRIPTORS_CONTROL, size: sizeof(buflen), buf: &buflen);
1321 if (ret != SAA_OK)
1322 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1323
1324 dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
1325 __func__, buflen);
1326
1327 /* Allocate enough storage for all of the descs */
1328 buf = kzalloc(size: buflen, GFP_KERNEL);
1329 if (!buf)
1330 return SAA_ERR_NO_RESOURCES;
1331
1332 /* Retrieve them */
1333 ret = saa7164_cmd_send(dev, id: 0, command: GET_CUR,
1334 GET_DESCRIPTORS_CONTROL, size: buflen, buf);
1335 if (ret != SAA_OK) {
1336 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1337 goto out;
1338 }
1339
1340 if (saa_debug & DBGLVL_API)
1341 print_hex_dump(KERN_INFO, prefix_str: "", prefix_type: DUMP_PREFIX_OFFSET, rowsize: 16, groupsize: 1, buf,
1342 len: buflen & ~15, ascii: false);
1343
1344 saa7164_api_dump_subdevs(dev, buf, len: buflen);
1345
1346out:
1347 kfree(objp: buf);
1348 return ret;
1349}
1350
1351int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
1352 u32 datalen, u8 *data)
1353{
1354 struct saa7164_dev *dev = bus->dev;
1355 u16 len = 0;
1356 int unitid;
1357 u8 buf[256];
1358 int ret;
1359
1360 dprintk(DBGLVL_API, "%s() addr=%x reglen=%d datalen=%d\n",
1361 __func__, addr, reglen, datalen);
1362
1363 if (reglen > 4)
1364 return -EIO;
1365
1366 /* Prepare the send buffer */
1367 /* Bytes 00-03 source register length
1368 * 04-07 source bytes to read
1369 * 08... register address
1370 */
1371 memset(buf, 0, sizeof(buf));
1372 memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
1373 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1374 *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
1375
1376 unitid = saa7164_i2caddr_to_unitid(bus, addr);
1377 if (unitid < 0) {
1378 printk(KERN_ERR
1379 "%s() error, cannot translate regaddr 0x%x to unitid\n",
1380 __func__, addr);
1381 return -EIO;
1382 }
1383
1384 ret = saa7164_cmd_send(dev: bus->dev, id: unitid, command: GET_LEN,
1385 EXU_REGISTER_ACCESS_CONTROL, size: sizeof(len), buf: &len);
1386 if (ret != SAA_OK) {
1387 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1388 return -EIO;
1389 }
1390
1391 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
1392
1393 if (saa_debug & DBGLVL_I2C)
1394 print_hex_dump(KERN_INFO, prefix_str: "", prefix_type: DUMP_PREFIX_OFFSET, rowsize: 16, groupsize: 1, buf,
1395 len: 32, ascii: false);
1396
1397 ret = saa7164_cmd_send(dev: bus->dev, id: unitid, command: GET_CUR,
1398 EXU_REGISTER_ACCESS_CONTROL, size: len, buf: &buf);
1399 if (ret != SAA_OK)
1400 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1401 else {
1402 if (saa_debug & DBGLVL_I2C)
1403 print_hex_dump(KERN_INFO, prefix_str: "", prefix_type: DUMP_PREFIX_OFFSET, rowsize: 16, groupsize: 1,
1404 buf, len: sizeof(buf), ascii: false);
1405 memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
1406 }
1407
1408 return ret == SAA_OK ? 0 : -EIO;
1409}
1410
1411/* For a given 8 bit i2c address device, write the buffer */
1412int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
1413 u8 *data)
1414{
1415 struct saa7164_dev *dev = bus->dev;
1416 u16 len = 0;
1417 int unitid;
1418 int reglen;
1419 u8 buf[256];
1420 int ret;
1421
1422 dprintk(DBGLVL_API, "%s() addr=0x%2x len=0x%x\n",
1423 __func__, addr, datalen);
1424
1425 if ((datalen == 0) || (datalen > 232))
1426 return -EIO;
1427
1428 memset(buf, 0, sizeof(buf));
1429
1430 unitid = saa7164_i2caddr_to_unitid(bus, addr);
1431 if (unitid < 0) {
1432 printk(KERN_ERR
1433 "%s() error, cannot translate regaddr 0x%x to unitid\n",
1434 __func__, addr);
1435 return -EIO;
1436 }
1437
1438 reglen = saa7164_i2caddr_to_reglen(bus, addr);
1439 if (reglen < 0) {
1440 printk(KERN_ERR
1441 "%s() error, cannot translate regaddr to reglen\n",
1442 __func__);
1443 return -EIO;
1444 }
1445
1446 ret = saa7164_cmd_send(dev: bus->dev, id: unitid, command: GET_LEN,
1447 EXU_REGISTER_ACCESS_CONTROL, size: sizeof(len), buf: &len);
1448 if (ret != SAA_OK) {
1449 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1450 return -EIO;
1451 }
1452
1453 dprintk(DBGLVL_API, "%s() len = %d bytes unitid=0x%x\n", __func__,
1454 len, unitid);
1455
1456 /* Prepare the send buffer */
1457 /* Bytes 00-03 dest register length
1458 * 04-07 dest bytes to write
1459 * 08... register address
1460 */
1461 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1462 *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
1463 memcpy((buf + 2 * sizeof(u32)), data, datalen);
1464
1465 if (saa_debug & DBGLVL_I2C)
1466 print_hex_dump(KERN_INFO, prefix_str: "", prefix_type: DUMP_PREFIX_OFFSET, rowsize: 16, groupsize: 1,
1467 buf, len: sizeof(buf), ascii: false);
1468
1469 ret = saa7164_cmd_send(dev: bus->dev, id: unitid, command: SET_CUR,
1470 EXU_REGISTER_ACCESS_CONTROL, size: len, buf: &buf);
1471 if (ret != SAA_OK)
1472 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1473
1474 return ret == SAA_OK ? 0 : -EIO;
1475}
1476
1477static int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
1478 u8 pin, u8 state)
1479{
1480 int ret;
1481 struct tmComResGPIO t;
1482
1483 dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
1484 __func__, unitid, pin, state);
1485
1486 if ((pin > 7) || (state > 2))
1487 return SAA_ERR_BAD_PARAMETER;
1488
1489 t.pin = pin;
1490 t.state = state;
1491
1492 ret = saa7164_cmd_send(dev, id: unitid, command: SET_CUR,
1493 EXU_GPIO_CONTROL, size: sizeof(t), buf: &t);
1494 if (ret != SAA_OK)
1495 printk(KERN_ERR "%s() error, ret = 0x%x\n",
1496 __func__, ret);
1497
1498 return ret;
1499}
1500
1501int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
1502 u8 pin)
1503{
1504 return saa7164_api_modify_gpio(dev, unitid, pin, state: 1);
1505}
1506
1507int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
1508 u8 pin)
1509{
1510 return saa7164_api_modify_gpio(dev, unitid, pin, state: 0);
1511}
1512
1513

source code of linux/drivers/media/pci/saa7164/saa7164-api.c