[media] saa7164: add firmware debug message collection and procfs changes
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / video / saa7164 / saa7164-api.c
blob01cf4ab13b0ff747d76bd3e5bafa9d67865bc353
1 /*
2 * Driver for the NXP SAA7164 PCIe bridge
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <linux/wait.h>
23 #include <linux/slab.h>
25 #include "saa7164.h"
27 int saa7164_api_collect_debug(struct saa7164_dev *dev, struct seq_file *m)
29 tmComResDebugGetData_t d;
30 u8 more = 255;
31 int ret;
33 dprintk(DBGLVL_API, "%s()\n", __func__);
35 while (more--) {
37 memset(&d, 0, sizeof(d));
39 ret = saa7164_cmd_send(dev, 0, GET_CUR,
40 GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
41 if (ret != SAA_OK) {
42 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
45 if (d.dwResult != SAA_OK)
46 break;
48 seq_printf(m, "%s", d.ucDebugData);
52 return 0;
55 int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
57 tmComResDebugSetLevel_t lvl;
58 int ret;
60 dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level);
62 /* Retrieve current state */
63 ret = saa7164_cmd_send(dev, 0, GET_CUR,
64 SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
65 if (ret != SAA_OK) {
66 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
68 dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
70 lvl.dwDebugLevel = level;
72 /* set new state */
73 ret = saa7164_cmd_send(dev, 0, SET_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);
79 return ret;
82 int saa7164_api_set_vbi_format(struct saa7164_port *port)
84 struct saa7164_dev *dev = port->dev;
85 tmComResProbeCommit_t fmt, rsp;
86 int ret;
88 dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__,
89 port->nr, port->hwcfg.unitid);
91 fmt.bmHint = 0;
92 fmt.bFormatIndex = 1;
93 fmt.bFrameIndex = 1;
95 /* Probe, see if it can support this format */
96 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
97 SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt);
98 if (ret != SAA_OK)
99 printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret);
101 /* See of the format change was successful */
102 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
103 GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp);
104 if (ret != SAA_OK) {
105 printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret);
106 } else {
107 /* Compare requested vs received, should be same */
108 if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
109 dprintk(DBGLVL_API, "SET/PROBE Verified\n");
111 /* Ask the device to select the negotiated format */
112 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
113 SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
114 if (ret != SAA_OK)
115 printk(KERN_ERR "%s() commit error, ret = 0x%x\n",
116 __func__, ret);
118 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
119 GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp);
120 if (ret != SAA_OK)
121 printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
122 __func__, ret);
124 if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) {
125 printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
126 __func__, ret);
127 } else
128 dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
130 dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
131 dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex);
132 dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", rsp.bFrameIndex);
133 } else
134 printk(KERN_ERR "%s() compare failed\n", __func__);
137 if (ret == SAA_OK)
138 dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr);
140 return ret;
143 int saa7164_api_set_gop_size(struct saa7164_port *port)
145 struct saa7164_dev *dev = port->dev;
146 tmComResEncVideoGopStructure_t gs;
147 int ret;
149 dprintk(DBGLVL_ENC, "%s()\n", __func__);
151 gs.ucRefFrameDist = port->encoder_params.refdist;
152 gs.ucGOPSize = port->encoder_params.gop_size;
153 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
154 EU_VIDEO_GOP_STRUCTURE_CONTROL,
155 sizeof(gs), &gs);
156 if (ret != SAA_OK)
157 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
159 return ret;
162 int saa7164_api_set_encoder(struct saa7164_port *port)
164 struct saa7164_dev *dev = port->dev;
165 tmComResEncVideoBitRate_t vb;
166 tmComResEncAudioBitRate_t ab;
167 int ret;
169 dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
170 port->hwcfg.sourceid);
172 if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
173 port->encoder_profile = EU_PROFILE_PS_DVD;
174 else
175 port->encoder_profile = EU_PROFILE_TS_HQ;
177 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
178 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
179 if (ret != SAA_OK)
180 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
182 /* Resolution */
183 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
184 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
185 if (ret != SAA_OK)
186 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
188 /* Establish video bitrates */
189 if (port->encoder_params.bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
190 vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT;
191 else
192 vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK;
193 vb.dwVideoBitRate = port->encoder_params.bitrate;
194 vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak;
195 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
196 EU_VIDEO_BIT_RATE_CONTROL, sizeof(tmComResEncVideoBitRate_t), &vb);
197 if (ret != SAA_OK)
198 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
200 /* Establish audio bitrates */
201 ab.ucAudioBitRateMode = 0;
202 ab.dwAudioBitRate = 384000;
203 ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
204 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
205 EU_AUDIO_BIT_RATE_CONTROL, sizeof(tmComResEncAudioBitRate_t), &ab);
206 if (ret != SAA_OK)
207 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
209 saa7164_api_set_aspect_ratio(port);
210 saa7164_api_set_gop_size(port);
212 return ret;
215 int saa7164_api_get_encoder(struct saa7164_port *port)
217 struct saa7164_dev *dev = port->dev;
218 tmComResEncVideoBitRate_t v;
219 tmComResEncAudioBitRate_t a;
220 tmComResEncVideoInputAspectRatio_t ar;
221 int ret;
223 dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, port->hwcfg.sourceid);
225 port->encoder_profile = 0;
226 port->video_format = 0;
227 port->video_resolution = 0;
228 port->audio_format = 0;
230 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
231 EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
232 if (ret != SAA_OK)
233 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
235 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
236 EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), &port->video_resolution);
237 if (ret != SAA_OK)
238 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
240 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
241 EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format);
242 if (ret != SAA_OK)
243 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
245 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
246 EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v);
247 if (ret != SAA_OK)
248 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
250 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
251 EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format);
252 if (ret != SAA_OK)
253 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
255 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
256 EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a);
257 if (ret != SAA_OK)
258 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
260 /* Aspect Ratio */
261 ar.width = 0;
262 ar.height = 0;
263 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
264 EU_VIDEO_INPUT_ASPECT_CONTROL,
265 sizeof(tmComResEncVideoInputAspectRatio_t), &ar);
266 if (ret != SAA_OK)
267 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
269 dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile);
270 dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format);
271 dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format);
272 dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
273 dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", v.ucVideoBitRateMode);
274 dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", v.dwVideoBitRate);
275 dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", v.dwVideoBitRatePeak);
276 dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", a.ucAudioBitRateMode);
277 dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", a.dwAudioBitRate);
278 dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", a.dwAudioBitRatePeak);
279 dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", ar.width, ar.height);
281 return ret;
284 int saa7164_api_set_aspect_ratio(struct saa7164_port *port)
286 struct saa7164_dev *dev = port->dev;
287 tmComResEncVideoInputAspectRatio_t ar;
288 int ret;
290 dprintk(DBGLVL_ENC, "%s(%d)\n", __func__,
291 port->encoder_params.ctl_aspect);
293 switch (port->encoder_params.ctl_aspect) {
294 case V4L2_MPEG_VIDEO_ASPECT_1x1:
295 ar.width = 1;
296 ar.height = 1;
297 break;
298 case V4L2_MPEG_VIDEO_ASPECT_4x3:
299 ar.width = 4;
300 ar.height = 3;
301 break;
302 case V4L2_MPEG_VIDEO_ASPECT_16x9:
303 ar.width = 16;
304 ar.height = 9;
305 break;
306 case V4L2_MPEG_VIDEO_ASPECT_221x100:
307 ar.width = 221;
308 ar.height = 100;
309 break;
310 default:
311 BUG();
314 dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__,
315 port->encoder_params.ctl_aspect,
316 ar.width, ar.height);
318 /* Aspect Ratio */
319 ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
320 EU_VIDEO_INPUT_ASPECT_CONTROL,
321 sizeof(tmComResEncVideoInputAspectRatio_t), &ar);
322 if (ret != SAA_OK)
323 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
325 return ret;
328 int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl)
330 struct saa7164_dev *dev = port->dev;
331 int ret;
332 u16 val;
334 if (ctl == PU_BRIGHTNESS_CONTROL)
335 val = port->ctl_brightness;
336 else
337 if (ctl == PU_CONTRAST_CONTROL)
338 val = port->ctl_contrast;
339 else
340 if (ctl == PU_HUE_CONTROL)
341 val = port->ctl_hue;
342 else
343 if (ctl == PU_SATURATION_CONTROL)
344 val = port->ctl_saturation;
345 else
346 if (ctl == PU_SHARPNESS_CONTROL)
347 val = port->ctl_sharpness;
348 else
349 return -EINVAL;
351 dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n",
352 __func__, port->encunit.vsourceid, ctl, val);
354 ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR,
355 ctl, sizeof(u16), &val);
356 if (ret != SAA_OK)
357 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
359 return ret;
362 int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl)
364 struct saa7164_dev *dev = port->dev;
365 int ret;
366 u16 val;
368 ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR,
369 ctl, sizeof(u16), &val);
370 if (ret != SAA_OK) {
371 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
372 return ret;
375 dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n",
376 __func__, ctl, val);
378 if (ctl == PU_BRIGHTNESS_CONTROL)
379 port->ctl_brightness = val;
380 else
381 if (ctl == PU_CONTRAST_CONTROL)
382 port->ctl_contrast = val;
383 else
384 if (ctl == PU_HUE_CONTROL)
385 port->ctl_hue = val;
386 else
387 if (ctl == PU_SATURATION_CONTROL)
388 port->ctl_saturation = val;
389 else
390 if (ctl == PU_SHARPNESS_CONTROL)
391 port->ctl_sharpness = val;
393 return ret;
396 int saa7164_api_set_videomux(struct saa7164_port *port)
398 struct saa7164_dev *dev = port->dev;
399 u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 };
400 int ret;
402 dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n",
403 __func__, port->mux_input, inputs[ port->mux_input - 1 ]);
405 /* Audio Mute */
406 ret = saa7164_api_audio_mute(port, 1);
407 if (ret != SAA_OK)
408 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
410 /* Video Mux */
411 ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR,
412 SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
413 if (ret != SAA_OK)
414 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
415 /* Audio Mux */
416 ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
417 SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[ port->mux_input - 1 ]);
418 if (ret != SAA_OK)
419 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
420 /* Audio UnMute */
421 ret = saa7164_api_audio_mute(port, 0);
422 if (ret != SAA_OK)
423 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
425 return ret;
428 int saa7164_api_audio_mute(struct saa7164_port *port, int mute)
430 struct saa7164_dev *dev = port->dev;
431 u8 v = mute;
432 int ret;
434 dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute);
436 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
437 MUTE_CONTROL, sizeof(u8), &v);
438 if (ret != SAA_OK)
439 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
441 return ret;
444 /* 0 = silence, 0xff = full */
445 int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
447 struct saa7164_dev *dev = port->dev;
448 s16 v, min, max;
449 int ret;
451 dprintk(DBGLVL_API, "%s(%d)\n", __func__, level);
453 /* Obtain the min/max ranges */
454 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN,
455 VOLUME_CONTROL, sizeof(u16), &min);
456 if (ret != SAA_OK)
457 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
459 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX,
460 VOLUME_CONTROL, sizeof(u16), &max);
461 if (ret != SAA_OK)
462 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
464 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
465 ( 0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
466 if (ret != SAA_OK)
467 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
469 dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
471 v = level;
472 if (v < min)
473 v = min;
474 if (v > max)
475 v = max;
477 /* Left */
478 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
479 ( 0x01 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);
480 if (ret != SAA_OK)
481 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
483 /* Right */
484 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
485 ( 0x02 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);
486 if (ret != SAA_OK)
487 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
489 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
490 ( 0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
491 if (ret != SAA_OK)
492 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
494 dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
496 return ret;
499 int saa7164_api_set_audio_std(struct saa7164_port *port)
501 struct saa7164_dev *dev = port->dev;
502 tmComResAudioDefaults_t lvl;
503 tmComResTunerStandard_t tvaudio;
504 int ret;
506 dprintk(DBGLVL_API, "%s()\n", __func__);
508 /* Establish default levels */
509 lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT;
510 lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT;
511 lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT;
512 lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT;
513 lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
514 lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
515 ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
516 AUDIO_DEFAULT_CONTROL, sizeof(tmComResAudioDefaults_t), &lvl);
517 if (ret != SAA_OK)
518 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
520 /* Manually select the appropriate TV audio standard */
521 if (port->encodernorm.id & V4L2_STD_NTSC) {
522 tvaudio.std = TU_STANDARD_NTSC_M;
523 tvaudio.country = 1;
524 } else {
525 tvaudio.std = TU_STANDARD_PAL_I;
526 tvaudio.country = 44;
529 ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
530 TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
531 if (ret != SAA_OK)
532 printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", __func__, ret);
533 return ret;
536 int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
538 struct saa7164_dev *dev = port->dev;
539 tmComResTunerStandardAuto_t p;
540 int ret;
542 dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect);
544 /* Disable TV Audio autodetect if not already set (buggy) */
545 if (autodetect)
546 p.mode = TU_STANDARD_AUTO;
547 else
548 p.mode = TU_STANDARD_MANUAL;
549 ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
550 TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
551 if (ret != SAA_OK)
552 printk(KERN_ERR "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", __func__, ret);
554 return ret;
557 int saa7164_api_get_videomux(struct saa7164_port *port)
559 struct saa7164_dev *dev = port->dev;
560 int ret;
562 ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR,
563 SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
564 if (ret != SAA_OK)
565 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
567 dprintk(DBGLVL_ENC, "%s() v_mux=%d\n",
568 __func__, port->mux_input);
570 return ret;
573 int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
575 struct saa7164_dev *dev = port->dev;
577 u16 len = 0;
578 u8 buf[256];
579 int ret;
580 u8 mas;
582 dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__,
583 port->nr, port->type, val);
585 if (port->nr == 0)
586 mas = 0xd0;
587 else
588 mas = 0xe0;
590 memset(buf, 0, sizeof(buf));
592 buf[0x00] = 0x04;
593 buf[0x01] = 0x00;
594 buf[0x02] = 0x00;
595 buf[0x03] = 0x00;
597 buf[0x04] = 0x04;
598 buf[0x05] = 0x00;
599 buf[0x06] = 0x00;
600 buf[0x07] = 0x00;
602 buf[0x08] = reg;
603 buf[0x09] = 0x26;
604 buf[0x0a] = mas;
605 buf[0x0b] = 0xb0;
607 buf[0x0c] = val;
608 buf[0x0d] = 0x00;
609 buf[0x0e] = 0x00;
610 buf[0x0f] = 0x00;
612 ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN,
613 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
614 if (ret != SAA_OK) {
615 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
616 return -EIO;
619 ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR,
620 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
621 if (ret != SAA_OK)
622 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
624 //saa7164_dumphex16(dev, buf, 16);
626 return ret == SAA_OK ? 0 : -EIO;
629 /* Disable the IF block AGC controls */
630 int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
632 struct saa7164_dev *dev = port->dev;
633 int ret = 0;
634 u8 agc_disable;
636 dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std);
638 if (std & V4L2_STD_NTSC) {
639 dprintk(DBGLVL_API, " NTSC\n");
640 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
641 agc_disable = 0;
642 } else if (std & V4L2_STD_PAL_I) {
643 dprintk(DBGLVL_API, " PAL-I\n");
644 saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */
645 agc_disable = 0;
646 } else if (std & V4L2_STD_PAL_M) {
647 dprintk(DBGLVL_API, " PAL-M\n");
648 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
649 agc_disable = 0;
650 } else if (std & V4L2_STD_PAL_N) {
651 dprintk(DBGLVL_API, " PAL-N\n");
652 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
653 agc_disable = 0;
654 } else if (std & V4L2_STD_PAL_Nc) {
655 dprintk(DBGLVL_API, " PAL-Nc\n");
656 saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
657 agc_disable = 0;
658 } else if (std & V4L2_STD_PAL_B) {
659 dprintk(DBGLVL_API, " PAL-B\n");
660 saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */
661 agc_disable = 0;
662 } else if (std & V4L2_STD_PAL_DK) {
663 dprintk(DBGLVL_API, " PAL-DK\n");
664 saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */
665 agc_disable = 0;
666 } else if (std & V4L2_STD_SECAM_L) {
667 dprintk(DBGLVL_API, " SECAM-L\n");
668 saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */
669 agc_disable = 0;
670 } else {
671 /* Unknown standard, assume DTV */
672 dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
673 saa7164_api_set_dif(port, 0x00, 0x80); /* Undefined Video Standard */
674 agc_disable = 1;
677 saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */
678 saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */
679 saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */
680 saa7164_api_set_dif(port, 0x04, 0x01); /* Active */
681 msleep(100);
682 saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */
683 msleep(100);
685 return ret;
688 /* Ensure the dif is in the correct state for the operating mode
689 * (analog / dtv). We only configure the diff through the analog encoder
690 * so when we're in digital mode we need to find the appropriate encoder
691 * and use it to configure the DIF.
693 int saa7164_api_initialize_dif(struct saa7164_port *port)
695 struct saa7164_dev *dev = port->dev;
696 struct saa7164_port *p = 0;
697 int ret = -EINVAL;
698 u32 std = 0;
700 dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__,
701 port->nr, port->type);
703 if (port->type == SAA7164_MPEG_ENCODER) {
704 /* Pick any analog standard to init the diff.
705 * we'll come back during encoder_init'
706 * and set the correct standard if requried.
708 std = V4L2_STD_NTSC;
709 } else
710 if (port->type == SAA7164_MPEG_DVB) {
711 if (port->nr == SAA7164_PORT_TS1)
712 p = &dev->ports[ SAA7164_PORT_ENC1 ];
713 else
714 p = &dev->ports[ SAA7164_PORT_ENC2 ];
715 } else
716 if (port->type == SAA7164_MPEG_VBI) {
717 std = V4L2_STD_NTSC;
718 if (port->nr == SAA7164_PORT_VBI1)
719 p = &dev->ports[ SAA7164_PORT_ENC1 ];
720 else
721 p = &dev->ports[ SAA7164_PORT_ENC2 ];
722 } else
723 BUG();
725 if (p)
726 ret = saa7164_api_configure_dif(p, std);
728 return ret;
731 int saa7164_api_transition_port(struct saa7164_port *port, u8 mode)
733 struct saa7164_dev *dev = port->dev;
735 int ret;
737 dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n",
738 __func__, port->nr, port->hwcfg.unitid, mode);
740 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
741 SAA_STATE_CONTROL, sizeof(mode), &mode);
742 if (ret != SAA_OK)
743 printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n",
744 __func__, port->nr, port->hwcfg.unitid, ret);
746 return ret;
749 int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
751 int ret;
753 ret = saa7164_cmd_send(dev, 0, GET_CUR,
754 GET_FW_VERSION_CONTROL, sizeof(u32), version);
755 if (ret != SAA_OK)
756 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
758 return ret;
761 int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
763 u8 reg[] = { 0x0f, 0x00 };
765 if (buflen < 128)
766 return -ENOMEM;
768 /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
769 /* TODO: Pull the details from the boards struct */
770 return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
771 &reg[0], 128, buf);
775 int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
776 struct saa7164_port *port)
778 tmComResVBIFormatDescrHeader_t *fmt = &port->vbi_fmt_ntsc;
780 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
781 dprintk(DBGLVL_API, " VideoStandard = 0x%x\n", fmt->VideoStandard);
782 dprintk(DBGLVL_API, " StartLine = %d\n", fmt->StartLine);
783 dprintk(DBGLVL_API, " EndLine = %d\n", fmt->EndLine);
784 dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate);
785 dprintk(DBGLVL_API, " bNumLines = %d\n", fmt->bNumLines);
787 /* Cache the hardware configuration in the port */
789 port->bufcounter = port->hwcfg.BARLocation;
790 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
791 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
792 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
793 port->bufptr32l = port->hwcfg.BARLocation +
794 (4 * sizeof(u32)) +
795 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
796 port->bufptr32h = port->hwcfg.BARLocation +
797 (4 * sizeof(u32)) +
798 (sizeof(u32) * port->hwcfg.buffercount);
799 port->bufptr64 = port->hwcfg.BARLocation +
800 (4 * sizeof(u32)) +
801 (sizeof(u32) * port->hwcfg.buffercount);
802 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
803 port->hwcfg.BARLocation);
805 dprintk(DBGLVL_API, " = VS_FORMAT_VBI (becomes dev->en[%d])\n",
806 port->nr);
808 return 0;
811 int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
812 struct saa7164_port *port,
813 tmComResTSFormatDescrHeader_t *tsfmt)
815 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
816 dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
817 dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
818 dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
819 dprintk(DBGLVL_API, " bguid = (....)\n");
821 /* Cache the hardware configuration in the port */
823 port->bufcounter = port->hwcfg.BARLocation;
824 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
825 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
826 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
827 port->bufptr32l = port->hwcfg.BARLocation +
828 (4 * sizeof(u32)) +
829 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
830 port->bufptr32h = port->hwcfg.BARLocation +
831 (4 * sizeof(u32)) +
832 (sizeof(u32) * port->hwcfg.buffercount);
833 port->bufptr64 = port->hwcfg.BARLocation +
834 (4 * sizeof(u32)) +
835 (sizeof(u32) * port->hwcfg.buffercount);
836 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
837 port->hwcfg.BARLocation);
839 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
840 port->nr);
842 return 0;
845 int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
846 struct saa7164_port *port,
847 tmComResPSFormatDescrHeader_t *fmt)
849 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
850 dprintk(DBGLVL_API, " wPacketLength= 0x%x\n", fmt->wPacketLength);
851 dprintk(DBGLVL_API, " wPackLength= 0x%x\n", fmt->wPackLength);
852 dprintk(DBGLVL_API, " bPackDataType= 0x%x\n", fmt->bPackDataType);
854 /* Cache the hardware configuration in the port */
855 /* TODO: CHECK THIS in the port config */
856 port->bufcounter = port->hwcfg.BARLocation;
857 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
858 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
859 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
860 port->bufptr32l = port->hwcfg.BARLocation +
861 (4 * sizeof(u32)) +
862 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
863 port->bufptr32h = port->hwcfg.BARLocation +
864 (4 * sizeof(u32)) +
865 (sizeof(u32) * port->hwcfg.buffercount);
866 port->bufptr64 = port->hwcfg.BARLocation +
867 (4 * sizeof(u32)) +
868 (sizeof(u32) * port->hwcfg.buffercount);
869 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
870 port->hwcfg.BARLocation);
872 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n",
873 port->nr);
875 return 0;
878 int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
880 struct saa7164_port *tsport = 0;
881 struct saa7164_port *encport = 0;
882 struct saa7164_port *vbiport = 0;
883 u32 idx, next_offset;
884 int i;
885 tmComResDescrHeader_t *hdr, *t;
886 tmComResExtDevDescrHeader_t *exthdr;
887 tmComResPathDescrHeader_t *pathhdr;
888 tmComResAntTermDescrHeader_t *anttermhdr;
889 tmComResTunerDescrHeader_t *tunerunithdr;
890 tmComResDMATermDescrHeader_t *vcoutputtermhdr;
891 tmComResTSFormatDescrHeader_t *tsfmt;
892 tmComResPSFormatDescrHeader_t *psfmt;
893 tmComResSelDescrHeader_t *psel;
894 tmComResProcDescrHeader_t *pdh;
895 tmComResAFeatureDescrHeader_t *afd;
896 tmComResEncoderDescrHeader_t *edh;
897 tmComResVBIFormatDescrHeader_t *vbifmt;
898 u32 currpath = 0;
900 dprintk(DBGLVL_API,
901 "%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n",
902 __func__, len, (u32)sizeof(tmComResDescrHeader_t));
904 for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) {
906 hdr = (tmComResDescrHeader_t *)(buf + idx);
908 if (hdr->type != CS_INTERFACE)
909 return SAA_ERR_NOT_SUPPORTED;
911 dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
912 switch (hdr->subtype) {
913 case GENERAL_REQUEST:
914 dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
915 break;
916 case VC_TUNER_PATH:
917 dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
918 pathhdr = (tmComResPathDescrHeader_t *)(buf + idx);
919 dprintk(DBGLVL_API, " pathid = 0x%x\n",
920 pathhdr->pathid);
921 currpath = pathhdr->pathid;
922 break;
923 case VC_INPUT_TERMINAL:
924 dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
925 anttermhdr =
926 (tmComResAntTermDescrHeader_t *)(buf + idx);
927 dprintk(DBGLVL_API, " terminalid = 0x%x\n",
928 anttermhdr->terminalid);
929 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
930 anttermhdr->terminaltype);
931 switch (anttermhdr->terminaltype) {
932 case ITT_ANTENNA:
933 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
934 break;
935 case LINE_CONNECTOR:
936 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
937 break;
938 case SPDIF_CONNECTOR:
939 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
940 break;
941 case COMPOSITE_CONNECTOR:
942 dprintk(DBGLVL_API,
943 " = COMPOSITE_CONNECTOR\n");
944 break;
945 case SVIDEO_CONNECTOR:
946 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
947 break;
948 case COMPONENT_CONNECTOR:
949 dprintk(DBGLVL_API,
950 " = COMPONENT_CONNECTOR\n");
951 break;
952 case STANDARD_DMA:
953 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
954 break;
955 default:
956 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
957 anttermhdr->terminaltype);
959 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
960 anttermhdr->assocterminal);
961 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
962 anttermhdr->iterminal);
963 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
964 anttermhdr->controlsize);
965 break;
966 case VC_OUTPUT_TERMINAL:
967 dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
968 vcoutputtermhdr =
969 (tmComResDMATermDescrHeader_t *)(buf + idx);
970 dprintk(DBGLVL_API, " unitid = 0x%x\n",
971 vcoutputtermhdr->unitid);
972 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
973 vcoutputtermhdr->terminaltype);
974 switch (vcoutputtermhdr->terminaltype) {
975 case ITT_ANTENNA:
976 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
977 break;
978 case LINE_CONNECTOR:
979 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
980 break;
981 case SPDIF_CONNECTOR:
982 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
983 break;
984 case COMPOSITE_CONNECTOR:
985 dprintk(DBGLVL_API,
986 " = COMPOSITE_CONNECTOR\n");
987 break;
988 case SVIDEO_CONNECTOR:
989 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
990 break;
991 case COMPONENT_CONNECTOR:
992 dprintk(DBGLVL_API,
993 " = COMPONENT_CONNECTOR\n");
994 break;
995 case STANDARD_DMA:
996 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
997 break;
998 default:
999 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
1000 vcoutputtermhdr->terminaltype);
1002 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
1003 vcoutputtermhdr->assocterminal);
1004 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1005 vcoutputtermhdr->sourceid);
1006 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
1007 vcoutputtermhdr->iterminal);
1008 dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
1009 vcoutputtermhdr->BARLocation);
1010 dprintk(DBGLVL_API, " flags = 0x%x\n",
1011 vcoutputtermhdr->flags);
1012 dprintk(DBGLVL_API, " interruptid = 0x%x\n",
1013 vcoutputtermhdr->interruptid);
1014 dprintk(DBGLVL_API, " buffercount = 0x%x\n",
1015 vcoutputtermhdr->buffercount);
1016 dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
1017 vcoutputtermhdr->metadatasize);
1018 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1019 vcoutputtermhdr->controlsize);
1020 dprintk(DBGLVL_API, " numformats = 0x%x\n",
1021 vcoutputtermhdr->numformats);
1023 t = (tmComResDescrHeader_t *)
1024 ((tmComResDMATermDescrHeader_t *)(buf + idx));
1025 next_offset = idx + (vcoutputtermhdr->len);
1026 for (i = 0; i < vcoutputtermhdr->numformats; i++) {
1027 t = (tmComResDescrHeader_t *)
1028 (buf + next_offset);
1029 switch (t->subtype) {
1030 case VS_FORMAT_MPEG2TS:
1031 tsfmt =
1032 (tmComResTSFormatDescrHeader_t *)t;
1033 if (currpath == 1)
1034 tsport = &dev->ports[ SAA7164_PORT_TS1 ];
1035 else
1036 tsport = &dev->ports[ SAA7164_PORT_TS2 ];
1037 memcpy(&tsport->hwcfg, vcoutputtermhdr,
1038 sizeof(*vcoutputtermhdr));
1039 saa7164_api_configure_port_mpeg2ts(dev,
1040 tsport, tsfmt);
1041 break;
1042 case VS_FORMAT_MPEG2PS:
1043 psfmt =
1044 (tmComResPSFormatDescrHeader_t *)t;
1045 if (currpath == 1)
1046 encport = &dev->ports[ SAA7164_PORT_ENC1 ];
1047 else
1048 encport = &dev->ports[ SAA7164_PORT_ENC2 ];
1049 memcpy(&encport->hwcfg, vcoutputtermhdr,
1050 sizeof(*vcoutputtermhdr));
1051 saa7164_api_configure_port_mpeg2ps(dev,
1052 encport, psfmt);
1053 break;
1054 case VS_FORMAT_VBI:
1055 vbifmt =
1056 (tmComResVBIFormatDescrHeader_t *)t;
1057 if (currpath == 1)
1058 vbiport = &dev->ports[ SAA7164_PORT_VBI1 ];
1059 else
1060 vbiport = &dev->ports[ SAA7164_PORT_VBI2 ];
1061 memcpy(&vbiport->hwcfg, vcoutputtermhdr,
1062 sizeof(*vcoutputtermhdr));
1063 memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, sizeof(*vbifmt));
1064 saa7164_api_configure_port_vbi(dev,
1065 vbiport);
1066 break;
1067 case VS_FORMAT_RDS:
1068 dprintk(DBGLVL_API,
1069 " = VS_FORMAT_RDS\n");
1070 break;
1071 case VS_FORMAT_UNCOMPRESSED:
1072 dprintk(DBGLVL_API,
1073 " = VS_FORMAT_UNCOMPRESSED\n");
1074 break;
1075 case VS_FORMAT_TYPE:
1076 dprintk(DBGLVL_API,
1077 " = VS_FORMAT_TYPE\n");
1078 break;
1079 default:
1080 dprintk(DBGLVL_API,
1081 " = undefined (0x%x)\n",
1082 t->subtype);
1084 next_offset += t->len;
1087 break;
1088 case TUNER_UNIT:
1089 dprintk(DBGLVL_API, " TUNER_UNIT\n");
1090 tunerunithdr =
1091 (tmComResTunerDescrHeader_t *)(buf + idx);
1092 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1093 tunerunithdr->unitid);
1094 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1095 tunerunithdr->sourceid);
1096 dprintk(DBGLVL_API, " iunit = 0x%x\n",
1097 tunerunithdr->iunit);
1098 dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
1099 tunerunithdr->tuningstandards);
1100 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1101 tunerunithdr->controlsize);
1102 dprintk(DBGLVL_API, " controls = 0x%x\n",
1103 tunerunithdr->controls);
1105 if (tunerunithdr->unitid == tunerunithdr->iunit) {
1106 if (currpath == 1)
1107 encport = &dev->ports[ SAA7164_PORT_ENC1 ];
1108 else
1109 encport = &dev->ports[ SAA7164_PORT_ENC2 ];
1110 memcpy(&encport->tunerunit, tunerunithdr,
1111 sizeof(tmComResTunerDescrHeader_t));
1112 dprintk(DBGLVL_API, " (becomes dev->enc[%d] tuner)\n", encport->nr);
1114 break;
1115 case VC_SELECTOR_UNIT:
1116 psel = (tmComResSelDescrHeader_t *)(buf + idx);
1117 dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
1118 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1119 psel->unitid);
1120 dprintk(DBGLVL_API, " nrinpins = 0x%x\n",
1121 psel->nrinpins);
1122 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1123 psel->sourceid);
1124 break;
1125 case VC_PROCESSING_UNIT:
1126 pdh = (tmComResProcDescrHeader_t *)(buf + idx);
1127 dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
1128 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1129 pdh->unitid);
1130 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1131 pdh->sourceid);
1132 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1133 pdh->controlsize);
1134 if (pdh->controlsize == 0x04) {
1135 if (currpath == 1)
1136 encport = &dev->ports[ SAA7164_PORT_ENC1 ];
1137 else
1138 encport = &dev->ports[ SAA7164_PORT_ENC2 ];
1139 memcpy(&encport->vidproc, pdh,
1140 sizeof(tmComResProcDescrHeader_t));
1141 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
1143 break;
1144 case FEATURE_UNIT:
1145 afd = (tmComResAFeatureDescrHeader_t *)(buf + idx);
1146 dprintk(DBGLVL_API, " FEATURE_UNIT\n");
1147 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1148 afd->unitid);
1149 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
1150 afd->sourceid);
1151 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1152 afd->controlsize);
1153 if (currpath == 1)
1154 encport = &dev->ports[ SAA7164_PORT_ENC1 ];
1155 else
1156 encport = &dev->ports[ SAA7164_PORT_ENC2 ];
1157 memcpy(&encport->audfeat, afd,
1158 sizeof(tmComResAFeatureDescrHeader_t));
1159 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
1160 break;
1161 case ENCODER_UNIT:
1162 edh = (tmComResEncoderDescrHeader_t *)(buf + idx);
1163 dprintk(DBGLVL_API, " ENCODER_UNIT\n");
1164 dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype);
1165 dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid);
1166 dprintk(DBGLVL_API, " vsourceid = 0x%x\n", edh->vsourceid);
1167 dprintk(DBGLVL_API, " asourceid = 0x%x\n", edh->asourceid);
1168 dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit);
1169 if (edh->iunit == edh->unitid) {
1170 if (currpath == 1)
1171 encport = &dev->ports[ SAA7164_PORT_ENC1 ];
1172 else
1173 encport = &dev->ports[ SAA7164_PORT_ENC2 ];
1174 memcpy(&encport->encunit, edh,
1175 sizeof(tmComResEncoderDescrHeader_t));
1176 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
1178 break;
1179 case EXTENSION_UNIT:
1180 dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
1181 exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx);
1182 dprintk(DBGLVL_API, " unitid = 0x%x\n",
1183 exthdr->unitid);
1184 dprintk(DBGLVL_API, " deviceid = 0x%x\n",
1185 exthdr->deviceid);
1186 dprintk(DBGLVL_API, " devicetype = 0x%x\n",
1187 exthdr->devicetype);
1188 if (exthdr->devicetype & 0x1)
1189 dprintk(DBGLVL_API, " = Decoder Device\n");
1190 if (exthdr->devicetype & 0x2)
1191 dprintk(DBGLVL_API, " = GPIO Source\n");
1192 if (exthdr->devicetype & 0x4)
1193 dprintk(DBGLVL_API, " = Video Decoder\n");
1194 if (exthdr->devicetype & 0x8)
1195 dprintk(DBGLVL_API, " = Audio Decoder\n");
1196 if (exthdr->devicetype & 0x20)
1197 dprintk(DBGLVL_API, " = Crossbar\n");
1198 if (exthdr->devicetype & 0x40)
1199 dprintk(DBGLVL_API, " = Tuner\n");
1200 if (exthdr->devicetype & 0x80)
1201 dprintk(DBGLVL_API, " = IF PLL\n");
1202 if (exthdr->devicetype & 0x100)
1203 dprintk(DBGLVL_API, " = Demodulator\n");
1204 if (exthdr->devicetype & 0x200)
1205 dprintk(DBGLVL_API, " = RDS Decoder\n");
1206 if (exthdr->devicetype & 0x400)
1207 dprintk(DBGLVL_API, " = Encoder\n");
1208 if (exthdr->devicetype & 0x800)
1209 dprintk(DBGLVL_API, " = IR Decoder\n");
1210 if (exthdr->devicetype & 0x1000)
1211 dprintk(DBGLVL_API, " = EEPROM\n");
1212 if (exthdr->devicetype & 0x2000)
1213 dprintk(DBGLVL_API,
1214 " = VBI Decoder\n");
1215 if (exthdr->devicetype & 0x10000)
1216 dprintk(DBGLVL_API,
1217 " = Streaming Device\n");
1218 if (exthdr->devicetype & 0x20000)
1219 dprintk(DBGLVL_API,
1220 " = DRM Device\n");
1221 if (exthdr->devicetype & 0x40000000)
1222 dprintk(DBGLVL_API,
1223 " = Generic Device\n");
1224 if (exthdr->devicetype & 0x80000000)
1225 dprintk(DBGLVL_API,
1226 " = Config Space Device\n");
1227 dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
1228 exthdr->numgpiopins);
1229 dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
1230 exthdr->numgpiogroups);
1231 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
1232 exthdr->controlsize);
1233 if (exthdr->devicetype & 0x80) {
1234 if (currpath == 1)
1235 encport = &dev->ports[ SAA7164_PORT_ENC1 ];
1236 else
1237 encport = &dev->ports[ SAA7164_PORT_ENC2 ];
1238 memcpy(&encport->ifunit, exthdr,
1239 sizeof(tmComResExtDevDescrHeader_t));
1240 dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
1242 break;
1243 case PVC_INFRARED_UNIT:
1244 dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
1245 break;
1246 case DRM_UNIT:
1247 dprintk(DBGLVL_API, " DRM_UNIT\n");
1248 break;
1249 default:
1250 dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
1253 dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
1254 dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
1255 dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
1256 dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
1258 idx += hdr->len;
1261 return 0;
1264 int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
1266 int ret;
1267 u32 buflen = 0;
1268 u8 *buf;
1270 dprintk(DBGLVL_API, "%s()\n", __func__);
1272 /* Get the total descriptor length */
1273 ret = saa7164_cmd_send(dev, 0, GET_LEN,
1274 GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
1275 if (ret != SAA_OK)
1276 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1278 dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
1279 __func__, buflen);
1281 /* Allocate enough storage for all of the descs */
1282 buf = kzalloc(buflen, GFP_KERNEL);
1283 if (buf == NULL)
1284 return SAA_ERR_NO_RESOURCES;
1286 /* Retrieve them */
1287 ret = saa7164_cmd_send(dev, 0, GET_CUR,
1288 GET_DESCRIPTORS_CONTROL, buflen, buf);
1289 if (ret != SAA_OK) {
1290 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1291 goto out;
1294 if (saa_debug & DBGLVL_API)
1295 saa7164_dumphex16(dev, buf, (buflen/16)*16);
1297 saa7164_api_dump_subdevs(dev, buf, buflen);
1299 out:
1300 kfree(buf);
1301 return ret;
1304 int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
1305 u32 datalen, u8 *data)
1307 struct saa7164_dev *dev = bus->dev;
1308 u16 len = 0;
1309 int unitid;
1310 u32 regval;
1311 u8 buf[256];
1312 int ret;
1314 dprintk(DBGLVL_API, "%s()\n", __func__);
1316 if (reglen > 4)
1317 return -EIO;
1319 if (reglen == 1)
1320 regval = *(reg);
1321 else
1322 if (reglen == 2)
1323 regval = ((*(reg) << 8) || *(reg+1));
1324 else
1325 if (reglen == 3)
1326 regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
1327 else
1328 if (reglen == 4)
1329 regval = ((*(reg) << 24) | (*(reg+1) << 16) |
1330 (*(reg+2) << 8) | *(reg+3));
1332 /* Prepare the send buffer */
1333 /* Bytes 00-03 source register length
1334 * 04-07 source bytes to read
1335 * 08... register address
1337 memset(buf, 0, sizeof(buf));
1338 memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
1339 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1340 *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
1342 unitid = saa7164_i2caddr_to_unitid(bus, addr);
1343 if (unitid < 0) {
1344 printk(KERN_ERR
1345 "%s() error, cannot translate regaddr 0x%x to unitid\n",
1346 __func__, addr);
1347 return -EIO;
1350 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
1351 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
1352 if (ret != SAA_OK) {
1353 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1354 return -EIO;
1357 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
1359 if (saa_debug & DBGLVL_I2C)
1360 saa7164_dumphex16(dev, buf, 2 * 16);
1362 ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
1363 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
1364 if (ret != SAA_OK)
1365 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1366 else {
1367 if (saa_debug & DBGLVL_I2C)
1368 saa7164_dumphex16(dev, buf, sizeof(buf));
1369 memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
1372 return ret == SAA_OK ? 0 : -EIO;
1375 /* For a given 8 bit i2c address device, write the buffer */
1376 int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
1377 u8 *data)
1379 struct saa7164_dev *dev = bus->dev;
1380 u16 len = 0;
1381 int unitid;
1382 int reglen;
1383 u8 buf[256];
1384 int ret;
1386 dprintk(DBGLVL_API, "%s()\n", __func__);
1388 if ((datalen == 0) || (datalen > 232))
1389 return -EIO;
1391 memset(buf, 0, sizeof(buf));
1393 unitid = saa7164_i2caddr_to_unitid(bus, addr);
1394 if (unitid < 0) {
1395 printk(KERN_ERR
1396 "%s() error, cannot translate regaddr 0x%x to unitid\n",
1397 __func__, addr);
1398 return -EIO;
1401 reglen = saa7164_i2caddr_to_reglen(bus, addr);
1402 if (reglen < 0) {
1403 printk(KERN_ERR
1404 "%s() error, cannot translate regaddr to reglen\n",
1405 __func__);
1406 return -EIO;
1409 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
1410 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
1411 if (ret != SAA_OK) {
1412 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1413 return -EIO;
1416 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
1418 /* Prepare the send buffer */
1419 /* Bytes 00-03 dest register length
1420 * 04-07 dest bytes to write
1421 * 08... register address
1423 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1424 *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
1425 memcpy((buf + 2 * sizeof(u32)), data, datalen);
1427 if (saa_debug & DBGLVL_I2C)
1428 saa7164_dumphex16(dev, buf, sizeof(buf));
1430 ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
1431 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
1432 if (ret != SAA_OK)
1433 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1435 return ret == SAA_OK ? 0 : -EIO;
1439 int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
1440 u8 pin, u8 state)
1442 int ret;
1443 tmComResGPIO_t t;
1445 dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
1446 __func__, unitid, pin, state);
1448 if ((pin > 7) || (state > 2))
1449 return SAA_ERR_BAD_PARAMETER;
1451 t.pin = pin;
1452 t.state = state;
1454 ret = saa7164_cmd_send(dev, unitid, SET_CUR,
1455 EXU_GPIO_CONTROL, sizeof(t), &t);
1456 if (ret != SAA_OK)
1457 printk(KERN_ERR "%s() error, ret = 0x%x\n",
1458 __func__, ret);
1460 return ret;
1463 int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
1464 u8 pin)
1466 return saa7164_api_modify_gpio(dev, unitid, pin, 1);
1469 int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
1470 u8 pin)
1472 return saa7164_api_modify_gpio(dev, unitid, pin, 0);