summaryrefslogtreecommitdiff
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-08-14 12:13:30 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-15 16:36:22 -0300
commitb285192a43f0432d82c2c10974204e78af0da596 (patch)
tree618aa87e760c9c949eca9e4df6ae0eeffa11dcfc /drivers/media/video/cx18
parent68de959f773a1d49096835c411390bceff5d1549 (diff)
downloadlwn-b285192a43f0432d82c2c10974204e78af0da596.tar.gz
lwn-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/cx18')
-rw-r--r--drivers/media/video/cx18/Kconfig35
-rw-r--r--drivers/media/video/cx18/Makefile13
-rw-r--r--drivers/media/video/cx18/cx18-alsa-main.c295
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.c175
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.h23
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.c356
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.h27
-rw-r--r--drivers/media/video/cx18/cx18-alsa.h75
-rw-r--r--drivers/media/video/cx18/cx18-audio.c92
-rw-r--r--drivers/media/video/cx18/cx18-audio.h24
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c471
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c1401
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h391
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c225
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c311
-rw-r--r--drivers/media/video/cx18/cx18-cards.c638
-rw-r--r--drivers/media/video/cx18/cx18-cards.h157
-rw-r--r--drivers/media/video/cx18/cx18-controls.c131
-rw-r--r--drivers/media/video/cx18/cx18-controls.h24
-rw-r--r--drivers/media/video/cx18/cx18-driver.c1360
-rw-r--r--drivers/media/video/cx18/cx18-driver.h730
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c609
-rw-r--r--drivers/media/video/cx18/cx18-dvb.h25
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c881
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h41
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c459
-rw-r--r--drivers/media/video/cx18/cx18-firmware.h25
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c347
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h34
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c330
-rw-r--r--drivers/media/video/cx18/cx18-i2c.h29
-rw-r--r--drivers/media/video/cx18/cx18-io.c97
-rw-r--r--drivers/media/video/cx18/cx18-io.h191
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c1194
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.h31
-rw-r--r--drivers/media/video/cx18/cx18-irq.c81
-rw-r--r--drivers/media/video/cx18/cx18-irq.h35
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c870
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h95
-rw-r--r--drivers/media/video/cx18/cx18-queue.c443
-rw-r--r--drivers/media/video/cx18/cx18-queue.h98
-rw-r--r--drivers/media/video/cx18/cx18-scb.c122
-rw-r--r--drivers/media/video/cx18/cx18-scb.h280
-rw-r--r--drivers/media/video/cx18/cx18-streams.c1060
-rw-r--r--drivers/media/video/cx18/cx18-streams.h62
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c277
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h26
-rw-r--r--drivers/media/video/cx18/cx18-version.h28
-rw-r--r--drivers/media/video/cx18/cx18-video.c32
-rw-r--r--drivers/media/video/cx18/cx18-video.h22
-rw-r--r--drivers/media/video/cx18/cx23418.h492
51 files changed, 0 insertions, 15270 deletions
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
deleted file mode 100644
index 53b3c7702573..000000000000
--- a/drivers/media/video/cx18/Kconfig
+++ /dev/null
@@ -1,35 +0,0 @@
-config VIDEO_CX18
- tristate "Conexant cx23418 MPEG encoder support"
- depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
- select I2C_ALGOBIT
- select VIDEOBUF_VMALLOC
- depends on RC_CORE
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_CX2341X
- select VIDEO_CS5345
- select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
- ---help---
- This is a video4linux driver for Conexant cx23418 based
- PCI combo video recorder devices.
-
- This is used in devices such as the Hauppauge HVR-1600
- cards.
-
- To compile this driver as a module, choose M here: the
- module will be called cx18.
-
-config VIDEO_CX18_ALSA
- tristate "Conexant 23418 DMA audio support"
- depends on VIDEO_CX18 && SND && EXPERIMENTAL
- select SND_PCM
- ---help---
- This is a video4linux driver for direct (DMA) audio on
- Conexant 23418 based TV cards using ALSA.
-
- To compile this driver as a module, choose M here: the
- module will be called cx18-alsa.
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile
deleted file mode 100644
index d3ff1545c2c5..000000000000
--- a/drivers/media/video/cx18/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \
- cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
- cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
- cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
- cx18-dvb.o cx18-io.o
-cx18-alsa-objs := cx18-alsa-main.o cx18-alsa-pcm.o
-
-obj-$(CONFIG_VIDEO_CX18) += cx18.o
-obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
-
-ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb-frontends
-ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
deleted file mode 100644
index 6d2a98246b6d..000000000000
--- a/drivers/media/video/cx18/cx18-alsa-main.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
- *
- * Portions of this work were sponsored by ONELAN Limited.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-
-#include <media/v4l2-device.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-
-#include "cx18-driver.h"
-#include "cx18-version.h"
-#include "cx18-alsa.h"
-#include "cx18-alsa-mixer.h"
-#include "cx18-alsa-pcm.h"
-
-int cx18_alsa_debug;
-
-#define CX18_DEBUG_ALSA_INFO(fmt, arg...) \
- do { \
- if (cx18_alsa_debug & 2) \
- printk(KERN_INFO "%s: " fmt, "cx18-alsa", ## arg); \
- } while (0);
-
-module_param_named(debug, cx18_alsa_debug, int, 0644);
-MODULE_PARM_DESC(debug,
- "Debug level (bitmask). Default: 0\n"
- "\t\t\t 1/0x0001: warning\n"
- "\t\t\t 2/0x0002: info\n");
-
-MODULE_AUTHOR("Andy Walls");
-MODULE_DESCRIPTION("CX23418 ALSA Interface");
-MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
-MODULE_LICENSE("GPL");
-
-MODULE_VERSION(CX18_VERSION);
-
-static inline
-struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
-{
- return to_cx18(v4l2_dev)->alsa;
-}
-
-static inline
-struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
-{
- return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
-}
-
-static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
-{
- if (cxsc == NULL)
- return;
-
- if (cxsc->v4l2_dev != NULL)
- to_cx18(cxsc->v4l2_dev)->alsa = NULL;
-
- /* FIXME - take any other stopping actions needed */
-
- kfree(cxsc);
-}
-
-static void snd_cx18_card_private_free(struct snd_card *sc)
-{
- if (sc == NULL)
- return;
- snd_cx18_card_free(sc->private_data);
- sc->private_data = NULL;
- sc->private_free = NULL;
-}
-
-static int snd_cx18_card_create(struct v4l2_device *v4l2_dev,
- struct snd_card *sc,
- struct snd_cx18_card **cxsc)
-{
- *cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL);
- if (*cxsc == NULL)
- return -ENOMEM;
-
- (*cxsc)->v4l2_dev = v4l2_dev;
- (*cxsc)->sc = sc;
-
- sc->private_data = *cxsc;
- sc->private_free = snd_cx18_card_private_free;
-
- return 0;
-}
-
-static int snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
-{
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- struct snd_card *sc = cxsc->sc;
-
- /* sc->driver is used by alsa-lib's configurator: simple, unique */
- strlcpy(sc->driver, "CX23418", sizeof(sc->driver));
-
- /* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
- snprintf(sc->shortname, sizeof(sc->shortname), "CX18-%d",
- cx->instance);
-
- /* sc->longname is read from /proc/asound/cards */
- snprintf(sc->longname, sizeof(sc->longname),
- "CX23418 #%d %s TV/FM Radio/Line-In Capture",
- cx->instance, cx->card_name);
-
- return 0;
-}
-
-static int snd_cx18_init(struct v4l2_device *v4l2_dev)
-{
- struct cx18 *cx = to_cx18(v4l2_dev);
- struct snd_card *sc = NULL;
- struct snd_cx18_card *cxsc;
- int ret;
-
- /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
-
- /* (1) Check and increment the device index */
- /* This is a no-op for us. We'll use the cx->instance */
-
- /* (2) Create a card instance */
- ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
- SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
- THIS_MODULE, 0, &sc);
- if (ret) {
- CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
- __func__, ret);
- goto err_exit;
- }
-
- /* (3) Create a main component */
- ret = snd_cx18_card_create(v4l2_dev, sc, &cxsc);
- if (ret) {
- CX18_ALSA_ERR("%s: snd_cx18_card_create() failed with err %d\n",
- __func__, ret);
- goto err_exit_free;
- }
-
- /* (4) Set the driver ID and name strings */
- snd_cx18_card_set_names(cxsc);
-
-
- ret = snd_cx18_pcm_create(cxsc);
- if (ret) {
- CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
- __func__, ret);
- goto err_exit_free;
- }
- /* FIXME - proc files */
-
- /* (7) Set the driver data and return 0 */
- /* We do this out of normal order for PCI drivers to avoid races */
- cx->alsa = cxsc;
-
- /* (6) Register the card instance */
- ret = snd_card_register(sc);
- if (ret) {
- cx->alsa = NULL;
- CX18_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
- __func__, ret);
- goto err_exit_free;
- }
-
- return 0;
-
-err_exit_free:
- if (sc != NULL)
- snd_card_free(sc);
- kfree(cxsc);
-err_exit:
- return ret;
-}
-
-int cx18_alsa_load(struct cx18 *cx)
-{
- struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
- struct cx18_stream *s;
-
- if (v4l2_dev == NULL) {
- printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
- __func__);
- return 0;
- }
-
- cx = to_cx18(v4l2_dev);
- if (cx == NULL) {
- printk(KERN_ERR "cx18-alsa cx is NULL\n");
- return 0;
- }
-
- s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
- if (s->video_dev == NULL) {
- CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
- "skipping\n", __func__);
- return 0;
- }
-
- if (cx->alsa != NULL) {
- CX18_ALSA_ERR("%s: struct snd_cx18_card * already exists\n",
- __func__);
- return 0;
- }
-
- if (snd_cx18_init(v4l2_dev)) {
- CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n",
- __func__);
- } else {
- CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance "
- "\n", __func__);
- }
- return 0;
-}
-
-static int __init cx18_alsa_init(void)
-{
- printk(KERN_INFO "cx18-alsa: module loading...\n");
- cx18_ext_init = &cx18_alsa_load;
- return 0;
-}
-
-static void __exit snd_cx18_exit(struct snd_cx18_card *cxsc)
-{
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
-
- /* FIXME - pointer checks & shutdown cxsc */
-
- snd_card_free(cxsc->sc);
- cx->alsa = NULL;
-}
-
-static int __exit cx18_alsa_exit_callback(struct device *dev, void *data)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct snd_cx18_card *cxsc;
-
- if (v4l2_dev == NULL) {
- printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
- __func__);
- return 0;
- }
-
- cxsc = to_snd_cx18_card(v4l2_dev);
- if (cxsc == NULL) {
- CX18_ALSA_WARN("%s: struct snd_cx18_card * is NULL\n",
- __func__);
- return 0;
- }
-
- snd_cx18_exit(cxsc);
- return 0;
-}
-
-static void __exit cx18_alsa_exit(void)
-{
- struct device_driver *drv;
- int ret;
-
- printk(KERN_INFO "cx18-alsa: module unloading...\n");
-
- drv = driver_find("cx18", &pci_bus_type);
- ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
- (void)ret; /* suppress compiler warning */
-
- cx18_ext_init = NULL;
- printk(KERN_INFO "cx18-alsa: module unload complete\n");
-}
-
-module_init(cx18_alsa_init);
-module_exit(cx18_alsa_exit);
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/video/cx18/cx18-alsa-mixer.c
deleted file mode 100644
index 341bddc00b77..000000000000
--- a/drivers/media/video/cx18/cx18-alsa-mixer.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * ALSA mixer controls for the
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-
-#include "cx18-alsa.h"
-#include "cx18-driver.h"
-
-/*
- * Note the cx18-av-core volume scale is funny, due to the alignment of the
- * scale with another chip's range:
- *
- * v4l2_control value /512 indicated dB actual dB reg 0x8d4
- * 0x0000 - 0x01ff 0 -119 -96 228
- * 0x0200 - 0x02ff 1 -118 -96 228
- * ...
- * 0x2c00 - 0x2dff 22 -97 -96 228
- * 0x2e00 - 0x2fff 23 -96 -96 228
- * 0x3000 - 0x31ff 24 -95 -95 226
- * ...
- * 0xee00 - 0xefff 119 0 0 36
- * ...
- * 0xfe00 - 0xffff 127 +8 +8 20
- */
-static inline int dB_to_cx18_av_vol(int dB)
-{
- if (dB < -96)
- dB = -96;
- else if (dB > 8)
- dB = 8;
- return (dB + 119) << 9;
-}
-
-static inline int cx18_av_vol_to_dB(int v)
-{
- if (v < (23 << 9))
- v = (23 << 9);
- else if (v > (127 << 9))
- v = (127 << 9);
- return (v >> 9) - 119;
-}
-
-static int snd_cx18_mixer_tv_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- /* We're already translating values, just keep this control in dB */
- uinfo->value.integer.min = -96;
- uinfo->value.integer.max = 8;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- struct v4l2_control vctrl;
- int ret;
-
- vctrl.id = V4L2_CID_AUDIO_VOLUME;
- vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
-
- snd_cx18_lock(cxsc);
- ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
- snd_cx18_unlock(cxsc);
-
- if (!ret)
- uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value);
- return ret;
-}
-
-static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- struct v4l2_control vctrl;
- int ret;
-
- vctrl.id = V4L2_CID_AUDIO_VOLUME;
- vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
-
- snd_cx18_lock(cxsc);
-
- /* Fetch current state */
- ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
-
- if (ret ||
- (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) {
-
- /* Set, if needed */
- vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
- ret = v4l2_subdev_call(cx->sd_av, core, s_ctrl, &vctrl);
- if (!ret)
- ret = 1; /* Indicate control was changed w/o error */
- }
- snd_cx18_unlock(cxsc);
-
- return ret;
-}
-
-
-/* This is a bit of overkill, the slider is already in dB internally */
-static DECLARE_TLV_DB_SCALE(snd_cx18_mixer_tv_vol_db_scale, -9600, 100, 0);
-
-static struct snd_kcontrol_new snd_cx18_mixer_tv_vol __initdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog TV Capture Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_cx18_mixer_tv_volume_info,
- .get = snd_cx18_mixer_tv_volume_get,
- .put = snd_cx18_mixer_tv_volume_put,
- .tlv.p = snd_cx18_mixer_tv_vol_db_scale
-};
-
-/* FIXME - add mute switch and balance, bass, treble sliders:
- V4L2_CID_AUDIO_MUTE
-
- V4L2_CID_AUDIO_BALANCE
-
- V4L2_CID_AUDIO_BASS
- V4L2_CID_AUDIO_TREBLE
-*/
-
-/* FIXME - add stereo, lang1, lang2, mono menu */
-/* FIXME - add CS5345 I2S volume for HVR-1600 */
-
-int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc)
-{
- struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
- struct snd_card *sc = cxsc->sc;
- int ret;
-
- strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername));
-
- ret = snd_ctl_add(sc, snd_ctl_new1(snd_cx18_mixer_tv_vol, cxsc));
- if (ret) {
- CX18_ALSA_WARN("%s: failed to add %s control, err %d\n",
- __func__, snd_cx18_mixer_tv_vol.name, ret);
- }
- return ret;
-}
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/video/cx18/cx18-alsa-mixer.h
deleted file mode 100644
index ec9238793f6f..000000000000
--- a/drivers/media/video/cx18/cx18-alsa-mixer.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * ALSA mixer controls for the
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc);
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c
deleted file mode 100644
index 7a5b84a86bb3..000000000000
--- a/drivers/media/video/cx18/cx18-alsa-pcm.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * ALSA PCM device for the
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
- *
- * Portions of this work were sponsored by ONELAN Limited.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/vmalloc.h>
-
-#include <media/v4l2-device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "cx18-driver.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-fileops.h"
-#include "cx18-alsa.h"
-
-static unsigned int pcm_debug;
-module_param(pcm_debug, int, 0644);
-MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
-
-#define dprintk(fmt, arg...) do { \
- if (pcm_debug) \
- printk(KERN_INFO "cx18-alsa-pcm %s: " fmt, \
- __func__, ##arg); \
- } while (0)
-
-static struct snd_pcm_hardware snd_cx18_hw_capture = {
- .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID,
-
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- .rates = SNDRV_PCM_RATE_48000,
-
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
- .period_bytes_min = 64, /* 12544/2, */
- .period_bytes_max = 12544,
- .periods_min = 2,
- .periods_max = 98, /* 12544, */
-};
-
-void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
- size_t num_bytes)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned int oldptr;
- unsigned int stride;
- int period_elapsed = 0;
- int length;
-
- dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
- pcm_data, num_bytes);
-
- substream = cxsc->capture_pcm_substream;
- if (substream == NULL) {
- dprintk("substream was NULL\n");
- return;
- }
-
- runtime = substream->runtime;
- if (runtime == NULL) {
- dprintk("runtime was NULL\n");
- return;
- }
-
- stride = runtime->frame_bits >> 3;
- if (stride == 0) {
- dprintk("stride is zero\n");
- return;
- }
-
- length = num_bytes / stride;
- if (length == 0) {
- dprintk("%s: length was zero\n", __func__);
- return;
- }
-
- if (runtime->dma_area == NULL) {
- dprintk("dma area was NULL - ignoring\n");
- return;
- }
-
- oldptr = cxsc->hwptr_done_capture;
- if (oldptr + length >= runtime->buffer_size) {
- unsigned int cnt =
- runtime->buffer_size - oldptr;
- memcpy(runtime->dma_area + oldptr * stride, pcm_data,
- cnt * stride);
- memcpy(runtime->dma_area, pcm_data + cnt * stride,
- length * stride - cnt * stride);
- } else {
- memcpy(runtime->dma_area + oldptr * stride, pcm_data,
- length * stride);
- }
- snd_pcm_stream_lock(substream);
-
- cxsc->hwptr_done_capture += length;
- if (cxsc->hwptr_done_capture >=
- runtime->buffer_size)
- cxsc->hwptr_done_capture -=
- runtime->buffer_size;
-
- cxsc->capture_transfer_done += length;
- if (cxsc->capture_transfer_done >=
- runtime->period_size) {
- cxsc->capture_transfer_done -=
- runtime->period_size;
- period_elapsed = 1;
- }
-
- snd_pcm_stream_unlock(substream);
-
- if (period_elapsed)
- snd_pcm_period_elapsed(substream);
-}
-
-static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
- struct cx18 *cx = to_cx18(v4l2_dev);
- struct cx18_stream *s;
- struct cx18_open_id item;
- int ret;
-
- /* Instruct the cx18 to start sending packets */
- snd_cx18_lock(cxsc);
- s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
-
- item.cx = cx;
- item.type = s->type;
- item.open_id = cx->open_id++;
-
- /* See if the stream is available */
- if (cx18_claim_stream(&item, item.type)) {
- /* No, it's already in use */
- snd_cx18_unlock(cxsc);
- return -EBUSY;
- }
-
- if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
- test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- /* We're already streaming. No additional action required */
- snd_cx18_unlock(cxsc);
- return 0;
- }
-
-
- runtime->hw = snd_cx18_hw_capture;
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- cxsc->capture_pcm_substream = substream;
- runtime->private_data = cx;
-
- cx->pcm_announce_callback = cx18_alsa_announce_pcm_data;
-
- /* Not currently streaming, so start it up */
- set_bit(CX18_F_S_STREAMING, &s->s_flags);
- ret = cx18_start_v4l2_encode_stream(s);
- snd_cx18_unlock(cxsc);
-
- return ret;
-}
-
-static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
- struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
- struct cx18 *cx = to_cx18(v4l2_dev);
- struct cx18_stream *s;
-
- /* Instruct the cx18 to stop sending packets */
- snd_cx18_lock(cxsc);
- s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
- cx18_stop_v4l2_encode_stream(s, 0);
- clear_bit(CX18_F_S_STREAMING, &s->s_flags);
-
- cx18_release_stream(s);
-
- cx->pcm_announce_callback = NULL;
- snd_cx18_unlock(cxsc);
-
- return 0;
-}
-
-static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
- int ret;
-
- snd_cx18_lock(cxsc);
- ret = snd_pcm_lib_ioctl(substream, cmd, arg);
- snd_cx18_unlock(cxsc);
- return ret;
-}
-
-
-static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
- size_t size)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- dprintk("Allocating vbuffer\n");
- if (runtime->dma_area) {
- if (runtime->dma_bytes > size)
- return 0;
-
- vfree(runtime->dma_area);
- }
- runtime->dma_area = vmalloc(size);
- if (!runtime->dma_area)
- return -ENOMEM;
-
- runtime->dma_bytes = size;
-
- return 0;
-}
-
-static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- dprintk("%s called\n", __func__);
-
- return snd_pcm_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(params));
-}
-
-static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
- unsigned long flags;
-
- spin_lock_irqsave(&cxsc->slock, flags);
- if (substream->runtime->dma_area) {
- dprintk("freeing pcm capture region\n");
- vfree(substream->runtime->dma_area);
- substream->runtime->dma_area = NULL;
- }
- spin_unlock_irqrestore(&cxsc->slock, flags);
-
- return 0;
-}
-
-static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
-
- cxsc->hwptr_done_capture = 0;
- cxsc->capture_transfer_done = 0;
-
- return 0;
-}
-
-static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- return 0;
-}
-
-static
-snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- snd_pcm_uframes_t hwptr_done;
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
-
- spin_lock_irqsave(&cxsc->slock, flags);
- hwptr_done = cxsc->hwptr_done_capture;
- spin_unlock_irqrestore(&cxsc->slock, flags);
-
- return hwptr_done;
-}
-
-static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
- unsigned long offset)
-{
- void *pageptr = subs->runtime->dma_area + offset;
-
- return vmalloc_to_page(pageptr);
-}
-
-static struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
- .open = snd_cx18_pcm_capture_open,
- .close = snd_cx18_pcm_capture_close,
- .ioctl = snd_cx18_pcm_ioctl,
- .hw_params = snd_cx18_pcm_hw_params,
- .hw_free = snd_cx18_pcm_hw_free,
- .prepare = snd_cx18_pcm_prepare,
- .trigger = snd_cx18_pcm_trigger,
- .pointer = snd_cx18_pcm_pointer,
- .page = snd_pcm_get_vmalloc_page,
-};
-
-int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
-{
- struct snd_pcm *sp;
- struct snd_card *sc = cxsc->sc;
- struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
- struct cx18 *cx = to_cx18(v4l2_dev);
- int ret;
-
- ret = snd_pcm_new(sc, "CX23418 PCM",
- 0, /* PCM device 0, the only one for this card */
- 0, /* 0 playback substreams */
- 1, /* 1 capture substream */
- &sp);
- if (ret) {
- CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
- __func__, ret);
- goto err_exit;
- }
-
- spin_lock_init(&cxsc->slock);
-
- snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
- &snd_cx18_pcm_capture_ops);
- sp->info_flags = 0;
- sp->private_data = cxsc;
- strlcpy(sp->name, cx->card_name, sizeof(sp->name));
-
- return 0;
-
-err_exit:
- return ret;
-}
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/video/cx18/cx18-alsa-pcm.h
deleted file mode 100644
index d26e51f94577..000000000000
--- a/drivers/media/video/cx18/cx18-alsa-pcm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * ALSA PCM device for the
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
-
-/* Used by cx18-mailbox to announce the PCM data to the module */
-void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
- size_t num_bytes);
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h
deleted file mode 100644
index 447da374c9e8..000000000000
--- a/drivers/media/video/cx18/cx18-alsa.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-struct snd_card;
-
-struct snd_cx18_card {
- struct v4l2_device *v4l2_dev;
- struct snd_card *sc;
- unsigned int capture_transfer_done;
- unsigned int hwptr_done_capture;
- struct snd_pcm_substream *capture_pcm_substream;
- spinlock_t slock;
-};
-
-extern int cx18_alsa_debug;
-
-/*
- * File operations that manipulate the encoder or video or audio subdevices
- * need to be serialized. Use the same lock we use for v4l2 file ops.
- */
-static inline void snd_cx18_lock(struct snd_cx18_card *cxsc)
-{
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- mutex_lock(&cx->serialize_lock);
-}
-
-static inline void snd_cx18_unlock(struct snd_cx18_card *cxsc)
-{
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- mutex_unlock(&cx->serialize_lock);
-}
-
-#define CX18_ALSA_DBGFLG_WARN (1 << 0)
-#define CX18_ALSA_DBGFLG_WARN (1 << 0)
-#define CX18_ALSA_DBGFLG_INFO (1 << 1)
-
-#define CX18_ALSA_DEBUG(x, type, fmt, args...) \
- do { \
- if ((x) & cx18_alsa_debug) \
- printk(KERN_INFO "%s-alsa: " type ": " fmt, \
- v4l2_dev->name , ## args); \
- } while (0)
-
-#define CX18_ALSA_DEBUG_WARN(fmt, args...) \
- CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_WARN, "warning", fmt , ## args)
-
-#define CX18_ALSA_DEBUG_INFO(fmt, args...) \
- CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_INFO, "info", fmt , ## args)
-
-#define CX18_ALSA_ERR(fmt, args...) \
- printk(KERN_ERR "%s-alsa: " fmt, v4l2_dev->name , ## args)
-
-#define CX18_ALSA_WARN(fmt, args...) \
- printk(KERN_WARNING "%s-alsa: " fmt, v4l2_dev->name , ## args)
-
-#define CX18_ALSA_INFO(fmt, args...) \
- printk(KERN_INFO "%s-alsa: " fmt, v4l2_dev->name , ## args)
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
deleted file mode 100644
index 35268923911c..000000000000
--- a/drivers/media/video/cx18/cx18-audio.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * cx18 audio-related functions
- *
- * Derived from ivtv-audio.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-cards.h"
-#include "cx18-audio.h"
-
-#define CX18_AUDIO_ENABLE 0xc72014
-#define CX18_AI1_MUX_MASK 0x30
-#define CX18_AI1_MUX_I2S1 0x00
-#define CX18_AI1_MUX_I2S2 0x10
-#define CX18_AI1_MUX_843_I2S 0x20
-
-/* Selects the audio input and output according to the current
- settings. */
-int cx18_audio_set_io(struct cx18 *cx)
-{
- const struct cx18_card_audio_input *in;
- u32 u, v;
- int err;
-
- /* Determine which input to use */
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
- in = &cx->card->radio_input;
- else
- in = &cx->card->audio_inputs[cx->audio_input];
-
- /* handle muxer chips */
- v4l2_subdev_call(cx->sd_extmux, audio, s_routing,
- (u32) in->muxer_input, 0, 0);
-
- err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
- audio, s_routing, in->audio_input, 0, 0);
- if (err)
- return err;
-
- /* FIXME - this internal mux should be abstracted to a subdev */
- u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
- v = u & ~CX18_AI1_MUX_MASK;
- switch (in->audio_input) {
- case CX18_AV_AUDIO_SERIAL1:
- v |= CX18_AI1_MUX_I2S1;
- break;
- case CX18_AV_AUDIO_SERIAL2:
- v |= CX18_AI1_MUX_I2S2;
- break;
- default:
- v |= CX18_AI1_MUX_843_I2S;
- break;
- }
- if (v == u) {
- /* force a toggle of some AI1 MUX control bits */
- u &= ~CX18_AI1_MUX_MASK;
- switch (in->audio_input) {
- case CX18_AV_AUDIO_SERIAL1:
- u |= CX18_AI1_MUX_843_I2S;
- break;
- case CX18_AV_AUDIO_SERIAL2:
- u |= CX18_AI1_MUX_843_I2S;
- break;
- default:
- u |= CX18_AI1_MUX_I2S1;
- break;
- }
- cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
- u, CX18_AI1_MUX_MASK);
- }
- cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
- v, CX18_AI1_MUX_MASK);
- return 0;
-}
diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/video/cx18/cx18-audio.h
deleted file mode 100644
index 2731d29b0ab9..000000000000
--- a/drivers/media/video/cx18/cx18-audio.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * cx18 audio-related functions
- *
- * Derived from ivtv-audio.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int cx18_audio_set_io(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
deleted file mode 100644
index 4a24ffb17a7d..000000000000
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * cx18 ADEC audio functions
- *
- * Derived from cx25840-audio.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "cx18-driver.h"
-
-static int set_audclk_freq(struct cx18 *cx, u32 freq)
-{
- struct cx18_av_state *state = &cx->av_state;
-
- if (freq != 32000 && freq != 44100 && freq != 48000)
- return -EINVAL;
-
- /*
- * The PLL parameters are based on the external crystal frequency that
- * would ideally be:
- *
- * NTSC Color subcarrier freq * 8 =
- * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
- *
- * The accidents of history and rationale that explain from where this
- * combination of magic numbers originate can be found in:
- *
- * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
- * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
- *
- * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
- * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
- *
- * As Mike Bradley has rightly pointed out, it's not the exact crystal
- * frequency that matters, only that all parts of the driver and
- * firmware are using the same value (close to the ideal value).
- *
- * Since I have a strong suspicion that, if the firmware ever assumes a
- * crystal value at all, it will assume 28.636360 MHz, the crystal
- * freq used in calculations in this driver will be:
- *
- * xtal_freq = 28.636360 MHz
- *
- * an error of less than 0.13 ppm which is way, way better than any off
- * the shelf crystal will have for accuracy anyway.
- *
- * Below I aim to run the PLLs' VCOs near 400 MHz to minimze error.
- *
- * Many thanks to Jeff Campbell and Mike Bradley for their extensive
- * investigation, experimentation, testing, and suggested solutions of
- * of audio/video sync problems with SVideo and CVBS captures.
- */
-
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- switch (freq) {
- case 32000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
- */
- cx18_av_write4(cx, 0x108, 0x200d040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x176740c */
- /* xtal * 0xd.bb3a060/0x20 = 32000 * 384: 393 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0176740c);
-
- /* src3/4/6_ctl */
- /* 0x1.f77f = (4 * xtal/8*2/455) / 32000 */
- cx18_av_write4(cx, 0x900, 0x0801f77f);
- cx18_av_write4(cx, 0x904, 0x0801f77f);
- cx18_av_write4(cx, 0x90c, 0x0801f77f);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
- cx18_av_write(cx, 0x127, 0x60);
-
- /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
- cx18_av_write4(cx, 0x12c, 0x11202fff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
- * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa00d2ef8);
- break;
-
- case 44100:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x18
- */
- cx18_av_write4(cx, 0x108, 0x180e040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x062a1f2 */
- /* xtal * 0xe.3150f90/0x18 = 44100 * 384: 406 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0062a1f2);
-
- /* src3/4/6_ctl */
- /* 0x1.6d59 = (4 * xtal/8*2/455) / 44100 */
- cx18_av_write4(cx, 0x900, 0x08016d59);
- cx18_av_write4(cx, 0x904, 0x08016d59);
- cx18_av_write4(cx, 0x90c, 0x08016d59);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x18 */
- cx18_av_write(cx, 0x127, 0x58);
-
- /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
- cx18_av_write4(cx, 0x12c, 0x112092ff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
- * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa01d4bf8);
- break;
-
- case 48000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x16
- */
- cx18_av_write4(cx, 0x108, 0x160e040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x05227ad */
- /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x005227ad);
-
- /* src3/4/6_ctl */
- /* 0x1.4faa = (4 * xtal/8*2/455) / 48000 */
- cx18_av_write4(cx, 0x900, 0x08014faa);
- cx18_av_write4(cx, 0x904, 0x08014faa);
- cx18_av_write4(cx, 0x90c, 0x08014faa);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
- cx18_av_write(cx, 0x127, 0x56);
-
- /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
- cx18_av_write4(cx, 0x12c, 0x11205fff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
- * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa01193f8);
- break;
- }
- } else {
- switch (freq) {
- case 32000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x30
- */
- cx18_av_write4(cx, 0x108, 0x300d040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x176740c */
- /* xtal * 0xd.bb3a060/0x30 = 32000 * 256: 393 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0176740c);
-
- /* src1_ctl */
- /* 0x1.0000 = 32000/32000 */
- cx18_av_write4(cx, 0x8f8, 0x08010000);
-
- /* src3/4/6_ctl */
- /* 0x2.0000 = 2 * (32000/32000) */
- cx18_av_write4(cx, 0x900, 0x08020000);
- cx18_av_write4(cx, 0x904, 0x08020000);
- cx18_av_write4(cx, 0x90c, 0x08020000);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x30 */
- cx18_av_write(cx, 0x127, 0x70);
-
- /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
- cx18_av_write4(cx, 0x12c, 0x11201fff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
- * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa00d2ef8);
- break;
-
- case 44100:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x24
- */
- cx18_av_write4(cx, 0x108, 0x240e040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x062a1f2 */
- /* xtal * 0xe.3150f90/0x24 = 44100 * 256: 406 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0062a1f2);
-
- /* src1_ctl */
- /* 0x1.60cd = 44100/32000 */
- cx18_av_write4(cx, 0x8f8, 0x080160cd);
-
- /* src3/4/6_ctl */
- /* 0x1.7385 = 2 * (32000/44100) */
- cx18_av_write4(cx, 0x900, 0x08017385);
- cx18_av_write4(cx, 0x904, 0x08017385);
- cx18_av_write4(cx, 0x90c, 0x08017385);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x24 */
- cx18_av_write(cx, 0x127, 0x64);
-
- /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
- cx18_av_write4(cx, 0x12c, 0x112061ff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
- * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa01d4bf8);
- break;
-
- case 48000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
- */
- cx18_av_write4(cx, 0x108, 0x200d040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x176740c */
- /* xtal * 0xd.bb3a060/0x20 = 48000 * 256: 393 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0176740c);
-
- /* src1_ctl */
- /* 0x1.8000 = 48000/32000 */
- cx18_av_write4(cx, 0x8f8, 0x08018000);
-
- /* src3/4/6_ctl */
- /* 0x1.5555 = 2 * (32000/48000) */
- cx18_av_write4(cx, 0x900, 0x08015555);
- cx18_av_write4(cx, 0x904, 0x08015555);
- cx18_av_write4(cx, 0x90c, 0x08015555);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
- cx18_av_write(cx, 0x127, 0x60);
-
- /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
- cx18_av_write4(cx, 0x12c, 0x11203fff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
- * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa01193f8);
- break;
- }
- }
-
- state->audclk_freq = freq;
-
- return 0;
-}
-
-void cx18_av_audio_set_path(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- u8 v;
-
- /* stop microcontroller */
- v = cx18_av_read(cx, 0x803) & ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
-
- /* assert soft reset */
- v = cx18_av_read(cx, 0x810) | 0x01;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-
- /* Mute everything to prevent the PFFT! */
- cx18_av_write(cx, 0x8d3, 0x1f);
-
- if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
- /* Set Path1 to Serial Audio Input */
- cx18_av_write4(cx, 0x8d0, 0x01011012);
-
- /* The microcontroller should not be started for the
- * non-tuner inputs: autodetection is specific for
- * TV audio. */
- } else {
- /* Set Path1 to Analog Demod Main Channel */
- cx18_av_write4(cx, 0x8d0, 0x1f063870);
- }
-
- set_audclk_freq(cx, state->audclk_freq);
-
- /* deassert soft reset */
- v = cx18_av_read(cx, 0x810) & ~0x01;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- /* When the microcontroller detects the
- * audio format, it will unmute the lines */
- v = cx18_av_read(cx, 0x803) | 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
-}
-
-static void set_volume(struct cx18 *cx, int volume)
-{
- /* First convert the volume to msp3400 values (0-127) */
- int vol = volume >> 9;
- /* now scale it up to cx18_av values
- * -114dB to -96dB maps to 0
- * this should be 19, but in my testing that was 4dB too loud */
- if (vol <= 23)
- vol = 0;
- else
- vol -= 23;
-
- /* PATH1_VOLUME */
- cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
-}
-
-static void set_bass(struct cx18 *cx, int bass)
-{
- /* PATH1_EQ_BASS_VOL */
- cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
-}
-
-static void set_treble(struct cx18 *cx, int treble)
-{
- /* PATH1_EQ_TREBLE_VOL */
- cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
-}
-
-static void set_balance(struct cx18 *cx, int balance)
-{
- int bal = balance >> 8;
- if (bal > 0x80) {
- /* PATH1_BAL_LEFT */
- cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
- /* PATH1_BAL_LEVEL */
- cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
- } else {
- /* PATH1_BAL_LEFT */
- cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
- /* PATH1_BAL_LEVEL */
- cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
- }
-}
-
-static void set_mute(struct cx18 *cx, int mute)
-{
- struct cx18_av_state *state = &cx->av_state;
- u8 v;
-
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- /* Must turn off microcontroller in order to mute sound.
- * Not sure if this is the best method, but it does work.
- * If the microcontroller is running, then it will undo any
- * changes to the mute register. */
- v = cx18_av_read(cx, 0x803);
- if (mute) {
- /* disable microcontroller */
- v &= ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- cx18_av_write(cx, 0x8d3, 0x1f);
- } else {
- /* enable microcontroller */
- v |= 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
- } else {
- /* SRC1_MUTE_EN */
- cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
- }
-}
-
-int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
- int retval;
- u8 v;
-
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) & ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- cx18_av_write(cx, 0x8d3, 0x1f);
- }
- v = cx18_av_read(cx, 0x810) | 0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-
- retval = set_audclk_freq(cx, freq);
-
- v = cx18_av_read(cx, 0x810) & ~0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) | 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
- return retval;
-}
-
-static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(cx, ctrl->val);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(cx, ctrl->val);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(cx, ctrl->val);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(cx, ctrl->val);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(cx, ctrl->val);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops = {
- .s_ctrl = cx18_av_audio_s_ctrl,
-};
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
deleted file mode 100644
index f164b7f610a5..000000000000
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ /dev/null
@@ -1,1401 +0,0 @@
-/*
- * cx18 ADEC audio functions
- *
- * Derived from cx25840-core.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <media/v4l2-chip-ident.h>
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-cards.h"
-
-int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
-{
- u32 reg = 0xc40000 + (addr & ~3);
- u32 mask = 0xff;
- int shift = (addr & 3) * 8;
- u32 x = cx18_read_reg(cx, reg);
-
- x = (x & ~(mask << shift)) | ((u32)value << shift);
- cx18_write_reg(cx, x, reg);
- return 0;
-}
-
-int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask)
-{
- u32 reg = 0xc40000 + (addr & ~3);
- int shift = (addr & 3) * 8;
- u32 x = cx18_read_reg(cx, reg);
-
- x = (x & ~((u32)0xff << shift)) | ((u32)value << shift);
- cx18_write_reg_expect(cx, x, reg,
- ((u32)eval << shift), ((u32)mask << shift));
- return 0;
-}
-
-int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
-{
- cx18_write_reg(cx, value, 0xc40000 + addr);
- return 0;
-}
-
-int
-cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval, u32 mask)
-{
- cx18_write_reg_expect(cx, value, 0xc40000 + addr, eval, mask);
- return 0;
-}
-
-int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value)
-{
- cx18_write_reg_noretry(cx, value, 0xc40000 + addr);
- return 0;
-}
-
-u8 cx18_av_read(struct cx18 *cx, u16 addr)
-{
- u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3));
- int shift = (addr & 3) * 8;
-
- return (x >> shift) & 0xff;
-}
-
-u32 cx18_av_read4(struct cx18 *cx, u16 addr)
-{
- return cx18_read_reg(cx, 0xc40000 + addr);
-}
-
-int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
- u8 or_value)
-{
- return cx18_av_write(cx, addr,
- (cx18_av_read(cx, addr) & and_mask) |
- or_value);
-}
-
-int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
- u32 or_value)
-{
- return cx18_av_write4(cx, addr,
- (cx18_av_read4(cx, addr) & and_mask) |
- or_value);
-}
-
-static void cx18_av_init(struct cx18 *cx)
-{
- /*
- * The crystal freq used in calculations in this driver will be
- * 28.636360 MHz.
- * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
- */
-
- /*
- * VDCLK Integer = 0x0f, Post Divider = 0x04
- * AIMCLK Integer = 0x0e, Post Divider = 0x16
- */
- cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
-
- /* VDCLK Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
- cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
-
- /* AIMCLK Fraction = 0x05227ad */
- /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
- cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
- cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
-}
-
-static void cx18_av_initialize(struct v4l2_subdev *sd)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- int default_volume;
- u32 v;
-
- cx18_av_loadfw(cx);
- /* Stop 8051 code execution */
- cx18_av_write4_expect(cx, CXADEC_DL_CTL, 0x03000000,
- 0x03000000, 0x13000000);
-
- /* initallize the PLL by toggling sleep bit */
- v = cx18_av_read4(cx, CXADEC_HOST_REG1);
- /* enable sleep mode - register appears to be read only... */
- cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v | 1, v, 0xfffe);
- /* disable sleep mode */
- cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v & 0xfffe,
- v & 0xfffe, 0xffff);
-
- /* initialize DLLs */
- v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
- /* disable FLD */
- cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v);
- /* enable FLD */
- cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100);
-
- v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF;
- /* disable FLD */
- cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v);
- /* enable FLD */
- cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100);
-
- /* set analog bias currents. Set Vreg to 1.20V. */
- cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802);
-
- v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
- /* enable TUNE_FIL_RST */
- cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3, v, v, 0x03009F0F);
- /* disable TUNE_FIL_RST */
- cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3,
- v & 0xFFFFFFFE, v & 0xFFFFFFFE, 0x03009F0F);
-
- /* enable 656 output */
- cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
-
- /* video output drive strength */
- cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2);
-
- /* reset video */
- cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
- cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
-
- /*
- * Disable Video Auto-config of the Analog Front End and Video PLL.
- *
- * Since we only use BT.656 pixel mode, which works for both 525 and 625
- * line systems, it's just easier for us to set registers
- * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL),
- * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC)
- * ourselves, than to run around cleaning up after the auto-config.
- *
- * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit
- * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL
- * autoconfig either.)
- *
- * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3.
- */
- cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
-
- /* Setup the Video and and Aux/Audio PLLs */
- cx18_av_init(cx);
-
- /* set video to auto-detect */
- /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
- /* set the comb notch = 1 */
- cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800);
-
- /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
- /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
- cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000);
-
- /* Set VGA_TRACK_RANGE to 0x20 */
- cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
-
- /*
- * Initial VBI setup
- * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
- * don't clamp raw samples when codes are in use, 1 byte user D-words,
- * IDID0 has line #, RP code V bit transition on VBLANK, data during
- * blanking intervals
- */
- cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);
-
- /* Set the video input.
- The setting in MODE_CTRL gets lost when we do the above setup */
- /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
- /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
-
- /*
- * Analog Front End (AFE)
- * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2
- * bypass_ch[1-3] use filter
- * droop_comp_ch[1-3] disable
- * clamp_en_ch[1-3] disable
- * aud_in_sel ADC2
- * luma_in_sel ADC1
- * chroma_in_sel ADC2
- * clamp_sel_ch[2-3] midcode
- * clamp_sel_ch1 video decoder
- * vga_sel_ch3 audio decoder
- * vga_sel_ch[1-2] video decoder
- * half_bw_ch[1-3] disable
- * +12db_ch[1-3] disable
- */
- cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
-
-/* if(dwEnable && dw3DCombAvailable) { */
-/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
-/* } else { */
-/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
-/* } */
- cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
- default_volume = cx18_av_read(cx, 0x8d4);
- /*
- * Enforce the legacy volume scale mapping limits to avoid
- * -ERANGE errors when initializing the volume control
- */
- if (default_volume > 228) {
- /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
- default_volume = 228;
- cx18_av_write(cx, 0x8d4, 228);
- } else if (default_volume < 20) {
- /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
- default_volume = 20;
- cx18_av_write(cx, 0x8d4, 20);
- }
- default_volume = (((228 - default_volume) >> 1) + 23) << 9;
- state->volume->cur.val = state->volume->default_value = default_volume;
- v4l2_ctrl_handler_setup(&state->hdl);
-}
-
-static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
-{
- cx18_av_initialize(sd);
- return 0;
-}
-
-static int cx18_av_load_fw(struct v4l2_subdev *sd)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
-
- if (!state->is_initialized) {
- /* initialize on first use */
- state->is_initialized = 1;
- cx18_av_initialize(sd);
- }
- return 0;
-}
-
-void cx18_av_std_setup(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd = &state->sd;
- v4l2_std_id std = state->std;
-
- /*
- * Video ADC crystal clock to pixel clock SRC decimation ratio
- * 28.636360 MHz/13.5 Mpps * 256 = 0x21f.07b
- */
- const int src_decimation = 0x21f;
-
- int hblank, hactive, burst, vblank, vactive, sc;
- int vblank656;
- int luma_lpf, uv_lpf, comb;
- u32 pll_int, pll_frac, pll_post;
-
- /* datasheet startup, step 8d */
- if (std & ~V4L2_STD_NTSC)
- cx18_av_write(cx, 0x49f, 0x11);
- else
- cx18_av_write(cx, 0x49f, 0x14);
-
- /*
- * Note: At the end of a field, there are 3 sets of half line duration
- * (double horizontal rate) pulses:
- *
- * 5 (625) or 6 (525) half-lines to blank for the vertical retrace
- * 5 (625) or 6 (525) vertical sync pulses of half line duration
- * 5 (625) or 6 (525) half-lines of equalization pulses
- */
- if (std & V4L2_STD_625_50) {
- /*
- * The following relationships of half line counts should hold:
- * 625 = vblank656 + vactive
- * 10 = vblank656 - vblank = vsync pulses + equalization pulses
- *
- * vblank656: half lines after line 625/mid-313 of blanked video
- * vblank: half lines, after line 5/317, of blanked video
- * vactive: half lines of active video +
- * 5 half lines after the end of active video
- *
- * As far as I can tell:
- * vblank656 starts counting from the falling edge of the first
- * vsync pulse (start of line 1 or mid-313)
- * vblank starts counting from the after the 5 vsync pulses and
- * 5 or 4 equalization pulses (start of line 6 or 318)
- *
- * For 625 line systems the driver will extract VBI information
- * from lines 6-23 and lines 318-335 (but the slicer can only
- * handle 17 lines, not the 18 in the vblank region).
- * In addition, we need vblank656 and vblank to be one whole
- * line longer, to cover line 24 and 336, so the SAV/EAV RP
- * codes get generated such that the encoder can actually
- * extract line 23 & 335 (WSS). We'll lose 1 line in each field
- * at the top of the screen.
- *
- * It appears the 5 half lines that happen after active
- * video must be included in vactive (579 instead of 574),
- * otherwise the colors get badly displayed in various regions
- * of the screen. I guess the chroma comb filter gets confused
- * without them (at least when a PVR-350 is the PAL source).
- */
- vblank656 = 48; /* lines 1 - 24 & 313 - 336 */
- vblank = 38; /* lines 6 - 24 & 318 - 336 */
- vactive = 579; /* lines 24 - 313 & 337 - 626 */
-
- /*
- * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is
- * is 864 pixels = 720 active + 144 blanking. ITU-R BT.601
- * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after
- * the end of active video to start a horizontal line, so that
- * leaves 132 pixels of hblank to ignore.
- */
- hblank = 132;
- hactive = 720;
-
- /*
- * Burst gate delay (for 625 line systems)
- * Hsync leading edge to color burst rise = 5.6 us
- * Color burst width = 2.25 us
- * Gate width = 4 pixel clocks
- * (5.6 us + 2.25/2 us) * 13.5 Mpps + 4/2 clocks = 92.79 clocks
- */
- burst = 93;
- luma_lpf = 2;
- if (std & V4L2_STD_PAL) {
- uv_lpf = 1;
- comb = 0x20;
- /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
- sc = 688700;
- } else if (std == V4L2_STD_PAL_Nc) {
- uv_lpf = 1;
- comb = 0x20;
- /* sc = 3582056.25 * src_decimation/28636360 * 2^13 */
- sc = 556422;
- } else { /* SECAM */
- uv_lpf = 0;
- comb = 0;
- /* (fr + fb)/2 = (4406260 + 4250000)/2 = 4328130 */
- /* sc = 4328130 * src_decimation/28636360 * 2^13 */
- sc = 672314;
- }
- } else {
- /*
- * The following relationships of half line counts should hold:
- * 525 = prevsync + vblank656 + vactive
- * 12 = vblank656 - vblank = vsync pulses + equalization pulses
- *
- * prevsync: 6 half-lines before the vsync pulses
- * vblank656: half lines, after line 3/mid-266, of blanked video
- * vblank: half lines, after line 9/272, of blanked video
- * vactive: half lines of active video
- *
- * As far as I can tell:
- * vblank656 starts counting from the falling edge of the first
- * vsync pulse (start of line 4 or mid-266)
- * vblank starts counting from the after the 6 vsync pulses and
- * 6 or 5 equalization pulses (start of line 10 or 272)
- *
- * For 525 line systems the driver will extract VBI information
- * from lines 10-21 and lines 273-284.
- */
- vblank656 = 38; /* lines 4 - 22 & 266 - 284 */
- vblank = 26; /* lines 10 - 22 & 272 - 284 */
- vactive = 481; /* lines 23 - 263 & 285 - 525 */
-
- /*
- * For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is
- * is 858 pixels = 720 active + 138 blanking. The Hsync leading
- * edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the
- * end of active video, leaving 122 pixels of hblank to ignore
- * before active video starts.
- */
- hactive = 720;
- hblank = 122;
- luma_lpf = 1;
- uv_lpf = 1;
-
- /*
- * Burst gate delay (for 525 line systems)
- * Hsync leading edge to color burst rise = 5.3 us
- * Color burst width = 2.5 us
- * Gate width = 4 pixel clocks
- * (5.3 us + 2.5/2 us) * 13.5 Mpps + 4/2 clocks = 90.425 clocks
- */
- if (std == V4L2_STD_PAL_60) {
- burst = 90;
- luma_lpf = 2;
- comb = 0x20;
- /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
- sc = 688700;
- } else if (std == V4L2_STD_PAL_M) {
- /* The 97 needs to be verified against PAL-M timings */
- burst = 97;
- comb = 0x20;
- /* sc = 3575611.49 * src_decimation/28636360 * 2^13 */
- sc = 555421;
- } else {
- burst = 90;
- comb = 0x66;
- /* sc = 3579545.45.. * src_decimation/28636360 * 2^13 */
- sc = 556032;
- }
- }
-
- /* DEBUG: Displays configured PLL frequency */
- pll_int = cx18_av_read(cx, 0x108);
- pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
- pll_post = cx18_av_read(cx, 0x109);
- CX18_DEBUG_INFO_DEV(sd, "PLL regs = int: %u, frac: %u, post: %u\n",
- pll_int, pll_frac, pll_post);
-
- if (pll_post) {
- int fsc, pll;
- u64 tmp;
-
- pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
- pll /= pll_post;
- CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n",
- pll / 1000000, pll % 1000000);
- CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n",
- pll / 8000000, (pll / 8) % 1000000);
-
- CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio "
- "= %d.%03d\n", src_decimation / 256,
- ((src_decimation % 256) * 1000) / 256);
-
- tmp = 28636360 * (u64) sc;
- do_div(tmp, src_decimation);
- fsc = tmp >> 13;
- CX18_DEBUG_INFO_DEV(sd,
- "Chroma sub-carrier initial freq = %d.%06d "
- "MHz\n", fsc / 1000000, fsc % 1000000);
-
- CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
- "vactive %i, vblank656 %i, src_dec %i, "
- "burst 0x%02x, luma_lpf %i, uv_lpf %i, "
- "comb 0x%02x, sc 0x%06x\n",
- hblank, hactive, vblank, vactive, vblank656,
- src_decimation, burst, luma_lpf, uv_lpf,
- comb, sc);
- }
-
- /* Sets horizontal blanking delay and active lines */
- cx18_av_write(cx, 0x470, hblank);
- cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) |
- (hactive << 4)));
- cx18_av_write(cx, 0x472, hactive >> 4);
-
- /* Sets burst gate delay */
- cx18_av_write(cx, 0x473, burst);
-
- /* Sets vertical blanking delay and active duration */
- cx18_av_write(cx, 0x474, vblank);
- cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) |
- (vactive << 4)));
- cx18_av_write(cx, 0x476, vactive >> 4);
- cx18_av_write(cx, 0x477, vblank656);
-
- /* Sets src decimation rate */
- cx18_av_write(cx, 0x478, 0xff & src_decimation);
- cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8));
-
- /* Sets Luma and UV Low pass filters */
- cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
-
- /* Enables comb filters */
- cx18_av_write(cx, 0x47b, comb);
-
- /* Sets SC Step*/
- cx18_av_write(cx, 0x47c, sc);
- cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
- cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
-
- if (std & V4L2_STD_625_50) {
- state->slicer_line_delay = 1;
- state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
- } else {
- state->slicer_line_delay = 0;
- state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
- }
- cx18_av_write(cx, 0x47f, state->slicer_line_delay);
-}
-
-static void input_change(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- v4l2_std_id std = state->std;
- u8 v;
-
- /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
- cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
- cx18_av_and_or(cx, 0x401, ~0x60, 0);
- cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
-
- if (std & V4L2_STD_525_60) {
- if (std == V4L2_STD_NTSC_M_JP) {
- /* Japan uses EIAJ audio standard */
- cx18_av_write_expect(cx, 0x808, 0xf7, 0xf7, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x02, 0x02, 0x3f);
- } else if (std == V4L2_STD_NTSC_M_KR) {
- /* South Korea uses A2 audio standard */
- cx18_av_write_expect(cx, 0x808, 0xf8, 0xf8, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
- } else {
- /* Others use the BTSC audio standard */
- cx18_av_write_expect(cx, 0x808, 0xf6, 0xf6, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x01, 0x01, 0x3f);
- }
- } else if (std & V4L2_STD_PAL) {
- /* Follow tuner change procedure for PAL */
- cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
- } else if (std & V4L2_STD_SECAM) {
- /* Select autodetect for SECAM */
- cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
- }
-
- v = cx18_av_read(cx, 0x803);
- if (v & 0x10) {
- /* restart audio decoder microcontroller */
- v &= ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- v |= 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
-}
-
-static int cx18_av_s_frequency(struct v4l2_subdev *sd,
- struct v4l2_frequency *freq)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- input_change(cx);
- return 0;
-}
-
-static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
- enum cx18_av_audio_input aud_input)
-{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd = &state->sd;
-
- enum analog_signal_type {
- NONE, CVBS, Y, C, SIF, Pb, Pr
- } ch[3] = {NONE, NONE, NONE};
-
- u8 afe_mux_cfg;
- u8 adc2_cfg;
- u8 input_mode;
- u32 afe_cfg;
- int i;
-
- CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
- vid_input, aud_input);
-
- if (vid_input >= CX18_AV_COMPOSITE1 &&
- vid_input <= CX18_AV_COMPOSITE8) {
- afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
- ch[0] = CVBS;
- input_mode = 0x0;
- } else if (vid_input >= CX18_AV_COMPONENT_LUMA1) {
- int luma = vid_input & 0xf000;
- int r_chroma = vid_input & 0xf0000;
- int b_chroma = vid_input & 0xf00000;
-
- if ((vid_input & ~0xfff000) ||
- luma < CX18_AV_COMPONENT_LUMA1 ||
- luma > CX18_AV_COMPONENT_LUMA8 ||
- r_chroma < CX18_AV_COMPONENT_R_CHROMA4 ||
- r_chroma > CX18_AV_COMPONENT_R_CHROMA6 ||
- b_chroma < CX18_AV_COMPONENT_B_CHROMA7 ||
- b_chroma > CX18_AV_COMPONENT_B_CHROMA8) {
- CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
- vid_input);
- return -EINVAL;
- }
- afe_mux_cfg = (luma - CX18_AV_COMPONENT_LUMA1) >> 12;
- ch[0] = Y;
- afe_mux_cfg |= (r_chroma - CX18_AV_COMPONENT_R_CHROMA4) >> 12;
- ch[1] = Pr;
- afe_mux_cfg |= (b_chroma - CX18_AV_COMPONENT_B_CHROMA7) >> 14;
- ch[2] = Pb;
- input_mode = 0x6;
- } else {
- int luma = vid_input & 0xf0;
- int chroma = vid_input & 0xf00;
-
- if ((vid_input & ~0xff0) ||
- luma < CX18_AV_SVIDEO_LUMA1 ||
- luma > CX18_AV_SVIDEO_LUMA8 ||
- chroma < CX18_AV_SVIDEO_CHROMA4 ||
- chroma > CX18_AV_SVIDEO_CHROMA8) {
- CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
- vid_input);
- return -EINVAL;
- }
- afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
- ch[0] = Y;
- if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
- afe_mux_cfg &= 0x3f;
- afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
- ch[2] = C;
- } else {
- afe_mux_cfg &= 0xcf;
- afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
- ch[1] = C;
- }
- input_mode = 0x2;
- }
-
- switch (aud_input) {
- case CX18_AV_AUDIO_SERIAL1:
- case CX18_AV_AUDIO_SERIAL2:
- /* do nothing, use serial audio input */
- break;
- case CX18_AV_AUDIO4:
- afe_mux_cfg &= ~0x30;
- ch[1] = SIF;
- break;
- case CX18_AV_AUDIO5:
- afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10;
- ch[1] = SIF;
- break;
- case CX18_AV_AUDIO6:
- afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20;
- ch[1] = SIF;
- break;
- case CX18_AV_AUDIO7:
- afe_mux_cfg &= ~0xc0;
- ch[2] = SIF;
- break;
- case CX18_AV_AUDIO8:
- afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40;
- ch[2] = SIF;
- break;
-
- default:
- CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
- aud_input);
- return -EINVAL;
- }
-
- /* Set up analog front end multiplexers */
- cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
- /* Set INPUT_MODE to Composite, S-Video, or Component */
- cx18_av_and_or(cx, 0x401, ~0x6, input_mode);
-
- /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
- adc2_cfg = cx18_av_read(cx, 0x102);
- if (ch[2] == NONE)
- adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */
- else
- adc2_cfg |= 0x2; /* Signal on CH3, set ADC2 to CH3 for input */
-
- /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
- if (ch[1] != NONE && ch[2] != NONE)
- adc2_cfg |= 0x4; /* Set dual mode */
- else
- adc2_cfg &= ~0x4; /* Clear dual mode */
- cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17);
-
- /* Configure the analog front end */
- afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL);
- afe_cfg &= 0xff000000;
- afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */
- if (ch[1] != NONE && ch[2] != NONE)
- afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */
-
- for (i = 0; i < 3; i++) {
- switch (ch[i]) {
- default:
- case NONE:
- /* CLAMP_SEL = Fixed to midcode clamp level */
- afe_cfg |= (0x00000200 << i);
- break;
- case CVBS:
- case Y:
- if (i > 0)
- afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */
- break;
- case C:
- case Pb:
- case Pr:
- /* CLAMP_SEL = Fixed to midcode clamp level */
- afe_cfg |= (0x00000200 << i);
- if (i == 0 && ch[i] == C)
- afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */
- break;
- case SIF:
- /*
- * VGA_GAIN_SEL = Audio Decoder
- * CLAMP_SEL = Fixed to midcode clamp level
- */
- afe_cfg |= (0x00000240 << i);
- if (i == 0)
- afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */
- break;
- }
- }
-
- cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg);
-
- state->vid_input = vid_input;
- state->aud_input = aud_input;
- cx18_av_audio_set_path(cx);
- input_change(cx);
- return 0;
-}
-
-static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- return set_input(cx, input, state->aud_input);
-}
-
-static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- return set_input(cx, state->vid_input, input);
-}
-
-static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- u8 vpres;
- u8 mode;
- int val = 0;
-
- if (state->radio)
- return 0;
-
- vpres = cx18_av_read(cx, 0x40e) & 0x20;
- vt->signal = vpres ? 0xffff : 0x0;
-
- vt->capability |=
- V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
- V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-
- mode = cx18_av_read(cx, 0x804);
-
- /* get rxsubchans and audmode */
- if ((mode & 0xf) == 1)
- val |= V4L2_TUNER_SUB_STEREO;
- else
- val |= V4L2_TUNER_SUB_MONO;
-
- if (mode == 2 || mode == 4)
- val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-
- if (mode & 0x10)
- val |= V4L2_TUNER_SUB_SAP;
-
- vt->rxsubchans = val;
- vt->audmode = state->audmode;
- return 0;
-}
-
-static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- u8 v;
-
- if (state->radio)
- return 0;
-
- v = cx18_av_read(cx, 0x809);
- v &= ~0xf;
-
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- /* mono -> mono
- stereo -> mono
- bilingual -> lang1 */
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1 */
- v |= 0x4;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1/lang2 */
- v |= 0x7;
- break;
- case V4L2_TUNER_MODE_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang2 */
- v |= 0x1;
- break;
- default:
- return -EINVAL;
- }
- cx18_av_write_expect(cx, 0x809, v, v, 0xff);
- state->audmode = vt->audmode;
- return 0;
-}
-
-static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- u8 fmt = 0; /* zero is autodetect */
- u8 pal_m = 0;
-
- if (state->radio == 0 && state->std == norm)
- return 0;
-
- state->radio = 0;
- state->std = norm;
-
- /* First tests should be against specific std */
- if (state->std == V4L2_STD_NTSC_M_JP) {
- fmt = 0x2;
- } else if (state->std == V4L2_STD_NTSC_443) {
- fmt = 0x3;
- } else if (state->std == V4L2_STD_PAL_M) {
- pal_m = 1;
- fmt = 0x5;
- } else if (state->std == V4L2_STD_PAL_N) {
- fmt = 0x6;
- } else if (state->std == V4L2_STD_PAL_Nc) {
- fmt = 0x7;
- } else if (state->std == V4L2_STD_PAL_60) {
- fmt = 0x8;
- } else {
- /* Then, test against generic ones */
- if (state->std & V4L2_STD_NTSC)
- fmt = 0x1;
- else if (state->std & V4L2_STD_PAL)
- fmt = 0x4;
- else if (state->std & V4L2_STD_SECAM)
- fmt = 0xc;
- }
-
- CX18_DEBUG_INFO_DEV(sd, "changing video std to fmt %i\n", fmt);
-
- /* Follow step 9 of section 3.16 in the cx18_av datasheet.
- Without this PAL may display a vertical ghosting effect.
- This happens for example with the Yuan MPC622. */
- if (fmt >= 4 && fmt < 8) {
- /* Set format to NTSC-M */
- cx18_av_and_or(cx, 0x400, ~0xf, 1);
- /* Turn off LCOMB */
- cx18_av_and_or(cx, 0x47b, ~6, 0);
- }
- cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20);
- cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
- cx18_av_std_setup(cx);
- input_change(cx);
- return 0;
-}
-
-static int cx18_av_s_radio(struct v4l2_subdev *sd)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- state->radio = 1;
- return 0;
-}
-
-static int cx18_av_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- cx18_av_write(cx, 0x414, ctrl->val - 128);
- break;
-
- case V4L2_CID_CONTRAST:
- cx18_av_write(cx, 0x415, ctrl->val << 1);
- break;
-
- case V4L2_CID_SATURATION:
- cx18_av_write(cx, 0x420, ctrl->val << 1);
- cx18_av_write(cx, 0x421, ctrl->val << 1);
- break;
-
- case V4L2_CID_HUE:
- cx18_av_write(cx, 0x422, ctrl->val);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
- int is_50Hz = !(state->std & V4L2_STD_525_60);
-
- if (fmt->code != V4L2_MBUS_FMT_FIXED)
- return -EINVAL;
-
- fmt->field = V4L2_FIELD_INTERLACED;
- fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
- Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
-
- Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
- Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
-
- /*
- * This adjustment reflects the excess of vactive, set in
- * cx18_av_std_setup(), above standard values:
- *
- * 480 + 1 for 60 Hz systems
- * 576 + 3 for 50 Hz systems
- */
- Vlines = fmt->height + (is_50Hz ? 3 : 1);
-
- /*
- * Invalid height and width scaling requests are:
- * 1. width less than 1/16 of the source width
- * 2. width greater than the source width
- * 3. height less than 1/8 of the source height
- * 4. height greater than the source height
- */
- if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
- (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
- CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
- fmt->width, fmt->height);
- return -ERANGE;
- }
-
- HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
- VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
- VSC &= 0x1fff;
-
- if (fmt->width >= 385)
- filter = 0;
- else if (fmt->width > 192)
- filter = 1;
- else if (fmt->width > 96)
- filter = 2;
- else
- filter = 3;
-
- CX18_DEBUG_INFO_DEV(sd,
- "decoder set size %dx%d -> scale %ux%u\n",
- fmt->width, fmt->height, HSC, VSC);
-
- /* HSCALE=HSC */
- cx18_av_write(cx, 0x418, HSC & 0xff);
- cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
- cx18_av_write(cx, 0x41a, HSC >> 16);
- /* VSCALE=VSC */
- cx18_av_write(cx, 0x41c, VSC & 0xff);
- cx18_av_write(cx, 0x41d, VSC >> 8);
- /* VS_INTRLACE=1 VFILT=filter */
- cx18_av_write(cx, 0x41e, 0x8 | filter);
- return 0;
-}
-
-static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- CX18_DEBUG_INFO_DEV(sd, "%s output\n", enable ? "enable" : "disable");
- if (enable) {
- cx18_av_write(cx, 0x115, 0x8c);
- cx18_av_write(cx, 0x116, 0x07);
- } else {
- cx18_av_write(cx, 0x115, 0x00);
- cx18_av_write(cx, 0x116, 0x00);
- }
- return 0;
-}
-
-static void log_video_status(struct cx18 *cx)
-{
- static const char *const fmt_strs[] = {
- "0x0",
- "NTSC-M", "NTSC-J", "NTSC-4.43",
- "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
- "0x9", "0xA", "0xB",
- "SECAM",
- "0xD", "0xE", "0xF"
- };
-
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd = &state->sd;
- u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
- u8 gen_stat1 = cx18_av_read(cx, 0x40d);
- u8 gen_stat2 = cx18_av_read(cx, 0x40e);
- int vid_input = state->vid_input;
-
- CX18_INFO_DEV(sd, "Video signal: %spresent\n",
- (gen_stat2 & 0x20) ? "" : "not ");
- CX18_INFO_DEV(sd, "Detected format: %s\n",
- fmt_strs[gen_stat1 & 0xf]);
-
- CX18_INFO_DEV(sd, "Specified standard: %s\n",
- vidfmt_sel ? fmt_strs[vidfmt_sel]
- : "automatic detection");
-
- if (vid_input >= CX18_AV_COMPOSITE1 &&
- vid_input <= CX18_AV_COMPOSITE8) {
- CX18_INFO_DEV(sd, "Specified video input: Composite %d\n",
- vid_input - CX18_AV_COMPOSITE1 + 1);
- } else {
- CX18_INFO_DEV(sd, "Specified video input: "
- "S-Video (Luma In%d, Chroma In%d)\n",
- (vid_input & 0xf0) >> 4,
- (vid_input & 0xf00) >> 8);
- }
-
- CX18_INFO_DEV(sd, "Specified audioclock freq: %d Hz\n",
- state->audclk_freq);
-}
-
-static void log_audio_status(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd = &state->sd;
- u8 download_ctl = cx18_av_read(cx, 0x803);
- u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
- u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
- u8 audio_config = cx18_av_read(cx, 0x808);
- u8 pref_mode = cx18_av_read(cx, 0x809);
- u8 afc0 = cx18_av_read(cx, 0x80b);
- u8 mute_ctl = cx18_av_read(cx, 0x8d3);
- int aud_input = state->aud_input;
- char *p;
-
- switch (mod_det_stat0) {
- case 0x00: p = "mono"; break;
- case 0x01: p = "stereo"; break;
- case 0x02: p = "dual"; break;
- case 0x04: p = "tri"; break;
- case 0x10: p = "mono with SAP"; break;
- case 0x11: p = "stereo with SAP"; break;
- case 0x12: p = "dual with SAP"; break;
- case 0x14: p = "tri with SAP"; break;
- case 0xfe: p = "forced mode"; break;
- default: p = "not defined"; break;
- }
- CX18_INFO_DEV(sd, "Detected audio mode: %s\n", p);
-
- switch (mod_det_stat1) {
- case 0x00: p = "not defined"; break;
- case 0x01: p = "EIAJ"; break;
- case 0x02: p = "A2-M"; break;
- case 0x03: p = "A2-BG"; break;
- case 0x04: p = "A2-DK1"; break;
- case 0x05: p = "A2-DK2"; break;
- case 0x06: p = "A2-DK3"; break;
- case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
- case 0x08: p = "AM-L"; break;
- case 0x09: p = "NICAM-BG"; break;
- case 0x0a: p = "NICAM-DK"; break;
- case 0x0b: p = "NICAM-I"; break;
- case 0x0c: p = "NICAM-L"; break;
- case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
- case 0x0e: p = "IF FM Radio"; break;
- case 0x0f: p = "BTSC"; break;
- case 0x10: p = "detected chrominance"; break;
- case 0xfd: p = "unknown audio standard"; break;
- case 0xfe: p = "forced audio standard"; break;
- case 0xff: p = "no detected audio standard"; break;
- default: p = "not defined"; break;
- }
- CX18_INFO_DEV(sd, "Detected audio standard: %s\n", p);
- CX18_INFO_DEV(sd, "Audio muted: %s\n",
- (mute_ctl & 0x2) ? "yes" : "no");
- CX18_INFO_DEV(sd, "Audio microcontroller: %s\n",
- (download_ctl & 0x10) ? "running" : "stopped");
-
- switch (audio_config >> 4) {
- case 0x00: p = "undefined"; break;
- case 0x01: p = "BTSC"; break;
- case 0x02: p = "EIAJ"; break;
- case 0x03: p = "A2-M"; break;
- case 0x04: p = "A2-BG"; break;
- case 0x05: p = "A2-DK1"; break;
- case 0x06: p = "A2-DK2"; break;
- case 0x07: p = "A2-DK3"; break;
- case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
- case 0x09: p = "AM-L"; break;
- case 0x0a: p = "NICAM-BG"; break;
- case 0x0b: p = "NICAM-DK"; break;
- case 0x0c: p = "NICAM-I"; break;
- case 0x0d: p = "NICAM-L"; break;
- case 0x0e: p = "FM radio"; break;
- case 0x0f: p = "automatic detection"; break;
- default: p = "undefined"; break;
- }
- CX18_INFO_DEV(sd, "Configured audio standard: %s\n", p);
-
- if ((audio_config >> 4) < 0xF) {
- switch (audio_config & 0xF) {
- case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
- case 0x01: p = "MONO2 (LANGUAGE B)"; break;
- case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
- case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
- case 0x04: p = "STEREO"; break;
- case 0x05: p = "DUAL1 (AC)"; break;
- case 0x06: p = "DUAL2 (BC)"; break;
- case 0x07: p = "DUAL3 (AB)"; break;
- default: p = "undefined";
- }
- CX18_INFO_DEV(sd, "Configured audio mode: %s\n", p);
- } else {
- switch (audio_config & 0xF) {
- case 0x00: p = "BG"; break;
- case 0x01: p = "DK1"; break;
- case 0x02: p = "DK2"; break;
- case 0x03: p = "DK3"; break;
- case 0x04: p = "I"; break;
- case 0x05: p = "L"; break;
- case 0x06: p = "BTSC"; break;
- case 0x07: p = "EIAJ"; break;
- case 0x08: p = "A2-M"; break;
- case 0x09: p = "FM Radio (4.5 MHz)"; break;
- case 0x0a: p = "FM Radio (5.5 MHz)"; break;
- case 0x0b: p = "S-Video"; break;
- case 0x0f: p = "automatic standard and mode detection"; break;
- default: p = "undefined"; break;
- }
- CX18_INFO_DEV(sd, "Configured audio system: %s\n", p);
- }
-
- if (aud_input)
- CX18_INFO_DEV(sd, "Specified audio input: Tuner (In%d)\n",
- aud_input);
- else
- CX18_INFO_DEV(sd, "Specified audio input: External\n");
-
- switch (pref_mode & 0xf) {
- case 0: p = "mono/language A"; break;
- case 1: p = "language B"; break;
- case 2: p = "language C"; break;
- case 3: p = "analog fallback"; break;
- case 4: p = "stereo"; break;
- case 5: p = "language AC"; break;
- case 6: p = "language BC"; break;
- case 7: p = "language AB"; break;
- default: p = "undefined"; break;
- }
- CX18_INFO_DEV(sd, "Preferred audio mode: %s\n", p);
-
- if ((audio_config & 0xf) == 0xf) {
- switch ((afc0 >> 3) & 0x1) {
- case 0: p = "system DK"; break;
- case 1: p = "system L"; break;
- }
- CX18_INFO_DEV(sd, "Selected 65 MHz format: %s\n", p);
-
- switch (afc0 & 0x7) {
- case 0: p = "Chroma"; break;
- case 1: p = "BTSC"; break;
- case 2: p = "EIAJ"; break;
- case 3: p = "A2-M"; break;
- case 4: p = "autodetect"; break;
- default: p = "undefined"; break;
- }
- CX18_INFO_DEV(sd, "Selected 45 MHz format: %s\n", p);
- }
-}
-
-static int cx18_av_log_status(struct v4l2_subdev *sd)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- log_video_status(cx);
- log_audio_status(cx);
- return 0;
-}
-
-static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
-{
- return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
-}
-
-static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
-
- if (cx18_av_dbg_match(&chip->match)) {
- chip->ident = state->id;
- chip->revision = state->rev;
- }
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx18_av_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- if (!cx18_av_dbg_match(&reg->match))
- return -EINVAL;
- if ((reg->reg & 0x3) != 0)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->size = 4;
- reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
- return 0;
-}
-
-static int cx18_av_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- if (!cx18_av_dbg_match(&reg->match))
- return -EINVAL;
- if ((reg->reg & 0x3) != 0)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
- return 0;
-}
-#endif
-
-static const struct v4l2_ctrl_ops cx18_av_ctrl_ops = {
- .s_ctrl = cx18_av_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
- .g_chip_ident = cx18_av_g_chip_ident,
- .log_status = cx18_av_log_status,
- .load_fw = cx18_av_load_fw,
- .reset = cx18_av_reset,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = cx18_av_s_std,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = cx18_av_g_register,
- .s_register = cx18_av_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = {
- .s_radio = cx18_av_s_radio,
- .s_frequency = cx18_av_s_frequency,
- .g_tuner = cx18_av_g_tuner,
- .s_tuner = cx18_av_s_tuner,
-};
-
-static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
- .s_clock_freq = cx18_av_s_clock_freq,
- .s_routing = cx18_av_s_audio_routing,
-};
-
-static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
- .s_routing = cx18_av_s_video_routing,
- .s_stream = cx18_av_s_stream,
- .s_mbus_fmt = cx18_av_s_mbus_fmt,
-};
-
-static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = {
- .decode_vbi_line = cx18_av_decode_vbi_line,
- .g_sliced_fmt = cx18_av_g_sliced_fmt,
- .s_sliced_fmt = cx18_av_s_sliced_fmt,
- .s_raw_fmt = cx18_av_s_raw_fmt,
-};
-
-static const struct v4l2_subdev_ops cx18_av_ops = {
- .core = &cx18_av_general_ops,
- .tuner = &cx18_av_tuner_ops,
- .audio = &cx18_av_audio_ops,
- .video = &cx18_av_video_ops,
- .vbi = &cx18_av_vbi_ops,
-};
-
-int cx18_av_probe(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd;
- int err;
-
- state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
- state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
- ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
-
- state->vid_input = CX18_AV_COMPOSITE7;
- state->aud_input = CX18_AV_AUDIO8;
- state->audclk_freq = 48000;
- state->audmode = V4L2_TUNER_MODE_LANG1;
- state->slicer_line_delay = 0;
- state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
-
- sd = &state->sd;
- v4l2_subdev_init(sd, &cx18_av_ops);
- v4l2_set_subdevdata(sd, cx);
- snprintf(sd->name, sizeof(sd->name),
- "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
- sd->grp_id = CX18_HW_418_AV;
- v4l2_ctrl_handler_init(&state->hdl, 9);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
- V4L2_CID_SATURATION, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
-
- state->volume = v4l2_ctrl_new_std(&state->hdl,
- &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
- 0, 65535, 65535 / 100, 0);
- v4l2_ctrl_new_std(&state->hdl,
- &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
- 0, 1, 1, 0);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
- V4L2_CID_AUDIO_BALANCE,
- 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
- V4L2_CID_AUDIO_BASS,
- 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
- V4L2_CID_AUDIO_TREBLE,
- 0, 65535, 65535 / 100, 32768);
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- return err;
- }
- err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
- if (err)
- v4l2_ctrl_handler_free(&state->hdl);
- else
- cx18_av_init(cx);
- return err;
-}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
deleted file mode 100644
index e9c69d9c9e4a..000000000000
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * cx18 ADEC header
- *
- * Derived from cx25840-core.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifndef _CX18_AV_CORE_H_
-#define _CX18_AV_CORE_H_
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-struct cx18;
-
-enum cx18_av_video_input {
- /* Composite video inputs In1-In8 */
- CX18_AV_COMPOSITE1 = 1,
- CX18_AV_COMPOSITE2,
- CX18_AV_COMPOSITE3,
- CX18_AV_COMPOSITE4,
- CX18_AV_COMPOSITE5,
- CX18_AV_COMPOSITE6,
- CX18_AV_COMPOSITE7,
- CX18_AV_COMPOSITE8,
-
- /* S-Video inputs consist of one luma input (In1-In8) ORed with one
- chroma input (In5-In8) */
- CX18_AV_SVIDEO_LUMA1 = 0x10,
- CX18_AV_SVIDEO_LUMA2 = 0x20,
- CX18_AV_SVIDEO_LUMA3 = 0x30,
- CX18_AV_SVIDEO_LUMA4 = 0x40,
- CX18_AV_SVIDEO_LUMA5 = 0x50,
- CX18_AV_SVIDEO_LUMA6 = 0x60,
- CX18_AV_SVIDEO_LUMA7 = 0x70,
- CX18_AV_SVIDEO_LUMA8 = 0x80,
- CX18_AV_SVIDEO_CHROMA4 = 0x400,
- CX18_AV_SVIDEO_CHROMA5 = 0x500,
- CX18_AV_SVIDEO_CHROMA6 = 0x600,
- CX18_AV_SVIDEO_CHROMA7 = 0x700,
- CX18_AV_SVIDEO_CHROMA8 = 0x800,
-
- /* S-Video aliases for common luma/chroma combinations */
- CX18_AV_SVIDEO1 = 0x510,
- CX18_AV_SVIDEO2 = 0x620,
- CX18_AV_SVIDEO3 = 0x730,
- CX18_AV_SVIDEO4 = 0x840,
-
- /* Component Video inputs consist of one luma input (In1-In8) ORed
- with a red chroma (In4-In6) and blue chroma input (In7-In8) */
- CX18_AV_COMPONENT_LUMA1 = 0x1000,
- CX18_AV_COMPONENT_LUMA2 = 0x2000,
- CX18_AV_COMPONENT_LUMA3 = 0x3000,
- CX18_AV_COMPONENT_LUMA4 = 0x4000,
- CX18_AV_COMPONENT_LUMA5 = 0x5000,
- CX18_AV_COMPONENT_LUMA6 = 0x6000,
- CX18_AV_COMPONENT_LUMA7 = 0x7000,
- CX18_AV_COMPONENT_LUMA8 = 0x8000,
- CX18_AV_COMPONENT_R_CHROMA4 = 0x40000,
- CX18_AV_COMPONENT_R_CHROMA5 = 0x50000,
- CX18_AV_COMPONENT_R_CHROMA6 = 0x60000,
- CX18_AV_COMPONENT_B_CHROMA7 = 0x700000,
- CX18_AV_COMPONENT_B_CHROMA8 = 0x800000,
-
- /* Component Video aliases for common combinations */
- CX18_AV_COMPONENT1 = 0x861000,
-};
-
-enum cx18_av_audio_input {
- /* Audio inputs: serial or In4-In8 */
- CX18_AV_AUDIO_SERIAL1,
- CX18_AV_AUDIO_SERIAL2,
- CX18_AV_AUDIO4 = 4,
- CX18_AV_AUDIO5,
- CX18_AV_AUDIO6,
- CX18_AV_AUDIO7,
- CX18_AV_AUDIO8,
-};
-
-struct cx18_av_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *volume;
- int radio;
- v4l2_std_id std;
- enum cx18_av_video_input vid_input;
- enum cx18_av_audio_input aud_input;
- u32 audclk_freq;
- int audmode;
- u32 id;
- u32 rev;
- int is_initialized;
-
- /*
- * The VBI slicer starts operating and counting lines, beginning at
- * slicer line count of 1, at D lines after the deassertion of VRESET.
- * This staring field line, S, is 6 (& 319) or 10 (& 273) for 625 or 525
- * line systems respectively. Sliced ancillary data captured on VBI
- * slicer line M is inserted after the VBI slicer is done with line M,
- * when VBI slicer line count is N = M+1. Thus when the VBI slicer
- * reports a VBI slicer line number with ancillary data, the IDID0 byte
- * indicates VBI slicer line N. The actual field line that the captured
- * data comes from is
- *
- * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2).
- *
- * L is the line in the field, not frame, from which the VBI data came.
- * N is the line reported by the slicer in the ancillary data.
- * D is the slicer_line_delay value programmed into register 0x47f.
- * S is 6 for 625 line systems or 10 for 525 line systems
- * (S+D-2) is the slicer_line_offset used to convert slicer reported
- * line counts to actual field lines.
- */
- int slicer_line_delay;
- int slicer_line_offset;
-};
-
-
-/* Registers */
-#define CXADEC_CHIP_TYPE_TIGER 0x837
-#define CXADEC_CHIP_TYPE_MAKO 0x843
-
-#define CXADEC_HOST_REG1 0x000
-#define CXADEC_HOST_REG2 0x001
-
-#define CXADEC_CHIP_CTRL 0x100
-#define CXADEC_AFE_CTRL 0x104
-#define CXADEC_PLL_CTRL1 0x108
-#define CXADEC_VID_PLL_FRAC 0x10C
-#define CXADEC_AUX_PLL_FRAC 0x110
-#define CXADEC_PIN_CTRL1 0x114
-#define CXADEC_PIN_CTRL2 0x118
-#define CXADEC_PIN_CFG1 0x11C
-#define CXADEC_PIN_CFG2 0x120
-
-#define CXADEC_PIN_CFG3 0x124
-#define CXADEC_I2S_MCLK 0x127
-
-#define CXADEC_AUD_LOCK1 0x128
-#define CXADEC_AUD_LOCK2 0x12C
-#define CXADEC_POWER_CTRL 0x130
-#define CXADEC_AFE_DIAG_CTRL1 0x134
-#define CXADEC_AFE_DIAG_CTRL2 0x138
-#define CXADEC_AFE_DIAG_CTRL3 0x13C
-#define CXADEC_PLL_DIAG_CTRL 0x140
-#define CXADEC_TEST_CTRL1 0x144
-#define CXADEC_TEST_CTRL2 0x148
-#define CXADEC_BIST_STAT 0x14C
-#define CXADEC_DLL1_DIAG_CTRL 0x158
-#define CXADEC_DLL2_DIAG_CTRL 0x15C
-
-/* IR registers */
-#define CXADEC_IR_CTRL_REG 0x200
-#define CXADEC_IR_TXCLK_REG 0x204
-#define CXADEC_IR_RXCLK_REG 0x208
-#define CXADEC_IR_CDUTY_REG 0x20C
-#define CXADEC_IR_STAT_REG 0x210
-#define CXADEC_IR_IRQEN_REG 0x214
-#define CXADEC_IR_FILTER_REG 0x218
-#define CXADEC_IR_FIFO_REG 0x21C
-
-/* Video Registers */
-#define CXADEC_MODE_CTRL 0x400
-#define CXADEC_OUT_CTRL1 0x404
-#define CXADEC_OUT_CTRL2 0x408
-#define CXADEC_GEN_STAT 0x40C
-#define CXADEC_INT_STAT_MASK 0x410
-#define CXADEC_LUMA_CTRL 0x414
-
-#define CXADEC_BRIGHTNESS_CTRL_BYTE 0x414
-#define CXADEC_CONTRAST_CTRL_BYTE 0x415
-#define CXADEC_LUMA_CTRL_BYTE_3 0x416
-
-#define CXADEC_HSCALE_CTRL 0x418
-#define CXADEC_VSCALE_CTRL 0x41C
-
-#define CXADEC_CHROMA_CTRL 0x420
-
-#define CXADEC_USAT_CTRL_BYTE 0x420
-#define CXADEC_VSAT_CTRL_BYTE 0x421
-#define CXADEC_HUE_CTRL_BYTE 0x422
-
-#define CXADEC_VBI_LINE_CTRL1 0x424
-#define CXADEC_VBI_LINE_CTRL2 0x428
-#define CXADEC_VBI_LINE_CTRL3 0x42C
-#define CXADEC_VBI_LINE_CTRL4 0x430
-#define CXADEC_VBI_LINE_CTRL5 0x434
-#define CXADEC_VBI_FC_CFG 0x438
-#define CXADEC_VBI_MISC_CFG1 0x43C
-#define CXADEC_VBI_MISC_CFG2 0x440
-#define CXADEC_VBI_PAY1 0x444
-#define CXADEC_VBI_PAY2 0x448
-#define CXADEC_VBI_CUST1_CFG1 0x44C
-#define CXADEC_VBI_CUST1_CFG2 0x450
-#define CXADEC_VBI_CUST1_CFG3 0x454
-#define CXADEC_VBI_CUST2_CFG1 0x458
-#define CXADEC_VBI_CUST2_CFG2 0x45C
-#define CXADEC_VBI_CUST2_CFG3 0x460
-#define CXADEC_VBI_CUST3_CFG1 0x464
-#define CXADEC_VBI_CUST3_CFG2 0x468
-#define CXADEC_VBI_CUST3_CFG3 0x46C
-#define CXADEC_HORIZ_TIM_CTRL 0x470
-#define CXADEC_VERT_TIM_CTRL 0x474
-#define CXADEC_SRC_COMB_CFG 0x478
-#define CXADEC_CHROMA_VBIOFF_CFG 0x47C
-#define CXADEC_FIELD_COUNT 0x480
-#define CXADEC_MISC_TIM_CTRL 0x484
-#define CXADEC_DFE_CTRL1 0x488
-#define CXADEC_DFE_CTRL2 0x48C
-#define CXADEC_DFE_CTRL3 0x490
-#define CXADEC_PLL_CTRL2 0x494
-#define CXADEC_HTL_CTRL 0x498
-#define CXADEC_COMB_CTRL 0x49C
-#define CXADEC_CRUSH_CTRL 0x4A0
-#define CXADEC_SOFT_RST_CTRL 0x4A4
-#define CXADEC_MV_DT_CTRL2 0x4A8
-#define CXADEC_MV_DT_CTRL3 0x4AC
-#define CXADEC_MISC_DIAG_CTRL 0x4B8
-
-#define CXADEC_DL_CTL 0x800
-#define CXADEC_DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */
-#define CXADEC_DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */
-#define CXADEC_DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */
-#define CXADEC_DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */
-
-#define CXADEC_STD_DET_STATUS 0x804
-
-#define CXADEC_STD_DET_CTL 0x808
-#define CXADEC_STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */
-#define CXADEC_STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */
-
-#define CXADEC_DW8051_INT 0x80C
-#define CXADEC_GENERAL_CTL 0x810
-#define CXADEC_AAGC_CTL 0x814
-#define CXADEC_IF_SRC_CTL 0x818
-#define CXADEC_ANLOG_DEMOD_CTL 0x81C
-#define CXADEC_ROT_FREQ_CTL 0x820
-#define CXADEC_FM1_CTL 0x824
-#define CXADEC_PDF_CTL 0x828
-#define CXADEC_DFT1_CTL1 0x82C
-#define CXADEC_DFT1_CTL2 0x830
-#define CXADEC_DFT_STATUS 0x834
-#define CXADEC_DFT2_CTL1 0x838
-#define CXADEC_DFT2_CTL2 0x83C
-#define CXADEC_DFT2_STATUS 0x840
-#define CXADEC_DFT3_CTL1 0x844
-#define CXADEC_DFT3_CTL2 0x848
-#define CXADEC_DFT3_STATUS 0x84C
-#define CXADEC_DFT4_CTL1 0x850
-#define CXADEC_DFT4_CTL2 0x854
-#define CXADEC_DFT4_STATUS 0x858
-#define CXADEC_AM_MTS_DET 0x85C
-#define CXADEC_ANALOG_MUX_CTL 0x860
-#define CXADEC_DIG_PLL_CTL1 0x864
-#define CXADEC_DIG_PLL_CTL2 0x868
-#define CXADEC_DIG_PLL_CTL3 0x86C
-#define CXADEC_DIG_PLL_CTL4 0x870
-#define CXADEC_DIG_PLL_CTL5 0x874
-#define CXADEC_DEEMPH_GAIN_CTL 0x878
-#define CXADEC_DEEMPH_COEF1 0x87C
-#define CXADEC_DEEMPH_COEF2 0x880
-#define CXADEC_DBX1_CTL1 0x884
-#define CXADEC_DBX1_CTL2 0x888
-#define CXADEC_DBX1_STATUS 0x88C
-#define CXADEC_DBX2_CTL1 0x890
-#define CXADEC_DBX2_CTL2 0x894
-#define CXADEC_DBX2_STATUS 0x898
-#define CXADEC_AM_FM_DIFF 0x89C
-
-/* NICAM registers go here */
-#define CXADEC_NICAM_STATUS 0x8C8
-#define CXADEC_DEMATRIX_CTL 0x8CC
-
-#define CXADEC_PATH1_CTL1 0x8D0
-#define CXADEC_PATH1_VOL_CTL 0x8D4
-#define CXADEC_PATH1_EQ_CTL 0x8D8
-#define CXADEC_PATH1_SC_CTL 0x8DC
-
-#define CXADEC_PATH2_CTL1 0x8E0
-#define CXADEC_PATH2_VOL_CTL 0x8E4
-#define CXADEC_PATH2_EQ_CTL 0x8E8
-#define CXADEC_PATH2_SC_CTL 0x8EC
-
-#define CXADEC_SRC_CTL 0x8F0
-#define CXADEC_SRC_LF_COEF 0x8F4
-#define CXADEC_SRC1_CTL 0x8F8
-#define CXADEC_SRC2_CTL 0x8FC
-#define CXADEC_SRC3_CTL 0x900
-#define CXADEC_SRC4_CTL 0x904
-#define CXADEC_SRC5_CTL 0x908
-#define CXADEC_SRC6_CTL 0x90C
-
-#define CXADEC_BASEBAND_OUT_SEL 0x910
-#define CXADEC_I2S_IN_CTL 0x914
-#define CXADEC_I2S_OUT_CTL 0x918
-#define CXADEC_AC97_CTL 0x91C
-#define CXADEC_QAM_PDF 0x920
-#define CXADEC_QAM_CONST_DEC 0x924
-#define CXADEC_QAM_ROTATOR_FREQ 0x948
-
-/* Bit definitions / settings used in Mako Audio */
-#define CXADEC_PREF_MODE_MONO_LANGA 0
-#define CXADEC_PREF_MODE_MONO_LANGB 1
-#define CXADEC_PREF_MODE_MONO_LANGC 2
-#define CXADEC_PREF_MODE_FALLBACK 3
-#define CXADEC_PREF_MODE_STEREO 4
-#define CXADEC_PREF_MODE_DUAL_LANG_AC 5
-#define CXADEC_PREF_MODE_DUAL_LANG_BC 6
-#define CXADEC_PREF_MODE_DUAL_LANG_AB 7
-
-
-#define CXADEC_DETECT_STEREO 1
-#define CXADEC_DETECT_DUAL 2
-#define CXADEC_DETECT_TRI 4
-#define CXADEC_DETECT_SAP 0x10
-#define CXADEC_DETECT_NO_SIGNAL 0xFF
-
-#define CXADEC_SELECT_AUDIO_STANDARD_BG 0xF0 /* NICAM BG and A2 BG */
-#define CXADEC_SELECT_AUDIO_STANDARD_DK1 0xF1 /* NICAM DK and A2 DK */
-#define CXADEC_SELECT_AUDIO_STANDARD_DK2 0xF2
-#define CXADEC_SELECT_AUDIO_STANDARD_DK3 0xF3
-#define CXADEC_SELECT_AUDIO_STANDARD_I 0xF4 /* NICAM I and A1 */
-#define CXADEC_SELECT_AUDIO_STANDARD_L 0xF5 /* NICAM L and System L AM */
-#define CXADEC_SELECT_AUDIO_STANDARD_BTSC 0xF6
-#define CXADEC_SELECT_AUDIO_STANDARD_EIAJ 0xF7
-#define CXADEC_SELECT_AUDIO_STANDARD_A2_M 0xF8 /* A2 M */
-#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
-#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
-
-static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct cx18_av_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct cx18_av_state, hdl)->sd;
-}
-
-/* ----------------------------------------------------------------------- */
-/* cx18_av-core.c */
-int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
-int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
-int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value);
-int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask);
-int cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval,
- u32 mask);
-u8 cx18_av_read(struct cx18 *cx, u16 addr);
-u32 cx18_av_read4(struct cx18 *cx, u16 addr);
-int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
-int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
-void cx18_av_std_setup(struct cx18 *cx);
-
-int cx18_av_probe(struct cx18 *cx);
-
-/* ----------------------------------------------------------------------- */
-/* cx18_av-firmware.c */
-int cx18_av_loadfw(struct cx18 *cx);
-
-/* ----------------------------------------------------------------------- */
-/* cx18_av-audio.c */
-int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
-void cx18_av_audio_set_path(struct cx18 *cx);
-extern const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops;
-
-/* ----------------------------------------------------------------------- */
-/* cx18_av-vbi.c */
-int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
- struct v4l2_decode_vbi_line *vbi);
-int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
-int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
-int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
-
-#endif
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
deleted file mode 100644
index a34fd082b76e..000000000000
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * cx18 ADEC firmware functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include <linux/firmware.h>
-
-#define CX18_AUDIO_ENABLE 0xc72014
-#define CX18_AI1_MUX_MASK 0x30
-#define CX18_AI1_MUX_I2S1 0x00
-#define CX18_AI1_MUX_I2S2 0x10
-#define CX18_AI1_MUX_843_I2S 0x20
-#define CX18_AI1_MUX_INVALID 0x30
-
-#define FWFILE "v4l-cx23418-dig.fw"
-
-static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
-{
- struct v4l2_subdev *sd = &cx->av_state.sd;
- int ret = 0;
- const u8 *data;
- u32 size;
- int addr;
- u32 expected, dl_control;
-
- /* Ensure we put the 8051 in reset and enable firmware upload mode */
- dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
- do {
- dl_control &= 0x00ffffff;
- dl_control |= 0x0f000000;
- cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control);
- dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
- } while ((dl_control & 0xff000000) != 0x0f000000);
-
- /* Read and auto increment until at address 0x0000 */
- while (dl_control & 0x3fff)
- dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
-
- data = fw->data;
- size = fw->size;
- for (addr = 0; addr < size; addr++) {
- dl_control &= 0xffff3fff; /* ignore top 2 bits of address */
- expected = 0x0f000000 | ((u32)data[addr] << 16) | addr;
- if (expected != dl_control) {
- CX18_ERR_DEV(sd, "verification of %s firmware load "
- "failed: expected %#010x got %#010x\n",
- FWFILE, expected, dl_control);
- ret = -EIO;
- break;
- }
- dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
- }
- if (ret == 0)
- CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n",
- FWFILE, size);
- return ret;
-}
-
-int cx18_av_loadfw(struct cx18 *cx)
-{
- struct v4l2_subdev *sd = &cx->av_state.sd;
- const struct firmware *fw = NULL;
- u32 size;
- u32 u, v;
- const u8 *ptr;
- int i;
- int retries1 = 0;
-
- if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
- CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE);
- return -EINVAL;
- }
-
- /* The firmware load often has byte errors, so allow for several
- retries, both at byte level and at the firmware load level. */
- while (retries1 < 5) {
- cx18_av_write4_expect(cx, CXADEC_CHIP_CTRL, 0x00010000,
- 0x00008430, 0xffffffff); /* cx25843 */
- cx18_av_write_expect(cx, CXADEC_STD_DET_CTL, 0xf6, 0xf6, 0xff);
-
- /* Reset the Mako core, Register is alias of CXADEC_CHIP_CTRL */
- cx18_av_write4_expect(cx, 0x8100, 0x00010000,
- 0x00008430, 0xffffffff); /* cx25843 */
-
- /* Put the 8051 in reset and enable firmware upload */
- cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000);
-
- ptr = fw->data;
- size = fw->size;
-
- for (i = 0; i < size; i++) {
- u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
- u32 value = 0;
- int retries2;
- int unrec_err = 0;
-
- for (retries2 = 0; retries2 < CX18_MAX_MMIO_WR_RETRIES;
- retries2++) {
- cx18_av_write4_noretry(cx, CXADEC_DL_CTL,
- dl_control);
- udelay(10);
- value = cx18_av_read4(cx, CXADEC_DL_CTL);
- if (value == dl_control)
- break;
- /* Check if we can correct the byte by changing
- the address. We can only write the lower
- address byte of the address. */
- if ((value & 0x3F00) != (dl_control & 0x3F00)) {
- unrec_err = 1;
- break;
- }
- }
- if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES)
- break;
- }
- if (i == size)
- break;
- retries1++;
- }
- if (retries1 >= 5) {
- CX18_ERR_DEV(sd, "unable to load firmware %s\n", FWFILE);
- release_firmware(fw);
- return -EIO;
- }
-
- cx18_av_write4_expect(cx, CXADEC_DL_CTL,
- 0x03000000 | fw->size, 0x03000000, 0x13000000);
-
- CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
-
- if (cx18_av_verifyfw(cx, fw) == 0)
- cx18_av_write4_expect(cx, CXADEC_DL_CTL,
- 0x13000000 | fw->size, 0x13000000, 0x13000000);
-
- /* Output to the 416 */
- cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
-
- /* Audio input control 1 set to Sony mode */
- /* Audio output input 2 is 0 for slave operation input */
- /* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
- /* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
- after WS transition for first bit of audio word. */
- cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0);
-
- /* Audio output control 1 is set to Sony mode */
- /* Audio output control 2 is set to 1 for master mode */
- /* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
- /* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
- after WS transition for first bit of audio word. */
- /* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT
- are generated) */
- cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
-
- /* set alt I2s master clock to /0x16 and enable alt divider i2s
- passthrough */
- cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687);
-
- cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
- 0x3F00FFFF);
- /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
-
- /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
- /* Register 0x09CC is defined by the Merlin firmware, and doesn't
- have a name in the spec. */
- cx18_av_write4(cx, 0x09CC, 1);
-
- v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
- /* If bit 11 is 1, clear bit 10 */
- if (v & 0x800)
- cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
- 0, 0x400);
-
- /* Toggle the AI1 MUX */
- v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
- u = v & CX18_AI1_MUX_MASK;
- v &= ~CX18_AI1_MUX_MASK;
- if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
- /* Switch to I2S1 */
- v |= CX18_AI1_MUX_I2S1;
- cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
- v, CX18_AI1_MUX_MASK);
- /* Switch back to the A/V decoder core I2S output */
- v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
- } else {
- /* Switch to the A/V decoder core I2S output */
- v |= CX18_AI1_MUX_843_I2S;
- cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
- v, CX18_AI1_MUX_MASK);
- /* Switch back to I2S1 or I2S2 */
- v = (v & ~CX18_AI1_MUX_MASK) | u;
- }
- cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
- v, CX18_AI1_MUX_MASK);
-
- /* Enable WW auto audio standard detection */
- v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
- v |= 0xFF; /* Auto by default */
- v |= 0x400; /* Stereo by default */
- v |= 0x14000000;
- cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
-
- release_firmware(fw);
- return 0;
-}
-
-MODULE_FIRMWARE(FWFILE);
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
deleted file mode 100644
index baa36fbcd4d4..000000000000
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * cx18 ADEC VBI functions
- *
- * Derived from cx25840-vbi.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-
-#include "cx18-driver.h"
-
-/*
- * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
- * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
- * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
- * (should!) look like:
- * 4 byte EAV code: 0xff 0x00 0x00 0xRP
- * unknown number of possible idle bytes
- * 3 byte Anc data preamble: 0x00 0xff 0xff
- * 1 byte data identifier: ne010iii (parity bits, 010, DID bits)
- * 1 byte secondary data id: nessssss (parity bits, SDID bits)
- * 1 byte data word count: necccccc (parity bits, NN Dword count)
- * 2 byte Internal DID: VBI-line-# 0x80
- * NN data bytes
- * 1 byte checksum
- * Fill bytes needed to fil out to 4*NN bytes of payload
- *
- * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
- * in the vertical blanking interval are:
- * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0)
- * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
- *
- * Since the V bit is only allowed to toggle in the EAV RP code, just
- * before the first active region line and for active lines, they are:
- * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0)
- * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
- *
- * The user application DID bytes we care about are:
- * 0x91 (1 0 010 0 !ActiveLine AncDataPresent)
- * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
- *
- */
-static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
-
-struct vbi_anc_data {
- /* u8 eav[4]; */
- /* u8 idle[]; Variable number of idle bytes */
- u8 preamble[3];
- u8 did;
- u8 sdid;
- u8 data_count;
- u8 idid[2];
- u8 payload[1]; /* data_count of payload */
- /* u8 checksum; */
- /* u8 fill[]; Variable number of fill bytes */
-};
-
-static int odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
-static int decode_vps(u8 *dst, u8 *p)
-{
- static const u8 biphase_tbl[] = {
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
- 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
- 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
- 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
- 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
- 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
- 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- };
-
- u8 c, err = 0;
- int i;
-
- for (i = 0; i < 2 * 13; i += 2) {
- err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
- c = (biphase_tbl[p[i + 1]] & 0xf) |
- ((biphase_tbl[p[i]] & 0xf) << 4);
- dst[i / 2] = c;
- }
-
- return err & 0xf0;
-}
-
-int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
- static const u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
- return 0;
-
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 7);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- } else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- }
- return 0;
-}
-
-int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
-
- /* Setup standard */
- cx18_av_std_setup(cx);
-
- /* VBI Offset */
- cx18_av_write(cx, 0x47f, state->slicer_line_delay);
- cx18_av_write(cx, 0x404, 0x2e);
- return 0;
-}
-
-int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i, x;
- u8 lcr[24];
-
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
-
- /* Setup standard */
- cx18_av_std_setup(cx);
-
- /* Sliced VBI */
- cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
- cx18_av_write(cx, 0x406, 0x13);
- cx18_av_write(cx, 0x47f, state->slicer_line_delay);
-
- /* Force impossible lines to 0 */
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
-
- /* Build register values for requested service lines */
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
-
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++)
- cx18_av_write(cx, i, lcr[6 + x]);
- } else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++)
- cx18_av_write(cx, i, lcr[9 + x]);
- for (i = 0x431; i <= 0x434; i++)
- cx18_av_write(cx, i, 0);
- }
-
- cx18_av_write(cx, 0x43c, 0x16);
- /* Should match vblank set in cx18_av_std_setup() */
- cx18_av_write(cx, 0x474, is_pal ? 38 : 26);
- return 0;
-}
-
-int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
- struct v4l2_decode_vbi_line *vbi)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
- struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
- u8 *p;
- int did, sdid, l, err = 0;
-
- /*
- * Check for the ancillary data header for sliced VBI
- */
- if (anc->preamble[0] ||
- anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
- (anc->did != sliced_vbi_did[0] &&
- anc->did != sliced_vbi_did[1])) {
- vbi->line = vbi->type = 0;
- return 0;
- }
-
- did = anc->did;
- sdid = anc->sdid & 0xf;
- l = anc->idid[0] & 0x3f;
- l += state->slicer_line_offset;
- p = anc->payload;
-
- /* Decode the SDID set by the slicer */
- switch (sdid) {
- case 1:
- sdid = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- sdid = V4L2_SLICED_WSS_625;
- break;
- case 6:
- sdid = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- sdid = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0)
- err = 1;
- break;
- default:
- sdid = 0;
- err = 1;
- break;
- }
-
- vbi->type = err ? 0 : sdid;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
- vbi->p = p;
- return 0;
-}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
deleted file mode 100644
index c07c849b1aaf..000000000000
--- a/drivers/media/video/cx18/cx18-cards.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * cx18 functions to query card hardware
- *
- * Derived from ivtv-cards.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-cards.h"
-#include "cx18-av-core.h"
-#include "cx18-i2c.h"
-#include <media/cs5345.h>
-
-#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM)
-
-/********************** card configuration *******************************/
-
-/* usual i2c tuner addresses to probe */
-static struct cx18_card_tuner_i2c cx18_i2c_std = {
- .radio = { I2C_CLIENT_END },
- .demod = { 0x43, I2C_CLIENT_END },
- .tv = { 0x61, 0x60, I2C_CLIENT_END },
-};
-
-/*
- * usual i2c tuner addresses to probe with additional demod address for
- * an NXP TDA8295 at 0x42 (N.B. it can possibly be at 0x4b or 0x4c too).
- */
-static struct cx18_card_tuner_i2c cx18_i2c_nxp = {
- .radio = { I2C_CLIENT_END },
- .demod = { 0x42, 0x43, I2C_CLIENT_END },
- .tv = { 0x61, 0x60, I2C_CLIENT_END },
-};
-
-/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
- This keeps the PCI ID database up to date. Note that the entries
- must be added under vendor 0x4444 (Conexant) as subsystem IDs.
- New vendor IDs should still be added to the vendor ID list. */
-
-/* Hauppauge HVR-1600 cards */
-
-/* Note: for Hauppauge cards the tveeprom information is used instead
- of PCI IDs */
-static const struct cx18_card cx18_card_hvr1600_esmt = {
- .type = CX18_CARD_HVR_1600_ESMT,
- .name = "Hauppauge HVR-1600",
- .comment = "Simultaneous Digital and Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
- CX18_HW_Z8F0811_IR_HAUP,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
- { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
- { CX18_CARD_INPUT_LINE_IN2,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
- .ddr = {
- /* ESMT M13S128324A-5B memory */
- .chip_config = 0x003,
- .refresh = 0x30c,
- .timing1 = 0x44220e82,
- .timing2 = 0x08,
- .tune_lane = 0,
- .initial_emrs = 0,
- },
- .gpio_init.initial_value = 0x3001,
- .gpio_init.direction = 0x3001,
- .gpio_i2c_slave_reset = {
- .active_lo_mask = 0x3001,
- .msecs_asserted = 10,
- .msecs_recovery = 40,
- .ir_reset_mask = 0x0001,
- },
- .i2c = &cx18_i2c_std,
-};
-
-static const struct cx18_card cx18_card_hvr1600_s5h1411 = {
- .type = CX18_CARD_HVR_1600_S5H1411,
- .name = "Hauppauge HVR-1600",
- .comment = "Simultaneous Digital and Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
- CX18_HW_Z8F0811_IR_HAUP,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
- { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
- { CX18_CARD_INPUT_LINE_IN2,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
- .ddr = {
- /* ESMT M13S128324A-5B memory */
- .chip_config = 0x003,
- .refresh = 0x30c,
- .timing1 = 0x44220e82,
- .timing2 = 0x08,
- .tune_lane = 0,
- .initial_emrs = 0,
- },
- .gpio_init.initial_value = 0x3801,
- .gpio_init.direction = 0x3801,
- .gpio_i2c_slave_reset = {
- .active_lo_mask = 0x3801,
- .msecs_asserted = 10,
- .msecs_recovery = 40,
- .ir_reset_mask = 0x0001,
- },
- .i2c = &cx18_i2c_nxp,
-};
-
-static const struct cx18_card cx18_card_hvr1600_samsung = {
- .type = CX18_CARD_HVR_1600_SAMSUNG,
- .name = "Hauppauge HVR-1600 (Preproduction)",
- .comment = "Simultaneous Digital and Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
- CX18_HW_Z8F0811_IR_HAUP,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
- { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
- { CX18_CARD_INPUT_LINE_IN2,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
- .ddr = {
- /* Samsung K4D263238G-VC33 memory */
- .chip_config = 0x003,
- .refresh = 0x30c,
- .timing1 = 0x23230b73,
- .timing2 = 0x08,
- .tune_lane = 0,
- .initial_emrs = 2,
- },
- .gpio_init.initial_value = 0x3001,
- .gpio_init.direction = 0x3001,
- .gpio_i2c_slave_reset = {
- .active_lo_mask = 0x3001,
- .msecs_asserted = 10,
- .msecs_recovery = 40,
- .ir_reset_mask = 0x0001,
- },
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Compro VideoMate H900: note that this card is analog only! */
-
-static const struct cx18_card_pci_info cx18_pci_h900[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_h900 = {
- .type = CX18_CARD_COMPRO_H900,
- .name = "Compro VideoMate H900",
- .comment = "Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL1, 0 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL1, 0 },
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .ddr = {
- /* EtronTech EM6A9160TS-5G memory */
- .chip_config = 0x50003,
- .refresh = 0x753,
- .timing1 = 0x24330e84,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 0,
- },
- .xceive_pin = 15,
- .pci_list = cx18_pci_h900,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPC718: not working at the moment! */
-
-static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_mpc718 = {
- .type = CX18_CARD_YUAN_MPC718,
- .name = "Yuan MPC718 MiniPCI DVB-T/Analog",
- .comment = "Experimenters needed for device to work well.\n"
- "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- { CX18_CARD_INPUT_SVIDEO2, 2,
- CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
- },
- .tuners = {
- /* XC3028 tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
- .ddr = {
- /* Hynix HY5DU283222B DDR RAM */
- .chip_config = 0x303,
- .refresh = 0x3bd,
- .timing1 = 0x36320966,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 2,
- },
- .gpio_init.initial_value = 0x1,
- .gpio_init.direction = 0x3,
- /* FIXME - these GPIO's are just guesses */
- .gpio_audio_input = { .mask = 0x3,
- .tuner = 0x1,
- .linein = 0x3,
- .radio = 0x1 },
- .xceive_pin = 0,
- .pci_list = cx18_pci_mpc718,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* GoTView PCI */
-
-static const struct cx18_card_pci_info cx18_pci_gotview_dvd3[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_GOTVIEW, 0x3343 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_gotview_dvd3 = {
- .type = CX18_CARD_GOTVIEW_PCI_DVD3,
- .name = "GoTView PCI DVD3 Hybrid",
- .comment = "Experimenters needed for device to work well.\n"
- "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- { CX18_CARD_INPUT_SVIDEO2, 2,
- CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
- },
- .tuners = {
- /* XC3028 tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
- .ddr = {
- /* Hynix HY5DU283222B DDR RAM */
- .chip_config = 0x303,
- .refresh = 0x3bd,
- .timing1 = 0x36320966,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 2,
- },
- .gpio_init.initial_value = 0x1,
- .gpio_init.direction = 0x3,
-
- .gpio_audio_input = { .mask = 0x3,
- .tuner = 0x1,
- .linein = 0x2,
- .radio = 0x1 },
- .xceive_pin = 0,
- .pci_list = cx18_pci_gotview_dvd3,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Conexant Raptor PAL/SECAM: note that this card is analog only! */
-
-static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_CONEXANT, 0x0009 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_cnxt_raptor_pal = {
- .type = CX18_CARD_CNXT_RAPTOR_PAL,
- .name = "Conexant Raptor PAL/SECAM",
- .comment = "Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- { CX18_CARD_INPUT_SVIDEO2, 2,
- CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
- },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 2 },
- .ddr = {
- /* MT 46V16M16 memory */
- .chip_config = 0x50306,
- .refresh = 0x753,
- .timing1 = 0x33220953,
- .timing2 = 0x09,
- .tune_lane = 0,
- .initial_emrs = 0,
- },
- .gpio_init.initial_value = 0x1002,
- .gpio_init.direction = 0xf002,
- .gpio_audio_input = { .mask = 0xf002,
- .tuner = 0x1002, /* LED D1 Tuner AF */
- .linein = 0x2000, /* LED D2 Line In 1 */
- .radio = 0x4002 }, /* LED D3 Tuner AF */
- .pci_list = cx18_pci_cnxt_raptor_pal,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Toshiba Qosmio laptop internal DVB-T/Analog Hybrid Tuner */
-
-static const struct cx18_card_pci_info cx18_pci_toshiba_qosmio_dvbt[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_TOSHIBA, 0x0110 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
- .type = CX18_CARD_TOSHIBA_QOSMIO_DVBT,
- .name = "Toshiba Qosmio DVB-T/Analog",
- .comment = "Experimenters and photos needed for device to work well.\n"
- "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- },
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .ddr = {
- .chip_config = 0x202,
- .refresh = 0x3bb,
- .timing1 = 0x33320a63,
- .timing2 = 0x0a,
- .tune_lane = 0,
- .initial_emrs = 0x42,
- },
- .xceive_pin = 15,
- .pci_list = cx18_pci_toshiba_qosmio_dvbt,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Leadtek WinFast PVR2100 */
-
-static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_leadtek_pvr2100 = {
- .type = CX18_CARD_LEADTEK_PVR2100,
- .name = "Leadtek WinFast PVR2100",
- .comment = "Experimenters and photos needed for device to work well.\n"
- "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
- CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- },
- .tuners = {
- /* XC2028 tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
- .ddr = {
- /* Pointer to proper DDR config values provided by Terry Wu */
- .chip_config = 0x303,
- .refresh = 0x3bb,
- .timing1 = 0x24220e83,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 0x2,
- },
- .gpio_init.initial_value = 0x6,
- .gpio_init.direction = 0x7,
- .gpio_audio_input = { .mask = 0x7,
- .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
- .xceive_pin = 1,
- .pci_list = cx18_pci_leadtek_pvr2100,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Leadtek WinFast DVR3100 H */
-
-static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_leadtek_dvr3100h = {
- .type = CX18_CARD_LEADTEK_DVR3100H,
- .name = "Leadtek WinFast DVR3100 H",
- .comment = "Simultaneous DVB-T and Analog capture supported,\n"
- "\texcept when capturing Analog from the antenna input.\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
- CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- },
- .tuners = {
- /* XC3028 tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
- .ddr = {
- /* Pointer to proper DDR config values provided by Terry Wu */
- .chip_config = 0x303,
- .refresh = 0x3bb,
- .timing1 = 0x24220e83,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 0x2,
- },
- .gpio_init.initial_value = 0x6,
- .gpio_init.direction = 0x7,
- .gpio_audio_input = { .mask = 0x7,
- .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
- .xceive_pin = 1,
- .pci_list = cx18_pci_leadtek_dvr3100h,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static const struct cx18_card *cx18_card_list[] = {
- &cx18_card_hvr1600_esmt,
- &cx18_card_hvr1600_samsung,
- &cx18_card_h900,
- &cx18_card_mpc718,
- &cx18_card_cnxt_raptor_pal,
- &cx18_card_toshiba_qosmio_dvbt,
- &cx18_card_leadtek_pvr2100,
- &cx18_card_leadtek_dvr3100h,
- &cx18_card_gotview_dvd3,
- &cx18_card_hvr1600_s5h1411
-};
-
-const struct cx18_card *cx18_get_card(u16 index)
-{
- if (index >= ARRAY_SIZE(cx18_card_list))
- return NULL;
- return cx18_card_list[index];
-}
-
-int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
-{
- const struct cx18_card_video_input *card_input =
- cx->card->video_inputs + index;
- static const char * const input_strs[] = {
- "Tuner 1",
- "S-Video 1",
- "S-Video 2",
- "Composite 1",
- "Composite 2",
- "Component 1"
- };
-
- if (index >= cx->nof_inputs)
- return -EINVAL;
- input->index = index;
- strlcpy(input->name, input_strs[card_input->video_type - 1],
- sizeof(input->name));
- input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ?
- V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
- input->audioset = (1 << cx->nof_audio_inputs) - 1;
- input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
- cx->tuner_std : V4L2_STD_ALL;
- return 0;
-}
-
-int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio)
-{
- const struct cx18_card_audio_input *aud_input =
- cx->card->audio_inputs + index;
- static const char * const input_strs[] = {
- "Tuner 1",
- "Line In 1",
- "Line In 2"
- };
-
- memset(audio, 0, sizeof(*audio));
- if (index >= cx->nof_audio_inputs)
- return -EINVAL;
- strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
- sizeof(audio->name));
- audio->index = index;
- audio->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
deleted file mode 100644
index add7391ecaba..000000000000
--- a/drivers/media/video/cx18/cx18-cards.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * cx18 functions to query card hardware
- *
- * Derived from ivtv-cards.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* hardware flags */
-#define CX18_HW_TUNER (1 << 0)
-#define CX18_HW_TVEEPROM (1 << 1)
-#define CX18_HW_CS5345 (1 << 2)
-#define CX18_HW_DVB (1 << 3)
-#define CX18_HW_418_AV (1 << 4)
-#define CX18_HW_GPIO_MUX (1 << 5)
-#define CX18_HW_GPIO_RESET_CTRL (1 << 6)
-#define CX18_HW_Z8F0811_IR_TX_HAUP (1 << 7)
-#define CX18_HW_Z8F0811_IR_RX_HAUP (1 << 8)
-#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \
- CX18_HW_Z8F0811_IR_TX_HAUP)
-
-#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
- CX18_HW_Z8F0811_IR_TX_HAUP)
-
-/* video inputs */
-#define CX18_CARD_INPUT_VID_TUNER 1
-#define CX18_CARD_INPUT_SVIDEO1 2
-#define CX18_CARD_INPUT_SVIDEO2 3
-#define CX18_CARD_INPUT_COMPOSITE1 4
-#define CX18_CARD_INPUT_COMPOSITE2 5
-#define CX18_CARD_INPUT_COMPONENT1 6
-
-/* audio inputs */
-#define CX18_CARD_INPUT_AUD_TUNER 1
-#define CX18_CARD_INPUT_LINE_IN1 2
-#define CX18_CARD_INPUT_LINE_IN2 3
-
-#define CX18_CARD_MAX_VIDEO_INPUTS 6
-#define CX18_CARD_MAX_AUDIO_INPUTS 3
-#define CX18_CARD_MAX_TUNERS 2
-
-/* V4L2 capability aliases */
-#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
- V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)
-
-struct cx18_card_video_input {
- u8 video_type; /* video input type */
- u8 audio_index; /* index in cx18_card_audio_input array */
- u32 video_input; /* hardware video input */
-};
-
-struct cx18_card_audio_input {
- u8 audio_type; /* audio input type */
- u32 audio_input; /* hardware audio input */
- u16 muxer_input; /* hardware muxer input for boards with a
- multiplexer chip */
-};
-
-struct cx18_card_pci_info {
- u16 device;
- u16 subsystem_vendor;
- u16 subsystem_device;
-};
-
-/* GPIO definitions */
-
-/* The mask is the set of bits used by the operation */
-
-struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
- u32 direction; /* DIR setting. Leave to 0 if no init is needed */
- u32 initial_value;
-};
-
-struct cx18_gpio_i2c_slave_reset {
- u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */
- u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
- int msecs_asserted; /* time period reset must remain asserted */
- int msecs_recovery; /* time after deassert for chips to be ready */
- u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */
-};
-
-struct cx18_gpio_audio_input { /* select tuner/line in input */
- u32 mask; /* leave to 0 if not supported */
- u32 tuner;
- u32 linein;
- u32 radio;
-};
-
-struct cx18_card_tuner {
- v4l2_std_id std; /* standard for which the tuner is suitable */
- int tuner; /* tuner ID (from tuner.h) */
-};
-
-struct cx18_card_tuner_i2c {
- unsigned short radio[2];/* radio tuner i2c address to probe */
- unsigned short demod[3];/* demodulator i2c address to probe */
- unsigned short tv[4]; /* tv tuner i2c addresses to probe */
-};
-
-struct cx18_ddr { /* DDR config data */
- u32 chip_config;
- u32 refresh;
- u32 timing1;
- u32 timing2;
- u32 tune_lane;
- u32 initial_emrs;
-};
-
-/* for card information/parameters */
-struct cx18_card {
- int type;
- char *name;
- char *comment;
- u32 v4l2_capabilities;
- u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only
- 1 dev allowed currently) */
- u32 hw_muxer; /* hardware used to multiplex audio input */
- u32 hw_all; /* all hardware used by the board */
- struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS];
- struct cx18_card_audio_input audio_inputs[CX18_CARD_MAX_AUDIO_INPUTS];
- struct cx18_card_audio_input radio_input;
-
- /* GPIO card-specific settings */
- u8 xceive_pin; /* XCeive tuner GPIO reset pin */
- struct cx18_gpio_init gpio_init;
- struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
- struct cx18_gpio_audio_input gpio_audio_input;
-
- struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
- struct cx18_card_tuner_i2c *i2c;
-
- struct cx18_ddr ddr;
-
- /* list of device and subsystem vendor/devices that
- correspond to this card type. */
- const struct cx18_card_pci_info *pci_list;
-};
-
-int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input);
-int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *input);
-const struct cx18_card *cx18_get_card(u16 index);
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
deleted file mode 100644
index 282a3d29fdaa..000000000000
--- a/drivers/media/video/cx18/cx18-controls.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * cx18 ioctl control functions
- *
- * Derived from ivtv-controls.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "cx18-driver.h"
-#include "cx18-cards.h"
-#include "cx18-ioctl.h"
-#include "cx18-audio.h"
-#include "cx18-mailbox.h"
-#include "cx18-controls.h"
-
-static int cx18_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
-{
- struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
- int type = cxhdl->stream_type->val;
-
- if (atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
- !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS ||
- type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD ||
- type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) {
- /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */
- cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
- CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
- "the MPEG stream\n");
- return 0;
- }
-
- /* Allocate sliced VBI buffers if needed. */
- if (cx->vbi.sliced_mpeg_data[0] == NULL) {
- int i;
-
- for (i = 0; i < CX18_VBI_FRAMES; i++) {
- cx->vbi.sliced_mpeg_data[i] =
- kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL);
- if (cx->vbi.sliced_mpeg_data[i] == NULL) {
- while (--i >= 0) {
- kfree(cx->vbi.sliced_mpeg_data[i]);
- cx->vbi.sliced_mpeg_data[i] = NULL;
- }
- cx->vbi.insert_mpeg =
- V4L2_MPEG_STREAM_VBI_FMT_NONE;
- CX18_WARN("Unable to allocate buffers for "
- "sliced VBI data insertion\n");
- return -ENOMEM;
- }
- }
- }
-
- cx->vbi.insert_mpeg = fmt;
- CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS,"
- "when sliced VBI is enabled\n");
-
- /*
- * If our current settings have no lines set for capture, store a valid,
- * default set of service lines to capture, in our current settings.
- */
- if (cx18_get_service_set(cx->vbi.sliced_in) == 0) {
- if (cx->is_60hz)
- cx->vbi.sliced_in->service_set =
- V4L2_SLICED_CAPTION_525;
- else
- cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
- cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz);
- }
- return 0;
-}
-
-static int cx18_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
-{
- struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
- int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
- struct v4l2_mbus_framefmt fmt;
-
- /* fix videodecoder resolution */
- fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
- fmt.height = cxhdl->height;
- fmt.code = V4L2_MBUS_FMT_FIXED;
- v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
- return 0;
-}
-
-static int cx18_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
-{
- static const u32 freqs[3] = { 44100, 48000, 32000 };
- struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
-
- /* The audio clock of the digitizer must match the codec sample
- rate otherwise you get some very strange effects. */
- if (idx < ARRAY_SIZE(freqs))
- cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
- return 0;
-}
-
-static int cx18_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val)
-{
- struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
-
- cx->dualwatch_stereo_mode = val;
- return 0;
-}
-
-struct cx2341x_handler_ops cx18_cxhdl_ops = {
- .s_audio_mode = cx18_s_audio_mode,
- .s_audio_sampling_freq = cx18_s_audio_sampling_freq,
- .s_video_encoding = cx18_s_video_encoding,
- .s_stream_vbi_fmt = cx18_s_stream_vbi_fmt,
-};
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h
deleted file mode 100644
index cb5dfc7b2054..000000000000
--- a/drivers/media/video/cx18/cx18-controls.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * cx18 ioctl control functions
- *
- * Derived from ivtv-controls.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-extern struct cx2341x_handler_ops cx18_cxhdl_ops;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
deleted file mode 100644
index c67733d32c8a..000000000000
--- a/drivers/media/video/cx18/cx18-driver.c
+++ /dev/null
@@ -1,1360 +0,0 @@
-/*
- * cx18 driver initialization and card probing
- *
- * Derived from ivtv-driver.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-version.h"
-#include "cx18-cards.h"
-#include "cx18-i2c.h"
-#include "cx18-irq.h"
-#include "cx18-gpio.h"
-#include "cx18-firmware.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-av-core.h"
-#include "cx18-scb.h"
-#include "cx18-mailbox.h"
-#include "cx18-ioctl.h"
-#include "cx18-controls.h"
-#include "tuner-xc2028.h"
-#include <linux/dma-mapping.h>
-#include <media/tveeprom.h>
-
-/* If you have already X v4l cards, then set this to X. This way
- the device numbers stay matched. Example: you have a WinTV card
- without radio and a Compro H900 with. Normally this would give a
- video1 device together with a radio0 device for the Compro. By
- setting this to 1 you ensure that radio0 is now also radio1. */
-int cx18_first_minor;
-
-/* Callback for registering extensions */
-int (*cx18_ext_init)(struct cx18 *);
-EXPORT_SYMBOL(cx18_ext_init);
-
-/* add your revision and whatnot here */
-static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
- {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
-
-static atomic_t cx18_instance = ATOMIC_INIT(0);
-
-/* Parameter declarations */
-static int cardtype[CX18_MAX_CARDS];
-static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-static unsigned cardtype_c = 1;
-static unsigned tuner_c = 1;
-static unsigned radio_c = 1;
-static char pal[] = "--";
-static char secam[] = "--";
-static char ntsc[] = "-";
-
-/* Buffers */
-static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
-static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
-static int enc_idx_buffers = CX18_DEFAULT_ENC_IDX_BUFFERS;
-static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
-static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
-static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
-
-static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE;
-static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
-static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
-static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
-static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
-
-static int enc_ts_bufs = -1;
-static int enc_mpg_bufs = -1;
-static int enc_idx_bufs = CX18_MAX_FW_MDLS_PER_STREAM;
-static int enc_yuv_bufs = -1;
-static int enc_vbi_bufs = -1;
-static int enc_pcm_bufs = -1;
-
-
-static int cx18_pci_latency = 1;
-
-static int mmio_ndelay;
-static int retry_mmio = 1;
-
-int cx18_debug;
-
-module_param_array(tuner, int, &tuner_c, 0644);
-module_param_array(radio, int, &radio_c, 0644);
-module_param_array(cardtype, int, &cardtype_c, 0644);
-module_param_string(pal, pal, sizeof(pal), 0644);
-module_param_string(secam, secam, sizeof(secam), 0644);
-module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
-module_param_named(debug, cx18_debug, int, 0644);
-module_param(mmio_ndelay, int, 0644);
-module_param(retry_mmio, int, 0644);
-module_param(cx18_pci_latency, int, 0644);
-module_param(cx18_first_minor, int, 0644);
-
-module_param(enc_ts_buffers, int, 0644);
-module_param(enc_mpg_buffers, int, 0644);
-module_param(enc_idx_buffers, int, 0644);
-module_param(enc_yuv_buffers, int, 0644);
-module_param(enc_vbi_buffers, int, 0644);
-module_param(enc_pcm_buffers, int, 0644);
-
-module_param(enc_ts_bufsize, int, 0644);
-module_param(enc_mpg_bufsize, int, 0644);
-module_param(enc_idx_bufsize, int, 0644);
-module_param(enc_yuv_bufsize, int, 0644);
-module_param(enc_pcm_bufsize, int, 0644);
-
-module_param(enc_ts_bufs, int, 0644);
-module_param(enc_mpg_bufs, int, 0644);
-module_param(enc_idx_bufs, int, 0644);
-module_param(enc_yuv_bufs, int, 0644);
-module_param(enc_vbi_bufs, int, 0644);
-module_param(enc_pcm_bufs, int, 0644);
-
-MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
- "\t\t\tsee tuner.h for values");
-MODULE_PARM_DESC(radio,
- "Enable or disable the radio. Use only if autodetection\n"
- "\t\t\tfails. 0 = disable, 1 = enable");
-MODULE_PARM_DESC(cardtype,
- "Only use this option if your card is not detected properly.\n"
- "\t\tSpecify card type:\n"
- "\t\t\t 1 = Hauppauge HVR 1600 (ESMT memory)\n"
- "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n"
- "\t\t\t 3 = Compro VideoMate H900\n"
- "\t\t\t 4 = Yuan MPC718\n"
- "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
- "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
- "\t\t\t 7 = Leadtek WinFast PVR2100\n"
- "\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
- "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n"
- "\t\t\t 10 = Hauppauge HVR 1600 (S5H1411)\n"
- "\t\t\t 0 = Autodetect (default)\n"
- "\t\t\t-1 = Ignore this card\n\t\t");
-MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
-MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
-MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
-MODULE_PARM_DESC(debug,
- "Debug level (bitmask). Default: 0\n"
- "\t\t\t 1/0x0001: warning\n"
- "\t\t\t 2/0x0002: info\n"
- "\t\t\t 4/0x0004: mailbox\n"
- "\t\t\t 8/0x0008: dma\n"
- "\t\t\t 16/0x0010: ioctl\n"
- "\t\t\t 32/0x0020: file\n"
- "\t\t\t 64/0x0040: i2c\n"
- "\t\t\t128/0x0080: irq\n"
- "\t\t\t256/0x0100: high volume\n");
-MODULE_PARM_DESC(cx18_pci_latency,
- "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
- "\t\t\tDefault: Yes");
-MODULE_PARM_DESC(retry_mmio,
- "(Deprecated) MMIO writes are now always checked and retried\n"
- "\t\t\tEffectively: 1 [Yes]");
-MODULE_PARM_DESC(mmio_ndelay,
- "(Deprecated) MMIO accesses are now never purposely delayed\n"
- "\t\t\tEffectively: 0 ns");
-MODULE_PARM_DESC(enc_ts_buffers,
- "Encoder TS buffer memory (MB). (enc_ts_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
-MODULE_PARM_DESC(enc_ts_bufsize,
- "Size of an encoder TS buffer (kB)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFSIZE));
-MODULE_PARM_DESC(enc_ts_bufs,
- "Number of encoder TS buffers\n"
- "\t\t\tDefault is computed from other enc_ts_* parameters");
-MODULE_PARM_DESC(enc_mpg_buffers,
- "Encoder MPG buffer memory (MB). (enc_mpg_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
-MODULE_PARM_DESC(enc_mpg_bufsize,
- "Size of an encoder MPG buffer (kB)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFSIZE));
-MODULE_PARM_DESC(enc_mpg_bufs,
- "Number of encoder MPG buffers\n"
- "\t\t\tDefault is computed from other enc_mpg_* parameters");
-MODULE_PARM_DESC(enc_idx_buffers,
- "(Deprecated) Encoder IDX buffer memory (MB)\n"
- "\t\t\tIgnored, except 0 disables IDX buffer allocations\n"
- "\t\t\tDefault: 1 [Enabled]");
-MODULE_PARM_DESC(enc_idx_bufsize,
- "Size of an encoder IDX buffer (kB)\n"
- "\t\t\tAllowed values are multiples of 1.5 kB rounded up\n"
- "\t\t\t(multiples of size required for 64 index entries)\n"
- "\t\t\tDefault: 2");
-MODULE_PARM_DESC(enc_idx_bufs,
- "Number of encoder IDX buffers\n"
- "\t\t\tDefault: " __stringify(CX18_MAX_FW_MDLS_PER_STREAM));
-MODULE_PARM_DESC(enc_yuv_buffers,
- "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
-MODULE_PARM_DESC(enc_yuv_bufsize,
- "Size of an encoder YUV buffer (kB)\n"
- "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
- "\t\t\t(multiples of size required for 32 screen lines)\n"
- "\t\t\tDefault: 102");
-MODULE_PARM_DESC(enc_yuv_bufs,
- "Number of encoder YUV buffers\n"
- "\t\t\tDefault is computed from other enc_yuv_* parameters");
-MODULE_PARM_DESC(enc_vbi_buffers,
- "Encoder VBI buffer memory (MB). (enc_vbi_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
-MODULE_PARM_DESC(enc_vbi_bufs,
- "Number of encoder VBI buffers\n"
- "\t\t\tDefault is computed from enc_vbi_buffers");
-MODULE_PARM_DESC(enc_pcm_buffers,
- "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
-MODULE_PARM_DESC(enc_pcm_bufsize,
- "Size of an encoder PCM buffer (kB)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFSIZE));
-MODULE_PARM_DESC(enc_pcm_bufs,
- "Number of encoder PCM buffers\n"
- "\t\t\tDefault is computed from other enc_pcm_* parameters");
-
-MODULE_PARM_DESC(cx18_first_minor,
- "Set device node number assigned to first card");
-
-MODULE_AUTHOR("Hans Verkuil");
-MODULE_DESCRIPTION("CX23418 driver");
-MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
-MODULE_LICENSE("GPL");
-
-MODULE_VERSION(CX18_VERSION);
-
-#if defined(CONFIG_MODULES) && defined(MODULE)
-static void request_module_async(struct work_struct *work)
-{
- struct cx18 *dev = container_of(work, struct cx18, request_module_wk);
-
- /* Make sure cx18-alsa module is loaded */
- request_module("cx18-alsa");
-
- /* Initialize cx18-alsa for this instance of the cx18 device */
- if (cx18_ext_init != NULL)
- cx18_ext_init(dev);
-}
-
-static void request_modules(struct cx18 *dev)
-{
- INIT_WORK(&dev->request_module_wk, request_module_async);
- schedule_work(&dev->request_module_wk);
-}
-
-static void flush_request_modules(struct cx18 *dev)
-{
- flush_work_sync(&dev->request_module_wk);
-}
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
-
-/* Generic utility functions */
-int cx18_msleep_timeout(unsigned int msecs, int intr)
-{
- long int timeout = msecs_to_jiffies(msecs);
- int sig;
-
- do {
- set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- sig = intr ? signal_pending(current) : 0;
- } while (!sig && timeout);
- return sig;
-}
-
-/* Release ioremapped memory */
-static void cx18_iounmap(struct cx18 *cx)
-{
- if (cx == NULL)
- return;
-
- /* Release io memory */
- if (cx->enc_mem != NULL) {
- CX18_DEBUG_INFO("releasing enc_mem\n");
- iounmap(cx->enc_mem);
- cx->enc_mem = NULL;
- }
-}
-
-static void cx18_eeprom_dump(struct cx18 *cx, unsigned char *eedata, int len)
-{
- int i;
-
- CX18_INFO("eeprom dump:\n");
- for (i = 0; i < len; i++) {
- if (0 == (i % 16))
- CX18_INFO("eeprom %02x:", i);
- printk(KERN_CONT " %02x", eedata[i]);
- if (15 == (i % 16))
- printk(KERN_CONT "\n");
- }
-}
-
-/* Hauppauge card? get values from tveeprom */
-void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
-{
- struct i2c_client c;
- u8 eedata[256];
-
- memset(&c, 0, sizeof(c));
- strlcpy(c.name, "cx18 tveeprom tmp", sizeof(c.name));
- c.adapter = &cx->i2c_adap[0];
- c.addr = 0xA0 >> 1;
-
- memset(tv, 0, sizeof(*tv));
- if (tveeprom_read(&c, eedata, sizeof(eedata)))
- return;
-
- switch (cx->card->type) {
- case CX18_CARD_HVR_1600_ESMT:
- case CX18_CARD_HVR_1600_SAMSUNG:
- case CX18_CARD_HVR_1600_S5H1411:
- tveeprom_hauppauge_analog(&c, tv, eedata);
- break;
- case CX18_CARD_YUAN_MPC718:
- case CX18_CARD_GOTVIEW_PCI_DVD3:
- tv->model = 0x718;
- cx18_eeprom_dump(cx, eedata, sizeof(eedata));
- CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n",
- eedata[2], eedata[1], eedata[4], eedata[3]);
- break;
- default:
- tv->model = 0xffffffff;
- cx18_eeprom_dump(cx, eedata, sizeof(eedata));
- break;
- }
-}
-
-static void cx18_process_eeprom(struct cx18 *cx)
-{
- struct tveeprom tv;
-
- cx18_read_eeprom(cx, &tv);
-
- /* Many thanks to Steven Toth from Hauppauge for providing the
- model numbers */
- /* Note: the Samsung memory models cannot be reliably determined
- from the model number. Use the cardtype module option if you
- have one of these preproduction models. */
- switch (tv.model) {
- case 74301: /* Retail models */
- case 74321:
- case 74351: /* OEM models */
- case 74361:
- /* Digital side is s5h1411/tda18271 */
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_S5H1411);
- break;
- case 74021: /* Retail models */
- case 74031:
- case 74041:
- case 74141:
- case 74541: /* OEM models */
- case 74551:
- case 74591:
- case 74651:
- case 74691:
- case 74751:
- case 74891:
- /* Digital side is s5h1409/mxl5005s */
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
- break;
- case 0x718:
- return;
- case 0xffffffff:
- CX18_INFO("Unknown EEPROM encoding\n");
- return;
- case 0:
- CX18_ERR("Invalid EEPROM\n");
- return;
- default:
- CX18_ERR("Unknown model %d, defaulting to original HVR-1600 "
- "(cardtype=1)\n", tv.model);
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
- break;
- }
-
- cx->v4l2_cap = cx->card->v4l2_capabilities;
- cx->card_name = cx->card->name;
- cx->card_i2c = cx->card->i2c;
-
- CX18_INFO("Autodetected %s\n", cx->card_name);
-
- if (tv.tuner_type == TUNER_ABSENT)
- CX18_ERR("tveeprom cannot autodetect tuner!\n");
-
- if (cx->options.tuner == -1)
- cx->options.tuner = tv.tuner_type;
- if (cx->options.radio == -1)
- cx->options.radio = (tv.has_radio != 0);
-
- if (cx->std != 0)
- /* user specified tuner standard */
- return;
-
- /* autodetect tuner standard */
-#define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \
- V4L2_STD_MN | \
- V4L2_STD_PAL_I | \
- V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \
- V4L2_STD_DK)
- if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL)
- == TVEEPROM_TUNER_FORMAT_ALL) {
- CX18_DEBUG_INFO("Worldwide tuner detected\n");
- cx->std = V4L2_STD_ALL;
- } else if (tv.tuner_formats & V4L2_STD_PAL) {
- CX18_DEBUG_INFO("PAL tuner detected\n");
- cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- } else if (tv.tuner_formats & V4L2_STD_NTSC) {
- CX18_DEBUG_INFO("NTSC tuner detected\n");
- cx->std |= V4L2_STD_NTSC_M;
- } else if (tv.tuner_formats & V4L2_STD_SECAM) {
- CX18_DEBUG_INFO("SECAM tuner detected\n");
- cx->std |= V4L2_STD_SECAM_L;
- } else {
- CX18_INFO("No tuner detected, default to NTSC-M\n");
- cx->std |= V4L2_STD_NTSC_M;
- }
-}
-
-static v4l2_std_id cx18_parse_std(struct cx18 *cx)
-{
- switch (pal[0]) {
- case '6':
- return V4L2_STD_PAL_60;
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- return V4L2_STD_PAL_BG;
- case 'h':
- case 'H':
- return V4L2_STD_PAL_H;
- case 'n':
- case 'N':
- if (pal[1] == 'c' || pal[1] == 'C')
- return V4L2_STD_PAL_Nc;
- return V4L2_STD_PAL_N;
- case 'i':
- case 'I':
- return V4L2_STD_PAL_I;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- return V4L2_STD_PAL_DK;
- case 'M':
- case 'm':
- return V4L2_STD_PAL_M;
- case '-':
- break;
- default:
- CX18_WARN("pal= argument not recognised\n");
- return 0;
- }
-
- switch (secam[0]) {
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- case 'h':
- case 'H':
- return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- return V4L2_STD_SECAM_DK;
- case 'l':
- case 'L':
- if (secam[1] == 'C' || secam[1] == 'c')
- return V4L2_STD_SECAM_LC;
- return V4L2_STD_SECAM_L;
- case '-':
- break;
- default:
- CX18_WARN("secam= argument not recognised\n");
- return 0;
- }
-
- switch (ntsc[0]) {
- case 'm':
- case 'M':
- return V4L2_STD_NTSC_M;
- case 'j':
- case 'J':
- return V4L2_STD_NTSC_M_JP;
- case 'k':
- case 'K':
- return V4L2_STD_NTSC_M_KR;
- case '-':
- break;
- default:
- CX18_WARN("ntsc= argument not recognised\n");
- return 0;
- }
-
- /* no match found */
- return 0;
-}
-
-static void cx18_process_options(struct cx18 *cx)
-{
- int i, j;
-
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control only */
-
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control, no data */
-
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
-
- /* Ensure stream_buffers & stream_buf_size are valid */
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */
- cx->options.megabytes[i] <= 0 || /* User said 0 MB total */
- cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */
- cx->options.megabytes[i] = 0;
- cx->stream_buffers[i] = 0;
- cx->stream_buf_size[i] = 0;
- continue;
- }
- /*
- * YUV is a special case where the stream_buf_size needs to be
- * an integral multiple of 33.75 kB (storage for 32 screens
- * lines to maintain alignment in case of lost buffers).
- *
- * IDX is a special case where the stream_buf_size should be
- * an integral multiple of 1.5 kB (storage for 64 index entries
- * to maintain alignment in case of lost buffers).
- *
- */
- if (i == CX18_ENC_STREAM_TYPE_YUV) {
- cx->stream_buf_size[i] *= 1024;
- cx->stream_buf_size[i] -=
- (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
-
- if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
- cx->stream_buf_size[i] =
- CX18_UNIT_ENC_YUV_BUFSIZE;
- } else if (i == CX18_ENC_STREAM_TYPE_IDX) {
- cx->stream_buf_size[i] *= 1024;
- cx->stream_buf_size[i] -=
- (cx->stream_buf_size[i] % CX18_UNIT_ENC_IDX_BUFSIZE);
-
- if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE)
- cx->stream_buf_size[i] =
- CX18_UNIT_ENC_IDX_BUFSIZE;
- }
- /*
- * YUV and IDX are special cases where the stream_buf_size is
- * now in bytes.
- * VBI is a special case where the stream_buf_size is fixed
- * and already in bytes
- */
- if (i == CX18_ENC_STREAM_TYPE_VBI ||
- i == CX18_ENC_STREAM_TYPE_YUV ||
- i == CX18_ENC_STREAM_TYPE_IDX) {
- if (cx->stream_buffers[i] < 0) {
- cx->stream_buffers[i] =
- cx->options.megabytes[i] * 1024 * 1024
- / cx->stream_buf_size[i];
- } else {
- /* N.B. This might round down to 0 */
- cx->options.megabytes[i] =
- cx->stream_buffers[i]
- * cx->stream_buf_size[i]/(1024 * 1024);
- }
- } else {
- /* All other streams have stream_buf_size in kB here */
- if (cx->stream_buffers[i] < 0) {
- cx->stream_buffers[i] =
- cx->options.megabytes[i] * 1024
- / cx->stream_buf_size[i];
- } else {
- /* N.B. This might round down to 0 */
- cx->options.megabytes[i] =
- cx->stream_buffers[i]
- * cx->stream_buf_size[i] / 1024;
- }
- /* convert from kB to bytes */
- cx->stream_buf_size[i] *= 1024;
- }
- CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
- "%d bytes\n", i, cx->options.megabytes[i],
- cx->stream_buffers[i], cx->stream_buf_size[i]);
- }
-
- cx->options.cardtype = cardtype[cx->instance];
- cx->options.tuner = tuner[cx->instance];
- cx->options.radio = radio[cx->instance];
-
- cx->std = cx18_parse_std(cx);
- if (cx->options.cardtype == -1) {
- CX18_INFO("Ignore card\n");
- return;
- }
- cx->card = cx18_get_card(cx->options.cardtype - 1);
- if (cx->card)
- CX18_INFO("User specified %s card\n", cx->card->name);
- else if (cx->options.cardtype != 0)
- CX18_ERR("Unknown user specified type, trying to autodetect card\n");
- if (cx->card == NULL) {
- if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
- CX18_INFO("Autodetected Hauppauge card\n");
- }
- }
- if (cx->card == NULL) {
- for (i = 0; (cx->card = cx18_get_card(i)); i++) {
- if (cx->card->pci_list == NULL)
- continue;
- for (j = 0; cx->card->pci_list[j].device; j++) {
- if (cx->pci_dev->device !=
- cx->card->pci_list[j].device)
- continue;
- if (cx->pci_dev->subsystem_vendor !=
- cx->card->pci_list[j].subsystem_vendor)
- continue;
- if (cx->pci_dev->subsystem_device !=
- cx->card->pci_list[j].subsystem_device)
- continue;
- CX18_INFO("Autodetected %s card\n", cx->card->name);
- goto done;
- }
- }
- }
-done:
-
- if (cx->card == NULL) {
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
- CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- cx->pci_dev->vendor, cx->pci_dev->device);
- CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- cx->pci_dev->subsystem_vendor,
- cx->pci_dev->subsystem_device);
- CX18_ERR("Defaulting to %s card\n", cx->card->name);
- CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
- CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
- CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
- }
- cx->v4l2_cap = cx->card->v4l2_capabilities;
- cx->card_name = cx->card->name;
- cx->card_i2c = cx->card->i2c;
-}
-
-static int __devinit cx18_create_in_workq(struct cx18 *cx)
-{
- snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
- cx->v4l2_dev.name);
- cx->in_work_queue = alloc_ordered_workqueue(cx->in_workq_name, 0);
- if (cx->in_work_queue == NULL) {
- CX18_ERR("Unable to create incoming mailbox handler thread\n");
- return -ENOMEM;
- }
- return 0;
-}
-
-static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
-{
- int i;
- for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
- cx->in_work_order[i].cx = cx;
- cx->in_work_order[i].str = cx->epu_debug_str;
- INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
- }
-}
-
-/* Precondition: the cx18 structure has been memset to 0. Only
- the dev and instance fields have been filled in.
- No assumptions on the card type may be made here (see cx18_init_struct2
- for that).
- */
-static int __devinit cx18_init_struct1(struct cx18 *cx)
-{
- int ret;
-
- cx->base_addr = pci_resource_start(cx->pci_dev, 0);
-
- mutex_init(&cx->serialize_lock);
- mutex_init(&cx->gpio_lock);
- mutex_init(&cx->epu2apu_mb_lock);
- mutex_init(&cx->epu2cpu_mb_lock);
-
- ret = cx18_create_in_workq(cx);
- if (ret)
- return ret;
-
- cx18_init_in_work_orders(cx);
-
- /* start counting open_id at 1 */
- cx->open_id = 1;
-
- /* Initial settings */
- cx->cxhdl.port = CX2341X_PORT_MEMORY;
- cx->cxhdl.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI;
- cx->cxhdl.ops = &cx18_cxhdl_ops;
- cx->cxhdl.func = cx18_api_func;
- cx->cxhdl.priv = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
- ret = cx2341x_handler_init(&cx->cxhdl, 50);
- if (ret)
- return ret;
- cx->v4l2_dev.ctrl_handler = &cx->cxhdl.hdl;
-
- cx->temporal_strength = cx->cxhdl.video_temporal_filter->cur.val;
- cx->spatial_strength = cx->cxhdl.video_spatial_filter->cur.val;
- cx->filter_mode = cx->cxhdl.video_spatial_filter_mode->cur.val |
- (cx->cxhdl.video_temporal_filter_mode->cur.val << 1) |
- (cx->cxhdl.video_median_filter_type->cur.val << 2);
-
- init_waitqueue_head(&cx->cap_w);
- init_waitqueue_head(&cx->mb_apu_waitq);
- init_waitqueue_head(&cx->mb_cpu_waitq);
- init_waitqueue_head(&cx->dma_waitq);
-
- /* VBI */
- cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
-
- /* IVTV style VBI insertion into MPEG streams */
- INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_buf.list);
- INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.list);
- INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.buf_list);
- list_add(&cx->vbi.sliced_mpeg_buf.list,
- &cx->vbi.sliced_mpeg_mdl.buf_list);
- return 0;
-}
-
-/* Second initialization part. Here the card type has been
- autodetected. */
-static void __devinit cx18_init_struct2(struct cx18 *cx)
-{
- int i;
-
- for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++)
- if (cx->card->video_inputs[i].video_type == 0)
- break;
- cx->nof_inputs = i;
- for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++)
- if (cx->card->audio_inputs[i].audio_type == 0)
- break;
- cx->nof_audio_inputs = i;
-
- /* Find tuner input */
- for (i = 0; i < cx->nof_inputs; i++) {
- if (cx->card->video_inputs[i].video_type ==
- CX18_CARD_INPUT_VID_TUNER)
- break;
- }
- if (i == cx->nof_inputs)
- i = 0;
- cx->active_input = i;
- cx->audio_input = cx->card->video_inputs[i].audio_index;
-}
-
-static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- u16 cmd;
- unsigned char pci_latency;
-
- CX18_DEBUG_INFO("Enabling pci device\n");
-
- if (pci_enable_device(pci_dev)) {
- CX18_ERR("Can't enable device %d!\n", cx->instance);
- return -EIO;
- }
- if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) {
- CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
- return -EIO;
- }
- if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
- CX18_ERR("Cannot request encoder memory region, card %d\n",
- cx->instance);
- return -EIO;
- }
-
- /* Enable bus mastering and memory mapped IO for the CX23418 */
- pci_read_config_word(pci_dev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
-
- cx->card_rev = pci_dev->revision;
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
-
- if (pci_latency < 64 && cx18_pci_latency) {
- CX18_INFO("Unreasonably low latency timer, "
- "setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
- }
-
- CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
- "irq: %d, latency: %d, memory: 0x%llx\n",
- cx->pci_dev->device, cx->card_rev, pci_dev->bus->number,
- PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn),
- cx->pci_dev->irq, pci_latency, (u64)cx->base_addr);
-
- return 0;
-}
-
-static void cx18_init_subdevs(struct cx18 *cx)
-{
- u32 hw = cx->card->hw_all;
- u32 device;
- int i;
-
- for (i = 0, device = 1; i < 32; i++, device <<= 1) {
-
- if (!(device & hw))
- continue;
-
- switch (device) {
- case CX18_HW_DVB:
- case CX18_HW_TVEEPROM:
- /* These subordinate devices do not use probing */
- cx->hw_flags |= device;
- break;
- case CX18_HW_418_AV:
- /* The A/V decoder gets probed earlier to set PLLs */
- /* Just note that the card uses it (i.e. has analog) */
- cx->hw_flags |= device;
- break;
- case CX18_HW_GPIO_RESET_CTRL:
- /*
- * The Reset Controller gets probed and added to
- * hw_flags earlier for i2c adapter/bus initialization
- */
- break;
- case CX18_HW_GPIO_MUX:
- if (cx18_gpio_register(cx, device) == 0)
- cx->hw_flags |= device;
- break;
- default:
- if (cx18_i2c_register(cx, i) == 0)
- cx->hw_flags |= device;
- break;
- }
- }
-
- if (cx->hw_flags & CX18_HW_418_AV)
- cx->sd_av = cx18_find_hw(cx, CX18_HW_418_AV);
-
- if (cx->card->hw_muxer != 0)
- cx->sd_extmux = cx18_find_hw(cx, cx->card->hw_muxer);
-}
-
-static int __devinit cx18_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- int retval = 0;
- int i;
- u32 devtype;
- struct cx18 *cx;
-
- /* FIXME - module parameter arrays constrain max instances */
- i = atomic_inc_return(&cx18_instance) - 1;
- if (i >= CX18_MAX_CARDS) {
- printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
- "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
- return -ENOMEM;
- }
-
- cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
- if (cx == NULL) {
- printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
- i);
- return -ENOMEM;
- }
- cx->pci_dev = pci_dev;
- cx->instance = i;
-
- retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
- if (retval) {
- printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
- "\n", cx->instance);
- kfree(cx);
- return retval;
- }
- snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
- cx->instance);
- CX18_INFO("Initializing card %d\n", cx->instance);
-
- cx18_process_options(cx);
- if (cx->options.cardtype == -1) {
- retval = -ENODEV;
- goto err;
- }
-
- retval = cx18_init_struct1(cx);
- if (retval)
- goto err;
-
- CX18_DEBUG_INFO("base addr: 0x%llx\n", (u64)cx->base_addr);
-
- /* PCI Device Setup */
- retval = cx18_setup_pci(cx, pci_dev, pci_id);
- if (retval != 0)
- goto free_workqueues;
-
- /* map io memory */
- CX18_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
- (u64)cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
- cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET,
- CX18_MEM_SIZE);
- if (!cx->enc_mem) {
- CX18_ERR("ioremap failed. Can't get a window into CX23418 "
- "memory and register space\n");
- CX18_ERR("Each capture card with a CX23418 needs 64 MB of "
- "vmalloc address space for the window\n");
- CX18_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
- CX18_ERR("Use the vmalloc= kernel command line option to set "
- "VmallocTotal to a larger value\n");
- retval = -ENOMEM;
- goto free_mem;
- }
- cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
- devtype = cx18_read_reg(cx, 0xC72028);
- switch (devtype & 0xff000000) {
- case 0xff000000:
- CX18_INFO("cx23418 revision %08x (A)\n", devtype);
- break;
- case 0x01000000:
- CX18_INFO("cx23418 revision %08x (B)\n", devtype);
- break;
- default:
- CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype);
- break;
- }
-
- cx18_init_power(cx, 1);
- cx18_init_memory(cx);
-
- cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET);
- cx18_init_scb(cx);
-
- cx18_gpio_init(cx);
-
- /* Initialize integrated A/V decoder early to set PLLs, just in case */
- retval = cx18_av_probe(cx);
- if (retval) {
- CX18_ERR("Could not register A/V decoder subdevice\n");
- goto free_map;
- }
-
- /* Initialize GPIO Reset Controller to do chip resets during i2c init */
- if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
- if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0)
- CX18_WARN("Could not register GPIO reset controller"
- "subdevice; proceeding anyway.\n");
- else
- cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL;
- }
-
- /* active i2c */
- CX18_DEBUG_INFO("activating i2c...\n");
- retval = init_cx18_i2c(cx);
- if (retval) {
- CX18_ERR("Could not initialize i2c\n");
- goto free_map;
- }
-
- if (cx->card->hw_all & CX18_HW_TVEEPROM) {
- /* Based on the model number the cardtype may be changed.
- The PCI IDs are not always reliable. */
- const struct cx18_card *orig_card = cx->card;
- cx18_process_eeprom(cx);
-
- if (cx->card != orig_card) {
- /* Changed the cardtype; re-reset the I2C chips */
- cx18_gpio_init(cx);
- cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
- core, reset, (u32) CX18_GPIO_RESET_I2C);
- }
- }
- if (cx->card->comment)
- CX18_INFO("%s", cx->card->comment);
- if (cx->card->v4l2_capabilities == 0) {
- retval = -ENODEV;
- goto free_i2c;
- }
- cx18_init_memory(cx);
- cx18_init_scb(cx);
-
- /* Register IRQ */
- retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
- IRQF_SHARED | IRQF_DISABLED,
- cx->v4l2_dev.name, (void *)cx);
- if (retval) {
- CX18_ERR("Failed to register irq %d\n", retval);
- goto free_i2c;
- }
-
- if (cx->std == 0)
- cx->std = V4L2_STD_NTSC_M;
-
- if (cx->options.tuner == -1) {
- for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
- if ((cx->std & cx->card->tuners[i].std) == 0)
- continue;
- cx->options.tuner = cx->card->tuners[i].tuner;
- break;
- }
- }
- /* if no tuner was found, then pick the first tuner in the card list */
- if (cx->options.tuner == -1 && cx->card->tuners[0].std) {
- cx->std = cx->card->tuners[0].std;
- if (cx->std & V4L2_STD_PAL)
- cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- else if (cx->std & V4L2_STD_NTSC)
- cx->std = V4L2_STD_NTSC_M;
- else if (cx->std & V4L2_STD_SECAM)
- cx->std = V4L2_STD_SECAM_L;
- cx->options.tuner = cx->card->tuners[0].tuner;
- }
- if (cx->options.radio == -1)
- cx->options.radio = (cx->card->radio_input.audio_type != 0);
-
- /* The card is now fully identified, continue with card-specific
- initialization. */
- cx18_init_struct2(cx);
-
- cx18_init_subdevs(cx);
-
- if (cx->std & V4L2_STD_525_60)
- cx->is_60hz = 1;
- else
- cx->is_50hz = 1;
-
- cx2341x_handler_set_50hz(&cx->cxhdl, !cx->is_60hz);
-
- if (cx->options.radio > 0)
- cx->v4l2_cap |= V4L2_CAP_RADIO;
-
- if (cx->options.tuner > -1) {
- struct tuner_setup setup;
-
- setup.addr = ADDR_UNSET;
- setup.type = cx->options.tuner;
- setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
- if (cx->options.radio > 0)
- setup.mode_mask |= T_RADIO;
- setup.tuner_callback = (setup.type == TUNER_XC2028) ?
- cx18_reset_tuner_gpio : NULL;
- cx18_call_all(cx, tuner, s_type_addr, &setup);
- if (setup.type == TUNER_XC2028) {
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- };
- struct v4l2_priv_tun_config cfg = {
- .tuner = cx->options.tuner,
- .priv = &ctrl,
- };
- cx18_call_all(cx, tuner, s_config, &cfg);
- }
- }
-
- /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
- are not. */
- cx->tuner_std = cx->std;
- if (cx->std == V4L2_STD_ALL)
- cx->std = V4L2_STD_NTSC_M;
-
- retval = cx18_streams_setup(cx);
- if (retval) {
- CX18_ERR("Error %d setting up streams\n", retval);
- goto free_irq;
- }
- retval = cx18_streams_register(cx);
- if (retval) {
- CX18_ERR("Error %d registering devices\n", retval);
- goto free_streams;
- }
-
- CX18_INFO("Initialized card: %s\n", cx->card_name);
-
- /* Load cx18 submodules (cx18-alsa) */
- request_modules(cx);
- return 0;
-
-free_streams:
- cx18_streams_cleanup(cx, 1);
-free_irq:
- free_irq(cx->pci_dev->irq, (void *)cx);
-free_i2c:
- exit_cx18_i2c(cx);
-free_map:
- cx18_iounmap(cx);
-free_mem:
- release_mem_region(cx->base_addr, CX18_MEM_SIZE);
-free_workqueues:
- destroy_workqueue(cx->in_work_queue);
-err:
- if (retval == 0)
- retval = -ENODEV;
- CX18_ERR("Error %d on initialization\n", retval);
-
- v4l2_device_unregister(&cx->v4l2_dev);
- kfree(cx);
- return retval;
-}
-
-int cx18_init_on_first_open(struct cx18 *cx)
-{
- int video_input;
- int fw_retry_count = 3;
- struct v4l2_frequency vf;
- struct cx18_open_id fh;
- v4l2_std_id std;
-
- fh.cx = cx;
-
- if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
- return -ENXIO;
-
- if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags))
- return 0;
-
- while (--fw_retry_count > 0) {
- /* load firmware */
- if (cx18_firmware_init(cx) == 0)
- break;
- if (fw_retry_count > 1)
- CX18_WARN("Retry loading firmware\n");
- }
-
- if (fw_retry_count == 0) {
- set_bit(CX18_F_I_FAILED, &cx->i_flags);
- return -ENXIO;
- }
- set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
-
- /*
- * Init the firmware twice to work around a silicon bug
- * with the digital TS.
- *
- * The second firmware load requires us to normalize the APU state,
- * or the audio for the first analog capture will be badly incorrect.
- *
- * I can't seem to call APU_RESETAI and have it succeed without the
- * APU capturing audio, so we start and stop it here to do the reset
- */
-
- /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
- cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
- cx18_vapi(cx, CX18_APU_RESETAI, 0);
- cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
-
- fw_retry_count = 3;
- while (--fw_retry_count > 0) {
- /* load firmware */
- if (cx18_firmware_init(cx) == 0)
- break;
- if (fw_retry_count > 1)
- CX18_WARN("Retry loading firmware\n");
- }
-
- if (fw_retry_count == 0) {
- set_bit(CX18_F_I_FAILED, &cx->i_flags);
- return -ENXIO;
- }
-
- /*
- * The second firmware load requires us to normalize the APU state,
- * or the audio for the first analog capture will be badly incorrect.
- *
- * I can't seem to call APU_RESETAI and have it succeed without the
- * APU capturing audio, so we start and stop it here to do the reset
- */
-
- /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
- cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
- cx18_vapi(cx, CX18_APU_RESETAI, 0);
- cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
-
- /* Init the A/V decoder, if it hasn't been already */
- v4l2_subdev_call(cx->sd_av, core, load_fw);
-
- vf.tuner = 0;
- vf.type = V4L2_TUNER_ANALOG_TV;
- vf.frequency = 6400; /* the tuner 'baseline' frequency */
-
- /* Set initial frequency. For PAL/SECAM broadcasts no
- 'default' channel exists AFAIK. */
- if (cx->std == V4L2_STD_NTSC_M_JP)
- vf.frequency = 1460; /* ch. 1 91250*16/1000 */
- else if (cx->std & V4L2_STD_NTSC_M)
- vf.frequency = 1076; /* ch. 4 67250*16/1000 */
-
- video_input = cx->active_input;
- cx->active_input++; /* Force update of input */
- cx18_s_input(NULL, &fh, video_input);
-
- /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
- in one place. */
- cx->std++; /* Force full standard initialization */
- std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
- cx18_s_std(NULL, &fh, &std);
- cx18_s_frequency(NULL, &fh, &vf);
- return 0;
-}
-
-static void cx18_cancel_in_work_orders(struct cx18 *cx)
-{
- int i;
- for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++)
- cancel_work_sync(&cx->in_work_order[i].work);
-}
-
-static void cx18_cancel_out_work_orders(struct cx18 *cx)
-{
- int i;
- for (i = 0; i < CX18_MAX_STREAMS; i++)
- if (&cx->streams[i].video_dev != NULL)
- cancel_work_sync(&cx->streams[i].out_work_order);
-}
-
-static void cx18_remove(struct pci_dev *pci_dev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct cx18 *cx = to_cx18(v4l2_dev);
- int i;
-
- CX18_DEBUG_INFO("Removing Card\n");
-
- flush_request_modules(cx);
-
- /* Stop all captures */
- CX18_DEBUG_INFO("Stopping all streams\n");
- if (atomic_read(&cx->tot_capturing) > 0)
- cx18_stop_all_captures(cx);
-
- /* Stop interrupts that cause incoming work to be queued */
- cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
-
- /* Incoming work can cause outgoing work, so clean up incoming first */
- cx18_cancel_in_work_orders(cx);
- cx18_cancel_out_work_orders(cx);
-
- /* Stop ack interrupts that may have been needed for work to finish */
- cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
-
- cx18_halt_firmware(cx);
-
- destroy_workqueue(cx->in_work_queue);
-
- cx18_streams_cleanup(cx, 1);
-
- exit_cx18_i2c(cx);
-
- free_irq(cx->pci_dev->irq, (void *)cx);
-
- cx18_iounmap(cx);
-
- release_mem_region(cx->base_addr, CX18_MEM_SIZE);
-
- pci_disable_device(cx->pci_dev);
-
- if (cx->vbi.sliced_mpeg_data[0] != NULL)
- for (i = 0; i < CX18_VBI_FRAMES; i++)
- kfree(cx->vbi.sliced_mpeg_data[i]);
-
- v4l2_ctrl_handler_free(&cx->av_state.hdl);
-
- CX18_INFO("Removed %s\n", cx->card_name);
-
- v4l2_device_unregister(v4l2_dev);
- kfree(cx);
-}
-
-
-/* define a pci_driver for card detection */
-static struct pci_driver cx18_pci_driver = {
- .name = "cx18",
- .id_table = cx18_pci_tbl,
- .probe = cx18_probe,
- .remove = cx18_remove,
-};
-
-static int __init module_start(void)
-{
- printk(KERN_INFO "cx18: Start initialization, version %s\n",
- CX18_VERSION);
-
- /* Validate parameters */
- if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
- printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
- CX18_MAX_CARDS - 1);
- return -1;
- }
-
- if (cx18_debug < 0 || cx18_debug > 511) {
- cx18_debug = 0;
- printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
- }
-
- if (pci_register_driver(&cx18_pci_driver)) {
- printk(KERN_ERR "cx18: Error detecting PCI card\n");
- return -ENODEV;
- }
- printk(KERN_INFO "cx18: End initialization\n");
- return 0;
-}
-
-static void __exit module_cleanup(void)
-{
- pci_unregister_driver(&cx18_pci_driver);
-}
-
-module_init(module_start);
-module_exit(module_cleanup);
-MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
deleted file mode 100644
index 2767c64df0c8..000000000000
--- a/drivers/media/video/cx18/cx18-driver.h
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * cx18 driver internal defines and structures
- *
- * Derived from ivtv-driver.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX18_DRIVER_H
-#define CX18_DRIVER_H
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/list.h>
-#include <linux/unistd.h>
-#include <linux/pagemap.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-fh.h>
-#include <media/tuner.h>
-#include <media/ir-kbd-i2c.h>
-#include "cx18-mailbox.h"
-#include "cx18-av-core.h"
-#include "cx23418.h"
-
-/* DVB */
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
-
-/* Videobuf / YUV support */
-#include <media/videobuf-core.h>
-#include <media/videobuf-vmalloc.h>
-
-#ifndef CONFIG_PCI
-# error "This driver requires kernel PCI support."
-#endif
-
-#define CX18_MEM_OFFSET 0x00000000
-#define CX18_MEM_SIZE 0x04000000
-#define CX18_REG_OFFSET 0x02000000
-
-/* Maximum cx18 driver instances. */
-#define CX18_MAX_CARDS 32
-
-/* Supported cards */
-#define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */
-#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
-#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
-#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
-#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
-#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
-#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
-#define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */
-#define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */
-#define CX18_CARD_HVR_1600_S5H1411 9 /* Hauppauge HVR 1600 s5h1411/tda18271*/
-#define CX18_CARD_LAST 9
-
-#define CX18_ENC_STREAM_TYPE_MPG 0
-#define CX18_ENC_STREAM_TYPE_TS 1
-#define CX18_ENC_STREAM_TYPE_YUV 2
-#define CX18_ENC_STREAM_TYPE_VBI 3
-#define CX18_ENC_STREAM_TYPE_PCM 4
-#define CX18_ENC_STREAM_TYPE_IDX 5
-#define CX18_ENC_STREAM_TYPE_RAD 6
-#define CX18_MAX_STREAMS 7
-
-/* system vendor and device IDs */
-#define PCI_VENDOR_ID_CX 0x14f1
-#define PCI_DEVICE_ID_CX23418 0x5b7a
-
-/* subsystem vendor ID */
-#define CX18_PCI_ID_HAUPPAUGE 0x0070
-#define CX18_PCI_ID_COMPRO 0x185b
-#define CX18_PCI_ID_YUAN 0x12ab
-#define CX18_PCI_ID_CONEXANT 0x14f1
-#define CX18_PCI_ID_TOSHIBA 0x1179
-#define CX18_PCI_ID_LEADTEK 0x107D
-#define CX18_PCI_ID_GOTVIEW 0x5854
-
-/* ======================================================================== */
-/* ========================== START USER SETTABLE DMA VARIABLES =========== */
-/* ======================================================================== */
-
-/* DMA Buffers, Default size in MB allocated */
-#define CX18_DEFAULT_ENC_TS_BUFFERS 1
-#define CX18_DEFAULT_ENC_MPG_BUFFERS 2
-#define CX18_DEFAULT_ENC_IDX_BUFFERS 1
-#define CX18_DEFAULT_ENC_YUV_BUFFERS 2
-#define CX18_DEFAULT_ENC_VBI_BUFFERS 1
-#define CX18_DEFAULT_ENC_PCM_BUFFERS 1
-
-/* Maximum firmware DMA buffers per stream */
-#define CX18_MAX_FW_MDLS_PER_STREAM 63
-
-/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
-#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */
-#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
-#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
-
-/* IDX buffer size should be a multiple of the index entry size from the chip */
-struct cx18_enc_idx_entry {
- __le32 length;
- __le32 offset_low;
- __le32 offset_high;
- __le32 flags;
- __le32 pts_low;
- __le32 pts_high;
-} __attribute__ ((packed));
-#define CX18_UNIT_ENC_IDX_BUFSIZE \
- (sizeof(struct cx18_enc_idx_entry) * V4L2_ENC_IDX_ENTRIES)
-
-/* DMA buffer, default size in kB allocated */
-#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
-#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
-#define CX18_DEFAULT_ENC_IDX_BUFSIZE (CX18_UNIT_ENC_IDX_BUFSIZE * 1 / 1024 + 1)
-#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
-#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
-
-/* i2c stuff */
-#define I2C_CLIENTS_MAX 16
-
-/* debugging */
-
-/* Flag to turn on high volume debugging */
-#define CX18_DBGFLG_WARN (1 << 0)
-#define CX18_DBGFLG_INFO (1 << 1)
-#define CX18_DBGFLG_API (1 << 2)
-#define CX18_DBGFLG_DMA (1 << 3)
-#define CX18_DBGFLG_IOCTL (1 << 4)
-#define CX18_DBGFLG_FILE (1 << 5)
-#define CX18_DBGFLG_I2C (1 << 6)
-#define CX18_DBGFLG_IRQ (1 << 7)
-/* Flag to turn on high volume debugging */
-#define CX18_DBGFLG_HIGHVOL (1 << 8)
-
-/* NOTE: extra space before comma in 'fmt , ## args' is required for
- gcc-2.95, otherwise it won't compile. */
-#define CX18_DEBUG(x, type, fmt, args...) \
- do { \
- if ((x) & cx18_debug) \
- v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
- } while (0)
-#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
-#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
-#define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args)
-#define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args)
-#define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args)
-#define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
-#define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
-
-#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
- do { \
- if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
- v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
- } while (0)
-#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
-#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
-#define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args)
-#define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args)
-#define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args)
-#define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
-#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
-
-/* Standard kernel messages */
-#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
-#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
-#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
-
-/* Messages for internal subdevs to use */
-#define CX18_DEBUG_DEV(x, dev, type, fmt, args...) \
- do { \
- if ((x) & cx18_debug) \
- v4l2_info(dev, " " type ": " fmt , ## args); \
- } while (0)
-#define CX18_DEBUG_WARN_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
-#define CX18_DEBUG_INFO_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
-#define CX18_DEBUG_API_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
-#define CX18_DEBUG_DMA_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
-#define CX18_DEBUG_IOCTL_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
-#define CX18_DEBUG_FILE_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
-#define CX18_DEBUG_I2C_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
-#define CX18_DEBUG_IRQ_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
-
-#define CX18_DEBUG_HIGH_VOL_DEV(x, dev, type, fmt, args...) \
- do { \
- if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
- v4l2_info(dev, " " type ": " fmt , ## args); \
- } while (0)
-#define CX18_DEBUG_HI_WARN_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
-#define CX18_DEBUG_HI_INFO_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
-#define CX18_DEBUG_HI_API_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
-#define CX18_DEBUG_HI_DMA_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
-#define CX18_DEBUG_HI_IOCTL_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
-#define CX18_DEBUG_HI_FILE_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
-#define CX18_DEBUG_HI_I2C_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
-#define CX18_DEBUG_HI_IRQ_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
-
-#define CX18_ERR_DEV(dev, fmt, args...) v4l2_err(dev, fmt , ## args)
-#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args)
-#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args)
-
-extern int cx18_debug;
-
-struct cx18_options {
- int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
- int cardtype; /* force card type on load */
- int tuner; /* set tuner on load */
- int radio; /* enable/disable radio */
-};
-
-/* per-mdl bit flags */
-#define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianess swapped */
-
-/* per-stream, s_flags */
-#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
-#define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
-#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
-#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
-#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
-#define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */
-
-/* per-cx18, i_flags */
-#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
-#define CX18_F_I_EOS 4 /* End of encoder stream */
-#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */
-#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
-#define CX18_F_I_INITED 21 /* set after first open */
-#define CX18_F_I_FAILED 22 /* set if first open failed */
-
-/* These are the VBI types as they appear in the embedded VBI private packets. */
-#define CX18_SLICED_TYPE_TELETEXT_B (1)
-#define CX18_SLICED_TYPE_CAPTION_525 (4)
-#define CX18_SLICED_TYPE_WSS_625 (5)
-#define CX18_SLICED_TYPE_VPS (7)
-
-/**
- * list_entry_is_past_end - check if a previous loop cursor is off list end
- * @pos: the type * previously used as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- *
- * Check if the entry's list_head is the head of the list, thus it's not a
- * real entry but was the loop cursor that walked past the end
- */
-#define list_entry_is_past_end(pos, head, member) \
- (&pos->member == (head))
-
-struct cx18_buffer {
- struct list_head list;
- dma_addr_t dma_handle;
- char *buf;
-
- u32 bytesused;
- u32 readpos;
-};
-
-struct cx18_mdl {
- struct list_head list;
- u32 id; /* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */
-
- unsigned int skipped;
- unsigned long m_flags;
-
- struct list_head buf_list;
- struct cx18_buffer *curr_buf; /* current buffer in list for reading */
-
- u32 bytesused;
- u32 readpos;
-};
-
-struct cx18_queue {
- struct list_head list;
- atomic_t depth;
- u32 bytesused;
- spinlock_t lock;
-};
-
-struct cx18_stream; /* forward reference */
-
-struct cx18_dvb {
- struct cx18_stream *stream;
- struct dmx_frontend hw_frontend;
- struct dmx_frontend mem_frontend;
- struct dmxdev dmxdev;
- struct dvb_adapter dvb_adapter;
- struct dvb_demux demux;
- struct dvb_frontend *fe;
- struct dvb_net dvbnet;
- int enabled;
- int feeding;
- struct mutex feedlock;
-};
-
-struct cx18; /* forward reference */
-struct cx18_scb; /* forward reference */
-
-
-#define CX18_MAX_MDL_ACKS 2
-#define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
-/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
-
-#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
-#define CX18_F_EWO_MB_STALE_WHILE_PROC 0x2
-#define CX18_F_EWO_MB_STALE \
- (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
-
-struct cx18_in_work_order {
- struct work_struct work;
- atomic_t pending;
- struct cx18 *cx;
- unsigned long flags;
- int rpu;
- struct cx18_mailbox mb;
- struct cx18_mdl_ack mdl_ack[CX18_MAX_MDL_ACKS];
- char *str;
-};
-
-#define CX18_INVALID_TASK_HANDLE 0xffffffff
-
-struct cx18_stream {
- /* These first five fields are always set, even if the stream
- is not actually created. */
- struct video_device *video_dev; /* NULL when stream not created */
- struct cx18_dvb *dvb; /* DVB / Digital Transport */
- struct cx18 *cx; /* for ease of use */
- const char *name; /* name of the stream */
- int type; /* stream type */
- u32 handle; /* task handle */
- unsigned int mdl_base_idx;
-
- u32 id;
- unsigned long s_flags; /* status flags, see above */
- int dma; /* can be PCI_DMA_TODEVICE,
- PCI_DMA_FROMDEVICE or
- PCI_DMA_NONE */
- wait_queue_head_t waitq;
-
- /* Buffers */
- struct list_head buf_pool; /* buffers not attached to an MDL */
- u32 buffers; /* total buffers owned by this stream */
- u32 buf_size; /* size in bytes of a single buffer */
-
- /* MDL sizes - all stream MDLs are the same size */
- u32 bufs_per_mdl;
- u32 mdl_size; /* total bytes in all buffers in a mdl */
-
- /* MDL Queues */
- struct cx18_queue q_free; /* free - in rotation, not committed */
- struct cx18_queue q_busy; /* busy - in use by firmware */
- struct cx18_queue q_full; /* full - data for user apps */
- struct cx18_queue q_idle; /* idle - not in rotation */
-
- struct work_struct out_work_order;
-
- /* Videobuf for YUV video */
- u32 pixelformat;
- u32 vb_bytes_per_frame;
- struct list_head vb_capture; /* video capture queue */
- spinlock_t vb_lock;
- struct timer_list vb_timeout;
-
- struct videobuf_queue vbuf_q;
- spinlock_t vbuf_q_lock; /* Protect vbuf_q */
- enum v4l2_buf_type vb_type;
-};
-
-struct cx18_videobuf_buffer {
- /* Common video buffer sub-system struct */
- struct videobuf_buffer vb;
- v4l2_std_id tvnorm; /* selected tv norm */
- u32 bytes_used;
-};
-
-struct cx18_open_id {
- struct v4l2_fh fh;
- u32 open_id;
- int type;
- struct cx18 *cx;
-};
-
-static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
-{
- return container_of(fh, struct cx18_open_id, fh);
-}
-
-static inline struct cx18_open_id *file2id(struct file *file)
-{
- return fh2id(file->private_data);
-}
-
-/* forward declaration of struct defined in cx18-cards.h */
-struct cx18_card;
-
-/*
- * A note about "sliced" VBI data as implemented in this driver:
- *
- * Currently we collect the sliced VBI in the form of Ancillary Data
- * packets, inserted by the AV core decoder/digitizer/slicer in the
- * horizontal blanking region of the VBI lines, in "raw" mode as far as
- * the Encoder is concerned. We don't ever tell the Encoder itself
- * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
- *
- * We then process the ancillary data ourselves to send the sliced data
- * to the user application directly or build up MPEG-2 private stream 1
- * packets to splice into (only!) MPEG-2 PS streams for the user app.
- *
- * (That's how ivtv essentially does it.)
- *
- * The Encoder should be able to extract certain sliced VBI data for
- * us and provide it in a separate stream or splice it into any type of
- * MPEG PS or TS stream, but this isn't implemented yet.
- */
-
-/*
- * Number of "raw" VBI samples per horizontal line we tell the Encoder to
- * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
- * It depends on the pixel clock and the horiz rate:
- *
- * (1/Fh)*(2*Fp) = Samples/line
- * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
- *
- * Sliced VBI data is sent as ancillary data during horizontal blanking
- * Raw VBI is sent as active video samples during vertcal blanking
- *
- * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
- * length of 720 pixels @ 4:2:2 sampling. Thus...
- *
- * For systems that use a 15.734 kHz horizontal rate, such as
- * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
- *
- * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
- * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
- *
- * For systems that use a 15.625 kHz horizontal rate, such as
- * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
- *
- * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
- * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
- */
-static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
-static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
-static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
-
-#define CX18_VBI_FRAMES 32
-
-struct vbi_info {
- /* Current state of v4l2 VBI settings for this device */
- struct v4l2_format in;
- struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
- u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
- u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
-
- u32 frame; /* Count of VBI buffers/frames received from Encoder */
-
- /*
- * Vars for creation and insertion of MPEG Private Stream 1 packets
- * of sliced VBI data into an MPEG PS
- */
-
- /* Boolean: create and insert Private Stream 1 packets into the PS */
- int insert_mpeg;
-
- /*
- * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
- * Used in cx18-vbi.c only for collecting sliced data, and as a source
- * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
- * We don't need to save state here, but the array may have been a bit
- * too big (2304 bytes) to alloc from the stack.
- */
- struct v4l2_sliced_vbi_data sliced_data[36];
-
- /*
- * A ring buffer of driver-generated MPEG-2 PS
- * Program Pack/Private Stream 1 packets for sliced VBI data insertion
- * into the MPEG PS stream.
- *
- * In each sliced_mpeg_data[] buffer is:
- * 16 byte MPEG-2 PS Program Pack Header
- * 16 byte MPEG-2 Private Stream 1 PES Header
- * 4 byte magic number: "itv0" or "ITV0"
- * 4 byte first field line mask, if "itv0"
- * 4 byte second field line mask, if "itv0"
- * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
- *
- * Each line in the payload is
- * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
- * 42 bytes of line data
- *
- * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
- * which is the payload size a PVR-350 (CX23415) MPEG decoder will
- * accept for VBI data. So, including the headers, it's a maximum 1584
- * bytes total.
- */
-#define CX18_SLICED_MPEG_DATA_MAXSZ 1584
- /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
-#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8)
- u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
- u32 sliced_mpeg_size[CX18_VBI_FRAMES];
-
- /* Count of Program Pack/Program Stream 1 packets inserted into PS */
- u32 inserted_frame;
-
- /*
- * A dummy driver stream transfer mdl & buffer with a copy of the next
- * sliced_mpeg_data[] buffer for output to userland apps.
- * Only used in cx18-fileops.c, but its state needs to persist at times.
- */
- struct cx18_mdl sliced_mpeg_mdl;
- struct cx18_buffer sliced_mpeg_buf;
-};
-
-/* Per cx23418, per I2C bus private algo callback data */
-struct cx18_i2c_algo_callback_data {
- struct cx18 *cx;
- int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
-};
-
-#define CX18_MAX_MMIO_WR_RETRIES 10
-
-/* Struct to hold info about cx18 cards */
-struct cx18 {
- int instance;
- struct pci_dev *pci_dev;
- struct v4l2_device v4l2_dev;
- struct v4l2_subdev *sd_av; /* A/V decoder/digitizer sub-device */
- struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */
-
- const struct cx18_card *card; /* card information */
- const char *card_name; /* full name of the card */
- const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
- u8 is_50hz;
- u8 is_60hz;
- u8 nof_inputs; /* number of video inputs */
- u8 nof_audio_inputs; /* number of audio inputs */
- u32 v4l2_cap; /* V4L2 capabilities of card */
- u32 hw_flags; /* Hardware description of the board */
- unsigned int free_mdl_idx;
- struct cx18_scb __iomem *scb; /* pointer to SCB */
- struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
- struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
-
- struct cx18_av_state av_state;
-
- /* codec settings */
- struct cx2341x_handler cxhdl;
- u32 filter_mode;
- u32 temporal_strength;
- u32 spatial_strength;
-
- /* dualwatch */
- unsigned long dualwatch_jiffies;
- u32 dualwatch_stereo_mode;
-
- struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
- struct cx18_options options; /* User options */
- int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
- int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
- struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
- struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
- void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
- size_t num_bytes);
-
- unsigned long i_flags; /* global cx18 flags */
- atomic_t ana_capturing; /* count number of active analog capture streams */
- atomic_t tot_capturing; /* total count number of active capture streams */
- int search_pack_header;
-
- int open_id; /* incremented each time an open occurs, used as
- unique ID. Starts at 1, so 0 can be used as
- uninitialized value in the stream->id. */
-
- resource_size_t base_addr;
-
- u8 card_rev;
- void __iomem *enc_mem, *reg_mem;
-
- struct vbi_info vbi;
-
- u64 mpg_data_received;
- u64 vbi_data_inserted;
-
- wait_queue_head_t mb_apu_waitq;
- wait_queue_head_t mb_cpu_waitq;
- wait_queue_head_t cap_w;
- /* when the current DMA is finished this queue is woken up */
- wait_queue_head_t dma_waitq;
-
- u32 sw1_irq_mask;
- u32 sw2_irq_mask;
- u32 hw2_irq_mask;
-
- struct workqueue_struct *in_work_queue;
- char in_workq_name[11]; /* "cx18-NN-in" */
- struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
- char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
-
- /* i2c */
- struct i2c_adapter i2c_adap[2];
- struct i2c_algo_bit_data i2c_algo[2];
- struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
-
- struct IR_i2c_init_data ir_i2c_init_data;
-
- /* gpio */
- u32 gpio_dir;
- u32 gpio_val;
- struct mutex gpio_lock;
- struct v4l2_subdev sd_gpiomux;
- struct v4l2_subdev sd_resetctrl;
-
- /* v4l2 and User settings */
-
- /* codec settings */
- u32 audio_input;
- u32 active_input;
- v4l2_std_id std;
- v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
-
- /* Used for cx18-alsa module loading */
- struct work_struct request_module_wk;
-};
-
-static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct cx18, v4l2_dev);
-}
-
-/* cx18 extensions to be loaded */
-extern int (*cx18_ext_init)(struct cx18 *);
-
-/* Globals */
-extern int cx18_first_minor;
-
-/*==============Prototypes==================*/
-
-/* Return non-zero if a signal is pending */
-int cx18_msleep_timeout(unsigned int msecs, int intr);
-
-/* Read Hauppauge eeprom */
-struct tveeprom; /* forward reference */
-void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
-
-/* First-open initialization: load firmware, etc. */
-int cx18_init_on_first_open(struct cx18 *cx);
-
-/* Test if the current VBI mode is raw (1) or sliced (0) */
-static inline int cx18_raw_vbi(const struct cx18 *cx)
-{
- return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
-}
-
-/* Call the specified callback for all subdevs with a grp_id bit matching the
- * mask in hw (if 0, then match them all). Ignore any errors. */
-#define cx18_call_hw(cx, hw, o, f, args...) \
- do { \
- struct v4l2_subdev *__sd; \
- __v4l2_device_call_subdevs_p(&(cx)->v4l2_dev, __sd, \
- !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
- } while (0)
-
-#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args)
-
-/* Call the specified callback for all subdevs with a grp_id bit matching the
- * mask in hw (if 0, then match them all). If the callback returns an error
- * other than 0 or -ENOIOCTLCMD, then return with that error code. */
-#define cx18_call_hw_err(cx, hw, o, f, args...) \
-({ \
- struct v4l2_subdev *__sd; \
- __v4l2_device_call_subdevs_until_err_p(&(cx)->v4l2_dev, \
- __sd, !(hw) || (__sd->grp_id & (hw)), o, f, \
- ##args); \
-})
-
-#define cx18_call_all_err(cx, o, f, args...) \
- cx18_call_hw_err(cx, 0, o, f , ##args)
-
-#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
deleted file mode 100644
index 3eac59c51231..000000000000
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * cx18 functions for DVB support
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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 "cx18-version.h"
-#include "cx18-dvb.h"
-#include "cx18-io.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-cards.h"
-#include "cx18-gpio.h"
-#include "s5h1409.h"
-#include "mxl5005s.h"
-#include "s5h1411.h"
-#include "tda18271.h"
-#include "zl10353.h"
-
-#include <linux/firmware.h>
-#include "mt352.h"
-#include "mt352_priv.h"
-#include "tuner-xc2028.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define FWFILE "dvb-cx18-mpc718-mt352.fw"
-
-#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
-#define CX18_CLOCK_ENABLE2 0xc71024
-#define CX18_DMUX_CLK_MASK 0x0080
-
-/*
- * CX18_CARD_HVR_1600_ESMT
- * CX18_CARD_HVR_1600_SAMSUNG
- */
-
-static struct mxl5005s_config hauppauge_hvr1600_tuner = {
- .i2c_address = 0xC6 >> 1,
- .if_freq = IF_FREQ_5380000HZ,
- .xtal_freq = CRYSTAL_FREQ_16000000HZ,
- .agc_mode = MXL_SINGLE_AGC,
- .tracking_filter = MXL_TF_C_H,
- .rssi_enable = MXL_RSSI_ENABLE,
- .cap_select = MXL_CAP_SEL_ENABLE,
- .div_out = MXL_DIV_OUT_4,
- .clock_out = MXL_CLOCK_OUT_DISABLE,
- .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
- .top = MXL5005S_TOP_25P2,
- .mod_mode = MXL_DIGITAL_MODE,
- .if_mode = MXL_ZERO_IF,
- .qam_gain = 0x02,
- .AgcMasterByte = 0x00,
-};
-
-static struct s5h1409_config hauppauge_hvr1600_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_ON,
- .qam_if = 44000,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
- .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE
-};
-
-/*
- * CX18_CARD_HVR_1600_S5H1411
- */
-static struct s5h1411_config hcw_s5h1411_config = {
- .output_mode = S5H1411_SERIAL_OUTPUT,
- .gpio = S5H1411_GPIO_OFF,
- .vsb_if = S5H1411_IF_44000,
- .qam_if = S5H1411_IF_4000,
- .inversion = S5H1411_INVERSION_ON,
- .status_mode = S5H1411_DEMODLOCKING,
- .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct tda18271_std_map hauppauge_tda18271_std_map = {
- .atsc_6 = { .if_freq = 5380, .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_tda18271_config = {
- .std_map = &hauppauge_tda18271_std_map,
- .gate = TDA18271_GATE_DIGITAL,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-/*
- * CX18_CARD_LEADTEK_DVR3100H
- */
-/* Information/confirmation of proper config values provided by Terry Wu */
-static struct zl10353_config leadtek_dvr3100h_demod = {
- .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
- .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
- .parallel_ts = 1, /* Not a serial TS */
- .no_tuner = 1, /* XC3028 is not behind the gate */
- .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
-};
-
-/*
- * CX18_CARD_YUAN_MPC718
- */
-/*
- * Due to
- *
- * 1. an absence of information on how to prgram the MT352
- * 2. the Linux mt352 module pushing MT352 initialzation off onto us here
- *
- * We have to use an init sequence that *you* must extract from the Windows
- * driver (yuanrap.sys) and which we load as a firmware.
- *
- * If someone can provide me with a Zarlink MT352 (Intel CE6352?) Design Manual
- * with chip programming details, then I can remove this annoyance.
- */
-static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream,
- const struct firmware **fw)
-{
- struct cx18 *cx = stream->cx;
- const char *fn = FWFILE;
- int ret;
-
- ret = request_firmware(fw, fn, &cx->pci_dev->dev);
- if (ret)
- CX18_ERR("Unable to open firmware file %s\n", fn);
- else {
- size_t sz = (*fw)->size;
- if (sz < 2 || sz > 64 || (sz % 2) != 0) {
- CX18_ERR("Firmware %s has a bad size: %lu bytes\n",
- fn, (unsigned long) sz);
- ret = -EILSEQ;
- release_firmware(*fw);
- *fw = NULL;
- }
- }
-
- if (ret) {
- CX18_ERR("The MPC718 board variant with the MT352 DVB-T"
- "demodualtor will not work without it\n");
- CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware "
- "mpc718' if you need the firmware\n");
- }
- return ret;
-}
-
-static int yuan_mpc718_mt352_init(struct dvb_frontend *fe)
-{
- struct cx18_dvb *dvb = container_of(fe->dvb,
- struct cx18_dvb, dvb_adapter);
- struct cx18_stream *stream = dvb->stream;
- const struct firmware *fw = NULL;
- int ret;
- int i;
- u8 buf[3];
-
- ret = yuan_mpc718_mt352_reqfw(stream, &fw);
- if (ret)
- return ret;
-
- /* Loop through all the register-value pairs in the firmware file */
- for (i = 0; i < fw->size; i += 2) {
- buf[0] = fw->data[i];
- /* Intercept a few registers we want to set ourselves */
- switch (buf[0]) {
- case TRL_NOMINAL_RATE_0:
- /* Set our custom OFDM bandwidth in the case below */
- break;
- case TRL_NOMINAL_RATE_1:
- /* 6 MHz: 64/7 * 6/8 / 20.48 * 2^16 = 0x55b6.db6 */
- /* 7 MHz: 64/7 * 7/8 / 20.48 * 2^16 = 0x6400 */
- /* 8 MHz: 64/7 * 8/8 / 20.48 * 2^16 = 0x7249.249 */
- buf[1] = 0x72;
- buf[2] = 0x49;
- mt352_write(fe, buf, 3);
- break;
- case INPUT_FREQ_0:
- /* Set our custom IF in the case below */
- break;
- case INPUT_FREQ_1:
- /* 4.56 MHz IF: (20.48 - 4.56)/20.48 * 2^14 = 0x31c0 */
- buf[1] = 0x31;
- buf[2] = 0xc0;
- mt352_write(fe, buf, 3);
- break;
- default:
- /* Pass through the register-value pair from the fw */
- buf[1] = fw->data[i+1];
- mt352_write(fe, buf, 2);
- break;
- }
- }
-
- buf[0] = (u8) TUNER_GO;
- buf[1] = 0x01; /* Go */
- mt352_write(fe, buf, 2);
- release_firmware(fw);
- return 0;
-}
-
-static struct mt352_config yuan_mpc718_mt352_demod = {
- .demod_address = 0x1e >> 1,
- .adc_clock = 20480, /* 20.480 MHz */
- .if2 = 4560, /* 4.560 MHz */
- .no_tuner = 1, /* XC3028 is not behind the gate */
- .demod_init = yuan_mpc718_mt352_init,
-};
-
-static struct zl10353_config yuan_mpc718_zl10353_demod = {
- .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
- .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
- .parallel_ts = 1, /* Not a serial TS */
- .no_tuner = 1, /* XC3028 is not behind the gate */
- .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
-};
-
-static struct zl10353_config gotview_dvd3_zl10353_demod = {
- .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
- .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
- .parallel_ts = 1, /* Not a serial TS */
- .no_tuner = 1, /* XC3028 is not behind the gate */
- .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
-};
-
-static int dvb_register(struct cx18_stream *stream);
-
-/* Kernel DVB framework calls this when the feed needs to start.
- * The CX18 framework should enable the transport DMA handling
- * and queue processing.
- */
-static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
- struct cx18 *cx;
- int ret;
- u32 v;
-
- if (!stream)
- return -EINVAL;
-
- cx = stream->cx;
- CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
- feed->pid, feed->index);
-
- mutex_lock(&cx->serialize_lock);
- ret = cx18_init_on_first_open(cx);
- mutex_unlock(&cx->serialize_lock);
- if (ret) {
- CX18_ERR("Failed to initialize firmware starting DVB feed\n");
- return ret;
- }
- ret = -EINVAL;
-
- switch (cx->card->type) {
- case CX18_CARD_HVR_1600_ESMT:
- case CX18_CARD_HVR_1600_SAMSUNG:
- case CX18_CARD_HVR_1600_S5H1411:
- v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
- v |= 0x00400000; /* Serial Mode */
- v |= 0x00002000; /* Data Length - Byte */
- v |= 0x00010000; /* Error - Polarity */
- v |= 0x00020000; /* Error - Passthru */
- v |= 0x000c0000; /* Error - Ignore */
- cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
- break;
-
- case CX18_CARD_LEADTEK_DVR3100H:
- case CX18_CARD_YUAN_MPC718:
- case CX18_CARD_GOTVIEW_PCI_DVD3:
- default:
- /* Assumption - Parallel transport - Signalling
- * undefined or default.
- */
- break;
- }
-
- if (!demux->dmx.frontend)
- return -EINVAL;
-
- mutex_lock(&stream->dvb->feedlock);
- if (stream->dvb->feeding++ == 0) {
- CX18_DEBUG_INFO("Starting Transport DMA\n");
- mutex_lock(&cx->serialize_lock);
- set_bit(CX18_F_S_STREAMING, &stream->s_flags);
- ret = cx18_start_v4l2_encode_stream(stream);
- if (ret < 0) {
- CX18_DEBUG_INFO("Failed to start Transport DMA\n");
- stream->dvb->feeding--;
- if (stream->dvb->feeding == 0)
- clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
- }
- mutex_unlock(&cx->serialize_lock);
- } else
- ret = 0;
- mutex_unlock(&stream->dvb->feedlock);
-
- return ret;
-}
-
-/* Kernel DVB framework calls this when the feed needs to stop. */
-static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
- struct cx18 *cx;
- int ret = -EINVAL;
-
- if (stream) {
- cx = stream->cx;
- CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
- feed->pid, feed->index);
-
- mutex_lock(&stream->dvb->feedlock);
- if (--stream->dvb->feeding == 0) {
- CX18_DEBUG_INFO("Stopping Transport DMA\n");
- mutex_lock(&cx->serialize_lock);
- ret = cx18_stop_v4l2_encode_stream(stream, 0);
- mutex_unlock(&cx->serialize_lock);
- } else
- ret = 0;
- mutex_unlock(&stream->dvb->feedlock);
- }
-
- return ret;
-}
-
-int cx18_dvb_register(struct cx18_stream *stream)
-{
- struct cx18 *cx = stream->cx;
- struct cx18_dvb *dvb = stream->dvb;
- struct dvb_adapter *dvb_adapter;
- struct dvb_demux *dvbdemux;
- struct dmx_demux *dmx;
- int ret;
-
- if (!dvb)
- return -EINVAL;
-
- dvb->enabled = 0;
- dvb->stream = stream;
-
- ret = dvb_register_adapter(&dvb->dvb_adapter,
- CX18_DRIVER_NAME,
- THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
- if (ret < 0)
- goto err_out;
-
- dvb_adapter = &dvb->dvb_adapter;
-
- dvbdemux = &dvb->demux;
-
- dvbdemux->priv = (void *)stream;
-
- dvbdemux->filternum = 256;
- dvbdemux->feednum = 256;
- dvbdemux->start_feed = cx18_dvb_start_feed;
- dvbdemux->stop_feed = cx18_dvb_stop_feed;
- dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
- DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
- ret = dvb_dmx_init(dvbdemux);
- if (ret < 0)
- goto err_dvb_unregister_adapter;
-
- dmx = &dvbdemux->dmx;
-
- dvb->hw_frontend.source = DMX_FRONTEND_0;
- dvb->mem_frontend.source = DMX_MEMORY_FE;
- dvb->dmxdev.filternum = 256;
- dvb->dmxdev.demux = dmx;
-
- ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter);
- if (ret < 0)
- goto err_dvb_dmx_release;
-
- ret = dmx->add_frontend(dmx, &dvb->hw_frontend);
- if (ret < 0)
- goto err_dvb_dmxdev_release;
-
- ret = dmx->add_frontend(dmx, &dvb->mem_frontend);
- if (ret < 0)
- goto err_remove_hw_frontend;
-
- ret = dmx->connect_frontend(dmx, &dvb->hw_frontend);
- if (ret < 0)
- goto err_remove_mem_frontend;
-
- ret = dvb_register(stream);
- if (ret < 0)
- goto err_disconnect_frontend;
-
- dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
-
- CX18_INFO("DVB Frontend registered\n");
- CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
- stream->dvb->dvb_adapter.num, stream->name,
- stream->buffers, stream->buf_size/1024,
- (stream->buf_size * 100 / 1024) % 100);
-
- mutex_init(&dvb->feedlock);
- dvb->enabled = 1;
- return ret;
-
-err_disconnect_frontend:
- dmx->disconnect_frontend(dmx);
-err_remove_mem_frontend:
- dmx->remove_frontend(dmx, &dvb->mem_frontend);
-err_remove_hw_frontend:
- dmx->remove_frontend(dmx, &dvb->hw_frontend);
-err_dvb_dmxdev_release:
- dvb_dmxdev_release(&dvb->dmxdev);
-err_dvb_dmx_release:
- dvb_dmx_release(dvbdemux);
-err_dvb_unregister_adapter:
- dvb_unregister_adapter(dvb_adapter);
-err_out:
- return ret;
-}
-
-void cx18_dvb_unregister(struct cx18_stream *stream)
-{
- struct cx18 *cx = stream->cx;
- struct cx18_dvb *dvb = stream->dvb;
- struct dvb_adapter *dvb_adapter;
- struct dvb_demux *dvbdemux;
- struct dmx_demux *dmx;
-
- CX18_INFO("unregister DVB\n");
-
- if (dvb == NULL || !dvb->enabled)
- return;
-
- dvb_adapter = &dvb->dvb_adapter;
- dvbdemux = &dvb->demux;
- dmx = &dvbdemux->dmx;
-
- dmx->close(dmx);
- dvb_net_release(&dvb->dvbnet);
- dmx->remove_frontend(dmx, &dvb->mem_frontend);
- dmx->remove_frontend(dmx, &dvb->hw_frontend);
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(dvbdemux);
- dvb_unregister_frontend(dvb->fe);
- dvb_frontend_detach(dvb->fe);
- dvb_unregister_adapter(dvb_adapter);
-}
-
-/* All the DVB attach calls go here, this function get's modified
- * for each new card. cx18_dvb_start_feed() will also need changes.
- */
-static int dvb_register(struct cx18_stream *stream)
-{
- struct cx18_dvb *dvb = stream->dvb;
- struct cx18 *cx = stream->cx;
- int ret = 0;
-
- switch (cx->card->type) {
- case CX18_CARD_HVR_1600_ESMT:
- case CX18_CARD_HVR_1600_SAMSUNG:
- dvb->fe = dvb_attach(s5h1409_attach,
- &hauppauge_hvr1600_config,
- &cx->i2c_adap[0]);
- if (dvb->fe != NULL) {
- dvb_attach(mxl5005s_attach, dvb->fe,
- &cx->i2c_adap[0],
- &hauppauge_hvr1600_tuner);
- ret = 0;
- }
- break;
- case CX18_CARD_HVR_1600_S5H1411:
- dvb->fe = dvb_attach(s5h1411_attach,
- &hcw_s5h1411_config,
- &cx->i2c_adap[0]);
- if (dvb->fe != NULL)
- dvb_attach(tda18271_attach, dvb->fe,
- 0x60, &cx->i2c_adap[0],
- &hauppauge_tda18271_config);
- break;
- case CX18_CARD_LEADTEK_DVR3100H:
- dvb->fe = dvb_attach(zl10353_attach,
- &leadtek_dvr3100h_demod,
- &cx->i2c_adap[1]);
- if (dvb->fe != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &cx->i2c_adap[1],
- .i2c_addr = 0xc2 >> 1,
- .ctrl = NULL,
- };
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_ZARLINK456,
- .type = XC2028_AUTO,
- };
-
- fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctrl);
- }
- break;
- case CX18_CARD_YUAN_MPC718:
- /*
- * TODO
- * Apparently, these cards also could instead have a
- * DiBcom demod supported by one of the db7000 drivers
- */
- dvb->fe = dvb_attach(mt352_attach,
- &yuan_mpc718_mt352_demod,
- &cx->i2c_adap[1]);
- if (dvb->fe == NULL)
- dvb->fe = dvb_attach(zl10353_attach,
- &yuan_mpc718_zl10353_demod,
- &cx->i2c_adap[1]);
- if (dvb->fe != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &cx->i2c_adap[1],
- .i2c_addr = 0xc2 >> 1,
- .ctrl = NULL,
- };
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_ZARLINK456,
- .type = XC2028_AUTO,
- };
-
- fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctrl);
- }
- break;
- case CX18_CARD_GOTVIEW_PCI_DVD3:
- dvb->fe = dvb_attach(zl10353_attach,
- &gotview_dvd3_zl10353_demod,
- &cx->i2c_adap[1]);
- if (dvb->fe != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &cx->i2c_adap[1],
- .i2c_addr = 0xc2 >> 1,
- .ctrl = NULL,
- };
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_ZARLINK456,
- .type = XC2028_AUTO,
- };
-
- fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctrl);
- }
- break;
- default:
- /* No Digital Tv Support */
- break;
- }
-
- if (dvb->fe == NULL) {
- CX18_ERR("frontend initialization failed\n");
- return -1;
- }
-
- dvb->fe->callback = cx18_reset_tuner_gpio;
-
- ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
- if (ret < 0) {
- if (dvb->fe->ops.release)
- dvb->fe->ops.release(dvb->fe);
- return ret;
- }
-
- /*
- * The firmware seems to enable the TS DMUX clock
- * under various circumstances. However, since we know we
- * might use it, let's just turn it on ourselves here.
- */
- cx18_write_reg_expect(cx,
- (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK,
- CX18_CLOCK_ENABLE2,
- CX18_DMUX_CLK_MASK,
- (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK);
-
- return ret;
-}
-
-MODULE_FIRMWARE(FWFILE);
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h
deleted file mode 100644
index bf8d8f6f5455..000000000000
--- a/drivers/media/video/cx18/cx18-dvb.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * cx18 functions for DVB support
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * 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 "cx18-driver.h"
-
-int cx18_dvb_register(struct cx18_stream *stream);
-void cx18_dvb_unregister(struct cx18_stream *stream);
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
deleted file mode 100644
index 4bfd865a4106..000000000000
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * cx18 file operation functions
- *
- * Derived from ivtv-fileops.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-fileops.h"
-#include "cx18-i2c.h"
-#include "cx18-queue.h"
-#include "cx18-vbi.h"
-#include "cx18-audio.h"
-#include "cx18-mailbox.h"
-#include "cx18-scb.h"
-#include "cx18-streams.h"
-#include "cx18-controls.h"
-#include "cx18-ioctl.h"
-#include "cx18-cards.h"
-
-/* This function tries to claim the stream for a specific file descriptor.
- If no one else is using this stream then the stream is claimed and
- associated VBI and IDX streams are also automatically claimed.
- Possible error returns: -EBUSY if someone else has claimed
- the stream or 0 on success. */
-int cx18_claim_stream(struct cx18_open_id *id, int type)
-{
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[type];
- struct cx18_stream *s_assoc;
-
- /* Nothing should ever try to directly claim the IDX stream */
- if (type == CX18_ENC_STREAM_TYPE_IDX) {
- CX18_WARN("MPEG Index stream cannot be claimed "
- "directly, but something tried.\n");
- return -EINVAL;
- }
-
- if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
- /* someone already claimed this stream */
- if (s->id == id->open_id) {
- /* yes, this file descriptor did. So that's OK. */
- return 0;
- }
- if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
- /* VBI is handled already internally, now also assign
- the file descriptor to this stream for external
- reading of the stream. */
- s->id = id->open_id;
- CX18_DEBUG_INFO("Start Read VBI\n");
- return 0;
- }
- /* someone else is using this stream already */
- CX18_DEBUG_INFO("Stream %d is busy\n", type);
- return -EBUSY;
- }
- s->id = id->open_id;
-
- /*
- * CX18_ENC_STREAM_TYPE_MPG needs to claim:
- * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
- * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
- * (We don't yet fix up MPEG Index entries for our inserted packets).
- *
- * For all other streams we're done.
- */
- if (type != CX18_ENC_STREAM_TYPE_MPG)
- return 0;
-
- s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
- s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- else if (!cx18_stream_enabled(s_assoc))
- return 0;
-
- set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
-
- /* mark that it is used internally */
- set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
- return 0;
-}
-EXPORT_SYMBOL(cx18_claim_stream);
-
-/* This function releases a previously claimed stream. It will take into
- account associated VBI streams. */
-void cx18_release_stream(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- struct cx18_stream *s_assoc;
-
- s->id = -1;
- if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
- /*
- * The IDX stream is only used internally, and can
- * only be indirectly unclaimed by unclaiming the MPG stream.
- */
- return;
- }
-
- if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
- test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
- /* this stream is still in use internally */
- return;
- }
- if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
- CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
- return;
- }
-
- cx18_flush_queues(s);
-
- /*
- * CX18_ENC_STREAM_TYPE_MPG needs to release the
- * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
- *
- * For all other streams we're done.
- */
- if (s->type != CX18_ENC_STREAM_TYPE_MPG)
- return;
-
- /* Unclaim the associated MPEG Index stream */
- s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
- clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
- cx18_flush_queues(s_assoc);
- }
-
- /* Unclaim the associated VBI stream */
- s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
- if (s_assoc->id == -1) {
- /*
- * The VBI stream is not still claimed by a file
- * descriptor, so completely unclaim it.
- */
- clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
- cx18_flush_queues(s_assoc);
- }
- }
-}
-EXPORT_SYMBOL(cx18_release_stream);
-
-static void cx18_dualwatch(struct cx18 *cx)
-{
- struct v4l2_tuner vt;
- u32 new_stereo_mode;
- const u32 dual = 0x0200;
-
- new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
- memset(&vt, 0, sizeof(vt));
- cx18_call_all(cx, tuner, g_tuner, &vt);
- if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
- (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
- new_stereo_mode = dual;
-
- if (new_stereo_mode == cx->dualwatch_stereo_mode)
- return;
-
- CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
- cx->dualwatch_stereo_mode, new_stereo_mode);
- if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
- CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
-}
-
-
-static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
- int *err)
-{
- struct cx18 *cx = s->cx;
- struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- struct cx18_mdl *mdl;
- DEFINE_WAIT(wait);
-
- *err = 0;
- while (1) {
- if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
- /* Process pending program updates and VBI data */
- if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
- cx->dualwatch_jiffies = jiffies;
- cx18_dualwatch(cx);
- }
- if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
- !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
- while ((mdl = cx18_dequeue(s_vbi,
- &s_vbi->q_full))) {
- /* byteswap and process VBI data */
- cx18_process_vbi_data(cx, mdl,
- s_vbi->type);
- cx18_stream_put_mdl_fw(s_vbi, mdl);
- }
- }
- mdl = &cx->vbi.sliced_mpeg_mdl;
- if (mdl->readpos != mdl->bytesused)
- return mdl;
- }
-
- /* do we have new data? */
- mdl = cx18_dequeue(s, &s->q_full);
- if (mdl) {
- if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
- &mdl->m_flags))
- return mdl;
- if (s->type == CX18_ENC_STREAM_TYPE_MPG)
- /* byteswap MPG data */
- cx18_mdl_swap(mdl);
- else {
- /* byteswap and process VBI data */
- cx18_process_vbi_data(cx, mdl, s->type);
- }
- return mdl;
- }
-
- /* return if end of stream */
- if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- CX18_DEBUG_INFO("EOS %s\n", s->name);
- return NULL;
- }
-
- /* return if file was opened with O_NONBLOCK */
- if (non_block) {
- *err = -EAGAIN;
- return NULL;
- }
-
- /* wait for more data to arrive */
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become available before we were added
- to the waitqueue */
- if (!atomic_read(&s->q_full.depth))
- schedule();
- finish_wait(&s->waitq, &wait);
- if (signal_pending(current)) {
- /* return if a signal was received */
- CX18_DEBUG_INFO("User stopped %s\n", s->name);
- *err = -EINTR;
- return NULL;
- }
- }
-}
-
-static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
-{
- struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
- struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
- int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
-
- buf->buf = cx->vbi.sliced_mpeg_data[idx];
- buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
- buf->readpos = 0;
-
- mdl->curr_buf = NULL;
- mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
- mdl->readpos = 0;
-}
-
-static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
- struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
-{
- struct cx18 *cx = s->cx;
- size_t len = buf->bytesused - buf->readpos;
-
- *stop = false;
- if (len > ucount)
- len = ucount;
- if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
- !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
- /*
- * Try to find a good splice point in the PS, just before
- * an MPEG-2 Program Pack start code, and provide only
- * up to that point to the user, so it's easy to insert VBI data
- * the next time around.
- *
- * This will not work for an MPEG-2 TS and has only been
- * verified by analysis to work for an MPEG-2 PS. Helen Buus
- * pointed out this works for the CX23416 MPEG-2 DVD compatible
- * stream, and research indicates both the MPEG 2 SVCD and DVD
- * stream types use an MPEG-2 PS container.
- */
- /*
- * An MPEG-2 Program Stream (PS) is a series of
- * MPEG-2 Program Packs terminated by an
- * MPEG Program End Code after the last Program Pack.
- * A Program Pack may hold a PS System Header packet and any
- * number of Program Elementary Stream (PES) Packets
- */
- const char *start = buf->buf + buf->readpos;
- const char *p = start + 1;
- const u8 *q;
- u8 ch = cx->search_pack_header ? 0xba : 0xe0;
- int stuffing, i;
-
- while (start + len > p) {
- /* Scan for a 0 to find a potential MPEG-2 start code */
- q = memchr(p, 0, start + len - p);
- if (q == NULL)
- break;
- p = q + 1;
- /*
- * Keep looking if not a
- * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba
- * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
- */
- if ((char *)q + 15 >= buf->buf + buf->bytesused ||
- q[1] != 0 || q[2] != 1 || q[3] != ch)
- continue;
-
- /* If expecting the primary video PES */
- if (!cx->search_pack_header) {
- /* Continue if it couldn't be a PES packet */
- if ((q[6] & 0xc0) != 0x80)
- continue;
- /* Check if a PTS or PTS & DTS follow */
- if (((q[7] & 0xc0) == 0x80 && /* PTS only */
- (q[9] & 0xf0) == 0x20) || /* PTS only */
- ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */
- (q[9] & 0xf0) == 0x30)) { /* DTS follows */
- /* Assume we found the video PES hdr */
- ch = 0xba; /* next want a Program Pack*/
- cx->search_pack_header = 1;
- p = q + 9; /* Skip this video PES hdr */
- }
- continue;
- }
-
- /* We may have found a Program Pack start code */
-
- /* Get the count of stuffing bytes & verify them */
- stuffing = q[13] & 7;
- /* all stuffing bytes must be 0xff */
- for (i = 0; i < stuffing; i++)
- if (q[14 + i] != 0xff)
- break;
- if (i == stuffing && /* right number of stuffing bytes*/
- (q[4] & 0xc4) == 0x44 && /* marker check */
- (q[12] & 3) == 3 && /* marker check */
- q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
- q[15 + stuffing] == 0 &&
- q[16 + stuffing] == 1) {
- /* We declare we actually found a Program Pack*/
- cx->search_pack_header = 0; /* expect vid PES */
- len = (char *)q - start;
- cx18_setup_sliced_vbi_mdl(cx);
- *stop = true;
- break;
- }
- }
- }
- if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
- CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
- len, s->name);
- return -EFAULT;
- }
- buf->readpos += len;
- if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
- buf != &cx->vbi.sliced_mpeg_buf)
- cx->mpg_data_received += len;
- return len;
-}
-
-static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
- struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
-{
- size_t tot_written = 0;
- int rc;
- bool stop = false;
-
- if (mdl->curr_buf == NULL)
- mdl->curr_buf = list_first_entry(&mdl->buf_list,
- struct cx18_buffer, list);
-
- if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
- /*
- * For some reason we've exhausted the buffers, but the MDL
- * object still said some data was unread.
- * Fix that and bail out.
- */
- mdl->readpos = mdl->bytesused;
- return 0;
- }
-
- list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
-
- if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
- continue;
-
- rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
- ucount - tot_written, &stop);
- if (rc < 0)
- return rc;
- mdl->readpos += rc;
- tot_written += rc;
-
- if (stop || /* Forced stopping point for VBI insertion */
- tot_written >= ucount || /* Reader request statisfied */
- mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
- mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
- break;
- }
- return tot_written;
-}
-
-static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
- size_t tot_count, int non_block)
-{
- struct cx18 *cx = s->cx;
- size_t tot_written = 0;
- int single_frame = 0;
-
- if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
- /* shouldn't happen */
- CX18_DEBUG_WARN("Stream %s not initialized before read\n",
- s->name);
- return -EIO;
- }
-
- /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
- frames should arrive one-by-one, so make sure we never output more
- than one VBI frame at a time */
- if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
- single_frame = 1;
-
- for (;;) {
- struct cx18_mdl *mdl;
- int rc;
-
- mdl = cx18_get_mdl(s, non_block, &rc);
- /* if there is no data available... */
- if (mdl == NULL) {
- /* if we got data, then return that regardless */
- if (tot_written)
- break;
- /* EOS condition */
- if (rc == 0) {
- clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
- clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
- cx18_release_stream(s);
- }
- /* set errno */
- return rc;
- }
-
- rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
- tot_count - tot_written);
-
- if (mdl != &cx->vbi.sliced_mpeg_mdl) {
- if (mdl->readpos == mdl->bytesused)
- cx18_stream_put_mdl_fw(s, mdl);
- else
- cx18_push(s, mdl, &s->q_full);
- } else if (mdl->readpos == mdl->bytesused) {
- int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
-
- cx->vbi.sliced_mpeg_size[idx] = 0;
- cx->vbi.inserted_frame++;
- cx->vbi_data_inserted += mdl->bytesused;
- }
- if (rc < 0)
- return rc;
- tot_written += rc;
-
- if (tot_written == tot_count || single_frame)
- break;
- }
- return tot_written;
-}
-
-static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
- size_t count, loff_t *pos, int non_block)
-{
- ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
- struct cx18 *cx = s->cx;
-
- CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
- if (rc > 0)
- pos += rc;
- return rc;
-}
-
-int cx18_start_capture(struct cx18_open_id *id)
-{
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- struct cx18_stream *s_vbi;
- struct cx18_stream *s_idx;
-
- if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
- /* you cannot read from these stream types. */
- return -EPERM;
- }
-
- /* Try to claim this stream. */
- if (cx18_claim_stream(id, s->type))
- return -EBUSY;
-
- /* If capture is already in progress, then we also have to
- do nothing extra. */
- if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
- test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- set_bit(CX18_F_S_APPL_IO, &s->s_flags);
- return 0;
- }
-
- /* Start associated VBI or IDX stream capture if required */
- s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
- /*
- * The VBI and IDX streams should have been claimed
- * automatically, if for internal use, when the MPG stream was
- * claimed. We only need to start these streams capturing.
- */
- if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
- !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
- if (cx18_start_v4l2_encode_stream(s_idx)) {
- CX18_DEBUG_WARN("IDX capture start failed\n");
- clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
- goto start_failed;
- }
- CX18_DEBUG_INFO("IDX capture started\n");
- }
- if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
- !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
- if (cx18_start_v4l2_encode_stream(s_vbi)) {
- CX18_DEBUG_WARN("VBI capture start failed\n");
- clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
- goto start_failed;
- }
- CX18_DEBUG_INFO("VBI insertion started\n");
- }
- }
-
- /* Tell the card to start capturing */
- if (!cx18_start_v4l2_encode_stream(s)) {
- /* We're done */
- set_bit(CX18_F_S_APPL_IO, &s->s_flags);
- /* Resume a possibly paused encoder */
- if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
- cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
- return 0;
- }
-
-start_failed:
- CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
-
- /*
- * The associated VBI and IDX streams for internal use are released
- * automatically when the MPG stream is released. We only need to stop
- * the associated stream.
- */
- if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
- /* Stop the IDX stream which is always for internal use */
- if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
- cx18_stop_v4l2_encode_stream(s_idx, 0);
- clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
- }
- /* Stop the VBI stream, if only running for internal use */
- if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
- !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
- cx18_stop_v4l2_encode_stream(s_vbi, 0);
- clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
- }
- }
- clear_bit(CX18_F_S_STREAMING, &s->s_flags);
- cx18_release_stream(s); /* Also releases associated streams */
- return -EIO;
-}
-
-ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
- loff_t *pos)
-{
- struct cx18_open_id *id = file2id(filp);
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- int rc;
-
- CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
-
- mutex_lock(&cx->serialize_lock);
- rc = cx18_start_capture(id);
- mutex_unlock(&cx->serialize_lock);
- if (rc)
- return rc;
-
- if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
- return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
- filp->f_flags & O_NONBLOCK);
- }
-
- return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
-}
-
-unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
-{
- struct cx18_open_id *id = file2id(filp);
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
-
- /* Start a capture if there is none */
- if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- int rc;
-
- mutex_lock(&cx->serialize_lock);
- rc = cx18_start_capture(id);
- mutex_unlock(&cx->serialize_lock);
- if (rc) {
- CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
- s->name, rc);
- return POLLERR;
- }
- CX18_DEBUG_FILE("Encoder poll started capture\n");
- }
-
- if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
- int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
- if (eof && videobuf_poll == POLLERR)
- return POLLHUP;
- else
- return videobuf_poll;
- }
-
- /* add stream's waitq to the poll list */
- CX18_DEBUG_HI_FILE("Encoder poll\n");
- poll_wait(filp, &s->waitq, wait);
-
- if (atomic_read(&s->q_full.depth))
- return POLLIN | POLLRDNORM;
- if (eof)
- return POLLHUP;
- return 0;
-}
-
-int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
-
- if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
-
- /* Start a capture if there is none */
- if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- int rc;
-
- mutex_lock(&cx->serialize_lock);
- rc = cx18_start_capture(id);
- mutex_unlock(&cx->serialize_lock);
- if (rc) {
- CX18_DEBUG_INFO(
- "Could not start capture for %s (%d)\n",
- s->name, rc);
- return -EINVAL;
- }
- CX18_DEBUG_FILE("Encoder mmap started capture\n");
- }
-
- return videobuf_mmap_mapper(&s->vbuf_q, vma);
- }
-
- return -EINVAL;
-}
-
-void cx18_vb_timeout(unsigned long data)
-{
- struct cx18_stream *s = (struct cx18_stream *)data;
- struct cx18_videobuf_buffer *buf;
- unsigned long flags;
-
- /* Return all of the buffers in error state, so the vbi/vid inode
- * can return from blocking.
- */
- spin_lock_irqsave(&s->vb_lock, flags);
- while (!list_empty(&s->vb_capture)) {
- buf = list_entry(s->vb_capture.next,
- struct cx18_videobuf_buffer, vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- }
- spin_unlock_irqrestore(&s->vb_lock, flags);
-}
-
-void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
-{
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
-
- CX18_DEBUG_IOCTL("close() of %s\n", s->name);
-
- /* 'Unclaim' this stream */
-
- /* Stop capturing */
- if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- CX18_DEBUG_INFO("close stopping capture\n");
- if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
- /* Stop internal use associated VBI and IDX streams */
- if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
- !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
- CX18_DEBUG_INFO("close stopping embedded VBI "
- "capture\n");
- cx18_stop_v4l2_encode_stream(s_vbi, 0);
- }
- if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
- CX18_DEBUG_INFO("close stopping IDX capture\n");
- cx18_stop_v4l2_encode_stream(s_idx, 0);
- }
- }
- if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
- test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
- /* Also used internally, don't stop capturing */
- s->id = -1;
- else
- cx18_stop_v4l2_encode_stream(s, gop_end);
- }
- if (!gop_end) {
- clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
- clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
- cx18_release_stream(s);
- }
-}
-
-int cx18_v4l2_close(struct file *filp)
-{
- struct v4l2_fh *fh = filp->private_data;
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- CX18_DEBUG_IOCTL("close() of %s\n", s->name);
-
- mutex_lock(&cx->serialize_lock);
- /* Stop radio */
- if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
- v4l2_fh_is_singular_file(filp)) {
- /* Closing radio device, return to TV mode */
- cx18_mute(cx);
- /* Mark that the radio is no longer in use */
- clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
- /* Switch tuner to TV */
- cx18_call_all(cx, core, s_std, cx->std);
- /* Select correct audio input (i.e. TV tuner or Line in) */
- cx18_audio_set_io(cx);
- if (atomic_read(&cx->ana_capturing) > 0) {
- /* Undo video mute */
- cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
- (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
- (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
- }
- /* Done! Unmute and continue. */
- cx18_unmute(cx);
- }
-
- v4l2_fh_del(fh);
- v4l2_fh_exit(fh);
-
- /* 'Unclaim' this stream */
- if (s->id == id->open_id)
- cx18_stop_capture(id, 0);
- kfree(id);
- mutex_unlock(&cx->serialize_lock);
- return 0;
-}
-
-static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
-{
- struct cx18 *cx = s->cx;
- struct cx18_open_id *item;
-
- CX18_DEBUG_FILE("open %s\n", s->name);
-
- /* Allocate memory */
- item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
- if (NULL == item) {
- CX18_DEBUG_WARN("nomem on v4l2 open\n");
- return -ENOMEM;
- }
- v4l2_fh_init(&item->fh, s->video_dev);
-
- item->cx = cx;
- item->type = s->type;
-
- item->open_id = cx->open_id++;
- filp->private_data = &item->fh;
- v4l2_fh_add(&item->fh);
-
- if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
- v4l2_fh_is_singular_file(filp)) {
- if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
- if (atomic_read(&cx->ana_capturing) > 0) {
- /* switching to radio while capture is
- in progress is not polite */
- v4l2_fh_del(&item->fh);
- v4l2_fh_exit(&item->fh);
- kfree(item);
- return -EBUSY;
- }
- }
-
- /* Mark that the radio is being used. */
- set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
- /* We have the radio */
- cx18_mute(cx);
- /* Switch tuner to radio */
- cx18_call_all(cx, tuner, s_radio);
- /* Select the correct audio input (i.e. radio tuner) */
- cx18_audio_set_io(cx);
- /* Done! Unmute and continue. */
- cx18_unmute(cx);
- }
- return 0;
-}
-
-int cx18_v4l2_open(struct file *filp)
-{
- int res;
- struct video_device *video_dev = video_devdata(filp);
- struct cx18_stream *s = video_get_drvdata(video_dev);
- struct cx18 *cx = s->cx;
-
- mutex_lock(&cx->serialize_lock);
- if (cx18_init_on_first_open(cx)) {
- CX18_ERR("Failed to initialize on %s\n",
- video_device_node_name(video_dev));
- mutex_unlock(&cx->serialize_lock);
- return -ENXIO;
- }
- res = cx18_serialized_open(s, filp);
- mutex_unlock(&cx->serialize_lock);
- return res;
-}
-
-void cx18_mute(struct cx18 *cx)
-{
- u32 h;
- if (atomic_read(&cx->ana_capturing)) {
- h = cx18_find_handle(cx);
- if (h != CX18_INVALID_TASK_HANDLE)
- cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
- else
- CX18_ERR("Can't find valid task handle for mute\n");
- }
- CX18_DEBUG_INFO("Mute\n");
-}
-
-void cx18_unmute(struct cx18 *cx)
-{
- u32 h;
- if (atomic_read(&cx->ana_capturing)) {
- h = cx18_find_handle(cx);
- if (h != CX18_INVALID_TASK_HANDLE) {
- cx18_msleep_timeout(100, 0);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
- cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
- } else
- CX18_ERR("Can't find valid task handle for unmute\n");
- }
- CX18_DEBUG_INFO("Unmute\n");
-}
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
deleted file mode 100644
index b9e5110ad043..000000000000
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * cx18 file operation functions
- *
- * Derived from ivtv-fileops.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-/* Testing/Debugging */
-int cx18_v4l2_open(struct file *filp);
-ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
- loff_t *pos);
-ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count,
- loff_t *pos);
-int cx18_v4l2_close(struct file *filp);
-unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait);
-int cx18_start_capture(struct cx18_open_id *id);
-void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
-void cx18_mute(struct cx18 *cx);
-void cx18_unmute(struct cx18 *cx);
-int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma);
-void cx18_vb_timeout(unsigned long data);
-
-/* Shared with cx18-alsa module */
-int cx18_claim_stream(struct cx18_open_id *id, int type);
-void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
deleted file mode 100644
index a1c1cec05f98..000000000000
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * cx18 firmware functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-scb.h"
-#include "cx18-irq.h"
-#include "cx18-firmware.h"
-#include "cx18-cards.h"
-#include <linux/firmware.h>
-
-#define CX18_PROC_SOFT_RESET 0xc70010
-#define CX18_DDR_SOFT_RESET 0xc70014
-#define CX18_CLOCK_SELECT1 0xc71000
-#define CX18_CLOCK_SELECT2 0xc71004
-#define CX18_HALF_CLOCK_SELECT1 0xc71008
-#define CX18_HALF_CLOCK_SELECT2 0xc7100C
-#define CX18_CLOCK_POLARITY1 0xc71010
-#define CX18_CLOCK_POLARITY2 0xc71014
-#define CX18_ADD_DELAY_ENABLE1 0xc71018
-#define CX18_ADD_DELAY_ENABLE2 0xc7101C
-#define CX18_CLOCK_ENABLE1 0xc71020
-#define CX18_CLOCK_ENABLE2 0xc71024
-
-#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
-
-#define CX18_FAST_CLOCK_PLL_INT 0xc78000
-#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
-#define CX18_FAST_CLOCK_PLL_POST 0xc78008
-#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C
-#define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010
-
-#define CX18_SLOW_CLOCK_PLL_INT 0xc78014
-#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018
-#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C
-#define CX18_MPEG_CLOCK_PLL_INT 0xc78040
-#define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044
-#define CX18_MPEG_CLOCK_PLL_POST 0xc78048
-#define CX18_PLL_POWER_DOWN 0xc78088
-#define CX18_SW1_INT_STATUS 0xc73104
-#define CX18_SW1_INT_ENABLE_PCI 0xc7311C
-#define CX18_SW2_INT_SET 0xc73140
-#define CX18_SW2_INT_STATUS 0xc73144
-#define CX18_ADEC_CONTROL 0xc78120
-
-#define CX18_DDR_REQUEST_ENABLE 0xc80000
-#define CX18_DDR_CHIP_CONFIG 0xc80004
-#define CX18_DDR_REFRESH 0xc80008
-#define CX18_DDR_TIMING1 0xc8000C
-#define CX18_DDR_TIMING2 0xc80010
-#define CX18_DDR_POWER_REG 0xc8001C
-
-#define CX18_DDR_TUNE_LANE 0xc80048
-#define CX18_DDR_INITIAL_EMRS 0xc80054
-#define CX18_DDR_MB_PER_ROW_7 0xc8009C
-#define CX18_DDR_BASE_63_ADDR 0xc804FC
-
-#define CX18_WMB_CLIENT02 0xc90108
-#define CX18_WMB_CLIENT05 0xc90114
-#define CX18_WMB_CLIENT06 0xc90118
-#define CX18_WMB_CLIENT07 0xc9011C
-#define CX18_WMB_CLIENT08 0xc90120
-#define CX18_WMB_CLIENT09 0xc90124
-#define CX18_WMB_CLIENT10 0xc90128
-#define CX18_WMB_CLIENT11 0xc9012C
-#define CX18_WMB_CLIENT12 0xc90130
-#define CX18_WMB_CLIENT13 0xc90134
-#define CX18_WMB_CLIENT14 0xc90138
-
-#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
-
-#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
-#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
-
-struct cx18_apu_rom_seghdr {
- u32 sync1;
- u32 sync2;
- u32 addr;
- u32 size;
-};
-
-static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
-{
- const struct firmware *fw = NULL;
- int i, j;
- unsigned size;
- u32 __iomem *dst = (u32 __iomem *)mem;
- const u32 *src;
-
- if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
- CX18_ERR("Unable to open firmware %s\n", fn);
- CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
- return -ENOMEM;
- }
-
- src = (const u32 *)fw->data;
-
- for (i = 0; i < fw->size; i += 4096) {
- cx18_setup_page(cx, i);
- for (j = i; j < fw->size && j < i + 4096; j += 4) {
- /* no need for endianness conversion on the ppc */
- cx18_raw_writel(cx, *src, dst);
- if (cx18_raw_readl(cx, dst) != *src) {
- CX18_ERR("Mismatch at offset %x\n", i);
- release_firmware(fw);
- cx18_setup_page(cx, 0);
- return -EIO;
- }
- dst++;
- src++;
- }
- }
- if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
- CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
- size = fw->size;
- release_firmware(fw);
- cx18_setup_page(cx, SCB_OFFSET);
- return size;
-}
-
-static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
- u32 *entry_addr)
-{
- const struct firmware *fw = NULL;
- int i, j;
- unsigned size;
- const u32 *src;
- struct cx18_apu_rom_seghdr seghdr;
- const u8 *vers;
- u32 offset = 0;
- u32 apu_version = 0;
- int sz;
-
- if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
- CX18_ERR("unable to open firmware %s\n", fn);
- CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
- cx18_setup_page(cx, 0);
- return -ENOMEM;
- }
-
- *entry_addr = 0;
- src = (const u32 *)fw->data;
- vers = fw->data + sizeof(seghdr);
- sz = fw->size;
-
- apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
- while (offset + sizeof(seghdr) < fw->size) {
- const u32 *shptr = src + offset / 4;
-
- seghdr.sync1 = le32_to_cpu(shptr[0]);
- seghdr.sync2 = le32_to_cpu(shptr[1]);
- seghdr.addr = le32_to_cpu(shptr[2]);
- seghdr.size = le32_to_cpu(shptr[3]);
-
- offset += sizeof(seghdr);
- if (seghdr.sync1 != APU_ROM_SYNC1 ||
- seghdr.sync2 != APU_ROM_SYNC2) {
- offset += seghdr.size;
- continue;
- }
- CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
- seghdr.addr + seghdr.size - 1);
- if (*entry_addr == 0)
- *entry_addr = seghdr.addr;
- if (offset + seghdr.size > sz)
- break;
- for (i = 0; i < seghdr.size; i += 4096) {
- cx18_setup_page(cx, seghdr.addr + i);
- for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
- /* no need for endianness conversion on the ppc */
- cx18_raw_writel(cx, src[(offset + j) / 4],
- dst + seghdr.addr + j);
- if (cx18_raw_readl(cx, dst + seghdr.addr + j)
- != src[(offset + j) / 4]) {
- CX18_ERR("Mismatch at offset %x\n",
- offset + j);
- release_firmware(fw);
- cx18_setup_page(cx, 0);
- return -EIO;
- }
- }
- }
- offset += seghdr.size;
- }
- if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
- CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
- fn, apu_version, fw->size);
- size = fw->size;
- release_firmware(fw);
- cx18_setup_page(cx, 0);
- return size;
-}
-
-void cx18_halt_firmware(struct cx18 *cx)
-{
- CX18_DEBUG_INFO("Preparing for firmware halt.\n");
- cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
- 0x0000000F, 0x000F000F);
- cx18_write_reg_expect(cx, 0x00020002, CX18_ADEC_CONTROL,
- 0x00000002, 0x00020002);
-}
-
-void cx18_init_power(struct cx18 *cx, int lowpwr)
-{
- /* power-down Spare and AOM PLLs */
- /* power-up fast, slow and mpeg PLLs */
- cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
-
- /* ADEC out of sleep */
- cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL,
- 0x00000000, 0x00020002);
-
- /*
- * The PLL parameters are based on the external crystal frequency that
- * would ideally be:
- *
- * NTSC Color subcarrier freq * 8 =
- * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
- *
- * The accidents of history and rationale that explain from where this
- * combination of magic numbers originate can be found in:
- *
- * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
- * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
- *
- * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
- * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
- *
- * As Mike Bradley has rightly pointed out, it's not the exact crystal
- * frequency that matters, only that all parts of the driver and
- * firmware are using the same value (close to the ideal value).
- *
- * Since I have a strong suspicion that, if the firmware ever assumes a
- * crystal value at all, it will assume 28.636360 MHz, the crystal
- * freq used in calculations in this driver will be:
- *
- * xtal_freq = 28.636360 MHz
- *
- * an error of less than 0.13 ppm which is way, way better than any off
- * the shelf crystal will have for accuracy anyway.
- *
- * Below I aim to run the PLLs' VCOs near 400 MHz to minimze errors.
- *
- * Many thanks to Jeff Campbell and Mike Bradley for their extensive
- * investigation, experimentation, testing, and suggested solutions of
- * of audio/video sync problems with SVideo and CVBS captures.
- */
-
- /* the fast clock is at 200/245 MHz */
- /* 1 * xtal_freq * 0x0d.f7df9b8 / 2 = 200 MHz: 400 MHz pre post-divide*/
- /* 1 * xtal_freq * 0x11.1c71eb8 / 2 = 245 MHz: 490 MHz pre post-divide*/
- cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
- cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
- CX18_FAST_CLOCK_PLL_FRAC);
-
- cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST);
- cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE);
- cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
-
- /* set slow clock to 125/120 MHz */
- /* xtal_freq * 0x0d.1861a20 / 3 = 125 MHz: 375 MHz before post-divide */
- /* xtal_freq * 0x0c.92493f8 / 3 = 120 MHz: 360 MHz before post-divide */
- cx18_write_reg(cx, lowpwr ? 0xD : 0xC, CX18_SLOW_CLOCK_PLL_INT);
- cx18_write_reg(cx, lowpwr ? 0x30C344 : 0x124927F,
- CX18_SLOW_CLOCK_PLL_FRAC);
- cx18_write_reg(cx, 3, CX18_SLOW_CLOCK_PLL_POST);
-
- /* mpeg clock pll 54MHz */
- /* xtal_freq * 0xf.15f17f0 / 8 = 54 MHz: 432 MHz before post-divide */
- cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
- cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
- cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
-
- /* Defaults */
- /* APU = SC or SC/2 = 125/62.5 */
- /* EPU = SC = 125 */
- /* DDR = FC = 180 */
- /* ENC = SC = 125 */
- /* AI1 = SC = 125 */
- /* VIM2 = disabled */
- /* PCI = FC/2 = 90 */
- /* AI2 = disabled */
- /* DEMUX = disabled */
- /* AO = SC/2 = 62.5 */
- /* SER = 54MHz */
- /* VFC = disabled */
- /* USB = disabled */
-
- if (lowpwr) {
- cx18_write_reg_expect(cx, 0xFFFF0020, CX18_CLOCK_SELECT1,
- 0x00000020, 0xFFFFFFFF);
- cx18_write_reg_expect(cx, 0xFFFF0004, CX18_CLOCK_SELECT2,
- 0x00000004, 0xFFFFFFFF);
- } else {
- /* This doesn't explicitly set every clock select */
- cx18_write_reg_expect(cx, 0x00060004, CX18_CLOCK_SELECT1,
- 0x00000004, 0x00060006);
- cx18_write_reg_expect(cx, 0x00060006, CX18_CLOCK_SELECT2,
- 0x00000006, 0x00060006);
- }
-
- cx18_write_reg_expect(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1,
- 0x00000002, 0xFFFFFFFF);
- cx18_write_reg_expect(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2,
- 0x00000104, 0xFFFFFFFF);
- cx18_write_reg_expect(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1,
- 0x00009026, 0xFFFFFFFF);
- cx18_write_reg_expect(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2,
- 0x00003105, 0xFFFFFFFF);
-}
-
-void cx18_init_memory(struct cx18 *cx)
-{
- cx18_msleep_timeout(10, 0);
- cx18_write_reg_expect(cx, 0x00010000, CX18_DDR_SOFT_RESET,
- 0x00000000, 0x00010001);
- cx18_msleep_timeout(10, 0);
-
- cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
-
- cx18_msleep_timeout(10, 0);
-
- cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH);
- cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1);
- cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2);
-
- cx18_msleep_timeout(10, 0);
-
- /* Initialize DQS pad time */
- cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
- cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
-
- cx18_msleep_timeout(10, 0);
-
- cx18_write_reg_expect(cx, 0x00020000, CX18_DDR_SOFT_RESET,
- 0x00000000, 0x00020002);
- cx18_msleep_timeout(10, 0);
-
- /* use power-down mode when idle */
- cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
-
- cx18_write_reg_expect(cx, 0x00010001, CX18_REG_BUS_TIMEOUT_EN,
- 0x00000001, 0x00010001);
-
- cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
- cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
-
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */
-}
-
-#define CX18_CPU_FIRMWARE "v4l-cx23418-cpu.fw"
-#define CX18_APU_FIRMWARE "v4l-cx23418-apu.fw"
-
-int cx18_firmware_init(struct cx18 *cx)
-{
- u32 fw_entry_addr;
- int sz, retries;
- u32 api_args[MAX_MB_ARGUMENTS];
-
- /* Allow chip to control CLKRUN */
- cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
-
- /* Stop the firmware */
- cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
- 0x0000000F, 0x000F000F);
-
- cx18_msleep_timeout(1, 0);
-
- /* If the CPU is still running */
- if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) {
- CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__);
- return -EIO;
- }
-
- cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
- cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
-
- sz = load_cpu_fw_direct(CX18_CPU_FIRMWARE, cx->enc_mem, cx);
- if (sz <= 0)
- return sz;
-
- /* The SCB & IPC area *must* be correct before starting the firmwares */
- cx18_init_scb(cx);
-
- fw_entry_addr = 0;
- sz = load_apu_fw_direct(CX18_APU_FIRMWARE, cx->enc_mem, cx,
- &fw_entry_addr);
- if (sz <= 0)
- return sz;
-
- /* Start the CPU. The CPU will take care of the APU for us. */
- cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET,
- 0x00000000, 0x00080008);
-
- /* Wait up to 500 ms for the APU to come out of reset */
- for (retries = 0;
- retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1;
- retries++)
- cx18_msleep_timeout(10, 0);
-
- cx18_msleep_timeout(200, 0);
-
- if (retries == 50 &&
- (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) {
- CX18_ERR("Could not start the CPU\n");
- return -EIO;
- }
-
- /*
- * The CPU had once before set up to receive an interrupt for it's
- * outgoing IRQ_CPU_TO_EPU_ACK to us. If it ever does this, we get an
- * interrupt when it sends us an ack, but by the time we process it,
- * that flag in the SW2 status register has been cleared by the CPU
- * firmware. We'll prevent that not so useful condition from happening
- * by clearing the CPU's interrupt enables for Ack IRQ's we want to
- * process.
- */
- cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
-
- /* Try a benign command to see if the CPU is alive and well */
- sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0);
- if (sz < 0)
- return sz;
-
- /* initialize GPIO */
- cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
- return 0;
-}
-
-MODULE_FIRMWARE(CX18_CPU_FIRMWARE);
-MODULE_FIRMWARE(CX18_APU_FIRMWARE);
diff --git a/drivers/media/video/cx18/cx18-firmware.h b/drivers/media/video/cx18/cx18-firmware.h
deleted file mode 100644
index 38d4c05e8499..000000000000
--- a/drivers/media/video/cx18/cx18-firmware.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * cx18 firmware functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int cx18_firmware_init(struct cx18 *cx);
-void cx18_halt_firmware(struct cx18 *cx);
-void cx18_init_memory(struct cx18 *cx);
-void cx18_init_power(struct cx18 *cx, int lowpwr);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
deleted file mode 100644
index 5374aeb0cd22..000000000000
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * cx18 gpio functions
- *
- * Derived from ivtv-gpio.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-cards.h"
-#include "cx18-gpio.h"
-#include "tuner-xc2028.h"
-
-/********************* GPIO stuffs *********************/
-
-/* GPIO registers */
-#define CX18_REG_GPIO_IN 0xc72010
-#define CX18_REG_GPIO_OUT1 0xc78100
-#define CX18_REG_GPIO_DIR1 0xc78108
-#define CX18_REG_GPIO_OUT2 0xc78104
-#define CX18_REG_GPIO_DIR2 0xc7810c
-
-/*
- * HVR-1600 GPIO pins, courtesy of Hauppauge:
- *
- * gpio0: zilog ir process reset pin
- * gpio1: zilog programming pin (you should never use this)
- * gpio12: cx24227 reset pin
- * gpio13: cs5345 reset pin
-*/
-
-/*
- * File scope utility functions
- */
-static void gpio_write(struct cx18 *cx)
-{
- u32 dir_lo = cx->gpio_dir & 0xffff;
- u32 val_lo = cx->gpio_val & 0xffff;
- u32 dir_hi = cx->gpio_dir >> 16;
- u32 val_hi = cx->gpio_val >> 16;
-
- cx18_write_reg_expect(cx, dir_lo << 16,
- CX18_REG_GPIO_DIR1, ~dir_lo, dir_lo);
- cx18_write_reg_expect(cx, (dir_lo << 16) | val_lo,
- CX18_REG_GPIO_OUT1, val_lo, dir_lo);
- cx18_write_reg_expect(cx, dir_hi << 16,
- CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
- cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
- CX18_REG_GPIO_OUT2, val_hi, dir_hi);
-}
-
-static void gpio_update(struct cx18 *cx, u32 mask, u32 data)
-{
- if (mask == 0)
- return;
-
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
-}
-
-static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi,
- unsigned int assert_msecs,
- unsigned int recovery_msecs)
-{
- u32 mask;
-
- mask = active_lo | active_hi;
- if (mask == 0)
- return;
-
- /*
- * Assuming that active_hi and active_lo are a subsets of the bits in
- * gpio_dir. Also assumes that active_lo and active_hi don't overlap
- * in any bit position
- */
-
- /* Assert */
- gpio_update(cx, mask, ~active_lo);
- schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs));
-
- /* Deassert */
- gpio_update(cx, mask, ~active_hi);
- schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs));
-}
-
-/*
- * GPIO Multiplexer - logical device
- */
-static int gpiomux_log_status(struct v4l2_subdev *sd)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- mutex_lock(&cx->gpio_lock);
- CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
- cx->gpio_dir, cx->gpio_val);
- mutex_unlock(&cx->gpio_lock);
- return 0;
-}
-
-static int gpiomux_s_radio(struct v4l2_subdev *sd)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- /*
- * FIXME - work out the cx->active/audio_input mess - this is
- * intended to handle the switch to radio mode and set the
- * audio routing, but we need to update the state in cx
- */
- gpio_update(cx, cx->card->gpio_audio_input.mask,
- cx->card->gpio_audio_input.radio);
- return 0;
-}
-
-static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- u32 data;
-
- switch (cx->card->audio_inputs[cx->audio_input].muxer_input) {
- case 1:
- data = cx->card->gpio_audio_input.linein;
- break;
- case 0:
- data = cx->card->gpio_audio_input.tuner;
- break;
- default:
- /*
- * FIXME - work out the cx->active/audio_input mess - this is
- * intended to handle the switch from radio mode and set the
- * audio routing, but we need to update the state in cx
- */
- data = cx->card->gpio_audio_input.tuner;
- break;
- }
- gpio_update(cx, cx->card->gpio_audio_input.mask, data);
- return 0;
-}
-
-static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- u32 data;
-
- switch (input) {
- case 0:
- data = cx->card->gpio_audio_input.tuner;
- break;
- case 1:
- data = cx->card->gpio_audio_input.linein;
- break;
- case 2:
- data = cx->card->gpio_audio_input.radio;
- break;
- default:
- return -EINVAL;
- }
- gpio_update(cx, cx->card->gpio_audio_input.mask, data);
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
- .log_status = gpiomux_log_status,
- .s_std = gpiomux_s_std,
-};
-
-static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
- .s_radio = gpiomux_s_radio,
-};
-
-static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
- .s_routing = gpiomux_s_audio_routing,
-};
-
-static const struct v4l2_subdev_ops gpiomux_ops = {
- .core = &gpiomux_core_ops,
- .tuner = &gpiomux_tuner_ops,
- .audio = &gpiomux_audio_ops,
-};
-
-/*
- * GPIO Reset Controller - logical device
- */
-static int resetctrl_log_status(struct v4l2_subdev *sd)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- mutex_lock(&cx->gpio_lock);
- CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
- cx->gpio_dir, cx->gpio_val);
- mutex_unlock(&cx->gpio_lock);
- return 0;
-}
-
-static int resetctrl_reset(struct v4l2_subdev *sd, u32 val)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- const struct cx18_gpio_i2c_slave_reset *p;
-
- p = &cx->card->gpio_i2c_slave_reset;
- switch (val) {
- case CX18_GPIO_RESET_I2C:
- gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask,
- p->msecs_asserted, p->msecs_recovery);
- break;
- case CX18_GPIO_RESET_Z8F0811:
- /*
- * Assert timing for the Z8F0811 on HVR-1600 boards:
- * 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to
- * initiate
- * 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock
- * cycles (6,601,085 nanoseconds ~= 7 milliseconds)
- * 3. DBG pin must be high before chip exits reset for normal
- * operation. DBG is open drain and hopefully pulled high
- * since we don't normally drive it (GPIO 1?) for the
- * HVR-1600
- * 4. Z8F0811 won't exit reset until RESET is deasserted
- * 5. Zilog comes out of reset, loads reset vector address and
- * executes from there. Required recovery delay unknown.
- */
- gpio_reset_seq(cx, p->ir_reset_mask, 0,
- p->msecs_asserted, p->msecs_recovery);
- break;
- case CX18_GPIO_RESET_XC2028:
- if (cx->card->tuners[0].tuner == TUNER_XC2028)
- gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0,
- 1, 1);
- break;
- }
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops resetctrl_core_ops = {
- .log_status = resetctrl_log_status,
- .reset = resetctrl_reset,
-};
-
-static const struct v4l2_subdev_ops resetctrl_ops = {
- .core = &resetctrl_core_ops,
-};
-
-/*
- * External entry points
- */
-void cx18_gpio_init(struct cx18 *cx)
-{
- mutex_lock(&cx->gpio_lock);
- cx->gpio_dir = cx->card->gpio_init.direction;
- cx->gpio_val = cx->card->gpio_init.initial_value;
-
- if (cx->card->tuners[0].tuner == TUNER_XC2028) {
- cx->gpio_dir |= 1 << cx->card->xceive_pin;
- cx->gpio_val |= 1 << cx->card->xceive_pin;
- }
-
- if (cx->gpio_dir == 0) {
- mutex_unlock(&cx->gpio_lock);
- return;
- }
-
- CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
- cx18_read_reg(cx, CX18_REG_GPIO_DIR1),
- cx18_read_reg(cx, CX18_REG_GPIO_DIR2),
- cx18_read_reg(cx, CX18_REG_GPIO_OUT1),
- cx18_read_reg(cx, CX18_REG_GPIO_OUT2));
-
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
-}
-
-int cx18_gpio_register(struct cx18 *cx, u32 hw)
-{
- struct v4l2_subdev *sd;
- const struct v4l2_subdev_ops *ops;
- char *str;
-
- switch (hw) {
- case CX18_HW_GPIO_MUX:
- sd = &cx->sd_gpiomux;
- ops = &gpiomux_ops;
- str = "gpio-mux";
- break;
- case CX18_HW_GPIO_RESET_CTRL:
- sd = &cx->sd_resetctrl;
- ops = &resetctrl_ops;
- str = "gpio-reset-ctrl";
- break;
- default:
- return -EINVAL;
- }
-
- v4l2_subdev_init(sd, ops);
- v4l2_set_subdevdata(sd, cx);
- snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str);
- sd->grp_id = hw;
- return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
-}
-
-void cx18_reset_ir_gpio(void *data)
-{
- struct cx18 *cx = to_cx18((struct v4l2_device *)data);
-
- if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0)
- return;
-
- CX18_DEBUG_INFO("Resetting IR microcontroller\n");
-
- v4l2_subdev_call(&cx->sd_resetctrl,
- core, reset, CX18_GPIO_RESET_Z8F0811);
-}
-EXPORT_SYMBOL(cx18_reset_ir_gpio);
-/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */
-
-/* Xceive tuner reset function */
-int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
-{
- struct i2c_algo_bit_data *algo = dev;
- struct cx18_i2c_algo_callback_data *cb_data = algo->data;
- struct cx18 *cx = cb_data->cx;
-
- if (cmd != XC2028_TUNER_RESET ||
- cx->card->tuners[0].tuner != TUNER_XC2028)
- return 0;
-
- CX18_DEBUG_INFO("Resetting XCeive tuner\n");
- return v4l2_subdev_call(&cx->sd_resetctrl,
- core, reset, CX18_GPIO_RESET_XC2028);
-}
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
deleted file mode 100644
index 4aea2ef88e8d..000000000000
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * cx18 gpio functions
- *
- * Derived from ivtv-gpio.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-void cx18_gpio_init(struct cx18 *cx);
-int cx18_gpio_register(struct cx18 *cx, u32 hw);
-
-enum cx18_gpio_reset_type {
- CX18_GPIO_RESET_I2C = 0,
- CX18_GPIO_RESET_Z8F0811 = 1,
- CX18_GPIO_RESET_XC2028 = 2,
-};
-
-void cx18_reset_ir_gpio(void *data);
-int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
deleted file mode 100644
index 51609d5c88ce..000000000000
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * cx18 I2C functions
- *
- * Derived from ivtv-i2c.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-cards.h"
-#include "cx18-gpio.h"
-#include "cx18-i2c.h"
-#include "cx18-irq.h"
-
-#define CX18_REG_I2C_1_WR 0xf15000
-#define CX18_REG_I2C_1_RD 0xf15008
-#define CX18_REG_I2C_2_WR 0xf25100
-#define CX18_REG_I2C_2_RD 0xf25108
-
-#define SETSCL_BIT 0x0001
-#define SETSDL_BIT 0x0002
-#define GETSCL_BIT 0x0004
-#define GETSDL_BIT 0x0008
-
-#define CX18_CS5345_I2C_ADDR 0x4c
-#define CX18_Z8F0811_IR_TX_I2C_ADDR 0x70
-#define CX18_Z8F0811_IR_RX_I2C_ADDR 0x71
-
-/* This array should match the CX18_HW_ defines */
-static const u8 hw_addrs[] = {
- 0, /* CX18_HW_TUNER */
- 0, /* CX18_HW_TVEEPROM */
- CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */
- 0, /* CX18_HW_DVB */
- 0, /* CX18_HW_418_AV */
- 0, /* CX18_HW_GPIO_MUX */
- 0, /* CX18_HW_GPIO_RESET_CTRL */
- CX18_Z8F0811_IR_TX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_TX_HAUP */
- CX18_Z8F0811_IR_RX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_RX_HAUP */
-};
-
-/* This array should match the CX18_HW_ defines */
-/* This might well become a card-specific array */
-static const u8 hw_bus[] = {
- 1, /* CX18_HW_TUNER */
- 0, /* CX18_HW_TVEEPROM */
- 0, /* CX18_HW_CS5345 */
- 0, /* CX18_HW_DVB */
- 0, /* CX18_HW_418_AV */
- 0, /* CX18_HW_GPIO_MUX */
- 0, /* CX18_HW_GPIO_RESET_CTRL */
- 0, /* CX18_HW_Z8F0811_IR_TX_HAUP */
- 0, /* CX18_HW_Z8F0811_IR_RX_HAUP */
-};
-
-/* This array should match the CX18_HW_ defines */
-static const char * const hw_devicenames[] = {
- "tuner",
- "tveeprom",
- "cs5345",
- "cx23418_DTV",
- "cx23418_AV",
- "gpio_mux",
- "gpio_reset_ctrl",
- "ir_tx_z8f0811_haup",
- "ir_rx_z8f0811_haup",
-};
-
-static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
- const char *type, u8 addr)
-{
- struct i2c_board_info info;
- struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data;
- unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, type, I2C_NAME_SIZE);
-
- /* Our default information for ir-kbd-i2c.c to use */
- switch (hw) {
- case CX18_HW_Z8F0811_IR_RX_HAUP:
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = cx->card_name;
- info.platform_data = init_data;
- break;
- }
-
- return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
- -1 : 0;
-}
-
-int cx18_i2c_register(struct cx18 *cx, unsigned idx)
-{
- struct v4l2_subdev *sd;
- int bus = hw_bus[idx];
- struct i2c_adapter *adap = &cx->i2c_adap[bus];
- const char *type = hw_devicenames[idx];
- u32 hw = 1 << idx;
-
- if (idx >= ARRAY_SIZE(hw_addrs))
- return -1;
-
- if (hw == CX18_HW_TUNER) {
- /* special tuner group handling */
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, type, 0, cx->card_i2c->radio);
- if (sd != NULL)
- sd->grp_id = hw;
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, type, 0, cx->card_i2c->demod);
- if (sd != NULL)
- sd->grp_id = hw;
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, type, 0, cx->card_i2c->tv);
- if (sd != NULL)
- sd->grp_id = hw;
- return sd != NULL ? 0 : -1;
- }
-
- if (hw & CX18_HW_IR_ANY)
- return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
-
- /* Is it not an I2C device or one we do not wish to register? */
- if (!hw_addrs[idx])
- return -1;
-
- /* It's an I2C device other than an analog tuner or IR chip */
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx],
- NULL);
- if (sd != NULL)
- sd->grp_id = hw;
- return sd != NULL ? 0 : -1;
-}
-
-/* Find the first member of the subdev group id in hw */
-struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw)
-{
- struct v4l2_subdev *result = NULL;
- struct v4l2_subdev *sd;
-
- spin_lock(&cx->v4l2_dev.lock);
- v4l2_device_for_each_subdev(sd, &cx->v4l2_dev) {
- if (sd->grp_id == hw) {
- result = sd;
- break;
- }
- }
- spin_unlock(&cx->v4l2_dev.lock);
- return result;
-}
-
-static void cx18_setscl(void *data, int state)
-{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
- u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
- u32 r = cx18_read_reg(cx, addr);
-
- if (state)
- cx18_write_reg(cx, r | SETSCL_BIT, addr);
- else
- cx18_write_reg(cx, r & ~SETSCL_BIT, addr);
-}
-
-static void cx18_setsda(void *data, int state)
-{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
- u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
- u32 r = cx18_read_reg(cx, addr);
-
- if (state)
- cx18_write_reg(cx, r | SETSDL_BIT, addr);
- else
- cx18_write_reg(cx, r & ~SETSDL_BIT, addr);
-}
-
-static int cx18_getscl(void *data)
-{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
- u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
-
- return cx18_read_reg(cx, addr) & GETSCL_BIT;
-}
-
-static int cx18_getsda(void *data)
-{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
- u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
-
- return cx18_read_reg(cx, addr) & GETSDL_BIT;
-}
-
-/* template for i2c-bit-algo */
-static struct i2c_adapter cx18_i2c_adap_template = {
- .name = "cx18 i2c driver",
- .algo = NULL, /* set by i2c-algo-bit */
- .algo_data = NULL, /* filled from template */
- .owner = THIS_MODULE,
-};
-
-#define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */
-#define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */
-
-static struct i2c_algo_bit_data cx18_i2c_algo_template = {
- .setsda = cx18_setsda,
- .setscl = cx18_setscl,
- .getsda = cx18_getsda,
- .getscl = cx18_getscl,
- .udelay = CX18_SCL_PERIOD/2, /* 1/2 clock period in usec*/
- .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
-};
-
-/* init + register i2c adapter */
-int init_cx18_i2c(struct cx18 *cx)
-{
- int i, err;
- CX18_DEBUG_I2C("i2c init\n");
-
- for (i = 0; i < 2; i++) {
- /* Setup algorithm for adapter */
- memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
- sizeof(struct i2c_algo_bit_data));
- cx->i2c_algo_cb_data[i].cx = cx;
- cx->i2c_algo_cb_data[i].bus_index = i;
- cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
-
- /* Setup adapter */
- memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
- sizeof(struct i2c_adapter));
- cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
- sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
- " #%d-%d", cx->instance, i);
- i2c_set_adapdata(&cx->i2c_adap[i], &cx->v4l2_dev);
- cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev;
- }
-
- if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
- /* Reset/Unreset I2C hardware block */
- /* Clock select 220MHz */
- cx18_write_reg_expect(cx, 0x10000000, 0xc71004,
- 0x00000000, 0x10001000);
- /* Clock Enable */
- cx18_write_reg_expect(cx, 0x10001000, 0xc71024,
- 0x00001000, 0x10001000);
- }
- /* courtesy of Steven Toth <stoth@hauppauge.com> */
- cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
- mdelay(10);
- cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0);
- mdelay(10);
- cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
- mdelay(10);
-
- /* Set to edge-triggered intrs. */
- cx18_write_reg(cx, 0x00c00000, 0xc730c8);
- /* Clear any stale intrs */
- cx18_write_reg_expect(cx, HW2_I2C1_INT|HW2_I2C2_INT, HW2_INT_CLR_STATUS,
- ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT);
-
- /* Hw I2C1 Clock Freq ~100kHz */
- cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
- cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
- cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
-
- /* Hw I2C2 Clock Freq ~100kHz */
- cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
- cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
- cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
-
- cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
- core, reset, (u32) CX18_GPIO_RESET_I2C);
-
- err = i2c_bit_add_bus(&cx->i2c_adap[0]);
- if (err)
- goto err;
- err = i2c_bit_add_bus(&cx->i2c_adap[1]);
- if (err)
- goto err_del_bus_0;
- return 0;
-
- err_del_bus_0:
- i2c_del_adapter(&cx->i2c_adap[0]);
- err:
- return err;
-}
-
-void exit_cx18_i2c(struct cx18 *cx)
-{
- int i;
- CX18_DEBUG_I2C("i2c exit\n");
- cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4,
- CX18_REG_I2C_1_WR);
- cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4,
- CX18_REG_I2C_2_WR);
-
- for (i = 0; i < 2; i++) {
- i2c_del_adapter(&cx->i2c_adap[i]);
- }
-}
-
-/*
- Hauppauge HVR1600 should have:
- 32 cx24227
- 98 unknown
- a0 eeprom
- c2 tuner
- e? zilog ir
- */
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h
deleted file mode 100644
index 1180fdc8d983..000000000000
--- a/drivers/media/video/cx18/cx18-i2c.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * cx18 I2C functions
- *
- * Derived from ivtv-i2c.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int cx18_i2c_register(struct cx18 *cx, unsigned idx);
-struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
-
-/* init + register i2c adapter */
-int init_cx18_i2c(struct cx18 *cx);
-void exit_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
deleted file mode 100644
index 49b9dbd06248..000000000000
--- a/drivers/media/video/cx18/cx18-io.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * cx18 driver PCI memory mapped IO access routines
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-irq.h"
-
-void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
-{
- u8 __iomem *dst = addr;
- u16 val2 = val | (val << 8);
- u32 val4 = val2 | (val2 << 16);
-
- /* Align writes on the CX23418's addresses */
- if ((count > 0) && ((unsigned long)dst & 1)) {
- cx18_writeb(cx, (u8) val, dst);
- count--;
- dst++;
- }
- if ((count > 1) && ((unsigned long)dst & 2)) {
- cx18_writew(cx, val2, dst);
- count -= 2;
- dst += 2;
- }
- while (count > 3) {
- cx18_writel(cx, val4, dst);
- count -= 4;
- dst += 4;
- }
- if (count > 1) {
- cx18_writew(cx, val2, dst);
- count -= 2;
- dst += 2;
- }
- if (count > 0)
- cx18_writeb(cx, (u8) val, dst);
-}
-
-void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
-{
- cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val);
- cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | val;
- cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
-}
-
-void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
-{
- cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) & ~val;
- cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
-}
-
-void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
-{
- cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val);
- cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | val;
- cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
-}
-
-void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
-{
- cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) & ~val;
- cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
-}
-
-void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val)
-{
- u32 r;
- r = cx18_read_reg(cx, SW2_INT_ENABLE_CPU);
- cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_CPU);
-}
-
-void cx18_setup_page(struct cx18 *cx, u32 addr)
-{
- u32 val;
- val = cx18_read_reg(cx, 0xD000F8);
- val = (val & ~0x1f00) | ((addr >> 17) & 0x1f00);
- cx18_write_reg(cx, val, 0xD000F8);
-}
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
deleted file mode 100644
index 18974d886cf7..000000000000
--- a/drivers/media/video/cx18/cx18-io.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * cx18 driver PCI memory mapped IO access routines
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX18_IO_H
-#define CX18_IO_H
-
-#include "cx18-driver.h"
-
-/*
- * Readback and retry of MMIO access for reliability:
- * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
- * The implmentation is the fault of Andy Walls <awalls@md.metrocast.net>.
- *
- * *write* functions are implied to retry the mmio unless suffixed with _noretry
- * *read* functions never retry the mmio (it never helps to do so)
- */
-
-/* Non byteswapping memory mapped IO */
-static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
-{
- return __raw_readl(addr);
-}
-
-static inline
-void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
-{
- __raw_writel(val, addr);
-}
-
-static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
-{
- int i;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_raw_writel_noretry(cx, val, addr);
- if (val == cx18_raw_readl(cx, addr))
- break;
- }
-}
-
-/* Normal memory mapped IO */
-static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
-{
- return readl(addr);
-}
-
-static inline
-void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
-{
- writel(val, addr);
-}
-
-static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
-{
- int i;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_writel_noretry(cx, val, addr);
- if (val == cx18_readl(cx, addr))
- break;
- }
-}
-
-static inline
-void cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
- u32 eval, u32 mask)
-{
- int i;
- u32 r;
- eval &= mask;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_writel_noretry(cx, val, addr);
- r = cx18_readl(cx, addr);
- if (r == 0xffffffff && eval != 0xffffffff)
- continue;
- if (eval == (r & mask))
- break;
- }
-}
-
-static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
-{
- return readw(addr);
-}
-
-static inline
-void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr)
-{
- writew(val, addr);
-}
-
-static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
-{
- int i;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_writew_noretry(cx, val, addr);
- if (val == cx18_readw(cx, addr))
- break;
- }
-}
-
-static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
-{
- return readb(addr);
-}
-
-static inline
-void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr)
-{
- writeb(val, addr);
-}
-
-static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
-{
- int i;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_writeb_noretry(cx, val, addr);
- if (val == cx18_readb(cx, addr))
- break;
- }
-}
-
-static inline
-void cx18_memcpy_fromio(struct cx18 *cx, void *to,
- const void __iomem *from, unsigned int len)
-{
- memcpy_fromio(to, from, len);
-}
-
-void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
-
-
-/* Access "register" region of CX23418 memory mapped I/O */
-static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg)
-{
- cx18_writel_noretry(cx, val, cx->reg_mem + reg);
-}
-
-static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
-{
- cx18_writel(cx, val, cx->reg_mem + reg);
-}
-
-static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
- u32 eval, u32 mask)
-{
- cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
-}
-
-static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
-{
- return cx18_readl(cx, cx->reg_mem + reg);
-}
-
-
-/* Access "encoder memory" region of CX23418 memory mapped I/O */
-static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
-{
- cx18_writel(cx, val, cx->enc_mem + addr);
-}
-
-static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
-{
- return cx18_readl(cx, cx->enc_mem + addr);
-}
-
-void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
-void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
-void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
-void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
-void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val);
-void cx18_setup_page(struct cx18 *cx, u32 addr);
-
-#endif /* CX18_IO_H */
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
deleted file mode 100644
index e9912db3b496..000000000000
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ /dev/null
@@ -1,1194 +0,0 @@
-/*
- * cx18 ioctl system call
- *
- * Derived from ivtv-ioctl.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-version.h"
-#include "cx18-mailbox.h"
-#include "cx18-i2c.h"
-#include "cx18-queue.h"
-#include "cx18-fileops.h"
-#include "cx18-vbi.h"
-#include "cx18-audio.h"
-#include "cx18-video.h"
-#include "cx18-streams.h"
-#include "cx18-ioctl.h"
-#include "cx18-gpio.h"
-#include "cx18-controls.h"
-#include "cx18-cards.h"
-#include "cx18-av-core.h"
-#include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
-
-u16 cx18_service2vbi(int type)
-{
- switch (type) {
- case V4L2_SLICED_TELETEXT_B:
- return CX18_SLICED_TYPE_TELETEXT_B;
- case V4L2_SLICED_CAPTION_525:
- return CX18_SLICED_TYPE_CAPTION_525;
- case V4L2_SLICED_WSS_625:
- return CX18_SLICED_TYPE_WSS_625;
- case V4L2_SLICED_VPS:
- return CX18_SLICED_TYPE_VPS;
- default:
- return 0;
- }
-}
-
-/* Check if VBI services are allowed on the (field, line) for the video std */
-static int valid_service_line(int field, int line, int is_pal)
-{
- return (is_pal && line >= 6 &&
- ((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
- (!is_pal && line >= 10 && line < 22);
-}
-
-/*
- * For a (field, line, std) and inbound potential set of services for that line,
- * return the first valid service of those passed in the incoming set for that
- * line in priority order:
- * CC, VPS, or WSS over TELETEXT for well known lines
- * TELETEXT, before VPS, before CC, before WSS, for other lines
- */
-static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
-{
- u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
- int i;
-
- set = set & valid_set;
- if (set == 0 || !valid_service_line(field, line, is_pal))
- return 0;
- if (!is_pal) {
- if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
- return V4L2_SLICED_CAPTION_525;
- } else {
- if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
- return V4L2_SLICED_VPS;
- if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
- return V4L2_SLICED_WSS_625;
- if (line == 23)
- return 0;
- }
- for (i = 0; i < 32; i++) {
- if ((1 << i) & set)
- return 1 << i;
- }
- return 0;
-}
-
-/*
- * Expand the service_set of *fmt into valid service_lines for the std,
- * and clear the passed in fmt->service_set
- */
-void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- u16 set = fmt->service_set;
- int f, l;
-
- fmt->service_set = 0;
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++)
- fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
- }
-}
-
-/*
- * Sanitize the service_lines in *fmt per the video std, and return 1
- * if any service_line is left as valid after santization
- */
-static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- int f, l;
- u16 set = 0;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
- set |= fmt->service_lines[f][l];
- }
- }
- return set != 0;
-}
-
-/* Compute the service_set from the assumed valid service_lines of *fmt */
-u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
-{
- int f, l;
- u16 set = 0;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++)
- set |= fmt->service_lines[f][l];
- }
- return set;
-}
-
-static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- pixfmt->width = cx->cxhdl.width;
- pixfmt->height = cx->cxhdl.height;
- pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
- pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
- if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
- pixfmt->pixelformat = s->pixelformat;
- pixfmt->sizeimage = s->vb_bytes_per_frame;
- pixfmt->bytesperline = 720;
- } else {
- pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
- pixfmt->sizeimage = 128 * 1024;
- pixfmt->bytesperline = 0;
- }
- return 0;
-}
-
-static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
-
- vbifmt->sampling_rate = 27000000;
- vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
- vbifmt->samples_per_line = vbi_active_samples - 4;
- vbifmt->sample_format = V4L2_PIX_FMT_GREY;
- vbifmt->start[0] = cx->vbi.start[0];
- vbifmt->start[1] = cx->vbi.start[1];
- vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
- vbifmt->flags = 0;
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- return 0;
-}
-
-static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
- /* sane, V4L2 spec compliant, defaults */
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
- vbifmt->service_set = 0;
-
- /*
- * Fetch the configured service_lines and total service_set from the
- * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
- * fmt->fmt.sliced under valid calling conditions
- */
- if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
- return -EINVAL;
-
- /* Ensure V4L2 spec compliant output */
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- vbifmt->service_set = cx18_get_service_set(vbifmt);
- return 0;
-}
-
-static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- int w = fmt->fmt.pix.width;
- int h = fmt->fmt.pix.height;
- int min_h = 2;
-
- w = min(w, 720);
- w = max(w, 2);
- if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
- /* YUV height must be a multiple of 32 */
- h &= ~0x1f;
- min_h = 32;
- }
- h = min(h, cx->is_50hz ? 576 : 480);
- h = max(h, min_h);
-
- fmt->fmt.pix.width = w;
- fmt->fmt.pix.height = h;
- return 0;
-}
-
-static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- return cx18_g_fmt_vbi_cap(file, fh, fmt);
-}
-
-static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
-
- /* If given a service set, expand it validly & clear passed in set */
- if (vbifmt->service_set)
- cx18_expand_service_set(vbifmt, cx->is_50hz);
- /* Sanitize the service_lines, and compute the new set if any valid */
- if (check_service_set(vbifmt, cx->is_50hz))
- vbifmt->service_set = cx18_get_service_set(vbifmt);
- return 0;
-}
-
-static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- struct v4l2_mbus_framefmt mbus_fmt;
- struct cx18_stream *s = &cx->streams[id->type];
- int ret;
- int w, h;
-
- ret = cx18_try_fmt_vid_cap(file, fh, fmt);
- if (ret)
- return ret;
- w = fmt->fmt.pix.width;
- h = fmt->fmt.pix.height;
-
- if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
- s->pixelformat == fmt->fmt.pix.pixelformat)
- return 0;
-
- if (atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- s->pixelformat = fmt->fmt.pix.pixelformat;
- /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
- UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
- if (s->pixelformat == V4L2_PIX_FMT_HM12)
- s->vb_bytes_per_frame = h * 720 * 3 / 2;
- else
- s->vb_bytes_per_frame = h * 720 * 2;
-
- mbus_fmt.width = cx->cxhdl.width = w;
- mbus_fmt.height = cx->cxhdl.height = h;
- mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
- v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
- return cx18_g_fmt_vid_cap(file, fh, fmt);
-}
-
-static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- int ret;
-
- /*
- * Changing the Encoder's Raw VBI parameters won't have any effect
- * if any analog capture is ongoing
- */
- if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- /*
- * Set the digitizer registers for raw active VBI.
- * Note cx18_av_vbi_wipes out a lot of the passed in fmt under valid
- * calling conditions
- */
- ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi);
- if (ret)
- return ret;
-
- /* Store our new v4l2 (non-)sliced VBI state */
- cx->vbi.sliced_in->service_set = 0;
- cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
-
- return cx18_g_fmt_vbi_cap(file, fh, fmt);
-}
-
-static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- int ret;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
- cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
-
- /*
- * Changing the Encoder's Raw VBI parameters won't have any effect
- * if any analog capture is ongoing
- */
- if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- /*
- * Set the service_lines requested in the digitizer/slicer registers.
- * Note, cx18_av_vbi() wipes some "impossible" service lines in the
- * passed in fmt->fmt.sliced under valid calling conditions
- */
- ret = v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &fmt->fmt.sliced);
- if (ret)
- return ret;
- /* Store our current v4l2 sliced VBI settings */
- cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
- return 0;
-}
-
-static int cx18_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- int err = 0;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- switch (chip->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- switch (chip->match.addr) {
- case 0:
- chip->ident = V4L2_IDENT_CX23418;
- chip->revision = cx18_read_reg(cx, 0xC72028);
- break;
- case 1:
- /*
- * The A/V decoder is always present, but in the rare
- * case that the card doesn't have analog, we don't
- * use it. We find it w/o using the cx->sd_av pointer
- */
- cx18_call_hw(cx, CX18_HW_418_AV,
- core, g_chip_ident, chip);
- break;
- default:
- /*
- * Could return ident = V4L2_IDENT_UNKNOWN if we had
- * other host chips at higher addresses, but we don't
- */
- err = -EINVAL; /* per V4L2 spec */
- break;
- }
- break;
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
- cx18_call_all(cx, core, g_chip_ident, chip);
- break;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /*
- * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
- * to look if a chip is at the address with no driver. That's a
- * dangerous thing to do with EEPROMs anyway.
- */
- cx18_call_all(cx, core, g_chip_ident, chip);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
-{
- struct v4l2_dbg_register *regs = arg;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
- return -EINVAL;
-
- regs->size = 4;
- if (cmd == VIDIOC_DBG_S_REGISTER)
- cx18_write_enc(cx, regs->val, regs->reg);
- else
- regs->val = cx18_read_enc(cx, regs->reg);
- return 0;
-}
-
-static int cx18_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (v4l2_chip_match_host(&reg->match))
- return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
- /* FIXME - errors shouldn't be ignored */
- cx18_call_all(cx, core, g_register, reg);
- return 0;
-}
-
-static int cx18_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (v4l2_chip_match_host(&reg->match))
- return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
- /* FIXME - errors shouldn't be ignored */
- cx18_call_all(cx, core, s_register, reg);
- return 0;
-}
-#endif
-
-static int cx18_querycap(struct file *file, void *fh,
- struct v4l2_capability *vcap)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
- strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info),
- "PCI:%s", pci_name(cx->pci_dev));
- vcap->capabilities = cx->v4l2_cap; /* capabilities */
- if (id->type == CX18_ENC_STREAM_TYPE_YUV)
- vcap->capabilities |= V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- return cx18_get_audio_input(cx, vin->index, vin);
-}
-
-static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- vin->index = cx->audio_input;
- return cx18_get_audio_input(cx, vin->index, vin);
-}
-
-static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (vout->index >= cx->nof_audio_inputs)
- return -EINVAL;
- cx->audio_input = vout->index;
- cx18_audio_set_io(cx);
- return 0;
-}
-
-static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- /* set it to defaults from our table */
- return cx18_get_input(cx, vin->index, vin);
-}
-
-static int cx18_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *cropcap)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = 720;
- cropcap->bounds.height = cx->is_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
- cropcap->defrect = cropcap->bounds;
- return 0;
-}
-
-static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
- return -EINVAL;
-}
-
-static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
- return -EINVAL;
-}
-
-static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_fmtdesc *fmt)
-{
- static const struct v4l2_fmtdesc formats[] = {
- { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
- "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
- },
- { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
- },
- { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
- "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
- },
- };
-
- if (fmt->index > ARRAY_SIZE(formats) - 1)
- return -EINVAL;
- *fmt = formats[fmt->index];
- return 0;
-}
-
-static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- *i = cx->active_input;
- return 0;
-}
-
-int cx18_s_input(struct file *file, void *fh, unsigned int inp)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if (inp >= cx->nof_inputs)
- return -EINVAL;
-
- if (inp == cx->active_input) {
- CX18_DEBUG_INFO("Input unchanged\n");
- return 0;
- }
-
- CX18_DEBUG_INFO("Changing input from %d to %d\n",
- cx->active_input, inp);
-
- cx->active_input = inp;
- /* Set the audio input to whatever is appropriate for the input type. */
- cx->audio_input = cx->card->video_inputs[inp].audio_index;
-
- /* prevent others from messing with the streams until
- we're finished changing inputs. */
- cx18_mute(cx);
- cx18_video_set_io(cx);
- cx18_audio_set_io(cx);
- cx18_unmute(cx);
- return 0;
-}
-
-static int cx18_g_frequency(struct file *file, void *fh,
- struct v4l2_frequency *vf)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (vf->tuner != 0)
- return -EINVAL;
-
- cx18_call_all(cx, tuner, g_frequency, vf);
- return 0;
-}
-
-int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if (vf->tuner != 0)
- return -EINVAL;
-
- cx18_mute(cx);
- CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
- cx18_call_all(cx, tuner, s_frequency, vf);
- cx18_unmute(cx);
- return 0;
-}
-
-static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- *std = cx->std;
- return 0;
-}
-
-int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if ((*std & V4L2_STD_ALL) == 0)
- return -EINVAL;
-
- if (*std == cx->std)
- return 0;
-
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
- atomic_read(&cx->ana_capturing) > 0) {
- /* Switching standard would turn off the radio or mess
- with already running streams, prevent that by
- returning EBUSY. */
- return -EBUSY;
- }
-
- cx->std = *std;
- cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
- cx->is_50hz = !cx->is_60hz;
- cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
- cx->cxhdl.width = 720;
- cx->cxhdl.height = cx->is_50hz ? 576 : 480;
- cx->vbi.count = cx->is_50hz ? 18 : 12;
- cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
- cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
- CX18_DEBUG_INFO("Switching standard to %llx.\n",
- (unsigned long long) cx->std);
-
- /* Tuner */
- cx18_call_all(cx, core, s_std, cx->std);
- return 0;
-}
-
-static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if (vt->index != 0)
- return -EINVAL;
-
- cx18_call_all(cx, tuner, s_tuner, vt);
- return 0;
-}
-
-static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (vt->index != 0)
- return -EINVAL;
-
- cx18_call_all(cx, tuner, g_tuner, vt);
-
- if (vt->type == V4L2_TUNER_RADIO)
- strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
- else
- strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
- return 0;
-}
-
-static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_sliced_vbi_cap *cap)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
- int f, l;
-
- if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
-
- cap->service_set = 0;
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- if (valid_service_line(f, l, cx->is_50hz)) {
- /*
- * We can find all v4l2 supported vbi services
- * for the standard, on a valid line for the std
- */
- cap->service_lines[f][l] = set;
- cap->service_set |= set;
- } else
- cap->service_lines[f][l] = 0;
- }
- }
- for (f = 0; f < 3; f++)
- cap->reserved[f] = 0;
- return 0;
-}
-
-static int _cx18_process_idx_data(struct cx18_buffer *buf,
- struct v4l2_enc_idx *idx)
-{
- int consumed, remaining;
- struct v4l2_enc_idx_entry *e_idx;
- struct cx18_enc_idx_entry *e_buf;
-
- /* Frame type lookup: 1=I, 2=P, 4=B */
- const int mapping[8] = {
- -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
- -1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
- };
-
- /*
- * Assumption here is that a buf holds an integral number of
- * struct cx18_enc_idx_entry objects and is properly aligned.
- * This is enforced by the module options on IDX buffer sizes.
- */
- remaining = buf->bytesused - buf->readpos;
- consumed = 0;
- e_idx = &idx->entry[idx->entries];
- e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
-
- while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
- idx->entries < V4L2_ENC_IDX_ENTRIES) {
-
- e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
- | le32_to_cpu(e_buf->offset_low);
-
- e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
- | le32_to_cpu(e_buf->pts_low);
-
- e_idx->length = le32_to_cpu(e_buf->length);
-
- e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
-
- e_idx->reserved[0] = 0;
- e_idx->reserved[1] = 0;
-
- idx->entries++;
- e_idx = &idx->entry[idx->entries];
- e_buf++;
-
- remaining -= sizeof(struct cx18_enc_idx_entry);
- consumed += sizeof(struct cx18_enc_idx_entry);
- }
-
- /* Swallow any partial entries at the end, if there are any */
- if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
- consumed += remaining;
-
- buf->readpos += consumed;
- return consumed;
-}
-
-static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct v4l2_enc_idx *idx)
-{
- if (s->type != CX18_ENC_STREAM_TYPE_IDX)
- return -EINVAL;
-
- if (mdl->curr_buf == NULL)
- mdl->curr_buf = list_first_entry(&mdl->buf_list,
- struct cx18_buffer, list);
-
- if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
- /*
- * For some reason we've exhausted the buffers, but the MDL
- * object still said some data was unread.
- * Fix that and bail out.
- */
- mdl->readpos = mdl->bytesused;
- return 0;
- }
-
- list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
-
- /* Skip any empty buffers in the MDL */
- if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
- continue;
-
- mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
-
- /* exit when MDL drained or request satisfied */
- if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
- mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
- mdl->readpos >= mdl->bytesused)
- break;
- }
- return 0;
-}
-
-static int cx18_g_enc_index(struct file *file, void *fh,
- struct v4l2_enc_idx *idx)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- s32 tmp;
- struct cx18_mdl *mdl;
-
- if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
- return -EINVAL;
-
- /* Compute the best case number of entries we can buffer */
- tmp = s->buffers -
- s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
- if (tmp <= 0)
- tmp = 1;
- tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
-
- /* Fill out the header of the return structure */
- idx->entries = 0;
- idx->entries_cap = tmp;
- memset(idx->reserved, 0, sizeof(idx->reserved));
-
- /* Pull IDX MDLs and buffers from q_full and populate the entries */
- do {
- mdl = cx18_dequeue(s, &s->q_full);
- if (mdl == NULL) /* No more IDX data right now */
- break;
-
- /* Extract the Index entry data from the MDL and buffers */
- cx18_process_idx_data(s, mdl, idx);
- if (mdl->readpos < mdl->bytesused) {
- /* We finished with data remaining, push the MDL back */
- cx18_push(s, mdl, &s->q_full);
- break;
- }
-
- /* We drained this MDL, schedule it to go to the firmware */
- cx18_enqueue(s, mdl, &s->q_free);
-
- } while (idx->entries < V4L2_ENC_IDX_ENTRIES);
-
- /* Tell the work handler to send free IDX MDLs to the firmware */
- cx18_stream_load_fw_queue(s);
- return 0;
-}
-
-static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
-{
- struct videobuf_queue *q = NULL;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- switch (s->vb_type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- q = &s->vbuf_q;
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- break;
- default:
- break;
- }
- return q;
-}
-
-static int cx18_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- /* Start the hardware only if we're the video device */
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- if (id->type != CX18_ENC_STREAM_TYPE_YUV)
- return -EINVAL;
-
- /* Establish a buffer timeout */
- mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
-
- return videobuf_streamon(cx18_vb_queue(id));
-}
-
-static int cx18_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- /* Start the hardware only if we're the video device */
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- if (id->type != CX18_ENC_STREAM_TYPE_YUV)
- return -EINVAL;
-
- return videobuf_streamoff(cx18_vb_queue(id));
-}
-
-static int cx18_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- return videobuf_reqbufs(cx18_vb_queue(id), rb);
-}
-
-static int cx18_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- return videobuf_querybuf(cx18_vb_queue(id), b);
-}
-
-static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- return videobuf_qbuf(cx18_vb_queue(id), b);
-}
-
-static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
-}
-
-static int cx18_encoder_cmd(struct file *file, void *fh,
- struct v4l2_encoder_cmd *enc)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- u32 h;
-
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- return cx18_start_capture(id);
-
- case V4L2_ENC_CMD_STOP:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- cx18_stop_capture(id,
- enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
- break;
-
- case V4L2_ENC_CMD_PAUSE:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
- if (!atomic_read(&cx->ana_capturing))
- return -EPERM;
- if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
- return 0;
- h = cx18_find_handle(cx);
- if (h == CX18_INVALID_TASK_HANDLE) {
- CX18_ERR("Can't find valid task handle for "
- "V4L2_ENC_CMD_PAUSE\n");
- return -EBADFD;
- }
- cx18_mute(cx);
- cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
- break;
-
- case V4L2_ENC_CMD_RESUME:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
- if (!atomic_read(&cx->ana_capturing))
- return -EPERM;
- if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
- return 0;
- h = cx18_find_handle(cx);
- if (h == CX18_INVALID_TASK_HANDLE) {
- CX18_ERR("Can't find valid task handle for "
- "V4L2_ENC_CMD_RESUME\n");
- return -EBADFD;
- }
- cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
- cx18_unmute(cx);
- break;
-
- default:
- CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
- return 0;
-}
-
-static int cx18_try_encoder_cmd(struct file *file, void *fh,
- struct v4l2_encoder_cmd *enc)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- break;
-
- case V4L2_ENC_CMD_STOP:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- break;
-
- case V4L2_ENC_CMD_PAUSE:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
- break;
-
- case V4L2_ENC_CMD_RESUME:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
- break;
-
- default:
- CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
- return 0;
-}
-
-static int cx18_log_status(struct file *file, void *fh)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct v4l2_input vidin;
- struct v4l2_audio audin;
- int i;
-
- CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
- if (cx->hw_flags & CX18_HW_TVEEPROM) {
- struct tveeprom tv;
-
- cx18_read_eeprom(cx, &tv);
- }
- cx18_call_all(cx, core, log_status);
- cx18_get_input(cx, cx->active_input, &vidin);
- cx18_get_audio_input(cx, cx->audio_input, &audin);
- CX18_INFO("Video Input: %s\n", vidin.name);
- CX18_INFO("Audio Input: %s\n", audin.name);
- mutex_lock(&cx->gpio_lock);
- CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
- cx->gpio_dir, cx->gpio_val);
- mutex_unlock(&cx->gpio_lock);
- CX18_INFO("Tuner: %s\n",
- test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
- v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
- CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- struct cx18_stream *s = &cx->streams[i];
-
- if (s->video_dev == NULL || s->buffers == 0)
- continue;
- CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
- s->name, s->s_flags,
- atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
- / s->buffers,
- (s->buffers * s->buf_size) / 1024, s->buffers);
- }
- CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
- (long long)cx->mpg_data_received,
- (long long)cx->vbi_data_inserted);
- return 0;
-}
-
-static long cx18_default(struct file *file, void *fh, bool valid_prio,
- int cmd, void *arg)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- switch (cmd) {
- case VIDIOC_INT_RESET: {
- u32 val = *(u32 *)arg;
-
- if ((val == 0) || (val & 0x01))
- cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
- (u32) CX18_GPIO_RESET_Z8F0811);
- break;
- }
-
- default:
- return -ENOTTY;
- }
- return 0;
-}
-
-static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
- .vidioc_querycap = cx18_querycap,
- .vidioc_s_audio = cx18_s_audio,
- .vidioc_g_audio = cx18_g_audio,
- .vidioc_enumaudio = cx18_enumaudio,
- .vidioc_enum_input = cx18_enum_input,
- .vidioc_cropcap = cx18_cropcap,
- .vidioc_s_crop = cx18_s_crop,
- .vidioc_g_crop = cx18_g_crop,
- .vidioc_g_input = cx18_g_input,
- .vidioc_s_input = cx18_s_input,
- .vidioc_g_frequency = cx18_g_frequency,
- .vidioc_s_frequency = cx18_s_frequency,
- .vidioc_s_tuner = cx18_s_tuner,
- .vidioc_g_tuner = cx18_g_tuner,
- .vidioc_g_enc_index = cx18_g_enc_index,
- .vidioc_g_std = cx18_g_std,
- .vidioc_s_std = cx18_s_std,
- .vidioc_log_status = cx18_log_status,
- .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap,
- .vidioc_encoder_cmd = cx18_encoder_cmd,
- .vidioc_try_encoder_cmd = cx18_try_encoder_cmd,
- .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap,
- .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap,
- .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap,
- .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap,
- .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap,
- .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap,
- .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap,
- .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap,
- .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap,
- .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap,
- .vidioc_g_chip_ident = cx18_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx18_g_register,
- .vidioc_s_register = cx18_s_register,
-#endif
- .vidioc_default = cx18_default,
- .vidioc_streamon = cx18_streamon,
- .vidioc_streamoff = cx18_streamoff,
- .vidioc_reqbufs = cx18_reqbufs,
- .vidioc_querybuf = cx18_querybuf,
- .vidioc_qbuf = cx18_qbuf,
- .vidioc_dqbuf = cx18_dqbuf,
-};
-
-void cx18_set_funcs(struct video_device *vdev)
-{
- vdev->ioctl_ops = &cx18_ioctl_ops;
-}
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h
deleted file mode 100644
index 2f9dd591ee0f..000000000000
--- a/drivers/media/video/cx18/cx18-ioctl.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * cx18 ioctl system call
- *
- * Derived from ivtv-ioctl.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-u16 cx18_service2vbi(int type);
-void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
-u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);
-void cx18_set_funcs(struct video_device *vdev);
-int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std);
-int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
-int cx18_s_input(struct file *file, void *fh, unsigned int inp);
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
deleted file mode 100644
index 80edfe93a3d8..000000000000
--- a/drivers/media/video/cx18/cx18-irq.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * cx18 interrupt handling
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-irq.h"
-#include "cx18-mailbox.h"
-#include "cx18-scb.h"
-
-static void xpu_ack(struct cx18 *cx, u32 sw2)
-{
- if (sw2 & IRQ_CPU_TO_EPU_ACK)
- wake_up(&cx->mb_cpu_waitq);
- if (sw2 & IRQ_APU_TO_EPU_ACK)
- wake_up(&cx->mb_apu_waitq);
-}
-
-static void epu_cmd(struct cx18 *cx, u32 sw1)
-{
- if (sw1 & IRQ_CPU_TO_EPU)
- cx18_api_epu_cmd_irq(cx, CPU);
- if (sw1 & IRQ_APU_TO_EPU)
- cx18_api_epu_cmd_irq(cx, APU);
-}
-
-irqreturn_t cx18_irq_handler(int irq, void *dev_id)
-{
- struct cx18 *cx = (struct cx18 *)dev_id;
- u32 sw1, sw2, hw2;
-
- sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & cx->sw1_irq_mask;
- sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & cx->sw2_irq_mask;
- hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & cx->hw2_irq_mask;
-
- if (sw1)
- cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1);
- if (sw2)
- cx18_write_reg_expect(cx, sw2, SW2_INT_STATUS, ~sw2, sw2);
- if (hw2)
- cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2);
-
- if (sw1 || sw2 || hw2)
- CX18_DEBUG_HI_IRQ("received interrupts "
- "SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
-
- /*
- * SW1 responses have to happen first. The sending XPU times out the
- * incoming mailboxes on us rather rapidly.
- */
- if (sw1)
- epu_cmd(cx, sw1);
-
- /* To do: interrupt-based I2C handling
- if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) {
- }
- */
-
- if (sw2)
- xpu_ack(cx, sw2);
-
- return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE;
-}
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h
deleted file mode 100644
index 30e7eaf8cb55..000000000000
--- a/drivers/media/video/cx18/cx18-irq.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * cx18 interrupt handling
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#define HW2_I2C1_INT (1 << 22)
-#define HW2_I2C2_INT (1 << 23)
-#define HW2_INT_CLR_STATUS 0xc730c4
-#define HW2_INT_MASK5_PCI 0xc730e4
-#define SW1_INT_SET 0xc73100
-#define SW1_INT_STATUS 0xc73104
-#define SW1_INT_ENABLE_PCI 0xc7311c
-#define SW2_INT_SET 0xc73140
-#define SW2_INT_STATUS 0xc73144
-#define SW2_INT_ENABLE_CPU 0xc73158
-#define SW2_INT_ENABLE_PCI 0xc7315c
-
-irqreturn_t cx18_irq_handler(int irq, void *dev_id);
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
deleted file mode 100644
index eabf00c6351b..000000000000
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ /dev/null
@@ -1,870 +0,0 @@
-/*
- * cx18 mailbox functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include <stdarg.h>
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-scb.h"
-#include "cx18-irq.h"
-#include "cx18-mailbox.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-alsa-pcm.h" /* FIXME make configurable */
-
-static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" };
-
-#define API_FAST (1 << 2) /* Short timeout */
-#define API_SLOW (1 << 3) /* Additional 300ms timeout */
-
-struct cx18_api_info {
- u32 cmd;
- u8 flags; /* Flags, see above */
- u8 rpu; /* Processing unit */
- const char *name; /* The name of the command */
-};
-
-#define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
-
-static const struct cx18_api_info api_info[] = {
- /* MPEG encoder API */
- API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
- API_ENTRY(CPU, CX18_EPU_DEBUG, 0),
- API_ENTRY(CPU, CX18_CREATE_TASK, 0),
- API_ENTRY(CPU, CX18_DESTROY_TASK, 0),
- API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW),
- API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW),
- API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0),
- API_ENTRY(CPU, CX18_CPU_CAPTURE_RESUME, 0),
- API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_IN, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RATE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RESOLUTION, 0),
- API_ENTRY(CPU, CX18_CPU_SET_FILTER_PARAM, 0),
- API_ENTRY(CPU, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_MEDIAN_CORING, 0),
- API_ENTRY(CPU, CX18_CPU_SET_INDEXTABLE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PARAMETERS, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_MUTE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_AUDIO_MUTE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_MISC_PARAMETERS, 0),
- API_ENTRY(CPU, CX18_CPU_SET_RAW_VBI_PARAM, API_SLOW),
- API_ENTRY(CPU, CX18_CPU_SET_CAPTURE_LINE_NO, 0),
- API_ENTRY(CPU, CX18_CPU_SET_COPYRIGHT, 0),
- API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PID, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_PID, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VER_CROP_LINE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_GOP_STRUCTURE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_SCENE_CHANGE_DETECTION, 0),
- API_ENTRY(CPU, CX18_CPU_SET_ASPECT_RATIO, 0),
- API_ENTRY(CPU, CX18_CPU_SET_SKIP_INPUT_FRAME, 0),
- API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0),
- API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0),
- API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VFC_PARAM, 0),
- API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
- API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
- API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
- API_ENTRY(APU, CX18_APU_START, 0),
- API_ENTRY(APU, CX18_APU_STOP, 0),
- API_ENTRY(APU, CX18_APU_RESETAI, 0),
- API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0),
- API_ENTRY(0, 0, 0),
-};
-
-static const struct cx18_api_info *find_api_info(u32 cmd)
-{
- int i;
-
- for (i = 0; api_info[i].cmd; i++)
- if (api_info[i].cmd == cmd)
- return &api_info[i];
- return NULL;
-}
-
-/* Call with buf of n*11+1 bytes */
-static char *u32arr2hex(u32 data[], int n, char *buf)
-{
- char *p;
- int i;
-
- for (i = 0, p = buf; i < n; i++, p += 11) {
- /* kernel snprintf() appends '\0' always */
- snprintf(p, 12, " %#010x", data[i]);
- }
- *p = '\0';
- return buf;
-}
-
-static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
-{
- char argstr[MAX_MB_ARGUMENTS*11+1];
-
- if (!(cx18_debug & CX18_DBGFLG_API))
- return;
-
- CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s"
- "\n", name, mb->request, mb->ack, mb->cmd, mb->error,
- u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr));
-}
-
-
-/*
- * Functions that run in a work_queue work handling context
- */
-
-static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
-
- if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0)
- return;
-
- /* We ignore mdl and buf readpos accounting here - it doesn't matter */
-
- /* The likely case */
- if (list_is_singular(&mdl->buf_list)) {
- buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
- list);
- if (buf->bytesused)
- dvb_dmx_swfilter(&s->dvb->demux,
- buf->buf, buf->bytesused);
- return;
- }
-
- list_for_each_entry(buf, &mdl->buf_list, list) {
- if (buf->bytesused == 0)
- break;
- dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused);
- }
-}
-
-static void cx18_mdl_send_to_videobuf(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18_videobuf_buffer *vb_buf;
- struct cx18_buffer *buf;
- u8 *p;
- u32 offset = 0;
- int dispatch = 0;
-
- if (mdl->bytesused == 0)
- return;
-
- /* Acquire a videobuf buffer, clone to and and release it */
- spin_lock(&s->vb_lock);
- if (list_empty(&s->vb_capture))
- goto out;
-
- vb_buf = list_first_entry(&s->vb_capture, struct cx18_videobuf_buffer,
- vb.queue);
-
- p = videobuf_to_vmalloc(&vb_buf->vb);
- if (!p)
- goto out;
-
- offset = vb_buf->bytes_used;
- list_for_each_entry(buf, &mdl->buf_list, list) {
- if (buf->bytesused == 0)
- break;
-
- if ((offset + buf->bytesused) <= vb_buf->vb.bsize) {
- memcpy(p + offset, buf->buf, buf->bytesused);
- offset += buf->bytesused;
- vb_buf->bytes_used += buf->bytesused;
- }
- }
-
- /* If we've filled the buffer as per the callers res then dispatch it */
- if (vb_buf->bytes_used >= s->vb_bytes_per_frame) {
- dispatch = 1;
- vb_buf->bytes_used = 0;
- }
-
- if (dispatch) {
- vb_buf->vb.ts = ktime_to_timeval(ktime_get());
- list_del(&vb_buf->vb.queue);
- vb_buf->vb.state = VIDEOBUF_DONE;
- wake_up(&vb_buf->vb.done);
- }
-
- mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
-
-out:
- spin_unlock(&s->vb_lock);
-}
-
-static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
-
- if (mdl->bytesused == 0)
- return;
-
- /* We ignore mdl and buf readpos accounting here - it doesn't matter */
-
- /* The likely case */
- if (list_is_singular(&mdl->buf_list)) {
- buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
- list);
- if (buf->bytesused)
- cx->pcm_announce_callback(cx->alsa, buf->buf,
- buf->bytesused);
- return;
- }
-
- list_for_each_entry(buf, &mdl->buf_list, list) {
- if (buf->bytesused == 0)
- break;
- cx->pcm_announce_callback(cx->alsa, buf->buf, buf->bytesused);
- }
-}
-
-static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- u32 handle, mdl_ack_count, id;
- struct cx18_mailbox *mb;
- struct cx18_mdl_ack *mdl_ack;
- struct cx18_stream *s;
- struct cx18_mdl *mdl;
- int i;
-
- mb = &order->mb;
- handle = mb->args[0];
- s = cx18_handle_to_stream(cx, handle);
-
- if (s == NULL) {
- CX18_WARN("Got DMA done notification for unknown/inactive"
- " handle %d, %s mailbox seq no %d\n", handle,
- (order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) ?
- "stale" : "good", mb->request);
- return;
- }
-
- mdl_ack_count = mb->args[2];
- mdl_ack = order->mdl_ack;
- for (i = 0; i < mdl_ack_count; i++, mdl_ack++) {
- id = mdl_ack->id;
- /*
- * Simple integrity check for processing a stale (and possibly
- * inconsistent mailbox): make sure the MDL id is in the
- * valid range for the stream.
- *
- * We go through the trouble of dealing with stale mailboxes
- * because most of the time, the mailbox data is still valid and
- * unchanged (and in practice the firmware ping-pongs the
- * two mdl_ack buffers so mdl_acks are not stale).
- *
- * There are occasions when we get a half changed mailbox,
- * which this check catches for a handle & id mismatch. If the
- * handle and id do correspond, the worst case is that we
- * completely lost the old MDL, but pick up the new MDL
- * early (but the new mdl_ack is guaranteed to be good in this
- * case as the firmware wouldn't point us to a new mdl_ack until
- * it's filled in).
- *
- * cx18_queue_get_mdl() will detect the lost MDLs
- * and send them back to q_free for fw rotation eventually.
- */
- if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
- !(id >= s->mdl_base_idx &&
- id < (s->mdl_base_idx + s->buffers))) {
- CX18_WARN("Fell behind! Ignoring stale mailbox with "
- " inconsistent data. Lost MDL for mailbox "
- "seq no %d\n", mb->request);
- break;
- }
- mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used);
-
- CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id);
- if (mdl == NULL) {
- CX18_WARN("Could not find MDL %d for stream %s\n",
- id, s->name);
- continue;
- }
-
- CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
- s->name, mdl->bytesused);
-
- if (s->type == CX18_ENC_STREAM_TYPE_TS) {
- cx18_mdl_send_to_dvb(s, mdl);
- cx18_enqueue(s, mdl, &s->q_free);
- } else if (s->type == CX18_ENC_STREAM_TYPE_PCM) {
- /* Pass the data to cx18-alsa */
- if (cx->pcm_announce_callback != NULL) {
- cx18_mdl_send_to_alsa(cx, s, mdl);
- cx18_enqueue(s, mdl, &s->q_free);
- } else {
- cx18_enqueue(s, mdl, &s->q_full);
- }
- } else if (s->type == CX18_ENC_STREAM_TYPE_YUV) {
- cx18_mdl_send_to_videobuf(s, mdl);
- cx18_enqueue(s, mdl, &s->q_free);
- } else {
- cx18_enqueue(s, mdl, &s->q_full);
- if (s->type == CX18_ENC_STREAM_TYPE_IDX)
- cx18_stream_rotate_idx_mdls(cx);
- }
- }
- /* Put as many MDLs as possible back into fw use */
- cx18_stream_load_fw_queue(s);
-
- wake_up(&cx->dma_waitq);
- if (s->id != -1)
- wake_up(&s->waitq);
-}
-
-static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- char *p;
- char *str = order->str;
-
- CX18_DEBUG_INFO("%x %s\n", order->mb.args[0], str);
- p = strchr(str, '.');
- if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str)
- CX18_INFO("FW version: %s\n", p - 1);
-}
-
-static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- switch (order->rpu) {
- case CPU:
- {
- switch (order->mb.cmd) {
- case CX18_EPU_DMA_DONE:
- epu_dma_done(cx, order);
- break;
- case CX18_EPU_DEBUG:
- epu_debug(cx, order);
- break;
- default:
- CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
- order->mb.cmd);
- break;
- }
- break;
- }
- case APU:
- CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
- order->mb.cmd);
- break;
- default:
- break;
- }
-}
-
-static
-void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- atomic_set(&order->pending, 0);
-}
-
-void cx18_in_work_handler(struct work_struct *work)
-{
- struct cx18_in_work_order *order =
- container_of(work, struct cx18_in_work_order, work);
- struct cx18 *cx = order->cx;
- epu_cmd(cx, order);
- free_in_work_order(cx, order);
-}
-
-
-/*
- * Functions that run in an interrupt handling context
- */
-
-static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- struct cx18_mailbox __iomem *ack_mb;
- u32 ack_irq, req;
-
- switch (order->rpu) {
- case APU:
- ack_irq = IRQ_EPU_TO_APU_ACK;
- ack_mb = &cx->scb->apu2epu_mb;
- break;
- case CPU:
- ack_irq = IRQ_EPU_TO_CPU_ACK;
- ack_mb = &cx->scb->cpu2epu_mb;
- break;
- default:
- CX18_WARN("Unhandled RPU (%d) for command %x ack\n",
- order->rpu, order->mb.cmd);
- return;
- }
-
- req = order->mb.request;
- /* Don't ack if the RPU has gotten impatient and timed us out */
- if (req != cx18_readl(cx, &ack_mb->request) ||
- req == cx18_readl(cx, &ack_mb->ack)) {
- CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
- "incoming %s to EPU mailbox (sequence no. %u) "
- "while processing\n",
- rpu_str[order->rpu], rpu_str[order->rpu], req);
- order->flags |= CX18_F_EWO_MB_STALE_WHILE_PROC;
- return;
- }
- cx18_writel(cx, req, &ack_mb->ack);
- cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq);
- return;
-}
-
-static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- u32 handle, mdl_ack_offset, mdl_ack_count;
- struct cx18_mailbox *mb;
- int i;
-
- mb = &order->mb;
- handle = mb->args[0];
- mdl_ack_offset = mb->args[1];
- mdl_ack_count = mb->args[2];
-
- if (handle == CX18_INVALID_TASK_HANDLE ||
- mdl_ack_count == 0 || mdl_ack_count > CX18_MAX_MDL_ACKS) {
- if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
- mb_ack_irq(cx, order);
- return -1;
- }
-
- for (i = 0; i < sizeof(struct cx18_mdl_ack) * mdl_ack_count; i += sizeof(u32))
- ((u32 *)order->mdl_ack)[i / sizeof(u32)] =
- cx18_readl(cx, cx->enc_mem + mdl_ack_offset + i);
-
- if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
- mb_ack_irq(cx, order);
- return 1;
-}
-
-static
-int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- u32 str_offset;
- char *str = order->str;
-
- str[0] = '\0';
- str_offset = order->mb.args[1];
- if (str_offset) {
- cx18_setup_page(cx, str_offset);
- cx18_memcpy_fromio(cx, str, cx->enc_mem + str_offset, 252);
- str[252] = '\0';
- cx18_setup_page(cx, SCB_OFFSET);
- }
-
- if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
- mb_ack_irq(cx, order);
-
- return str_offset ? 1 : 0;
-}
-
-static inline
-int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- int ret = -1;
-
- switch (order->rpu) {
- case CPU:
- {
- switch (order->mb.cmd) {
- case CX18_EPU_DMA_DONE:
- ret = epu_dma_done_irq(cx, order);
- break;
- case CX18_EPU_DEBUG:
- ret = epu_debug_irq(cx, order);
- break;
- default:
- CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
- order->mb.cmd);
- break;
- }
- break;
- }
- case APU:
- CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
- order->mb.cmd);
- break;
- default:
- break;
- }
- return ret;
-}
-
-static inline
-struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx)
-{
- int i;
- struct cx18_in_work_order *order = NULL;
-
- for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
- /*
- * We only need "pending" atomic to inspect its contents,
- * and need not do a check and set because:
- * 1. Any work handler thread only clears "pending" and only
- * on one, particular work order at a time, per handler thread.
- * 2. "pending" is only set here, and we're serialized because
- * we're called in an IRQ handler context.
- */
- if (atomic_read(&cx->in_work_order[i].pending) == 0) {
- order = &cx->in_work_order[i];
- atomic_set(&order->pending, 1);
- break;
- }
- }
- return order;
-}
-
-void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
-{
- struct cx18_mailbox __iomem *mb;
- struct cx18_mailbox *order_mb;
- struct cx18_in_work_order *order;
- int submit;
- int i;
-
- switch (rpu) {
- case CPU:
- mb = &cx->scb->cpu2epu_mb;
- break;
- case APU:
- mb = &cx->scb->apu2epu_mb;
- break;
- default:
- return;
- }
-
- order = alloc_in_work_order_irq(cx);
- if (order == NULL) {
- CX18_WARN("Unable to find blank work order form to schedule "
- "incoming mailbox command processing\n");
- return;
- }
-
- order->flags = 0;
- order->rpu = rpu;
- order_mb = &order->mb;
-
- /* mb->cmd and mb->args[0] through mb->args[2] */
- for (i = 0; i < 4; i++)
- (&order_mb->cmd)[i] = cx18_readl(cx, &mb->cmd + i);
-
- /* mb->request and mb->ack. N.B. we want to read mb->ack last */
- for (i = 0; i < 2; i++)
- (&order_mb->request)[i] = cx18_readl(cx, &mb->request + i);
-
- if (order_mb->request == order_mb->ack) {
- CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
- "incoming %s to EPU mailbox (sequence no. %u)"
- "\n",
- rpu_str[rpu], rpu_str[rpu], order_mb->request);
- if (cx18_debug & CX18_DBGFLG_WARN)
- dump_mb(cx, order_mb, "incoming");
- order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
- }
-
- /*
- * Individual EPU command processing is responsible for ack-ing
- * a non-stale mailbox as soon as possible
- */
- submit = epu_cmd_irq(cx, order);
- if (submit > 0) {
- queue_work(cx->in_work_queue, &order->work);
- }
-}
-
-
-/*
- * Functions called from a non-interrupt, non work_queue context
- */
-
-static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
-{
- const struct cx18_api_info *info = find_api_info(cmd);
- u32 irq, req, ack, err;
- struct cx18_mailbox __iomem *mb;
- wait_queue_head_t *waitq;
- struct mutex *mb_lock;
- unsigned long int t0, timeout, ret;
- int i;
- char argstr[MAX_MB_ARGUMENTS*11+1];
- DEFINE_WAIT(w);
-
- if (info == NULL) {
- CX18_WARN("unknown cmd %x\n", cmd);
- return -EINVAL;
- }
-
- if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */
- if (cmd == CX18_CPU_DE_SET_MDL) {
- if (cx18_debug & CX18_DBGFLG_HIGHVOL)
- CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n",
- info->name, cmd,
- u32arr2hex(data, args, argstr));
- } else
- CX18_DEBUG_API("%s\tcmd %#010x args%s\n",
- info->name, cmd,
- u32arr2hex(data, args, argstr));
- }
-
- switch (info->rpu) {
- case APU:
- waitq = &cx->mb_apu_waitq;
- mb_lock = &cx->epu2apu_mb_lock;
- irq = IRQ_EPU_TO_APU;
- mb = &cx->scb->epu2apu_mb;
- break;
- case CPU:
- waitq = &cx->mb_cpu_waitq;
- mb_lock = &cx->epu2cpu_mb_lock;
- irq = IRQ_EPU_TO_CPU;
- mb = &cx->scb->epu2cpu_mb;
- break;
- default:
- CX18_WARN("Unknown RPU (%d) for API call\n", info->rpu);
- return -EINVAL;
- }
-
- mutex_lock(mb_lock);
- /*
- * Wait for an in-use mailbox to complete
- *
- * If the XPU is responding with Ack's, the mailbox shouldn't be in
- * a busy state, since we serialize access to it on our end.
- *
- * If the wait for ack after sending a previous command was interrupted
- * by a signal, we may get here and find a busy mailbox. After waiting,
- * mark it "not busy" from our end, if the XPU hasn't ack'ed it still.
- */
- req = cx18_readl(cx, &mb->request);
- timeout = msecs_to_jiffies(10);
- ret = wait_event_timeout(*waitq,
- (ack = cx18_readl(cx, &mb->ack)) == req,
- timeout);
- if (req != ack) {
- /* waited long enough, make the mbox "not busy" from our end */
- cx18_writel(cx, req, &mb->ack);
- CX18_ERR("mbox was found stuck busy when setting up for %s; "
- "clearing busy and trying to proceed\n", info->name);
- } else if (ret != timeout)
- CX18_DEBUG_API("waited %u msecs for busy mbox to be acked\n",
- jiffies_to_msecs(timeout-ret));
-
- /* Build the outgoing mailbox */
- req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1;
-
- cx18_writel(cx, cmd, &mb->cmd);
- for (i = 0; i < args; i++)
- cx18_writel(cx, data[i], &mb->args[i]);
- cx18_writel(cx, 0, &mb->error);
- cx18_writel(cx, req, &mb->request);
- cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */
-
- /*
- * Notify the XPU and wait for it to send an Ack back
- */
- timeout = msecs_to_jiffies((info->flags & API_FAST) ? 10 : 20);
-
- CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
- irq, info->name);
-
- /* So we don't miss the wakeup, prepare to wait before notifying fw */
- prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
- cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
-
- t0 = jiffies;
- ack = cx18_readl(cx, &mb->ack);
- if (ack != req) {
- schedule_timeout(timeout);
- ret = jiffies - t0;
- ack = cx18_readl(cx, &mb->ack);
- } else {
- ret = jiffies - t0;
- }
-
- finish_wait(waitq, &w);
-
- if (req != ack) {
- mutex_unlock(mb_lock);
- if (ret >= timeout) {
- /* Timed out */
- CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
- "for RPU acknowledgement\n",
- info->name, jiffies_to_msecs(ret));
- } else {
- CX18_DEBUG_WARN("woken up before mailbox ack was ready "
- "after submitting %s to RPU. only "
- "waited %d msecs on req %u but awakened"
- " with unmatched ack %u\n",
- info->name,
- jiffies_to_msecs(ret),
- req, ack);
- }
- return -EINVAL;
- }
-
- if (ret >= timeout)
- CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
- "sending %s; timed out waiting %d msecs\n",
- info->name, jiffies_to_msecs(ret));
- else
- CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
- jiffies_to_msecs(ret), info->name);
-
- /* Collect data returned by the XPU */
- for (i = 0; i < MAX_MB_ARGUMENTS; i++)
- data[i] = cx18_readl(cx, &mb->args[i]);
- err = cx18_readl(cx, &mb->error);
- mutex_unlock(mb_lock);
-
- /*
- * Wait for XPU to perform extra actions for the caller in some cases.
- * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
- * back in a burst shortly thereafter
- */
- if (info->flags & API_SLOW)
- cx18_msleep_timeout(300, 0);
-
- if (err)
- CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
- info->name);
- return err ? -EIO : 0;
-}
-
-int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[])
-{
- return cx18_api_call(cx, cmd, args, data);
-}
-
-static int cx18_set_filter_param(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- u32 mode;
- int ret;
-
- mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0);
- ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
- s->handle, 1, mode, cx->spatial_strength);
- mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0);
- ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
- s->handle, 0, mode, cx->temporal_strength);
- ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
- s->handle, 2, cx->filter_mode >> 2, 0);
- return ret;
-}
-
-int cx18_api_func(void *priv, u32 cmd, int in, int out,
- u32 data[CX2341X_MBOX_MAX_DATA])
-{
- struct cx18_stream *s = priv;
- struct cx18 *cx = s->cx;
-
- switch (cmd) {
- case CX2341X_ENC_SET_OUTPUT_PORT:
- return 0;
- case CX2341X_ENC_SET_FRAME_RATE:
- return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6,
- s->handle, 0, 0, 0, 0, data[0]);
- case CX2341X_ENC_SET_FRAME_SIZE:
- return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3,
- s->handle, data[1], data[0]);
- case CX2341X_ENC_SET_STREAM_TYPE:
- return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2,
- s->handle, data[0]);
- case CX2341X_ENC_SET_ASPECT_RATIO:
- return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2,
- s->handle, data[0]);
-
- case CX2341X_ENC_SET_GOP_PROPERTIES:
- return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3,
- s->handle, data[0], data[1]);
- case CX2341X_ENC_SET_GOP_CLOSURE:
- return 0;
- case CX2341X_ENC_SET_AUDIO_PROPERTIES:
- return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
- s->handle, data[0]);
- case CX2341X_ENC_MUTE_AUDIO:
- return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
- s->handle, data[0]);
- case CX2341X_ENC_SET_BIT_RATE:
- return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5,
- s->handle, data[0], data[1], data[2], data[3]);
- case CX2341X_ENC_MUTE_VIDEO:
- return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
- s->handle, data[0]);
- case CX2341X_ENC_SET_FRAME_DROP_RATE:
- return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2,
- s->handle, data[0]);
- case CX2341X_ENC_MISC:
- return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4,
- s->handle, data[0], data[1], data[2]);
- case CX2341X_ENC_SET_DNR_FILTER_MODE:
- cx->filter_mode = (data[0] & 3) | (data[1] << 2);
- return cx18_set_filter_param(s);
- case CX2341X_ENC_SET_DNR_FILTER_PROPS:
- cx->spatial_strength = data[0];
- cx->temporal_strength = data[1];
- return cx18_set_filter_param(s);
- case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
- return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3,
- s->handle, data[0], data[1]);
- case CX2341X_ENC_SET_CORING_LEVELS:
- return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5,
- s->handle, data[0], data[1], data[2], data[3]);
- }
- CX18_WARN("Unknown cmd %x\n", cmd);
- return 0;
-}
-
-int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS],
- u32 cmd, int args, ...)
-{
- va_list ap;
- int i;
-
- va_start(ap, args);
- for (i = 0; i < args; i++)
- data[i] = va_arg(ap, u32);
- va_end(ap);
- return cx18_api(cx, cmd, args, data);
-}
-
-int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...)
-{
- u32 data[MAX_MB_ARGUMENTS];
- va_list ap;
- int i;
-
- if (cx == NULL) {
- CX18_ERR("cx == NULL (cmd=%x)\n", cmd);
- return 0;
- }
- if (args > MAX_MB_ARGUMENTS) {
- CX18_ERR("args too big (cmd=%x)\n", cmd);
- args = MAX_MB_ARGUMENTS;
- }
- va_start(ap, args);
- for (i = 0; i < args; i++)
- data[i] = va_arg(ap, u32);
- va_end(ap);
- return cx18_api(cx, cmd, args, data);
-}
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
deleted file mode 100644
index b63fdfaac49e..000000000000
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * cx18 mailbox functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef _CX18_MAILBOX_H_
-#define _CX18_MAILBOX_H_
-
-/* mailbox max args */
-#define MAX_MB_ARGUMENTS 6
-/* compatibility, should be same as the define in cx2341x.h */
-#define CX2341X_MBOX_MAX_DATA 16
-
-#define MB_RESERVED_HANDLE_0 0
-#define MB_RESERVED_HANDLE_1 0xFFFFFFFF
-
-#define APU 0
-#define CPU 1
-#define EPU 2
-#define HPU 3
-
-struct cx18;
-
-/*
- * This structure is used by CPU to provide completed MDL & buffers information.
- * Its structure is dictated by the layout of the SCB, required by the
- * firmware, but its definition needs to be here, instead of in cx18-scb.h,
- * for mailbox work order scheduling
- */
-struct cx18_mdl_ack {
- u32 id; /* ID of a completed MDL */
- u32 data_used; /* Total data filled in the MDL with 'id' */
-};
-
-/* The cx18_mailbox struct is the mailbox structure which is used for passing
- messages between processors */
-struct cx18_mailbox {
- /* The sender sets a handle in 'request' after he fills the command. The
- 'request' should be different than 'ack'. The sender, also, generates
- an interrupt on XPU2YPU_irq where XPU is the sender and YPU is the
- receiver. */
- u32 request;
- /* The receiver detects a new command when 'req' is different than 'ack'.
- He sets 'ack' to the same value as 'req' to clear the command. He, also,
- generates an interrupt on YPU2XPU_irq where XPU is the sender and YPU
- is the receiver. */
- u32 ack;
- u32 reserved[6];
- /* 'cmd' identifies the command. The list of these commands are in
- cx23418.h */
- u32 cmd;
- /* Each command can have up to 6 arguments */
- u32 args[MAX_MB_ARGUMENTS];
- /* The return code can be one of the codes in the file cx23418.h. If the
- command is completed successfully, the error will be ERR_SYS_SUCCESS.
- If it is pending, the code is ERR_SYS_PENDING. If it failed, the error
- code would indicate the task from which the error originated and will
- be one of the errors in cx23418.h. In that case, the following
- applies ((error & 0xff) != 0).
- If the command is pending, the return will be passed in a MB from the
- receiver to the sender. 'req' will be returned in args[0] */
- u32 error;
-};
-
-struct cx18_stream;
-
-int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]);
-int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd,
- int args, ...);
-int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...);
-int cx18_api_func(void *priv, u32 cmd, int in, int out,
- u32 data[CX2341X_MBOX_MAX_DATA]);
-
-void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu);
-
-void cx18_in_work_handler(struct work_struct *work);
-
-#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
deleted file mode 100644
index 8884537bd62f..000000000000
--- a/drivers/media/video/cx18/cx18-queue.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * cx18 buffer queues
- *
- * Derived from ivtv-queue.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-scb.h"
-#include "cx18-io.h"
-
-void cx18_buf_swap(struct cx18_buffer *buf)
-{
- int i;
-
- for (i = 0; i < buf->bytesused; i += 4)
- swab32s((u32 *)(buf->buf + i));
-}
-
-void _cx18_mdl_swap(struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
-
- list_for_each_entry(buf, &mdl->buf_list, list) {
- if (buf->bytesused == 0)
- break;
- cx18_buf_swap(buf);
- }
-}
-
-void cx18_queue_init(struct cx18_queue *q)
-{
- INIT_LIST_HEAD(&q->list);
- atomic_set(&q->depth, 0);
- q->bytesused = 0;
-}
-
-struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct cx18_queue *q, int to_front)
-{
- /* clear the mdl if it is not to be enqueued to the full queue */
- if (q != &s->q_full) {
- mdl->bytesused = 0;
- mdl->readpos = 0;
- mdl->m_flags = 0;
- mdl->skipped = 0;
- mdl->curr_buf = NULL;
- }
-
- /* q_busy is restricted to a max buffer count imposed by firmware */
- if (q == &s->q_busy &&
- atomic_read(&q->depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
- q = &s->q_free;
-
- spin_lock(&q->lock);
-
- if (to_front)
- list_add(&mdl->list, &q->list); /* LIFO */
- else
- list_add_tail(&mdl->list, &q->list); /* FIFO */
- q->bytesused += mdl->bytesused - mdl->readpos;
- atomic_inc(&q->depth);
-
- spin_unlock(&q->lock);
- return q;
-}
-
-struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
-{
- struct cx18_mdl *mdl = NULL;
-
- spin_lock(&q->lock);
- if (!list_empty(&q->list)) {
- mdl = list_first_entry(&q->list, struct cx18_mdl, list);
- list_del_init(&mdl->list);
- q->bytesused -= mdl->bytesused - mdl->readpos;
- mdl->skipped = 0;
- atomic_dec(&q->depth);
- }
- spin_unlock(&q->lock);
- return mdl;
-}
-
-static void _cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
- u32 buf_size = s->buf_size;
- u32 bytesused = mdl->bytesused;
-
- list_for_each_entry(buf, &mdl->buf_list, list) {
- buf->readpos = 0;
- if (bytesused >= buf_size) {
- buf->bytesused = buf_size;
- bytesused -= buf_size;
- } else {
- buf->bytesused = bytesused;
- bytesused = 0;
- }
- cx18_buf_sync_for_cpu(s, buf);
- }
-}
-
-static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
-
- if (list_is_singular(&mdl->buf_list)) {
- buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
- list);
- buf->bytesused = mdl->bytesused;
- buf->readpos = 0;
- cx18_buf_sync_for_cpu(s, buf);
- } else {
- _cx18_mdl_update_bufs_for_cpu(s, mdl);
- }
-}
-
-struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
- u32 bytesused)
-{
- struct cx18 *cx = s->cx;
- struct cx18_mdl *mdl;
- struct cx18_mdl *tmp;
- struct cx18_mdl *ret = NULL;
- LIST_HEAD(sweep_up);
-
- /*
- * We don't have to acquire multiple q locks here, because we are
- * serialized by the single threaded work handler.
- * MDLs from the firmware will thus remain in order as
- * they are moved from q_busy to q_full or to the dvb ring buffer.
- */
- spin_lock(&s->q_busy.lock);
- list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) {
- /*
- * We should find what the firmware told us is done,
- * right at the front of the queue. If we don't, we likely have
- * missed an mdl done message from the firmware.
- * Once we skip an mdl repeatedly, relative to the size of
- * q_busy, we have high confidence we've missed it.
- */
- if (mdl->id != id) {
- mdl->skipped++;
- if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) {
- /* mdl must have fallen out of rotation */
- CX18_WARN("Skipped %s, MDL %d, %d "
- "times - it must have dropped out of "
- "rotation\n", s->name, mdl->id,
- mdl->skipped);
- /* Sweep it up to put it back into rotation */
- list_move_tail(&mdl->list, &sweep_up);
- atomic_dec(&s->q_busy.depth);
- }
- continue;
- }
- /*
- * We pull the desired mdl off of the queue here. Something
- * will have to put it back on a queue later.
- */
- list_del_init(&mdl->list);
- atomic_dec(&s->q_busy.depth);
- ret = mdl;
- break;
- }
- spin_unlock(&s->q_busy.lock);
-
- /*
- * We found the mdl for which we were looking. Get it ready for
- * the caller to put on q_full or in the dvb ring buffer.
- */
- if (ret != NULL) {
- ret->bytesused = bytesused;
- ret->skipped = 0;
- /* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */
- cx18_mdl_update_bufs_for_cpu(s, ret);
- if (s->type != CX18_ENC_STREAM_TYPE_TS)
- set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags);
- }
-
- /* Put any mdls the firmware is ignoring back into normal rotation */
- list_for_each_entry_safe(mdl, tmp, &sweep_up, list) {
- list_del_init(&mdl->list);
- cx18_enqueue(s, mdl, &s->q_free);
- }
- return ret;
-}
-
-/* Move all mdls of a queue, while flushing the mdl */
-static void cx18_queue_flush(struct cx18_stream *s,
- struct cx18_queue *q_src, struct cx18_queue *q_dst)
-{
- struct cx18_mdl *mdl;
-
- /* It only makes sense to flush to q_free or q_idle */
- if (q_src == q_dst || q_dst == &s->q_full || q_dst == &s->q_busy)
- return;
-
- spin_lock(&q_src->lock);
- spin_lock(&q_dst->lock);
- while (!list_empty(&q_src->list)) {
- mdl = list_first_entry(&q_src->list, struct cx18_mdl, list);
- list_move_tail(&mdl->list, &q_dst->list);
- mdl->bytesused = 0;
- mdl->readpos = 0;
- mdl->m_flags = 0;
- mdl->skipped = 0;
- mdl->curr_buf = NULL;
- atomic_inc(&q_dst->depth);
- }
- cx18_queue_init(q_src);
- spin_unlock(&q_src->lock);
- spin_unlock(&q_dst->lock);
-}
-
-void cx18_flush_queues(struct cx18_stream *s)
-{
- cx18_queue_flush(s, &s->q_busy, &s->q_free);
- cx18_queue_flush(s, &s->q_full, &s->q_free);
-}
-
-/*
- * Note, s->buf_pool is not protected by a lock,
- * the stream better not have *anything* going on when calling this
- */
-void cx18_unload_queues(struct cx18_stream *s)
-{
- struct cx18_queue *q_idle = &s->q_idle;
- struct cx18_mdl *mdl;
- struct cx18_buffer *buf;
-
- /* Move all MDLS to q_idle */
- cx18_queue_flush(s, &s->q_busy, q_idle);
- cx18_queue_flush(s, &s->q_full, q_idle);
- cx18_queue_flush(s, &s->q_free, q_idle);
-
- /* Reset MDL id's and move all buffers back to the stream's buf_pool */
- spin_lock(&q_idle->lock);
- list_for_each_entry(mdl, &q_idle->list, list) {
- while (!list_empty(&mdl->buf_list)) {
- buf = list_first_entry(&mdl->buf_list,
- struct cx18_buffer, list);
- list_move_tail(&buf->list, &s->buf_pool);
- buf->bytesused = 0;
- buf->readpos = 0;
- }
- mdl->id = s->mdl_base_idx; /* reset id to a "safe" value */
- /* all other mdl fields were cleared by cx18_queue_flush() */
- }
- spin_unlock(&q_idle->lock);
-}
-
-/*
- * Note, s->buf_pool is not protected by a lock,
- * the stream better not have *anything* going on when calling this
- */
-void cx18_load_queues(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- struct cx18_mdl *mdl;
- struct cx18_buffer *buf;
- int mdl_id;
- int i;
- u32 partial_buf_size;
-
- /*
- * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free
- * Excess MDLs are left on q_idle
- * Excess buffers are left in buf_pool and/or on an MDL in q_idle
- */
- mdl_id = s->mdl_base_idx;
- for (mdl = cx18_dequeue(s, &s->q_idle), i = s->bufs_per_mdl;
- mdl != NULL && i == s->bufs_per_mdl;
- mdl = cx18_dequeue(s, &s->q_idle)) {
-
- mdl->id = mdl_id;
-
- for (i = 0; i < s->bufs_per_mdl; i++) {
- if (list_empty(&s->buf_pool))
- break;
-
- buf = list_first_entry(&s->buf_pool, struct cx18_buffer,
- list);
- list_move_tail(&buf->list, &mdl->buf_list);
-
- /* update the firmware's MDL array with this buffer */
- cx18_writel(cx, buf->dma_handle,
- &cx->scb->cpu_mdl[mdl_id + i].paddr);
- cx18_writel(cx, s->buf_size,
- &cx->scb->cpu_mdl[mdl_id + i].length);
- }
-
- if (i == s->bufs_per_mdl) {
- /*
- * The encoder doesn't honor s->mdl_size. So in the
- * case of a non-integral number of buffers to meet
- * mdl_size, we lie about the size of the last buffer
- * in the MDL to get the encoder to really only send
- * us mdl_size bytes per MDL transfer.
- */
- partial_buf_size = s->mdl_size % s->buf_size;
- if (partial_buf_size) {
- cx18_writel(cx, partial_buf_size,
- &cx->scb->cpu_mdl[mdl_id + i - 1].length);
- }
- cx18_enqueue(s, mdl, &s->q_free);
- } else {
- /* Not enough buffers for this MDL; we won't use it */
- cx18_push(s, mdl, &s->q_idle);
- }
- mdl_id += i;
- }
-}
-
-void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl)
-{
- int dma = s->dma;
- u32 buf_size = s->buf_size;
- struct pci_dev *pci_dev = s->cx->pci_dev;
- struct cx18_buffer *buf;
-
- list_for_each_entry(buf, &mdl->buf_list, list)
- pci_dma_sync_single_for_device(pci_dev, buf->dma_handle,
- buf_size, dma);
-}
-
-int cx18_stream_alloc(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- int i;
-
- if (s->buffers == 0)
- return 0;
-
- CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
- "(%d.%02d kB total)\n",
- s->name, s->buffers, s->buf_size,
- s->buffers * s->buf_size / 1024,
- (s->buffers * s->buf_size * 100 / 1024) % 100);
-
- if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
- (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
- unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
- ((char __iomem *)cx->scb->cpu_mdl));
-
- CX18_ERR("Too many buffers, cannot fit in SCB area\n");
- CX18_ERR("Max buffers = %zd\n",
- bufsz / sizeof(struct cx18_mdl_ent));
- return -ENOMEM;
- }
-
- s->mdl_base_idx = cx->free_mdl_idx;
-
- /* allocate stream buffers and MDLs */
- for (i = 0; i < s->buffers; i++) {
- struct cx18_mdl *mdl;
- struct cx18_buffer *buf;
-
- /* 1 MDL per buffer to handle the worst & also default case */
- mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN);
- if (mdl == NULL)
- break;
-
- buf = kzalloc(sizeof(struct cx18_buffer),
- GFP_KERNEL|__GFP_NOWARN);
- if (buf == NULL) {
- kfree(mdl);
- break;
- }
-
- buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
- if (buf->buf == NULL) {
- kfree(mdl);
- kfree(buf);
- break;
- }
-
- INIT_LIST_HEAD(&mdl->list);
- INIT_LIST_HEAD(&mdl->buf_list);
- mdl->id = s->mdl_base_idx; /* a somewhat safe value */
- cx18_enqueue(s, mdl, &s->q_idle);
-
- INIT_LIST_HEAD(&buf->list);
- buf->dma_handle = pci_map_single(s->cx->pci_dev,
- buf->buf, s->buf_size, s->dma);
- cx18_buf_sync_for_cpu(s, buf);
- list_add_tail(&buf->list, &s->buf_pool);
- }
- if (i == s->buffers) {
- cx->free_mdl_idx += s->buffers;
- return 0;
- }
- CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
- cx18_stream_free(s);
- return -ENOMEM;
-}
-
-void cx18_stream_free(struct cx18_stream *s)
-{
- struct cx18_mdl *mdl;
- struct cx18_buffer *buf;
- struct cx18 *cx = s->cx;
-
- CX18_DEBUG_INFO("Deallocating buffers for %s stream\n", s->name);
-
- /* move all buffers to buf_pool and all MDLs to q_idle */
- cx18_unload_queues(s);
-
- /* empty q_idle */
- while ((mdl = cx18_dequeue(s, &s->q_idle)))
- kfree(mdl);
-
- /* empty buf_pool */
- while (!list_empty(&s->buf_pool)) {
- buf = list_first_entry(&s->buf_pool, struct cx18_buffer, list);
- list_del_init(&buf->list);
-
- pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
- s->buf_size, s->dma);
- kfree(buf->buf);
- kfree(buf);
- }
-}
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
deleted file mode 100644
index 4201ddc16091..000000000000
--- a/drivers/media/video/cx18/cx18-queue.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * cx18 buffer queues
- *
- * Derived from ivtv-queue.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#define CX18_DMA_UNMAPPED ((u32) -1)
-
-/* cx18_buffer utility functions */
-
-static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
- struct cx18_buffer *buf)
-{
- pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle,
- s->buf_size, s->dma);
-}
-
-static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
- struct cx18_buffer *buf)
-{
- pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle,
- s->buf_size, s->dma);
-}
-
-void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl);
-
-static inline void cx18_mdl_sync_for_device(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- if (list_is_singular(&mdl->buf_list))
- cx18_buf_sync_for_device(s, list_first_entry(&mdl->buf_list,
- struct cx18_buffer,
- list));
- else
- _cx18_mdl_sync_for_device(s, mdl);
-}
-
-void cx18_buf_swap(struct cx18_buffer *buf);
-void _cx18_mdl_swap(struct cx18_mdl *mdl);
-
-static inline void cx18_mdl_swap(struct cx18_mdl *mdl)
-{
- if (list_is_singular(&mdl->buf_list))
- cx18_buf_swap(list_first_entry(&mdl->buf_list,
- struct cx18_buffer, list));
- else
- _cx18_mdl_swap(mdl);
-}
-
-/* cx18_queue utility functions */
-struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct cx18_queue *q, int to_front);
-
-static inline
-struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct cx18_queue *q)
-{
- return _cx18_enqueue(s, mdl, q, 0); /* FIFO */
-}
-
-static inline
-struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct cx18_queue *q)
-{
- return _cx18_enqueue(s, mdl, q, 1); /* LIFO */
-}
-
-void cx18_queue_init(struct cx18_queue *q);
-struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
-struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
- u32 bytesused);
-void cx18_flush_queues(struct cx18_stream *s);
-
-/* queue MDL reconfiguration helpers */
-void cx18_unload_queues(struct cx18_stream *s);
-void cx18_load_queues(struct cx18_stream *s);
-
-/* cx18_stream utility functions */
-int cx18_stream_alloc(struct cx18_stream *s);
-void cx18_stream_free(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c
deleted file mode 100644
index 85cc59637e54..000000000000
--- a/drivers/media/video/cx18/cx18-scb.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * cx18 System Control Block initialization
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-scb.h"
-
-void cx18_init_scb(struct cx18 *cx)
-{
- cx18_setup_page(cx, SCB_OFFSET);
- cx18_memset_io(cx, cx->scb, 0, 0x10000);
-
- cx18_writel(cx, IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
- cx18_writel(cx, IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
- cx18_writel(cx, IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
- cx18_writel(cx, IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
- cx18_writel(cx, IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
- cx18_writel(cx, IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
- cx18_writel(cx, IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
- cx18_writel(cx, IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
-
- cx18_writel(cx, IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
- cx18_writel(cx, IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
- cx18_writel(cx, IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
- cx18_writel(cx, IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
- cx18_writel(cx, IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
- cx18_writel(cx, IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
- cx18_writel(cx, IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
- cx18_writel(cx, IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
-
- cx18_writel(cx, IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
- cx18_writel(cx, IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
- cx18_writel(cx, IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
- cx18_writel(cx, IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
- cx18_writel(cx, IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
- cx18_writel(cx, IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
- cx18_writel(cx, IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
- cx18_writel(cx, IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
-
- cx18_writel(cx, IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
- cx18_writel(cx, IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
- cx18_writel(cx, IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
- cx18_writel(cx, IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
- cx18_writel(cx, IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
- cx18_writel(cx, IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
- cx18_writel(cx, IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
- cx18_writel(cx, IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
-
- cx18_writel(cx, IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
- cx18_writel(cx, IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
- cx18_writel(cx, IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
- cx18_writel(cx, IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
- cx18_writel(cx, IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
- cx18_writel(cx, IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
- cx18_writel(cx, IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
- cx18_writel(cx, IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
-
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
- &cx->scb->apu2cpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
- &cx->scb->hpu2cpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
- &cx->scb->ppu2cpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
- &cx->scb->epu2cpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
- &cx->scb->cpu2apu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
- &cx->scb->hpu2apu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
- &cx->scb->ppu2apu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
- &cx->scb->epu2apu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
- &cx->scb->cpu2hpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
- &cx->scb->apu2hpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
- &cx->scb->ppu2hpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
- &cx->scb->epu2hpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
- &cx->scb->cpu2ppu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
- &cx->scb->apu2ppu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
- &cx->scb->hpu2ppu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
- &cx->scb->epu2ppu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
- &cx->scb->cpu2epu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
- &cx->scb->apu2epu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
- &cx->scb->hpu2epu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
- &cx->scb->ppu2epu_mb_offset);
-
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
- &cx->scb->ipc_offset);
-
- cx18_writel(cx, 1, &cx->scb->epu_state);
-}
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
deleted file mode 100644
index 08877652e321..000000000000
--- a/drivers/media/video/cx18/cx18-scb.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * cx18 System Control Block initialization
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX18_SCB_H
-#define CX18_SCB_H
-
-#include "cx18-mailbox.h"
-
-/* NOTE: All ACK interrupts are in the SW2 register. All non-ACK interrupts
- are in the SW1 register. */
-
-#define IRQ_APU_TO_CPU 0x00000001
-#define IRQ_CPU_TO_APU_ACK 0x00000001
-#define IRQ_HPU_TO_CPU 0x00000002
-#define IRQ_CPU_TO_HPU_ACK 0x00000002
-#define IRQ_PPU_TO_CPU 0x00000004
-#define IRQ_CPU_TO_PPU_ACK 0x00000004
-#define IRQ_EPU_TO_CPU 0x00000008
-#define IRQ_CPU_TO_EPU_ACK 0x00000008
-
-#define IRQ_CPU_TO_APU 0x00000010
-#define IRQ_APU_TO_CPU_ACK 0x00000010
-#define IRQ_HPU_TO_APU 0x00000020
-#define IRQ_APU_TO_HPU_ACK 0x00000020
-#define IRQ_PPU_TO_APU 0x00000040
-#define IRQ_APU_TO_PPU_ACK 0x00000040
-#define IRQ_EPU_TO_APU 0x00000080
-#define IRQ_APU_TO_EPU_ACK 0x00000080
-
-#define IRQ_CPU_TO_HPU 0x00000100
-#define IRQ_HPU_TO_CPU_ACK 0x00000100
-#define IRQ_APU_TO_HPU 0x00000200
-#define IRQ_HPU_TO_APU_ACK 0x00000200
-#define IRQ_PPU_TO_HPU 0x00000400
-#define IRQ_HPU_TO_PPU_ACK 0x00000400
-#define IRQ_EPU_TO_HPU 0x00000800
-#define IRQ_HPU_TO_EPU_ACK 0x00000800
-
-#define IRQ_CPU_TO_PPU 0x00001000
-#define IRQ_PPU_TO_CPU_ACK 0x00001000
-#define IRQ_APU_TO_PPU 0x00002000
-#define IRQ_PPU_TO_APU_ACK 0x00002000
-#define IRQ_HPU_TO_PPU 0x00004000
-#define IRQ_PPU_TO_HPU_ACK 0x00004000
-#define IRQ_EPU_TO_PPU 0x00008000
-#define IRQ_PPU_TO_EPU_ACK 0x00008000
-
-#define IRQ_CPU_TO_EPU 0x00010000
-#define IRQ_EPU_TO_CPU_ACK 0x00010000
-#define IRQ_APU_TO_EPU 0x00020000
-#define IRQ_EPU_TO_APU_ACK 0x00020000
-#define IRQ_HPU_TO_EPU 0x00040000
-#define IRQ_EPU_TO_HPU_ACK 0x00040000
-#define IRQ_PPU_TO_EPU 0x00080000
-#define IRQ_EPU_TO_PPU_ACK 0x00080000
-
-#define SCB_OFFSET 0xDC0000
-
-/* If Firmware uses fixed memory map, it shall not allocate the area
- between SCB_OFFSET and SCB_OFFSET+SCB_RESERVED_SIZE-1 inclusive */
-#define SCB_RESERVED_SIZE 0x10000
-
-
-/* This structure is used by EPU to provide memory descriptors in its memory */
-struct cx18_mdl_ent {
- u32 paddr; /* Physical address of a buffer segment */
- u32 length; /* Length of the buffer segment */
-};
-
-struct cx18_scb {
- /* These fields form the System Control Block which is used at boot time
- for localizing the IPC data as well as the code positions for all
- processors. The offsets are from the start of this struct. */
-
- /* Offset where to find the Inter-Processor Communication data */
- u32 ipc_offset;
- u32 reserved01[7];
- /* Offset where to find the start of the CPU code */
- u32 cpu_code_offset;
- u32 reserved02[3];
- /* Offset where to find the start of the APU code */
- u32 apu_code_offset;
- u32 reserved03[3];
- /* Offset where to find the start of the HPU code */
- u32 hpu_code_offset;
- u32 reserved04[3];
- /* Offset where to find the start of the PPU code */
- u32 ppu_code_offset;
- u32 reserved05[3];
-
- /* These fields form Inter-Processor Communication data which is used
- by all processors to locate the information needed for communicating
- with other processors */
-
- /* Fields for CPU: */
-
- /* bit 0: 1/0 processor ready/not ready. Set other bits to 0. */
- u32 cpu_state;
- u32 reserved1[7];
- /* Offset to the mailbox used for sending commands from APU to CPU */
- u32 apu2cpu_mb_offset;
- /* Value to write to register SW1 register set (0xC7003100) after the
- command is ready */
- u32 apu2cpu_irq;
- /* Value to write to register SW2 register set (0xC7003140) after the
- command is cleared */
- u32 cpu2apu_irq_ack;
- u32 reserved2[13];
-
- u32 hpu2cpu_mb_offset;
- u32 hpu2cpu_irq;
- u32 cpu2hpu_irq_ack;
- u32 reserved3[13];
-
- u32 ppu2cpu_mb_offset;
- u32 ppu2cpu_irq;
- u32 cpu2ppu_irq_ack;
- u32 reserved4[13];
-
- u32 epu2cpu_mb_offset;
- u32 epu2cpu_irq;
- u32 cpu2epu_irq_ack;
- u32 reserved5[13];
- u32 reserved6[8];
-
- /* Fields for APU: */
-
- u32 apu_state;
- u32 reserved11[7];
- u32 cpu2apu_mb_offset;
- u32 cpu2apu_irq;
- u32 apu2cpu_irq_ack;
- u32 reserved12[13];
-
- u32 hpu2apu_mb_offset;
- u32 hpu2apu_irq;
- u32 apu2hpu_irq_ack;
- u32 reserved13[13];
-
- u32 ppu2apu_mb_offset;
- u32 ppu2apu_irq;
- u32 apu2ppu_irq_ack;
- u32 reserved14[13];
-
- u32 epu2apu_mb_offset;
- u32 epu2apu_irq;
- u32 apu2epu_irq_ack;
- u32 reserved15[13];
- u32 reserved16[8];
-
- /* Fields for HPU: */
-
- u32 hpu_state;
- u32 reserved21[7];
- u32 cpu2hpu_mb_offset;
- u32 cpu2hpu_irq;
- u32 hpu2cpu_irq_ack;
- u32 reserved22[13];
-
- u32 apu2hpu_mb_offset;
- u32 apu2hpu_irq;
- u32 hpu2apu_irq_ack;
- u32 reserved23[13];
-
- u32 ppu2hpu_mb_offset;
- u32 ppu2hpu_irq;
- u32 hpu2ppu_irq_ack;
- u32 reserved24[13];
-
- u32 epu2hpu_mb_offset;
- u32 epu2hpu_irq;
- u32 hpu2epu_irq_ack;
- u32 reserved25[13];
- u32 reserved26[8];
-
- /* Fields for PPU: */
-
- u32 ppu_state;
- u32 reserved31[7];
- u32 cpu2ppu_mb_offset;
- u32 cpu2ppu_irq;
- u32 ppu2cpu_irq_ack;
- u32 reserved32[13];
-
- u32 apu2ppu_mb_offset;
- u32 apu2ppu_irq;
- u32 ppu2apu_irq_ack;
- u32 reserved33[13];
-
- u32 hpu2ppu_mb_offset;
- u32 hpu2ppu_irq;
- u32 ppu2hpu_irq_ack;
- u32 reserved34[13];
-
- u32 epu2ppu_mb_offset;
- u32 epu2ppu_irq;
- u32 ppu2epu_irq_ack;
- u32 reserved35[13];
- u32 reserved36[8];
-
- /* Fields for EPU: */
-
- u32 epu_state;
- u32 reserved41[7];
- u32 cpu2epu_mb_offset;
- u32 cpu2epu_irq;
- u32 epu2cpu_irq_ack;
- u32 reserved42[13];
-
- u32 apu2epu_mb_offset;
- u32 apu2epu_irq;
- u32 epu2apu_irq_ack;
- u32 reserved43[13];
-
- u32 hpu2epu_mb_offset;
- u32 hpu2epu_irq;
- u32 epu2hpu_irq_ack;
- u32 reserved44[13];
-
- u32 ppu2epu_mb_offset;
- u32 ppu2epu_irq;
- u32 epu2ppu_irq_ack;
- u32 reserved45[13];
- u32 reserved46[8];
-
- u32 semaphores[8]; /* Semaphores */
-
- u32 reserved50[32]; /* Reserved for future use */
-
- struct cx18_mailbox apu2cpu_mb;
- struct cx18_mailbox hpu2cpu_mb;
- struct cx18_mailbox ppu2cpu_mb;
- struct cx18_mailbox epu2cpu_mb;
-
- struct cx18_mailbox cpu2apu_mb;
- struct cx18_mailbox hpu2apu_mb;
- struct cx18_mailbox ppu2apu_mb;
- struct cx18_mailbox epu2apu_mb;
-
- struct cx18_mailbox cpu2hpu_mb;
- struct cx18_mailbox apu2hpu_mb;
- struct cx18_mailbox ppu2hpu_mb;
- struct cx18_mailbox epu2hpu_mb;
-
- struct cx18_mailbox cpu2ppu_mb;
- struct cx18_mailbox apu2ppu_mb;
- struct cx18_mailbox hpu2ppu_mb;
- struct cx18_mailbox epu2ppu_mb;
-
- struct cx18_mailbox cpu2epu_mb;
- struct cx18_mailbox apu2epu_mb;
- struct cx18_mailbox hpu2epu_mb;
- struct cx18_mailbox ppu2epu_mb;
-
- struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
- struct cx18_mdl_ent cpu_mdl[1];
-};
-
-void cx18_init_scb(struct cx18 *cx);
-
-#endif
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
deleted file mode 100644
index 9d598ab88615..000000000000
--- a/drivers/media/video/cx18/cx18-streams.c
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- * cx18 init/start/stop/exit stream functions
- *
- * Derived from ivtv-streams.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-fileops.h"
-#include "cx18-mailbox.h"
-#include "cx18-i2c.h"
-#include "cx18-queue.h"
-#include "cx18-ioctl.h"
-#include "cx18-streams.h"
-#include "cx18-cards.h"
-#include "cx18-scb.h"
-#include "cx18-dvb.h"
-
-#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
-
-static struct v4l2_file_operations cx18_v4l2_enc_fops = {
- .owner = THIS_MODULE,
- .read = cx18_v4l2_read,
- .open = cx18_v4l2_open,
- .unlocked_ioctl = video_ioctl2,
- .release = cx18_v4l2_close,
- .poll = cx18_v4l2_enc_poll,
- .mmap = cx18_v4l2_mmap,
-};
-
-/* offset from 0 to register ts v4l2 minors on */
-#define CX18_V4L2_ENC_TS_OFFSET 16
-/* offset from 0 to register pcm v4l2 minors on */
-#define CX18_V4L2_ENC_PCM_OFFSET 24
-/* offset from 0 to register yuv v4l2 minors on */
-#define CX18_V4L2_ENC_YUV_OFFSET 32
-
-static struct {
- const char *name;
- int vfl_type;
- int num_offset;
- int dma;
- enum v4l2_buf_type buf_type;
-} cx18_stream_info[] = {
- { /* CX18_ENC_STREAM_TYPE_MPG */
- "encoder MPEG",
- VFL_TYPE_GRABBER, 0,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_TS */
- "TS",
- VFL_TYPE_GRABBER, -1,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_YUV */
- "encoder YUV",
- VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_VBI */
- "encoder VBI",
- VFL_TYPE_VBI, 0,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_PCM */
- "encoder PCM audio",
- VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
- },
- { /* CX18_ENC_STREAM_TYPE_IDX */
- "encoder IDX",
- VFL_TYPE_GRABBER, -1,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_RAD */
- "encoder radio",
- VFL_TYPE_RADIO, 0,
- PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
- },
-};
-
-
-void cx18_dma_free(struct videobuf_queue *q,
- struct cx18_stream *s, struct cx18_videobuf_buffer *buf)
-{
- videobuf_waiton(q, &buf->vb, 0, 0);
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int cx18_prepare_buffer(struct videobuf_queue *q,
- struct cx18_stream *s,
- struct cx18_videobuf_buffer *buf,
- u32 pixelformat,
- unsigned int width, unsigned int height,
- enum v4l2_field field)
-{
- struct cx18 *cx = s->cx;
- int rc = 0;
-
- /* check settings */
- buf->bytes_used = 0;
-
- if ((width < 48) || (height < 32))
- return -EINVAL;
-
- buf->vb.size = (width * height * 2);
- if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
- return -EINVAL;
-
- /* alloc + fill struct (if changed) */
- if (buf->vb.width != width || buf->vb.height != height ||
- buf->vb.field != field || s->pixelformat != pixelformat ||
- buf->tvnorm != cx->std) {
-
- buf->vb.width = width;
- buf->vb.height = height;
- buf->vb.field = field;
- buf->tvnorm = cx->std;
- s->pixelformat = pixelformat;
-
- /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
- UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
- if (s->pixelformat == V4L2_PIX_FMT_HM12)
- s->vb_bytes_per_frame = height * 720 * 3 / 2;
- else
- s->vb_bytes_per_frame = height * 720 * 2;
- cx18_dma_free(q, s, buf);
- }
-
- if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
- return -EINVAL;
-
- if (buf->vb.field == 0)
- buf->vb.field = V4L2_FIELD_INTERLACED;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- buf->vb.width = width;
- buf->vb.height = height;
- buf->vb.field = field;
- buf->tvnorm = cx->std;
- s->pixelformat = pixelformat;
-
- /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
- UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
- if (s->pixelformat == V4L2_PIX_FMT_HM12)
- s->vb_bytes_per_frame = height * 720 * 3 / 2;
- else
- s->vb_bytes_per_frame = height * 720 * 2;
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (rc != 0)
- goto fail;
- }
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- cx18_dma_free(q, s, buf);
- return rc;
-
-}
-
-/* VB_MIN_BUFSIZE is lcm(1440 * 480, 1440 * 576)
- 1440 is a single line of 4:2:2 YUV at 720 luma samples wide
-*/
-#define VB_MIN_BUFFERS 32
-#define VB_MIN_BUFSIZE 4147200
-
-static int buffer_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct cx18_stream *s = q->priv_data;
- struct cx18 *cx = s->cx;
-
- *size = 2 * cx->cxhdl.width * cx->cxhdl.height;
- if (*count == 0)
- *count = VB_MIN_BUFFERS;
-
- while (*size * *count > VB_MIN_BUFFERS * VB_MIN_BUFSIZE)
- (*count)--;
-
- q->field = V4L2_FIELD_INTERLACED;
- q->last = V4L2_FIELD_INTERLACED;
-
- return 0;
-}
-
-static int buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx18_videobuf_buffer *buf =
- container_of(vb, struct cx18_videobuf_buffer, vb);
- struct cx18_stream *s = q->priv_data;
- struct cx18 *cx = s->cx;
-
- return cx18_prepare_buffer(q, s, buf, s->pixelformat,
- cx->cxhdl.width, cx->cxhdl.height, field);
-}
-
-static void buffer_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct cx18_videobuf_buffer *buf =
- container_of(vb, struct cx18_videobuf_buffer, vb);
- struct cx18_stream *s = q->priv_data;
-
- cx18_dma_free(q, s, buf);
-}
-
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx18_videobuf_buffer *buf =
- container_of(vb, struct cx18_videobuf_buffer, vb);
- struct cx18_stream *s = q->priv_data;
-
- buf->vb.state = VIDEOBUF_QUEUED;
-
- list_add_tail(&buf->vb.queue, &s->vb_capture);
-}
-
-static struct videobuf_queue_ops cx18_videobuf_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-static void cx18_stream_init(struct cx18 *cx, int type)
-{
- struct cx18_stream *s = &cx->streams[type];
- struct video_device *video_dev = s->video_dev;
-
- /* we need to keep video_dev, so restore it afterwards */
- memset(s, 0, sizeof(*s));
- s->video_dev = video_dev;
-
- /* initialize cx18_stream fields */
- s->dvb = NULL;
- s->cx = cx;
- s->type = type;
- s->name = cx18_stream_info[type].name;
- s->handle = CX18_INVALID_TASK_HANDLE;
-
- s->dma = cx18_stream_info[type].dma;
- s->buffers = cx->stream_buffers[type];
- s->buf_size = cx->stream_buf_size[type];
- INIT_LIST_HEAD(&s->buf_pool);
- s->bufs_per_mdl = 1;
- s->mdl_size = s->buf_size * s->bufs_per_mdl;
-
- init_waitqueue_head(&s->waitq);
- s->id = -1;
- spin_lock_init(&s->q_free.lock);
- cx18_queue_init(&s->q_free);
- spin_lock_init(&s->q_busy.lock);
- cx18_queue_init(&s->q_busy);
- spin_lock_init(&s->q_full.lock);
- cx18_queue_init(&s->q_full);
- spin_lock_init(&s->q_idle.lock);
- cx18_queue_init(&s->q_idle);
-
- INIT_WORK(&s->out_work_order, cx18_out_work_handler);
-
- INIT_LIST_HEAD(&s->vb_capture);
- s->vb_timeout.function = cx18_vb_timeout;
- s->vb_timeout.data = (unsigned long)s;
- init_timer(&s->vb_timeout);
- spin_lock_init(&s->vb_lock);
- if (type == CX18_ENC_STREAM_TYPE_YUV) {
- spin_lock_init(&s->vbuf_q_lock);
-
- s->vb_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- videobuf_queue_vmalloc_init(&s->vbuf_q, &cx18_videobuf_qops,
- &cx->pci_dev->dev, &s->vbuf_q_lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx18_videobuf_buffer),
- s, &cx->serialize_lock);
-
- /* Assume the previous pixel default */
- s->pixelformat = V4L2_PIX_FMT_HM12;
- s->vb_bytes_per_frame = cx->cxhdl.height * 720 * 3 / 2;
- }
-}
-
-static int cx18_prep_dev(struct cx18 *cx, int type)
-{
- struct cx18_stream *s = &cx->streams[type];
- u32 cap = cx->v4l2_cap;
- int num_offset = cx18_stream_info[type].num_offset;
- int num = cx->instance + cx18_first_minor + num_offset;
-
- /*
- * These five fields are always initialized.
- * For analog capture related streams, if video_dev == NULL then the
- * stream is not in use.
- * For the TS stream, if dvb == NULL then the stream is not in use.
- * In those cases no other fields but these four can be used.
- */
- s->video_dev = NULL;
- s->dvb = NULL;
- s->cx = cx;
- s->type = type;
- s->name = cx18_stream_info[type].name;
-
- /* Check whether the radio is supported */
- if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
- return 0;
-
- /* Check whether VBI is supported */
- if (type == CX18_ENC_STREAM_TYPE_VBI &&
- !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
- return 0;
-
- /* User explicitly selected 0 buffers for these streams, so don't
- create them. */
- if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
- cx->stream_buffers[type] == 0) {
- CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
- return 0;
- }
-
- cx18_stream_init(cx, type);
-
- /* Allocate the cx18_dvb struct only for the TS on cards with DTV */
- if (type == CX18_ENC_STREAM_TYPE_TS) {
- if (cx->card->hw_all & CX18_HW_DVB) {
- s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL);
- if (s->dvb == NULL) {
- CX18_ERR("Couldn't allocate cx18_dvb structure"
- " for %s\n", s->name);
- return -ENOMEM;
- }
- } else {
- /* Don't need buffers for the TS, if there is no DVB */
- s->buffers = 0;
- }
- }
-
- if (num_offset == -1)
- return 0;
-
- /* allocate and initialize the v4l2 video device structure */
- s->video_dev = video_device_alloc();
- if (s->video_dev == NULL) {
- CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
- s->name);
- return -ENOMEM;
- }
-
- snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
- cx->v4l2_dev.name, s->name);
-
- s->video_dev->num = num;
- s->video_dev->v4l2_dev = &cx->v4l2_dev;
- s->video_dev->fops = &cx18_v4l2_enc_fops;
- s->video_dev->release = video_device_release;
- s->video_dev->tvnorms = V4L2_STD_ALL;
- s->video_dev->lock = &cx->serialize_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
- cx18_set_funcs(s->video_dev);
- return 0;
-}
-
-/* Initialize v4l2 variables and register v4l2 devices */
-int cx18_streams_setup(struct cx18 *cx)
-{
- int type, ret;
-
- /* Setup V4L2 Devices */
- for (type = 0; type < CX18_MAX_STREAMS; type++) {
- /* Prepare device */
- ret = cx18_prep_dev(cx, type);
- if (ret < 0)
- break;
-
- /* Allocate Stream */
- ret = cx18_stream_alloc(&cx->streams[type]);
- if (ret < 0)
- break;
- }
- if (type == CX18_MAX_STREAMS)
- return 0;
-
- /* One or more streams could not be initialized. Clean 'em all up. */
- cx18_streams_cleanup(cx, 0);
- return ret;
-}
-
-static int cx18_reg_dev(struct cx18 *cx, int type)
-{
- struct cx18_stream *s = &cx->streams[type];
- int vfl_type = cx18_stream_info[type].vfl_type;
- const char *name;
- int num, ret;
-
- if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) {
- ret = cx18_dvb_register(s);
- if (ret < 0) {
- CX18_ERR("DVB failed to register\n");
- return ret;
- }
- }
-
- if (s->video_dev == NULL)
- return 0;
-
- num = s->video_dev->num;
- /* card number + user defined offset + device offset */
- if (type != CX18_ENC_STREAM_TYPE_MPG) {
- struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
-
- if (s_mpg->video_dev)
- num = s_mpg->video_dev->num
- + cx18_stream_info[type].num_offset;
- }
- video_set_drvdata(s->video_dev, s);
-
- /* Register device. First try the desired minor, then any free one. */
- ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
- if (ret < 0) {
- CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
- s->name, num);
- video_device_release(s->video_dev);
- s->video_dev = NULL;
- return ret;
- }
-
- name = video_device_node_name(s->video_dev);
-
- switch (vfl_type) {
- case VFL_TYPE_GRABBER:
- CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",
- name, s->name, cx->stream_buffers[type],
- cx->stream_buf_size[type] / 1024,
- (cx->stream_buf_size[type] * 100 / 1024) % 100);
- break;
-
- case VFL_TYPE_RADIO:
- CX18_INFO("Registered device %s for %s\n", name, s->name);
- break;
-
- case VFL_TYPE_VBI:
- if (cx->stream_buffers[type])
- CX18_INFO("Registered device %s for %s "
- "(%d x %d bytes)\n",
- name, s->name, cx->stream_buffers[type],
- cx->stream_buf_size[type]);
- else
- CX18_INFO("Registered device %s for %s\n",
- name, s->name);
- break;
- }
-
- return 0;
-}
-
-/* Register v4l2 devices */
-int cx18_streams_register(struct cx18 *cx)
-{
- int type;
- int err;
- int ret = 0;
-
- /* Register V4L2 devices */
- for (type = 0; type < CX18_MAX_STREAMS; type++) {
- err = cx18_reg_dev(cx, type);
- if (err && ret == 0)
- ret = err;
- }
-
- if (ret == 0)
- return 0;
-
- /* One or more streams could not be initialized. Clean 'em all up. */
- cx18_streams_cleanup(cx, 1);
- return ret;
-}
-
-/* Unregister v4l2 devices */
-void cx18_streams_cleanup(struct cx18 *cx, int unregister)
-{
- struct video_device *vdev;
- int type;
-
- /* Teardown all streams */
- for (type = 0; type < CX18_MAX_STREAMS; type++) {
-
- /* The TS has a cx18_dvb structure, not a video_device */
- if (type == CX18_ENC_STREAM_TYPE_TS) {
- if (cx->streams[type].dvb != NULL) {
- if (unregister)
- cx18_dvb_unregister(&cx->streams[type]);
- kfree(cx->streams[type].dvb);
- cx->streams[type].dvb = NULL;
- cx18_stream_free(&cx->streams[type]);
- }
- continue;
- }
-
- /* No struct video_device, but can have buffers allocated */
- if (type == CX18_ENC_STREAM_TYPE_IDX) {
- /* If the module params didn't inhibit IDX ... */
- if (cx->stream_buffers[type] != 0) {
- cx->stream_buffers[type] = 0;
- /*
- * Before calling cx18_stream_free(),
- * check if the IDX stream was actually set up.
- * Needed, since the cx18_probe() error path
- * exits through here as well as normal clean up
- */
- if (cx->streams[type].buffers != 0)
- cx18_stream_free(&cx->streams[type]);
- }
- continue;
- }
-
- /* If struct video_device exists, can have buffers allocated */
- vdev = cx->streams[type].video_dev;
-
- cx->streams[type].video_dev = NULL;
- if (vdev == NULL)
- continue;
-
- if (type == CX18_ENC_STREAM_TYPE_YUV)
- videobuf_mmap_free(&cx->streams[type].vbuf_q);
-
- cx18_stream_free(&cx->streams[type]);
-
- /* Unregister or release device */
- if (unregister)
- video_unregister_device(vdev);
- else
- video_device_release(vdev);
- }
-}
-
-static void cx18_vbi_setup(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- int raw = cx18_raw_vbi(cx);
- u32 data[CX2341X_MBOX_MAX_DATA];
- int lines;
-
- if (cx->is_60hz) {
- cx->vbi.count = 12;
- cx->vbi.start[0] = 10;
- cx->vbi.start[1] = 273;
- } else { /* PAL/SECAM */
- cx->vbi.count = 18;
- cx->vbi.start[0] = 6;
- cx->vbi.start[1] = 318;
- }
-
- /* setup VBI registers */
- if (raw)
- v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &cx->vbi.in.fmt.vbi);
- else
- v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &cx->vbi.in.fmt.sliced);
-
- /*
- * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
- * VBI when the first analog capture channel starts, as once it starts
- * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
- * (i.e. for the VBI capture channels). We also send it for each
- * analog capture channel anyway just to make sure we get the proper
- * behavior
- */
- if (raw) {
- lines = cx->vbi.count * 2;
- } else {
- /*
- * For 525/60 systems, according to the VIP 2 & BT.656 std:
- * The EAV RP code's Field bit toggles on line 4, a few lines
- * after the Vertcal Blank bit has already toggled.
- * Tell the encoder to capture 21-4+1=18 lines per field,
- * since we want lines 10 through 21.
- *
- * For 625/50 systems, according to the VIP 2 & BT.656 std:
- * The EAV RP code's Field bit toggles on line 1, a few lines
- * after the Vertcal Blank bit has already toggled.
- * (We've actually set the digitizer so that the Field bit
- * toggles on line 2.) Tell the encoder to capture 23-2+1=22
- * lines per field, since we want lines 6 through 23.
- */
- lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2;
- }
-
- data[0] = s->handle;
- /* Lines per field */
- data[1] = (lines / 2) | ((lines / 2) << 16);
- /* bytes per line */
- data[2] = (raw ? vbi_active_samples
- : (cx->is_60hz ? vbi_hblank_samples_60Hz
- : vbi_hblank_samples_50Hz));
- /* Every X number of frames a VBI interrupt arrives
- (frames as in 25 or 30 fps) */
- data[3] = 1;
- /*
- * Set the SAV/EAV RP codes to look for as start/stop points
- * when in VIP-1.1 mode
- */
- if (raw) {
- /*
- * Start codes for beginning of "active" line in vertical blank
- * 0x20 ( VerticalBlank )
- * 0x60 ( EvenField VerticalBlank )
- */
- data[4] = 0x20602060;
- /*
- * End codes for end of "active" raw lines and regular lines
- * 0x30 ( VerticalBlank HorizontalBlank)
- * 0x70 ( EvenField VerticalBlank HorizontalBlank)
- * 0x90 (Task HorizontalBlank)
- * 0xd0 (Task EvenField HorizontalBlank)
- */
- data[5] = 0x307090d0;
- } else {
- /*
- * End codes for active video, we want data in the hblank region
- * 0xb0 (Task 0 VerticalBlank HorizontalBlank)
- * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
- *
- * Since the V bit is only allowed to toggle in the EAV RP code,
- * just before the first active region line, these two
- * are problematic:
- * 0x90 (Task HorizontalBlank)
- * 0xd0 (Task EvenField HorizontalBlank)
- *
- * We have set the digitzer such that we don't have to worry
- * about these problem codes.
- */
- data[4] = 0xB0F0B0F0;
- /*
- * Start codes for beginning of active line in vertical blank
- * 0xa0 (Task VerticalBlank )
- * 0xe0 (Task EvenField VerticalBlank )
- */
- data[5] = 0xA0E0A0E0;
- }
-
- CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
- data[0], data[1], data[2], data[3], data[4], data[5]);
-
- cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
-}
-
-void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
-{
- struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- struct cx18_mdl *mdl;
-
- if (!cx18_stream_enabled(s))
- return;
-
- /* Return if the firmware is not running low on MDLs */
- if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
- CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
- return;
-
- /* Return if there are no MDLs to rotate back to the firmware */
- if (atomic_read(&s->q_full.depth) < 2)
- return;
-
- /*
- * Take the oldest IDX MDL still holding data, and discard its index
- * entries by scheduling the MDL to go back to the firmware
- */
- mdl = cx18_dequeue(s, &s->q_full);
- if (mdl != NULL)
- cx18_enqueue(s, mdl, &s->q_free);
-}
-
-static
-struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18 *cx = s->cx;
- struct cx18_queue *q;
-
- /* Don't give it to the firmware, if we're not running a capture */
- if (s->handle == CX18_INVALID_TASK_HANDLE ||
- test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
- !test_bit(CX18_F_S_STREAMING, &s->s_flags))
- return cx18_enqueue(s, mdl, &s->q_free);
-
- q = cx18_enqueue(s, mdl, &s->q_busy);
- if (q != &s->q_busy)
- return q; /* The firmware has the max MDLs it can handle */
-
- cx18_mdl_sync_for_device(s, mdl);
- cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
- (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
- s->bufs_per_mdl, mdl->id, s->mdl_size);
- return q;
-}
-
-static
-void _cx18_stream_load_fw_queue(struct cx18_stream *s)
-{
- struct cx18_queue *q;
- struct cx18_mdl *mdl;
-
- if (atomic_read(&s->q_free.depth) == 0 ||
- atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
- return;
-
- /* Move from q_free to q_busy notifying the firmware, until the limit */
- do {
- mdl = cx18_dequeue(s, &s->q_free);
- if (mdl == NULL)
- break;
- q = _cx18_stream_put_mdl_fw(s, mdl);
- } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
- && q == &s->q_busy);
-}
-
-void cx18_out_work_handler(struct work_struct *work)
-{
- struct cx18_stream *s =
- container_of(work, struct cx18_stream, out_work_order);
-
- _cx18_stream_load_fw_queue(s);
-}
-
-static void cx18_stream_configure_mdls(struct cx18_stream *s)
-{
- cx18_unload_queues(s);
-
- switch (s->type) {
- case CX18_ENC_STREAM_TYPE_YUV:
- /*
- * Height should be a multiple of 32 lines.
- * Set the MDL size to the exact size needed for one frame.
- * Use enough buffers per MDL to cover the MDL size
- */
- if (s->pixelformat == V4L2_PIX_FMT_HM12)
- s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
- else
- s->mdl_size = 720 * s->cx->cxhdl.height * 2;
- s->bufs_per_mdl = s->mdl_size / s->buf_size;
- if (s->mdl_size % s->buf_size)
- s->bufs_per_mdl++;
- break;
- case CX18_ENC_STREAM_TYPE_VBI:
- s->bufs_per_mdl = 1;
- if (cx18_raw_vbi(s->cx)) {
- s->mdl_size = (s->cx->is_60hz ? 12 : 18)
- * 2 * vbi_active_samples;
- } else {
- /*
- * See comment in cx18_vbi_setup() below about the
- * extra lines we capture in sliced VBI mode due to
- * the lines on which EAV RP codes toggle.
- */
- s->mdl_size = s->cx->is_60hz
- ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz
- : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz;
- }
- break;
- default:
- s->bufs_per_mdl = 1;
- s->mdl_size = s->buf_size * s->bufs_per_mdl;
- break;
- }
-
- cx18_load_queues(s);
-}
-
-int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
-{
- u32 data[MAX_MB_ARGUMENTS];
- struct cx18 *cx = s->cx;
- int captype = 0;
- struct cx18_stream *s_idx;
-
- if (!cx18_stream_enabled(s))
- return -EINVAL;
-
- CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
-
- switch (s->type) {
- case CX18_ENC_STREAM_TYPE_MPG:
- captype = CAPTURE_CHANNEL_TYPE_MPEG;
- cx->mpg_data_received = cx->vbi_data_inserted = 0;
- cx->dualwatch_jiffies = jiffies;
- cx->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
- cx->search_pack_header = 0;
- break;
-
- case CX18_ENC_STREAM_TYPE_IDX:
- captype = CAPTURE_CHANNEL_TYPE_INDEX;
- break;
- case CX18_ENC_STREAM_TYPE_TS:
- captype = CAPTURE_CHANNEL_TYPE_TS;
- break;
- case CX18_ENC_STREAM_TYPE_YUV:
- captype = CAPTURE_CHANNEL_TYPE_YUV;
- break;
- case CX18_ENC_STREAM_TYPE_PCM:
- captype = CAPTURE_CHANNEL_TYPE_PCM;
- break;
- case CX18_ENC_STREAM_TYPE_VBI:
-#ifdef CX18_ENCODER_PARSES_SLICED
- captype = cx18_raw_vbi(cx) ?
- CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
-#else
- /*
- * Currently we set things up so that Sliced VBI from the
- * digitizer is handled as Raw VBI by the encoder
- */
- captype = CAPTURE_CHANNEL_TYPE_VBI;
-#endif
- cx->vbi.frame = 0;
- cx->vbi.inserted_frame = 0;
- memset(cx->vbi.sliced_mpeg_size,
- 0, sizeof(cx->vbi.sliced_mpeg_size));
- break;
- default:
- return -EINVAL;
- }
-
- /* Clear Streamoff flags in case left from last capture */
- clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
-
- cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE);
- s->handle = data[0];
- cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
-
- /*
- * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
- * set up all the parameters, as it is not obvious which parameters the
- * firmware shares across capture channel types and which it does not.
- *
- * Some of the cx18_vapi() calls below apply to only certain capture
- * channel types. We're hoping there's no harm in calling most of them
- * anyway, as long as the values are all consistent. Setting some
- * shared parameters will have no effect once an analog capture channel
- * has started streaming.
- */
- if (captype != CAPTURE_CHANNEL_TYPE_TS) {
- cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
-
- /*
- * Audio related reset according to
- * Documentation/video4linux/cx2341x/fw-encoder-api.txt
- */
- if (atomic_read(&cx->ana_capturing) == 0)
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
- s->handle, 12);
-
- /*
- * Number of lines for Field 1 & Field 2 according to
- * Documentation/video4linux/cx2341x/fw-encoder-api.txt
- * Field 1 is 312 for 625 line systems in BT.656
- * Field 2 is 313 for 625 line systems in BT.656
- */
- cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
- s->handle, 312, 313);
-
- if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
- cx18_vbi_setup(s);
-
- /*
- * Select to receive I, P, and B frame index entries, if the
- * index stream is enabled. Otherwise disable index entry
- * generation.
- */
- s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2,
- s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
-
- /* Call out to the common CX2341x API setup for user controls */
- cx->cxhdl.priv = s;
- cx2341x_handler_setup(&cx->cxhdl);
-
- /*
- * When starting a capture and we're set for radio,
- * ensure the video is muted, despite the user control.
- */
- if (!cx->cxhdl.video_mute &&
- test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
- cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
- (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
-
- /* Enable the Video Format Converter for UYVY 4:2:2 support,
- * rather than the default HM12 Macroblovk 4:2:0 support.
- */
- if (captype == CAPTURE_CHANNEL_TYPE_YUV) {
- if (s->pixelformat == V4L2_PIX_FMT_UYVY)
- cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
- s->handle, 1);
- else
- /* If in doubt, default to HM12 */
- cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
- s->handle, 0);
- }
- }
-
- if (atomic_read(&cx->tot_capturing) == 0) {
- cx2341x_handler_set_busy(&cx->cxhdl, 1);
- clear_bit(CX18_F_I_EOS, &cx->i_flags);
- cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
- }
-
- cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
- (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
- (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
-
- /* Init all the cpu_mdls for this stream */
- cx18_stream_configure_mdls(s);
- _cx18_stream_load_fw_queue(s);
-
- /* begin_capture */
- if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
- CX18_DEBUG_WARN("Error starting capture!\n");
- /* Ensure we're really not capturing before releasing MDLs */
- set_bit(CX18_F_S_STOPPING, &s->s_flags);
- if (s->type == CX18_ENC_STREAM_TYPE_MPG)
- cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
- else
- cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
- clear_bit(CX18_F_S_STREAMING, &s->s_flags);
- /* FIXME - CX18_F_S_STREAMOFF as well? */
- cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
- cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
- s->handle = CX18_INVALID_TASK_HANDLE;
- clear_bit(CX18_F_S_STOPPING, &s->s_flags);
- if (atomic_read(&cx->tot_capturing) == 0) {
- set_bit(CX18_F_I_EOS, &cx->i_flags);
- cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
- }
- return -EINVAL;
- }
-
- /* you're live! sit back and await interrupts :) */
- if (captype != CAPTURE_CHANNEL_TYPE_TS)
- atomic_inc(&cx->ana_capturing);
- atomic_inc(&cx->tot_capturing);
- return 0;
-}
-EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);
-
-void cx18_stop_all_captures(struct cx18 *cx)
-{
- int i;
-
- for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
- struct cx18_stream *s = &cx->streams[i];
-
- if (!cx18_stream_enabled(s))
- continue;
- if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
- cx18_stop_v4l2_encode_stream(s, 0);
- }
-}
-
-int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
-{
- struct cx18 *cx = s->cx;
-
- if (!cx18_stream_enabled(s))
- return -EINVAL;
-
- /* This function assumes that you are allowed to stop the capture
- and that we are actually capturing */
-
- CX18_DEBUG_INFO("Stop Capture\n");
-
- if (atomic_read(&cx->tot_capturing) == 0)
- return 0;
-
- set_bit(CX18_F_S_STOPPING, &s->s_flags);
- if (s->type == CX18_ENC_STREAM_TYPE_MPG)
- cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
- else
- cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
-
- if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
- CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
- }
-
- if (s->type != CX18_ENC_STREAM_TYPE_TS)
- atomic_dec(&cx->ana_capturing);
- atomic_dec(&cx->tot_capturing);
-
- /* Clear capture and no-read bits */
- clear_bit(CX18_F_S_STREAMING, &s->s_flags);
-
- /* Tell the CX23418 it can't use our buffers anymore */
- cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
-
- cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
- s->handle = CX18_INVALID_TASK_HANDLE;
- clear_bit(CX18_F_S_STOPPING, &s->s_flags);
-
- if (atomic_read(&cx->tot_capturing) > 0)
- return 0;
-
- cx2341x_handler_set_busy(&cx->cxhdl, 0);
- cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
- wake_up(&s->waitq);
-
- return 0;
-}
-EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);
-
-u32 cx18_find_handle(struct cx18 *cx)
-{
- int i;
-
- /* find first available handle to be used for global settings */
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- struct cx18_stream *s = &cx->streams[i];
-
- if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
- return s->handle;
- }
- return CX18_INVALID_TASK_HANDLE;
-}
-
-struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
-{
- int i;
- struct cx18_stream *s;
-
- if (handle == CX18_INVALID_TASK_HANDLE)
- return NULL;
-
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- s = &cx->streams[i];
- if (s->handle != handle)
- continue;
- if (cx18_stream_enabled(s))
- return s;
- }
- return NULL;
-}
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
deleted file mode 100644
index 713b0e61536d..000000000000
--- a/drivers/media/video/cx18/cx18-streams.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * cx18 init/start/stop/exit stream functions
- *
- * Derived from ivtv-streams.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-u32 cx18_find_handle(struct cx18 *cx);
-struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle);
-int cx18_streams_setup(struct cx18 *cx);
-int cx18_streams_register(struct cx18 *cx);
-void cx18_streams_cleanup(struct cx18 *cx, int unregister);
-
-#define CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN (3)
-void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
-
-static inline bool cx18_stream_enabled(struct cx18_stream *s)
-{
- return s->video_dev ||
- (s->dvb && s->dvb->enabled) ||
- (s->type == CX18_ENC_STREAM_TYPE_IDX &&
- s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
-}
-
-/* Related to submission of mdls to firmware */
-static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
-{
- schedule_work(&s->out_work_order);
-}
-
-static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- /* Put mdl on q_free; the out work handler will move mdl(s) to q_busy */
- cx18_enqueue(s, mdl, &s->q_free);
- cx18_stream_load_fw_queue(s);
-}
-
-void cx18_out_work_handler(struct work_struct *work);
-
-/* Capture related */
-int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
-int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
-
-void cx18_stop_all_captures(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
deleted file mode 100644
index 6d3121ff45a2..000000000000
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * cx18 Vertical Blank Interval support functions
- *
- * Derived from ivtv-vbi.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-vbi.h"
-#include "cx18-ioctl.h"
-#include "cx18-queue.h"
-
-/*
- * Raster Reference/Protection (RP) bytes, used in Start/End Active
- * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start
- * of VBI sample or VBI ancillary data regions in the digitial ratser line.
- *
- * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0
- */
-static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */
-static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */
-
-static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
-{
- int line = 0;
- int i;
- u32 linemask[2] = { 0, 0 };
- unsigned short size;
- static const u8 mpeg_hdr_data[] = {
- /* MPEG-2 Program Pack */
- 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */
- 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */
- 0x01, 0xd1, 0xd3, /* Mux Rate, markers */
- 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */
- /* MPEG-2 Private Stream 1 PES Packet */
- 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */
- 0x00, 0x1a, /* length */
- 0x84, 0x80, 0x07, /* flags, hdr data len */
- 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
- 0xff, 0xff /* stuffing */
- };
- const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
- int idx = cx->vbi.frame % CX18_VBI_FRAMES;
- u8 *dst = &cx->vbi.sliced_mpeg_data[idx][0];
-
- for (i = 0; i < lines; i++) {
- struct v4l2_sliced_vbi_data *sdata = cx->vbi.sliced_data + i;
- int f, l;
-
- if (sdata->id == 0)
- continue;
-
- l = sdata->line - 6;
- f = sdata->field;
- if (f)
- l += 18;
- if (l < 32)
- linemask[0] |= (1 << l);
- else
- linemask[1] |= (1 << (l - 32));
- dst[sd + 12 + line * 43] = cx18_service2vbi(sdata->id);
- memcpy(dst + sd + 12 + line * 43 + 1, sdata->data, 42);
- line++;
- }
- memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
- if (line == 36) {
- /* All lines are used, so there is no space for the linemask
- (the max size of the VBI data is 36 * 43 + 4 bytes).
- So in this case we use the magic number 'ITV0'. */
- memcpy(dst + sd, "ITV0", 4);
- memcpy(dst + sd + 4, dst + sd + 12, line * 43);
- size = 4 + ((43 * line + 3) & ~3);
- } else {
- memcpy(dst + sd, "itv0", 4);
- cpu_to_le32s(&linemask[0]);
- cpu_to_le32s(&linemask[1]);
- memcpy(dst + sd + 4, &linemask[0], 8);
- size = 12 + ((43 * line + 3) & ~3);
- }
- dst[4+16] = (size + 10) >> 8;
- dst[5+16] = (size + 10) & 0xff;
- dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
- dst[10+16] = (pts_stamp >> 22) & 0xff;
- dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
- dst[12+16] = (pts_stamp >> 7) & 0xff;
- dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
- cx->vbi.sliced_mpeg_size[idx] = sd + size;
-}
-
-/* Compress raw VBI format, removes leading SAV codes and surplus space
- after the frame. Returns new compressed size. */
-/* FIXME - this function ignores the input size. */
-static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
-{
- u32 line_size = vbi_active_samples;
- u32 lines = cx->vbi.count * 2;
- u8 *q = buf;
- u8 *p;
- int i;
-
- /* Skip the header */
- buf += hdr_size;
-
- for (i = 0; i < lines; i++) {
- p = buf + i * line_size;
-
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] ||
- (p[3] != raw_vbi_sav_rp[0] &&
- p[3] != raw_vbi_sav_rp[1]))
- break;
- if (i == lines - 1) {
- /* last line is hdr_size bytes short - extrapolate it */
- memcpy(q, p + 4, line_size - 4 - hdr_size);
- q += line_size - 4 - hdr_size;
- p += line_size - hdr_size - 1;
- memset(q, (int) *p, hdr_size);
- } else {
- memcpy(q, p + 4, line_size - 4);
- q += line_size - 4;
- }
- }
- return lines * (line_size - 4);
-}
-
-static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
- const u32 hdr_size)
-{
- struct v4l2_decode_vbi_line vbi;
- int i;
- u32 line = 0;
- u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
- : vbi_hblank_samples_50Hz;
-
- /* find the first valid line */
- for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
- if (buf[0] == 0xff && !buf[1] && !buf[2] &&
- (buf[3] == sliced_vbi_eav_rp[0] ||
- buf[3] == sliced_vbi_eav_rp[1]))
- break;
- }
-
- /*
- * The last line is short by hdr_size bytes, but for the remaining
- * checks against size, we pretend that it is not, by counting the
- * header bytes we knowingly skipped
- */
- size -= (i - hdr_size);
- if (size < line_size)
- return line;
-
- for (i = 0; i < size / line_size; i++) {
- u8 *p = buf + i * line_size;
-
- /* Look for EAV code */
- if (p[0] != 0xff || p[1] || p[2] ||
- (p[3] != sliced_vbi_eav_rp[0] &&
- p[3] != sliced_vbi_eav_rp[1]))
- continue;
- vbi.p = p + 4;
- v4l2_subdev_call(cx->sd_av, vbi, decode_vbi_line, &vbi);
- if (vbi.type) {
- cx->vbi.sliced_data[line].id = vbi.type;
- cx->vbi.sliced_data[line].field = vbi.is_second_field;
- cx->vbi.sliced_data[line].line = vbi.line;
- memcpy(cx->vbi.sliced_data[line].data, vbi.p, 42);
- line++;
- }
- }
- return line;
-}
-
-static void _cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf)
-{
- /*
- * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
- * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp]
- */
- struct vbi_data_hdr {
- __be32 magic;
- __be32 unknown;
- __be32 pts;
- } *hdr = (struct vbi_data_hdr *) buf->buf;
-
- u8 *p = (u8 *) buf->buf;
- u32 size = buf->bytesused;
- u32 pts;
- int lines;
-
- /*
- * The CX23418 sends us data that is 32 bit little-endian swapped,
- * but we want the raw VBI bytes in the order they were in the raster
- * line. This has a side effect of making the header big endian
- */
- cx18_buf_swap(buf);
-
- /* Raw VBI data */
- if (cx18_raw_vbi(cx)) {
-
- size = buf->bytesused =
- compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr));
-
- /*
- * Hack needed for compatibility with old VBI software.
- * Write the frame # at the last 4 bytes of the frame
- */
- p += size - 4;
- memcpy(p, &cx->vbi.frame, 4);
- cx->vbi.frame++;
- return;
- }
-
- /* Sliced VBI data with data insertion */
-
- pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts)
- : 0;
-
- lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr));
-
- /* always return at least one empty line */
- if (lines == 0) {
- cx->vbi.sliced_data[0].id = 0;
- cx->vbi.sliced_data[0].line = 0;
- cx->vbi.sliced_data[0].field = 0;
- lines = 1;
- }
- buf->bytesused = size = lines * sizeof(cx->vbi.sliced_data[0]);
- memcpy(p, &cx->vbi.sliced_data[0], size);
-
- if (cx->vbi.insert_mpeg)
- copy_vbi_data(cx, lines, pts);
- cx->vbi.frame++;
-}
-
-void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
- int streamtype)
-{
- struct cx18_buffer *buf;
- u32 orig_used;
-
- if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
- return;
-
- /*
- * Big assumption here:
- * Every buffer hooked to the MDL's buf_list is a complete VBI frame
- * that ends at the end of the buffer.
- *
- * To assume anything else would make the code in this file
- * more complex, or require extra memcpy()'s to make the
- * buffers satisfy the above assumption. It's just simpler to set
- * up the encoder buffer transfers to make the assumption true.
- */
- list_for_each_entry(buf, &mdl->buf_list, list) {
- orig_used = buf->bytesused;
- if (orig_used == 0)
- break;
- _cx18_process_vbi_data(cx, buf);
- mdl->bytesused -= (orig_used - buf->bytesused);
- }
-}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
deleted file mode 100644
index b365cf4b4668..000000000000
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * cx18 Vertical Blank Interval support functions
- *
- * Derived from ivtv-vbi.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
- int streamtype);
-int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
deleted file mode 100644
index fed48b6bb67b..000000000000
--- a/drivers/media/video/cx18/cx18-version.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * cx18 driver version information
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX18_VERSION_H
-#define CX18_VERSION_H
-
-#define CX18_DRIVER_NAME "cx18"
-#define CX18_VERSION "1.5.1"
-
-#endif
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
deleted file mode 100644
index 6dc84aac8f44..000000000000
--- a/drivers/media/video/cx18/cx18-video.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * cx18 video interface functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-video.h"
-#include "cx18-cards.h"
-
-void cx18_video_set_io(struct cx18 *cx)
-{
- int inp = cx->active_input;
-
- v4l2_subdev_call(cx->sd_av, video, s_routing,
- cx->card->video_inputs[inp].video_input, 0, 0);
-}
diff --git a/drivers/media/video/cx18/cx18-video.h b/drivers/media/video/cx18/cx18-video.h
deleted file mode 100644
index 529006a06e5c..000000000000
--- a/drivers/media/video/cx18/cx18-video.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * cx18 video interface functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-void cx18_video_set_io(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
deleted file mode 100644
index 767a8d23e3f2..000000000000
--- a/drivers/media/video/cx18/cx23418.h
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * cx18 header containing common defines.
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX23418_H
-#define CX23418_H
-
-#include <media/cx2341x.h>
-
-#define MGR_CMD_MASK 0x40000000
-/* The MSB of the command code indicates that this is the completion of a
- command */
-#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000)
-
-/* Description: This command creates a new instance of a certain task
- IN[0] - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is
- the processor on which the task YYY will be created
- OUT[0] - Task handle. This handle is passed along with commands to
- dispatch to the right instance of the task
- ReturnCode - One of the ERR_SYS_... */
-#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001)
-
-/* Description: This command destroys an instance of a task
- IN[0] - Task handle. Hanlde of the task to destroy
- ReturnCode - One of the ERR_SYS_... */
-#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002)
-
-/* All commands for CPU have the following mask set */
-#define CPU_CMD_MASK 0x20000000
-#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000)
-#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
-#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
-#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
-
-#define EPU_CMD_MASK 0x02000000
-#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000)
-#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000)
-
-#define APU_CMD_MASK 0x10000000
-#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
-
-#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28)
-#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28)
-
-/* Description: Command APU to start audio
- IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?)
- IN[1] - caller buffer address, or 0
- ReturnCode - ??? */
-#define CX18_APU_START (APU_CMD_MASK | 0x01)
-
-/* Description: Command APU to stop audio
- IN[0] - encoding method to stop
- ReturnCode - ??? */
-#define CX18_APU_STOP (APU_CMD_MASK | 0x02)
-
-/* Description: Command APU to reset the AI
- ReturnCode - ??? */
-#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
-
-/* Description: This command indicates that a Memory Descriptor List has been
- filled with the requested channel type
- IN[0] - Task handle. Handle of the task
- IN[1] - Offset of the MDL_ACK from the beginning of the local DDR.
- IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1]
- ReturnCode - One of the ERR_DE_... */
-#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001)
-
-/* Something interesting happened
- IN[0] - A value to log
- IN[1] - An offset of a string in the MiniMe memory;
- 0/zero/NULL means "I have nothing to say" */
-#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)
-
-/* Reads memory/registers (32-bit)
- IN[0] - Address
- OUT[1] - Value */
-#define CX18_CPU_DEBUG_PEEK32 (CPU_CMD_MASK_DEBUG | 0x0003)
-
-/* Description: This command starts streaming with the set channel type
- IN[0] - Task handle. Handle of the task to start
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002)
-
-/* Description: This command stops streaming with the set channel type
- IN[0] - Task handle. Handle of the task to stop
- IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only)
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003)
-
-/* Description: This command pauses streaming with the set channel type
- IN[0] - Task handle. Handle of the task to pause
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007)
-
-/* Description: This command resumes streaming with the set channel type
- IN[0] - Task handle. Handle of the task to resume
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008)
-
-#define CAPTURE_CHANNEL_TYPE_NONE 0
-#define CAPTURE_CHANNEL_TYPE_MPEG 1
-#define CAPTURE_CHANNEL_TYPE_INDEX 2
-#define CAPTURE_CHANNEL_TYPE_YUV 3
-#define CAPTURE_CHANNEL_TYPE_PCM 4
-#define CAPTURE_CHANNEL_TYPE_VBI 5
-#define CAPTURE_CHANNEL_TYPE_SLICED_VBI 6
-#define CAPTURE_CHANNEL_TYPE_TS 7
-#define CAPTURE_CHANNEL_TYPE_MAX 15
-
-/* Description: This command sets the channel type. This can only be done
- when stopped.
- IN[0] - Task handle. Handle of the task to start
- IN[1] - Channel Type. See Below.
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1)
-
-/* Description: Set stream output type
- IN[0] - task handle. Handle of the task to start
- IN[1] - type
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_STREAM_OUTPUT_TYPE (CPU_CMD_MASK_CAPTURE | 0x0012)
-
-/* Description: Set video input resolution and frame rate
- IN[0] - task handle
- IN[1] - reserved
- IN[2] - reserved
- IN[3] - reserved
- IN[4] - reserved
- IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004)
-
-/* Description: Set video frame rate
- IN[0] - task handle. Handle of the task to start
- IN[1] - video bit rate mode
- IN[2] - video average rate
- IN[3] - video peak rate
- IN[4] - system mux rate
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005)
-
-/* Description: Set video output resolution
- IN[0] - task handle
- IN[1] - horizontal size
- IN[2] - vertical size
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_RESOLUTION (CPU_CMD_MASK_CAPTURE | 0x0006)
-
-/* Description: This command set filter parameters
- IN[0] - Task handle. Handle of the task
- IN[1] - type, 0 - temporal, 1 - spatial, 2 - median
- IN[2] - mode, temporal/spatial: 0 - disable, 1 - static, 2 - dynamic
- median: 0 = disable, 1 = horizontal, 2 = vertical,
- 3 = horizontal/vertical, 4 = diagonal
- IN[3] - strength, temporal 0 - 31, spatial 0 - 15
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009)
-
-/* Description: This command set spatial filter type
- IN[0] - Task handle.
- IN[1] - luma type: 0 = disable, 1 = 1D horizontal only, 2 = 1D vertical only,
- 3 = 2D H/V separable, 4 = 2D symmetric non-separable
- IN[2] - chroma type: 0 - disable, 1 = 1D horizontal
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C)
-
-/* Description: This command set coring levels for median filter
- IN[0] - Task handle.
- IN[1] - luma_high
- IN[2] - luma_low
- IN[3] - chroma_high
- IN[4] - chroma_low
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
-
-/* Description: This command set the picture type mask for index file
- IN[0] - Task handle (ignored by firmware)
- IN[1] - 0 = disable index file output
- 1 = output I picture
- 2 = P picture
- 4 = B picture
- other = illegal */
-#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010)
-
-/* Description: Set audio parameters
- IN[0] - task handle. Handle of the task to start
- IN[1] - audio parameter
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_AUDIO_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0011)
-
-/* Description: Set video mute
- IN[0] - task handle. Handle of the task to start
- IN[1] - bit31-24: muteYvalue
- bit23-16: muteUvalue
- bit15-8: muteVvalue
- bit0: 1:mute, 0: unmute
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0013)
-
-/* Description: Set audio mute
- IN[0] - task handle. Handle of the task to start
- IN[1] - mute/unmute
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_AUDIO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0014)
-
-/* Description: Set stream output type
- IN[0] - task handle. Handle of the task to start
- IN[1] - subType
- SET_INITIAL_SCR 1
- SET_QUALITY_MODE 2
- SET_VIM_PROTECT_MODE 3
- SET_PTS_CORRECTION 4
- SET_USB_FLUSH_MODE 5
- SET_MERAQPAR_ENABLE 6
- SET_NAV_PACK_INSERTION 7
- SET_SCENE_CHANGE_ENABLE 8
- IN[2] - parameter 1
- IN[3] - parameter 2
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_MISC_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0015)
-
-/* Description: Set raw VBI parameters
- IN[0] - Task handle
- IN[1] - No. of input lines per field:
- bit[15:0]: field 1,
- bit[31:16]: field 2
- IN[2] - No. of input bytes per line
- IN[3] - No. of output frames per transfer
- IN[4] - start code
- IN[5] - stop code
- ReturnCode */
-#define CX18_CPU_SET_RAW_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0016)
-
-/* Description: Set capture line No.
- IN[0] - task handle. Handle of the task to start
- IN[1] - height1
- IN[2] - height2
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_CAPTURE_LINE_NO (CPU_CMD_MASK_CAPTURE | 0x0017)
-
-/* Description: Set copyright
- IN[0] - task handle. Handle of the task to start
- IN[1] - copyright
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_COPYRIGHT (CPU_CMD_MASK_CAPTURE | 0x0018)
-
-/* Description: Set audio PID
- IN[0] - task handle. Handle of the task to start
- IN[1] - PID
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_AUDIO_PID (CPU_CMD_MASK_CAPTURE | 0x0019)
-
-/* Description: Set video PID
- IN[0] - task handle. Handle of the task to start
- IN[1] - PID
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_PID (CPU_CMD_MASK_CAPTURE | 0x001A)
-
-/* Description: Set Vertical Crop Line
- IN[0] - task handle. Handle of the task to start
- IN[1] - Line
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VER_CROP_LINE (CPU_CMD_MASK_CAPTURE | 0x001B)
-
-/* Description: Set COP structure
- IN[0] - task handle. Handle of the task to start
- IN[1] - M
- IN[2] - N
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_GOP_STRUCTURE (CPU_CMD_MASK_CAPTURE | 0x001C)
-
-/* Description: Set Scene Change Detection
- IN[0] - task handle. Handle of the task to start
- IN[1] - scene change
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_SCENE_CHANGE_DETECTION (CPU_CMD_MASK_CAPTURE | 0x001D)
-
-/* Description: Set Aspect Ratio
- IN[0] - task handle. Handle of the task to start
- IN[1] - AspectRatio
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_ASPECT_RATIO (CPU_CMD_MASK_CAPTURE | 0x001E)
-
-/* Description: Set Skip Input Frame
- IN[0] - task handle. Handle of the task to start
- IN[1] - skip input frames
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_SKIP_INPUT_FRAME (CPU_CMD_MASK_CAPTURE | 0x001F)
-
-/* Description: Set sliced VBI parameters -
- Note This API will only apply to MPEG and Sliced VBI Channels
- IN[0] - Task handle
- IN[1] - output type, 0 - CC, 1 - Moji, 2 - Teletext
- IN[2] - start / stop line
- bit[15:0] start line number
- bit[31:16] stop line number
- IN[3] - number of output frames per interrupt
- IN[4] - VBI insertion mode
- bit 0: output user data, 1 - enable
- bit 1: output private stream, 1 - enable
- bit 2: mux option, 0 - in GOP, 1 - in picture
- bit[7:0] private stream ID
- IN[5] - insertion period while mux option is in picture
- ReturnCode - VBI data offset */
-#define CX18_CPU_SET_SLICED_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0020)
-
-/* Description: Set the user data place holder
- IN[0] - type of data (0 for user)
- IN[1] - Stuffing period
- IN[2] - ID data size in word (less than 10)
- IN[3] - Pointer to ID buffer */
-#define CX18_CPU_SET_USERDATA_PLACE_HOLDER (CPU_CMD_MASK_CAPTURE | 0x0021)
-
-
-/* Description:
- In[0] Task Handle
- return parameter:
- Out[0] Reserved
- Out[1] Video PTS bit[32:2] of last output video frame.
- Out[2] Video PTS bit[ 1:0] of last output video frame.
- Out[3] Hardware Video PTS counter bit[31:0],
- these bits get incremented on every 90kHz clock tick.
- Out[4] Hardware Video PTS counter bit32,
- these bits get incremented on every 90kHz clock tick.
- ReturnCode */
-#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022)
-
-/* Description: Set VFC parameters
- IN[0] - task handle
- IN[1] - VFC enable flag, 1 - enable, 0 - disable
-*/
-#define CX18_CPU_SET_VFC_PARAM (CPU_CMD_MASK_CAPTURE | 0x0023)
-
-/* Below is the list of commands related to the data exchange */
-#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
-
-/* Description: This command provides the physical base address of the local
- DDR as viewed by EPU
- IN[0] - Physical offset where EPU has the local DDR mapped
- ReturnCode - One of the ERR_DE_... */
-#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001)
-
-/* Description: This command provides the offsets in the device memory where
- the 2 cx18_mdl_ack blocks reside
- IN[0] - Task handle. Handle of the task to start
- IN[1] - Offset of the first cx18_mdl_ack from the beginning of the
- local DDR.
- IN[2] - Offset of the second cx18_mdl_ack from the beginning of the
- local DDR.
- ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002)
-
-/* Description: This command provides the offset to a Memory Descriptor List
- IN[0] - Task handle. Handle of the task to start
- IN[1] - Offset of the MDL from the beginning of the local DDR.
- IN[2] - Number of cx18_mdl_ent structures in the array pointed to by IN[1]
- IN[3] - Buffer ID
- IN[4] - Total buffer length
- ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005)
-
-/* Description: This command requests return of all current Memory
- Descriptor Lists to the driver
- IN[0] - Task handle. Handle of the task to start
- ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006)
-
-/* Description: This command signals the cpu that the dat buffer has been
- consumed and ready for re-use.
- IN[0] - Task handle. Handle of the task
- IN[1] - Offset of the data block from the beginning of the local DDR.
- IN[2] - Number of bytes in the data block
- ReturnCode - One of the ERR_DE_... */
-/* #define CX18_CPU_DE_RELEASE_BUFFER (CPU_CMD_MASK_DE | 0x0007) */
-
-/* No Error / Success */
-#define CNXT_OK 0x000000
-
-/* Received unknown command */
-#define CXERR_UNK_CMD 0x000001
-
-/* First parameter in the command is invalid */
-#define CXERR_INVALID_PARAM1 0x000002
-
-/* Second parameter in the command is invalid */
-#define CXERR_INVALID_PARAM2 0x000003
-
-/* Device interface is not open/found */
-#define CXERR_DEV_NOT_FOUND 0x000004
-
-/* Requested function is not implemented/available */
-#define CXERR_NOTSUPPORTED 0x000005
-
-/* Invalid pointer is provided */
-#define CXERR_BADPTR 0x000006
-
-/* Unable to allocate memory */
-#define CXERR_NOMEM 0x000007
-
-/* Object/Link not found */
-#define CXERR_LINK 0x000008
-
-/* Device busy, command cannot be executed */
-#define CXERR_BUSY 0x000009
-
-/* File/device/handle is not open. */
-#define CXERR_NOT_OPEN 0x00000A
-
-/* Value is out of range */
-#define CXERR_OUTOFRANGE 0x00000B
-
-/* Buffer overflow */
-#define CXERR_OVERFLOW 0x00000C
-
-/* Version mismatch */
-#define CXERR_BADVER 0x00000D
-
-/* Operation timed out */
-#define CXERR_TIMEOUT 0x00000E
-
-/* Operation aborted */
-#define CXERR_ABORT 0x00000F
-
-/* Specified I2C device not found for read/write */
-#define CXERR_I2CDEV_NOTFOUND 0x000010
-
-/* Error in I2C data xfer (but I2C device is present) */
-#define CXERR_I2CDEV_XFERERR 0x000011
-
-/* Chanel changing component not ready */
-#define CXERR_CHANNELNOTREADY 0x000012
-
-/* PPU (Presensation/Decoder) mail box is corrupted */
-#define CXERR_PPU_MB_CORRUPT 0x000013
-
-/* CPU (Capture/Encoder) mail box is corrupted */
-#define CXERR_CPU_MB_CORRUPT 0x000014
-
-/* APU (Audio) mail box is corrupted */
-#define CXERR_APU_MB_CORRUPT 0x000015
-
-/* Unable to open file for reading */
-#define CXERR_FILE_OPEN_READ 0x000016
-
-/* Unable to open file for writing */
-#define CXERR_FILE_OPEN_WRITE 0x000017
-
-/* Unable to find the I2C section specified */
-#define CXERR_I2C_BADSECTION 0x000018
-
-/* Error in I2C data xfer (but I2C device is present) */
-#define CXERR_I2CDEV_DATALOW 0x000019
-
-/* Error in I2C data xfer (but I2C device is present) */
-#define CXERR_I2CDEV_CLOCKLOW 0x00001A
-
-/* No Interrupt received from HW (for I2C access) */
-#define CXERR_NO_HW_I2C_INTR 0x00001B
-
-/* RPU is not ready to accept commands! */
-#define CXERR_RPU_NOT_READY 0x00001C
-
-/* RPU is not ready to accept commands! */
-#define CXERR_RPU_NO_ACK 0x00001D
-
-/* The are no buffers ready. Try again soon! */
-#define CXERR_NODATA_AGAIN 0x00001E
-
-/* The stream is stopping. Function not allowed now! */
-#define CXERR_STOPPING_STATUS 0x00001F
-
-/* Trying to access hardware when the power is turned OFF */
-#define CXERR_DEVPOWER_OFF 0x000020
-
-#endif /* CX23418_H */