Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Driver for the NXP SAA7164 PCIe bridge
0004  *
0005  *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
0006  */
0007 
0008 #include <linux/wait.h>
0009 #include <linux/slab.h>
0010 
0011 #include "saa7164.h"
0012 
0013 int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i)
0014 {
0015     int ret;
0016 
0017     if (!(saa_debug & DBGLVL_CPU))
0018         return 0;
0019 
0020     dprintk(DBGLVL_API, "%s()\n", __func__);
0021 
0022     i->deviceinst = 0;
0023     i->devicespec = 0;
0024     i->mode = 0;
0025     i->status = 0;
0026 
0027     ret = saa7164_cmd_send(dev, 0, GET_CUR,
0028         GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i);
0029     if (ret != SAA_OK)
0030         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0031 
0032     printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad);
0033 
0034     return ret;
0035 }
0036 
0037 int saa7164_api_collect_debug(struct saa7164_dev *dev)
0038 {
0039     struct tmComResDebugGetData d;
0040     u8 more = 255;
0041     int ret;
0042 
0043     dprintk(DBGLVL_API, "%s()\n", __func__);
0044 
0045     while (more--) {
0046 
0047         memset(&d, 0, sizeof(d));
0048 
0049         ret = saa7164_cmd_send(dev, 0, GET_CUR,
0050             GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
0051         if (ret != SAA_OK)
0052             printk(KERN_ERR "%s() error, ret = 0x%x\n",
0053                 __func__, ret);
0054 
0055         if (d.dwResult != SAA_OK)
0056             break;
0057 
0058         printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr,
0059             d.ucDebugData);
0060     }
0061 
0062     return 0;
0063 }
0064 
0065 int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
0066 {
0067     struct tmComResDebugSetLevel lvl;
0068     int ret;
0069 
0070     dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level);
0071 
0072     /* Retrieve current state */
0073     ret = saa7164_cmd_send(dev, 0, GET_CUR,
0074         SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
0075     if (ret != SAA_OK)
0076         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0077 
0078     dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
0079 
0080     lvl.dwDebugLevel = level;
0081 
0082     /* set new state */
0083     ret = saa7164_cmd_send(dev, 0, SET_CUR,
0084         SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
0085     if (ret != SAA_OK)
0086         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0087 
0088     return ret;
0089 }
0090 
0091 int saa7164_api_set_vbi_format(struct saa7164_port *port)
0092 {
0093     struct saa7164_dev *dev = port->dev;
0094     struct tmComResProbeCommit fmt, rsp;
0095     int ret;
0096 
0097     dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__,
0098         port->nr, port->hwcfg.unitid);
0099 
0100     fmt.bmHint = 0;
0101     fmt.bFormatIndex = 1;
0102     fmt.bFrameIndex = 1;
0103 
0104     /* Probe, see if it can support this format */
0105     ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
0106         SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt);
0107     if (ret != SAA_OK)
0108         printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret);
0109 
0110     /* See of the format change was successful */
0111     ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
0112         GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp);
0113     if (ret != SAA_OK) {
0114         printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret);
0115     } else {
0116         /* Compare requested vs received, should be same */
0117         if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
0118             dprintk(DBGLVL_API, "SET/PROBE Verified\n");
0119 
0120             /* Ask the device to select the negotiated format */
0121             ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
0122                 SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
0123             if (ret != SAA_OK)
0124                 printk(KERN_ERR "%s() commit error, ret = 0x%x\n",
0125                     __func__, ret);
0126 
0127             ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
0128                 GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp);
0129             if (ret != SAA_OK)
0130                 printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
0131                     __func__, ret);
0132 
0133             if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) {
0134                 printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
0135                     __func__, ret);
0136             } else
0137                 dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
0138 
0139             dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
0140             dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n",
0141                 rsp.bFormatIndex);
0142             dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n",
0143                 rsp.bFrameIndex);
0144         } else
0145             printk(KERN_ERR "%s() compare failed\n", __func__);
0146     }
0147 
0148     if (ret == SAA_OK)
0149         dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr);
0150 
0151     return ret;
0152 }
0153 
0154 static int saa7164_api_set_gop_size(struct saa7164_port *port)
0155 {
0156     struct saa7164_dev *dev = port->dev;
0157     struct tmComResEncVideoGopStructure gs;
0158     int ret;
0159 
0160     dprintk(DBGLVL_ENC, "%s()\n", __func__);
0161 
0162     gs.ucRefFrameDist = port->encoder_params.refdist;
0163     gs.ucGOPSize = port->encoder_params.gop_size;
0164     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
0165         EU_VIDEO_GOP_STRUCTURE_CONTROL,
0166         sizeof(gs), &gs);
0167     if (ret != SAA_OK)
0168         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0169 
0170     return ret;
0171 }
0172 
0173 int saa7164_api_set_encoder(struct saa7164_port *port)
0174 {
0175     struct saa7164_dev *dev = port->dev;
0176     struct tmComResEncVideoBitRate vb;
0177     struct tmComResEncAudioBitRate ab;
0178     int ret;
0179 
0180     dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
0181         port->hwcfg.sourceid);
0182 
0183     if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
0184         port->encoder_profile = EU_PROFILE_PS_DVD;
0185     else
0186         port->encoder_profile = EU_PROFILE_TS_HQ;
0187 
0188     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
0189         EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
0190     if (ret != SAA_OK)
0191         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0192 
0193     /* Resolution */
0194     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
0195         EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
0196     if (ret != SAA_OK)
0197         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0198 
0199     /* Establish video bitrates */
0200     if (port->encoder_params.bitrate_mode ==
0201         V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
0202         vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT;
0203     else
0204         vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK;
0205     vb.dwVideoBitRate = port->encoder_params.bitrate;
0206     vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak;
0207     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
0208         EU_VIDEO_BIT_RATE_CONTROL,
0209         sizeof(struct tmComResEncVideoBitRate),
0210         &vb);
0211     if (ret != SAA_OK)
0212         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0213 
0214     /* Establish audio bitrates */
0215     ab.ucAudioBitRateMode = 0;
0216     ab.dwAudioBitRate = 384000;
0217     ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
0218     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
0219         EU_AUDIO_BIT_RATE_CONTROL,
0220         sizeof(struct tmComResEncAudioBitRate),
0221         &ab);
0222     if (ret != SAA_OK)
0223         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
0224             ret);
0225 
0226     saa7164_api_set_aspect_ratio(port);
0227     saa7164_api_set_gop_size(port);
0228 
0229     return ret;
0230 }
0231 
0232 int saa7164_api_get_encoder(struct saa7164_port *port)
0233 {
0234     struct saa7164_dev *dev = port->dev;
0235     struct tmComResEncVideoBitRate v;
0236     struct tmComResEncAudioBitRate a;
0237     struct tmComResEncVideoInputAspectRatio ar;
0238     int ret;
0239 
0240     dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
0241         port->hwcfg.sourceid);
0242 
0243     port->encoder_profile = 0;
0244     port->video_format = 0;
0245     port->video_resolution = 0;
0246     port->audio_format = 0;
0247 
0248     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
0249         EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
0250     if (ret != SAA_OK)
0251         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0252 
0253     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
0254         EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8),
0255         &port->video_resolution);
0256     if (ret != SAA_OK)
0257         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0258 
0259     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
0260         EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format);
0261     if (ret != SAA_OK)
0262         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0263 
0264     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
0265         EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v);
0266     if (ret != SAA_OK)
0267         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0268 
0269     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
0270         EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format);
0271     if (ret != SAA_OK)
0272         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0273 
0274     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
0275         EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a);
0276     if (ret != SAA_OK)
0277         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0278 
0279     /* Aspect Ratio */
0280     ar.width = 0;
0281     ar.height = 0;
0282     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
0283         EU_VIDEO_INPUT_ASPECT_CONTROL,
0284         sizeof(struct tmComResEncVideoInputAspectRatio), &ar);
0285     if (ret != SAA_OK)
0286         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0287 
0288     dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile);
0289     dprintk(DBGLVL_ENC, "video_format    = %d\n", port->video_format);
0290     dprintk(DBGLVL_ENC, "audio_format    = %d\n", port->audio_format);
0291     dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
0292     dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n",
0293         v.ucVideoBitRateMode);
0294     dprintk(DBGLVL_ENC, "v.dwVideoBitRate     = %d\n",
0295         v.dwVideoBitRate);
0296     dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n",
0297         v.dwVideoBitRatePeak);
0298     dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n",
0299         a.ucAudioBitRateMode);
0300     dprintk(DBGLVL_ENC, "a.dwVideoBitRate     = %d\n",
0301         a.dwAudioBitRate);
0302     dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n",
0303         a.dwAudioBitRatePeak);
0304     dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n",
0305         ar.width, ar.height);
0306 
0307     return ret;
0308 }
0309 
0310 int saa7164_api_set_aspect_ratio(struct saa7164_port *port)
0311 {
0312     struct saa7164_dev *dev = port->dev;
0313     struct tmComResEncVideoInputAspectRatio ar;
0314     int ret;
0315 
0316     dprintk(DBGLVL_ENC, "%s(%d)\n", __func__,
0317         port->encoder_params.ctl_aspect);
0318 
0319     switch (port->encoder_params.ctl_aspect) {
0320     case V4L2_MPEG_VIDEO_ASPECT_1x1:
0321         ar.width = 1;
0322         ar.height = 1;
0323         break;
0324     case V4L2_MPEG_VIDEO_ASPECT_4x3:
0325         ar.width = 4;
0326         ar.height = 3;
0327         break;
0328     case V4L2_MPEG_VIDEO_ASPECT_16x9:
0329         ar.width = 16;
0330         ar.height = 9;
0331         break;
0332     case V4L2_MPEG_VIDEO_ASPECT_221x100:
0333         ar.width = 221;
0334         ar.height = 100;
0335         break;
0336     default:
0337         BUG();
0338     }
0339 
0340     dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__,
0341         port->encoder_params.ctl_aspect,
0342         ar.width, ar.height);
0343 
0344     /* Aspect Ratio */
0345     ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
0346         EU_VIDEO_INPUT_ASPECT_CONTROL,
0347         sizeof(struct tmComResEncVideoInputAspectRatio), &ar);
0348     if (ret != SAA_OK)
0349         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0350 
0351     return ret;
0352 }
0353 
0354 int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl)
0355 {
0356     struct saa7164_dev *dev = port->dev;
0357     int ret;
0358     u16 val;
0359 
0360     if (ctl == PU_BRIGHTNESS_CONTROL)
0361         val = port->ctl_brightness;
0362     else
0363     if (ctl == PU_CONTRAST_CONTROL)
0364         val = port->ctl_contrast;
0365     else
0366     if (ctl == PU_HUE_CONTROL)
0367         val = port->ctl_hue;
0368     else
0369     if (ctl == PU_SATURATION_CONTROL)
0370         val = port->ctl_saturation;
0371     else
0372     if (ctl == PU_SHARPNESS_CONTROL)
0373         val = port->ctl_sharpness;
0374     else
0375         return -EINVAL;
0376 
0377     dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n",
0378         __func__, port->encunit.vsourceid, ctl, val);
0379 
0380     ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR,
0381         ctl, sizeof(u16), &val);
0382     if (ret != SAA_OK)
0383         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0384 
0385     return ret;
0386 }
0387 
0388 int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl)
0389 {
0390     struct saa7164_dev *dev = port->dev;
0391     int ret;
0392     u16 val;
0393 
0394     ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR,
0395         ctl, sizeof(u16), &val);
0396     if (ret != SAA_OK) {
0397         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0398         return ret;
0399     }
0400 
0401     dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n",
0402         __func__, ctl, val);
0403 
0404     if (ctl == PU_BRIGHTNESS_CONTROL)
0405         port->ctl_brightness = val;
0406     else
0407     if (ctl == PU_CONTRAST_CONTROL)
0408         port->ctl_contrast = val;
0409     else
0410     if (ctl == PU_HUE_CONTROL)
0411         port->ctl_hue = val;
0412     else
0413     if (ctl == PU_SATURATION_CONTROL)
0414         port->ctl_saturation = val;
0415     else
0416     if (ctl == PU_SHARPNESS_CONTROL)
0417         port->ctl_sharpness = val;
0418 
0419     return ret;
0420 }
0421 
0422 int saa7164_api_set_videomux(struct saa7164_port *port)
0423 {
0424     struct saa7164_dev *dev = port->dev;
0425     u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 };
0426     int ret;
0427 
0428     dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n",
0429         __func__, port->mux_input, inputs[port->mux_input - 1]);
0430 
0431     /* Audio Mute */
0432     ret = saa7164_api_audio_mute(port, 1);
0433     if (ret != SAA_OK)
0434         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0435 
0436     /* Video Mux */
0437     ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR,
0438         SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
0439     if (ret != SAA_OK)
0440         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0441 
0442     /* Audio Mux */
0443     ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
0444         SU_INPUT_SELECT_CONTROL, sizeof(u8),
0445         &inputs[port->mux_input - 1]);
0446     if (ret != SAA_OK)
0447         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0448 
0449     /* Audio UnMute */
0450     ret = saa7164_api_audio_mute(port, 0);
0451     if (ret != SAA_OK)
0452         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0453 
0454     return ret;
0455 }
0456 
0457 int saa7164_api_audio_mute(struct saa7164_port *port, int mute)
0458 {
0459     struct saa7164_dev *dev = port->dev;
0460     u8 v = mute;
0461     int ret;
0462 
0463     dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute);
0464 
0465     ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
0466         MUTE_CONTROL, sizeof(u8), &v);
0467     if (ret != SAA_OK)
0468         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0469 
0470     return ret;
0471 }
0472 
0473 /* 0 = silence, 0xff = full */
0474 int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
0475 {
0476     struct saa7164_dev *dev = port->dev;
0477     s16 v, min, max;
0478     int ret;
0479 
0480     dprintk(DBGLVL_API, "%s(%d)\n", __func__, level);
0481 
0482     /* Obtain the min/max ranges */
0483     ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN,
0484         VOLUME_CONTROL, sizeof(u16), &min);
0485     if (ret != SAA_OK)
0486         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0487 
0488     ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX,
0489         VOLUME_CONTROL, sizeof(u16), &max);
0490     if (ret != SAA_OK)
0491         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0492 
0493     ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
0494         (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
0495     if (ret != SAA_OK)
0496         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0497 
0498     dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
0499         level, min, max, v);
0500 
0501     v = level;
0502     if (v < min)
0503         v = min;
0504     if (v > max)
0505         v = max;
0506 
0507     /* Left */
0508     ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
0509         (0x01 << 8) | VOLUME_CONTROL, sizeof(s16), &v);
0510     if (ret != SAA_OK)
0511         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0512 
0513     /* Right */
0514     ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
0515         (0x02 << 8) | VOLUME_CONTROL, sizeof(s16), &v);
0516     if (ret != SAA_OK)
0517         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0518 
0519     ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
0520         (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
0521     if (ret != SAA_OK)
0522         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0523 
0524     dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
0525         level, min, max, v);
0526 
0527     return ret;
0528 }
0529 
0530 int saa7164_api_set_audio_std(struct saa7164_port *port)
0531 {
0532     struct saa7164_dev *dev = port->dev;
0533     struct tmComResAudioDefaults lvl;
0534     struct tmComResTunerStandard tvaudio;
0535     int ret;
0536 
0537     dprintk(DBGLVL_API, "%s()\n", __func__);
0538 
0539     /* Establish default levels */
0540     lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT;
0541     lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT;
0542     lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT;
0543     lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT;
0544     lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
0545     lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
0546     ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
0547         AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults),
0548         &lvl);
0549     if (ret != SAA_OK)
0550         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0551 
0552     /* Manually select the appropriate TV audio standard */
0553     if (port->encodernorm.id & V4L2_STD_NTSC) {
0554         tvaudio.std = TU_STANDARD_NTSC_M;
0555         tvaudio.country = 1;
0556     } else {
0557         tvaudio.std = TU_STANDARD_PAL_I;
0558         tvaudio.country = 44;
0559     }
0560 
0561     ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
0562         TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
0563     if (ret != SAA_OK)
0564         printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n",
0565             __func__, ret);
0566     return ret;
0567 }
0568 
0569 int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
0570 {
0571     struct saa7164_dev *dev = port->dev;
0572     struct tmComResTunerStandardAuto p;
0573     int ret;
0574 
0575     dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect);
0576 
0577     /* Disable TV Audio autodetect if not already set (buggy) */
0578     if (autodetect)
0579         p.mode = TU_STANDARD_AUTO;
0580     else
0581         p.mode = TU_STANDARD_MANUAL;
0582     ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
0583         TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
0584     if (ret != SAA_OK)
0585         printk(KERN_ERR
0586             "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n",
0587             __func__, ret);
0588 
0589     return ret;
0590 }
0591 
0592 int saa7164_api_get_videomux(struct saa7164_port *port)
0593 {
0594     struct saa7164_dev *dev = port->dev;
0595     int ret;
0596 
0597     ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR,
0598         SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
0599     if (ret != SAA_OK)
0600         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0601 
0602     dprintk(DBGLVL_ENC, "%s() v_mux=%d\n",
0603         __func__, port->mux_input);
0604 
0605     return ret;
0606 }
0607 
0608 static int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
0609 {
0610     struct saa7164_dev *dev = port->dev;
0611 
0612     u16 len = 0;
0613     u8 buf[256];
0614     int ret;
0615     u8 mas;
0616 
0617     dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__,
0618         port->nr, port->type, val);
0619 
0620     if (port->nr == 0)
0621         mas = 0xd0;
0622     else
0623         mas = 0xe0;
0624 
0625     memset(buf, 0, sizeof(buf));
0626 
0627     buf[0x00] = 0x04;
0628     buf[0x01] = 0x00;
0629     buf[0x02] = 0x00;
0630     buf[0x03] = 0x00;
0631 
0632     buf[0x04] = 0x04;
0633     buf[0x05] = 0x00;
0634     buf[0x06] = 0x00;
0635     buf[0x07] = 0x00;
0636 
0637     buf[0x08] = reg;
0638     buf[0x09] = 0x26;
0639     buf[0x0a] = mas;
0640     buf[0x0b] = 0xb0;
0641 
0642     buf[0x0c] = val;
0643     buf[0x0d] = 0x00;
0644     buf[0x0e] = 0x00;
0645     buf[0x0f] = 0x00;
0646 
0647     ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN,
0648         EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
0649     if (ret != SAA_OK) {
0650         printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
0651         return -EIO;
0652     }
0653 
0654     ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR,
0655         EXU_REGISTER_ACCESS_CONTROL, len, &buf);
0656     if (ret != SAA_OK)
0657         printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
0658 #if 0
0659     print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, 16,
0660                false);
0661 #endif
0662     return ret == SAA_OK ? 0 : -EIO;
0663 }
0664 
0665 /* Disable the IF block AGC controls */
0666 int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
0667 {
0668     struct saa7164_dev *dev = port->dev;
0669     u8 agc_disable;
0670 
0671     dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std);
0672 
0673     if (std & V4L2_STD_NTSC) {
0674         dprintk(DBGLVL_API, " NTSC\n");
0675         saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
0676         agc_disable = 0;
0677     } else if (std & V4L2_STD_PAL_I) {
0678         dprintk(DBGLVL_API, " PAL-I\n");
0679         saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */
0680         agc_disable = 0;
0681     } else if (std & V4L2_STD_PAL_M) {
0682         dprintk(DBGLVL_API, " PAL-M\n");
0683         saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
0684         agc_disable = 0;
0685     } else if (std & V4L2_STD_PAL_N) {
0686         dprintk(DBGLVL_API, " PAL-N\n");
0687         saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
0688         agc_disable = 0;
0689     } else if (std & V4L2_STD_PAL_Nc) {
0690         dprintk(DBGLVL_API, " PAL-Nc\n");
0691         saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
0692         agc_disable = 0;
0693     } else if (std & V4L2_STD_PAL_B) {
0694         dprintk(DBGLVL_API, " PAL-B\n");
0695         saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */
0696         agc_disable = 0;
0697     } else if (std & V4L2_STD_PAL_DK) {
0698         dprintk(DBGLVL_API, " PAL-DK\n");
0699         saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */
0700         agc_disable = 0;
0701     } else if (std & V4L2_STD_SECAM_L) {
0702         dprintk(DBGLVL_API, " SECAM-L\n");
0703         saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */
0704         agc_disable = 0;
0705     } else {
0706         /* Unknown standard, assume DTV */
0707         dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
0708         /* Undefinded Video Standard */
0709         saa7164_api_set_dif(port, 0x00, 0x80);
0710         agc_disable = 1;
0711     }
0712 
0713     saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */
0714     saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */
0715     saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */
0716     saa7164_api_set_dif(port, 0x04, 0x01); /* Active */
0717     msleep(100);
0718     saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */
0719     msleep(100);
0720 
0721     return 0;
0722 }
0723 
0724 /* Ensure the dif is in the correct state for the operating mode
0725  * (analog / dtv). We only configure the diff through the analog encoder
0726  * so when we're in digital mode we need to find the appropriate encoder
0727  * and use it to configure the DIF.
0728  */
0729 int saa7164_api_initialize_dif(struct saa7164_port *port)
0730 {
0731     struct saa7164_dev *dev = port->dev;
0732     struct saa7164_port *p = NULL;
0733     int ret = -EINVAL;
0734     u32 std = 0;
0735 
0736     dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__,
0737         port->nr, port->type);
0738 
0739     if (port->type == SAA7164_MPEG_ENCODER) {
0740         /* Pick any analog standard to init the diff.
0741          * we'll come back during encoder_init'
0742          * and set the correct standard if required.
0743          */
0744         std = V4L2_STD_NTSC;
0745     } else
0746     if (port->type == SAA7164_MPEG_DVB) {
0747         if (port->nr == SAA7164_PORT_TS1)
0748             p = &dev->ports[SAA7164_PORT_ENC1];
0749         else
0750             p = &dev->ports[SAA7164_PORT_ENC2];
0751     } else
0752     if (port->type == SAA7164_MPEG_VBI) {
0753         std = V4L2_STD_NTSC;
0754         if (port->nr == SAA7164_PORT_VBI1)
0755             p = &dev->ports[SAA7164_PORT_ENC1];
0756         else
0757             p = &dev->ports[SAA7164_PORT_ENC2];
0758     } else
0759         BUG();
0760 
0761     if (p)
0762         ret = saa7164_api_configure_dif(p, std);
0763 
0764     return ret;
0765 }
0766 
0767 int saa7164_api_transition_port(struct saa7164_port *port, u8 mode)
0768 {
0769     struct saa7164_dev *dev = port->dev;
0770 
0771     int ret;
0772 
0773     dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n",
0774         __func__, port->nr, port->hwcfg.unitid, mode);
0775 
0776     ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
0777         SAA_STATE_CONTROL, sizeof(mode), &mode);
0778     if (ret != SAA_OK)
0779         printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n",
0780             __func__, port->nr, port->hwcfg.unitid, ret);
0781 
0782     return ret;
0783 }
0784 
0785 int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
0786 {
0787     int ret;
0788 
0789     ret = saa7164_cmd_send(dev, 0, GET_CUR,
0790         GET_FW_VERSION_CONTROL, sizeof(u32), version);
0791     if (ret != SAA_OK)
0792         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
0793 
0794     return ret;
0795 }
0796 
0797 int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
0798 {
0799     u8 reg[] = { 0x0f, 0x00 };
0800 
0801     if (buflen < 128)
0802         return -ENOMEM;
0803 
0804     /* Assumption: Hauppauge eeprom is at 0xa0 on bus 0 */
0805     /* TODO: Pull the details from the boards struct */
0806     return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
0807         &reg[0], 128, buf);
0808 }
0809 
0810 static int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
0811                       struct saa7164_port *port)
0812 {
0813     struct tmComResVBIFormatDescrHeader *fmt = &port->vbi_fmt_ntsc;
0814 
0815     dprintk(DBGLVL_API, "    bFormatIndex  = 0x%x\n", fmt->bFormatIndex);
0816     dprintk(DBGLVL_API, "    VideoStandard = 0x%x\n", fmt->VideoStandard);
0817     dprintk(DBGLVL_API, "    StartLine     = %d\n", fmt->StartLine);
0818     dprintk(DBGLVL_API, "    EndLine       = %d\n", fmt->EndLine);
0819     dprintk(DBGLVL_API, "    FieldRate     = %d\n", fmt->FieldRate);
0820     dprintk(DBGLVL_API, "    bNumLines     = %d\n", fmt->bNumLines);
0821 
0822     /* Cache the hardware configuration in the port */
0823 
0824     port->bufcounter = port->hwcfg.BARLocation;
0825     port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
0826     port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
0827     port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
0828     port->bufptr32l = port->hwcfg.BARLocation +
0829         (4 * sizeof(u32)) +
0830         (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
0831     port->bufptr32h = port->hwcfg.BARLocation +
0832         (4 * sizeof(u32)) +
0833         (sizeof(u32) * port->hwcfg.buffercount);
0834     port->bufptr64 = port->hwcfg.BARLocation +
0835         (4 * sizeof(u32)) +
0836         (sizeof(u32) * port->hwcfg.buffercount);
0837     dprintk(DBGLVL_API, "   = port->hwcfg.BARLocation = 0x%x\n",
0838         port->hwcfg.BARLocation);
0839 
0840     dprintk(DBGLVL_API, "   = VS_FORMAT_VBI (becomes dev->en[%d])\n",
0841         port->nr);
0842 
0843     return 0;
0844 }
0845 
0846 static int
0847 saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
0848                    struct saa7164_port *port,
0849                    struct tmComResTSFormatDescrHeader *tsfmt)
0850 {
0851     dprintk(DBGLVL_API, "    bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
0852     dprintk(DBGLVL_API, "    bDataOffset  = 0x%x\n", tsfmt->bDataOffset);
0853     dprintk(DBGLVL_API, "    bPacketLength= 0x%x\n", tsfmt->bPacketLength);
0854     dprintk(DBGLVL_API, "    bStrideLength= 0x%x\n", tsfmt->bStrideLength);
0855     dprintk(DBGLVL_API, "    bguid        = (....)\n");
0856 
0857     /* Cache the hardware configuration in the port */
0858 
0859     port->bufcounter = port->hwcfg.BARLocation;
0860     port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
0861     port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
0862     port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
0863     port->bufptr32l = port->hwcfg.BARLocation +
0864         (4 * sizeof(u32)) +
0865         (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
0866     port->bufptr32h = port->hwcfg.BARLocation +
0867         (4 * sizeof(u32)) +
0868         (sizeof(u32) * port->hwcfg.buffercount);
0869     port->bufptr64 = port->hwcfg.BARLocation +
0870         (4 * sizeof(u32)) +
0871         (sizeof(u32) * port->hwcfg.buffercount);
0872     dprintk(DBGLVL_API, "   = port->hwcfg.BARLocation = 0x%x\n",
0873         port->hwcfg.BARLocation);
0874 
0875     dprintk(DBGLVL_API, "   = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
0876         port->nr);
0877 
0878     return 0;
0879 }
0880 
0881 static int
0882 saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
0883                    struct saa7164_port *port,
0884                    struct tmComResPSFormatDescrHeader *fmt)
0885 {
0886     dprintk(DBGLVL_API, "    bFormatIndex = 0x%x\n", fmt->bFormatIndex);
0887     dprintk(DBGLVL_API, "    wPacketLength= 0x%x\n", fmt->wPacketLength);
0888     dprintk(DBGLVL_API, "    wPackLength=   0x%x\n", fmt->wPackLength);
0889     dprintk(DBGLVL_API, "    bPackDataType= 0x%x\n", fmt->bPackDataType);
0890 
0891     /* Cache the hardware configuration in the port */
0892     /* TODO: CHECK THIS in the port config */
0893     port->bufcounter = port->hwcfg.BARLocation;
0894     port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
0895     port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
0896     port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
0897     port->bufptr32l = port->hwcfg.BARLocation +
0898         (4 * sizeof(u32)) +
0899         (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
0900     port->bufptr32h = port->hwcfg.BARLocation +
0901         (4 * sizeof(u32)) +
0902         (sizeof(u32) * port->hwcfg.buffercount);
0903     port->bufptr64 = port->hwcfg.BARLocation +
0904         (4 * sizeof(u32)) +
0905         (sizeof(u32) * port->hwcfg.buffercount);
0906     dprintk(DBGLVL_API, "   = port->hwcfg.BARLocation = 0x%x\n",
0907         port->hwcfg.BARLocation);
0908 
0909     dprintk(DBGLVL_API, "   = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n",
0910         port->nr);
0911 
0912     return 0;
0913 }
0914 
0915 static int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
0916 {
0917     struct saa7164_port *tsport = NULL;
0918     struct saa7164_port *encport = NULL;
0919     struct saa7164_port *vbiport = NULL;
0920     u32 idx, next_offset;
0921     int i;
0922     struct tmComResDescrHeader *hdr, *t;
0923     struct tmComResExtDevDescrHeader *exthdr;
0924     struct tmComResPathDescrHeader *pathhdr;
0925     struct tmComResAntTermDescrHeader *anttermhdr;
0926     struct tmComResTunerDescrHeader *tunerunithdr;
0927     struct tmComResDMATermDescrHeader *vcoutputtermhdr;
0928     struct tmComResTSFormatDescrHeader *tsfmt;
0929     struct tmComResPSFormatDescrHeader *psfmt;
0930     struct tmComResSelDescrHeader *psel;
0931     struct tmComResProcDescrHeader *pdh;
0932     struct tmComResAFeatureDescrHeader *afd;
0933     struct tmComResEncoderDescrHeader *edh;
0934     struct tmComResVBIFormatDescrHeader *vbifmt;
0935     u32 currpath = 0;
0936 
0937     dprintk(DBGLVL_API,
0938         "%s(?,?,%d) sizeof(struct tmComResDescrHeader) = %d bytes\n",
0939         __func__, len, (u32)sizeof(struct tmComResDescrHeader));
0940 
0941     for (idx = 0; idx < (len - sizeof(struct tmComResDescrHeader));) {
0942 
0943         hdr = (struct tmComResDescrHeader *)(buf + idx);
0944 
0945         if (hdr->type != CS_INTERFACE)
0946             return SAA_ERR_NOT_SUPPORTED;
0947 
0948         dprintk(DBGLVL_API, "@ 0x%x =\n", idx);
0949         switch (hdr->subtype) {
0950         case GENERAL_REQUEST:
0951             dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
0952             break;
0953         case VC_TUNER_PATH:
0954             dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
0955             pathhdr = (struct tmComResPathDescrHeader *)(buf + idx);
0956             dprintk(DBGLVL_API, "  pathid = 0x%x\n",
0957                 pathhdr->pathid);
0958             currpath = pathhdr->pathid;
0959             break;
0960         case VC_INPUT_TERMINAL:
0961             dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
0962             anttermhdr =
0963                 (struct tmComResAntTermDescrHeader *)(buf + idx);
0964             dprintk(DBGLVL_API, "  terminalid   = 0x%x\n",
0965                 anttermhdr->terminalid);
0966             dprintk(DBGLVL_API, "  terminaltype = 0x%x\n",
0967                 anttermhdr->terminaltype);
0968             switch (anttermhdr->terminaltype) {
0969             case ITT_ANTENNA:
0970                 dprintk(DBGLVL_API, "   = ITT_ANTENNA\n");
0971                 break;
0972             case LINE_CONNECTOR:
0973                 dprintk(DBGLVL_API, "   = LINE_CONNECTOR\n");
0974                 break;
0975             case SPDIF_CONNECTOR:
0976                 dprintk(DBGLVL_API, "   = SPDIF_CONNECTOR\n");
0977                 break;
0978             case COMPOSITE_CONNECTOR:
0979                 dprintk(DBGLVL_API,
0980                     "   = COMPOSITE_CONNECTOR\n");
0981                 break;
0982             case SVIDEO_CONNECTOR:
0983                 dprintk(DBGLVL_API, "   = SVIDEO_CONNECTOR\n");
0984                 break;
0985             case COMPONENT_CONNECTOR:
0986                 dprintk(DBGLVL_API,
0987                     "   = COMPONENT_CONNECTOR\n");
0988                 break;
0989             case STANDARD_DMA:
0990                 dprintk(DBGLVL_API, "   = STANDARD_DMA\n");
0991                 break;
0992             default:
0993                 dprintk(DBGLVL_API, "   = undefined (0x%x)\n",
0994                     anttermhdr->terminaltype);
0995             }
0996             dprintk(DBGLVL_API, "  assocterminal= 0x%x\n",
0997                 anttermhdr->assocterminal);
0998             dprintk(DBGLVL_API, "  iterminal    = 0x%x\n",
0999                 anttermhdr->iterminal);
1000             dprintk(DBGLVL_API, "  controlsize  = 0x%x\n",
1001                 anttermhdr->controlsize);
1002             break;
1003         case VC_OUTPUT_TERMINAL:
1004             dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
1005             vcoutputtermhdr =
1006                 (struct tmComResDMATermDescrHeader *)(buf + idx);
1007             dprintk(DBGLVL_API, "  unitid = 0x%x\n",
1008                 vcoutputtermhdr->unitid);
1009             dprintk(DBGLVL_API, "  terminaltype = 0x%x\n",
1010                 vcoutputtermhdr->terminaltype);
1011             switch (vcoutputtermhdr->terminaltype) {
1012             case ITT_ANTENNA:
1013                 dprintk(DBGLVL_API, "   = ITT_ANTENNA\n");
1014                 break;
1015             case LINE_CONNECTOR:
1016                 dprintk(DBGLVL_API, "   = LINE_CONNECTOR\n");
1017                 break;
1018             case SPDIF_CONNECTOR:
1019                 dprintk(DBGLVL_API, "   = SPDIF_CONNECTOR\n");
1020                 break;
1021             case COMPOSITE_CONNECTOR:
1022                 dprintk(DBGLVL_API,
1023                     "   = COMPOSITE_CONNECTOR\n");
1024                 break;
1025             case SVIDEO_CONNECTOR:
1026                 dprintk(DBGLVL_API, "   = SVIDEO_CONNECTOR\n");
1027                 break;
1028             case COMPONENT_CONNECTOR:
1029                 dprintk(DBGLVL_API,
1030                     "   = COMPONENT_CONNECTOR\n");
1031                 break;
1032             case STANDARD_DMA:
1033                 dprintk(DBGLVL_API, "   = STANDARD_DMA\n");
1034                 break;
1035             default:
1036                 dprintk(DBGLVL_API, "   = undefined (0x%x)\n",
1037                     vcoutputtermhdr->terminaltype);
1038             }
1039             dprintk(DBGLVL_API, "  assocterminal= 0x%x\n",
1040                 vcoutputtermhdr->assocterminal);
1041             dprintk(DBGLVL_API, "  sourceid     = 0x%x\n",
1042                 vcoutputtermhdr->sourceid);
1043             dprintk(DBGLVL_API, "  iterminal    = 0x%x\n",
1044                 vcoutputtermhdr->iterminal);
1045             dprintk(DBGLVL_API, "  BARLocation  = 0x%x\n",
1046                 vcoutputtermhdr->BARLocation);
1047             dprintk(DBGLVL_API, "  flags        = 0x%x\n",
1048                 vcoutputtermhdr->flags);
1049             dprintk(DBGLVL_API, "  interruptid  = 0x%x\n",
1050                 vcoutputtermhdr->interruptid);
1051             dprintk(DBGLVL_API, "  buffercount  = 0x%x\n",
1052                 vcoutputtermhdr->buffercount);
1053             dprintk(DBGLVL_API, "  metadatasize = 0x%x\n",
1054                 vcoutputtermhdr->metadatasize);
1055             dprintk(DBGLVL_API, "  controlsize  = 0x%x\n",
1056                 vcoutputtermhdr->controlsize);
1057             dprintk(DBGLVL_API, "  numformats   = 0x%x\n",
1058                 vcoutputtermhdr->numformats);
1059 
1060             next_offset = idx + (vcoutputtermhdr->len);
1061             for (i = 0; i < vcoutputtermhdr->numformats; i++) {
1062                 t = (struct tmComResDescrHeader *)
1063                     (buf + next_offset);
1064                 switch (t->subtype) {
1065                 case VS_FORMAT_MPEG2TS:
1066                     tsfmt =
1067                     (struct tmComResTSFormatDescrHeader *)t;
1068                     if (currpath == 1)
1069                         tsport = &dev->ports[SAA7164_PORT_TS1];
1070                     else
1071                         tsport = &dev->ports[SAA7164_PORT_TS2];
1072                     memcpy(&tsport->hwcfg, vcoutputtermhdr,
1073                         sizeof(*vcoutputtermhdr));
1074                     saa7164_api_configure_port_mpeg2ts(dev,
1075                         tsport, tsfmt);
1076                     break;
1077                 case VS_FORMAT_MPEG2PS:
1078                     psfmt =
1079                     (struct tmComResPSFormatDescrHeader *)t;
1080                     if (currpath == 1)
1081                         encport = &dev->ports[SAA7164_PORT_ENC1];
1082                     else
1083                         encport = &dev->ports[SAA7164_PORT_ENC2];
1084                     memcpy(&encport->hwcfg, vcoutputtermhdr,
1085                         sizeof(*vcoutputtermhdr));
1086                     saa7164_api_configure_port_mpeg2ps(dev,
1087                         encport, psfmt);
1088                     break;
1089                 case VS_FORMAT_VBI:
1090                     vbifmt =
1091                     (struct tmComResVBIFormatDescrHeader *)t;
1092                     if (currpath == 1)
1093                         vbiport = &dev->ports[SAA7164_PORT_VBI1];
1094                     else
1095                         vbiport = &dev->ports[SAA7164_PORT_VBI2];
1096                     memcpy(&vbiport->hwcfg, vcoutputtermhdr,
1097                         sizeof(*vcoutputtermhdr));
1098                     memcpy(&vbiport->vbi_fmt_ntsc, vbifmt,
1099                         sizeof(*vbifmt));
1100                     saa7164_api_configure_port_vbi(dev,
1101                         vbiport);
1102                     break;
1103                 case VS_FORMAT_RDS:
1104                     dprintk(DBGLVL_API,
1105                         "   = VS_FORMAT_RDS\n");
1106                     break;
1107                 case VS_FORMAT_UNCOMPRESSED:
1108                     dprintk(DBGLVL_API,
1109                     "   = VS_FORMAT_UNCOMPRESSED\n");
1110                     break;
1111                 case VS_FORMAT_TYPE:
1112                     dprintk(DBGLVL_API,
1113                         "   = VS_FORMAT_TYPE\n");
1114                     break;
1115                 default:
1116                     dprintk(DBGLVL_API,
1117                         "   = undefined (0x%x)\n",
1118                         t->subtype);
1119                 }
1120                 next_offset += t->len;
1121             }
1122 
1123             break;
1124         case TUNER_UNIT:
1125             dprintk(DBGLVL_API, " TUNER_UNIT\n");
1126             tunerunithdr =
1127                 (struct tmComResTunerDescrHeader *)(buf + idx);
1128             dprintk(DBGLVL_API, "  unitid = 0x%x\n",
1129                 tunerunithdr->unitid);
1130             dprintk(DBGLVL_API, "  sourceid = 0x%x\n",
1131                 tunerunithdr->sourceid);
1132             dprintk(DBGLVL_API, "  iunit = 0x%x\n",
1133                 tunerunithdr->iunit);
1134             dprintk(DBGLVL_API, "  tuningstandards = 0x%x\n",
1135                 tunerunithdr->tuningstandards);
1136             dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
1137                 tunerunithdr->controlsize);
1138             dprintk(DBGLVL_API, "  controls = 0x%x\n",
1139                 tunerunithdr->controls);
1140 
1141             if (tunerunithdr->unitid == tunerunithdr->iunit) {
1142                 if (currpath == 1)
1143                     encport = &dev->ports[SAA7164_PORT_ENC1];
1144                 else
1145                     encport = &dev->ports[SAA7164_PORT_ENC2];
1146                 memcpy(&encport->tunerunit, tunerunithdr,
1147                     sizeof(struct tmComResTunerDescrHeader));
1148                 dprintk(DBGLVL_API,
1149                     "  (becomes dev->enc[%d] tuner)\n",
1150                     encport->nr);
1151             }
1152             break;
1153         case VC_SELECTOR_UNIT:
1154             psel = (struct tmComResSelDescrHeader *)(buf + idx);
1155             dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
1156             dprintk(DBGLVL_API, "  unitid = 0x%x\n",
1157                 psel->unitid);
1158             dprintk(DBGLVL_API, "  nrinpins = 0x%x\n",
1159                 psel->nrinpins);
1160             dprintk(DBGLVL_API, "  sourceid = 0x%x\n",
1161                 psel->sourceid);
1162             break;
1163         case VC_PROCESSING_UNIT:
1164             pdh = (struct tmComResProcDescrHeader *)(buf + idx);
1165             dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
1166             dprintk(DBGLVL_API, "  unitid = 0x%x\n",
1167                 pdh->unitid);
1168             dprintk(DBGLVL_API, "  sourceid = 0x%x\n",
1169                 pdh->sourceid);
1170             dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
1171                 pdh->controlsize);
1172             if (pdh->controlsize == 0x04) {
1173                 if (currpath == 1)
1174                     encport = &dev->ports[SAA7164_PORT_ENC1];
1175                 else
1176                     encport = &dev->ports[SAA7164_PORT_ENC2];
1177                 memcpy(&encport->vidproc, pdh,
1178                     sizeof(struct tmComResProcDescrHeader));
1179                 dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n",
1180                     encport->nr);
1181             }
1182             break;
1183         case FEATURE_UNIT:
1184             afd = (struct tmComResAFeatureDescrHeader *)(buf + idx);
1185             dprintk(DBGLVL_API, " FEATURE_UNIT\n");
1186             dprintk(DBGLVL_API, "  unitid = 0x%x\n",
1187                 afd->unitid);
1188             dprintk(DBGLVL_API, "  sourceid = 0x%x\n",
1189                 afd->sourceid);
1190             dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
1191                 afd->controlsize);
1192             if (currpath == 1)
1193                 encport = &dev->ports[SAA7164_PORT_ENC1];
1194             else
1195                 encport = &dev->ports[SAA7164_PORT_ENC2];
1196             memcpy(&encport->audfeat, afd,
1197                 sizeof(struct tmComResAFeatureDescrHeader));
1198             dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n",
1199                 encport->nr);
1200             break;
1201         case ENCODER_UNIT:
1202             edh = (struct tmComResEncoderDescrHeader *)(buf + idx);
1203             dprintk(DBGLVL_API, " ENCODER_UNIT\n");
1204             dprintk(DBGLVL_API, "  subtype = 0x%x\n", edh->subtype);
1205             dprintk(DBGLVL_API, "  unitid = 0x%x\n", edh->unitid);
1206             dprintk(DBGLVL_API, "  vsourceid = 0x%x\n",
1207             edh->vsourceid);
1208             dprintk(DBGLVL_API, "  asourceid = 0x%x\n",
1209                 edh->asourceid);
1210             dprintk(DBGLVL_API, "  iunit = 0x%x\n", edh->iunit);
1211             if (edh->iunit == edh->unitid) {
1212                 if (currpath == 1)
1213                     encport = &dev->ports[SAA7164_PORT_ENC1];
1214                 else
1215                     encport = &dev->ports[SAA7164_PORT_ENC2];
1216                 memcpy(&encport->encunit, edh,
1217                     sizeof(struct tmComResEncoderDescrHeader));
1218                 dprintk(DBGLVL_API,
1219                     "  (becomes dev->enc[%d])\n",
1220                     encport->nr);
1221             }
1222             break;
1223         case EXTENSION_UNIT:
1224             dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
1225             exthdr = (struct tmComResExtDevDescrHeader *)(buf + idx);
1226             dprintk(DBGLVL_API, "  unitid = 0x%x\n",
1227                 exthdr->unitid);
1228             dprintk(DBGLVL_API, "  deviceid = 0x%x\n",
1229                 exthdr->deviceid);
1230             dprintk(DBGLVL_API, "  devicetype = 0x%x\n",
1231                 exthdr->devicetype);
1232             if (exthdr->devicetype & 0x1)
1233                 dprintk(DBGLVL_API, "   = Decoder Device\n");
1234             if (exthdr->devicetype & 0x2)
1235                 dprintk(DBGLVL_API, "   = GPIO Source\n");
1236             if (exthdr->devicetype & 0x4)
1237                 dprintk(DBGLVL_API, "   = Video Decoder\n");
1238             if (exthdr->devicetype & 0x8)
1239                 dprintk(DBGLVL_API, "   = Audio Decoder\n");
1240             if (exthdr->devicetype & 0x20)
1241                 dprintk(DBGLVL_API, "   = Crossbar\n");
1242             if (exthdr->devicetype & 0x40)
1243                 dprintk(DBGLVL_API, "   = Tuner\n");
1244             if (exthdr->devicetype & 0x80)
1245                 dprintk(DBGLVL_API, "   = IF PLL\n");
1246             if (exthdr->devicetype & 0x100)
1247                 dprintk(DBGLVL_API, "   = Demodulator\n");
1248             if (exthdr->devicetype & 0x200)
1249                 dprintk(DBGLVL_API, "   = RDS Decoder\n");
1250             if (exthdr->devicetype & 0x400)
1251                 dprintk(DBGLVL_API, "   = Encoder\n");
1252             if (exthdr->devicetype & 0x800)
1253                 dprintk(DBGLVL_API, "   = IR Decoder\n");
1254             if (exthdr->devicetype & 0x1000)
1255                 dprintk(DBGLVL_API, "   = EEPROM\n");
1256             if (exthdr->devicetype & 0x2000)
1257                 dprintk(DBGLVL_API,
1258                     "   = VBI Decoder\n");
1259             if (exthdr->devicetype & 0x10000)
1260                 dprintk(DBGLVL_API,
1261                     "   = Streaming Device\n");
1262             if (exthdr->devicetype & 0x20000)
1263                 dprintk(DBGLVL_API,
1264                     "   = DRM Device\n");
1265             if (exthdr->devicetype & 0x40000000)
1266                 dprintk(DBGLVL_API,
1267                     "   = Generic Device\n");
1268             if (exthdr->devicetype & 0x80000000)
1269                 dprintk(DBGLVL_API,
1270                     "   = Config Space Device\n");
1271             dprintk(DBGLVL_API, "  numgpiopins = 0x%x\n",
1272                 exthdr->numgpiopins);
1273             dprintk(DBGLVL_API, "  numgpiogroups = 0x%x\n",
1274                 exthdr->numgpiogroups);
1275             dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
1276                 exthdr->controlsize);
1277             if (exthdr->devicetype & 0x80) {
1278                 if (currpath == 1)
1279                     encport = &dev->ports[SAA7164_PORT_ENC1];
1280                 else
1281                     encport = &dev->ports[SAA7164_PORT_ENC2];
1282                 memcpy(&encport->ifunit, exthdr,
1283                     sizeof(struct tmComResExtDevDescrHeader));
1284                 dprintk(DBGLVL_API,
1285                     "  (becomes dev->enc[%d])\n",
1286                     encport->nr);
1287             }
1288             break;
1289         case PVC_INFRARED_UNIT:
1290             dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
1291             break;
1292         case DRM_UNIT:
1293             dprintk(DBGLVL_API, " DRM_UNIT\n");
1294             break;
1295         default:
1296             dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
1297         }
1298 
1299         dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
1300         dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
1301         dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
1302         dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
1303 
1304         idx += hdr->len;
1305     }
1306 
1307     return 0;
1308 }
1309 
1310 int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
1311 {
1312     int ret;
1313     u32 buflen = 0;
1314     u8 *buf;
1315 
1316     dprintk(DBGLVL_API, "%s()\n", __func__);
1317 
1318     /* Get the total descriptor length */
1319     ret = saa7164_cmd_send(dev, 0, GET_LEN,
1320         GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
1321     if (ret != SAA_OK)
1322         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1323 
1324     dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
1325         __func__, buflen);
1326 
1327     /* Allocate enough storage for all of the descs */
1328     buf = kzalloc(buflen, GFP_KERNEL);
1329     if (!buf)
1330         return SAA_ERR_NO_RESOURCES;
1331 
1332     /* Retrieve them */
1333     ret = saa7164_cmd_send(dev, 0, GET_CUR,
1334         GET_DESCRIPTORS_CONTROL, buflen, buf);
1335     if (ret != SAA_OK) {
1336         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
1337         goto out;
1338     }
1339 
1340     if (saa_debug & DBGLVL_API)
1341         print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf,
1342                    buflen & ~15, false);
1343 
1344     saa7164_api_dump_subdevs(dev, buf, buflen);
1345 
1346 out:
1347     kfree(buf);
1348     return ret;
1349 }
1350 
1351 int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
1352     u32 datalen, u8 *data)
1353 {
1354     struct saa7164_dev *dev = bus->dev;
1355     u16 len = 0;
1356     int unitid;
1357     u8 buf[256];
1358     int ret;
1359 
1360     dprintk(DBGLVL_API, "%s() addr=%x reglen=%d datalen=%d\n",
1361         __func__, addr, reglen, datalen);
1362 
1363     if (reglen > 4)
1364         return -EIO;
1365 
1366     /* Prepare the send buffer */
1367     /* Bytes 00-03 source register length
1368      *       04-07 source bytes to read
1369      *       08... register address
1370      */
1371     memset(buf, 0, sizeof(buf));
1372     memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
1373     *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1374     *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
1375 
1376     unitid = saa7164_i2caddr_to_unitid(bus, addr);
1377     if (unitid < 0) {
1378         printk(KERN_ERR
1379             "%s() error, cannot translate regaddr 0x%x to unitid\n",
1380             __func__, addr);
1381         return -EIO;
1382     }
1383 
1384     ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
1385         EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
1386     if (ret != SAA_OK) {
1387         printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1388         return -EIO;
1389     }
1390 
1391     dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
1392 
1393     if (saa_debug & DBGLVL_I2C)
1394         print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf,
1395                    32, false);
1396 
1397     ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
1398         EXU_REGISTER_ACCESS_CONTROL, len, &buf);
1399     if (ret != SAA_OK)
1400         printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1401     else {
1402         if (saa_debug & DBGLVL_I2C)
1403             print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
1404                        buf, sizeof(buf), false);
1405         memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
1406     }
1407 
1408     return ret == SAA_OK ? 0 : -EIO;
1409 }
1410 
1411 /* For a given 8 bit i2c address device, write the buffer */
1412 int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
1413     u8 *data)
1414 {
1415     struct saa7164_dev *dev = bus->dev;
1416     u16 len = 0;
1417     int unitid;
1418     int reglen;
1419     u8 buf[256];
1420     int ret;
1421 
1422     dprintk(DBGLVL_API, "%s() addr=0x%2x len=0x%x\n",
1423         __func__, addr, datalen);
1424 
1425     if ((datalen == 0) || (datalen > 232))
1426         return -EIO;
1427 
1428     memset(buf, 0, sizeof(buf));
1429 
1430     unitid = saa7164_i2caddr_to_unitid(bus, addr);
1431     if (unitid < 0) {
1432         printk(KERN_ERR
1433             "%s() error, cannot translate regaddr 0x%x to unitid\n",
1434             __func__, addr);
1435         return -EIO;
1436     }
1437 
1438     reglen = saa7164_i2caddr_to_reglen(bus, addr);
1439     if (reglen < 0) {
1440         printk(KERN_ERR
1441             "%s() error, cannot translate regaddr to reglen\n",
1442             __func__);
1443         return -EIO;
1444     }
1445 
1446     ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
1447         EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
1448     if (ret != SAA_OK) {
1449         printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
1450         return -EIO;
1451     }
1452 
1453     dprintk(DBGLVL_API, "%s() len = %d bytes unitid=0x%x\n", __func__,
1454         len, unitid);
1455 
1456     /* Prepare the send buffer */
1457     /* Bytes 00-03 dest register length
1458      *       04-07 dest bytes to write
1459      *       08... register address
1460      */
1461     *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
1462     *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
1463     memcpy((buf + 2 * sizeof(u32)), data, datalen);
1464 
1465     if (saa_debug & DBGLVL_I2C)
1466         print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
1467                    buf, sizeof(buf), false);
1468 
1469     ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
1470         EXU_REGISTER_ACCESS_CONTROL, len, &buf);
1471     if (ret != SAA_OK)
1472         printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
1473 
1474     return ret == SAA_OK ? 0 : -EIO;
1475 }
1476 
1477 static int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
1478     u8 pin, u8 state)
1479 {
1480     int ret;
1481     struct tmComResGPIO t;
1482 
1483     dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
1484         __func__, unitid, pin, state);
1485 
1486     if ((pin > 7) || (state > 2))
1487         return SAA_ERR_BAD_PARAMETER;
1488 
1489     t.pin = pin;
1490     t.state = state;
1491 
1492     ret = saa7164_cmd_send(dev, unitid, SET_CUR,
1493         EXU_GPIO_CONTROL, sizeof(t), &t);
1494     if (ret != SAA_OK)
1495         printk(KERN_ERR "%s() error, ret = 0x%x\n",
1496             __func__, ret);
1497 
1498     return ret;
1499 }
1500 
1501 int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
1502     u8 pin)
1503 {
1504     return saa7164_api_modify_gpio(dev, unitid, pin, 1);
1505 }
1506 
1507 int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
1508     u8 pin)
1509 {
1510     return saa7164_api_modify_gpio(dev, unitid, pin, 0);
1511 }
1512