diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-14 17:13:30 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 21:36:22 +0200 |
commit | b285192a43f0432d82c2c10974204e78af0da596 (patch) | |
tree | 618aa87e760c9c949eca9e4df6ae0eeffa11dcfc /drivers/media/video/saa7164 | |
parent | [media] bt8xx: move analog TV part to be together with DTV one (diff) | |
download | linux-b285192a43f0432d82c2c10974204e78af0da596.tar.xz linux-b285192a43f0432d82c2c10974204e78af0da596.zip |
[media] rename most media/video pci drivers to media/pci
Rename all PCI drivers with their own directory under
drivers/media/video into drivers/media/pci and update the
building system.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7164')
-rw-r--r-- | drivers/media/video/saa7164/Kconfig | 18 | ||||
-rw-r--r-- | drivers/media/video/saa7164/Makefile | 12 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-api.c | 1524 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-buffer.c | 322 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-bus.c | 475 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-cards.c | 773 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-cmd.c | 589 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-core.c | 1488 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-dvb.c | 556 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-encoder.c | 1500 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-fw.c | 613 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-i2c.c | 125 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-reg.h | 219 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-types.h | 442 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-vbi.c | 1374 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164.h | 616 |
16 files changed, 0 insertions, 10646 deletions
diff --git a/drivers/media/video/saa7164/Kconfig b/drivers/media/video/saa7164/Kconfig deleted file mode 100644 index 353263725172..000000000000 --- a/drivers/media/video/saa7164/Kconfig +++ /dev/null @@ -1,18 +0,0 @@ -config VIDEO_SAA7164 - tristate "NXP SAA7164 support" - depends on DVB_CORE && PCI && I2C - select I2C_ALGOBIT - select FW_LOADER - select VIDEO_TUNER - select VIDEO_TVEEPROM - select VIDEOBUF_DVB - select DVB_TDA10048 if !DVB_FE_CUSTOMISE - select DVB_S5H1411 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE - ---help--- - This is a video4linux driver for NXP SAA7164 based - TV cards. - - To compile this driver as a module, choose M here: the - module will be called saa7164 - diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile deleted file mode 100644 index 847110c2e14c..000000000000 --- a/drivers/media/video/saa7164/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \ - saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \ - saa7164-buffer.o saa7164-encoder.o saa7164-vbi.o - -obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o - -ccflags-y += -I$(srctree)/drivers/media/video -ccflags-y += -I$(srctree)/drivers/media/tuners -ccflags-y += -I$(srctree)/drivers/media/dvb-core -ccflags-y += -I$(srctree)/drivers/media/dvb-frontends - -ccflags-y += $(extra-cflags-y) $(extra-cflags-m) diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c deleted file mode 100644 index eff7135cf0e8..000000000000 --- a/drivers/media/video/saa7164/saa7164-api.c +++ /dev/null @@ -1,1524 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/wait.h> -#include <linux/slab.h> - -#include "saa7164.h" - -int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i) -{ - int ret; - - if (!(saa_debug & DBGLVL_CPU)) - return 0; - - dprintk(DBGLVL_API, "%s()\n", __func__); - - i->deviceinst = 0; - i->devicespec = 0; - i->mode = 0; - i->status = 0; - - ret = saa7164_cmd_send(dev, 0, GET_CUR, - GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad); - - return ret; -} - -int saa7164_api_collect_debug(struct saa7164_dev *dev) -{ - struct tmComResDebugGetData d; - u8 more = 255; - int ret; - - dprintk(DBGLVL_API, "%s()\n", __func__); - - while (more--) { - - memset(&d, 0, sizeof(d)); - - ret = saa7164_cmd_send(dev, 0, GET_CUR, - GET_DEBUG_DATA_CONTROL, sizeof(d), &d); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", - __func__, ret); - - if (d.dwResult != SAA_OK) - break; - - printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, - d.ucDebugData); - } - - return 0; -} - -int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level) -{ - struct tmComResDebugSetLevel lvl; - int ret; - - dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level); - - /* Retrieve current state */ - ret = saa7164_cmd_send(dev, 0, GET_CUR, - SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel); - - lvl.dwDebugLevel = level; - - /* set new state */ - ret = saa7164_cmd_send(dev, 0, SET_CUR, - SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - return ret; -} - -int saa7164_api_set_vbi_format(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct tmComResProbeCommit fmt, rsp; - int ret; - - dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__, - port->nr, port->hwcfg.unitid); - - fmt.bmHint = 0; - fmt.bFormatIndex = 1; - fmt.bFrameIndex = 1; - - /* Probe, see if it can support this format */ - ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, - SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt); - if (ret != SAA_OK) - printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret); - - /* See of the format change was successful */ - ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, - GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret); - } else { - /* Compare requested vs received, should be same */ - if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) { - dprintk(DBGLVL_API, "SET/PROBE Verified\n"); - - /* Ask the device to select the negotiated format */ - ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, - SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt); - if (ret != SAA_OK) - printk(KERN_ERR "%s() commit error, ret = 0x%x\n", - __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, - GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp); - if (ret != SAA_OK) - printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n", - __func__, ret); - - if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) { - printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n", - __func__, ret); - } else - dprintk(DBGLVL_API, "SET/COMMIT Verified\n"); - - dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint); - dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", - rsp.bFormatIndex); - dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", - rsp.bFrameIndex); - } else - printk(KERN_ERR "%s() compare failed\n", __func__); - } - - if (ret == SAA_OK) - dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr); - - return ret; -} - -int saa7164_api_set_gop_size(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct tmComResEncVideoGopStructure gs; - int ret; - - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - gs.ucRefFrameDist = port->encoder_params.refdist; - gs.ucGOPSize = port->encoder_params.gop_size; - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, - EU_VIDEO_GOP_STRUCTURE_CONTROL, - sizeof(gs), &gs); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - return ret; -} - -int saa7164_api_set_encoder(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct tmComResEncVideoBitRate vb; - struct tmComResEncAudioBitRate ab; - int ret; - - dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, - port->hwcfg.sourceid); - - if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) - port->encoder_profile = EU_PROFILE_PS_DVD; - else - port->encoder_profile = EU_PROFILE_TS_HQ; - - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, - EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Resolution */ - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, - EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Establish video bitrates */ - if (port->encoder_params.bitrate_mode == - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) - vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT; - else - vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK; - vb.dwVideoBitRate = port->encoder_params.bitrate; - vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak; - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, - EU_VIDEO_BIT_RATE_CONTROL, - sizeof(struct tmComResEncVideoBitRate), - &vb); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Establish audio bitrates */ - ab.ucAudioBitRateMode = 0; - ab.dwAudioBitRate = 384000; - ab.dwAudioBitRatePeak = ab.dwAudioBitRate; - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, - EU_AUDIO_BIT_RATE_CONTROL, - sizeof(struct tmComResEncAudioBitRate), - &ab); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, - ret); - - saa7164_api_set_aspect_ratio(port); - saa7164_api_set_gop_size(port); - - return ret; -} - -int saa7164_api_get_encoder(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct tmComResEncVideoBitRate v; - struct tmComResEncAudioBitRate a; - struct tmComResEncVideoInputAspectRatio ar; - int ret; - - dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, - port->hwcfg.sourceid); - - port->encoder_profile = 0; - port->video_format = 0; - port->video_resolution = 0; - port->audio_format = 0; - - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, - EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, - EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), - &port->video_resolution); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, - EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, - EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, - EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, - EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Aspect Ratio */ - ar.width = 0; - ar.height = 0; - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, - EU_VIDEO_INPUT_ASPECT_CONTROL, - sizeof(struct tmComResEncVideoInputAspectRatio), &ar); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile); - dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format); - dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format); - dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution); - dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", - v.ucVideoBitRateMode); - dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", - v.dwVideoBitRate); - dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", - v.dwVideoBitRatePeak); - dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", - a.ucAudioBitRateMode); - dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", - a.dwAudioBitRate); - dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", - a.dwAudioBitRatePeak); - dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", - ar.width, ar.height); - - return ret; -} - -int saa7164_api_set_aspect_ratio(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct tmComResEncVideoInputAspectRatio ar; - int ret; - - dprintk(DBGLVL_ENC, "%s(%d)\n", __func__, - port->encoder_params.ctl_aspect); - - switch (port->encoder_params.ctl_aspect) { - case V4L2_MPEG_VIDEO_ASPECT_1x1: - ar.width = 1; - ar.height = 1; - break; - case V4L2_MPEG_VIDEO_ASPECT_4x3: - ar.width = 4; - ar.height = 3; - break; - case V4L2_MPEG_VIDEO_ASPECT_16x9: - ar.width = 16; - ar.height = 9; - break; - case V4L2_MPEG_VIDEO_ASPECT_221x100: - ar.width = 221; - ar.height = 100; - break; - default: - BUG(); - } - - dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__, - port->encoder_params.ctl_aspect, - ar.width, ar.height); - - /* Aspect Ratio */ - ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, - EU_VIDEO_INPUT_ASPECT_CONTROL, - sizeof(struct tmComResEncVideoInputAspectRatio), &ar); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - return ret; -} - -int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl) -{ - struct saa7164_dev *dev = port->dev; - int ret; - u16 val; - - if (ctl == PU_BRIGHTNESS_CONTROL) - val = port->ctl_brightness; - else - if (ctl == PU_CONTRAST_CONTROL) - val = port->ctl_contrast; - else - if (ctl == PU_HUE_CONTROL) - val = port->ctl_hue; - else - if (ctl == PU_SATURATION_CONTROL) - val = port->ctl_saturation; - else - if (ctl == PU_SHARPNESS_CONTROL) - val = port->ctl_sharpness; - else - return -EINVAL; - - dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n", - __func__, port->encunit.vsourceid, ctl, val); - - ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR, - ctl, sizeof(u16), &val); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - return ret; -} - -int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl) -{ - struct saa7164_dev *dev = port->dev; - int ret; - u16 val; - - ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR, - ctl, sizeof(u16), &val); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - return ret; - } - - dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n", - __func__, ctl, val); - - if (ctl == PU_BRIGHTNESS_CONTROL) - port->ctl_brightness = val; - else - if (ctl == PU_CONTRAST_CONTROL) - port->ctl_contrast = val; - else - if (ctl == PU_HUE_CONTROL) - port->ctl_hue = val; - else - if (ctl == PU_SATURATION_CONTROL) - port->ctl_saturation = val; - else - if (ctl == PU_SHARPNESS_CONTROL) - port->ctl_sharpness = val; - - return ret; -} - -int saa7164_api_set_videomux(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 }; - int ret; - - dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n", - __func__, port->mux_input, inputs[port->mux_input - 1]); - - /* Audio Mute */ - ret = saa7164_api_audio_mute(port, 1); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Video Mux */ - ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR, - SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Audio Mux */ - ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR, - SU_INPUT_SELECT_CONTROL, sizeof(u8), - &inputs[port->mux_input - 1]); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Audio UnMute */ - ret = saa7164_api_audio_mute(port, 0); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - return ret; -} - -int saa7164_api_audio_mute(struct saa7164_port *port, int mute) -{ - struct saa7164_dev *dev = port->dev; - u8 v = mute; - int ret; - - dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute); - - ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, - MUTE_CONTROL, sizeof(u8), &v); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - return ret; -} - -/* 0 = silence, 0xff = full */ -int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level) -{ - struct saa7164_dev *dev = port->dev; - s16 v, min, max; - int ret; - - dprintk(DBGLVL_API, "%s(%d)\n", __func__, level); - - /* Obtain the min/max ranges */ - ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN, - VOLUME_CONTROL, sizeof(u16), &min); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX, - VOLUME_CONTROL, sizeof(u16), &max); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR, - (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, - level, min, max, v); - - v = level; - if (v < min) - v = min; - if (v > max) - v = max; - - /* Left */ - ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, - (0x01 << 8) | VOLUME_CONTROL, sizeof(s16), &v); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Right */ - ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, - (0x02 << 8) | VOLUME_CONTROL, sizeof(s16), &v); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR, - (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, - level, min, max, v); - - return ret; -} - -int saa7164_api_set_audio_std(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct tmComResAudioDefaults lvl; - struct tmComResTunerStandard tvaudio; - int ret; - - dprintk(DBGLVL_API, "%s()\n", __func__); - - /* Establish default levels */ - lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT; - lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT; - lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT; - lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT; - lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT; - lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT; - ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, - AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults), - &lvl); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - /* Manually select the appropriate TV audio standard */ - if (port->encodernorm.id & V4L2_STD_NTSC) { - tvaudio.std = TU_STANDARD_NTSC_M; - tvaudio.country = 1; - } else { - tvaudio.std = TU_STANDARD_PAL_I; - tvaudio.country = 44; - } - - ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, - TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio); - if (ret != SAA_OK) - printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", - __func__, ret); - return ret; -} - -int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect) -{ - struct saa7164_dev *dev = port->dev; - struct tmComResTunerStandardAuto p; - int ret; - - dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect); - - /* Disable TV Audio autodetect if not already set (buggy) */ - if (autodetect) - p.mode = TU_STANDARD_AUTO; - else - p.mode = TU_STANDARD_MANUAL; - ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, - TU_STANDARD_AUTO_CONTROL, sizeof(p), &p); - if (ret != SAA_OK) - printk(KERN_ERR - "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", - __func__, ret); - - return ret; -} - -int saa7164_api_get_videomux(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR, - SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - dprintk(DBGLVL_ENC, "%s() v_mux=%d\n", - __func__, port->mux_input); - - return ret; -} - -int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val) -{ - struct saa7164_dev *dev = port->dev; - - u16 len = 0; - u8 buf[256]; - int ret; - u8 mas; - - dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__, - port->nr, port->type, val); - - if (port->nr == 0) - mas = 0xd0; - else - mas = 0xe0; - - memset(buf, 0, sizeof(buf)); - - buf[0x00] = 0x04; - buf[0x01] = 0x00; - buf[0x02] = 0x00; - buf[0x03] = 0x00; - - buf[0x04] = 0x04; - buf[0x05] = 0x00; - buf[0x06] = 0x00; - buf[0x07] = 0x00; - - buf[0x08] = reg; - buf[0x09] = 0x26; - buf[0x0a] = mas; - buf[0x0b] = 0xb0; - - buf[0x0c] = val; - buf[0x0d] = 0x00; - buf[0x0e] = 0x00; - buf[0x0f] = 0x00; - - ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN, - EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret); - return -EIO; - } - - ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR, - EXU_REGISTER_ACCESS_CONTROL, len, &buf); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); -#if 0 - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, 16, - false); -#endif - return ret == SAA_OK ? 0 : -EIO; -} - -/* Disable the IF block AGC controls */ -int saa7164_api_configure_dif(struct saa7164_port *port, u32 std) -{ - struct saa7164_dev *dev = port->dev; - int ret = 0; - u8 agc_disable; - - dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std); - - if (std & V4L2_STD_NTSC) { - dprintk(DBGLVL_API, " NTSC\n"); - saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ - agc_disable = 0; - } else if (std & V4L2_STD_PAL_I) { - dprintk(DBGLVL_API, " PAL-I\n"); - saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */ - agc_disable = 0; - } else if (std & V4L2_STD_PAL_M) { - dprintk(DBGLVL_API, " PAL-M\n"); - saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ - agc_disable = 0; - } else if (std & V4L2_STD_PAL_N) { - dprintk(DBGLVL_API, " PAL-N\n"); - saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ - agc_disable = 0; - } else if (std & V4L2_STD_PAL_Nc) { - dprintk(DBGLVL_API, " PAL-Nc\n"); - saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ - agc_disable = 0; - } else if (std & V4L2_STD_PAL_B) { - dprintk(DBGLVL_API, " PAL-B\n"); - saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */ - agc_disable = 0; - } else if (std & V4L2_STD_PAL_DK) { - dprintk(DBGLVL_API, " PAL-DK\n"); - saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */ - agc_disable = 0; - } else if (std & V4L2_STD_SECAM_L) { - dprintk(DBGLVL_API, " SECAM-L\n"); - saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */ - agc_disable = 0; - } else { - /* Unknown standard, assume DTV */ - dprintk(DBGLVL_API, " Unknown (assuming DTV)\n"); - /* Undefinded Video Standard */ - saa7164_api_set_dif(port, 0x00, 0x80); - agc_disable = 1; - } - - saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */ - saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */ - saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */ - saa7164_api_set_dif(port, 0x04, 0x01); /* Active */ - msleep(100); - saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */ - msleep(100); - - return ret; -} - -/* Ensure the dif is in the correct state for the operating mode - * (analog / dtv). We only configure the diff through the analog encoder - * so when we're in digital mode we need to find the appropriate encoder - * and use it to configure the DIF. - */ -int saa7164_api_initialize_dif(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_port *p = NULL; - int ret = -EINVAL; - u32 std = 0; - - dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__, - port->nr, port->type); - - if (port->type == SAA7164_MPEG_ENCODER) { - /* Pick any analog standard to init the diff. - * we'll come back during encoder_init' - * and set the correct standard if requried. - */ - std = V4L2_STD_NTSC; - } else - if (port->type == SAA7164_MPEG_DVB) { - if (port->nr == SAA7164_PORT_TS1) - p = &dev->ports[SAA7164_PORT_ENC1]; - else - p = &dev->ports[SAA7164_PORT_ENC2]; - } else - if (port->type == SAA7164_MPEG_VBI) { - std = V4L2_STD_NTSC; - if (port->nr == SAA7164_PORT_VBI1) - p = &dev->ports[SAA7164_PORT_ENC1]; - else - p = &dev->ports[SAA7164_PORT_ENC2]; - } else - BUG(); - - if (p) - ret = saa7164_api_configure_dif(p, std); - - return ret; -} - -int saa7164_api_transition_port(struct saa7164_port *port, u8 mode) -{ - struct saa7164_dev *dev = port->dev; - - int ret; - - dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n", - __func__, port->nr, port->hwcfg.unitid, mode); - - ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR, - SAA_STATE_CONTROL, sizeof(mode), &mode); - if (ret != SAA_OK) - printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n", - __func__, port->nr, port->hwcfg.unitid, ret); - - return ret; -} - -int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version) -{ - int ret; - - ret = saa7164_cmd_send(dev, 0, GET_CUR, - GET_FW_VERSION_CONTROL, sizeof(u32), version); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - return ret; -} - -int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen) -{ - u8 reg[] = { 0x0f, 0x00 }; - - if (buflen < 128) - return -ENOMEM; - - /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */ - /* TODO: Pull the details from the boards struct */ - return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg), - ®[0], 128, buf); -} - -int saa7164_api_configure_port_vbi(struct saa7164_dev *dev, - struct saa7164_port *port) -{ - struct tmComResVBIFormatDescrHeader *fmt = &port->vbi_fmt_ntsc; - - dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex); - dprintk(DBGLVL_API, " VideoStandard = 0x%x\n", fmt->VideoStandard); - dprintk(DBGLVL_API, " StartLine = %d\n", fmt->StartLine); - dprintk(DBGLVL_API, " EndLine = %d\n", fmt->EndLine); - dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate); - dprintk(DBGLVL_API, " bNumLines = %d\n", fmt->bNumLines); - - /* Cache the hardware configuration in the port */ - - port->bufcounter = port->hwcfg.BARLocation; - port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32)); - port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32)); - port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32)); - port->bufptr32l = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32); - port->bufptr32h = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount); - port->bufptr64 = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount); - dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n", - port->hwcfg.BARLocation); - - dprintk(DBGLVL_API, " = VS_FORMAT_VBI (becomes dev->en[%d])\n", - port->nr); - - return 0; -} - -int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev, - struct saa7164_port *port, - struct tmComResTSFormatDescrHeader *tsfmt) -{ - dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex); - dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset); - dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength); - dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength); - dprintk(DBGLVL_API, " bguid = (....)\n"); - - /* Cache the hardware configuration in the port */ - - port->bufcounter = port->hwcfg.BARLocation; - port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32)); - port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32)); - port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32)); - port->bufptr32l = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32); - port->bufptr32h = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount); - port->bufptr64 = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount); - dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n", - port->hwcfg.BARLocation); - - dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n", - port->nr); - - return 0; -} - -int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev, - struct saa7164_port *port, - struct tmComResPSFormatDescrHeader *fmt) -{ - dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex); - dprintk(DBGLVL_API, " wPacketLength= 0x%x\n", fmt->wPacketLength); - dprintk(DBGLVL_API, " wPackLength= 0x%x\n", fmt->wPackLength); - dprintk(DBGLVL_API, " bPackDataType= 0x%x\n", fmt->bPackDataType); - - /* Cache the hardware configuration in the port */ - /* TODO: CHECK THIS in the port config */ - port->bufcounter = port->hwcfg.BARLocation; - port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32)); - port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32)); - port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32)); - port->bufptr32l = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32); - port->bufptr32h = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount); - port->bufptr64 = port->hwcfg.BARLocation + - (4 * sizeof(u32)) + - (sizeof(u32) * port->hwcfg.buffercount); - dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n", - port->hwcfg.BARLocation); - - dprintk(DBGLVL_API, " = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n", - port->nr); - - return 0; -} - -int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) -{ - struct saa7164_port *tsport = NULL; - struct saa7164_port *encport = NULL; - struct saa7164_port *vbiport = NULL; - u32 idx, next_offset; - int i; - struct tmComResDescrHeader *hdr, *t; - struct tmComResExtDevDescrHeader *exthdr; - struct tmComResPathDescrHeader *pathhdr; - struct tmComResAntTermDescrHeader *anttermhdr; - struct tmComResTunerDescrHeader *tunerunithdr; - struct tmComResDMATermDescrHeader *vcoutputtermhdr; - struct tmComResTSFormatDescrHeader *tsfmt; - struct tmComResPSFormatDescrHeader *psfmt; - struct tmComResSelDescrHeader *psel; - struct tmComResProcDescrHeader *pdh; - struct tmComResAFeatureDescrHeader *afd; - struct tmComResEncoderDescrHeader *edh; - struct tmComResVBIFormatDescrHeader *vbifmt; - u32 currpath = 0; - - dprintk(DBGLVL_API, - "%s(?,?,%d) sizeof(struct tmComResDescrHeader) = %d bytes\n", - __func__, len, (u32)sizeof(struct tmComResDescrHeader)); - - for (idx = 0; idx < (len - sizeof(struct tmComResDescrHeader));) { - - hdr = (struct tmComResDescrHeader *)(buf + idx); - - if (hdr->type != CS_INTERFACE) - return SAA_ERR_NOT_SUPPORTED; - - dprintk(DBGLVL_API, "@ 0x%x =\n", idx); - switch (hdr->subtype) { - case GENERAL_REQUEST: - dprintk(DBGLVL_API, " GENERAL_REQUEST\n"); - break; - case VC_TUNER_PATH: - dprintk(DBGLVL_API, " VC_TUNER_PATH\n"); - pathhdr = (struct tmComResPathDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " pathid = 0x%x\n", - pathhdr->pathid); - currpath = pathhdr->pathid; - break; - case VC_INPUT_TERMINAL: - dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n"); - anttermhdr = - (struct tmComResAntTermDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " terminalid = 0x%x\n", - anttermhdr->terminalid); - dprintk(DBGLVL_API, " terminaltype = 0x%x\n", - anttermhdr->terminaltype); - switch (anttermhdr->terminaltype) { - case ITT_ANTENNA: - dprintk(DBGLVL_API, " = ITT_ANTENNA\n"); - break; - case LINE_CONNECTOR: - dprintk(DBGLVL_API, " = LINE_CONNECTOR\n"); - break; - case SPDIF_CONNECTOR: - dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n"); - break; - case COMPOSITE_CONNECTOR: - dprintk(DBGLVL_API, - " = COMPOSITE_CONNECTOR\n"); - break; - case SVIDEO_CONNECTOR: - dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n"); - break; - case COMPONENT_CONNECTOR: - dprintk(DBGLVL_API, - " = COMPONENT_CONNECTOR\n"); - break; - case STANDARD_DMA: - dprintk(DBGLVL_API, " = STANDARD_DMA\n"); - break; - default: - dprintk(DBGLVL_API, " = undefined (0x%x)\n", - anttermhdr->terminaltype); - } - dprintk(DBGLVL_API, " assocterminal= 0x%x\n", - anttermhdr->assocterminal); - dprintk(DBGLVL_API, " iterminal = 0x%x\n", - anttermhdr->iterminal); - dprintk(DBGLVL_API, " controlsize = 0x%x\n", - anttermhdr->controlsize); - break; - case VC_OUTPUT_TERMINAL: - dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n"); - vcoutputtermhdr = - (struct tmComResDMATermDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " unitid = 0x%x\n", - vcoutputtermhdr->unitid); - dprintk(DBGLVL_API, " terminaltype = 0x%x\n", - vcoutputtermhdr->terminaltype); - switch (vcoutputtermhdr->terminaltype) { - case ITT_ANTENNA: - dprintk(DBGLVL_API, " = ITT_ANTENNA\n"); - break; - case LINE_CONNECTOR: - dprintk(DBGLVL_API, " = LINE_CONNECTOR\n"); - break; - case SPDIF_CONNECTOR: - dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n"); - break; - case COMPOSITE_CONNECTOR: - dprintk(DBGLVL_API, - " = COMPOSITE_CONNECTOR\n"); - break; - case SVIDEO_CONNECTOR: - dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n"); - break; - case COMPONENT_CONNECTOR: - dprintk(DBGLVL_API, - " = COMPONENT_CONNECTOR\n"); - break; - case STANDARD_DMA: - dprintk(DBGLVL_API, " = STANDARD_DMA\n"); - break; - default: - dprintk(DBGLVL_API, " = undefined (0x%x)\n", - vcoutputtermhdr->terminaltype); - } - dprintk(DBGLVL_API, " assocterminal= 0x%x\n", - vcoutputtermhdr->assocterminal); - dprintk(DBGLVL_API, " sourceid = 0x%x\n", - vcoutputtermhdr->sourceid); - dprintk(DBGLVL_API, " iterminal = 0x%x\n", - vcoutputtermhdr->iterminal); - dprintk(DBGLVL_API, " BARLocation = 0x%x\n", - vcoutputtermhdr->BARLocation); - dprintk(DBGLVL_API, " flags = 0x%x\n", - vcoutputtermhdr->flags); - dprintk(DBGLVL_API, " interruptid = 0x%x\n", - vcoutputtermhdr->interruptid); - dprintk(DBGLVL_API, " buffercount = 0x%x\n", - vcoutputtermhdr->buffercount); - dprintk(DBGLVL_API, " metadatasize = 0x%x\n", - vcoutputtermhdr->metadatasize); - dprintk(DBGLVL_API, " controlsize = 0x%x\n", - vcoutputtermhdr->controlsize); - dprintk(DBGLVL_API, " numformats = 0x%x\n", - vcoutputtermhdr->numformats); - - t = (struct tmComResDescrHeader *) - ((struct tmComResDMATermDescrHeader *)(buf + idx)); - next_offset = idx + (vcoutputtermhdr->len); - for (i = 0; i < vcoutputtermhdr->numformats; i++) { - t = (struct tmComResDescrHeader *) - (buf + next_offset); - switch (t->subtype) { - case VS_FORMAT_MPEG2TS: - tsfmt = - (struct tmComResTSFormatDescrHeader *)t; - if (currpath == 1) - tsport = &dev->ports[SAA7164_PORT_TS1]; - else - tsport = &dev->ports[SAA7164_PORT_TS2]; - memcpy(&tsport->hwcfg, vcoutputtermhdr, - sizeof(*vcoutputtermhdr)); - saa7164_api_configure_port_mpeg2ts(dev, - tsport, tsfmt); - break; - case VS_FORMAT_MPEG2PS: - psfmt = - (struct tmComResPSFormatDescrHeader *)t; - if (currpath == 1) - encport = &dev->ports[SAA7164_PORT_ENC1]; - else - encport = &dev->ports[SAA7164_PORT_ENC2]; - memcpy(&encport->hwcfg, vcoutputtermhdr, - sizeof(*vcoutputtermhdr)); - saa7164_api_configure_port_mpeg2ps(dev, - encport, psfmt); - break; - case VS_FORMAT_VBI: - vbifmt = - (struct tmComResVBIFormatDescrHeader *)t; - if (currpath == 1) - vbiport = &dev->ports[SAA7164_PORT_VBI1]; - else - vbiport = &dev->ports[SAA7164_PORT_VBI2]; - memcpy(&vbiport->hwcfg, vcoutputtermhdr, - sizeof(*vcoutputtermhdr)); - memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, - sizeof(*vbifmt)); - saa7164_api_configure_port_vbi(dev, - vbiport); - break; - case VS_FORMAT_RDS: - dprintk(DBGLVL_API, - " = VS_FORMAT_RDS\n"); - break; - case VS_FORMAT_UNCOMPRESSED: - dprintk(DBGLVL_API, - " = VS_FORMAT_UNCOMPRESSED\n"); - break; - case VS_FORMAT_TYPE: - dprintk(DBGLVL_API, - " = VS_FORMAT_TYPE\n"); - break; - default: - dprintk(DBGLVL_API, - " = undefined (0x%x)\n", - t->subtype); - } - next_offset += t->len; - } - - break; - case TUNER_UNIT: - dprintk(DBGLVL_API, " TUNER_UNIT\n"); - tunerunithdr = - (struct tmComResTunerDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " unitid = 0x%x\n", - tunerunithdr->unitid); - dprintk(DBGLVL_API, " sourceid = 0x%x\n", - tunerunithdr->sourceid); - dprintk(DBGLVL_API, " iunit = 0x%x\n", - tunerunithdr->iunit); - dprintk(DBGLVL_API, " tuningstandards = 0x%x\n", - tunerunithdr->tuningstandards); - dprintk(DBGLVL_API, " controlsize = 0x%x\n", - tunerunithdr->controlsize); - dprintk(DBGLVL_API, " controls = 0x%x\n", - tunerunithdr->controls); - - if (tunerunithdr->unitid == tunerunithdr->iunit) { - if (currpath == 1) - encport = &dev->ports[SAA7164_PORT_ENC1]; - else - encport = &dev->ports[SAA7164_PORT_ENC2]; - memcpy(&encport->tunerunit, tunerunithdr, - sizeof(struct tmComResTunerDescrHeader)); - dprintk(DBGLVL_API, - " (becomes dev->enc[%d] tuner)\n", - encport->nr); - } - break; - case VC_SELECTOR_UNIT: - psel = (struct tmComResSelDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n"); - dprintk(DBGLVL_API, " unitid = 0x%x\n", - psel->unitid); - dprintk(DBGLVL_API, " nrinpins = 0x%x\n", - psel->nrinpins); - dprintk(DBGLVL_API, " sourceid = 0x%x\n", - psel->sourceid); - break; - case VC_PROCESSING_UNIT: - pdh = (struct tmComResProcDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n"); - dprintk(DBGLVL_API, " unitid = 0x%x\n", - pdh->unitid); - dprintk(DBGLVL_API, " sourceid = 0x%x\n", - pdh->sourceid); - dprintk(DBGLVL_API, " controlsize = 0x%x\n", - pdh->controlsize); - if (pdh->controlsize == 0x04) { - if (currpath == 1) - encport = &dev->ports[SAA7164_PORT_ENC1]; - else - encport = &dev->ports[SAA7164_PORT_ENC2]; - memcpy(&encport->vidproc, pdh, - sizeof(struct tmComResProcDescrHeader)); - dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", - encport->nr); - } - break; - case FEATURE_UNIT: - afd = (struct tmComResAFeatureDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " FEATURE_UNIT\n"); - dprintk(DBGLVL_API, " unitid = 0x%x\n", - afd->unitid); - dprintk(DBGLVL_API, " sourceid = 0x%x\n", - afd->sourceid); - dprintk(DBGLVL_API, " controlsize = 0x%x\n", - afd->controlsize); - if (currpath == 1) - encport = &dev->ports[SAA7164_PORT_ENC1]; - else - encport = &dev->ports[SAA7164_PORT_ENC2]; - memcpy(&encport->audfeat, afd, - sizeof(struct tmComResAFeatureDescrHeader)); - dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", - encport->nr); - break; - case ENCODER_UNIT: - edh = (struct tmComResEncoderDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " ENCODER_UNIT\n"); - dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype); - dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid); - dprintk(DBGLVL_API, " vsourceid = 0x%x\n", - edh->vsourceid); - dprintk(DBGLVL_API, " asourceid = 0x%x\n", - edh->asourceid); - dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit); - if (edh->iunit == edh->unitid) { - if (currpath == 1) - encport = &dev->ports[SAA7164_PORT_ENC1]; - else - encport = &dev->ports[SAA7164_PORT_ENC2]; - memcpy(&encport->encunit, edh, - sizeof(struct tmComResEncoderDescrHeader)); - dprintk(DBGLVL_API, - " (becomes dev->enc[%d])\n", - encport->nr); - } - break; - case EXTENSION_UNIT: - dprintk(DBGLVL_API, " EXTENSION_UNIT\n"); - exthdr = (struct tmComResExtDevDescrHeader *)(buf + idx); - dprintk(DBGLVL_API, " unitid = 0x%x\n", - exthdr->unitid); - dprintk(DBGLVL_API, " deviceid = 0x%x\n", - exthdr->deviceid); - dprintk(DBGLVL_API, " devicetype = 0x%x\n", - exthdr->devicetype); - if (exthdr->devicetype & 0x1) - dprintk(DBGLVL_API, " = Decoder Device\n"); - if (exthdr->devicetype & 0x2) - dprintk(DBGLVL_API, " = GPIO Source\n"); - if (exthdr->devicetype & 0x4) - dprintk(DBGLVL_API, " = Video Decoder\n"); - if (exthdr->devicetype & 0x8) - dprintk(DBGLVL_API, " = Audio Decoder\n"); - if (exthdr->devicetype & 0x20) - dprintk(DBGLVL_API, " = Crossbar\n"); - if (exthdr->devicetype & 0x40) - dprintk(DBGLVL_API, " = Tuner\n"); - if (exthdr->devicetype & 0x80) - dprintk(DBGLVL_API, " = IF PLL\n"); - if (exthdr->devicetype & 0x100) - dprintk(DBGLVL_API, " = Demodulator\n"); - if (exthdr->devicetype & 0x200) - dprintk(DBGLVL_API, " = RDS Decoder\n"); - if (exthdr->devicetype & 0x400) - dprintk(DBGLVL_API, " = Encoder\n"); - if (exthdr->devicetype & 0x800) - dprintk(DBGLVL_API, " = IR Decoder\n"); - if (exthdr->devicetype & 0x1000) - dprintk(DBGLVL_API, " = EEPROM\n"); - if (exthdr->devicetype & 0x2000) - dprintk(DBGLVL_API, - " = VBI Decoder\n"); - if (exthdr->devicetype & 0x10000) - dprintk(DBGLVL_API, - " = Streaming Device\n"); - if (exthdr->devicetype & 0x20000) - dprintk(DBGLVL_API, - " = DRM Device\n"); - if (exthdr->devicetype & 0x40000000) - dprintk(DBGLVL_API, - " = Generic Device\n"); - if (exthdr->devicetype & 0x80000000) - dprintk(DBGLVL_API, - " = Config Space Device\n"); - dprintk(DBGLVL_API, " numgpiopins = 0x%x\n", - exthdr->numgpiopins); - dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n", - exthdr->numgpiogroups); - dprintk(DBGLVL_API, " controlsize = 0x%x\n", - exthdr->controlsize); - if (exthdr->devicetype & 0x80) { - if (currpath == 1) - encport = &dev->ports[SAA7164_PORT_ENC1]; - else - encport = &dev->ports[SAA7164_PORT_ENC2]; - memcpy(&encport->ifunit, exthdr, - sizeof(struct tmComResExtDevDescrHeader)); - dprintk(DBGLVL_API, - " (becomes dev->enc[%d])\n", - encport->nr); - } - break; - case PVC_INFRARED_UNIT: - dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n"); - break; - case DRM_UNIT: - dprintk(DBGLVL_API, " DRM_UNIT\n"); - break; - default: - dprintk(DBGLVL_API, "default %d\n", hdr->subtype); - } - - dprintk(DBGLVL_API, " 1.%x\n", hdr->len); - dprintk(DBGLVL_API, " 2.%x\n", hdr->type); - dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype); - dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid); - - idx += hdr->len; - } - - return 0; -} - -int saa7164_api_enum_subdevs(struct saa7164_dev *dev) -{ - int ret; - u32 buflen = 0; - u8 *buf; - - dprintk(DBGLVL_API, "%s()\n", __func__); - - /* Get the total descriptor length */ - ret = saa7164_cmd_send(dev, 0, GET_LEN, - GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - - dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n", - __func__, buflen); - - /* Allocate enough storage for all of the descs */ - buf = kzalloc(buflen, GFP_KERNEL); - if (!buf) - return SAA_ERR_NO_RESOURCES; - - /* Retrieve them */ - ret = saa7164_cmd_send(dev, 0, GET_CUR, - GET_DESCRIPTORS_CONTROL, buflen, buf); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); - goto out; - } - - if (saa_debug & DBGLVL_API) - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, - buflen & ~15, false); - - saa7164_api_dump_subdevs(dev, buf, buflen); - -out: - kfree(buf); - return ret; -} - -int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, - u32 datalen, u8 *data) -{ - struct saa7164_dev *dev = bus->dev; - u16 len = 0; - int unitid; - u8 buf[256]; - int ret; - - dprintk(DBGLVL_API, "%s()\n", __func__); - - if (reglen > 4) - return -EIO; - - /* Prepare the send buffer */ - /* Bytes 00-03 source register length - * 04-07 source bytes to read - * 08... register address - */ - memset(buf, 0, sizeof(buf)); - memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen); - *((u32 *)(buf + 0 * sizeof(u32))) = reglen; - *((u32 *)(buf + 1 * sizeof(u32))) = datalen; - - unitid = saa7164_i2caddr_to_unitid(bus, addr); - if (unitid < 0) { - printk(KERN_ERR - "%s() error, cannot translate regaddr 0x%x to unitid\n", - __func__, addr); - return -EIO; - } - - ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN, - EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret); - return -EIO; - } - - dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len); - - if (saa_debug & DBGLVL_I2C) - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, - 32, false); - - ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR, - EXU_REGISTER_ACCESS_CONTROL, len, &buf); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); - else { - if (saa_debug & DBGLVL_I2C) - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, - buf, sizeof(buf), false); - memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen); - } - - return ret == SAA_OK ? 0 : -EIO; -} - -/* For a given 8 bit i2c address device, write the buffer */ -int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen, - u8 *data) -{ - struct saa7164_dev *dev = bus->dev; - u16 len = 0; - int unitid; - int reglen; - u8 buf[256]; - int ret; - - dprintk(DBGLVL_API, "%s()\n", __func__); - - if ((datalen == 0) || (datalen > 232)) - return -EIO; - - memset(buf, 0, sizeof(buf)); - - unitid = saa7164_i2caddr_to_unitid(bus, addr); - if (unitid < 0) { - printk(KERN_ERR - "%s() error, cannot translate regaddr 0x%x to unitid\n", - __func__, addr); - return -EIO; - } - - reglen = saa7164_i2caddr_to_reglen(bus, addr); - if (reglen < 0) { - printk(KERN_ERR - "%s() error, cannot translate regaddr to reglen\n", - __func__); - return -EIO; - } - - ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN, - EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret); - return -EIO; - } - - dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len); - - /* Prepare the send buffer */ - /* Bytes 00-03 dest register length - * 04-07 dest bytes to write - * 08... register address - */ - *((u32 *)(buf + 0 * sizeof(u32))) = reglen; - *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen; - memcpy((buf + 2 * sizeof(u32)), data, datalen); - - if (saa_debug & DBGLVL_I2C) - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, - buf, sizeof(buf), false); - - ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR, - EXU_REGISTER_ACCESS_CONTROL, len, &buf); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); - - return ret == SAA_OK ? 0 : -EIO; -} - -int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid, - u8 pin, u8 state) -{ - int ret; - struct tmComResGPIO t; - - dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n", - __func__, unitid, pin, state); - - if ((pin > 7) || (state > 2)) - return SAA_ERR_BAD_PARAMETER; - - t.pin = pin; - t.state = state; - - ret = saa7164_cmd_send(dev, unitid, SET_CUR, - EXU_GPIO_CONTROL, sizeof(t), &t); - if (ret != SAA_OK) - printk(KERN_ERR "%s() error, ret = 0x%x\n", - __func__, ret); - - return ret; -} - -int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, - u8 pin) -{ - return saa7164_api_modify_gpio(dev, unitid, pin, 1); -} - -int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, - u8 pin) -{ - return saa7164_api_modify_gpio(dev, unitid, pin, 0); -} - diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c deleted file mode 100644 index 66696fa8341d..000000000000 --- a/drivers/media/video/saa7164/saa7164-buffer.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/slab.h> - -#include "saa7164.h" - -/* The PCI address space for buffer handling looks like this: - * - * +-u32 wide-------------+ - * | + - * +-u64 wide------------------------------------+ - * + + - * +----------------------+ - * | CurrentBufferPtr + Pointer to current PCI buffer >-+ - * +----------------------+ | - * | Unused + | - * +----------------------+ | - * | Pitch + = 188 (bytes) | - * +----------------------+ | - * | PCI buffer size + = pitch * number of lines (312) | - * +----------------------+ | - * |0| Buf0 Write Offset + | - * +----------------------+ v - * |1| Buf1 Write Offset + | - * +----------------------+ | - * |2| Buf2 Write Offset + | - * +----------------------+ | - * |3| Buf3 Write Offset + | - * +----------------------+ | - * ... More write offsets | - * +---------------------------------------------+ | - * +0| set of ptrs to PCI pagetables + | - * +---------------------------------------------+ | - * +1| set of ptrs to PCI pagetables + <--------+ - * +---------------------------------------------+ - * +2| set of ptrs to PCI pagetables + - * +---------------------------------------------+ - * +3| set of ptrs to PCI pagetables + >--+ - * +---------------------------------------------+ | - * ... More buffer pointers | +----------------+ - * +->| pt[0] TS data | - * | +----------------+ - * | - * | +----------------+ - * +->| pt[1] TS data | - * | +----------------+ - * | etc - */ - -void saa7164_buffer_display(struct saa7164_buffer *buf) -{ - struct saa7164_dev *dev = buf->port->dev; - int i; - - dprintk(DBGLVL_BUF, "%s() buffer @ 0x%p nr=%d\n", - __func__, buf, buf->idx); - dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08llx len = 0x%x\n", - buf->cpu, (long long)buf->dma, buf->pci_size); - dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08llx len = 0x%x\n", - buf->pt_cpu, (long long)buf->pt_dma, buf->pt_size); - - /* Format the Page Table Entries to point into the data buffer */ - for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) { - - dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n", - i, buf->pt_cpu, (u64)*(buf->pt_cpu)); - - } -} -/* Allocate a new buffer structure and associated PCI space in bytes. - * len must be a multiple of sizeof(u64) - */ -struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port, - u32 len) -{ - struct tmHWStreamParameters *params = &port->hw_streamingparams; - struct saa7164_buffer *buf = NULL; - struct saa7164_dev *dev = port->dev; - int i; - - if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) { - log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__); - goto ret; - } - - buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL); - if (!buf) { - log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__); - goto ret; - } - - buf->idx = -1; - buf->port = port; - buf->flags = SAA7164_BUFFER_FREE; - buf->pos = 0; - buf->actual_size = params->pitch * params->numberoflines; - buf->crc = 0; - /* TODO: arg len is being ignored */ - buf->pci_size = SAA7164_PT_ENTRIES * 0x1000; - buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000; - - /* Allocate contiguous memory */ - buf->cpu = pci_alloc_consistent(port->dev->pci, buf->pci_size, - &buf->dma); - if (!buf->cpu) - goto fail1; - - buf->pt_cpu = pci_alloc_consistent(port->dev->pci, buf->pt_size, - &buf->pt_dma); - if (!buf->pt_cpu) - goto fail2; - - /* init the buffers to a known pattern, easier during debugging */ - memset_io(buf->cpu, 0xff, buf->pci_size); - buf->crc = crc32(0, buf->cpu, buf->actual_size); - memset_io(buf->pt_cpu, 0xff, buf->pt_size); - - dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n", - __func__, buf, params->numpagetables); - dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n", - buf->cpu, (long)buf->dma, buf->pci_size); - dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n", - buf->pt_cpu, (long)buf->pt_dma, buf->pt_size); - - /* Format the Page Table Entries to point into the data buffer */ - for (i = 0 ; i < params->numpagetables; i++) { - - *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */ - dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n", - i, buf->pt_cpu, (u64)*(buf->pt_cpu)); - - } - - goto ret; - -fail2: - pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma); -fail1: - kfree(buf); - - buf = NULL; -ret: - return buf; -} - -int saa7164_buffer_dealloc(struct saa7164_buffer *buf) -{ - struct saa7164_dev *dev; - - if (!buf || !buf->port) - return SAA_ERR_BAD_PARAMETER; - dev = buf->port->dev; - - dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", - __func__, buf); - - if (buf->flags != SAA7164_BUFFER_FREE) - log_warn(" freeing a non-free buffer\n"); - - pci_free_consistent(dev->pci, buf->pci_size, buf->cpu, buf->dma); - pci_free_consistent(dev->pci, buf->pt_size, buf->pt_cpu, buf->pt_dma); - - kfree(buf); - - return SAA_OK; -} - -int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i) -{ - struct saa7164_dev *dev = port->dev; - - if ((i < 0) || (i >= port->hwcfg.buffercount)) - return -EINVAL; - - dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i); - - saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0); - - return 0; -} - -/* Write a buffer into the hardware */ -int saa7164_buffer_activate(struct saa7164_buffer *buf, int i) -{ - struct saa7164_port *port = buf->port; - struct saa7164_dev *dev = port->dev; - - if ((i < 0) || (i >= port->hwcfg.buffercount)) - return -EINVAL; - - dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i); - - buf->idx = i; /* Note of which buffer list index position we occupy */ - buf->flags = SAA7164_BUFFER_BUSY; - buf->pos = 0; - - /* TODO: Review this in light of 32v64 assignments */ - saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0); - saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma); - saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0); - - dprintk(DBGLVL_BUF, " buf[%d] offset 0x%llx (0x%x) " - "buf 0x%llx/%llx (0x%x/%x) nr=%d\n", - buf->idx, - (u64)port->bufoffset + (i * sizeof(u32)), - saa7164_readl(port->bufoffset + (sizeof(u32) * i)), - (u64)port->bufptr32h + ((sizeof(u32) * 2) * i), - (u64)port->bufptr32l + ((sizeof(u32) * 2) * i), - saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) * 2)), - saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) * 2)), - buf->idx); - - return 0; -} - -int saa7164_buffer_cfg_port(struct saa7164_port *port) -{ - struct tmHWStreamParameters *params = &port->hw_streamingparams; - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct list_head *c, *n; - int i = 0; - - dprintk(DBGLVL_BUF, "%s(port=%d)\n", __func__, port->nr); - - saa7164_writel(port->bufcounter, 0); - saa7164_writel(port->pitch, params->pitch); - saa7164_writel(port->bufsize, params->pitch * params->numberoflines); - - dprintk(DBGLVL_BUF, " configured:\n"); - dprintk(DBGLVL_BUF, " lmmio 0x%p\n", dev->lmmio); - dprintk(DBGLVL_BUF, " bufcounter 0x%x = 0x%x\n", port->bufcounter, - saa7164_readl(port->bufcounter)); - - dprintk(DBGLVL_BUF, " pitch 0x%x = %d\n", port->pitch, - saa7164_readl(port->pitch)); - - dprintk(DBGLVL_BUF, " bufsize 0x%x = %d\n", port->bufsize, - saa7164_readl(port->bufsize)); - - dprintk(DBGLVL_BUF, " buffercount = %d\n", port->hwcfg.buffercount); - dprintk(DBGLVL_BUF, " bufoffset = 0x%x\n", port->bufoffset); - dprintk(DBGLVL_BUF, " bufptr32h = 0x%x\n", port->bufptr32h); - dprintk(DBGLVL_BUF, " bufptr32l = 0x%x\n", port->bufptr32l); - - /* Poke the buffers and offsets into PCI space */ - mutex_lock(&port->dmaqueue_lock); - list_for_each_safe(c, n, &port->dmaqueue.list) { - buf = list_entry(c, struct saa7164_buffer, list); - - if (buf->flags != SAA7164_BUFFER_FREE) - BUG(); - - /* Place the buffer in the h/w queue */ - saa7164_buffer_activate(buf, i); - - /* Don't exceed the device maximum # bufs */ - if (i++ > port->hwcfg.buffercount) - BUG(); - - } - mutex_unlock(&port->dmaqueue_lock); - - return 0; -} - -struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, - u32 len) -{ - struct saa7164_user_buffer *buf; - - buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL); - if (!buf) - return NULL; - - buf->data = kzalloc(len, GFP_KERNEL); - - if (!buf->data) { - kfree(buf); - return NULL; - } - - buf->actual_size = len; - buf->pos = 0; - buf->crc = 0; - - dprintk(DBGLVL_BUF, "%s() allocated user buffer @ 0x%p\n", - __func__, buf); - - return buf; -} - -void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf) -{ - if (!buf) - return; - - kfree(buf->data); - buf->data = NULL; - - kfree(buf); -} - diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c deleted file mode 100644 index a7f58a998752..000000000000 --- a/drivers/media/video/saa7164/saa7164-bus.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "saa7164.h" - -/* The message bus to/from the firmware is a ring buffer in PCI address - * space. Establish the defaults. - */ -int saa7164_bus_setup(struct saa7164_dev *dev) -{ - struct tmComResBusInfo *b = &dev->bus; - - mutex_init(&b->lock); - - b->Type = TYPE_BUS_PCIe; - b->m_wMaxReqSize = SAA_DEVICE_MAXREQUESTSIZE; - - b->m_pdwSetRing = (u8 *)(dev->bmmio + - ((u32)dev->busdesc.CommandRing)); - - b->m_dwSizeSetRing = SAA_DEVICE_BUFFERBLOCKSIZE; - - b->m_pdwGetRing = (u8 *)(dev->bmmio + - ((u32)dev->busdesc.ResponseRing)); - - b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE; - - b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) + - (2 * sizeof(u64)); - b->m_dwSetReadPos = b->m_dwSetWritePos + (1 * sizeof(u32)); - - b->m_dwGetWritePos = b->m_dwSetWritePos + (2 * sizeof(u32)); - b->m_dwGetReadPos = b->m_dwSetWritePos + (3 * sizeof(u32)); - - return 0; -} - -void saa7164_bus_dump(struct saa7164_dev *dev) -{ - struct tmComResBusInfo *b = &dev->bus; - - dprintk(DBGLVL_BUS, "Dumping the bus structure:\n"); - dprintk(DBGLVL_BUS, " .type = %d\n", b->Type); - dprintk(DBGLVL_BUS, " .dev->bmmio = 0x%p\n", dev->bmmio); - dprintk(DBGLVL_BUS, " .m_wMaxReqSize = 0x%x\n", b->m_wMaxReqSize); - dprintk(DBGLVL_BUS, " .m_pdwSetRing = 0x%p\n", b->m_pdwSetRing); - dprintk(DBGLVL_BUS, " .m_dwSizeSetRing = 0x%x\n", b->m_dwSizeSetRing); - dprintk(DBGLVL_BUS, " .m_pdwGetRing = 0x%p\n", b->m_pdwGetRing); - dprintk(DBGLVL_BUS, " .m_dwSizeGetRing = 0x%x\n", b->m_dwSizeGetRing); - - dprintk(DBGLVL_BUS, " .m_dwSetReadPos = 0x%x (0x%08x)\n", - b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos)); - - dprintk(DBGLVL_BUS, " .m_dwSetWritePos = 0x%x (0x%08x)\n", - b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos)); - - dprintk(DBGLVL_BUS, " .m_dwGetReadPos = 0x%x (0x%08x)\n", - b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos)); - - dprintk(DBGLVL_BUS, " .m_dwGetWritePos = 0x%x (0x%08x)\n", - b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos)); - -} - -/* Intensionally throw a BUG() if the state of the message bus looks corrupt */ -void saa7164_bus_verify(struct saa7164_dev *dev) -{ - struct tmComResBusInfo *b = &dev->bus; - int bug = 0; - - if (saa7164_readl(b->m_dwSetReadPos) > b->m_dwSizeSetRing) - bug++; - - if (saa7164_readl(b->m_dwSetWritePos) > b->m_dwSizeSetRing) - bug++; - - if (saa7164_readl(b->m_dwGetReadPos) > b->m_dwSizeGetRing) - bug++; - - if (saa7164_readl(b->m_dwGetWritePos) > b->m_dwSizeGetRing) - bug++; - - if (bug) { - saa_debug = 0xffff; /* Ensure we get the bus dump */ - saa7164_bus_dump(dev); - saa_debug = 1024; /* Ensure we get the bus dump */ - BUG(); - } -} - -void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, - void *buf) -{ - dprintk(DBGLVL_BUS, "Dumping msg structure:\n"); - dprintk(DBGLVL_BUS, " .id = %d\n", m->id); - dprintk(DBGLVL_BUS, " .flags = 0x%x\n", m->flags); - dprintk(DBGLVL_BUS, " .size = 0x%x\n", m->size); - dprintk(DBGLVL_BUS, " .command = 0x%x\n", m->command); - dprintk(DBGLVL_BUS, " .controlselector = 0x%x\n", m->controlselector); - dprintk(DBGLVL_BUS, " .seqno = %d\n", m->seqno); - if (buf) - dprintk(DBGLVL_BUS, " .buffer (ignored)\n"); -} - -/* - * Places a command or a response on the bus. The implementation does not - * know if it is a command or a response it just places the data on the - * bus depending on the bus information given in the struct tmComResBusInfo - * structure. If the command or response does not fit into the bus ring - * buffer it will be refused. - * - * Return Value: - * SAA_OK The function executed successfully. - * < 0 One or more members are not initialized. - */ -int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, - void *buf) -{ - struct tmComResBusInfo *bus = &dev->bus; - u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp; - u32 new_swp, space_rem; - int ret = SAA_ERR_BAD_PARAMETER; - - if (!msg) { - printk(KERN_ERR "%s() !msg\n", __func__); - return SAA_ERR_BAD_PARAMETER; - } - - dprintk(DBGLVL_BUS, "%s()\n", __func__); - - saa7164_bus_verify(dev); - - msg->size = cpu_to_le16(msg->size); - msg->command = cpu_to_le32(msg->command); - msg->controlselector = cpu_to_le16(msg->controlselector); - - if (msg->size > dev->bus.m_wMaxReqSize) { - printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n", - __func__); - return SAA_ERR_BAD_PARAMETER; - } - - if ((msg->size > 0) && (buf == NULL)) { - printk(KERN_ERR "%s() Missing message buffer\n", __func__); - return SAA_ERR_BAD_PARAMETER; - } - - /* Lock the bus from any other access */ - mutex_lock(&bus->lock); - - bytes_to_write = sizeof(*msg) + msg->size; - free_write_space = 0; - timeout = SAA_BUS_TIMEOUT; - curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); - curr_swp = le32_to_cpu(saa7164_readl(bus->m_dwSetWritePos)); - - /* Deal with ring wrapping issues */ - if (curr_srp > curr_swp) - /* Deal with the wrapped ring */ - free_write_space = curr_srp - curr_swp; - else - /* The ring has not wrapped yet */ - free_write_space = (curr_srp + bus->m_dwSizeSetRing) - curr_swp; - - dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__, - bytes_to_write); - - dprintk(DBGLVL_BUS, "%s() free_write_space = %d\n", __func__, - free_write_space); - - dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp); - dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp); - - /* Process the msg and write the content onto the bus */ - while (bytes_to_write >= free_write_space) { - - if (timeout-- == 0) { - printk(KERN_ERR "%s() bus timeout\n", __func__); - ret = SAA_ERR_NO_RESOURCES; - goto out; - } - - /* TODO: Review this delay, efficient? */ - /* Wait, allowing the hardware fetch time */ - mdelay(1); - - /* Check the space usage again */ - curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); - - /* Deal with ring wrapping issues */ - if (curr_srp > curr_swp) - /* Deal with the wrapped ring */ - free_write_space = curr_srp - curr_swp; - else - /* Read didn't wrap around the buffer */ - free_write_space = (curr_srp + bus->m_dwSizeSetRing) - - curr_swp; - - } - - /* Calculate the new write position */ - new_swp = curr_swp + bytes_to_write; - - dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp); - dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__, - bus->m_dwSizeSetRing); - - /* Mental Note: line 462 tmmhComResBusPCIe.cpp */ - - /* Check if we're going to wrap again */ - if (new_swp > bus->m_dwSizeSetRing) { - - /* Ring wraps */ - new_swp -= bus->m_dwSizeSetRing; - - space_rem = bus->m_dwSizeSetRing - curr_swp; - - dprintk(DBGLVL_BUS, "%s() space_rem = %x\n", __func__, - space_rem); - - dprintk(DBGLVL_BUS, "%s() sizeof(*msg) = %d\n", __func__, - (u32)sizeof(*msg)); - - if (space_rem < sizeof(*msg)) { - dprintk(DBGLVL_BUS, "%s() tr4\n", __func__); - - /* Split the msg into pieces as the ring wraps */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem); - memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem, - sizeof(*msg) - space_rem); - - memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem, - buf, msg->size); - - } else if (space_rem == sizeof(*msg)) { - dprintk(DBGLVL_BUS, "%s() tr5\n", __func__); - - /* Additional data at the beginning of the ring */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - memcpy(bus->m_pdwSetRing, buf, msg->size); - - } else { - /* Additional data wraps around the ring */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - if (msg->size > 0) { - memcpy(bus->m_pdwSetRing + curr_swp + - sizeof(*msg), buf, space_rem - - sizeof(*msg)); - memcpy(bus->m_pdwSetRing, (u8 *)buf + - space_rem - sizeof(*msg), - bytes_to_write - space_rem); - } - - } - - } /* (new_swp > bus->m_dwSizeSetRing) */ - else { - dprintk(DBGLVL_BUS, "%s() tr6\n", __func__); - - /* The ring buffer doesn't wrap, two simple copies */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, - msg->size); - } - - dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp); - - /* Update the bus write position */ - saa7164_writel(bus->m_dwSetWritePos, cpu_to_le32(new_swp)); - ret = SAA_OK; - -out: - saa7164_bus_dump(dev); - mutex_unlock(&bus->lock); - saa7164_bus_verify(dev); - return ret; -} - -/* - * Receive a command or a response from the bus. The implementation does not - * know if it is a command or a response it simply dequeues the data, - * depending on the bus information given in the struct tmComResBusInfo - * structure. - * - * Return Value: - * 0 The function executed successfully. - * < 0 One or more members are not initialized. - */ -int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, - void *buf, int peekonly) -{ - struct tmComResBusInfo *bus = &dev->bus; - u32 bytes_to_read, write_distance, curr_grp, curr_gwp, - new_grp, buf_size, space_rem; - struct tmComResInfo msg_tmp; - int ret = SAA_ERR_BAD_PARAMETER; - - saa7164_bus_verify(dev); - - if (msg == NULL) - return ret; - - if (msg->size > dev->bus.m_wMaxReqSize) { - printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n", - __func__); - return ret; - } - - if ((peekonly == 0) && (msg->size > 0) && (buf == NULL)) { - printk(KERN_ERR - "%s() Missing msg buf, size should be %d bytes\n", - __func__, msg->size); - return ret; - } - - mutex_lock(&bus->lock); - - /* Peek the bus to see if a msg exists, if it's not what we're expecting - * then return cleanly else read the message from the bus. - */ - curr_gwp = le32_to_cpu(saa7164_readl(bus->m_dwGetWritePos)); - curr_grp = le32_to_cpu(saa7164_readl(bus->m_dwGetReadPos)); - - if (curr_gwp == curr_grp) { - ret = SAA_ERR_EMPTY; - goto out; - } - - bytes_to_read = sizeof(*msg); - - /* Calculate write distance to current read position */ - write_distance = 0; - if (curr_gwp >= curr_grp) - /* Write doesn't wrap around the ring */ - write_distance = curr_gwp - curr_grp; - else - /* Write wraps around the ring */ - write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp; - - if (bytes_to_read > write_distance) { - printk(KERN_ERR "%s() No message/response found\n", __func__); - ret = SAA_ERR_INVALID_COMMAND; - goto out; - } - - /* Calculate the new read position */ - new_grp = curr_grp + bytes_to_read; - if (new_grp > bus->m_dwSizeGetRing) { - - /* Ring wraps */ - new_grp -= bus->m_dwSizeGetRing; - space_rem = bus->m_dwSizeGetRing - curr_grp; - - memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem); - memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing, - bytes_to_read - space_rem); - - } else { - /* No wrapping */ - memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read); - } - - /* No need to update the read positions, because this was a peek */ - /* If the caller specifically want to peek, return */ - if (peekonly) { - memcpy(msg, &msg_tmp, sizeof(*msg)); - goto peekout; - } - - /* Check if the command/response matches what is expected */ - if ((msg_tmp.id != msg->id) || (msg_tmp.command != msg->command) || - (msg_tmp.controlselector != msg->controlselector) || - (msg_tmp.seqno != msg->seqno) || (msg_tmp.size != msg->size)) { - - printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__); - saa7164_bus_dumpmsg(dev, msg, buf); - saa7164_bus_dumpmsg(dev, &msg_tmp, NULL); - ret = SAA_ERR_INVALID_COMMAND; - goto out; - } - - /* Get the actual command and response from the bus */ - buf_size = msg->size; - - bytes_to_read = sizeof(*msg) + msg->size; - /* Calculate write distance to current read position */ - write_distance = 0; - if (curr_gwp >= curr_grp) - /* Write doesn't wrap around the ring */ - write_distance = curr_gwp - curr_grp; - else - /* Write wraps around the ring */ - write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp; - - if (bytes_to_read > write_distance) { - printk(KERN_ERR "%s() Invalid bus state, missing msg " - "or mangled ring, faulty H/W / bad code?\n", __func__); - ret = SAA_ERR_INVALID_COMMAND; - goto out; - } - - /* Calculate the new read position */ - new_grp = curr_grp + bytes_to_read; - if (new_grp > bus->m_dwSizeGetRing) { - - /* Ring wraps */ - new_grp -= bus->m_dwSizeGetRing; - space_rem = bus->m_dwSizeGetRing - curr_grp; - - if (space_rem < sizeof(*msg)) { - /* msg wraps around the ring */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem); - memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing, - sizeof(*msg) - space_rem); - if (buf) - memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) - - space_rem, buf_size); - - } else if (space_rem == sizeof(*msg)) { - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); - if (buf) - memcpy(buf, bus->m_pdwGetRing, buf_size); - } else { - /* Additional data wraps around the ring */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); - if (buf) { - memcpy(buf, bus->m_pdwGetRing + curr_grp + - sizeof(*msg), space_rem - sizeof(*msg)); - memcpy(buf + space_rem - sizeof(*msg), - bus->m_pdwGetRing, bytes_to_read - - space_rem); - } - - } - - } else { - /* No wrapping */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); - if (buf) - memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), - buf_size); - } - - /* Update the read positions, adjusting the ring */ - saa7164_writel(bus->m_dwGetReadPos, cpu_to_le32(new_grp)); - -peekout: - msg->size = le16_to_cpu(msg->size); - msg->command = le32_to_cpu(msg->command); - msg->controlselector = le16_to_cpu(msg->controlselector); - ret = SAA_OK; -out: - mutex_unlock(&bus->lock); - saa7164_bus_verify(dev); - return ret; -} - diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c deleted file mode 100644 index 5b72da5ce418..000000000000 --- a/drivers/media/video/saa7164/saa7164-cards.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/delay.h> - -#include "saa7164.h" - -/* The Bridge API needs to understand register widths (in bytes) for the - * attached I2C devices, so we can simplify the virtual i2c mechansms - * and keep the -i2c.c implementation clean. - */ -#define REGLEN_8bit 1 -#define REGLEN_16bit 2 - -struct saa7164_board saa7164_boards[] = { - [SAA7164_BOARD_UNKNOWN] = { - /* Bridge will not load any firmware, without knowing - * the rev this would be fatal. */ - .name = "Unknown", - }, - [SAA7164_BOARD_UNKNOWN_REV2] = { - /* Bridge will load the v2 f/w and dump descriptors */ - /* Required during new board bringup */ - .name = "Generic Rev2", - .chiprev = SAA7164_CHIP_REV2, - }, - [SAA7164_BOARD_UNKNOWN_REV3] = { - /* Bridge will load the v2 f/w and dump descriptors */ - /* Required during new board bringup */ - .name = "Generic Rev3", - .chiprev = SAA7164_CHIP_REV3, - }, - [SAA7164_BOARD_HAUPPAUGE_HVR2200] = { - .name = "Hauppauge WinTV-HVR2200", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .portc = SAA7164_MPEG_ENCODER, - .portd = SAA7164_MPEG_ENCODER, - .porte = SAA7164_MPEG_VBI, - .portf = SAA7164_MPEG_VBI, - .chiprev = SAA7164_CHIP_REV3, - .unit = {{ - .id = 0x1d, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1b, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1e, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x10 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1f, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x12 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, - [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = { - .name = "Hauppauge WinTV-HVR2200", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .portc = SAA7164_MPEG_ENCODER, - .portd = SAA7164_MPEG_ENCODER, - .porte = SAA7164_MPEG_VBI, - .portf = SAA7164_MPEG_VBI, - .chiprev = SAA7164_CHIP_REV2, - .unit = {{ - .id = 0x06, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x05, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x10 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1e, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1f, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x12 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, - [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = { - .name = "Hauppauge WinTV-HVR2200", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .portc = SAA7164_MPEG_ENCODER, - .portd = SAA7164_MPEG_ENCODER, - .porte = SAA7164_MPEG_VBI, - .portf = SAA7164_MPEG_VBI, - .chiprev = SAA7164_CHIP_REV2, - .unit = {{ - .id = 0x1d, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x05, - .type = SAA7164_UNIT_ANALOG_DEMODULATOR, - .name = "TDA8290-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x84 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1b, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1c, - .type = SAA7164_UNIT_ANALOG_DEMODULATOR, - .name = "TDA8290-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x84 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1e, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x10 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1f, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x12 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, - [SAA7164_BOARD_HAUPPAUGE_HVR2200_4] = { - .name = "Hauppauge WinTV-HVR2200", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .portc = SAA7164_MPEG_ENCODER, - .portd = SAA7164_MPEG_ENCODER, - .porte = SAA7164_MPEG_VBI, - .portf = SAA7164_MPEG_VBI, - .chiprev = SAA7164_CHIP_REV3, - .unit = {{ - .id = 0x1d, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x05, - .type = SAA7164_UNIT_ANALOG_DEMODULATOR, - .name = "TDA8290-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x84 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1b, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1c, - .type = SAA7164_UNIT_ANALOG_DEMODULATOR, - .name = "TDA8290-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x84 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1e, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x10 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1f, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x12 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, - [SAA7164_BOARD_HAUPPAUGE_HVR2250] = { - .name = "Hauppauge WinTV-HVR2250", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .portc = SAA7164_MPEG_ENCODER, - .portd = SAA7164_MPEG_ENCODER, - .porte = SAA7164_MPEG_VBI, - .portf = SAA7164_MPEG_VBI, - .chiprev = SAA7164_CHIP_REV3, - .unit = {{ - .id = 0x22, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x07, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-1 (TOP)", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x32 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x08, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-1 (QAM)", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x34 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x1e, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x20, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-2 (TOP)", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x32 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x23, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-2 (QAM)", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x34 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, - [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = { - .name = "Hauppauge WinTV-HVR2250", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .portc = SAA7164_MPEG_ENCODER, - .portd = SAA7164_MPEG_ENCODER, - .porte = SAA7164_MPEG_VBI, - .portf = SAA7164_MPEG_VBI, - .chiprev = SAA7164_CHIP_REV3, - .unit = {{ - .id = 0x28, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x07, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-1 (TOP)", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x32 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x08, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-1 (QAM)", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x34 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x24, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x26, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-2 (TOP)", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x32 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x29, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-2 (QAM)", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x34 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, - [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = { - .name = "Hauppauge WinTV-HVR2250", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .portc = SAA7164_MPEG_ENCODER, - .portd = SAA7164_MPEG_ENCODER, - .porte = SAA7164_MPEG_VBI, - .portf = SAA7164_MPEG_VBI, - .chiprev = SAA7164_CHIP_REV3, - .unit = {{ - .id = 0x26, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x07, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-1 (TOP)", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x32 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x08, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-1 (QAM)", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x34 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x22, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x24, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-2 (TOP)", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x32 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x27, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "CX24228/S5H1411-2 (QAM)", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x34 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, - [SAA7164_BOARD_HAUPPAUGE_HVR2200_5] = { - .name = "Hauppauge WinTV-HVR2200", - .porta = SAA7164_MPEG_DVB, - .portb = SAA7164_MPEG_DVB, - .chiprev = SAA7164_CHIP_REV3, - .unit = {{ - .id = 0x23, - .type = SAA7164_UNIT_EEPROM, - .name = "4K EEPROM", - .i2c_bus_nr = SAA7164_I2C_BUS_0, - .i2c_bus_addr = 0xa0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x04, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x05, - .type = SAA7164_UNIT_ANALOG_DEMODULATOR, - .name = "TDA8290-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x84 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x21, - .type = SAA7164_UNIT_TUNER, - .name = "TDA18271-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0xc0 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x22, - .type = SAA7164_UNIT_ANALOG_DEMODULATOR, - .name = "TDA8290-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x84 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x24, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-1", - .i2c_bus_nr = SAA7164_I2C_BUS_1, - .i2c_bus_addr = 0x10 >> 1, - .i2c_reg_len = REGLEN_8bit, - }, { - .id = 0x25, - .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, - .name = "TDA10048-2", - .i2c_bus_nr = SAA7164_I2C_BUS_2, - .i2c_bus_addr = 0x12 >> 1, - .i2c_reg_len = REGLEN_8bit, - } }, - }, -}; -const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards); - -/* ------------------------------------------------------------------ */ -/* PCI subsystem IDs */ - -struct saa7164_subid saa7164_subids[] = { - { - .subvendor = 0x0070, - .subdevice = 0x8880, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2250, - }, { - .subvendor = 0x0070, - .subdevice = 0x8810, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2250, - }, { - .subvendor = 0x0070, - .subdevice = 0x8980, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2200, - }, { - .subvendor = 0x0070, - .subdevice = 0x8900, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2, - }, { - .subvendor = 0x0070, - .subdevice = 0x8901, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3, - }, { - .subvendor = 0x0070, - .subdevice = 0x88A1, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3, - }, { - .subvendor = 0x0070, - .subdevice = 0x8891, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, - }, { - .subvendor = 0x0070, - .subdevice = 0x8851, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, - }, { - .subvendor = 0x0070, - .subdevice = 0x8940, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_4, - }, { - .subvendor = 0x0070, - .subdevice = 0x8953, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_5, - }, -}; -const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids); - -void saa7164_card_list(struct saa7164_dev *dev) -{ - int i; - - if (0 == dev->pci->subsystem_vendor && - 0 == dev->pci->subsystem_device) { - printk(KERN_ERR - "%s: Board has no valid PCIe Subsystem ID and can't\n" - "%s: be autodetected. Pass card=<n> insmod option to\n" - "%s: workaround that. Send complaints to the vendor\n" - "%s: of the TV card. Best regards,\n" - "%s: -- tux\n", - dev->name, dev->name, dev->name, dev->name, dev->name); - } else { - printk(KERN_ERR - "%s: Your board isn't known (yet) to the driver.\n" - "%s: Try to pick one of the existing card configs via\n" - "%s: card=<n> insmod option. Updating to the latest\n" - "%s: version might help as well.\n", - dev->name, dev->name, dev->name, dev->name); - } - - printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod " - "option:\n", dev->name); - - for (i = 0; i < saa7164_bcount; i++) - printk(KERN_ERR "%s: card=%d -> %s\n", - dev->name, i, saa7164_boards[i].name); -} - -/* TODO: clean this define up into the -cards.c structs */ -#define PCIEBRIDGE_UNITID 2 - -void saa7164_gpio_setup(struct saa7164_dev *dev) -{ - switch (dev->board) { - case SAA7164_BOARD_HAUPPAUGE_HVR2200: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_5: - case SAA7164_BOARD_HAUPPAUGE_HVR2250: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: - /* - GPIO 2: s5h1411 / tda10048-1 demod reset - GPIO 3: s5h1411 / tda10048-2 demod reset - GPIO 7: IRBlaster Zilog reset - */ - - /* Reset parts by going in and out of reset */ - saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2); - saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3); - - msleep(20); - - saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2); - saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3); - break; - } -} - -static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data) -{ - struct tveeprom tv; - - /* TODO: Assumption: eeprom on bus 0 */ - tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, - eeprom_data); - - /* Make sure we support the board model */ - switch (tv.model) { - case 88001: - /* Development board - Limit circulation */ - /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) - * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */ - case 88021: - /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) - * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */ - break; - case 88041: - /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) - * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */ - break; - case 88061: - /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) - * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */ - break; - case 89519: - case 89609: - /* WinTV-HVR2200 (PCIe, Retail, full-height) - * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ - break; - case 89619: - /* WinTV-HVR2200 (PCIe, Retail, half-height) - * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ - break; - default: - printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n", - dev->name, tv.model); - break; - } - - printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name, - tv.model); -} - -void saa7164_card_setup(struct saa7164_dev *dev) -{ - static u8 eeprom[256]; - - if (dev->i2c_bus[0].i2c_rc == 0) { - if (saa7164_api_read_eeprom(dev, &eeprom[0], - sizeof(eeprom)) < 0) - return; - } - - switch (dev->board) { - case SAA7164_BOARD_HAUPPAUGE_HVR2200: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_5: - case SAA7164_BOARD_HAUPPAUGE_HVR2250: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: - hauppauge_eeprom(dev, &eeprom[0]); - break; - } -} - -/* With most other drivers, the kernel expects to communicate with subdrivers - * through i2c. This bridge does not allow that, it does not expose any direct - * access to I2C. Instead we have to communicate through the device f/w for - * register access to 'processing units'. Each unit has a unique - * id, regardless of how the physical implementation occurs across - * the three physical i2c busses. The being said if we want leverge of - * the existing kernel drivers for tuners and demods we have to 'speak i2c', - * to this bridge implements 3 virtual i2c buses. This is a helper function - * for those. - * - * Description: Translate the kernels notion of an i2c address and bus into - * the appropriate unitid. - */ -int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr) -{ - /* For a given bus and i2c device address, return the saa7164 unique - * unitid. < 0 on error */ - - struct saa7164_dev *dev = bus->dev; - struct saa7164_unit *unit; - int i; - - for (i = 0; i < SAA7164_MAX_UNITS; i++) { - unit = &saa7164_boards[dev->board].unit[i]; - - if (unit->type == SAA7164_UNIT_UNDEFINED) - continue; - if ((bus->nr == unit->i2c_bus_nr) && - (addr == unit->i2c_bus_addr)) - return unit->id; - } - - return -1; -} - -/* The 7164 API needs to know the i2c register length in advance. - * this is a helper function. Based on a specific chip addr and bus return the - * reg length. - */ -int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr) -{ - /* For a given bus and i2c device address, return the - * saa7164 registry address width. < 0 on error - */ - - struct saa7164_dev *dev = bus->dev; - struct saa7164_unit *unit; - int i; - - for (i = 0; i < SAA7164_MAX_UNITS; i++) { - unit = &saa7164_boards[dev->board].unit[i]; - - if (unit->type == SAA7164_UNIT_UNDEFINED) - continue; - - if ((bus->nr == unit->i2c_bus_nr) && - (addr == unit->i2c_bus_addr)) - return unit->i2c_reg_len; - } - - return -1; -} -/* TODO: implement a 'findeeprom' functio like the above and fix any other - * eeprom related todo's in -api.c. - */ - -/* Translate a unitid into a x readable device name, for display purposes. */ -char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid) -{ - char *undefed = "UNDEFINED"; - char *bridge = "BRIDGE"; - struct saa7164_unit *unit; - int i; - - if (unitid == 0) - return bridge; - - for (i = 0; i < SAA7164_MAX_UNITS; i++) { - unit = &saa7164_boards[dev->board].unit[i]; - - if (unit->type == SAA7164_UNIT_UNDEFINED) - continue; - - if (unitid == unit->id) - return unit->name; - } - - return undefed; -} - diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c deleted file mode 100644 index 62fac7f9d04e..000000000000 --- a/drivers/media/video/saa7164/saa7164-cmd.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/wait.h> - -#include "saa7164.h" - -int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev) -{ - int i, ret = -1; - - mutex_lock(&dev->lock); - for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) { - if (dev->cmds[i].inuse == 0) { - dev->cmds[i].inuse = 1; - dev->cmds[i].signalled = 0; - dev->cmds[i].timeout = 0; - ret = dev->cmds[i].seqno; - break; - } - } - mutex_unlock(&dev->lock); - - return ret; -} - -void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno) -{ - mutex_lock(&dev->lock); - if ((dev->cmds[seqno].inuse == 1) && - (dev->cmds[seqno].seqno == seqno)) { - dev->cmds[seqno].inuse = 0; - dev->cmds[seqno].signalled = 0; - dev->cmds[seqno].timeout = 0; - } - mutex_unlock(&dev->lock); -} - -void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno) -{ - mutex_lock(&dev->lock); - if ((dev->cmds[seqno].inuse == 1) && - (dev->cmds[seqno].seqno == seqno)) { - dev->cmds[seqno].timeout = 1; - } - mutex_unlock(&dev->lock); -} - -u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno) -{ - int ret = 0; - - mutex_lock(&dev->lock); - if ((dev->cmds[seqno].inuse == 1) && - (dev->cmds[seqno].seqno == seqno)) { - ret = dev->cmds[seqno].timeout; - } - mutex_unlock(&dev->lock); - - return ret; -} - -/* Commands to the f/w get marshelled to/from this code then onto the PCI - * -bus/c running buffer. */ -int saa7164_irq_dequeue(struct saa7164_dev *dev) -{ - int ret = SAA_OK, i = 0; - u32 timeout; - wait_queue_head_t *q = NULL; - u8 tmp[512]; - dprintk(DBGLVL_CMD, "%s()\n", __func__); - - /* While any outstand message on the bus exists... */ - do { - - /* Peek the msg bus */ - struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 }; - ret = saa7164_bus_get(dev, &tRsp, NULL, 1); - if (ret != SAA_OK) - break; - - q = &dev->cmds[tRsp.seqno].wait; - timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno); - dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout); - if (!timeout) { - dprintk(DBGLVL_CMD, - "%s() signalled seqno(%d) (for dequeue)\n", - __func__, tRsp.seqno); - dev->cmds[tRsp.seqno].signalled = 1; - wake_up(q); - } else { - printk(KERN_ERR - "%s() found timed out command on the bus\n", - __func__); - - /* Clean the bus */ - ret = saa7164_bus_get(dev, &tRsp, &tmp, 0); - printk(KERN_ERR "%s() ret = %x\n", __func__, ret); - if (ret == SAA_ERR_EMPTY) - /* Someone else already fetched the response */ - return SAA_OK; - - if (ret != SAA_OK) - return ret; - } - - /* It's unlikely to have more than 4 or 5 pending messages, - * ensure we exit at some point regardless. - */ - } while (i++ < 32); - - return ret; -} - -/* Commands to the f/w get marshelled to/from this code then onto the PCI - * -bus/c running buffer. */ -int saa7164_cmd_dequeue(struct saa7164_dev *dev) -{ - int loop = 1; - int ret; - u32 timeout; - wait_queue_head_t *q = NULL; - u8 tmp[512]; - dprintk(DBGLVL_CMD, "%s()\n", __func__); - - while (loop) { - - struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 }; - ret = saa7164_bus_get(dev, &tRsp, NULL, 1); - if (ret == SAA_ERR_EMPTY) - return SAA_OK; - - if (ret != SAA_OK) - return ret; - - q = &dev->cmds[tRsp.seqno].wait; - timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno); - dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout); - if (timeout) { - printk(KERN_ERR "found timed out command on the bus\n"); - - /* Clean the bus */ - ret = saa7164_bus_get(dev, &tRsp, &tmp, 0); - printk(KERN_ERR "ret = %x\n", ret); - if (ret == SAA_ERR_EMPTY) - /* Someone else already fetched the response */ - return SAA_OK; - - if (ret != SAA_OK) - return ret; - - if (tRsp.flags & PVC_CMDFLAG_CONTINUE) - printk(KERN_ERR "split response\n"); - else - saa7164_cmd_free_seqno(dev, tRsp.seqno); - - printk(KERN_ERR " timeout continue\n"); - continue; - } - - dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n", - __func__, tRsp.seqno); - dev->cmds[tRsp.seqno].signalled = 1; - wake_up(q); - return SAA_OK; - } - - return SAA_OK; -} - -int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg, - void *buf) -{ - struct tmComResBusInfo *bus = &dev->bus; - u8 cmd_sent; - u16 size, idx; - u32 cmds; - void *tmp; - int ret = -1; - - if (!msg) { - printk(KERN_ERR "%s() !msg\n", __func__); - return SAA_ERR_BAD_PARAMETER; - } - - mutex_lock(&dev->cmds[msg->id].lock); - - size = msg->size; - idx = 0; - cmds = size / bus->m_wMaxReqSize; - if (size % bus->m_wMaxReqSize == 0) - cmds -= 1; - - cmd_sent = 0; - - /* Split the request into smaller chunks */ - for (idx = 0; idx < cmds; idx++) { - - msg->flags |= SAA_CMDFLAG_CONTINUE; - msg->size = bus->m_wMaxReqSize; - tmp = buf + idx * bus->m_wMaxReqSize; - - ret = saa7164_bus_set(dev, msg, tmp); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() set failed %d\n", __func__, ret); - - if (cmd_sent) { - ret = SAA_ERR_BUSY; - goto out; - } - ret = SAA_ERR_OVERFLOW; - goto out; - } - cmd_sent = 1; - } - - /* If not the last command... */ - if (idx != 0) - msg->flags &= ~SAA_CMDFLAG_CONTINUE; - - msg->size = size - idx * bus->m_wMaxReqSize; - - ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() set last failed %d\n", __func__, ret); - - if (cmd_sent) { - ret = SAA_ERR_BUSY; - goto out; - } - ret = SAA_ERR_OVERFLOW; - goto out; - } - ret = SAA_OK; - -out: - mutex_unlock(&dev->cmds[msg->id].lock); - return ret; -} - -/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if - * the event never occurred, or SAA_OK if it was signaled during the wait. - */ -int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno) -{ - wait_queue_head_t *q = NULL; - int ret = SAA_BUS_TIMEOUT; - unsigned long stamp; - int r; - - if (saa_debug >= 4) - saa7164_bus_dump(dev); - - dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno); - - mutex_lock(&dev->lock); - if ((dev->cmds[seqno].inuse == 1) && - (dev->cmds[seqno].seqno == seqno)) { - q = &dev->cmds[seqno].wait; - } - mutex_unlock(&dev->lock); - - if (q) { - /* If we haven't been signalled we need to wait */ - if (dev->cmds[seqno].signalled == 0) { - stamp = jiffies; - dprintk(DBGLVL_CMD, - "%s(seqno=%d) Waiting (signalled=%d)\n", - __func__, seqno, dev->cmds[seqno].signalled); - - /* Wait for signalled to be flagged or timeout */ - /* In a highly stressed system this can easily extend - * into multiple seconds before the deferred worker - * is scheduled, and we're woken up via signal. - * We typically are signalled in < 50ms but it can - * take MUCH longer. - */ - wait_event_timeout(*q, dev->cmds[seqno].signalled, - (HZ * waitsecs)); - r = time_before(jiffies, stamp + (HZ * waitsecs)); - if (r) - ret = SAA_OK; - else - saa7164_cmd_timeout_seqno(dev, seqno); - - dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d " - "(signalled=%d)\n", __func__, seqno, r, - dev->cmds[seqno].signalled); - } else - ret = SAA_OK; - } else - printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n", - __func__, seqno); - - return ret; -} - -void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno) -{ - int i; - dprintk(DBGLVL_CMD, "%s()\n", __func__); - - mutex_lock(&dev->lock); - for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) { - if (dev->cmds[i].inuse == 1) { - dprintk(DBGLVL_CMD, - "seqno %d inuse, sig = %d, t/out = %d\n", - dev->cmds[i].seqno, - dev->cmds[i].signalled, - dev->cmds[i].timeout); - } - } - - for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) { - if ((dev->cmds[i].inuse == 1) && ((i == 0) || - (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) { - dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n", - __func__, i); - dev->cmds[i].signalled = 1; - wake_up(&dev->cmds[i].wait); - } - } - mutex_unlock(&dev->lock); -} - -int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command, - u16 controlselector, u16 size, void *buf) -{ - struct tmComResInfo command_t, *pcommand_t; - struct tmComResInfo response_t, *presponse_t; - u8 errdata[256]; - u16 resp_dsize; - u16 data_recd; - u32 loop; - int ret; - int safety = 0; - - dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, " - "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id, - command, controlselector); - - if ((size == 0) || (buf == NULL)) { - printk(KERN_ERR "%s() Invalid param\n", __func__); - return SAA_ERR_BAD_PARAMETER; - } - - /* Prepare some basic command/response structures */ - memset(&command_t, 0, sizeof(command_t)); - memset(&response_t, 0, sizeof(response_t)); - pcommand_t = &command_t; - presponse_t = &response_t; - command_t.id = id; - command_t.command = command; - command_t.controlselector = controlselector; - command_t.size = size; - - /* Allocate a unique sequence number */ - ret = saa7164_cmd_alloc_seqno(dev); - if (ret < 0) { - printk(KERN_ERR "%s() No free sequences\n", __func__); - ret = SAA_ERR_NO_RESOURCES; - goto out; - } - - command_t.seqno = (u8)ret; - - /* Send Command */ - resp_dsize = size; - pcommand_t->size = size; - - dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n", - __func__, pcommand_t->seqno); - - dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n", - __func__, pcommand_t->size); - - ret = saa7164_cmd_set(dev, pcommand_t, buf); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() set command failed %d\n", __func__, ret); - - if (ret != SAA_ERR_BUSY) - saa7164_cmd_free_seqno(dev, pcommand_t->seqno); - else - /* Flag a timeout, because at least one - * command was sent */ - saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno); - - goto out; - } - - /* With split responses we have to collect the msgs piece by piece */ - data_recd = 0; - loop = 1; - while (loop) { - dprintk(DBGLVL_CMD, "%s() loop\n", __func__); - - ret = saa7164_cmd_wait(dev, pcommand_t->seqno); - dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret); - - /* if power is down and this is not a power command ... */ - - if (ret == SAA_BUS_TIMEOUT) { - printk(KERN_ERR "Event timed out\n"); - saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno); - return ret; - } - - if (ret != SAA_OK) { - printk(KERN_ERR "spurious error\n"); - return ret; - } - - /* Peek response */ - ret = saa7164_bus_get(dev, presponse_t, NULL, 1); - if (ret == SAA_ERR_EMPTY) { - dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__); - continue; - } - if (ret != SAA_OK) { - printk(KERN_ERR "peek failed\n"); - return ret; - } - - dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n", - __func__, presponse_t->seqno); - - dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n", - __func__, presponse_t->flags); - - dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n", - __func__, presponse_t->size); - - /* Check if the response was for our command */ - if (presponse_t->seqno != pcommand_t->seqno) { - - dprintk(DBGLVL_CMD, - "wrong event: seqno = %d, " - "expected seqno = %d, " - "will dequeue regardless\n", - presponse_t->seqno, pcommand_t->seqno); - - ret = saa7164_cmd_dequeue(dev); - if (ret != SAA_OK) { - printk(KERN_ERR "dequeue failed, ret = %d\n", - ret); - if (safety++ > 16) { - printk(KERN_ERR - "dequeue exceeded, safety exit\n"); - return SAA_ERR_BUSY; - } - } - - continue; - } - - if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) { - - memset(&errdata[0], 0, sizeof(errdata)); - - ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0); - if (ret != SAA_OK) { - printk(KERN_ERR "get error(2)\n"); - return ret; - } - - saa7164_cmd_free_seqno(dev, pcommand_t->seqno); - - dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n", - __func__, errdata[0], errdata[1], errdata[2], - errdata[3]); - - /* Map error codes */ - dprintk(DBGLVL_CMD, "%s() cmd, error code = 0x%x\n", - __func__, errdata[0]); - - switch (errdata[0]) { - case PVC_ERRORCODE_INVALID_COMMAND: - dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n", - __func__); - ret = SAA_ERR_INVALID_COMMAND; - break; - case PVC_ERRORCODE_INVALID_DATA: - dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n", - __func__); - ret = SAA_ERR_BAD_PARAMETER; - break; - case PVC_ERRORCODE_TIMEOUT: - dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__); - ret = SAA_ERR_TIMEOUT; - break; - case PVC_ERRORCODE_NAK: - dprintk(DBGLVL_CMD, "%s() NAK\n", __func__); - ret = SAA_ERR_NULL_PACKET; - break; - case PVC_ERRORCODE_UNKNOWN: - case PVC_ERRORCODE_INVALID_CONTROL: - dprintk(DBGLVL_CMD, - "%s() UNKNOWN OR INVALID CONTROL\n", - __func__); - default: - dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__); - ret = SAA_ERR_NOT_SUPPORTED; - } - - /* See of other commands are on the bus */ - if (saa7164_cmd_dequeue(dev) != SAA_OK) - printk(KERN_ERR "dequeue(2) failed\n"); - - return ret; - } - - /* If response is invalid */ - if ((presponse_t->id != pcommand_t->id) || - (presponse_t->command != pcommand_t->command) || - (presponse_t->controlselector != - pcommand_t->controlselector) || - (((resp_dsize - data_recd) != presponse_t->size) && - !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) || - ((resp_dsize - data_recd) < presponse_t->size)) { - - /* Invalid */ - dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__); - ret = saa7164_bus_get(dev, presponse_t, NULL, 0); - if (ret != SAA_OK) { - printk(KERN_ERR "get failed\n"); - return ret; - } - - /* See of other commands are on the bus */ - if (saa7164_cmd_dequeue(dev) != SAA_OK) - printk(KERN_ERR "dequeue(3) failed\n"); - continue; - } - - /* OK, now we're actually getting out correct response */ - ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0); - if (ret != SAA_OK) { - printk(KERN_ERR "get failed\n"); - return ret; - } - - data_recd = presponse_t->size + data_recd; - if (resp_dsize == data_recd) { - dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__); - break; - } - - /* See of other commands are on the bus */ - if (saa7164_cmd_dequeue(dev) != SAA_OK) - printk(KERN_ERR "dequeue(3) failed\n"); - - continue; - - } /* (loop) */ - - /* Release the sequence number allocation */ - saa7164_cmd_free_seqno(dev, pcommand_t->seqno); - - /* if powerdown signal all pending commands */ - - dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__); - - /* See of other commands are on the bus */ - if (saa7164_cmd_dequeue(dev) != SAA_OK) - printk(KERN_ERR "dequeue(4) failed\n"); - - ret = SAA_OK; -out: - return ret; -} - diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c deleted file mode 100644 index 2c9ad878bef3..000000000000 --- a/drivers/media/video/saa7164/saa7164-core.c +++ /dev/null @@ -1,1488 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/init.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kmod.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <asm/div64.h> - -#ifdef CONFIG_PROC_FS -#include <linux/proc_fs.h> -#endif -#include "saa7164.h" - -MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards"); -MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>"); -MODULE_LICENSE("GPL"); - -/* - * 1 Basic - * 2 - * 4 i2c - * 8 api - * 16 cmd - * 32 bus - */ - -unsigned int saa_debug; -module_param_named(debug, saa_debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debug messages"); - -unsigned int fw_debug; -module_param(fw_debug, int, 0644); -MODULE_PARM_DESC(fw_debug, "Firware debug level def:2"); - -unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS; -module_param(encoder_buffers, int, 0644); -MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64"); - -unsigned int vbi_buffers = SAA7164_MAX_VBI_BUFFERS; -module_param(vbi_buffers, int, 0644); -MODULE_PARM_DESC(vbi_buffers, "Total buffers in read queue 16-512 def:64"); - -unsigned int waitsecs = 10; -module_param(waitsecs, int, 0644); -MODULE_PARM_DESC(waitsecs, "timeout on firmware messages"); - -static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET }; -module_param_array(card, int, NULL, 0444); -MODULE_PARM_DESC(card, "card type"); - -unsigned int print_histogram = 64; -module_param(print_histogram, int, 0644); -MODULE_PARM_DESC(print_histogram, "print histogram values once"); - -unsigned int crc_checking = 1; -module_param(crc_checking, int, 0644); -MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers"); - -unsigned int guard_checking = 1; -module_param(guard_checking, int, 0644); -MODULE_PARM_DESC(guard_checking, - "enable dma sanity checking for buffer overruns"); - -static unsigned int saa7164_devcount; - -static DEFINE_MUTEX(devlist); -LIST_HEAD(saa7164_devlist); - -#define INT_SIZE 16 - -static void saa7164_pack_verifier(struct saa7164_buffer *buf) -{ - u8 *p = (u8 *)buf->cpu; - int i; - - for (i = 0; i < buf->actual_size; i += 2048) { - - if ((*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) || - (*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) { - printk(KERN_ERR "No pack at 0x%x\n", i); -#if 0 - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, - p + 1, 32, false); -#endif - } - } -} - -#define FIXED_VIDEO_PID 0xf1 -#define FIXED_AUDIO_PID 0xf2 - -static void saa7164_ts_verifier(struct saa7164_buffer *buf) -{ - struct saa7164_port *port = buf->port; - u32 i; - u8 cc, a; - u16 pid; - u8 __iomem *bufcpu = (u8 *)buf->cpu; - - port->sync_errors = 0; - port->v_cc_errors = 0; - port->a_cc_errors = 0; - - for (i = 0; i < buf->actual_size; i += 188) { - if (*(bufcpu + i) != 0x47) - port->sync_errors++; - - /* TODO: Query pid lower 8 bits, ignoring upper bits intensionally */ - pid = ((*(bufcpu + i + 1) & 0x1f) << 8) | *(bufcpu + i + 2); - cc = *(bufcpu + i + 3) & 0x0f; - - if (pid == FIXED_VIDEO_PID) { - a = ((port->last_v_cc + 1) & 0x0f); - if (a != cc) { - printk(KERN_ERR "video cc last = %x current = %x i = %d\n", - port->last_v_cc, cc, i); - port->v_cc_errors++; - } - - port->last_v_cc = cc; - } else - if (pid == FIXED_AUDIO_PID) { - a = ((port->last_a_cc + 1) & 0x0f); - if (a != cc) { - printk(KERN_ERR "audio cc last = %x current = %x i = %d\n", - port->last_a_cc, cc, i); - port->a_cc_errors++; - } - - port->last_a_cc = cc; - } - - } - - /* Only report errors if we've been through this function atleast - * once already and the cached cc values are primed. First time through - * always generates errors. - */ - if (port->v_cc_errors && (port->done_first_interrupt > 1)) - printk(KERN_ERR "video pid cc, %d errors\n", port->v_cc_errors); - - if (port->a_cc_errors && (port->done_first_interrupt > 1)) - printk(KERN_ERR "audio pid cc, %d errors\n", port->a_cc_errors); - - if (port->sync_errors && (port->done_first_interrupt > 1)) - printk(KERN_ERR "sync_errors = %d\n", port->sync_errors); - - if (port->done_first_interrupt == 1) - port->done_first_interrupt++; -} - -static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name) -{ - int i; - - memset(hg, 0, sizeof(struct saa7164_histogram)); - strcpy(hg->name, name); - - /* First 30ms x 1ms */ - for (i = 0; i < 30; i++) - hg->counter1[0 + i].val = i; - - /* 30 - 200ms x 10ms */ - for (i = 0; i < 18; i++) - hg->counter1[30 + i].val = 30 + (i * 10); - - /* 200 - 2000ms x 100ms */ - for (i = 0; i < 15; i++) - hg->counter1[48 + i].val = 200 + (i * 200); - - /* Catch all massive value (2secs) */ - hg->counter1[55].val = 2000; - - /* Catch all massive value (4secs) */ - hg->counter1[56].val = 4000; - - /* Catch all massive value (8secs) */ - hg->counter1[57].val = 8000; - - /* Catch all massive value (15secs) */ - hg->counter1[58].val = 15000; - - /* Catch all massive value (30secs) */ - hg->counter1[59].val = 30000; - - /* Catch all massive value (60secs) */ - hg->counter1[60].val = 60000; - - /* Catch all massive value (5mins) */ - hg->counter1[61].val = 300000; - - /* Catch all massive value (15mins) */ - hg->counter1[62].val = 900000; - - /* Catch all massive values (1hr) */ - hg->counter1[63].val = 3600000; -} - -void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val) -{ - int i; - for (i = 0; i < 64; i++) { - if (val <= hg->counter1[i].val) { - hg->counter1[i].count++; - hg->counter1[i].update_time = jiffies; - break; - } - } -} - -static void saa7164_histogram_print(struct saa7164_port *port, - struct saa7164_histogram *hg) -{ - u32 entries = 0; - int i; - - printk(KERN_ERR "Histogram named %s (ms, count, last_update_jiffy)\n", hg->name); - for (i = 0; i < 64; i++) { - if (hg->counter1[i].count == 0) - continue; - - printk(KERN_ERR " %4d %12d %Ld\n", - hg->counter1[i].val, - hg->counter1[i].count, - hg->counter1[i].update_time); - - entries++; - } - printk(KERN_ERR "Total: %d\n", entries); -} - -static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf = NULL; - struct saa7164_user_buffer *ubuf = NULL; - struct list_head *c, *n; - int i = 0; - u8 __iomem *p; - - mutex_lock(&port->dmaqueue_lock); - list_for_each_safe(c, n, &port->dmaqueue.list) { - - buf = list_entry(c, struct saa7164_buffer, list); - if (i++ > port->hwcfg.buffercount) { - printk(KERN_ERR "%s() illegal i count %d\n", - __func__, i); - break; - } - - if (buf->idx == bufnr) { - - /* Found the buffer, deal with it */ - dprintk(DBGLVL_IRQ, "%s() bufnr: %d\n", __func__, bufnr); - - if (crc_checking) { - /* Throw a new checksum on the dma buffer */ - buf->crc = crc32(0, buf->cpu, buf->actual_size); - } - - if (guard_checking) { - p = (u8 *)buf->cpu; - if ((*(p + buf->actual_size + 0) != 0xff) || - (*(p + buf->actual_size + 1) != 0xff) || - (*(p + buf->actual_size + 2) != 0xff) || - (*(p + buf->actual_size + 3) != 0xff) || - (*(p + buf->actual_size + 0x10) != 0xff) || - (*(p + buf->actual_size + 0x11) != 0xff) || - (*(p + buf->actual_size + 0x12) != 0xff) || - (*(p + buf->actual_size + 0x13) != 0xff)) { - printk(KERN_ERR "%s() buf %p guard buffer breach\n", - __func__, buf); -#if 0 - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, - p + buf->actual_size - 32, 64, false); -#endif - } - } - - if ((port->nr != SAA7164_PORT_VBI1) && (port->nr != SAA7164_PORT_VBI2)) { - /* Validate the incoming buffer content */ - if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) - saa7164_ts_verifier(buf); - else if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) - saa7164_pack_verifier(buf); - } - - /* find a free user buffer and clone to it */ - if (!list_empty(&port->list_buf_free.list)) { - - /* Pull the first buffer from the used list */ - ubuf = list_first_entry(&port->list_buf_free.list, - struct saa7164_user_buffer, list); - - if (buf->actual_size <= ubuf->actual_size) { - - memcpy_fromio(ubuf->data, buf->cpu, - ubuf->actual_size); - - if (crc_checking) { - /* Throw a new checksum on the read buffer */ - ubuf->crc = crc32(0, ubuf->data, ubuf->actual_size); - } - - /* Requeue the buffer on the free list */ - ubuf->pos = 0; - - list_move_tail(&ubuf->list, - &port->list_buf_used.list); - - /* Flag any userland waiters */ - wake_up_interruptible(&port->wait_read); - - } else { - printk(KERN_ERR "buf %p bufsize fails match\n", buf); - } - - } else - printk(KERN_ERR "encirq no free buffers, increase param encoder_buffers\n"); - - /* Ensure offset into buffer remains 0, fill buffer - * with known bad data. We check for this data at a later point - * in time. */ - saa7164_buffer_zero_offsets(port, bufnr); - memset_io(buf->cpu, 0xff, buf->pci_size); - if (crc_checking) { - /* Throw yet aanother new checksum on the dma buffer */ - buf->crc = crc32(0, buf->cpu, buf->actual_size); - } - - break; - } - } - mutex_unlock(&port->dmaqueue_lock); -} - -static void saa7164_work_enchandler(struct work_struct *w) -{ - struct saa7164_port *port = - container_of(w, struct saa7164_port, workenc); - struct saa7164_dev *dev = port->dev; - - u32 wp, mcb, rp, cnt = 0; - - port->last_svc_msecs_diff = port->last_svc_msecs; - port->last_svc_msecs = jiffies_to_msecs(jiffies); - - port->last_svc_msecs_diff = port->last_svc_msecs - - port->last_svc_msecs_diff; - - saa7164_histogram_update(&port->svc_interval, - port->last_svc_msecs_diff); - - port->last_irq_svc_msecs_diff = port->last_svc_msecs - - port->last_irq_msecs; - - saa7164_histogram_update(&port->irq_svc_interval, - port->last_irq_svc_msecs_diff); - - dprintk(DBGLVL_IRQ, - "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n", - __func__, - port->last_svc_msecs_diff, - port->last_irq_svc_msecs_diff, - port->last_svc_wp, - port->last_svc_rp - ); - - /* Current write position */ - wp = saa7164_readl(port->bufcounter); - if (wp > (port->hwcfg.buffercount - 1)) { - printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp); - return; - } - - /* Most current complete buffer */ - if (wp == 0) - mcb = (port->hwcfg.buffercount - 1); - else - mcb = wp - 1; - - while (1) { - if (port->done_first_interrupt == 0) { - port->done_first_interrupt++; - rp = mcb; - } else - rp = (port->last_svc_rp + 1) % 8; - - if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) { - printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp); - break; - } - - saa7164_work_enchandler_helper(port, rp); - port->last_svc_rp = rp; - cnt++; - - if (rp == mcb) - break; - } - - /* TODO: Convert this into a /proc/saa7164 style readable file */ - if (print_histogram == port->nr) { - saa7164_histogram_print(port, &port->irq_interval); - saa7164_histogram_print(port, &port->svc_interval); - saa7164_histogram_print(port, &port->irq_svc_interval); - saa7164_histogram_print(port, &port->read_interval); - saa7164_histogram_print(port, &port->poll_interval); - /* TODO: fix this to preserve any previous state */ - print_histogram = 64 + port->nr; - } -} - -static void saa7164_work_vbihandler(struct work_struct *w) -{ - struct saa7164_port *port = - container_of(w, struct saa7164_port, workenc); - struct saa7164_dev *dev = port->dev; - - u32 wp, mcb, rp, cnt = 0; - - port->last_svc_msecs_diff = port->last_svc_msecs; - port->last_svc_msecs = jiffies_to_msecs(jiffies); - port->last_svc_msecs_diff = port->last_svc_msecs - - port->last_svc_msecs_diff; - - saa7164_histogram_update(&port->svc_interval, - port->last_svc_msecs_diff); - - port->last_irq_svc_msecs_diff = port->last_svc_msecs - - port->last_irq_msecs; - - saa7164_histogram_update(&port->irq_svc_interval, - port->last_irq_svc_msecs_diff); - - dprintk(DBGLVL_IRQ, - "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n", - __func__, - port->last_svc_msecs_diff, - port->last_irq_svc_msecs_diff, - port->last_svc_wp, - port->last_svc_rp - ); - - /* Current write position */ - wp = saa7164_readl(port->bufcounter); - if (wp > (port->hwcfg.buffercount - 1)) { - printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp); - return; - } - - /* Most current complete buffer */ - if (wp == 0) - mcb = (port->hwcfg.buffercount - 1); - else - mcb = wp - 1; - - while (1) { - if (port->done_first_interrupt == 0) { - port->done_first_interrupt++; - rp = mcb; - } else - rp = (port->last_svc_rp + 1) % 8; - - if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) { - printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp); - break; - } - - saa7164_work_enchandler_helper(port, rp); - port->last_svc_rp = rp; - cnt++; - - if (rp == mcb) - break; - } - - /* TODO: Convert this into a /proc/saa7164 style readable file */ - if (print_histogram == port->nr) { - saa7164_histogram_print(port, &port->irq_interval); - saa7164_histogram_print(port, &port->svc_interval); - saa7164_histogram_print(port, &port->irq_svc_interval); - saa7164_histogram_print(port, &port->read_interval); - saa7164_histogram_print(port, &port->poll_interval); - /* TODO: fix this to preserve any previous state */ - print_histogram = 64 + port->nr; - } -} - -static void saa7164_work_cmdhandler(struct work_struct *w) -{ - struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd); - - /* Wake up any complete commands */ - saa7164_irq_dequeue(dev); -} - -static void saa7164_buffer_deliver(struct saa7164_buffer *buf) -{ - struct saa7164_port *port = buf->port; - - /* Feed the transport payload into the kernel demux */ - dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu, - SAA7164_TS_NUMBER_OF_LINES); - -} - -static irqreturn_t saa7164_irq_vbi(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - - /* Store old time */ - port->last_irq_msecs_diff = port->last_irq_msecs; - - /* Collect new stats */ - port->last_irq_msecs = jiffies_to_msecs(jiffies); - - /* Calculate stats */ - port->last_irq_msecs_diff = port->last_irq_msecs - - port->last_irq_msecs_diff; - - saa7164_histogram_update(&port->irq_interval, - port->last_irq_msecs_diff); - - dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__, - port->last_irq_msecs_diff); - - /* Tis calls the vbi irq handler */ - schedule_work(&port->workenc); - return 0; -} - -static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - - /* Store old time */ - port->last_irq_msecs_diff = port->last_irq_msecs; - - /* Collect new stats */ - port->last_irq_msecs = jiffies_to_msecs(jiffies); - - /* Calculate stats */ - port->last_irq_msecs_diff = port->last_irq_msecs - - port->last_irq_msecs_diff; - - saa7164_histogram_update(&port->irq_interval, - port->last_irq_msecs_diff); - - dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__, - port->last_irq_msecs_diff); - - schedule_work(&port->workenc); - return 0; -} - -static irqreturn_t saa7164_irq_ts(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct list_head *c, *n; - int wp, i = 0, rp; - - /* Find the current write point from the hardware */ - wp = saa7164_readl(port->bufcounter); - if (wp > (port->hwcfg.buffercount - 1)) - BUG(); - - /* Find the previous buffer to the current write point */ - if (wp == 0) - rp = (port->hwcfg.buffercount - 1); - else - rp = wp - 1; - - /* Lookup the WP in the buffer list */ - /* TODO: turn this into a worker thread */ - list_for_each_safe(c, n, &port->dmaqueue.list) { - buf = list_entry(c, struct saa7164_buffer, list); - if (i++ > port->hwcfg.buffercount) - BUG(); - - if (buf->idx == rp) { - /* Found the buffer, deal with it */ - dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n", - __func__, wp, rp); - saa7164_buffer_deliver(buf); - break; - } - - } - return 0; -} - -/* Primary IRQ handler and dispatch mechanism */ -static irqreturn_t saa7164_irq(int irq, void *dev_id) -{ - struct saa7164_dev *dev = dev_id; - struct saa7164_port *porta = &dev->ports[SAA7164_PORT_TS1]; - struct saa7164_port *portb = &dev->ports[SAA7164_PORT_TS2]; - struct saa7164_port *portc = &dev->ports[SAA7164_PORT_ENC1]; - struct saa7164_port *portd = &dev->ports[SAA7164_PORT_ENC2]; - struct saa7164_port *porte = &dev->ports[SAA7164_PORT_VBI1]; - struct saa7164_port *portf = &dev->ports[SAA7164_PORT_VBI2]; - - u32 intid, intstat[INT_SIZE/4]; - int i, handled = 0, bit; - - if (dev == NULL) { - printk(KERN_ERR "%s() No device specified\n", __func__); - handled = 0; - goto out; - } - - /* Check that the hardware is accessible. If the status bytes are - * 0xFF then the device is not accessible, the the IRQ belongs - * to another driver. - * 4 x u32 interrupt registers. - */ - for (i = 0; i < INT_SIZE/4; i++) { - - /* TODO: Convert into saa7164_readl() */ - /* Read the 4 hardware interrupt registers */ - intstat[i] = saa7164_readl(dev->int_status + (i * 4)); - - if (intstat[i]) - handled = 1; - } - if (handled == 0) - goto out; - - /* For each of the HW interrupt registers */ - for (i = 0; i < INT_SIZE/4; i++) { - - if (intstat[i]) { - /* Each function of the board has it's own interruptid. - * Find the function that triggered then call - * it's handler. - */ - for (bit = 0; bit < 32; bit++) { - - if (((intstat[i] >> bit) & 0x00000001) == 0) - continue; - - /* Calculate the interrupt id (0x00 to 0x7f) */ - - intid = (i * 32) + bit; - if (intid == dev->intfdesc.bInterruptId) { - /* A response to an cmd/api call */ - schedule_work(&dev->workcmd); - } else if (intid == porta->hwcfg.interruptid) { - - /* Transport path 1 */ - saa7164_irq_ts(porta); - - } else if (intid == portb->hwcfg.interruptid) { - - /* Transport path 2 */ - saa7164_irq_ts(portb); - - } else if (intid == portc->hwcfg.interruptid) { - - /* Encoder path 1 */ - saa7164_irq_encoder(portc); - - } else if (intid == portd->hwcfg.interruptid) { - - /* Encoder path 2 */ - saa7164_irq_encoder(portd); - - } else if (intid == porte->hwcfg.interruptid) { - - /* VBI path 1 */ - saa7164_irq_vbi(porte); - - } else if (intid == portf->hwcfg.interruptid) { - - /* VBI path 2 */ - saa7164_irq_vbi(portf); - - } else { - /* Find the function */ - dprintk(DBGLVL_IRQ, - "%s() unhandled interrupt " - "reg 0x%x bit 0x%x " - "intid = 0x%x\n", - __func__, i, bit, intid); - } - } - - /* Ack it */ - saa7164_writel(dev->int_ack + (i * 4), intstat[i]); - - } - } -out: - return IRQ_RETVAL(handled); -} - -void saa7164_getfirmwarestatus(struct saa7164_dev *dev) -{ - struct saa7164_fw_status *s = &dev->fw_status; - - dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS); - dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE); - dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC); - dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST); - dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD); - dev->fw_status.remainheap = - saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP); - - dprintk(1, "Firmware status:\n"); - dprintk(1, " .status = 0x%08x\n", s->status); - dprintk(1, " .mode = 0x%08x\n", s->mode); - dprintk(1, " .spec = 0x%08x\n", s->spec); - dprintk(1, " .inst = 0x%08x\n", s->inst); - dprintk(1, " .cpuload = 0x%08x\n", s->cpuload); - dprintk(1, " .remainheap = 0x%08x\n", s->remainheap); -} - -u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev) -{ - u32 reg; - - reg = saa7164_readl(SAA_DEVICE_VERSION); - dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n", - (reg & 0x0000fc00) >> 10, - (reg & 0x000003e0) >> 5, - (reg & 0x0000001f), - (reg & 0xffff0000) >> 16, - reg); - - return reg; -} - -/* TODO: Debugging func, remove */ -void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr) -{ - int i; - - dprintk(1, "--------------------> " - "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"); - - for (i = 0; i < 0x100; i += 16) - dprintk(1, "region0[0x%08x] = " - "%02x %02x %02x %02x %02x %02x %02x %02x" - " %02x %02x %02x %02x %02x %02x %02x %02x\n", i, - (u8)saa7164_readb(addr + i + 0), - (u8)saa7164_readb(addr + i + 1), - (u8)saa7164_readb(addr + i + 2), - (u8)saa7164_readb(addr + i + 3), - (u8)saa7164_readb(addr + i + 4), - (u8)saa7164_readb(addr + i + 5), - (u8)saa7164_readb(addr + i + 6), - (u8)saa7164_readb(addr + i + 7), - (u8)saa7164_readb(addr + i + 8), - (u8)saa7164_readb(addr + i + 9), - (u8)saa7164_readb(addr + i + 10), - (u8)saa7164_readb(addr + i + 11), - (u8)saa7164_readb(addr + i + 12), - (u8)saa7164_readb(addr + i + 13), - (u8)saa7164_readb(addr + i + 14), - (u8)saa7164_readb(addr + i + 15) - ); -} - -static void saa7164_dump_hwdesc(struct saa7164_dev *dev) -{ - dprintk(1, "@0x%p hwdesc sizeof(struct tmComResHWDescr) = %d bytes\n", - &dev->hwdesc, (u32)sizeof(struct tmComResHWDescr)); - - dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength); - dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType); - dprintk(1, " .bDescriptorSubtype = 0x%x\n", - dev->hwdesc.bDescriptorSubtype); - - dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion); - dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency); - dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes); - dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities); - dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n", - dev->hwdesc.dwDeviceRegistersLocation); - - dprintk(1, " .dwHostMemoryRegion = 0x%x\n", - dev->hwdesc.dwHostMemoryRegion); - - dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n", - dev->hwdesc.dwHostMemoryRegionSize); - - dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n", - dev->hwdesc.dwHostHibernatMemRegion); - - dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n", - dev->hwdesc.dwHostHibernatMemRegionSize); -} - -static void saa7164_dump_intfdesc(struct saa7164_dev *dev) -{ - dprintk(1, "@0x%p intfdesc " - "sizeof(struct tmComResInterfaceDescr) = %d bytes\n", - &dev->intfdesc, (u32)sizeof(struct tmComResInterfaceDescr)); - - dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength); - dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType); - dprintk(1, " .bDescriptorSubtype = 0x%x\n", - dev->intfdesc.bDescriptorSubtype); - - dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags); - dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType); - dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId); - dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface); - dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId); - dprintk(1, " .bDebugInterruptId = 0x%x\n", - dev->intfdesc.bDebugInterruptId); - - dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation); -} - -static void saa7164_dump_busdesc(struct saa7164_dev *dev) -{ - dprintk(1, "@0x%p busdesc sizeof(struct tmComResBusDescr) = %d bytes\n", - &dev->busdesc, (u32)sizeof(struct tmComResBusDescr)); - - dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing); - dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing); - dprintk(1, " .CommandWrite = 0x%x\n", dev->busdesc.CommandWrite); - dprintk(1, " .CommandRead = 0x%x\n", dev->busdesc.CommandRead); - dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite); - dprintk(1, " .ResponseRead = 0x%x\n", dev->busdesc.ResponseRead); -} - -/* Much of the hardware configuration and PCI registers are configured - * dynamically depending on firmware. We have to cache some initial - * structures then use these to locate other important structures - * from PCI space. - */ -static void saa7164_get_descriptors(struct saa7164_dev *dev) -{ - memcpy_fromio(&dev->hwdesc, dev->bmmio, sizeof(struct tmComResHWDescr)); - memcpy_fromio(&dev->intfdesc, dev->bmmio + sizeof(struct tmComResHWDescr), - sizeof(struct tmComResInterfaceDescr)); - memcpy_fromio(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation, - sizeof(struct tmComResBusDescr)); - - if (dev->hwdesc.bLength != sizeof(struct tmComResHWDescr)) { - printk(KERN_ERR "Structure struct tmComResHWDescr is mangled\n"); - printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength, - (u32)sizeof(struct tmComResHWDescr)); - } else - saa7164_dump_hwdesc(dev); - - if (dev->intfdesc.bLength != sizeof(struct tmComResInterfaceDescr)) { - printk(KERN_ERR "struct struct tmComResInterfaceDescr is mangled\n"); - printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength, - (u32)sizeof(struct tmComResInterfaceDescr)); - } else - saa7164_dump_intfdesc(dev); - - saa7164_dump_busdesc(dev); -} - -static int saa7164_pci_quirks(struct saa7164_dev *dev) -{ - return 0; -} - -static int get_resources(struct saa7164_dev *dev) -{ - if (request_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0), dev->name)) { - - if (request_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2), dev->name)) - return 0; - } - - printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n", - dev->name, - (u64)pci_resource_start(dev->pci, 0), - (u64)pci_resource_start(dev->pci, 2)); - - return -EBUSY; -} - -static int saa7164_port_init(struct saa7164_dev *dev, int portnr) -{ - struct saa7164_port *port = NULL; - - if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS)) - BUG(); - - port = &dev->ports[portnr]; - - port->dev = dev; - port->nr = portnr; - - if ((portnr == SAA7164_PORT_TS1) || (portnr == SAA7164_PORT_TS2)) - port->type = SAA7164_MPEG_DVB; - else - if ((portnr == SAA7164_PORT_ENC1) || (portnr == SAA7164_PORT_ENC2)) { - port->type = SAA7164_MPEG_ENCODER; - - /* We need a deferred interrupt handler for cmd handling */ - INIT_WORK(&port->workenc, saa7164_work_enchandler); - } else if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) { - port->type = SAA7164_MPEG_VBI; - - /* We need a deferred interrupt handler for cmd handling */ - INIT_WORK(&port->workenc, saa7164_work_vbihandler); - } else - BUG(); - - /* Init all the critical resources */ - mutex_init(&port->dvb.lock); - INIT_LIST_HEAD(&port->dmaqueue.list); - mutex_init(&port->dmaqueue_lock); - - INIT_LIST_HEAD(&port->list_buf_used.list); - INIT_LIST_HEAD(&port->list_buf_free.list); - init_waitqueue_head(&port->wait_read); - - - saa7164_histogram_reset(&port->irq_interval, "irq intervals"); - saa7164_histogram_reset(&port->svc_interval, "deferred intervals"); - saa7164_histogram_reset(&port->irq_svc_interval, - "irq to deferred intervals"); - saa7164_histogram_reset(&port->read_interval, - "encoder/vbi read() intervals"); - saa7164_histogram_reset(&port->poll_interval, - "encoder/vbi poll() intervals"); - - return 0; -} - -static int saa7164_dev_setup(struct saa7164_dev *dev) -{ - int i; - - mutex_init(&dev->lock); - atomic_inc(&dev->refcount); - dev->nr = saa7164_devcount++; - - snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); - - /* board config */ - dev->board = UNSET; - if (card[dev->nr] < saa7164_bcount) - dev->board = card[dev->nr]; - - for (i = 0; UNSET == dev->board && i < saa7164_idcount; i++) - if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor && - dev->pci->subsystem_device == - saa7164_subids[i].subdevice) - dev->board = saa7164_subids[i].card; - - if (UNSET == dev->board) { - dev->board = SAA7164_BOARD_UNKNOWN; - saa7164_card_list(dev); - } - - dev->pci_bus = dev->pci->bus->number; - dev->pci_slot = PCI_SLOT(dev->pci->devfn); - - /* I2C Defaults / setup */ - dev->i2c_bus[0].dev = dev; - dev->i2c_bus[0].nr = 0; - dev->i2c_bus[1].dev = dev; - dev->i2c_bus[1].nr = 1; - dev->i2c_bus[2].dev = dev; - dev->i2c_bus[2].nr = 2; - - /* Transport + Encoder ports 1, 2, 3, 4 - Defaults / setup */ - saa7164_port_init(dev, SAA7164_PORT_TS1); - saa7164_port_init(dev, SAA7164_PORT_TS2); - saa7164_port_init(dev, SAA7164_PORT_ENC1); - saa7164_port_init(dev, SAA7164_PORT_ENC2); - saa7164_port_init(dev, SAA7164_PORT_VBI1); - saa7164_port_init(dev, SAA7164_PORT_VBI2); - - if (get_resources(dev) < 0) { - printk(KERN_ERR "CORE %s No more PCIe resources for " - "subsystem: %04x:%04x\n", - dev->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device); - - saa7164_devcount--; - return -ENODEV; - } - - /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); - - dev->bmmio = (u8 __iomem *)dev->lmmio; - dev->bmmio2 = (u8 __iomem *)dev->lmmio2; - - /* Inerrupt and ack register locations offset of bmmio */ - dev->int_status = 0x183000 + 0xf80; - dev->int_ack = 0x183000 + 0xf90; - - printk(KERN_INFO - "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", - dev->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device, saa7164_boards[dev->board].name, - dev->board, card[dev->nr] == dev->board ? - "insmod option" : "autodetected"); - - saa7164_pci_quirks(dev); - - return 0; -} - -static void saa7164_dev_unregister(struct saa7164_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); - - if (!atomic_dec_and_test(&dev->refcount)) - return; - - iounmap(dev->lmmio); - iounmap(dev->lmmio2); - - return; -} - -#ifdef CONFIG_PROC_FS -static int saa7164_proc_show(struct seq_file *m, void *v) -{ - struct saa7164_dev *dev; - struct tmComResBusInfo *b; - struct list_head *list; - int i, c; - - if (saa7164_devcount == 0) - return 0; - - list_for_each(list, &saa7164_devlist) { - dev = list_entry(list, struct saa7164_dev, devlist); - seq_printf(m, "%s = %p\n", dev->name, dev); - - /* Lock the bus from any other access */ - b = &dev->bus; - mutex_lock(&b->lock); - - seq_printf(m, " .m_pdwSetWritePos = 0x%x (0x%08x)\n", - b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos)); - - seq_printf(m, " .m_pdwSetReadPos = 0x%x (0x%08x)\n", - b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos)); - - seq_printf(m, " .m_pdwGetWritePos = 0x%x (0x%08x)\n", - b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos)); - - seq_printf(m, " .m_pdwGetReadPos = 0x%x (0x%08x)\n", - b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos)); - c = 0; - seq_printf(m, "\n Set Ring:\n"); - seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"); - for (i = 0; i < b->m_dwSizeSetRing; i++) { - if (c == 0) - seq_printf(m, " %04x:", i); - - seq_printf(m, " %02x", *(b->m_pdwSetRing + i)); - - if (++c == 16) { - seq_printf(m, "\n"); - c = 0; - } - } - - c = 0; - seq_printf(m, "\n Get Ring:\n"); - seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"); - for (i = 0; i < b->m_dwSizeGetRing; i++) { - if (c == 0) - seq_printf(m, " %04x:", i); - - seq_printf(m, " %02x", *(b->m_pdwGetRing + i)); - - if (++c == 16) { - seq_printf(m, "\n"); - c = 0; - } - } - - mutex_unlock(&b->lock); - - } - - return 0; -} - -static int saa7164_proc_open(struct inode *inode, struct file *filp) -{ - return single_open(filp, saa7164_proc_show, NULL); -} - -static const struct file_operations saa7164_proc_fops = { - .open = saa7164_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int saa7164_proc_create(void) -{ - struct proc_dir_entry *pe; - - pe = proc_create("saa7164", S_IRUGO, NULL, &saa7164_proc_fops); - if (!pe) - return -ENOMEM; - - return 0; -} -#endif - -static int saa7164_thread_function(void *data) -{ - struct saa7164_dev *dev = data; - struct tmFwInfoStruct fwinfo; - u64 last_poll_time = 0; - - dprintk(DBGLVL_THR, "thread started\n"); - - set_freezable(); - - while (1) { - msleep_interruptible(100); - if (kthread_should_stop()) - break; - try_to_freeze(); - - dprintk(DBGLVL_THR, "thread running\n"); - - /* Dump the firmware debug message to console */ - /* Polling this costs us 1-2% of the arm CPU */ - /* convert this into a respnde to interrupt 0x7a */ - saa7164_api_collect_debug(dev); - - /* Monitor CPU load every 1 second */ - if ((last_poll_time + 1000 /* ms */) < jiffies_to_msecs(jiffies)) { - saa7164_api_get_load_info(dev, &fwinfo); - last_poll_time = jiffies_to_msecs(jiffies); - } - - } - - dprintk(DBGLVL_THR, "thread exiting\n"); - return 0; -} - -static int __devinit saa7164_initdev(struct pci_dev *pci_dev, - const struct pci_device_id *pci_id) -{ - struct saa7164_dev *dev; - int err, i; - u32 version; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (NULL == dev) - return -ENOMEM; - - /* pci init */ - dev->pci = pci_dev; - if (pci_enable_device(pci_dev)) { - err = -EIO; - goto fail_free; - } - - if (saa7164_dev_setup(dev) < 0) { - err = -EINVAL; - goto fail_free; - } - - /* print pci info */ - dev->pci_rev = pci_dev->revision; - pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", dev->name, - pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat, - (unsigned long long)pci_resource_start(pci_dev, 0)); - - pci_set_master(pci_dev); - /* TODO */ - if (!pci_dma_supported(pci_dev, 0xffffffff)) { - printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); - err = -EIO; - goto fail_irq; - } - - err = request_irq(pci_dev->irq, saa7164_irq, - IRQF_SHARED | IRQF_DISABLED, dev->name, dev); - if (err < 0) { - printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name, - pci_dev->irq); - err = -EIO; - goto fail_irq; - } - - pci_set_drvdata(pci_dev, dev); - - /* Init the internal command list */ - for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) { - dev->cmds[i].seqno = i; - dev->cmds[i].inuse = 0; - mutex_init(&dev->cmds[i].lock); - init_waitqueue_head(&dev->cmds[i].wait); - } - - /* We need a deferred interrupt handler for cmd handling */ - INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler); - - /* Only load the firmware if we know the board */ - if (dev->board != SAA7164_BOARD_UNKNOWN) { - - err = saa7164_downloadfirmware(dev); - if (err < 0) { - printk(KERN_ERR - "Failed to boot firmware, no features " - "registered\n"); - goto fail_fw; - } - - saa7164_get_descriptors(dev); - saa7164_dumpregs(dev, 0); - saa7164_getcurrentfirmwareversion(dev); - saa7164_getfirmwarestatus(dev); - err = saa7164_bus_setup(dev); - if (err < 0) - printk(KERN_ERR - "Failed to setup the bus, will continue\n"); - saa7164_bus_dump(dev); - - /* Ping the running firmware via the command bus and get the - * firmware version, this checks the bus is running OK. - */ - version = 0; - if (saa7164_api_get_fw_version(dev, &version) == SAA_OK) - dprintk(1, "Bus is operating correctly using " - "version %d.%d.%d.%d (0x%x)\n", - (version & 0x0000fc00) >> 10, - (version & 0x000003e0) >> 5, - (version & 0x0000001f), - (version & 0xffff0000) >> 16, - version); - else - printk(KERN_ERR - "Failed to communicate with the firmware\n"); - - /* Bring up the I2C buses */ - saa7164_i2c_register(&dev->i2c_bus[0]); - saa7164_i2c_register(&dev->i2c_bus[1]); - saa7164_i2c_register(&dev->i2c_bus[2]); - saa7164_gpio_setup(dev); - saa7164_card_setup(dev); - - /* Parse the dynamic device configuration, find various - * media endpoints (MPEG, WMV, PS, TS) and cache their - * configuration details into the driver, so we can - * reference them later during simething_register() func, - * interrupt handlers, deferred work handlers etc. - */ - saa7164_api_enum_subdevs(dev); - - /* Begin to create the video sub-systems and register funcs */ - if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) { - if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS1]) < 0) { - printk(KERN_ERR "%s() Failed to register " - "dvb adapters on porta\n", - __func__); - } - } - - if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) { - if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS2]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "dvb adapters on portb\n", - __func__); - } - } - - if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) { - if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC1]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "mpeg encoder\n", __func__); - } - } - - if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) { - if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC2]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "mpeg encoder\n", __func__); - } - } - - if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) { - if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI1]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "vbi device\n", __func__); - } - } - - if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) { - if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI2]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "vbi device\n", __func__); - } - } - saa7164_api_set_debug(dev, fw_debug); - - if (fw_debug) { - dev->kthread = kthread_run(saa7164_thread_function, dev, - "saa7164 debug"); - if (!dev->kthread) - printk(KERN_ERR "%s() Failed to create " - "debug kernel thread\n", __func__); - } - - } /* != BOARD_UNKNOWN */ - else - printk(KERN_ERR "%s() Unsupported board detected, " - "registering without firmware\n", __func__); - - dprintk(1, "%s() parameter debug = %d\n", __func__, saa_debug); - dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs); - -fail_fw: - return 0; - -fail_irq: - saa7164_dev_unregister(dev); -fail_free: - kfree(dev); - return err; -} - -static void saa7164_shutdown(struct saa7164_dev *dev) -{ - dprintk(1, "%s()\n", __func__); -} - -static void __devexit saa7164_finidev(struct pci_dev *pci_dev) -{ - struct saa7164_dev *dev = pci_get_drvdata(pci_dev); - - if (dev->board != SAA7164_BOARD_UNKNOWN) { - if (fw_debug && dev->kthread) { - kthread_stop(dev->kthread); - dev->kthread = NULL; - } - if (dev->firmwareloaded) - saa7164_api_set_debug(dev, 0x00); - } - - saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], - &dev->ports[SAA7164_PORT_ENC1].irq_interval); - saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], - &dev->ports[SAA7164_PORT_ENC1].svc_interval); - saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], - &dev->ports[SAA7164_PORT_ENC1].irq_svc_interval); - saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], - &dev->ports[SAA7164_PORT_ENC1].read_interval); - saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], - &dev->ports[SAA7164_PORT_ENC1].poll_interval); - saa7164_histogram_print(&dev->ports[SAA7164_PORT_VBI1], - &dev->ports[SAA7164_PORT_VBI1].read_interval); - saa7164_histogram_print(&dev->ports[SAA7164_PORT_VBI2], - &dev->ports[SAA7164_PORT_VBI2].poll_interval); - - saa7164_shutdown(dev); - - if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) - saa7164_dvb_unregister(&dev->ports[SAA7164_PORT_TS1]); - - if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) - saa7164_dvb_unregister(&dev->ports[SAA7164_PORT_TS2]); - - if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) - saa7164_encoder_unregister(&dev->ports[SAA7164_PORT_ENC1]); - - if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) - saa7164_encoder_unregister(&dev->ports[SAA7164_PORT_ENC2]); - - if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) - saa7164_vbi_unregister(&dev->ports[SAA7164_PORT_VBI1]); - - if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) - saa7164_vbi_unregister(&dev->ports[SAA7164_PORT_VBI2]); - - saa7164_i2c_unregister(&dev->i2c_bus[0]); - saa7164_i2c_unregister(&dev->i2c_bus[1]); - saa7164_i2c_unregister(&dev->i2c_bus[2]); - - pci_disable_device(pci_dev); - - /* unregister stuff */ - free_irq(pci_dev->irq, dev); - pci_set_drvdata(pci_dev, NULL); - - mutex_lock(&devlist); - list_del(&dev->devlist); - mutex_unlock(&devlist); - - saa7164_dev_unregister(dev); - kfree(dev); -} - -static struct pci_device_id saa7164_pci_tbl[] = { - { - /* SAA7164 */ - .vendor = 0x1131, - .device = 0x7164, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { - /* --- end of list --- */ - } -}; -MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl); - -static struct pci_driver saa7164_pci_driver = { - .name = "saa7164", - .id_table = saa7164_pci_tbl, - .probe = saa7164_initdev, - .remove = __devexit_p(saa7164_finidev), - /* TODO */ - .suspend = NULL, - .resume = NULL, -}; - -static int __init saa7164_init(void) -{ - printk(KERN_INFO "saa7164 driver loaded\n"); - -#ifdef CONFIG_PROC_FS - saa7164_proc_create(); -#endif - return pci_register_driver(&saa7164_pci_driver); -} - -static void __exit saa7164_fini(void) -{ -#ifdef CONFIG_PROC_FS - remove_proc_entry("saa7164", NULL); -#endif - pci_unregister_driver(&saa7164_pci_driver); -} - -module_init(saa7164_init); -module_exit(saa7164_fini); - diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c deleted file mode 100644 index 5c5cc3ebf9bd..000000000000 --- a/drivers/media/video/saa7164/saa7164-dvb.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "saa7164.h" - -#include "tda10048.h" -#include "tda18271.h" -#include "s5h1411.h" - -#define DRIVER_NAME "saa7164" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -/* addr is in the card struct, get it from there */ -static struct tda10048_config hauppauge_hvr2200_1_config = { - .demod_address = 0x10 >> 1, - .output_mode = TDA10048_SERIAL_OUTPUT, - .fwbulkwritelen = TDA10048_BULKWRITE_200, - .inversion = TDA10048_INVERSION_ON, - .dtv6_if_freq_khz = TDA10048_IF_3300, - .dtv7_if_freq_khz = TDA10048_IF_3500, - .dtv8_if_freq_khz = TDA10048_IF_4000, - .clk_freq_khz = TDA10048_CLK_16000, -}; -static struct tda10048_config hauppauge_hvr2200_2_config = { - .demod_address = 0x12 >> 1, - .output_mode = TDA10048_SERIAL_OUTPUT, - .fwbulkwritelen = TDA10048_BULKWRITE_200, - .inversion = TDA10048_INVERSION_ON, - .dtv6_if_freq_khz = TDA10048_IF_3300, - .dtv7_if_freq_khz = TDA10048_IF_3500, - .dtv8_if_freq_khz = TDA10048_IF_4000, - .clk_freq_khz = TDA10048_CLK_16000, -}; - -static struct tda18271_std_map hauppauge_tda18271_std_map = { - .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3, - .if_lvl = 6, .rfagc_top = 0x37 }, - .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, - .if_lvl = 6, .rfagc_top = 0x37 }, -}; - -static struct tda18271_config hauppauge_hvr22x0_tuner_config = { - .std_map = &hauppauge_tda18271_std_map, - .gate = TDA18271_GATE_ANALOG, - .role = TDA18271_MASTER, -}; - -static struct tda18271_config hauppauge_hvr22x0s_tuner_config = { - .std_map = &hauppauge_tda18271_std_map, - .gate = TDA18271_GATE_ANALOG, - .role = TDA18271_SLAVE, - .output_opt = TDA18271_OUTPUT_LT_OFF, - .rf_cal_on_startup = 1 -}; - -static struct s5h1411_config hauppauge_s5h1411_config = { - .output_mode = S5H1411_SERIAL_OUTPUT, - .gpio = S5H1411_GPIO_ON, - .qam_if = S5H1411_IF_4000, - .vsb_if = S5H1411_IF_3250, - .inversion = S5H1411_INVERSION_ON, - .status_mode = S5H1411_DEMODLOCKING, - .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static int saa7164_dvb_stop_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__); - ret = 0; - } - - return ret; -} - -static int saa7164_dvb_acquire_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__); - ret = 0; - } - - return ret; -} - -static int saa7164_dvb_pause_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_DVB, "%s() Paused\n", __func__); - ret = 0; - } - - return ret; -} - -/* Firmware is very windows centric, meaning you have to transition - * the part through AVStream / KS Windows stages, forwards or backwards. - * States are: stopped, acquired (h/w), paused, started. - */ -static int saa7164_dvb_stop_streaming(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct list_head *p, *q; - int ret; - - dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); - - ret = saa7164_dvb_pause_port(port); - ret = saa7164_dvb_acquire_port(port); - ret = saa7164_dvb_stop_port(port); - - /* Mark the hardware buffers as free */ - mutex_lock(&port->dmaqueue_lock); - list_for_each_safe(p, q, &port->dmaqueue.list) { - buf = list_entry(p, struct saa7164_buffer, list); - buf->flags = SAA7164_BUFFER_FREE; - } - mutex_unlock(&port->dmaqueue_lock); - - return ret; -} - -static int saa7164_dvb_start_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret = 0, result; - - dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); - - saa7164_buffer_cfg_port(port); - - /* Acquire the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n", - __func__, result); - - /* Stop the hardware, regardless */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire/forced stop transition " - "failed, res = 0x%x\n", __func__, result); - } - ret = -EIO; - goto out; - } else - dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__); - - /* Pause the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n", - __func__, result); - - /* Stop the hardware, regardless */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause/forced stop transition " - "failed, res = 0x%x\n", __func__, result); - } - - ret = -EIO; - goto out; - } else - dprintk(DBGLVL_DVB, "%s() Paused\n", __func__); - - /* Start the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() run transition failed, result = 0x%x\n", - __func__, result); - - /* Stop the hardware, regardless */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() run/forced stop transition " - "failed, res = 0x%x\n", __func__, result); - } - - ret = -EIO; - } else - dprintk(DBGLVL_DVB, "%s() Running\n", __func__); - -out: - return ret; -} - -static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct saa7164_port *port = (struct saa7164_port *) demux->priv; - struct saa7164_dvb *dvb = &port->dvb; - struct saa7164_dev *dev = port->dev; - int ret = 0; - - dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); - - if (!demux->dmx.frontend) - return -EINVAL; - - if (dvb) { - mutex_lock(&dvb->lock); - if (dvb->feeding++ == 0) { - /* Start transport */ - ret = saa7164_dvb_start_port(port); - } - mutex_unlock(&dvb->lock); - dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", - __func__, port->nr, dvb->feeding); - } - - return ret; -} - -static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct saa7164_port *port = (struct saa7164_port *) demux->priv; - struct saa7164_dvb *dvb = &port->dvb; - struct saa7164_dev *dev = port->dev; - int ret = 0; - - dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); - - if (dvb) { - mutex_lock(&dvb->lock); - if (--dvb->feeding == 0) { - /* Stop transport */ - ret = saa7164_dvb_stop_streaming(port); - } - mutex_unlock(&dvb->lock); - dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", - __func__, port->nr, dvb->feeding); - } - - return ret; -} - -static int dvb_register(struct saa7164_port *port) -{ - struct saa7164_dvb *dvb = &port->dvb; - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - int result, i; - - dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); - - if (port->type != SAA7164_MPEG_DVB) - BUG(); - - /* Sanity check that the PCI configuration space is active */ - if (port->hwcfg.BARLocation == 0) { - result = -ENOMEM; - printk(KERN_ERR "%s: dvb_register_adapter failed " - "(errno = %d), NO PCI configuration\n", - DRIVER_NAME, result); - goto fail_adapter; - } - - /* Init and establish defaults */ - port->hw_streamingparams.bitspersample = 8; - port->hw_streamingparams.samplesperline = 188; - port->hw_streamingparams.numberoflines = - (SAA7164_TS_NUMBER_OF_LINES * 188) / 188; - - port->hw_streamingparams.pitch = 188; - port->hw_streamingparams.linethreshold = 0; - port->hw_streamingparams.pagetablelistvirt = NULL; - port->hw_streamingparams.pagetablelistphys = NULL; - port->hw_streamingparams.numpagetables = 2 + - ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE); - - port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount; - - /* Allocate the PCI resources */ - for (i = 0; i < port->hwcfg.buffercount; i++) { - buf = saa7164_buffer_alloc(port, - port->hw_streamingparams.numberoflines * - port->hw_streamingparams.pitch); - - if (!buf) { - result = -ENOMEM; - printk(KERN_ERR "%s: dvb_register_adapter failed " - "(errno = %d), unable to allocate buffers\n", - DRIVER_NAME, result); - goto fail_adapter; - } - - mutex_lock(&port->dmaqueue_lock); - list_add_tail(&buf->list, &port->dmaqueue.list); - mutex_unlock(&port->dmaqueue_lock); - } - - /* register adapter */ - result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE, - &dev->pci->dev, adapter_nr); - if (result < 0) { - printk(KERN_ERR "%s: dvb_register_adapter failed " - "(errno = %d)\n", DRIVER_NAME, result); - goto fail_adapter; - } - dvb->adapter.priv = port; - - /* register frontend */ - result = dvb_register_frontend(&dvb->adapter, dvb->frontend); - if (result < 0) { - printk(KERN_ERR "%s: dvb_register_frontend failed " - "(errno = %d)\n", DRIVER_NAME, result); - goto fail_frontend; - } - - /* register demux stuff */ - dvb->demux.dmx.capabilities = - DMX_TS_FILTERING | DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING; - dvb->demux.priv = port; - dvb->demux.filternum = 256; - dvb->demux.feednum = 256; - dvb->demux.start_feed = saa7164_dvb_start_feed; - dvb->demux.stop_feed = saa7164_dvb_stop_feed; - result = dvb_dmx_init(&dvb->demux); - if (result < 0) { - printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n", - DRIVER_NAME, result); - goto fail_dmx; - } - - dvb->dmxdev.filternum = 256; - dvb->dmxdev.demux = &dvb->demux.dmx; - dvb->dmxdev.capabilities = 0; - result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); - if (result < 0) { - printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n", - DRIVER_NAME, result); - goto fail_dmxdev; - } - - dvb->fe_hw.source = DMX_FRONTEND_0; - result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); - if (result < 0) { - printk(KERN_ERR "%s: add_frontend failed " - "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result); - goto fail_fe_hw; - } - - dvb->fe_mem.source = DMX_MEMORY_FE; - result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); - if (result < 0) { - printk(KERN_ERR "%s: add_frontend failed " - "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result); - goto fail_fe_mem; - } - - result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); - if (result < 0) { - printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n", - DRIVER_NAME, result); - goto fail_fe_conn; - } - - /* register network adapter */ - dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); - return 0; - -fail_fe_conn: - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); -fail_fe_mem: - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); -fail_fe_hw: - dvb_dmxdev_release(&dvb->dmxdev); -fail_dmxdev: - dvb_dmx_release(&dvb->demux); -fail_dmx: - dvb_unregister_frontend(dvb->frontend); -fail_frontend: - dvb_frontend_detach(dvb->frontend); - dvb_unregister_adapter(&dvb->adapter); -fail_adapter: - return result; -} - -int saa7164_dvb_unregister(struct saa7164_port *port) -{ - struct saa7164_dvb *dvb = &port->dvb; - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *b; - struct list_head *c, *n; - - dprintk(DBGLVL_DVB, "%s()\n", __func__); - - if (port->type != SAA7164_MPEG_DVB) - BUG(); - - /* Remove any allocated buffers */ - mutex_lock(&port->dmaqueue_lock); - list_for_each_safe(c, n, &port->dmaqueue.list) { - b = list_entry(c, struct saa7164_buffer, list); - list_del(c); - saa7164_buffer_dealloc(b); - } - mutex_unlock(&port->dmaqueue_lock); - - if (dvb->frontend == NULL) - return 0; - - dvb_net_release(&dvb->net); - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); - dvb_dmxdev_release(&dvb->dmxdev); - dvb_dmx_release(&dvb->demux); - dvb_unregister_frontend(dvb->frontend); - dvb_frontend_detach(dvb->frontend); - dvb_unregister_adapter(&dvb->adapter); - return 0; -} - -/* All the DVB attach calls go here, this function get's modified - * for each new card. - */ -int saa7164_dvb_register(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_dvb *dvb = &port->dvb; - struct saa7164_i2c *i2c_bus = NULL; - int ret; - - dprintk(DBGLVL_DVB, "%s()\n", __func__); - - /* init frontend */ - switch (dev->board) { - case SAA7164_BOARD_HAUPPAUGE_HVR2200: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: - case SAA7164_BOARD_HAUPPAUGE_HVR2200_5: - i2c_bus = &dev->i2c_bus[port->nr + 1]; - switch (port->nr) { - case 0: - port->dvb.frontend = dvb_attach(tda10048_attach, - &hauppauge_hvr2200_1_config, - &i2c_bus->i2c_adap); - - if (port->dvb.frontend != NULL) { - /* TODO: addr is in the card struct */ - dvb_attach(tda18271_attach, port->dvb.frontend, - 0xc0 >> 1, &i2c_bus->i2c_adap, - &hauppauge_hvr22x0_tuner_config); - } - - break; - case 1: - port->dvb.frontend = dvb_attach(tda10048_attach, - &hauppauge_hvr2200_2_config, - &i2c_bus->i2c_adap); - - if (port->dvb.frontend != NULL) { - /* TODO: addr is in the card struct */ - dvb_attach(tda18271_attach, port->dvb.frontend, - 0xc0 >> 1, &i2c_bus->i2c_adap, - &hauppauge_hvr22x0s_tuner_config); - } - - break; - } - break; - case SAA7164_BOARD_HAUPPAUGE_HVR2250: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: - i2c_bus = &dev->i2c_bus[port->nr + 1]; - - port->dvb.frontend = dvb_attach(s5h1411_attach, - &hauppauge_s5h1411_config, - &i2c_bus->i2c_adap); - - if (port->dvb.frontend != NULL) { - if (port->nr == 0) { - /* Master TDA18271 */ - /* TODO: addr is in the card struct */ - dvb_attach(tda18271_attach, port->dvb.frontend, - 0xc0 >> 1, &i2c_bus->i2c_adap, - &hauppauge_hvr22x0_tuner_config); - } else { - /* Slave TDA18271 */ - dvb_attach(tda18271_attach, port->dvb.frontend, - 0xc0 >> 1, &i2c_bus->i2c_adap, - &hauppauge_hvr22x0s_tuner_config); - } - } - - break; - default: - printk(KERN_ERR "%s: The frontend isn't supported\n", - dev->name); - break; - } - if (NULL == dvb->frontend) { - printk(KERN_ERR "%s() Frontend initialization failed\n", - __func__); - return -1; - } - - /* register everything */ - ret = dvb_register(port); - if (ret < 0) { - if (dvb->frontend->ops.release) - dvb->frontend->ops.release(dvb->frontend); - return ret; - } - - return 0; -} - diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c deleted file mode 100644 index a9ed686ad08a..000000000000 --- a/drivers/media/video/saa7164/saa7164-encoder.c +++ /dev/null @@ -1,1500 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "saa7164.h" - -#define ENCODER_MAX_BITRATE 6500000 -#define ENCODER_MIN_BITRATE 1000000 -#define ENCODER_DEF_BITRATE 5000000 - -static struct saa7164_tvnorm saa7164_tvnorms[] = { - { - .name = "NTSC-M", - .id = V4L2_STD_NTSC_M, - }, { - .name = "NTSC-JP", - .id = V4L2_STD_NTSC_M_JP, - } -}; - -static const u32 saa7164_v4l2_ctrls[] = { - V4L2_CID_BRIGHTNESS, - V4L2_CID_CONTRAST, - V4L2_CID_SATURATION, - V4L2_CID_HUE, - V4L2_CID_AUDIO_VOLUME, - V4L2_CID_SHARPNESS, - V4L2_CID_MPEG_STREAM_TYPE, - V4L2_CID_MPEG_VIDEO_ASPECT, - V4L2_CID_MPEG_VIDEO_B_FRAMES, - V4L2_CID_MPEG_VIDEO_GOP_SIZE, - V4L2_CID_MPEG_AUDIO_MUTE, - V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - V4L2_CID_MPEG_VIDEO_BITRATE, - V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, - 0 -}; - -/* Take the encoder configuration form the port struct and - * flush it to the hardware. - */ -static void saa7164_encoder_configure(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - port->encoder_params.width = port->width; - port->encoder_params.height = port->height; - port->encoder_params.is_50hz = - (port->encodernorm.id & V4L2_STD_625_50) != 0; - - /* Set up the DIF (enable it) for analog mode by default */ - saa7164_api_initialize_dif(port); - - /* Configure the correct video standard */ - saa7164_api_configure_dif(port, port->encodernorm.id); - - /* Ensure the audio decoder is correct configured */ - saa7164_api_set_audio_std(port); -} - -static int saa7164_encoder_buffers_dealloc(struct saa7164_port *port) -{ - struct list_head *c, *n, *p, *q, *l, *v; - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct saa7164_user_buffer *ubuf; - - /* Remove any allocated buffers */ - mutex_lock(&port->dmaqueue_lock); - - dprintk(DBGLVL_ENC, "%s(port=%d) dmaqueue\n", __func__, port->nr); - list_for_each_safe(c, n, &port->dmaqueue.list) { - buf = list_entry(c, struct saa7164_buffer, list); - list_del(c); - saa7164_buffer_dealloc(buf); - } - - dprintk(DBGLVL_ENC, "%s(port=%d) used\n", __func__, port->nr); - list_for_each_safe(p, q, &port->list_buf_used.list) { - ubuf = list_entry(p, struct saa7164_user_buffer, list); - list_del(p); - saa7164_buffer_dealloc_user(ubuf); - } - - dprintk(DBGLVL_ENC, "%s(port=%d) free\n", __func__, port->nr); - list_for_each_safe(l, v, &port->list_buf_free.list) { - ubuf = list_entry(l, struct saa7164_user_buffer, list); - list_del(l); - saa7164_buffer_dealloc_user(ubuf); - } - - mutex_unlock(&port->dmaqueue_lock); - dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr); - - return 0; -} - -/* Dynamic buffer switch at encoder start time */ -static int saa7164_encoder_buffers_alloc(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct saa7164_user_buffer *ubuf; - struct tmHWStreamParameters *params = &port->hw_streamingparams; - int result = -ENODEV, i; - int len = 0; - - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - if (port->encoder_params.stream_type == - V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { - dprintk(DBGLVL_ENC, - "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", - __func__); - params->samplesperline = 128; - params->numberoflines = 256; - params->pitch = 128; - params->numpagetables = 2 + - ((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE); - } else - if (port->encoder_params.stream_type == - V4L2_MPEG_STREAM_TYPE_MPEG2_TS) { - dprintk(DBGLVL_ENC, - "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", - __func__); - params->samplesperline = 188; - params->numberoflines = 312; - params->pitch = 188; - params->numpagetables = 2 + - ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE); - } else - BUG(); - - /* Init and establish defaults */ - params->bitspersample = 8; - params->linethreshold = 0; - params->pagetablelistvirt = NULL; - params->pagetablelistphys = NULL; - params->numpagetableentries = port->hwcfg.buffercount; - - /* Allocate the PCI resources, buffers (hard) */ - for (i = 0; i < port->hwcfg.buffercount; i++) { - buf = saa7164_buffer_alloc(port, - params->numberoflines * - params->pitch); - - if (!buf) { - printk(KERN_ERR "%s() failed " - "(errno = %d), unable to allocate buffer\n", - __func__, result); - result = -ENOMEM; - goto failed; - } else { - - mutex_lock(&port->dmaqueue_lock); - list_add_tail(&buf->list, &port->dmaqueue.list); - mutex_unlock(&port->dmaqueue_lock); - - } - } - - /* Allocate some kernel buffers for copying - * to userpsace. - */ - len = params->numberoflines * params->pitch; - - if (encoder_buffers < 16) - encoder_buffers = 16; - if (encoder_buffers > 512) - encoder_buffers = 512; - - for (i = 0; i < encoder_buffers; i++) { - - ubuf = saa7164_buffer_alloc_user(dev, len); - if (ubuf) { - mutex_lock(&port->dmaqueue_lock); - list_add_tail(&ubuf->list, &port->list_buf_free.list); - mutex_unlock(&port->dmaqueue_lock); - } - - } - - result = 0; - -failed: - return result; -} - -static int saa7164_encoder_initialize(struct saa7164_port *port) -{ - saa7164_encoder_configure(port); - return 0; -} - -/* -- V4L2 --------------------------------------------------------- */ -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - unsigned int i; - - dprintk(DBGLVL_ENC, "%s(id=0x%x)\n", __func__, (u32)*id); - - for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) { - if (*id & saa7164_tvnorms[i].id) - break; - } - if (i == ARRAY_SIZE(saa7164_tvnorms)) - return -EINVAL; - - port->encodernorm = saa7164_tvnorms[i]; - - /* Update the audio decoder while is not running in - * auto detect mode. - */ - saa7164_api_set_audio_std(port); - - dprintk(DBGLVL_ENC, "%s(id=0x%x) OK\n", __func__, (u32)*id); - - return 0; -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - int n; - - char *inputs[] = { "tuner", "composite", "svideo", "aux", - "composite 2", "svideo 2", "aux 2" }; - - if (i->index >= 7) - return -EINVAL; - - strcpy(i->name, inputs[i->index]); - - if (i->index == 0) - i->type = V4L2_INPUT_TYPE_TUNER; - else - i->type = V4L2_INPUT_TYPE_CAMERA; - - for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++) - i->std |= saa7164_tvnorms[n].id; - - return 0; -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - if (saa7164_api_get_videomux(port) != SAA_OK) - return -EIO; - - *i = (port->mux_input - 1); - - dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, *i); - - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, i); - - if (i >= 7) - return -EINVAL; - - port->mux_input = i + 1; - - if (saa7164_api_set_videomux(port) != SAA_OK) - return -EIO; - - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - if (0 != t->index) - return -EINVAL; - - strcpy(t->name, "tuner"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO; - - dprintk(DBGLVL_ENC, "VIDIOC_G_TUNER: tuner type %d\n", t->type); - - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - /* Update the A/V core */ - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = port->freq; - - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - struct saa7164_port *tsport; - struct dvb_frontend *fe; - - /* TODO: Pull this for the std */ - struct analog_parameters params = { - .mode = V4L2_TUNER_ANALOG_TV, - .audmode = V4L2_TUNER_MODE_STEREO, - .std = port->encodernorm.id, - .frequency = f->frequency - }; - - /* Stop the encoder */ - dprintk(DBGLVL_ENC, "%s() frequency=%d tuner=%d\n", __func__, - f->frequency, f->tuner); - - if (f->tuner != 0) - return -EINVAL; - - if (f->type != V4L2_TUNER_ANALOG_TV) - return -EINVAL; - - port->freq = f->frequency; - - /* Update the hardware */ - if (port->nr == SAA7164_PORT_ENC1) - tsport = &dev->ports[SAA7164_PORT_TS1]; - else - if (port->nr == SAA7164_PORT_ENC2) - tsport = &dev->ports[SAA7164_PORT_TS2]; - else - BUG(); - - fe = tsport->dvb.frontend; - - if (fe && fe->ops.tuner_ops.set_analog_params) - fe->ops.tuner_ops.set_analog_params(fe, ¶ms); - else - printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__); - - saa7164_encoder_initialize(port); - - return 0; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__, - ctl->id, ctl->value); - - switch (ctl->id) { - case V4L2_CID_BRIGHTNESS: - ctl->value = port->ctl_brightness; - break; - case V4L2_CID_CONTRAST: - ctl->value = port->ctl_contrast; - break; - case V4L2_CID_SATURATION: - ctl->value = port->ctl_saturation; - break; - case V4L2_CID_HUE: - ctl->value = port->ctl_hue; - break; - case V4L2_CID_SHARPNESS: - ctl->value = port->ctl_sharpness; - break; - case V4L2_CID_AUDIO_VOLUME: - ctl->value = port->ctl_volume; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - int ret = 0; - - dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__, - ctl->id, ctl->value); - - switch (ctl->id) { - case V4L2_CID_BRIGHTNESS: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_brightness = ctl->value; - saa7164_api_set_usercontrol(port, - PU_BRIGHTNESS_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_CONTRAST: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_contrast = ctl->value; - saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_SATURATION: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_saturation = ctl->value; - saa7164_api_set_usercontrol(port, - PU_SATURATION_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_HUE: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_hue = ctl->value; - saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_SHARPNESS: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_sharpness = ctl->value; - saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_AUDIO_VOLUME: - if ((ctl->value >= -83) && (ctl->value <= 24)) { - port->ctl_volume = ctl->value; - saa7164_api_set_audio_volume(port, port->ctl_volume); - } else - ret = -EINVAL; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int saa7164_get_ctrl(struct saa7164_port *port, - struct v4l2_ext_control *ctrl) -{ - struct saa7164_encoder_params *params = &port->encoder_params; - - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_BITRATE: - ctrl->value = params->bitrate; - break; - case V4L2_CID_MPEG_STREAM_TYPE: - ctrl->value = params->stream_type; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - ctrl->value = params->ctl_mute; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - ctrl->value = params->ctl_aspect; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - ctrl->value = params->bitrate_mode; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - ctrl->value = params->refdist; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - ctrl->value = params->bitrate_peak; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - ctrl->value = params->gop_size; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_get_ctrl(port, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - -static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) -{ - int ret = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_BITRATE: - if ((ctrl->value >= ENCODER_MIN_BITRATE) && - (ctrl->value <= ENCODER_MAX_BITRATE)) - ret = 0; - break; - case V4L2_CID_MPEG_STREAM_TYPE: - if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) || - (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)) - ret = 0; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - if ((ctrl->value >= 0) && - (ctrl->value <= 1)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) && - (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - if ((ctrl->value >= 0) && - (ctrl->value <= 255)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - if ((ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) || - (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - if ((ctrl->value >= 1) && - (ctrl->value <= 3)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - if ((ctrl->value >= ENCODER_MIN_BITRATE) && - (ctrl->value <= ENCODER_MAX_BITRATE)) - ret = 0; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_try_ctrl(ctrl, 0); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - } - - return -EINVAL; -} - -static int saa7164_set_ctrl(struct saa7164_port *port, - struct v4l2_ext_control *ctrl) -{ - struct saa7164_encoder_params *params = &port->encoder_params; - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_BITRATE: - params->bitrate = ctrl->value; - break; - case V4L2_CID_MPEG_STREAM_TYPE: - params->stream_type = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - params->ctl_mute = ctrl->value; - ret = saa7164_api_audio_mute(port, params->ctl_mute); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, - ret); - ret = -EIO; - } - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - params->ctl_aspect = ctrl->value; - ret = saa7164_api_set_aspect_ratio(port); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, - ret); - ret = -EIO; - } - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - params->bitrate_mode = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - params->refdist = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - params->bitrate_peak = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - params->gop_size = ctrl->value; - break; - default: - return -EINVAL; - } - - /* TODO: Update the hardware */ - - return ret; -} - -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_try_ctrl(ctrl, 0); - if (err) { - ctrls->error_idx = i; - break; - } - err = saa7164_set_ctrl(port, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - strcpy(cap->driver, dev->name); - strlcpy(cap->card, saa7164_boards[dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - 0; - - cap->capabilities |= V4L2_CAP_TUNER; - cap->version = 0; - - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (f->index != 0) - return -EINVAL; - - strlcpy(f->description, "MPEG", sizeof(f->description)); - f->pixelformat = V4L2_PIX_FMT_MPEG; - - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - f->fmt.pix.width = port->width; - f->fmt.pix.height = port->height; - - dprintk(DBGLVL_ENC, "VIDIOC_G_FMT: w: %d, h: %d\n", - port->width, port->height); - - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(DBGLVL_ENC, "VIDIOC_TRY_FMT: w: %d, h: %d\n", - port->width, port->height); - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - - dprintk(DBGLVL_ENC, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); - - return 0; -} - -static int fill_queryctrl(struct saa7164_encoder_params *params, - struct v4l2_queryctrl *c) -{ - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128); - case V4L2_CID_SHARPNESS: - return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8); - case V4L2_CID_MPEG_AUDIO_MUTE: - return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(c, -83, 24, 1, 20); - case V4L2_CID_MPEG_VIDEO_BITRATE: - return v4l2_ctrl_query_fill(c, - ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE, - 100000, ENCODER_DEF_BITRATE); - case V4L2_CID_MPEG_STREAM_TYPE: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - V4L2_MPEG_STREAM_TYPE_MPEG2_TS, - 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS); - case V4L2_CID_MPEG_VIDEO_ASPECT: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_VIDEO_ASPECT_1x1, - V4L2_MPEG_VIDEO_ASPECT_221x100, - 1, V4L2_MPEG_VIDEO_ASPECT_4x3); - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - return v4l2_ctrl_query_fill(c, 1, 255, 1, 15); - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, - 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - return v4l2_ctrl_query_fill(c, - 1, 3, 1, 1); - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - return v4l2_ctrl_query_fill(c, - ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE, - 100000, ENCODER_DEF_BITRATE); - default: - return -EINVAL; - } -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct saa7164_encoder_fh *fh = priv; - struct saa7164_port *port = fh->port; - int i, next; - u32 id = c->id; - - memset(c, 0, sizeof(*c)); - - next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); - c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; - - for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) { - if (next) { - if (c->id < saa7164_v4l2_ctrls[i]) - c->id = saa7164_v4l2_ctrls[i]; - else - continue; - } - - if (c->id == saa7164_v4l2_ctrls[i]) - return fill_queryctrl(&port->encoder_params, c); - - if (c->id < saa7164_v4l2_ctrls[i]) - break; - } - - return -EINVAL; -} - -static int saa7164_encoder_stop_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_ENC, "%s() Stopped\n", __func__); - ret = 0; - } - - return ret; -} - -static int saa7164_encoder_acquire_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__); - ret = 0; - } - - return ret; -} - -static int saa7164_encoder_pause_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_ENC, "%s() Paused\n", __func__); - ret = 0; - } - - return ret; -} - -/* Firmware is very windows centric, meaning you have to transition - * the part through AVStream / KS Windows stages, forwards or backwards. - * States are: stopped, acquired (h/w), paused, started. - * We have to leave here will all of the soft buffers on the free list, - * else the cfg_post() func won't have soft buffers to correctly configure. - */ -static int saa7164_encoder_stop_streaming(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct saa7164_user_buffer *ubuf; - struct list_head *c, *n; - int ret; - - dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr); - - ret = saa7164_encoder_pause_port(port); - ret = saa7164_encoder_acquire_port(port); - ret = saa7164_encoder_stop_port(port); - - dprintk(DBGLVL_ENC, "%s(port=%d) Hardware stopped\n", __func__, - port->nr); - - /* Reset the state of any allocated buffer resources */ - mutex_lock(&port->dmaqueue_lock); - - /* Reset the hard and soft buffer state */ - list_for_each_safe(c, n, &port->dmaqueue.list) { - buf = list_entry(c, struct saa7164_buffer, list); - buf->flags = SAA7164_BUFFER_FREE; - buf->pos = 0; - } - - list_for_each_safe(c, n, &port->list_buf_used.list) { - ubuf = list_entry(c, struct saa7164_user_buffer, list); - ubuf->pos = 0; - list_move_tail(&ubuf->list, &port->list_buf_free.list); - } - - mutex_unlock(&port->dmaqueue_lock); - - /* Free any allocated resources */ - saa7164_encoder_buffers_dealloc(port); - - dprintk(DBGLVL_ENC, "%s(port=%d) Released\n", __func__, port->nr); - - return ret; -} - -static int saa7164_encoder_start_streaming(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int result, ret = 0; - - dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr); - - port->done_first_interrupt = 0; - - /* allocate all of the PCIe DMA buffer resources on the fly, - * allowing switching between TS and PS payloads without - * requiring a complete driver reload. - */ - saa7164_encoder_buffers_alloc(port); - - /* Configure the encoder with any cache values */ - saa7164_api_set_encoder(port); - saa7164_api_get_encoder(port); - - /* Place the empty buffers on the hardware */ - saa7164_buffer_cfg_port(port); - - /* Acquire the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n", - __func__, result); - - /* Stop the hardware, regardless */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire/forced stop transition " - "failed, res = 0x%x\n", __func__, result); - } - ret = -EIO; - goto out; - } else - dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__); - - /* Pause the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n", - __func__, result); - - /* Stop the hardware, regardless */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause/forced stop transition " - "failed, res = 0x%x\n", __func__, result); - } - - ret = -EIO; - goto out; - } else - dprintk(DBGLVL_ENC, "%s() Paused\n", __func__); - - /* Start the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() run transition failed, result = 0x%x\n", - __func__, result); - - /* Stop the hardware, regardless */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() run/forced stop transition " - "failed, res = 0x%x\n", __func__, result); - } - - ret = -EIO; - } else - dprintk(DBGLVL_ENC, "%s() Running\n", __func__); - -out: - return ret; -} - -static int fops_open(struct file *file) -{ - struct saa7164_dev *dev; - struct saa7164_port *port; - struct saa7164_encoder_fh *fh; - - port = (struct saa7164_port *)video_get_drvdata(video_devdata(file)); - if (!port) - return -ENODEV; - - dev = port->dev; - - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) - return -ENOMEM; - - file->private_data = fh; - fh->port = port; - - return 0; -} - -static int fops_release(struct file *file) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - /* Shut device down on last close */ - if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { - if (atomic_dec_return(&port->v4l_reader_count) == 0) { - /* stop mpeg capture then cancel buffers */ - saa7164_encoder_stop_streaming(port); - } - } - - file->private_data = NULL; - kfree(fh); - - return 0; -} - -struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port) -{ - struct saa7164_user_buffer *ubuf = NULL; - struct saa7164_dev *dev = port->dev; - u32 crc; - - mutex_lock(&port->dmaqueue_lock); - if (!list_empty(&port->list_buf_used.list)) { - ubuf = list_first_entry(&port->list_buf_used.list, - struct saa7164_user_buffer, list); - - if (crc_checking) { - crc = crc32(0, ubuf->data, ubuf->actual_size); - if (crc != ubuf->crc) { - printk(KERN_ERR - "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", - __func__, - ubuf, ubuf->crc, crc); - } - } - - } - mutex_unlock(&port->dmaqueue_lock); - - dprintk(DBGLVL_ENC, "%s() returns %p\n", __func__, ubuf); - - return ubuf; -} - -static ssize_t fops_read(struct file *file, char __user *buffer, - size_t count, loff_t *pos) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_user_buffer *ubuf = NULL; - struct saa7164_dev *dev = port->dev; - int ret = 0; - int rem, cnt; - u8 *p; - - port->last_read_msecs_diff = port->last_read_msecs; - port->last_read_msecs = jiffies_to_msecs(jiffies); - port->last_read_msecs_diff = port->last_read_msecs - - port->last_read_msecs_diff; - - saa7164_histogram_update(&port->read_interval, - port->last_read_msecs_diff); - - if (*pos) { - printk(KERN_ERR "%s() ESPIPE\n", __func__); - return -ESPIPE; - } - - if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { - if (atomic_inc_return(&port->v4l_reader_count) == 1) { - - if (saa7164_encoder_initialize(port) < 0) { - printk(KERN_ERR "%s() EINVAL\n", __func__); - return -EINVAL; - } - - saa7164_encoder_start_streaming(port); - msleep(200); - } - } - - /* blocking wait for buffer */ - if ((file->f_flags & O_NONBLOCK) == 0) { - if (wait_event_interruptible(port->wait_read, - saa7164_enc_next_buf(port))) { - printk(KERN_ERR "%s() ERESTARTSYS\n", __func__); - return -ERESTARTSYS; - } - } - - /* Pull the first buffer from the used list */ - ubuf = saa7164_enc_next_buf(port); - - while ((count > 0) && ubuf) { - - /* set remaining bytes to copy */ - rem = ubuf->actual_size - ubuf->pos; - cnt = rem > count ? count : rem; - - p = ubuf->data + ubuf->pos; - - dprintk(DBGLVL_ENC, - "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n", - __func__, (int)count, cnt, rem, ubuf, ubuf->pos); - - if (copy_to_user(buffer, p, cnt)) { - printk(KERN_ERR "%s() copy_to_user failed\n", __func__); - if (!ret) { - printk(KERN_ERR "%s() EFAULT\n", __func__); - ret = -EFAULT; - } - goto err; - } - - ubuf->pos += cnt; - count -= cnt; - buffer += cnt; - ret += cnt; - - if (ubuf->pos > ubuf->actual_size) - printk(KERN_ERR "read() pos > actual, huh?\n"); - - if (ubuf->pos == ubuf->actual_size) { - - /* finished with current buffer, take next buffer */ - - /* Requeue the buffer on the free list */ - ubuf->pos = 0; - - mutex_lock(&port->dmaqueue_lock); - list_move_tail(&ubuf->list, &port->list_buf_free.list); - mutex_unlock(&port->dmaqueue_lock); - - /* Dequeue next */ - if ((file->f_flags & O_NONBLOCK) == 0) { - if (wait_event_interruptible(port->wait_read, - saa7164_enc_next_buf(port))) { - break; - } - } - ubuf = saa7164_enc_next_buf(port); - } - } -err: - if (!ret && !ubuf) - ret = -EAGAIN; - - return ret; -} - -static unsigned int fops_poll(struct file *file, poll_table *wait) -{ - struct saa7164_encoder_fh *fh = - (struct saa7164_encoder_fh *)file->private_data; - struct saa7164_port *port = fh->port; - unsigned int mask = 0; - - port->last_poll_msecs_diff = port->last_poll_msecs; - port->last_poll_msecs = jiffies_to_msecs(jiffies); - port->last_poll_msecs_diff = port->last_poll_msecs - - port->last_poll_msecs_diff; - - saa7164_histogram_update(&port->poll_interval, - port->last_poll_msecs_diff); - - if (!video_is_registered(port->v4l_device)) - return -EIO; - - if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { - if (atomic_inc_return(&port->v4l_reader_count) == 1) { - if (saa7164_encoder_initialize(port) < 0) - return -EINVAL; - saa7164_encoder_start_streaming(port); - msleep(200); - } - } - - /* blocking wait for buffer */ - if ((file->f_flags & O_NONBLOCK) == 0) { - if (wait_event_interruptible(port->wait_read, - saa7164_enc_next_buf(port))) { - return -ERESTARTSYS; - } - } - - /* Pull the first buffer from the used list */ - if (!list_empty(&port->list_buf_used.list)) - mask |= POLLIN | POLLRDNORM; - - return mask; -} - -static const struct v4l2_file_operations mpeg_fops = { - .owner = THIS_MODULE, - .open = fops_open, - .release = fops_release, - .read = fops_read, - .poll = fops_poll, - .unlocked_ioctl = video_ioctl2, -}; - -int saa7164_g_chip_ident(struct file *file, void *fh, - struct v4l2_dbg_chip_ident *chip) -{ - struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port; - struct saa7164_dev *dev = port->dev; - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - return 0; -} - -int saa7164_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port; - struct saa7164_dev *dev = port->dev; - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - return 0; -} - -int saa7164_s_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port; - struct saa7164_dev *dev = port->dev; - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - return 0; -} - -static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_chip_ident = saa7164_g_chip_ident, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = saa7164_g_register, - .vidioc_s_register = saa7164_s_register, -#endif -}; - -static struct video_device saa7164_mpeg_template = { - .name = "saa7164", - .fops = &mpeg_fops, - .ioctl_ops = &mpeg_ioctl_ops, - .minor = -1, - .tvnorms = SAA7164_NORMS, - .current_norm = V4L2_STD_NTSC_M, -}; - -static struct video_device *saa7164_encoder_alloc( - struct saa7164_port *port, - struct pci_dev *pci, - struct video_device *template, - char *type) -{ - struct video_device *vfd; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - - *vfd = *template; - snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, - type, saa7164_boards[dev->board].name); - - vfd->parent = &pci->dev; - vfd->release = video_device_release; - return vfd; -} - -int saa7164_encoder_register(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int result = -ENODEV; - - dprintk(DBGLVL_ENC, "%s()\n", __func__); - - if (port->type != SAA7164_MPEG_ENCODER) - BUG(); - - /* Sanity check that the PCI configuration space is active */ - if (port->hwcfg.BARLocation == 0) { - printk(KERN_ERR "%s() failed " - "(errno = %d), NO PCI configuration\n", - __func__, result); - result = -ENOMEM; - goto failed; - } - - /* Establish encoder defaults here */ - /* Set default TV standard */ - port->encodernorm = saa7164_tvnorms[0]; - port->width = 720; - port->mux_input = 1; /* Composite */ - port->video_format = EU_VIDEO_FORMAT_MPEG_2; - port->audio_format = 0; - port->video_resolution = 0; - port->ctl_brightness = 127; - port->ctl_contrast = 66; - port->ctl_hue = 128; - port->ctl_saturation = 62; - port->ctl_sharpness = 8; - port->encoder_params.bitrate = ENCODER_DEF_BITRATE; - port->encoder_params.bitrate_peak = ENCODER_DEF_BITRATE; - port->encoder_params.bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; - port->encoder_params.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS; - port->encoder_params.ctl_mute = 0; - port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3; - port->encoder_params.refdist = 1; - port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE; - - if (port->encodernorm.id & V4L2_STD_525_60) - port->height = 480; - else - port->height = 576; - - /* Allocate and register the video device node */ - port->v4l_device = saa7164_encoder_alloc(port, - dev->pci, &saa7164_mpeg_template, "mpeg"); - - if (!port->v4l_device) { - printk(KERN_INFO "%s: can't allocate mpeg device\n", - dev->name); - result = -ENOMEM; - goto failed; - } - - video_set_drvdata(port->v4l_device, port); - result = video_register_device(port->v4l_device, - VFL_TYPE_GRABBER, -1); - if (result < 0) { - printk(KERN_INFO "%s: can't register mpeg device\n", - dev->name); - /* TODO: We're going to leak here if we don't dealloc - The buffers above. The unreg function can't deal wit it. - */ - goto failed; - } - - printk(KERN_INFO "%s: registered device video%d [mpeg]\n", - dev->name, port->v4l_device->num); - - /* Configure the hardware defaults */ - saa7164_api_set_videomux(port); - saa7164_api_set_usercontrol(port, PU_BRIGHTNESS_CONTROL); - saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); - saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); - saa7164_api_set_usercontrol(port, PU_SATURATION_CONTROL); - saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); - saa7164_api_audio_mute(port, 0); - saa7164_api_set_audio_volume(port, 20); - saa7164_api_set_aspect_ratio(port); - - /* Disable audio standard detection, it's buggy */ - saa7164_api_set_audio_detection(port, 0); - - saa7164_api_set_encoder(port); - saa7164_api_get_encoder(port); - - result = 0; -failed: - return result; -} - -void saa7164_encoder_unregister(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr); - - if (port->type != SAA7164_MPEG_ENCODER) - BUG(); - - if (port->v4l_device) { - if (port->v4l_device->minor != -1) - video_unregister_device(port->v4l_device); - else - video_device_release(port->v4l_device); - - port->v4l_device = NULL; - } - - dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr); -} - diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c deleted file mode 100644 index a266bf0169e6..000000000000 --- a/drivers/media/video/saa7164/saa7164-fw.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/firmware.h> -#include <linux/slab.h> - -#include "saa7164.h" - -#define SAA7164_REV2_FIRMWARE "NXP7164-2010-03-10.1.fw" -#define SAA7164_REV2_FIRMWARE_SIZE 4019072 - -#define SAA7164_REV3_FIRMWARE "NXP7164-2010-03-10.1.fw" -#define SAA7164_REV3_FIRMWARE_SIZE 4019072 - -struct fw_header { - u32 firmwaresize; - u32 bslsize; - u32 reserved; - u32 version; -}; - -int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg) -{ - u32 timeout = SAA_DEVICE_TIMEOUT; - while ((saa7164_readl(reg) & 0x01) == 0) { - timeout -= 10; - if (timeout == 0) { - printk(KERN_ERR "%s() timeout (no d/l ack)\n", - __func__); - return -EBUSY; - } - msleep(100); - } - - return 0; -} - -int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg) -{ - u32 timeout = SAA_DEVICE_TIMEOUT; - while (saa7164_readl(reg) & 0x01) { - timeout -= 10; - if (timeout == 0) { - printk(KERN_ERR "%s() timeout (no d/l clr)\n", - __func__); - return -EBUSY; - } - msleep(100); - } - - return 0; -} - -/* TODO: move dlflags into dev-> and change to write/readl/b */ -/* TODO: Excessive levels of debug */ -int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize, - u32 dlflags, u8 *dst, u32 dstsize) -{ - u32 reg, timeout, offset; - u8 *srcbuf = NULL; - int ret; - - u32 dlflag = dlflags; - u32 dlflag_ack = dlflag + 4; - u32 drflag = dlflag_ack + 4; - u32 drflag_ack = drflag + 4; - u32 bleflag = drflag_ack + 4; - - dprintk(DBGLVL_FW, - "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n", - __func__, src, srcsize, dlflags, dst, dstsize); - - if ((src == NULL) || (dst == NULL)) { - ret = -EIO; - goto out; - } - - srcbuf = kzalloc(4 * 1048576, GFP_KERNEL); - if (NULL == srcbuf) { - ret = -ENOMEM; - goto out; - } - - if (srcsize > (4*1048576)) { - ret = -ENOMEM; - goto out; - } - - memcpy(srcbuf, src, srcsize); - - dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag); - dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack); - dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag); - dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack); - dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag); - - reg = saa7164_readl(dlflag); - dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg); - if (reg == 1) - dprintk(DBGLVL_FW, - "%s() Download flag already set, please reboot\n", - __func__); - - /* Indicate download start */ - saa7164_writel(dlflag, 1); - ret = saa7164_dl_wait_ack(dev, dlflag_ack); - if (ret < 0) - goto out; - - /* Ack download start, then wait for wait */ - saa7164_writel(dlflag, 0); - ret = saa7164_dl_wait_clr(dev, dlflag_ack); - if (ret < 0) - goto out; - - /* Deal with the raw firmware, in the appropriate chunk size */ - for (offset = 0; srcsize > dstsize; - srcsize -= dstsize, offset += dstsize) { - - dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize); - memcpy(dst, srcbuf + offset, dstsize); - - /* Flag the data as ready */ - saa7164_writel(drflag, 1); - ret = saa7164_dl_wait_ack(dev, drflag_ack); - if (ret < 0) - goto out; - - /* Wait for indication data was received */ - saa7164_writel(drflag, 0); - ret = saa7164_dl_wait_clr(dev, drflag_ack); - if (ret < 0) - goto out; - - } - - dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize); - /* Write last block to the device */ - memcpy(dst, srcbuf+offset, srcsize); - - /* Flag the data as ready */ - saa7164_writel(drflag, 1); - ret = saa7164_dl_wait_ack(dev, drflag_ack); - if (ret < 0) - goto out; - - saa7164_writel(drflag, 0); - timeout = 0; - while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) { - if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) { - printk(KERN_ERR "%s() image corrupt\n", __func__); - ret = -EBUSY; - goto out; - } - - if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) { - printk(KERN_ERR "%s() device memory corrupt\n", - __func__); - ret = -EBUSY; - goto out; - } - - msleep(10); /* Checkpatch throws a < 20ms warning */ - if (timeout++ > 60) - break; - } - - printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__); - - ret = saa7164_dl_wait_clr(dev, drflag_ack); - if (ret < 0) - goto out; - - printk(KERN_INFO "%s() Image booted successfully.\n", __func__); - ret = 0; - -out: - kfree(srcbuf); - return ret; -} - -/* TODO: Excessive debug */ -/* Load the firmware. Optionally it can be in ROM or newer versions - * can be on disk, saving the expense of the ROM hardware. */ -int saa7164_downloadfirmware(struct saa7164_dev *dev) -{ - /* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */ - u32 tmp, filesize, version, err_flags, first_timeout, fwlength; - u32 second_timeout, updatebootloader = 1, bootloadersize = 0; - const struct firmware *fw = NULL; - struct fw_header *hdr, *boothdr = NULL, *fwhdr; - u32 bootloaderversion = 0, fwloadersize; - u8 *bootloaderoffset = NULL, *fwloaderoffset; - char *fwname; - int ret; - - dprintk(DBGLVL_FW, "%s()\n", __func__); - - if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) { - fwname = SAA7164_REV2_FIRMWARE; - fwlength = SAA7164_REV2_FIRMWARE_SIZE; - } else { - fwname = SAA7164_REV3_FIRMWARE; - fwlength = SAA7164_REV3_FIRMWARE_SIZE; - } - - version = saa7164_getcurrentfirmwareversion(dev); - - if (version == 0x00) { - - second_timeout = 100; - first_timeout = 100; - err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS); - dprintk(DBGLVL_FW, "%s() err_flags = %x\n", - __func__, err_flags); - - while (err_flags != SAA_DEVICE_IMAGE_BOOTING) { - dprintk(DBGLVL_FW, "%s() err_flags = %x\n", - __func__, err_flags); - msleep(10); /* Checkpatch throws a < 20ms warning */ - - if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) { - printk(KERN_ERR "%s() firmware corrupt\n", - __func__); - break; - } - if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) { - printk(KERN_ERR "%s() device memory corrupt\n", - __func__); - break; - } - if (err_flags & SAA_DEVICE_NO_IMAGE) { - printk(KERN_ERR "%s() no first image\n", - __func__); - break; - } - if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) { - first_timeout -= 10; - if (first_timeout == 0) { - printk(KERN_ERR - "%s() no first image\n", - __func__); - break; - } - } else if (err_flags & SAA_DEVICE_IMAGE_LOADING) { - second_timeout -= 10; - if (second_timeout == 0) { - printk(KERN_ERR - "%s() FW load time exceeded\n", - __func__); - break; - } - } else { - second_timeout -= 10; - if (second_timeout == 0) { - printk(KERN_ERR - "%s() Unknown bootloader flags 0x%x\n", - __func__, err_flags); - break; - } - } - - err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS); - } /* While != Booting */ - - if (err_flags == SAA_DEVICE_IMAGE_BOOTING) { - dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n", - __func__); - first_timeout = SAA_DEVICE_TIMEOUT; - second_timeout = 60 * SAA_DEVICE_TIMEOUT; - second_timeout = 100; - - err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS); - dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n", - __func__, err_flags); - while (err_flags != SAA_DEVICE_IMAGE_BOOTING) { - dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n", - __func__, err_flags); - msleep(10); /* Checkpatch throws a < 20ms warning */ - - if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) { - printk(KERN_ERR - "%s() firmware corrupt\n", - __func__); - break; - } - if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) { - printk(KERN_ERR - "%s() device memory corrupt\n", - __func__); - break; - } - if (err_flags & SAA_DEVICE_NO_IMAGE) { - printk(KERN_ERR "%s() no first image\n", - __func__); - break; - } - if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) { - first_timeout -= 10; - if (first_timeout == 0) { - printk(KERN_ERR - "%s() no second image\n", - __func__); - break; - } - } else if (err_flags & - SAA_DEVICE_IMAGE_LOADING) { - second_timeout -= 10; - if (second_timeout == 0) { - printk(KERN_ERR - "%s() FW load time exceeded\n", - __func__); - break; - } - } else { - second_timeout -= 10; - if (second_timeout == 0) { - printk(KERN_ERR - "%s() Unknown bootloader flags 0x%x\n", - __func__, err_flags); - break; - } - } - - err_flags = - saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS); - } /* err_flags != SAA_DEVICE_IMAGE_BOOTING */ - - dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n", - __func__, - saa7164_readl(SAA_BOOTLOADERERROR_FLAGS), - saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS)); - - } /* err_flags == SAA_DEVICE_IMAGE_BOOTING */ - - /* It's possible for both firmwares to have booted, - * but that doesn't mean they've finished booting yet. - */ - if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) == - SAA_DEVICE_IMAGE_BOOTING) && - (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) == - SAA_DEVICE_IMAGE_BOOTING)) { - - - dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n", - __func__); - - first_timeout = SAA_DEVICE_TIMEOUT; - while (first_timeout) { - msleep(10); /* Checkpatch throws a < 20ms warning */ - - version = - saa7164_getcurrentfirmwareversion(dev); - if (version) { - dprintk(DBGLVL_FW, - "%s() All f/w loaded successfully\n", - __func__); - break; - } else { - first_timeout -= 10; - if (first_timeout == 0) { - printk(KERN_ERR - "%s() FW did not boot\n", - __func__); - break; - } - } - } - } - version = saa7164_getcurrentfirmwareversion(dev); - } /* version == 0 */ - - /* Has the firmware really booted? */ - if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) == - SAA_DEVICE_IMAGE_BOOTING) && - (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) == - SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) { - - printk(KERN_ERR - "%s() The firmware hung, probably bad firmware\n", - __func__); - - /* Tell the second stage loader we have a deadlock */ - saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET, - SAA_DEVICE_DEADLOCK_DETECTED); - - saa7164_getfirmwarestatus(dev); - - return -ENOMEM; - } - - dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n", - (version & 0x0000fc00) >> 10, - (version & 0x000003e0) >> 5, - (version & 0x0000001f), - (version & 0xffff0000) >> 16); - - /* Load the firmwware from the disk if required */ - if (version == 0) { - - printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n", - __func__, fwname); - - ret = request_firmware(&fw, fwname, &dev->pci->dev); - if (ret) { - printk(KERN_ERR "%s() Upload failed. " - "(file not found?)\n", __func__); - return -ENOMEM; - } - - printk(KERN_INFO "%s() firmware read %Zu bytes.\n", - __func__, fw->size); - - if (fw->size != fwlength) { - printk(KERN_ERR "xc5000: firmware incorrect size\n"); - ret = -ENOMEM; - goto out; - } - - printk(KERN_INFO "%s() firmware loaded.\n", __func__); - - hdr = (struct fw_header *)fw->data; - printk(KERN_INFO "Firmware file header part 1:\n"); - printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize); - printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize); - printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved); - printk(KERN_INFO " .Version = 0x%x\n", hdr->version); - - /* Retrieve bootloader if reqd */ - if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) - /* Second bootloader in the firmware file */ - filesize = hdr->reserved * 16; - else - filesize = (hdr->firmwaresize + hdr->bslsize) * - 16 + sizeof(struct fw_header); - - printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n", - __func__, filesize); - - /* Get bootloader (if reqd) and firmware header */ - if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) { - /* Second boot loader is required */ - - /* Get the loader header */ - boothdr = (struct fw_header *)(fw->data + - sizeof(struct fw_header)); - - bootloaderversion = - saa7164_readl(SAA_DEVICE_2ND_VERSION); - dprintk(DBGLVL_FW, "Onboard BootLoader:\n"); - dprintk(DBGLVL_FW, "->Flag 0x%x\n", - saa7164_readl(SAA_BOOTLOADERERROR_FLAGS)); - dprintk(DBGLVL_FW, "->Ack 0x%x\n", - saa7164_readl(SAA_DATAREADY_FLAG_ACK)); - dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version); - dprintk(DBGLVL_FW, "->Loader Version 0x%x\n", - bootloaderversion); - - if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) == - 0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK) - == 0x00) && (version == 0x00)) { - - dprintk(DBGLVL_FW, "BootLoader version in " - "rom %d.%d.%d.%d\n", - (bootloaderversion & 0x0000fc00) >> 10, - (bootloaderversion & 0x000003e0) >> 5, - (bootloaderversion & 0x0000001f), - (bootloaderversion & 0xffff0000) >> 16 - ); - dprintk(DBGLVL_FW, "BootLoader version " - "in file %d.%d.%d.%d\n", - (boothdr->version & 0x0000fc00) >> 10, - (boothdr->version & 0x000003e0) >> 5, - (boothdr->version & 0x0000001f), - (boothdr->version & 0xffff0000) >> 16 - ); - - if (bootloaderversion == boothdr->version) - updatebootloader = 0; - } - - /* Calculate offset to firmware header */ - tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 + - (sizeof(struct fw_header) + - sizeof(struct fw_header)); - - fwhdr = (struct fw_header *)(fw->data+tmp); - } else { - /* No second boot loader */ - fwhdr = hdr; - } - - dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n", - (fwhdr->version & 0x0000fc00) >> 10, - (fwhdr->version & 0x000003e0) >> 5, - (fwhdr->version & 0x0000001f), - (fwhdr->version & 0xffff0000) >> 16 - ); - - if (version == fwhdr->version) { - /* No download, firmware already on board */ - ret = 0; - goto out; - } - - if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) { - if (updatebootloader) { - /* Get ready to upload the bootloader */ - bootloadersize = (boothdr->firmwaresize + - boothdr->bslsize) * 16 + - sizeof(struct fw_header); - - bootloaderoffset = (u8 *)(fw->data + - sizeof(struct fw_header)); - - dprintk(DBGLVL_FW, "bootloader d/l starts.\n"); - printk(KERN_INFO "%s() FirmwareSize = 0x%x\n", - __func__, boothdr->firmwaresize); - printk(KERN_INFO "%s() BSLSize = 0x%x\n", - __func__, boothdr->bslsize); - printk(KERN_INFO "%s() Reserved = 0x%x\n", - __func__, boothdr->reserved); - printk(KERN_INFO "%s() Version = 0x%x\n", - __func__, boothdr->version); - ret = saa7164_downloadimage( - dev, - bootloaderoffset, - bootloadersize, - SAA_DOWNLOAD_FLAGS, - dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET, - SAA_DEVICE_BUFFERBLOCKSIZE); - if (ret < 0) { - printk(KERN_ERR - "bootloader d/l has failed\n"); - goto out; - } - dprintk(DBGLVL_FW, - "bootloader download complete.\n"); - - } - - printk(KERN_ERR "starting firmware download(2)\n"); - bootloadersize = (boothdr->firmwaresize + - boothdr->bslsize) * 16 + - sizeof(struct fw_header); - - bootloaderoffset = - (u8 *)(fw->data + sizeof(struct fw_header)); - - fwloaderoffset = bootloaderoffset + bootloadersize; - - /* TODO: fix this bounds overrun here with old f/ws */ - fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) * - 16 + sizeof(struct fw_header); - - ret = saa7164_downloadimage( - dev, - fwloaderoffset, - fwloadersize, - SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET, - dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET, - SAA_DEVICE_2ND_BUFFERBLOCKSIZE); - if (ret < 0) { - printk(KERN_ERR "firmware download failed\n"); - goto out; - } - printk(KERN_ERR "firmware download complete.\n"); - - } else { - - /* No bootloader update reqd, download firmware only */ - printk(KERN_ERR "starting firmware download(3)\n"); - - ret = saa7164_downloadimage( - dev, - (u8 *)fw->data, - fw->size, - SAA_DOWNLOAD_FLAGS, - dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET, - SAA_DEVICE_BUFFERBLOCKSIZE); - if (ret < 0) { - printk(KERN_ERR "firmware download failed\n"); - goto out; - } - printk(KERN_ERR "firmware download complete.\n"); - } - } - - dev->firmwareloaded = 1; - ret = 0; - -out: - release_firmware(fw); - return ret; -} diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c deleted file mode 100644 index 4f7e3b42263f..000000000000 --- a/drivers/media/video/saa7164/saa7164-i2c.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/io.h> - -#include "saa7164.h" - -static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) -{ - struct saa7164_i2c *bus = i2c_adap->algo_data; - struct saa7164_dev *dev = bus->dev; - int i, retval = 0; - - dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num); - - for (i = 0 ; i < num; i++) { - dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x len = 0x%x\n", - __func__, num, msgs[i].addr, msgs[i].len); - if (msgs[i].flags & I2C_M_RD) { - /* Unsupported - Yet*/ - printk(KERN_ERR "%s() Unsupported - Yet\n", __func__); - continue; - } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && - msgs[i].addr == msgs[i + 1].addr) { - /* write then read from same address */ - - retval = saa7164_api_i2c_read(bus, msgs[i].addr, - msgs[i].len, msgs[i].buf, - msgs[i+1].len, msgs[i+1].buf - ); - - i++; - - if (retval < 0) - goto err; - } else { - /* write */ - retval = saa7164_api_i2c_write(bus, msgs[i].addr, - msgs[i].len, msgs[i].buf); - } - if (retval < 0) - goto err; - } - return num; - -err: - return retval; -} - -static u32 saa7164_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm saa7164_i2c_algo_template = { - .master_xfer = i2c_xfer, - .functionality = saa7164_functionality, -}; - -/* ----------------------------------------------------------------------- */ - -static struct i2c_adapter saa7164_i2c_adap_template = { - .name = "saa7164", - .owner = THIS_MODULE, - .algo = &saa7164_i2c_algo_template, -}; - -static struct i2c_client saa7164_i2c_client_template = { - .name = "saa7164 internal", -}; - -int saa7164_i2c_register(struct saa7164_i2c *bus) -{ - struct saa7164_dev *dev = bus->dev; - - dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr); - - bus->i2c_adap = saa7164_i2c_adap_template; - bus->i2c_client = saa7164_i2c_client_template; - - bus->i2c_adap.dev.parent = &dev->pci->dev; - - strlcpy(bus->i2c_adap.name, bus->dev->name, - sizeof(bus->i2c_adap.name)); - - bus->i2c_adap.algo_data = bus; - i2c_set_adapdata(&bus->i2c_adap, bus); - i2c_add_adapter(&bus->i2c_adap); - - bus->i2c_client.adapter = &bus->i2c_adap; - - if (0 != bus->i2c_rc) - printk(KERN_ERR "%s: i2c bus %d register FAILED\n", - dev->name, bus->nr); - - return bus->i2c_rc; -} - -int saa7164_i2c_unregister(struct saa7164_i2c *bus) -{ - i2c_del_adapter(&bus->i2c_adap); - return 0; -} diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/video/saa7164/saa7164-reg.h deleted file mode 100644 index 2bbf81583d33..000000000000 --- a/drivers/media/video/saa7164/saa7164-reg.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* TODO: Retest the driver with errors expressed as negatives */ - -/* Result codes */ -#define SAA_OK 0 -#define SAA_ERR_BAD_PARAMETER 0x09 -#define SAA_ERR_NO_RESOURCES 0x0c -#define SAA_ERR_NOT_SUPPORTED 0x13 -#define SAA_ERR_BUSY 0x15 -#define SAA_ERR_READ 0x17 -#define SAA_ERR_TIMEOUT 0x1f -#define SAA_ERR_OVERFLOW 0x20 -#define SAA_ERR_EMPTY 0x22 -#define SAA_ERR_NOT_STARTED 0x23 -#define SAA_ERR_ALREADY_STARTED 0x24 -#define SAA_ERR_NOT_STOPPED 0x25 -#define SAA_ERR_ALREADY_STOPPED 0x26 -#define SAA_ERR_INVALID_COMMAND 0x3e -#define SAA_ERR_NULL_PACKET 0x59 - -/* Errors and flags from the silicon */ -#define PVC_ERRORCODE_UNKNOWN 0x00 -#define PVC_ERRORCODE_INVALID_COMMAND 0x01 -#define PVC_ERRORCODE_INVALID_CONTROL 0x02 -#define PVC_ERRORCODE_INVALID_DATA 0x03 -#define PVC_ERRORCODE_TIMEOUT 0x04 -#define PVC_ERRORCODE_NAK 0x05 -#define PVC_RESPONSEFLAG_ERROR 0x01 -#define PVC_RESPONSEFLAG_OVERFLOW 0x02 -#define PVC_RESPONSEFLAG_RESET 0x04 -#define PVC_RESPONSEFLAG_INTERFACE 0x08 -#define PVC_RESPONSEFLAG_CONTINUED 0x10 -#define PVC_CMDFLAG_INTERRUPT 0x02 -#define PVC_CMDFLAG_INTERFACE 0x04 -#define PVC_CMDFLAG_SERIALIZE 0x08 -#define PVC_CMDFLAG_CONTINUE 0x10 - -/* Silicon Commands */ -#define GET_DESCRIPTORS_CONTROL 0x01 -#define GET_STRING_CONTROL 0x03 -#define GET_LANGUAGE_CONTROL 0x05 -#define SET_POWER_CONTROL 0x07 -#define GET_FW_STATUS_CONTROL 0x08 -#define GET_FW_VERSION_CONTROL 0x09 -#define SET_DEBUG_LEVEL_CONTROL 0x0B -#define GET_DEBUG_DATA_CONTROL 0x0C -#define GET_PRODUCTION_INFO_CONTROL 0x0D - -/* cmd defines */ -#define SAA_CMDFLAG_CONTINUE 0x10 -#define SAA_CMD_MAX_MSG_UNITS 256 - -/* Some defines */ -#define SAA_BUS_TIMEOUT 50 -#define SAA_DEVICE_TIMEOUT 5000 -#define SAA_DEVICE_MAXREQUESTSIZE 256 - -/* Register addresses */ -#define SAA_DEVICE_VERSION 0x30 -#define SAA_DOWNLOAD_FLAGS 0x34 -#define SAA_DOWNLOAD_FLAG 0x34 -#define SAA_DOWNLOAD_FLAG_ACK 0x38 -#define SAA_DATAREADY_FLAG 0x3C -#define SAA_DATAREADY_FLAG_ACK 0x40 - -/* Boot loader register and bit definitions */ -#define SAA_BOOTLOADERERROR_FLAGS 0x44 -#define SAA_DEVICE_IMAGE_SEARCHING 0x01 -#define SAA_DEVICE_IMAGE_LOADING 0x02 -#define SAA_DEVICE_IMAGE_BOOTING 0x03 -#define SAA_DEVICE_IMAGE_CORRUPT 0x04 -#define SAA_DEVICE_MEMORY_CORRUPT 0x08 -#define SAA_DEVICE_NO_IMAGE 0x10 - -/* Register addresses */ -#define SAA_DEVICE_2ND_VERSION 0x50 -#define SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET 0x54 - -/* Register addresses */ -#define SAA_SECONDSTAGEERROR_FLAGS 0x64 - -/* Bootloader regs and flags */ -#define SAA_DEVICE_DEADLOCK_DETECTED_OFFSET 0x6C -#define SAA_DEVICE_DEADLOCK_DETECTED 0xDEADDEAD - -/* Basic firmware status registers */ -#define SAA_DEVICE_SYSINIT_STATUS_OFFSET 0x70 -#define SAA_DEVICE_SYSINIT_STATUS 0x70 -#define SAA_DEVICE_SYSINIT_MODE 0x74 -#define SAA_DEVICE_SYSINIT_SPEC 0x78 -#define SAA_DEVICE_SYSINIT_INST 0x7C -#define SAA_DEVICE_SYSINIT_CPULOAD 0x80 -#define SAA_DEVICE_SYSINIT_REMAINHEAP 0x84 - -#define SAA_DEVICE_DOWNLOAD_OFFSET 0x1000 -#define SAA_DEVICE_BUFFERBLOCKSIZE 0x1000 - -#define SAA_DEVICE_2ND_BUFFERBLOCKSIZE 0x100000 -#define SAA_DEVICE_2ND_DOWNLOAD_OFFSET 0x200000 - -/* Descriptors */ -#define CS_INTERFACE 0x24 - -/* Descriptor subtypes */ -#define VC_INPUT_TERMINAL 0x02 -#define VC_OUTPUT_TERMINAL 0x03 -#define VC_SELECTOR_UNIT 0x04 -#define VC_PROCESSING_UNIT 0x05 -#define FEATURE_UNIT 0x06 -#define TUNER_UNIT 0x09 -#define ENCODER_UNIT 0x0A -#define EXTENSION_UNIT 0x0B -#define VC_TUNER_PATH 0xF0 -#define PVC_HARDWARE_DESCRIPTOR 0xF1 -#define PVC_INTERFACE_DESCRIPTOR 0xF2 -#define PVC_INFRARED_UNIT 0xF3 -#define DRM_UNIT 0xF4 -#define GENERAL_REQUEST 0xF5 - -/* Format Types */ -#define VS_FORMAT_TYPE 0x02 -#define VS_FORMAT_TYPE_I 0x01 -#define VS_FORMAT_UNCOMPRESSED 0x04 -#define VS_FRAME_UNCOMPRESSED 0x05 -#define VS_FORMAT_MPEG2PS 0x09 -#define VS_FORMAT_MPEG2TS 0x0A -#define VS_FORMAT_MPEG4SL 0x0B -#define VS_FORMAT_WM9 0x0C -#define VS_FORMAT_DIVX 0x0D -#define VS_FORMAT_VBI 0x0E -#define VS_FORMAT_RDS 0x0F - -/* Device extension commands */ -#define EXU_REGISTER_ACCESS_CONTROL 0x00 -#define EXU_GPIO_CONTROL 0x01 -#define EXU_GPIO_GROUP_CONTROL 0x02 -#define EXU_INTERRUPT_CONTROL 0x03 - -/* State Transition and args */ -#define SAA_PROBE_CONTROL 0x01 -#define SAA_COMMIT_CONTROL 0x02 -#define SAA_STATE_CONTROL 0x03 -#define SAA_DMASTATE_STOP 0x00 -#define SAA_DMASTATE_ACQUIRE 0x01 -#define SAA_DMASTATE_PAUSE 0x02 -#define SAA_DMASTATE_RUN 0x03 - -/* A/V Mux Input Selector */ -#define SU_INPUT_SELECT_CONTROL 0x01 - -/* Encoder Profiles */ -#define EU_PROFILE_PS_DVD 0x06 -#define EU_PROFILE_TS_HQ 0x09 -#define EU_VIDEO_FORMAT_MPEG_2 0x02 - -/* Tuner */ -#define TU_AUDIO_MODE_CONTROL 0x17 - -/* Video Formats */ -#define TU_STANDARD_CONTROL 0x00 -#define TU_STANDARD_AUTO_CONTROL 0x01 -#define TU_STANDARD_NONE 0x00 -#define TU_STANDARD_NTSC_M 0x01 -#define TU_STANDARD_PAL_I 0x08 -#define TU_STANDARD_MANUAL 0x00 -#define TU_STANDARD_AUTO 0x01 - -/* Video Controls */ -#define PU_BRIGHTNESS_CONTROL 0x02 -#define PU_CONTRAST_CONTROL 0x03 -#define PU_HUE_CONTROL 0x06 -#define PU_SATURATION_CONTROL 0x07 -#define PU_SHARPNESS_CONTROL 0x08 - -/* Audio Controls */ -#define MUTE_CONTROL 0x01 -#define VOLUME_CONTROL 0x02 -#define AUDIO_DEFAULT_CONTROL 0x0D - -/* Default Volume Levels */ -#define TMHW_LEV_ADJ_DECLEV_DEFAULT 0x00 -#define TMHW_LEV_ADJ_MONOLEV_DEFAULT 0x00 -#define TMHW_LEV_ADJ_NICLEV_DEFAULT 0x00 -#define TMHW_LEV_ADJ_SAPLEV_DEFAULT 0x00 -#define TMHW_LEV_ADJ_ADCLEV_DEFAULT 0x00 - -/* Encoder Related Commands */ -#define EU_PROFILE_CONTROL 0x00 -#define EU_VIDEO_FORMAT_CONTROL 0x01 -#define EU_VIDEO_BIT_RATE_CONTROL 0x02 -#define EU_VIDEO_RESOLUTION_CONTROL 0x03 -#define EU_VIDEO_GOP_STRUCTURE_CONTROL 0x04 -#define EU_VIDEO_INPUT_ASPECT_CONTROL 0x0A -#define EU_AUDIO_FORMAT_CONTROL 0x0C -#define EU_AUDIO_BIT_RATE_CONTROL 0x0D - -/* Firmware Debugging */ -#define SET_DEBUG_LEVEL_CONTROL 0x0B -#define GET_DEBUG_DATA_CONTROL 0x0C diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h deleted file mode 100644 index 1d2140a3eb38..000000000000 --- a/drivers/media/video/saa7164/saa7164-types.h +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* TODO: Cleanup and shorten the namespace */ - -/* Some structues are passed directly to/from the firmware and - * have strict alignment requirements. This is one of them. - */ -struct tmComResHWDescr { - u8 bLength; - u8 bDescriptorType; - u8 bDescriptorSubtype; - u16 bcdSpecVersion; - u32 dwClockFrequency; - u32 dwClockUpdateRes; - u8 bCapabilities; - u32 dwDeviceRegistersLocation; - u32 dwHostMemoryRegion; - u32 dwHostMemoryRegionSize; - u32 dwHostHibernatMemRegion; - u32 dwHostHibernatMemRegionSize; -} __attribute__((packed)); - -/* This is DWORD aligned on windows but I can't find the right - * gcc syntax to match the binary data from the device. - * I've manually padded with Reserved[3] bytes to match the hardware, - * but this could break if GCC decies to pack in a different way. - */ -struct tmComResInterfaceDescr { - u8 bLength; - u8 bDescriptorType; - u8 bDescriptorSubtype; - u8 bFlags; - u8 bInterfaceType; - u8 bInterfaceId; - u8 bBaseInterface; - u8 bInterruptId; - u8 bDebugInterruptId; - u8 BARLocation; - u8 Reserved[3]; -}; - -struct tmComResBusDescr { - u64 CommandRing; - u64 ResponseRing; - u32 CommandWrite; - u32 CommandRead; - u32 ResponseWrite; - u32 ResponseRead; -}; - -enum tmBusType { - NONE = 0, - TYPE_BUS_PCI = 1, - TYPE_BUS_PCIe = 2, - TYPE_BUS_USB = 3, - TYPE_BUS_I2C = 4 -}; - -struct tmComResBusInfo { - enum tmBusType Type; - u16 m_wMaxReqSize; - u8 *m_pdwSetRing; - u32 m_dwSizeSetRing; - u8 *m_pdwGetRing; - u32 m_dwSizeGetRing; - u32 m_dwSetWritePos; - u32 m_dwSetReadPos; - u32 m_dwGetWritePos; - u32 m_dwGetReadPos; - - /* All access is protected */ - struct mutex lock; - -}; - -struct tmComResInfo { - u8 id; - u8 flags; - u16 size; - u32 command; - u16 controlselector; - u8 seqno; -} __attribute__((packed)); - -enum tmComResCmd { - SET_CUR = 0x01, - GET_CUR = 0x81, - GET_MIN = 0x82, - GET_MAX = 0x83, - GET_RES = 0x84, - GET_LEN = 0x85, - GET_INFO = 0x86, - GET_DEF = 0x87 -}; - -struct cmd { - u8 seqno; - u32 inuse; - u32 timeout; - u32 signalled; - struct mutex lock; - wait_queue_head_t wait; -}; - -struct tmDescriptor { - u32 pathid; - u32 size; - void *descriptor; -}; - -struct tmComResDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 unitid; -} __attribute__((packed)); - -struct tmComResExtDevDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 unitid; - u32 devicetype; - u16 deviceid; - u32 numgpiopins; - u8 numgpiogroups; - u8 controlsize; -} __attribute__((packed)); - -struct tmComResGPIO { - u32 pin; - u8 state; -} __attribute__((packed)); - -struct tmComResPathDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 pathid; -} __attribute__((packed)); - -/* terminaltype */ -enum tmComResTermType { - ITT_ANTENNA = 0x0203, - LINE_CONNECTOR = 0x0603, - SPDIF_CONNECTOR = 0x0605, - COMPOSITE_CONNECTOR = 0x0401, - SVIDEO_CONNECTOR = 0x0402, - COMPONENT_CONNECTOR = 0x0403, - STANDARD_DMA = 0xF101 -}; - -struct tmComResAntTermDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 terminalid; - u16 terminaltype; - u8 assocterminal; - u8 iterminal; - u8 controlsize; -} __attribute__((packed)); - -struct tmComResTunerDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 unitid; - u8 sourceid; - u8 iunit; - u32 tuningstandards; - u8 controlsize; - u32 controls; -} __attribute__((packed)); - -enum tmBufferFlag { - /* the buffer does not contain any valid data */ - TM_BUFFER_FLAG_EMPTY, - - /* the buffer is filled with valid data */ - TM_BUFFER_FLAG_DONE, - - /* the buffer is the dummy buffer - TODO??? */ - TM_BUFFER_FLAG_DUMMY_BUFFER -}; - -struct tmBuffer { - u64 *pagetablevirt; - u64 pagetablephys; - u16 offset; - u8 *context; - u64 timestamp; - enum tmBufferFlag BufferFlag; - u32 lostbuffers; - u32 validbuffers; - u64 *dummypagevirt; - u64 dummypagephys; - u64 *addressvirt; -}; - -struct tmHWStreamParameters { - u32 bitspersample; - u32 samplesperline; - u32 numberoflines; - u32 pitch; - u32 linethreshold; - u64 **pagetablelistvirt; - u64 *pagetablelistphys; - u32 numpagetables; - u32 numpagetableentries; -}; - -struct tmStreamParameters { - struct tmHWStreamParameters HWStreamParameters; - u64 qwDummyPageTablePhys; - u64 *pDummyPageTableVirt; -}; - -struct tmComResDMATermDescrHeader { - u8 len; - u8 type; - u8 subtyle; - u8 unitid; - u16 terminaltype; - u8 assocterminal; - u8 sourceid; - u8 iterminal; - u32 BARLocation; - u8 flags; - u8 interruptid; - u8 buffercount; - u8 metadatasize; - u8 numformats; - u8 controlsize; -} __attribute__((packed)); - -/* - * - * Description: - * This is the transport stream format header. - * - * Settings: - * bLength - The size of this descriptor in bytes. - * bDescriptorType - CS_INTERFACE. - * bDescriptorSubtype - VS_FORMAT_MPEG2TS descriptor subtype. - * bFormatIndex - A non-zero constant that uniquely identifies the - * format. - * bDataOffset - Offset to TSP packet within MPEG-2 TS transport - * stride, in bytes. - * bPacketLength - Length of TSP packet, in bytes (typically 188). - * bStrideLength - Length of MPEG-2 TS transport stride. - * guidStrideFormat - A Globally Unique Identifier indicating the - * format of the stride data (if any). Set to zeros - * if there is no Stride Data, or if the Stride - * Data is to be ignored by the application. - * - */ -struct tmComResTSFormatDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 bFormatIndex; - u8 bDataOffset; - u8 bPacketLength; - u8 bStrideLength; - u8 guidStrideFormat[16]; -} __attribute__((packed)); - -/* Encoder related structures */ - -/* A/V Mux Selector */ -struct tmComResSelDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 unitid; - u8 nrinpins; - u8 sourceid; -} __attribute__((packed)); - -/* A/V Audio processor definitions */ -struct tmComResProcDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 unitid; - u8 sourceid; - u16 wreserved; - u8 controlsize; -} __attribute__((packed)); - -/* Video bitrate control message */ -#define EU_VIDEO_BIT_RATE_MODE_CONSTANT (0) -#define EU_VIDEO_BIT_RATE_MODE_VARIABLE_AVERAGE (1) -#define EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK (2) -struct tmComResEncVideoBitRate { - u8 ucVideoBitRateMode; - u32 dwVideoBitRate; - u32 dwVideoBitRatePeak; -} __attribute__((packed)); - -/* Video Encoder Aspect Ratio message */ -struct tmComResEncVideoInputAspectRatio { - u8 width; - u8 height; -} __attribute__((packed)); - -/* Video Encoder GOP IBP message */ -/* 1. IPPPPPPPPPPPPPP */ -/* 2. IBPBPBPBPBPBPBP */ -/* 3. IBBPBBPBBPBBP */ -#define SAA7164_ENCODER_DEFAULT_GOP_DIST (1) -#define SAA7164_ENCODER_DEFAULT_GOP_SIZE (15) -struct tmComResEncVideoGopStructure { - u8 ucGOPSize; /* GOP Size 12, 15 */ - u8 ucRefFrameDist; /* Reference Frame Distance */ -} __attribute__((packed)); - -/* Encoder processor definition */ -struct tmComResEncoderDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 unitid; - u8 vsourceid; - u8 asourceid; - u8 iunit; - u32 dwmControlCap; - u32 dwmProfileCap; - u32 dwmVidFormatCap; - u8 bmVidBitrateCap; - u16 wmVidResolutionsCap; - u16 wmVidFrmRateCap; - u32 dwmAudFormatCap; - u8 bmAudBitrateCap; -} __attribute__((packed)); - -/* Audio processor definition */ -struct tmComResAFeatureDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 unitid; - u8 sourceid; - u8 controlsize; -} __attribute__((packed)); - -/* Audio control messages */ -struct tmComResAudioDefaults { - u8 ucDecoderLevel; - u8 ucDecoderFM_Level; - u8 ucMonoLevel; - u8 ucNICAM_Level; - u8 ucSAP_Level; - u8 ucADC_Level; -} __attribute__((packed)); - -/* Audio bitrate control message */ -struct tmComResEncAudioBitRate { - u8 ucAudioBitRateMode; - u32 dwAudioBitRate; - u32 dwAudioBitRatePeak; -} __attribute__((packed)); - -/* Tuner / AV Decoder messages */ -struct tmComResTunerStandard { - u8 std; - u32 country; -} __attribute__((packed)); - -struct tmComResTunerStandardAuto { - u8 mode; -} __attribute__((packed)); - -/* EEPROM definition for PS stream types */ -struct tmComResPSFormatDescrHeader { - u8 len; - u8 type; - u8 subtype; - u8 bFormatIndex; - u16 wPacketLength; - u16 wPackLength; - u8 bPackDataType; -} __attribute__((packed)); - -/* VBI control structure */ -struct tmComResVBIFormatDescrHeader { - u8 len; - u8 type; - u8 subtype; /* VS_FORMAT_VBI */ - u8 bFormatIndex; - u32 VideoStandard; /* See KS_AnalogVideoStandard, NTSC = 1 */ - u8 StartLine; /* NTSC Start = 10 */ - u8 EndLine; /* NTSC = 21 */ - u8 FieldRate; /* 60 for NTSC */ - u8 bNumLines; /* Unused - scheduled for removal */ -} __attribute__((packed)); - -struct tmComResProbeCommit { - u16 bmHint; - u8 bFormatIndex; - u8 bFrameIndex; -} __attribute__((packed)); - -struct tmComResDebugSetLevel { - u32 dwDebugLevel; -} __attribute__((packed)); - -struct tmComResDebugGetData { - u32 dwResult; - u8 ucDebugData[256]; -} __attribute__((packed)); - -struct tmFwInfoStruct { - u32 status; - u32 mode; - u32 devicespec; - u32 deviceinst; - u32 CPULoad; - u32 RemainHeap; - u32 CPUClock; - u32 RAMSpeed; -} __attribute__((packed)); diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c deleted file mode 100644 index d8e6c8f14079..000000000000 --- a/drivers/media/video/saa7164/saa7164-vbi.c +++ /dev/null @@ -1,1374 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "saa7164.h" - -static struct saa7164_tvnorm saa7164_tvnorms[] = { - { - .name = "NTSC-M", - .id = V4L2_STD_NTSC_M, - }, { - .name = "NTSC-JP", - .id = V4L2_STD_NTSC_M_JP, - } -}; - -static const u32 saa7164_v4l2_ctrls[] = { - 0 -}; - -/* Take the encoder configuration from the port struct and - * flush it to the hardware. - */ -static void saa7164_vbi_configure(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - dprintk(DBGLVL_VBI, "%s()\n", __func__); - - port->vbi_params.width = port->width; - port->vbi_params.height = port->height; - port->vbi_params.is_50hz = - (port->encodernorm.id & V4L2_STD_625_50) != 0; - - /* Set up the DIF (enable it) for analog mode by default */ - saa7164_api_initialize_dif(port); - - /* Configure the correct video standard */ -#if 0 - saa7164_api_configure_dif(port, port->encodernorm.id); -#endif - -#if 0 - /* Ensure the audio decoder is correct configured */ - saa7164_api_set_audio_std(port); -#endif - dprintk(DBGLVL_VBI, "%s() ends\n", __func__); -} - -static int saa7164_vbi_buffers_dealloc(struct saa7164_port *port) -{ - struct list_head *c, *n, *p, *q, *l, *v; - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct saa7164_user_buffer *ubuf; - - /* Remove any allocated buffers */ - mutex_lock(&port->dmaqueue_lock); - - dprintk(DBGLVL_VBI, "%s(port=%d) dmaqueue\n", __func__, port->nr); - list_for_each_safe(c, n, &port->dmaqueue.list) { - buf = list_entry(c, struct saa7164_buffer, list); - list_del(c); - saa7164_buffer_dealloc(buf); - } - - dprintk(DBGLVL_VBI, "%s(port=%d) used\n", __func__, port->nr); - list_for_each_safe(p, q, &port->list_buf_used.list) { - ubuf = list_entry(p, struct saa7164_user_buffer, list); - list_del(p); - saa7164_buffer_dealloc_user(ubuf); - } - - dprintk(DBGLVL_VBI, "%s(port=%d) free\n", __func__, port->nr); - list_for_each_safe(l, v, &port->list_buf_free.list) { - ubuf = list_entry(l, struct saa7164_user_buffer, list); - list_del(l); - saa7164_buffer_dealloc_user(ubuf); - } - - mutex_unlock(&port->dmaqueue_lock); - dprintk(DBGLVL_VBI, "%s(port=%d) done\n", __func__, port->nr); - - return 0; -} - -/* Dynamic buffer switch at vbi start time */ -static int saa7164_vbi_buffers_alloc(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct saa7164_user_buffer *ubuf; - struct tmHWStreamParameters *params = &port->hw_streamingparams; - int result = -ENODEV, i; - int len = 0; - - dprintk(DBGLVL_VBI, "%s()\n", __func__); - - /* TODO: NTSC SPECIFIC */ - /* Init and establish defaults */ - params->samplesperline = 1440; - params->numberoflines = 12; - params->numberoflines = 18; - params->pitch = 1600; - params->pitch = 1440; - params->numpagetables = 2 + - ((params->numberoflines * params->pitch) / PAGE_SIZE); - params->bitspersample = 8; - params->linethreshold = 0; - params->pagetablelistvirt = NULL; - params->pagetablelistphys = NULL; - params->numpagetableentries = port->hwcfg.buffercount; - - /* Allocate the PCI resources, buffers (hard) */ - for (i = 0; i < port->hwcfg.buffercount; i++) { - buf = saa7164_buffer_alloc(port, - params->numberoflines * - params->pitch); - - if (!buf) { - printk(KERN_ERR "%s() failed " - "(errno = %d), unable to allocate buffer\n", - __func__, result); - result = -ENOMEM; - goto failed; - } else { - - mutex_lock(&port->dmaqueue_lock); - list_add_tail(&buf->list, &port->dmaqueue.list); - mutex_unlock(&port->dmaqueue_lock); - - } - } - - /* Allocate some kernel buffers for copying - * to userpsace. - */ - len = params->numberoflines * params->pitch; - - if (vbi_buffers < 16) - vbi_buffers = 16; - if (vbi_buffers > 512) - vbi_buffers = 512; - - for (i = 0; i < vbi_buffers; i++) { - - ubuf = saa7164_buffer_alloc_user(dev, len); - if (ubuf) { - mutex_lock(&port->dmaqueue_lock); - list_add_tail(&ubuf->list, &port->list_buf_free.list); - mutex_unlock(&port->dmaqueue_lock); - } - - } - - result = 0; - -failed: - return result; -} - - -static int saa7164_vbi_initialize(struct saa7164_port *port) -{ - saa7164_vbi_configure(port); - return 0; -} - -/* -- V4L2 --------------------------------------------------------- */ -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - unsigned int i; - - dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)*id); - - for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) { - if (*id & saa7164_tvnorms[i].id) - break; - } - if (i == ARRAY_SIZE(saa7164_tvnorms)) - return -EINVAL; - - port->encodernorm = saa7164_tvnorms[i]; - - /* Update the audio decoder while is not running in - * auto detect mode. - */ - saa7164_api_set_audio_std(port); - - dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)*id); - - return 0; -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - int n; - - char *inputs[] = { "tuner", "composite", "svideo", "aux", - "composite 2", "svideo 2", "aux 2" }; - - if (i->index >= 7) - return -EINVAL; - - strcpy(i->name, inputs[i->index]); - - if (i->index == 0) - i->type = V4L2_INPUT_TYPE_TUNER; - else - i->type = V4L2_INPUT_TYPE_CAMERA; - - for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++) - i->std |= saa7164_tvnorms[n].id; - - return 0; -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - if (saa7164_api_get_videomux(port) != SAA_OK) - return -EIO; - - *i = (port->mux_input - 1); - - dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i); - - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i); - - if (i >= 7) - return -EINVAL; - - port->mux_input = i + 1; - - if (saa7164_api_set_videomux(port) != SAA_OK) - return -EIO; - - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - if (0 != t->index) - return -EINVAL; - - strcpy(t->name, "tuner"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO; - - dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type); - - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - /* Update the A/V core */ - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = port->freq; - - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - struct saa7164_port *tsport; - struct dvb_frontend *fe; - - /* TODO: Pull this for the std */ - struct analog_parameters params = { - .mode = V4L2_TUNER_ANALOG_TV, - .audmode = V4L2_TUNER_MODE_STEREO, - .std = port->encodernorm.id, - .frequency = f->frequency - }; - - /* Stop the encoder */ - dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__, - f->frequency, f->tuner); - - if (f->tuner != 0) - return -EINVAL; - - if (f->type != V4L2_TUNER_ANALOG_TV) - return -EINVAL; - - port->freq = f->frequency; - - /* Update the hardware */ - if (port->nr == SAA7164_PORT_VBI1) - tsport = &dev->ports[SAA7164_PORT_TS1]; - else - if (port->nr == SAA7164_PORT_VBI2) - tsport = &dev->ports[SAA7164_PORT_TS2]; - else - BUG(); - - fe = tsport->dvb.frontend; - - if (fe && fe->ops.tuner_ops.set_analog_params) - fe->ops.tuner_ops.set_analog_params(fe, ¶ms); - else - printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__); - - saa7164_vbi_initialize(port); - - return 0; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__, - ctl->id, ctl->value); - - switch (ctl->id) { - case V4L2_CID_BRIGHTNESS: - ctl->value = port->ctl_brightness; - break; - case V4L2_CID_CONTRAST: - ctl->value = port->ctl_contrast; - break; - case V4L2_CID_SATURATION: - ctl->value = port->ctl_saturation; - break; - case V4L2_CID_HUE: - ctl->value = port->ctl_hue; - break; - case V4L2_CID_SHARPNESS: - ctl->value = port->ctl_sharpness; - break; - case V4L2_CID_AUDIO_VOLUME: - ctl->value = port->ctl_volume; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - int ret = 0; - - dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__, - ctl->id, ctl->value); - - switch (ctl->id) { - case V4L2_CID_BRIGHTNESS: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_brightness = ctl->value; - saa7164_api_set_usercontrol(port, - PU_BRIGHTNESS_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_CONTRAST: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_contrast = ctl->value; - saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_SATURATION: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_saturation = ctl->value; - saa7164_api_set_usercontrol(port, - PU_SATURATION_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_HUE: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_hue = ctl->value; - saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_SHARPNESS: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_sharpness = ctl->value; - saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_AUDIO_VOLUME: - if ((ctl->value >= -83) && (ctl->value <= 24)) { - port->ctl_volume = ctl->value; - saa7164_api_set_audio_volume(port, port->ctl_volume); - } else - ret = -EINVAL; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int saa7164_get_ctrl(struct saa7164_port *port, - struct v4l2_ext_control *ctrl) -{ - struct saa7164_vbi_params *params = &port->vbi_params; - - switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - ctrl->value = params->stream_type; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - ctrl->value = params->ctl_mute; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - ctrl->value = params->ctl_aspect; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - ctrl->value = params->refdist; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - ctrl->value = params->gop_size; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_get_ctrl(port, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - -static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) -{ - int ret = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) || - (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)) - ret = 0; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - if ((ctrl->value >= 0) && - (ctrl->value <= 1)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) && - (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - if ((ctrl->value >= 0) && - (ctrl->value <= 255)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - if ((ctrl->value >= 1) && - (ctrl->value <= 3)) - ret = 0; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_try_ctrl(ctrl, 0); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - } - - return -EINVAL; -} - -static int saa7164_set_ctrl(struct saa7164_port *port, - struct v4l2_ext_control *ctrl) -{ - struct saa7164_vbi_params *params = &port->vbi_params; - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - params->stream_type = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - params->ctl_mute = ctrl->value; - ret = saa7164_api_audio_mute(port, params->ctl_mute); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, - ret); - ret = -EIO; - } - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - params->ctl_aspect = ctrl->value; - ret = saa7164_api_set_aspect_ratio(port); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, - ret); - ret = -EIO; - } - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - params->refdist = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - params->gop_size = ctrl->value; - break; - default: - return -EINVAL; - } - - /* TODO: Update the hardware */ - - return ret; -} - -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_try_ctrl(ctrl, 0); - if (err) { - ctrls->error_idx = i; - break; - } - err = saa7164_set_ctrl(port, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - strcpy(cap->driver, dev->name); - strlcpy(cap->card, saa7164_boards[dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - - cap->capabilities = - V4L2_CAP_VBI_CAPTURE | - V4L2_CAP_READWRITE | - 0; - - cap->capabilities |= V4L2_CAP_TUNER; - cap->version = 0; - - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (f->index != 0) - return -EINVAL; - - strlcpy(f->description, "VBI", sizeof(f->description)); - f->pixelformat = V4L2_PIX_FMT_MPEG; - - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - f->fmt.pix.width = port->width; - f->fmt.pix.height = port->height; - - dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n", - port->width, port->height); - - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n", - port->width, port->height); - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - - dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); - - return 0; -} - -static int fill_queryctrl(struct saa7164_vbi_params *params, - struct v4l2_queryctrl *c) -{ - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128); - case V4L2_CID_SHARPNESS: - return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8); - case V4L2_CID_MPEG_AUDIO_MUTE: - return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(c, -83, 24, 1, 20); - case V4L2_CID_MPEG_STREAM_TYPE: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - V4L2_MPEG_STREAM_TYPE_MPEG2_TS, - 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS); - case V4L2_CID_MPEG_VIDEO_ASPECT: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_VIDEO_ASPECT_1x1, - V4L2_MPEG_VIDEO_ASPECT_221x100, - 1, V4L2_MPEG_VIDEO_ASPECT_4x3); - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - return v4l2_ctrl_query_fill(c, 1, 255, 1, 15); - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - return v4l2_ctrl_query_fill(c, - 1, 3, 1, 1); - default: - return -EINVAL; - } -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct saa7164_vbi_fh *fh = priv; - struct saa7164_port *port = fh->port; - int i, next; - u32 id = c->id; - - memset(c, 0, sizeof(*c)); - - next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); - c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; - - for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) { - if (next) { - if (c->id < saa7164_v4l2_ctrls[i]) - c->id = saa7164_v4l2_ctrls[i]; - else - continue; - } - - if (c->id == saa7164_v4l2_ctrls[i]) - return fill_queryctrl(&port->vbi_params, c); - - if (c->id < saa7164_v4l2_ctrls[i]) - break; - } - - return -EINVAL; -} - -static int saa7164_vbi_stop_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_VBI, "%s() Stopped\n", __func__); - ret = 0; - } - - return ret; -} - -static int saa7164_vbi_acquire_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__); - ret = 0; - } - - return ret; -} - -static int saa7164_vbi_pause_port(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int ret; - - ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); - if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n", - __func__, ret); - ret = -EIO; - } else { - dprintk(DBGLVL_VBI, "%s() Paused\n", __func__); - ret = 0; - } - - return ret; -} - -/* Firmware is very windows centric, meaning you have to transition - * the part through AVStream / KS Windows stages, forwards or backwards. - * States are: stopped, acquired (h/w), paused, started. - * We have to leave here will all of the soft buffers on the free list, - * else the cfg_post() func won't have soft buffers to correctly configure. - */ -static int saa7164_vbi_stop_streaming(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *buf; - struct saa7164_user_buffer *ubuf; - struct list_head *c, *n; - int ret; - - dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr); - - ret = saa7164_vbi_pause_port(port); - ret = saa7164_vbi_acquire_port(port); - ret = saa7164_vbi_stop_port(port); - - dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__, - port->nr); - - /* Reset the state of any allocated buffer resources */ - mutex_lock(&port->dmaqueue_lock); - - /* Reset the hard and soft buffer state */ - list_for_each_safe(c, n, &port->dmaqueue.list) { - buf = list_entry(c, struct saa7164_buffer, list); - buf->flags = SAA7164_BUFFER_FREE; - buf->pos = 0; - } - - list_for_each_safe(c, n, &port->list_buf_used.list) { - ubuf = list_entry(c, struct saa7164_user_buffer, list); - ubuf->pos = 0; - list_move_tail(&ubuf->list, &port->list_buf_free.list); - } - - mutex_unlock(&port->dmaqueue_lock); - - /* Free any allocated resources */ - saa7164_vbi_buffers_dealloc(port); - - dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr); - - return ret; -} - -static int saa7164_vbi_start_streaming(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int result, ret = 0; - - dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr); - - port->done_first_interrupt = 0; - - /* allocate all of the PCIe DMA buffer resources on the fly, - * allowing switching between TS and PS payloads without - * requiring a complete driver reload. - */ - saa7164_vbi_buffers_alloc(port); - - /* Configure the encoder with any cache values */ -#if 0 - saa7164_api_set_encoder(port); - saa7164_api_get_encoder(port); -#endif - - /* Place the empty buffers on the hardware */ - saa7164_buffer_cfg_port(port); - - /* Negotiate format */ - if (saa7164_api_set_vbi_format(port) != SAA_OK) { - printk(KERN_ERR "%s() No supported VBI format\n", __func__); - ret = -EIO; - goto out; - } - - /* Acquire the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n", - __func__, result); - - ret = -EIO; - goto out; - } else - dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__); - - /* Pause the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n", - __func__, result); - - /* Stop the hardware, regardless */ - result = saa7164_vbi_stop_port(port); - if (result != SAA_OK) { - printk(KERN_ERR "%s() pause/forced stop transition " - "failed, res = 0x%x\n", __func__, result); - } - - ret = -EIO; - goto out; - } else - dprintk(DBGLVL_VBI, "%s() Paused\n", __func__); - - /* Start the hardware */ - result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN); - if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() run transition failed, result = 0x%x\n", - __func__, result); - - /* Stop the hardware, regardless */ - result = saa7164_vbi_acquire_port(port); - result = saa7164_vbi_stop_port(port); - if (result != SAA_OK) { - printk(KERN_ERR "%s() run/forced stop transition " - "failed, res = 0x%x\n", __func__, result); - } - - ret = -EIO; - } else - dprintk(DBGLVL_VBI, "%s() Running\n", __func__); - -out: - return ret; -} - -int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - /* ntsc */ - f->fmt.vbi.samples_per_line = 1600; - f->fmt.vbi.samples_per_line = 1440; - f->fmt.vbi.sampling_rate = 27000000; - f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - f->fmt.vbi.offset = 0; - f->fmt.vbi.flags = 0; - f->fmt.vbi.start[0] = 10; - f->fmt.vbi.count[0] = 18; - f->fmt.vbi.start[1] = 263 + 10 + 1; - f->fmt.vbi.count[1] = 18; - return 0; -} - -static int fops_open(struct file *file) -{ - struct saa7164_dev *dev; - struct saa7164_port *port; - struct saa7164_vbi_fh *fh; - - port = (struct saa7164_port *)video_get_drvdata(video_devdata(file)); - if (!port) - return -ENODEV; - - dev = port->dev; - - dprintk(DBGLVL_VBI, "%s()\n", __func__); - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) - return -ENOMEM; - - file->private_data = fh; - fh->port = port; - - return 0; -} - -static int fops_release(struct file *file) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_VBI, "%s()\n", __func__); - - /* Shut device down on last close */ - if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { - if (atomic_dec_return(&port->v4l_reader_count) == 0) { - /* stop vbi capture then cancel buffers */ - saa7164_vbi_stop_streaming(port); - } - } - - file->private_data = NULL; - kfree(fh); - - return 0; -} - -struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port) -{ - struct saa7164_user_buffer *ubuf = NULL; - struct saa7164_dev *dev = port->dev; - u32 crc; - - mutex_lock(&port->dmaqueue_lock); - if (!list_empty(&port->list_buf_used.list)) { - ubuf = list_first_entry(&port->list_buf_used.list, - struct saa7164_user_buffer, list); - - if (crc_checking) { - crc = crc32(0, ubuf->data, ubuf->actual_size); - if (crc != ubuf->crc) { - printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", - __func__, - ubuf, ubuf->crc, crc); - } - } - - } - mutex_unlock(&port->dmaqueue_lock); - - dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf); - - return ubuf; -} - -static ssize_t fops_read(struct file *file, char __user *buffer, - size_t count, loff_t *pos) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_user_buffer *ubuf = NULL; - struct saa7164_dev *dev = port->dev; - int ret = 0; - int rem, cnt; - u8 *p; - - port->last_read_msecs_diff = port->last_read_msecs; - port->last_read_msecs = jiffies_to_msecs(jiffies); - port->last_read_msecs_diff = port->last_read_msecs - - port->last_read_msecs_diff; - - saa7164_histogram_update(&port->read_interval, - port->last_read_msecs_diff); - - if (*pos) { - printk(KERN_ERR "%s() ESPIPE\n", __func__); - return -ESPIPE; - } - - if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { - if (atomic_inc_return(&port->v4l_reader_count) == 1) { - - if (saa7164_vbi_initialize(port) < 0) { - printk(KERN_ERR "%s() EINVAL\n", __func__); - return -EINVAL; - } - - saa7164_vbi_start_streaming(port); - msleep(200); - } - } - - /* blocking wait for buffer */ - if ((file->f_flags & O_NONBLOCK) == 0) { - if (wait_event_interruptible(port->wait_read, - saa7164_vbi_next_buf(port))) { - printk(KERN_ERR "%s() ERESTARTSYS\n", __func__); - return -ERESTARTSYS; - } - } - - /* Pull the first buffer from the used list */ - ubuf = saa7164_vbi_next_buf(port); - - while ((count > 0) && ubuf) { - - /* set remaining bytes to copy */ - rem = ubuf->actual_size - ubuf->pos; - cnt = rem > count ? count : rem; - - p = ubuf->data + ubuf->pos; - - dprintk(DBGLVL_VBI, - "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n", - __func__, (int)count, cnt, rem, ubuf, ubuf->pos); - - if (copy_to_user(buffer, p, cnt)) { - printk(KERN_ERR "%s() copy_to_user failed\n", __func__); - if (!ret) { - printk(KERN_ERR "%s() EFAULT\n", __func__); - ret = -EFAULT; - } - goto err; - } - - ubuf->pos += cnt; - count -= cnt; - buffer += cnt; - ret += cnt; - - if (ubuf->pos > ubuf->actual_size) - printk(KERN_ERR "read() pos > actual, huh?\n"); - - if (ubuf->pos == ubuf->actual_size) { - - /* finished with current buffer, take next buffer */ - - /* Requeue the buffer on the free list */ - ubuf->pos = 0; - - mutex_lock(&port->dmaqueue_lock); - list_move_tail(&ubuf->list, &port->list_buf_free.list); - mutex_unlock(&port->dmaqueue_lock); - - /* Dequeue next */ - if ((file->f_flags & O_NONBLOCK) == 0) { - if (wait_event_interruptible(port->wait_read, - saa7164_vbi_next_buf(port))) { - break; - } - } - ubuf = saa7164_vbi_next_buf(port); - } - } -err: - if (!ret && !ubuf) { - printk(KERN_ERR "%s() EAGAIN\n", __func__); - ret = -EAGAIN; - } - - return ret; -} - -static unsigned int fops_poll(struct file *file, poll_table *wait) -{ - struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data; - struct saa7164_port *port = fh->port; - unsigned int mask = 0; - - port->last_poll_msecs_diff = port->last_poll_msecs; - port->last_poll_msecs = jiffies_to_msecs(jiffies); - port->last_poll_msecs_diff = port->last_poll_msecs - - port->last_poll_msecs_diff; - - saa7164_histogram_update(&port->poll_interval, - port->last_poll_msecs_diff); - - if (!video_is_registered(port->v4l_device)) - return -EIO; - - if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { - if (atomic_inc_return(&port->v4l_reader_count) == 1) { - if (saa7164_vbi_initialize(port) < 0) - return -EINVAL; - saa7164_vbi_start_streaming(port); - msleep(200); - } - } - - /* blocking wait for buffer */ - if ((file->f_flags & O_NONBLOCK) == 0) { - if (wait_event_interruptible(port->wait_read, - saa7164_vbi_next_buf(port))) { - return -ERESTARTSYS; - } - } - - /* Pull the first buffer from the used list */ - if (!list_empty(&port->list_buf_used.list)) - mask |= POLLIN | POLLRDNORM; - - return mask; -} -static const struct v4l2_file_operations vbi_fops = { - .owner = THIS_MODULE, - .open = fops_open, - .release = fops_release, - .read = fops_read, - .poll = fops_poll, - .unlocked_ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops vbi_ioctl_ops = { - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, - .vidioc_queryctrl = vidioc_queryctrl, -#if 0 - .vidioc_g_chip_ident = saa7164_g_chip_ident, -#endif -#ifdef CONFIG_VIDEO_ADV_DEBUG -#if 0 - .vidioc_g_register = saa7164_g_register, - .vidioc_s_register = saa7164_s_register, -#endif -#endif - .vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt, - .vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt, - .vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt, -}; - -static struct video_device saa7164_vbi_template = { - .name = "saa7164", - .fops = &vbi_fops, - .ioctl_ops = &vbi_ioctl_ops, - .minor = -1, - .tvnorms = SAA7164_NORMS, - .current_norm = V4L2_STD_NTSC_M, -}; - -static struct video_device *saa7164_vbi_alloc( - struct saa7164_port *port, - struct pci_dev *pci, - struct video_device *template, - char *type) -{ - struct video_device *vfd; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_VBI, "%s()\n", __func__); - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - - *vfd = *template; - snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, - type, saa7164_boards[dev->board].name); - - vfd->parent = &pci->dev; - vfd->release = video_device_release; - return vfd; -} - -int saa7164_vbi_register(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - int result = -ENODEV; - - dprintk(DBGLVL_VBI, "%s()\n", __func__); - - if (port->type != SAA7164_MPEG_VBI) - BUG(); - - /* Sanity check that the PCI configuration space is active */ - if (port->hwcfg.BARLocation == 0) { - printk(KERN_ERR "%s() failed " - "(errno = %d), NO PCI configuration\n", - __func__, result); - result = -ENOMEM; - goto failed; - } - - /* Establish VBI defaults here */ - - /* Allocate and register the video device node */ - port->v4l_device = saa7164_vbi_alloc(port, - dev->pci, &saa7164_vbi_template, "vbi"); - - if (!port->v4l_device) { - printk(KERN_INFO "%s: can't allocate vbi device\n", - dev->name); - result = -ENOMEM; - goto failed; - } - - video_set_drvdata(port->v4l_device, port); - result = video_register_device(port->v4l_device, - VFL_TYPE_VBI, -1); - if (result < 0) { - printk(KERN_INFO "%s: can't register vbi device\n", - dev->name); - /* TODO: We're going to leak here if we don't dealloc - The buffers above. The unreg function can't deal wit it. - */ - goto failed; - } - - printk(KERN_INFO "%s: registered device vbi%d [vbi]\n", - dev->name, port->v4l_device->num); - - /* Configure the hardware defaults */ - - result = 0; -failed: - return result; -} - -void saa7164_vbi_unregister(struct saa7164_port *port) -{ - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr); - - if (port->type != SAA7164_MPEG_VBI) - BUG(); - - if (port->v4l_device) { - if (port->v4l_device->minor != -1) - video_unregister_device(port->v4l_device); - else - video_device_release(port->v4l_device); - - port->v4l_device = NULL; - } - -} diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h deleted file mode 100644 index 437284e747c9..000000000000 --- a/drivers/media/video/saa7164/saa7164.h +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Driver for the NXP SAA7164 PCIe bridge - * - * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - Driver architecture - ******************* - - saa7164_core.c/buffer.c/cards.c/i2c.c/dvb.c - | : Standard Linux driver framework for creating - | : exposing and managing interfaces to the rest - | : of the kernel or userland. Also uses _fw.c to load - | : firmware direct into the PCIe bus, bypassing layers. - V - saa7164_api..() : Translate kernel specific functions/features - | : into command buffers. - V - saa7164_cmd..() : Manages the flow of command packets on/off, - | : the bus. Deal with bus errors, timeouts etc. - V - saa7164_bus..() : Manage a read/write memory ring buffer in the - | : PCIe Address space. - | - | saa7164_fw...() : Load any frimware - | | : direct into the device - V V - <- ----------------- PCIe address space -------------------- -> -*/ - -#include <linux/pci.h> -#include <linux/i2c.h> -#include <linux/kdev_t.h> -#include <linux/mutex.h> -#include <linux/crc32.h> -#include <linux/kthread.h> -#include <linux/freezer.h> - -#include <media/tuner.h> -#include <media/tveeprom.h> -#include <media/videobuf-dma-sg.h> -#include <media/videobuf-dvb.h> -#include <dvb_demux.h> -#include <dvb_frontend.h> -#include <dvb_net.h> -#include <dvbdev.h> -#include <dmxdev.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include <media/v4l2-chip-ident.h> - -#include "saa7164-reg.h" -#include "saa7164-types.h" - -#define SAA7164_MAXBOARDS 8 - -#define UNSET (-1U) -#define SAA7164_BOARD_NOAUTO UNSET -#define SAA7164_BOARD_UNKNOWN 0 -#define SAA7164_BOARD_UNKNOWN_REV2 1 -#define SAA7164_BOARD_UNKNOWN_REV3 2 -#define SAA7164_BOARD_HAUPPAUGE_HVR2250 3 -#define SAA7164_BOARD_HAUPPAUGE_HVR2200 4 -#define SAA7164_BOARD_HAUPPAUGE_HVR2200_2 5 -#define SAA7164_BOARD_HAUPPAUGE_HVR2200_3 6 -#define SAA7164_BOARD_HAUPPAUGE_HVR2250_2 7 -#define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8 -#define SAA7164_BOARD_HAUPPAUGE_HVR2200_4 9 -#define SAA7164_BOARD_HAUPPAUGE_HVR2200_5 10 - -#define SAA7164_MAX_UNITS 8 -#define SAA7164_TS_NUMBER_OF_LINES 312 -#define SAA7164_PS_NUMBER_OF_LINES 256 -#define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */ -#define SAA7164_MAX_ENCODER_BUFFERS 64 /* max 5secs of latency at 6Mbps */ -#define SAA7164_MAX_VBI_BUFFERS 64 - -/* Port related defines */ -#define SAA7164_PORT_TS1 (0) -#define SAA7164_PORT_TS2 (SAA7164_PORT_TS1 + 1) -#define SAA7164_PORT_ENC1 (SAA7164_PORT_TS2 + 1) -#define SAA7164_PORT_ENC2 (SAA7164_PORT_ENC1 + 1) -#define SAA7164_PORT_VBI1 (SAA7164_PORT_ENC2 + 1) -#define SAA7164_PORT_VBI2 (SAA7164_PORT_VBI1 + 1) -#define SAA7164_MAX_PORTS (SAA7164_PORT_VBI2 + 1) - -#define DBGLVL_FW 4 -#define DBGLVL_DVB 8 -#define DBGLVL_I2C 16 -#define DBGLVL_API 32 -#define DBGLVL_CMD 64 -#define DBGLVL_BUS 128 -#define DBGLVL_IRQ 256 -#define DBGLVL_BUF 512 -#define DBGLVL_ENC 1024 -#define DBGLVL_VBI 2048 -#define DBGLVL_THR 4096 -#define DBGLVL_CPU 8192 - -#define SAA7164_NORMS \ - (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443) - -enum port_t { - SAA7164_MPEG_UNDEFINED = 0, - SAA7164_MPEG_DVB, - SAA7164_MPEG_ENCODER, - SAA7164_MPEG_VBI, -}; - -enum saa7164_i2c_bus_nr { - SAA7164_I2C_BUS_0 = 0, - SAA7164_I2C_BUS_1, - SAA7164_I2C_BUS_2, -}; - -enum saa7164_buffer_flags { - SAA7164_BUFFER_UNDEFINED = 0, - SAA7164_BUFFER_FREE, - SAA7164_BUFFER_BUSY, - SAA7164_BUFFER_FULL -}; - -enum saa7164_unit_type { - SAA7164_UNIT_UNDEFINED = 0, - SAA7164_UNIT_DIGITAL_DEMODULATOR, - SAA7164_UNIT_ANALOG_DEMODULATOR, - SAA7164_UNIT_TUNER, - SAA7164_UNIT_EEPROM, - SAA7164_UNIT_ZILOG_IRBLASTER, - SAA7164_UNIT_ENCODER, -}; - -/* The PCIe bridge doesn't grant direct access to i2c. - * Instead, you address i2c devices using a uniqely - * allocated 'unitid' value via a messaging API. This - * is a problem. The kernel and existing demod/tuner - * drivers expect to talk 'i2c', so we have to maintain - * a translation layer, and a series of functions to - * convert i2c bus + device address into a unit id. - */ -struct saa7164_unit { - enum saa7164_unit_type type; - u8 id; - char *name; - enum saa7164_i2c_bus_nr i2c_bus_nr; - u8 i2c_bus_addr; - u8 i2c_reg_len; -}; - -struct saa7164_board { - char *name; - enum port_t porta, portb, portc, - portd, porte, portf; - enum { - SAA7164_CHIP_UNDEFINED = 0, - SAA7164_CHIP_REV2, - SAA7164_CHIP_REV3, - } chiprev; - struct saa7164_unit unit[SAA7164_MAX_UNITS]; -}; - -struct saa7164_subid { - u16 subvendor; - u16 subdevice; - u32 card; -}; - -struct saa7164_encoder_fh { - struct saa7164_port *port; - atomic_t v4l_reading; -}; - -struct saa7164_vbi_fh { - struct saa7164_port *port; - atomic_t v4l_reading; -}; - -struct saa7164_histogram_bucket { - u32 val; - u32 count; - u64 update_time; -}; - -struct saa7164_histogram { - char name[32]; - struct saa7164_histogram_bucket counter1[64]; -}; - -struct saa7164_user_buffer { - struct list_head list; - - /* Attributes */ - u8 *data; - u32 pos; - u32 actual_size; - - u32 crc; -}; - -struct saa7164_fw_status { - - /* RISC Core details */ - u32 status; - u32 mode; - u32 spec; - u32 inst; - u32 cpuload; - u32 remainheap; - - /* Firmware version */ - u32 version; - u32 major; - u32 sub; - u32 rel; - u32 buildnr; -}; - -struct saa7164_dvb { - struct mutex lock; - struct dvb_adapter adapter; - struct dvb_frontend *frontend; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dmx_frontend fe_hw; - struct dmx_frontend fe_mem; - struct dvb_net net; - int feeding; -}; - -struct saa7164_i2c { - struct saa7164_dev *dev; - - enum saa7164_i2c_bus_nr nr; - - /* I2C I/O */ - struct i2c_adapter i2c_adap; - struct i2c_client i2c_client; - u32 i2c_rc; -}; - -struct saa7164_ctrl { - struct v4l2_queryctrl v; -}; - -struct saa7164_tvnorm { - char *name; - v4l2_std_id id; -}; - -struct saa7164_encoder_params { - struct saa7164_tvnorm encodernorm; - u32 height; - u32 width; - u32 is_50hz; - u32 bitrate; /* bps */ - u32 bitrate_peak; /* bps */ - u32 bitrate_mode; - u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */ - - u32 audio_sampling_freq; - u32 ctl_mute; - u32 ctl_aspect; - u32 refdist; - u32 gop_size; -}; - -struct saa7164_vbi_params { - struct saa7164_tvnorm encodernorm; - u32 height; - u32 width; - u32 is_50hz; - u32 bitrate; /* bps */ - u32 bitrate_peak; /* bps */ - u32 bitrate_mode; - u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */ - - u32 audio_sampling_freq; - u32 ctl_mute; - u32 ctl_aspect; - u32 refdist; - u32 gop_size; -}; - -struct saa7164_port; - -struct saa7164_buffer { - struct list_head list; - - /* Note of which h/w buffer list index position we occupy */ - int idx; - - struct saa7164_port *port; - - /* Hardware Specific */ - /* PCI Memory allocations */ - enum saa7164_buffer_flags flags; /* Free, Busy, Full */ - - /* A block of page align PCI memory */ - u32 pci_size; /* PCI allocation size in bytes */ - u64 __iomem *cpu; /* Virtual address */ - dma_addr_t dma; /* Physical address */ - u32 crc; /* Checksum for the entire buffer data */ - - /* A page table that splits the block into a number of entries */ - u32 pt_size; /* PCI allocation size in bytes */ - u64 __iomem *pt_cpu; /* Virtual address */ - dma_addr_t pt_dma; /* Physical address */ - - /* Encoder fops */ - u32 pos; - u32 actual_size; -}; - -struct saa7164_port { - - struct saa7164_dev *dev; - enum port_t type; - int nr; - - /* --- Generic port attributes --- */ - - /* HW stream parameters */ - struct tmHWStreamParameters hw_streamingparams; - - /* DMA configuration values, is seeded during initialization */ - struct tmComResDMATermDescrHeader hwcfg; - - /* hardware specific registers */ - u32 bufcounter; - u32 pitch; - u32 bufsize; - u32 bufoffset; - u32 bufptr32l; - u32 bufptr32h; - u64 bufptr64; - - u32 numpte; /* Number of entries in array, only valid in head */ - - struct mutex dmaqueue_lock; - struct saa7164_buffer dmaqueue; - - u64 last_irq_msecs, last_svc_msecs; - u64 last_irq_msecs_diff, last_svc_msecs_diff; - u32 last_svc_wp; - u32 last_svc_rp; - u64 last_irq_svc_msecs_diff; - u64 last_read_msecs, last_read_msecs_diff; - u64 last_poll_msecs, last_poll_msecs_diff; - - struct saa7164_histogram irq_interval; - struct saa7164_histogram svc_interval; - struct saa7164_histogram irq_svc_interval; - struct saa7164_histogram read_interval; - struct saa7164_histogram poll_interval; - - /* --- DVB Transport Specific --- */ - struct saa7164_dvb dvb; - - /* --- Encoder/V4L related attributes --- */ - /* Encoder */ - /* Defaults established in saa7164-encoder.c */ - struct saa7164_tvnorm encodernorm; - u32 height; - u32 width; - u32 freq; - u32 ts_packet_size; - u32 ts_packet_count; - u8 mux_input; - u8 encoder_profile; - u8 video_format; - u8 audio_format; - u8 video_resolution; - u16 ctl_brightness; - u16 ctl_contrast; - u16 ctl_hue; - u16 ctl_saturation; - u16 ctl_sharpness; - s8 ctl_volume; - - struct tmComResAFeatureDescrHeader audfeat; - struct tmComResEncoderDescrHeader encunit; - struct tmComResProcDescrHeader vidproc; - struct tmComResExtDevDescrHeader ifunit; - struct tmComResTunerDescrHeader tunerunit; - - struct work_struct workenc; - - /* V4L Encoder Video */ - struct saa7164_encoder_params encoder_params; - struct video_device *v4l_device; - atomic_t v4l_reader_count; - - struct saa7164_buffer list_buf_used; - struct saa7164_buffer list_buf_free; - wait_queue_head_t wait_read; - - /* V4L VBI */ - struct tmComResVBIFormatDescrHeader vbi_fmt_ntsc; - struct saa7164_vbi_params vbi_params; - - /* Debug */ - u32 sync_errors; - u32 v_cc_errors; - u32 a_cc_errors; - u8 last_v_cc; - u8 last_a_cc; - u32 done_first_interrupt; -}; - -struct saa7164_dev { - struct list_head devlist; - atomic_t refcount; - - /* pci stuff */ - struct pci_dev *pci; - unsigned char pci_rev, pci_lat; - int pci_bus, pci_slot; - u32 __iomem *lmmio; - u8 __iomem *bmmio; - u32 __iomem *lmmio2; - u8 __iomem *bmmio2; - int pci_irqmask; - - /* board details */ - int nr; - int hwrevision; - u32 board; - char name[16]; - - /* firmware status */ - struct saa7164_fw_status fw_status; - u32 firmwareloaded; - - struct tmComResHWDescr hwdesc; - struct tmComResInterfaceDescr intfdesc; - struct tmComResBusDescr busdesc; - - struct tmComResBusInfo bus; - - /* Interrupt status and ack registers */ - u32 int_status; - u32 int_ack; - - struct cmd cmds[SAA_CMD_MAX_MSG_UNITS]; - struct mutex lock; - - /* I2c related */ - struct saa7164_i2c i2c_bus[3]; - - /* Transport related */ - struct saa7164_port ports[SAA7164_MAX_PORTS]; - - /* Deferred command/api interrupts handling */ - struct work_struct workcmd; - - /* A kernel thread to monitor the firmware log, used - * only in debug mode. - */ - struct task_struct *kthread; - -}; - -extern struct list_head saa7164_devlist; -extern unsigned int waitsecs; -extern unsigned int encoder_buffers; -extern unsigned int vbi_buffers; - -/* ----------------------------------------------------------- */ -/* saa7164-core.c */ -void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr); -void saa7164_getfirmwarestatus(struct saa7164_dev *dev); -u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev); -void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val); - -/* ----------------------------------------------------------- */ -/* saa7164-fw.c */ -int saa7164_downloadfirmware(struct saa7164_dev *dev); - -/* ----------------------------------------------------------- */ -/* saa7164-i2c.c */ -extern int saa7164_i2c_register(struct saa7164_i2c *bus); -extern int saa7164_i2c_unregister(struct saa7164_i2c *bus); -extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus, - unsigned int cmd, void *arg); - -/* ----------------------------------------------------------- */ -/* saa7164-bus.c */ -int saa7164_bus_setup(struct saa7164_dev *dev); -void saa7164_bus_dump(struct saa7164_dev *dev); -int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, - void *buf); -int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, - void *buf, int peekonly); - -/* ----------------------------------------------------------- */ -/* saa7164-cmd.c */ -int saa7164_cmd_send(struct saa7164_dev *dev, - u8 id, enum tmComResCmd command, u16 controlselector, - u16 size, void *buf); -void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno); -int saa7164_irq_dequeue(struct saa7164_dev *dev); - -/* ----------------------------------------------------------- */ -/* saa7164-api.c */ -int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version); -int saa7164_api_enum_subdevs(struct saa7164_dev *dev); -int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, - u32 datalen, u8 *data); -int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, - u32 datalen, u8 *data); -int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr, - u32 datalen, u8 *data); -int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen); -int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin); -int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin); -int saa7164_api_transition_port(struct saa7164_port *port, u8 mode); -int saa7164_api_initialize_dif(struct saa7164_port *port); -int saa7164_api_configure_dif(struct saa7164_port *port, u32 std); -int saa7164_api_set_encoder(struct saa7164_port *port); -int saa7164_api_get_encoder(struct saa7164_port *port); -int saa7164_api_set_aspect_ratio(struct saa7164_port *port); -int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl); -int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl); -int saa7164_api_set_videomux(struct saa7164_port *port); -int saa7164_api_audio_mute(struct saa7164_port *port, int mute); -int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level); -int saa7164_api_set_audio_std(struct saa7164_port *port); -int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect); -int saa7164_api_get_videomux(struct saa7164_port *port); -int saa7164_api_set_vbi_format(struct saa7164_port *port); -int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level); -int saa7164_api_collect_debug(struct saa7164_dev *dev); -int saa7164_api_get_load_info(struct saa7164_dev *dev, - struct tmFwInfoStruct *i); - -/* ----------------------------------------------------------- */ -/* saa7164-cards.c */ -extern struct saa7164_board saa7164_boards[]; -extern const unsigned int saa7164_bcount; - -extern struct saa7164_subid saa7164_subids[]; -extern const unsigned int saa7164_idcount; - -extern void saa7164_card_list(struct saa7164_dev *dev); -extern void saa7164_gpio_setup(struct saa7164_dev *dev); -extern void saa7164_card_setup(struct saa7164_dev *dev); - -extern int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr); -extern int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr); -extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid); - -/* ----------------------------------------------------------- */ -/* saa7164-dvb.c */ -extern int saa7164_dvb_register(struct saa7164_port *port); -extern int saa7164_dvb_unregister(struct saa7164_port *port); - -/* ----------------------------------------------------------- */ -/* saa7164-buffer.c */ -extern struct saa7164_buffer *saa7164_buffer_alloc( - struct saa7164_port *port, u32 len); -extern int saa7164_buffer_dealloc(struct saa7164_buffer *buf); -extern void saa7164_buffer_display(struct saa7164_buffer *buf); -extern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i); -extern int saa7164_buffer_cfg_port(struct saa7164_port *port); -extern struct saa7164_user_buffer *saa7164_buffer_alloc_user( - struct saa7164_dev *dev, u32 len); -extern void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf); -extern int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i); - -/* ----------------------------------------------------------- */ -/* saa7164-encoder.c */ -int saa7164_encoder_register(struct saa7164_port *port); -void saa7164_encoder_unregister(struct saa7164_port *port); - -/* ----------------------------------------------------------- */ -/* saa7164-vbi.c */ -int saa7164_vbi_register(struct saa7164_port *port); -void saa7164_vbi_unregister(struct saa7164_port *port); - -/* ----------------------------------------------------------- */ - -extern unsigned int crc_checking; - -extern unsigned int saa_debug; -#define dprintk(level, fmt, arg...)\ - do { if (saa_debug & level)\ - printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\ - } while (0) - -#define log_warn(fmt, arg...)\ - do { \ - printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\ - } while (0) - -#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2)) -#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2)) - -#define saa7164_readb(reg) readl(dev->bmmio + (reg)) -#define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg)) - |