aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/video/cx18
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
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.c360
-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.c223
-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.c1357
-rw-r--r--drivers/media/video/cx18/cx18-driver.h735
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c605
-rw-r--r--drivers/media/video/cx18/cx18-dvb.h25
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c896
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h41
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c448
-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.c1212
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.h33
-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.c869
-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.c1050
-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, 15283 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
new file mode 100644
index 00000000000..53b3c770257
--- /dev/null
+++ b/drivers/media/video/cx18/Kconfig
@@ -0,0 +1,35 @@
1config VIDEO_CX18
2 tristate "Conexant cx23418 MPEG encoder support"
3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
4 select I2C_ALGOBIT
5 select VIDEOBUF_VMALLOC
6 depends on RC_CORE
7 select VIDEO_TUNER
8 select VIDEO_TVEEPROM
9 select VIDEO_CX2341X
10 select VIDEO_CS5345
11 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
12 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
13 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
14 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
15 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
16 ---help---
17 This is a video4linux driver for Conexant cx23418 based
18 PCI combo video recorder devices.
19
20 This is used in devices such as the Hauppauge HVR-1600
21 cards.
22
23 To compile this driver as a module, choose M here: the
24 module will be called cx18.
25
26config VIDEO_CX18_ALSA
27 tristate "Conexant 23418 DMA audio support"
28 depends on VIDEO_CX18 && SND && EXPERIMENTAL
29 select SND_PCM
30 ---help---
31 This is a video4linux driver for direct (DMA) audio on
32 Conexant 23418 based TV cards using ALSA.
33
34 To compile this driver as a module, choose M here: the
35 module will be called cx18-alsa.
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile
new file mode 100644
index 00000000000..2fadd9ded34
--- /dev/null
+++ b/drivers/media/video/cx18/Makefile
@@ -0,0 +1,13 @@
1cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \
2 cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
5 cx18-dvb.o cx18-io.o
6cx18-alsa-objs := cx18-alsa-main.o cx18-alsa-pcm.o
7
8obj-$(CONFIG_VIDEO_CX18) += cx18.o
9obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
10
11EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
12EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
13EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
new file mode 100644
index 00000000000..a1e6c2a3247
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-main.c
@@ -0,0 +1,295 @@
1/*
2 * ALSA interface to cx18 PCM capture streams
3 *
4 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
5 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
6 *
7 * Portions of this work were sponsored by ONELAN Limited.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include <linux/init.h>
26#include <linux/slab.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/device.h>
30#include <linux/spinlock.h>
31
32#include <media/v4l2-device.h>
33
34#include <sound/core.h>
35#include <sound/initval.h>
36
37#include "cx18-driver.h"
38#include "cx18-version.h"
39#include "cx18-alsa.h"
40#include "cx18-alsa-mixer.h"
41#include "cx18-alsa-pcm.h"
42
43int cx18_alsa_debug;
44
45#define CX18_DEBUG_ALSA_INFO(fmt, arg...) \
46 do { \
47 if (cx18_alsa_debug & 2) \
48 printk(KERN_INFO "%s: " fmt, "cx18-alsa", ## arg); \
49 } while (0);
50
51module_param_named(debug, cx18_alsa_debug, int, 0644);
52MODULE_PARM_DESC(debug,
53 "Debug level (bitmask). Default: 0\n"
54 "\t\t\t 1/0x0001: warning\n"
55 "\t\t\t 2/0x0002: info\n");
56
57MODULE_AUTHOR("Andy Walls");
58MODULE_DESCRIPTION("CX23418 ALSA Interface");
59MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
60MODULE_LICENSE("GPL");
61
62MODULE_VERSION(CX18_VERSION);
63
64static inline
65struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
66{
67 return to_cx18(v4l2_dev)->alsa;
68}
69
70static inline
71struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
72{
73 return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
74}
75
76static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
77{
78 if (cxsc == NULL)
79 return;
80
81 if (cxsc->v4l2_dev != NULL)
82 to_cx18(cxsc->v4l2_dev)->alsa = NULL;
83
84 /* FIXME - take any other stopping actions needed */
85
86 kfree(cxsc);
87}
88
89static void snd_cx18_card_private_free(struct snd_card *sc)
90{
91 if (sc == NULL)
92 return;
93 snd_cx18_card_free(sc->private_data);
94 sc->private_data = NULL;
95 sc->private_free = NULL;
96}
97
98static int snd_cx18_card_create(struct v4l2_device *v4l2_dev,
99 struct snd_card *sc,
100 struct snd_cx18_card **cxsc)
101{
102 *cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL);
103 if (*cxsc == NULL)
104 return -ENOMEM;
105
106 (*cxsc)->v4l2_dev = v4l2_dev;
107 (*cxsc)->sc = sc;
108
109 sc->private_data = *cxsc;
110 sc->private_free = snd_cx18_card_private_free;
111
112 return 0;
113}
114
115static int snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
116{
117 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
118 struct snd_card *sc = cxsc->sc;
119
120 /* sc->driver is used by alsa-lib's configurator: simple, unique */
121 strlcpy(sc->driver, "CX23418", sizeof(sc->driver));
122
123 /* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
124 snprintf(sc->shortname, sizeof(sc->shortname), "CX18-%d",
125 cx->instance);
126
127 /* sc->longname is read from /proc/asound/cards */
128 snprintf(sc->longname, sizeof(sc->longname),
129 "CX23418 #%d %s TV/FM Radio/Line-In Capture",
130 cx->instance, cx->card_name);
131
132 return 0;
133}
134
135static int snd_cx18_init(struct v4l2_device *v4l2_dev)
136{
137 struct cx18 *cx = to_cx18(v4l2_dev);
138 struct snd_card *sc = NULL;
139 struct snd_cx18_card *cxsc;
140 int ret;
141
142 /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
143
144 /* (1) Check and increment the device index */
145 /* This is a no-op for us. We'll use the cx->instance */
146
147 /* (2) Create a card instance */
148 ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
149 SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
150 THIS_MODULE, 0, &sc);
151 if (ret) {
152 CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
153 __func__, ret);
154 goto err_exit;
155 }
156
157 /* (3) Create a main component */
158 ret = snd_cx18_card_create(v4l2_dev, sc, &cxsc);
159 if (ret) {
160 CX18_ALSA_ERR("%s: snd_cx18_card_create() failed with err %d\n",
161 __func__, ret);
162 goto err_exit_free;
163 }
164
165 /* (4) Set the driver ID and name strings */
166 snd_cx18_card_set_names(cxsc);
167
168
169 ret = snd_cx18_pcm_create(cxsc);
170 if (ret) {
171 CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
172 __func__, ret);
173 goto err_exit_free;
174 }
175 /* FIXME - proc files */
176
177 /* (7) Set the driver data and return 0 */
178 /* We do this out of normal order for PCI drivers to avoid races */
179 cx->alsa = cxsc;
180
181 /* (6) Register the card instance */
182 ret = snd_card_register(sc);
183 if (ret) {
184 cx->alsa = NULL;
185 CX18_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
186 __func__, ret);
187 goto err_exit_free;
188 }
189
190 return 0;
191
192err_exit_free:
193 if (sc != NULL)
194 snd_card_free(sc);
195 kfree(cxsc);
196err_exit:
197 return ret;
198}
199
200int cx18_alsa_load(struct cx18 *cx)
201{
202 struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
203 struct cx18_stream *s;
204
205 if (v4l2_dev == NULL) {
206 printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
207 __func__);
208 return 0;
209 }
210
211 cx = to_cx18(v4l2_dev);
212 if (cx == NULL) {
213 printk(KERN_ERR "cx18-alsa cx is NULL\n");
214 return 0;
215 }
216
217 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
218 if (s->video_dev == NULL) {
219 CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
220 "skipping\n", __func__);
221 return 0;
222 }
223
224 if (cx->alsa != NULL) {
225 CX18_ALSA_ERR("%s: struct snd_cx18_card * already exists\n",
226 __func__);
227 return 0;
228 }
229
230 if (snd_cx18_init(v4l2_dev)) {
231 CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n",
232 __func__);
233 } else {
234 CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance "
235 "\n", __func__);
236 }
237 return 0;
238}
239
240static int __init cx18_alsa_init(void)
241{
242 printk(KERN_INFO "cx18-alsa: module loading...\n");
243 cx18_ext_init = &cx18_alsa_load;
244 return 0;
245}
246
247static void __exit snd_cx18_exit(struct snd_cx18_card *cxsc)
248{
249 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
250
251 /* FIXME - pointer checks & shutdown cxsc */
252
253 snd_card_free(cxsc->sc);
254 cx->alsa = NULL;
255}
256
257static int __exit cx18_alsa_exit_callback(struct device *dev, void *data)
258{
259 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
260 struct snd_cx18_card *cxsc;
261
262 if (v4l2_dev == NULL) {
263 printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
264 __func__);
265 return 0;
266 }
267
268 cxsc = to_snd_cx18_card(v4l2_dev);
269 if (cxsc == NULL) {
270 CX18_ALSA_WARN("%s: struct snd_cx18_card * is NULL\n",
271 __func__);
272 return 0;
273 }
274
275 snd_cx18_exit(cxsc);
276 return 0;
277}
278
279static void __exit cx18_alsa_exit(void)
280{
281 struct device_driver *drv;
282 int ret;
283
284 printk(KERN_INFO "cx18-alsa: module unloading...\n");
285
286 drv = driver_find("cx18", &pci_bus_type);
287 ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
288 put_driver(drv);
289
290 cx18_ext_init = NULL;
291 printk(KERN_INFO "cx18-alsa: module unload complete\n");
292}
293
294module_init(cx18_alsa_init);
295module_exit(cx18_alsa_exit);
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/video/cx18/cx18-alsa-mixer.c
new file mode 100644
index 00000000000..341bddc00b7
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.c
@@ -0,0 +1,175 @@
1/*
2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/device.h>
26#include <linux/spinlock.h>
27#include <linux/videodev2.h>
28
29#include <media/v4l2-device.h>
30
31#include <sound/core.h>
32#include <sound/control.h>
33#include <sound/tlv.h>
34
35#include "cx18-alsa.h"
36#include "cx18-driver.h"
37
38/*
39 * Note the cx18-av-core volume scale is funny, due to the alignment of the
40 * scale with another chip's range:
41 *
42 * v4l2_control value /512 indicated dB actual dB reg 0x8d4
43 * 0x0000 - 0x01ff 0 -119 -96 228
44 * 0x0200 - 0x02ff 1 -118 -96 228
45 * ...
46 * 0x2c00 - 0x2dff 22 -97 -96 228
47 * 0x2e00 - 0x2fff 23 -96 -96 228
48 * 0x3000 - 0x31ff 24 -95 -95 226
49 * ...
50 * 0xee00 - 0xefff 119 0 0 36
51 * ...
52 * 0xfe00 - 0xffff 127 +8 +8 20
53 */
54static inline int dB_to_cx18_av_vol(int dB)
55{
56 if (dB < -96)
57 dB = -96;
58 else if (dB > 8)
59 dB = 8;
60 return (dB + 119) << 9;
61}
62
63static inline int cx18_av_vol_to_dB(int v)
64{
65 if (v < (23 << 9))
66 v = (23 << 9);
67 else if (v > (127 << 9))
68 v = (127 << 9);
69 return (v >> 9) - 119;
70}
71
72static int snd_cx18_mixer_tv_vol_info(struct snd_kcontrol *kcontrol,
73 struct snd_ctl_elem_info *uinfo)
74{
75 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
76 uinfo->count = 1;
77 /* We're already translating values, just keep this control in dB */
78 uinfo->value.integer.min = -96;
79 uinfo->value.integer.max = 8;
80 uinfo->value.integer.step = 1;
81 return 0;
82}
83
84static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl,
85 struct snd_ctl_elem_value *uctl)
86{
87 struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
88 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
89 struct v4l2_control vctrl;
90 int ret;
91
92 vctrl.id = V4L2_CID_AUDIO_VOLUME;
93 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
94
95 snd_cx18_lock(cxsc);
96 ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
97 snd_cx18_unlock(cxsc);
98
99 if (!ret)
100 uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value);
101 return ret;
102}
103
104static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl,
105 struct snd_ctl_elem_value *uctl)
106{
107 struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
108 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
109 struct v4l2_control vctrl;
110 int ret;
111
112 vctrl.id = V4L2_CID_AUDIO_VOLUME;
113 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
114
115 snd_cx18_lock(cxsc);
116
117 /* Fetch current state */
118 ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
119
120 if (ret ||
121 (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) {
122
123 /* Set, if needed */
124 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
125 ret = v4l2_subdev_call(cx->sd_av, core, s_ctrl, &vctrl);
126 if (!ret)
127 ret = 1; /* Indicate control was changed w/o error */
128 }
129 snd_cx18_unlock(cxsc);
130
131 return ret;
132}
133
134
135/* This is a bit of overkill, the slider is already in dB internally */
136static DECLARE_TLV_DB_SCALE(snd_cx18_mixer_tv_vol_db_scale, -9600, 100, 0);
137
138static struct snd_kcontrol_new snd_cx18_mixer_tv_vol __initdata = {
139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
140 .name = "Analog TV Capture Volume",
141 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
142 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
143 .info = snd_cx18_mixer_tv_volume_info,
144 .get = snd_cx18_mixer_tv_volume_get,
145 .put = snd_cx18_mixer_tv_volume_put,
146 .tlv.p = snd_cx18_mixer_tv_vol_db_scale
147};
148
149/* FIXME - add mute switch and balance, bass, treble sliders:
150 V4L2_CID_AUDIO_MUTE
151
152 V4L2_CID_AUDIO_BALANCE
153
154 V4L2_CID_AUDIO_BASS
155 V4L2_CID_AUDIO_TREBLE
156*/
157
158/* FIXME - add stereo, lang1, lang2, mono menu */
159/* FIXME - add CS5345 I2S volume for HVR-1600 */
160
161int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc)
162{
163 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
164 struct snd_card *sc = cxsc->sc;
165 int ret;
166
167 strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername));
168
169 ret = snd_ctl_add(sc, snd_ctl_new1(snd_cx18_mixer_tv_vol, cxsc));
170 if (ret) {
171 CX18_ALSA_WARN("%s: failed to add %s control, err %d\n",
172 __func__, snd_cx18_mixer_tv_vol.name, ret);
173 }
174 return ret;
175}
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/video/cx18/cx18-alsa-mixer.h
new file mode 100644
index 00000000000..ec9238793f6
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.h
@@ -0,0 +1,23 @@
1/*
2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23int __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
new file mode 100644
index 00000000000..82d195be919
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.c
@@ -0,0 +1,360 @@
1/*
2 * ALSA PCM device for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
6 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 *
8 * Portions of this work were sponsored by ONELAN Limited.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 * 02111-1307 USA
24 */
25
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/vmalloc.h>
29
30#include <media/v4l2-device.h>
31
32#include <sound/core.h>
33#include <sound/pcm.h>
34
35#include "cx18-driver.h"
36#include "cx18-queue.h"
37#include "cx18-streams.h"
38#include "cx18-fileops.h"
39#include "cx18-alsa.h"
40
41static unsigned int pcm_debug;
42module_param(pcm_debug, int, 0644);
43MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
44
45#define dprintk(fmt, arg...) do { \
46 if (pcm_debug) \
47 printk(KERN_INFO "cx18-alsa-pcm %s: " fmt, \
48 __func__, ##arg); \
49 } while (0)
50
51static struct snd_pcm_hardware snd_cx18_hw_capture = {
52 .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
53 SNDRV_PCM_INFO_MMAP |
54 SNDRV_PCM_INFO_INTERLEAVED |
55 SNDRV_PCM_INFO_MMAP_VALID,
56
57 .formats = SNDRV_PCM_FMTBIT_S16_LE,
58
59 .rates = SNDRV_PCM_RATE_48000,
60
61 .rate_min = 48000,
62 .rate_max = 48000,
63 .channels_min = 2,
64 .channels_max = 2,
65 .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
66 .period_bytes_min = 64, /* 12544/2, */
67 .period_bytes_max = 12544,
68 .periods_min = 2,
69 .periods_max = 98, /* 12544, */
70};
71
72void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
73 size_t num_bytes)
74{
75 struct snd_pcm_substream *substream;
76 struct snd_pcm_runtime *runtime;
77 unsigned int oldptr;
78 unsigned int stride;
79 int period_elapsed = 0;
80 int length;
81
82 dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
83 pcm_data, num_bytes);
84
85 substream = cxsc->capture_pcm_substream;
86 if (substream == NULL) {
87 dprintk("substream was NULL\n");
88 return;
89 }
90
91 runtime = substream->runtime;
92 if (runtime == NULL) {
93 dprintk("runtime was NULL\n");
94 return;
95 }
96
97 stride = runtime->frame_bits >> 3;
98 if (stride == 0) {
99 dprintk("stride is zero\n");
100 return;
101 }
102
103 length = num_bytes / stride;
104 if (length == 0) {
105 dprintk("%s: length was zero\n", __func__);
106 return;
107 }
108
109 if (runtime->dma_area == NULL) {
110 dprintk("dma area was NULL - ignoring\n");
111 return;
112 }
113
114 oldptr = cxsc->hwptr_done_capture;
115 if (oldptr + length >= runtime->buffer_size) {
116 unsigned int cnt =
117 runtime->buffer_size - oldptr;
118 memcpy(runtime->dma_area + oldptr * stride, pcm_data,
119 cnt * stride);
120 memcpy(runtime->dma_area, pcm_data + cnt * stride,
121 length * stride - cnt * stride);
122 } else {
123 memcpy(runtime->dma_area + oldptr * stride, pcm_data,
124 length * stride);
125 }
126 snd_pcm_stream_lock(substream);
127
128 cxsc->hwptr_done_capture += length;
129 if (cxsc->hwptr_done_capture >=
130 runtime->buffer_size)
131 cxsc->hwptr_done_capture -=
132 runtime->buffer_size;
133
134 cxsc->capture_transfer_done += length;
135 if (cxsc->capture_transfer_done >=
136 runtime->period_size) {
137 cxsc->capture_transfer_done -=
138 runtime->period_size;
139 period_elapsed = 1;
140 }
141
142 snd_pcm_stream_unlock(substream);
143
144 if (period_elapsed)
145 snd_pcm_period_elapsed(substream);
146}
147
148static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
149{
150 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
151 struct snd_pcm_runtime *runtime = substream->runtime;
152 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
153 struct cx18 *cx = to_cx18(v4l2_dev);
154 struct cx18_stream *s;
155 struct cx18_open_id item;
156 int ret;
157
158 /* Instruct the cx18 to start sending packets */
159 snd_cx18_lock(cxsc);
160 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
161
162 item.cx = cx;
163 item.type = s->type;
164 item.open_id = cx->open_id++;
165
166 /* See if the stream is available */
167 if (cx18_claim_stream(&item, item.type)) {
168 /* No, it's already in use */
169 snd_cx18_unlock(cxsc);
170 return -EBUSY;
171 }
172
173 if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
174 test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
175 /* We're already streaming. No additional action required */
176 snd_cx18_unlock(cxsc);
177 return 0;
178 }
179
180
181 runtime->hw = snd_cx18_hw_capture;
182 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
183 cxsc->capture_pcm_substream = substream;
184 runtime->private_data = cx;
185
186 cx->pcm_announce_callback = cx18_alsa_announce_pcm_data;
187
188 /* Not currently streaming, so start it up */
189 set_bit(CX18_F_S_STREAMING, &s->s_flags);
190 ret = cx18_start_v4l2_encode_stream(s);
191 snd_cx18_unlock(cxsc);
192
193 return 0;
194}
195
196static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
197{
198 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
199 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
200 struct cx18 *cx = to_cx18(v4l2_dev);
201 struct cx18_stream *s;
202 int ret;
203
204 /* Instruct the cx18 to stop sending packets */
205 snd_cx18_lock(cxsc);
206 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
207 ret = cx18_stop_v4l2_encode_stream(s, 0);
208 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
209
210 cx18_release_stream(s);
211
212 cx->pcm_announce_callback = NULL;
213 snd_cx18_unlock(cxsc);
214
215 return 0;
216}
217
218static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
219 unsigned int cmd, void *arg)
220{
221 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
222 int ret;
223
224 snd_cx18_lock(cxsc);
225 ret = snd_pcm_lib_ioctl(substream, cmd, arg);
226 snd_cx18_unlock(cxsc);
227 return ret;
228}
229
230
231static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
232 size_t size)
233{
234 struct snd_pcm_runtime *runtime = subs->runtime;
235
236 dprintk("Allocating vbuffer\n");
237 if (runtime->dma_area) {
238 if (runtime->dma_bytes > size)
239 return 0;
240
241 vfree(runtime->dma_area);
242 }
243 runtime->dma_area = vmalloc(size);
244 if (!runtime->dma_area)
245 return -ENOMEM;
246
247 runtime->dma_bytes = size;
248
249 return 0;
250}
251
252static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
253 struct snd_pcm_hw_params *params)
254{
255 int ret;
256
257 dprintk("%s called\n", __func__);
258
259 ret = snd_pcm_alloc_vmalloc_buffer(substream,
260 params_buffer_bytes(params));
261 return 0;
262}
263
264static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
265{
266 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
267 unsigned long flags;
268
269 spin_lock_irqsave(&cxsc->slock, flags);
270 if (substream->runtime->dma_area) {
271 dprintk("freeing pcm capture region\n");
272 vfree(substream->runtime->dma_area);
273 substream->runtime->dma_area = NULL;
274 }
275 spin_unlock_irqrestore(&cxsc->slock, flags);
276
277 return 0;
278}
279
280static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
281{
282 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
283
284 cxsc->hwptr_done_capture = 0;
285 cxsc->capture_transfer_done = 0;
286
287 return 0;
288}
289
290static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
291{
292 return 0;
293}
294
295static
296snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
297{
298 unsigned long flags;
299 snd_pcm_uframes_t hwptr_done;
300 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
301
302 spin_lock_irqsave(&cxsc->slock, flags);
303 hwptr_done = cxsc->hwptr_done_capture;
304 spin_unlock_irqrestore(&cxsc->slock, flags);
305
306 return hwptr_done;
307}
308
309static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
310 unsigned long offset)
311{
312 void *pageptr = subs->runtime->dma_area + offset;
313
314 return vmalloc_to_page(pageptr);
315}
316
317static struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
318 .open = snd_cx18_pcm_capture_open,
319 .close = snd_cx18_pcm_capture_close,
320 .ioctl = snd_cx18_pcm_ioctl,
321 .hw_params = snd_cx18_pcm_hw_params,
322 .hw_free = snd_cx18_pcm_hw_free,
323 .prepare = snd_cx18_pcm_prepare,
324 .trigger = snd_cx18_pcm_trigger,
325 .pointer = snd_cx18_pcm_pointer,
326 .page = snd_pcm_get_vmalloc_page,
327};
328
329int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
330{
331 struct snd_pcm *sp;
332 struct snd_card *sc = cxsc->sc;
333 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
334 struct cx18 *cx = to_cx18(v4l2_dev);
335 int ret;
336
337 ret = snd_pcm_new(sc, "CX23418 PCM",
338 0, /* PCM device 0, the only one for this card */
339 0, /* 0 playback substreams */
340 1, /* 1 capture substream */
341 &sp);
342 if (ret) {
343 CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
344 __func__, ret);
345 goto err_exit;
346 }
347
348 spin_lock_init(&cxsc->slock);
349
350 snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
351 &snd_cx18_pcm_capture_ops);
352 sp->info_flags = 0;
353 sp->private_data = cxsc;
354 strlcpy(sp->name, cx->card_name, sizeof(sp->name));
355
356 return 0;
357
358err_exit:
359 return ret;
360}
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/video/cx18/cx18-alsa-pcm.h
new file mode 100644
index 00000000000..d26e51f9457
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.h
@@ -0,0 +1,27 @@
1/*
2 * ALSA PCM device for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
24
25/* Used by cx18-mailbox to announce the PCM data to the module */
26void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
27 size_t num_bytes);
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h
new file mode 100644
index 00000000000..447da374c9e
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa.h
@@ -0,0 +1,75 @@
1/*
2 * ALSA interface to cx18 PCM capture streams
3 *
4 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22struct snd_card;
23
24struct snd_cx18_card {
25 struct v4l2_device *v4l2_dev;
26 struct snd_card *sc;
27 unsigned int capture_transfer_done;
28 unsigned int hwptr_done_capture;
29 struct snd_pcm_substream *capture_pcm_substream;
30 spinlock_t slock;
31};
32
33extern int cx18_alsa_debug;
34
35/*
36 * File operations that manipulate the encoder or video or audio subdevices
37 * need to be serialized. Use the same lock we use for v4l2 file ops.
38 */
39static inline void snd_cx18_lock(struct snd_cx18_card *cxsc)
40{
41 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
42 mutex_lock(&cx->serialize_lock);
43}
44
45static inline void snd_cx18_unlock(struct snd_cx18_card *cxsc)
46{
47 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
48 mutex_unlock(&cx->serialize_lock);
49}
50
51#define CX18_ALSA_DBGFLG_WARN (1 << 0)
52#define CX18_ALSA_DBGFLG_WARN (1 << 0)
53#define CX18_ALSA_DBGFLG_INFO (1 << 1)
54
55#define CX18_ALSA_DEBUG(x, type, fmt, args...) \
56 do { \
57 if ((x) & cx18_alsa_debug) \
58 printk(KERN_INFO "%s-alsa: " type ": " fmt, \
59 v4l2_dev->name , ## args); \
60 } while (0)
61
62#define CX18_ALSA_DEBUG_WARN(fmt, args...) \
63 CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_WARN, "warning", fmt , ## args)
64
65#define CX18_ALSA_DEBUG_INFO(fmt, args...) \
66 CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_INFO, "info", fmt , ## args)
67
68#define CX18_ALSA_ERR(fmt, args...) \
69 printk(KERN_ERR "%s-alsa: " fmt, v4l2_dev->name , ## args)
70
71#define CX18_ALSA_WARN(fmt, args...) \
72 printk(KERN_WARNING "%s-alsa: " fmt, v4l2_dev->name , ## args)
73
74#define CX18_ALSA_INFO(fmt, args...) \
75 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
new file mode 100644
index 00000000000..35268923911
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -0,0 +1,92 @@
1/*
2 * cx18 audio-related functions
3 *
4 * Derived from ivtv-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-io.h"
26#include "cx18-cards.h"
27#include "cx18-audio.h"
28
29#define CX18_AUDIO_ENABLE 0xc72014
30#define CX18_AI1_MUX_MASK 0x30
31#define CX18_AI1_MUX_I2S1 0x00
32#define CX18_AI1_MUX_I2S2 0x10
33#define CX18_AI1_MUX_843_I2S 0x20
34
35/* Selects the audio input and output according to the current
36 settings. */
37int cx18_audio_set_io(struct cx18 *cx)
38{
39 const struct cx18_card_audio_input *in;
40 u32 u, v;
41 int err;
42
43 /* Determine which input to use */
44 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
45 in = &cx->card->radio_input;
46 else
47 in = &cx->card->audio_inputs[cx->audio_input];
48
49 /* handle muxer chips */
50 v4l2_subdev_call(cx->sd_extmux, audio, s_routing,
51 (u32) in->muxer_input, 0, 0);
52
53 err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
54 audio, s_routing, in->audio_input, 0, 0);
55 if (err)
56 return err;
57
58 /* FIXME - this internal mux should be abstracted to a subdev */
59 u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
60 v = u & ~CX18_AI1_MUX_MASK;
61 switch (in->audio_input) {
62 case CX18_AV_AUDIO_SERIAL1:
63 v |= CX18_AI1_MUX_I2S1;
64 break;
65 case CX18_AV_AUDIO_SERIAL2:
66 v |= CX18_AI1_MUX_I2S2;
67 break;
68 default:
69 v |= CX18_AI1_MUX_843_I2S;
70 break;
71 }
72 if (v == u) {
73 /* force a toggle of some AI1 MUX control bits */
74 u &= ~CX18_AI1_MUX_MASK;
75 switch (in->audio_input) {
76 case CX18_AV_AUDIO_SERIAL1:
77 u |= CX18_AI1_MUX_843_I2S;
78 break;
79 case CX18_AV_AUDIO_SERIAL2:
80 u |= CX18_AI1_MUX_843_I2S;
81 break;
82 default:
83 u |= CX18_AI1_MUX_I2S1;
84 break;
85 }
86 cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
87 u, CX18_AI1_MUX_MASK);
88 }
89 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
90 v, CX18_AI1_MUX_MASK);
91 return 0;
92}
diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/video/cx18/cx18-audio.h
new file mode 100644
index 00000000000..2731d29b0ab
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-audio.h
@@ -0,0 +1,24 @@
1/*
2 * cx18 audio-related functions
3 *
4 * Derived from ivtv-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24int 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
new file mode 100644
index 00000000000..4a24ffb17a7
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -0,0 +1,471 @@
1/*
2 * cx18 ADEC audio functions
3 *
4 * Derived from cx25840-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301, USA.
23 */
24
25#include "cx18-driver.h"
26
27static int set_audclk_freq(struct cx18 *cx, u32 freq)
28{
29 struct cx18_av_state *state = &cx->av_state;
30
31 if (freq != 32000 && freq != 44100 && freq != 48000)
32 return -EINVAL;
33
34 /*
35 * The PLL parameters are based on the external crystal frequency that
36 * would ideally be:
37 *
38 * NTSC Color subcarrier freq * 8 =
39 * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
40 *
41 * The accidents of history and rationale that explain from where this
42 * combination of magic numbers originate can be found in:
43 *
44 * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
45 * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
46 *
47 * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
48 * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
49 *
50 * As Mike Bradley has rightly pointed out, it's not the exact crystal
51 * frequency that matters, only that all parts of the driver and
52 * firmware are using the same value (close to the ideal value).
53 *
54 * Since I have a strong suspicion that, if the firmware ever assumes a
55 * crystal value at all, it will assume 28.636360 MHz, the crystal
56 * freq used in calculations in this driver will be:
57 *
58 * xtal_freq = 28.636360 MHz
59 *
60 * an error of less than 0.13 ppm which is way, way better than any off
61 * the shelf crystal will have for accuracy anyway.
62 *
63 * Below I aim to run the PLLs' VCOs near 400 MHz to minimze error.
64 *
65 * Many thanks to Jeff Campbell and Mike Bradley for their extensive
66 * investigation, experimentation, testing, and suggested solutions of
67 * of audio/video sync problems with SVideo and CVBS captures.
68 */
69
70 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
71 switch (freq) {
72 case 32000:
73 /*
74 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
75 * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
76 */
77 cx18_av_write4(cx, 0x108, 0x200d040f);
78
79 /* VID_PLL Fraction = 0x2be2fe */
80 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
81 cx18_av_write4(cx, 0x10c, 0x002be2fe);
82
83 /* AUX_PLL Fraction = 0x176740c */
84 /* xtal * 0xd.bb3a060/0x20 = 32000 * 384: 393 MHz p-pd*/
85 cx18_av_write4(cx, 0x110, 0x0176740c);
86
87 /* src3/4/6_ctl */
88 /* 0x1.f77f = (4 * xtal/8*2/455) / 32000 */
89 cx18_av_write4(cx, 0x900, 0x0801f77f);
90 cx18_av_write4(cx, 0x904, 0x0801f77f);
91 cx18_av_write4(cx, 0x90c, 0x0801f77f);
92
93 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
94 cx18_av_write(cx, 0x127, 0x60);
95
96 /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
97 cx18_av_write4(cx, 0x12c, 0x11202fff);
98
99 /*
100 * EN_AV_LOCK = 0
101 * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
102 * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
103 */
104 cx18_av_write4(cx, 0x128, 0xa00d2ef8);
105 break;
106
107 case 44100:
108 /*
109 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
110 * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x18
111 */
112 cx18_av_write4(cx, 0x108, 0x180e040f);
113
114 /* VID_PLL Fraction = 0x2be2fe */
115 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
116 cx18_av_write4(cx, 0x10c, 0x002be2fe);
117
118 /* AUX_PLL Fraction = 0x062a1f2 */
119 /* xtal * 0xe.3150f90/0x18 = 44100 * 384: 406 MHz p-pd*/
120 cx18_av_write4(cx, 0x110, 0x0062a1f2);
121
122 /* src3/4/6_ctl */
123 /* 0x1.6d59 = (4 * xtal/8*2/455) / 44100 */
124 cx18_av_write4(cx, 0x900, 0x08016d59);
125 cx18_av_write4(cx, 0x904, 0x08016d59);
126 cx18_av_write4(cx, 0x90c, 0x08016d59);
127
128 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x18 */
129 cx18_av_write(cx, 0x127, 0x58);
130
131 /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
132 cx18_av_write4(cx, 0x12c, 0x112092ff);
133
134 /*
135 * EN_AV_LOCK = 0
136 * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
137 * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
138 */
139 cx18_av_write4(cx, 0x128, 0xa01d4bf8);
140 break;
141
142 case 48000:
143 /*
144 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
145 * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x16
146 */
147 cx18_av_write4(cx, 0x108, 0x160e040f);
148
149 /* VID_PLL Fraction = 0x2be2fe */
150 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
151 cx18_av_write4(cx, 0x10c, 0x002be2fe);
152
153 /* AUX_PLL Fraction = 0x05227ad */
154 /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz p-pd*/
155 cx18_av_write4(cx, 0x110, 0x005227ad);
156
157 /* src3/4/6_ctl */
158 /* 0x1.4faa = (4 * xtal/8*2/455) / 48000 */
159 cx18_av_write4(cx, 0x900, 0x08014faa);
160 cx18_av_write4(cx, 0x904, 0x08014faa);
161 cx18_av_write4(cx, 0x90c, 0x08014faa);
162
163 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
164 cx18_av_write(cx, 0x127, 0x56);
165
166 /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
167 cx18_av_write4(cx, 0x12c, 0x11205fff);
168
169 /*
170 * EN_AV_LOCK = 0
171 * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
172 * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
173 */
174 cx18_av_write4(cx, 0x128, 0xa01193f8);
175 break;
176 }
177 } else {
178 switch (freq) {
179 case 32000:
180 /*
181 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
182 * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x30
183 */
184 cx18_av_write4(cx, 0x108, 0x300d040f);
185
186 /* VID_PLL Fraction = 0x2be2fe */
187 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
188 cx18_av_write4(cx, 0x10c, 0x002be2fe);
189
190 /* AUX_PLL Fraction = 0x176740c */
191 /* xtal * 0xd.bb3a060/0x30 = 32000 * 256: 393 MHz p-pd*/
192 cx18_av_write4(cx, 0x110, 0x0176740c);
193
194 /* src1_ctl */
195 /* 0x1.0000 = 32000/32000 */
196 cx18_av_write4(cx, 0x8f8, 0x08010000);
197
198 /* src3/4/6_ctl */
199 /* 0x2.0000 = 2 * (32000/32000) */
200 cx18_av_write4(cx, 0x900, 0x08020000);
201 cx18_av_write4(cx, 0x904, 0x08020000);
202 cx18_av_write4(cx, 0x90c, 0x08020000);
203
204 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x30 */
205 cx18_av_write(cx, 0x127, 0x70);
206
207 /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
208 cx18_av_write4(cx, 0x12c, 0x11201fff);
209
210 /*
211 * EN_AV_LOCK = 0
212 * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
213 * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
214 */
215 cx18_av_write4(cx, 0x128, 0xa00d2ef8);
216 break;
217
218 case 44100:
219 /*
220 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
221 * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x24
222 */
223 cx18_av_write4(cx, 0x108, 0x240e040f);
224
225 /* VID_PLL Fraction = 0x2be2fe */
226 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
227 cx18_av_write4(cx, 0x10c, 0x002be2fe);
228
229 /* AUX_PLL Fraction = 0x062a1f2 */
230 /* xtal * 0xe.3150f90/0x24 = 44100 * 256: 406 MHz p-pd*/
231 cx18_av_write4(cx, 0x110, 0x0062a1f2);
232
233 /* src1_ctl */
234 /* 0x1.60cd = 44100/32000 */
235 cx18_av_write4(cx, 0x8f8, 0x080160cd);
236
237 /* src3/4/6_ctl */
238 /* 0x1.7385 = 2 * (32000/44100) */
239 cx18_av_write4(cx, 0x900, 0x08017385);
240 cx18_av_write4(cx, 0x904, 0x08017385);
241 cx18_av_write4(cx, 0x90c, 0x08017385);
242
243 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x24 */
244 cx18_av_write(cx, 0x127, 0x64);
245
246 /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
247 cx18_av_write4(cx, 0x12c, 0x112061ff);
248
249 /*
250 * EN_AV_LOCK = 0
251 * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
252 * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
253 */
254 cx18_av_write4(cx, 0x128, 0xa01d4bf8);
255 break;
256
257 case 48000:
258 /*
259 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
260 * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
261 */
262 cx18_av_write4(cx, 0x108, 0x200d040f);
263
264 /* VID_PLL Fraction = 0x2be2fe */
265 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
266 cx18_av_write4(cx, 0x10c, 0x002be2fe);
267
268 /* AUX_PLL Fraction = 0x176740c */
269 /* xtal * 0xd.bb3a060/0x20 = 48000 * 256: 393 MHz p-pd*/
270 cx18_av_write4(cx, 0x110, 0x0176740c);
271
272 /* src1_ctl */
273 /* 0x1.8000 = 48000/32000 */
274 cx18_av_write4(cx, 0x8f8, 0x08018000);
275
276 /* src3/4/6_ctl */
277 /* 0x1.5555 = 2 * (32000/48000) */
278 cx18_av_write4(cx, 0x900, 0x08015555);
279 cx18_av_write4(cx, 0x904, 0x08015555);
280 cx18_av_write4(cx, 0x90c, 0x08015555);
281
282 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
283 cx18_av_write(cx, 0x127, 0x60);
284
285 /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
286 cx18_av_write4(cx, 0x12c, 0x11203fff);
287
288 /*
289 * EN_AV_LOCK = 0
290 * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
291 * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
292 */
293 cx18_av_write4(cx, 0x128, 0xa01193f8);
294 break;
295 }
296 }
297
298 state->audclk_freq = freq;
299
300 return 0;
301}
302
303void cx18_av_audio_set_path(struct cx18 *cx)
304{
305 struct cx18_av_state *state = &cx->av_state;
306 u8 v;
307
308 /* stop microcontroller */
309 v = cx18_av_read(cx, 0x803) & ~0x10;
310 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
311
312 /* assert soft reset */
313 v = cx18_av_read(cx, 0x810) | 0x01;
314 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
315
316 /* Mute everything to prevent the PFFT! */
317 cx18_av_write(cx, 0x8d3, 0x1f);
318
319 if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
320 /* Set Path1 to Serial Audio Input */
321 cx18_av_write4(cx, 0x8d0, 0x01011012);
322
323 /* The microcontroller should not be started for the
324 * non-tuner inputs: autodetection is specific for
325 * TV audio. */
326 } else {
327 /* Set Path1 to Analog Demod Main Channel */
328 cx18_av_write4(cx, 0x8d0, 0x1f063870);
329 }
330
331 set_audclk_freq(cx, state->audclk_freq);
332
333 /* deassert soft reset */
334 v = cx18_av_read(cx, 0x810) & ~0x01;
335 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
336
337 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
338 /* When the microcontroller detects the
339 * audio format, it will unmute the lines */
340 v = cx18_av_read(cx, 0x803) | 0x10;
341 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
342 }
343}
344
345static void set_volume(struct cx18 *cx, int volume)
346{
347 /* First convert the volume to msp3400 values (0-127) */
348 int vol = volume >> 9;
349 /* now scale it up to cx18_av values
350 * -114dB to -96dB maps to 0
351 * this should be 19, but in my testing that was 4dB too loud */
352 if (vol <= 23)
353 vol = 0;
354 else
355 vol -= 23;
356
357 /* PATH1_VOLUME */
358 cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
359}
360
361static void set_bass(struct cx18 *cx, int bass)
362{
363 /* PATH1_EQ_BASS_VOL */
364 cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
365}
366
367static void set_treble(struct cx18 *cx, int treble)
368{
369 /* PATH1_EQ_TREBLE_VOL */
370 cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
371}
372
373static void set_balance(struct cx18 *cx, int balance)
374{
375 int bal = balance >> 8;
376 if (bal > 0x80) {
377 /* PATH1_BAL_LEFT */
378 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
379 /* PATH1_BAL_LEVEL */
380 cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
381 } else {
382 /* PATH1_BAL_LEFT */
383 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
384 /* PATH1_BAL_LEVEL */
385 cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
386 }
387}
388
389static void set_mute(struct cx18 *cx, int mute)
390{
391 struct cx18_av_state *state = &cx->av_state;
392 u8 v;
393
394 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
395 /* Must turn off microcontroller in order to mute sound.
396 * Not sure if this is the best method, but it does work.
397 * If the microcontroller is running, then it will undo any
398 * changes to the mute register. */
399 v = cx18_av_read(cx, 0x803);
400 if (mute) {
401 /* disable microcontroller */
402 v &= ~0x10;
403 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
404 cx18_av_write(cx, 0x8d3, 0x1f);
405 } else {
406 /* enable microcontroller */
407 v |= 0x10;
408 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
409 }
410 } else {
411 /* SRC1_MUTE_EN */
412 cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
413 }
414}
415
416int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
417{
418 struct cx18 *cx = v4l2_get_subdevdata(sd);
419 struct cx18_av_state *state = &cx->av_state;
420 int retval;
421 u8 v;
422
423 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
424 v = cx18_av_read(cx, 0x803) & ~0x10;
425 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
426 cx18_av_write(cx, 0x8d3, 0x1f);
427 }
428 v = cx18_av_read(cx, 0x810) | 0x1;
429 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
430
431 retval = set_audclk_freq(cx, freq);
432
433 v = cx18_av_read(cx, 0x810) & ~0x1;
434 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
435 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
436 v = cx18_av_read(cx, 0x803) | 0x10;
437 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
438 }
439 return retval;
440}
441
442static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
443{
444 struct v4l2_subdev *sd = to_sd(ctrl);
445 struct cx18 *cx = v4l2_get_subdevdata(sd);
446
447 switch (ctrl->id) {
448 case V4L2_CID_AUDIO_VOLUME:
449 set_volume(cx, ctrl->val);
450 break;
451 case V4L2_CID_AUDIO_BASS:
452 set_bass(cx, ctrl->val);
453 break;
454 case V4L2_CID_AUDIO_TREBLE:
455 set_treble(cx, ctrl->val);
456 break;
457 case V4L2_CID_AUDIO_BALANCE:
458 set_balance(cx, ctrl->val);
459 break;
460 case V4L2_CID_AUDIO_MUTE:
461 set_mute(cx, ctrl->val);
462 break;
463 default:
464 return -EINVAL;
465 }
466 return 0;
467}
468
469const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops = {
470 .s_ctrl = cx18_av_audio_s_ctrl,
471};
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
new file mode 100644
index 00000000000..f164b7f610a
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -0,0 +1,1401 @@
1/*
2 * cx18 ADEC audio functions
3 *
4 * Derived from cx25840-core.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301, USA.
23 */
24
25#include <media/v4l2-chip-ident.h>
26#include "cx18-driver.h"
27#include "cx18-io.h"
28#include "cx18-cards.h"
29
30int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
31{
32 u32 reg = 0xc40000 + (addr & ~3);
33 u32 mask = 0xff;
34 int shift = (addr & 3) * 8;
35 u32 x = cx18_read_reg(cx, reg);
36
37 x = (x & ~(mask << shift)) | ((u32)value << shift);
38 cx18_write_reg(cx, x, reg);
39 return 0;
40}
41
42int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask)
43{
44 u32 reg = 0xc40000 + (addr & ~3);
45 int shift = (addr & 3) * 8;
46 u32 x = cx18_read_reg(cx, reg);
47
48 x = (x & ~((u32)0xff << shift)) | ((u32)value << shift);
49 cx18_write_reg_expect(cx, x, reg,
50 ((u32)eval << shift), ((u32)mask << shift));
51 return 0;
52}
53
54int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
55{
56 cx18_write_reg(cx, value, 0xc40000 + addr);
57 return 0;
58}
59
60int
61cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval, u32 mask)
62{
63 cx18_write_reg_expect(cx, value, 0xc40000 + addr, eval, mask);
64 return 0;
65}
66
67int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value)
68{
69 cx18_write_reg_noretry(cx, value, 0xc40000 + addr);
70 return 0;
71}
72
73u8 cx18_av_read(struct cx18 *cx, u16 addr)
74{
75 u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3));
76 int shift = (addr & 3) * 8;
77
78 return (x >> shift) & 0xff;
79}
80
81u32 cx18_av_read4(struct cx18 *cx, u16 addr)
82{
83 return cx18_read_reg(cx, 0xc40000 + addr);
84}
85
86int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
87 u8 or_value)
88{
89 return cx18_av_write(cx, addr,
90 (cx18_av_read(cx, addr) & and_mask) |
91 or_value);
92}
93
94int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
95 u32 or_value)
96{
97 return cx18_av_write4(cx, addr,
98 (cx18_av_read4(cx, addr) & and_mask) |
99 or_value);
100}
101
102static void cx18_av_init(struct cx18 *cx)
103{
104 /*
105 * The crystal freq used in calculations in this driver will be
106 * 28.636360 MHz.
107 * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
108 */
109
110 /*
111 * VDCLK Integer = 0x0f, Post Divider = 0x04
112 * AIMCLK Integer = 0x0e, Post Divider = 0x16
113 */
114 cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
115
116 /* VDCLK Fraction = 0x2be2fe */
117 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
118 cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
119
120 /* AIMCLK Fraction = 0x05227ad */
121 /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
122 cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
123
124 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
125 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
126}
127
128static void cx18_av_initialize(struct v4l2_subdev *sd)
129{
130 struct cx18_av_state *state = to_cx18_av_state(sd);
131 struct cx18 *cx = v4l2_get_subdevdata(sd);
132 int default_volume;
133 u32 v;
134
135 cx18_av_loadfw(cx);
136 /* Stop 8051 code execution */
137 cx18_av_write4_expect(cx, CXADEC_DL_CTL, 0x03000000,
138 0x03000000, 0x13000000);
139
140 /* initallize the PLL by toggling sleep bit */
141 v = cx18_av_read4(cx, CXADEC_HOST_REG1);
142 /* enable sleep mode - register appears to be read only... */
143 cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v | 1, v, 0xfffe);
144 /* disable sleep mode */
145 cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v & 0xfffe,
146 v & 0xfffe, 0xffff);
147
148 /* initialize DLLs */
149 v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
150 /* disable FLD */
151 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v);
152 /* enable FLD */
153 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100);
154
155 v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF;
156 /* disable FLD */
157 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v);
158 /* enable FLD */
159 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100);
160
161 /* set analog bias currents. Set Vreg to 1.20V. */
162 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802);
163
164 v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
165 /* enable TUNE_FIL_RST */
166 cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3, v, v, 0x03009F0F);
167 /* disable TUNE_FIL_RST */
168 cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3,
169 v & 0xFFFFFFFE, v & 0xFFFFFFFE, 0x03009F0F);
170
171 /* enable 656 output */
172 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
173
174 /* video output drive strength */
175 cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2);
176
177 /* reset video */
178 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
179 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
180
181 /*
182 * Disable Video Auto-config of the Analog Front End and Video PLL.
183 *
184 * Since we only use BT.656 pixel mode, which works for both 525 and 625
185 * line systems, it's just easier for us to set registers
186 * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL),
187 * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC)
188 * ourselves, than to run around cleaning up after the auto-config.
189 *
190 * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit
191 * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL
192 * autoconfig either.)
193 *
194 * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3.
195 */
196 cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
197
198 /* Setup the Video and and Aux/Audio PLLs */
199 cx18_av_init(cx);
200
201 /* set video to auto-detect */
202 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
203 /* set the comb notch = 1 */
204 cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800);
205
206 /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
207 /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
208 cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000);
209
210 /* Set VGA_TRACK_RANGE to 0x20 */
211 cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
212
213 /*
214 * Initial VBI setup
215 * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
216 * don't clamp raw samples when codes are in use, 1 byte user D-words,
217 * IDID0 has line #, RP code V bit transition on VBLANK, data during
218 * blanking intervals
219 */
220 cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);
221
222 /* Set the video input.
223 The setting in MODE_CTRL gets lost when we do the above setup */
224 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
225 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
226
227 /*
228 * Analog Front End (AFE)
229 * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2
230 * bypass_ch[1-3] use filter
231 * droop_comp_ch[1-3] disable
232 * clamp_en_ch[1-3] disable
233 * aud_in_sel ADC2
234 * luma_in_sel ADC1
235 * chroma_in_sel ADC2
236 * clamp_sel_ch[2-3] midcode
237 * clamp_sel_ch1 video decoder
238 * vga_sel_ch3 audio decoder
239 * vga_sel_ch[1-2] video decoder
240 * half_bw_ch[1-3] disable
241 * +12db_ch[1-3] disable
242 */
243 cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
244
245/* if(dwEnable && dw3DCombAvailable) { */
246/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
247/* } else { */
248/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
249/* } */
250 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
251 default_volume = cx18_av_read(cx, 0x8d4);
252 /*
253 * Enforce the legacy volume scale mapping limits to avoid
254 * -ERANGE errors when initializing the volume control
255 */
256 if (default_volume > 228) {
257 /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
258 default_volume = 228;
259 cx18_av_write(cx, 0x8d4, 228);
260 } else if (default_volume < 20) {
261 /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
262 default_volume = 20;
263 cx18_av_write(cx, 0x8d4, 20);
264 }
265 default_volume = (((228 - default_volume) >> 1) + 23) << 9;
266 state->volume->cur.val = state->volume->default_value = default_volume;
267 v4l2_ctrl_handler_setup(&state->hdl);
268}
269
270static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
271{
272 cx18_av_initialize(sd);
273 return 0;
274}
275
276static int cx18_av_load_fw(struct v4l2_subdev *sd)
277{
278 struct cx18_av_state *state = to_cx18_av_state(sd);
279
280 if (!state->is_initialized) {
281 /* initialize on first use */
282 state->is_initialized = 1;
283 cx18_av_initialize(sd);
284 }
285 return 0;
286}
287
288void cx18_av_std_setup(struct cx18 *cx)
289{
290 struct cx18_av_state *state = &cx->av_state;
291 struct v4l2_subdev *sd = &state->sd;
292 v4l2_std_id std = state->std;
293
294 /*
295 * Video ADC crystal clock to pixel clock SRC decimation ratio
296 * 28.636360 MHz/13.5 Mpps * 256 = 0x21f.07b
297 */
298 const int src_decimation = 0x21f;
299
300 int hblank, hactive, burst, vblank, vactive, sc;
301 int vblank656;
302 int luma_lpf, uv_lpf, comb;
303 u32 pll_int, pll_frac, pll_post;
304
305 /* datasheet startup, step 8d */
306 if (std & ~V4L2_STD_NTSC)
307 cx18_av_write(cx, 0x49f, 0x11);
308 else
309 cx18_av_write(cx, 0x49f, 0x14);
310
311 /*
312 * Note: At the end of a field, there are 3 sets of half line duration
313 * (double horizontal rate) pulses:
314 *
315 * 5 (625) or 6 (525) half-lines to blank for the vertical retrace
316 * 5 (625) or 6 (525) vertical sync pulses of half line duration
317 * 5 (625) or 6 (525) half-lines of equalization pulses
318 */
319 if (std & V4L2_STD_625_50) {
320 /*
321 * The following relationships of half line counts should hold:
322 * 625 = vblank656 + vactive
323 * 10 = vblank656 - vblank = vsync pulses + equalization pulses
324 *
325 * vblank656: half lines after line 625/mid-313 of blanked video
326 * vblank: half lines, after line 5/317, of blanked video
327 * vactive: half lines of active video +
328 * 5 half lines after the end of active video
329 *
330 * As far as I can tell:
331 * vblank656 starts counting from the falling edge of the first
332 * vsync pulse (start of line 1 or mid-313)
333 * vblank starts counting from the after the 5 vsync pulses and
334 * 5 or 4 equalization pulses (start of line 6 or 318)
335 *
336 * For 625 line systems the driver will extract VBI information
337 * from lines 6-23 and lines 318-335 (but the slicer can only
338 * handle 17 lines, not the 18 in the vblank region).
339 * In addition, we need vblank656 and vblank to be one whole
340 * line longer, to cover line 24 and 336, so the SAV/EAV RP
341 * codes get generated such that the encoder can actually
342 * extract line 23 & 335 (WSS). We'll lose 1 line in each field
343 * at the top of the screen.
344 *
345 * It appears the 5 half lines that happen after active
346 * video must be included in vactive (579 instead of 574),
347 * otherwise the colors get badly displayed in various regions
348 * of the screen. I guess the chroma comb filter gets confused
349 * without them (at least when a PVR-350 is the PAL source).
350 */
351 vblank656 = 48; /* lines 1 - 24 & 313 - 336 */
352 vblank = 38; /* lines 6 - 24 & 318 - 336 */
353 vactive = 579; /* lines 24 - 313 & 337 - 626 */
354
355 /*
356 * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is
357 * is 864 pixels = 720 active + 144 blanking. ITU-R BT.601
358 * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after
359 * the end of active video to start a horizontal line, so that
360 * leaves 132 pixels of hblank to ignore.
361 */
362 hblank = 132;
363 hactive = 720;
364
365 /*
366 * Burst gate delay (for 625 line systems)
367 * Hsync leading edge to color burst rise = 5.6 us
368 * Color burst width = 2.25 us
369 * Gate width = 4 pixel clocks
370 * (5.6 us + 2.25/2 us) * 13.5 Mpps + 4/2 clocks = 92.79 clocks
371 */
372 burst = 93;
373 luma_lpf = 2;
374 if (std & V4L2_STD_PAL) {
375 uv_lpf = 1;
376 comb = 0x20;
377 /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
378 sc = 688700;
379 } else if (std == V4L2_STD_PAL_Nc) {
380 uv_lpf = 1;
381 comb = 0x20;
382 /* sc = 3582056.25 * src_decimation/28636360 * 2^13 */
383 sc = 556422;
384 } else { /* SECAM */
385 uv_lpf = 0;
386 comb = 0;
387 /* (fr + fb)/2 = (4406260 + 4250000)/2 = 4328130 */
388 /* sc = 4328130 * src_decimation/28636360 * 2^13 */
389 sc = 672314;
390 }
391 } else {
392 /*
393 * The following relationships of half line counts should hold:
394 * 525 = prevsync + vblank656 + vactive
395 * 12 = vblank656 - vblank = vsync pulses + equalization pulses
396 *
397 * prevsync: 6 half-lines before the vsync pulses
398 * vblank656: half lines, after line 3/mid-266, of blanked video
399 * vblank: half lines, after line 9/272, of blanked video
400 * vactive: half lines of active video
401 *
402 * As far as I can tell:
403 * vblank656 starts counting from the falling edge of the first
404 * vsync pulse (start of line 4 or mid-266)
405 * vblank starts counting from the after the 6 vsync pulses and
406 * 6 or 5 equalization pulses (start of line 10 or 272)
407 *
408 * For 525 line systems the driver will extract VBI information
409 * from lines 10-21 and lines 273-284.
410 */
411 vblank656 = 38; /* lines 4 - 22 & 266 - 284 */
412 vblank = 26; /* lines 10 - 22 & 272 - 284 */
413 vactive = 481; /* lines 23 - 263 & 285 - 525 */
414
415 /*
416 * For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is
417 * is 858 pixels = 720 active + 138 blanking. The Hsync leading
418 * edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the
419 * end of active video, leaving 122 pixels of hblank to ignore
420 * before active video starts.
421 */
422 hactive = 720;
423 hblank = 122;
424 luma_lpf = 1;
425 uv_lpf = 1;
426
427 /*
428 * Burst gate delay (for 525 line systems)
429 * Hsync leading edge to color burst rise = 5.3 us
430 * Color burst width = 2.5 us
431 * Gate width = 4 pixel clocks
432 * (5.3 us + 2.5/2 us) * 13.5 Mpps + 4/2 clocks = 90.425 clocks
433 */
434 if (std == V4L2_STD_PAL_60) {
435 burst = 90;
436 luma_lpf = 2;
437 comb = 0x20;
438 /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
439 sc = 688700;
440 } else if (std == V4L2_STD_PAL_M) {
441 /* The 97 needs to be verified against PAL-M timings */
442 burst = 97;
443 comb = 0x20;
444 /* sc = 3575611.49 * src_decimation/28636360 * 2^13 */
445 sc = 555421;
446 } else {
447 burst = 90;
448 comb = 0x66;
449 /* sc = 3579545.45.. * src_decimation/28636360 * 2^13 */
450 sc = 556032;
451 }
452 }
453
454 /* DEBUG: Displays configured PLL frequency */
455 pll_int = cx18_av_read(cx, 0x108);
456 pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
457 pll_post = cx18_av_read(cx, 0x109);
458 CX18_DEBUG_INFO_DEV(sd, "PLL regs = int: %u, frac: %u, post: %u\n",
459 pll_int, pll_frac, pll_post);
460
461 if (pll_post) {
462 int fsc, pll;
463 u64 tmp;
464
465 pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
466 pll /= pll_post;
467 CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n",
468 pll / 1000000, pll % 1000000);
469 CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n",
470 pll / 8000000, (pll / 8) % 1000000);
471
472 CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio "
473 "= %d.%03d\n", src_decimation / 256,
474 ((src_decimation % 256) * 1000) / 256);
475
476 tmp = 28636360 * (u64) sc;
477 do_div(tmp, src_decimation);
478 fsc = tmp >> 13;
479 CX18_DEBUG_INFO_DEV(sd,
480 "Chroma sub-carrier initial freq = %d.%06d "
481 "MHz\n", fsc / 1000000, fsc % 1000000);
482
483 CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
484 "vactive %i, vblank656 %i, src_dec %i, "
485 "burst 0x%02x, luma_lpf %i, uv_lpf %i, "
486 "comb 0x%02x, sc 0x%06x\n",
487 hblank, hactive, vblank, vactive, vblank656,
488 src_decimation, burst, luma_lpf, uv_lpf,
489 comb, sc);
490 }
491
492 /* Sets horizontal blanking delay and active lines */
493 cx18_av_write(cx, 0x470, hblank);
494 cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) |
495 (hactive << 4)));
496 cx18_av_write(cx, 0x472, hactive >> 4);
497
498 /* Sets burst gate delay */
499 cx18_av_write(cx, 0x473, burst);
500
501 /* Sets vertical blanking delay and active duration */
502 cx18_av_write(cx, 0x474, vblank);
503 cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) |
504 (vactive << 4)));
505 cx18_av_write(cx, 0x476, vactive >> 4);
506 cx18_av_write(cx, 0x477, vblank656);
507
508 /* Sets src decimation rate */
509 cx18_av_write(cx, 0x478, 0xff & src_decimation);
510 cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8));
511
512 /* Sets Luma and UV Low pass filters */
513 cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
514
515 /* Enables comb filters */
516 cx18_av_write(cx, 0x47b, comb);
517
518 /* Sets SC Step*/
519 cx18_av_write(cx, 0x47c, sc);
520 cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
521 cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
522
523 if (std & V4L2_STD_625_50) {
524 state->slicer_line_delay = 1;
525 state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
526 } else {
527 state->slicer_line_delay = 0;
528 state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
529 }
530 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
531}
532
533static void input_change(struct cx18 *cx)
534{
535 struct cx18_av_state *state = &cx->av_state;
536 v4l2_std_id std = state->std;
537 u8 v;
538
539 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
540 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
541 cx18_av_and_or(cx, 0x401, ~0x60, 0);
542 cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
543
544 if (std & V4L2_STD_525_60) {
545 if (std == V4L2_STD_NTSC_M_JP) {
546 /* Japan uses EIAJ audio standard */
547 cx18_av_write_expect(cx, 0x808, 0xf7, 0xf7, 0xff);
548 cx18_av_write_expect(cx, 0x80b, 0x02, 0x02, 0x3f);
549 } else if (std == V4L2_STD_NTSC_M_KR) {
550 /* South Korea uses A2 audio standard */
551 cx18_av_write_expect(cx, 0x808, 0xf8, 0xf8, 0xff);
552 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
553 } else {
554 /* Others use the BTSC audio standard */
555 cx18_av_write_expect(cx, 0x808, 0xf6, 0xf6, 0xff);
556 cx18_av_write_expect(cx, 0x80b, 0x01, 0x01, 0x3f);
557 }
558 } else if (std & V4L2_STD_PAL) {
559 /* Follow tuner change procedure for PAL */
560 cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
561 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
562 } else if (std & V4L2_STD_SECAM) {
563 /* Select autodetect for SECAM */
564 cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
565 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
566 }
567
568 v = cx18_av_read(cx, 0x803);
569 if (v & 0x10) {
570 /* restart audio decoder microcontroller */
571 v &= ~0x10;
572 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
573 v |= 0x10;
574 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
575 }
576}
577
578static int cx18_av_s_frequency(struct v4l2_subdev *sd,
579 struct v4l2_frequency *freq)
580{
581 struct cx18 *cx = v4l2_get_subdevdata(sd);
582 input_change(cx);
583 return 0;
584}
585
586static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
587 enum cx18_av_audio_input aud_input)
588{
589 struct cx18_av_state *state = &cx->av_state;
590 struct v4l2_subdev *sd = &state->sd;
591
592 enum analog_signal_type {
593 NONE, CVBS, Y, C, SIF, Pb, Pr
594 } ch[3] = {NONE, NONE, NONE};
595
596 u8 afe_mux_cfg;
597 u8 adc2_cfg;
598 u8 input_mode;
599 u32 afe_cfg;
600 int i;
601
602 CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
603 vid_input, aud_input);
604
605 if (vid_input >= CX18_AV_COMPOSITE1 &&
606 vid_input <= CX18_AV_COMPOSITE8) {
607 afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
608 ch[0] = CVBS;
609 input_mode = 0x0;
610 } else if (vid_input >= CX18_AV_COMPONENT_LUMA1) {
611 int luma = vid_input & 0xf000;
612 int r_chroma = vid_input & 0xf0000;
613 int b_chroma = vid_input & 0xf00000;
614
615 if ((vid_input & ~0xfff000) ||
616 luma < CX18_AV_COMPONENT_LUMA1 ||
617 luma > CX18_AV_COMPONENT_LUMA8 ||
618 r_chroma < CX18_AV_COMPONENT_R_CHROMA4 ||
619 r_chroma > CX18_AV_COMPONENT_R_CHROMA6 ||
620 b_chroma < CX18_AV_COMPONENT_B_CHROMA7 ||
621 b_chroma > CX18_AV_COMPONENT_B_CHROMA8) {
622 CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
623 vid_input);
624 return -EINVAL;
625 }
626 afe_mux_cfg = (luma - CX18_AV_COMPONENT_LUMA1) >> 12;
627 ch[0] = Y;
628 afe_mux_cfg |= (r_chroma - CX18_AV_COMPONENT_R_CHROMA4) >> 12;
629 ch[1] = Pr;
630 afe_mux_cfg |= (b_chroma - CX18_AV_COMPONENT_B_CHROMA7) >> 14;
631 ch[2] = Pb;
632 input_mode = 0x6;
633 } else {
634 int luma = vid_input & 0xf0;
635 int chroma = vid_input & 0xf00;
636
637 if ((vid_input & ~0xff0) ||
638 luma < CX18_AV_SVIDEO_LUMA1 ||
639 luma > CX18_AV_SVIDEO_LUMA8 ||
640 chroma < CX18_AV_SVIDEO_CHROMA4 ||
641 chroma > CX18_AV_SVIDEO_CHROMA8) {
642 CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
643 vid_input);
644 return -EINVAL;
645 }
646 afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
647 ch[0] = Y;
648 if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
649 afe_mux_cfg &= 0x3f;
650 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
651 ch[2] = C;
652 } else {
653 afe_mux_cfg &= 0xcf;
654 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
655 ch[1] = C;
656 }
657 input_mode = 0x2;
658 }
659
660 switch (aud_input) {
661 case CX18_AV_AUDIO_SERIAL1:
662 case CX18_AV_AUDIO_SERIAL2:
663 /* do nothing, use serial audio input */
664 break;
665 case CX18_AV_AUDIO4:
666 afe_mux_cfg &= ~0x30;
667 ch[1] = SIF;
668 break;
669 case CX18_AV_AUDIO5:
670 afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10;
671 ch[1] = SIF;
672 break;
673 case CX18_AV_AUDIO6:
674 afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20;
675 ch[1] = SIF;
676 break;
677 case CX18_AV_AUDIO7:
678 afe_mux_cfg &= ~0xc0;
679 ch[2] = SIF;
680 break;
681 case CX18_AV_AUDIO8:
682 afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40;
683 ch[2] = SIF;
684 break;
685
686 default:
687 CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
688 aud_input);
689 return -EINVAL;
690 }
691
692 /* Set up analog front end multiplexers */
693 cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
694 /* Set INPUT_MODE to Composite, S-Video, or Component */
695 cx18_av_and_or(cx, 0x401, ~0x6, input_mode);
696
697 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
698 adc2_cfg = cx18_av_read(cx, 0x102);
699 if (ch[2] == NONE)
700 adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */
701 else
702 adc2_cfg |= 0x2; /* Signal on CH3, set ADC2 to CH3 for input */
703
704 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
705 if (ch[1] != NONE && ch[2] != NONE)
706 adc2_cfg |= 0x4; /* Set dual mode */
707 else
708 adc2_cfg &= ~0x4; /* Clear dual mode */
709 cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17);
710
711 /* Configure the analog front end */
712 afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL);
713 afe_cfg &= 0xff000000;
714 afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */
715 if (ch[1] != NONE && ch[2] != NONE)
716 afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */
717
718 for (i = 0; i < 3; i++) {
719 switch (ch[i]) {
720 default:
721 case NONE:
722 /* CLAMP_SEL = Fixed to midcode clamp level */
723 afe_cfg |= (0x00000200 << i);
724 break;
725 case CVBS:
726 case Y:
727 if (i > 0)
728 afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */
729 break;
730 case C:
731 case Pb:
732 case Pr:
733 /* CLAMP_SEL = Fixed to midcode clamp level */
734 afe_cfg |= (0x00000200 << i);
735 if (i == 0 && ch[i] == C)
736 afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */
737 break;
738 case SIF:
739 /*
740 * VGA_GAIN_SEL = Audio Decoder
741 * CLAMP_SEL = Fixed to midcode clamp level
742 */
743 afe_cfg |= (0x00000240 << i);
744 if (i == 0)
745 afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */
746 break;
747 }
748 }
749
750 cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg);
751
752 state->vid_input = vid_input;
753 state->aud_input = aud_input;
754 cx18_av_audio_set_path(cx);
755 input_change(cx);
756 return 0;
757}
758
759static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
760 u32 input, u32 output, u32 config)
761{
762 struct cx18_av_state *state = to_cx18_av_state(sd);
763 struct cx18 *cx = v4l2_get_subdevdata(sd);
764 return set_input(cx, input, state->aud_input);
765}
766
767static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
768 u32 input, u32 output, u32 config)
769{
770 struct cx18_av_state *state = to_cx18_av_state(sd);
771 struct cx18 *cx = v4l2_get_subdevdata(sd);
772 return set_input(cx, state->vid_input, input);
773}
774
775static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
776{
777 struct cx18_av_state *state = to_cx18_av_state(sd);
778 struct cx18 *cx = v4l2_get_subdevdata(sd);
779 u8 vpres;
780 u8 mode;
781 int val = 0;
782
783 if (state->radio)
784 return 0;
785
786 vpres = cx18_av_read(cx, 0x40e) & 0x20;
787 vt->signal = vpres ? 0xffff : 0x0;
788
789 vt->capability |=
790 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
791 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
792
793 mode = cx18_av_read(cx, 0x804);
794
795 /* get rxsubchans and audmode */
796 if ((mode & 0xf) == 1)
797 val |= V4L2_TUNER_SUB_STEREO;
798 else
799 val |= V4L2_TUNER_SUB_MONO;
800
801 if (mode == 2 || mode == 4)
802 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
803
804 if (mode & 0x10)
805 val |= V4L2_TUNER_SUB_SAP;
806
807 vt->rxsubchans = val;
808 vt->audmode = state->audmode;
809 return 0;
810}
811
812static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
813{
814 struct cx18_av_state *state = to_cx18_av_state(sd);
815 struct cx18 *cx = v4l2_get_subdevdata(sd);
816 u8 v;
817
818 if (state->radio)
819 return 0;
820
821 v = cx18_av_read(cx, 0x809);
822 v &= ~0xf;
823
824 switch (vt->audmode) {
825 case V4L2_TUNER_MODE_MONO:
826 /* mono -> mono
827 stereo -> mono
828 bilingual -> lang1 */
829 break;
830 case V4L2_TUNER_MODE_STEREO:
831 case V4L2_TUNER_MODE_LANG1:
832 /* mono -> mono
833 stereo -> stereo
834 bilingual -> lang1 */
835 v |= 0x4;
836 break;
837 case V4L2_TUNER_MODE_LANG1_LANG2:
838 /* mono -> mono
839 stereo -> stereo
840 bilingual -> lang1/lang2 */
841 v |= 0x7;
842 break;
843 case V4L2_TUNER_MODE_LANG2:
844 /* mono -> mono
845 stereo -> stereo
846 bilingual -> lang2 */
847 v |= 0x1;
848 break;
849 default:
850 return -EINVAL;
851 }
852 cx18_av_write_expect(cx, 0x809, v, v, 0xff);
853 state->audmode = vt->audmode;
854 return 0;
855}
856
857static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
858{
859 struct cx18_av_state *state = to_cx18_av_state(sd);
860 struct cx18 *cx = v4l2_get_subdevdata(sd);
861
862 u8 fmt = 0; /* zero is autodetect */
863 u8 pal_m = 0;
864
865 if (state->radio == 0 && state->std == norm)
866 return 0;
867
868 state->radio = 0;
869 state->std = norm;
870
871 /* First tests should be against specific std */
872 if (state->std == V4L2_STD_NTSC_M_JP) {
873 fmt = 0x2;
874 } else if (state->std == V4L2_STD_NTSC_443) {
875 fmt = 0x3;
876 } else if (state->std == V4L2_STD_PAL_M) {
877 pal_m = 1;
878 fmt = 0x5;
879 } else if (state->std == V4L2_STD_PAL_N) {
880 fmt = 0x6;
881 } else if (state->std == V4L2_STD_PAL_Nc) {
882 fmt = 0x7;
883 } else if (state->std == V4L2_STD_PAL_60) {
884 fmt = 0x8;
885 } else {
886 /* Then, test against generic ones */
887 if (state->std & V4L2_STD_NTSC)
888 fmt = 0x1;
889 else if (state->std & V4L2_STD_PAL)
890 fmt = 0x4;
891 else if (state->std & V4L2_STD_SECAM)
892 fmt = 0xc;
893 }
894
895 CX18_DEBUG_INFO_DEV(sd, "changing video std to fmt %i\n", fmt);
896
897 /* Follow step 9 of section 3.16 in the cx18_av datasheet.
898 Without this PAL may display a vertical ghosting effect.
899 This happens for example with the Yuan MPC622. */
900 if (fmt >= 4 && fmt < 8) {
901 /* Set format to NTSC-M */
902 cx18_av_and_or(cx, 0x400, ~0xf, 1);
903 /* Turn off LCOMB */
904 cx18_av_and_or(cx, 0x47b, ~6, 0);
905 }
906 cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20);
907 cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
908 cx18_av_std_setup(cx);
909 input_change(cx);
910 return 0;
911}
912
913static int cx18_av_s_radio(struct v4l2_subdev *sd)
914{
915 struct cx18_av_state *state = to_cx18_av_state(sd);
916 state->radio = 1;
917 return 0;
918}
919
920static int cx18_av_s_ctrl(struct v4l2_ctrl *ctrl)
921{
922 struct v4l2_subdev *sd = to_sd(ctrl);
923 struct cx18 *cx = v4l2_get_subdevdata(sd);
924
925 switch (ctrl->id) {
926 case V4L2_CID_BRIGHTNESS:
927 cx18_av_write(cx, 0x414, ctrl->val - 128);
928 break;
929
930 case V4L2_CID_CONTRAST:
931 cx18_av_write(cx, 0x415, ctrl->val << 1);
932 break;
933
934 case V4L2_CID_SATURATION:
935 cx18_av_write(cx, 0x420, ctrl->val << 1);
936 cx18_av_write(cx, 0x421, ctrl->val << 1);
937 break;
938
939 case V4L2_CID_HUE:
940 cx18_av_write(cx, 0x422, ctrl->val);
941 break;
942
943 default:
944 return -EINVAL;
945 }
946 return 0;
947}
948
949static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
950{
951 struct cx18_av_state *state = to_cx18_av_state(sd);
952 struct cx18 *cx = v4l2_get_subdevdata(sd);
953 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
954 int is_50Hz = !(state->std & V4L2_STD_525_60);
955
956 if (fmt->code != V4L2_MBUS_FMT_FIXED)
957 return -EINVAL;
958
959 fmt->field = V4L2_FIELD_INTERLACED;
960 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
961
962 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
963 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
964
965 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
966 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
967
968 /*
969 * This adjustment reflects the excess of vactive, set in
970 * cx18_av_std_setup(), above standard values:
971 *
972 * 480 + 1 for 60 Hz systems
973 * 576 + 3 for 50 Hz systems
974 */
975 Vlines = fmt->height + (is_50Hz ? 3 : 1);
976
977 /*
978 * Invalid height and width scaling requests are:
979 * 1. width less than 1/16 of the source width
980 * 2. width greater than the source width
981 * 3. height less than 1/8 of the source height
982 * 4. height greater than the source height
983 */
984 if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
985 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
986 CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
987 fmt->width, fmt->height);
988 return -ERANGE;
989 }
990
991 HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
992 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
993 VSC &= 0x1fff;
994
995 if (fmt->width >= 385)
996 filter = 0;
997 else if (fmt->width > 192)
998 filter = 1;
999 else if (fmt->width > 96)
1000 filter = 2;
1001 else
1002 filter = 3;
1003
1004 CX18_DEBUG_INFO_DEV(sd,
1005 "decoder set size %dx%d -> scale %ux%u\n",
1006 fmt->width, fmt->height, HSC, VSC);
1007
1008 /* HSCALE=HSC */
1009 cx18_av_write(cx, 0x418, HSC & 0xff);
1010 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
1011 cx18_av_write(cx, 0x41a, HSC >> 16);
1012 /* VSCALE=VSC */
1013 cx18_av_write(cx, 0x41c, VSC & 0xff);
1014 cx18_av_write(cx, 0x41d, VSC >> 8);
1015 /* VS_INTRLACE=1 VFILT=filter */
1016 cx18_av_write(cx, 0x41e, 0x8 | filter);
1017 return 0;
1018}
1019
1020static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable)
1021{
1022 struct cx18 *cx = v4l2_get_subdevdata(sd);
1023
1024 CX18_DEBUG_INFO_DEV(sd, "%s output\n", enable ? "enable" : "disable");
1025 if (enable) {
1026 cx18_av_write(cx, 0x115, 0x8c);
1027 cx18_av_write(cx, 0x116, 0x07);
1028 } else {
1029 cx18_av_write(cx, 0x115, 0x00);
1030 cx18_av_write(cx, 0x116, 0x00);
1031 }
1032 return 0;
1033}
1034
1035static void log_video_status(struct cx18 *cx)
1036{
1037 static const char *const fmt_strs[] = {
1038 "0x0",
1039 "NTSC-M", "NTSC-J", "NTSC-4.43",
1040 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
1041 "0x9", "0xA", "0xB",
1042 "SECAM",
1043 "0xD", "0xE", "0xF"
1044 };
1045
1046 struct cx18_av_state *state = &cx->av_state;
1047 struct v4l2_subdev *sd = &state->sd;
1048 u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
1049 u8 gen_stat1 = cx18_av_read(cx, 0x40d);
1050 u8 gen_stat2 = cx18_av_read(cx, 0x40e);
1051 int vid_input = state->vid_input;
1052
1053 CX18_INFO_DEV(sd, "Video signal: %spresent\n",
1054 (gen_stat2 & 0x20) ? "" : "not ");
1055 CX18_INFO_DEV(sd, "Detected format: %s\n",
1056 fmt_strs[gen_stat1 & 0xf]);
1057
1058 CX18_INFO_DEV(sd, "Specified standard: %s\n",
1059 vidfmt_sel ? fmt_strs[vidfmt_sel]
1060 : "automatic detection");
1061
1062 if (vid_input >= CX18_AV_COMPOSITE1 &&
1063 vid_input <= CX18_AV_COMPOSITE8) {
1064 CX18_INFO_DEV(sd, "Specified video input: Composite %d\n",
1065 vid_input - CX18_AV_COMPOSITE1 + 1);
1066 } else {
1067 CX18_INFO_DEV(sd, "Specified video input: "
1068 "S-Video (Luma In%d, Chroma In%d)\n",
1069 (vid_input & 0xf0) >> 4,
1070 (vid_input & 0xf00) >> 8);
1071 }
1072
1073 CX18_INFO_DEV(sd, "Specified audioclock freq: %d Hz\n",
1074 state->audclk_freq);
1075}
1076
1077static void log_audio_status(struct cx18 *cx)
1078{
1079 struct cx18_av_state *state = &cx->av_state;
1080 struct v4l2_subdev *sd = &state->sd;
1081 u8 download_ctl = cx18_av_read(cx, 0x803);
1082 u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
1083 u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
1084 u8 audio_config = cx18_av_read(cx, 0x808);
1085 u8 pref_mode = cx18_av_read(cx, 0x809);
1086 u8 afc0 = cx18_av_read(cx, 0x80b);
1087 u8 mute_ctl = cx18_av_read(cx, 0x8d3);
1088 int aud_input = state->aud_input;
1089 char *p;
1090
1091 switch (mod_det_stat0) {
1092 case 0x00: p = "mono"; break;
1093 case 0x01: p = "stereo"; break;
1094 case 0x02: p = "dual"; break;
1095 case 0x04: p = "tri"; break;
1096 case 0x10: p = "mono with SAP"; break;
1097 case 0x11: p = "stereo with SAP"; break;
1098 case 0x12: p = "dual with SAP"; break;
1099 case 0x14: p = "tri with SAP"; break;
1100 case 0xfe: p = "forced mode"; break;
1101 default: p = "not defined"; break;
1102 }
1103 CX18_INFO_DEV(sd, "Detected audio mode: %s\n", p);
1104
1105 switch (mod_det_stat1) {
1106 case 0x00: p = "not defined"; break;
1107 case 0x01: p = "EIAJ"; break;
1108 case 0x02: p = "A2-M"; break;
1109 case 0x03: p = "A2-BG"; break;
1110 case 0x04: p = "A2-DK1"; break;
1111 case 0x05: p = "A2-DK2"; break;
1112 case 0x06: p = "A2-DK3"; break;
1113 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
1114 case 0x08: p = "AM-L"; break;
1115 case 0x09: p = "NICAM-BG"; break;
1116 case 0x0a: p = "NICAM-DK"; break;
1117 case 0x0b: p = "NICAM-I"; break;
1118 case 0x0c: p = "NICAM-L"; break;
1119 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
1120 case 0x0e: p = "IF FM Radio"; break;
1121 case 0x0f: p = "BTSC"; break;
1122 case 0x10: p = "detected chrominance"; break;
1123 case 0xfd: p = "unknown audio standard"; break;
1124 case 0xfe: p = "forced audio standard"; break;
1125 case 0xff: p = "no detected audio standard"; break;
1126 default: p = "not defined"; break;
1127 }
1128 CX18_INFO_DEV(sd, "Detected audio standard: %s\n", p);
1129 CX18_INFO_DEV(sd, "Audio muted: %s\n",
1130 (mute_ctl & 0x2) ? "yes" : "no");
1131 CX18_INFO_DEV(sd, "Audio microcontroller: %s\n",
1132 (download_ctl & 0x10) ? "running" : "stopped");
1133
1134 switch (audio_config >> 4) {
1135 case 0x00: p = "undefined"; break;
1136 case 0x01: p = "BTSC"; break;
1137 case 0x02: p = "EIAJ"; break;
1138 case 0x03: p = "A2-M"; break;
1139 case 0x04: p = "A2-BG"; break;
1140 case 0x05: p = "A2-DK1"; break;
1141 case 0x06: p = "A2-DK2"; break;
1142 case 0x07: p = "A2-DK3"; break;
1143 case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
1144 case 0x09: p = "AM-L"; break;
1145 case 0x0a: p = "NICAM-BG"; break;
1146 case 0x0b: p = "NICAM-DK"; break;
1147 case 0x0c: p = "NICAM-I"; break;
1148 case 0x0d: p = "NICAM-L"; break;
1149 case 0x0e: p = "FM radio"; break;
1150 case 0x0f: p = "automatic detection"; break;
1151 default: p = "undefined"; break;
1152 }
1153 CX18_INFO_DEV(sd, "Configured audio standard: %s\n", p);
1154
1155 if ((audio_config >> 4) < 0xF) {
1156 switch (audio_config & 0xF) {
1157 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
1158 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
1159 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
1160 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
1161 case 0x04: p = "STEREO"; break;
1162 case 0x05: p = "DUAL1 (AC)"; break;
1163 case 0x06: p = "DUAL2 (BC)"; break;
1164 case 0x07: p = "DUAL3 (AB)"; break;
1165 default: p = "undefined";
1166 }
1167 CX18_INFO_DEV(sd, "Configured audio mode: %s\n", p);
1168 } else {
1169 switch (audio_config & 0xF) {
1170 case 0x00: p = "BG"; break;
1171 case 0x01: p = "DK1"; break;
1172 case 0x02: p = "DK2"; break;
1173 case 0x03: p = "DK3"; break;
1174 case 0x04: p = "I"; break;
1175 case 0x05: p = "L"; break;
1176 case 0x06: p = "BTSC"; break;
1177 case 0x07: p = "EIAJ"; break;
1178 case 0x08: p = "A2-M"; break;
1179 case 0x09: p = "FM Radio (4.5 MHz)"; break;
1180 case 0x0a: p = "FM Radio (5.5 MHz)"; break;
1181 case 0x0b: p = "S-Video"; break;
1182 case 0x0f: p = "automatic standard and mode detection"; break;
1183 default: p = "undefined"; break;
1184 }
1185 CX18_INFO_DEV(sd, "Configured audio system: %s\n", p);
1186 }
1187
1188 if (aud_input)
1189 CX18_INFO_DEV(sd, "Specified audio input: Tuner (In%d)\n",
1190 aud_input);
1191 else
1192 CX18_INFO_DEV(sd, "Specified audio input: External\n");
1193
1194 switch (pref_mode & 0xf) {
1195 case 0: p = "mono/language A"; break;
1196 case 1: p = "language B"; break;
1197 case 2: p = "language C"; break;
1198 case 3: p = "analog fallback"; break;
1199 case 4: p = "stereo"; break;
1200 case 5: p = "language AC"; break;
1201 case 6: p = "language BC"; break;
1202 case 7: p = "language AB"; break;
1203 default: p = "undefined"; break;
1204 }
1205 CX18_INFO_DEV(sd, "Preferred audio mode: %s\n", p);
1206
1207 if ((audio_config & 0xf) == 0xf) {
1208 switch ((afc0 >> 3) & 0x1) {
1209 case 0: p = "system DK"; break;
1210 case 1: p = "system L"; break;
1211 }
1212 CX18_INFO_DEV(sd, "Selected 65 MHz format: %s\n", p);
1213
1214 switch (afc0 & 0x7) {
1215 case 0: p = "Chroma"; break;
1216 case 1: p = "BTSC"; break;
1217 case 2: p = "EIAJ"; break;
1218 case 3: p = "A2-M"; break;
1219 case 4: p = "autodetect"; break;
1220 default: p = "undefined"; break;
1221 }
1222 CX18_INFO_DEV(sd, "Selected 45 MHz format: %s\n", p);
1223 }
1224}
1225
1226static int cx18_av_log_status(struct v4l2_subdev *sd)
1227{
1228 struct cx18 *cx = v4l2_get_subdevdata(sd);
1229 log_video_status(cx);
1230 log_audio_status(cx);
1231 return 0;
1232}
1233
1234static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
1235{
1236 return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
1237}
1238
1239static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
1240 struct v4l2_dbg_chip_ident *chip)
1241{
1242 struct cx18_av_state *state = to_cx18_av_state(sd);
1243
1244 if (cx18_av_dbg_match(&chip->match)) {
1245 chip->ident = state->id;
1246 chip->revision = state->rev;
1247 }
1248 return 0;
1249}
1250
1251#ifdef CONFIG_VIDEO_ADV_DEBUG
1252static int cx18_av_g_register(struct v4l2_subdev *sd,
1253 struct v4l2_dbg_register *reg)
1254{
1255 struct cx18 *cx = v4l2_get_subdevdata(sd);
1256
1257 if (!cx18_av_dbg_match(&reg->match))
1258 return -EINVAL;
1259 if ((reg->reg & 0x3) != 0)
1260 return -EINVAL;
1261 if (!capable(CAP_SYS_ADMIN))
1262 return -EPERM;
1263 reg->size = 4;
1264 reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
1265 return 0;
1266}
1267
1268static int cx18_av_s_register(struct v4l2_subdev *sd,
1269 struct v4l2_dbg_register *reg)
1270{
1271 struct cx18 *cx = v4l2_get_subdevdata(sd);
1272
1273 if (!cx18_av_dbg_match(&reg->match))
1274 return -EINVAL;
1275 if ((reg->reg & 0x3) != 0)
1276 return -EINVAL;
1277 if (!capable(CAP_SYS_ADMIN))
1278 return -EPERM;
1279 cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
1280 return 0;
1281}
1282#endif
1283
1284static const struct v4l2_ctrl_ops cx18_av_ctrl_ops = {
1285 .s_ctrl = cx18_av_s_ctrl,
1286};
1287
1288static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
1289 .g_chip_ident = cx18_av_g_chip_ident,
1290 .log_status = cx18_av_log_status,
1291 .load_fw = cx18_av_load_fw,
1292 .reset = cx18_av_reset,
1293 .g_ctrl = v4l2_subdev_g_ctrl,
1294 .s_ctrl = v4l2_subdev_s_ctrl,
1295 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
1296 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
1297 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
1298 .queryctrl = v4l2_subdev_queryctrl,
1299 .querymenu = v4l2_subdev_querymenu,
1300 .s_std = cx18_av_s_std,
1301#ifdef CONFIG_VIDEO_ADV_DEBUG
1302 .g_register = cx18_av_g_register,
1303 .s_register = cx18_av_s_register,
1304#endif
1305};
1306
1307static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = {
1308 .s_radio = cx18_av_s_radio,
1309 .s_frequency = cx18_av_s_frequency,
1310 .g_tuner = cx18_av_g_tuner,
1311 .s_tuner = cx18_av_s_tuner,
1312};
1313
1314static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
1315 .s_clock_freq = cx18_av_s_clock_freq,
1316 .s_routing = cx18_av_s_audio_routing,
1317};
1318
1319static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
1320 .s_routing = cx18_av_s_video_routing,
1321 .s_stream = cx18_av_s_stream,
1322 .s_mbus_fmt = cx18_av_s_mbus_fmt,
1323};
1324
1325static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = {
1326 .decode_vbi_line = cx18_av_decode_vbi_line,
1327 .g_sliced_fmt = cx18_av_g_sliced_fmt,
1328 .s_sliced_fmt = cx18_av_s_sliced_fmt,
1329 .s_raw_fmt = cx18_av_s_raw_fmt,
1330};
1331
1332static const struct v4l2_subdev_ops cx18_av_ops = {
1333 .core = &cx18_av_general_ops,
1334 .tuner = &cx18_av_tuner_ops,
1335 .audio = &cx18_av_audio_ops,
1336 .video = &cx18_av_video_ops,
1337 .vbi = &cx18_av_vbi_ops,
1338};
1339
1340int cx18_av_probe(struct cx18 *cx)
1341{
1342 struct cx18_av_state *state = &cx->av_state;
1343 struct v4l2_subdev *sd;
1344 int err;
1345
1346 state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
1347 state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
1348 ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
1349
1350 state->vid_input = CX18_AV_COMPOSITE7;
1351 state->aud_input = CX18_AV_AUDIO8;
1352 state->audclk_freq = 48000;
1353 state->audmode = V4L2_TUNER_MODE_LANG1;
1354 state->slicer_line_delay = 0;
1355 state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
1356
1357 sd = &state->sd;
1358 v4l2_subdev_init(sd, &cx18_av_ops);
1359 v4l2_set_subdevdata(sd, cx);
1360 snprintf(sd->name, sizeof(sd->name),
1361 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
1362 sd->grp_id = CX18_HW_418_AV;
1363 v4l2_ctrl_handler_init(&state->hdl, 9);
1364 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1365 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1366 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1367 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1368 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1369 V4L2_CID_SATURATION, 0, 127, 1, 64);
1370 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1371 V4L2_CID_HUE, -128, 127, 1, 0);
1372
1373 state->volume = v4l2_ctrl_new_std(&state->hdl,
1374 &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
1375 0, 65535, 65535 / 100, 0);
1376 v4l2_ctrl_new_std(&state->hdl,
1377 &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
1378 0, 1, 1, 0);
1379 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1380 V4L2_CID_AUDIO_BALANCE,
1381 0, 65535, 65535 / 100, 32768);
1382 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1383 V4L2_CID_AUDIO_BASS,
1384 0, 65535, 65535 / 100, 32768);
1385 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1386 V4L2_CID_AUDIO_TREBLE,
1387 0, 65535, 65535 / 100, 32768);
1388 sd->ctrl_handler = &state->hdl;
1389 if (state->hdl.error) {
1390 int err = state->hdl.error;
1391
1392 v4l2_ctrl_handler_free(&state->hdl);
1393 return err;
1394 }
1395 err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
1396 if (err)
1397 v4l2_ctrl_handler_free(&state->hdl);
1398 else
1399 cx18_av_init(cx);
1400 return err;
1401}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
new file mode 100644
index 00000000000..e9c69d9c9e4
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -0,0 +1,391 @@
1/*
2 * cx18 ADEC header
3 *
4 * Derived from cx25840-core.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301, USA.
23 */
24
25#ifndef _CX18_AV_CORE_H_
26#define _CX18_AV_CORE_H_
27
28#include <media/v4l2-device.h>
29#include <media/v4l2-ctrls.h>
30
31struct cx18;
32
33enum cx18_av_video_input {
34 /* Composite video inputs In1-In8 */
35 CX18_AV_COMPOSITE1 = 1,
36 CX18_AV_COMPOSITE2,
37 CX18_AV_COMPOSITE3,
38 CX18_AV_COMPOSITE4,
39 CX18_AV_COMPOSITE5,
40 CX18_AV_COMPOSITE6,
41 CX18_AV_COMPOSITE7,
42 CX18_AV_COMPOSITE8,
43
44 /* S-Video inputs consist of one luma input (In1-In8) ORed with one
45 chroma input (In5-In8) */
46 CX18_AV_SVIDEO_LUMA1 = 0x10,
47 CX18_AV_SVIDEO_LUMA2 = 0x20,
48 CX18_AV_SVIDEO_LUMA3 = 0x30,
49 CX18_AV_SVIDEO_LUMA4 = 0x40,
50 CX18_AV_SVIDEO_LUMA5 = 0x50,
51 CX18_AV_SVIDEO_LUMA6 = 0x60,
52 CX18_AV_SVIDEO_LUMA7 = 0x70,
53 CX18_AV_SVIDEO_LUMA8 = 0x80,
54 CX18_AV_SVIDEO_CHROMA4 = 0x400,
55 CX18_AV_SVIDEO_CHROMA5 = 0x500,
56 CX18_AV_SVIDEO_CHROMA6 = 0x600,
57 CX18_AV_SVIDEO_CHROMA7 = 0x700,
58 CX18_AV_SVIDEO_CHROMA8 = 0x800,
59
60 /* S-Video aliases for common luma/chroma combinations */
61 CX18_AV_SVIDEO1 = 0x510,
62 CX18_AV_SVIDEO2 = 0x620,
63 CX18_AV_SVIDEO3 = 0x730,
64 CX18_AV_SVIDEO4 = 0x840,
65
66 /* Component Video inputs consist of one luma input (In1-In8) ORed
67 with a red chroma (In4-In6) and blue chroma input (In7-In8) */
68 CX18_AV_COMPONENT_LUMA1 = 0x1000,
69 CX18_AV_COMPONENT_LUMA2 = 0x2000,
70 CX18_AV_COMPONENT_LUMA3 = 0x3000,
71 CX18_AV_COMPONENT_LUMA4 = 0x4000,
72 CX18_AV_COMPONENT_LUMA5 = 0x5000,
73 CX18_AV_COMPONENT_LUMA6 = 0x6000,
74 CX18_AV_COMPONENT_LUMA7 = 0x7000,
75 CX18_AV_COMPONENT_LUMA8 = 0x8000,
76 CX18_AV_COMPONENT_R_CHROMA4 = 0x40000,
77 CX18_AV_COMPONENT_R_CHROMA5 = 0x50000,
78 CX18_AV_COMPONENT_R_CHROMA6 = 0x60000,
79 CX18_AV_COMPONENT_B_CHROMA7 = 0x700000,
80 CX18_AV_COMPONENT_B_CHROMA8 = 0x800000,
81
82 /* Component Video aliases for common combinations */
83 CX18_AV_COMPONENT1 = 0x861000,
84};
85
86enum cx18_av_audio_input {
87 /* Audio inputs: serial or In4-In8 */
88 CX18_AV_AUDIO_SERIAL1,
89 CX18_AV_AUDIO_SERIAL2,
90 CX18_AV_AUDIO4 = 4,
91 CX18_AV_AUDIO5,
92 CX18_AV_AUDIO6,
93 CX18_AV_AUDIO7,
94 CX18_AV_AUDIO8,
95};
96
97struct cx18_av_state {
98 struct v4l2_subdev sd;
99 struct v4l2_ctrl_handler hdl;
100 struct v4l2_ctrl *volume;
101 int radio;
102 v4l2_std_id std;
103 enum cx18_av_video_input vid_input;
104 enum cx18_av_audio_input aud_input;
105 u32 audclk_freq;
106 int audmode;
107 u32 id;
108 u32 rev;
109 int is_initialized;
110
111 /*
112 * The VBI slicer starts operating and counting lines, beginning at
113 * slicer line count of 1, at D lines after the deassertion of VRESET.
114 * This staring field line, S, is 6 (& 319) or 10 (& 273) for 625 or 525
115 * line systems respectively. Sliced ancillary data captured on VBI
116 * slicer line M is inserted after the VBI slicer is done with line M,
117 * when VBI slicer line count is N = M+1. Thus when the VBI slicer
118 * reports a VBI slicer line number with ancillary data, the IDID0 byte
119 * indicates VBI slicer line N. The actual field line that the captured
120 * data comes from is
121 *
122 * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2).
123 *
124 * L is the line in the field, not frame, from which the VBI data came.
125 * N is the line reported by the slicer in the ancillary data.
126 * D is the slicer_line_delay value programmed into register 0x47f.
127 * S is 6 for 625 line systems or 10 for 525 line systems
128 * (S+D-2) is the slicer_line_offset used to convert slicer reported
129 * line counts to actual field lines.
130 */
131 int slicer_line_delay;
132 int slicer_line_offset;
133};
134
135
136/* Registers */
137#define CXADEC_CHIP_TYPE_TIGER 0x837
138#define CXADEC_CHIP_TYPE_MAKO 0x843
139
140#define CXADEC_HOST_REG1 0x000
141#define CXADEC_HOST_REG2 0x001
142
143#define CXADEC_CHIP_CTRL 0x100
144#define CXADEC_AFE_CTRL 0x104
145#define CXADEC_PLL_CTRL1 0x108
146#define CXADEC_VID_PLL_FRAC 0x10C
147#define CXADEC_AUX_PLL_FRAC 0x110
148#define CXADEC_PIN_CTRL1 0x114
149#define CXADEC_PIN_CTRL2 0x118
150#define CXADEC_PIN_CFG1 0x11C
151#define CXADEC_PIN_CFG2 0x120
152
153#define CXADEC_PIN_CFG3 0x124
154#define CXADEC_I2S_MCLK 0x127
155
156#define CXADEC_AUD_LOCK1 0x128
157#define CXADEC_AUD_LOCK2 0x12C
158#define CXADEC_POWER_CTRL 0x130
159#define CXADEC_AFE_DIAG_CTRL1 0x134
160#define CXADEC_AFE_DIAG_CTRL2 0x138
161#define CXADEC_AFE_DIAG_CTRL3 0x13C
162#define CXADEC_PLL_DIAG_CTRL 0x140
163#define CXADEC_TEST_CTRL1 0x144
164#define CXADEC_TEST_CTRL2 0x148
165#define CXADEC_BIST_STAT 0x14C
166#define CXADEC_DLL1_DIAG_CTRL 0x158
167#define CXADEC_DLL2_DIAG_CTRL 0x15C
168
169/* IR registers */
170#define CXADEC_IR_CTRL_REG 0x200
171#define CXADEC_IR_TXCLK_REG 0x204
172#define CXADEC_IR_RXCLK_REG 0x208
173#define CXADEC_IR_CDUTY_REG 0x20C
174#define CXADEC_IR_STAT_REG 0x210
175#define CXADEC_IR_IRQEN_REG 0x214
176#define CXADEC_IR_FILTER_REG 0x218
177#define CXADEC_IR_FIFO_REG 0x21C
178
179/* Video Registers */
180#define CXADEC_MODE_CTRL 0x400
181#define CXADEC_OUT_CTRL1 0x404
182#define CXADEC_OUT_CTRL2 0x408
183#define CXADEC_GEN_STAT 0x40C
184#define CXADEC_INT_STAT_MASK 0x410
185#define CXADEC_LUMA_CTRL 0x414
186
187#define CXADEC_BRIGHTNESS_CTRL_BYTE 0x414
188#define CXADEC_CONTRAST_CTRL_BYTE 0x415
189#define CXADEC_LUMA_CTRL_BYTE_3 0x416
190
191#define CXADEC_HSCALE_CTRL 0x418
192#define CXADEC_VSCALE_CTRL 0x41C
193
194#define CXADEC_CHROMA_CTRL 0x420
195
196#define CXADEC_USAT_CTRL_BYTE 0x420
197#define CXADEC_VSAT_CTRL_BYTE 0x421
198#define CXADEC_HUE_CTRL_BYTE 0x422
199
200#define CXADEC_VBI_LINE_CTRL1 0x424
201#define CXADEC_VBI_LINE_CTRL2 0x428
202#define CXADEC_VBI_LINE_CTRL3 0x42C
203#define CXADEC_VBI_LINE_CTRL4 0x430
204#define CXADEC_VBI_LINE_CTRL5 0x434
205#define CXADEC_VBI_FC_CFG 0x438
206#define CXADEC_VBI_MISC_CFG1 0x43C
207#define CXADEC_VBI_MISC_CFG2 0x440
208#define CXADEC_VBI_PAY1 0x444
209#define CXADEC_VBI_PAY2 0x448
210#define CXADEC_VBI_CUST1_CFG1 0x44C
211#define CXADEC_VBI_CUST1_CFG2 0x450
212#define CXADEC_VBI_CUST1_CFG3 0x454
213#define CXADEC_VBI_CUST2_CFG1 0x458
214#define CXADEC_VBI_CUST2_CFG2 0x45C
215#define CXADEC_VBI_CUST2_CFG3 0x460
216#define CXADEC_VBI_CUST3_CFG1 0x464
217#define CXADEC_VBI_CUST3_CFG2 0x468
218#define CXADEC_VBI_CUST3_CFG3 0x46C
219#define CXADEC_HORIZ_TIM_CTRL 0x470
220#define CXADEC_VERT_TIM_CTRL 0x474
221#define CXADEC_SRC_COMB_CFG 0x478
222#define CXADEC_CHROMA_VBIOFF_CFG 0x47C
223#define CXADEC_FIELD_COUNT 0x480
224#define CXADEC_MISC_TIM_CTRL 0x484
225#define CXADEC_DFE_CTRL1 0x488
226#define CXADEC_DFE_CTRL2 0x48C
227#define CXADEC_DFE_CTRL3 0x490
228#define CXADEC_PLL_CTRL2 0x494
229#define CXADEC_HTL_CTRL 0x498
230#define CXADEC_COMB_CTRL 0x49C
231#define CXADEC_CRUSH_CTRL 0x4A0
232#define CXADEC_SOFT_RST_CTRL 0x4A4
233#define CXADEC_MV_DT_CTRL2 0x4A8
234#define CXADEC_MV_DT_CTRL3 0x4AC
235#define CXADEC_MISC_DIAG_CTRL 0x4B8
236
237#define CXADEC_DL_CTL 0x800
238#define CXADEC_DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */
239#define CXADEC_DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */
240#define CXADEC_DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */
241#define CXADEC_DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */
242
243#define CXADEC_STD_DET_STATUS 0x804
244
245#define CXADEC_STD_DET_CTL 0x808
246#define CXADEC_STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */
247#define CXADEC_STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */
248
249#define CXADEC_DW8051_INT 0x80C
250#define CXADEC_GENERAL_CTL 0x810
251#define CXADEC_AAGC_CTL 0x814
252#define CXADEC_IF_SRC_CTL 0x818
253#define CXADEC_ANLOG_DEMOD_CTL 0x81C
254#define CXADEC_ROT_FREQ_CTL 0x820
255#define CXADEC_FM1_CTL 0x824
256#define CXADEC_PDF_CTL 0x828
257#define CXADEC_DFT1_CTL1 0x82C
258#define CXADEC_DFT1_CTL2 0x830
259#define CXADEC_DFT_STATUS 0x834
260#define CXADEC_DFT2_CTL1 0x838
261#define CXADEC_DFT2_CTL2 0x83C
262#define CXADEC_DFT2_STATUS 0x840
263#define CXADEC_DFT3_CTL1 0x844
264#define CXADEC_DFT3_CTL2 0x848
265#define CXADEC_DFT3_STATUS 0x84C
266#define CXADEC_DFT4_CTL1 0x850
267#define CXADEC_DFT4_CTL2 0x854
268#define CXADEC_DFT4_STATUS 0x858
269#define CXADEC_AM_MTS_DET 0x85C
270#define CXADEC_ANALOG_MUX_CTL 0x860
271#define CXADEC_DIG_PLL_CTL1 0x864
272#define CXADEC_DIG_PLL_CTL2 0x868
273#define CXADEC_DIG_PLL_CTL3 0x86C
274#define CXADEC_DIG_PLL_CTL4 0x870
275#define CXADEC_DIG_PLL_CTL5 0x874
276#define CXADEC_DEEMPH_GAIN_CTL 0x878
277#define CXADEC_DEEMPH_COEF1 0x87C
278#define CXADEC_DEEMPH_COEF2 0x880
279#define CXADEC_DBX1_CTL1 0x884
280#define CXADEC_DBX1_CTL2 0x888
281#define CXADEC_DBX1_STATUS 0x88C
282#define CXADEC_DBX2_CTL1 0x890
283#define CXADEC_DBX2_CTL2 0x894
284#define CXADEC_DBX2_STATUS 0x898
285#define CXADEC_AM_FM_DIFF 0x89C
286
287/* NICAM registers go here */
288#define CXADEC_NICAM_STATUS 0x8C8
289#define CXADEC_DEMATRIX_CTL 0x8CC
290
291#define CXADEC_PATH1_CTL1 0x8D0
292#define CXADEC_PATH1_VOL_CTL 0x8D4
293#define CXADEC_PATH1_EQ_CTL 0x8D8
294#define CXADEC_PATH1_SC_CTL 0x8DC
295
296#define CXADEC_PATH2_CTL1 0x8E0
297#define CXADEC_PATH2_VOL_CTL 0x8E4
298#define CXADEC_PATH2_EQ_CTL 0x8E8
299#define CXADEC_PATH2_SC_CTL 0x8EC
300
301#define CXADEC_SRC_CTL 0x8F0
302#define CXADEC_SRC_LF_COEF 0x8F4
303#define CXADEC_SRC1_CTL 0x8F8
304#define CXADEC_SRC2_CTL 0x8FC
305#define CXADEC_SRC3_CTL 0x900
306#define CXADEC_SRC4_CTL 0x904
307#define CXADEC_SRC5_CTL 0x908
308#define CXADEC_SRC6_CTL 0x90C
309
310#define CXADEC_BASEBAND_OUT_SEL 0x910
311#define CXADEC_I2S_IN_CTL 0x914
312#define CXADEC_I2S_OUT_CTL 0x918
313#define CXADEC_AC97_CTL 0x91C
314#define CXADEC_QAM_PDF 0x920
315#define CXADEC_QAM_CONST_DEC 0x924
316#define CXADEC_QAM_ROTATOR_FREQ 0x948
317
318/* Bit definitions / settings used in Mako Audio */
319#define CXADEC_PREF_MODE_MONO_LANGA 0
320#define CXADEC_PREF_MODE_MONO_LANGB 1
321#define CXADEC_PREF_MODE_MONO_LANGC 2
322#define CXADEC_PREF_MODE_FALLBACK 3
323#define CXADEC_PREF_MODE_STEREO 4
324#define CXADEC_PREF_MODE_DUAL_LANG_AC 5
325#define CXADEC_PREF_MODE_DUAL_LANG_BC 6
326#define CXADEC_PREF_MODE_DUAL_LANG_AB 7
327
328
329#define CXADEC_DETECT_STEREO 1
330#define CXADEC_DETECT_DUAL 2
331#define CXADEC_DETECT_TRI 4
332#define CXADEC_DETECT_SAP 0x10
333#define CXADEC_DETECT_NO_SIGNAL 0xFF
334
335#define CXADEC_SELECT_AUDIO_STANDARD_BG 0xF0 /* NICAM BG and A2 BG */
336#define CXADEC_SELECT_AUDIO_STANDARD_DK1 0xF1 /* NICAM DK and A2 DK */
337#define CXADEC_SELECT_AUDIO_STANDARD_DK2 0xF2
338#define CXADEC_SELECT_AUDIO_STANDARD_DK3 0xF3
339#define CXADEC_SELECT_AUDIO_STANDARD_I 0xF4 /* NICAM I and A1 */
340#define CXADEC_SELECT_AUDIO_STANDARD_L 0xF5 /* NICAM L and System L AM */
341#define CXADEC_SELECT_AUDIO_STANDARD_BTSC 0xF6
342#define CXADEC_SELECT_AUDIO_STANDARD_EIAJ 0xF7
343#define CXADEC_SELECT_AUDIO_STANDARD_A2_M 0xF8 /* A2 M */
344#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
345#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
346
347static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
348{
349 return container_of(sd, struct cx18_av_state, sd);
350}
351
352static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
353{
354 return &container_of(ctrl->handler, struct cx18_av_state, hdl)->sd;
355}
356
357/* ----------------------------------------------------------------------- */
358/* cx18_av-core.c */
359int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
360int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
361int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value);
362int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask);
363int cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval,
364 u32 mask);
365u8 cx18_av_read(struct cx18 *cx, u16 addr);
366u32 cx18_av_read4(struct cx18 *cx, u16 addr);
367int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
368int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
369void cx18_av_std_setup(struct cx18 *cx);
370
371int cx18_av_probe(struct cx18 *cx);
372
373/* ----------------------------------------------------------------------- */
374/* cx18_av-firmware.c */
375int cx18_av_loadfw(struct cx18 *cx);
376
377/* ----------------------------------------------------------------------- */
378/* cx18_av-audio.c */
379int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
380void cx18_av_audio_set_path(struct cx18 *cx);
381extern const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops;
382
383/* ----------------------------------------------------------------------- */
384/* cx18_av-vbi.c */
385int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
386 struct v4l2_decode_vbi_line *vbi);
387int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
388int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
389int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
390
391#endif
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
new file mode 100644
index 00000000000..280aa4d2248
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -0,0 +1,223 @@
1/*
2 * cx18 ADEC firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23#include "cx18-driver.h"
24#include "cx18-io.h"
25#include <linux/firmware.h>
26
27#define CX18_AUDIO_ENABLE 0xc72014
28#define CX18_AI1_MUX_MASK 0x30
29#define CX18_AI1_MUX_I2S1 0x00
30#define CX18_AI1_MUX_I2S2 0x10
31#define CX18_AI1_MUX_843_I2S 0x20
32#define CX18_AI1_MUX_INVALID 0x30
33
34#define FWFILE "v4l-cx23418-dig.fw"
35
36static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
37{
38 struct v4l2_subdev *sd = &cx->av_state.sd;
39 int ret = 0;
40 const u8 *data;
41 u32 size;
42 int addr;
43 u32 expected, dl_control;
44
45 /* Ensure we put the 8051 in reset and enable firmware upload mode */
46 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
47 do {
48 dl_control &= 0x00ffffff;
49 dl_control |= 0x0f000000;
50 cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control);
51 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
52 } while ((dl_control & 0xff000000) != 0x0f000000);
53
54 /* Read and auto increment until at address 0x0000 */
55 while (dl_control & 0x3fff)
56 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
57
58 data = fw->data;
59 size = fw->size;
60 for (addr = 0; addr < size; addr++) {
61 dl_control &= 0xffff3fff; /* ignore top 2 bits of address */
62 expected = 0x0f000000 | ((u32)data[addr] << 16) | addr;
63 if (expected != dl_control) {
64 CX18_ERR_DEV(sd, "verification of %s firmware load "
65 "failed: expected %#010x got %#010x\n",
66 FWFILE, expected, dl_control);
67 ret = -EIO;
68 break;
69 }
70 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
71 }
72 if (ret == 0)
73 CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n",
74 FWFILE, size);
75 return ret;
76}
77
78int cx18_av_loadfw(struct cx18 *cx)
79{
80 struct v4l2_subdev *sd = &cx->av_state.sd;
81 const struct firmware *fw = NULL;
82 u32 size;
83 u32 u, v;
84 const u8 *ptr;
85 int i;
86 int retries1 = 0;
87
88 if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
89 CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE);
90 return -EINVAL;
91 }
92
93 /* The firmware load often has byte errors, so allow for several
94 retries, both at byte level and at the firmware load level. */
95 while (retries1 < 5) {
96 cx18_av_write4_expect(cx, CXADEC_CHIP_CTRL, 0x00010000,
97 0x00008430, 0xffffffff); /* cx25843 */
98 cx18_av_write_expect(cx, CXADEC_STD_DET_CTL, 0xf6, 0xf6, 0xff);
99
100 /* Reset the Mako core, Register is alias of CXADEC_CHIP_CTRL */
101 cx18_av_write4_expect(cx, 0x8100, 0x00010000,
102 0x00008430, 0xffffffff); /* cx25843 */
103
104 /* Put the 8051 in reset and enable firmware upload */
105 cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000);
106
107 ptr = fw->data;
108 size = fw->size;
109
110 for (i = 0; i < size; i++) {
111 u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
112 u32 value = 0;
113 int retries2;
114 int unrec_err = 0;
115
116 for (retries2 = 0; retries2 < CX18_MAX_MMIO_WR_RETRIES;
117 retries2++) {
118 cx18_av_write4_noretry(cx, CXADEC_DL_CTL,
119 dl_control);
120 udelay(10);
121 value = cx18_av_read4(cx, CXADEC_DL_CTL);
122 if (value == dl_control)
123 break;
124 /* Check if we can correct the byte by changing
125 the address. We can only write the lower
126 address byte of the address. */
127 if ((value & 0x3F00) != (dl_control & 0x3F00)) {
128 unrec_err = 1;
129 break;
130 }
131 }
132 if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES)
133 break;
134 }
135 if (i == size)
136 break;
137 retries1++;
138 }
139 if (retries1 >= 5) {
140 CX18_ERR_DEV(sd, "unable to load firmware %s\n", FWFILE);
141 release_firmware(fw);
142 return -EIO;
143 }
144
145 cx18_av_write4_expect(cx, CXADEC_DL_CTL,
146 0x03000000 | fw->size, 0x03000000, 0x13000000);
147
148 CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
149
150 if (cx18_av_verifyfw(cx, fw) == 0)
151 cx18_av_write4_expect(cx, CXADEC_DL_CTL,
152 0x13000000 | fw->size, 0x13000000, 0x13000000);
153
154 /* Output to the 416 */
155 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
156
157 /* Audio input control 1 set to Sony mode */
158 /* Audio output input 2 is 0 for slave operation input */
159 /* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
160 /* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
161 after WS transition for first bit of audio word. */
162 cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0);
163
164 /* Audio output control 1 is set to Sony mode */
165 /* Audio output control 2 is set to 1 for master mode */
166 /* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
167 /* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
168 after WS transition for first bit of audio word. */
169 /* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT
170 are generated) */
171 cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
172
173 /* set alt I2s master clock to /0x16 and enable alt divider i2s
174 passthrough */
175 cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687);
176
177 cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
178 0x3F00FFFF);
179 /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
180
181 /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
182 /* Register 0x09CC is defined by the Merlin firmware, and doesn't
183 have a name in the spec. */
184 cx18_av_write4(cx, 0x09CC, 1);
185
186 v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
187 /* If bit 11 is 1, clear bit 10 */
188 if (v & 0x800)
189 cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
190 0, 0x400);
191
192 /* Toggle the AI1 MUX */
193 v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
194 u = v & CX18_AI1_MUX_MASK;
195 v &= ~CX18_AI1_MUX_MASK;
196 if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
197 /* Switch to I2S1 */
198 v |= CX18_AI1_MUX_I2S1;
199 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
200 v, CX18_AI1_MUX_MASK);
201 /* Switch back to the A/V decoder core I2S output */
202 v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
203 } else {
204 /* Switch to the A/V decoder core I2S output */
205 v |= CX18_AI1_MUX_843_I2S;
206 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
207 v, CX18_AI1_MUX_MASK);
208 /* Switch back to I2S1 or I2S2 */
209 v = (v & ~CX18_AI1_MUX_MASK) | u;
210 }
211 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
212 v, CX18_AI1_MUX_MASK);
213
214 /* Enable WW auto audio standard detection */
215 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
216 v |= 0xFF; /* Auto by default */
217 v |= 0x400; /* Stereo by default */
218 v |= 0x14000000;
219 cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
220
221 release_firmware(fw);
222 return 0;
223}
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
new file mode 100644
index 00000000000..baa36fbcd4d
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -0,0 +1,311 @@
1/*
2 * cx18 ADEC VBI functions
3 *
4 * Derived from cx25840-vbi.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24
25#include "cx18-driver.h"
26
27/*
28 * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
29 * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
30 * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
31 * (should!) look like:
32 * 4 byte EAV code: 0xff 0x00 0x00 0xRP
33 * unknown number of possible idle bytes
34 * 3 byte Anc data preamble: 0x00 0xff 0xff
35 * 1 byte data identifier: ne010iii (parity bits, 010, DID bits)
36 * 1 byte secondary data id: nessssss (parity bits, SDID bits)
37 * 1 byte data word count: necccccc (parity bits, NN Dword count)
38 * 2 byte Internal DID: VBI-line-# 0x80
39 * NN data bytes
40 * 1 byte checksum
41 * Fill bytes needed to fil out to 4*NN bytes of payload
42 *
43 * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
44 * in the vertical blanking interval are:
45 * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0)
46 * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
47 *
48 * Since the V bit is only allowed to toggle in the EAV RP code, just
49 * before the first active region line and for active lines, they are:
50 * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0)
51 * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
52 *
53 * The user application DID bytes we care about are:
54 * 0x91 (1 0 010 0 !ActiveLine AncDataPresent)
55 * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
56 *
57 */
58static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
59
60struct vbi_anc_data {
61 /* u8 eav[4]; */
62 /* u8 idle[]; Variable number of idle bytes */
63 u8 preamble[3];
64 u8 did;
65 u8 sdid;
66 u8 data_count;
67 u8 idid[2];
68 u8 payload[1]; /* data_count of payload */
69 /* u8 checksum; */
70 /* u8 fill[]; Variable number of fill bytes */
71};
72
73static int odd_parity(u8 c)
74{
75 c ^= (c >> 4);
76 c ^= (c >> 2);
77 c ^= (c >> 1);
78
79 return c & 1;
80}
81
82static int decode_vps(u8 *dst, u8 *p)
83{
84 static const u8 biphase_tbl[] = {
85 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
86 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
87 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
88 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
89 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
90 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
91 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
92 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
93 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
94 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
95 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
96 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
97 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
98 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
99 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
100 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
101 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
102 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
103 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
104 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
105 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
106 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
107 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
108 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
109 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
110 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
111 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
112 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
113 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
114 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
115 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
116 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
117 };
118
119 u8 c, err = 0;
120 int i;
121
122 for (i = 0; i < 2 * 13; i += 2) {
123 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
124 c = (biphase_tbl[p[i + 1]] & 0xf) |
125 ((biphase_tbl[p[i]] & 0xf) << 4);
126 dst[i / 2] = c;
127 }
128
129 return err & 0xf0;
130}
131
132int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
133{
134 struct cx18 *cx = v4l2_get_subdevdata(sd);
135 struct cx18_av_state *state = &cx->av_state;
136 static const u16 lcr2vbi[] = {
137 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
138 0, V4L2_SLICED_WSS_625, 0, /* 4 */
139 V4L2_SLICED_CAPTION_525, /* 6 */
140 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
141 0, 0, 0, 0
142 };
143 int is_pal = !(state->std & V4L2_STD_525_60);
144 int i;
145
146 memset(svbi, 0, sizeof(*svbi));
147 /* we're done if raw VBI is active */
148 if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
149 return 0;
150
151 if (is_pal) {
152 for (i = 7; i <= 23; i++) {
153 u8 v = cx18_av_read(cx, 0x424 + i - 7);
154
155 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
156 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
157 svbi->service_set |= svbi->service_lines[0][i] |
158 svbi->service_lines[1][i];
159 }
160 } else {
161 for (i = 10; i <= 21; i++) {
162 u8 v = cx18_av_read(cx, 0x424 + i - 10);
163
164 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
165 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
166 svbi->service_set |= svbi->service_lines[0][i] |
167 svbi->service_lines[1][i];
168 }
169 }
170 return 0;
171}
172
173int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
174{
175 struct cx18 *cx = v4l2_get_subdevdata(sd);
176 struct cx18_av_state *state = &cx->av_state;
177
178 /* Setup standard */
179 cx18_av_std_setup(cx);
180
181 /* VBI Offset */
182 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
183 cx18_av_write(cx, 0x404, 0x2e);
184 return 0;
185}
186
187int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
188{
189 struct cx18 *cx = v4l2_get_subdevdata(sd);
190 struct cx18_av_state *state = &cx->av_state;
191 int is_pal = !(state->std & V4L2_STD_525_60);
192 int i, x;
193 u8 lcr[24];
194
195 for (x = 0; x <= 23; x++)
196 lcr[x] = 0x00;
197
198 /* Setup standard */
199 cx18_av_std_setup(cx);
200
201 /* Sliced VBI */
202 cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
203 cx18_av_write(cx, 0x406, 0x13);
204 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
205
206 /* Force impossible lines to 0 */
207 if (is_pal) {
208 for (i = 0; i <= 6; i++)
209 svbi->service_lines[0][i] =
210 svbi->service_lines[1][i] = 0;
211 } else {
212 for (i = 0; i <= 9; i++)
213 svbi->service_lines[0][i] =
214 svbi->service_lines[1][i] = 0;
215
216 for (i = 22; i <= 23; i++)
217 svbi->service_lines[0][i] =
218 svbi->service_lines[1][i] = 0;
219 }
220
221 /* Build register values for requested service lines */
222 for (i = 7; i <= 23; i++) {
223 for (x = 0; x <= 1; x++) {
224 switch (svbi->service_lines[1-x][i]) {
225 case V4L2_SLICED_TELETEXT_B:
226 lcr[i] |= 1 << (4 * x);
227 break;
228 case V4L2_SLICED_WSS_625:
229 lcr[i] |= 4 << (4 * x);
230 break;
231 case V4L2_SLICED_CAPTION_525:
232 lcr[i] |= 6 << (4 * x);
233 break;
234 case V4L2_SLICED_VPS:
235 lcr[i] |= 9 << (4 * x);
236 break;
237 }
238 }
239 }
240
241 if (is_pal) {
242 for (x = 1, i = 0x424; i <= 0x434; i++, x++)
243 cx18_av_write(cx, i, lcr[6 + x]);
244 } else {
245 for (x = 1, i = 0x424; i <= 0x430; i++, x++)
246 cx18_av_write(cx, i, lcr[9 + x]);
247 for (i = 0x431; i <= 0x434; i++)
248 cx18_av_write(cx, i, 0);
249 }
250
251 cx18_av_write(cx, 0x43c, 0x16);
252 /* Should match vblank set in cx18_av_std_setup() */
253 cx18_av_write(cx, 0x474, is_pal ? 38 : 26);
254 return 0;
255}
256
257int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
258 struct v4l2_decode_vbi_line *vbi)
259{
260 struct cx18 *cx = v4l2_get_subdevdata(sd);
261 struct cx18_av_state *state = &cx->av_state;
262 struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
263 u8 *p;
264 int did, sdid, l, err = 0;
265
266 /*
267 * Check for the ancillary data header for sliced VBI
268 */
269 if (anc->preamble[0] ||
270 anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
271 (anc->did != sliced_vbi_did[0] &&
272 anc->did != sliced_vbi_did[1])) {
273 vbi->line = vbi->type = 0;
274 return 0;
275 }
276
277 did = anc->did;
278 sdid = anc->sdid & 0xf;
279 l = anc->idid[0] & 0x3f;
280 l += state->slicer_line_offset;
281 p = anc->payload;
282
283 /* Decode the SDID set by the slicer */
284 switch (sdid) {
285 case 1:
286 sdid = V4L2_SLICED_TELETEXT_B;
287 break;
288 case 4:
289 sdid = V4L2_SLICED_WSS_625;
290 break;
291 case 6:
292 sdid = V4L2_SLICED_CAPTION_525;
293 err = !odd_parity(p[0]) || !odd_parity(p[1]);
294 break;
295 case 9:
296 sdid = V4L2_SLICED_VPS;
297 if (decode_vps(p, p) != 0)
298 err = 1;
299 break;
300 default:
301 sdid = 0;
302 err = 1;
303 break;
304 }
305
306 vbi->type = err ? 0 : sdid;
307 vbi->line = err ? 0 : l;
308 vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
309 vbi->p = p;
310 return 0;
311}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
new file mode 100644
index 00000000000..c07c849b1aa
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -0,0 +1,638 @@
1/*
2 * cx18 functions to query card hardware
3 *
4 * Derived from ivtv-cards.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-cards.h"
27#include "cx18-av-core.h"
28#include "cx18-i2c.h"
29#include <media/cs5345.h>
30
31#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM)
32
33/********************** card configuration *******************************/
34
35/* usual i2c tuner addresses to probe */
36static struct cx18_card_tuner_i2c cx18_i2c_std = {
37 .radio = { I2C_CLIENT_END },
38 .demod = { 0x43, I2C_CLIENT_END },
39 .tv = { 0x61, 0x60, I2C_CLIENT_END },
40};
41
42/*
43 * usual i2c tuner addresses to probe with additional demod address for
44 * an NXP TDA8295 at 0x42 (N.B. it can possibly be at 0x4b or 0x4c too).
45 */
46static struct cx18_card_tuner_i2c cx18_i2c_nxp = {
47 .radio = { I2C_CLIENT_END },
48 .demod = { 0x42, 0x43, I2C_CLIENT_END },
49 .tv = { 0x61, 0x60, I2C_CLIENT_END },
50};
51
52/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
53 This keeps the PCI ID database up to date. Note that the entries
54 must be added under vendor 0x4444 (Conexant) as subsystem IDs.
55 New vendor IDs should still be added to the vendor ID list. */
56
57/* Hauppauge HVR-1600 cards */
58
59/* Note: for Hauppauge cards the tveeprom information is used instead
60 of PCI IDs */
61static const struct cx18_card cx18_card_hvr1600_esmt = {
62 .type = CX18_CARD_HVR_1600_ESMT,
63 .name = "Hauppauge HVR-1600",
64 .comment = "Simultaneous Digital and Analog TV capture supported\n",
65 .v4l2_capabilities = CX18_CAP_ENCODER,
66 .hw_audio_ctrl = CX18_HW_418_AV,
67 .hw_muxer = CX18_HW_CS5345,
68 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
69 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
70 CX18_HW_Z8F0811_IR_HAUP,
71 .video_inputs = {
72 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
73 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
74 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
75 { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
76 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
77 },
78 .audio_inputs = {
79 { CX18_CARD_INPUT_AUD_TUNER,
80 CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
81 { CX18_CARD_INPUT_LINE_IN1,
82 CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
83 { CX18_CARD_INPUT_LINE_IN2,
84 CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
85 },
86 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
87 CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
88 .ddr = {
89 /* ESMT M13S128324A-5B memory */
90 .chip_config = 0x003,
91 .refresh = 0x30c,
92 .timing1 = 0x44220e82,
93 .timing2 = 0x08,
94 .tune_lane = 0,
95 .initial_emrs = 0,
96 },
97 .gpio_init.initial_value = 0x3001,
98 .gpio_init.direction = 0x3001,
99 .gpio_i2c_slave_reset = {
100 .active_lo_mask = 0x3001,
101 .msecs_asserted = 10,
102 .msecs_recovery = 40,
103 .ir_reset_mask = 0x0001,
104 },
105 .i2c = &cx18_i2c_std,
106};
107
108static const struct cx18_card cx18_card_hvr1600_s5h1411 = {
109 .type = CX18_CARD_HVR_1600_S5H1411,
110 .name = "Hauppauge HVR-1600",
111 .comment = "Simultaneous Digital and Analog TV capture supported\n",
112 .v4l2_capabilities = CX18_CAP_ENCODER,
113 .hw_audio_ctrl = CX18_HW_418_AV,
114 .hw_muxer = CX18_HW_CS5345,
115 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
116 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
117 CX18_HW_Z8F0811_IR_HAUP,
118 .video_inputs = {
119 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
120 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
121 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
122 { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
123 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
124 },
125 .audio_inputs = {
126 { CX18_CARD_INPUT_AUD_TUNER,
127 CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
128 { CX18_CARD_INPUT_LINE_IN1,
129 CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
130 { CX18_CARD_INPUT_LINE_IN2,
131 CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
132 },
133 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
134 CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
135 .ddr = {
136 /* ESMT M13S128324A-5B memory */
137 .chip_config = 0x003,
138 .refresh = 0x30c,
139 .timing1 = 0x44220e82,
140 .timing2 = 0x08,
141 .tune_lane = 0,
142 .initial_emrs = 0,
143 },
144 .gpio_init.initial_value = 0x3801,
145 .gpio_init.direction = 0x3801,
146 .gpio_i2c_slave_reset = {
147 .active_lo_mask = 0x3801,
148 .msecs_asserted = 10,
149 .msecs_recovery = 40,
150 .ir_reset_mask = 0x0001,
151 },
152 .i2c = &cx18_i2c_nxp,
153};
154
155static const struct cx18_card cx18_card_hvr1600_samsung = {
156 .type = CX18_CARD_HVR_1600_SAMSUNG,
157 .name = "Hauppauge HVR-1600 (Preproduction)",
158 .comment = "Simultaneous Digital and Analog TV capture supported\n",
159 .v4l2_capabilities = CX18_CAP_ENCODER,
160 .hw_audio_ctrl = CX18_HW_418_AV,
161 .hw_muxer = CX18_HW_CS5345,
162 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
163 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
164 CX18_HW_Z8F0811_IR_HAUP,
165 .video_inputs = {
166 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
167 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
168 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
169 { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
170 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
171 },
172 .audio_inputs = {
173 { CX18_CARD_INPUT_AUD_TUNER,
174 CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
175 { CX18_CARD_INPUT_LINE_IN1,
176 CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
177 { CX18_CARD_INPUT_LINE_IN2,
178 CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
179 },
180 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
181 CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
182 .ddr = {
183 /* Samsung K4D263238G-VC33 memory */
184 .chip_config = 0x003,
185 .refresh = 0x30c,
186 .timing1 = 0x23230b73,
187 .timing2 = 0x08,
188 .tune_lane = 0,
189 .initial_emrs = 2,
190 },
191 .gpio_init.initial_value = 0x3001,
192 .gpio_init.direction = 0x3001,
193 .gpio_i2c_slave_reset = {
194 .active_lo_mask = 0x3001,
195 .msecs_asserted = 10,
196 .msecs_recovery = 40,
197 .ir_reset_mask = 0x0001,
198 },
199 .i2c = &cx18_i2c_std,
200};
201
202/* ------------------------------------------------------------------------- */
203
204/* Compro VideoMate H900: note that this card is analog only! */
205
206static const struct cx18_card_pci_info cx18_pci_h900[] = {
207 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 },
208 { 0, 0, 0 }
209};
210
211static const struct cx18_card cx18_card_h900 = {
212 .type = CX18_CARD_COMPRO_H900,
213 .name = "Compro VideoMate H900",
214 .comment = "Analog TV capture supported\n",
215 .v4l2_capabilities = CX18_CAP_ENCODER,
216 .hw_audio_ctrl = CX18_HW_418_AV,
217 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
218 .video_inputs = {
219 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
220 { CX18_CARD_INPUT_SVIDEO1, 1,
221 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
222 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
223 },
224 .audio_inputs = {
225 { CX18_CARD_INPUT_AUD_TUNER,
226 CX18_AV_AUDIO5, 0 },
227 { CX18_CARD_INPUT_LINE_IN1,
228 CX18_AV_AUDIO_SERIAL1, 0 },
229 },
230 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
231 CX18_AV_AUDIO_SERIAL1, 0 },
232 .tuners = {
233 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
234 },
235 .ddr = {
236 /* EtronTech EM6A9160TS-5G memory */
237 .chip_config = 0x50003,
238 .refresh = 0x753,
239 .timing1 = 0x24330e84,
240 .timing2 = 0x1f,
241 .tune_lane = 0,
242 .initial_emrs = 0,
243 },
244 .xceive_pin = 15,
245 .pci_list = cx18_pci_h900,
246 .i2c = &cx18_i2c_std,
247};
248
249/* ------------------------------------------------------------------------- */
250
251/* Yuan MPC718: not working at the moment! */
252
253static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
254 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 },
255 { 0, 0, 0 }
256};
257
258static const struct cx18_card cx18_card_mpc718 = {
259 .type = CX18_CARD_YUAN_MPC718,
260 .name = "Yuan MPC718 MiniPCI DVB-T/Analog",
261 .comment = "Experimenters needed for device to work well.\n"
262 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
263 .v4l2_capabilities = CX18_CAP_ENCODER,
264 .hw_audio_ctrl = CX18_HW_418_AV,
265 .hw_muxer = CX18_HW_GPIO_MUX,
266 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
267 CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
268 .video_inputs = {
269 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
270 { CX18_CARD_INPUT_SVIDEO1, 1,
271 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
272 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
273 { CX18_CARD_INPUT_SVIDEO2, 2,
274 CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
275 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
276 },
277 .audio_inputs = {
278 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
279 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
280 { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
281 },
282 .tuners = {
283 /* XC3028 tuner */
284 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
285 },
286 /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
287 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
288 .ddr = {
289 /* Hynix HY5DU283222B DDR RAM */
290 .chip_config = 0x303,
291 .refresh = 0x3bd,
292 .timing1 = 0x36320966,
293 .timing2 = 0x1f,
294 .tune_lane = 0,
295 .initial_emrs = 2,
296 },
297 .gpio_init.initial_value = 0x1,
298 .gpio_init.direction = 0x3,
299 /* FIXME - these GPIO's are just guesses */
300 .gpio_audio_input = { .mask = 0x3,
301 .tuner = 0x1,
302 .linein = 0x3,
303 .radio = 0x1 },
304 .xceive_pin = 0,
305 .pci_list = cx18_pci_mpc718,
306 .i2c = &cx18_i2c_std,
307};
308
309/* ------------------------------------------------------------------------- */
310
311/* GoTView PCI */
312
313static const struct cx18_card_pci_info cx18_pci_gotview_dvd3[] = {
314 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_GOTVIEW, 0x3343 },
315 { 0, 0, 0 }
316};
317
318static const struct cx18_card cx18_card_gotview_dvd3 = {
319 .type = CX18_CARD_GOTVIEW_PCI_DVD3,
320 .name = "GoTView PCI DVD3 Hybrid",
321 .comment = "Experimenters needed for device to work well.\n"
322 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
323 .v4l2_capabilities = CX18_CAP_ENCODER,
324 .hw_audio_ctrl = CX18_HW_418_AV,
325 .hw_muxer = CX18_HW_GPIO_MUX,
326 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
327 CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
328 .video_inputs = {
329 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
330 { CX18_CARD_INPUT_SVIDEO1, 1,
331 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
332 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
333 { CX18_CARD_INPUT_SVIDEO2, 2,
334 CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
335 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
336 },
337 .audio_inputs = {
338 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
339 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
340 { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
341 },
342 .tuners = {
343 /* XC3028 tuner */
344 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
345 },
346 /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
347 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
348 .ddr = {
349 /* Hynix HY5DU283222B DDR RAM */
350 .chip_config = 0x303,
351 .refresh = 0x3bd,
352 .timing1 = 0x36320966,
353 .timing2 = 0x1f,
354 .tune_lane = 0,
355 .initial_emrs = 2,
356 },
357 .gpio_init.initial_value = 0x1,
358 .gpio_init.direction = 0x3,
359
360 .gpio_audio_input = { .mask = 0x3,
361 .tuner = 0x1,
362 .linein = 0x2,
363 .radio = 0x1 },
364 .xceive_pin = 0,
365 .pci_list = cx18_pci_gotview_dvd3,
366 .i2c = &cx18_i2c_std,
367};
368
369/* ------------------------------------------------------------------------- */
370
371/* Conexant Raptor PAL/SECAM: note that this card is analog only! */
372
373static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
374 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_CONEXANT, 0x0009 },
375 { 0, 0, 0 }
376};
377
378static const struct cx18_card cx18_card_cnxt_raptor_pal = {
379 .type = CX18_CARD_CNXT_RAPTOR_PAL,
380 .name = "Conexant Raptor PAL/SECAM",
381 .comment = "Analog TV capture supported\n",
382 .v4l2_capabilities = CX18_CAP_ENCODER,
383 .hw_audio_ctrl = CX18_HW_418_AV,
384 .hw_muxer = CX18_HW_GPIO_MUX,
385 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX,
386 .video_inputs = {
387 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
388 { CX18_CARD_INPUT_SVIDEO1, 1,
389 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
390 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
391 { CX18_CARD_INPUT_SVIDEO2, 2,
392 CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
393 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
394 },
395 .audio_inputs = {
396 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
397 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
398 { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
399 },
400 .tuners = {
401 { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
402 },
403 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 2 },
404 .ddr = {
405 /* MT 46V16M16 memory */
406 .chip_config = 0x50306,
407 .refresh = 0x753,
408 .timing1 = 0x33220953,
409 .timing2 = 0x09,
410 .tune_lane = 0,
411 .initial_emrs = 0,
412 },
413 .gpio_init.initial_value = 0x1002,
414 .gpio_init.direction = 0xf002,
415 .gpio_audio_input = { .mask = 0xf002,
416 .tuner = 0x1002, /* LED D1 Tuner AF */
417 .linein = 0x2000, /* LED D2 Line In 1 */
418 .radio = 0x4002 }, /* LED D3 Tuner AF */
419 .pci_list = cx18_pci_cnxt_raptor_pal,
420 .i2c = &cx18_i2c_std,
421};
422
423/* ------------------------------------------------------------------------- */
424
425/* Toshiba Qosmio laptop internal DVB-T/Analog Hybrid Tuner */
426
427static const struct cx18_card_pci_info cx18_pci_toshiba_qosmio_dvbt[] = {
428 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_TOSHIBA, 0x0110 },
429 { 0, 0, 0 }
430};
431
432static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
433 .type = CX18_CARD_TOSHIBA_QOSMIO_DVBT,
434 .name = "Toshiba Qosmio DVB-T/Analog",
435 .comment = "Experimenters and photos needed for device to work well.\n"
436 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
437 .v4l2_capabilities = CX18_CAP_ENCODER,
438 .hw_audio_ctrl = CX18_HW_418_AV,
439 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
440 .video_inputs = {
441 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 },
442 { CX18_CARD_INPUT_SVIDEO1, 1,
443 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
444 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
445 },
446 .audio_inputs = {
447 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
448 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
449 },
450 .tuners = {
451 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
452 },
453 .ddr = {
454 .chip_config = 0x202,
455 .refresh = 0x3bb,
456 .timing1 = 0x33320a63,
457 .timing2 = 0x0a,
458 .tune_lane = 0,
459 .initial_emrs = 0x42,
460 },
461 .xceive_pin = 15,
462 .pci_list = cx18_pci_toshiba_qosmio_dvbt,
463 .i2c = &cx18_i2c_std,
464};
465
466/* ------------------------------------------------------------------------- */
467
468/* Leadtek WinFast PVR2100 */
469
470static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
471 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */
472 { 0, 0, 0 }
473};
474
475static const struct cx18_card cx18_card_leadtek_pvr2100 = {
476 .type = CX18_CARD_LEADTEK_PVR2100,
477 .name = "Leadtek WinFast PVR2100",
478 .comment = "Experimenters and photos needed for device to work well.\n"
479 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
480 .v4l2_capabilities = CX18_CAP_ENCODER,
481 .hw_audio_ctrl = CX18_HW_418_AV,
482 .hw_muxer = CX18_HW_GPIO_MUX,
483 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
484 CX18_HW_GPIO_RESET_CTRL,
485 .video_inputs = {
486 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
487 { CX18_CARD_INPUT_SVIDEO1, 1,
488 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
489 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
490 { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
491 },
492 .audio_inputs = {
493 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
494 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
495 },
496 .tuners = {
497 /* XC2028 tuner */
498 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
499 },
500 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
501 .ddr = {
502 /* Pointer to proper DDR config values provided by Terry Wu */
503 .chip_config = 0x303,
504 .refresh = 0x3bb,
505 .timing1 = 0x24220e83,
506 .timing2 = 0x1f,
507 .tune_lane = 0,
508 .initial_emrs = 0x2,
509 },
510 .gpio_init.initial_value = 0x6,
511 .gpio_init.direction = 0x7,
512 .gpio_audio_input = { .mask = 0x7,
513 .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
514 .xceive_pin = 1,
515 .pci_list = cx18_pci_leadtek_pvr2100,
516 .i2c = &cx18_i2c_std,
517};
518
519/* ------------------------------------------------------------------------- */
520
521/* Leadtek WinFast DVR3100 H */
522
523static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = {
524 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
525 { 0, 0, 0 }
526};
527
528static const struct cx18_card cx18_card_leadtek_dvr3100h = {
529 .type = CX18_CARD_LEADTEK_DVR3100H,
530 .name = "Leadtek WinFast DVR3100 H",
531 .comment = "Simultaneous DVB-T and Analog capture supported,\n"
532 "\texcept when capturing Analog from the antenna input.\n",
533 .v4l2_capabilities = CX18_CAP_ENCODER,
534 .hw_audio_ctrl = CX18_HW_418_AV,
535 .hw_muxer = CX18_HW_GPIO_MUX,
536 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
537 CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
538 .video_inputs = {
539 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
540 { CX18_CARD_INPUT_SVIDEO1, 1,
541 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
542 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
543 { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
544 },
545 .audio_inputs = {
546 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
547 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
548 },
549 .tuners = {
550 /* XC3028 tuner */
551 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
552 },
553 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
554 .ddr = {
555 /* Pointer to proper DDR config values provided by Terry Wu */
556 .chip_config = 0x303,
557 .refresh = 0x3bb,
558 .timing1 = 0x24220e83,
559 .timing2 = 0x1f,
560 .tune_lane = 0,
561 .initial_emrs = 0x2,
562 },
563 .gpio_init.initial_value = 0x6,
564 .gpio_init.direction = 0x7,
565 .gpio_audio_input = { .mask = 0x7,
566 .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
567 .xceive_pin = 1,
568 .pci_list = cx18_pci_leadtek_dvr3100h,
569 .i2c = &cx18_i2c_std,
570};
571
572/* ------------------------------------------------------------------------- */
573
574static const struct cx18_card *cx18_card_list[] = {
575 &cx18_card_hvr1600_esmt,
576 &cx18_card_hvr1600_samsung,
577 &cx18_card_h900,
578 &cx18_card_mpc718,
579 &cx18_card_cnxt_raptor_pal,
580 &cx18_card_toshiba_qosmio_dvbt,
581 &cx18_card_leadtek_pvr2100,
582 &cx18_card_leadtek_dvr3100h,
583 &cx18_card_gotview_dvd3,
584 &cx18_card_hvr1600_s5h1411
585};
586
587const struct cx18_card *cx18_get_card(u16 index)
588{
589 if (index >= ARRAY_SIZE(cx18_card_list))
590 return NULL;
591 return cx18_card_list[index];
592}
593
594int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
595{
596 const struct cx18_card_video_input *card_input =
597 cx->card->video_inputs + index;
598 static const char * const input_strs[] = {
599 "Tuner 1",
600 "S-Video 1",
601 "S-Video 2",
602 "Composite 1",
603 "Composite 2",
604 "Component 1"
605 };
606
607 if (index >= cx->nof_inputs)
608 return -EINVAL;
609 input->index = index;
610 strlcpy(input->name, input_strs[card_input->video_type - 1],
611 sizeof(input->name));
612 input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ?
613 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
614 input->audioset = (1 << cx->nof_audio_inputs) - 1;
615 input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
616 cx->tuner_std : V4L2_STD_ALL;
617 return 0;
618}
619
620int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio)
621{
622 const struct cx18_card_audio_input *aud_input =
623 cx->card->audio_inputs + index;
624 static const char * const input_strs[] = {
625 "Tuner 1",
626 "Line In 1",
627 "Line In 2"
628 };
629
630 memset(audio, 0, sizeof(*audio));
631 if (index >= cx->nof_audio_inputs)
632 return -EINVAL;
633 strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
634 sizeof(audio->name));
635 audio->index = index;
636 audio->capability = V4L2_AUDCAP_STEREO;
637 return 0;
638}
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
new file mode 100644
index 00000000000..add7391ecab
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -0,0 +1,157 @@
1/*
2 * cx18 functions to query card hardware
3 *
4 * Derived from ivtv-cards.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24/* hardware flags */
25#define CX18_HW_TUNER (1 << 0)
26#define CX18_HW_TVEEPROM (1 << 1)
27#define CX18_HW_CS5345 (1 << 2)
28#define CX18_HW_DVB (1 << 3)
29#define CX18_HW_418_AV (1 << 4)
30#define CX18_HW_GPIO_MUX (1 << 5)
31#define CX18_HW_GPIO_RESET_CTRL (1 << 6)
32#define CX18_HW_Z8F0811_IR_TX_HAUP (1 << 7)
33#define CX18_HW_Z8F0811_IR_RX_HAUP (1 << 8)
34#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \
35 CX18_HW_Z8F0811_IR_TX_HAUP)
36
37#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
38 CX18_HW_Z8F0811_IR_TX_HAUP)
39
40/* video inputs */
41#define CX18_CARD_INPUT_VID_TUNER 1
42#define CX18_CARD_INPUT_SVIDEO1 2
43#define CX18_CARD_INPUT_SVIDEO2 3
44#define CX18_CARD_INPUT_COMPOSITE1 4
45#define CX18_CARD_INPUT_COMPOSITE2 5
46#define CX18_CARD_INPUT_COMPONENT1 6
47
48/* audio inputs */
49#define CX18_CARD_INPUT_AUD_TUNER 1
50#define CX18_CARD_INPUT_LINE_IN1 2
51#define CX18_CARD_INPUT_LINE_IN2 3
52
53#define CX18_CARD_MAX_VIDEO_INPUTS 6
54#define CX18_CARD_MAX_AUDIO_INPUTS 3
55#define CX18_CARD_MAX_TUNERS 2
56
57/* V4L2 capability aliases */
58#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
59 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
60 V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)
61
62struct cx18_card_video_input {
63 u8 video_type; /* video input type */
64 u8 audio_index; /* index in cx18_card_audio_input array */
65 u32 video_input; /* hardware video input */
66};
67
68struct cx18_card_audio_input {
69 u8 audio_type; /* audio input type */
70 u32 audio_input; /* hardware audio input */
71 u16 muxer_input; /* hardware muxer input for boards with a
72 multiplexer chip */
73};
74
75struct cx18_card_pci_info {
76 u16 device;
77 u16 subsystem_vendor;
78 u16 subsystem_device;
79};
80
81/* GPIO definitions */
82
83/* The mask is the set of bits used by the operation */
84
85struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
86 u32 direction; /* DIR setting. Leave to 0 if no init is needed */
87 u32 initial_value;
88};
89
90struct cx18_gpio_i2c_slave_reset {
91 u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */
92 u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
93 int msecs_asserted; /* time period reset must remain asserted */
94 int msecs_recovery; /* time after deassert for chips to be ready */
95 u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */
96};
97
98struct cx18_gpio_audio_input { /* select tuner/line in input */
99 u32 mask; /* leave to 0 if not supported */
100 u32 tuner;
101 u32 linein;
102 u32 radio;
103};
104
105struct cx18_card_tuner {
106 v4l2_std_id std; /* standard for which the tuner is suitable */
107 int tuner; /* tuner ID (from tuner.h) */
108};
109
110struct cx18_card_tuner_i2c {
111 unsigned short radio[2];/* radio tuner i2c address to probe */
112 unsigned short demod[3];/* demodulator i2c address to probe */
113 unsigned short tv[4]; /* tv tuner i2c addresses to probe */
114};
115
116struct cx18_ddr { /* DDR config data */
117 u32 chip_config;
118 u32 refresh;
119 u32 timing1;
120 u32 timing2;
121 u32 tune_lane;
122 u32 initial_emrs;
123};
124
125/* for card information/parameters */
126struct cx18_card {
127 int type;
128 char *name;
129 char *comment;
130 u32 v4l2_capabilities;
131 u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only
132 1 dev allowed currently) */
133 u32 hw_muxer; /* hardware used to multiplex audio input */
134 u32 hw_all; /* all hardware used by the board */
135 struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS];
136 struct cx18_card_audio_input audio_inputs[CX18_CARD_MAX_AUDIO_INPUTS];
137 struct cx18_card_audio_input radio_input;
138
139 /* GPIO card-specific settings */
140 u8 xceive_pin; /* XCeive tuner GPIO reset pin */
141 struct cx18_gpio_init gpio_init;
142 struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
143 struct cx18_gpio_audio_input gpio_audio_input;
144
145 struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
146 struct cx18_card_tuner_i2c *i2c;
147
148 struct cx18_ddr ddr;
149
150 /* list of device and subsystem vendor/devices that
151 correspond to this card type. */
152 const struct cx18_card_pci_info *pci_list;
153};
154
155int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input);
156int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *input);
157const 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
new file mode 100644
index 00000000000..282a3d29fda
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -0,0 +1,131 @@
1/*
2 * cx18 ioctl control functions
3 *
4 * Derived from ivtv-controls.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23#include <linux/kernel.h>
24#include <linux/slab.h>
25
26#include "cx18-driver.h"
27#include "cx18-cards.h"
28#include "cx18-ioctl.h"
29#include "cx18-audio.h"
30#include "cx18-mailbox.h"
31#include "cx18-controls.h"
32
33static int cx18_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
34{
35 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
36 int type = cxhdl->stream_type->val;
37
38 if (atomic_read(&cx->ana_capturing) > 0)
39 return -EBUSY;
40
41 if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
42 !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS ||
43 type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD ||
44 type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) {
45 /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */
46 cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
47 CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
48 "the MPEG stream\n");
49 return 0;
50 }
51
52 /* Allocate sliced VBI buffers if needed. */
53 if (cx->vbi.sliced_mpeg_data[0] == NULL) {
54 int i;
55
56 for (i = 0; i < CX18_VBI_FRAMES; i++) {
57 cx->vbi.sliced_mpeg_data[i] =
58 kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL);
59 if (cx->vbi.sliced_mpeg_data[i] == NULL) {
60 while (--i >= 0) {
61 kfree(cx->vbi.sliced_mpeg_data[i]);
62 cx->vbi.sliced_mpeg_data[i] = NULL;
63 }
64 cx->vbi.insert_mpeg =
65 V4L2_MPEG_STREAM_VBI_FMT_NONE;
66 CX18_WARN("Unable to allocate buffers for "
67 "sliced VBI data insertion\n");
68 return -ENOMEM;
69 }
70 }
71 }
72
73 cx->vbi.insert_mpeg = fmt;
74 CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS,"
75 "when sliced VBI is enabled\n");
76
77 /*
78 * If our current settings have no lines set for capture, store a valid,
79 * default set of service lines to capture, in our current settings.
80 */
81 if (cx18_get_service_set(cx->vbi.sliced_in) == 0) {
82 if (cx->is_60hz)
83 cx->vbi.sliced_in->service_set =
84 V4L2_SLICED_CAPTION_525;
85 else
86 cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
87 cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz);
88 }
89 return 0;
90}
91
92static int cx18_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
93{
94 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
95 int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
96 struct v4l2_mbus_framefmt fmt;
97
98 /* fix videodecoder resolution */
99 fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
100 fmt.height = cxhdl->height;
101 fmt.code = V4L2_MBUS_FMT_FIXED;
102 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
103 return 0;
104}
105
106static int cx18_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
107{
108 static const u32 freqs[3] = { 44100, 48000, 32000 };
109 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
110
111 /* The audio clock of the digitizer must match the codec sample
112 rate otherwise you get some very strange effects. */
113 if (idx < ARRAY_SIZE(freqs))
114 cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
115 return 0;
116}
117
118static int cx18_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val)
119{
120 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
121
122 cx->dualwatch_stereo_mode = val;
123 return 0;
124}
125
126struct cx2341x_handler_ops cx18_cxhdl_ops = {
127 .s_audio_mode = cx18_s_audio_mode,
128 .s_audio_sampling_freq = cx18_s_audio_sampling_freq,
129 .s_video_encoding = cx18_s_video_encoding,
130 .s_stream_vbi_fmt = cx18_s_stream_vbi_fmt,
131};
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h
new file mode 100644
index 00000000000..cb5dfc7b205
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-controls.h
@@ -0,0 +1,24 @@
1/*
2 * cx18 ioctl control functions
3 *
4 * Derived from ivtv-controls.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24extern 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
new file mode 100644
index 00000000000..9e2f870f425
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -0,0 +1,1357 @@
1/*
2 * cx18 driver initialization and card probing
3 *
4 * Derived from ivtv-driver.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-io.h"
27#include "cx18-version.h"
28#include "cx18-cards.h"
29#include "cx18-i2c.h"
30#include "cx18-irq.h"
31#include "cx18-gpio.h"
32#include "cx18-firmware.h"
33#include "cx18-queue.h"
34#include "cx18-streams.h"
35#include "cx18-av-core.h"
36#include "cx18-scb.h"
37#include "cx18-mailbox.h"
38#include "cx18-ioctl.h"
39#include "cx18-controls.h"
40#include "tuner-xc2028.h"
41
42#include <media/tveeprom.h>
43
44/* If you have already X v4l cards, then set this to X. This way
45 the device numbers stay matched. Example: you have a WinTV card
46 without radio and a Compro H900 with. Normally this would give a
47 video1 device together with a radio0 device for the Compro. By
48 setting this to 1 you ensure that radio0 is now also radio1. */
49int cx18_first_minor;
50
51/* Callback for registering extensions */
52int (*cx18_ext_init)(struct cx18 *);
53EXPORT_SYMBOL(cx18_ext_init);
54
55/* add your revision and whatnot here */
56static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
57 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
58 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
59 {0,}
60};
61
62MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
63
64static atomic_t cx18_instance = ATOMIC_INIT(0);
65
66/* Parameter declarations */
67static int cardtype[CX18_MAX_CARDS];
68static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
69 -1, -1, -1, -1, -1, -1, -1, -1,
70 -1, -1, -1, -1, -1, -1, -1, -1,
71 -1, -1, -1, -1, -1, -1, -1, -1 };
72static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
73 -1, -1, -1, -1, -1, -1, -1, -1,
74 -1, -1, -1, -1, -1, -1, -1, -1,
75 -1, -1, -1, -1, -1, -1, -1, -1 };
76static unsigned cardtype_c = 1;
77static unsigned tuner_c = 1;
78static unsigned radio_c = 1;
79static char pal[] = "--";
80static char secam[] = "--";
81static char ntsc[] = "-";
82
83/* Buffers */
84static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
85static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
86static int enc_idx_buffers = CX18_DEFAULT_ENC_IDX_BUFFERS;
87static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
88static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
89static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
90
91static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE;
92static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
93static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
94static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
95static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
96
97static int enc_ts_bufs = -1;
98static int enc_mpg_bufs = -1;
99static int enc_idx_bufs = CX18_MAX_FW_MDLS_PER_STREAM;
100static int enc_yuv_bufs = -1;
101static int enc_vbi_bufs = -1;
102static int enc_pcm_bufs = -1;
103
104
105static int cx18_pci_latency = 1;
106
107static int mmio_ndelay;
108static int retry_mmio = 1;
109
110int cx18_debug;
111
112module_param_array(tuner, int, &tuner_c, 0644);
113module_param_array(radio, bool, &radio_c, 0644);
114module_param_array(cardtype, int, &cardtype_c, 0644);
115module_param_string(pal, pal, sizeof(pal), 0644);
116module_param_string(secam, secam, sizeof(secam), 0644);
117module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
118module_param_named(debug, cx18_debug, int, 0644);
119module_param(mmio_ndelay, int, 0644);
120module_param(retry_mmio, int, 0644);
121module_param(cx18_pci_latency, int, 0644);
122module_param(cx18_first_minor, int, 0644);
123
124module_param(enc_ts_buffers, int, 0644);
125module_param(enc_mpg_buffers, int, 0644);
126module_param(enc_idx_buffers, int, 0644);
127module_param(enc_yuv_buffers, int, 0644);
128module_param(enc_vbi_buffers, int, 0644);
129module_param(enc_pcm_buffers, int, 0644);
130
131module_param(enc_ts_bufsize, int, 0644);
132module_param(enc_mpg_bufsize, int, 0644);
133module_param(enc_idx_bufsize, int, 0644);
134module_param(enc_yuv_bufsize, int, 0644);
135module_param(enc_pcm_bufsize, int, 0644);
136
137module_param(enc_ts_bufs, int, 0644);
138module_param(enc_mpg_bufs, int, 0644);
139module_param(enc_idx_bufs, int, 0644);
140module_param(enc_yuv_bufs, int, 0644);
141module_param(enc_vbi_bufs, int, 0644);
142module_param(enc_pcm_bufs, int, 0644);
143
144MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
145 "\t\t\tsee tuner.h for values");
146MODULE_PARM_DESC(radio,
147 "Enable or disable the radio. Use only if autodetection\n"
148 "\t\t\tfails. 0 = disable, 1 = enable");
149MODULE_PARM_DESC(cardtype,
150 "Only use this option if your card is not detected properly.\n"
151 "\t\tSpecify card type:\n"
152 "\t\t\t 1 = Hauppauge HVR 1600 (ESMT memory)\n"
153 "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n"
154 "\t\t\t 3 = Compro VideoMate H900\n"
155 "\t\t\t 4 = Yuan MPC718\n"
156 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
157 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
158 "\t\t\t 7 = Leadtek WinFast PVR2100\n"
159 "\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
160 "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n"
161 "\t\t\t 10 = Hauppauge HVR 1600 (S5H1411)\n"
162 "\t\t\t 0 = Autodetect (default)\n"
163 "\t\t\t-1 = Ignore this card\n\t\t");
164MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
165MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
166MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
167MODULE_PARM_DESC(debug,
168 "Debug level (bitmask). Default: 0\n"
169 "\t\t\t 1/0x0001: warning\n"
170 "\t\t\t 2/0x0002: info\n"
171 "\t\t\t 4/0x0004: mailbox\n"
172 "\t\t\t 8/0x0008: dma\n"
173 "\t\t\t 16/0x0010: ioctl\n"
174 "\t\t\t 32/0x0020: file\n"
175 "\t\t\t 64/0x0040: i2c\n"
176 "\t\t\t128/0x0080: irq\n"
177 "\t\t\t256/0x0100: high volume\n");
178MODULE_PARM_DESC(cx18_pci_latency,
179 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
180 "\t\t\tDefault: Yes");
181MODULE_PARM_DESC(retry_mmio,
182 "(Deprecated) MMIO writes are now always checked and retried\n"
183 "\t\t\tEffectively: 1 [Yes]");
184MODULE_PARM_DESC(mmio_ndelay,
185 "(Deprecated) MMIO accesses are now never purposely delayed\n"
186 "\t\t\tEffectively: 0 ns");
187MODULE_PARM_DESC(enc_ts_buffers,
188 "Encoder TS buffer memory (MB). (enc_ts_bufs can override)\n"
189 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
190MODULE_PARM_DESC(enc_ts_bufsize,
191 "Size of an encoder TS buffer (kB)\n"
192 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFSIZE));
193MODULE_PARM_DESC(enc_ts_bufs,
194 "Number of encoder TS buffers\n"
195 "\t\t\tDefault is computed from other enc_ts_* parameters");
196MODULE_PARM_DESC(enc_mpg_buffers,
197 "Encoder MPG buffer memory (MB). (enc_mpg_bufs can override)\n"
198 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
199MODULE_PARM_DESC(enc_mpg_bufsize,
200 "Size of an encoder MPG buffer (kB)\n"
201 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFSIZE));
202MODULE_PARM_DESC(enc_mpg_bufs,
203 "Number of encoder MPG buffers\n"
204 "\t\t\tDefault is computed from other enc_mpg_* parameters");
205MODULE_PARM_DESC(enc_idx_buffers,
206 "(Deprecated) Encoder IDX buffer memory (MB)\n"
207 "\t\t\tIgnored, except 0 disables IDX buffer allocations\n"
208 "\t\t\tDefault: 1 [Enabled]");
209MODULE_PARM_DESC(enc_idx_bufsize,
210 "Size of an encoder IDX buffer (kB)\n"
211 "\t\t\tAllowed values are multiples of 1.5 kB rounded up\n"
212 "\t\t\t(multiples of size required for 64 index entries)\n"
213 "\t\t\tDefault: 2");
214MODULE_PARM_DESC(enc_idx_bufs,
215 "Number of encoder IDX buffers\n"
216 "\t\t\tDefault: " __stringify(CX18_MAX_FW_MDLS_PER_STREAM));
217MODULE_PARM_DESC(enc_yuv_buffers,
218 "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
219 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
220MODULE_PARM_DESC(enc_yuv_bufsize,
221 "Size of an encoder YUV buffer (kB)\n"
222 "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
223 "\t\t\t(multiples of size required for 32 screen lines)\n"
224 "\t\t\tDefault: 102");
225MODULE_PARM_DESC(enc_yuv_bufs,
226 "Number of encoder YUV buffers\n"
227 "\t\t\tDefault is computed from other enc_yuv_* parameters");
228MODULE_PARM_DESC(enc_vbi_buffers,
229 "Encoder VBI buffer memory (MB). (enc_vbi_bufs can override)\n"
230 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
231MODULE_PARM_DESC(enc_vbi_bufs,
232 "Number of encoder VBI buffers\n"
233 "\t\t\tDefault is computed from enc_vbi_buffers");
234MODULE_PARM_DESC(enc_pcm_buffers,
235 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
236 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
237MODULE_PARM_DESC(enc_pcm_bufsize,
238 "Size of an encoder PCM buffer (kB)\n"
239 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFSIZE));
240MODULE_PARM_DESC(enc_pcm_bufs,
241 "Number of encoder PCM buffers\n"
242 "\t\t\tDefault is computed from other enc_pcm_* parameters");
243
244MODULE_PARM_DESC(cx18_first_minor,
245 "Set device node number assigned to first card");
246
247MODULE_AUTHOR("Hans Verkuil");
248MODULE_DESCRIPTION("CX23418 driver");
249MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
250MODULE_LICENSE("GPL");
251
252MODULE_VERSION(CX18_VERSION);
253
254#if defined(CONFIG_MODULES) && defined(MODULE)
255static void request_module_async(struct work_struct *work)
256{
257 struct cx18 *dev = container_of(work, struct cx18, request_module_wk);
258
259 /* Make sure cx18-alsa module is loaded */
260 request_module("cx18-alsa");
261
262 /* Initialize cx18-alsa for this instance of the cx18 device */
263 if (cx18_ext_init != NULL)
264 cx18_ext_init(dev);
265}
266
267static void request_modules(struct cx18 *dev)
268{
269 INIT_WORK(&dev->request_module_wk, request_module_async);
270 schedule_work(&dev->request_module_wk);
271}
272
273static void flush_request_modules(struct cx18 *dev)
274{
275 flush_work_sync(&dev->request_module_wk);
276}
277#else
278#define request_modules(dev)
279#define flush_request_modules(dev)
280#endif /* CONFIG_MODULES */
281
282/* Generic utility functions */
283int cx18_msleep_timeout(unsigned int msecs, int intr)
284{
285 long int timeout = msecs_to_jiffies(msecs);
286 int sig;
287
288 do {
289 set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
290 timeout = schedule_timeout(timeout);
291 sig = intr ? signal_pending(current) : 0;
292 } while (!sig && timeout);
293 return sig;
294}
295
296/* Release ioremapped memory */
297static void cx18_iounmap(struct cx18 *cx)
298{
299 if (cx == NULL)
300 return;
301
302 /* Release io memory */
303 if (cx->enc_mem != NULL) {
304 CX18_DEBUG_INFO("releasing enc_mem\n");
305 iounmap(cx->enc_mem);
306 cx->enc_mem = NULL;
307 }
308}
309
310static void cx18_eeprom_dump(struct cx18 *cx, unsigned char *eedata, int len)
311{
312 int i;
313
314 CX18_INFO("eeprom dump:\n");
315 for (i = 0; i < len; i++) {
316 if (0 == (i % 16))
317 CX18_INFO("eeprom %02x:", i);
318 printk(KERN_CONT " %02x", eedata[i]);
319 if (15 == (i % 16))
320 printk(KERN_CONT "\n");
321 }
322}
323
324/* Hauppauge card? get values from tveeprom */
325void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
326{
327 struct i2c_client c;
328 u8 eedata[256];
329
330 memset(&c, 0, sizeof(c));
331 strlcpy(c.name, "cx18 tveeprom tmp", sizeof(c.name));
332 c.adapter = &cx->i2c_adap[0];
333 c.addr = 0xA0 >> 1;
334
335 memset(tv, 0, sizeof(*tv));
336 if (tveeprom_read(&c, eedata, sizeof(eedata)))
337 return;
338
339 switch (cx->card->type) {
340 case CX18_CARD_HVR_1600_ESMT:
341 case CX18_CARD_HVR_1600_SAMSUNG:
342 case CX18_CARD_HVR_1600_S5H1411:
343 tveeprom_hauppauge_analog(&c, tv, eedata);
344 break;
345 case CX18_CARD_YUAN_MPC718:
346 case CX18_CARD_GOTVIEW_PCI_DVD3:
347 tv->model = 0x718;
348 cx18_eeprom_dump(cx, eedata, sizeof(eedata));
349 CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n",
350 eedata[2], eedata[1], eedata[4], eedata[3]);
351 break;
352 default:
353 tv->model = 0xffffffff;
354 cx18_eeprom_dump(cx, eedata, sizeof(eedata));
355 break;
356 }
357}
358
359static void cx18_process_eeprom(struct cx18 *cx)
360{
361 struct tveeprom tv;
362
363 cx18_read_eeprom(cx, &tv);
364
365 /* Many thanks to Steven Toth from Hauppauge for providing the
366 model numbers */
367 /* Note: the Samsung memory models cannot be reliably determined
368 from the model number. Use the cardtype module option if you
369 have one of these preproduction models. */
370 switch (tv.model) {
371 case 74301: /* Retail models */
372 case 74321:
373 case 74351: /* OEM models */
374 case 74361:
375 /* Digital side is s5h1411/tda18271 */
376 cx->card = cx18_get_card(CX18_CARD_HVR_1600_S5H1411);
377 break;
378 case 74021: /* Retail models */
379 case 74031:
380 case 74041:
381 case 74141:
382 case 74541: /* OEM models */
383 case 74551:
384 case 74591:
385 case 74651:
386 case 74691:
387 case 74751:
388 case 74891:
389 /* Digital side is s5h1409/mxl5005s */
390 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
391 break;
392 case 0x718:
393 return;
394 case 0xffffffff:
395 CX18_INFO("Unknown EEPROM encoding\n");
396 return;
397 case 0:
398 CX18_ERR("Invalid EEPROM\n");
399 return;
400 default:
401 CX18_ERR("Unknown model %d, defaulting to original HVR-1600 "
402 "(cardtype=1)\n", tv.model);
403 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
404 break;
405 }
406
407 cx->v4l2_cap = cx->card->v4l2_capabilities;
408 cx->card_name = cx->card->name;
409 cx->card_i2c = cx->card->i2c;
410
411 CX18_INFO("Autodetected %s\n", cx->card_name);
412
413 if (tv.tuner_type == TUNER_ABSENT)
414 CX18_ERR("tveeprom cannot autodetect tuner!\n");
415
416 if (cx->options.tuner == -1)
417 cx->options.tuner = tv.tuner_type;
418 if (cx->options.radio == -1)
419 cx->options.radio = (tv.has_radio != 0);
420
421 if (cx->std != 0)
422 /* user specified tuner standard */
423 return;
424
425 /* autodetect tuner standard */
426#define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \
427 V4L2_STD_MN | \
428 V4L2_STD_PAL_I | \
429 V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \
430 V4L2_STD_DK)
431 if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL)
432 == TVEEPROM_TUNER_FORMAT_ALL) {
433 CX18_DEBUG_INFO("Worldwide tuner detected\n");
434 cx->std = V4L2_STD_ALL;
435 } else if (tv.tuner_formats & V4L2_STD_PAL) {
436 CX18_DEBUG_INFO("PAL tuner detected\n");
437 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
438 } else if (tv.tuner_formats & V4L2_STD_NTSC) {
439 CX18_DEBUG_INFO("NTSC tuner detected\n");
440 cx->std |= V4L2_STD_NTSC_M;
441 } else if (tv.tuner_formats & V4L2_STD_SECAM) {
442 CX18_DEBUG_INFO("SECAM tuner detected\n");
443 cx->std |= V4L2_STD_SECAM_L;
444 } else {
445 CX18_INFO("No tuner detected, default to NTSC-M\n");
446 cx->std |= V4L2_STD_NTSC_M;
447 }
448}
449
450static v4l2_std_id cx18_parse_std(struct cx18 *cx)
451{
452 switch (pal[0]) {
453 case '6':
454 return V4L2_STD_PAL_60;
455 case 'b':
456 case 'B':
457 case 'g':
458 case 'G':
459 return V4L2_STD_PAL_BG;
460 case 'h':
461 case 'H':
462 return V4L2_STD_PAL_H;
463 case 'n':
464 case 'N':
465 if (pal[1] == 'c' || pal[1] == 'C')
466 return V4L2_STD_PAL_Nc;
467 return V4L2_STD_PAL_N;
468 case 'i':
469 case 'I':
470 return V4L2_STD_PAL_I;
471 case 'd':
472 case 'D':
473 case 'k':
474 case 'K':
475 return V4L2_STD_PAL_DK;
476 case 'M':
477 case 'm':
478 return V4L2_STD_PAL_M;
479 case '-':
480 break;
481 default:
482 CX18_WARN("pal= argument not recognised\n");
483 return 0;
484 }
485
486 switch (secam[0]) {
487 case 'b':
488 case 'B':
489 case 'g':
490 case 'G':
491 case 'h':
492 case 'H':
493 return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
494 case 'd':
495 case 'D':
496 case 'k':
497 case 'K':
498 return V4L2_STD_SECAM_DK;
499 case 'l':
500 case 'L':
501 if (secam[1] == 'C' || secam[1] == 'c')
502 return V4L2_STD_SECAM_LC;
503 return V4L2_STD_SECAM_L;
504 case '-':
505 break;
506 default:
507 CX18_WARN("secam= argument not recognised\n");
508 return 0;
509 }
510
511 switch (ntsc[0]) {
512 case 'm':
513 case 'M':
514 return V4L2_STD_NTSC_M;
515 case 'j':
516 case 'J':
517 return V4L2_STD_NTSC_M_JP;
518 case 'k':
519 case 'K':
520 return V4L2_STD_NTSC_M_KR;
521 case '-':
522 break;
523 default:
524 CX18_WARN("ntsc= argument not recognised\n");
525 return 0;
526 }
527
528 /* no match found */
529 return 0;
530}
531
532static void cx18_process_options(struct cx18 *cx)
533{
534 int i, j;
535
536 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
537 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
538 cx->options.megabytes[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_buffers;
539 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
540 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
541 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
542 cx->options.megabytes[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control only */
543
544 cx->stream_buffers[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufs;
545 cx->stream_buffers[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufs;
546 cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufs;
547 cx->stream_buffers[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufs;
548 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_bufs;
549 cx->stream_buffers[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufs;
550 cx->stream_buffers[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control, no data */
551
552 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufsize;
553 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
554 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
555 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
556 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
557 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
558 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
559
560 /* Ensure stream_buffers & stream_buf_size are valid */
561 for (i = 0; i < CX18_MAX_STREAMS; i++) {
562 if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */
563 cx->options.megabytes[i] <= 0 || /* User said 0 MB total */
564 cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */
565 cx->options.megabytes[i] = 0;
566 cx->stream_buffers[i] = 0;
567 cx->stream_buf_size[i] = 0;
568 continue;
569 }
570 /*
571 * YUV is a special case where the stream_buf_size needs to be
572 * an integral multiple of 33.75 kB (storage for 32 screens
573 * lines to maintain alignment in case of lost buffers).
574 *
575 * IDX is a special case where the stream_buf_size should be
576 * an integral multiple of 1.5 kB (storage for 64 index entries
577 * to maintain alignment in case of lost buffers).
578 *
579 */
580 if (i == CX18_ENC_STREAM_TYPE_YUV) {
581 cx->stream_buf_size[i] *= 1024;
582 cx->stream_buf_size[i] -=
583 (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
584
585 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
586 cx->stream_buf_size[i] =
587 CX18_UNIT_ENC_YUV_BUFSIZE;
588 } else if (i == CX18_ENC_STREAM_TYPE_IDX) {
589 cx->stream_buf_size[i] *= 1024;
590 cx->stream_buf_size[i] -=
591 (cx->stream_buf_size[i] % CX18_UNIT_ENC_IDX_BUFSIZE);
592
593 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE)
594 cx->stream_buf_size[i] =
595 CX18_UNIT_ENC_IDX_BUFSIZE;
596 }
597 /*
598 * YUV and IDX are special cases where the stream_buf_size is
599 * now in bytes.
600 * VBI is a special case where the stream_buf_size is fixed
601 * and already in bytes
602 */
603 if (i == CX18_ENC_STREAM_TYPE_VBI ||
604 i == CX18_ENC_STREAM_TYPE_YUV ||
605 i == CX18_ENC_STREAM_TYPE_IDX) {
606 if (cx->stream_buffers[i] < 0) {
607 cx->stream_buffers[i] =
608 cx->options.megabytes[i] * 1024 * 1024
609 / cx->stream_buf_size[i];
610 } else {
611 /* N.B. This might round down to 0 */
612 cx->options.megabytes[i] =
613 cx->stream_buffers[i]
614 * cx->stream_buf_size[i]/(1024 * 1024);
615 }
616 } else {
617 /* All other streams have stream_buf_size in kB here */
618 if (cx->stream_buffers[i] < 0) {
619 cx->stream_buffers[i] =
620 cx->options.megabytes[i] * 1024
621 / cx->stream_buf_size[i];
622 } else {
623 /* N.B. This might round down to 0 */
624 cx->options.megabytes[i] =
625 cx->stream_buffers[i]
626 * cx->stream_buf_size[i] / 1024;
627 }
628 /* convert from kB to bytes */
629 cx->stream_buf_size[i] *= 1024;
630 }
631 CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
632 "%d bytes\n", i, cx->options.megabytes[i],
633 cx->stream_buffers[i], cx->stream_buf_size[i]);
634 }
635
636 cx->options.cardtype = cardtype[cx->instance];
637 cx->options.tuner = tuner[cx->instance];
638 cx->options.radio = radio[cx->instance];
639
640 cx->std = cx18_parse_std(cx);
641 if (cx->options.cardtype == -1) {
642 CX18_INFO("Ignore card\n");
643 return;
644 }
645 cx->card = cx18_get_card(cx->options.cardtype - 1);
646 if (cx->card)
647 CX18_INFO("User specified %s card\n", cx->card->name);
648 else if (cx->options.cardtype != 0)
649 CX18_ERR("Unknown user specified type, trying to autodetect card\n");
650 if (cx->card == NULL) {
651 if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
652 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
653 CX18_INFO("Autodetected Hauppauge card\n");
654 }
655 }
656 if (cx->card == NULL) {
657 for (i = 0; (cx->card = cx18_get_card(i)); i++) {
658 if (cx->card->pci_list == NULL)
659 continue;
660 for (j = 0; cx->card->pci_list[j].device; j++) {
661 if (cx->pci_dev->device !=
662 cx->card->pci_list[j].device)
663 continue;
664 if (cx->pci_dev->subsystem_vendor !=
665 cx->card->pci_list[j].subsystem_vendor)
666 continue;
667 if (cx->pci_dev->subsystem_device !=
668 cx->card->pci_list[j].subsystem_device)
669 continue;
670 CX18_INFO("Autodetected %s card\n", cx->card->name);
671 goto done;
672 }
673 }
674 }
675done:
676
677 if (cx->card == NULL) {
678 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
679 CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
680 cx->pci_dev->vendor, cx->pci_dev->device);
681 CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
682 cx->pci_dev->subsystem_vendor,
683 cx->pci_dev->subsystem_device);
684 CX18_ERR("Defaulting to %s card\n", cx->card->name);
685 CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
686 CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
687 CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
688 }
689 cx->v4l2_cap = cx->card->v4l2_capabilities;
690 cx->card_name = cx->card->name;
691 cx->card_i2c = cx->card->i2c;
692}
693
694static int __devinit cx18_create_in_workq(struct cx18 *cx)
695{
696 snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
697 cx->v4l2_dev.name);
698 cx->in_work_queue = alloc_ordered_workqueue(cx->in_workq_name, 0);
699 if (cx->in_work_queue == NULL) {
700 CX18_ERR("Unable to create incoming mailbox handler thread\n");
701 return -ENOMEM;
702 }
703 return 0;
704}
705
706static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
707{
708 int i;
709 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
710 cx->in_work_order[i].cx = cx;
711 cx->in_work_order[i].str = cx->epu_debug_str;
712 INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
713 }
714}
715
716/* Precondition: the cx18 structure has been memset to 0. Only
717 the dev and instance fields have been filled in.
718 No assumptions on the card type may be made here (see cx18_init_struct2
719 for that).
720 */
721static int __devinit cx18_init_struct1(struct cx18 *cx)
722{
723 int ret;
724
725 cx->base_addr = pci_resource_start(cx->pci_dev, 0);
726
727 mutex_init(&cx->serialize_lock);
728 mutex_init(&cx->gpio_lock);
729 mutex_init(&cx->epu2apu_mb_lock);
730 mutex_init(&cx->epu2cpu_mb_lock);
731
732 ret = cx18_create_in_workq(cx);
733 if (ret)
734 return ret;
735
736 cx18_init_in_work_orders(cx);
737
738 /* start counting open_id at 1 */
739 cx->open_id = 1;
740
741 /* Initial settings */
742 cx->cxhdl.port = CX2341X_PORT_MEMORY;
743 cx->cxhdl.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI;
744 cx->cxhdl.ops = &cx18_cxhdl_ops;
745 cx->cxhdl.func = cx18_api_func;
746 cx->cxhdl.priv = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
747 ret = cx2341x_handler_init(&cx->cxhdl, 50);
748 if (ret)
749 return ret;
750 cx->v4l2_dev.ctrl_handler = &cx->cxhdl.hdl;
751
752 cx->temporal_strength = cx->cxhdl.video_temporal_filter->cur.val;
753 cx->spatial_strength = cx->cxhdl.video_spatial_filter->cur.val;
754 cx->filter_mode = cx->cxhdl.video_spatial_filter_mode->cur.val |
755 (cx->cxhdl.video_temporal_filter_mode->cur.val << 1) |
756 (cx->cxhdl.video_median_filter_type->cur.val << 2);
757
758 init_waitqueue_head(&cx->cap_w);
759 init_waitqueue_head(&cx->mb_apu_waitq);
760 init_waitqueue_head(&cx->mb_cpu_waitq);
761 init_waitqueue_head(&cx->dma_waitq);
762
763 /* VBI */
764 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
765 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
766
767 /* IVTV style VBI insertion into MPEG streams */
768 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_buf.list);
769 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.list);
770 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.buf_list);
771 list_add(&cx->vbi.sliced_mpeg_buf.list,
772 &cx->vbi.sliced_mpeg_mdl.buf_list);
773 return 0;
774}
775
776/* Second initialization part. Here the card type has been
777 autodetected. */
778static void __devinit cx18_init_struct2(struct cx18 *cx)
779{
780 int i;
781
782 for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++)
783 if (cx->card->video_inputs[i].video_type == 0)
784 break;
785 cx->nof_inputs = i;
786 for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++)
787 if (cx->card->audio_inputs[i].audio_type == 0)
788 break;
789 cx->nof_audio_inputs = i;
790
791 /* Find tuner input */
792 for (i = 0; i < cx->nof_inputs; i++) {
793 if (cx->card->video_inputs[i].video_type ==
794 CX18_CARD_INPUT_VID_TUNER)
795 break;
796 }
797 if (i == cx->nof_inputs)
798 i = 0;
799 cx->active_input = i;
800 cx->audio_input = cx->card->video_inputs[i].audio_index;
801}
802
803static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
804 const struct pci_device_id *pci_id)
805{
806 u16 cmd;
807 unsigned char pci_latency;
808
809 CX18_DEBUG_INFO("Enabling pci device\n");
810
811 if (pci_enable_device(pci_dev)) {
812 CX18_ERR("Can't enable device %d!\n", cx->instance);
813 return -EIO;
814 }
815 if (pci_set_dma_mask(pci_dev, 0xffffffff)) {
816 CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
817 return -EIO;
818 }
819 if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
820 CX18_ERR("Cannot request encoder memory region, card %d\n",
821 cx->instance);
822 return -EIO;
823 }
824
825 /* Enable bus mastering and memory mapped IO for the CX23418 */
826 pci_read_config_word(pci_dev, PCI_COMMAND, &cmd);
827 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
828 pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
829
830 cx->card_rev = pci_dev->revision;
831 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
832
833 if (pci_latency < 64 && cx18_pci_latency) {
834 CX18_INFO("Unreasonably low latency timer, "
835 "setting to 64 (was %d)\n", pci_latency);
836 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64);
837 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
838 }
839
840 CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
841 "irq: %d, latency: %d, memory: 0x%lx\n",
842 cx->pci_dev->device, cx->card_rev, pci_dev->bus->number,
843 PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn),
844 cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr);
845
846 return 0;
847}
848
849static void cx18_init_subdevs(struct cx18 *cx)
850{
851 u32 hw = cx->card->hw_all;
852 u32 device;
853 int i;
854
855 for (i = 0, device = 1; i < 32; i++, device <<= 1) {
856
857 if (!(device & hw))
858 continue;
859
860 switch (device) {
861 case CX18_HW_DVB:
862 case CX18_HW_TVEEPROM:
863 /* These subordinate devices do not use probing */
864 cx->hw_flags |= device;
865 break;
866 case CX18_HW_418_AV:
867 /* The A/V decoder gets probed earlier to set PLLs */
868 /* Just note that the card uses it (i.e. has analog) */
869 cx->hw_flags |= device;
870 break;
871 case CX18_HW_GPIO_RESET_CTRL:
872 /*
873 * The Reset Controller gets probed and added to
874 * hw_flags earlier for i2c adapter/bus initialization
875 */
876 break;
877 case CX18_HW_GPIO_MUX:
878 if (cx18_gpio_register(cx, device) == 0)
879 cx->hw_flags |= device;
880 break;
881 default:
882 if (cx18_i2c_register(cx, i) == 0)
883 cx->hw_flags |= device;
884 break;
885 }
886 }
887
888 if (cx->hw_flags & CX18_HW_418_AV)
889 cx->sd_av = cx18_find_hw(cx, CX18_HW_418_AV);
890
891 if (cx->card->hw_muxer != 0)
892 cx->sd_extmux = cx18_find_hw(cx, cx->card->hw_muxer);
893}
894
895static int __devinit cx18_probe(struct pci_dev *pci_dev,
896 const struct pci_device_id *pci_id)
897{
898 int retval = 0;
899 int i;
900 u32 devtype;
901 struct cx18 *cx;
902
903 /* FIXME - module parameter arrays constrain max instances */
904 i = atomic_inc_return(&cx18_instance) - 1;
905 if (i >= CX18_MAX_CARDS) {
906 printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
907 "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
908 return -ENOMEM;
909 }
910
911 cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
912 if (cx == NULL) {
913 printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
914 i);
915 return -ENOMEM;
916 }
917 cx->pci_dev = pci_dev;
918 cx->instance = i;
919
920 retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
921 if (retval) {
922 printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
923 "\n", cx->instance);
924 kfree(cx);
925 return retval;
926 }
927 snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
928 cx->instance);
929 CX18_INFO("Initializing card %d\n", cx->instance);
930
931 cx18_process_options(cx);
932 if (cx->options.cardtype == -1) {
933 retval = -ENODEV;
934 goto err;
935 }
936
937 retval = cx18_init_struct1(cx);
938 if (retval)
939 goto err;
940
941 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
942
943 /* PCI Device Setup */
944 retval = cx18_setup_pci(cx, pci_dev, pci_id);
945 if (retval != 0)
946 goto free_workqueues;
947
948 /* map io memory */
949 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
950 cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
951 cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET,
952 CX18_MEM_SIZE);
953 if (!cx->enc_mem) {
954 CX18_ERR("ioremap failed. Can't get a window into CX23418 "
955 "memory and register space\n");
956 CX18_ERR("Each capture card with a CX23418 needs 64 MB of "
957 "vmalloc address space for the window\n");
958 CX18_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
959 CX18_ERR("Use the vmalloc= kernel command line option to set "
960 "VmallocTotal to a larger value\n");
961 retval = -ENOMEM;
962 goto free_mem;
963 }
964 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
965 devtype = cx18_read_reg(cx, 0xC72028);
966 switch (devtype & 0xff000000) {
967 case 0xff000000:
968 CX18_INFO("cx23418 revision %08x (A)\n", devtype);
969 break;
970 case 0x01000000:
971 CX18_INFO("cx23418 revision %08x (B)\n", devtype);
972 break;
973 default:
974 CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype);
975 break;
976 }
977
978 cx18_init_power(cx, 1);
979 cx18_init_memory(cx);
980
981 cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET);
982 cx18_init_scb(cx);
983
984 cx18_gpio_init(cx);
985
986 /* Initialize integrated A/V decoder early to set PLLs, just in case */
987 retval = cx18_av_probe(cx);
988 if (retval) {
989 CX18_ERR("Could not register A/V decoder subdevice\n");
990 goto free_map;
991 }
992
993 /* Initialize GPIO Reset Controller to do chip resets during i2c init */
994 if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
995 if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0)
996 CX18_WARN("Could not register GPIO reset controller"
997 "subdevice; proceeding anyway.\n");
998 else
999 cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL;
1000 }
1001
1002 /* active i2c */
1003 CX18_DEBUG_INFO("activating i2c...\n");
1004 retval = init_cx18_i2c(cx);
1005 if (retval) {
1006 CX18_ERR("Could not initialize i2c\n");
1007 goto free_map;
1008 }
1009
1010 if (cx->card->hw_all & CX18_HW_TVEEPROM) {
1011 /* Based on the model number the cardtype may be changed.
1012 The PCI IDs are not always reliable. */
1013 const struct cx18_card *orig_card = cx->card;
1014 cx18_process_eeprom(cx);
1015
1016 if (cx->card != orig_card) {
1017 /* Changed the cardtype; re-reset the I2C chips */
1018 cx18_gpio_init(cx);
1019 cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
1020 core, reset, (u32) CX18_GPIO_RESET_I2C);
1021 }
1022 }
1023 if (cx->card->comment)
1024 CX18_INFO("%s", cx->card->comment);
1025 if (cx->card->v4l2_capabilities == 0) {
1026 retval = -ENODEV;
1027 goto free_i2c;
1028 }
1029 cx18_init_memory(cx);
1030 cx18_init_scb(cx);
1031
1032 /* Register IRQ */
1033 retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
1034 IRQF_SHARED | IRQF_DISABLED,
1035 cx->v4l2_dev.name, (void *)cx);
1036 if (retval) {
1037 CX18_ERR("Failed to register irq %d\n", retval);
1038 goto free_i2c;
1039 }
1040
1041 if (cx->std == 0)
1042 cx->std = V4L2_STD_NTSC_M;
1043
1044 if (cx->options.tuner == -1) {
1045 for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
1046 if ((cx->std & cx->card->tuners[i].std) == 0)
1047 continue;
1048 cx->options.tuner = cx->card->tuners[i].tuner;
1049 break;
1050 }
1051 }
1052 /* if no tuner was found, then pick the first tuner in the card list */
1053 if (cx->options.tuner == -1 && cx->card->tuners[0].std) {
1054 cx->std = cx->card->tuners[0].std;
1055 if (cx->std & V4L2_STD_PAL)
1056 cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
1057 else if (cx->std & V4L2_STD_NTSC)
1058 cx->std = V4L2_STD_NTSC_M;
1059 else if (cx->std & V4L2_STD_SECAM)
1060 cx->std = V4L2_STD_SECAM_L;
1061 cx->options.tuner = cx->card->tuners[0].tuner;
1062 }
1063 if (cx->options.radio == -1)
1064 cx->options.radio = (cx->card->radio_input.audio_type != 0);
1065
1066 /* The card is now fully identified, continue with card-specific
1067 initialization. */
1068 cx18_init_struct2(cx);
1069
1070 cx18_init_subdevs(cx);
1071
1072 if (cx->std & V4L2_STD_525_60)
1073 cx->is_60hz = 1;
1074 else
1075 cx->is_50hz = 1;
1076
1077 cx2341x_handler_set_50hz(&cx->cxhdl, !cx->is_60hz);
1078
1079 if (cx->options.radio > 0)
1080 cx->v4l2_cap |= V4L2_CAP_RADIO;
1081
1082 if (cx->options.tuner > -1) {
1083 struct tuner_setup setup;
1084
1085 setup.addr = ADDR_UNSET;
1086 setup.type = cx->options.tuner;
1087 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
1088 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
1089 cx18_reset_tuner_gpio : NULL;
1090 cx18_call_all(cx, tuner, s_type_addr, &setup);
1091 if (setup.type == TUNER_XC2028) {
1092 static struct xc2028_ctrl ctrl = {
1093 .fname = XC2028_DEFAULT_FIRMWARE,
1094 .max_len = 64,
1095 };
1096 struct v4l2_priv_tun_config cfg = {
1097 .tuner = cx->options.tuner,
1098 .priv = &ctrl,
1099 };
1100 cx18_call_all(cx, tuner, s_config, &cfg);
1101 }
1102 }
1103
1104 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
1105 are not. */
1106 cx->tuner_std = cx->std;
1107 if (cx->std == V4L2_STD_ALL)
1108 cx->std = V4L2_STD_NTSC_M;
1109
1110 retval = cx18_streams_setup(cx);
1111 if (retval) {
1112 CX18_ERR("Error %d setting up streams\n", retval);
1113 goto free_irq;
1114 }
1115 retval = cx18_streams_register(cx);
1116 if (retval) {
1117 CX18_ERR("Error %d registering devices\n", retval);
1118 goto free_streams;
1119 }
1120
1121 CX18_INFO("Initialized card: %s\n", cx->card_name);
1122
1123 /* Load cx18 submodules (cx18-alsa) */
1124 request_modules(cx);
1125 return 0;
1126
1127free_streams:
1128 cx18_streams_cleanup(cx, 1);
1129free_irq:
1130 free_irq(cx->pci_dev->irq, (void *)cx);
1131free_i2c:
1132 exit_cx18_i2c(cx);
1133free_map:
1134 cx18_iounmap(cx);
1135free_mem:
1136 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
1137free_workqueues:
1138 destroy_workqueue(cx->in_work_queue);
1139err:
1140 if (retval == 0)
1141 retval = -ENODEV;
1142 CX18_ERR("Error %d on initialization\n", retval);
1143
1144 v4l2_device_unregister(&cx->v4l2_dev);
1145 kfree(cx);
1146 return retval;
1147}
1148
1149int cx18_init_on_first_open(struct cx18 *cx)
1150{
1151 int video_input;
1152 int fw_retry_count = 3;
1153 struct v4l2_frequency vf;
1154 struct cx18_open_id fh;
1155 v4l2_std_id std;
1156
1157 fh.cx = cx;
1158
1159 if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
1160 return -ENXIO;
1161
1162 if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags))
1163 return 0;
1164
1165 while (--fw_retry_count > 0) {
1166 /* load firmware */
1167 if (cx18_firmware_init(cx) == 0)
1168 break;
1169 if (fw_retry_count > 1)
1170 CX18_WARN("Retry loading firmware\n");
1171 }
1172
1173 if (fw_retry_count == 0) {
1174 set_bit(CX18_F_I_FAILED, &cx->i_flags);
1175 return -ENXIO;
1176 }
1177 set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
1178
1179 /*
1180 * Init the firmware twice to work around a silicon bug
1181 * with the digital TS.
1182 *
1183 * The second firmware load requires us to normalize the APU state,
1184 * or the audio for the first analog capture will be badly incorrect.
1185 *
1186 * I can't seem to call APU_RESETAI and have it succeed without the
1187 * APU capturing audio, so we start and stop it here to do the reset
1188 */
1189
1190 /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
1191 cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
1192 cx18_vapi(cx, CX18_APU_RESETAI, 0);
1193 cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
1194
1195 fw_retry_count = 3;
1196 while (--fw_retry_count > 0) {
1197 /* load firmware */
1198 if (cx18_firmware_init(cx) == 0)
1199 break;
1200 if (fw_retry_count > 1)
1201 CX18_WARN("Retry loading firmware\n");
1202 }
1203
1204 if (fw_retry_count == 0) {
1205 set_bit(CX18_F_I_FAILED, &cx->i_flags);
1206 return -ENXIO;
1207 }
1208
1209 /*
1210 * The second firmware load requires us to normalize the APU state,
1211 * or the audio for the first analog capture will be badly incorrect.
1212 *
1213 * I can't seem to call APU_RESETAI and have it succeed without the
1214 * APU capturing audio, so we start and stop it here to do the reset
1215 */
1216
1217 /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
1218 cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
1219 cx18_vapi(cx, CX18_APU_RESETAI, 0);
1220 cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
1221
1222 /* Init the A/V decoder, if it hasn't been already */
1223 v4l2_subdev_call(cx->sd_av, core, load_fw);
1224
1225 vf.tuner = 0;
1226 vf.type = V4L2_TUNER_ANALOG_TV;
1227 vf.frequency = 6400; /* the tuner 'baseline' frequency */
1228
1229 /* Set initial frequency. For PAL/SECAM broadcasts no
1230 'default' channel exists AFAIK. */
1231 if (cx->std == V4L2_STD_NTSC_M_JP)
1232 vf.frequency = 1460; /* ch. 1 91250*16/1000 */
1233 else if (cx->std & V4L2_STD_NTSC_M)
1234 vf.frequency = 1076; /* ch. 4 67250*16/1000 */
1235
1236 video_input = cx->active_input;
1237 cx->active_input++; /* Force update of input */
1238 cx18_s_input(NULL, &fh, video_input);
1239
1240 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
1241 in one place. */
1242 cx->std++; /* Force full standard initialization */
1243 std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
1244 cx18_s_std(NULL, &fh, &std);
1245 cx18_s_frequency(NULL, &fh, &vf);
1246 return 0;
1247}
1248
1249static void cx18_cancel_in_work_orders(struct cx18 *cx)
1250{
1251 int i;
1252 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++)
1253 cancel_work_sync(&cx->in_work_order[i].work);
1254}
1255
1256static void cx18_cancel_out_work_orders(struct cx18 *cx)
1257{
1258 int i;
1259 for (i = 0; i < CX18_MAX_STREAMS; i++)
1260 if (&cx->streams[i].video_dev != NULL)
1261 cancel_work_sync(&cx->streams[i].out_work_order);
1262}
1263
1264static void cx18_remove(struct pci_dev *pci_dev)
1265{
1266 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1267 struct cx18 *cx = to_cx18(v4l2_dev);
1268 int i;
1269
1270 CX18_DEBUG_INFO("Removing Card\n");
1271
1272 flush_request_modules(cx);
1273
1274 /* Stop all captures */
1275 CX18_DEBUG_INFO("Stopping all streams\n");
1276 if (atomic_read(&cx->tot_capturing) > 0)
1277 cx18_stop_all_captures(cx);
1278
1279 /* Stop interrupts that cause incoming work to be queued */
1280 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
1281
1282 /* Incoming work can cause outgoing work, so clean up incoming first */
1283 cx18_cancel_in_work_orders(cx);
1284 cx18_cancel_out_work_orders(cx);
1285
1286 /* Stop ack interrupts that may have been needed for work to finish */
1287 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
1288
1289 cx18_halt_firmware(cx);
1290
1291 destroy_workqueue(cx->in_work_queue);
1292
1293 cx18_streams_cleanup(cx, 1);
1294
1295 exit_cx18_i2c(cx);
1296
1297 free_irq(cx->pci_dev->irq, (void *)cx);
1298
1299 cx18_iounmap(cx);
1300
1301 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
1302
1303 pci_disable_device(cx->pci_dev);
1304
1305 if (cx->vbi.sliced_mpeg_data[0] != NULL)
1306 for (i = 0; i < CX18_VBI_FRAMES; i++)
1307 kfree(cx->vbi.sliced_mpeg_data[i]);
1308
1309 v4l2_ctrl_handler_free(&cx->av_state.hdl);
1310
1311 CX18_INFO("Removed %s\n", cx->card_name);
1312
1313 v4l2_device_unregister(v4l2_dev);
1314 kfree(cx);
1315}
1316
1317
1318/* define a pci_driver for card detection */
1319static struct pci_driver cx18_pci_driver = {
1320 .name = "cx18",
1321 .id_table = cx18_pci_tbl,
1322 .probe = cx18_probe,
1323 .remove = cx18_remove,
1324};
1325
1326static int __init module_start(void)
1327{
1328 printk(KERN_INFO "cx18: Start initialization, version %s\n",
1329 CX18_VERSION);
1330
1331 /* Validate parameters */
1332 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
1333 printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
1334 CX18_MAX_CARDS - 1);
1335 return -1;
1336 }
1337
1338 if (cx18_debug < 0 || cx18_debug > 511) {
1339 cx18_debug = 0;
1340 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
1341 }
1342
1343 if (pci_register_driver(&cx18_pci_driver)) {
1344 printk(KERN_ERR "cx18: Error detecting PCI card\n");
1345 return -ENODEV;
1346 }
1347 printk(KERN_INFO "cx18: End initialization\n");
1348 return 0;
1349}
1350
1351static void __exit module_cleanup(void)
1352{
1353 pci_unregister_driver(&cx18_pci_driver);
1354}
1355
1356module_init(module_start);
1357module_exit(module_cleanup);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
new file mode 100644
index 00000000000..18342072306
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -0,0 +1,735 @@
1/*
2 * cx18 driver internal defines and structures
3 *
4 * Derived from ivtv-driver.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#ifndef CX18_DRIVER_H
26#define CX18_DRIVER_H
27
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <linux/sched.h>
33#include <linux/fs.h>
34#include <linux/pci.h>
35#include <linux/interrupt.h>
36#include <linux/spinlock.h>
37#include <linux/i2c.h>
38#include <linux/i2c-algo-bit.h>
39#include <linux/list.h>
40#include <linux/unistd.h>
41#include <linux/pagemap.h>
42#include <linux/workqueue.h>
43#include <linux/mutex.h>
44#include <linux/slab.h>
45#include <asm/byteorder.h>
46
47#include <linux/dvb/video.h>
48#include <linux/dvb/audio.h>
49#include <media/v4l2-common.h>
50#include <media/v4l2-ioctl.h>
51#include <media/v4l2-device.h>
52#include <media/v4l2-fh.h>
53#include <media/tuner.h>
54#include <media/ir-kbd-i2c.h>
55#include "cx18-mailbox.h"
56#include "cx18-av-core.h"
57#include "cx23418.h"
58
59/* DVB */
60#include "demux.h"
61#include "dmxdev.h"
62#include "dvb_demux.h"
63#include "dvb_frontend.h"
64#include "dvb_net.h"
65#include "dvbdev.h"
66
67/* Videobuf / YUV support */
68#include <media/videobuf-core.h>
69#include <media/videobuf-vmalloc.h>
70
71#ifndef CONFIG_PCI
72# error "This driver requires kernel PCI support."
73#endif
74
75#define CX18_MEM_OFFSET 0x00000000
76#define CX18_MEM_SIZE 0x04000000
77#define CX18_REG_OFFSET 0x02000000
78
79/* Maximum cx18 driver instances. */
80#define CX18_MAX_CARDS 32
81
82/* Supported cards */
83#define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */
84#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
85#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
86#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
87#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
88#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
89#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
90#define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */
91#define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */
92#define CX18_CARD_HVR_1600_S5H1411 9 /* Hauppauge HVR 1600 s5h1411/tda18271*/
93#define CX18_CARD_LAST 9
94
95#define CX18_ENC_STREAM_TYPE_MPG 0
96#define CX18_ENC_STREAM_TYPE_TS 1
97#define CX18_ENC_STREAM_TYPE_YUV 2
98#define CX18_ENC_STREAM_TYPE_VBI 3
99#define CX18_ENC_STREAM_TYPE_PCM 4
100#define CX18_ENC_STREAM_TYPE_IDX 5
101#define CX18_ENC_STREAM_TYPE_RAD 6
102#define CX18_MAX_STREAMS 7
103
104/* system vendor and device IDs */
105#define PCI_VENDOR_ID_CX 0x14f1
106#define PCI_DEVICE_ID_CX23418 0x5b7a
107
108/* subsystem vendor ID */
109#define CX18_PCI_ID_HAUPPAUGE 0x0070
110#define CX18_PCI_ID_COMPRO 0x185b
111#define CX18_PCI_ID_YUAN 0x12ab
112#define CX18_PCI_ID_CONEXANT 0x14f1
113#define CX18_PCI_ID_TOSHIBA 0x1179
114#define CX18_PCI_ID_LEADTEK 0x107D
115#define CX18_PCI_ID_GOTVIEW 0x5854
116
117/* ======================================================================== */
118/* ========================== START USER SETTABLE DMA VARIABLES =========== */
119/* ======================================================================== */
120
121/* DMA Buffers, Default size in MB allocated */
122#define CX18_DEFAULT_ENC_TS_BUFFERS 1
123#define CX18_DEFAULT_ENC_MPG_BUFFERS 2
124#define CX18_DEFAULT_ENC_IDX_BUFFERS 1
125#define CX18_DEFAULT_ENC_YUV_BUFFERS 2
126#define CX18_DEFAULT_ENC_VBI_BUFFERS 1
127#define CX18_DEFAULT_ENC_PCM_BUFFERS 1
128
129/* Maximum firmware DMA buffers per stream */
130#define CX18_MAX_FW_MDLS_PER_STREAM 63
131
132/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
133#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */
134#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
135#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
136
137/* IDX buffer size should be a multiple of the index entry size from the chip */
138struct cx18_enc_idx_entry {
139 __le32 length;
140 __le32 offset_low;
141 __le32 offset_high;
142 __le32 flags;
143 __le32 pts_low;
144 __le32 pts_high;
145} __attribute__ ((packed));
146#define CX18_UNIT_ENC_IDX_BUFSIZE \
147 (sizeof(struct cx18_enc_idx_entry) * V4L2_ENC_IDX_ENTRIES)
148
149/* DMA buffer, default size in kB allocated */
150#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
151#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
152#define CX18_DEFAULT_ENC_IDX_BUFSIZE (CX18_UNIT_ENC_IDX_BUFSIZE * 1 / 1024 + 1)
153#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
154#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
155
156/* i2c stuff */
157#define I2C_CLIENTS_MAX 16
158
159/* debugging */
160
161/* Flag to turn on high volume debugging */
162#define CX18_DBGFLG_WARN (1 << 0)
163#define CX18_DBGFLG_INFO (1 << 1)
164#define CX18_DBGFLG_API (1 << 2)
165#define CX18_DBGFLG_DMA (1 << 3)
166#define CX18_DBGFLG_IOCTL (1 << 4)
167#define CX18_DBGFLG_FILE (1 << 5)
168#define CX18_DBGFLG_I2C (1 << 6)
169#define CX18_DBGFLG_IRQ (1 << 7)
170/* Flag to turn on high volume debugging */
171#define CX18_DBGFLG_HIGHVOL (1 << 8)
172
173/* NOTE: extra space before comma in 'fmt , ## args' is required for
174 gcc-2.95, otherwise it won't compile. */
175#define CX18_DEBUG(x, type, fmt, args...) \
176 do { \
177 if ((x) & cx18_debug) \
178 v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
179 } while (0)
180#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
181#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
182#define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args)
183#define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args)
184#define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
185#define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args)
186#define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
187#define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
188
189#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
190 do { \
191 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
192 v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
193 } while (0)
194#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
195#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
196#define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args)
197#define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args)
198#define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
199#define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args)
200#define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
201#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
202
203/* Standard kernel messages */
204#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
205#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
206#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
207
208/* Messages for internal subdevs to use */
209#define CX18_DEBUG_DEV(x, dev, type, fmt, args...) \
210 do { \
211 if ((x) & cx18_debug) \
212 v4l2_info(dev, " " type ": " fmt , ## args); \
213 } while (0)
214#define CX18_DEBUG_WARN_DEV(dev, fmt, args...) \
215 CX18_DEBUG_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
216#define CX18_DEBUG_INFO_DEV(dev, fmt, args...) \
217 CX18_DEBUG_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
218#define CX18_DEBUG_API_DEV(dev, fmt, args...) \
219 CX18_DEBUG_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
220#define CX18_DEBUG_DMA_DEV(dev, fmt, args...) \
221 CX18_DEBUG_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
222#define CX18_DEBUG_IOCTL_DEV(dev, fmt, args...) \
223 CX18_DEBUG_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
224#define CX18_DEBUG_FILE_DEV(dev, fmt, args...) \
225 CX18_DEBUG_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
226#define CX18_DEBUG_I2C_DEV(dev, fmt, args...) \
227 CX18_DEBUG_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
228#define CX18_DEBUG_IRQ_DEV(dev, fmt, args...) \
229 CX18_DEBUG_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
230
231#define CX18_DEBUG_HIGH_VOL_DEV(x, dev, type, fmt, args...) \
232 do { \
233 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
234 v4l2_info(dev, " " type ": " fmt , ## args); \
235 } while (0)
236#define CX18_DEBUG_HI_WARN_DEV(dev, fmt, args...) \
237 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
238#define CX18_DEBUG_HI_INFO_DEV(dev, fmt, args...) \
239 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
240#define CX18_DEBUG_HI_API_DEV(dev, fmt, args...) \
241 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
242#define CX18_DEBUG_HI_DMA_DEV(dev, fmt, args...) \
243 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
244#define CX18_DEBUG_HI_IOCTL_DEV(dev, fmt, args...) \
245 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
246#define CX18_DEBUG_HI_FILE_DEV(dev, fmt, args...) \
247 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
248#define CX18_DEBUG_HI_I2C_DEV(dev, fmt, args...) \
249 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
250#define CX18_DEBUG_HI_IRQ_DEV(dev, fmt, args...) \
251 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
252
253#define CX18_ERR_DEV(dev, fmt, args...) v4l2_err(dev, fmt , ## args)
254#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args)
255#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args)
256
257extern int cx18_debug;
258
259struct cx18_options {
260 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
261 int cardtype; /* force card type on load */
262 int tuner; /* set tuner on load */
263 int radio; /* enable/disable radio */
264};
265
266/* per-mdl bit flags */
267#define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianess swapped */
268
269/* per-stream, s_flags */
270#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
271#define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
272#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
273#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
274#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
275#define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */
276
277/* per-cx18, i_flags */
278#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
279#define CX18_F_I_EOS 4 /* End of encoder stream */
280#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */
281#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
282#define CX18_F_I_INITED 21 /* set after first open */
283#define CX18_F_I_FAILED 22 /* set if first open failed */
284
285/* These are the VBI types as they appear in the embedded VBI private packets. */
286#define CX18_SLICED_TYPE_TELETEXT_B (1)
287#define CX18_SLICED_TYPE_CAPTION_525 (4)
288#define CX18_SLICED_TYPE_WSS_625 (5)
289#define CX18_SLICED_TYPE_VPS (7)
290
291/**
292 * list_entry_is_past_end - check if a previous loop cursor is off list end
293 * @pos: the type * previously used as a loop cursor.
294 * @head: the head for your list.
295 * @member: the name of the list_struct within the struct.
296 *
297 * Check if the entry's list_head is the head of the list, thus it's not a
298 * real entry but was the loop cursor that walked past the end
299 */
300#define list_entry_is_past_end(pos, head, member) \
301 (&pos->member == (head))
302
303struct cx18_buffer {
304 struct list_head list;
305 dma_addr_t dma_handle;
306 char *buf;
307
308 u32 bytesused;
309 u32 readpos;
310};
311
312struct cx18_mdl {
313 struct list_head list;
314 u32 id; /* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */
315
316 unsigned int skipped;
317 unsigned long m_flags;
318
319 struct list_head buf_list;
320 struct cx18_buffer *curr_buf; /* current buffer in list for reading */
321
322 u32 bytesused;
323 u32 readpos;
324};
325
326struct cx18_queue {
327 struct list_head list;
328 atomic_t depth;
329 u32 bytesused;
330 spinlock_t lock;
331};
332
333struct cx18_stream; /* forward reference */
334
335struct cx18_dvb {
336 struct cx18_stream *stream;
337 struct dmx_frontend hw_frontend;
338 struct dmx_frontend mem_frontend;
339 struct dmxdev dmxdev;
340 struct dvb_adapter dvb_adapter;
341 struct dvb_demux demux;
342 struct dvb_frontend *fe;
343 struct dvb_net dvbnet;
344 int enabled;
345 int feeding;
346 struct mutex feedlock;
347};
348
349struct cx18; /* forward reference */
350struct cx18_scb; /* forward reference */
351
352
353#define CX18_MAX_MDL_ACKS 2
354#define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
355/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
356
357#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
358#define CX18_F_EWO_MB_STALE_WHILE_PROC 0x2
359#define CX18_F_EWO_MB_STALE \
360 (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
361
362struct cx18_in_work_order {
363 struct work_struct work;
364 atomic_t pending;
365 struct cx18 *cx;
366 unsigned long flags;
367 int rpu;
368 struct cx18_mailbox mb;
369 struct cx18_mdl_ack mdl_ack[CX18_MAX_MDL_ACKS];
370 char *str;
371};
372
373#define CX18_INVALID_TASK_HANDLE 0xffffffff
374
375struct cx18_stream {
376 /* These first five fields are always set, even if the stream
377 is not actually created. */
378 struct video_device *video_dev; /* NULL when stream not created */
379 struct cx18_dvb *dvb; /* DVB / Digital Transport */
380 struct cx18 *cx; /* for ease of use */
381 const char *name; /* name of the stream */
382 int type; /* stream type */
383 u32 handle; /* task handle */
384 unsigned int mdl_base_idx;
385
386 u32 id;
387 unsigned long s_flags; /* status flags, see above */
388 int dma; /* can be PCI_DMA_TODEVICE,
389 PCI_DMA_FROMDEVICE or
390 PCI_DMA_NONE */
391 wait_queue_head_t waitq;
392
393 /* Buffers */
394 struct list_head buf_pool; /* buffers not attached to an MDL */
395 u32 buffers; /* total buffers owned by this stream */
396 u32 buf_size; /* size in bytes of a single buffer */
397
398 /* MDL sizes - all stream MDLs are the same size */
399 u32 bufs_per_mdl;
400 u32 mdl_size; /* total bytes in all buffers in a mdl */
401
402 /* MDL Queues */
403 struct cx18_queue q_free; /* free - in rotation, not committed */
404 struct cx18_queue q_busy; /* busy - in use by firmware */
405 struct cx18_queue q_full; /* full - data for user apps */
406 struct cx18_queue q_idle; /* idle - not in rotation */
407
408 struct work_struct out_work_order;
409
410 /* Videobuf for YUV video */
411 u32 pixelformat;
412 struct list_head vb_capture; /* video capture queue */
413 spinlock_t vb_lock;
414 struct timer_list vb_timeout;
415
416 struct videobuf_queue vbuf_q;
417 spinlock_t vbuf_q_lock; /* Protect vbuf_q */
418 enum v4l2_buf_type vb_type;
419};
420
421struct cx18_videobuf_buffer {
422 /* Common video buffer sub-system struct */
423 struct videobuf_buffer vb;
424 v4l2_std_id tvnorm; /* selected tv norm */
425 u32 bytes_used;
426};
427
428struct cx18_open_id {
429 struct v4l2_fh fh;
430 u32 open_id;
431 int type;
432 struct cx18 *cx;
433
434 struct videobuf_queue vbuf_q;
435 spinlock_t s_lock; /* Protect vbuf_q */
436 enum v4l2_buf_type vb_type;
437};
438
439static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
440{
441 return container_of(fh, struct cx18_open_id, fh);
442}
443
444static inline struct cx18_open_id *file2id(struct file *file)
445{
446 return fh2id(file->private_data);
447}
448
449/* forward declaration of struct defined in cx18-cards.h */
450struct cx18_card;
451
452/*
453 * A note about "sliced" VBI data as implemented in this driver:
454 *
455 * Currently we collect the sliced VBI in the form of Ancillary Data
456 * packets, inserted by the AV core decoder/digitizer/slicer in the
457 * horizontal blanking region of the VBI lines, in "raw" mode as far as
458 * the Encoder is concerned. We don't ever tell the Encoder itself
459 * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
460 *
461 * We then process the ancillary data ourselves to send the sliced data
462 * to the user application directly or build up MPEG-2 private stream 1
463 * packets to splice into (only!) MPEG-2 PS streams for the user app.
464 *
465 * (That's how ivtv essentially does it.)
466 *
467 * The Encoder should be able to extract certain sliced VBI data for
468 * us and provide it in a separate stream or splice it into any type of
469 * MPEG PS or TS stream, but this isn't implemented yet.
470 */
471
472/*
473 * Number of "raw" VBI samples per horizontal line we tell the Encoder to
474 * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
475 * It depends on the pixel clock and the horiz rate:
476 *
477 * (1/Fh)*(2*Fp) = Samples/line
478 * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
479 *
480 * Sliced VBI data is sent as ancillary data during horizontal blanking
481 * Raw VBI is sent as active video samples during vertcal blanking
482 *
483 * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
484 * length of 720 pixels @ 4:2:2 sampling. Thus...
485 *
486 * For systems that use a 15.734 kHz horizontal rate, such as
487 * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
488 *
489 * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
490 * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
491 *
492 * For systems that use a 15.625 kHz horizontal rate, such as
493 * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
494 *
495 * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
496 * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
497 */
498static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
499static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
500static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
501
502#define CX18_VBI_FRAMES 32
503
504struct vbi_info {
505 /* Current state of v4l2 VBI settings for this device */
506 struct v4l2_format in;
507 struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
508 u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
509 u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
510
511 u32 frame; /* Count of VBI buffers/frames received from Encoder */
512
513 /*
514 * Vars for creation and insertion of MPEG Private Stream 1 packets
515 * of sliced VBI data into an MPEG PS
516 */
517
518 /* Boolean: create and insert Private Stream 1 packets into the PS */
519 int insert_mpeg;
520
521 /*
522 * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
523 * Used in cx18-vbi.c only for collecting sliced data, and as a source
524 * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
525 * We don't need to save state here, but the array may have been a bit
526 * too big (2304 bytes) to alloc from the stack.
527 */
528 struct v4l2_sliced_vbi_data sliced_data[36];
529
530 /*
531 * A ring buffer of driver-generated MPEG-2 PS
532 * Program Pack/Private Stream 1 packets for sliced VBI data insertion
533 * into the MPEG PS stream.
534 *
535 * In each sliced_mpeg_data[] buffer is:
536 * 16 byte MPEG-2 PS Program Pack Header
537 * 16 byte MPEG-2 Private Stream 1 PES Header
538 * 4 byte magic number: "itv0" or "ITV0"
539 * 4 byte first field line mask, if "itv0"
540 * 4 byte second field line mask, if "itv0"
541 * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
542 *
543 * Each line in the payload is
544 * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
545 * 42 bytes of line data
546 *
547 * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
548 * which is the payload size a PVR-350 (CX23415) MPEG decoder will
549 * accept for VBI data. So, including the headers, it's a maximum 1584
550 * bytes total.
551 */
552#define CX18_SLICED_MPEG_DATA_MAXSZ 1584
553 /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
554#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8)
555 u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
556 u32 sliced_mpeg_size[CX18_VBI_FRAMES];
557
558 /* Count of Program Pack/Program Stream 1 packets inserted into PS */
559 u32 inserted_frame;
560
561 /*
562 * A dummy driver stream transfer mdl & buffer with a copy of the next
563 * sliced_mpeg_data[] buffer for output to userland apps.
564 * Only used in cx18-fileops.c, but its state needs to persist at times.
565 */
566 struct cx18_mdl sliced_mpeg_mdl;
567 struct cx18_buffer sliced_mpeg_buf;
568};
569
570/* Per cx23418, per I2C bus private algo callback data */
571struct cx18_i2c_algo_callback_data {
572 struct cx18 *cx;
573 int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
574};
575
576#define CX18_MAX_MMIO_WR_RETRIES 10
577
578/* Struct to hold info about cx18 cards */
579struct cx18 {
580 int instance;
581 struct pci_dev *pci_dev;
582 struct v4l2_device v4l2_dev;
583 struct v4l2_subdev *sd_av; /* A/V decoder/digitizer sub-device */
584 struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */
585
586 const struct cx18_card *card; /* card information */
587 const char *card_name; /* full name of the card */
588 const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
589 u8 is_50hz;
590 u8 is_60hz;
591 u8 nof_inputs; /* number of video inputs */
592 u8 nof_audio_inputs; /* number of audio inputs */
593 u32 v4l2_cap; /* V4L2 capabilities of card */
594 u32 hw_flags; /* Hardware description of the board */
595 unsigned int free_mdl_idx;
596 struct cx18_scb __iomem *scb; /* pointer to SCB */
597 struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
598 struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
599
600 struct cx18_av_state av_state;
601
602 /* codec settings */
603 struct cx2341x_handler cxhdl;
604 u32 filter_mode;
605 u32 temporal_strength;
606 u32 spatial_strength;
607
608 /* dualwatch */
609 unsigned long dualwatch_jiffies;
610 u32 dualwatch_stereo_mode;
611
612 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
613 struct cx18_options options; /* User options */
614 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
615 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
616 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
617 struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
618 void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
619 size_t num_bytes);
620
621 unsigned long i_flags; /* global cx18 flags */
622 atomic_t ana_capturing; /* count number of active analog capture streams */
623 atomic_t tot_capturing; /* total count number of active capture streams */
624 int search_pack_header;
625
626 int open_id; /* incremented each time an open occurs, used as
627 unique ID. Starts at 1, so 0 can be used as
628 uninitialized value in the stream->id. */
629
630 u32 base_addr;
631
632 u8 card_rev;
633 void __iomem *enc_mem, *reg_mem;
634
635 struct vbi_info vbi;
636
637 u64 mpg_data_received;
638 u64 vbi_data_inserted;
639
640 wait_queue_head_t mb_apu_waitq;
641 wait_queue_head_t mb_cpu_waitq;
642 wait_queue_head_t cap_w;
643 /* when the current DMA is finished this queue is woken up */
644 wait_queue_head_t dma_waitq;
645
646 u32 sw1_irq_mask;
647 u32 sw2_irq_mask;
648 u32 hw2_irq_mask;
649
650 struct workqueue_struct *in_work_queue;
651 char in_workq_name[11]; /* "cx18-NN-in" */
652 struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
653 char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
654
655 /* i2c */
656 struct i2c_adapter i2c_adap[2];
657 struct i2c_algo_bit_data i2c_algo[2];
658 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
659
660 struct IR_i2c_init_data ir_i2c_init_data;
661
662 /* gpio */
663 u32 gpio_dir;
664 u32 gpio_val;
665 struct mutex gpio_lock;
666 struct v4l2_subdev sd_gpiomux;
667 struct v4l2_subdev sd_resetctrl;
668
669 /* v4l2 and User settings */
670
671 /* codec settings */
672 u32 audio_input;
673 u32 active_input;
674 v4l2_std_id std;
675 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
676
677 /* Used for cx18-alsa module loading */
678 struct work_struct request_module_wk;
679};
680
681static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
682{
683 return container_of(v4l2_dev, struct cx18, v4l2_dev);
684}
685
686/* cx18 extensions to be loaded */
687extern int (*cx18_ext_init)(struct cx18 *);
688
689/* Globals */
690extern int cx18_first_minor;
691
692/*==============Prototypes==================*/
693
694/* Return non-zero if a signal is pending */
695int cx18_msleep_timeout(unsigned int msecs, int intr);
696
697/* Read Hauppauge eeprom */
698struct tveeprom; /* forward reference */
699void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
700
701/* First-open initialization: load firmware, etc. */
702int cx18_init_on_first_open(struct cx18 *cx);
703
704/* Test if the current VBI mode is raw (1) or sliced (0) */
705static inline int cx18_raw_vbi(const struct cx18 *cx)
706{
707 return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
708}
709
710/* Call the specified callback for all subdevs with a grp_id bit matching the
711 * mask in hw (if 0, then match them all). Ignore any errors. */
712#define cx18_call_hw(cx, hw, o, f, args...) \
713 do { \
714 struct v4l2_subdev *__sd; \
715 __v4l2_device_call_subdevs_p(&(cx)->v4l2_dev, __sd, \
716 !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
717 } while (0)
718
719#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args)
720
721/* Call the specified callback for all subdevs with a grp_id bit matching the
722 * mask in hw (if 0, then match them all). If the callback returns an error
723 * other than 0 or -ENOIOCTLCMD, then return with that error code. */
724#define cx18_call_hw_err(cx, hw, o, f, args...) \
725({ \
726 struct v4l2_subdev *__sd; \
727 __v4l2_device_call_subdevs_until_err_p(&(cx)->v4l2_dev, \
728 __sd, !(hw) || (__sd->grp_id & (hw)), o, f, \
729 ##args); \
730})
731
732#define cx18_call_all_err(cx, o, f, args...) \
733 cx18_call_hw_err(cx, 0, o, f , ##args)
734
735#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
new file mode 100644
index 00000000000..f41922bd402
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -0,0 +1,605 @@
1/*
2 * cx18 functions for DVB support
3 *
4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx18-version.h"
24#include "cx18-dvb.h"
25#include "cx18-io.h"
26#include "cx18-queue.h"
27#include "cx18-streams.h"
28#include "cx18-cards.h"
29#include "cx18-gpio.h"
30#include "s5h1409.h"
31#include "mxl5005s.h"
32#include "s5h1411.h"
33#include "tda18271.h"
34#include "zl10353.h"
35
36#include <linux/firmware.h>
37#include "mt352.h"
38#include "mt352_priv.h"
39#include "tuner-xc2028.h"
40
41DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
42
43#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
44#define CX18_CLOCK_ENABLE2 0xc71024
45#define CX18_DMUX_CLK_MASK 0x0080
46
47/*
48 * CX18_CARD_HVR_1600_ESMT
49 * CX18_CARD_HVR_1600_SAMSUNG
50 */
51
52static struct mxl5005s_config hauppauge_hvr1600_tuner = {
53 .i2c_address = 0xC6 >> 1,
54 .if_freq = IF_FREQ_5380000HZ,
55 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
56 .agc_mode = MXL_SINGLE_AGC,
57 .tracking_filter = MXL_TF_C_H,
58 .rssi_enable = MXL_RSSI_ENABLE,
59 .cap_select = MXL_CAP_SEL_ENABLE,
60 .div_out = MXL_DIV_OUT_4,
61 .clock_out = MXL_CLOCK_OUT_DISABLE,
62 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
63 .top = MXL5005S_TOP_25P2,
64 .mod_mode = MXL_DIGITAL_MODE,
65 .if_mode = MXL_ZERO_IF,
66 .qam_gain = 0x02,
67 .AgcMasterByte = 0x00,
68};
69
70static struct s5h1409_config hauppauge_hvr1600_config = {
71 .demod_address = 0x32 >> 1,
72 .output_mode = S5H1409_SERIAL_OUTPUT,
73 .gpio = S5H1409_GPIO_ON,
74 .qam_if = 44000,
75 .inversion = S5H1409_INVERSION_OFF,
76 .status_mode = S5H1409_DEMODLOCKING,
77 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
78 .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE
79};
80
81/*
82 * CX18_CARD_HVR_1600_S5H1411
83 */
84static struct s5h1411_config hcw_s5h1411_config = {
85 .output_mode = S5H1411_SERIAL_OUTPUT,
86 .gpio = S5H1411_GPIO_OFF,
87 .vsb_if = S5H1411_IF_44000,
88 .qam_if = S5H1411_IF_4000,
89 .inversion = S5H1411_INVERSION_ON,
90 .status_mode = S5H1411_DEMODLOCKING,
91 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
92};
93
94static struct tda18271_std_map hauppauge_tda18271_std_map = {
95 .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3,
96 .if_lvl = 6, .rfagc_top = 0x37 },
97 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
98 .if_lvl = 6, .rfagc_top = 0x37 },
99};
100
101static struct tda18271_config hauppauge_tda18271_config = {
102 .std_map = &hauppauge_tda18271_std_map,
103 .gate = TDA18271_GATE_DIGITAL,
104 .output_opt = TDA18271_OUTPUT_LT_OFF,
105};
106
107/*
108 * CX18_CARD_LEADTEK_DVR3100H
109 */
110/* Information/confirmation of proper config values provided by Terry Wu */
111static struct zl10353_config leadtek_dvr3100h_demod = {
112 .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
113 .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
114 .parallel_ts = 1, /* Not a serial TS */
115 .no_tuner = 1, /* XC3028 is not behind the gate */
116 .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
117};
118
119/*
120 * CX18_CARD_YUAN_MPC718
121 */
122/*
123 * Due to
124 *
125 * 1. an absence of information on how to prgram the MT352
126 * 2. the Linux mt352 module pushing MT352 initialzation off onto us here
127 *
128 * We have to use an init sequence that *you* must extract from the Windows
129 * driver (yuanrap.sys) and which we load as a firmware.
130 *
131 * If someone can provide me with a Zarlink MT352 (Intel CE6352?) Design Manual
132 * with chip programming details, then I can remove this annoyance.
133 */
134static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream,
135 const struct firmware **fw)
136{
137 struct cx18 *cx = stream->cx;
138 const char *fn = "dvb-cx18-mpc718-mt352.fw";
139 int ret;
140
141 ret = request_firmware(fw, fn, &cx->pci_dev->dev);
142 if (ret)
143 CX18_ERR("Unable to open firmware file %s\n", fn);
144 else {
145 size_t sz = (*fw)->size;
146 if (sz < 2 || sz > 64 || (sz % 2) != 0) {
147 CX18_ERR("Firmware %s has a bad size: %lu bytes\n",
148 fn, (unsigned long) sz);
149 ret = -EILSEQ;
150 release_firmware(*fw);
151 *fw = NULL;
152 }
153 }
154
155 if (ret) {
156 CX18_ERR("The MPC718 board variant with the MT352 DVB-T"
157 "demodualtor will not work without it\n");
158 CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware "
159 "mpc718' if you need the firmware\n");
160 }
161 return ret;
162}
163
164static int yuan_mpc718_mt352_init(struct dvb_frontend *fe)
165{
166 struct cx18_dvb *dvb = container_of(fe->dvb,
167 struct cx18_dvb, dvb_adapter);
168 struct cx18_stream *stream = dvb->stream;
169 const struct firmware *fw = NULL;
170 int ret;
171 int i;
172 u8 buf[3];
173
174 ret = yuan_mpc718_mt352_reqfw(stream, &fw);
175 if (ret)
176 return ret;
177
178 /* Loop through all the register-value pairs in the firmware file */
179 for (i = 0; i < fw->size; i += 2) {
180 buf[0] = fw->data[i];
181 /* Intercept a few registers we want to set ourselves */
182 switch (buf[0]) {
183 case TRL_NOMINAL_RATE_0:
184 /* Set our custom OFDM bandwidth in the case below */
185 break;
186 case TRL_NOMINAL_RATE_1:
187 /* 6 MHz: 64/7 * 6/8 / 20.48 * 2^16 = 0x55b6.db6 */
188 /* 7 MHz: 64/7 * 7/8 / 20.48 * 2^16 = 0x6400 */
189 /* 8 MHz: 64/7 * 8/8 / 20.48 * 2^16 = 0x7249.249 */
190 buf[1] = 0x72;
191 buf[2] = 0x49;
192 mt352_write(fe, buf, 3);
193 break;
194 case INPUT_FREQ_0:
195 /* Set our custom IF in the case below */
196 break;
197 case INPUT_FREQ_1:
198 /* 4.56 MHz IF: (20.48 - 4.56)/20.48 * 2^14 = 0x31c0 */
199 buf[1] = 0x31;
200 buf[2] = 0xc0;
201 mt352_write(fe, buf, 3);
202 break;
203 default:
204 /* Pass through the register-value pair from the fw */
205 buf[1] = fw->data[i+1];
206 mt352_write(fe, buf, 2);
207 break;
208 }
209 }
210
211 buf[0] = (u8) TUNER_GO;
212 buf[1] = 0x01; /* Go */
213 mt352_write(fe, buf, 2);
214 release_firmware(fw);
215 return 0;
216}
217
218static struct mt352_config yuan_mpc718_mt352_demod = {
219 .demod_address = 0x1e >> 1,
220 .adc_clock = 20480, /* 20.480 MHz */
221 .if2 = 4560, /* 4.560 MHz */
222 .no_tuner = 1, /* XC3028 is not behind the gate */
223 .demod_init = yuan_mpc718_mt352_init,
224};
225
226static struct zl10353_config yuan_mpc718_zl10353_demod = {
227 .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
228 .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
229 .parallel_ts = 1, /* Not a serial TS */
230 .no_tuner = 1, /* XC3028 is not behind the gate */
231 .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
232};
233
234static struct zl10353_config gotview_dvd3_zl10353_demod = {
235 .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
236 .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
237 .parallel_ts = 1, /* Not a serial TS */
238 .no_tuner = 1, /* XC3028 is not behind the gate */
239 .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
240};
241
242static int dvb_register(struct cx18_stream *stream);
243
244/* Kernel DVB framework calls this when the feed needs to start.
245 * The CX18 framework should enable the transport DMA handling
246 * and queue processing.
247 */
248static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
249{
250 struct dvb_demux *demux = feed->demux;
251 struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
252 struct cx18 *cx;
253 int ret;
254 u32 v;
255
256 if (!stream)
257 return -EINVAL;
258
259 cx = stream->cx;
260 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
261 feed->pid, feed->index);
262
263 mutex_lock(&cx->serialize_lock);
264 ret = cx18_init_on_first_open(cx);
265 mutex_unlock(&cx->serialize_lock);
266 if (ret) {
267 CX18_ERR("Failed to initialize firmware starting DVB feed\n");
268 return ret;
269 }
270 ret = -EINVAL;
271
272 switch (cx->card->type) {
273 case CX18_CARD_HVR_1600_ESMT:
274 case CX18_CARD_HVR_1600_SAMSUNG:
275 case CX18_CARD_HVR_1600_S5H1411:
276 v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
277 v |= 0x00400000; /* Serial Mode */
278 v |= 0x00002000; /* Data Length - Byte */
279 v |= 0x00010000; /* Error - Polarity */
280 v |= 0x00020000; /* Error - Passthru */
281 v |= 0x000c0000; /* Error - Ignore */
282 cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
283 break;
284
285 case CX18_CARD_LEADTEK_DVR3100H:
286 case CX18_CARD_YUAN_MPC718:
287 case CX18_CARD_GOTVIEW_PCI_DVD3:
288 default:
289 /* Assumption - Parallel transport - Signalling
290 * undefined or default.
291 */
292 break;
293 }
294
295 if (!demux->dmx.frontend)
296 return -EINVAL;
297
298 mutex_lock(&stream->dvb->feedlock);
299 if (stream->dvb->feeding++ == 0) {
300 CX18_DEBUG_INFO("Starting Transport DMA\n");
301 mutex_lock(&cx->serialize_lock);
302 set_bit(CX18_F_S_STREAMING, &stream->s_flags);
303 ret = cx18_start_v4l2_encode_stream(stream);
304 if (ret < 0) {
305 CX18_DEBUG_INFO("Failed to start Transport DMA\n");
306 stream->dvb->feeding--;
307 if (stream->dvb->feeding == 0)
308 clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
309 }
310 mutex_unlock(&cx->serialize_lock);
311 } else
312 ret = 0;
313 mutex_unlock(&stream->dvb->feedlock);
314
315 return ret;
316}
317
318/* Kernel DVB framework calls this when the feed needs to stop. */
319static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
320{
321 struct dvb_demux *demux = feed->demux;
322 struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
323 struct cx18 *cx;
324 int ret = -EINVAL;
325
326 if (stream) {
327 cx = stream->cx;
328 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
329 feed->pid, feed->index);
330
331 mutex_lock(&stream->dvb->feedlock);
332 if (--stream->dvb->feeding == 0) {
333 CX18_DEBUG_INFO("Stopping Transport DMA\n");
334 mutex_lock(&cx->serialize_lock);
335 ret = cx18_stop_v4l2_encode_stream(stream, 0);
336 mutex_unlock(&cx->serialize_lock);
337 } else
338 ret = 0;
339 mutex_unlock(&stream->dvb->feedlock);
340 }
341
342 return ret;
343}
344
345int cx18_dvb_register(struct cx18_stream *stream)
346{
347 struct cx18 *cx = stream->cx;
348 struct cx18_dvb *dvb = stream->dvb;
349 struct dvb_adapter *dvb_adapter;
350 struct dvb_demux *dvbdemux;
351 struct dmx_demux *dmx;
352 int ret;
353
354 if (!dvb)
355 return -EINVAL;
356
357 dvb->enabled = 0;
358 dvb->stream = stream;
359
360 ret = dvb_register_adapter(&dvb->dvb_adapter,
361 CX18_DRIVER_NAME,
362 THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
363 if (ret < 0)
364 goto err_out;
365
366 dvb_adapter = &dvb->dvb_adapter;
367
368 dvbdemux = &dvb->demux;
369
370 dvbdemux->priv = (void *)stream;
371
372 dvbdemux->filternum = 256;
373 dvbdemux->feednum = 256;
374 dvbdemux->start_feed = cx18_dvb_start_feed;
375 dvbdemux->stop_feed = cx18_dvb_stop_feed;
376 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
377 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
378 ret = dvb_dmx_init(dvbdemux);
379 if (ret < 0)
380 goto err_dvb_unregister_adapter;
381
382 dmx = &dvbdemux->dmx;
383
384 dvb->hw_frontend.source = DMX_FRONTEND_0;
385 dvb->mem_frontend.source = DMX_MEMORY_FE;
386 dvb->dmxdev.filternum = 256;
387 dvb->dmxdev.demux = dmx;
388
389 ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter);
390 if (ret < 0)
391 goto err_dvb_dmx_release;
392
393 ret = dmx->add_frontend(dmx, &dvb->hw_frontend);
394 if (ret < 0)
395 goto err_dvb_dmxdev_release;
396
397 ret = dmx->add_frontend(dmx, &dvb->mem_frontend);
398 if (ret < 0)
399 goto err_remove_hw_frontend;
400
401 ret = dmx->connect_frontend(dmx, &dvb->hw_frontend);
402 if (ret < 0)
403 goto err_remove_mem_frontend;
404
405 ret = dvb_register(stream);
406 if (ret < 0)
407 goto err_disconnect_frontend;
408
409 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
410
411 CX18_INFO("DVB Frontend registered\n");
412 CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
413 stream->dvb->dvb_adapter.num, stream->name,
414 stream->buffers, stream->buf_size/1024,
415 (stream->buf_size * 100 / 1024) % 100);
416
417 mutex_init(&dvb->feedlock);
418 dvb->enabled = 1;
419 return ret;
420
421err_disconnect_frontend:
422 dmx->disconnect_frontend(dmx);
423err_remove_mem_frontend:
424 dmx->remove_frontend(dmx, &dvb->mem_frontend);
425err_remove_hw_frontend:
426 dmx->remove_frontend(dmx, &dvb->hw_frontend);
427err_dvb_dmxdev_release:
428 dvb_dmxdev_release(&dvb->dmxdev);
429err_dvb_dmx_release:
430 dvb_dmx_release(dvbdemux);
431err_dvb_unregister_adapter:
432 dvb_unregister_adapter(dvb_adapter);
433err_out:
434 return ret;
435}
436
437void cx18_dvb_unregister(struct cx18_stream *stream)
438{
439 struct cx18 *cx = stream->cx;
440 struct cx18_dvb *dvb = stream->dvb;
441 struct dvb_adapter *dvb_adapter;
442 struct dvb_demux *dvbdemux;
443 struct dmx_demux *dmx;
444
445 CX18_INFO("unregister DVB\n");
446
447 if (dvb == NULL || !dvb->enabled)
448 return;
449
450 dvb_adapter = &dvb->dvb_adapter;
451 dvbdemux = &dvb->demux;
452 dmx = &dvbdemux->dmx;
453
454 dmx->close(dmx);
455 dvb_net_release(&dvb->dvbnet);
456 dmx->remove_frontend(dmx, &dvb->mem_frontend);
457 dmx->remove_frontend(dmx, &dvb->hw_frontend);
458 dvb_dmxdev_release(&dvb->dmxdev);
459 dvb_dmx_release(dvbdemux);
460 dvb_unregister_frontend(dvb->fe);
461 dvb_frontend_detach(dvb->fe);
462 dvb_unregister_adapter(dvb_adapter);
463}
464
465/* All the DVB attach calls go here, this function get's modified
466 * for each new card. cx18_dvb_start_feed() will also need changes.
467 */
468static int dvb_register(struct cx18_stream *stream)
469{
470 struct cx18_dvb *dvb = stream->dvb;
471 struct cx18 *cx = stream->cx;
472 int ret = 0;
473
474 switch (cx->card->type) {
475 case CX18_CARD_HVR_1600_ESMT:
476 case CX18_CARD_HVR_1600_SAMSUNG:
477 dvb->fe = dvb_attach(s5h1409_attach,
478 &hauppauge_hvr1600_config,
479 &cx->i2c_adap[0]);
480 if (dvb->fe != NULL) {
481 dvb_attach(mxl5005s_attach, dvb->fe,
482 &cx->i2c_adap[0],
483 &hauppauge_hvr1600_tuner);
484 ret = 0;
485 }
486 break;
487 case CX18_CARD_HVR_1600_S5H1411:
488 dvb->fe = dvb_attach(s5h1411_attach,
489 &hcw_s5h1411_config,
490 &cx->i2c_adap[0]);
491 if (dvb->fe != NULL)
492 dvb_attach(tda18271_attach, dvb->fe,
493 0x60, &cx->i2c_adap[0],
494 &hauppauge_tda18271_config);
495 break;
496 case CX18_CARD_LEADTEK_DVR3100H:
497 dvb->fe = dvb_attach(zl10353_attach,
498 &leadtek_dvr3100h_demod,
499 &cx->i2c_adap[1]);
500 if (dvb->fe != NULL) {
501 struct dvb_frontend *fe;
502 struct xc2028_config cfg = {
503 .i2c_adap = &cx->i2c_adap[1],
504 .i2c_addr = 0xc2 >> 1,
505 .ctrl = NULL,
506 };
507 static struct xc2028_ctrl ctrl = {
508 .fname = XC2028_DEFAULT_FIRMWARE,
509 .max_len = 64,
510 .demod = XC3028_FE_ZARLINK456,
511 .type = XC2028_AUTO,
512 };
513
514 fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
515 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
516 fe->ops.tuner_ops.set_config(fe, &ctrl);
517 }
518 break;
519 case CX18_CARD_YUAN_MPC718:
520 /*
521 * TODO
522 * Apparently, these cards also could instead have a
523 * DiBcom demod supported by one of the db7000 drivers
524 */
525 dvb->fe = dvb_attach(mt352_attach,
526 &yuan_mpc718_mt352_demod,
527 &cx->i2c_adap[1]);
528 if (dvb->fe == NULL)
529 dvb->fe = dvb_attach(zl10353_attach,
530 &yuan_mpc718_zl10353_demod,
531 &cx->i2c_adap[1]);
532 if (dvb->fe != NULL) {
533 struct dvb_frontend *fe;
534 struct xc2028_config cfg = {
535 .i2c_adap = &cx->i2c_adap[1],
536 .i2c_addr = 0xc2 >> 1,
537 .ctrl = NULL,
538 };
539 static struct xc2028_ctrl ctrl = {
540 .fname = XC2028_DEFAULT_FIRMWARE,
541 .max_len = 64,
542 .demod = XC3028_FE_ZARLINK456,
543 .type = XC2028_AUTO,
544 };
545
546 fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
547 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
548 fe->ops.tuner_ops.set_config(fe, &ctrl);
549 }
550 break;
551 case CX18_CARD_GOTVIEW_PCI_DVD3:
552 dvb->fe = dvb_attach(zl10353_attach,
553 &gotview_dvd3_zl10353_demod,
554 &cx->i2c_adap[1]);
555 if (dvb->fe != NULL) {
556 struct dvb_frontend *fe;
557 struct xc2028_config cfg = {
558 .i2c_adap = &cx->i2c_adap[1],
559 .i2c_addr = 0xc2 >> 1,
560 .ctrl = NULL,
561 };
562 static struct xc2028_ctrl ctrl = {
563 .fname = XC2028_DEFAULT_FIRMWARE,
564 .max_len = 64,
565 .demod = XC3028_FE_ZARLINK456,
566 .type = XC2028_AUTO,
567 };
568
569 fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
570 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
571 fe->ops.tuner_ops.set_config(fe, &ctrl);
572 }
573 break;
574 default:
575 /* No Digital Tv Support */
576 break;
577 }
578
579 if (dvb->fe == NULL) {
580 CX18_ERR("frontend initialization failed\n");
581 return -1;
582 }
583
584 dvb->fe->callback = cx18_reset_tuner_gpio;
585
586 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
587 if (ret < 0) {
588 if (dvb->fe->ops.release)
589 dvb->fe->ops.release(dvb->fe);
590 return ret;
591 }
592
593 /*
594 * The firmware seems to enable the TS DMUX clock
595 * under various circumstances. However, since we know we
596 * might use it, let's just turn it on ourselves here.
597 */
598 cx18_write_reg_expect(cx,
599 (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK,
600 CX18_CLOCK_ENABLE2,
601 CX18_DMUX_CLK_MASK,
602 (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK);
603
604 return ret;
605}
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h
new file mode 100644
index 00000000000..bf8d8f6f545
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-dvb.h
@@ -0,0 +1,25 @@
1/*
2 * cx18 functions for DVB support
3 *
4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "cx18-driver.h"
23
24int cx18_dvb_register(struct cx18_stream *stream);
25void 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
new file mode 100644
index 00000000000..07411f34885
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -0,0 +1,896 @@
1/*
2 * cx18 file operation functions
3 *
4 * Derived from ivtv-fileops.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-fileops.h"
27#include "cx18-i2c.h"
28#include "cx18-queue.h"
29#include "cx18-vbi.h"
30#include "cx18-audio.h"
31#include "cx18-mailbox.h"
32#include "cx18-scb.h"
33#include "cx18-streams.h"
34#include "cx18-controls.h"
35#include "cx18-ioctl.h"
36#include "cx18-cards.h"
37
38/* This function tries to claim the stream for a specific file descriptor.
39 If no one else is using this stream then the stream is claimed and
40 associated VBI and IDX streams are also automatically claimed.
41 Possible error returns: -EBUSY if someone else has claimed
42 the stream or 0 on success. */
43int cx18_claim_stream(struct cx18_open_id *id, int type)
44{
45 struct cx18 *cx = id->cx;
46 struct cx18_stream *s = &cx->streams[type];
47 struct cx18_stream *s_assoc;
48
49 /* Nothing should ever try to directly claim the IDX stream */
50 if (type == CX18_ENC_STREAM_TYPE_IDX) {
51 CX18_WARN("MPEG Index stream cannot be claimed "
52 "directly, but something tried.\n");
53 return -EINVAL;
54 }
55
56 if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
57 /* someone already claimed this stream */
58 if (s->id == id->open_id) {
59 /* yes, this file descriptor did. So that's OK. */
60 return 0;
61 }
62 if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
63 /* VBI is handled already internally, now also assign
64 the file descriptor to this stream for external
65 reading of the stream. */
66 s->id = id->open_id;
67 CX18_DEBUG_INFO("Start Read VBI\n");
68 return 0;
69 }
70 /* someone else is using this stream already */
71 CX18_DEBUG_INFO("Stream %d is busy\n", type);
72 return -EBUSY;
73 }
74 s->id = id->open_id;
75
76 /*
77 * CX18_ENC_STREAM_TYPE_MPG needs to claim:
78 * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
79 * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
80 * (We don't yet fix up MPEG Index entries for our inserted packets).
81 *
82 * For all other streams we're done.
83 */
84 if (type != CX18_ENC_STREAM_TYPE_MPG)
85 return 0;
86
87 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
88 if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
89 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
90 else if (!cx18_stream_enabled(s_assoc))
91 return 0;
92
93 set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
94
95 /* mark that it is used internally */
96 set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
97 return 0;
98}
99EXPORT_SYMBOL(cx18_claim_stream);
100
101/* This function releases a previously claimed stream. It will take into
102 account associated VBI streams. */
103void cx18_release_stream(struct cx18_stream *s)
104{
105 struct cx18 *cx = s->cx;
106 struct cx18_stream *s_assoc;
107
108 s->id = -1;
109 if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
110 /*
111 * The IDX stream is only used internally, and can
112 * only be indirectly unclaimed by unclaiming the MPG stream.
113 */
114 return;
115 }
116
117 if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
118 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
119 /* this stream is still in use internally */
120 return;
121 }
122 if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
123 CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
124 return;
125 }
126
127 cx18_flush_queues(s);
128
129 /*
130 * CX18_ENC_STREAM_TYPE_MPG needs to release the
131 * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
132 *
133 * For all other streams we're done.
134 */
135 if (s->type != CX18_ENC_STREAM_TYPE_MPG)
136 return;
137
138 /* Unclaim the associated MPEG Index stream */
139 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
140 if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
141 clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
142 cx18_flush_queues(s_assoc);
143 }
144
145 /* Unclaim the associated VBI stream */
146 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
147 if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
148 if (s_assoc->id == -1) {
149 /*
150 * The VBI stream is not still claimed by a file
151 * descriptor, so completely unclaim it.
152 */
153 clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
154 cx18_flush_queues(s_assoc);
155 }
156 }
157}
158EXPORT_SYMBOL(cx18_release_stream);
159
160static void cx18_dualwatch(struct cx18 *cx)
161{
162 struct v4l2_tuner vt;
163 u32 new_stereo_mode;
164 const u32 dual = 0x0200;
165
166 new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
167 memset(&vt, 0, sizeof(vt));
168 cx18_call_all(cx, tuner, g_tuner, &vt);
169 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
170 (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
171 new_stereo_mode = dual;
172
173 if (new_stereo_mode == cx->dualwatch_stereo_mode)
174 return;
175
176 CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
177 cx->dualwatch_stereo_mode, new_stereo_mode);
178 if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
179 CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
180}
181
182
183static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
184 int *err)
185{
186 struct cx18 *cx = s->cx;
187 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
188 struct cx18_mdl *mdl;
189 DEFINE_WAIT(wait);
190
191 *err = 0;
192 while (1) {
193 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
194 /* Process pending program updates and VBI data */
195 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
196 cx->dualwatch_jiffies = jiffies;
197 cx18_dualwatch(cx);
198 }
199 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
200 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
201 while ((mdl = cx18_dequeue(s_vbi,
202 &s_vbi->q_full))) {
203 /* byteswap and process VBI data */
204 cx18_process_vbi_data(cx, mdl,
205 s_vbi->type);
206 cx18_stream_put_mdl_fw(s_vbi, mdl);
207 }
208 }
209 mdl = &cx->vbi.sliced_mpeg_mdl;
210 if (mdl->readpos != mdl->bytesused)
211 return mdl;
212 }
213
214 /* do we have new data? */
215 mdl = cx18_dequeue(s, &s->q_full);
216 if (mdl) {
217 if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
218 &mdl->m_flags))
219 return mdl;
220 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
221 /* byteswap MPG data */
222 cx18_mdl_swap(mdl);
223 else {
224 /* byteswap and process VBI data */
225 cx18_process_vbi_data(cx, mdl, s->type);
226 }
227 return mdl;
228 }
229
230 /* return if end of stream */
231 if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
232 CX18_DEBUG_INFO("EOS %s\n", s->name);
233 return NULL;
234 }
235
236 /* return if file was opened with O_NONBLOCK */
237 if (non_block) {
238 *err = -EAGAIN;
239 return NULL;
240 }
241
242 /* wait for more data to arrive */
243 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
244 /* New buffers might have become available before we were added
245 to the waitqueue */
246 if (!atomic_read(&s->q_full.depth))
247 schedule();
248 finish_wait(&s->waitq, &wait);
249 if (signal_pending(current)) {
250 /* return if a signal was received */
251 CX18_DEBUG_INFO("User stopped %s\n", s->name);
252 *err = -EINTR;
253 return NULL;
254 }
255 }
256}
257
258static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
259{
260 struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
261 struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
262 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
263
264 buf->buf = cx->vbi.sliced_mpeg_data[idx];
265 buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
266 buf->readpos = 0;
267
268 mdl->curr_buf = NULL;
269 mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
270 mdl->readpos = 0;
271}
272
273static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
274 struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
275{
276 struct cx18 *cx = s->cx;
277 size_t len = buf->bytesused - buf->readpos;
278
279 *stop = false;
280 if (len > ucount)
281 len = ucount;
282 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
283 !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
284 /*
285 * Try to find a good splice point in the PS, just before
286 * an MPEG-2 Program Pack start code, and provide only
287 * up to that point to the user, so it's easy to insert VBI data
288 * the next time around.
289 *
290 * This will not work for an MPEG-2 TS and has only been
291 * verified by analysis to work for an MPEG-2 PS. Helen Buus
292 * pointed out this works for the CX23416 MPEG-2 DVD compatible
293 * stream, and research indicates both the MPEG 2 SVCD and DVD
294 * stream types use an MPEG-2 PS container.
295 */
296 /*
297 * An MPEG-2 Program Stream (PS) is a series of
298 * MPEG-2 Program Packs terminated by an
299 * MPEG Program End Code after the last Program Pack.
300 * A Program Pack may hold a PS System Header packet and any
301 * number of Program Elementary Stream (PES) Packets
302 */
303 const char *start = buf->buf + buf->readpos;
304 const char *p = start + 1;
305 const u8 *q;
306 u8 ch = cx->search_pack_header ? 0xba : 0xe0;
307 int stuffing, i;
308
309 while (start + len > p) {
310 /* Scan for a 0 to find a potential MPEG-2 start code */
311 q = memchr(p, 0, start + len - p);
312 if (q == NULL)
313 break;
314 p = q + 1;
315 /*
316 * Keep looking if not a
317 * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba
318 * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
319 */
320 if ((char *)q + 15 >= buf->buf + buf->bytesused ||
321 q[1] != 0 || q[2] != 1 || q[3] != ch)
322 continue;
323
324 /* If expecting the primary video PES */
325 if (!cx->search_pack_header) {
326 /* Continue if it couldn't be a PES packet */
327 if ((q[6] & 0xc0) != 0x80)
328 continue;
329 /* Check if a PTS or PTS & DTS follow */
330 if (((q[7] & 0xc0) == 0x80 && /* PTS only */
331 (q[9] & 0xf0) == 0x20) || /* PTS only */
332 ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */
333 (q[9] & 0xf0) == 0x30)) { /* DTS follows */
334 /* Assume we found the video PES hdr */
335 ch = 0xba; /* next want a Program Pack*/
336 cx->search_pack_header = 1;
337 p = q + 9; /* Skip this video PES hdr */
338 }
339 continue;
340 }
341
342 /* We may have found a Program Pack start code */
343
344 /* Get the count of stuffing bytes & verify them */
345 stuffing = q[13] & 7;
346 /* all stuffing bytes must be 0xff */
347 for (i = 0; i < stuffing; i++)
348 if (q[14 + i] != 0xff)
349 break;
350 if (i == stuffing && /* right number of stuffing bytes*/
351 (q[4] & 0xc4) == 0x44 && /* marker check */
352 (q[12] & 3) == 3 && /* marker check */
353 q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
354 q[15 + stuffing] == 0 &&
355 q[16 + stuffing] == 1) {
356 /* We declare we actually found a Program Pack*/
357 cx->search_pack_header = 0; /* expect vid PES */
358 len = (char *)q - start;
359 cx18_setup_sliced_vbi_mdl(cx);
360 *stop = true;
361 break;
362 }
363 }
364 }
365 if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
366 CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
367 len, s->name);
368 return -EFAULT;
369 }
370 buf->readpos += len;
371 if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
372 buf != &cx->vbi.sliced_mpeg_buf)
373 cx->mpg_data_received += len;
374 return len;
375}
376
377static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
378 struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
379{
380 size_t tot_written = 0;
381 int rc;
382 bool stop = false;
383
384 if (mdl->curr_buf == NULL)
385 mdl->curr_buf = list_first_entry(&mdl->buf_list,
386 struct cx18_buffer, list);
387
388 if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
389 /*
390 * For some reason we've exhausted the buffers, but the MDL
391 * object still said some data was unread.
392 * Fix that and bail out.
393 */
394 mdl->readpos = mdl->bytesused;
395 return 0;
396 }
397
398 list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
399
400 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
401 continue;
402
403 rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
404 ucount - tot_written, &stop);
405 if (rc < 0)
406 return rc;
407 mdl->readpos += rc;
408 tot_written += rc;
409
410 if (stop || /* Forced stopping point for VBI insertion */
411 tot_written >= ucount || /* Reader request statisfied */
412 mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
413 mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
414 break;
415 }
416 return tot_written;
417}
418
419static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
420 size_t tot_count, int non_block)
421{
422 struct cx18 *cx = s->cx;
423 size_t tot_written = 0;
424 int single_frame = 0;
425
426 if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
427 /* shouldn't happen */
428 CX18_DEBUG_WARN("Stream %s not initialized before read\n",
429 s->name);
430 return -EIO;
431 }
432
433 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
434 frames should arrive one-by-one, so make sure we never output more
435 than one VBI frame at a time */
436 if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
437 single_frame = 1;
438
439 for (;;) {
440 struct cx18_mdl *mdl;
441 int rc;
442
443 mdl = cx18_get_mdl(s, non_block, &rc);
444 /* if there is no data available... */
445 if (mdl == NULL) {
446 /* if we got data, then return that regardless */
447 if (tot_written)
448 break;
449 /* EOS condition */
450 if (rc == 0) {
451 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
452 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
453 cx18_release_stream(s);
454 }
455 /* set errno */
456 return rc;
457 }
458
459 rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
460 tot_count - tot_written);
461
462 if (mdl != &cx->vbi.sliced_mpeg_mdl) {
463 if (mdl->readpos == mdl->bytesused)
464 cx18_stream_put_mdl_fw(s, mdl);
465 else
466 cx18_push(s, mdl, &s->q_full);
467 } else if (mdl->readpos == mdl->bytesused) {
468 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
469
470 cx->vbi.sliced_mpeg_size[idx] = 0;
471 cx->vbi.inserted_frame++;
472 cx->vbi_data_inserted += mdl->bytesused;
473 }
474 if (rc < 0)
475 return rc;
476 tot_written += rc;
477
478 if (tot_written == tot_count || single_frame)
479 break;
480 }
481 return tot_written;
482}
483
484static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
485 size_t count, loff_t *pos, int non_block)
486{
487 ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
488 struct cx18 *cx = s->cx;
489
490 CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
491 if (rc > 0)
492 pos += rc;
493 return rc;
494}
495
496int cx18_start_capture(struct cx18_open_id *id)
497{
498 struct cx18 *cx = id->cx;
499 struct cx18_stream *s = &cx->streams[id->type];
500 struct cx18_stream *s_vbi;
501 struct cx18_stream *s_idx;
502
503 if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
504 /* you cannot read from these stream types. */
505 return -EPERM;
506 }
507
508 /* Try to claim this stream. */
509 if (cx18_claim_stream(id, s->type))
510 return -EBUSY;
511
512 /* If capture is already in progress, then we also have to
513 do nothing extra. */
514 if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
515 test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
516 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
517 return 0;
518 }
519
520 /* Start associated VBI or IDX stream capture if required */
521 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
522 s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
523 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
524 /*
525 * The VBI and IDX streams should have been claimed
526 * automatically, if for internal use, when the MPG stream was
527 * claimed. We only need to start these streams capturing.
528 */
529 if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
530 !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
531 if (cx18_start_v4l2_encode_stream(s_idx)) {
532 CX18_DEBUG_WARN("IDX capture start failed\n");
533 clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
534 goto start_failed;
535 }
536 CX18_DEBUG_INFO("IDX capture started\n");
537 }
538 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
539 !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
540 if (cx18_start_v4l2_encode_stream(s_vbi)) {
541 CX18_DEBUG_WARN("VBI capture start failed\n");
542 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
543 goto start_failed;
544 }
545 CX18_DEBUG_INFO("VBI insertion started\n");
546 }
547 }
548
549 /* Tell the card to start capturing */
550 if (!cx18_start_v4l2_encode_stream(s)) {
551 /* We're done */
552 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
553 /* Resume a possibly paused encoder */
554 if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
555 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
556 return 0;
557 }
558
559start_failed:
560 CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
561
562 /*
563 * The associated VBI and IDX streams for internal use are released
564 * automatically when the MPG stream is released. We only need to stop
565 * the associated stream.
566 */
567 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
568 /* Stop the IDX stream which is always for internal use */
569 if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
570 cx18_stop_v4l2_encode_stream(s_idx, 0);
571 clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
572 }
573 /* Stop the VBI stream, if only running for internal use */
574 if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
575 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
576 cx18_stop_v4l2_encode_stream(s_vbi, 0);
577 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
578 }
579 }
580 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
581 cx18_release_stream(s); /* Also releases associated streams */
582 return -EIO;
583}
584
585ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
586 loff_t *pos)
587{
588 struct cx18_open_id *id = file2id(filp);
589 struct cx18 *cx = id->cx;
590 struct cx18_stream *s = &cx->streams[id->type];
591 int rc;
592
593 CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
594
595 mutex_lock(&cx->serialize_lock);
596 rc = cx18_start_capture(id);
597 mutex_unlock(&cx->serialize_lock);
598 if (rc)
599 return rc;
600
601 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
602 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
603 return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
604 filp->f_flags & O_NONBLOCK);
605 }
606
607 return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
608}
609
610unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
611{
612 struct cx18_open_id *id = file2id(filp);
613 struct cx18 *cx = id->cx;
614 struct cx18_stream *s = &cx->streams[id->type];
615 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
616
617 /* Start a capture if there is none */
618 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
619 int rc;
620
621 mutex_lock(&cx->serialize_lock);
622 rc = cx18_start_capture(id);
623 mutex_unlock(&cx->serialize_lock);
624 if (rc) {
625 CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
626 s->name, rc);
627 return POLLERR;
628 }
629 CX18_DEBUG_FILE("Encoder poll started capture\n");
630 }
631
632 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
633 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
634 int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
635 if (eof && videobuf_poll == POLLERR)
636 return POLLHUP;
637 else
638 return videobuf_poll;
639 }
640
641 /* add stream's waitq to the poll list */
642 CX18_DEBUG_HI_FILE("Encoder poll\n");
643 poll_wait(filp, &s->waitq, wait);
644
645 if (atomic_read(&s->q_full.depth))
646 return POLLIN | POLLRDNORM;
647 if (eof)
648 return POLLHUP;
649 return 0;
650}
651
652int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
653{
654 struct cx18_open_id *id = file->private_data;
655 struct cx18 *cx = id->cx;
656 struct cx18_stream *s = &cx->streams[id->type];
657 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
658
659 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
660 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
661
662 /* Start a capture if there is none */
663 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
664 int rc;
665
666 mutex_lock(&cx->serialize_lock);
667 rc = cx18_start_capture(id);
668 mutex_unlock(&cx->serialize_lock);
669 if (rc) {
670 CX18_DEBUG_INFO(
671 "Could not start capture for %s (%d)\n",
672 s->name, rc);
673 return -EINVAL;
674 }
675 CX18_DEBUG_FILE("Encoder mmap started capture\n");
676 }
677
678 return videobuf_mmap_mapper(&s->vbuf_q, vma);
679 }
680
681 return -EINVAL;
682}
683
684void cx18_vb_timeout(unsigned long data)
685{
686 struct cx18_stream *s = (struct cx18_stream *)data;
687 struct cx18_videobuf_buffer *buf;
688 unsigned long flags;
689
690 /* Return all of the buffers in error state, so the vbi/vid inode
691 * can return from blocking.
692 */
693 spin_lock_irqsave(&s->vb_lock, flags);
694 while (!list_empty(&s->vb_capture)) {
695 buf = list_entry(s->vb_capture.next,
696 struct cx18_videobuf_buffer, vb.queue);
697 list_del(&buf->vb.queue);
698 buf->vb.state = VIDEOBUF_ERROR;
699 wake_up(&buf->vb.done);
700 }
701 spin_unlock_irqrestore(&s->vb_lock, flags);
702}
703
704void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
705{
706 struct cx18 *cx = id->cx;
707 struct cx18_stream *s = &cx->streams[id->type];
708 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
709 struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
710
711 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
712
713 /* 'Unclaim' this stream */
714
715 /* Stop capturing */
716 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
717 CX18_DEBUG_INFO("close stopping capture\n");
718 if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
719 /* Stop internal use associated VBI and IDX streams */
720 if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
721 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
722 CX18_DEBUG_INFO("close stopping embedded VBI "
723 "capture\n");
724 cx18_stop_v4l2_encode_stream(s_vbi, 0);
725 }
726 if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
727 CX18_DEBUG_INFO("close stopping IDX capture\n");
728 cx18_stop_v4l2_encode_stream(s_idx, 0);
729 }
730 }
731 if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
732 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
733 /* Also used internally, don't stop capturing */
734 s->id = -1;
735 else
736 cx18_stop_v4l2_encode_stream(s, gop_end);
737 }
738 if (!gop_end) {
739 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
740 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
741 cx18_release_stream(s);
742 }
743}
744
745int cx18_v4l2_close(struct file *filp)
746{
747 struct v4l2_fh *fh = filp->private_data;
748 struct cx18_open_id *id = fh2id(fh);
749 struct cx18 *cx = id->cx;
750 struct cx18_stream *s = &cx->streams[id->type];
751
752 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
753
754 v4l2_fh_del(fh);
755 v4l2_fh_exit(fh);
756
757 /* Easy case first: this stream was never claimed by us */
758 if (s->id != id->open_id) {
759 kfree(id);
760 return 0;
761 }
762
763 /* 'Unclaim' this stream */
764
765 /* Stop radio */
766 mutex_lock(&cx->serialize_lock);
767 if (id->type == CX18_ENC_STREAM_TYPE_RAD) {
768 /* Closing radio device, return to TV mode */
769 cx18_mute(cx);
770 /* Mark that the radio is no longer in use */
771 clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
772 /* Switch tuner to TV */
773 cx18_call_all(cx, core, s_std, cx->std);
774 /* Select correct audio input (i.e. TV tuner or Line in) */
775 cx18_audio_set_io(cx);
776 if (atomic_read(&cx->ana_capturing) > 0) {
777 /* Undo video mute */
778 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
779 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
780 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
781 }
782 /* Done! Unmute and continue. */
783 cx18_unmute(cx);
784 cx18_release_stream(s);
785 } else {
786 cx18_stop_capture(id, 0);
787 if (id->type == CX18_ENC_STREAM_TYPE_YUV)
788 videobuf_mmap_free(&id->vbuf_q);
789 }
790 kfree(id);
791 mutex_unlock(&cx->serialize_lock);
792 return 0;
793}
794
795static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
796{
797 struct cx18 *cx = s->cx;
798 struct cx18_open_id *item;
799
800 CX18_DEBUG_FILE("open %s\n", s->name);
801
802 /* Allocate memory */
803 item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
804 if (NULL == item) {
805 CX18_DEBUG_WARN("nomem on v4l2 open\n");
806 return -ENOMEM;
807 }
808 v4l2_fh_init(&item->fh, s->video_dev);
809
810 item->cx = cx;
811 item->type = s->type;
812
813 item->open_id = cx->open_id++;
814 filp->private_data = &item->fh;
815
816 if (item->type == CX18_ENC_STREAM_TYPE_RAD) {
817 /* Try to claim this stream */
818 if (cx18_claim_stream(item, item->type)) {
819 /* No, it's already in use */
820 v4l2_fh_exit(&item->fh);
821 kfree(item);
822 return -EBUSY;
823 }
824
825 if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
826 if (atomic_read(&cx->ana_capturing) > 0) {
827 /* switching to radio while capture is
828 in progress is not polite */
829 cx18_release_stream(s);
830 v4l2_fh_exit(&item->fh);
831 kfree(item);
832 return -EBUSY;
833 }
834 }
835
836 /* Mark that the radio is being used. */
837 set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
838 /* We have the radio */
839 cx18_mute(cx);
840 /* Switch tuner to radio */
841 cx18_call_all(cx, tuner, s_radio);
842 /* Select the correct audio input (i.e. radio tuner) */
843 cx18_audio_set_io(cx);
844 /* Done! Unmute and continue. */
845 cx18_unmute(cx);
846 }
847 v4l2_fh_add(&item->fh);
848 return 0;
849}
850
851int cx18_v4l2_open(struct file *filp)
852{
853 int res;
854 struct video_device *video_dev = video_devdata(filp);
855 struct cx18_stream *s = video_get_drvdata(video_dev);
856 struct cx18 *cx = s->cx;
857
858 mutex_lock(&cx->serialize_lock);
859 if (cx18_init_on_first_open(cx)) {
860 CX18_ERR("Failed to initialize on %s\n",
861 video_device_node_name(video_dev));
862 mutex_unlock(&cx->serialize_lock);
863 return -ENXIO;
864 }
865 res = cx18_serialized_open(s, filp);
866 mutex_unlock(&cx->serialize_lock);
867 return res;
868}
869
870void cx18_mute(struct cx18 *cx)
871{
872 u32 h;
873 if (atomic_read(&cx->ana_capturing)) {
874 h = cx18_find_handle(cx);
875 if (h != CX18_INVALID_TASK_HANDLE)
876 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
877 else
878 CX18_ERR("Can't find valid task handle for mute\n");
879 }
880 CX18_DEBUG_INFO("Mute\n");
881}
882
883void cx18_unmute(struct cx18 *cx)
884{
885 u32 h;
886 if (atomic_read(&cx->ana_capturing)) {
887 h = cx18_find_handle(cx);
888 if (h != CX18_INVALID_TASK_HANDLE) {
889 cx18_msleep_timeout(100, 0);
890 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
891 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
892 } else
893 CX18_ERR("Can't find valid task handle for unmute\n");
894 }
895 CX18_DEBUG_INFO("Unmute\n");
896}
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
new file mode 100644
index 00000000000..b9e5110ad04
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -0,0 +1,41 @@
1/*
2 * cx18 file operation functions
3 *
4 * Derived from ivtv-fileops.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24/* Testing/Debugging */
25int cx18_v4l2_open(struct file *filp);
26ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
27 loff_t *pos);
28ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count,
29 loff_t *pos);
30int cx18_v4l2_close(struct file *filp);
31unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait);
32int cx18_start_capture(struct cx18_open_id *id);
33void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
34void cx18_mute(struct cx18 *cx);
35void cx18_unmute(struct cx18 *cx);
36int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma);
37void cx18_vb_timeout(unsigned long data);
38
39/* Shared with cx18-alsa module */
40int cx18_claim_stream(struct cx18_open_id *id, int type);
41void 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
new file mode 100644
index 00000000000..1b3fb502e6b
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -0,0 +1,448 @@
1/*
2 * cx18 firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#include "cx18-driver.h"
24#include "cx18-io.h"
25#include "cx18-scb.h"
26#include "cx18-irq.h"
27#include "cx18-firmware.h"
28#include "cx18-cards.h"
29#include <linux/firmware.h>
30
31#define CX18_PROC_SOFT_RESET 0xc70010
32#define CX18_DDR_SOFT_RESET 0xc70014
33#define CX18_CLOCK_SELECT1 0xc71000
34#define CX18_CLOCK_SELECT2 0xc71004
35#define CX18_HALF_CLOCK_SELECT1 0xc71008
36#define CX18_HALF_CLOCK_SELECT2 0xc7100C
37#define CX18_CLOCK_POLARITY1 0xc71010
38#define CX18_CLOCK_POLARITY2 0xc71014
39#define CX18_ADD_DELAY_ENABLE1 0xc71018
40#define CX18_ADD_DELAY_ENABLE2 0xc7101C
41#define CX18_CLOCK_ENABLE1 0xc71020
42#define CX18_CLOCK_ENABLE2 0xc71024
43
44#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
45
46#define CX18_FAST_CLOCK_PLL_INT 0xc78000
47#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
48#define CX18_FAST_CLOCK_PLL_POST 0xc78008
49#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C
50#define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010
51
52#define CX18_SLOW_CLOCK_PLL_INT 0xc78014
53#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018
54#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C
55#define CX18_MPEG_CLOCK_PLL_INT 0xc78040
56#define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044
57#define CX18_MPEG_CLOCK_PLL_POST 0xc78048
58#define CX18_PLL_POWER_DOWN 0xc78088
59#define CX18_SW1_INT_STATUS 0xc73104
60#define CX18_SW1_INT_ENABLE_PCI 0xc7311C
61#define CX18_SW2_INT_SET 0xc73140
62#define CX18_SW2_INT_STATUS 0xc73144
63#define CX18_ADEC_CONTROL 0xc78120
64
65#define CX18_DDR_REQUEST_ENABLE 0xc80000
66#define CX18_DDR_CHIP_CONFIG 0xc80004
67#define CX18_DDR_REFRESH 0xc80008
68#define CX18_DDR_TIMING1 0xc8000C
69#define CX18_DDR_TIMING2 0xc80010
70#define CX18_DDR_POWER_REG 0xc8001C
71
72#define CX18_DDR_TUNE_LANE 0xc80048
73#define CX18_DDR_INITIAL_EMRS 0xc80054
74#define CX18_DDR_MB_PER_ROW_7 0xc8009C
75#define CX18_DDR_BASE_63_ADDR 0xc804FC
76
77#define CX18_WMB_CLIENT02 0xc90108
78#define CX18_WMB_CLIENT05 0xc90114
79#define CX18_WMB_CLIENT06 0xc90118
80#define CX18_WMB_CLIENT07 0xc9011C
81#define CX18_WMB_CLIENT08 0xc90120
82#define CX18_WMB_CLIENT09 0xc90124
83#define CX18_WMB_CLIENT10 0xc90128
84#define CX18_WMB_CLIENT11 0xc9012C
85#define CX18_WMB_CLIENT12 0xc90130
86#define CX18_WMB_CLIENT13 0xc90134
87#define CX18_WMB_CLIENT14 0xc90138
88
89#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
90
91#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
92#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
93
94struct cx18_apu_rom_seghdr {
95 u32 sync1;
96 u32 sync2;
97 u32 addr;
98 u32 size;
99};
100
101static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
102{
103 const struct firmware *fw = NULL;
104 int i, j;
105 unsigned size;
106 u32 __iomem *dst = (u32 __iomem *)mem;
107 const u32 *src;
108
109 if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
110 CX18_ERR("Unable to open firmware %s\n", fn);
111 CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
112 return -ENOMEM;
113 }
114
115 src = (const u32 *)fw->data;
116
117 for (i = 0; i < fw->size; i += 4096) {
118 cx18_setup_page(cx, i);
119 for (j = i; j < fw->size && j < i + 4096; j += 4) {
120 /* no need for endianness conversion on the ppc */
121 cx18_raw_writel(cx, *src, dst);
122 if (cx18_raw_readl(cx, dst) != *src) {
123 CX18_ERR("Mismatch at offset %x\n", i);
124 release_firmware(fw);
125 cx18_setup_page(cx, 0);
126 return -EIO;
127 }
128 dst++;
129 src++;
130 }
131 }
132 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
133 CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
134 size = fw->size;
135 release_firmware(fw);
136 cx18_setup_page(cx, SCB_OFFSET);
137 return size;
138}
139
140static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
141 u32 *entry_addr)
142{
143 const struct firmware *fw = NULL;
144 int i, j;
145 unsigned size;
146 const u32 *src;
147 struct cx18_apu_rom_seghdr seghdr;
148 const u8 *vers;
149 u32 offset = 0;
150 u32 apu_version = 0;
151 int sz;
152
153 if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
154 CX18_ERR("unable to open firmware %s\n", fn);
155 CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
156 cx18_setup_page(cx, 0);
157 return -ENOMEM;
158 }
159
160 *entry_addr = 0;
161 src = (const u32 *)fw->data;
162 vers = fw->data + sizeof(seghdr);
163 sz = fw->size;
164
165 apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
166 while (offset + sizeof(seghdr) < fw->size) {
167 /* TODO: byteswapping */
168 memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
169 offset += sizeof(seghdr);
170 if (seghdr.sync1 != APU_ROM_SYNC1 ||
171 seghdr.sync2 != APU_ROM_SYNC2) {
172 offset += seghdr.size;
173 continue;
174 }
175 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
176 seghdr.addr + seghdr.size - 1);
177 if (*entry_addr == 0)
178 *entry_addr = seghdr.addr;
179 if (offset + seghdr.size > sz)
180 break;
181 for (i = 0; i < seghdr.size; i += 4096) {
182 cx18_setup_page(cx, seghdr.addr + i);
183 for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
184 /* no need for endianness conversion on the ppc */
185 cx18_raw_writel(cx, src[(offset + j) / 4],
186 dst + seghdr.addr + j);
187 if (cx18_raw_readl(cx, dst + seghdr.addr + j)
188 != src[(offset + j) / 4]) {
189 CX18_ERR("Mismatch at offset %x\n",
190 offset + j);
191 release_firmware(fw);
192 cx18_setup_page(cx, 0);
193 return -EIO;
194 }
195 }
196 }
197 offset += seghdr.size;
198 }
199 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
200 CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
201 fn, apu_version, fw->size);
202 size = fw->size;
203 release_firmware(fw);
204 cx18_setup_page(cx, 0);
205 return size;
206}
207
208void cx18_halt_firmware(struct cx18 *cx)
209{
210 CX18_DEBUG_INFO("Preparing for firmware halt.\n");
211 cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
212 0x0000000F, 0x000F000F);
213 cx18_write_reg_expect(cx, 0x00020002, CX18_ADEC_CONTROL,
214 0x00000002, 0x00020002);
215}
216
217void cx18_init_power(struct cx18 *cx, int lowpwr)
218{
219 /* power-down Spare and AOM PLLs */
220 /* power-up fast, slow and mpeg PLLs */
221 cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
222
223 /* ADEC out of sleep */
224 cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL,
225 0x00000000, 0x00020002);
226
227 /*
228 * The PLL parameters are based on the external crystal frequency that
229 * would ideally be:
230 *
231 * NTSC Color subcarrier freq * 8 =
232 * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
233 *
234 * The accidents of history and rationale that explain from where this
235 * combination of magic numbers originate can be found in:
236 *
237 * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
238 * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
239 *
240 * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
241 * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
242 *
243 * As Mike Bradley has rightly pointed out, it's not the exact crystal
244 * frequency that matters, only that all parts of the driver and
245 * firmware are using the same value (close to the ideal value).
246 *
247 * Since I have a strong suspicion that, if the firmware ever assumes a
248 * crystal value at all, it will assume 28.636360 MHz, the crystal
249 * freq used in calculations in this driver will be:
250 *
251 * xtal_freq = 28.636360 MHz
252 *
253 * an error of less than 0.13 ppm which is way, way better than any off
254 * the shelf crystal will have for accuracy anyway.
255 *
256 * Below I aim to run the PLLs' VCOs near 400 MHz to minimze errors.
257 *
258 * Many thanks to Jeff Campbell and Mike Bradley for their extensive
259 * investigation, experimentation, testing, and suggested solutions of
260 * of audio/video sync problems with SVideo and CVBS captures.
261 */
262
263 /* the fast clock is at 200/245 MHz */
264 /* 1 * xtal_freq * 0x0d.f7df9b8 / 2 = 200 MHz: 400 MHz pre post-divide*/
265 /* 1 * xtal_freq * 0x11.1c71eb8 / 2 = 245 MHz: 490 MHz pre post-divide*/
266 cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
267 cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
268 CX18_FAST_CLOCK_PLL_FRAC);
269
270 cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST);
271 cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE);
272 cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
273
274 /* set slow clock to 125/120 MHz */
275 /* xtal_freq * 0x0d.1861a20 / 3 = 125 MHz: 375 MHz before post-divide */
276 /* xtal_freq * 0x0c.92493f8 / 3 = 120 MHz: 360 MHz before post-divide */
277 cx18_write_reg(cx, lowpwr ? 0xD : 0xC, CX18_SLOW_CLOCK_PLL_INT);
278 cx18_write_reg(cx, lowpwr ? 0x30C344 : 0x124927F,
279 CX18_SLOW_CLOCK_PLL_FRAC);
280 cx18_write_reg(cx, 3, CX18_SLOW_CLOCK_PLL_POST);
281
282 /* mpeg clock pll 54MHz */
283 /* xtal_freq * 0xf.15f17f0 / 8 = 54 MHz: 432 MHz before post-divide */
284 cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
285 cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
286 cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
287
288 /* Defaults */
289 /* APU = SC or SC/2 = 125/62.5 */
290 /* EPU = SC = 125 */
291 /* DDR = FC = 180 */
292 /* ENC = SC = 125 */
293 /* AI1 = SC = 125 */
294 /* VIM2 = disabled */
295 /* PCI = FC/2 = 90 */
296 /* AI2 = disabled */
297 /* DEMUX = disabled */
298 /* AO = SC/2 = 62.5 */
299 /* SER = 54MHz */
300 /* VFC = disabled */
301 /* USB = disabled */
302
303 if (lowpwr) {
304 cx18_write_reg_expect(cx, 0xFFFF0020, CX18_CLOCK_SELECT1,
305 0x00000020, 0xFFFFFFFF);
306 cx18_write_reg_expect(cx, 0xFFFF0004, CX18_CLOCK_SELECT2,
307 0x00000004, 0xFFFFFFFF);
308 } else {
309 /* This doesn't explicitly set every clock select */
310 cx18_write_reg_expect(cx, 0x00060004, CX18_CLOCK_SELECT1,
311 0x00000004, 0x00060006);
312 cx18_write_reg_expect(cx, 0x00060006, CX18_CLOCK_SELECT2,
313 0x00000006, 0x00060006);
314 }
315
316 cx18_write_reg_expect(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1,
317 0x00000002, 0xFFFFFFFF);
318 cx18_write_reg_expect(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2,
319 0x00000104, 0xFFFFFFFF);
320 cx18_write_reg_expect(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1,
321 0x00009026, 0xFFFFFFFF);
322 cx18_write_reg_expect(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2,
323 0x00003105, 0xFFFFFFFF);
324}
325
326void cx18_init_memory(struct cx18 *cx)
327{
328 cx18_msleep_timeout(10, 0);
329 cx18_write_reg_expect(cx, 0x00010000, CX18_DDR_SOFT_RESET,
330 0x00000000, 0x00010001);
331 cx18_msleep_timeout(10, 0);
332
333 cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
334
335 cx18_msleep_timeout(10, 0);
336
337 cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH);
338 cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1);
339 cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2);
340
341 cx18_msleep_timeout(10, 0);
342
343 /* Initialize DQS pad time */
344 cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
345 cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
346
347 cx18_msleep_timeout(10, 0);
348
349 cx18_write_reg_expect(cx, 0x00020000, CX18_DDR_SOFT_RESET,
350 0x00000000, 0x00020002);
351 cx18_msleep_timeout(10, 0);
352
353 /* use power-down mode when idle */
354 cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
355
356 cx18_write_reg_expect(cx, 0x00010001, CX18_REG_BUS_TIMEOUT_EN,
357 0x00000001, 0x00010001);
358
359 cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
360 cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
361
362 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */
363 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */
364 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
365 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */
366 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
367 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */
368 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */
369 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */
370 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */
371 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */
372}
373
374int cx18_firmware_init(struct cx18 *cx)
375{
376 u32 fw_entry_addr;
377 int sz, retries;
378 u32 api_args[MAX_MB_ARGUMENTS];
379
380 /* Allow chip to control CLKRUN */
381 cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
382
383 /* Stop the firmware */
384 cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
385 0x0000000F, 0x000F000F);
386
387 cx18_msleep_timeout(1, 0);
388
389 /* If the CPU is still running */
390 if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) {
391 CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__);
392 return -EIO;
393 }
394
395 cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
396 cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
397
398 sz = load_cpu_fw_direct("v4l-cx23418-cpu.fw", cx->enc_mem, cx);
399 if (sz <= 0)
400 return sz;
401
402 /* The SCB & IPC area *must* be correct before starting the firmwares */
403 cx18_init_scb(cx);
404
405 fw_entry_addr = 0;
406 sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx,
407 &fw_entry_addr);
408 if (sz <= 0)
409 return sz;
410
411 /* Start the CPU. The CPU will take care of the APU for us. */
412 cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET,
413 0x00000000, 0x00080008);
414
415 /* Wait up to 500 ms for the APU to come out of reset */
416 for (retries = 0;
417 retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1;
418 retries++)
419 cx18_msleep_timeout(10, 0);
420
421 cx18_msleep_timeout(200, 0);
422
423 if (retries == 50 &&
424 (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) {
425 CX18_ERR("Could not start the CPU\n");
426 return -EIO;
427 }
428
429 /*
430 * The CPU had once before set up to receive an interrupt for it's
431 * outgoing IRQ_CPU_TO_EPU_ACK to us. If it ever does this, we get an
432 * interrupt when it sends us an ack, but by the time we process it,
433 * that flag in the SW2 status register has been cleared by the CPU
434 * firmware. We'll prevent that not so useful condition from happening
435 * by clearing the CPU's interrupt enables for Ack IRQ's we want to
436 * process.
437 */
438 cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
439
440 /* Try a benign command to see if the CPU is alive and well */
441 sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0);
442 if (sz < 0)
443 return sz;
444
445 /* initialize GPIO */
446 cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
447 return 0;
448}
diff --git a/drivers/media/video/cx18/cx18-firmware.h b/drivers/media/video/cx18/cx18-firmware.h
new file mode 100644
index 00000000000..38d4c05e849
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-firmware.h
@@ -0,0 +1,25 @@
1/*
2 * cx18 firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22int cx18_firmware_init(struct cx18 *cx);
23void cx18_halt_firmware(struct cx18 *cx);
24void cx18_init_memory(struct cx18 *cx);
25void 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
new file mode 100644
index 00000000000..5374aeb0cd2
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -0,0 +1,347 @@
1/*
2 * cx18 gpio functions
3 *
4 * Derived from ivtv-gpio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-io.h"
27#include "cx18-cards.h"
28#include "cx18-gpio.h"
29#include "tuner-xc2028.h"
30
31/********************* GPIO stuffs *********************/
32
33/* GPIO registers */
34#define CX18_REG_GPIO_IN 0xc72010
35#define CX18_REG_GPIO_OUT1 0xc78100
36#define CX18_REG_GPIO_DIR1 0xc78108
37#define CX18_REG_GPIO_OUT2 0xc78104
38#define CX18_REG_GPIO_DIR2 0xc7810c
39
40/*
41 * HVR-1600 GPIO pins, courtesy of Hauppauge:
42 *
43 * gpio0: zilog ir process reset pin
44 * gpio1: zilog programming pin (you should never use this)
45 * gpio12: cx24227 reset pin
46 * gpio13: cs5345 reset pin
47*/
48
49/*
50 * File scope utility functions
51 */
52static void gpio_write(struct cx18 *cx)
53{
54 u32 dir_lo = cx->gpio_dir & 0xffff;
55 u32 val_lo = cx->gpio_val & 0xffff;
56 u32 dir_hi = cx->gpio_dir >> 16;
57 u32 val_hi = cx->gpio_val >> 16;
58
59 cx18_write_reg_expect(cx, dir_lo << 16,
60 CX18_REG_GPIO_DIR1, ~dir_lo, dir_lo);
61 cx18_write_reg_expect(cx, (dir_lo << 16) | val_lo,
62 CX18_REG_GPIO_OUT1, val_lo, dir_lo);
63 cx18_write_reg_expect(cx, dir_hi << 16,
64 CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
65 cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
66 CX18_REG_GPIO_OUT2, val_hi, dir_hi);
67}
68
69static void gpio_update(struct cx18 *cx, u32 mask, u32 data)
70{
71 if (mask == 0)
72 return;
73
74 mutex_lock(&cx->gpio_lock);
75 cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
76 gpio_write(cx);
77 mutex_unlock(&cx->gpio_lock);
78}
79
80static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi,
81 unsigned int assert_msecs,
82 unsigned int recovery_msecs)
83{
84 u32 mask;
85
86 mask = active_lo | active_hi;
87 if (mask == 0)
88 return;
89
90 /*
91 * Assuming that active_hi and active_lo are a subsets of the bits in
92 * gpio_dir. Also assumes that active_lo and active_hi don't overlap
93 * in any bit position
94 */
95
96 /* Assert */
97 gpio_update(cx, mask, ~active_lo);
98 schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs));
99
100 /* Deassert */
101 gpio_update(cx, mask, ~active_hi);
102 schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs));
103}
104
105/*
106 * GPIO Multiplexer - logical device
107 */
108static int gpiomux_log_status(struct v4l2_subdev *sd)
109{
110 struct cx18 *cx = v4l2_get_subdevdata(sd);
111
112 mutex_lock(&cx->gpio_lock);
113 CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
114 cx->gpio_dir, cx->gpio_val);
115 mutex_unlock(&cx->gpio_lock);
116 return 0;
117}
118
119static int gpiomux_s_radio(struct v4l2_subdev *sd)
120{
121 struct cx18 *cx = v4l2_get_subdevdata(sd);
122
123 /*
124 * FIXME - work out the cx->active/audio_input mess - this is
125 * intended to handle the switch to radio mode and set the
126 * audio routing, but we need to update the state in cx
127 */
128 gpio_update(cx, cx->card->gpio_audio_input.mask,
129 cx->card->gpio_audio_input.radio);
130 return 0;
131}
132
133static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
134{
135 struct cx18 *cx = v4l2_get_subdevdata(sd);
136 u32 data;
137
138 switch (cx->card->audio_inputs[cx->audio_input].muxer_input) {
139 case 1:
140 data = cx->card->gpio_audio_input.linein;
141 break;
142 case 0:
143 data = cx->card->gpio_audio_input.tuner;
144 break;
145 default:
146 /*
147 * FIXME - work out the cx->active/audio_input mess - this is
148 * intended to handle the switch from radio mode and set the
149 * audio routing, but we need to update the state in cx
150 */
151 data = cx->card->gpio_audio_input.tuner;
152 break;
153 }
154 gpio_update(cx, cx->card->gpio_audio_input.mask, data);
155 return 0;
156}
157
158static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
159 u32 input, u32 output, u32 config)
160{
161 struct cx18 *cx = v4l2_get_subdevdata(sd);
162 u32 data;
163
164 switch (input) {
165 case 0:
166 data = cx->card->gpio_audio_input.tuner;
167 break;
168 case 1:
169 data = cx->card->gpio_audio_input.linein;
170 break;
171 case 2:
172 data = cx->card->gpio_audio_input.radio;
173 break;
174 default:
175 return -EINVAL;
176 }
177 gpio_update(cx, cx->card->gpio_audio_input.mask, data);
178 return 0;
179}
180
181static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
182 .log_status = gpiomux_log_status,
183 .s_std = gpiomux_s_std,
184};
185
186static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
187 .s_radio = gpiomux_s_radio,
188};
189
190static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
191 .s_routing = gpiomux_s_audio_routing,
192};
193
194static const struct v4l2_subdev_ops gpiomux_ops = {
195 .core = &gpiomux_core_ops,
196 .tuner = &gpiomux_tuner_ops,
197 .audio = &gpiomux_audio_ops,
198};
199
200/*
201 * GPIO Reset Controller - logical device
202 */
203static int resetctrl_log_status(struct v4l2_subdev *sd)
204{
205 struct cx18 *cx = v4l2_get_subdevdata(sd);
206
207 mutex_lock(&cx->gpio_lock);
208 CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
209 cx->gpio_dir, cx->gpio_val);
210 mutex_unlock(&cx->gpio_lock);
211 return 0;
212}
213
214static int resetctrl_reset(struct v4l2_subdev *sd, u32 val)
215{
216 struct cx18 *cx = v4l2_get_subdevdata(sd);
217 const struct cx18_gpio_i2c_slave_reset *p;
218
219 p = &cx->card->gpio_i2c_slave_reset;
220 switch (val) {
221 case CX18_GPIO_RESET_I2C:
222 gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask,
223 p->msecs_asserted, p->msecs_recovery);
224 break;
225 case CX18_GPIO_RESET_Z8F0811:
226 /*
227 * Assert timing for the Z8F0811 on HVR-1600 boards:
228 * 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to
229 * initiate
230 * 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock
231 * cycles (6,601,085 nanoseconds ~= 7 milliseconds)
232 * 3. DBG pin must be high before chip exits reset for normal
233 * operation. DBG is open drain and hopefully pulled high
234 * since we don't normally drive it (GPIO 1?) for the
235 * HVR-1600
236 * 4. Z8F0811 won't exit reset until RESET is deasserted
237 * 5. Zilog comes out of reset, loads reset vector address and
238 * executes from there. Required recovery delay unknown.
239 */
240 gpio_reset_seq(cx, p->ir_reset_mask, 0,
241 p->msecs_asserted, p->msecs_recovery);
242 break;
243 case CX18_GPIO_RESET_XC2028:
244 if (cx->card->tuners[0].tuner == TUNER_XC2028)
245 gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0,
246 1, 1);
247 break;
248 }
249 return 0;
250}
251
252static const struct v4l2_subdev_core_ops resetctrl_core_ops = {
253 .log_status = resetctrl_log_status,
254 .reset = resetctrl_reset,
255};
256
257static const struct v4l2_subdev_ops resetctrl_ops = {
258 .core = &resetctrl_core_ops,
259};
260
261/*
262 * External entry points
263 */
264void cx18_gpio_init(struct cx18 *cx)
265{
266 mutex_lock(&cx->gpio_lock);
267 cx->gpio_dir = cx->card->gpio_init.direction;
268 cx->gpio_val = cx->card->gpio_init.initial_value;
269
270 if (cx->card->tuners[0].tuner == TUNER_XC2028) {
271 cx->gpio_dir |= 1 << cx->card->xceive_pin;
272 cx->gpio_val |= 1 << cx->card->xceive_pin;
273 }
274
275 if (cx->gpio_dir == 0) {
276 mutex_unlock(&cx->gpio_lock);
277 return;
278 }
279
280 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
281 cx18_read_reg(cx, CX18_REG_GPIO_DIR1),
282 cx18_read_reg(cx, CX18_REG_GPIO_DIR2),
283 cx18_read_reg(cx, CX18_REG_GPIO_OUT1),
284 cx18_read_reg(cx, CX18_REG_GPIO_OUT2));
285
286 gpio_write(cx);
287 mutex_unlock(&cx->gpio_lock);
288}
289
290int cx18_gpio_register(struct cx18 *cx, u32 hw)
291{
292 struct v4l2_subdev *sd;
293 const struct v4l2_subdev_ops *ops;
294 char *str;
295
296 switch (hw) {
297 case CX18_HW_GPIO_MUX:
298 sd = &cx->sd_gpiomux;
299 ops = &gpiomux_ops;
300 str = "gpio-mux";
301 break;
302 case CX18_HW_GPIO_RESET_CTRL:
303 sd = &cx->sd_resetctrl;
304 ops = &resetctrl_ops;
305 str = "gpio-reset-ctrl";
306 break;
307 default:
308 return -EINVAL;
309 }
310
311 v4l2_subdev_init(sd, ops);
312 v4l2_set_subdevdata(sd, cx);
313 snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str);
314 sd->grp_id = hw;
315 return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
316}
317
318void cx18_reset_ir_gpio(void *data)
319{
320 struct cx18 *cx = to_cx18((struct v4l2_device *)data);
321
322 if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0)
323 return;
324
325 CX18_DEBUG_INFO("Resetting IR microcontroller\n");
326
327 v4l2_subdev_call(&cx->sd_resetctrl,
328 core, reset, CX18_GPIO_RESET_Z8F0811);
329}
330EXPORT_SYMBOL(cx18_reset_ir_gpio);
331/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */
332
333/* Xceive tuner reset function */
334int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
335{
336 struct i2c_algo_bit_data *algo = dev;
337 struct cx18_i2c_algo_callback_data *cb_data = algo->data;
338 struct cx18 *cx = cb_data->cx;
339
340 if (cmd != XC2028_TUNER_RESET ||
341 cx->card->tuners[0].tuner != TUNER_XC2028)
342 return 0;
343
344 CX18_DEBUG_INFO("Resetting XCeive tuner\n");
345 return v4l2_subdev_call(&cx->sd_resetctrl,
346 core, reset, CX18_GPIO_RESET_XC2028);
347}
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
new file mode 100644
index 00000000000..4aea2ef88e8
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -0,0 +1,34 @@
1/*
2 * cx18 gpio functions
3 *
4 * Derived from ivtv-gpio.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24void cx18_gpio_init(struct cx18 *cx);
25int cx18_gpio_register(struct cx18 *cx, u32 hw);
26
27enum cx18_gpio_reset_type {
28 CX18_GPIO_RESET_I2C = 0,
29 CX18_GPIO_RESET_Z8F0811 = 1,
30 CX18_GPIO_RESET_XC2028 = 2,
31};
32
33void cx18_reset_ir_gpio(void *data);
34int 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
new file mode 100644
index 00000000000..040aaa87579
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -0,0 +1,330 @@
1/*
2 * cx18 I2C functions
3 *
4 * Derived from ivtv-i2c.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-io.h"
27#include "cx18-cards.h"
28#include "cx18-gpio.h"
29#include "cx18-i2c.h"
30#include "cx18-irq.h"
31
32#define CX18_REG_I2C_1_WR 0xf15000
33#define CX18_REG_I2C_1_RD 0xf15008
34#define CX18_REG_I2C_2_WR 0xf25100
35#define CX18_REG_I2C_2_RD 0xf25108
36
37#define SETSCL_BIT 0x0001
38#define SETSDL_BIT 0x0002
39#define GETSCL_BIT 0x0004
40#define GETSDL_BIT 0x0008
41
42#define CX18_CS5345_I2C_ADDR 0x4c
43#define CX18_Z8F0811_IR_TX_I2C_ADDR 0x70
44#define CX18_Z8F0811_IR_RX_I2C_ADDR 0x71
45
46/* This array should match the CX18_HW_ defines */
47static const u8 hw_addrs[] = {
48 0, /* CX18_HW_TUNER */
49 0, /* CX18_HW_TVEEPROM */
50 CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */
51 0, /* CX18_HW_DVB */
52 0, /* CX18_HW_418_AV */
53 0, /* CX18_HW_GPIO_MUX */
54 0, /* CX18_HW_GPIO_RESET_CTRL */
55 CX18_Z8F0811_IR_TX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_TX_HAUP */
56 CX18_Z8F0811_IR_RX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_RX_HAUP */
57};
58
59/* This array should match the CX18_HW_ defines */
60/* This might well become a card-specific array */
61static const u8 hw_bus[] = {
62 1, /* CX18_HW_TUNER */
63 0, /* CX18_HW_TVEEPROM */
64 0, /* CX18_HW_CS5345 */
65 0, /* CX18_HW_DVB */
66 0, /* CX18_HW_418_AV */
67 0, /* CX18_HW_GPIO_MUX */
68 0, /* CX18_HW_GPIO_RESET_CTRL */
69 0, /* CX18_HW_Z8F0811_IR_TX_HAUP */
70 0, /* CX18_HW_Z8F0811_IR_RX_HAUP */
71};
72
73/* This array should match the CX18_HW_ defines */
74static const char * const hw_devicenames[] = {
75 "tuner",
76 "tveeprom",
77 "cs5345",
78 "cx23418_DTV",
79 "cx23418_AV",
80 "gpio_mux",
81 "gpio_reset_ctrl",
82 "ir_tx_z8f0811_haup",
83 "ir_rx_z8f0811_haup",
84};
85
86static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
87 const char *type, u8 addr)
88{
89 struct i2c_board_info info;
90 struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data;
91 unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
92
93 memset(&info, 0, sizeof(struct i2c_board_info));
94 strlcpy(info.type, type, I2C_NAME_SIZE);
95
96 /* Our default information for ir-kbd-i2c.c to use */
97 switch (hw) {
98 case CX18_HW_Z8F0811_IR_RX_HAUP:
99 init_data->ir_codes = RC_MAP_HAUPPAUGE;
100 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
101 init_data->type = RC_TYPE_RC5;
102 init_data->name = cx->card_name;
103 info.platform_data = init_data;
104 break;
105 }
106
107 return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
108 -1 : 0;
109}
110
111int cx18_i2c_register(struct cx18 *cx, unsigned idx)
112{
113 struct v4l2_subdev *sd;
114 int bus = hw_bus[idx];
115 struct i2c_adapter *adap = &cx->i2c_adap[bus];
116 const char *type = hw_devicenames[idx];
117 u32 hw = 1 << idx;
118
119 if (idx >= ARRAY_SIZE(hw_addrs))
120 return -1;
121
122 if (hw == CX18_HW_TUNER) {
123 /* special tuner group handling */
124 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
125 adap, type, 0, cx->card_i2c->radio);
126 if (sd != NULL)
127 sd->grp_id = hw;
128 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
129 adap, type, 0, cx->card_i2c->demod);
130 if (sd != NULL)
131 sd->grp_id = hw;
132 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
133 adap, type, 0, cx->card_i2c->tv);
134 if (sd != NULL)
135 sd->grp_id = hw;
136 return sd != NULL ? 0 : -1;
137 }
138
139 if (hw & CX18_HW_IR_ANY)
140 return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
141
142 /* Is it not an I2C device or one we do not wish to register? */
143 if (!hw_addrs[idx])
144 return -1;
145
146 /* It's an I2C device other than an analog tuner or IR chip */
147 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx],
148 NULL);
149 if (sd != NULL)
150 sd->grp_id = hw;
151 return sd != NULL ? 0 : -1;
152}
153
154/* Find the first member of the subdev group id in hw */
155struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw)
156{
157 struct v4l2_subdev *result = NULL;
158 struct v4l2_subdev *sd;
159
160 spin_lock(&cx->v4l2_dev.lock);
161 v4l2_device_for_each_subdev(sd, &cx->v4l2_dev) {
162 if (sd->grp_id == hw) {
163 result = sd;
164 break;
165 }
166 }
167 spin_unlock(&cx->v4l2_dev.lock);
168 return result;
169}
170
171static void cx18_setscl(void *data, int state)
172{
173 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
174 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
175 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
176 u32 r = cx18_read_reg(cx, addr);
177
178 if (state)
179 cx18_write_reg(cx, r | SETSCL_BIT, addr);
180 else
181 cx18_write_reg(cx, r & ~SETSCL_BIT, addr);
182}
183
184static void cx18_setsda(void *data, int state)
185{
186 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
187 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
188 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
189 u32 r = cx18_read_reg(cx, addr);
190
191 if (state)
192 cx18_write_reg(cx, r | SETSDL_BIT, addr);
193 else
194 cx18_write_reg(cx, r & ~SETSDL_BIT, addr);
195}
196
197static int cx18_getscl(void *data)
198{
199 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
200 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
201 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
202
203 return cx18_read_reg(cx, addr) & GETSCL_BIT;
204}
205
206static int cx18_getsda(void *data)
207{
208 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
209 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
210 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
211
212 return cx18_read_reg(cx, addr) & GETSDL_BIT;
213}
214
215/* template for i2c-bit-algo */
216static struct i2c_adapter cx18_i2c_adap_template = {
217 .name = "cx18 i2c driver",
218 .algo = NULL, /* set by i2c-algo-bit */
219 .algo_data = NULL, /* filled from template */
220 .owner = THIS_MODULE,
221};
222
223#define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */
224#define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */
225
226static struct i2c_algo_bit_data cx18_i2c_algo_template = {
227 .setsda = cx18_setsda,
228 .setscl = cx18_setscl,
229 .getsda = cx18_getsda,
230 .getscl = cx18_getscl,
231 .udelay = CX18_SCL_PERIOD/2, /* 1/2 clock period in usec*/
232 .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
233};
234
235/* init + register i2c algo-bit adapter */
236int init_cx18_i2c(struct cx18 *cx)
237{
238 int i, err;
239 CX18_DEBUG_I2C("i2c init\n");
240
241 for (i = 0; i < 2; i++) {
242 /* Setup algorithm for adapter */
243 memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
244 sizeof(struct i2c_algo_bit_data));
245 cx->i2c_algo_cb_data[i].cx = cx;
246 cx->i2c_algo_cb_data[i].bus_index = i;
247 cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
248
249 /* Setup adapter */
250 memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
251 sizeof(struct i2c_adapter));
252 cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
253 sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
254 " #%d-%d", cx->instance, i);
255 i2c_set_adapdata(&cx->i2c_adap[i], &cx->v4l2_dev);
256 cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev;
257 }
258
259 if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
260 /* Reset/Unreset I2C hardware block */
261 /* Clock select 220MHz */
262 cx18_write_reg_expect(cx, 0x10000000, 0xc71004,
263 0x00000000, 0x10001000);
264 /* Clock Enable */
265 cx18_write_reg_expect(cx, 0x10001000, 0xc71024,
266 0x00001000, 0x10001000);
267 }
268 /* courtesy of Steven Toth <stoth@hauppauge.com> */
269 cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
270 mdelay(10);
271 cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0);
272 mdelay(10);
273 cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
274 mdelay(10);
275
276 /* Set to edge-triggered intrs. */
277 cx18_write_reg(cx, 0x00c00000, 0xc730c8);
278 /* Clear any stale intrs */
279 cx18_write_reg_expect(cx, HW2_I2C1_INT|HW2_I2C2_INT, HW2_INT_CLR_STATUS,
280 ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT);
281
282 /* Hw I2C1 Clock Freq ~100kHz */
283 cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
284 cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
285 cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
286
287 /* Hw I2C2 Clock Freq ~100kHz */
288 cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
289 cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
290 cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
291
292 cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
293 core, reset, (u32) CX18_GPIO_RESET_I2C);
294
295 err = i2c_bit_add_bus(&cx->i2c_adap[0]);
296 if (err)
297 goto err;
298 err = i2c_bit_add_bus(&cx->i2c_adap[1]);
299 if (err)
300 goto err_del_bus_0;
301 return 0;
302
303 err_del_bus_0:
304 i2c_del_adapter(&cx->i2c_adap[0]);
305 err:
306 return err;
307}
308
309void exit_cx18_i2c(struct cx18 *cx)
310{
311 int i;
312 CX18_DEBUG_I2C("i2c exit\n");
313 cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4,
314 CX18_REG_I2C_1_WR);
315 cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4,
316 CX18_REG_I2C_2_WR);
317
318 for (i = 0; i < 2; i++) {
319 i2c_del_adapter(&cx->i2c_adap[i]);
320 }
321}
322
323/*
324 Hauppauge HVR1600 should have:
325 32 cx24227
326 98 unknown
327 a0 eeprom
328 c2 tuner
329 e? zilog ir
330 */
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h
new file mode 100644
index 00000000000..bdfd1921e30
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-i2c.h
@@ -0,0 +1,29 @@
1/*
2 * cx18 I2C functions
3 *
4 * Derived from ivtv-i2c.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24int cx18_i2c_register(struct cx18 *cx, unsigned idx);
25struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
26
27/* init + register i2c algo-bit adapter */
28int init_cx18_i2c(struct cx18 *cx);
29void exit_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
new file mode 100644
index 00000000000..49b9dbd0624
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-io.c
@@ -0,0 +1,97 @@
1/*
2 * cx18 driver PCI memory mapped IO access routines
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#include "cx18-driver.h"
24#include "cx18-io.h"
25#include "cx18-irq.h"
26
27void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
28{
29 u8 __iomem *dst = addr;
30 u16 val2 = val | (val << 8);
31 u32 val4 = val2 | (val2 << 16);
32
33 /* Align writes on the CX23418's addresses */
34 if ((count > 0) && ((unsigned long)dst & 1)) {
35 cx18_writeb(cx, (u8) val, dst);
36 count--;
37 dst++;
38 }
39 if ((count > 1) && ((unsigned long)dst & 2)) {
40 cx18_writew(cx, val2, dst);
41 count -= 2;
42 dst += 2;
43 }
44 while (count > 3) {
45 cx18_writel(cx, val4, dst);
46 count -= 4;
47 dst += 4;
48 }
49 if (count > 1) {
50 cx18_writew(cx, val2, dst);
51 count -= 2;
52 dst += 2;
53 }
54 if (count > 0)
55 cx18_writeb(cx, (u8) val, dst);
56}
57
58void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
59{
60 cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val);
61 cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | val;
62 cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
63}
64
65void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
66{
67 cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) & ~val;
68 cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
69}
70
71void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
72{
73 cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val);
74 cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | val;
75 cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
76}
77
78void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
79{
80 cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) & ~val;
81 cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
82}
83
84void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val)
85{
86 u32 r;
87 r = cx18_read_reg(cx, SW2_INT_ENABLE_CPU);
88 cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_CPU);
89}
90
91void cx18_setup_page(struct cx18 *cx, u32 addr)
92{
93 u32 val;
94 val = cx18_read_reg(cx, 0xD000F8);
95 val = (val & ~0x1f00) | ((addr >> 17) & 0x1f00);
96 cx18_write_reg(cx, val, 0xD000F8);
97}
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
new file mode 100644
index 00000000000..18974d886cf
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-io.h
@@ -0,0 +1,191 @@
1/*
2 * cx18 driver PCI memory mapped IO access routines
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#ifndef CX18_IO_H
24#define CX18_IO_H
25
26#include "cx18-driver.h"
27
28/*
29 * Readback and retry of MMIO access for reliability:
30 * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
31 * The implmentation is the fault of Andy Walls <awalls@md.metrocast.net>.
32 *
33 * *write* functions are implied to retry the mmio unless suffixed with _noretry
34 * *read* functions never retry the mmio (it never helps to do so)
35 */
36
37/* Non byteswapping memory mapped IO */
38static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
39{
40 return __raw_readl(addr);
41}
42
43static inline
44void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
45{
46 __raw_writel(val, addr);
47}
48
49static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
50{
51 int i;
52 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
53 cx18_raw_writel_noretry(cx, val, addr);
54 if (val == cx18_raw_readl(cx, addr))
55 break;
56 }
57}
58
59/* Normal memory mapped IO */
60static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
61{
62 return readl(addr);
63}
64
65static inline
66void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
67{
68 writel(val, addr);
69}
70
71static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
72{
73 int i;
74 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
75 cx18_writel_noretry(cx, val, addr);
76 if (val == cx18_readl(cx, addr))
77 break;
78 }
79}
80
81static inline
82void cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
83 u32 eval, u32 mask)
84{
85 int i;
86 u32 r;
87 eval &= mask;
88 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
89 cx18_writel_noretry(cx, val, addr);
90 r = cx18_readl(cx, addr);
91 if (r == 0xffffffff && eval != 0xffffffff)
92 continue;
93 if (eval == (r & mask))
94 break;
95 }
96}
97
98static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
99{
100 return readw(addr);
101}
102
103static inline
104void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr)
105{
106 writew(val, addr);
107}
108
109static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
110{
111 int i;
112 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
113 cx18_writew_noretry(cx, val, addr);
114 if (val == cx18_readw(cx, addr))
115 break;
116 }
117}
118
119static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
120{
121 return readb(addr);
122}
123
124static inline
125void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr)
126{
127 writeb(val, addr);
128}
129
130static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
131{
132 int i;
133 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
134 cx18_writeb_noretry(cx, val, addr);
135 if (val == cx18_readb(cx, addr))
136 break;
137 }
138}
139
140static inline
141void cx18_memcpy_fromio(struct cx18 *cx, void *to,
142 const void __iomem *from, unsigned int len)
143{
144 memcpy_fromio(to, from, len);
145}
146
147void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
148
149
150/* Access "register" region of CX23418 memory mapped I/O */
151static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg)
152{
153 cx18_writel_noretry(cx, val, cx->reg_mem + reg);
154}
155
156static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
157{
158 cx18_writel(cx, val, cx->reg_mem + reg);
159}
160
161static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
162 u32 eval, u32 mask)
163{
164 cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
165}
166
167static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
168{
169 return cx18_readl(cx, cx->reg_mem + reg);
170}
171
172
173/* Access "encoder memory" region of CX23418 memory mapped I/O */
174static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
175{
176 cx18_writel(cx, val, cx->enc_mem + addr);
177}
178
179static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
180{
181 return cx18_readl(cx, cx->enc_mem + addr);
182}
183
184void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
185void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
186void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
187void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
188void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val);
189void cx18_setup_page(struct cx18 *cx, u32 addr);
190
191#endif /* CX18_IO_H */
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
new file mode 100644
index 00000000000..afe0a29e720
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -0,0 +1,1212 @@
1/*
2 * cx18 ioctl system call
3 *
4 * Derived from ivtv-ioctl.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-io.h"
27#include "cx18-version.h"
28#include "cx18-mailbox.h"
29#include "cx18-i2c.h"
30#include "cx18-queue.h"
31#include "cx18-fileops.h"
32#include "cx18-vbi.h"
33#include "cx18-audio.h"
34#include "cx18-video.h"
35#include "cx18-streams.h"
36#include "cx18-ioctl.h"
37#include "cx18-gpio.h"
38#include "cx18-controls.h"
39#include "cx18-cards.h"
40#include "cx18-av-core.h"
41#include <media/tveeprom.h>
42#include <media/v4l2-chip-ident.h>
43
44u16 cx18_service2vbi(int type)
45{
46 switch (type) {
47 case V4L2_SLICED_TELETEXT_B:
48 return CX18_SLICED_TYPE_TELETEXT_B;
49 case V4L2_SLICED_CAPTION_525:
50 return CX18_SLICED_TYPE_CAPTION_525;
51 case V4L2_SLICED_WSS_625:
52 return CX18_SLICED_TYPE_WSS_625;
53 case V4L2_SLICED_VPS:
54 return CX18_SLICED_TYPE_VPS;
55 default:
56 return 0;
57 }
58}
59
60/* Check if VBI services are allowed on the (field, line) for the video std */
61static int valid_service_line(int field, int line, int is_pal)
62{
63 return (is_pal && line >= 6 &&
64 ((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
65 (!is_pal && line >= 10 && line < 22);
66}
67
68/*
69 * For a (field, line, std) and inbound potential set of services for that line,
70 * return the first valid service of those passed in the incoming set for that
71 * line in priority order:
72 * CC, VPS, or WSS over TELETEXT for well known lines
73 * TELETEXT, before VPS, before CC, before WSS, for other lines
74 */
75static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
76{
77 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
78 int i;
79
80 set = set & valid_set;
81 if (set == 0 || !valid_service_line(field, line, is_pal))
82 return 0;
83 if (!is_pal) {
84 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
85 return V4L2_SLICED_CAPTION_525;
86 } else {
87 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
88 return V4L2_SLICED_VPS;
89 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
90 return V4L2_SLICED_WSS_625;
91 if (line == 23)
92 return 0;
93 }
94 for (i = 0; i < 32; i++) {
95 if ((1 << i) & set)
96 return 1 << i;
97 }
98 return 0;
99}
100
101/*
102 * Expand the service_set of *fmt into valid service_lines for the std,
103 * and clear the passed in fmt->service_set
104 */
105void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
106{
107 u16 set = fmt->service_set;
108 int f, l;
109
110 fmt->service_set = 0;
111 for (f = 0; f < 2; f++) {
112 for (l = 0; l < 24; l++)
113 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
114 }
115}
116
117/*
118 * Sanitize the service_lines in *fmt per the video std, and return 1
119 * if any service_line is left as valid after santization
120 */
121static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
122{
123 int f, l;
124 u16 set = 0;
125
126 for (f = 0; f < 2; f++) {
127 for (l = 0; l < 24; l++) {
128 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
129 set |= fmt->service_lines[f][l];
130 }
131 }
132 return set != 0;
133}
134
135/* Compute the service_set from the assumed valid service_lines of *fmt */
136u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
137{
138 int f, l;
139 u16 set = 0;
140
141 for (f = 0; f < 2; f++) {
142 for (l = 0; l < 24; l++)
143 set |= fmt->service_lines[f][l];
144 }
145 return set;
146}
147
148static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
149 struct v4l2_format *fmt)
150{
151 struct cx18_open_id *id = fh2id(fh);
152 struct cx18 *cx = id->cx;
153 struct cx18_stream *s = &cx->streams[id->type];
154 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
155
156 pixfmt->width = cx->cxhdl.width;
157 pixfmt->height = cx->cxhdl.height;
158 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
159 pixfmt->field = V4L2_FIELD_INTERLACED;
160 pixfmt->priv = 0;
161 if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
162 pixfmt->pixelformat = s->pixelformat;
163 /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
164 UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
165 if (s->pixelformat == V4L2_PIX_FMT_HM12)
166 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
167 else
168 pixfmt->sizeimage = pixfmt->height * 720 * 2;
169 pixfmt->bytesperline = 720;
170 } else {
171 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
172 pixfmt->sizeimage = 128 * 1024;
173 pixfmt->bytesperline = 0;
174 }
175 return 0;
176}
177
178static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
179 struct v4l2_format *fmt)
180{
181 struct cx18 *cx = fh2id(fh)->cx;
182 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
183
184 vbifmt->sampling_rate = 27000000;
185 vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
186 vbifmt->samples_per_line = vbi_active_samples - 4;
187 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
188 vbifmt->start[0] = cx->vbi.start[0];
189 vbifmt->start[1] = cx->vbi.start[1];
190 vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
191 vbifmt->flags = 0;
192 vbifmt->reserved[0] = 0;
193 vbifmt->reserved[1] = 0;
194 return 0;
195}
196
197static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
198 struct v4l2_format *fmt)
199{
200 struct cx18 *cx = fh2id(fh)->cx;
201 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
202
203 /* sane, V4L2 spec compliant, defaults */
204 vbifmt->reserved[0] = 0;
205 vbifmt->reserved[1] = 0;
206 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
207 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
208 vbifmt->service_set = 0;
209
210 /*
211 * Fetch the configured service_lines and total service_set from the
212 * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
213 * fmt->fmt.sliced under valid calling conditions
214 */
215 if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
216 return -EINVAL;
217
218 /* Ensure V4L2 spec compliant output */
219 vbifmt->reserved[0] = 0;
220 vbifmt->reserved[1] = 0;
221 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
222 vbifmt->service_set = cx18_get_service_set(vbifmt);
223 return 0;
224}
225
226static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
227 struct v4l2_format *fmt)
228{
229 struct cx18_open_id *id = fh2id(fh);
230 struct cx18 *cx = id->cx;
231 int w = fmt->fmt.pix.width;
232 int h = fmt->fmt.pix.height;
233 int min_h = 2;
234
235 w = min(w, 720);
236 w = max(w, 2);
237 if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
238 /* YUV height must be a multiple of 32 */
239 h &= ~0x1f;
240 min_h = 32;
241 }
242 h = min(h, cx->is_50hz ? 576 : 480);
243 h = max(h, min_h);
244
245 fmt->fmt.pix.width = w;
246 fmt->fmt.pix.height = h;
247 return 0;
248}
249
250static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
251 struct v4l2_format *fmt)
252{
253 return cx18_g_fmt_vbi_cap(file, fh, fmt);
254}
255
256static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
257 struct v4l2_format *fmt)
258{
259 struct cx18 *cx = fh2id(fh)->cx;
260 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
261
262 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
263 vbifmt->reserved[0] = 0;
264 vbifmt->reserved[1] = 0;
265
266 /* If given a service set, expand it validly & clear passed in set */
267 if (vbifmt->service_set)
268 cx18_expand_service_set(vbifmt, cx->is_50hz);
269 /* Sanitize the service_lines, and compute the new set if any valid */
270 if (check_service_set(vbifmt, cx->is_50hz))
271 vbifmt->service_set = cx18_get_service_set(vbifmt);
272 return 0;
273}
274
275static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
276 struct v4l2_format *fmt)
277{
278 struct cx18_open_id *id = fh2id(fh);
279 struct cx18 *cx = id->cx;
280 struct v4l2_mbus_framefmt mbus_fmt;
281 struct cx18_stream *s = &cx->streams[id->type];
282 int ret;
283 int w, h;
284
285 ret = cx18_try_fmt_vid_cap(file, fh, fmt);
286 if (ret)
287 return ret;
288 w = fmt->fmt.pix.width;
289 h = fmt->fmt.pix.height;
290
291 if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
292 s->pixelformat == fmt->fmt.pix.pixelformat)
293 return 0;
294
295 if (atomic_read(&cx->ana_capturing) > 0)
296 return -EBUSY;
297
298 s->pixelformat = fmt->fmt.pix.pixelformat;
299
300 mbus_fmt.width = cx->cxhdl.width = w;
301 mbus_fmt.height = cx->cxhdl.height = h;
302 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
303 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
304 return cx18_g_fmt_vid_cap(file, fh, fmt);
305}
306
307static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
308 struct v4l2_format *fmt)
309{
310 struct cx18_open_id *id = fh2id(fh);
311 struct cx18 *cx = id->cx;
312 int ret;
313
314 /*
315 * Changing the Encoder's Raw VBI parameters won't have any effect
316 * if any analog capture is ongoing
317 */
318 if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
319 return -EBUSY;
320
321 /*
322 * Set the digitizer registers for raw active VBI.
323 * Note cx18_av_vbi_wipes out a lot of the passed in fmt under valid
324 * calling conditions
325 */
326 ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi);
327 if (ret)
328 return ret;
329
330 /* Store our new v4l2 (non-)sliced VBI state */
331 cx->vbi.sliced_in->service_set = 0;
332 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
333
334 return cx18_g_fmt_vbi_cap(file, fh, fmt);
335}
336
337static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
338 struct v4l2_format *fmt)
339{
340 struct cx18_open_id *id = fh2id(fh);
341 struct cx18 *cx = id->cx;
342 int ret;
343 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
344
345 cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
346
347 /*
348 * Changing the Encoder's Raw VBI parameters won't have any effect
349 * if any analog capture is ongoing
350 */
351 if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
352 return -EBUSY;
353
354 /*
355 * Set the service_lines requested in the digitizer/slicer registers.
356 * Note, cx18_av_vbi() wipes some "impossible" service lines in the
357 * passed in fmt->fmt.sliced under valid calling conditions
358 */
359 ret = v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &fmt->fmt.sliced);
360 if (ret)
361 return ret;
362 /* Store our current v4l2 sliced VBI settings */
363 cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
364 memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
365 return 0;
366}
367
368static int cx18_g_chip_ident(struct file *file, void *fh,
369 struct v4l2_dbg_chip_ident *chip)
370{
371 struct cx18 *cx = fh2id(fh)->cx;
372 int err = 0;
373
374 chip->ident = V4L2_IDENT_NONE;
375 chip->revision = 0;
376 switch (chip->match.type) {
377 case V4L2_CHIP_MATCH_HOST:
378 switch (chip->match.addr) {
379 case 0:
380 chip->ident = V4L2_IDENT_CX23418;
381 chip->revision = cx18_read_reg(cx, 0xC72028);
382 break;
383 case 1:
384 /*
385 * The A/V decoder is always present, but in the rare
386 * case that the card doesn't have analog, we don't
387 * use it. We find it w/o using the cx->sd_av pointer
388 */
389 cx18_call_hw(cx, CX18_HW_418_AV,
390 core, g_chip_ident, chip);
391 break;
392 default:
393 /*
394 * Could return ident = V4L2_IDENT_UNKNOWN if we had
395 * other host chips at higher addresses, but we don't
396 */
397 err = -EINVAL; /* per V4L2 spec */
398 break;
399 }
400 break;
401 case V4L2_CHIP_MATCH_I2C_DRIVER:
402 /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
403 cx18_call_all(cx, core, g_chip_ident, chip);
404 break;
405 case V4L2_CHIP_MATCH_I2C_ADDR:
406 /*
407 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
408 * to look if a chip is at the address with no driver. That's a
409 * dangerous thing to do with EEPROMs anyway.
410 */
411 cx18_call_all(cx, core, g_chip_ident, chip);
412 break;
413 default:
414 err = -EINVAL;
415 break;
416 }
417 return err;
418}
419
420#ifdef CONFIG_VIDEO_ADV_DEBUG
421static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
422{
423 struct v4l2_dbg_register *regs = arg;
424
425 if (!capable(CAP_SYS_ADMIN))
426 return -EPERM;
427 if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
428 return -EINVAL;
429
430 regs->size = 4;
431 if (cmd == VIDIOC_DBG_S_REGISTER)
432 cx18_write_enc(cx, regs->val, regs->reg);
433 else
434 regs->val = cx18_read_enc(cx, regs->reg);
435 return 0;
436}
437
438static int cx18_g_register(struct file *file, void *fh,
439 struct v4l2_dbg_register *reg)
440{
441 struct cx18 *cx = fh2id(fh)->cx;
442
443 if (v4l2_chip_match_host(&reg->match))
444 return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
445 /* FIXME - errors shouldn't be ignored */
446 cx18_call_all(cx, core, g_register, reg);
447 return 0;
448}
449
450static int cx18_s_register(struct file *file, void *fh,
451 struct v4l2_dbg_register *reg)
452{
453 struct cx18 *cx = fh2id(fh)->cx;
454
455 if (v4l2_chip_match_host(&reg->match))
456 return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
457 /* FIXME - errors shouldn't be ignored */
458 cx18_call_all(cx, core, s_register, reg);
459 return 0;
460}
461#endif
462
463static int cx18_querycap(struct file *file, void *fh,
464 struct v4l2_capability *vcap)
465{
466 struct cx18 *cx = fh2id(fh)->cx;
467
468 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
469 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
470 snprintf(vcap->bus_info, sizeof(vcap->bus_info),
471 "PCI:%s", pci_name(cx->pci_dev));
472 vcap->capabilities = cx->v4l2_cap; /* capabilities */
473 return 0;
474}
475
476static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
477{
478 struct cx18 *cx = fh2id(fh)->cx;
479
480 return cx18_get_audio_input(cx, vin->index, vin);
481}
482
483static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
484{
485 struct cx18 *cx = fh2id(fh)->cx;
486
487 vin->index = cx->audio_input;
488 return cx18_get_audio_input(cx, vin->index, vin);
489}
490
491static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
492{
493 struct cx18 *cx = fh2id(fh)->cx;
494
495 if (vout->index >= cx->nof_audio_inputs)
496 return -EINVAL;
497 cx->audio_input = vout->index;
498 cx18_audio_set_io(cx);
499 return 0;
500}
501
502static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
503{
504 struct cx18 *cx = fh2id(fh)->cx;
505
506 /* set it to defaults from our table */
507 return cx18_get_input(cx, vin->index, vin);
508}
509
510static int cx18_cropcap(struct file *file, void *fh,
511 struct v4l2_cropcap *cropcap)
512{
513 struct cx18 *cx = fh2id(fh)->cx;
514
515 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
516 return -EINVAL;
517 cropcap->bounds.top = cropcap->bounds.left = 0;
518 cropcap->bounds.width = 720;
519 cropcap->bounds.height = cx->is_50hz ? 576 : 480;
520 cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
521 cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
522 cropcap->defrect = cropcap->bounds;
523 return 0;
524}
525
526static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
527{
528 struct cx18_open_id *id = fh2id(fh);
529 struct cx18 *cx = id->cx;
530
531 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
532 return -EINVAL;
533 CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
534 return -EINVAL;
535}
536
537static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
538{
539 struct cx18 *cx = fh2id(fh)->cx;
540
541 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
542 return -EINVAL;
543 CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
544 return -EINVAL;
545}
546
547static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
548 struct v4l2_fmtdesc *fmt)
549{
550 static const struct v4l2_fmtdesc formats[] = {
551 { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
552 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
553 },
554 { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
555 "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
556 },
557 { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
558 "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
559 },
560 };
561
562 if (fmt->index > ARRAY_SIZE(formats) - 1)
563 return -EINVAL;
564 *fmt = formats[fmt->index];
565 return 0;
566}
567
568static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
569{
570 struct cx18 *cx = fh2id(fh)->cx;
571
572 *i = cx->active_input;
573 return 0;
574}
575
576int cx18_s_input(struct file *file, void *fh, unsigned int inp)
577{
578 struct cx18_open_id *id = fh2id(fh);
579 struct cx18 *cx = id->cx;
580
581 if (inp >= cx->nof_inputs)
582 return -EINVAL;
583
584 if (inp == cx->active_input) {
585 CX18_DEBUG_INFO("Input unchanged\n");
586 return 0;
587 }
588
589 CX18_DEBUG_INFO("Changing input from %d to %d\n",
590 cx->active_input, inp);
591
592 cx->active_input = inp;
593 /* Set the audio input to whatever is appropriate for the input type. */
594 cx->audio_input = cx->card->video_inputs[inp].audio_index;
595
596 /* prevent others from messing with the streams until
597 we're finished changing inputs. */
598 cx18_mute(cx);
599 cx18_video_set_io(cx);
600 cx18_audio_set_io(cx);
601 cx18_unmute(cx);
602 return 0;
603}
604
605static int cx18_g_frequency(struct file *file, void *fh,
606 struct v4l2_frequency *vf)
607{
608 struct cx18 *cx = fh2id(fh)->cx;
609
610 if (vf->tuner != 0)
611 return -EINVAL;
612
613 cx18_call_all(cx, tuner, g_frequency, vf);
614 return 0;
615}
616
617int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
618{
619 struct cx18_open_id *id = fh2id(fh);
620 struct cx18 *cx = id->cx;
621
622 if (vf->tuner != 0)
623 return -EINVAL;
624
625 cx18_mute(cx);
626 CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
627 cx18_call_all(cx, tuner, s_frequency, vf);
628 cx18_unmute(cx);
629 return 0;
630}
631
632static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
633{
634 struct cx18 *cx = fh2id(fh)->cx;
635
636 *std = cx->std;
637 return 0;
638}
639
640int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
641{
642 struct cx18_open_id *id = fh2id(fh);
643 struct cx18 *cx = id->cx;
644
645 if ((*std & V4L2_STD_ALL) == 0)
646 return -EINVAL;
647
648 if (*std == cx->std)
649 return 0;
650
651 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
652 atomic_read(&cx->ana_capturing) > 0) {
653 /* Switching standard would turn off the radio or mess
654 with already running streams, prevent that by
655 returning EBUSY. */
656 return -EBUSY;
657 }
658
659 cx->std = *std;
660 cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
661 cx->is_50hz = !cx->is_60hz;
662 cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
663 cx->cxhdl.width = 720;
664 cx->cxhdl.height = cx->is_50hz ? 576 : 480;
665 cx->vbi.count = cx->is_50hz ? 18 : 12;
666 cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
667 cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
668 CX18_DEBUG_INFO("Switching standard to %llx.\n",
669 (unsigned long long) cx->std);
670
671 /* Tuner */
672 cx18_call_all(cx, core, s_std, cx->std);
673 return 0;
674}
675
676static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
677{
678 struct cx18_open_id *id = fh2id(fh);
679 struct cx18 *cx = id->cx;
680
681 if (vt->index != 0)
682 return -EINVAL;
683
684 cx18_call_all(cx, tuner, s_tuner, vt);
685 return 0;
686}
687
688static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
689{
690 struct cx18 *cx = fh2id(fh)->cx;
691
692 if (vt->index != 0)
693 return -EINVAL;
694
695 cx18_call_all(cx, tuner, g_tuner, vt);
696
697 if (vt->type == V4L2_TUNER_RADIO)
698 strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
699 else
700 strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
701 return 0;
702}
703
704static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
705 struct v4l2_sliced_vbi_cap *cap)
706{
707 struct cx18 *cx = fh2id(fh)->cx;
708 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
709 int f, l;
710
711 if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
712 return -EINVAL;
713
714 cap->service_set = 0;
715 for (f = 0; f < 2; f++) {
716 for (l = 0; l < 24; l++) {
717 if (valid_service_line(f, l, cx->is_50hz)) {
718 /*
719 * We can find all v4l2 supported vbi services
720 * for the standard, on a valid line for the std
721 */
722 cap->service_lines[f][l] = set;
723 cap->service_set |= set;
724 } else
725 cap->service_lines[f][l] = 0;
726 }
727 }
728 for (f = 0; f < 3; f++)
729 cap->reserved[f] = 0;
730 return 0;
731}
732
733static int _cx18_process_idx_data(struct cx18_buffer *buf,
734 struct v4l2_enc_idx *idx)
735{
736 int consumed, remaining;
737 struct v4l2_enc_idx_entry *e_idx;
738 struct cx18_enc_idx_entry *e_buf;
739
740 /* Frame type lookup: 1=I, 2=P, 4=B */
741 const int mapping[8] = {
742 -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
743 -1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
744 };
745
746 /*
747 * Assumption here is that a buf holds an integral number of
748 * struct cx18_enc_idx_entry objects and is properly aligned.
749 * This is enforced by the module options on IDX buffer sizes.
750 */
751 remaining = buf->bytesused - buf->readpos;
752 consumed = 0;
753 e_idx = &idx->entry[idx->entries];
754 e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
755
756 while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
757 idx->entries < V4L2_ENC_IDX_ENTRIES) {
758
759 e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
760 | le32_to_cpu(e_buf->offset_low);
761
762 e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
763 | le32_to_cpu(e_buf->pts_low);
764
765 e_idx->length = le32_to_cpu(e_buf->length);
766
767 e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
768
769 e_idx->reserved[0] = 0;
770 e_idx->reserved[1] = 0;
771
772 idx->entries++;
773 e_idx = &idx->entry[idx->entries];
774 e_buf++;
775
776 remaining -= sizeof(struct cx18_enc_idx_entry);
777 consumed += sizeof(struct cx18_enc_idx_entry);
778 }
779
780 /* Swallow any partial entries at the end, if there are any */
781 if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
782 consumed += remaining;
783
784 buf->readpos += consumed;
785 return consumed;
786}
787
788static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
789 struct v4l2_enc_idx *idx)
790{
791 if (s->type != CX18_ENC_STREAM_TYPE_IDX)
792 return -EINVAL;
793
794 if (mdl->curr_buf == NULL)
795 mdl->curr_buf = list_first_entry(&mdl->buf_list,
796 struct cx18_buffer, list);
797
798 if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
799 /*
800 * For some reason we've exhausted the buffers, but the MDL
801 * object still said some data was unread.
802 * Fix that and bail out.
803 */
804 mdl->readpos = mdl->bytesused;
805 return 0;
806 }
807
808 list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
809
810 /* Skip any empty buffers in the MDL */
811 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
812 continue;
813
814 mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
815
816 /* exit when MDL drained or request satisfied */
817 if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
818 mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
819 mdl->readpos >= mdl->bytesused)
820 break;
821 }
822 return 0;
823}
824
825static int cx18_g_enc_index(struct file *file, void *fh,
826 struct v4l2_enc_idx *idx)
827{
828 struct cx18 *cx = fh2id(fh)->cx;
829 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
830 s32 tmp;
831 struct cx18_mdl *mdl;
832
833 if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
834 return -EINVAL;
835
836 /* Compute the best case number of entries we can buffer */
837 tmp = s->buffers -
838 s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
839 if (tmp <= 0)
840 tmp = 1;
841 tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
842
843 /* Fill out the header of the return structure */
844 idx->entries = 0;
845 idx->entries_cap = tmp;
846 memset(idx->reserved, 0, sizeof(idx->reserved));
847
848 /* Pull IDX MDLs and buffers from q_full and populate the entries */
849 do {
850 mdl = cx18_dequeue(s, &s->q_full);
851 if (mdl == NULL) /* No more IDX data right now */
852 break;
853
854 /* Extract the Index entry data from the MDL and buffers */
855 cx18_process_idx_data(s, mdl, idx);
856 if (mdl->readpos < mdl->bytesused) {
857 /* We finished with data remaining, push the MDL back */
858 cx18_push(s, mdl, &s->q_full);
859 break;
860 }
861
862 /* We drained this MDL, schedule it to go to the firmware */
863 cx18_enqueue(s, mdl, &s->q_free);
864
865 } while (idx->entries < V4L2_ENC_IDX_ENTRIES);
866
867 /* Tell the work handler to send free IDX MDLs to the firmware */
868 cx18_stream_load_fw_queue(s);
869 return 0;
870}
871
872static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
873{
874 struct videobuf_queue *q = NULL;
875 struct cx18 *cx = id->cx;
876 struct cx18_stream *s = &cx->streams[id->type];
877
878 switch (s->vb_type) {
879 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
880 q = &s->vbuf_q;
881 break;
882 case V4L2_BUF_TYPE_VBI_CAPTURE:
883 break;
884 default:
885 break;
886 }
887 return q;
888}
889
890static int cx18_streamon(struct file *file, void *priv,
891 enum v4l2_buf_type type)
892{
893 struct cx18_open_id *id = file->private_data;
894 struct cx18 *cx = id->cx;
895 struct cx18_stream *s = &cx->streams[id->type];
896
897 /* Start the hardware only if we're the video device */
898 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
899 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
900 return -EINVAL;
901
902 if (id->type != CX18_ENC_STREAM_TYPE_YUV)
903 return -EINVAL;
904
905 /* Establish a buffer timeout */
906 mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
907
908 return videobuf_streamon(cx18_vb_queue(id));
909}
910
911static int cx18_streamoff(struct file *file, void *priv,
912 enum v4l2_buf_type type)
913{
914 struct cx18_open_id *id = file->private_data;
915 struct cx18 *cx = id->cx;
916 struct cx18_stream *s = &cx->streams[id->type];
917
918 /* Start the hardware only if we're the video device */
919 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
920 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
921 return -EINVAL;
922
923 if (id->type != CX18_ENC_STREAM_TYPE_YUV)
924 return -EINVAL;
925
926 return videobuf_streamoff(cx18_vb_queue(id));
927}
928
929static int cx18_reqbufs(struct file *file, void *priv,
930 struct v4l2_requestbuffers *rb)
931{
932 struct cx18_open_id *id = file->private_data;
933 struct cx18 *cx = id->cx;
934 struct cx18_stream *s = &cx->streams[id->type];
935
936 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
937 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
938 return -EINVAL;
939
940 return videobuf_reqbufs(cx18_vb_queue(id), rb);
941}
942
943static int cx18_querybuf(struct file *file, void *priv,
944 struct v4l2_buffer *b)
945{
946 struct cx18_open_id *id = file->private_data;
947 struct cx18 *cx = id->cx;
948 struct cx18_stream *s = &cx->streams[id->type];
949
950 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
951 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
952 return -EINVAL;
953
954 return videobuf_querybuf(cx18_vb_queue(id), b);
955}
956
957static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
958{
959 struct cx18_open_id *id = file->private_data;
960 struct cx18 *cx = id->cx;
961 struct cx18_stream *s = &cx->streams[id->type];
962
963 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
964 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
965 return -EINVAL;
966
967 return videobuf_qbuf(cx18_vb_queue(id), b);
968}
969
970static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
971{
972 struct cx18_open_id *id = file->private_data;
973 struct cx18 *cx = id->cx;
974 struct cx18_stream *s = &cx->streams[id->type];
975
976 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
977 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
978 return -EINVAL;
979
980 return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
981}
982
983static int cx18_encoder_cmd(struct file *file, void *fh,
984 struct v4l2_encoder_cmd *enc)
985{
986 struct cx18_open_id *id = fh2id(fh);
987 struct cx18 *cx = id->cx;
988 u32 h;
989
990 switch (enc->cmd) {
991 case V4L2_ENC_CMD_START:
992 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
993 enc->flags = 0;
994 return cx18_start_capture(id);
995
996 case V4L2_ENC_CMD_STOP:
997 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
998 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
999 cx18_stop_capture(id,
1000 enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1001 break;
1002
1003 case V4L2_ENC_CMD_PAUSE:
1004 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1005 enc->flags = 0;
1006 if (!atomic_read(&cx->ana_capturing))
1007 return -EPERM;
1008 if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
1009 return 0;
1010 h = cx18_find_handle(cx);
1011 if (h == CX18_INVALID_TASK_HANDLE) {
1012 CX18_ERR("Can't find valid task handle for "
1013 "V4L2_ENC_CMD_PAUSE\n");
1014 return -EBADFD;
1015 }
1016 cx18_mute(cx);
1017 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
1018 break;
1019
1020 case V4L2_ENC_CMD_RESUME:
1021 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1022 enc->flags = 0;
1023 if (!atomic_read(&cx->ana_capturing))
1024 return -EPERM;
1025 if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
1026 return 0;
1027 h = cx18_find_handle(cx);
1028 if (h == CX18_INVALID_TASK_HANDLE) {
1029 CX18_ERR("Can't find valid task handle for "
1030 "V4L2_ENC_CMD_RESUME\n");
1031 return -EBADFD;
1032 }
1033 cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
1034 cx18_unmute(cx);
1035 break;
1036
1037 default:
1038 CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1039 return -EINVAL;
1040 }
1041 return 0;
1042}
1043
1044static int cx18_try_encoder_cmd(struct file *file, void *fh,
1045 struct v4l2_encoder_cmd *enc)
1046{
1047 struct cx18 *cx = fh2id(fh)->cx;
1048
1049 switch (enc->cmd) {
1050 case V4L2_ENC_CMD_START:
1051 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1052 enc->flags = 0;
1053 break;
1054
1055 case V4L2_ENC_CMD_STOP:
1056 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1057 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1058 break;
1059
1060 case V4L2_ENC_CMD_PAUSE:
1061 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1062 enc->flags = 0;
1063 break;
1064
1065 case V4L2_ENC_CMD_RESUME:
1066 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1067 enc->flags = 0;
1068 break;
1069
1070 default:
1071 CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1072 return -EINVAL;
1073 }
1074 return 0;
1075}
1076
1077static int cx18_log_status(struct file *file, void *fh)
1078{
1079 struct cx18 *cx = fh2id(fh)->cx;
1080 struct v4l2_input vidin;
1081 struct v4l2_audio audin;
1082 int i;
1083
1084 CX18_INFO("================= START STATUS CARD #%d "
1085 "=================\n", cx->instance);
1086 CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
1087 if (cx->hw_flags & CX18_HW_TVEEPROM) {
1088 struct tveeprom tv;
1089
1090 cx18_read_eeprom(cx, &tv);
1091 }
1092 cx18_call_all(cx, core, log_status);
1093 cx18_get_input(cx, cx->active_input, &vidin);
1094 cx18_get_audio_input(cx, cx->audio_input, &audin);
1095 CX18_INFO("Video Input: %s\n", vidin.name);
1096 CX18_INFO("Audio Input: %s\n", audin.name);
1097 mutex_lock(&cx->gpio_lock);
1098 CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
1099 cx->gpio_dir, cx->gpio_val);
1100 mutex_unlock(&cx->gpio_lock);
1101 CX18_INFO("Tuner: %s\n",
1102 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
1103 v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
1104 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
1105 for (i = 0; i < CX18_MAX_STREAMS; i++) {
1106 struct cx18_stream *s = &cx->streams[i];
1107
1108 if (s->video_dev == NULL || s->buffers == 0)
1109 continue;
1110 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
1111 s->name, s->s_flags,
1112 atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
1113 / s->buffers,
1114 (s->buffers * s->buf_size) / 1024, s->buffers);
1115 }
1116 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
1117 (long long)cx->mpg_data_received,
1118 (long long)cx->vbi_data_inserted);
1119 CX18_INFO("================== END STATUS CARD #%d "
1120 "==================\n", cx->instance);
1121 return 0;
1122}
1123
1124static long cx18_default(struct file *file, void *fh, bool valid_prio,
1125 int cmd, void *arg)
1126{
1127 struct cx18 *cx = fh2id(fh)->cx;
1128
1129 switch (cmd) {
1130 case VIDIOC_INT_RESET: {
1131 u32 val = *(u32 *)arg;
1132
1133 if ((val == 0) || (val & 0x01))
1134 cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
1135 (u32) CX18_GPIO_RESET_Z8F0811);
1136 break;
1137 }
1138
1139 default:
1140 return -EINVAL;
1141 }
1142 return 0;
1143}
1144
1145long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
1146 unsigned long arg)
1147{
1148 struct video_device *vfd = video_devdata(filp);
1149 struct cx18_open_id *id = file2id(filp);
1150 struct cx18 *cx = id->cx;
1151 long res;
1152
1153 mutex_lock(&cx->serialize_lock);
1154
1155 if (cx18_debug & CX18_DBGFLG_IOCTL)
1156 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1157 res = video_ioctl2(filp, cmd, arg);
1158 vfd->debug = 0;
1159 mutex_unlock(&cx->serialize_lock);
1160 return res;
1161}
1162
1163static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1164 .vidioc_querycap = cx18_querycap,
1165 .vidioc_s_audio = cx18_s_audio,
1166 .vidioc_g_audio = cx18_g_audio,
1167 .vidioc_enumaudio = cx18_enumaudio,
1168 .vidioc_enum_input = cx18_enum_input,
1169 .vidioc_cropcap = cx18_cropcap,
1170 .vidioc_s_crop = cx18_s_crop,
1171 .vidioc_g_crop = cx18_g_crop,
1172 .vidioc_g_input = cx18_g_input,
1173 .vidioc_s_input = cx18_s_input,
1174 .vidioc_g_frequency = cx18_g_frequency,
1175 .vidioc_s_frequency = cx18_s_frequency,
1176 .vidioc_s_tuner = cx18_s_tuner,
1177 .vidioc_g_tuner = cx18_g_tuner,
1178 .vidioc_g_enc_index = cx18_g_enc_index,
1179 .vidioc_g_std = cx18_g_std,
1180 .vidioc_s_std = cx18_s_std,
1181 .vidioc_log_status = cx18_log_status,
1182 .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap,
1183 .vidioc_encoder_cmd = cx18_encoder_cmd,
1184 .vidioc_try_encoder_cmd = cx18_try_encoder_cmd,
1185 .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap,
1186 .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap,
1187 .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap,
1188 .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap,
1189 .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap,
1190 .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap,
1191 .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap,
1192 .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap,
1193 .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap,
1194 .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap,
1195 .vidioc_g_chip_ident = cx18_g_chip_ident,
1196#ifdef CONFIG_VIDEO_ADV_DEBUG
1197 .vidioc_g_register = cx18_g_register,
1198 .vidioc_s_register = cx18_s_register,
1199#endif
1200 .vidioc_default = cx18_default,
1201 .vidioc_streamon = cx18_streamon,
1202 .vidioc_streamoff = cx18_streamoff,
1203 .vidioc_reqbufs = cx18_reqbufs,
1204 .vidioc_querybuf = cx18_querybuf,
1205 .vidioc_qbuf = cx18_qbuf,
1206 .vidioc_dqbuf = cx18_dqbuf,
1207};
1208
1209void cx18_set_funcs(struct video_device *vdev)
1210{
1211 vdev->ioctl_ops = &cx18_ioctl_ops;
1212}
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h
new file mode 100644
index 00000000000..dcb2559ad52
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-ioctl.h
@@ -0,0 +1,33 @@
1/*
2 * cx18 ioctl system call
3 *
4 * Derived from ivtv-ioctl.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25u16 cx18_service2vbi(int type);
26void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
27u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);
28void cx18_set_funcs(struct video_device *vdev);
29int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std);
30int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
31int cx18_s_input(struct file *file, void *fh, unsigned int inp);
32long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
33 unsigned long arg);
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
new file mode 100644
index 00000000000..80edfe93a3d
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -0,0 +1,81 @@
1/*
2 * cx18 interrupt handling
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#include "cx18-driver.h"
24#include "cx18-io.h"
25#include "cx18-irq.h"
26#include "cx18-mailbox.h"
27#include "cx18-scb.h"
28
29static void xpu_ack(struct cx18 *cx, u32 sw2)
30{
31 if (sw2 & IRQ_CPU_TO_EPU_ACK)
32 wake_up(&cx->mb_cpu_waitq);
33 if (sw2 & IRQ_APU_TO_EPU_ACK)
34 wake_up(&cx->mb_apu_waitq);
35}
36
37static void epu_cmd(struct cx18 *cx, u32 sw1)
38{
39 if (sw1 & IRQ_CPU_TO_EPU)
40 cx18_api_epu_cmd_irq(cx, CPU);
41 if (sw1 & IRQ_APU_TO_EPU)
42 cx18_api_epu_cmd_irq(cx, APU);
43}
44
45irqreturn_t cx18_irq_handler(int irq, void *dev_id)
46{
47 struct cx18 *cx = (struct cx18 *)dev_id;
48 u32 sw1, sw2, hw2;
49
50 sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & cx->sw1_irq_mask;
51 sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & cx->sw2_irq_mask;
52 hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & cx->hw2_irq_mask;
53
54 if (sw1)
55 cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1);
56 if (sw2)
57 cx18_write_reg_expect(cx, sw2, SW2_INT_STATUS, ~sw2, sw2);
58 if (hw2)
59 cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2);
60
61 if (sw1 || sw2 || hw2)
62 CX18_DEBUG_HI_IRQ("received interrupts "
63 "SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
64
65 /*
66 * SW1 responses have to happen first. The sending XPU times out the
67 * incoming mailboxes on us rather rapidly.
68 */
69 if (sw1)
70 epu_cmd(cx, sw1);
71
72 /* To do: interrupt-based I2C handling
73 if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) {
74 }
75 */
76
77 if (sw2)
78 xpu_ack(cx, sw2);
79
80 return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE;
81}
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h
new file mode 100644
index 00000000000..30e7eaf8cb5
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-irq.h
@@ -0,0 +1,35 @@
1/*
2 * cx18 interrupt handling
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#define HW2_I2C1_INT (1 << 22)
24#define HW2_I2C2_INT (1 << 23)
25#define HW2_INT_CLR_STATUS 0xc730c4
26#define HW2_INT_MASK5_PCI 0xc730e4
27#define SW1_INT_SET 0xc73100
28#define SW1_INT_STATUS 0xc73104
29#define SW1_INT_ENABLE_PCI 0xc7311c
30#define SW2_INT_SET 0xc73140
31#define SW2_INT_STATUS 0xc73144
32#define SW2_INT_ENABLE_CPU 0xc73158
33#define SW2_INT_ENABLE_PCI 0xc7315c
34
35irqreturn_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
new file mode 100644
index 00000000000..c07191e09fc
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -0,0 +1,869 @@
1/*
2 * cx18 mailbox functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#include <stdarg.h>
24
25#include "cx18-driver.h"
26#include "cx18-io.h"
27#include "cx18-scb.h"
28#include "cx18-irq.h"
29#include "cx18-mailbox.h"
30#include "cx18-queue.h"
31#include "cx18-streams.h"
32#include "cx18-alsa-pcm.h" /* FIXME make configurable */
33
34static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" };
35
36#define API_FAST (1 << 2) /* Short timeout */
37#define API_SLOW (1 << 3) /* Additional 300ms timeout */
38
39struct cx18_api_info {
40 u32 cmd;
41 u8 flags; /* Flags, see above */
42 u8 rpu; /* Processing unit */
43 const char *name; /* The name of the command */
44};
45
46#define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
47
48static const struct cx18_api_info api_info[] = {
49 /* MPEG encoder API */
50 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
51 API_ENTRY(CPU, CX18_EPU_DEBUG, 0),
52 API_ENTRY(CPU, CX18_CREATE_TASK, 0),
53 API_ENTRY(CPU, CX18_DESTROY_TASK, 0),
54 API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW),
55 API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW),
56 API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0),
57 API_ENTRY(CPU, CX18_CPU_CAPTURE_RESUME, 0),
58 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
59 API_ENTRY(CPU, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 0),
60 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_IN, 0),
61 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RATE, 0),
62 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RESOLUTION, 0),
63 API_ENTRY(CPU, CX18_CPU_SET_FILTER_PARAM, 0),
64 API_ENTRY(CPU, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 0),
65 API_ENTRY(CPU, CX18_CPU_SET_MEDIAN_CORING, 0),
66 API_ENTRY(CPU, CX18_CPU_SET_INDEXTABLE, 0),
67 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PARAMETERS, 0),
68 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_MUTE, 0),
69 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_MUTE, 0),
70 API_ENTRY(CPU, CX18_CPU_SET_MISC_PARAMETERS, 0),
71 API_ENTRY(CPU, CX18_CPU_SET_RAW_VBI_PARAM, API_SLOW),
72 API_ENTRY(CPU, CX18_CPU_SET_CAPTURE_LINE_NO, 0),
73 API_ENTRY(CPU, CX18_CPU_SET_COPYRIGHT, 0),
74 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PID, 0),
75 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_PID, 0),
76 API_ENTRY(CPU, CX18_CPU_SET_VER_CROP_LINE, 0),
77 API_ENTRY(CPU, CX18_CPU_SET_GOP_STRUCTURE, 0),
78 API_ENTRY(CPU, CX18_CPU_SET_SCENE_CHANGE_DETECTION, 0),
79 API_ENTRY(CPU, CX18_CPU_SET_ASPECT_RATIO, 0),
80 API_ENTRY(CPU, CX18_CPU_SET_SKIP_INPUT_FRAME, 0),
81 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0),
82 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0),
83 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
84 API_ENTRY(CPU, CX18_CPU_SET_VFC_PARAM, 0),
85 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
86 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
87 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
88 API_ENTRY(APU, CX18_APU_START, 0),
89 API_ENTRY(APU, CX18_APU_STOP, 0),
90 API_ENTRY(APU, CX18_APU_RESETAI, 0),
91 API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0),
92 API_ENTRY(0, 0, 0),
93};
94
95static const struct cx18_api_info *find_api_info(u32 cmd)
96{
97 int i;
98
99 for (i = 0; api_info[i].cmd; i++)
100 if (api_info[i].cmd == cmd)
101 return &api_info[i];
102 return NULL;
103}
104
105/* Call with buf of n*11+1 bytes */
106static char *u32arr2hex(u32 data[], int n, char *buf)
107{
108 char *p;
109 int i;
110
111 for (i = 0, p = buf; i < n; i++, p += 11) {
112 /* kernel snprintf() appends '\0' always */
113 snprintf(p, 12, " %#010x", data[i]);
114 }
115 *p = '\0';
116 return buf;
117}
118
119static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
120{
121 char argstr[MAX_MB_ARGUMENTS*11+1];
122
123 if (!(cx18_debug & CX18_DBGFLG_API))
124 return;
125
126 CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s"
127 "\n", name, mb->request, mb->ack, mb->cmd, mb->error,
128 u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr));
129}
130
131
132/*
133 * Functions that run in a work_queue work handling context
134 */
135
136static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
137{
138 struct cx18_buffer *buf;
139
140 if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0)
141 return;
142
143 /* We ignore mdl and buf readpos accounting here - it doesn't matter */
144
145 /* The likely case */
146 if (list_is_singular(&mdl->buf_list)) {
147 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
148 list);
149 if (buf->bytesused)
150 dvb_dmx_swfilter(&s->dvb->demux,
151 buf->buf, buf->bytesused);
152 return;
153 }
154
155 list_for_each_entry(buf, &mdl->buf_list, list) {
156 if (buf->bytesused == 0)
157 break;
158 dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused);
159 }
160}
161
162static void cx18_mdl_send_to_videobuf(struct cx18_stream *s,
163 struct cx18_mdl *mdl)
164{
165 struct cx18_videobuf_buffer *vb_buf;
166 struct cx18_buffer *buf;
167 u8 *p;
168 u32 offset = 0;
169 int dispatch = 0;
170
171 if (mdl->bytesused == 0)
172 return;
173
174 /* Acquire a videobuf buffer, clone to and and release it */
175 spin_lock(&s->vb_lock);
176 if (list_empty(&s->vb_capture))
177 goto out;
178
179 vb_buf = list_first_entry(&s->vb_capture, struct cx18_videobuf_buffer,
180 vb.queue);
181
182 p = videobuf_to_vmalloc(&vb_buf->vb);
183 if (!p)
184 goto out;
185
186 offset = vb_buf->bytes_used;
187 list_for_each_entry(buf, &mdl->buf_list, list) {
188 if (buf->bytesused == 0)
189 break;
190
191 if ((offset + buf->bytesused) <= vb_buf->vb.bsize) {
192 memcpy(p + offset, buf->buf, buf->bytesused);
193 offset += buf->bytesused;
194 vb_buf->bytes_used += buf->bytesused;
195 }
196 }
197
198 /* If we've filled the buffer as per the callers res then dispatch it */
199 if (vb_buf->bytes_used >= (vb_buf->vb.width * vb_buf->vb.height * 2)) {
200 dispatch = 1;
201 vb_buf->bytes_used = 0;
202 }
203
204 if (dispatch) {
205 vb_buf->vb.ts = ktime_to_timeval(ktime_get());
206 list_del(&vb_buf->vb.queue);
207 vb_buf->vb.state = VIDEOBUF_DONE;
208 wake_up(&vb_buf->vb.done);
209 }
210
211 mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
212
213out:
214 spin_unlock(&s->vb_lock);
215}
216
217static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
218 struct cx18_mdl *mdl)
219{
220 struct cx18_buffer *buf;
221
222 if (mdl->bytesused == 0)
223 return;
224
225 /* We ignore mdl and buf readpos accounting here - it doesn't matter */
226
227 /* The likely case */
228 if (list_is_singular(&mdl->buf_list)) {
229 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
230 list);
231 if (buf->bytesused)
232 cx->pcm_announce_callback(cx->alsa, buf->buf,
233 buf->bytesused);
234 return;
235 }
236
237 list_for_each_entry(buf, &mdl->buf_list, list) {
238 if (buf->bytesused == 0)
239 break;
240 cx->pcm_announce_callback(cx->alsa, buf->buf, buf->bytesused);
241 }
242}
243
244static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
245{
246 u32 handle, mdl_ack_count, id;
247 struct cx18_mailbox *mb;
248 struct cx18_mdl_ack *mdl_ack;
249 struct cx18_stream *s;
250 struct cx18_mdl *mdl;
251 int i;
252
253 mb = &order->mb;
254 handle = mb->args[0];
255 s = cx18_handle_to_stream(cx, handle);
256
257 if (s == NULL) {
258 CX18_WARN("Got DMA done notification for unknown/inactive"
259 " handle %d, %s mailbox seq no %d\n", handle,
260 (order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) ?
261 "stale" : "good", mb->request);
262 return;
263 }
264
265 mdl_ack_count = mb->args[2];
266 mdl_ack = order->mdl_ack;
267 for (i = 0; i < mdl_ack_count; i++, mdl_ack++) {
268 id = mdl_ack->id;
269 /*
270 * Simple integrity check for processing a stale (and possibly
271 * inconsistent mailbox): make sure the MDL id is in the
272 * valid range for the stream.
273 *
274 * We go through the trouble of dealing with stale mailboxes
275 * because most of the time, the mailbox data is still valid and
276 * unchanged (and in practice the firmware ping-pongs the
277 * two mdl_ack buffers so mdl_acks are not stale).
278 *
279 * There are occasions when we get a half changed mailbox,
280 * which this check catches for a handle & id mismatch. If the
281 * handle and id do correspond, the worst case is that we
282 * completely lost the old MDL, but pick up the new MDL
283 * early (but the new mdl_ack is guaranteed to be good in this
284 * case as the firmware wouldn't point us to a new mdl_ack until
285 * it's filled in).
286 *
287 * cx18_queue_get_mdl() will detect the lost MDLs
288 * and send them back to q_free for fw rotation eventually.
289 */
290 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
291 !(id >= s->mdl_base_idx &&
292 id < (s->mdl_base_idx + s->buffers))) {
293 CX18_WARN("Fell behind! Ignoring stale mailbox with "
294 " inconsistent data. Lost MDL for mailbox "
295 "seq no %d\n", mb->request);
296 break;
297 }
298 mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used);
299
300 CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id);
301 if (mdl == NULL) {
302 CX18_WARN("Could not find MDL %d for stream %s\n",
303 id, s->name);
304 continue;
305 }
306
307 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
308 s->name, mdl->bytesused);
309
310 if (s->type == CX18_ENC_STREAM_TYPE_TS) {
311 cx18_mdl_send_to_dvb(s, mdl);
312 cx18_enqueue(s, mdl, &s->q_free);
313 } else if (s->type == CX18_ENC_STREAM_TYPE_PCM) {
314 /* Pass the data to cx18-alsa */
315 if (cx->pcm_announce_callback != NULL) {
316 cx18_mdl_send_to_alsa(cx, s, mdl);
317 cx18_enqueue(s, mdl, &s->q_free);
318 } else {
319 cx18_enqueue(s, mdl, &s->q_full);
320 }
321 } else if (s->type == CX18_ENC_STREAM_TYPE_YUV) {
322 cx18_mdl_send_to_videobuf(s, mdl);
323 cx18_enqueue(s, mdl, &s->q_free);
324 } else {
325 cx18_enqueue(s, mdl, &s->q_full);
326 if (s->type == CX18_ENC_STREAM_TYPE_IDX)
327 cx18_stream_rotate_idx_mdls(cx);
328 }
329 }
330 /* Put as many MDLs as possible back into fw use */
331 cx18_stream_load_fw_queue(s);
332
333 wake_up(&cx->dma_waitq);
334 if (s->id != -1)
335 wake_up(&s->waitq);
336}
337
338static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order)
339{
340 char *p;
341 char *str = order->str;
342
343 CX18_DEBUG_INFO("%x %s\n", order->mb.args[0], str);
344 p = strchr(str, '.');
345 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str)
346 CX18_INFO("FW version: %s\n", p - 1);
347}
348
349static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order)
350{
351 switch (order->rpu) {
352 case CPU:
353 {
354 switch (order->mb.cmd) {
355 case CX18_EPU_DMA_DONE:
356 epu_dma_done(cx, order);
357 break;
358 case CX18_EPU_DEBUG:
359 epu_debug(cx, order);
360 break;
361 default:
362 CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
363 order->mb.cmd);
364 break;
365 }
366 break;
367 }
368 case APU:
369 CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
370 order->mb.cmd);
371 break;
372 default:
373 break;
374 }
375}
376
377static
378void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order)
379{
380 atomic_set(&order->pending, 0);
381}
382
383void cx18_in_work_handler(struct work_struct *work)
384{
385 struct cx18_in_work_order *order =
386 container_of(work, struct cx18_in_work_order, work);
387 struct cx18 *cx = order->cx;
388 epu_cmd(cx, order);
389 free_in_work_order(cx, order);
390}
391
392
393/*
394 * Functions that run in an interrupt handling context
395 */
396
397static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order)
398{
399 struct cx18_mailbox __iomem *ack_mb;
400 u32 ack_irq, req;
401
402 switch (order->rpu) {
403 case APU:
404 ack_irq = IRQ_EPU_TO_APU_ACK;
405 ack_mb = &cx->scb->apu2epu_mb;
406 break;
407 case CPU:
408 ack_irq = IRQ_EPU_TO_CPU_ACK;
409 ack_mb = &cx->scb->cpu2epu_mb;
410 break;
411 default:
412 CX18_WARN("Unhandled RPU (%d) for command %x ack\n",
413 order->rpu, order->mb.cmd);
414 return;
415 }
416
417 req = order->mb.request;
418 /* Don't ack if the RPU has gotten impatient and timed us out */
419 if (req != cx18_readl(cx, &ack_mb->request) ||
420 req == cx18_readl(cx, &ack_mb->ack)) {
421 CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
422 "incoming %s to EPU mailbox (sequence no. %u) "
423 "while processing\n",
424 rpu_str[order->rpu], rpu_str[order->rpu], req);
425 order->flags |= CX18_F_EWO_MB_STALE_WHILE_PROC;
426 return;
427 }
428 cx18_writel(cx, req, &ack_mb->ack);
429 cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq);
430 return;
431}
432
433static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order)
434{
435 u32 handle, mdl_ack_offset, mdl_ack_count;
436 struct cx18_mailbox *mb;
437
438 mb = &order->mb;
439 handle = mb->args[0];
440 mdl_ack_offset = mb->args[1];
441 mdl_ack_count = mb->args[2];
442
443 if (handle == CX18_INVALID_TASK_HANDLE ||
444 mdl_ack_count == 0 || mdl_ack_count > CX18_MAX_MDL_ACKS) {
445 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
446 mb_ack_irq(cx, order);
447 return -1;
448 }
449
450 cx18_memcpy_fromio(cx, order->mdl_ack, cx->enc_mem + mdl_ack_offset,
451 sizeof(struct cx18_mdl_ack) * mdl_ack_count);
452
453 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
454 mb_ack_irq(cx, order);
455 return 1;
456}
457
458static
459int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order)
460{
461 u32 str_offset;
462 char *str = order->str;
463
464 str[0] = '\0';
465 str_offset = order->mb.args[1];
466 if (str_offset) {
467 cx18_setup_page(cx, str_offset);
468 cx18_memcpy_fromio(cx, str, cx->enc_mem + str_offset, 252);
469 str[252] = '\0';
470 cx18_setup_page(cx, SCB_OFFSET);
471 }
472
473 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
474 mb_ack_irq(cx, order);
475
476 return str_offset ? 1 : 0;
477}
478
479static inline
480int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order)
481{
482 int ret = -1;
483
484 switch (order->rpu) {
485 case CPU:
486 {
487 switch (order->mb.cmd) {
488 case CX18_EPU_DMA_DONE:
489 ret = epu_dma_done_irq(cx, order);
490 break;
491 case CX18_EPU_DEBUG:
492 ret = epu_debug_irq(cx, order);
493 break;
494 default:
495 CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
496 order->mb.cmd);
497 break;
498 }
499 break;
500 }
501 case APU:
502 CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
503 order->mb.cmd);
504 break;
505 default:
506 break;
507 }
508 return ret;
509}
510
511static inline
512struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx)
513{
514 int i;
515 struct cx18_in_work_order *order = NULL;
516
517 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
518 /*
519 * We only need "pending" atomic to inspect its contents,
520 * and need not do a check and set because:
521 * 1. Any work handler thread only clears "pending" and only
522 * on one, particular work order at a time, per handler thread.
523 * 2. "pending" is only set here, and we're serialized because
524 * we're called in an IRQ handler context.
525 */
526 if (atomic_read(&cx->in_work_order[i].pending) == 0) {
527 order = &cx->in_work_order[i];
528 atomic_set(&order->pending, 1);
529 break;
530 }
531 }
532 return order;
533}
534
535void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
536{
537 struct cx18_mailbox __iomem *mb;
538 struct cx18_mailbox *order_mb;
539 struct cx18_in_work_order *order;
540 int submit;
541
542 switch (rpu) {
543 case CPU:
544 mb = &cx->scb->cpu2epu_mb;
545 break;
546 case APU:
547 mb = &cx->scb->apu2epu_mb;
548 break;
549 default:
550 return;
551 }
552
553 order = alloc_in_work_order_irq(cx);
554 if (order == NULL) {
555 CX18_WARN("Unable to find blank work order form to schedule "
556 "incoming mailbox command processing\n");
557 return;
558 }
559
560 order->flags = 0;
561 order->rpu = rpu;
562 order_mb = &order->mb;
563
564 /* mb->cmd and mb->args[0] through mb->args[2] */
565 cx18_memcpy_fromio(cx, &order_mb->cmd, &mb->cmd, 4 * sizeof(u32));
566 /* mb->request and mb->ack. N.B. we want to read mb->ack last */
567 cx18_memcpy_fromio(cx, &order_mb->request, &mb->request,
568 2 * sizeof(u32));
569
570 if (order_mb->request == order_mb->ack) {
571 CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
572 "incoming %s to EPU mailbox (sequence no. %u)"
573 "\n",
574 rpu_str[rpu], rpu_str[rpu], order_mb->request);
575 if (cx18_debug & CX18_DBGFLG_WARN)
576 dump_mb(cx, order_mb, "incoming");
577 order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
578 }
579
580 /*
581 * Individual EPU command processing is responsible for ack-ing
582 * a non-stale mailbox as soon as possible
583 */
584 submit = epu_cmd_irq(cx, order);
585 if (submit > 0) {
586 queue_work(cx->in_work_queue, &order->work);
587 }
588}
589
590
591/*
592 * Functions called from a non-interrupt, non work_queue context
593 */
594
595static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
596{
597 const struct cx18_api_info *info = find_api_info(cmd);
598 u32 state, irq, req, ack, err;
599 struct cx18_mailbox __iomem *mb;
600 u32 __iomem *xpu_state;
601 wait_queue_head_t *waitq;
602 struct mutex *mb_lock;
603 unsigned long int t0, timeout, ret;
604 int i;
605 char argstr[MAX_MB_ARGUMENTS*11+1];
606 DEFINE_WAIT(w);
607
608 if (info == NULL) {
609 CX18_WARN("unknown cmd %x\n", cmd);
610 return -EINVAL;
611 }
612
613 if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */
614 if (cmd == CX18_CPU_DE_SET_MDL) {
615 if (cx18_debug & CX18_DBGFLG_HIGHVOL)
616 CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n",
617 info->name, cmd,
618 u32arr2hex(data, args, argstr));
619 } else
620 CX18_DEBUG_API("%s\tcmd %#010x args%s\n",
621 info->name, cmd,
622 u32arr2hex(data, args, argstr));
623 }
624
625 switch (info->rpu) {
626 case APU:
627 waitq = &cx->mb_apu_waitq;
628 mb_lock = &cx->epu2apu_mb_lock;
629 irq = IRQ_EPU_TO_APU;
630 mb = &cx->scb->epu2apu_mb;
631 xpu_state = &cx->scb->apu_state;
632 break;
633 case CPU:
634 waitq = &cx->mb_cpu_waitq;
635 mb_lock = &cx->epu2cpu_mb_lock;
636 irq = IRQ_EPU_TO_CPU;
637 mb = &cx->scb->epu2cpu_mb;
638 xpu_state = &cx->scb->cpu_state;
639 break;
640 default:
641 CX18_WARN("Unknown RPU (%d) for API call\n", info->rpu);
642 return -EINVAL;
643 }
644
645 mutex_lock(mb_lock);
646 /*
647 * Wait for an in-use mailbox to complete
648 *
649 * If the XPU is responding with Ack's, the mailbox shouldn't be in
650 * a busy state, since we serialize access to it on our end.
651 *
652 * If the wait for ack after sending a previous command was interrupted
653 * by a signal, we may get here and find a busy mailbox. After waiting,
654 * mark it "not busy" from our end, if the XPU hasn't ack'ed it still.
655 */
656 state = cx18_readl(cx, xpu_state);
657 req = cx18_readl(cx, &mb->request);
658 timeout = msecs_to_jiffies(10);
659 ret = wait_event_timeout(*waitq,
660 (ack = cx18_readl(cx, &mb->ack)) == req,
661 timeout);
662 if (req != ack) {
663 /* waited long enough, make the mbox "not busy" from our end */
664 cx18_writel(cx, req, &mb->ack);
665 CX18_ERR("mbox was found stuck busy when setting up for %s; "
666 "clearing busy and trying to proceed\n", info->name);
667 } else if (ret != timeout)
668 CX18_DEBUG_API("waited %u msecs for busy mbox to be acked\n",
669 jiffies_to_msecs(timeout-ret));
670
671 /* Build the outgoing mailbox */
672 req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1;
673
674 cx18_writel(cx, cmd, &mb->cmd);
675 for (i = 0; i < args; i++)
676 cx18_writel(cx, data[i], &mb->args[i]);
677 cx18_writel(cx, 0, &mb->error);
678 cx18_writel(cx, req, &mb->request);
679 cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */
680
681 /*
682 * Notify the XPU and wait for it to send an Ack back
683 */
684 timeout = msecs_to_jiffies((info->flags & API_FAST) ? 10 : 20);
685
686 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
687 irq, info->name);
688
689 /* So we don't miss the wakeup, prepare to wait before notifying fw */
690 prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
691 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
692
693 t0 = jiffies;
694 ack = cx18_readl(cx, &mb->ack);
695 if (ack != req) {
696 schedule_timeout(timeout);
697 ret = jiffies - t0;
698 ack = cx18_readl(cx, &mb->ack);
699 } else {
700 ret = jiffies - t0;
701 }
702
703 finish_wait(waitq, &w);
704
705 if (req != ack) {
706 mutex_unlock(mb_lock);
707 if (ret >= timeout) {
708 /* Timed out */
709 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
710 "for RPU acknowledgement\n",
711 info->name, jiffies_to_msecs(ret));
712 } else {
713 CX18_DEBUG_WARN("woken up before mailbox ack was ready "
714 "after submitting %s to RPU. only "
715 "waited %d msecs on req %u but awakened"
716 " with unmatched ack %u\n",
717 info->name,
718 jiffies_to_msecs(ret),
719 req, ack);
720 }
721 return -EINVAL;
722 }
723
724 if (ret >= timeout)
725 CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
726 "sending %s; timed out waiting %d msecs\n",
727 info->name, jiffies_to_msecs(ret));
728 else
729 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
730 jiffies_to_msecs(ret), info->name);
731
732 /* Collect data returned by the XPU */
733 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
734 data[i] = cx18_readl(cx, &mb->args[i]);
735 err = cx18_readl(cx, &mb->error);
736 mutex_unlock(mb_lock);
737
738 /*
739 * Wait for XPU to perform extra actions for the caller in some cases.
740 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
741 * back in a burst shortly thereafter
742 */
743 if (info->flags & API_SLOW)
744 cx18_msleep_timeout(300, 0);
745
746 if (err)
747 CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
748 info->name);
749 return err ? -EIO : 0;
750}
751
752int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[])
753{
754 return cx18_api_call(cx, cmd, args, data);
755}
756
757static int cx18_set_filter_param(struct cx18_stream *s)
758{
759 struct cx18 *cx = s->cx;
760 u32 mode;
761 int ret;
762
763 mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0);
764 ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
765 s->handle, 1, mode, cx->spatial_strength);
766 mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0);
767 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
768 s->handle, 0, mode, cx->temporal_strength);
769 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
770 s->handle, 2, cx->filter_mode >> 2, 0);
771 return ret;
772}
773
774int cx18_api_func(void *priv, u32 cmd, int in, int out,
775 u32 data[CX2341X_MBOX_MAX_DATA])
776{
777 struct cx18_stream *s = priv;
778 struct cx18 *cx = s->cx;
779
780 switch (cmd) {
781 case CX2341X_ENC_SET_OUTPUT_PORT:
782 return 0;
783 case CX2341X_ENC_SET_FRAME_RATE:
784 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6,
785 s->handle, 0, 0, 0, 0, data[0]);
786 case CX2341X_ENC_SET_FRAME_SIZE:
787 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3,
788 s->handle, data[1], data[0]);
789 case CX2341X_ENC_SET_STREAM_TYPE:
790 return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2,
791 s->handle, data[0]);
792 case CX2341X_ENC_SET_ASPECT_RATIO:
793 return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2,
794 s->handle, data[0]);
795
796 case CX2341X_ENC_SET_GOP_PROPERTIES:
797 return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3,
798 s->handle, data[0], data[1]);
799 case CX2341X_ENC_SET_GOP_CLOSURE:
800 return 0;
801 case CX2341X_ENC_SET_AUDIO_PROPERTIES:
802 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
803 s->handle, data[0]);
804 case CX2341X_ENC_MUTE_AUDIO:
805 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
806 s->handle, data[0]);
807 case CX2341X_ENC_SET_BIT_RATE:
808 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5,
809 s->handle, data[0], data[1], data[2], data[3]);
810 case CX2341X_ENC_MUTE_VIDEO:
811 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
812 s->handle, data[0]);
813 case CX2341X_ENC_SET_FRAME_DROP_RATE:
814 return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2,
815 s->handle, data[0]);
816 case CX2341X_ENC_MISC:
817 return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4,
818 s->handle, data[0], data[1], data[2]);
819 case CX2341X_ENC_SET_DNR_FILTER_MODE:
820 cx->filter_mode = (data[0] & 3) | (data[1] << 2);
821 return cx18_set_filter_param(s);
822 case CX2341X_ENC_SET_DNR_FILTER_PROPS:
823 cx->spatial_strength = data[0];
824 cx->temporal_strength = data[1];
825 return cx18_set_filter_param(s);
826 case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
827 return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3,
828 s->handle, data[0], data[1]);
829 case CX2341X_ENC_SET_CORING_LEVELS:
830 return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5,
831 s->handle, data[0], data[1], data[2], data[3]);
832 }
833 CX18_WARN("Unknown cmd %x\n", cmd);
834 return 0;
835}
836
837int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS],
838 u32 cmd, int args, ...)
839{
840 va_list ap;
841 int i;
842
843 va_start(ap, args);
844 for (i = 0; i < args; i++)
845 data[i] = va_arg(ap, u32);
846 va_end(ap);
847 return cx18_api(cx, cmd, args, data);
848}
849
850int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...)
851{
852 u32 data[MAX_MB_ARGUMENTS];
853 va_list ap;
854 int i;
855
856 if (cx == NULL) {
857 CX18_ERR("cx == NULL (cmd=%x)\n", cmd);
858 return 0;
859 }
860 if (args > MAX_MB_ARGUMENTS) {
861 CX18_ERR("args too big (cmd=%x)\n", cmd);
862 args = MAX_MB_ARGUMENTS;
863 }
864 va_start(ap, args);
865 for (i = 0; i < args; i++)
866 data[i] = va_arg(ap, u32);
867 va_end(ap);
868 return cx18_api(cx, cmd, args, data);
869}
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
new file mode 100644
index 00000000000..05fe6bdbe06
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -0,0 +1,95 @@
1/*
2 * cx18 mailbox functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#ifndef _CX18_MAILBOX_H_
24#define _CX18_MAILBOX_H_
25
26/* mailbox max args */
27#define MAX_MB_ARGUMENTS 6
28/* compatibility, should be same as the define in cx2341x.h */
29#define CX2341X_MBOX_MAX_DATA 16
30
31#define MB_RESERVED_HANDLE_0 0
32#define MB_RESERVED_HANDLE_1 0xFFFFFFFF
33
34#define APU 0
35#define CPU 1
36#define EPU 2
37#define HPU 3
38
39struct cx18;
40
41/*
42 * This structure is used by CPU to provide completed MDL & buffers information.
43 * Its structure is dictated by the layout of the SCB, required by the
44 * firmware, but its definition needs to be here, instead of in cx18-scb.h,
45 * for mailbox work order scheduling
46 */
47struct cx18_mdl_ack {
48 u32 id; /* ID of a completed MDL */
49 u32 data_used; /* Total data filled in the MDL with 'id' */
50};
51
52/* The cx18_mailbox struct is the mailbox structure which is used for passing
53 messages between processors */
54struct cx18_mailbox {
55 /* The sender sets a handle in 'request' after he fills the command. The
56 'request' should be different than 'ack'. The sender, also, generates
57 an interrupt on XPU2YPU_irq where XPU is the sender and YPU is the
58 receiver. */
59 u32 request;
60 /* The receiver detects a new command when 'req' is different than 'ack'.
61 He sets 'ack' to the same value as 'req' to clear the command. He, also,
62 generates an interrupt on YPU2XPU_irq where XPU is the sender and YPU
63 is the receiver. */
64 u32 ack;
65 u32 reserved[6];
66 /* 'cmd' identifies the command. The list of these commands are in
67 cx23418.h */
68 u32 cmd;
69 /* Each command can have up to 6 arguments */
70 u32 args[MAX_MB_ARGUMENTS];
71 /* The return code can be one of the codes in the file cx23418.h. If the
72 command is completed successfuly, the error will be ERR_SYS_SUCCESS.
73 If it is pending, the code is ERR_SYS_PENDING. If it failed, the error
74 code would indicate the task from which the error originated and will
75 be one of the errors in cx23418.h. In that case, the following
76 applies ((error & 0xff) != 0).
77 If the command is pending, the return will be passed in a MB from the
78 receiver to the sender. 'req' will be returned in args[0] */
79 u32 error;
80};
81
82struct cx18_stream;
83
84int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]);
85int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd,
86 int args, ...);
87int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...);
88int cx18_api_func(void *priv, u32 cmd, int in, int out,
89 u32 data[CX2341X_MBOX_MAX_DATA]);
90
91void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu);
92
93void cx18_in_work_handler(struct work_struct *work);
94
95#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
new file mode 100644
index 00000000000..8884537bd62
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -0,0 +1,443 @@
1/*
2 * cx18 buffer queues
3 *
4 * Derived from ivtv-queue.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-queue.h"
27#include "cx18-streams.h"
28#include "cx18-scb.h"
29#include "cx18-io.h"
30
31void cx18_buf_swap(struct cx18_buffer *buf)
32{
33 int i;
34
35 for (i = 0; i < buf->bytesused; i += 4)
36 swab32s((u32 *)(buf->buf + i));
37}
38
39void _cx18_mdl_swap(struct cx18_mdl *mdl)
40{
41 struct cx18_buffer *buf;
42
43 list_for_each_entry(buf, &mdl->buf_list, list) {
44 if (buf->bytesused == 0)
45 break;
46 cx18_buf_swap(buf);
47 }
48}
49
50void cx18_queue_init(struct cx18_queue *q)
51{
52 INIT_LIST_HEAD(&q->list);
53 atomic_set(&q->depth, 0);
54 q->bytesused = 0;
55}
56
57struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
58 struct cx18_queue *q, int to_front)
59{
60 /* clear the mdl if it is not to be enqueued to the full queue */
61 if (q != &s->q_full) {
62 mdl->bytesused = 0;
63 mdl->readpos = 0;
64 mdl->m_flags = 0;
65 mdl->skipped = 0;
66 mdl->curr_buf = NULL;
67 }
68
69 /* q_busy is restricted to a max buffer count imposed by firmware */
70 if (q == &s->q_busy &&
71 atomic_read(&q->depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
72 q = &s->q_free;
73
74 spin_lock(&q->lock);
75
76 if (to_front)
77 list_add(&mdl->list, &q->list); /* LIFO */
78 else
79 list_add_tail(&mdl->list, &q->list); /* FIFO */
80 q->bytesused += mdl->bytesused - mdl->readpos;
81 atomic_inc(&q->depth);
82
83 spin_unlock(&q->lock);
84 return q;
85}
86
87struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
88{
89 struct cx18_mdl *mdl = NULL;
90
91 spin_lock(&q->lock);
92 if (!list_empty(&q->list)) {
93 mdl = list_first_entry(&q->list, struct cx18_mdl, list);
94 list_del_init(&mdl->list);
95 q->bytesused -= mdl->bytesused - mdl->readpos;
96 mdl->skipped = 0;
97 atomic_dec(&q->depth);
98 }
99 spin_unlock(&q->lock);
100 return mdl;
101}
102
103static void _cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
104 struct cx18_mdl *mdl)
105{
106 struct cx18_buffer *buf;
107 u32 buf_size = s->buf_size;
108 u32 bytesused = mdl->bytesused;
109
110 list_for_each_entry(buf, &mdl->buf_list, list) {
111 buf->readpos = 0;
112 if (bytesused >= buf_size) {
113 buf->bytesused = buf_size;
114 bytesused -= buf_size;
115 } else {
116 buf->bytesused = bytesused;
117 bytesused = 0;
118 }
119 cx18_buf_sync_for_cpu(s, buf);
120 }
121}
122
123static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
124 struct cx18_mdl *mdl)
125{
126 struct cx18_buffer *buf;
127
128 if (list_is_singular(&mdl->buf_list)) {
129 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
130 list);
131 buf->bytesused = mdl->bytesused;
132 buf->readpos = 0;
133 cx18_buf_sync_for_cpu(s, buf);
134 } else {
135 _cx18_mdl_update_bufs_for_cpu(s, mdl);
136 }
137}
138
139struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
140 u32 bytesused)
141{
142 struct cx18 *cx = s->cx;
143 struct cx18_mdl *mdl;
144 struct cx18_mdl *tmp;
145 struct cx18_mdl *ret = NULL;
146 LIST_HEAD(sweep_up);
147
148 /*
149 * We don't have to acquire multiple q locks here, because we are
150 * serialized by the single threaded work handler.
151 * MDLs from the firmware will thus remain in order as
152 * they are moved from q_busy to q_full or to the dvb ring buffer.
153 */
154 spin_lock(&s->q_busy.lock);
155 list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) {
156 /*
157 * We should find what the firmware told us is done,
158 * right at the front of the queue. If we don't, we likely have
159 * missed an mdl done message from the firmware.
160 * Once we skip an mdl repeatedly, relative to the size of
161 * q_busy, we have high confidence we've missed it.
162 */
163 if (mdl->id != id) {
164 mdl->skipped++;
165 if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) {
166 /* mdl must have fallen out of rotation */
167 CX18_WARN("Skipped %s, MDL %d, %d "
168 "times - it must have dropped out of "
169 "rotation\n", s->name, mdl->id,
170 mdl->skipped);
171 /* Sweep it up to put it back into rotation */
172 list_move_tail(&mdl->list, &sweep_up);
173 atomic_dec(&s->q_busy.depth);
174 }
175 continue;
176 }
177 /*
178 * We pull the desired mdl off of the queue here. Something
179 * will have to put it back on a queue later.
180 */
181 list_del_init(&mdl->list);
182 atomic_dec(&s->q_busy.depth);
183 ret = mdl;
184 break;
185 }
186 spin_unlock(&s->q_busy.lock);
187
188 /*
189 * We found the mdl for which we were looking. Get it ready for
190 * the caller to put on q_full or in the dvb ring buffer.
191 */
192 if (ret != NULL) {
193 ret->bytesused = bytesused;
194 ret->skipped = 0;
195 /* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */
196 cx18_mdl_update_bufs_for_cpu(s, ret);
197 if (s->type != CX18_ENC_STREAM_TYPE_TS)
198 set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags);
199 }
200
201 /* Put any mdls the firmware is ignoring back into normal rotation */
202 list_for_each_entry_safe(mdl, tmp, &sweep_up, list) {
203 list_del_init(&mdl->list);
204 cx18_enqueue(s, mdl, &s->q_free);
205 }
206 return ret;
207}
208
209/* Move all mdls of a queue, while flushing the mdl */
210static void cx18_queue_flush(struct cx18_stream *s,
211 struct cx18_queue *q_src, struct cx18_queue *q_dst)
212{
213 struct cx18_mdl *mdl;
214
215 /* It only makes sense to flush to q_free or q_idle */
216 if (q_src == q_dst || q_dst == &s->q_full || q_dst == &s->q_busy)
217 return;
218
219 spin_lock(&q_src->lock);
220 spin_lock(&q_dst->lock);
221 while (!list_empty(&q_src->list)) {
222 mdl = list_first_entry(&q_src->list, struct cx18_mdl, list);
223 list_move_tail(&mdl->list, &q_dst->list);
224 mdl->bytesused = 0;
225 mdl->readpos = 0;
226 mdl->m_flags = 0;
227 mdl->skipped = 0;
228 mdl->curr_buf = NULL;
229 atomic_inc(&q_dst->depth);
230 }
231 cx18_queue_init(q_src);
232 spin_unlock(&q_src->lock);
233 spin_unlock(&q_dst->lock);
234}
235
236void cx18_flush_queues(struct cx18_stream *s)
237{
238 cx18_queue_flush(s, &s->q_busy, &s->q_free);
239 cx18_queue_flush(s, &s->q_full, &s->q_free);
240}
241
242/*
243 * Note, s->buf_pool is not protected by a lock,
244 * the stream better not have *anything* going on when calling this
245 */
246void cx18_unload_queues(struct cx18_stream *s)
247{
248 struct cx18_queue *q_idle = &s->q_idle;
249 struct cx18_mdl *mdl;
250 struct cx18_buffer *buf;
251
252 /* Move all MDLS to q_idle */
253 cx18_queue_flush(s, &s->q_busy, q_idle);
254 cx18_queue_flush(s, &s->q_full, q_idle);
255 cx18_queue_flush(s, &s->q_free, q_idle);
256
257 /* Reset MDL id's and move all buffers back to the stream's buf_pool */
258 spin_lock(&q_idle->lock);
259 list_for_each_entry(mdl, &q_idle->list, list) {
260 while (!list_empty(&mdl->buf_list)) {
261 buf = list_first_entry(&mdl->buf_list,
262 struct cx18_buffer, list);
263 list_move_tail(&buf->list, &s->buf_pool);
264 buf->bytesused = 0;
265 buf->readpos = 0;
266 }
267 mdl->id = s->mdl_base_idx; /* reset id to a "safe" value */
268 /* all other mdl fields were cleared by cx18_queue_flush() */
269 }
270 spin_unlock(&q_idle->lock);
271}
272
273/*
274 * Note, s->buf_pool is not protected by a lock,
275 * the stream better not have *anything* going on when calling this
276 */
277void cx18_load_queues(struct cx18_stream *s)
278{
279 struct cx18 *cx = s->cx;
280 struct cx18_mdl *mdl;
281 struct cx18_buffer *buf;
282 int mdl_id;
283 int i;
284 u32 partial_buf_size;
285
286 /*
287 * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free
288 * Excess MDLs are left on q_idle
289 * Excess buffers are left in buf_pool and/or on an MDL in q_idle
290 */
291 mdl_id = s->mdl_base_idx;
292 for (mdl = cx18_dequeue(s, &s->q_idle), i = s->bufs_per_mdl;
293 mdl != NULL && i == s->bufs_per_mdl;
294 mdl = cx18_dequeue(s, &s->q_idle)) {
295
296 mdl->id = mdl_id;
297
298 for (i = 0; i < s->bufs_per_mdl; i++) {
299 if (list_empty(&s->buf_pool))
300 break;
301
302 buf = list_first_entry(&s->buf_pool, struct cx18_buffer,
303 list);
304 list_move_tail(&buf->list, &mdl->buf_list);
305
306 /* update the firmware's MDL array with this buffer */
307 cx18_writel(cx, buf->dma_handle,
308 &cx->scb->cpu_mdl[mdl_id + i].paddr);
309 cx18_writel(cx, s->buf_size,
310 &cx->scb->cpu_mdl[mdl_id + i].length);
311 }
312
313 if (i == s->bufs_per_mdl) {
314 /*
315 * The encoder doesn't honor s->mdl_size. So in the
316 * case of a non-integral number of buffers to meet
317 * mdl_size, we lie about the size of the last buffer
318 * in the MDL to get the encoder to really only send
319 * us mdl_size bytes per MDL transfer.
320 */
321 partial_buf_size = s->mdl_size % s->buf_size;
322 if (partial_buf_size) {
323 cx18_writel(cx, partial_buf_size,
324 &cx->scb->cpu_mdl[mdl_id + i - 1].length);
325 }
326 cx18_enqueue(s, mdl, &s->q_free);
327 } else {
328 /* Not enough buffers for this MDL; we won't use it */
329 cx18_push(s, mdl, &s->q_idle);
330 }
331 mdl_id += i;
332 }
333}
334
335void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl)
336{
337 int dma = s->dma;
338 u32 buf_size = s->buf_size;
339 struct pci_dev *pci_dev = s->cx->pci_dev;
340 struct cx18_buffer *buf;
341
342 list_for_each_entry(buf, &mdl->buf_list, list)
343 pci_dma_sync_single_for_device(pci_dev, buf->dma_handle,
344 buf_size, dma);
345}
346
347int cx18_stream_alloc(struct cx18_stream *s)
348{
349 struct cx18 *cx = s->cx;
350 int i;
351
352 if (s->buffers == 0)
353 return 0;
354
355 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
356 "(%d.%02d kB total)\n",
357 s->name, s->buffers, s->buf_size,
358 s->buffers * s->buf_size / 1024,
359 (s->buffers * s->buf_size * 100 / 1024) % 100);
360
361 if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
362 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
363 unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
364 ((char __iomem *)cx->scb->cpu_mdl));
365
366 CX18_ERR("Too many buffers, cannot fit in SCB area\n");
367 CX18_ERR("Max buffers = %zd\n",
368 bufsz / sizeof(struct cx18_mdl_ent));
369 return -ENOMEM;
370 }
371
372 s->mdl_base_idx = cx->free_mdl_idx;
373
374 /* allocate stream buffers and MDLs */
375 for (i = 0; i < s->buffers; i++) {
376 struct cx18_mdl *mdl;
377 struct cx18_buffer *buf;
378
379 /* 1 MDL per buffer to handle the worst & also default case */
380 mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN);
381 if (mdl == NULL)
382 break;
383
384 buf = kzalloc(sizeof(struct cx18_buffer),
385 GFP_KERNEL|__GFP_NOWARN);
386 if (buf == NULL) {
387 kfree(mdl);
388 break;
389 }
390
391 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
392 if (buf->buf == NULL) {
393 kfree(mdl);
394 kfree(buf);
395 break;
396 }
397
398 INIT_LIST_HEAD(&mdl->list);
399 INIT_LIST_HEAD(&mdl->buf_list);
400 mdl->id = s->mdl_base_idx; /* a somewhat safe value */
401 cx18_enqueue(s, mdl, &s->q_idle);
402
403 INIT_LIST_HEAD(&buf->list);
404 buf->dma_handle = pci_map_single(s->cx->pci_dev,
405 buf->buf, s->buf_size, s->dma);
406 cx18_buf_sync_for_cpu(s, buf);
407 list_add_tail(&buf->list, &s->buf_pool);
408 }
409 if (i == s->buffers) {
410 cx->free_mdl_idx += s->buffers;
411 return 0;
412 }
413 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
414 cx18_stream_free(s);
415 return -ENOMEM;
416}
417
418void cx18_stream_free(struct cx18_stream *s)
419{
420 struct cx18_mdl *mdl;
421 struct cx18_buffer *buf;
422 struct cx18 *cx = s->cx;
423
424 CX18_DEBUG_INFO("Deallocating buffers for %s stream\n", s->name);
425
426 /* move all buffers to buf_pool and all MDLs to q_idle */
427 cx18_unload_queues(s);
428
429 /* empty q_idle */
430 while ((mdl = cx18_dequeue(s, &s->q_idle)))
431 kfree(mdl);
432
433 /* empty buf_pool */
434 while (!list_empty(&s->buf_pool)) {
435 buf = list_first_entry(&s->buf_pool, struct cx18_buffer, list);
436 list_del_init(&buf->list);
437
438 pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
439 s->buf_size, s->dma);
440 kfree(buf->buf);
441 kfree(buf);
442 }
443}
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
new file mode 100644
index 00000000000..4201ddc1609
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -0,0 +1,98 @@
1/*
2 * cx18 buffer queues
3 *
4 * Derived from ivtv-queue.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#define CX18_DMA_UNMAPPED ((u32) -1)
26
27/* cx18_buffer utility functions */
28
29static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
30 struct cx18_buffer *buf)
31{
32 pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle,
33 s->buf_size, s->dma);
34}
35
36static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
37 struct cx18_buffer *buf)
38{
39 pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle,
40 s->buf_size, s->dma);
41}
42
43void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl);
44
45static inline void cx18_mdl_sync_for_device(struct cx18_stream *s,
46 struct cx18_mdl *mdl)
47{
48 if (list_is_singular(&mdl->buf_list))
49 cx18_buf_sync_for_device(s, list_first_entry(&mdl->buf_list,
50 struct cx18_buffer,
51 list));
52 else
53 _cx18_mdl_sync_for_device(s, mdl);
54}
55
56void cx18_buf_swap(struct cx18_buffer *buf);
57void _cx18_mdl_swap(struct cx18_mdl *mdl);
58
59static inline void cx18_mdl_swap(struct cx18_mdl *mdl)
60{
61 if (list_is_singular(&mdl->buf_list))
62 cx18_buf_swap(list_first_entry(&mdl->buf_list,
63 struct cx18_buffer, list));
64 else
65 _cx18_mdl_swap(mdl);
66}
67
68/* cx18_queue utility functions */
69struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
70 struct cx18_queue *q, int to_front);
71
72static inline
73struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
74 struct cx18_queue *q)
75{
76 return _cx18_enqueue(s, mdl, q, 0); /* FIFO */
77}
78
79static inline
80struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_mdl *mdl,
81 struct cx18_queue *q)
82{
83 return _cx18_enqueue(s, mdl, q, 1); /* LIFO */
84}
85
86void cx18_queue_init(struct cx18_queue *q);
87struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
88struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
89 u32 bytesused);
90void cx18_flush_queues(struct cx18_stream *s);
91
92/* queue MDL reconfiguration helpers */
93void cx18_unload_queues(struct cx18_stream *s);
94void cx18_load_queues(struct cx18_stream *s);
95
96/* cx18_stream utility functions */
97int cx18_stream_alloc(struct cx18_stream *s);
98void 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
new file mode 100644
index 00000000000..85cc59637e5
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-scb.c
@@ -0,0 +1,122 @@
1/*
2 * cx18 System Control Block initialization
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#include "cx18-driver.h"
24#include "cx18-io.h"
25#include "cx18-scb.h"
26
27void cx18_init_scb(struct cx18 *cx)
28{
29 cx18_setup_page(cx, SCB_OFFSET);
30 cx18_memset_io(cx, cx->scb, 0, 0x10000);
31
32 cx18_writel(cx, IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
33 cx18_writel(cx, IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
34 cx18_writel(cx, IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
35 cx18_writel(cx, IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
36 cx18_writel(cx, IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
37 cx18_writel(cx, IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
38 cx18_writel(cx, IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
39 cx18_writel(cx, IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
40
41 cx18_writel(cx, IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
42 cx18_writel(cx, IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
43 cx18_writel(cx, IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
44 cx18_writel(cx, IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
45 cx18_writel(cx, IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
46 cx18_writel(cx, IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
47 cx18_writel(cx, IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
48 cx18_writel(cx, IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
49
50 cx18_writel(cx, IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
51 cx18_writel(cx, IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
52 cx18_writel(cx, IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
53 cx18_writel(cx, IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
54 cx18_writel(cx, IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
55 cx18_writel(cx, IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
56 cx18_writel(cx, IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
57 cx18_writel(cx, IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
58
59 cx18_writel(cx, IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
60 cx18_writel(cx, IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
61 cx18_writel(cx, IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
62 cx18_writel(cx, IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
63 cx18_writel(cx, IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
64 cx18_writel(cx, IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
65 cx18_writel(cx, IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
66 cx18_writel(cx, IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
67
68 cx18_writel(cx, IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
69 cx18_writel(cx, IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
70 cx18_writel(cx, IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
71 cx18_writel(cx, IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
72 cx18_writel(cx, IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
73 cx18_writel(cx, IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
74 cx18_writel(cx, IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
75 cx18_writel(cx, IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
76
77 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
78 &cx->scb->apu2cpu_mb_offset);
79 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
80 &cx->scb->hpu2cpu_mb_offset);
81 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
82 &cx->scb->ppu2cpu_mb_offset);
83 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
84 &cx->scb->epu2cpu_mb_offset);
85 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
86 &cx->scb->cpu2apu_mb_offset);
87 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
88 &cx->scb->hpu2apu_mb_offset);
89 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
90 &cx->scb->ppu2apu_mb_offset);
91 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
92 &cx->scb->epu2apu_mb_offset);
93 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
94 &cx->scb->cpu2hpu_mb_offset);
95 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
96 &cx->scb->apu2hpu_mb_offset);
97 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
98 &cx->scb->ppu2hpu_mb_offset);
99 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
100 &cx->scb->epu2hpu_mb_offset);
101 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
102 &cx->scb->cpu2ppu_mb_offset);
103 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
104 &cx->scb->apu2ppu_mb_offset);
105 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
106 &cx->scb->hpu2ppu_mb_offset);
107 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
108 &cx->scb->epu2ppu_mb_offset);
109 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
110 &cx->scb->cpu2epu_mb_offset);
111 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
112 &cx->scb->apu2epu_mb_offset);
113 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
114 &cx->scb->hpu2epu_mb_offset);
115 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
116 &cx->scb->ppu2epu_mb_offset);
117
118 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
119 &cx->scb->ipc_offset);
120
121 cx18_writel(cx, 1, &cx->scb->epu_state);
122}
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
new file mode 100644
index 00000000000..08877652e32
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-scb.h
@@ -0,0 +1,280 @@
1/*
2 * cx18 System Control Block initialization
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#ifndef CX18_SCB_H
24#define CX18_SCB_H
25
26#include "cx18-mailbox.h"
27
28/* NOTE: All ACK interrupts are in the SW2 register. All non-ACK interrupts
29 are in the SW1 register. */
30
31#define IRQ_APU_TO_CPU 0x00000001
32#define IRQ_CPU_TO_APU_ACK 0x00000001
33#define IRQ_HPU_TO_CPU 0x00000002
34#define IRQ_CPU_TO_HPU_ACK 0x00000002
35#define IRQ_PPU_TO_CPU 0x00000004
36#define IRQ_CPU_TO_PPU_ACK 0x00000004
37#define IRQ_EPU_TO_CPU 0x00000008
38#define IRQ_CPU_TO_EPU_ACK 0x00000008
39
40#define IRQ_CPU_TO_APU 0x00000010
41#define IRQ_APU_TO_CPU_ACK 0x00000010
42#define IRQ_HPU_TO_APU 0x00000020
43#define IRQ_APU_TO_HPU_ACK 0x00000020
44#define IRQ_PPU_TO_APU 0x00000040
45#define IRQ_APU_TO_PPU_ACK 0x00000040
46#define IRQ_EPU_TO_APU 0x00000080
47#define IRQ_APU_TO_EPU_ACK 0x00000080
48
49#define IRQ_CPU_TO_HPU 0x00000100
50#define IRQ_HPU_TO_CPU_ACK 0x00000100
51#define IRQ_APU_TO_HPU 0x00000200
52#define IRQ_HPU_TO_APU_ACK 0x00000200
53#define IRQ_PPU_TO_HPU 0x00000400
54#define IRQ_HPU_TO_PPU_ACK 0x00000400
55#define IRQ_EPU_TO_HPU 0x00000800
56#define IRQ_HPU_TO_EPU_ACK 0x00000800
57
58#define IRQ_CPU_TO_PPU 0x00001000
59#define IRQ_PPU_TO_CPU_ACK 0x00001000
60#define IRQ_APU_TO_PPU 0x00002000
61#define IRQ_PPU_TO_APU_ACK 0x00002000
62#define IRQ_HPU_TO_PPU 0x00004000
63#define IRQ_PPU_TO_HPU_ACK 0x00004000
64#define IRQ_EPU_TO_PPU 0x00008000
65#define IRQ_PPU_TO_EPU_ACK 0x00008000
66
67#define IRQ_CPU_TO_EPU 0x00010000
68#define IRQ_EPU_TO_CPU_ACK 0x00010000
69#define IRQ_APU_TO_EPU 0x00020000
70#define IRQ_EPU_TO_APU_ACK 0x00020000
71#define IRQ_HPU_TO_EPU 0x00040000
72#define IRQ_EPU_TO_HPU_ACK 0x00040000
73#define IRQ_PPU_TO_EPU 0x00080000
74#define IRQ_EPU_TO_PPU_ACK 0x00080000
75
76#define SCB_OFFSET 0xDC0000
77
78/* If Firmware uses fixed memory map, it shall not allocate the area
79 between SCB_OFFSET and SCB_OFFSET+SCB_RESERVED_SIZE-1 inclusive */
80#define SCB_RESERVED_SIZE 0x10000
81
82
83/* This structure is used by EPU to provide memory descriptors in its memory */
84struct cx18_mdl_ent {
85 u32 paddr; /* Physical address of a buffer segment */
86 u32 length; /* Length of the buffer segment */
87};
88
89struct cx18_scb {
90 /* These fields form the System Control Block which is used at boot time
91 for localizing the IPC data as well as the code positions for all
92 processors. The offsets are from the start of this struct. */
93
94 /* Offset where to find the Inter-Processor Communication data */
95 u32 ipc_offset;
96 u32 reserved01[7];
97 /* Offset where to find the start of the CPU code */
98 u32 cpu_code_offset;
99 u32 reserved02[3];
100 /* Offset where to find the start of the APU code */
101 u32 apu_code_offset;
102 u32 reserved03[3];
103 /* Offset where to find the start of the HPU code */
104 u32 hpu_code_offset;
105 u32 reserved04[3];
106 /* Offset where to find the start of the PPU code */
107 u32 ppu_code_offset;
108 u32 reserved05[3];
109
110 /* These fields form Inter-Processor Communication data which is used
111 by all processors to locate the information needed for communicating
112 with other processors */
113
114 /* Fields for CPU: */
115
116 /* bit 0: 1/0 processor ready/not ready. Set other bits to 0. */
117 u32 cpu_state;
118 u32 reserved1[7];
119 /* Offset to the mailbox used for sending commands from APU to CPU */
120 u32 apu2cpu_mb_offset;
121 /* Value to write to register SW1 register set (0xC7003100) after the
122 command is ready */
123 u32 apu2cpu_irq;
124 /* Value to write to register SW2 register set (0xC7003140) after the
125 command is cleared */
126 u32 cpu2apu_irq_ack;
127 u32 reserved2[13];
128
129 u32 hpu2cpu_mb_offset;
130 u32 hpu2cpu_irq;
131 u32 cpu2hpu_irq_ack;
132 u32 reserved3[13];
133
134 u32 ppu2cpu_mb_offset;
135 u32 ppu2cpu_irq;
136 u32 cpu2ppu_irq_ack;
137 u32 reserved4[13];
138
139 u32 epu2cpu_mb_offset;
140 u32 epu2cpu_irq;
141 u32 cpu2epu_irq_ack;
142 u32 reserved5[13];
143 u32 reserved6[8];
144
145 /* Fields for APU: */
146
147 u32 apu_state;
148 u32 reserved11[7];
149 u32 cpu2apu_mb_offset;
150 u32 cpu2apu_irq;
151 u32 apu2cpu_irq_ack;
152 u32 reserved12[13];
153
154 u32 hpu2apu_mb_offset;
155 u32 hpu2apu_irq;
156 u32 apu2hpu_irq_ack;
157 u32 reserved13[13];
158
159 u32 ppu2apu_mb_offset;
160 u32 ppu2apu_irq;
161 u32 apu2ppu_irq_ack;
162 u32 reserved14[13];
163
164 u32 epu2apu_mb_offset;
165 u32 epu2apu_irq;
166 u32 apu2epu_irq_ack;
167 u32 reserved15[13];
168 u32 reserved16[8];
169
170 /* Fields for HPU: */
171
172 u32 hpu_state;
173 u32 reserved21[7];
174 u32 cpu2hpu_mb_offset;
175 u32 cpu2hpu_irq;
176 u32 hpu2cpu_irq_ack;
177 u32 reserved22[13];
178
179 u32 apu2hpu_mb_offset;
180 u32 apu2hpu_irq;
181 u32 hpu2apu_irq_ack;
182 u32 reserved23[13];
183
184 u32 ppu2hpu_mb_offset;
185 u32 ppu2hpu_irq;
186 u32 hpu2ppu_irq_ack;
187 u32 reserved24[13];
188
189 u32 epu2hpu_mb_offset;
190 u32 epu2hpu_irq;
191 u32 hpu2epu_irq_ack;
192 u32 reserved25[13];
193 u32 reserved26[8];
194
195 /* Fields for PPU: */
196
197 u32 ppu_state;
198 u32 reserved31[7];
199 u32 cpu2ppu_mb_offset;
200 u32 cpu2ppu_irq;
201 u32 ppu2cpu_irq_ack;
202 u32 reserved32[13];
203
204 u32 apu2ppu_mb_offset;
205 u32 apu2ppu_irq;
206 u32 ppu2apu_irq_ack;
207 u32 reserved33[13];
208
209 u32 hpu2ppu_mb_offset;
210 u32 hpu2ppu_irq;
211 u32 ppu2hpu_irq_ack;
212 u32 reserved34[13];
213
214 u32 epu2ppu_mb_offset;
215 u32 epu2ppu_irq;
216 u32 ppu2epu_irq_ack;
217 u32 reserved35[13];
218 u32 reserved36[8];
219
220 /* Fields for EPU: */
221
222 u32 epu_state;
223 u32 reserved41[7];
224 u32 cpu2epu_mb_offset;
225 u32 cpu2epu_irq;
226 u32 epu2cpu_irq_ack;
227 u32 reserved42[13];
228
229 u32 apu2epu_mb_offset;
230 u32 apu2epu_irq;
231 u32 epu2apu_irq_ack;
232 u32 reserved43[13];
233
234 u32 hpu2epu_mb_offset;
235 u32 hpu2epu_irq;
236 u32 epu2hpu_irq_ack;
237 u32 reserved44[13];
238
239 u32 ppu2epu_mb_offset;
240 u32 ppu2epu_irq;
241 u32 epu2ppu_irq_ack;
242 u32 reserved45[13];
243 u32 reserved46[8];
244
245 u32 semaphores[8]; /* Semaphores */
246
247 u32 reserved50[32]; /* Reserved for future use */
248
249 struct cx18_mailbox apu2cpu_mb;
250 struct cx18_mailbox hpu2cpu_mb;
251 struct cx18_mailbox ppu2cpu_mb;
252 struct cx18_mailbox epu2cpu_mb;
253
254 struct cx18_mailbox cpu2apu_mb;
255 struct cx18_mailbox hpu2apu_mb;
256 struct cx18_mailbox ppu2apu_mb;
257 struct cx18_mailbox epu2apu_mb;
258
259 struct cx18_mailbox cpu2hpu_mb;
260 struct cx18_mailbox apu2hpu_mb;
261 struct cx18_mailbox ppu2hpu_mb;
262 struct cx18_mailbox epu2hpu_mb;
263
264 struct cx18_mailbox cpu2ppu_mb;
265 struct cx18_mailbox apu2ppu_mb;
266 struct cx18_mailbox hpu2ppu_mb;
267 struct cx18_mailbox epu2ppu_mb;
268
269 struct cx18_mailbox cpu2epu_mb;
270 struct cx18_mailbox apu2epu_mb;
271 struct cx18_mailbox hpu2epu_mb;
272 struct cx18_mailbox ppu2epu_mb;
273
274 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
275 struct cx18_mdl_ent cpu_mdl[1];
276};
277
278void cx18_init_scb(struct cx18 *cx);
279
280#endif
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
new file mode 100644
index 00000000000..852f420fd27
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -0,0 +1,1050 @@
1/*
2 * cx18 init/start/stop/exit stream functions
3 *
4 * Derived from ivtv-streams.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-io.h"
27#include "cx18-fileops.h"
28#include "cx18-mailbox.h"
29#include "cx18-i2c.h"
30#include "cx18-queue.h"
31#include "cx18-ioctl.h"
32#include "cx18-streams.h"
33#include "cx18-cards.h"
34#include "cx18-scb.h"
35#include "cx18-dvb.h"
36
37#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
38
39static struct v4l2_file_operations cx18_v4l2_enc_fops = {
40 .owner = THIS_MODULE,
41 .read = cx18_v4l2_read,
42 .open = cx18_v4l2_open,
43 /* FIXME change to video_ioctl2 if serialization lock can be removed */
44 .unlocked_ioctl = cx18_v4l2_ioctl,
45 .release = cx18_v4l2_close,
46 .poll = cx18_v4l2_enc_poll,
47 .mmap = cx18_v4l2_mmap,
48};
49
50/* offset from 0 to register ts v4l2 minors on */
51#define CX18_V4L2_ENC_TS_OFFSET 16
52/* offset from 0 to register pcm v4l2 minors on */
53#define CX18_V4L2_ENC_PCM_OFFSET 24
54/* offset from 0 to register yuv v4l2 minors on */
55#define CX18_V4L2_ENC_YUV_OFFSET 32
56
57static struct {
58 const char *name;
59 int vfl_type;
60 int num_offset;
61 int dma;
62 enum v4l2_buf_type buf_type;
63} cx18_stream_info[] = {
64 { /* CX18_ENC_STREAM_TYPE_MPG */
65 "encoder MPEG",
66 VFL_TYPE_GRABBER, 0,
67 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
68 },
69 { /* CX18_ENC_STREAM_TYPE_TS */
70 "TS",
71 VFL_TYPE_GRABBER, -1,
72 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
73 },
74 { /* CX18_ENC_STREAM_TYPE_YUV */
75 "encoder YUV",
76 VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
77 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
78 },
79 { /* CX18_ENC_STREAM_TYPE_VBI */
80 "encoder VBI",
81 VFL_TYPE_VBI, 0,
82 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
83 },
84 { /* CX18_ENC_STREAM_TYPE_PCM */
85 "encoder PCM audio",
86 VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
87 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
88 },
89 { /* CX18_ENC_STREAM_TYPE_IDX */
90 "encoder IDX",
91 VFL_TYPE_GRABBER, -1,
92 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
93 },
94 { /* CX18_ENC_STREAM_TYPE_RAD */
95 "encoder radio",
96 VFL_TYPE_RADIO, 0,
97 PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
98 },
99};
100
101
102void cx18_dma_free(struct videobuf_queue *q,
103 struct cx18_stream *s, struct cx18_videobuf_buffer *buf)
104{
105 videobuf_waiton(q, &buf->vb, 0, 0);
106 videobuf_vmalloc_free(&buf->vb);
107 buf->vb.state = VIDEOBUF_NEEDS_INIT;
108}
109
110static int cx18_prepare_buffer(struct videobuf_queue *q,
111 struct cx18_stream *s,
112 struct cx18_videobuf_buffer *buf,
113 u32 pixelformat,
114 unsigned int width, unsigned int height,
115 enum v4l2_field field)
116{
117 struct cx18 *cx = s->cx;
118 int rc = 0;
119
120 /* check settings */
121 buf->bytes_used = 0;
122
123 if ((width < 48) || (height < 32))
124 return -EINVAL;
125
126 buf->vb.size = (width * height * 2);
127 if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
128 return -EINVAL;
129
130 /* alloc + fill struct (if changed) */
131 if (buf->vb.width != width || buf->vb.height != height ||
132 buf->vb.field != field || s->pixelformat != pixelformat ||
133 buf->tvnorm != cx->std) {
134
135 buf->vb.width = width;
136 buf->vb.height = height;
137 buf->vb.field = field;
138 buf->tvnorm = cx->std;
139 s->pixelformat = pixelformat;
140
141 cx18_dma_free(q, s, buf);
142 }
143
144 if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
145 return -EINVAL;
146
147 if (buf->vb.field == 0)
148 buf->vb.field = V4L2_FIELD_INTERLACED;
149
150 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
151 buf->vb.width = width;
152 buf->vb.height = height;
153 buf->vb.field = field;
154 buf->tvnorm = cx->std;
155 s->pixelformat = pixelformat;
156
157 rc = videobuf_iolock(q, &buf->vb, NULL);
158 if (rc != 0)
159 goto fail;
160 }
161 buf->vb.state = VIDEOBUF_PREPARED;
162 return 0;
163
164fail:
165 cx18_dma_free(q, s, buf);
166 return rc;
167
168}
169
170/* VB_MIN_BUFSIZE is lcm(1440 * 480, 1440 * 576)
171 1440 is a single line of 4:2:2 YUV at 720 luma samples wide
172*/
173#define VB_MIN_BUFFERS 32
174#define VB_MIN_BUFSIZE 4147200
175
176static int buffer_setup(struct videobuf_queue *q,
177 unsigned int *count, unsigned int *size)
178{
179 struct cx18_stream *s = q->priv_data;
180 struct cx18 *cx = s->cx;
181
182 *size = 2 * cx->cxhdl.width * cx->cxhdl.height;
183 if (*count == 0)
184 *count = VB_MIN_BUFFERS;
185
186 while (*size * *count > VB_MIN_BUFFERS * VB_MIN_BUFSIZE)
187 (*count)--;
188
189 q->field = V4L2_FIELD_INTERLACED;
190 q->last = V4L2_FIELD_INTERLACED;
191
192 return 0;
193}
194
195static int buffer_prepare(struct videobuf_queue *q,
196 struct videobuf_buffer *vb,
197 enum v4l2_field field)
198{
199 struct cx18_videobuf_buffer *buf =
200 container_of(vb, struct cx18_videobuf_buffer, vb);
201 struct cx18_stream *s = q->priv_data;
202 struct cx18 *cx = s->cx;
203
204 return cx18_prepare_buffer(q, s, buf, s->pixelformat,
205 cx->cxhdl.width, cx->cxhdl.height, field);
206}
207
208static void buffer_release(struct videobuf_queue *q,
209 struct videobuf_buffer *vb)
210{
211 struct cx18_videobuf_buffer *buf =
212 container_of(vb, struct cx18_videobuf_buffer, vb);
213 struct cx18_stream *s = q->priv_data;
214
215 cx18_dma_free(q, s, buf);
216}
217
218static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
219{
220 struct cx18_videobuf_buffer *buf =
221 container_of(vb, struct cx18_videobuf_buffer, vb);
222 struct cx18_stream *s = q->priv_data;
223
224 buf->vb.state = VIDEOBUF_QUEUED;
225
226 list_add_tail(&buf->vb.queue, &s->vb_capture);
227}
228
229static struct videobuf_queue_ops cx18_videobuf_qops = {
230 .buf_setup = buffer_setup,
231 .buf_prepare = buffer_prepare,
232 .buf_queue = buffer_queue,
233 .buf_release = buffer_release,
234};
235
236static void cx18_stream_init(struct cx18 *cx, int type)
237{
238 struct cx18_stream *s = &cx->streams[type];
239 struct video_device *video_dev = s->video_dev;
240
241 /* we need to keep video_dev, so restore it afterwards */
242 memset(s, 0, sizeof(*s));
243 s->video_dev = video_dev;
244
245 /* initialize cx18_stream fields */
246 s->dvb = NULL;
247 s->cx = cx;
248 s->type = type;
249 s->name = cx18_stream_info[type].name;
250 s->handle = CX18_INVALID_TASK_HANDLE;
251
252 s->dma = cx18_stream_info[type].dma;
253 s->buffers = cx->stream_buffers[type];
254 s->buf_size = cx->stream_buf_size[type];
255 INIT_LIST_HEAD(&s->buf_pool);
256 s->bufs_per_mdl = 1;
257 s->mdl_size = s->buf_size * s->bufs_per_mdl;
258
259 init_waitqueue_head(&s->waitq);
260 s->id = -1;
261 spin_lock_init(&s->q_free.lock);
262 cx18_queue_init(&s->q_free);
263 spin_lock_init(&s->q_busy.lock);
264 cx18_queue_init(&s->q_busy);
265 spin_lock_init(&s->q_full.lock);
266 cx18_queue_init(&s->q_full);
267 spin_lock_init(&s->q_idle.lock);
268 cx18_queue_init(&s->q_idle);
269
270 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
271
272 INIT_LIST_HEAD(&s->vb_capture);
273 s->vb_timeout.function = cx18_vb_timeout;
274 s->vb_timeout.data = (unsigned long)s;
275 init_timer(&s->vb_timeout);
276 spin_lock_init(&s->vb_lock);
277 if (type == CX18_ENC_STREAM_TYPE_YUV) {
278 spin_lock_init(&s->vbuf_q_lock);
279
280 s->vb_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
281 videobuf_queue_vmalloc_init(&s->vbuf_q, &cx18_videobuf_qops,
282 &cx->pci_dev->dev, &s->vbuf_q_lock,
283 V4L2_BUF_TYPE_VIDEO_CAPTURE,
284 V4L2_FIELD_INTERLACED,
285 sizeof(struct cx18_videobuf_buffer),
286 s, &cx->serialize_lock);
287
288 /* Assume the previous pixel default */
289 s->pixelformat = V4L2_PIX_FMT_HM12;
290 }
291}
292
293static int cx18_prep_dev(struct cx18 *cx, int type)
294{
295 struct cx18_stream *s = &cx->streams[type];
296 u32 cap = cx->v4l2_cap;
297 int num_offset = cx18_stream_info[type].num_offset;
298 int num = cx->instance + cx18_first_minor + num_offset;
299
300 /*
301 * These five fields are always initialized.
302 * For analog capture related streams, if video_dev == NULL then the
303 * stream is not in use.
304 * For the TS stream, if dvb == NULL then the stream is not in use.
305 * In those cases no other fields but these four can be used.
306 */
307 s->video_dev = NULL;
308 s->dvb = NULL;
309 s->cx = cx;
310 s->type = type;
311 s->name = cx18_stream_info[type].name;
312
313 /* Check whether the radio is supported */
314 if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
315 return 0;
316
317 /* Check whether VBI is supported */
318 if (type == CX18_ENC_STREAM_TYPE_VBI &&
319 !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
320 return 0;
321
322 /* User explicitly selected 0 buffers for these streams, so don't
323 create them. */
324 if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
325 cx->stream_buffers[type] == 0) {
326 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
327 return 0;
328 }
329
330 cx18_stream_init(cx, type);
331
332 /* Allocate the cx18_dvb struct only for the TS on cards with DTV */
333 if (type == CX18_ENC_STREAM_TYPE_TS) {
334 if (cx->card->hw_all & CX18_HW_DVB) {
335 s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL);
336 if (s->dvb == NULL) {
337 CX18_ERR("Couldn't allocate cx18_dvb structure"
338 " for %s\n", s->name);
339 return -ENOMEM;
340 }
341 } else {
342 /* Don't need buffers for the TS, if there is no DVB */
343 s->buffers = 0;
344 }
345 }
346
347 if (num_offset == -1)
348 return 0;
349
350 /* allocate and initialize the v4l2 video device structure */
351 s->video_dev = video_device_alloc();
352 if (s->video_dev == NULL) {
353 CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
354 s->name);
355 return -ENOMEM;
356 }
357
358 snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
359 cx->v4l2_dev.name, s->name);
360
361 s->video_dev->num = num;
362 s->video_dev->v4l2_dev = &cx->v4l2_dev;
363 s->video_dev->fops = &cx18_v4l2_enc_fops;
364 s->video_dev->release = video_device_release;
365 s->video_dev->tvnorms = V4L2_STD_ALL;
366 set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
367 cx18_set_funcs(s->video_dev);
368 return 0;
369}
370
371/* Initialize v4l2 variables and register v4l2 devices */
372int cx18_streams_setup(struct cx18 *cx)
373{
374 int type, ret;
375
376 /* Setup V4L2 Devices */
377 for (type = 0; type < CX18_MAX_STREAMS; type++) {
378 /* Prepare device */
379 ret = cx18_prep_dev(cx, type);
380 if (ret < 0)
381 break;
382
383 /* Allocate Stream */
384 ret = cx18_stream_alloc(&cx->streams[type]);
385 if (ret < 0)
386 break;
387 }
388 if (type == CX18_MAX_STREAMS)
389 return 0;
390
391 /* One or more streams could not be initialized. Clean 'em all up. */
392 cx18_streams_cleanup(cx, 0);
393 return ret;
394}
395
396static int cx18_reg_dev(struct cx18 *cx, int type)
397{
398 struct cx18_stream *s = &cx->streams[type];
399 int vfl_type = cx18_stream_info[type].vfl_type;
400 const char *name;
401 int num, ret;
402
403 if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) {
404 ret = cx18_dvb_register(s);
405 if (ret < 0) {
406 CX18_ERR("DVB failed to register\n");
407 return ret;
408 }
409 }
410
411 if (s->video_dev == NULL)
412 return 0;
413
414 num = s->video_dev->num;
415 /* card number + user defined offset + device offset */
416 if (type != CX18_ENC_STREAM_TYPE_MPG) {
417 struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
418
419 if (s_mpg->video_dev)
420 num = s_mpg->video_dev->num
421 + cx18_stream_info[type].num_offset;
422 }
423 video_set_drvdata(s->video_dev, s);
424
425 /* Register device. First try the desired minor, then any free one. */
426 ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
427 if (ret < 0) {
428 CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
429 s->name, num);
430 video_device_release(s->video_dev);
431 s->video_dev = NULL;
432 return ret;
433 }
434
435 name = video_device_node_name(s->video_dev);
436
437 switch (vfl_type) {
438 case VFL_TYPE_GRABBER:
439 CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",
440 name, s->name, cx->stream_buffers[type],
441 cx->stream_buf_size[type] / 1024,
442 (cx->stream_buf_size[type] * 100 / 1024) % 100);
443 break;
444
445 case VFL_TYPE_RADIO:
446 CX18_INFO("Registered device %s for %s\n", name, s->name);
447 break;
448
449 case VFL_TYPE_VBI:
450 if (cx->stream_buffers[type])
451 CX18_INFO("Registered device %s for %s "
452 "(%d x %d bytes)\n",
453 name, s->name, cx->stream_buffers[type],
454 cx->stream_buf_size[type]);
455 else
456 CX18_INFO("Registered device %s for %s\n",
457 name, s->name);
458 break;
459 }
460
461 return 0;
462}
463
464/* Register v4l2 devices */
465int cx18_streams_register(struct cx18 *cx)
466{
467 int type;
468 int err;
469 int ret = 0;
470
471 /* Register V4L2 devices */
472 for (type = 0; type < CX18_MAX_STREAMS; type++) {
473 err = cx18_reg_dev(cx, type);
474 if (err && ret == 0)
475 ret = err;
476 }
477
478 if (ret == 0)
479 return 0;
480
481 /* One or more streams could not be initialized. Clean 'em all up. */
482 cx18_streams_cleanup(cx, 1);
483 return ret;
484}
485
486/* Unregister v4l2 devices */
487void cx18_streams_cleanup(struct cx18 *cx, int unregister)
488{
489 struct video_device *vdev;
490 int type;
491
492 /* Teardown all streams */
493 for (type = 0; type < CX18_MAX_STREAMS; type++) {
494
495 /* The TS has a cx18_dvb structure, not a video_device */
496 if (type == CX18_ENC_STREAM_TYPE_TS) {
497 if (cx->streams[type].dvb != NULL) {
498 if (unregister)
499 cx18_dvb_unregister(&cx->streams[type]);
500 kfree(cx->streams[type].dvb);
501 cx->streams[type].dvb = NULL;
502 cx18_stream_free(&cx->streams[type]);
503 }
504 continue;
505 }
506
507 /* No struct video_device, but can have buffers allocated */
508 if (type == CX18_ENC_STREAM_TYPE_IDX) {
509 /* If the module params didn't inhibit IDX ... */
510 if (cx->stream_buffers[type] != 0) {
511 cx->stream_buffers[type] = 0;
512 /*
513 * Before calling cx18_stream_free(),
514 * check if the IDX stream was actually set up.
515 * Needed, since the cx18_probe() error path
516 * exits through here as well as normal clean up
517 */
518 if (cx->streams[type].buffers != 0)
519 cx18_stream_free(&cx->streams[type]);
520 }
521 continue;
522 }
523
524 /* If struct video_device exists, can have buffers allocated */
525 vdev = cx->streams[type].video_dev;
526
527 cx->streams[type].video_dev = NULL;
528 if (vdev == NULL)
529 continue;
530
531 if (type == CX18_ENC_STREAM_TYPE_YUV)
532 videobuf_mmap_free(&cx->streams[type].vbuf_q);
533
534 cx18_stream_free(&cx->streams[type]);
535
536 /* Unregister or release device */
537 if (unregister)
538 video_unregister_device(vdev);
539 else
540 video_device_release(vdev);
541 }
542}
543
544static void cx18_vbi_setup(struct cx18_stream *s)
545{
546 struct cx18 *cx = s->cx;
547 int raw = cx18_raw_vbi(cx);
548 u32 data[CX2341X_MBOX_MAX_DATA];
549 int lines;
550
551 if (cx->is_60hz) {
552 cx->vbi.count = 12;
553 cx->vbi.start[0] = 10;
554 cx->vbi.start[1] = 273;
555 } else { /* PAL/SECAM */
556 cx->vbi.count = 18;
557 cx->vbi.start[0] = 6;
558 cx->vbi.start[1] = 318;
559 }
560
561 /* setup VBI registers */
562 if (raw)
563 v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &cx->vbi.in.fmt.vbi);
564 else
565 v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &cx->vbi.in.fmt.sliced);
566
567 /*
568 * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
569 * VBI when the first analog capture channel starts, as once it starts
570 * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
571 * (i.e. for the VBI capture channels). We also send it for each
572 * analog capture channel anyway just to make sure we get the proper
573 * behavior
574 */
575 if (raw) {
576 lines = cx->vbi.count * 2;
577 } else {
578 /*
579 * For 525/60 systems, according to the VIP 2 & BT.656 std:
580 * The EAV RP code's Field bit toggles on line 4, a few lines
581 * after the Vertcal Blank bit has already toggled.
582 * Tell the encoder to capture 21-4+1=18 lines per field,
583 * since we want lines 10 through 21.
584 *
585 * For 625/50 systems, according to the VIP 2 & BT.656 std:
586 * The EAV RP code's Field bit toggles on line 1, a few lines
587 * after the Vertcal Blank bit has already toggled.
588 * (We've actually set the digitizer so that the Field bit
589 * toggles on line 2.) Tell the encoder to capture 23-2+1=22
590 * lines per field, since we want lines 6 through 23.
591 */
592 lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2;
593 }
594
595 data[0] = s->handle;
596 /* Lines per field */
597 data[1] = (lines / 2) | ((lines / 2) << 16);
598 /* bytes per line */
599 data[2] = (raw ? vbi_active_samples
600 : (cx->is_60hz ? vbi_hblank_samples_60Hz
601 : vbi_hblank_samples_50Hz));
602 /* Every X number of frames a VBI interrupt arrives
603 (frames as in 25 or 30 fps) */
604 data[3] = 1;
605 /*
606 * Set the SAV/EAV RP codes to look for as start/stop points
607 * when in VIP-1.1 mode
608 */
609 if (raw) {
610 /*
611 * Start codes for beginning of "active" line in vertical blank
612 * 0x20 ( VerticalBlank )
613 * 0x60 ( EvenField VerticalBlank )
614 */
615 data[4] = 0x20602060;
616 /*
617 * End codes for end of "active" raw lines and regular lines
618 * 0x30 ( VerticalBlank HorizontalBlank)
619 * 0x70 ( EvenField VerticalBlank HorizontalBlank)
620 * 0x90 (Task HorizontalBlank)
621 * 0xd0 (Task EvenField HorizontalBlank)
622 */
623 data[5] = 0x307090d0;
624 } else {
625 /*
626 * End codes for active video, we want data in the hblank region
627 * 0xb0 (Task 0 VerticalBlank HorizontalBlank)
628 * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
629 *
630 * Since the V bit is only allowed to toggle in the EAV RP code,
631 * just before the first active region line, these two
632 * are problematic:
633 * 0x90 (Task HorizontalBlank)
634 * 0xd0 (Task EvenField HorizontalBlank)
635 *
636 * We have set the digitzer such that we don't have to worry
637 * about these problem codes.
638 */
639 data[4] = 0xB0F0B0F0;
640 /*
641 * Start codes for beginning of active line in vertical blank
642 * 0xa0 (Task VerticalBlank )
643 * 0xe0 (Task EvenField VerticalBlank )
644 */
645 data[5] = 0xA0E0A0E0;
646 }
647
648 CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
649 data[0], data[1], data[2], data[3], data[4], data[5]);
650
651 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
652}
653
654void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
655{
656 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
657 struct cx18_mdl *mdl;
658
659 if (!cx18_stream_enabled(s))
660 return;
661
662 /* Return if the firmware is not running low on MDLs */
663 if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
664 CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
665 return;
666
667 /* Return if there are no MDLs to rotate back to the firmware */
668 if (atomic_read(&s->q_full.depth) < 2)
669 return;
670
671 /*
672 * Take the oldest IDX MDL still holding data, and discard its index
673 * entries by scheduling the MDL to go back to the firmware
674 */
675 mdl = cx18_dequeue(s, &s->q_full);
676 if (mdl != NULL)
677 cx18_enqueue(s, mdl, &s->q_free);
678}
679
680static
681struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
682 struct cx18_mdl *mdl)
683{
684 struct cx18 *cx = s->cx;
685 struct cx18_queue *q;
686
687 /* Don't give it to the firmware, if we're not running a capture */
688 if (s->handle == CX18_INVALID_TASK_HANDLE ||
689 test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
690 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
691 return cx18_enqueue(s, mdl, &s->q_free);
692
693 q = cx18_enqueue(s, mdl, &s->q_busy);
694 if (q != &s->q_busy)
695 return q; /* The firmware has the max MDLs it can handle */
696
697 cx18_mdl_sync_for_device(s, mdl);
698 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
699 (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
700 s->bufs_per_mdl, mdl->id, s->mdl_size);
701 return q;
702}
703
704static
705void _cx18_stream_load_fw_queue(struct cx18_stream *s)
706{
707 struct cx18_queue *q;
708 struct cx18_mdl *mdl;
709
710 if (atomic_read(&s->q_free.depth) == 0 ||
711 atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
712 return;
713
714 /* Move from q_free to q_busy notifying the firmware, until the limit */
715 do {
716 mdl = cx18_dequeue(s, &s->q_free);
717 if (mdl == NULL)
718 break;
719 q = _cx18_stream_put_mdl_fw(s, mdl);
720 } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
721 && q == &s->q_busy);
722}
723
724void cx18_out_work_handler(struct work_struct *work)
725{
726 struct cx18_stream *s =
727 container_of(work, struct cx18_stream, out_work_order);
728
729 _cx18_stream_load_fw_queue(s);
730}
731
732static void cx18_stream_configure_mdls(struct cx18_stream *s)
733{
734 cx18_unload_queues(s);
735
736 switch (s->type) {
737 case CX18_ENC_STREAM_TYPE_YUV:
738 /*
739 * Height should be a multiple of 32 lines.
740 * Set the MDL size to the exact size needed for one frame.
741 * Use enough buffers per MDL to cover the MDL size
742 */
743 if (s->pixelformat == V4L2_PIX_FMT_HM12)
744 s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
745 else
746 s->mdl_size = 720 * s->cx->cxhdl.height * 2;
747 s->bufs_per_mdl = s->mdl_size / s->buf_size;
748 if (s->mdl_size % s->buf_size)
749 s->bufs_per_mdl++;
750 break;
751 case CX18_ENC_STREAM_TYPE_VBI:
752 s->bufs_per_mdl = 1;
753 if (cx18_raw_vbi(s->cx)) {
754 s->mdl_size = (s->cx->is_60hz ? 12 : 18)
755 * 2 * vbi_active_samples;
756 } else {
757 /*
758 * See comment in cx18_vbi_setup() below about the
759 * extra lines we capture in sliced VBI mode due to
760 * the lines on which EAV RP codes toggle.
761 */
762 s->mdl_size = s->cx->is_60hz
763 ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz
764 : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz;
765 }
766 break;
767 default:
768 s->bufs_per_mdl = 1;
769 s->mdl_size = s->buf_size * s->bufs_per_mdl;
770 break;
771 }
772
773 cx18_load_queues(s);
774}
775
776int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
777{
778 u32 data[MAX_MB_ARGUMENTS];
779 struct cx18 *cx = s->cx;
780 int captype = 0;
781 struct cx18_stream *s_idx;
782
783 if (!cx18_stream_enabled(s))
784 return -EINVAL;
785
786 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
787
788 switch (s->type) {
789 case CX18_ENC_STREAM_TYPE_MPG:
790 captype = CAPTURE_CHANNEL_TYPE_MPEG;
791 cx->mpg_data_received = cx->vbi_data_inserted = 0;
792 cx->dualwatch_jiffies = jiffies;
793 cx->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
794 cx->search_pack_header = 0;
795 break;
796
797 case CX18_ENC_STREAM_TYPE_IDX:
798 captype = CAPTURE_CHANNEL_TYPE_INDEX;
799 break;
800 case CX18_ENC_STREAM_TYPE_TS:
801 captype = CAPTURE_CHANNEL_TYPE_TS;
802 break;
803 case CX18_ENC_STREAM_TYPE_YUV:
804 captype = CAPTURE_CHANNEL_TYPE_YUV;
805 break;
806 case CX18_ENC_STREAM_TYPE_PCM:
807 captype = CAPTURE_CHANNEL_TYPE_PCM;
808 break;
809 case CX18_ENC_STREAM_TYPE_VBI:
810#ifdef CX18_ENCODER_PARSES_SLICED
811 captype = cx18_raw_vbi(cx) ?
812 CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
813#else
814 /*
815 * Currently we set things up so that Sliced VBI from the
816 * digitizer is handled as Raw VBI by the encoder
817 */
818 captype = CAPTURE_CHANNEL_TYPE_VBI;
819#endif
820 cx->vbi.frame = 0;
821 cx->vbi.inserted_frame = 0;
822 memset(cx->vbi.sliced_mpeg_size,
823 0, sizeof(cx->vbi.sliced_mpeg_size));
824 break;
825 default:
826 return -EINVAL;
827 }
828
829 /* Clear Streamoff flags in case left from last capture */
830 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
831
832 cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE);
833 s->handle = data[0];
834 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
835
836 /*
837 * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
838 * set up all the parameters, as it is not obvious which parameters the
839 * firmware shares across capture channel types and which it does not.
840 *
841 * Some of the cx18_vapi() calls below apply to only certain capture
842 * channel types. We're hoping there's no harm in calling most of them
843 * anyway, as long as the values are all consistent. Setting some
844 * shared parameters will have no effect once an analog capture channel
845 * has started streaming.
846 */
847 if (captype != CAPTURE_CHANNEL_TYPE_TS) {
848 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
849 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
850 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
851 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
852
853 /*
854 * Audio related reset according to
855 * Documentation/video4linux/cx2341x/fw-encoder-api.txt
856 */
857 if (atomic_read(&cx->ana_capturing) == 0)
858 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
859 s->handle, 12);
860
861 /*
862 * Number of lines for Field 1 & Field 2 according to
863 * Documentation/video4linux/cx2341x/fw-encoder-api.txt
864 * Field 1 is 312 for 625 line systems in BT.656
865 * Field 2 is 313 for 625 line systems in BT.656
866 */
867 cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
868 s->handle, 312, 313);
869
870 if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
871 cx18_vbi_setup(s);
872
873 /*
874 * Select to receive I, P, and B frame index entries, if the
875 * index stream is enabled. Otherwise disable index entry
876 * generation.
877 */
878 s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
879 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2,
880 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
881
882 /* Call out to the common CX2341x API setup for user controls */
883 cx->cxhdl.priv = s;
884 cx2341x_handler_setup(&cx->cxhdl);
885
886 /*
887 * When starting a capture and we're set for radio,
888 * ensure the video is muted, despite the user control.
889 */
890 if (!cx->cxhdl.video_mute &&
891 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
892 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
893 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
894
895 /* Enable the Video Format Converter for UYVY 4:2:2 support,
896 * rather than the default HM12 Macroblovk 4:2:0 support.
897 */
898 if (captype == CAPTURE_CHANNEL_TYPE_YUV) {
899 if (s->pixelformat == V4L2_PIX_FMT_UYVY)
900 cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
901 s->handle, 1);
902 else
903 /* If in doubt, default to HM12 */
904 cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
905 s->handle, 0);
906 }
907 }
908
909 if (atomic_read(&cx->tot_capturing) == 0) {
910 cx2341x_handler_set_busy(&cx->cxhdl, 1);
911 clear_bit(CX18_F_I_EOS, &cx->i_flags);
912 cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
913 }
914
915 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
916 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
917 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
918
919 /* Init all the cpu_mdls for this stream */
920 cx18_stream_configure_mdls(s);
921 _cx18_stream_load_fw_queue(s);
922
923 /* begin_capture */
924 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
925 CX18_DEBUG_WARN("Error starting capture!\n");
926 /* Ensure we're really not capturing before releasing MDLs */
927 set_bit(CX18_F_S_STOPPING, &s->s_flags);
928 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
929 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
930 else
931 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
932 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
933 /* FIXME - CX18_F_S_STREAMOFF as well? */
934 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
935 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
936 s->handle = CX18_INVALID_TASK_HANDLE;
937 clear_bit(CX18_F_S_STOPPING, &s->s_flags);
938 if (atomic_read(&cx->tot_capturing) == 0) {
939 set_bit(CX18_F_I_EOS, &cx->i_flags);
940 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
941 }
942 return -EINVAL;
943 }
944
945 /* you're live! sit back and await interrupts :) */
946 if (captype != CAPTURE_CHANNEL_TYPE_TS)
947 atomic_inc(&cx->ana_capturing);
948 atomic_inc(&cx->tot_capturing);
949 return 0;
950}
951EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);
952
953void cx18_stop_all_captures(struct cx18 *cx)
954{
955 int i;
956
957 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
958 struct cx18_stream *s = &cx->streams[i];
959
960 if (!cx18_stream_enabled(s))
961 continue;
962 if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
963 cx18_stop_v4l2_encode_stream(s, 0);
964 }
965}
966
967int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
968{
969 struct cx18 *cx = s->cx;
970 unsigned long then;
971
972 if (!cx18_stream_enabled(s))
973 return -EINVAL;
974
975 /* This function assumes that you are allowed to stop the capture
976 and that we are actually capturing */
977
978 CX18_DEBUG_INFO("Stop Capture\n");
979
980 if (atomic_read(&cx->tot_capturing) == 0)
981 return 0;
982
983 set_bit(CX18_F_S_STOPPING, &s->s_flags);
984 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
985 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
986 else
987 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
988
989 then = jiffies;
990
991 if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
992 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
993 }
994
995 if (s->type != CX18_ENC_STREAM_TYPE_TS)
996 atomic_dec(&cx->ana_capturing);
997 atomic_dec(&cx->tot_capturing);
998
999 /* Clear capture and no-read bits */
1000 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
1001
1002 /* Tell the CX23418 it can't use our buffers anymore */
1003 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
1004
1005 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
1006 s->handle = CX18_INVALID_TASK_HANDLE;
1007 clear_bit(CX18_F_S_STOPPING, &s->s_flags);
1008
1009 if (atomic_read(&cx->tot_capturing) > 0)
1010 return 0;
1011
1012 cx2341x_handler_set_busy(&cx->cxhdl, 0);
1013 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
1014 wake_up(&s->waitq);
1015
1016 return 0;
1017}
1018EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);
1019
1020u32 cx18_find_handle(struct cx18 *cx)
1021{
1022 int i;
1023
1024 /* find first available handle to be used for global settings */
1025 for (i = 0; i < CX18_MAX_STREAMS; i++) {
1026 struct cx18_stream *s = &cx->streams[i];
1027
1028 if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
1029 return s->handle;
1030 }
1031 return CX18_INVALID_TASK_HANDLE;
1032}
1033
1034struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
1035{
1036 int i;
1037 struct cx18_stream *s;
1038
1039 if (handle == CX18_INVALID_TASK_HANDLE)
1040 return NULL;
1041
1042 for (i = 0; i < CX18_MAX_STREAMS; i++) {
1043 s = &cx->streams[i];
1044 if (s->handle != handle)
1045 continue;
1046 if (cx18_stream_enabled(s))
1047 return s;
1048 }
1049 return NULL;
1050}
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
new file mode 100644
index 00000000000..713b0e61536
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -0,0 +1,62 @@
1/*
2 * cx18 init/start/stop/exit stream functions
3 *
4 * Derived from ivtv-streams.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25u32 cx18_find_handle(struct cx18 *cx);
26struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle);
27int cx18_streams_setup(struct cx18 *cx);
28int cx18_streams_register(struct cx18 *cx);
29void cx18_streams_cleanup(struct cx18 *cx, int unregister);
30
31#define CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN (3)
32void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
33
34static inline bool cx18_stream_enabled(struct cx18_stream *s)
35{
36 return s->video_dev ||
37 (s->dvb && s->dvb->enabled) ||
38 (s->type == CX18_ENC_STREAM_TYPE_IDX &&
39 s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
40}
41
42/* Related to submission of mdls to firmware */
43static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
44{
45 schedule_work(&s->out_work_order);
46}
47
48static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,
49 struct cx18_mdl *mdl)
50{
51 /* Put mdl on q_free; the out work handler will move mdl(s) to q_busy */
52 cx18_enqueue(s, mdl, &s->q_free);
53 cx18_stream_load_fw_queue(s);
54}
55
56void cx18_out_work_handler(struct work_struct *work);
57
58/* Capture related */
59int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
60int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
61
62void 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
new file mode 100644
index 00000000000..6d3121ff45a
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -0,0 +1,277 @@
1/*
2 * cx18 Vertical Blank Interval support functions
3 *
4 * Derived from ivtv-vbi.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-vbi.h"
26#include "cx18-ioctl.h"
27#include "cx18-queue.h"
28
29/*
30 * Raster Reference/Protection (RP) bytes, used in Start/End Active
31 * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start
32 * of VBI sample or VBI ancillary data regions in the digitial ratser line.
33 *
34 * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0
35 */
36static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */
37static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */
38
39static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
40{
41 int line = 0;
42 int i;
43 u32 linemask[2] = { 0, 0 };
44 unsigned short size;
45 static const u8 mpeg_hdr_data[] = {
46 /* MPEG-2 Program Pack */
47 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */
48 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */
49 0x01, 0xd1, 0xd3, /* Mux Rate, markers */
50 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */
51 /* MPEG-2 Private Stream 1 PES Packet */
52 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */
53 0x00, 0x1a, /* length */
54 0x84, 0x80, 0x07, /* flags, hdr data len */
55 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
56 0xff, 0xff /* stuffing */
57 };
58 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
59 int idx = cx->vbi.frame % CX18_VBI_FRAMES;
60 u8 *dst = &cx->vbi.sliced_mpeg_data[idx][0];
61
62 for (i = 0; i < lines; i++) {
63 struct v4l2_sliced_vbi_data *sdata = cx->vbi.sliced_data + i;
64 int f, l;
65
66 if (sdata->id == 0)
67 continue;
68
69 l = sdata->line - 6;
70 f = sdata->field;
71 if (f)
72 l += 18;
73 if (l < 32)
74 linemask[0] |= (1 << l);
75 else
76 linemask[1] |= (1 << (l - 32));
77 dst[sd + 12 + line * 43] = cx18_service2vbi(sdata->id);
78 memcpy(dst + sd + 12 + line * 43 + 1, sdata->data, 42);
79 line++;
80 }
81 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
82 if (line == 36) {
83 /* All lines are used, so there is no space for the linemask
84 (the max size of the VBI data is 36 * 43 + 4 bytes).
85 So in this case we use the magic number 'ITV0'. */
86 memcpy(dst + sd, "ITV0", 4);
87 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
88 size = 4 + ((43 * line + 3) & ~3);
89 } else {
90 memcpy(dst + sd, "itv0", 4);
91 cpu_to_le32s(&linemask[0]);
92 cpu_to_le32s(&linemask[1]);
93 memcpy(dst + sd + 4, &linemask[0], 8);
94 size = 12 + ((43 * line + 3) & ~3);
95 }
96 dst[4+16] = (size + 10) >> 8;
97 dst[5+16] = (size + 10) & 0xff;
98 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
99 dst[10+16] = (pts_stamp >> 22) & 0xff;
100 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
101 dst[12+16] = (pts_stamp >> 7) & 0xff;
102 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
103 cx->vbi.sliced_mpeg_size[idx] = sd + size;
104}
105
106/* Compress raw VBI format, removes leading SAV codes and surplus space
107 after the frame. Returns new compressed size. */
108/* FIXME - this function ignores the input size. */
109static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
110{
111 u32 line_size = vbi_active_samples;
112 u32 lines = cx->vbi.count * 2;
113 u8 *q = buf;
114 u8 *p;
115 int i;
116
117 /* Skip the header */
118 buf += hdr_size;
119
120 for (i = 0; i < lines; i++) {
121 p = buf + i * line_size;
122
123 /* Look for SAV code */
124 if (p[0] != 0xff || p[1] || p[2] ||
125 (p[3] != raw_vbi_sav_rp[0] &&
126 p[3] != raw_vbi_sav_rp[1]))
127 break;
128 if (i == lines - 1) {
129 /* last line is hdr_size bytes short - extrapolate it */
130 memcpy(q, p + 4, line_size - 4 - hdr_size);
131 q += line_size - 4 - hdr_size;
132 p += line_size - hdr_size - 1;
133 memset(q, (int) *p, hdr_size);
134 } else {
135 memcpy(q, p + 4, line_size - 4);
136 q += line_size - 4;
137 }
138 }
139 return lines * (line_size - 4);
140}
141
142static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
143 const u32 hdr_size)
144{
145 struct v4l2_decode_vbi_line vbi;
146 int i;
147 u32 line = 0;
148 u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
149 : vbi_hblank_samples_50Hz;
150
151 /* find the first valid line */
152 for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
153 if (buf[0] == 0xff && !buf[1] && !buf[2] &&
154 (buf[3] == sliced_vbi_eav_rp[0] ||
155 buf[3] == sliced_vbi_eav_rp[1]))
156 break;
157 }
158
159 /*
160 * The last line is short by hdr_size bytes, but for the remaining
161 * checks against size, we pretend that it is not, by counting the
162 * header bytes we knowingly skipped
163 */
164 size -= (i - hdr_size);
165 if (size < line_size)
166 return line;
167
168 for (i = 0; i < size / line_size; i++) {
169 u8 *p = buf + i * line_size;
170
171 /* Look for EAV code */
172 if (p[0] != 0xff || p[1] || p[2] ||
173 (p[3] != sliced_vbi_eav_rp[0] &&
174 p[3] != sliced_vbi_eav_rp[1]))
175 continue;
176 vbi.p = p + 4;
177 v4l2_subdev_call(cx->sd_av, vbi, decode_vbi_line, &vbi);
178 if (vbi.type) {
179 cx->vbi.sliced_data[line].id = vbi.type;
180 cx->vbi.sliced_data[line].field = vbi.is_second_field;
181 cx->vbi.sliced_data[line].line = vbi.line;
182 memcpy(cx->vbi.sliced_data[line].data, vbi.p, 42);
183 line++;
184 }
185 }
186 return line;
187}
188
189static void _cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf)
190{
191 /*
192 * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
193 * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp]
194 */
195 struct vbi_data_hdr {
196 __be32 magic;
197 __be32 unknown;
198 __be32 pts;
199 } *hdr = (struct vbi_data_hdr *) buf->buf;
200
201 u8 *p = (u8 *) buf->buf;
202 u32 size = buf->bytesused;
203 u32 pts;
204 int lines;
205
206 /*
207 * The CX23418 sends us data that is 32 bit little-endian swapped,
208 * but we want the raw VBI bytes in the order they were in the raster
209 * line. This has a side effect of making the header big endian
210 */
211 cx18_buf_swap(buf);
212
213 /* Raw VBI data */
214 if (cx18_raw_vbi(cx)) {
215
216 size = buf->bytesused =
217 compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr));
218
219 /*
220 * Hack needed for compatibility with old VBI software.
221 * Write the frame # at the last 4 bytes of the frame
222 */
223 p += size - 4;
224 memcpy(p, &cx->vbi.frame, 4);
225 cx->vbi.frame++;
226 return;
227 }
228
229 /* Sliced VBI data with data insertion */
230
231 pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts)
232 : 0;
233
234 lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr));
235
236 /* always return at least one empty line */
237 if (lines == 0) {
238 cx->vbi.sliced_data[0].id = 0;
239 cx->vbi.sliced_data[0].line = 0;
240 cx->vbi.sliced_data[0].field = 0;
241 lines = 1;
242 }
243 buf->bytesused = size = lines * sizeof(cx->vbi.sliced_data[0]);
244 memcpy(p, &cx->vbi.sliced_data[0], size);
245
246 if (cx->vbi.insert_mpeg)
247 copy_vbi_data(cx, lines, pts);
248 cx->vbi.frame++;
249}
250
251void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
252 int streamtype)
253{
254 struct cx18_buffer *buf;
255 u32 orig_used;
256
257 if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
258 return;
259
260 /*
261 * Big assumption here:
262 * Every buffer hooked to the MDL's buf_list is a complete VBI frame
263 * that ends at the end of the buffer.
264 *
265 * To assume anything else would make the code in this file
266 * more complex, or require extra memcpy()'s to make the
267 * buffers satisfy the above assumption. It's just simpler to set
268 * up the encoder buffer transfers to make the assumption true.
269 */
270 list_for_each_entry(buf, &mdl->buf_list, list) {
271 orig_used = buf->bytesused;
272 if (orig_used == 0)
273 break;
274 _cx18_process_vbi_data(cx, buf);
275 mdl->bytesused -= (orig_used - buf->bytesused);
276 }
277}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
new file mode 100644
index 00000000000..b365cf4b466
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -0,0 +1,26 @@
1/*
2 * cx18 Vertical Blank Interval support functions
3 *
4 * Derived from ivtv-vbi.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
25 int streamtype);
26int 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
new file mode 100644
index 00000000000..fed48b6bb67
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -0,0 +1,28 @@
1/*
2 * cx18 driver version information
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef CX18_VERSION_H
23#define CX18_VERSION_H
24
25#define CX18_DRIVER_NAME "cx18"
26#define CX18_VERSION "1.5.1"
27
28#endif
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
new file mode 100644
index 00000000000..6dc84aac8f4
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-video.c
@@ -0,0 +1,32 @@
1/*
2 * cx18 video interface functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-video.h"
24#include "cx18-cards.h"
25
26void cx18_video_set_io(struct cx18 *cx)
27{
28 int inp = cx->active_input;
29
30 v4l2_subdev_call(cx->sd_av, video, s_routing,
31 cx->card->video_inputs[inp].video_input, 0, 0);
32}
diff --git a/drivers/media/video/cx18/cx18-video.h b/drivers/media/video/cx18/cx18-video.h
new file mode 100644
index 00000000000..529006a06e5
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-video.h
@@ -0,0 +1,22 @@
1/*
2 * cx18 video interface functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22void cx18_video_set_io(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
new file mode 100644
index 00000000000..767a8d23e3f
--- /dev/null
+++ b/drivers/media/video/cx18/cx23418.h
@@ -0,0 +1,492 @@
1/*
2 * cx18 header containing common defines.
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef CX23418_H
23#define CX23418_H
24
25#include <media/cx2341x.h>
26
27#define MGR_CMD_MASK 0x40000000
28/* The MSB of the command code indicates that this is the completion of a
29 command */
30#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000)
31
32/* Description: This command creates a new instance of a certain task
33 IN[0] - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is
34 the processor on which the task YYY will be created
35 OUT[0] - Task handle. This handle is passed along with commands to
36 dispatch to the right instance of the task
37 ReturnCode - One of the ERR_SYS_... */
38#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001)
39
40/* Description: This command destroys an instance of a task
41 IN[0] - Task handle. Hanlde of the task to destroy
42 ReturnCode - One of the ERR_SYS_... */
43#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002)
44
45/* All commands for CPU have the following mask set */
46#define CPU_CMD_MASK 0x20000000
47#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000)
48#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
49#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
50#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
51
52#define EPU_CMD_MASK 0x02000000
53#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000)
54#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000)
55
56#define APU_CMD_MASK 0x10000000
57#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
58
59#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28)
60#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28)
61
62/* Description: Command APU to start audio
63 IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?)
64 IN[1] - caller buffer address, or 0
65 ReturnCode - ??? */
66#define CX18_APU_START (APU_CMD_MASK | 0x01)
67
68/* Description: Command APU to stop audio
69 IN[0] - encoding method to stop
70 ReturnCode - ??? */
71#define CX18_APU_STOP (APU_CMD_MASK | 0x02)
72
73/* Description: Command APU to reset the AI
74 ReturnCode - ??? */
75#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
76
77/* Description: This command indicates that a Memory Descriptor List has been
78 filled with the requested channel type
79 IN[0] - Task handle. Handle of the task
80 IN[1] - Offset of the MDL_ACK from the beginning of the local DDR.
81 IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1]
82 ReturnCode - One of the ERR_DE_... */
83#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001)
84
85/* Something interesting happened
86 IN[0] - A value to log
87 IN[1] - An offset of a string in the MiniMe memory;
88 0/zero/NULL means "I have nothing to say" */
89#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)
90
91/* Reads memory/registers (32-bit)
92 IN[0] - Address
93 OUT[1] - Value */
94#define CX18_CPU_DEBUG_PEEK32 (CPU_CMD_MASK_DEBUG | 0x0003)
95
96/* Description: This command starts streaming with the set channel type
97 IN[0] - Task handle. Handle of the task to start
98 ReturnCode - One of the ERR_CAPTURE_... */
99#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002)
100
101/* Description: This command stops streaming with the set channel type
102 IN[0] - Task handle. Handle of the task to stop
103 IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only)
104 ReturnCode - One of the ERR_CAPTURE_... */
105#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003)
106
107/* Description: This command pauses streaming with the set channel type
108 IN[0] - Task handle. Handle of the task to pause
109 ReturnCode - One of the ERR_CAPTURE_... */
110#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007)
111
112/* Description: This command resumes streaming with the set channel type
113 IN[0] - Task handle. Handle of the task to resume
114 ReturnCode - One of the ERR_CAPTURE_... */
115#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008)
116
117#define CAPTURE_CHANNEL_TYPE_NONE 0
118#define CAPTURE_CHANNEL_TYPE_MPEG 1
119#define CAPTURE_CHANNEL_TYPE_INDEX 2
120#define CAPTURE_CHANNEL_TYPE_YUV 3
121#define CAPTURE_CHANNEL_TYPE_PCM 4
122#define CAPTURE_CHANNEL_TYPE_VBI 5
123#define CAPTURE_CHANNEL_TYPE_SLICED_VBI 6
124#define CAPTURE_CHANNEL_TYPE_TS 7
125#define CAPTURE_CHANNEL_TYPE_MAX 15
126
127/* Description: This command sets the channel type. This can only be done
128 when stopped.
129 IN[0] - Task handle. Handle of the task to start
130 IN[1] - Channel Type. See Below.
131 ReturnCode - One of the ERR_CAPTURE_... */
132#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1)
133
134/* Description: Set stream output type
135 IN[0] - task handle. Handle of the task to start
136 IN[1] - type
137 ReturnCode - One of the ERR_CAPTURE_... */
138#define CX18_CPU_SET_STREAM_OUTPUT_TYPE (CPU_CMD_MASK_CAPTURE | 0x0012)
139
140/* Description: Set video input resolution and frame rate
141 IN[0] - task handle
142 IN[1] - reserved
143 IN[2] - reserved
144 IN[3] - reserved
145 IN[4] - reserved
146 IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s
147 ReturnCode - One of the ERR_CAPTURE_... */
148#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004)
149
150/* Description: Set video frame rate
151 IN[0] - task handle. Handle of the task to start
152 IN[1] - video bit rate mode
153 IN[2] - video average rate
154 IN[3] - video peak rate
155 IN[4] - system mux rate
156 ReturnCode - One of the ERR_CAPTURE_... */
157#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005)
158
159/* Description: Set video output resolution
160 IN[0] - task handle
161 IN[1] - horizontal size
162 IN[2] - vertical size
163 ReturnCode - One of the ERR_CAPTURE_... */
164#define CX18_CPU_SET_VIDEO_RESOLUTION (CPU_CMD_MASK_CAPTURE | 0x0006)
165
166/* Description: This command set filter parameters
167 IN[0] - Task handle. Handle of the task
168 IN[1] - type, 0 - temporal, 1 - spatial, 2 - median
169 IN[2] - mode, temporal/spatial: 0 - disable, 1 - static, 2 - dynamic
170 median: 0 = disable, 1 = horizontal, 2 = vertical,
171 3 = horizontal/vertical, 4 = diagonal
172 IN[3] - strength, temporal 0 - 31, spatial 0 - 15
173 ReturnCode - One of the ERR_CAPTURE_... */
174#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009)
175
176/* Description: This command set spatial filter type
177 IN[0] - Task handle.
178 IN[1] - luma type: 0 = disable, 1 = 1D horizontal only, 2 = 1D vertical only,
179 3 = 2D H/V separable, 4 = 2D symmetric non-separable
180 IN[2] - chroma type: 0 - disable, 1 = 1D horizontal
181 ReturnCode - One of the ERR_CAPTURE_... */
182#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C)
183
184/* Description: This command set coring levels for median filter
185 IN[0] - Task handle.
186 IN[1] - luma_high
187 IN[2] - luma_low
188 IN[3] - chroma_high
189 IN[4] - chroma_low
190 ReturnCode - One of the ERR_CAPTURE_... */
191#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
192
193/* Description: This command set the picture type mask for index file
194 IN[0] - Task handle (ignored by firmware)
195 IN[1] - 0 = disable index file output
196 1 = output I picture
197 2 = P picture
198 4 = B picture
199 other = illegal */
200#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010)
201
202/* Description: Set audio parameters
203 IN[0] - task handle. Handle of the task to start
204 IN[1] - audio parameter
205 ReturnCode - One of the ERR_CAPTURE_... */
206#define CX18_CPU_SET_AUDIO_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0011)
207
208/* Description: Set video mute
209 IN[0] - task handle. Handle of the task to start
210 IN[1] - bit31-24: muteYvalue
211 bit23-16: muteUvalue
212 bit15-8: muteVvalue
213 bit0: 1:mute, 0: unmute
214 ReturnCode - One of the ERR_CAPTURE_... */
215#define CX18_CPU_SET_VIDEO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0013)
216
217/* Description: Set audio mute
218 IN[0] - task handle. Handle of the task to start
219 IN[1] - mute/unmute
220 ReturnCode - One of the ERR_CAPTURE_... */
221#define CX18_CPU_SET_AUDIO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0014)
222
223/* Description: Set stream output type
224 IN[0] - task handle. Handle of the task to start
225 IN[1] - subType
226 SET_INITIAL_SCR 1
227 SET_QUALITY_MODE 2
228 SET_VIM_PROTECT_MODE 3
229 SET_PTS_CORRECTION 4
230 SET_USB_FLUSH_MODE 5
231 SET_MERAQPAR_ENABLE 6
232 SET_NAV_PACK_INSERTION 7
233 SET_SCENE_CHANGE_ENABLE 8
234 IN[2] - parameter 1
235 IN[3] - parameter 2
236 ReturnCode - One of the ERR_CAPTURE_... */
237#define CX18_CPU_SET_MISC_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0015)
238
239/* Description: Set raw VBI parameters
240 IN[0] - Task handle
241 IN[1] - No. of input lines per field:
242 bit[15:0]: field 1,
243 bit[31:16]: field 2
244 IN[2] - No. of input bytes per line
245 IN[3] - No. of output frames per transfer
246 IN[4] - start code
247 IN[5] - stop code
248 ReturnCode */
249#define CX18_CPU_SET_RAW_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0016)
250
251/* Description: Set capture line No.
252 IN[0] - task handle. Handle of the task to start
253 IN[1] - height1
254 IN[2] - height2
255 ReturnCode - One of the ERR_CAPTURE_... */
256#define CX18_CPU_SET_CAPTURE_LINE_NO (CPU_CMD_MASK_CAPTURE | 0x0017)
257
258/* Description: Set copyright
259 IN[0] - task handle. Handle of the task to start
260 IN[1] - copyright
261 ReturnCode - One of the ERR_CAPTURE_... */
262#define CX18_CPU_SET_COPYRIGHT (CPU_CMD_MASK_CAPTURE | 0x0018)
263
264/* Description: Set audio PID
265 IN[0] - task handle. Handle of the task to start
266 IN[1] - PID
267 ReturnCode - One of the ERR_CAPTURE_... */
268#define CX18_CPU_SET_AUDIO_PID (CPU_CMD_MASK_CAPTURE | 0x0019)
269
270/* Description: Set video PID
271 IN[0] - task handle. Handle of the task to start
272 IN[1] - PID
273 ReturnCode - One of the ERR_CAPTURE_... */
274#define CX18_CPU_SET_VIDEO_PID (CPU_CMD_MASK_CAPTURE | 0x001A)
275
276/* Description: Set Vertical Crop Line
277 IN[0] - task handle. Handle of the task to start
278 IN[1] - Line
279 ReturnCode - One of the ERR_CAPTURE_... */
280#define CX18_CPU_SET_VER_CROP_LINE (CPU_CMD_MASK_CAPTURE | 0x001B)
281
282/* Description: Set COP structure
283 IN[0] - task handle. Handle of the task to start
284 IN[1] - M
285 IN[2] - N
286 ReturnCode - One of the ERR_CAPTURE_... */
287#define CX18_CPU_SET_GOP_STRUCTURE (CPU_CMD_MASK_CAPTURE | 0x001C)
288
289/* Description: Set Scene Change Detection
290 IN[0] - task handle. Handle of the task to start
291 IN[1] - scene change
292 ReturnCode - One of the ERR_CAPTURE_... */
293#define CX18_CPU_SET_SCENE_CHANGE_DETECTION (CPU_CMD_MASK_CAPTURE | 0x001D)
294
295/* Description: Set Aspect Ratio
296 IN[0] - task handle. Handle of the task to start
297 IN[1] - AspectRatio
298 ReturnCode - One of the ERR_CAPTURE_... */
299#define CX18_CPU_SET_ASPECT_RATIO (CPU_CMD_MASK_CAPTURE | 0x001E)
300
301/* Description: Set Skip Input Frame
302 IN[0] - task handle. Handle of the task to start
303 IN[1] - skip input frames
304 ReturnCode - One of the ERR_CAPTURE_... */
305#define CX18_CPU_SET_SKIP_INPUT_FRAME (CPU_CMD_MASK_CAPTURE | 0x001F)
306
307/* Description: Set sliced VBI parameters -
308 Note This API will only apply to MPEG and Sliced VBI Channels
309 IN[0] - Task handle
310 IN[1] - output type, 0 - CC, 1 - Moji, 2 - Teletext
311 IN[2] - start / stop line
312 bit[15:0] start line number
313 bit[31:16] stop line number
314 IN[3] - number of output frames per interrupt
315 IN[4] - VBI insertion mode
316 bit 0: output user data, 1 - enable
317 bit 1: output private stream, 1 - enable
318 bit 2: mux option, 0 - in GOP, 1 - in picture
319 bit[7:0] private stream ID
320 IN[5] - insertion period while mux option is in picture
321 ReturnCode - VBI data offset */
322#define CX18_CPU_SET_SLICED_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0020)
323
324/* Description: Set the user data place holder
325 IN[0] - type of data (0 for user)
326 IN[1] - Stuffing period
327 IN[2] - ID data size in word (less than 10)
328 IN[3] - Pointer to ID buffer */
329#define CX18_CPU_SET_USERDATA_PLACE_HOLDER (CPU_CMD_MASK_CAPTURE | 0x0021)
330
331
332/* Description:
333 In[0] Task Handle
334 return parameter:
335 Out[0] Reserved
336 Out[1] Video PTS bit[32:2] of last output video frame.
337 Out[2] Video PTS bit[ 1:0] of last output video frame.
338 Out[3] Hardware Video PTS counter bit[31:0],
339 these bits get incremented on every 90kHz clock tick.
340 Out[4] Hardware Video PTS counter bit32,
341 these bits get incremented on every 90kHz clock tick.
342 ReturnCode */
343#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022)
344
345/* Description: Set VFC parameters
346 IN[0] - task handle
347 IN[1] - VFC enable flag, 1 - enable, 0 - disable
348*/
349#define CX18_CPU_SET_VFC_PARAM (CPU_CMD_MASK_CAPTURE | 0x0023)
350
351/* Below is the list of commands related to the data exchange */
352#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
353
354/* Description: This command provides the physical base address of the local
355 DDR as viewed by EPU
356 IN[0] - Physical offset where EPU has the local DDR mapped
357 ReturnCode - One of the ERR_DE_... */
358#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001)
359
360/* Description: This command provides the offsets in the device memory where
361 the 2 cx18_mdl_ack blocks reside
362 IN[0] - Task handle. Handle of the task to start
363 IN[1] - Offset of the first cx18_mdl_ack from the beginning of the
364 local DDR.
365 IN[2] - Offset of the second cx18_mdl_ack from the beginning of the
366 local DDR.
367 ReturnCode - One of the ERR_DE_... */
368#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002)
369
370/* Description: This command provides the offset to a Memory Descriptor List
371 IN[0] - Task handle. Handle of the task to start
372 IN[1] - Offset of the MDL from the beginning of the local DDR.
373 IN[2] - Number of cx18_mdl_ent structures in the array pointed to by IN[1]
374 IN[3] - Buffer ID
375 IN[4] - Total buffer length
376 ReturnCode - One of the ERR_DE_... */
377#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005)
378
379/* Description: This command requests return of all current Memory
380 Descriptor Lists to the driver
381 IN[0] - Task handle. Handle of the task to start
382 ReturnCode - One of the ERR_DE_... */
383#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006)
384
385/* Description: This command signals the cpu that the dat buffer has been
386 consumed and ready for re-use.
387 IN[0] - Task handle. Handle of the task
388 IN[1] - Offset of the data block from the beginning of the local DDR.
389 IN[2] - Number of bytes in the data block
390 ReturnCode - One of the ERR_DE_... */
391/* #define CX18_CPU_DE_RELEASE_BUFFER (CPU_CMD_MASK_DE | 0x0007) */
392
393/* No Error / Success */
394#define CNXT_OK 0x000000
395
396/* Received unknown command */
397#define CXERR_UNK_CMD 0x000001
398
399/* First parameter in the command is invalid */
400#define CXERR_INVALID_PARAM1 0x000002
401
402/* Second parameter in the command is invalid */
403#define CXERR_INVALID_PARAM2 0x000003
404
405/* Device interface is not open/found */
406#define CXERR_DEV_NOT_FOUND 0x000004
407
408/* Requested function is not implemented/available */
409#define CXERR_NOTSUPPORTED 0x000005
410
411/* Invalid pointer is provided */
412#define CXERR_BADPTR 0x000006
413
414/* Unable to allocate memory */
415#define CXERR_NOMEM 0x000007
416
417/* Object/Link not found */
418#define CXERR_LINK 0x000008
419
420/* Device busy, command cannot be executed */
421#define CXERR_BUSY 0x000009
422
423/* File/device/handle is not open. */
424#define CXERR_NOT_OPEN 0x00000A
425
426/* Value is out of range */
427#define CXERR_OUTOFRANGE 0x00000B
428
429/* Buffer overflow */
430#define CXERR_OVERFLOW 0x00000C
431
432/* Version mismatch */
433#define CXERR_BADVER 0x00000D
434
435/* Operation timed out */
436#define CXERR_TIMEOUT 0x00000E
437
438/* Operation aborted */
439#define CXERR_ABORT 0x00000F
440
441/* Specified I2C device not found for read/write */
442#define CXERR_I2CDEV_NOTFOUND 0x000010
443
444/* Error in I2C data xfer (but I2C device is present) */
445#define CXERR_I2CDEV_XFERERR 0x000011
446
447/* Chanel changing component not ready */
448#define CXERR_CHANNELNOTREADY 0x000012
449
450/* PPU (Presensation/Decoder) mail box is corrupted */
451#define CXERR_PPU_MB_CORRUPT 0x000013
452
453/* CPU (Capture/Encoder) mail box is corrupted */
454#define CXERR_CPU_MB_CORRUPT 0x000014
455
456/* APU (Audio) mail box is corrupted */
457#define CXERR_APU_MB_CORRUPT 0x000015
458
459/* Unable to open file for reading */
460#define CXERR_FILE_OPEN_READ 0x000016
461
462/* Unable to open file for writing */
463#define CXERR_FILE_OPEN_WRITE 0x000017
464
465/* Unable to find the I2C section specified */
466#define CXERR_I2C_BADSECTION 0x000018
467
468/* Error in I2C data xfer (but I2C device is present) */
469#define CXERR_I2CDEV_DATALOW 0x000019
470
471/* Error in I2C data xfer (but I2C device is present) */
472#define CXERR_I2CDEV_CLOCKLOW 0x00001A
473
474/* No Interrupt received from HW (for I2C access) */
475#define CXERR_NO_HW_I2C_INTR 0x00001B
476
477/* RPU is not ready to accept commands! */
478#define CXERR_RPU_NOT_READY 0x00001C
479
480/* RPU is not ready to accept commands! */
481#define CXERR_RPU_NO_ACK 0x00001D
482
483/* The are no buffers ready. Try again soon! */
484#define CXERR_NODATA_AGAIN 0x00001E
485
486/* The stream is stopping. Function not allowed now! */
487#define CXERR_STOPPING_STATUS 0x00001F
488
489/* Trying to access hardware when the power is turned OFF */
490#define CXERR_DEVPOWER_OFF 0x000020
491
492#endif /* CX23418_H */