18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Driver for the NXP SAA7164 PCIe bridge 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/wait.h> 98c2ecf20Sopenharmony_ci#include <linux/slab.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "saa7164.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ciint saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci int ret; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci if (!(saa_debug & DBGLVL_CPU)) 188c2ecf20Sopenharmony_ci return 0; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s()\n", __func__); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci i->deviceinst = 0; 238c2ecf20Sopenharmony_ci i->devicespec = 0; 248c2ecf20Sopenharmony_ci i->mode = 0; 258c2ecf20Sopenharmony_ci i->status = 0; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, 0, GET_CUR, 288c2ecf20Sopenharmony_ci GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i); 298c2ecf20Sopenharmony_ci if (ret != SAA_OK) 308c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad); 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci return ret; 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ciint saa7164_api_collect_debug(struct saa7164_dev *dev) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci struct tmComResDebugGetData d; 408c2ecf20Sopenharmony_ci u8 more = 255; 418c2ecf20Sopenharmony_ci int ret; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s()\n", __func__); 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci while (more--) { 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci memset(&d, 0, sizeof(d)); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, 0, GET_CUR, 508c2ecf20Sopenharmony_ci GET_DEBUG_DATA_CONTROL, sizeof(d), &d); 518c2ecf20Sopenharmony_ci if (ret != SAA_OK) 528c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", 538c2ecf20Sopenharmony_ci __func__, ret); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci if (d.dwResult != SAA_OK) 568c2ecf20Sopenharmony_ci break; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, 598c2ecf20Sopenharmony_ci d.ucDebugData); 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci return 0; 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ciint saa7164_api_set_debug(struct saa7164_dev *dev, u8 level) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci struct tmComResDebugSetLevel lvl; 688c2ecf20Sopenharmony_ci int ret; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci /* Retrieve current state */ 738c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, 0, GET_CUR, 748c2ecf20Sopenharmony_ci SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); 758c2ecf20Sopenharmony_ci if (ret != SAA_OK) 768c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci lvl.dwDebugLevel = level; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci /* set new state */ 838c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, 0, SET_CUR, 848c2ecf20Sopenharmony_ci SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); 858c2ecf20Sopenharmony_ci if (ret != SAA_OK) 868c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci return ret; 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ciint saa7164_api_set_vbi_format(struct saa7164_port *port) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 948c2ecf20Sopenharmony_ci struct tmComResProbeCommit fmt, rsp; 958c2ecf20Sopenharmony_ci int ret; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__, 988c2ecf20Sopenharmony_ci port->nr, port->hwcfg.unitid); 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci fmt.bmHint = 0; 1018c2ecf20Sopenharmony_ci fmt.bFormatIndex = 1; 1028c2ecf20Sopenharmony_ci fmt.bFrameIndex = 1; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci /* Probe, see if it can support this format */ 1058c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, 1068c2ecf20Sopenharmony_ci SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt); 1078c2ecf20Sopenharmony_ci if (ret != SAA_OK) 1088c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci /* See of the format change was successful */ 1118c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, 1128c2ecf20Sopenharmony_ci GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp); 1138c2ecf20Sopenharmony_ci if (ret != SAA_OK) { 1148c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret); 1158c2ecf20Sopenharmony_ci } else { 1168c2ecf20Sopenharmony_ci /* Compare requested vs received, should be same */ 1178c2ecf20Sopenharmony_ci if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) { 1188c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "SET/PROBE Verified\n"); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* Ask the device to select the negotiated format */ 1218c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, 1228c2ecf20Sopenharmony_ci SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt); 1238c2ecf20Sopenharmony_ci if (ret != SAA_OK) 1248c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() commit error, ret = 0x%x\n", 1258c2ecf20Sopenharmony_ci __func__, ret); 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, 1288c2ecf20Sopenharmony_ci GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp); 1298c2ecf20Sopenharmony_ci if (ret != SAA_OK) 1308c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n", 1318c2ecf20Sopenharmony_ci __func__, ret); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) { 1348c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n", 1358c2ecf20Sopenharmony_ci __func__, ret); 1368c2ecf20Sopenharmony_ci } else 1378c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "SET/COMMIT Verified\n"); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint); 1408c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", 1418c2ecf20Sopenharmony_ci rsp.bFormatIndex); 1428c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", 1438c2ecf20Sopenharmony_ci rsp.bFrameIndex); 1448c2ecf20Sopenharmony_ci } else 1458c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() compare failed\n", __func__); 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci if (ret == SAA_OK) 1498c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci return ret; 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic int saa7164_api_set_gop_size(struct saa7164_port *port) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 1578c2ecf20Sopenharmony_ci struct tmComResEncVideoGopStructure gs; 1588c2ecf20Sopenharmony_ci int ret; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s()\n", __func__); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci gs.ucRefFrameDist = port->encoder_params.refdist; 1638c2ecf20Sopenharmony_ci gs.ucGOPSize = port->encoder_params.gop_size; 1648c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, 1658c2ecf20Sopenharmony_ci EU_VIDEO_GOP_STRUCTURE_CONTROL, 1668c2ecf20Sopenharmony_ci sizeof(gs), &gs); 1678c2ecf20Sopenharmony_ci if (ret != SAA_OK) 1688c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci return ret; 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ciint saa7164_api_set_encoder(struct saa7164_port *port) 1748c2ecf20Sopenharmony_ci{ 1758c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 1768c2ecf20Sopenharmony_ci struct tmComResEncVideoBitRate vb; 1778c2ecf20Sopenharmony_ci struct tmComResEncAudioBitRate ab; 1788c2ecf20Sopenharmony_ci int ret; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, 1818c2ecf20Sopenharmony_ci port->hwcfg.sourceid); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) 1848c2ecf20Sopenharmony_ci port->encoder_profile = EU_PROFILE_PS_DVD; 1858c2ecf20Sopenharmony_ci else 1868c2ecf20Sopenharmony_ci port->encoder_profile = EU_PROFILE_TS_HQ; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, 1898c2ecf20Sopenharmony_ci EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); 1908c2ecf20Sopenharmony_ci if (ret != SAA_OK) 1918c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci /* Resolution */ 1948c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, 1958c2ecf20Sopenharmony_ci EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); 1968c2ecf20Sopenharmony_ci if (ret != SAA_OK) 1978c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci /* Establish video bitrates */ 2008c2ecf20Sopenharmony_ci if (port->encoder_params.bitrate_mode == 2018c2ecf20Sopenharmony_ci V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) 2028c2ecf20Sopenharmony_ci vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT; 2038c2ecf20Sopenharmony_ci else 2048c2ecf20Sopenharmony_ci vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK; 2058c2ecf20Sopenharmony_ci vb.dwVideoBitRate = port->encoder_params.bitrate; 2068c2ecf20Sopenharmony_ci vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak; 2078c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, 2088c2ecf20Sopenharmony_ci EU_VIDEO_BIT_RATE_CONTROL, 2098c2ecf20Sopenharmony_ci sizeof(struct tmComResEncVideoBitRate), 2108c2ecf20Sopenharmony_ci &vb); 2118c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2128c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci /* Establish audio bitrates */ 2158c2ecf20Sopenharmony_ci ab.ucAudioBitRateMode = 0; 2168c2ecf20Sopenharmony_ci ab.dwAudioBitRate = 384000; 2178c2ecf20Sopenharmony_ci ab.dwAudioBitRatePeak = ab.dwAudioBitRate; 2188c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, 2198c2ecf20Sopenharmony_ci EU_AUDIO_BIT_RATE_CONTROL, 2208c2ecf20Sopenharmony_ci sizeof(struct tmComResEncAudioBitRate), 2218c2ecf20Sopenharmony_ci &ab); 2228c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2238c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, 2248c2ecf20Sopenharmony_ci ret); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci saa7164_api_set_aspect_ratio(port); 2278c2ecf20Sopenharmony_ci saa7164_api_set_gop_size(port); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci return ret; 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ciint saa7164_api_get_encoder(struct saa7164_port *port) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 2358c2ecf20Sopenharmony_ci struct tmComResEncVideoBitRate v; 2368c2ecf20Sopenharmony_ci struct tmComResEncAudioBitRate a; 2378c2ecf20Sopenharmony_ci struct tmComResEncVideoInputAspectRatio ar; 2388c2ecf20Sopenharmony_ci int ret; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, 2418c2ecf20Sopenharmony_ci port->hwcfg.sourceid); 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci port->encoder_profile = 0; 2448c2ecf20Sopenharmony_ci port->video_format = 0; 2458c2ecf20Sopenharmony_ci port->video_resolution = 0; 2468c2ecf20Sopenharmony_ci port->audio_format = 0; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, 2498c2ecf20Sopenharmony_ci EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); 2508c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2518c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, 2548c2ecf20Sopenharmony_ci EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), 2558c2ecf20Sopenharmony_ci &port->video_resolution); 2568c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2578c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, 2608c2ecf20Sopenharmony_ci EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format); 2618c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2628c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, 2658c2ecf20Sopenharmony_ci EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v); 2668c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2678c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, 2708c2ecf20Sopenharmony_ci EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format); 2718c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2728c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, 2758c2ecf20Sopenharmony_ci EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a); 2768c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2778c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci /* Aspect Ratio */ 2808c2ecf20Sopenharmony_ci ar.width = 0; 2818c2ecf20Sopenharmony_ci ar.height = 0; 2828c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, 2838c2ecf20Sopenharmony_ci EU_VIDEO_INPUT_ASPECT_CONTROL, 2848c2ecf20Sopenharmony_ci sizeof(struct tmComResEncVideoInputAspectRatio), &ar); 2858c2ecf20Sopenharmony_ci if (ret != SAA_OK) 2868c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile); 2898c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format); 2908c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format); 2918c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution); 2928c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", 2938c2ecf20Sopenharmony_ci v.ucVideoBitRateMode); 2948c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", 2958c2ecf20Sopenharmony_ci v.dwVideoBitRate); 2968c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", 2978c2ecf20Sopenharmony_ci v.dwVideoBitRatePeak); 2988c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", 2998c2ecf20Sopenharmony_ci a.ucAudioBitRateMode); 3008c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", 3018c2ecf20Sopenharmony_ci a.dwAudioBitRate); 3028c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", 3038c2ecf20Sopenharmony_ci a.dwAudioBitRatePeak); 3048c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", 3058c2ecf20Sopenharmony_ci ar.width, ar.height); 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci return ret; 3088c2ecf20Sopenharmony_ci} 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ciint saa7164_api_set_aspect_ratio(struct saa7164_port *port) 3118c2ecf20Sopenharmony_ci{ 3128c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 3138c2ecf20Sopenharmony_ci struct tmComResEncVideoInputAspectRatio ar; 3148c2ecf20Sopenharmony_ci int ret; 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s(%d)\n", __func__, 3178c2ecf20Sopenharmony_ci port->encoder_params.ctl_aspect); 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci switch (port->encoder_params.ctl_aspect) { 3208c2ecf20Sopenharmony_ci case V4L2_MPEG_VIDEO_ASPECT_1x1: 3218c2ecf20Sopenharmony_ci ar.width = 1; 3228c2ecf20Sopenharmony_ci ar.height = 1; 3238c2ecf20Sopenharmony_ci break; 3248c2ecf20Sopenharmony_ci case V4L2_MPEG_VIDEO_ASPECT_4x3: 3258c2ecf20Sopenharmony_ci ar.width = 4; 3268c2ecf20Sopenharmony_ci ar.height = 3; 3278c2ecf20Sopenharmony_ci break; 3288c2ecf20Sopenharmony_ci case V4L2_MPEG_VIDEO_ASPECT_16x9: 3298c2ecf20Sopenharmony_ci ar.width = 16; 3308c2ecf20Sopenharmony_ci ar.height = 9; 3318c2ecf20Sopenharmony_ci break; 3328c2ecf20Sopenharmony_ci case V4L2_MPEG_VIDEO_ASPECT_221x100: 3338c2ecf20Sopenharmony_ci ar.width = 221; 3348c2ecf20Sopenharmony_ci ar.height = 100; 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci default: 3378c2ecf20Sopenharmony_ci BUG(); 3388c2ecf20Sopenharmony_ci } 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__, 3418c2ecf20Sopenharmony_ci port->encoder_params.ctl_aspect, 3428c2ecf20Sopenharmony_ci ar.width, ar.height); 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci /* Aspect Ratio */ 3458c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, 3468c2ecf20Sopenharmony_ci EU_VIDEO_INPUT_ASPECT_CONTROL, 3478c2ecf20Sopenharmony_ci sizeof(struct tmComResEncVideoInputAspectRatio), &ar); 3488c2ecf20Sopenharmony_ci if (ret != SAA_OK) 3498c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci return ret; 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ciint saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl) 3558c2ecf20Sopenharmony_ci{ 3568c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 3578c2ecf20Sopenharmony_ci int ret; 3588c2ecf20Sopenharmony_ci u16 val; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci if (ctl == PU_BRIGHTNESS_CONTROL) 3618c2ecf20Sopenharmony_ci val = port->ctl_brightness; 3628c2ecf20Sopenharmony_ci else 3638c2ecf20Sopenharmony_ci if (ctl == PU_CONTRAST_CONTROL) 3648c2ecf20Sopenharmony_ci val = port->ctl_contrast; 3658c2ecf20Sopenharmony_ci else 3668c2ecf20Sopenharmony_ci if (ctl == PU_HUE_CONTROL) 3678c2ecf20Sopenharmony_ci val = port->ctl_hue; 3688c2ecf20Sopenharmony_ci else 3698c2ecf20Sopenharmony_ci if (ctl == PU_SATURATION_CONTROL) 3708c2ecf20Sopenharmony_ci val = port->ctl_saturation; 3718c2ecf20Sopenharmony_ci else 3728c2ecf20Sopenharmony_ci if (ctl == PU_SHARPNESS_CONTROL) 3738c2ecf20Sopenharmony_ci val = port->ctl_sharpness; 3748c2ecf20Sopenharmony_ci else 3758c2ecf20Sopenharmony_ci return -EINVAL; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n", 3788c2ecf20Sopenharmony_ci __func__, port->encunit.vsourceid, ctl, val); 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR, 3818c2ecf20Sopenharmony_ci ctl, sizeof(u16), &val); 3828c2ecf20Sopenharmony_ci if (ret != SAA_OK) 3838c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci return ret; 3868c2ecf20Sopenharmony_ci} 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ciint saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 3918c2ecf20Sopenharmony_ci int ret; 3928c2ecf20Sopenharmony_ci u16 val; 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR, 3958c2ecf20Sopenharmony_ci ctl, sizeof(u16), &val); 3968c2ecf20Sopenharmony_ci if (ret != SAA_OK) { 3978c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 3988c2ecf20Sopenharmony_ci return ret; 3998c2ecf20Sopenharmony_ci } 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n", 4028c2ecf20Sopenharmony_ci __func__, ctl, val); 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci if (ctl == PU_BRIGHTNESS_CONTROL) 4058c2ecf20Sopenharmony_ci port->ctl_brightness = val; 4068c2ecf20Sopenharmony_ci else 4078c2ecf20Sopenharmony_ci if (ctl == PU_CONTRAST_CONTROL) 4088c2ecf20Sopenharmony_ci port->ctl_contrast = val; 4098c2ecf20Sopenharmony_ci else 4108c2ecf20Sopenharmony_ci if (ctl == PU_HUE_CONTROL) 4118c2ecf20Sopenharmony_ci port->ctl_hue = val; 4128c2ecf20Sopenharmony_ci else 4138c2ecf20Sopenharmony_ci if (ctl == PU_SATURATION_CONTROL) 4148c2ecf20Sopenharmony_ci port->ctl_saturation = val; 4158c2ecf20Sopenharmony_ci else 4168c2ecf20Sopenharmony_ci if (ctl == PU_SHARPNESS_CONTROL) 4178c2ecf20Sopenharmony_ci port->ctl_sharpness = val; 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci return ret; 4208c2ecf20Sopenharmony_ci} 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ciint saa7164_api_set_videomux(struct saa7164_port *port) 4238c2ecf20Sopenharmony_ci{ 4248c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 4258c2ecf20Sopenharmony_ci u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 }; 4268c2ecf20Sopenharmony_ci int ret; 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n", 4298c2ecf20Sopenharmony_ci __func__, port->mux_input, inputs[port->mux_input - 1]); 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci /* Audio Mute */ 4328c2ecf20Sopenharmony_ci ret = saa7164_api_audio_mute(port, 1); 4338c2ecf20Sopenharmony_ci if (ret != SAA_OK) 4348c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci /* Video Mux */ 4378c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR, 4388c2ecf20Sopenharmony_ci SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input); 4398c2ecf20Sopenharmony_ci if (ret != SAA_OK) 4408c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci /* Audio Mux */ 4438c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR, 4448c2ecf20Sopenharmony_ci SU_INPUT_SELECT_CONTROL, sizeof(u8), 4458c2ecf20Sopenharmony_ci &inputs[port->mux_input - 1]); 4468c2ecf20Sopenharmony_ci if (ret != SAA_OK) 4478c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci /* Audio UnMute */ 4508c2ecf20Sopenharmony_ci ret = saa7164_api_audio_mute(port, 0); 4518c2ecf20Sopenharmony_ci if (ret != SAA_OK) 4528c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci return ret; 4558c2ecf20Sopenharmony_ci} 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ciint saa7164_api_audio_mute(struct saa7164_port *port, int mute) 4588c2ecf20Sopenharmony_ci{ 4598c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 4608c2ecf20Sopenharmony_ci u8 v = mute; 4618c2ecf20Sopenharmony_ci int ret; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute); 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, 4668c2ecf20Sopenharmony_ci MUTE_CONTROL, sizeof(u8), &v); 4678c2ecf20Sopenharmony_ci if (ret != SAA_OK) 4688c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci return ret; 4718c2ecf20Sopenharmony_ci} 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci/* 0 = silence, 0xff = full */ 4748c2ecf20Sopenharmony_ciint saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level) 4758c2ecf20Sopenharmony_ci{ 4768c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 4778c2ecf20Sopenharmony_ci s16 v, min, max; 4788c2ecf20Sopenharmony_ci int ret; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(%d)\n", __func__, level); 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci /* Obtain the min/max ranges */ 4838c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN, 4848c2ecf20Sopenharmony_ci VOLUME_CONTROL, sizeof(u16), &min); 4858c2ecf20Sopenharmony_ci if (ret != SAA_OK) 4868c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX, 4898c2ecf20Sopenharmony_ci VOLUME_CONTROL, sizeof(u16), &max); 4908c2ecf20Sopenharmony_ci if (ret != SAA_OK) 4918c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR, 4948c2ecf20Sopenharmony_ci (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v); 4958c2ecf20Sopenharmony_ci if (ret != SAA_OK) 4968c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, 4998c2ecf20Sopenharmony_ci level, min, max, v); 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci v = level; 5028c2ecf20Sopenharmony_ci if (v < min) 5038c2ecf20Sopenharmony_ci v = min; 5048c2ecf20Sopenharmony_ci if (v > max) 5058c2ecf20Sopenharmony_ci v = max; 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci /* Left */ 5088c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, 5098c2ecf20Sopenharmony_ci (0x01 << 8) | VOLUME_CONTROL, sizeof(s16), &v); 5108c2ecf20Sopenharmony_ci if (ret != SAA_OK) 5118c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci /* Right */ 5148c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, 5158c2ecf20Sopenharmony_ci (0x02 << 8) | VOLUME_CONTROL, sizeof(s16), &v); 5168c2ecf20Sopenharmony_ci if (ret != SAA_OK) 5178c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR, 5208c2ecf20Sopenharmony_ci (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v); 5218c2ecf20Sopenharmony_ci if (ret != SAA_OK) 5228c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, 5258c2ecf20Sopenharmony_ci level, min, max, v); 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci return ret; 5288c2ecf20Sopenharmony_ci} 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ciint saa7164_api_set_audio_std(struct saa7164_port *port) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 5338c2ecf20Sopenharmony_ci struct tmComResAudioDefaults lvl; 5348c2ecf20Sopenharmony_ci struct tmComResTunerStandard tvaudio; 5358c2ecf20Sopenharmony_ci int ret; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s()\n", __func__); 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci /* Establish default levels */ 5408c2ecf20Sopenharmony_ci lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT; 5418c2ecf20Sopenharmony_ci lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT; 5428c2ecf20Sopenharmony_ci lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT; 5438c2ecf20Sopenharmony_ci lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT; 5448c2ecf20Sopenharmony_ci lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT; 5458c2ecf20Sopenharmony_ci lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT; 5468c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, 5478c2ecf20Sopenharmony_ci AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults), 5488c2ecf20Sopenharmony_ci &lvl); 5498c2ecf20Sopenharmony_ci if (ret != SAA_OK) 5508c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci /* Manually select the appropriate TV audio standard */ 5538c2ecf20Sopenharmony_ci if (port->encodernorm.id & V4L2_STD_NTSC) { 5548c2ecf20Sopenharmony_ci tvaudio.std = TU_STANDARD_NTSC_M; 5558c2ecf20Sopenharmony_ci tvaudio.country = 1; 5568c2ecf20Sopenharmony_ci } else { 5578c2ecf20Sopenharmony_ci tvaudio.std = TU_STANDARD_PAL_I; 5588c2ecf20Sopenharmony_ci tvaudio.country = 44; 5598c2ecf20Sopenharmony_ci } 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, 5628c2ecf20Sopenharmony_ci TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio); 5638c2ecf20Sopenharmony_ci if (ret != SAA_OK) 5648c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", 5658c2ecf20Sopenharmony_ci __func__, ret); 5668c2ecf20Sopenharmony_ci return ret; 5678c2ecf20Sopenharmony_ci} 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ciint saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect) 5708c2ecf20Sopenharmony_ci{ 5718c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 5728c2ecf20Sopenharmony_ci struct tmComResTunerStandardAuto p; 5738c2ecf20Sopenharmony_ci int ret; 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect); 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_ci /* Disable TV Audio autodetect if not already set (buggy) */ 5788c2ecf20Sopenharmony_ci if (autodetect) 5798c2ecf20Sopenharmony_ci p.mode = TU_STANDARD_AUTO; 5808c2ecf20Sopenharmony_ci else 5818c2ecf20Sopenharmony_ci p.mode = TU_STANDARD_MANUAL; 5828c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, 5838c2ecf20Sopenharmony_ci TU_STANDARD_AUTO_CONTROL, sizeof(p), &p); 5848c2ecf20Sopenharmony_ci if (ret != SAA_OK) 5858c2ecf20Sopenharmony_ci printk(KERN_ERR 5868c2ecf20Sopenharmony_ci "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", 5878c2ecf20Sopenharmony_ci __func__, ret); 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci return ret; 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ciint saa7164_api_get_videomux(struct saa7164_port *port) 5938c2ecf20Sopenharmony_ci{ 5948c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 5958c2ecf20Sopenharmony_ci int ret; 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR, 5988c2ecf20Sopenharmony_ci SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input); 5998c2ecf20Sopenharmony_ci if (ret != SAA_OK) 6008c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci dprintk(DBGLVL_ENC, "%s() v_mux=%d\n", 6038c2ecf20Sopenharmony_ci __func__, port->mux_input); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci return ret; 6068c2ecf20Sopenharmony_ci} 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_cistatic int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val) 6098c2ecf20Sopenharmony_ci{ 6108c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci u16 len = 0; 6138c2ecf20Sopenharmony_ci u8 buf[256]; 6148c2ecf20Sopenharmony_ci int ret; 6158c2ecf20Sopenharmony_ci u8 mas; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__, 6188c2ecf20Sopenharmony_ci port->nr, port->type, val); 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci if (port->nr == 0) 6218c2ecf20Sopenharmony_ci mas = 0xd0; 6228c2ecf20Sopenharmony_ci else 6238c2ecf20Sopenharmony_ci mas = 0xe0; 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci memset(buf, 0, sizeof(buf)); 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci buf[0x00] = 0x04; 6288c2ecf20Sopenharmony_ci buf[0x01] = 0x00; 6298c2ecf20Sopenharmony_ci buf[0x02] = 0x00; 6308c2ecf20Sopenharmony_ci buf[0x03] = 0x00; 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci buf[0x04] = 0x04; 6338c2ecf20Sopenharmony_ci buf[0x05] = 0x00; 6348c2ecf20Sopenharmony_ci buf[0x06] = 0x00; 6358c2ecf20Sopenharmony_ci buf[0x07] = 0x00; 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci buf[0x08] = reg; 6388c2ecf20Sopenharmony_ci buf[0x09] = 0x26; 6398c2ecf20Sopenharmony_ci buf[0x0a] = mas; 6408c2ecf20Sopenharmony_ci buf[0x0b] = 0xb0; 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci buf[0x0c] = val; 6438c2ecf20Sopenharmony_ci buf[0x0d] = 0x00; 6448c2ecf20Sopenharmony_ci buf[0x0e] = 0x00; 6458c2ecf20Sopenharmony_ci buf[0x0f] = 0x00; 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN, 6488c2ecf20Sopenharmony_ci EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len); 6498c2ecf20Sopenharmony_ci if (ret != SAA_OK) { 6508c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret); 6518c2ecf20Sopenharmony_ci return -EIO; 6528c2ecf20Sopenharmony_ci } 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR, 6558c2ecf20Sopenharmony_ci EXU_REGISTER_ACCESS_CONTROL, len, &buf); 6568c2ecf20Sopenharmony_ci if (ret != SAA_OK) 6578c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); 6588c2ecf20Sopenharmony_ci#if 0 6598c2ecf20Sopenharmony_ci print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, 16, 6608c2ecf20Sopenharmony_ci false); 6618c2ecf20Sopenharmony_ci#endif 6628c2ecf20Sopenharmony_ci return ret == SAA_OK ? 0 : -EIO; 6638c2ecf20Sopenharmony_ci} 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_ci/* Disable the IF block AGC controls */ 6668c2ecf20Sopenharmony_ciint saa7164_api_configure_dif(struct saa7164_port *port, u32 std) 6678c2ecf20Sopenharmony_ci{ 6688c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 6698c2ecf20Sopenharmony_ci u8 agc_disable; 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std); 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ci if (std & V4L2_STD_NTSC) { 6748c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " NTSC\n"); 6758c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ 6768c2ecf20Sopenharmony_ci agc_disable = 0; 6778c2ecf20Sopenharmony_ci } else if (std & V4L2_STD_PAL_I) { 6788c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " PAL-I\n"); 6798c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */ 6808c2ecf20Sopenharmony_ci agc_disable = 0; 6818c2ecf20Sopenharmony_ci } else if (std & V4L2_STD_PAL_M) { 6828c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " PAL-M\n"); 6838c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ 6848c2ecf20Sopenharmony_ci agc_disable = 0; 6858c2ecf20Sopenharmony_ci } else if (std & V4L2_STD_PAL_N) { 6868c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " PAL-N\n"); 6878c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ 6888c2ecf20Sopenharmony_ci agc_disable = 0; 6898c2ecf20Sopenharmony_ci } else if (std & V4L2_STD_PAL_Nc) { 6908c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " PAL-Nc\n"); 6918c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ 6928c2ecf20Sopenharmony_ci agc_disable = 0; 6938c2ecf20Sopenharmony_ci } else if (std & V4L2_STD_PAL_B) { 6948c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " PAL-B\n"); 6958c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */ 6968c2ecf20Sopenharmony_ci agc_disable = 0; 6978c2ecf20Sopenharmony_ci } else if (std & V4L2_STD_PAL_DK) { 6988c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " PAL-DK\n"); 6998c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */ 7008c2ecf20Sopenharmony_ci agc_disable = 0; 7018c2ecf20Sopenharmony_ci } else if (std & V4L2_STD_SECAM_L) { 7028c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " SECAM-L\n"); 7038c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */ 7048c2ecf20Sopenharmony_ci agc_disable = 0; 7058c2ecf20Sopenharmony_ci } else { 7068c2ecf20Sopenharmony_ci /* Unknown standard, assume DTV */ 7078c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " Unknown (assuming DTV)\n"); 7088c2ecf20Sopenharmony_ci /* Undefinded Video Standard */ 7098c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x00, 0x80); 7108c2ecf20Sopenharmony_ci agc_disable = 1; 7118c2ecf20Sopenharmony_ci } 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */ 7148c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */ 7158c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */ 7168c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x04, 0x01); /* Active */ 7178c2ecf20Sopenharmony_ci msleep(100); 7188c2ecf20Sopenharmony_ci saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */ 7198c2ecf20Sopenharmony_ci msleep(100); 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci return 0; 7228c2ecf20Sopenharmony_ci} 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci/* Ensure the dif is in the correct state for the operating mode 7258c2ecf20Sopenharmony_ci * (analog / dtv). We only configure the diff through the analog encoder 7268c2ecf20Sopenharmony_ci * so when we're in digital mode we need to find the appropriate encoder 7278c2ecf20Sopenharmony_ci * and use it to configure the DIF. 7288c2ecf20Sopenharmony_ci */ 7298c2ecf20Sopenharmony_ciint saa7164_api_initialize_dif(struct saa7164_port *port) 7308c2ecf20Sopenharmony_ci{ 7318c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 7328c2ecf20Sopenharmony_ci struct saa7164_port *p = NULL; 7338c2ecf20Sopenharmony_ci int ret = -EINVAL; 7348c2ecf20Sopenharmony_ci u32 std = 0; 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__, 7378c2ecf20Sopenharmony_ci port->nr, port->type); 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci if (port->type == SAA7164_MPEG_ENCODER) { 7408c2ecf20Sopenharmony_ci /* Pick any analog standard to init the diff. 7418c2ecf20Sopenharmony_ci * we'll come back during encoder_init' 7428c2ecf20Sopenharmony_ci * and set the correct standard if required. 7438c2ecf20Sopenharmony_ci */ 7448c2ecf20Sopenharmony_ci std = V4L2_STD_NTSC; 7458c2ecf20Sopenharmony_ci } else 7468c2ecf20Sopenharmony_ci if (port->type == SAA7164_MPEG_DVB) { 7478c2ecf20Sopenharmony_ci if (port->nr == SAA7164_PORT_TS1) 7488c2ecf20Sopenharmony_ci p = &dev->ports[SAA7164_PORT_ENC1]; 7498c2ecf20Sopenharmony_ci else 7508c2ecf20Sopenharmony_ci p = &dev->ports[SAA7164_PORT_ENC2]; 7518c2ecf20Sopenharmony_ci } else 7528c2ecf20Sopenharmony_ci if (port->type == SAA7164_MPEG_VBI) { 7538c2ecf20Sopenharmony_ci std = V4L2_STD_NTSC; 7548c2ecf20Sopenharmony_ci if (port->nr == SAA7164_PORT_VBI1) 7558c2ecf20Sopenharmony_ci p = &dev->ports[SAA7164_PORT_ENC1]; 7568c2ecf20Sopenharmony_ci else 7578c2ecf20Sopenharmony_ci p = &dev->ports[SAA7164_PORT_ENC2]; 7588c2ecf20Sopenharmony_ci } else 7598c2ecf20Sopenharmony_ci BUG(); 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci if (p) 7628c2ecf20Sopenharmony_ci ret = saa7164_api_configure_dif(p, std); 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci return ret; 7658c2ecf20Sopenharmony_ci} 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ciint saa7164_api_transition_port(struct saa7164_port *port, u8 mode) 7688c2ecf20Sopenharmony_ci{ 7698c2ecf20Sopenharmony_ci struct saa7164_dev *dev = port->dev; 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci int ret; 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n", 7748c2ecf20Sopenharmony_ci __func__, port->nr, port->hwcfg.unitid, mode); 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR, 7778c2ecf20Sopenharmony_ci SAA_STATE_CONTROL, sizeof(mode), &mode); 7788c2ecf20Sopenharmony_ci if (ret != SAA_OK) 7798c2ecf20Sopenharmony_ci printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n", 7808c2ecf20Sopenharmony_ci __func__, port->nr, port->hwcfg.unitid, ret); 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci return ret; 7838c2ecf20Sopenharmony_ci} 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ciint saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version) 7868c2ecf20Sopenharmony_ci{ 7878c2ecf20Sopenharmony_ci int ret; 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, 0, GET_CUR, 7908c2ecf20Sopenharmony_ci GET_FW_VERSION_CONTROL, sizeof(u32), version); 7918c2ecf20Sopenharmony_ci if (ret != SAA_OK) 7928c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 7938c2ecf20Sopenharmony_ci 7948c2ecf20Sopenharmony_ci return ret; 7958c2ecf20Sopenharmony_ci} 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ciint saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen) 7988c2ecf20Sopenharmony_ci{ 7998c2ecf20Sopenharmony_ci u8 reg[] = { 0x0f, 0x00 }; 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci if (buflen < 128) 8028c2ecf20Sopenharmony_ci return -ENOMEM; 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_ci /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */ 8058c2ecf20Sopenharmony_ci /* TODO: Pull the details from the boards struct */ 8068c2ecf20Sopenharmony_ci return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg), 8078c2ecf20Sopenharmony_ci ®[0], 128, buf); 8088c2ecf20Sopenharmony_ci} 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_cistatic int saa7164_api_configure_port_vbi(struct saa7164_dev *dev, 8118c2ecf20Sopenharmony_ci struct saa7164_port *port) 8128c2ecf20Sopenharmony_ci{ 8138c2ecf20Sopenharmony_ci struct tmComResVBIFormatDescrHeader *fmt = &port->vbi_fmt_ntsc; 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex); 8168c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " VideoStandard = 0x%x\n", fmt->VideoStandard); 8178c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " StartLine = %d\n", fmt->StartLine); 8188c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " EndLine = %d\n", fmt->EndLine); 8198c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate); 8208c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bNumLines = %d\n", fmt->bNumLines); 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_ci /* Cache the hardware configuration in the port */ 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci port->bufcounter = port->hwcfg.BARLocation; 8258c2ecf20Sopenharmony_ci port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32)); 8268c2ecf20Sopenharmony_ci port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32)); 8278c2ecf20Sopenharmony_ci port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32)); 8288c2ecf20Sopenharmony_ci port->bufptr32l = port->hwcfg.BARLocation + 8298c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 8308c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32); 8318c2ecf20Sopenharmony_ci port->bufptr32h = port->hwcfg.BARLocation + 8328c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 8338c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount); 8348c2ecf20Sopenharmony_ci port->bufptr64 = port->hwcfg.BARLocation + 8358c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 8368c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount); 8378c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n", 8388c2ecf20Sopenharmony_ci port->hwcfg.BARLocation); 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = VS_FORMAT_VBI (becomes dev->en[%d])\n", 8418c2ecf20Sopenharmony_ci port->nr); 8428c2ecf20Sopenharmony_ci 8438c2ecf20Sopenharmony_ci return 0; 8448c2ecf20Sopenharmony_ci} 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_cistatic int 8478c2ecf20Sopenharmony_cisaa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev, 8488c2ecf20Sopenharmony_ci struct saa7164_port *port, 8498c2ecf20Sopenharmony_ci struct tmComResTSFormatDescrHeader *tsfmt) 8508c2ecf20Sopenharmony_ci{ 8518c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex); 8528c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset); 8538c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength); 8548c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength); 8558c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bguid = (....)\n"); 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci /* Cache the hardware configuration in the port */ 8588c2ecf20Sopenharmony_ci 8598c2ecf20Sopenharmony_ci port->bufcounter = port->hwcfg.BARLocation; 8608c2ecf20Sopenharmony_ci port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32)); 8618c2ecf20Sopenharmony_ci port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32)); 8628c2ecf20Sopenharmony_ci port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32)); 8638c2ecf20Sopenharmony_ci port->bufptr32l = port->hwcfg.BARLocation + 8648c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 8658c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32); 8668c2ecf20Sopenharmony_ci port->bufptr32h = port->hwcfg.BARLocation + 8678c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 8688c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount); 8698c2ecf20Sopenharmony_ci port->bufptr64 = port->hwcfg.BARLocation + 8708c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 8718c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount); 8728c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n", 8738c2ecf20Sopenharmony_ci port->hwcfg.BARLocation); 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n", 8768c2ecf20Sopenharmony_ci port->nr); 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci return 0; 8798c2ecf20Sopenharmony_ci} 8808c2ecf20Sopenharmony_ci 8818c2ecf20Sopenharmony_cistatic int 8828c2ecf20Sopenharmony_cisaa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev, 8838c2ecf20Sopenharmony_ci struct saa7164_port *port, 8848c2ecf20Sopenharmony_ci struct tmComResPSFormatDescrHeader *fmt) 8858c2ecf20Sopenharmony_ci{ 8868c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex); 8878c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " wPacketLength= 0x%x\n", fmt->wPacketLength); 8888c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " wPackLength= 0x%x\n", fmt->wPackLength); 8898c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " bPackDataType= 0x%x\n", fmt->bPackDataType); 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci /* Cache the hardware configuration in the port */ 8928c2ecf20Sopenharmony_ci /* TODO: CHECK THIS in the port config */ 8938c2ecf20Sopenharmony_ci port->bufcounter = port->hwcfg.BARLocation; 8948c2ecf20Sopenharmony_ci port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32)); 8958c2ecf20Sopenharmony_ci port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32)); 8968c2ecf20Sopenharmony_ci port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32)); 8978c2ecf20Sopenharmony_ci port->bufptr32l = port->hwcfg.BARLocation + 8988c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 8998c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32); 9008c2ecf20Sopenharmony_ci port->bufptr32h = port->hwcfg.BARLocation + 9018c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 9028c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount); 9038c2ecf20Sopenharmony_ci port->bufptr64 = port->hwcfg.BARLocation + 9048c2ecf20Sopenharmony_ci (4 * sizeof(u32)) + 9058c2ecf20Sopenharmony_ci (sizeof(u32) * port->hwcfg.buffercount); 9068c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n", 9078c2ecf20Sopenharmony_ci port->hwcfg.BARLocation); 9088c2ecf20Sopenharmony_ci 9098c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n", 9108c2ecf20Sopenharmony_ci port->nr); 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci return 0; 9138c2ecf20Sopenharmony_ci} 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_cistatic int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) 9168c2ecf20Sopenharmony_ci{ 9178c2ecf20Sopenharmony_ci struct saa7164_port *tsport = NULL; 9188c2ecf20Sopenharmony_ci struct saa7164_port *encport = NULL; 9198c2ecf20Sopenharmony_ci struct saa7164_port *vbiport = NULL; 9208c2ecf20Sopenharmony_ci u32 idx, next_offset; 9218c2ecf20Sopenharmony_ci int i; 9228c2ecf20Sopenharmony_ci struct tmComResDescrHeader *hdr, *t; 9238c2ecf20Sopenharmony_ci struct tmComResExtDevDescrHeader *exthdr; 9248c2ecf20Sopenharmony_ci struct tmComResPathDescrHeader *pathhdr; 9258c2ecf20Sopenharmony_ci struct tmComResAntTermDescrHeader *anttermhdr; 9268c2ecf20Sopenharmony_ci struct tmComResTunerDescrHeader *tunerunithdr; 9278c2ecf20Sopenharmony_ci struct tmComResDMATermDescrHeader *vcoutputtermhdr; 9288c2ecf20Sopenharmony_ci struct tmComResTSFormatDescrHeader *tsfmt; 9298c2ecf20Sopenharmony_ci struct tmComResPSFormatDescrHeader *psfmt; 9308c2ecf20Sopenharmony_ci struct tmComResSelDescrHeader *psel; 9318c2ecf20Sopenharmony_ci struct tmComResProcDescrHeader *pdh; 9328c2ecf20Sopenharmony_ci struct tmComResAFeatureDescrHeader *afd; 9338c2ecf20Sopenharmony_ci struct tmComResEncoderDescrHeader *edh; 9348c2ecf20Sopenharmony_ci struct tmComResVBIFormatDescrHeader *vbifmt; 9358c2ecf20Sopenharmony_ci u32 currpath = 0; 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 9388c2ecf20Sopenharmony_ci "%s(?,?,%d) sizeof(struct tmComResDescrHeader) = %d bytes\n", 9398c2ecf20Sopenharmony_ci __func__, len, (u32)sizeof(struct tmComResDescrHeader)); 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_ci for (idx = 0; idx < (len - sizeof(struct tmComResDescrHeader));) { 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci hdr = (struct tmComResDescrHeader *)(buf + idx); 9448c2ecf20Sopenharmony_ci 9458c2ecf20Sopenharmony_ci if (hdr->type != CS_INTERFACE) 9468c2ecf20Sopenharmony_ci return SAA_ERR_NOT_SUPPORTED; 9478c2ecf20Sopenharmony_ci 9488c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "@ 0x%x =\n", idx); 9498c2ecf20Sopenharmony_ci switch (hdr->subtype) { 9508c2ecf20Sopenharmony_ci case GENERAL_REQUEST: 9518c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " GENERAL_REQUEST\n"); 9528c2ecf20Sopenharmony_ci break; 9538c2ecf20Sopenharmony_ci case VC_TUNER_PATH: 9548c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " VC_TUNER_PATH\n"); 9558c2ecf20Sopenharmony_ci pathhdr = (struct tmComResPathDescrHeader *)(buf + idx); 9568c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " pathid = 0x%x\n", 9578c2ecf20Sopenharmony_ci pathhdr->pathid); 9588c2ecf20Sopenharmony_ci currpath = pathhdr->pathid; 9598c2ecf20Sopenharmony_ci break; 9608c2ecf20Sopenharmony_ci case VC_INPUT_TERMINAL: 9618c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n"); 9628c2ecf20Sopenharmony_ci anttermhdr = 9638c2ecf20Sopenharmony_ci (struct tmComResAntTermDescrHeader *)(buf + idx); 9648c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " terminalid = 0x%x\n", 9658c2ecf20Sopenharmony_ci anttermhdr->terminalid); 9668c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " terminaltype = 0x%x\n", 9678c2ecf20Sopenharmony_ci anttermhdr->terminaltype); 9688c2ecf20Sopenharmony_ci switch (anttermhdr->terminaltype) { 9698c2ecf20Sopenharmony_ci case ITT_ANTENNA: 9708c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = ITT_ANTENNA\n"); 9718c2ecf20Sopenharmony_ci break; 9728c2ecf20Sopenharmony_ci case LINE_CONNECTOR: 9738c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = LINE_CONNECTOR\n"); 9748c2ecf20Sopenharmony_ci break; 9758c2ecf20Sopenharmony_ci case SPDIF_CONNECTOR: 9768c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n"); 9778c2ecf20Sopenharmony_ci break; 9788c2ecf20Sopenharmony_ci case COMPOSITE_CONNECTOR: 9798c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 9808c2ecf20Sopenharmony_ci " = COMPOSITE_CONNECTOR\n"); 9818c2ecf20Sopenharmony_ci break; 9828c2ecf20Sopenharmony_ci case SVIDEO_CONNECTOR: 9838c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n"); 9848c2ecf20Sopenharmony_ci break; 9858c2ecf20Sopenharmony_ci case COMPONENT_CONNECTOR: 9868c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 9878c2ecf20Sopenharmony_ci " = COMPONENT_CONNECTOR\n"); 9888c2ecf20Sopenharmony_ci break; 9898c2ecf20Sopenharmony_ci case STANDARD_DMA: 9908c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = STANDARD_DMA\n"); 9918c2ecf20Sopenharmony_ci break; 9928c2ecf20Sopenharmony_ci default: 9938c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = undefined (0x%x)\n", 9948c2ecf20Sopenharmony_ci anttermhdr->terminaltype); 9958c2ecf20Sopenharmony_ci } 9968c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " assocterminal= 0x%x\n", 9978c2ecf20Sopenharmony_ci anttermhdr->assocterminal); 9988c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " iterminal = 0x%x\n", 9998c2ecf20Sopenharmony_ci anttermhdr->iterminal); 10008c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " controlsize = 0x%x\n", 10018c2ecf20Sopenharmony_ci anttermhdr->controlsize); 10028c2ecf20Sopenharmony_ci break; 10038c2ecf20Sopenharmony_ci case VC_OUTPUT_TERMINAL: 10048c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n"); 10058c2ecf20Sopenharmony_ci vcoutputtermhdr = 10068c2ecf20Sopenharmony_ci (struct tmComResDMATermDescrHeader *)(buf + idx); 10078c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " unitid = 0x%x\n", 10088c2ecf20Sopenharmony_ci vcoutputtermhdr->unitid); 10098c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " terminaltype = 0x%x\n", 10108c2ecf20Sopenharmony_ci vcoutputtermhdr->terminaltype); 10118c2ecf20Sopenharmony_ci switch (vcoutputtermhdr->terminaltype) { 10128c2ecf20Sopenharmony_ci case ITT_ANTENNA: 10138c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = ITT_ANTENNA\n"); 10148c2ecf20Sopenharmony_ci break; 10158c2ecf20Sopenharmony_ci case LINE_CONNECTOR: 10168c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = LINE_CONNECTOR\n"); 10178c2ecf20Sopenharmony_ci break; 10188c2ecf20Sopenharmony_ci case SPDIF_CONNECTOR: 10198c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n"); 10208c2ecf20Sopenharmony_ci break; 10218c2ecf20Sopenharmony_ci case COMPOSITE_CONNECTOR: 10228c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 10238c2ecf20Sopenharmony_ci " = COMPOSITE_CONNECTOR\n"); 10248c2ecf20Sopenharmony_ci break; 10258c2ecf20Sopenharmony_ci case SVIDEO_CONNECTOR: 10268c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n"); 10278c2ecf20Sopenharmony_ci break; 10288c2ecf20Sopenharmony_ci case COMPONENT_CONNECTOR: 10298c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 10308c2ecf20Sopenharmony_ci " = COMPONENT_CONNECTOR\n"); 10318c2ecf20Sopenharmony_ci break; 10328c2ecf20Sopenharmony_ci case STANDARD_DMA: 10338c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = STANDARD_DMA\n"); 10348c2ecf20Sopenharmony_ci break; 10358c2ecf20Sopenharmony_ci default: 10368c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = undefined (0x%x)\n", 10378c2ecf20Sopenharmony_ci vcoutputtermhdr->terminaltype); 10388c2ecf20Sopenharmony_ci } 10398c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " assocterminal= 0x%x\n", 10408c2ecf20Sopenharmony_ci vcoutputtermhdr->assocterminal); 10418c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " sourceid = 0x%x\n", 10428c2ecf20Sopenharmony_ci vcoutputtermhdr->sourceid); 10438c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " iterminal = 0x%x\n", 10448c2ecf20Sopenharmony_ci vcoutputtermhdr->iterminal); 10458c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " BARLocation = 0x%x\n", 10468c2ecf20Sopenharmony_ci vcoutputtermhdr->BARLocation); 10478c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " flags = 0x%x\n", 10488c2ecf20Sopenharmony_ci vcoutputtermhdr->flags); 10498c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " interruptid = 0x%x\n", 10508c2ecf20Sopenharmony_ci vcoutputtermhdr->interruptid); 10518c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " buffercount = 0x%x\n", 10528c2ecf20Sopenharmony_ci vcoutputtermhdr->buffercount); 10538c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " metadatasize = 0x%x\n", 10548c2ecf20Sopenharmony_ci vcoutputtermhdr->metadatasize); 10558c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " controlsize = 0x%x\n", 10568c2ecf20Sopenharmony_ci vcoutputtermhdr->controlsize); 10578c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " numformats = 0x%x\n", 10588c2ecf20Sopenharmony_ci vcoutputtermhdr->numformats); 10598c2ecf20Sopenharmony_ci 10608c2ecf20Sopenharmony_ci t = (struct tmComResDescrHeader *) 10618c2ecf20Sopenharmony_ci ((struct tmComResDMATermDescrHeader *)(buf + idx)); 10628c2ecf20Sopenharmony_ci next_offset = idx + (vcoutputtermhdr->len); 10638c2ecf20Sopenharmony_ci for (i = 0; i < vcoutputtermhdr->numformats; i++) { 10648c2ecf20Sopenharmony_ci t = (struct tmComResDescrHeader *) 10658c2ecf20Sopenharmony_ci (buf + next_offset); 10668c2ecf20Sopenharmony_ci switch (t->subtype) { 10678c2ecf20Sopenharmony_ci case VS_FORMAT_MPEG2TS: 10688c2ecf20Sopenharmony_ci tsfmt = 10698c2ecf20Sopenharmony_ci (struct tmComResTSFormatDescrHeader *)t; 10708c2ecf20Sopenharmony_ci if (currpath == 1) 10718c2ecf20Sopenharmony_ci tsport = &dev->ports[SAA7164_PORT_TS1]; 10728c2ecf20Sopenharmony_ci else 10738c2ecf20Sopenharmony_ci tsport = &dev->ports[SAA7164_PORT_TS2]; 10748c2ecf20Sopenharmony_ci memcpy(&tsport->hwcfg, vcoutputtermhdr, 10758c2ecf20Sopenharmony_ci sizeof(*vcoutputtermhdr)); 10768c2ecf20Sopenharmony_ci saa7164_api_configure_port_mpeg2ts(dev, 10778c2ecf20Sopenharmony_ci tsport, tsfmt); 10788c2ecf20Sopenharmony_ci break; 10798c2ecf20Sopenharmony_ci case VS_FORMAT_MPEG2PS: 10808c2ecf20Sopenharmony_ci psfmt = 10818c2ecf20Sopenharmony_ci (struct tmComResPSFormatDescrHeader *)t; 10828c2ecf20Sopenharmony_ci if (currpath == 1) 10838c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC1]; 10848c2ecf20Sopenharmony_ci else 10858c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC2]; 10868c2ecf20Sopenharmony_ci memcpy(&encport->hwcfg, vcoutputtermhdr, 10878c2ecf20Sopenharmony_ci sizeof(*vcoutputtermhdr)); 10888c2ecf20Sopenharmony_ci saa7164_api_configure_port_mpeg2ps(dev, 10898c2ecf20Sopenharmony_ci encport, psfmt); 10908c2ecf20Sopenharmony_ci break; 10918c2ecf20Sopenharmony_ci case VS_FORMAT_VBI: 10928c2ecf20Sopenharmony_ci vbifmt = 10938c2ecf20Sopenharmony_ci (struct tmComResVBIFormatDescrHeader *)t; 10948c2ecf20Sopenharmony_ci if (currpath == 1) 10958c2ecf20Sopenharmony_ci vbiport = &dev->ports[SAA7164_PORT_VBI1]; 10968c2ecf20Sopenharmony_ci else 10978c2ecf20Sopenharmony_ci vbiport = &dev->ports[SAA7164_PORT_VBI2]; 10988c2ecf20Sopenharmony_ci memcpy(&vbiport->hwcfg, vcoutputtermhdr, 10998c2ecf20Sopenharmony_ci sizeof(*vcoutputtermhdr)); 11008c2ecf20Sopenharmony_ci memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, 11018c2ecf20Sopenharmony_ci sizeof(*vbifmt)); 11028c2ecf20Sopenharmony_ci saa7164_api_configure_port_vbi(dev, 11038c2ecf20Sopenharmony_ci vbiport); 11048c2ecf20Sopenharmony_ci break; 11058c2ecf20Sopenharmony_ci case VS_FORMAT_RDS: 11068c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 11078c2ecf20Sopenharmony_ci " = VS_FORMAT_RDS\n"); 11088c2ecf20Sopenharmony_ci break; 11098c2ecf20Sopenharmony_ci case VS_FORMAT_UNCOMPRESSED: 11108c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 11118c2ecf20Sopenharmony_ci " = VS_FORMAT_UNCOMPRESSED\n"); 11128c2ecf20Sopenharmony_ci break; 11138c2ecf20Sopenharmony_ci case VS_FORMAT_TYPE: 11148c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 11158c2ecf20Sopenharmony_ci " = VS_FORMAT_TYPE\n"); 11168c2ecf20Sopenharmony_ci break; 11178c2ecf20Sopenharmony_ci default: 11188c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 11198c2ecf20Sopenharmony_ci " = undefined (0x%x)\n", 11208c2ecf20Sopenharmony_ci t->subtype); 11218c2ecf20Sopenharmony_ci } 11228c2ecf20Sopenharmony_ci next_offset += t->len; 11238c2ecf20Sopenharmony_ci } 11248c2ecf20Sopenharmony_ci 11258c2ecf20Sopenharmony_ci break; 11268c2ecf20Sopenharmony_ci case TUNER_UNIT: 11278c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " TUNER_UNIT\n"); 11288c2ecf20Sopenharmony_ci tunerunithdr = 11298c2ecf20Sopenharmony_ci (struct tmComResTunerDescrHeader *)(buf + idx); 11308c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " unitid = 0x%x\n", 11318c2ecf20Sopenharmony_ci tunerunithdr->unitid); 11328c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " sourceid = 0x%x\n", 11338c2ecf20Sopenharmony_ci tunerunithdr->sourceid); 11348c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " iunit = 0x%x\n", 11358c2ecf20Sopenharmony_ci tunerunithdr->iunit); 11368c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " tuningstandards = 0x%x\n", 11378c2ecf20Sopenharmony_ci tunerunithdr->tuningstandards); 11388c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " controlsize = 0x%x\n", 11398c2ecf20Sopenharmony_ci tunerunithdr->controlsize); 11408c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " controls = 0x%x\n", 11418c2ecf20Sopenharmony_ci tunerunithdr->controls); 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_ci if (tunerunithdr->unitid == tunerunithdr->iunit) { 11448c2ecf20Sopenharmony_ci if (currpath == 1) 11458c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC1]; 11468c2ecf20Sopenharmony_ci else 11478c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC2]; 11488c2ecf20Sopenharmony_ci memcpy(&encport->tunerunit, tunerunithdr, 11498c2ecf20Sopenharmony_ci sizeof(struct tmComResTunerDescrHeader)); 11508c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 11518c2ecf20Sopenharmony_ci " (becomes dev->enc[%d] tuner)\n", 11528c2ecf20Sopenharmony_ci encport->nr); 11538c2ecf20Sopenharmony_ci } 11548c2ecf20Sopenharmony_ci break; 11558c2ecf20Sopenharmony_ci case VC_SELECTOR_UNIT: 11568c2ecf20Sopenharmony_ci psel = (struct tmComResSelDescrHeader *)(buf + idx); 11578c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n"); 11588c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " unitid = 0x%x\n", 11598c2ecf20Sopenharmony_ci psel->unitid); 11608c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " nrinpins = 0x%x\n", 11618c2ecf20Sopenharmony_ci psel->nrinpins); 11628c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " sourceid = 0x%x\n", 11638c2ecf20Sopenharmony_ci psel->sourceid); 11648c2ecf20Sopenharmony_ci break; 11658c2ecf20Sopenharmony_ci case VC_PROCESSING_UNIT: 11668c2ecf20Sopenharmony_ci pdh = (struct tmComResProcDescrHeader *)(buf + idx); 11678c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n"); 11688c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " unitid = 0x%x\n", 11698c2ecf20Sopenharmony_ci pdh->unitid); 11708c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " sourceid = 0x%x\n", 11718c2ecf20Sopenharmony_ci pdh->sourceid); 11728c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " controlsize = 0x%x\n", 11738c2ecf20Sopenharmony_ci pdh->controlsize); 11748c2ecf20Sopenharmony_ci if (pdh->controlsize == 0x04) { 11758c2ecf20Sopenharmony_ci if (currpath == 1) 11768c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC1]; 11778c2ecf20Sopenharmony_ci else 11788c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC2]; 11798c2ecf20Sopenharmony_ci memcpy(&encport->vidproc, pdh, 11808c2ecf20Sopenharmony_ci sizeof(struct tmComResProcDescrHeader)); 11818c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", 11828c2ecf20Sopenharmony_ci encport->nr); 11838c2ecf20Sopenharmony_ci } 11848c2ecf20Sopenharmony_ci break; 11858c2ecf20Sopenharmony_ci case FEATURE_UNIT: 11868c2ecf20Sopenharmony_ci afd = (struct tmComResAFeatureDescrHeader *)(buf + idx); 11878c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " FEATURE_UNIT\n"); 11888c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " unitid = 0x%x\n", 11898c2ecf20Sopenharmony_ci afd->unitid); 11908c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " sourceid = 0x%x\n", 11918c2ecf20Sopenharmony_ci afd->sourceid); 11928c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " controlsize = 0x%x\n", 11938c2ecf20Sopenharmony_ci afd->controlsize); 11948c2ecf20Sopenharmony_ci if (currpath == 1) 11958c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC1]; 11968c2ecf20Sopenharmony_ci else 11978c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC2]; 11988c2ecf20Sopenharmony_ci memcpy(&encport->audfeat, afd, 11998c2ecf20Sopenharmony_ci sizeof(struct tmComResAFeatureDescrHeader)); 12008c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", 12018c2ecf20Sopenharmony_ci encport->nr); 12028c2ecf20Sopenharmony_ci break; 12038c2ecf20Sopenharmony_ci case ENCODER_UNIT: 12048c2ecf20Sopenharmony_ci edh = (struct tmComResEncoderDescrHeader *)(buf + idx); 12058c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " ENCODER_UNIT\n"); 12068c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype); 12078c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid); 12088c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " vsourceid = 0x%x\n", 12098c2ecf20Sopenharmony_ci edh->vsourceid); 12108c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " asourceid = 0x%x\n", 12118c2ecf20Sopenharmony_ci edh->asourceid); 12128c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit); 12138c2ecf20Sopenharmony_ci if (edh->iunit == edh->unitid) { 12148c2ecf20Sopenharmony_ci if (currpath == 1) 12158c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC1]; 12168c2ecf20Sopenharmony_ci else 12178c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC2]; 12188c2ecf20Sopenharmony_ci memcpy(&encport->encunit, edh, 12198c2ecf20Sopenharmony_ci sizeof(struct tmComResEncoderDescrHeader)); 12208c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 12218c2ecf20Sopenharmony_ci " (becomes dev->enc[%d])\n", 12228c2ecf20Sopenharmony_ci encport->nr); 12238c2ecf20Sopenharmony_ci } 12248c2ecf20Sopenharmony_ci break; 12258c2ecf20Sopenharmony_ci case EXTENSION_UNIT: 12268c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " EXTENSION_UNIT\n"); 12278c2ecf20Sopenharmony_ci exthdr = (struct tmComResExtDevDescrHeader *)(buf + idx); 12288c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " unitid = 0x%x\n", 12298c2ecf20Sopenharmony_ci exthdr->unitid); 12308c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " deviceid = 0x%x\n", 12318c2ecf20Sopenharmony_ci exthdr->deviceid); 12328c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " devicetype = 0x%x\n", 12338c2ecf20Sopenharmony_ci exthdr->devicetype); 12348c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x1) 12358c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = Decoder Device\n"); 12368c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x2) 12378c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = GPIO Source\n"); 12388c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x4) 12398c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = Video Decoder\n"); 12408c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x8) 12418c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = Audio Decoder\n"); 12428c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x20) 12438c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = Crossbar\n"); 12448c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x40) 12458c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = Tuner\n"); 12468c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x80) 12478c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = IF PLL\n"); 12488c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x100) 12498c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = Demodulator\n"); 12508c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x200) 12518c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = RDS Decoder\n"); 12528c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x400) 12538c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = Encoder\n"); 12548c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x800) 12558c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = IR Decoder\n"); 12568c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x1000) 12578c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " = EEPROM\n"); 12588c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x2000) 12598c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 12608c2ecf20Sopenharmony_ci " = VBI Decoder\n"); 12618c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x10000) 12628c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 12638c2ecf20Sopenharmony_ci " = Streaming Device\n"); 12648c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x20000) 12658c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 12668c2ecf20Sopenharmony_ci " = DRM Device\n"); 12678c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x40000000) 12688c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 12698c2ecf20Sopenharmony_ci " = Generic Device\n"); 12708c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x80000000) 12718c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 12728c2ecf20Sopenharmony_ci " = Config Space Device\n"); 12738c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " numgpiopins = 0x%x\n", 12748c2ecf20Sopenharmony_ci exthdr->numgpiopins); 12758c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n", 12768c2ecf20Sopenharmony_ci exthdr->numgpiogroups); 12778c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " controlsize = 0x%x\n", 12788c2ecf20Sopenharmony_ci exthdr->controlsize); 12798c2ecf20Sopenharmony_ci if (exthdr->devicetype & 0x80) { 12808c2ecf20Sopenharmony_ci if (currpath == 1) 12818c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC1]; 12828c2ecf20Sopenharmony_ci else 12838c2ecf20Sopenharmony_ci encport = &dev->ports[SAA7164_PORT_ENC2]; 12848c2ecf20Sopenharmony_ci memcpy(&encport->ifunit, exthdr, 12858c2ecf20Sopenharmony_ci sizeof(struct tmComResExtDevDescrHeader)); 12868c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, 12878c2ecf20Sopenharmony_ci " (becomes dev->enc[%d])\n", 12888c2ecf20Sopenharmony_ci encport->nr); 12898c2ecf20Sopenharmony_ci } 12908c2ecf20Sopenharmony_ci break; 12918c2ecf20Sopenharmony_ci case PVC_INFRARED_UNIT: 12928c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n"); 12938c2ecf20Sopenharmony_ci break; 12948c2ecf20Sopenharmony_ci case DRM_UNIT: 12958c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " DRM_UNIT\n"); 12968c2ecf20Sopenharmony_ci break; 12978c2ecf20Sopenharmony_ci default: 12988c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "default %d\n", hdr->subtype); 12998c2ecf20Sopenharmony_ci } 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " 1.%x\n", hdr->len); 13028c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " 2.%x\n", hdr->type); 13038c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype); 13048c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid); 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_ci idx += hdr->len; 13078c2ecf20Sopenharmony_ci } 13088c2ecf20Sopenharmony_ci 13098c2ecf20Sopenharmony_ci return 0; 13108c2ecf20Sopenharmony_ci} 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ciint saa7164_api_enum_subdevs(struct saa7164_dev *dev) 13138c2ecf20Sopenharmony_ci{ 13148c2ecf20Sopenharmony_ci int ret; 13158c2ecf20Sopenharmony_ci u32 buflen = 0; 13168c2ecf20Sopenharmony_ci u8 *buf; 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s()\n", __func__); 13198c2ecf20Sopenharmony_ci 13208c2ecf20Sopenharmony_ci /* Get the total descriptor length */ 13218c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, 0, GET_LEN, 13228c2ecf20Sopenharmony_ci GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen); 13238c2ecf20Sopenharmony_ci if (ret != SAA_OK) 13248c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 13258c2ecf20Sopenharmony_ci 13268c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n", 13278c2ecf20Sopenharmony_ci __func__, buflen); 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_ci /* Allocate enough storage for all of the descs */ 13308c2ecf20Sopenharmony_ci buf = kzalloc(buflen, GFP_KERNEL); 13318c2ecf20Sopenharmony_ci if (!buf) 13328c2ecf20Sopenharmony_ci return SAA_ERR_NO_RESOURCES; 13338c2ecf20Sopenharmony_ci 13348c2ecf20Sopenharmony_ci /* Retrieve them */ 13358c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, 0, GET_CUR, 13368c2ecf20Sopenharmony_ci GET_DESCRIPTORS_CONTROL, buflen, buf); 13378c2ecf20Sopenharmony_ci if (ret != SAA_OK) { 13388c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); 13398c2ecf20Sopenharmony_ci goto out; 13408c2ecf20Sopenharmony_ci } 13418c2ecf20Sopenharmony_ci 13428c2ecf20Sopenharmony_ci if (saa_debug & DBGLVL_API) 13438c2ecf20Sopenharmony_ci print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, 13448c2ecf20Sopenharmony_ci buflen & ~15, false); 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_ci saa7164_api_dump_subdevs(dev, buf, buflen); 13478c2ecf20Sopenharmony_ci 13488c2ecf20Sopenharmony_ciout: 13498c2ecf20Sopenharmony_ci kfree(buf); 13508c2ecf20Sopenharmony_ci return ret; 13518c2ecf20Sopenharmony_ci} 13528c2ecf20Sopenharmony_ci 13538c2ecf20Sopenharmony_ciint saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, 13548c2ecf20Sopenharmony_ci u32 datalen, u8 *data) 13558c2ecf20Sopenharmony_ci{ 13568c2ecf20Sopenharmony_ci struct saa7164_dev *dev = bus->dev; 13578c2ecf20Sopenharmony_ci u16 len = 0; 13588c2ecf20Sopenharmony_ci int unitid; 13598c2ecf20Sopenharmony_ci u8 buf[256]; 13608c2ecf20Sopenharmony_ci int ret; 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s() addr=%x reglen=%d datalen=%d\n", 13638c2ecf20Sopenharmony_ci __func__, addr, reglen, datalen); 13648c2ecf20Sopenharmony_ci 13658c2ecf20Sopenharmony_ci if (reglen > 4) 13668c2ecf20Sopenharmony_ci return -EIO; 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_ci /* Prepare the send buffer */ 13698c2ecf20Sopenharmony_ci /* Bytes 00-03 source register length 13708c2ecf20Sopenharmony_ci * 04-07 source bytes to read 13718c2ecf20Sopenharmony_ci * 08... register address 13728c2ecf20Sopenharmony_ci */ 13738c2ecf20Sopenharmony_ci memset(buf, 0, sizeof(buf)); 13748c2ecf20Sopenharmony_ci memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen); 13758c2ecf20Sopenharmony_ci *((u32 *)(buf + 0 * sizeof(u32))) = reglen; 13768c2ecf20Sopenharmony_ci *((u32 *)(buf + 1 * sizeof(u32))) = datalen; 13778c2ecf20Sopenharmony_ci 13788c2ecf20Sopenharmony_ci unitid = saa7164_i2caddr_to_unitid(bus, addr); 13798c2ecf20Sopenharmony_ci if (unitid < 0) { 13808c2ecf20Sopenharmony_ci printk(KERN_ERR 13818c2ecf20Sopenharmony_ci "%s() error, cannot translate regaddr 0x%x to unitid\n", 13828c2ecf20Sopenharmony_ci __func__, addr); 13838c2ecf20Sopenharmony_ci return -EIO; 13848c2ecf20Sopenharmony_ci } 13858c2ecf20Sopenharmony_ci 13868c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN, 13878c2ecf20Sopenharmony_ci EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len); 13888c2ecf20Sopenharmony_ci if (ret != SAA_OK) { 13898c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret); 13908c2ecf20Sopenharmony_ci return -EIO; 13918c2ecf20Sopenharmony_ci } 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len); 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_ci if (saa_debug & DBGLVL_I2C) 13968c2ecf20Sopenharmony_ci print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, 13978c2ecf20Sopenharmony_ci 32, false); 13988c2ecf20Sopenharmony_ci 13998c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR, 14008c2ecf20Sopenharmony_ci EXU_REGISTER_ACCESS_CONTROL, len, &buf); 14018c2ecf20Sopenharmony_ci if (ret != SAA_OK) 14028c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); 14038c2ecf20Sopenharmony_ci else { 14048c2ecf20Sopenharmony_ci if (saa_debug & DBGLVL_I2C) 14058c2ecf20Sopenharmony_ci print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, 14068c2ecf20Sopenharmony_ci buf, sizeof(buf), false); 14078c2ecf20Sopenharmony_ci memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen); 14088c2ecf20Sopenharmony_ci } 14098c2ecf20Sopenharmony_ci 14108c2ecf20Sopenharmony_ci return ret == SAA_OK ? 0 : -EIO; 14118c2ecf20Sopenharmony_ci} 14128c2ecf20Sopenharmony_ci 14138c2ecf20Sopenharmony_ci/* For a given 8 bit i2c address device, write the buffer */ 14148c2ecf20Sopenharmony_ciint saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen, 14158c2ecf20Sopenharmony_ci u8 *data) 14168c2ecf20Sopenharmony_ci{ 14178c2ecf20Sopenharmony_ci struct saa7164_dev *dev = bus->dev; 14188c2ecf20Sopenharmony_ci u16 len = 0; 14198c2ecf20Sopenharmony_ci int unitid; 14208c2ecf20Sopenharmony_ci int reglen; 14218c2ecf20Sopenharmony_ci u8 buf[256]; 14228c2ecf20Sopenharmony_ci int ret; 14238c2ecf20Sopenharmony_ci 14248c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s() addr=0x%2x len=0x%x\n", 14258c2ecf20Sopenharmony_ci __func__, addr, datalen); 14268c2ecf20Sopenharmony_ci 14278c2ecf20Sopenharmony_ci if ((datalen == 0) || (datalen > 232)) 14288c2ecf20Sopenharmony_ci return -EIO; 14298c2ecf20Sopenharmony_ci 14308c2ecf20Sopenharmony_ci memset(buf, 0, sizeof(buf)); 14318c2ecf20Sopenharmony_ci 14328c2ecf20Sopenharmony_ci unitid = saa7164_i2caddr_to_unitid(bus, addr); 14338c2ecf20Sopenharmony_ci if (unitid < 0) { 14348c2ecf20Sopenharmony_ci printk(KERN_ERR 14358c2ecf20Sopenharmony_ci "%s() error, cannot translate regaddr 0x%x to unitid\n", 14368c2ecf20Sopenharmony_ci __func__, addr); 14378c2ecf20Sopenharmony_ci return -EIO; 14388c2ecf20Sopenharmony_ci } 14398c2ecf20Sopenharmony_ci 14408c2ecf20Sopenharmony_ci reglen = saa7164_i2caddr_to_reglen(bus, addr); 14418c2ecf20Sopenharmony_ci if (reglen < 0) { 14428c2ecf20Sopenharmony_ci printk(KERN_ERR 14438c2ecf20Sopenharmony_ci "%s() error, cannot translate regaddr to reglen\n", 14448c2ecf20Sopenharmony_ci __func__); 14458c2ecf20Sopenharmony_ci return -EIO; 14468c2ecf20Sopenharmony_ci } 14478c2ecf20Sopenharmony_ci 14488c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN, 14498c2ecf20Sopenharmony_ci EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len); 14508c2ecf20Sopenharmony_ci if (ret != SAA_OK) { 14518c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret); 14528c2ecf20Sopenharmony_ci return -EIO; 14538c2ecf20Sopenharmony_ci } 14548c2ecf20Sopenharmony_ci 14558c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s() len = %d bytes unitid=0x%x\n", __func__, 14568c2ecf20Sopenharmony_ci len, unitid); 14578c2ecf20Sopenharmony_ci 14588c2ecf20Sopenharmony_ci /* Prepare the send buffer */ 14598c2ecf20Sopenharmony_ci /* Bytes 00-03 dest register length 14608c2ecf20Sopenharmony_ci * 04-07 dest bytes to write 14618c2ecf20Sopenharmony_ci * 08... register address 14628c2ecf20Sopenharmony_ci */ 14638c2ecf20Sopenharmony_ci *((u32 *)(buf + 0 * sizeof(u32))) = reglen; 14648c2ecf20Sopenharmony_ci *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen; 14658c2ecf20Sopenharmony_ci memcpy((buf + 2 * sizeof(u32)), data, datalen); 14668c2ecf20Sopenharmony_ci 14678c2ecf20Sopenharmony_ci if (saa_debug & DBGLVL_I2C) 14688c2ecf20Sopenharmony_ci print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, 14698c2ecf20Sopenharmony_ci buf, sizeof(buf), false); 14708c2ecf20Sopenharmony_ci 14718c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR, 14728c2ecf20Sopenharmony_ci EXU_REGISTER_ACCESS_CONTROL, len, &buf); 14738c2ecf20Sopenharmony_ci if (ret != SAA_OK) 14748c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); 14758c2ecf20Sopenharmony_ci 14768c2ecf20Sopenharmony_ci return ret == SAA_OK ? 0 : -EIO; 14778c2ecf20Sopenharmony_ci} 14788c2ecf20Sopenharmony_ci 14798c2ecf20Sopenharmony_cistatic int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid, 14808c2ecf20Sopenharmony_ci u8 pin, u8 state) 14818c2ecf20Sopenharmony_ci{ 14828c2ecf20Sopenharmony_ci int ret; 14838c2ecf20Sopenharmony_ci struct tmComResGPIO t; 14848c2ecf20Sopenharmony_ci 14858c2ecf20Sopenharmony_ci dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n", 14868c2ecf20Sopenharmony_ci __func__, unitid, pin, state); 14878c2ecf20Sopenharmony_ci 14888c2ecf20Sopenharmony_ci if ((pin > 7) || (state > 2)) 14898c2ecf20Sopenharmony_ci return SAA_ERR_BAD_PARAMETER; 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ci t.pin = pin; 14928c2ecf20Sopenharmony_ci t.state = state; 14938c2ecf20Sopenharmony_ci 14948c2ecf20Sopenharmony_ci ret = saa7164_cmd_send(dev, unitid, SET_CUR, 14958c2ecf20Sopenharmony_ci EXU_GPIO_CONTROL, sizeof(t), &t); 14968c2ecf20Sopenharmony_ci if (ret != SAA_OK) 14978c2ecf20Sopenharmony_ci printk(KERN_ERR "%s() error, ret = 0x%x\n", 14988c2ecf20Sopenharmony_ci __func__, ret); 14998c2ecf20Sopenharmony_ci 15008c2ecf20Sopenharmony_ci return ret; 15018c2ecf20Sopenharmony_ci} 15028c2ecf20Sopenharmony_ci 15038c2ecf20Sopenharmony_ciint saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, 15048c2ecf20Sopenharmony_ci u8 pin) 15058c2ecf20Sopenharmony_ci{ 15068c2ecf20Sopenharmony_ci return saa7164_api_modify_gpio(dev, unitid, pin, 1); 15078c2ecf20Sopenharmony_ci} 15088c2ecf20Sopenharmony_ci 15098c2ecf20Sopenharmony_ciint saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, 15108c2ecf20Sopenharmony_ci u8 pin) 15118c2ecf20Sopenharmony_ci{ 15128c2ecf20Sopenharmony_ci return saa7164_api_modify_gpio(dev, unitid, pin, 0); 15138c2ecf20Sopenharmony_ci} 15148c2ecf20Sopenharmony_ci 1515