[go: nahoru, domu]

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