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