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