aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/pci/cx18
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/pci/cx18')
-rw-r--r--drivers/media/pci/cx18/Kconfig35
-rw-r--r--drivers/media/pci/cx18/Makefile13
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-main.c295
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-mixer.c175
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-mixer.h23
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-pcm.c356
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-pcm.h27
-rw-r--r--drivers/media/pci/cx18/cx18-alsa.h75
-rw-r--r--drivers/media/pci/cx18/cx18-audio.c92
-rw-r--r--drivers/media/pci/cx18/cx18-audio.h24
-rw-r--r--drivers/media/pci/cx18/cx18-av-audio.c471
-rw-r--r--drivers/media/pci/cx18/cx18-av-core.c1401
-rw-r--r--drivers/media/pci/cx18/cx18-av-core.h391
-rw-r--r--drivers/media/pci/cx18/cx18-av-firmware.c225
-rw-r--r--drivers/media/pci/cx18/cx18-av-vbi.c311
-rw-r--r--drivers/media/pci/cx18/cx18-cards.c638
-rw-r--r--drivers/media/pci/cx18/cx18-cards.h157
-rw-r--r--drivers/media/pci/cx18/cx18-controls.c131
-rw-r--r--drivers/media/pci/cx18/cx18-controls.h24
-rw-r--r--drivers/media/pci/cx18/cx18-driver.c1360
-rw-r--r--drivers/media/pci/cx18/cx18-driver.h730
-rw-r--r--drivers/media/pci/cx18/cx18-dvb.c609
-rw-r--r--drivers/media/pci/cx18/cx18-dvb.h25
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.c881
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.h41
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.c459
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.h25
-rw-r--r--drivers/media/pci/cx18/cx18-gpio.c347
-rw-r--r--drivers/media/pci/cx18/cx18-gpio.h34
-rw-r--r--drivers/media/pci/cx18/cx18-i2c.c330
-rw-r--r--drivers/media/pci/cx18/cx18-i2c.h29
-rw-r--r--drivers/media/pci/cx18/cx18-io.c97
-rw-r--r--drivers/media/pci/cx18/cx18-io.h191
-rw-r--r--drivers/media/pci/cx18/cx18-ioctl.c1194
-rw-r--r--drivers/media/pci/cx18/cx18-ioctl.h31
-rw-r--r--drivers/media/pci/cx18/cx18-irq.c81
-rw-r--r--drivers/media/pci/cx18/cx18-irq.h35
-rw-r--r--drivers/media/pci/cx18/cx18-mailbox.c870
-rw-r--r--drivers/media/pci/cx18/cx18-mailbox.h95
-rw-r--r--drivers/media/pci/cx18/cx18-queue.c443
-rw-r--r--drivers/media/pci/cx18/cx18-queue.h98
-rw-r--r--drivers/media/pci/cx18/cx18-scb.c122
-rw-r--r--drivers/media/pci/cx18/cx18-scb.h280
-rw-r--r--drivers/media/pci/cx18/cx18-streams.c1060
-rw-r--r--drivers/media/pci/cx18/cx18-streams.h62
-rw-r--r--drivers/media/pci/cx18/cx18-vbi.c277
-rw-r--r--drivers/media/pci/cx18/cx18-vbi.h26
-rw-r--r--drivers/media/pci/cx18/cx18-version.h28
-rw-r--r--drivers/media/pci/cx18/cx18-video.c32
-rw-r--r--drivers/media/pci/cx18/cx18-video.h22
-rw-r--r--drivers/media/pci/cx18/cx23418.h492
51 files changed, 15270 insertions, 0 deletions
diff --git a/drivers/media/pci/cx18/Kconfig b/drivers/media/pci/cx18/Kconfig
new file mode 100644
index 000000000000..53b3c7702573
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/Makefile b/drivers/media/pci/cx18/Makefile
new file mode 100644
index 000000000000..d3ff1545c2c5
--- /dev/null
+++ b/drivers/media/pci/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
11ccflags-y += -Idrivers/media/dvb-core
12ccflags-y += -Idrivers/media/dvb-frontends
13ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c
new file mode 100644
index 000000000000..6d2a98246b6d
--- /dev/null
+++ b/drivers/media/pci/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 (void)ret; /* suppress compiler warning */
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/pci/cx18/cx18-alsa-mixer.c b/drivers/media/pci/cx18/cx18-alsa-mixer.c
new file mode 100644
index 000000000000..341bddc00b77
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-alsa-mixer.h b/drivers/media/pci/cx18/cx18-alsa-mixer.h
new file mode 100644
index 000000000000..ec9238793f6f
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-alsa-pcm.c b/drivers/media/pci/cx18/cx18-alsa-pcm.c
new file mode 100644
index 000000000000..7a5b84a86bb3
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-alsa-pcm.c
@@ -0,0 +1,356 @@
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 ret;
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
203 /* Instruct the cx18 to stop sending packets */
204 snd_cx18_lock(cxsc);
205 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
206 cx18_stop_v4l2_encode_stream(s, 0);
207 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
208
209 cx18_release_stream(s);
210
211 cx->pcm_announce_callback = NULL;
212 snd_cx18_unlock(cxsc);
213
214 return 0;
215}
216
217static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
218 unsigned int cmd, void *arg)
219{
220 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
221 int ret;
222
223 snd_cx18_lock(cxsc);
224 ret = snd_pcm_lib_ioctl(substream, cmd, arg);
225 snd_cx18_unlock(cxsc);
226 return ret;
227}
228
229
230static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
231 size_t size)
232{
233 struct snd_pcm_runtime *runtime = subs->runtime;
234
235 dprintk("Allocating vbuffer\n");
236 if (runtime->dma_area) {
237 if (runtime->dma_bytes > size)
238 return 0;
239
240 vfree(runtime->dma_area);
241 }
242 runtime->dma_area = vmalloc(size);
243 if (!runtime->dma_area)
244 return -ENOMEM;
245
246 runtime->dma_bytes = size;
247
248 return 0;
249}
250
251static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
252 struct snd_pcm_hw_params *params)
253{
254 dprintk("%s called\n", __func__);
255
256 return snd_pcm_alloc_vmalloc_buffer(substream,
257 params_buffer_bytes(params));
258}
259
260static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
261{
262 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
263 unsigned long flags;
264
265 spin_lock_irqsave(&cxsc->slock, flags);
266 if (substream->runtime->dma_area) {
267 dprintk("freeing pcm capture region\n");
268 vfree(substream->runtime->dma_area);
269 substream->runtime->dma_area = NULL;
270 }
271 spin_unlock_irqrestore(&cxsc->slock, flags);
272
273 return 0;
274}
275
276static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
277{
278 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
279
280 cxsc->hwptr_done_capture = 0;
281 cxsc->capture_transfer_done = 0;
282
283 return 0;
284}
285
286static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
287{
288 return 0;
289}
290
291static
292snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
293{
294 unsigned long flags;
295 snd_pcm_uframes_t hwptr_done;
296 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
297
298 spin_lock_irqsave(&cxsc->slock, flags);
299 hwptr_done = cxsc->hwptr_done_capture;
300 spin_unlock_irqrestore(&cxsc->slock, flags);
301
302 return hwptr_done;
303}
304
305static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
306 unsigned long offset)
307{
308 void *pageptr = subs->runtime->dma_area + offset;
309
310 return vmalloc_to_page(pageptr);
311}
312
313static struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
314 .open = snd_cx18_pcm_capture_open,
315 .close = snd_cx18_pcm_capture_close,
316 .ioctl = snd_cx18_pcm_ioctl,
317 .hw_params = snd_cx18_pcm_hw_params,
318 .hw_free = snd_cx18_pcm_hw_free,
319 .prepare = snd_cx18_pcm_prepare,
320 .trigger = snd_cx18_pcm_trigger,
321 .pointer = snd_cx18_pcm_pointer,
322 .page = snd_pcm_get_vmalloc_page,
323};
324
325int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
326{
327 struct snd_pcm *sp;
328 struct snd_card *sc = cxsc->sc;
329 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
330 struct cx18 *cx = to_cx18(v4l2_dev);
331 int ret;
332
333 ret = snd_pcm_new(sc, "CX23418 PCM",
334 0, /* PCM device 0, the only one for this card */
335 0, /* 0 playback substreams */
336 1, /* 1 capture substream */
337 &sp);
338 if (ret) {
339 CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
340 __func__, ret);
341 goto err_exit;
342 }
343
344 spin_lock_init(&cxsc->slock);
345
346 snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
347 &snd_cx18_pcm_capture_ops);
348 sp->info_flags = 0;
349 sp->private_data = cxsc;
350 strlcpy(sp->name, cx->card_name, sizeof(sp->name));
351
352 return 0;
353
354err_exit:
355 return ret;
356}
diff --git a/drivers/media/pci/cx18/cx18-alsa-pcm.h b/drivers/media/pci/cx18/cx18-alsa-pcm.h
new file mode 100644
index 000000000000..d26e51f94577
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-alsa.h b/drivers/media/pci/cx18/cx18-alsa.h
new file mode 100644
index 000000000000..447da374c9e8
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-audio.c b/drivers/media/pci/cx18/cx18-audio.c
new file mode 100644
index 000000000000..35268923911c
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-audio.h b/drivers/media/pci/cx18/cx18-audio.h
new file mode 100644
index 000000000000..2731d29b0ab9
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-av-audio.c b/drivers/media/pci/cx18/cx18-av-audio.c
new file mode 100644
index 000000000000..4a24ffb17a7d
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c
new file mode 100644
index 000000000000..f164b7f610a5
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-av-core.h b/drivers/media/pci/cx18/cx18-av-core.h
new file mode 100644
index 000000000000..e9c69d9c9e4a
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-av-firmware.c b/drivers/media/pci/cx18/cx18-av-firmware.c
new file mode 100644
index 000000000000..a34fd082b76e
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-av-firmware.c
@@ -0,0 +1,225 @@
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}
224
225MODULE_FIRMWARE(FWFILE);
diff --git a/drivers/media/pci/cx18/cx18-av-vbi.c b/drivers/media/pci/cx18/cx18-av-vbi.c
new file mode 100644
index 000000000000..baa36fbcd4d4
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-cards.c b/drivers/media/pci/cx18/cx18-cards.c
new file mode 100644
index 000000000000..c07c849b1aaf
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-cards.h b/drivers/media/pci/cx18/cx18-cards.h
new file mode 100644
index 000000000000..add7391ecaba
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-controls.c b/drivers/media/pci/cx18/cx18-controls.c
new file mode 100644
index 000000000000..282a3d29fdaa
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-controls.h b/drivers/media/pci/cx18/cx18-controls.h
new file mode 100644
index 000000000000..cb5dfc7b2054
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
new file mode 100644
index 000000000000..c67733d32c8a
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-driver.c
@@ -0,0 +1,1360 @@
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#include <linux/dma-mapping.h>
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, int, &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, DMA_BIT_MASK(32))) {
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%llx\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, (u64)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%llx\n", (u64)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%llx len 0x%08x\n",
950 (u64)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 if (cx->options.radio > 0)
1089 setup.mode_mask |= T_RADIO;
1090 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
1091 cx18_reset_tuner_gpio : NULL;
1092 cx18_call_all(cx, tuner, s_type_addr, &setup);
1093 if (setup.type == TUNER_XC2028) {
1094 static struct xc2028_ctrl ctrl = {
1095 .fname = XC2028_DEFAULT_FIRMWARE,
1096 .max_len = 64,
1097 };
1098 struct v4l2_priv_tun_config cfg = {
1099 .tuner = cx->options.tuner,
1100 .priv = &ctrl,
1101 };
1102 cx18_call_all(cx, tuner, s_config, &cfg);
1103 }
1104 }
1105
1106 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
1107 are not. */
1108 cx->tuner_std = cx->std;
1109 if (cx->std == V4L2_STD_ALL)
1110 cx->std = V4L2_STD_NTSC_M;
1111
1112 retval = cx18_streams_setup(cx);
1113 if (retval) {
1114 CX18_ERR("Error %d setting up streams\n", retval);
1115 goto free_irq;
1116 }
1117 retval = cx18_streams_register(cx);
1118 if (retval) {
1119 CX18_ERR("Error %d registering devices\n", retval);
1120 goto free_streams;
1121 }
1122
1123 CX18_INFO("Initialized card: %s\n", cx->card_name);
1124
1125 /* Load cx18 submodules (cx18-alsa) */
1126 request_modules(cx);
1127 return 0;
1128
1129free_streams:
1130 cx18_streams_cleanup(cx, 1);
1131free_irq:
1132 free_irq(cx->pci_dev->irq, (void *)cx);
1133free_i2c:
1134 exit_cx18_i2c(cx);
1135free_map:
1136 cx18_iounmap(cx);
1137free_mem:
1138 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
1139free_workqueues:
1140 destroy_workqueue(cx->in_work_queue);
1141err:
1142 if (retval == 0)
1143 retval = -ENODEV;
1144 CX18_ERR("Error %d on initialization\n", retval);
1145
1146 v4l2_device_unregister(&cx->v4l2_dev);
1147 kfree(cx);
1148 return retval;
1149}
1150
1151int cx18_init_on_first_open(struct cx18 *cx)
1152{
1153 int video_input;
1154 int fw_retry_count = 3;
1155 struct v4l2_frequency vf;
1156 struct cx18_open_id fh;
1157 v4l2_std_id std;
1158
1159 fh.cx = cx;
1160
1161 if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
1162 return -ENXIO;
1163
1164 if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags))
1165 return 0;
1166
1167 while (--fw_retry_count > 0) {
1168 /* load firmware */
1169 if (cx18_firmware_init(cx) == 0)
1170 break;
1171 if (fw_retry_count > 1)
1172 CX18_WARN("Retry loading firmware\n");
1173 }
1174
1175 if (fw_retry_count == 0) {
1176 set_bit(CX18_F_I_FAILED, &cx->i_flags);
1177 return -ENXIO;
1178 }
1179 set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
1180
1181 /*
1182 * Init the firmware twice to work around a silicon bug
1183 * with the digital TS.
1184 *
1185 * The second firmware load requires us to normalize the APU state,
1186 * or the audio for the first analog capture will be badly incorrect.
1187 *
1188 * I can't seem to call APU_RESETAI and have it succeed without the
1189 * APU capturing audio, so we start and stop it here to do the reset
1190 */
1191
1192 /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
1193 cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
1194 cx18_vapi(cx, CX18_APU_RESETAI, 0);
1195 cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
1196
1197 fw_retry_count = 3;
1198 while (--fw_retry_count > 0) {
1199 /* load firmware */
1200 if (cx18_firmware_init(cx) == 0)
1201 break;
1202 if (fw_retry_count > 1)
1203 CX18_WARN("Retry loading firmware\n");
1204 }
1205
1206 if (fw_retry_count == 0) {
1207 set_bit(CX18_F_I_FAILED, &cx->i_flags);
1208 return -ENXIO;
1209 }
1210
1211 /*
1212 * The second firmware load requires us to normalize the APU state,
1213 * or the audio for the first analog capture will be badly incorrect.
1214 *
1215 * I can't seem to call APU_RESETAI and have it succeed without the
1216 * APU capturing audio, so we start and stop it here to do the reset
1217 */
1218
1219 /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
1220 cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
1221 cx18_vapi(cx, CX18_APU_RESETAI, 0);
1222 cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
1223
1224 /* Init the A/V decoder, if it hasn't been already */
1225 v4l2_subdev_call(cx->sd_av, core, load_fw);
1226
1227 vf.tuner = 0;
1228 vf.type = V4L2_TUNER_ANALOG_TV;
1229 vf.frequency = 6400; /* the tuner 'baseline' frequency */
1230
1231 /* Set initial frequency. For PAL/SECAM broadcasts no
1232 'default' channel exists AFAIK. */
1233 if (cx->std == V4L2_STD_NTSC_M_JP)
1234 vf.frequency = 1460; /* ch. 1 91250*16/1000 */
1235 else if (cx->std & V4L2_STD_NTSC_M)
1236 vf.frequency = 1076; /* ch. 4 67250*16/1000 */
1237
1238 video_input = cx->active_input;
1239 cx->active_input++; /* Force update of input */
1240 cx18_s_input(NULL, &fh, video_input);
1241
1242 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
1243 in one place. */
1244 cx->std++; /* Force full standard initialization */
1245 std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
1246 cx18_s_std(NULL, &fh, &std);
1247 cx18_s_frequency(NULL, &fh, &vf);
1248 return 0;
1249}
1250
1251static void cx18_cancel_in_work_orders(struct cx18 *cx)
1252{
1253 int i;
1254 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++)
1255 cancel_work_sync(&cx->in_work_order[i].work);
1256}
1257
1258static void cx18_cancel_out_work_orders(struct cx18 *cx)
1259{
1260 int i;
1261 for (i = 0; i < CX18_MAX_STREAMS; i++)
1262 if (&cx->streams[i].video_dev != NULL)
1263 cancel_work_sync(&cx->streams[i].out_work_order);
1264}
1265
1266static void cx18_remove(struct pci_dev *pci_dev)
1267{
1268 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1269 struct cx18 *cx = to_cx18(v4l2_dev);
1270 int i;
1271
1272 CX18_DEBUG_INFO("Removing Card\n");
1273
1274 flush_request_modules(cx);
1275
1276 /* Stop all captures */
1277 CX18_DEBUG_INFO("Stopping all streams\n");
1278 if (atomic_read(&cx->tot_capturing) > 0)
1279 cx18_stop_all_captures(cx);
1280
1281 /* Stop interrupts that cause incoming work to be queued */
1282 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
1283
1284 /* Incoming work can cause outgoing work, so clean up incoming first */
1285 cx18_cancel_in_work_orders(cx);
1286 cx18_cancel_out_work_orders(cx);
1287
1288 /* Stop ack interrupts that may have been needed for work to finish */
1289 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
1290
1291 cx18_halt_firmware(cx);
1292
1293 destroy_workqueue(cx->in_work_queue);
1294
1295 cx18_streams_cleanup(cx, 1);
1296
1297 exit_cx18_i2c(cx);
1298
1299 free_irq(cx->pci_dev->irq, (void *)cx);
1300
1301 cx18_iounmap(cx);
1302
1303 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
1304
1305 pci_disable_device(cx->pci_dev);
1306
1307 if (cx->vbi.sliced_mpeg_data[0] != NULL)
1308 for (i = 0; i < CX18_VBI_FRAMES; i++)
1309 kfree(cx->vbi.sliced_mpeg_data[i]);
1310
1311 v4l2_ctrl_handler_free(&cx->av_state.hdl);
1312
1313 CX18_INFO("Removed %s\n", cx->card_name);
1314
1315 v4l2_device_unregister(v4l2_dev);
1316 kfree(cx);
1317}
1318
1319
1320/* define a pci_driver for card detection */
1321static struct pci_driver cx18_pci_driver = {
1322 .name = "cx18",
1323 .id_table = cx18_pci_tbl,
1324 .probe = cx18_probe,
1325 .remove = cx18_remove,
1326};
1327
1328static int __init module_start(void)
1329{
1330 printk(KERN_INFO "cx18: Start initialization, version %s\n",
1331 CX18_VERSION);
1332
1333 /* Validate parameters */
1334 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
1335 printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
1336 CX18_MAX_CARDS - 1);
1337 return -1;
1338 }
1339
1340 if (cx18_debug < 0 || cx18_debug > 511) {
1341 cx18_debug = 0;
1342 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
1343 }
1344
1345 if (pci_register_driver(&cx18_pci_driver)) {
1346 printk(KERN_ERR "cx18: Error detecting PCI card\n");
1347 return -ENODEV;
1348 }
1349 printk(KERN_INFO "cx18: End initialization\n");
1350 return 0;
1351}
1352
1353static void __exit module_cleanup(void)
1354{
1355 pci_unregister_driver(&cx18_pci_driver);
1356}
1357
1358module_init(module_start);
1359module_exit(module_cleanup);
1360MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h
new file mode 100644
index 000000000000..2767c64df0c8
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-driver.h
@@ -0,0 +1,730 @@
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 <media/v4l2-common.h>
48#include <media/v4l2-ioctl.h>
49#include <media/v4l2-device.h>
50#include <media/v4l2-fh.h>
51#include <media/tuner.h>
52#include <media/ir-kbd-i2c.h>
53#include "cx18-mailbox.h"
54#include "cx18-av-core.h"
55#include "cx23418.h"
56
57/* DVB */
58#include "demux.h"
59#include "dmxdev.h"
60#include "dvb_demux.h"
61#include "dvb_frontend.h"
62#include "dvb_net.h"
63#include "dvbdev.h"
64
65/* Videobuf / YUV support */
66#include <media/videobuf-core.h>
67#include <media/videobuf-vmalloc.h>
68
69#ifndef CONFIG_PCI
70# error "This driver requires kernel PCI support."
71#endif
72
73#define CX18_MEM_OFFSET 0x00000000
74#define CX18_MEM_SIZE 0x04000000
75#define CX18_REG_OFFSET 0x02000000
76
77/* Maximum cx18 driver instances. */
78#define CX18_MAX_CARDS 32
79
80/* Supported cards */
81#define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */
82#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
83#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
84#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
85#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
86#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
87#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
88#define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */
89#define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */
90#define CX18_CARD_HVR_1600_S5H1411 9 /* Hauppauge HVR 1600 s5h1411/tda18271*/
91#define CX18_CARD_LAST 9
92
93#define CX18_ENC_STREAM_TYPE_MPG 0
94#define CX18_ENC_STREAM_TYPE_TS 1
95#define CX18_ENC_STREAM_TYPE_YUV 2
96#define CX18_ENC_STREAM_TYPE_VBI 3
97#define CX18_ENC_STREAM_TYPE_PCM 4
98#define CX18_ENC_STREAM_TYPE_IDX 5
99#define CX18_ENC_STREAM_TYPE_RAD 6
100#define CX18_MAX_STREAMS 7
101
102/* system vendor and device IDs */
103#define PCI_VENDOR_ID_CX 0x14f1
104#define PCI_DEVICE_ID_CX23418 0x5b7a
105
106/* subsystem vendor ID */
107#define CX18_PCI_ID_HAUPPAUGE 0x0070
108#define CX18_PCI_ID_COMPRO 0x185b
109#define CX18_PCI_ID_YUAN 0x12ab
110#define CX18_PCI_ID_CONEXANT 0x14f1
111#define CX18_PCI_ID_TOSHIBA 0x1179
112#define CX18_PCI_ID_LEADTEK 0x107D
113#define CX18_PCI_ID_GOTVIEW 0x5854
114
115/* ======================================================================== */
116/* ========================== START USER SETTABLE DMA VARIABLES =========== */
117/* ======================================================================== */
118
119/* DMA Buffers, Default size in MB allocated */
120#define CX18_DEFAULT_ENC_TS_BUFFERS 1
121#define CX18_DEFAULT_ENC_MPG_BUFFERS 2
122#define CX18_DEFAULT_ENC_IDX_BUFFERS 1
123#define CX18_DEFAULT_ENC_YUV_BUFFERS 2
124#define CX18_DEFAULT_ENC_VBI_BUFFERS 1
125#define CX18_DEFAULT_ENC_PCM_BUFFERS 1
126
127/* Maximum firmware DMA buffers per stream */
128#define CX18_MAX_FW_MDLS_PER_STREAM 63
129
130/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
131#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */
132#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
133#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
134
135/* IDX buffer size should be a multiple of the index entry size from the chip */
136struct cx18_enc_idx_entry {
137 __le32 length;
138 __le32 offset_low;
139 __le32 offset_high;
140 __le32 flags;
141 __le32 pts_low;
142 __le32 pts_high;
143} __attribute__ ((packed));
144#define CX18_UNIT_ENC_IDX_BUFSIZE \
145 (sizeof(struct cx18_enc_idx_entry) * V4L2_ENC_IDX_ENTRIES)
146
147/* DMA buffer, default size in kB allocated */
148#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
149#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
150#define CX18_DEFAULT_ENC_IDX_BUFSIZE (CX18_UNIT_ENC_IDX_BUFSIZE * 1 / 1024 + 1)
151#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
152#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
153
154/* i2c stuff */
155#define I2C_CLIENTS_MAX 16
156
157/* debugging */
158
159/* Flag to turn on high volume debugging */
160#define CX18_DBGFLG_WARN (1 << 0)
161#define CX18_DBGFLG_INFO (1 << 1)
162#define CX18_DBGFLG_API (1 << 2)
163#define CX18_DBGFLG_DMA (1 << 3)
164#define CX18_DBGFLG_IOCTL (1 << 4)
165#define CX18_DBGFLG_FILE (1 << 5)
166#define CX18_DBGFLG_I2C (1 << 6)
167#define CX18_DBGFLG_IRQ (1 << 7)
168/* Flag to turn on high volume debugging */
169#define CX18_DBGFLG_HIGHVOL (1 << 8)
170
171/* NOTE: extra space before comma in 'fmt , ## args' is required for
172 gcc-2.95, otherwise it won't compile. */
173#define CX18_DEBUG(x, type, fmt, args...) \
174 do { \
175 if ((x) & cx18_debug) \
176 v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
177 } while (0)
178#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
179#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
180#define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args)
181#define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args)
182#define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
183#define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args)
184#define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
185#define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
186
187#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
188 do { \
189 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
190 v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
191 } while (0)
192#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
193#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
194#define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args)
195#define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args)
196#define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
197#define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args)
198#define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
199#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
200
201/* Standard kernel messages */
202#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
203#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
204#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
205
206/* Messages for internal subdevs to use */
207#define CX18_DEBUG_DEV(x, dev, type, fmt, args...) \
208 do { \
209 if ((x) & cx18_debug) \
210 v4l2_info(dev, " " type ": " fmt , ## args); \
211 } while (0)
212#define CX18_DEBUG_WARN_DEV(dev, fmt, args...) \
213 CX18_DEBUG_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
214#define CX18_DEBUG_INFO_DEV(dev, fmt, args...) \
215 CX18_DEBUG_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
216#define CX18_DEBUG_API_DEV(dev, fmt, args...) \
217 CX18_DEBUG_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
218#define CX18_DEBUG_DMA_DEV(dev, fmt, args...) \
219 CX18_DEBUG_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
220#define CX18_DEBUG_IOCTL_DEV(dev, fmt, args...) \
221 CX18_DEBUG_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
222#define CX18_DEBUG_FILE_DEV(dev, fmt, args...) \
223 CX18_DEBUG_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
224#define CX18_DEBUG_I2C_DEV(dev, fmt, args...) \
225 CX18_DEBUG_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
226#define CX18_DEBUG_IRQ_DEV(dev, fmt, args...) \
227 CX18_DEBUG_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
228
229#define CX18_DEBUG_HIGH_VOL_DEV(x, dev, type, fmt, args...) \
230 do { \
231 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
232 v4l2_info(dev, " " type ": " fmt , ## args); \
233 } while (0)
234#define CX18_DEBUG_HI_WARN_DEV(dev, fmt, args...) \
235 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
236#define CX18_DEBUG_HI_INFO_DEV(dev, fmt, args...) \
237 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
238#define CX18_DEBUG_HI_API_DEV(dev, fmt, args...) \
239 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
240#define CX18_DEBUG_HI_DMA_DEV(dev, fmt, args...) \
241 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
242#define CX18_DEBUG_HI_IOCTL_DEV(dev, fmt, args...) \
243 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
244#define CX18_DEBUG_HI_FILE_DEV(dev, fmt, args...) \
245 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
246#define CX18_DEBUG_HI_I2C_DEV(dev, fmt, args...) \
247 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
248#define CX18_DEBUG_HI_IRQ_DEV(dev, fmt, args...) \
249 CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
250
251#define CX18_ERR_DEV(dev, fmt, args...) v4l2_err(dev, fmt , ## args)
252#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args)
253#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args)
254
255extern int cx18_debug;
256
257struct cx18_options {
258 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
259 int cardtype; /* force card type on load */
260 int tuner; /* set tuner on load */
261 int radio; /* enable/disable radio */
262};
263
264/* per-mdl bit flags */
265#define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianess swapped */
266
267/* per-stream, s_flags */
268#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
269#define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
270#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
271#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
272#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
273#define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */
274
275/* per-cx18, i_flags */
276#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
277#define CX18_F_I_EOS 4 /* End of encoder stream */
278#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */
279#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
280#define CX18_F_I_INITED 21 /* set after first open */
281#define CX18_F_I_FAILED 22 /* set if first open failed */
282
283/* These are the VBI types as they appear in the embedded VBI private packets. */
284#define CX18_SLICED_TYPE_TELETEXT_B (1)
285#define CX18_SLICED_TYPE_CAPTION_525 (4)
286#define CX18_SLICED_TYPE_WSS_625 (5)
287#define CX18_SLICED_TYPE_VPS (7)
288
289/**
290 * list_entry_is_past_end - check if a previous loop cursor is off list end
291 * @pos: the type * previously used as a loop cursor.
292 * @head: the head for your list.
293 * @member: the name of the list_struct within the struct.
294 *
295 * Check if the entry's list_head is the head of the list, thus it's not a
296 * real entry but was the loop cursor that walked past the end
297 */
298#define list_entry_is_past_end(pos, head, member) \
299 (&pos->member == (head))
300
301struct cx18_buffer {
302 struct list_head list;
303 dma_addr_t dma_handle;
304 char *buf;
305
306 u32 bytesused;
307 u32 readpos;
308};
309
310struct cx18_mdl {
311 struct list_head list;
312 u32 id; /* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */
313
314 unsigned int skipped;
315 unsigned long m_flags;
316
317 struct list_head buf_list;
318 struct cx18_buffer *curr_buf; /* current buffer in list for reading */
319
320 u32 bytesused;
321 u32 readpos;
322};
323
324struct cx18_queue {
325 struct list_head list;
326 atomic_t depth;
327 u32 bytesused;
328 spinlock_t lock;
329};
330
331struct cx18_stream; /* forward reference */
332
333struct cx18_dvb {
334 struct cx18_stream *stream;
335 struct dmx_frontend hw_frontend;
336 struct dmx_frontend mem_frontend;
337 struct dmxdev dmxdev;
338 struct dvb_adapter dvb_adapter;
339 struct dvb_demux demux;
340 struct dvb_frontend *fe;
341 struct dvb_net dvbnet;
342 int enabled;
343 int feeding;
344 struct mutex feedlock;
345};
346
347struct cx18; /* forward reference */
348struct cx18_scb; /* forward reference */
349
350
351#define CX18_MAX_MDL_ACKS 2
352#define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
353/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
354
355#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
356#define CX18_F_EWO_MB_STALE_WHILE_PROC 0x2
357#define CX18_F_EWO_MB_STALE \
358 (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
359
360struct cx18_in_work_order {
361 struct work_struct work;
362 atomic_t pending;
363 struct cx18 *cx;
364 unsigned long flags;
365 int rpu;
366 struct cx18_mailbox mb;
367 struct cx18_mdl_ack mdl_ack[CX18_MAX_MDL_ACKS];
368 char *str;
369};
370
371#define CX18_INVALID_TASK_HANDLE 0xffffffff
372
373struct cx18_stream {
374 /* These first five fields are always set, even if the stream
375 is not actually created. */
376 struct video_device *video_dev; /* NULL when stream not created */
377 struct cx18_dvb *dvb; /* DVB / Digital Transport */
378 struct cx18 *cx; /* for ease of use */
379 const char *name; /* name of the stream */
380 int type; /* stream type */
381 u32 handle; /* task handle */
382 unsigned int mdl_base_idx;
383
384 u32 id;
385 unsigned long s_flags; /* status flags, see above */
386 int dma; /* can be PCI_DMA_TODEVICE,
387 PCI_DMA_FROMDEVICE or
388 PCI_DMA_NONE */
389 wait_queue_head_t waitq;
390
391 /* Buffers */
392 struct list_head buf_pool; /* buffers not attached to an MDL */
393 u32 buffers; /* total buffers owned by this stream */
394 u32 buf_size; /* size in bytes of a single buffer */
395
396 /* MDL sizes - all stream MDLs are the same size */
397 u32 bufs_per_mdl;
398 u32 mdl_size; /* total bytes in all buffers in a mdl */
399
400 /* MDL Queues */
401 struct cx18_queue q_free; /* free - in rotation, not committed */
402 struct cx18_queue q_busy; /* busy - in use by firmware */
403 struct cx18_queue q_full; /* full - data for user apps */
404 struct cx18_queue q_idle; /* idle - not in rotation */
405
406 struct work_struct out_work_order;
407
408 /* Videobuf for YUV video */
409 u32 pixelformat;
410 u32 vb_bytes_per_frame;
411 struct list_head vb_capture; /* video capture queue */
412 spinlock_t vb_lock;
413 struct timer_list vb_timeout;
414
415 struct videobuf_queue vbuf_q;
416 spinlock_t vbuf_q_lock; /* Protect vbuf_q */
417 enum v4l2_buf_type vb_type;
418};
419
420struct cx18_videobuf_buffer {
421 /* Common video buffer sub-system struct */
422 struct videobuf_buffer vb;
423 v4l2_std_id tvnorm; /* selected tv norm */
424 u32 bytes_used;
425};
426
427struct cx18_open_id {
428 struct v4l2_fh fh;
429 u32 open_id;
430 int type;
431 struct cx18 *cx;
432};
433
434static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
435{
436 return container_of(fh, struct cx18_open_id, fh);
437}
438
439static inline struct cx18_open_id *file2id(struct file *file)
440{
441 return fh2id(file->private_data);
442}
443
444/* forward declaration of struct defined in cx18-cards.h */
445struct cx18_card;
446
447/*
448 * A note about "sliced" VBI data as implemented in this driver:
449 *
450 * Currently we collect the sliced VBI in the form of Ancillary Data
451 * packets, inserted by the AV core decoder/digitizer/slicer in the
452 * horizontal blanking region of the VBI lines, in "raw" mode as far as
453 * the Encoder is concerned. We don't ever tell the Encoder itself
454 * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
455 *
456 * We then process the ancillary data ourselves to send the sliced data
457 * to the user application directly or build up MPEG-2 private stream 1
458 * packets to splice into (only!) MPEG-2 PS streams for the user app.
459 *
460 * (That's how ivtv essentially does it.)
461 *
462 * The Encoder should be able to extract certain sliced VBI data for
463 * us and provide it in a separate stream or splice it into any type of
464 * MPEG PS or TS stream, but this isn't implemented yet.
465 */
466
467/*
468 * Number of "raw" VBI samples per horizontal line we tell the Encoder to
469 * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
470 * It depends on the pixel clock and the horiz rate:
471 *
472 * (1/Fh)*(2*Fp) = Samples/line
473 * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
474 *
475 * Sliced VBI data is sent as ancillary data during horizontal blanking
476 * Raw VBI is sent as active video samples during vertcal blanking
477 *
478 * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
479 * length of 720 pixels @ 4:2:2 sampling. Thus...
480 *
481 * For systems that use a 15.734 kHz horizontal rate, such as
482 * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
483 *
484 * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
485 * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
486 *
487 * For systems that use a 15.625 kHz horizontal rate, such as
488 * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
489 *
490 * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
491 * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
492 */
493static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
494static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
495static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
496
497#define CX18_VBI_FRAMES 32
498
499struct vbi_info {
500 /* Current state of v4l2 VBI settings for this device */
501 struct v4l2_format in;
502 struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
503 u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
504 u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
505
506 u32 frame; /* Count of VBI buffers/frames received from Encoder */
507
508 /*
509 * Vars for creation and insertion of MPEG Private Stream 1 packets
510 * of sliced VBI data into an MPEG PS
511 */
512
513 /* Boolean: create and insert Private Stream 1 packets into the PS */
514 int insert_mpeg;
515
516 /*
517 * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
518 * Used in cx18-vbi.c only for collecting sliced data, and as a source
519 * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
520 * We don't need to save state here, but the array may have been a bit
521 * too big (2304 bytes) to alloc from the stack.
522 */
523 struct v4l2_sliced_vbi_data sliced_data[36];
524
525 /*
526 * A ring buffer of driver-generated MPEG-2 PS
527 * Program Pack/Private Stream 1 packets for sliced VBI data insertion
528 * into the MPEG PS stream.
529 *
530 * In each sliced_mpeg_data[] buffer is:
531 * 16 byte MPEG-2 PS Program Pack Header
532 * 16 byte MPEG-2 Private Stream 1 PES Header
533 * 4 byte magic number: "itv0" or "ITV0"
534 * 4 byte first field line mask, if "itv0"
535 * 4 byte second field line mask, if "itv0"
536 * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
537 *
538 * Each line in the payload is
539 * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
540 * 42 bytes of line data
541 *
542 * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
543 * which is the payload size a PVR-350 (CX23415) MPEG decoder will
544 * accept for VBI data. So, including the headers, it's a maximum 1584
545 * bytes total.
546 */
547#define CX18_SLICED_MPEG_DATA_MAXSZ 1584
548 /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
549#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8)
550 u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
551 u32 sliced_mpeg_size[CX18_VBI_FRAMES];
552
553 /* Count of Program Pack/Program Stream 1 packets inserted into PS */
554 u32 inserted_frame;
555
556 /*
557 * A dummy driver stream transfer mdl & buffer with a copy of the next
558 * sliced_mpeg_data[] buffer for output to userland apps.
559 * Only used in cx18-fileops.c, but its state needs to persist at times.
560 */
561 struct cx18_mdl sliced_mpeg_mdl;
562 struct cx18_buffer sliced_mpeg_buf;
563};
564
565/* Per cx23418, per I2C bus private algo callback data */
566struct cx18_i2c_algo_callback_data {
567 struct cx18 *cx;
568 int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
569};
570
571#define CX18_MAX_MMIO_WR_RETRIES 10
572
573/* Struct to hold info about cx18 cards */
574struct cx18 {
575 int instance;
576 struct pci_dev *pci_dev;
577 struct v4l2_device v4l2_dev;
578 struct v4l2_subdev *sd_av; /* A/V decoder/digitizer sub-device */
579 struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */
580
581 const struct cx18_card *card; /* card information */
582 const char *card_name; /* full name of the card */
583 const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
584 u8 is_50hz;
585 u8 is_60hz;
586 u8 nof_inputs; /* number of video inputs */
587 u8 nof_audio_inputs; /* number of audio inputs */
588 u32 v4l2_cap; /* V4L2 capabilities of card */
589 u32 hw_flags; /* Hardware description of the board */
590 unsigned int free_mdl_idx;
591 struct cx18_scb __iomem *scb; /* pointer to SCB */
592 struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
593 struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
594
595 struct cx18_av_state av_state;
596
597 /* codec settings */
598 struct cx2341x_handler cxhdl;
599 u32 filter_mode;
600 u32 temporal_strength;
601 u32 spatial_strength;
602
603 /* dualwatch */
604 unsigned long dualwatch_jiffies;
605 u32 dualwatch_stereo_mode;
606
607 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
608 struct cx18_options options; /* User options */
609 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
610 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
611 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
612 struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
613 void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
614 size_t num_bytes);
615
616 unsigned long i_flags; /* global cx18 flags */
617 atomic_t ana_capturing; /* count number of active analog capture streams */
618 atomic_t tot_capturing; /* total count number of active capture streams */
619 int search_pack_header;
620
621 int open_id; /* incremented each time an open occurs, used as
622 unique ID. Starts at 1, so 0 can be used as
623 uninitialized value in the stream->id. */
624
625 resource_size_t base_addr;
626
627 u8 card_rev;
628 void __iomem *enc_mem, *reg_mem;
629
630 struct vbi_info vbi;
631
632 u64 mpg_data_received;
633 u64 vbi_data_inserted;
634
635 wait_queue_head_t mb_apu_waitq;
636 wait_queue_head_t mb_cpu_waitq;
637 wait_queue_head_t cap_w;
638 /* when the current DMA is finished this queue is woken up */
639 wait_queue_head_t dma_waitq;
640
641 u32 sw1_irq_mask;
642 u32 sw2_irq_mask;
643 u32 hw2_irq_mask;
644
645 struct workqueue_struct *in_work_queue;
646 char in_workq_name[11]; /* "cx18-NN-in" */
647 struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
648 char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
649
650 /* i2c */
651 struct i2c_adapter i2c_adap[2];
652 struct i2c_algo_bit_data i2c_algo[2];
653 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
654
655 struct IR_i2c_init_data ir_i2c_init_data;
656
657 /* gpio */
658 u32 gpio_dir;
659 u32 gpio_val;
660 struct mutex gpio_lock;
661 struct v4l2_subdev sd_gpiomux;
662 struct v4l2_subdev sd_resetctrl;
663
664 /* v4l2 and User settings */
665
666 /* codec settings */
667 u32 audio_input;
668 u32 active_input;
669 v4l2_std_id std;
670 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
671
672 /* Used for cx18-alsa module loading */
673 struct work_struct request_module_wk;
674};
675
676static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
677{
678 return container_of(v4l2_dev, struct cx18, v4l2_dev);
679}
680
681/* cx18 extensions to be loaded */
682extern int (*cx18_ext_init)(struct cx18 *);
683
684/* Globals */
685extern int cx18_first_minor;
686
687/*==============Prototypes==================*/
688
689/* Return non-zero if a signal is pending */
690int cx18_msleep_timeout(unsigned int msecs, int intr);
691
692/* Read Hauppauge eeprom */
693struct tveeprom; /* forward reference */
694void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
695
696/* First-open initialization: load firmware, etc. */
697int cx18_init_on_first_open(struct cx18 *cx);
698
699/* Test if the current VBI mode is raw (1) or sliced (0) */
700static inline int cx18_raw_vbi(const struct cx18 *cx)
701{
702 return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
703}
704
705/* Call the specified callback for all subdevs with a grp_id bit matching the
706 * mask in hw (if 0, then match them all). Ignore any errors. */
707#define cx18_call_hw(cx, hw, o, f, args...) \
708 do { \
709 struct v4l2_subdev *__sd; \
710 __v4l2_device_call_subdevs_p(&(cx)->v4l2_dev, __sd, \
711 !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
712 } while (0)
713
714#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args)
715
716/* Call the specified callback for all subdevs with a grp_id bit matching the
717 * mask in hw (if 0, then match them all). If the callback returns an error
718 * other than 0 or -ENOIOCTLCMD, then return with that error code. */
719#define cx18_call_hw_err(cx, hw, o, f, args...) \
720({ \
721 struct v4l2_subdev *__sd; \
722 __v4l2_device_call_subdevs_until_err_p(&(cx)->v4l2_dev, \
723 __sd, !(hw) || (__sd->grp_id & (hw)), o, f, \
724 ##args); \
725})
726
727#define cx18_call_all_err(cx, o, f, args...) \
728 cx18_call_hw_err(cx, 0, o, f , ##args)
729
730#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/pci/cx18/cx18-dvb.c b/drivers/media/pci/cx18/cx18-dvb.c
new file mode 100644
index 000000000000..3eac59c51231
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-dvb.c
@@ -0,0 +1,609 @@
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 FWFILE "dvb-cx18-mpc718-mt352.fw"
44
45#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
46#define CX18_CLOCK_ENABLE2 0xc71024
47#define CX18_DMUX_CLK_MASK 0x0080
48
49/*
50 * CX18_CARD_HVR_1600_ESMT
51 * CX18_CARD_HVR_1600_SAMSUNG
52 */
53
54static struct mxl5005s_config hauppauge_hvr1600_tuner = {
55 .i2c_address = 0xC6 >> 1,
56 .if_freq = IF_FREQ_5380000HZ,
57 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
58 .agc_mode = MXL_SINGLE_AGC,
59 .tracking_filter = MXL_TF_C_H,
60 .rssi_enable = MXL_RSSI_ENABLE,
61 .cap_select = MXL_CAP_SEL_ENABLE,
62 .div_out = MXL_DIV_OUT_4,
63 .clock_out = MXL_CLOCK_OUT_DISABLE,
64 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
65 .top = MXL5005S_TOP_25P2,
66 .mod_mode = MXL_DIGITAL_MODE,
67 .if_mode = MXL_ZERO_IF,
68 .qam_gain = 0x02,
69 .AgcMasterByte = 0x00,
70};
71
72static struct s5h1409_config hauppauge_hvr1600_config = {
73 .demod_address = 0x32 >> 1,
74 .output_mode = S5H1409_SERIAL_OUTPUT,
75 .gpio = S5H1409_GPIO_ON,
76 .qam_if = 44000,
77 .inversion = S5H1409_INVERSION_OFF,
78 .status_mode = S5H1409_DEMODLOCKING,
79 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
80 .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE
81};
82
83/*
84 * CX18_CARD_HVR_1600_S5H1411
85 */
86static struct s5h1411_config hcw_s5h1411_config = {
87 .output_mode = S5H1411_SERIAL_OUTPUT,
88 .gpio = S5H1411_GPIO_OFF,
89 .vsb_if = S5H1411_IF_44000,
90 .qam_if = S5H1411_IF_4000,
91 .inversion = S5H1411_INVERSION_ON,
92 .status_mode = S5H1411_DEMODLOCKING,
93 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
94};
95
96static struct tda18271_std_map hauppauge_tda18271_std_map = {
97 .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3,
98 .if_lvl = 6, .rfagc_top = 0x37 },
99 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
100 .if_lvl = 6, .rfagc_top = 0x37 },
101};
102
103static struct tda18271_config hauppauge_tda18271_config = {
104 .std_map = &hauppauge_tda18271_std_map,
105 .gate = TDA18271_GATE_DIGITAL,
106 .output_opt = TDA18271_OUTPUT_LT_OFF,
107};
108
109/*
110 * CX18_CARD_LEADTEK_DVR3100H
111 */
112/* Information/confirmation of proper config values provided by Terry Wu */
113static struct zl10353_config leadtek_dvr3100h_demod = {
114 .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
115 .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
116 .parallel_ts = 1, /* Not a serial TS */
117 .no_tuner = 1, /* XC3028 is not behind the gate */
118 .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
119};
120
121/*
122 * CX18_CARD_YUAN_MPC718
123 */
124/*
125 * Due to
126 *
127 * 1. an absence of information on how to prgram the MT352
128 * 2. the Linux mt352 module pushing MT352 initialzation off onto us here
129 *
130 * We have to use an init sequence that *you* must extract from the Windows
131 * driver (yuanrap.sys) and which we load as a firmware.
132 *
133 * If someone can provide me with a Zarlink MT352 (Intel CE6352?) Design Manual
134 * with chip programming details, then I can remove this annoyance.
135 */
136static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream,
137 const struct firmware **fw)
138{
139 struct cx18 *cx = stream->cx;
140 const char *fn = FWFILE;
141 int ret;
142
143 ret = request_firmware(fw, fn, &cx->pci_dev->dev);
144 if (ret)
145 CX18_ERR("Unable to open firmware file %s\n", fn);
146 else {
147 size_t sz = (*fw)->size;
148 if (sz < 2 || sz > 64 || (sz % 2) != 0) {
149 CX18_ERR("Firmware %s has a bad size: %lu bytes\n",
150 fn, (unsigned long) sz);
151 ret = -EILSEQ;
152 release_firmware(*fw);
153 *fw = NULL;
154 }
155 }
156
157 if (ret) {
158 CX18_ERR("The MPC718 board variant with the MT352 DVB-T"
159 "demodualtor will not work without it\n");
160 CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware "
161 "mpc718' if you need the firmware\n");
162 }
163 return ret;
164}
165
166static int yuan_mpc718_mt352_init(struct dvb_frontend *fe)
167{
168 struct cx18_dvb *dvb = container_of(fe->dvb,
169 struct cx18_dvb, dvb_adapter);
170 struct cx18_stream *stream = dvb->stream;
171 const struct firmware *fw = NULL;
172 int ret;
173 int i;
174 u8 buf[3];
175
176 ret = yuan_mpc718_mt352_reqfw(stream, &fw);
177 if (ret)
178 return ret;
179
180 /* Loop through all the register-value pairs in the firmware file */
181 for (i = 0; i < fw->size; i += 2) {
182 buf[0] = fw->data[i];
183 /* Intercept a few registers we want to set ourselves */
184 switch (buf[0]) {
185 case TRL_NOMINAL_RATE_0:
186 /* Set our custom OFDM bandwidth in the case below */
187 break;
188 case TRL_NOMINAL_RATE_1:
189 /* 6 MHz: 64/7 * 6/8 / 20.48 * 2^16 = 0x55b6.db6 */
190 /* 7 MHz: 64/7 * 7/8 / 20.48 * 2^16 = 0x6400 */
191 /* 8 MHz: 64/7 * 8/8 / 20.48 * 2^16 = 0x7249.249 */
192 buf[1] = 0x72;
193 buf[2] = 0x49;
194 mt352_write(fe, buf, 3);
195 break;
196 case INPUT_FREQ_0:
197 /* Set our custom IF in the case below */
198 break;
199 case INPUT_FREQ_1:
200 /* 4.56 MHz IF: (20.48 - 4.56)/20.48 * 2^14 = 0x31c0 */
201 buf[1] = 0x31;
202 buf[2] = 0xc0;
203 mt352_write(fe, buf, 3);
204 break;
205 default:
206 /* Pass through the register-value pair from the fw */
207 buf[1] = fw->data[i+1];
208 mt352_write(fe, buf, 2);
209 break;
210 }
211 }
212
213 buf[0] = (u8) TUNER_GO;
214 buf[1] = 0x01; /* Go */
215 mt352_write(fe, buf, 2);
216 release_firmware(fw);
217 return 0;
218}
219
220static struct mt352_config yuan_mpc718_mt352_demod = {
221 .demod_address = 0x1e >> 1,
222 .adc_clock = 20480, /* 20.480 MHz */
223 .if2 = 4560, /* 4.560 MHz */
224 .no_tuner = 1, /* XC3028 is not behind the gate */
225 .demod_init = yuan_mpc718_mt352_init,
226};
227
228static struct zl10353_config yuan_mpc718_zl10353_demod = {
229 .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
230 .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
231 .parallel_ts = 1, /* Not a serial TS */
232 .no_tuner = 1, /* XC3028 is not behind the gate */
233 .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
234};
235
236static struct zl10353_config gotview_dvd3_zl10353_demod = {
237 .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
238 .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
239 .parallel_ts = 1, /* Not a serial TS */
240 .no_tuner = 1, /* XC3028 is not behind the gate */
241 .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
242};
243
244static int dvb_register(struct cx18_stream *stream);
245
246/* Kernel DVB framework calls this when the feed needs to start.
247 * The CX18 framework should enable the transport DMA handling
248 * and queue processing.
249 */
250static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
251{
252 struct dvb_demux *demux = feed->demux;
253 struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
254 struct cx18 *cx;
255 int ret;
256 u32 v;
257
258 if (!stream)
259 return -EINVAL;
260
261 cx = stream->cx;
262 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
263 feed->pid, feed->index);
264
265 mutex_lock(&cx->serialize_lock);
266 ret = cx18_init_on_first_open(cx);
267 mutex_unlock(&cx->serialize_lock);
268 if (ret) {
269 CX18_ERR("Failed to initialize firmware starting DVB feed\n");
270 return ret;
271 }
272 ret = -EINVAL;
273
274 switch (cx->card->type) {
275 case CX18_CARD_HVR_1600_ESMT:
276 case CX18_CARD_HVR_1600_SAMSUNG:
277 case CX18_CARD_HVR_1600_S5H1411:
278 v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
279 v |= 0x00400000; /* Serial Mode */
280 v |= 0x00002000; /* Data Length - Byte */
281 v |= 0x00010000; /* Error - Polarity */
282 v |= 0x00020000; /* Error - Passthru */
283 v |= 0x000c0000; /* Error - Ignore */
284 cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
285 break;
286
287 case CX18_CARD_LEADTEK_DVR3100H:
288 case CX18_CARD_YUAN_MPC718:
289 case CX18_CARD_GOTVIEW_PCI_DVD3:
290 default:
291 /* Assumption - Parallel transport - Signalling
292 * undefined or default.
293 */
294 break;
295 }
296
297 if (!demux->dmx.frontend)
298 return -EINVAL;
299
300 mutex_lock(&stream->dvb->feedlock);
301 if (stream->dvb->feeding++ == 0) {
302 CX18_DEBUG_INFO("Starting Transport DMA\n");
303 mutex_lock(&cx->serialize_lock);
304 set_bit(CX18_F_S_STREAMING, &stream->s_flags);
305 ret = cx18_start_v4l2_encode_stream(stream);
306 if (ret < 0) {
307 CX18_DEBUG_INFO("Failed to start Transport DMA\n");
308 stream->dvb->feeding--;
309 if (stream->dvb->feeding == 0)
310 clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
311 }
312 mutex_unlock(&cx->serialize_lock);
313 } else
314 ret = 0;
315 mutex_unlock(&stream->dvb->feedlock);
316
317 return ret;
318}
319
320/* Kernel DVB framework calls this when the feed needs to stop. */
321static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
322{
323 struct dvb_demux *demux = feed->demux;
324 struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
325 struct cx18 *cx;
326 int ret = -EINVAL;
327
328 if (stream) {
329 cx = stream->cx;
330 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
331 feed->pid, feed->index);
332
333 mutex_lock(&stream->dvb->feedlock);
334 if (--stream->dvb->feeding == 0) {
335 CX18_DEBUG_INFO("Stopping Transport DMA\n");
336 mutex_lock(&cx->serialize_lock);
337 ret = cx18_stop_v4l2_encode_stream(stream, 0);
338 mutex_unlock(&cx->serialize_lock);
339 } else
340 ret = 0;
341 mutex_unlock(&stream->dvb->feedlock);
342 }
343
344 return ret;
345}
346
347int cx18_dvb_register(struct cx18_stream *stream)
348{
349 struct cx18 *cx = stream->cx;
350 struct cx18_dvb *dvb = stream->dvb;
351 struct dvb_adapter *dvb_adapter;
352 struct dvb_demux *dvbdemux;
353 struct dmx_demux *dmx;
354 int ret;
355
356 if (!dvb)
357 return -EINVAL;
358
359 dvb->enabled = 0;
360 dvb->stream = stream;
361
362 ret = dvb_register_adapter(&dvb->dvb_adapter,
363 CX18_DRIVER_NAME,
364 THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
365 if (ret < 0)
366 goto err_out;
367
368 dvb_adapter = &dvb->dvb_adapter;
369
370 dvbdemux = &dvb->demux;
371
372 dvbdemux->priv = (void *)stream;
373
374 dvbdemux->filternum = 256;
375 dvbdemux->feednum = 256;
376 dvbdemux->start_feed = cx18_dvb_start_feed;
377 dvbdemux->stop_feed = cx18_dvb_stop_feed;
378 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
379 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
380 ret = dvb_dmx_init(dvbdemux);
381 if (ret < 0)
382 goto err_dvb_unregister_adapter;
383
384 dmx = &dvbdemux->dmx;
385
386 dvb->hw_frontend.source = DMX_FRONTEND_0;
387 dvb->mem_frontend.source = DMX_MEMORY_FE;
388 dvb->dmxdev.filternum = 256;
389 dvb->dmxdev.demux = dmx;
390
391 ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter);
392 if (ret < 0)
393 goto err_dvb_dmx_release;
394
395 ret = dmx->add_frontend(dmx, &dvb->hw_frontend);
396 if (ret < 0)
397 goto err_dvb_dmxdev_release;
398
399 ret = dmx->add_frontend(dmx, &dvb->mem_frontend);
400 if (ret < 0)
401 goto err_remove_hw_frontend;
402
403 ret = dmx->connect_frontend(dmx, &dvb->hw_frontend);
404 if (ret < 0)
405 goto err_remove_mem_frontend;
406
407 ret = dvb_register(stream);
408 if (ret < 0)
409 goto err_disconnect_frontend;
410
411 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
412
413 CX18_INFO("DVB Frontend registered\n");
414 CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
415 stream->dvb->dvb_adapter.num, stream->name,
416 stream->buffers, stream->buf_size/1024,
417 (stream->buf_size * 100 / 1024) % 100);
418
419 mutex_init(&dvb->feedlock);
420 dvb->enabled = 1;
421 return ret;
422
423err_disconnect_frontend:
424 dmx->disconnect_frontend(dmx);
425err_remove_mem_frontend:
426 dmx->remove_frontend(dmx, &dvb->mem_frontend);
427err_remove_hw_frontend:
428 dmx->remove_frontend(dmx, &dvb->hw_frontend);
429err_dvb_dmxdev_release:
430 dvb_dmxdev_release(&dvb->dmxdev);
431err_dvb_dmx_release:
432 dvb_dmx_release(dvbdemux);
433err_dvb_unregister_adapter:
434 dvb_unregister_adapter(dvb_adapter);
435err_out:
436 return ret;
437}
438
439void cx18_dvb_unregister(struct cx18_stream *stream)
440{
441 struct cx18 *cx = stream->cx;
442 struct cx18_dvb *dvb = stream->dvb;
443 struct dvb_adapter *dvb_adapter;
444 struct dvb_demux *dvbdemux;
445 struct dmx_demux *dmx;
446
447 CX18_INFO("unregister DVB\n");
448
449 if (dvb == NULL || !dvb->enabled)
450 return;
451
452 dvb_adapter = &dvb->dvb_adapter;
453 dvbdemux = &dvb->demux;
454 dmx = &dvbdemux->dmx;
455
456 dmx->close(dmx);
457 dvb_net_release(&dvb->dvbnet);
458 dmx->remove_frontend(dmx, &dvb->mem_frontend);
459 dmx->remove_frontend(dmx, &dvb->hw_frontend);
460 dvb_dmxdev_release(&dvb->dmxdev);
461 dvb_dmx_release(dvbdemux);
462 dvb_unregister_frontend(dvb->fe);
463 dvb_frontend_detach(dvb->fe);
464 dvb_unregister_adapter(dvb_adapter);
465}
466
467/* All the DVB attach calls go here, this function get's modified
468 * for each new card. cx18_dvb_start_feed() will also need changes.
469 */
470static int dvb_register(struct cx18_stream *stream)
471{
472 struct cx18_dvb *dvb = stream->dvb;
473 struct cx18 *cx = stream->cx;
474 int ret = 0;
475
476 switch (cx->card->type) {
477 case CX18_CARD_HVR_1600_ESMT:
478 case CX18_CARD_HVR_1600_SAMSUNG:
479 dvb->fe = dvb_attach(s5h1409_attach,
480 &hauppauge_hvr1600_config,
481 &cx->i2c_adap[0]);
482 if (dvb->fe != NULL) {
483 dvb_attach(mxl5005s_attach, dvb->fe,
484 &cx->i2c_adap[0],
485 &hauppauge_hvr1600_tuner);
486 ret = 0;
487 }
488 break;
489 case CX18_CARD_HVR_1600_S5H1411:
490 dvb->fe = dvb_attach(s5h1411_attach,
491 &hcw_s5h1411_config,
492 &cx->i2c_adap[0]);
493 if (dvb->fe != NULL)
494 dvb_attach(tda18271_attach, dvb->fe,
495 0x60, &cx->i2c_adap[0],
496 &hauppauge_tda18271_config);
497 break;
498 case CX18_CARD_LEADTEK_DVR3100H:
499 dvb->fe = dvb_attach(zl10353_attach,
500 &leadtek_dvr3100h_demod,
501 &cx->i2c_adap[1]);
502 if (dvb->fe != NULL) {
503 struct dvb_frontend *fe;
504 struct xc2028_config cfg = {
505 .i2c_adap = &cx->i2c_adap[1],
506 .i2c_addr = 0xc2 >> 1,
507 .ctrl = NULL,
508 };
509 static struct xc2028_ctrl ctrl = {
510 .fname = XC2028_DEFAULT_FIRMWARE,
511 .max_len = 64,
512 .demod = XC3028_FE_ZARLINK456,
513 .type = XC2028_AUTO,
514 };
515
516 fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
517 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
518 fe->ops.tuner_ops.set_config(fe, &ctrl);
519 }
520 break;
521 case CX18_CARD_YUAN_MPC718:
522 /*
523 * TODO
524 * Apparently, these cards also could instead have a
525 * DiBcom demod supported by one of the db7000 drivers
526 */
527 dvb->fe = dvb_attach(mt352_attach,
528 &yuan_mpc718_mt352_demod,
529 &cx->i2c_adap[1]);
530 if (dvb->fe == NULL)
531 dvb->fe = dvb_attach(zl10353_attach,
532 &yuan_mpc718_zl10353_demod,
533 &cx->i2c_adap[1]);
534 if (dvb->fe != NULL) {
535 struct dvb_frontend *fe;
536 struct xc2028_config cfg = {
537 .i2c_adap = &cx->i2c_adap[1],
538 .i2c_addr = 0xc2 >> 1,
539 .ctrl = NULL,
540 };
541 static struct xc2028_ctrl ctrl = {
542 .fname = XC2028_DEFAULT_FIRMWARE,
543 .max_len = 64,
544 .demod = XC3028_FE_ZARLINK456,
545 .type = XC2028_AUTO,
546 };
547
548 fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
549 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
550 fe->ops.tuner_ops.set_config(fe, &ctrl);
551 }
552 break;
553 case CX18_CARD_GOTVIEW_PCI_DVD3:
554 dvb->fe = dvb_attach(zl10353_attach,
555 &gotview_dvd3_zl10353_demod,
556 &cx->i2c_adap[1]);
557 if (dvb->fe != NULL) {
558 struct dvb_frontend *fe;
559 struct xc2028_config cfg = {
560 .i2c_adap = &cx->i2c_adap[1],
561 .i2c_addr = 0xc2 >> 1,
562 .ctrl = NULL,
563 };
564 static struct xc2028_ctrl ctrl = {
565 .fname = XC2028_DEFAULT_FIRMWARE,
566 .max_len = 64,
567 .demod = XC3028_FE_ZARLINK456,
568 .type = XC2028_AUTO,
569 };
570
571 fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
572 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
573 fe->ops.tuner_ops.set_config(fe, &ctrl);
574 }
575 break;
576 default:
577 /* No Digital Tv Support */
578 break;
579 }
580
581 if (dvb->fe == NULL) {
582 CX18_ERR("frontend initialization failed\n");
583 return -1;
584 }
585
586 dvb->fe->callback = cx18_reset_tuner_gpio;
587
588 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
589 if (ret < 0) {
590 if (dvb->fe->ops.release)
591 dvb->fe->ops.release(dvb->fe);
592 return ret;
593 }
594
595 /*
596 * The firmware seems to enable the TS DMUX clock
597 * under various circumstances. However, since we know we
598 * might use it, let's just turn it on ourselves here.
599 */
600 cx18_write_reg_expect(cx,
601 (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK,
602 CX18_CLOCK_ENABLE2,
603 CX18_DMUX_CLK_MASK,
604 (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK);
605
606 return ret;
607}
608
609MODULE_FIRMWARE(FWFILE);
diff --git a/drivers/media/pci/cx18/cx18-dvb.h b/drivers/media/pci/cx18/cx18-dvb.h
new file mode 100644
index 000000000000..bf8d8f6f5455
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c
new file mode 100644
index 000000000000..4bfd865a4106
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-fileops.c
@@ -0,0 +1,881 @@
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 mutex_lock(&cx->serialize_lock);
755 /* Stop radio */
756 if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
757 v4l2_fh_is_singular_file(filp)) {
758 /* Closing radio device, return to TV mode */
759 cx18_mute(cx);
760 /* Mark that the radio is no longer in use */
761 clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
762 /* Switch tuner to TV */
763 cx18_call_all(cx, core, s_std, cx->std);
764 /* Select correct audio input (i.e. TV tuner or Line in) */
765 cx18_audio_set_io(cx);
766 if (atomic_read(&cx->ana_capturing) > 0) {
767 /* Undo video mute */
768 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
769 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
770 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
771 }
772 /* Done! Unmute and continue. */
773 cx18_unmute(cx);
774 }
775
776 v4l2_fh_del(fh);
777 v4l2_fh_exit(fh);
778
779 /* 'Unclaim' this stream */
780 if (s->id == id->open_id)
781 cx18_stop_capture(id, 0);
782 kfree(id);
783 mutex_unlock(&cx->serialize_lock);
784 return 0;
785}
786
787static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
788{
789 struct cx18 *cx = s->cx;
790 struct cx18_open_id *item;
791
792 CX18_DEBUG_FILE("open %s\n", s->name);
793
794 /* Allocate memory */
795 item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
796 if (NULL == item) {
797 CX18_DEBUG_WARN("nomem on v4l2 open\n");
798 return -ENOMEM;
799 }
800 v4l2_fh_init(&item->fh, s->video_dev);
801
802 item->cx = cx;
803 item->type = s->type;
804
805 item->open_id = cx->open_id++;
806 filp->private_data = &item->fh;
807 v4l2_fh_add(&item->fh);
808
809 if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
810 v4l2_fh_is_singular_file(filp)) {
811 if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
812 if (atomic_read(&cx->ana_capturing) > 0) {
813 /* switching to radio while capture is
814 in progress is not polite */
815 v4l2_fh_del(&item->fh);
816 v4l2_fh_exit(&item->fh);
817 kfree(item);
818 return -EBUSY;
819 }
820 }
821
822 /* Mark that the radio is being used. */
823 set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
824 /* We have the radio */
825 cx18_mute(cx);
826 /* Switch tuner to radio */
827 cx18_call_all(cx, tuner, s_radio);
828 /* Select the correct audio input (i.e. radio tuner) */
829 cx18_audio_set_io(cx);
830 /* Done! Unmute and continue. */
831 cx18_unmute(cx);
832 }
833 return 0;
834}
835
836int cx18_v4l2_open(struct file *filp)
837{
838 int res;
839 struct video_device *video_dev = video_devdata(filp);
840 struct cx18_stream *s = video_get_drvdata(video_dev);
841 struct cx18 *cx = s->cx;
842
843 mutex_lock(&cx->serialize_lock);
844 if (cx18_init_on_first_open(cx)) {
845 CX18_ERR("Failed to initialize on %s\n",
846 video_device_node_name(video_dev));
847 mutex_unlock(&cx->serialize_lock);
848 return -ENXIO;
849 }
850 res = cx18_serialized_open(s, filp);
851 mutex_unlock(&cx->serialize_lock);
852 return res;
853}
854
855void cx18_mute(struct cx18 *cx)
856{
857 u32 h;
858 if (atomic_read(&cx->ana_capturing)) {
859 h = cx18_find_handle(cx);
860 if (h != CX18_INVALID_TASK_HANDLE)
861 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
862 else
863 CX18_ERR("Can't find valid task handle for mute\n");
864 }
865 CX18_DEBUG_INFO("Mute\n");
866}
867
868void cx18_unmute(struct cx18 *cx)
869{
870 u32 h;
871 if (atomic_read(&cx->ana_capturing)) {
872 h = cx18_find_handle(cx);
873 if (h != CX18_INVALID_TASK_HANDLE) {
874 cx18_msleep_timeout(100, 0);
875 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
876 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
877 } else
878 CX18_ERR("Can't find valid task handle for unmute\n");
879 }
880 CX18_DEBUG_INFO("Unmute\n");
881}
diff --git a/drivers/media/pci/cx18/cx18-fileops.h b/drivers/media/pci/cx18/cx18-fileops.h
new file mode 100644
index 000000000000..b9e5110ad043
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-firmware.c b/drivers/media/pci/cx18/cx18-firmware.c
new file mode 100644
index 000000000000..a1c1cec05f98
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-firmware.c
@@ -0,0 +1,459 @@
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 const u32 *shptr = src + offset / 4;
168
169 seghdr.sync1 = le32_to_cpu(shptr[0]);
170 seghdr.sync2 = le32_to_cpu(shptr[1]);
171 seghdr.addr = le32_to_cpu(shptr[2]);
172 seghdr.size = le32_to_cpu(shptr[3]);
173
174 offset += sizeof(seghdr);
175 if (seghdr.sync1 != APU_ROM_SYNC1 ||
176 seghdr.sync2 != APU_ROM_SYNC2) {
177 offset += seghdr.size;
178 continue;
179 }
180 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
181 seghdr.addr + seghdr.size - 1);
182 if (*entry_addr == 0)
183 *entry_addr = seghdr.addr;
184 if (offset + seghdr.size > sz)
185 break;
186 for (i = 0; i < seghdr.size; i += 4096) {
187 cx18_setup_page(cx, seghdr.addr + i);
188 for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
189 /* no need for endianness conversion on the ppc */
190 cx18_raw_writel(cx, src[(offset + j) / 4],
191 dst + seghdr.addr + j);
192 if (cx18_raw_readl(cx, dst + seghdr.addr + j)
193 != src[(offset + j) / 4]) {
194 CX18_ERR("Mismatch at offset %x\n",
195 offset + j);
196 release_firmware(fw);
197 cx18_setup_page(cx, 0);
198 return -EIO;
199 }
200 }
201 }
202 offset += seghdr.size;
203 }
204 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
205 CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
206 fn, apu_version, fw->size);
207 size = fw->size;
208 release_firmware(fw);
209 cx18_setup_page(cx, 0);
210 return size;
211}
212
213void cx18_halt_firmware(struct cx18 *cx)
214{
215 CX18_DEBUG_INFO("Preparing for firmware halt.\n");
216 cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
217 0x0000000F, 0x000F000F);
218 cx18_write_reg_expect(cx, 0x00020002, CX18_ADEC_CONTROL,
219 0x00000002, 0x00020002);
220}
221
222void cx18_init_power(struct cx18 *cx, int lowpwr)
223{
224 /* power-down Spare and AOM PLLs */
225 /* power-up fast, slow and mpeg PLLs */
226 cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
227
228 /* ADEC out of sleep */
229 cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL,
230 0x00000000, 0x00020002);
231
232 /*
233 * The PLL parameters are based on the external crystal frequency that
234 * would ideally be:
235 *
236 * NTSC Color subcarrier freq * 8 =
237 * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
238 *
239 * The accidents of history and rationale that explain from where this
240 * combination of magic numbers originate can be found in:
241 *
242 * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
243 * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
244 *
245 * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
246 * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
247 *
248 * As Mike Bradley has rightly pointed out, it's not the exact crystal
249 * frequency that matters, only that all parts of the driver and
250 * firmware are using the same value (close to the ideal value).
251 *
252 * Since I have a strong suspicion that, if the firmware ever assumes a
253 * crystal value at all, it will assume 28.636360 MHz, the crystal
254 * freq used in calculations in this driver will be:
255 *
256 * xtal_freq = 28.636360 MHz
257 *
258 * an error of less than 0.13 ppm which is way, way better than any off
259 * the shelf crystal will have for accuracy anyway.
260 *
261 * Below I aim to run the PLLs' VCOs near 400 MHz to minimze errors.
262 *
263 * Many thanks to Jeff Campbell and Mike Bradley for their extensive
264 * investigation, experimentation, testing, and suggested solutions of
265 * of audio/video sync problems with SVideo and CVBS captures.
266 */
267
268 /* the fast clock is at 200/245 MHz */
269 /* 1 * xtal_freq * 0x0d.f7df9b8 / 2 = 200 MHz: 400 MHz pre post-divide*/
270 /* 1 * xtal_freq * 0x11.1c71eb8 / 2 = 245 MHz: 490 MHz pre post-divide*/
271 cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
272 cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
273 CX18_FAST_CLOCK_PLL_FRAC);
274
275 cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST);
276 cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE);
277 cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
278
279 /* set slow clock to 125/120 MHz */
280 /* xtal_freq * 0x0d.1861a20 / 3 = 125 MHz: 375 MHz before post-divide */
281 /* xtal_freq * 0x0c.92493f8 / 3 = 120 MHz: 360 MHz before post-divide */
282 cx18_write_reg(cx, lowpwr ? 0xD : 0xC, CX18_SLOW_CLOCK_PLL_INT);
283 cx18_write_reg(cx, lowpwr ? 0x30C344 : 0x124927F,
284 CX18_SLOW_CLOCK_PLL_FRAC);
285 cx18_write_reg(cx, 3, CX18_SLOW_CLOCK_PLL_POST);
286
287 /* mpeg clock pll 54MHz */
288 /* xtal_freq * 0xf.15f17f0 / 8 = 54 MHz: 432 MHz before post-divide */
289 cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
290 cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
291 cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
292
293 /* Defaults */
294 /* APU = SC or SC/2 = 125/62.5 */
295 /* EPU = SC = 125 */
296 /* DDR = FC = 180 */
297 /* ENC = SC = 125 */
298 /* AI1 = SC = 125 */
299 /* VIM2 = disabled */
300 /* PCI = FC/2 = 90 */
301 /* AI2 = disabled */
302 /* DEMUX = disabled */
303 /* AO = SC/2 = 62.5 */
304 /* SER = 54MHz */
305 /* VFC = disabled */
306 /* USB = disabled */
307
308 if (lowpwr) {
309 cx18_write_reg_expect(cx, 0xFFFF0020, CX18_CLOCK_SELECT1,
310 0x00000020, 0xFFFFFFFF);
311 cx18_write_reg_expect(cx, 0xFFFF0004, CX18_CLOCK_SELECT2,
312 0x00000004, 0xFFFFFFFF);
313 } else {
314 /* This doesn't explicitly set every clock select */
315 cx18_write_reg_expect(cx, 0x00060004, CX18_CLOCK_SELECT1,
316 0x00000004, 0x00060006);
317 cx18_write_reg_expect(cx, 0x00060006, CX18_CLOCK_SELECT2,
318 0x00000006, 0x00060006);
319 }
320
321 cx18_write_reg_expect(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1,
322 0x00000002, 0xFFFFFFFF);
323 cx18_write_reg_expect(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2,
324 0x00000104, 0xFFFFFFFF);
325 cx18_write_reg_expect(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1,
326 0x00009026, 0xFFFFFFFF);
327 cx18_write_reg_expect(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2,
328 0x00003105, 0xFFFFFFFF);
329}
330
331void cx18_init_memory(struct cx18 *cx)
332{
333 cx18_msleep_timeout(10, 0);
334 cx18_write_reg_expect(cx, 0x00010000, CX18_DDR_SOFT_RESET,
335 0x00000000, 0x00010001);
336 cx18_msleep_timeout(10, 0);
337
338 cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
339
340 cx18_msleep_timeout(10, 0);
341
342 cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH);
343 cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1);
344 cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2);
345
346 cx18_msleep_timeout(10, 0);
347
348 /* Initialize DQS pad time */
349 cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
350 cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
351
352 cx18_msleep_timeout(10, 0);
353
354 cx18_write_reg_expect(cx, 0x00020000, CX18_DDR_SOFT_RESET,
355 0x00000000, 0x00020002);
356 cx18_msleep_timeout(10, 0);
357
358 /* use power-down mode when idle */
359 cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
360
361 cx18_write_reg_expect(cx, 0x00010001, CX18_REG_BUS_TIMEOUT_EN,
362 0x00000001, 0x00010001);
363
364 cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
365 cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
366
367 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */
368 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */
369 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
370 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */
371 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
372 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */
373 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */
374 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */
375 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */
376 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */
377}
378
379#define CX18_CPU_FIRMWARE "v4l-cx23418-cpu.fw"
380#define CX18_APU_FIRMWARE "v4l-cx23418-apu.fw"
381
382int cx18_firmware_init(struct cx18 *cx)
383{
384 u32 fw_entry_addr;
385 int sz, retries;
386 u32 api_args[MAX_MB_ARGUMENTS];
387
388 /* Allow chip to control CLKRUN */
389 cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
390
391 /* Stop the firmware */
392 cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
393 0x0000000F, 0x000F000F);
394
395 cx18_msleep_timeout(1, 0);
396
397 /* If the CPU is still running */
398 if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) {
399 CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__);
400 return -EIO;
401 }
402
403 cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
404 cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
405
406 sz = load_cpu_fw_direct(CX18_CPU_FIRMWARE, cx->enc_mem, cx);
407 if (sz <= 0)
408 return sz;
409
410 /* The SCB & IPC area *must* be correct before starting the firmwares */
411 cx18_init_scb(cx);
412
413 fw_entry_addr = 0;
414 sz = load_apu_fw_direct(CX18_APU_FIRMWARE, cx->enc_mem, cx,
415 &fw_entry_addr);
416 if (sz <= 0)
417 return sz;
418
419 /* Start the CPU. The CPU will take care of the APU for us. */
420 cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET,
421 0x00000000, 0x00080008);
422
423 /* Wait up to 500 ms for the APU to come out of reset */
424 for (retries = 0;
425 retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1;
426 retries++)
427 cx18_msleep_timeout(10, 0);
428
429 cx18_msleep_timeout(200, 0);
430
431 if (retries == 50 &&
432 (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) {
433 CX18_ERR("Could not start the CPU\n");
434 return -EIO;
435 }
436
437 /*
438 * The CPU had once before set up to receive an interrupt for it's
439 * outgoing IRQ_CPU_TO_EPU_ACK to us. If it ever does this, we get an
440 * interrupt when it sends us an ack, but by the time we process it,
441 * that flag in the SW2 status register has been cleared by the CPU
442 * firmware. We'll prevent that not so useful condition from happening
443 * by clearing the CPU's interrupt enables for Ack IRQ's we want to
444 * process.
445 */
446 cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
447
448 /* Try a benign command to see if the CPU is alive and well */
449 sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0);
450 if (sz < 0)
451 return sz;
452
453 /* initialize GPIO */
454 cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
455 return 0;
456}
457
458MODULE_FIRMWARE(CX18_CPU_FIRMWARE);
459MODULE_FIRMWARE(CX18_APU_FIRMWARE);
diff --git a/drivers/media/pci/cx18/cx18-firmware.h b/drivers/media/pci/cx18/cx18-firmware.h
new file mode 100644
index 000000000000..38d4c05e8499
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-gpio.c b/drivers/media/pci/cx18/cx18-gpio.c
new file mode 100644
index 000000000000..5374aeb0cd22
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-gpio.h b/drivers/media/pci/cx18/cx18-gpio.h
new file mode 100644
index 000000000000..4aea2ef88e8d
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c
new file mode 100644
index 000000000000..51609d5c88ce
--- /dev/null
+++ b/drivers/media/pci/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 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/pci/cx18/cx18-i2c.h b/drivers/media/pci/cx18/cx18-i2c.h
new file mode 100644
index 000000000000..1180fdc8d983
--- /dev/null
+++ b/drivers/media/pci/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 adapter */
28int init_cx18_i2c(struct cx18 *cx);
29void exit_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/pci/cx18/cx18-io.c b/drivers/media/pci/cx18/cx18-io.c
new file mode 100644
index 000000000000..49b9dbd06248
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-io.h b/drivers/media/pci/cx18/cx18-io.h
new file mode 100644
index 000000000000..18974d886cf7
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
new file mode 100644
index 000000000000..e9912db3b496
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-ioctl.c
@@ -0,0 +1,1194 @@
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 pixfmt->sizeimage = s->vb_bytes_per_frame;
164 pixfmt->bytesperline = 720;
165 } else {
166 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
167 pixfmt->sizeimage = 128 * 1024;
168 pixfmt->bytesperline = 0;
169 }
170 return 0;
171}
172
173static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
174 struct v4l2_format *fmt)
175{
176 struct cx18 *cx = fh2id(fh)->cx;
177 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
178
179 vbifmt->sampling_rate = 27000000;
180 vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
181 vbifmt->samples_per_line = vbi_active_samples - 4;
182 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
183 vbifmt->start[0] = cx->vbi.start[0];
184 vbifmt->start[1] = cx->vbi.start[1];
185 vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
186 vbifmt->flags = 0;
187 vbifmt->reserved[0] = 0;
188 vbifmt->reserved[1] = 0;
189 return 0;
190}
191
192static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
193 struct v4l2_format *fmt)
194{
195 struct cx18 *cx = fh2id(fh)->cx;
196 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
197
198 /* sane, V4L2 spec compliant, defaults */
199 vbifmt->reserved[0] = 0;
200 vbifmt->reserved[1] = 0;
201 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
202 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
203 vbifmt->service_set = 0;
204
205 /*
206 * Fetch the configured service_lines and total service_set from the
207 * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
208 * fmt->fmt.sliced under valid calling conditions
209 */
210 if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
211 return -EINVAL;
212
213 /* Ensure V4L2 spec compliant output */
214 vbifmt->reserved[0] = 0;
215 vbifmt->reserved[1] = 0;
216 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
217 vbifmt->service_set = cx18_get_service_set(vbifmt);
218 return 0;
219}
220
221static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
222 struct v4l2_format *fmt)
223{
224 struct cx18_open_id *id = fh2id(fh);
225 struct cx18 *cx = id->cx;
226 int w = fmt->fmt.pix.width;
227 int h = fmt->fmt.pix.height;
228 int min_h = 2;
229
230 w = min(w, 720);
231 w = max(w, 2);
232 if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
233 /* YUV height must be a multiple of 32 */
234 h &= ~0x1f;
235 min_h = 32;
236 }
237 h = min(h, cx->is_50hz ? 576 : 480);
238 h = max(h, min_h);
239
240 fmt->fmt.pix.width = w;
241 fmt->fmt.pix.height = h;
242 return 0;
243}
244
245static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
246 struct v4l2_format *fmt)
247{
248 return cx18_g_fmt_vbi_cap(file, fh, fmt);
249}
250
251static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
252 struct v4l2_format *fmt)
253{
254 struct cx18 *cx = fh2id(fh)->cx;
255 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
256
257 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
258 vbifmt->reserved[0] = 0;
259 vbifmt->reserved[1] = 0;
260
261 /* If given a service set, expand it validly & clear passed in set */
262 if (vbifmt->service_set)
263 cx18_expand_service_set(vbifmt, cx->is_50hz);
264 /* Sanitize the service_lines, and compute the new set if any valid */
265 if (check_service_set(vbifmt, cx->is_50hz))
266 vbifmt->service_set = cx18_get_service_set(vbifmt);
267 return 0;
268}
269
270static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
271 struct v4l2_format *fmt)
272{
273 struct cx18_open_id *id = fh2id(fh);
274 struct cx18 *cx = id->cx;
275 struct v4l2_mbus_framefmt mbus_fmt;
276 struct cx18_stream *s = &cx->streams[id->type];
277 int ret;
278 int w, h;
279
280 ret = cx18_try_fmt_vid_cap(file, fh, fmt);
281 if (ret)
282 return ret;
283 w = fmt->fmt.pix.width;
284 h = fmt->fmt.pix.height;
285
286 if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
287 s->pixelformat == fmt->fmt.pix.pixelformat)
288 return 0;
289
290 if (atomic_read(&cx->ana_capturing) > 0)
291 return -EBUSY;
292
293 s->pixelformat = fmt->fmt.pix.pixelformat;
294 /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
295 UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
296 if (s->pixelformat == V4L2_PIX_FMT_HM12)
297 s->vb_bytes_per_frame = h * 720 * 3 / 2;
298 else
299 s->vb_bytes_per_frame = h * 720 * 2;
300
301 mbus_fmt.width = cx->cxhdl.width = w;
302 mbus_fmt.height = cx->cxhdl.height = h;
303 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
304 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
305 return cx18_g_fmt_vid_cap(file, fh, fmt);
306}
307
308static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
309 struct v4l2_format *fmt)
310{
311 struct cx18_open_id *id = fh2id(fh);
312 struct cx18 *cx = id->cx;
313 int ret;
314
315 /*
316 * Changing the Encoder's Raw VBI parameters won't have any effect
317 * if any analog capture is ongoing
318 */
319 if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
320 return -EBUSY;
321
322 /*
323 * Set the digitizer registers for raw active VBI.
324 * Note cx18_av_vbi_wipes out a lot of the passed in fmt under valid
325 * calling conditions
326 */
327 ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi);
328 if (ret)
329 return ret;
330
331 /* Store our new v4l2 (non-)sliced VBI state */
332 cx->vbi.sliced_in->service_set = 0;
333 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
334
335 return cx18_g_fmt_vbi_cap(file, fh, fmt);
336}
337
338static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
339 struct v4l2_format *fmt)
340{
341 struct cx18_open_id *id = fh2id(fh);
342 struct cx18 *cx = id->cx;
343 int ret;
344 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
345
346 cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
347
348 /*
349 * Changing the Encoder's Raw VBI parameters won't have any effect
350 * if any analog capture is ongoing
351 */
352 if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
353 return -EBUSY;
354
355 /*
356 * Set the service_lines requested in the digitizer/slicer registers.
357 * Note, cx18_av_vbi() wipes some "impossible" service lines in the
358 * passed in fmt->fmt.sliced under valid calling conditions
359 */
360 ret = v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &fmt->fmt.sliced);
361 if (ret)
362 return ret;
363 /* Store our current v4l2 sliced VBI settings */
364 cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
365 memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
366 return 0;
367}
368
369static int cx18_g_chip_ident(struct file *file, void *fh,
370 struct v4l2_dbg_chip_ident *chip)
371{
372 struct cx18 *cx = fh2id(fh)->cx;
373 int err = 0;
374
375 chip->ident = V4L2_IDENT_NONE;
376 chip->revision = 0;
377 switch (chip->match.type) {
378 case V4L2_CHIP_MATCH_HOST:
379 switch (chip->match.addr) {
380 case 0:
381 chip->ident = V4L2_IDENT_CX23418;
382 chip->revision = cx18_read_reg(cx, 0xC72028);
383 break;
384 case 1:
385 /*
386 * The A/V decoder is always present, but in the rare
387 * case that the card doesn't have analog, we don't
388 * use it. We find it w/o using the cx->sd_av pointer
389 */
390 cx18_call_hw(cx, CX18_HW_418_AV,
391 core, g_chip_ident, chip);
392 break;
393 default:
394 /*
395 * Could return ident = V4L2_IDENT_UNKNOWN if we had
396 * other host chips at higher addresses, but we don't
397 */
398 err = -EINVAL; /* per V4L2 spec */
399 break;
400 }
401 break;
402 case V4L2_CHIP_MATCH_I2C_DRIVER:
403 /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
404 cx18_call_all(cx, core, g_chip_ident, chip);
405 break;
406 case V4L2_CHIP_MATCH_I2C_ADDR:
407 /*
408 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
409 * to look if a chip is at the address with no driver. That's a
410 * dangerous thing to do with EEPROMs anyway.
411 */
412 cx18_call_all(cx, core, g_chip_ident, chip);
413 break;
414 default:
415 err = -EINVAL;
416 break;
417 }
418 return err;
419}
420
421#ifdef CONFIG_VIDEO_ADV_DEBUG
422static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
423{
424 struct v4l2_dbg_register *regs = arg;
425
426 if (!capable(CAP_SYS_ADMIN))
427 return -EPERM;
428 if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
429 return -EINVAL;
430
431 regs->size = 4;
432 if (cmd == VIDIOC_DBG_S_REGISTER)
433 cx18_write_enc(cx, regs->val, regs->reg);
434 else
435 regs->val = cx18_read_enc(cx, regs->reg);
436 return 0;
437}
438
439static int cx18_g_register(struct file *file, void *fh,
440 struct v4l2_dbg_register *reg)
441{
442 struct cx18 *cx = fh2id(fh)->cx;
443
444 if (v4l2_chip_match_host(&reg->match))
445 return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
446 /* FIXME - errors shouldn't be ignored */
447 cx18_call_all(cx, core, g_register, reg);
448 return 0;
449}
450
451static int cx18_s_register(struct file *file, void *fh,
452 struct v4l2_dbg_register *reg)
453{
454 struct cx18 *cx = fh2id(fh)->cx;
455
456 if (v4l2_chip_match_host(&reg->match))
457 return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
458 /* FIXME - errors shouldn't be ignored */
459 cx18_call_all(cx, core, s_register, reg);
460 return 0;
461}
462#endif
463
464static int cx18_querycap(struct file *file, void *fh,
465 struct v4l2_capability *vcap)
466{
467 struct cx18_open_id *id = fh2id(fh);
468 struct cx18 *cx = id->cx;
469
470 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
471 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
472 snprintf(vcap->bus_info, sizeof(vcap->bus_info),
473 "PCI:%s", pci_name(cx->pci_dev));
474 vcap->capabilities = cx->v4l2_cap; /* capabilities */
475 if (id->type == CX18_ENC_STREAM_TYPE_YUV)
476 vcap->capabilities |= V4L2_CAP_STREAMING;
477 return 0;
478}
479
480static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
481{
482 struct cx18 *cx = fh2id(fh)->cx;
483
484 return cx18_get_audio_input(cx, vin->index, vin);
485}
486
487static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
488{
489 struct cx18 *cx = fh2id(fh)->cx;
490
491 vin->index = cx->audio_input;
492 return cx18_get_audio_input(cx, vin->index, vin);
493}
494
495static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
496{
497 struct cx18 *cx = fh2id(fh)->cx;
498
499 if (vout->index >= cx->nof_audio_inputs)
500 return -EINVAL;
501 cx->audio_input = vout->index;
502 cx18_audio_set_io(cx);
503 return 0;
504}
505
506static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
507{
508 struct cx18 *cx = fh2id(fh)->cx;
509
510 /* set it to defaults from our table */
511 return cx18_get_input(cx, vin->index, vin);
512}
513
514static int cx18_cropcap(struct file *file, void *fh,
515 struct v4l2_cropcap *cropcap)
516{
517 struct cx18 *cx = fh2id(fh)->cx;
518
519 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
520 return -EINVAL;
521 cropcap->bounds.top = cropcap->bounds.left = 0;
522 cropcap->bounds.width = 720;
523 cropcap->bounds.height = cx->is_50hz ? 576 : 480;
524 cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
525 cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
526 cropcap->defrect = cropcap->bounds;
527 return 0;
528}
529
530static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
531{
532 struct cx18_open_id *id = fh2id(fh);
533 struct cx18 *cx = id->cx;
534
535 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
536 return -EINVAL;
537 CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
538 return -EINVAL;
539}
540
541static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
542{
543 struct cx18 *cx = fh2id(fh)->cx;
544
545 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
546 return -EINVAL;
547 CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
548 return -EINVAL;
549}
550
551static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
552 struct v4l2_fmtdesc *fmt)
553{
554 static const struct v4l2_fmtdesc formats[] = {
555 { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
556 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
557 },
558 { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
559 "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
560 },
561 { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
562 "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
563 },
564 };
565
566 if (fmt->index > ARRAY_SIZE(formats) - 1)
567 return -EINVAL;
568 *fmt = formats[fmt->index];
569 return 0;
570}
571
572static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
573{
574 struct cx18 *cx = fh2id(fh)->cx;
575
576 *i = cx->active_input;
577 return 0;
578}
579
580int cx18_s_input(struct file *file, void *fh, unsigned int inp)
581{
582 struct cx18_open_id *id = fh2id(fh);
583 struct cx18 *cx = id->cx;
584
585 if (inp >= cx->nof_inputs)
586 return -EINVAL;
587
588 if (inp == cx->active_input) {
589 CX18_DEBUG_INFO("Input unchanged\n");
590 return 0;
591 }
592
593 CX18_DEBUG_INFO("Changing input from %d to %d\n",
594 cx->active_input, inp);
595
596 cx->active_input = inp;
597 /* Set the audio input to whatever is appropriate for the input type. */
598 cx->audio_input = cx->card->video_inputs[inp].audio_index;
599
600 /* prevent others from messing with the streams until
601 we're finished changing inputs. */
602 cx18_mute(cx);
603 cx18_video_set_io(cx);
604 cx18_audio_set_io(cx);
605 cx18_unmute(cx);
606 return 0;
607}
608
609static int cx18_g_frequency(struct file *file, void *fh,
610 struct v4l2_frequency *vf)
611{
612 struct cx18 *cx = fh2id(fh)->cx;
613
614 if (vf->tuner != 0)
615 return -EINVAL;
616
617 cx18_call_all(cx, tuner, g_frequency, vf);
618 return 0;
619}
620
621int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
622{
623 struct cx18_open_id *id = fh2id(fh);
624 struct cx18 *cx = id->cx;
625
626 if (vf->tuner != 0)
627 return -EINVAL;
628
629 cx18_mute(cx);
630 CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
631 cx18_call_all(cx, tuner, s_frequency, vf);
632 cx18_unmute(cx);
633 return 0;
634}
635
636static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
637{
638 struct cx18 *cx = fh2id(fh)->cx;
639
640 *std = cx->std;
641 return 0;
642}
643
644int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
645{
646 struct cx18_open_id *id = fh2id(fh);
647 struct cx18 *cx = id->cx;
648
649 if ((*std & V4L2_STD_ALL) == 0)
650 return -EINVAL;
651
652 if (*std == cx->std)
653 return 0;
654
655 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
656 atomic_read(&cx->ana_capturing) > 0) {
657 /* Switching standard would turn off the radio or mess
658 with already running streams, prevent that by
659 returning EBUSY. */
660 return -EBUSY;
661 }
662
663 cx->std = *std;
664 cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
665 cx->is_50hz = !cx->is_60hz;
666 cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
667 cx->cxhdl.width = 720;
668 cx->cxhdl.height = cx->is_50hz ? 576 : 480;
669 cx->vbi.count = cx->is_50hz ? 18 : 12;
670 cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
671 cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
672 CX18_DEBUG_INFO("Switching standard to %llx.\n",
673 (unsigned long long) cx->std);
674
675 /* Tuner */
676 cx18_call_all(cx, core, s_std, cx->std);
677 return 0;
678}
679
680static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
681{
682 struct cx18_open_id *id = fh2id(fh);
683 struct cx18 *cx = id->cx;
684
685 if (vt->index != 0)
686 return -EINVAL;
687
688 cx18_call_all(cx, tuner, s_tuner, vt);
689 return 0;
690}
691
692static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
693{
694 struct cx18 *cx = fh2id(fh)->cx;
695
696 if (vt->index != 0)
697 return -EINVAL;
698
699 cx18_call_all(cx, tuner, g_tuner, vt);
700
701 if (vt->type == V4L2_TUNER_RADIO)
702 strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
703 else
704 strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
705 return 0;
706}
707
708static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
709 struct v4l2_sliced_vbi_cap *cap)
710{
711 struct cx18 *cx = fh2id(fh)->cx;
712 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
713 int f, l;
714
715 if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
716 return -EINVAL;
717
718 cap->service_set = 0;
719 for (f = 0; f < 2; f++) {
720 for (l = 0; l < 24; l++) {
721 if (valid_service_line(f, l, cx->is_50hz)) {
722 /*
723 * We can find all v4l2 supported vbi services
724 * for the standard, on a valid line for the std
725 */
726 cap->service_lines[f][l] = set;
727 cap->service_set |= set;
728 } else
729 cap->service_lines[f][l] = 0;
730 }
731 }
732 for (f = 0; f < 3; f++)
733 cap->reserved[f] = 0;
734 return 0;
735}
736
737static int _cx18_process_idx_data(struct cx18_buffer *buf,
738 struct v4l2_enc_idx *idx)
739{
740 int consumed, remaining;
741 struct v4l2_enc_idx_entry *e_idx;
742 struct cx18_enc_idx_entry *e_buf;
743
744 /* Frame type lookup: 1=I, 2=P, 4=B */
745 const int mapping[8] = {
746 -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
747 -1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
748 };
749
750 /*
751 * Assumption here is that a buf holds an integral number of
752 * struct cx18_enc_idx_entry objects and is properly aligned.
753 * This is enforced by the module options on IDX buffer sizes.
754 */
755 remaining = buf->bytesused - buf->readpos;
756 consumed = 0;
757 e_idx = &idx->entry[idx->entries];
758 e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
759
760 while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
761 idx->entries < V4L2_ENC_IDX_ENTRIES) {
762
763 e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
764 | le32_to_cpu(e_buf->offset_low);
765
766 e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
767 | le32_to_cpu(e_buf->pts_low);
768
769 e_idx->length = le32_to_cpu(e_buf->length);
770
771 e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
772
773 e_idx->reserved[0] = 0;
774 e_idx->reserved[1] = 0;
775
776 idx->entries++;
777 e_idx = &idx->entry[idx->entries];
778 e_buf++;
779
780 remaining -= sizeof(struct cx18_enc_idx_entry);
781 consumed += sizeof(struct cx18_enc_idx_entry);
782 }
783
784 /* Swallow any partial entries at the end, if there are any */
785 if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
786 consumed += remaining;
787
788 buf->readpos += consumed;
789 return consumed;
790}
791
792static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
793 struct v4l2_enc_idx *idx)
794{
795 if (s->type != CX18_ENC_STREAM_TYPE_IDX)
796 return -EINVAL;
797
798 if (mdl->curr_buf == NULL)
799 mdl->curr_buf = list_first_entry(&mdl->buf_list,
800 struct cx18_buffer, list);
801
802 if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
803 /*
804 * For some reason we've exhausted the buffers, but the MDL
805 * object still said some data was unread.
806 * Fix that and bail out.
807 */
808 mdl->readpos = mdl->bytesused;
809 return 0;
810 }
811
812 list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
813
814 /* Skip any empty buffers in the MDL */
815 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
816 continue;
817
818 mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
819
820 /* exit when MDL drained or request satisfied */
821 if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
822 mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
823 mdl->readpos >= mdl->bytesused)
824 break;
825 }
826 return 0;
827}
828
829static int cx18_g_enc_index(struct file *file, void *fh,
830 struct v4l2_enc_idx *idx)
831{
832 struct cx18 *cx = fh2id(fh)->cx;
833 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
834 s32 tmp;
835 struct cx18_mdl *mdl;
836
837 if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
838 return -EINVAL;
839
840 /* Compute the best case number of entries we can buffer */
841 tmp = s->buffers -
842 s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
843 if (tmp <= 0)
844 tmp = 1;
845 tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
846
847 /* Fill out the header of the return structure */
848 idx->entries = 0;
849 idx->entries_cap = tmp;
850 memset(idx->reserved, 0, sizeof(idx->reserved));
851
852 /* Pull IDX MDLs and buffers from q_full and populate the entries */
853 do {
854 mdl = cx18_dequeue(s, &s->q_full);
855 if (mdl == NULL) /* No more IDX data right now */
856 break;
857
858 /* Extract the Index entry data from the MDL and buffers */
859 cx18_process_idx_data(s, mdl, idx);
860 if (mdl->readpos < mdl->bytesused) {
861 /* We finished with data remaining, push the MDL back */
862 cx18_push(s, mdl, &s->q_full);
863 break;
864 }
865
866 /* We drained this MDL, schedule it to go to the firmware */
867 cx18_enqueue(s, mdl, &s->q_free);
868
869 } while (idx->entries < V4L2_ENC_IDX_ENTRIES);
870
871 /* Tell the work handler to send free IDX MDLs to the firmware */
872 cx18_stream_load_fw_queue(s);
873 return 0;
874}
875
876static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
877{
878 struct videobuf_queue *q = NULL;
879 struct cx18 *cx = id->cx;
880 struct cx18_stream *s = &cx->streams[id->type];
881
882 switch (s->vb_type) {
883 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
884 q = &s->vbuf_q;
885 break;
886 case V4L2_BUF_TYPE_VBI_CAPTURE:
887 break;
888 default:
889 break;
890 }
891 return q;
892}
893
894static int cx18_streamon(struct file *file, void *priv,
895 enum v4l2_buf_type type)
896{
897 struct cx18_open_id *id = file->private_data;
898 struct cx18 *cx = id->cx;
899 struct cx18_stream *s = &cx->streams[id->type];
900
901 /* Start the hardware only if we're the video device */
902 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
903 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
904 return -EINVAL;
905
906 if (id->type != CX18_ENC_STREAM_TYPE_YUV)
907 return -EINVAL;
908
909 /* Establish a buffer timeout */
910 mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
911
912 return videobuf_streamon(cx18_vb_queue(id));
913}
914
915static int cx18_streamoff(struct file *file, void *priv,
916 enum v4l2_buf_type type)
917{
918 struct cx18_open_id *id = file->private_data;
919 struct cx18 *cx = id->cx;
920 struct cx18_stream *s = &cx->streams[id->type];
921
922 /* Start the hardware only if we're the video device */
923 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
924 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
925 return -EINVAL;
926
927 if (id->type != CX18_ENC_STREAM_TYPE_YUV)
928 return -EINVAL;
929
930 return videobuf_streamoff(cx18_vb_queue(id));
931}
932
933static int cx18_reqbufs(struct file *file, void *priv,
934 struct v4l2_requestbuffers *rb)
935{
936 struct cx18_open_id *id = file->private_data;
937 struct cx18 *cx = id->cx;
938 struct cx18_stream *s = &cx->streams[id->type];
939
940 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
941 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
942 return -EINVAL;
943
944 return videobuf_reqbufs(cx18_vb_queue(id), rb);
945}
946
947static int cx18_querybuf(struct file *file, void *priv,
948 struct v4l2_buffer *b)
949{
950 struct cx18_open_id *id = file->private_data;
951 struct cx18 *cx = id->cx;
952 struct cx18_stream *s = &cx->streams[id->type];
953
954 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
955 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
956 return -EINVAL;
957
958 return videobuf_querybuf(cx18_vb_queue(id), b);
959}
960
961static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
962{
963 struct cx18_open_id *id = file->private_data;
964 struct cx18 *cx = id->cx;
965 struct cx18_stream *s = &cx->streams[id->type];
966
967 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
968 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
969 return -EINVAL;
970
971 return videobuf_qbuf(cx18_vb_queue(id), b);
972}
973
974static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
975{
976 struct cx18_open_id *id = file->private_data;
977 struct cx18 *cx = id->cx;
978 struct cx18_stream *s = &cx->streams[id->type];
979
980 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
981 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
982 return -EINVAL;
983
984 return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
985}
986
987static int cx18_encoder_cmd(struct file *file, void *fh,
988 struct v4l2_encoder_cmd *enc)
989{
990 struct cx18_open_id *id = fh2id(fh);
991 struct cx18 *cx = id->cx;
992 u32 h;
993
994 switch (enc->cmd) {
995 case V4L2_ENC_CMD_START:
996 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
997 enc->flags = 0;
998 return cx18_start_capture(id);
999
1000 case V4L2_ENC_CMD_STOP:
1001 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1002 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1003 cx18_stop_capture(id,
1004 enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1005 break;
1006
1007 case V4L2_ENC_CMD_PAUSE:
1008 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1009 enc->flags = 0;
1010 if (!atomic_read(&cx->ana_capturing))
1011 return -EPERM;
1012 if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
1013 return 0;
1014 h = cx18_find_handle(cx);
1015 if (h == CX18_INVALID_TASK_HANDLE) {
1016 CX18_ERR("Can't find valid task handle for "
1017 "V4L2_ENC_CMD_PAUSE\n");
1018 return -EBADFD;
1019 }
1020 cx18_mute(cx);
1021 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
1022 break;
1023
1024 case V4L2_ENC_CMD_RESUME:
1025 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1026 enc->flags = 0;
1027 if (!atomic_read(&cx->ana_capturing))
1028 return -EPERM;
1029 if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
1030 return 0;
1031 h = cx18_find_handle(cx);
1032 if (h == CX18_INVALID_TASK_HANDLE) {
1033 CX18_ERR("Can't find valid task handle for "
1034 "V4L2_ENC_CMD_RESUME\n");
1035 return -EBADFD;
1036 }
1037 cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
1038 cx18_unmute(cx);
1039 break;
1040
1041 default:
1042 CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1043 return -EINVAL;
1044 }
1045 return 0;
1046}
1047
1048static int cx18_try_encoder_cmd(struct file *file, void *fh,
1049 struct v4l2_encoder_cmd *enc)
1050{
1051 struct cx18 *cx = fh2id(fh)->cx;
1052
1053 switch (enc->cmd) {
1054 case V4L2_ENC_CMD_START:
1055 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1056 enc->flags = 0;
1057 break;
1058
1059 case V4L2_ENC_CMD_STOP:
1060 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1061 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1062 break;
1063
1064 case V4L2_ENC_CMD_PAUSE:
1065 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1066 enc->flags = 0;
1067 break;
1068
1069 case V4L2_ENC_CMD_RESUME:
1070 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1071 enc->flags = 0;
1072 break;
1073
1074 default:
1075 CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1076 return -EINVAL;
1077 }
1078 return 0;
1079}
1080
1081static int cx18_log_status(struct file *file, void *fh)
1082{
1083 struct cx18 *cx = fh2id(fh)->cx;
1084 struct v4l2_input vidin;
1085 struct v4l2_audio audin;
1086 int i;
1087
1088 CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
1089 if (cx->hw_flags & CX18_HW_TVEEPROM) {
1090 struct tveeprom tv;
1091
1092 cx18_read_eeprom(cx, &tv);
1093 }
1094 cx18_call_all(cx, core, log_status);
1095 cx18_get_input(cx, cx->active_input, &vidin);
1096 cx18_get_audio_input(cx, cx->audio_input, &audin);
1097 CX18_INFO("Video Input: %s\n", vidin.name);
1098 CX18_INFO("Audio Input: %s\n", audin.name);
1099 mutex_lock(&cx->gpio_lock);
1100 CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
1101 cx->gpio_dir, cx->gpio_val);
1102 mutex_unlock(&cx->gpio_lock);
1103 CX18_INFO("Tuner: %s\n",
1104 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
1105 v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
1106 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
1107 for (i = 0; i < CX18_MAX_STREAMS; i++) {
1108 struct cx18_stream *s = &cx->streams[i];
1109
1110 if (s->video_dev == NULL || s->buffers == 0)
1111 continue;
1112 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
1113 s->name, s->s_flags,
1114 atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
1115 / s->buffers,
1116 (s->buffers * s->buf_size) / 1024, s->buffers);
1117 }
1118 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
1119 (long long)cx->mpg_data_received,
1120 (long long)cx->vbi_data_inserted);
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 -ENOTTY;
1141 }
1142 return 0;
1143}
1144
1145static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1146 .vidioc_querycap = cx18_querycap,
1147 .vidioc_s_audio = cx18_s_audio,
1148 .vidioc_g_audio = cx18_g_audio,
1149 .vidioc_enumaudio = cx18_enumaudio,
1150 .vidioc_enum_input = cx18_enum_input,
1151 .vidioc_cropcap = cx18_cropcap,
1152 .vidioc_s_crop = cx18_s_crop,
1153 .vidioc_g_crop = cx18_g_crop,
1154 .vidioc_g_input = cx18_g_input,
1155 .vidioc_s_input = cx18_s_input,
1156 .vidioc_g_frequency = cx18_g_frequency,
1157 .vidioc_s_frequency = cx18_s_frequency,
1158 .vidioc_s_tuner = cx18_s_tuner,
1159 .vidioc_g_tuner = cx18_g_tuner,
1160 .vidioc_g_enc_index = cx18_g_enc_index,
1161 .vidioc_g_std = cx18_g_std,
1162 .vidioc_s_std = cx18_s_std,
1163 .vidioc_log_status = cx18_log_status,
1164 .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap,
1165 .vidioc_encoder_cmd = cx18_encoder_cmd,
1166 .vidioc_try_encoder_cmd = cx18_try_encoder_cmd,
1167 .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap,
1168 .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap,
1169 .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap,
1170 .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap,
1171 .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap,
1172 .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap,
1173 .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap,
1174 .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap,
1175 .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap,
1176 .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap,
1177 .vidioc_g_chip_ident = cx18_g_chip_ident,
1178#ifdef CONFIG_VIDEO_ADV_DEBUG
1179 .vidioc_g_register = cx18_g_register,
1180 .vidioc_s_register = cx18_s_register,
1181#endif
1182 .vidioc_default = cx18_default,
1183 .vidioc_streamon = cx18_streamon,
1184 .vidioc_streamoff = cx18_streamoff,
1185 .vidioc_reqbufs = cx18_reqbufs,
1186 .vidioc_querybuf = cx18_querybuf,
1187 .vidioc_qbuf = cx18_qbuf,
1188 .vidioc_dqbuf = cx18_dqbuf,
1189};
1190
1191void cx18_set_funcs(struct video_device *vdev)
1192{
1193 vdev->ioctl_ops = &cx18_ioctl_ops;
1194}
diff --git a/drivers/media/pci/cx18/cx18-ioctl.h b/drivers/media/pci/cx18/cx18-ioctl.h
new file mode 100644
index 000000000000..2f9dd591ee0f
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-ioctl.h
@@ -0,0 +1,31 @@
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);
diff --git a/drivers/media/pci/cx18/cx18-irq.c b/drivers/media/pci/cx18/cx18-irq.c
new file mode 100644
index 000000000000..80edfe93a3d8
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-irq.h b/drivers/media/pci/cx18/cx18-irq.h
new file mode 100644
index 000000000000..30e7eaf8cb55
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c
new file mode 100644
index 000000000000..eabf00c6351b
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-mailbox.c
@@ -0,0 +1,870 @@
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 >= s->vb_bytes_per_frame) {
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 int i;
438
439 mb = &order->mb;
440 handle = mb->args[0];
441 mdl_ack_offset = mb->args[1];
442 mdl_ack_count = mb->args[2];
443
444 if (handle == CX18_INVALID_TASK_HANDLE ||
445 mdl_ack_count == 0 || mdl_ack_count > CX18_MAX_MDL_ACKS) {
446 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
447 mb_ack_irq(cx, order);
448 return -1;
449 }
450
451 for (i = 0; i < sizeof(struct cx18_mdl_ack) * mdl_ack_count; i += sizeof(u32))
452 ((u32 *)order->mdl_ack)[i / sizeof(u32)] =
453 cx18_readl(cx, cx->enc_mem + mdl_ack_offset + i);
454
455 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
456 mb_ack_irq(cx, order);
457 return 1;
458}
459
460static
461int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order)
462{
463 u32 str_offset;
464 char *str = order->str;
465
466 str[0] = '\0';
467 str_offset = order->mb.args[1];
468 if (str_offset) {
469 cx18_setup_page(cx, str_offset);
470 cx18_memcpy_fromio(cx, str, cx->enc_mem + str_offset, 252);
471 str[252] = '\0';
472 cx18_setup_page(cx, SCB_OFFSET);
473 }
474
475 if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
476 mb_ack_irq(cx, order);
477
478 return str_offset ? 1 : 0;
479}
480
481static inline
482int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order)
483{
484 int ret = -1;
485
486 switch (order->rpu) {
487 case CPU:
488 {
489 switch (order->mb.cmd) {
490 case CX18_EPU_DMA_DONE:
491 ret = epu_dma_done_irq(cx, order);
492 break;
493 case CX18_EPU_DEBUG:
494 ret = epu_debug_irq(cx, order);
495 break;
496 default:
497 CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
498 order->mb.cmd);
499 break;
500 }
501 break;
502 }
503 case APU:
504 CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
505 order->mb.cmd);
506 break;
507 default:
508 break;
509 }
510 return ret;
511}
512
513static inline
514struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx)
515{
516 int i;
517 struct cx18_in_work_order *order = NULL;
518
519 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
520 /*
521 * We only need "pending" atomic to inspect its contents,
522 * and need not do a check and set because:
523 * 1. Any work handler thread only clears "pending" and only
524 * on one, particular work order at a time, per handler thread.
525 * 2. "pending" is only set here, and we're serialized because
526 * we're called in an IRQ handler context.
527 */
528 if (atomic_read(&cx->in_work_order[i].pending) == 0) {
529 order = &cx->in_work_order[i];
530 atomic_set(&order->pending, 1);
531 break;
532 }
533 }
534 return order;
535}
536
537void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
538{
539 struct cx18_mailbox __iomem *mb;
540 struct cx18_mailbox *order_mb;
541 struct cx18_in_work_order *order;
542 int submit;
543 int i;
544
545 switch (rpu) {
546 case CPU:
547 mb = &cx->scb->cpu2epu_mb;
548 break;
549 case APU:
550 mb = &cx->scb->apu2epu_mb;
551 break;
552 default:
553 return;
554 }
555
556 order = alloc_in_work_order_irq(cx);
557 if (order == NULL) {
558 CX18_WARN("Unable to find blank work order form to schedule "
559 "incoming mailbox command processing\n");
560 return;
561 }
562
563 order->flags = 0;
564 order->rpu = rpu;
565 order_mb = &order->mb;
566
567 /* mb->cmd and mb->args[0] through mb->args[2] */
568 for (i = 0; i < 4; i++)
569 (&order_mb->cmd)[i] = cx18_readl(cx, &mb->cmd + i);
570
571 /* mb->request and mb->ack. N.B. we want to read mb->ack last */
572 for (i = 0; i < 2; i++)
573 (&order_mb->request)[i] = cx18_readl(cx, &mb->request + i);
574
575 if (order_mb->request == order_mb->ack) {
576 CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
577 "incoming %s to EPU mailbox (sequence no. %u)"
578 "\n",
579 rpu_str[rpu], rpu_str[rpu], order_mb->request);
580 if (cx18_debug & CX18_DBGFLG_WARN)
581 dump_mb(cx, order_mb, "incoming");
582 order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
583 }
584
585 /*
586 * Individual EPU command processing is responsible for ack-ing
587 * a non-stale mailbox as soon as possible
588 */
589 submit = epu_cmd_irq(cx, order);
590 if (submit > 0) {
591 queue_work(cx->in_work_queue, &order->work);
592 }
593}
594
595
596/*
597 * Functions called from a non-interrupt, non work_queue context
598 */
599
600static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
601{
602 const struct cx18_api_info *info = find_api_info(cmd);
603 u32 irq, req, ack, err;
604 struct cx18_mailbox __iomem *mb;
605 wait_queue_head_t *waitq;
606 struct mutex *mb_lock;
607 unsigned long int t0, timeout, ret;
608 int i;
609 char argstr[MAX_MB_ARGUMENTS*11+1];
610 DEFINE_WAIT(w);
611
612 if (info == NULL) {
613 CX18_WARN("unknown cmd %x\n", cmd);
614 return -EINVAL;
615 }
616
617 if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */
618 if (cmd == CX18_CPU_DE_SET_MDL) {
619 if (cx18_debug & CX18_DBGFLG_HIGHVOL)
620 CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n",
621 info->name, cmd,
622 u32arr2hex(data, args, argstr));
623 } else
624 CX18_DEBUG_API("%s\tcmd %#010x args%s\n",
625 info->name, cmd,
626 u32arr2hex(data, args, argstr));
627 }
628
629 switch (info->rpu) {
630 case APU:
631 waitq = &cx->mb_apu_waitq;
632 mb_lock = &cx->epu2apu_mb_lock;
633 irq = IRQ_EPU_TO_APU;
634 mb = &cx->scb->epu2apu_mb;
635 break;
636 case CPU:
637 waitq = &cx->mb_cpu_waitq;
638 mb_lock = &cx->epu2cpu_mb_lock;
639 irq = IRQ_EPU_TO_CPU;
640 mb = &cx->scb->epu2cpu_mb;
641 break;
642 default:
643 CX18_WARN("Unknown RPU (%d) for API call\n", info->rpu);
644 return -EINVAL;
645 }
646
647 mutex_lock(mb_lock);
648 /*
649 * Wait for an in-use mailbox to complete
650 *
651 * If the XPU is responding with Ack's, the mailbox shouldn't be in
652 * a busy state, since we serialize access to it on our end.
653 *
654 * If the wait for ack after sending a previous command was interrupted
655 * by a signal, we may get here and find a busy mailbox. After waiting,
656 * mark it "not busy" from our end, if the XPU hasn't ack'ed it still.
657 */
658 req = cx18_readl(cx, &mb->request);
659 timeout = msecs_to_jiffies(10);
660 ret = wait_event_timeout(*waitq,
661 (ack = cx18_readl(cx, &mb->ack)) == req,
662 timeout);
663 if (req != ack) {
664 /* waited long enough, make the mbox "not busy" from our end */
665 cx18_writel(cx, req, &mb->ack);
666 CX18_ERR("mbox was found stuck busy when setting up for %s; "
667 "clearing busy and trying to proceed\n", info->name);
668 } else if (ret != timeout)
669 CX18_DEBUG_API("waited %u msecs for busy mbox to be acked\n",
670 jiffies_to_msecs(timeout-ret));
671
672 /* Build the outgoing mailbox */
673 req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1;
674
675 cx18_writel(cx, cmd, &mb->cmd);
676 for (i = 0; i < args; i++)
677 cx18_writel(cx, data[i], &mb->args[i]);
678 cx18_writel(cx, 0, &mb->error);
679 cx18_writel(cx, req, &mb->request);
680 cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */
681
682 /*
683 * Notify the XPU and wait for it to send an Ack back
684 */
685 timeout = msecs_to_jiffies((info->flags & API_FAST) ? 10 : 20);
686
687 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
688 irq, info->name);
689
690 /* So we don't miss the wakeup, prepare to wait before notifying fw */
691 prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
692 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
693
694 t0 = jiffies;
695 ack = cx18_readl(cx, &mb->ack);
696 if (ack != req) {
697 schedule_timeout(timeout);
698 ret = jiffies - t0;
699 ack = cx18_readl(cx, &mb->ack);
700 } else {
701 ret = jiffies - t0;
702 }
703
704 finish_wait(waitq, &w);
705
706 if (req != ack) {
707 mutex_unlock(mb_lock);
708 if (ret >= timeout) {
709 /* Timed out */
710 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
711 "for RPU acknowledgement\n",
712 info->name, jiffies_to_msecs(ret));
713 } else {
714 CX18_DEBUG_WARN("woken up before mailbox ack was ready "
715 "after submitting %s to RPU. only "
716 "waited %d msecs on req %u but awakened"
717 " with unmatched ack %u\n",
718 info->name,
719 jiffies_to_msecs(ret),
720 req, ack);
721 }
722 return -EINVAL;
723 }
724
725 if (ret >= timeout)
726 CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
727 "sending %s; timed out waiting %d msecs\n",
728 info->name, jiffies_to_msecs(ret));
729 else
730 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
731 jiffies_to_msecs(ret), info->name);
732
733 /* Collect data returned by the XPU */
734 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
735 data[i] = cx18_readl(cx, &mb->args[i]);
736 err = cx18_readl(cx, &mb->error);
737 mutex_unlock(mb_lock);
738
739 /*
740 * Wait for XPU to perform extra actions for the caller in some cases.
741 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
742 * back in a burst shortly thereafter
743 */
744 if (info->flags & API_SLOW)
745 cx18_msleep_timeout(300, 0);
746
747 if (err)
748 CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
749 info->name);
750 return err ? -EIO : 0;
751}
752
753int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[])
754{
755 return cx18_api_call(cx, cmd, args, data);
756}
757
758static int cx18_set_filter_param(struct cx18_stream *s)
759{
760 struct cx18 *cx = s->cx;
761 u32 mode;
762 int ret;
763
764 mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0);
765 ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
766 s->handle, 1, mode, cx->spatial_strength);
767 mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0);
768 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
769 s->handle, 0, mode, cx->temporal_strength);
770 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
771 s->handle, 2, cx->filter_mode >> 2, 0);
772 return ret;
773}
774
775int cx18_api_func(void *priv, u32 cmd, int in, int out,
776 u32 data[CX2341X_MBOX_MAX_DATA])
777{
778 struct cx18_stream *s = priv;
779 struct cx18 *cx = s->cx;
780
781 switch (cmd) {
782 case CX2341X_ENC_SET_OUTPUT_PORT:
783 return 0;
784 case CX2341X_ENC_SET_FRAME_RATE:
785 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6,
786 s->handle, 0, 0, 0, 0, data[0]);
787 case CX2341X_ENC_SET_FRAME_SIZE:
788 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3,
789 s->handle, data[1], data[0]);
790 case CX2341X_ENC_SET_STREAM_TYPE:
791 return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2,
792 s->handle, data[0]);
793 case CX2341X_ENC_SET_ASPECT_RATIO:
794 return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2,
795 s->handle, data[0]);
796
797 case CX2341X_ENC_SET_GOP_PROPERTIES:
798 return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3,
799 s->handle, data[0], data[1]);
800 case CX2341X_ENC_SET_GOP_CLOSURE:
801 return 0;
802 case CX2341X_ENC_SET_AUDIO_PROPERTIES:
803 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
804 s->handle, data[0]);
805 case CX2341X_ENC_MUTE_AUDIO:
806 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
807 s->handle, data[0]);
808 case CX2341X_ENC_SET_BIT_RATE:
809 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5,
810 s->handle, data[0], data[1], data[2], data[3]);
811 case CX2341X_ENC_MUTE_VIDEO:
812 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
813 s->handle, data[0]);
814 case CX2341X_ENC_SET_FRAME_DROP_RATE:
815 return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2,
816 s->handle, data[0]);
817 case CX2341X_ENC_MISC:
818 return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4,
819 s->handle, data[0], data[1], data[2]);
820 case CX2341X_ENC_SET_DNR_FILTER_MODE:
821 cx->filter_mode = (data[0] & 3) | (data[1] << 2);
822 return cx18_set_filter_param(s);
823 case CX2341X_ENC_SET_DNR_FILTER_PROPS:
824 cx->spatial_strength = data[0];
825 cx->temporal_strength = data[1];
826 return cx18_set_filter_param(s);
827 case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
828 return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3,
829 s->handle, data[0], data[1]);
830 case CX2341X_ENC_SET_CORING_LEVELS:
831 return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5,
832 s->handle, data[0], data[1], data[2], data[3]);
833 }
834 CX18_WARN("Unknown cmd %x\n", cmd);
835 return 0;
836}
837
838int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS],
839 u32 cmd, int args, ...)
840{
841 va_list ap;
842 int i;
843
844 va_start(ap, args);
845 for (i = 0; i < args; i++)
846 data[i] = va_arg(ap, u32);
847 va_end(ap);
848 return cx18_api(cx, cmd, args, data);
849}
850
851int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...)
852{
853 u32 data[MAX_MB_ARGUMENTS];
854 va_list ap;
855 int i;
856
857 if (cx == NULL) {
858 CX18_ERR("cx == NULL (cmd=%x)\n", cmd);
859 return 0;
860 }
861 if (args > MAX_MB_ARGUMENTS) {
862 CX18_ERR("args too big (cmd=%x)\n", cmd);
863 args = MAX_MB_ARGUMENTS;
864 }
865 va_start(ap, args);
866 for (i = 0; i < args; i++)
867 data[i] = va_arg(ap, u32);
868 va_end(ap);
869 return cx18_api(cx, cmd, args, data);
870}
diff --git a/drivers/media/pci/cx18/cx18-mailbox.h b/drivers/media/pci/cx18/cx18-mailbox.h
new file mode 100644
index 000000000000..b63fdfaac49e
--- /dev/null
+++ b/drivers/media/pci/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 successfully, 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/pci/cx18/cx18-queue.c b/drivers/media/pci/cx18/cx18-queue.c
new file mode 100644
index 000000000000..8884537bd62f
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-queue.h b/drivers/media/pci/cx18/cx18-queue.h
new file mode 100644
index 000000000000..4201ddc16091
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-scb.c b/drivers/media/pci/cx18/cx18-scb.c
new file mode 100644
index 000000000000..85cc59637e54
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-scb.h b/drivers/media/pci/cx18/cx18-scb.h
new file mode 100644
index 000000000000..08877652e321
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
new file mode 100644
index 000000000000..9d598ab88615
--- /dev/null
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -0,0 +1,1060 @@
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 .unlocked_ioctl = video_ioctl2,
44 .release = cx18_v4l2_close,
45 .poll = cx18_v4l2_enc_poll,
46 .mmap = cx18_v4l2_mmap,
47};
48
49/* offset from 0 to register ts v4l2 minors on */
50#define CX18_V4L2_ENC_TS_OFFSET 16
51/* offset from 0 to register pcm v4l2 minors on */
52#define CX18_V4L2_ENC_PCM_OFFSET 24
53/* offset from 0 to register yuv v4l2 minors on */
54#define CX18_V4L2_ENC_YUV_OFFSET 32
55
56static struct {
57 const char *name;
58 int vfl_type;
59 int num_offset;
60 int dma;
61 enum v4l2_buf_type buf_type;
62} cx18_stream_info[] = {
63 { /* CX18_ENC_STREAM_TYPE_MPG */
64 "encoder MPEG",
65 VFL_TYPE_GRABBER, 0,
66 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
67 },
68 { /* CX18_ENC_STREAM_TYPE_TS */
69 "TS",
70 VFL_TYPE_GRABBER, -1,
71 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
72 },
73 { /* CX18_ENC_STREAM_TYPE_YUV */
74 "encoder YUV",
75 VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
76 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
77 },
78 { /* CX18_ENC_STREAM_TYPE_VBI */
79 "encoder VBI",
80 VFL_TYPE_VBI, 0,
81 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
82 },
83 { /* CX18_ENC_STREAM_TYPE_PCM */
84 "encoder PCM audio",
85 VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
86 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
87 },
88 { /* CX18_ENC_STREAM_TYPE_IDX */
89 "encoder IDX",
90 VFL_TYPE_GRABBER, -1,
91 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
92 },
93 { /* CX18_ENC_STREAM_TYPE_RAD */
94 "encoder radio",
95 VFL_TYPE_RADIO, 0,
96 PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
97 },
98};
99
100
101void cx18_dma_free(struct videobuf_queue *q,
102 struct cx18_stream *s, struct cx18_videobuf_buffer *buf)
103{
104 videobuf_waiton(q, &buf->vb, 0, 0);
105 videobuf_vmalloc_free(&buf->vb);
106 buf->vb.state = VIDEOBUF_NEEDS_INIT;
107}
108
109static int cx18_prepare_buffer(struct videobuf_queue *q,
110 struct cx18_stream *s,
111 struct cx18_videobuf_buffer *buf,
112 u32 pixelformat,
113 unsigned int width, unsigned int height,
114 enum v4l2_field field)
115{
116 struct cx18 *cx = s->cx;
117 int rc = 0;
118
119 /* check settings */
120 buf->bytes_used = 0;
121
122 if ((width < 48) || (height < 32))
123 return -EINVAL;
124
125 buf->vb.size = (width * height * 2);
126 if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
127 return -EINVAL;
128
129 /* alloc + fill struct (if changed) */
130 if (buf->vb.width != width || buf->vb.height != height ||
131 buf->vb.field != field || s->pixelformat != pixelformat ||
132 buf->tvnorm != cx->std) {
133
134 buf->vb.width = width;
135 buf->vb.height = height;
136 buf->vb.field = field;
137 buf->tvnorm = cx->std;
138 s->pixelformat = pixelformat;
139
140 /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
141 UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
142 if (s->pixelformat == V4L2_PIX_FMT_HM12)
143 s->vb_bytes_per_frame = height * 720 * 3 / 2;
144 else
145 s->vb_bytes_per_frame = height * 720 * 2;
146 cx18_dma_free(q, s, buf);
147 }
148
149 if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
150 return -EINVAL;
151
152 if (buf->vb.field == 0)
153 buf->vb.field = V4L2_FIELD_INTERLACED;
154
155 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
156 buf->vb.width = width;
157 buf->vb.height = height;
158 buf->vb.field = field;
159 buf->tvnorm = cx->std;
160 s->pixelformat = pixelformat;
161
162 /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
163 UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
164 if (s->pixelformat == V4L2_PIX_FMT_HM12)
165 s->vb_bytes_per_frame = height * 720 * 3 / 2;
166 else
167 s->vb_bytes_per_frame = height * 720 * 2;
168 rc = videobuf_iolock(q, &buf->vb, NULL);
169 if (rc != 0)
170 goto fail;
171 }
172 buf->vb.state = VIDEOBUF_PREPARED;
173 return 0;
174
175fail:
176 cx18_dma_free(q, s, buf);
177 return rc;
178
179}
180
181/* VB_MIN_BUFSIZE is lcm(1440 * 480, 1440 * 576)
182 1440 is a single line of 4:2:2 YUV at 720 luma samples wide
183*/
184#define VB_MIN_BUFFERS 32
185#define VB_MIN_BUFSIZE 4147200
186
187static int buffer_setup(struct videobuf_queue *q,
188 unsigned int *count, unsigned int *size)
189{
190 struct cx18_stream *s = q->priv_data;
191 struct cx18 *cx = s->cx;
192
193 *size = 2 * cx->cxhdl.width * cx->cxhdl.height;
194 if (*count == 0)
195 *count = VB_MIN_BUFFERS;
196
197 while (*size * *count > VB_MIN_BUFFERS * VB_MIN_BUFSIZE)
198 (*count)--;
199
200 q->field = V4L2_FIELD_INTERLACED;
201 q->last = V4L2_FIELD_INTERLACED;
202
203 return 0;
204}
205
206static int buffer_prepare(struct videobuf_queue *q,
207 struct videobuf_buffer *vb,
208 enum v4l2_field field)
209{
210 struct cx18_videobuf_buffer *buf =
211 container_of(vb, struct cx18_videobuf_buffer, vb);
212 struct cx18_stream *s = q->priv_data;
213 struct cx18 *cx = s->cx;
214
215 return cx18_prepare_buffer(q, s, buf, s->pixelformat,
216 cx->cxhdl.width, cx->cxhdl.height, field);
217}
218
219static void buffer_release(struct videobuf_queue *q,
220 struct videobuf_buffer *vb)
221{
222 struct cx18_videobuf_buffer *buf =
223 container_of(vb, struct cx18_videobuf_buffer, vb);
224 struct cx18_stream *s = q->priv_data;
225
226 cx18_dma_free(q, s, buf);
227}
228
229static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
230{
231 struct cx18_videobuf_buffer *buf =
232 container_of(vb, struct cx18_videobuf_buffer, vb);
233 struct cx18_stream *s = q->priv_data;
234
235 buf->vb.state = VIDEOBUF_QUEUED;
236
237 list_add_tail(&buf->vb.queue, &s->vb_capture);
238}
239
240static struct videobuf_queue_ops cx18_videobuf_qops = {
241 .buf_setup = buffer_setup,
242 .buf_prepare = buffer_prepare,
243 .buf_queue = buffer_queue,
244 .buf_release = buffer_release,
245};
246
247static void cx18_stream_init(struct cx18 *cx, int type)
248{
249 struct cx18_stream *s = &cx->streams[type];
250 struct video_device *video_dev = s->video_dev;
251
252 /* we need to keep video_dev, so restore it afterwards */
253 memset(s, 0, sizeof(*s));
254 s->video_dev = video_dev;
255
256 /* initialize cx18_stream fields */
257 s->dvb = NULL;
258 s->cx = cx;
259 s->type = type;
260 s->name = cx18_stream_info[type].name;
261 s->handle = CX18_INVALID_TASK_HANDLE;
262
263 s->dma = cx18_stream_info[type].dma;
264 s->buffers = cx->stream_buffers[type];
265 s->buf_size = cx->stream_buf_size[type];
266 INIT_LIST_HEAD(&s->buf_pool);
267 s->bufs_per_mdl = 1;
268 s->mdl_size = s->buf_size * s->bufs_per_mdl;
269
270 init_waitqueue_head(&s->waitq);
271 s->id = -1;
272 spin_lock_init(&s->q_free.lock);
273 cx18_queue_init(&s->q_free);
274 spin_lock_init(&s->q_busy.lock);
275 cx18_queue_init(&s->q_busy);
276 spin_lock_init(&s->q_full.lock);
277 cx18_queue_init(&s->q_full);
278 spin_lock_init(&s->q_idle.lock);
279 cx18_queue_init(&s->q_idle);
280
281 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
282
283 INIT_LIST_HEAD(&s->vb_capture);
284 s->vb_timeout.function = cx18_vb_timeout;
285 s->vb_timeout.data = (unsigned long)s;
286 init_timer(&s->vb_timeout);
287 spin_lock_init(&s->vb_lock);
288 if (type == CX18_ENC_STREAM_TYPE_YUV) {
289 spin_lock_init(&s->vbuf_q_lock);
290
291 s->vb_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
292 videobuf_queue_vmalloc_init(&s->vbuf_q, &cx18_videobuf_qops,
293 &cx->pci_dev->dev, &s->vbuf_q_lock,
294 V4L2_BUF_TYPE_VIDEO_CAPTURE,
295 V4L2_FIELD_INTERLACED,
296 sizeof(struct cx18_videobuf_buffer),
297 s, &cx->serialize_lock);
298
299 /* Assume the previous pixel default */
300 s->pixelformat = V4L2_PIX_FMT_HM12;
301 s->vb_bytes_per_frame = cx->cxhdl.height * 720 * 3 / 2;
302 }
303}
304
305static int cx18_prep_dev(struct cx18 *cx, int type)
306{
307 struct cx18_stream *s = &cx->streams[type];
308 u32 cap = cx->v4l2_cap;
309 int num_offset = cx18_stream_info[type].num_offset;
310 int num = cx->instance + cx18_first_minor + num_offset;
311
312 /*
313 * These five fields are always initialized.
314 * For analog capture related streams, if video_dev == NULL then the
315 * stream is not in use.
316 * For the TS stream, if dvb == NULL then the stream is not in use.
317 * In those cases no other fields but these four can be used.
318 */
319 s->video_dev = NULL;
320 s->dvb = NULL;
321 s->cx = cx;
322 s->type = type;
323 s->name = cx18_stream_info[type].name;
324
325 /* Check whether the radio is supported */
326 if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
327 return 0;
328
329 /* Check whether VBI is supported */
330 if (type == CX18_ENC_STREAM_TYPE_VBI &&
331 !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
332 return 0;
333
334 /* User explicitly selected 0 buffers for these streams, so don't
335 create them. */
336 if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
337 cx->stream_buffers[type] == 0) {
338 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
339 return 0;
340 }
341
342 cx18_stream_init(cx, type);
343
344 /* Allocate the cx18_dvb struct only for the TS on cards with DTV */
345 if (type == CX18_ENC_STREAM_TYPE_TS) {
346 if (cx->card->hw_all & CX18_HW_DVB) {
347 s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL);
348 if (s->dvb == NULL) {
349 CX18_ERR("Couldn't allocate cx18_dvb structure"
350 " for %s\n", s->name);
351 return -ENOMEM;
352 }
353 } else {
354 /* Don't need buffers for the TS, if there is no DVB */
355 s->buffers = 0;
356 }
357 }
358
359 if (num_offset == -1)
360 return 0;
361
362 /* allocate and initialize the v4l2 video device structure */
363 s->video_dev = video_device_alloc();
364 if (s->video_dev == NULL) {
365 CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
366 s->name);
367 return -ENOMEM;
368 }
369
370 snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
371 cx->v4l2_dev.name, s->name);
372
373 s->video_dev->num = num;
374 s->video_dev->v4l2_dev = &cx->v4l2_dev;
375 s->video_dev->fops = &cx18_v4l2_enc_fops;
376 s->video_dev->release = video_device_release;
377 s->video_dev->tvnorms = V4L2_STD_ALL;
378 s->video_dev->lock = &cx->serialize_lock;
379 set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
380 cx18_set_funcs(s->video_dev);
381 return 0;
382}
383
384/* Initialize v4l2 variables and register v4l2 devices */
385int cx18_streams_setup(struct cx18 *cx)
386{
387 int type, ret;
388
389 /* Setup V4L2 Devices */
390 for (type = 0; type < CX18_MAX_STREAMS; type++) {
391 /* Prepare device */
392 ret = cx18_prep_dev(cx, type);
393 if (ret < 0)
394 break;
395
396 /* Allocate Stream */
397 ret = cx18_stream_alloc(&cx->streams[type]);
398 if (ret < 0)
399 break;
400 }
401 if (type == CX18_MAX_STREAMS)
402 return 0;
403
404 /* One or more streams could not be initialized. Clean 'em all up. */
405 cx18_streams_cleanup(cx, 0);
406 return ret;
407}
408
409static int cx18_reg_dev(struct cx18 *cx, int type)
410{
411 struct cx18_stream *s = &cx->streams[type];
412 int vfl_type = cx18_stream_info[type].vfl_type;
413 const char *name;
414 int num, ret;
415
416 if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) {
417 ret = cx18_dvb_register(s);
418 if (ret < 0) {
419 CX18_ERR("DVB failed to register\n");
420 return ret;
421 }
422 }
423
424 if (s->video_dev == NULL)
425 return 0;
426
427 num = s->video_dev->num;
428 /* card number + user defined offset + device offset */
429 if (type != CX18_ENC_STREAM_TYPE_MPG) {
430 struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
431
432 if (s_mpg->video_dev)
433 num = s_mpg->video_dev->num
434 + cx18_stream_info[type].num_offset;
435 }
436 video_set_drvdata(s->video_dev, s);
437
438 /* Register device. First try the desired minor, then any free one. */
439 ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
440 if (ret < 0) {
441 CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
442 s->name, num);
443 video_device_release(s->video_dev);
444 s->video_dev = NULL;
445 return ret;
446 }
447
448 name = video_device_node_name(s->video_dev);
449
450 switch (vfl_type) {
451 case VFL_TYPE_GRABBER:
452 CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",
453 name, s->name, cx->stream_buffers[type],
454 cx->stream_buf_size[type] / 1024,
455 (cx->stream_buf_size[type] * 100 / 1024) % 100);
456 break;
457
458 case VFL_TYPE_RADIO:
459 CX18_INFO("Registered device %s for %s\n", name, s->name);
460 break;
461
462 case VFL_TYPE_VBI:
463 if (cx->stream_buffers[type])
464 CX18_INFO("Registered device %s for %s "
465 "(%d x %d bytes)\n",
466 name, s->name, cx->stream_buffers[type],
467 cx->stream_buf_size[type]);
468 else
469 CX18_INFO("Registered device %s for %s\n",
470 name, s->name);
471 break;
472 }
473
474 return 0;
475}
476
477/* Register v4l2 devices */
478int cx18_streams_register(struct cx18 *cx)
479{
480 int type;
481 int err;
482 int ret = 0;
483
484 /* Register V4L2 devices */
485 for (type = 0; type < CX18_MAX_STREAMS; type++) {
486 err = cx18_reg_dev(cx, type);
487 if (err && ret == 0)
488 ret = err;
489 }
490
491 if (ret == 0)
492 return 0;
493
494 /* One or more streams could not be initialized. Clean 'em all up. */
495 cx18_streams_cleanup(cx, 1);
496 return ret;
497}
498
499/* Unregister v4l2 devices */
500void cx18_streams_cleanup(struct cx18 *cx, int unregister)
501{
502 struct video_device *vdev;
503 int type;
504
505 /* Teardown all streams */
506 for (type = 0; type < CX18_MAX_STREAMS; type++) {
507
508 /* The TS has a cx18_dvb structure, not a video_device */
509 if (type == CX18_ENC_STREAM_TYPE_TS) {
510 if (cx->streams[type].dvb != NULL) {
511 if (unregister)
512 cx18_dvb_unregister(&cx->streams[type]);
513 kfree(cx->streams[type].dvb);
514 cx->streams[type].dvb = NULL;
515 cx18_stream_free(&cx->streams[type]);
516 }
517 continue;
518 }
519
520 /* No struct video_device, but can have buffers allocated */
521 if (type == CX18_ENC_STREAM_TYPE_IDX) {
522 /* If the module params didn't inhibit IDX ... */
523 if (cx->stream_buffers[type] != 0) {
524 cx->stream_buffers[type] = 0;
525 /*
526 * Before calling cx18_stream_free(),
527 * check if the IDX stream was actually set up.
528 * Needed, since the cx18_probe() error path
529 * exits through here as well as normal clean up
530 */
531 if (cx->streams[type].buffers != 0)
532 cx18_stream_free(&cx->streams[type]);
533 }
534 continue;
535 }
536
537 /* If struct video_device exists, can have buffers allocated */
538 vdev = cx->streams[type].video_dev;
539
540 cx->streams[type].video_dev = NULL;
541 if (vdev == NULL)
542 continue;
543
544 if (type == CX18_ENC_STREAM_TYPE_YUV)
545 videobuf_mmap_free(&cx->streams[type].vbuf_q);
546
547 cx18_stream_free(&cx->streams[type]);
548
549 /* Unregister or release device */
550 if (unregister)
551 video_unregister_device(vdev);
552 else
553 video_device_release(vdev);
554 }
555}
556
557static void cx18_vbi_setup(struct cx18_stream *s)
558{
559 struct cx18 *cx = s->cx;
560 int raw = cx18_raw_vbi(cx);
561 u32 data[CX2341X_MBOX_MAX_DATA];
562 int lines;
563
564 if (cx->is_60hz) {
565 cx->vbi.count = 12;
566 cx->vbi.start[0] = 10;
567 cx->vbi.start[1] = 273;
568 } else { /* PAL/SECAM */
569 cx->vbi.count = 18;
570 cx->vbi.start[0] = 6;
571 cx->vbi.start[1] = 318;
572 }
573
574 /* setup VBI registers */
575 if (raw)
576 v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &cx->vbi.in.fmt.vbi);
577 else
578 v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &cx->vbi.in.fmt.sliced);
579
580 /*
581 * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
582 * VBI when the first analog capture channel starts, as once it starts
583 * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
584 * (i.e. for the VBI capture channels). We also send it for each
585 * analog capture channel anyway just to make sure we get the proper
586 * behavior
587 */
588 if (raw) {
589 lines = cx->vbi.count * 2;
590 } else {
591 /*
592 * For 525/60 systems, according to the VIP 2 & BT.656 std:
593 * The EAV RP code's Field bit toggles on line 4, a few lines
594 * after the Vertcal Blank bit has already toggled.
595 * Tell the encoder to capture 21-4+1=18 lines per field,
596 * since we want lines 10 through 21.
597 *
598 * For 625/50 systems, according to the VIP 2 & BT.656 std:
599 * The EAV RP code's Field bit toggles on line 1, a few lines
600 * after the Vertcal Blank bit has already toggled.
601 * (We've actually set the digitizer so that the Field bit
602 * toggles on line 2.) Tell the encoder to capture 23-2+1=22
603 * lines per field, since we want lines 6 through 23.
604 */
605 lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2;
606 }
607
608 data[0] = s->handle;
609 /* Lines per field */
610 data[1] = (lines / 2) | ((lines / 2) << 16);
611 /* bytes per line */
612 data[2] = (raw ? vbi_active_samples
613 : (cx->is_60hz ? vbi_hblank_samples_60Hz
614 : vbi_hblank_samples_50Hz));
615 /* Every X number of frames a VBI interrupt arrives
616 (frames as in 25 or 30 fps) */
617 data[3] = 1;
618 /*
619 * Set the SAV/EAV RP codes to look for as start/stop points
620 * when in VIP-1.1 mode
621 */
622 if (raw) {
623 /*
624 * Start codes for beginning of "active" line in vertical blank
625 * 0x20 ( VerticalBlank )
626 * 0x60 ( EvenField VerticalBlank )
627 */
628 data[4] = 0x20602060;
629 /*
630 * End codes for end of "active" raw lines and regular lines
631 * 0x30 ( VerticalBlank HorizontalBlank)
632 * 0x70 ( EvenField VerticalBlank HorizontalBlank)
633 * 0x90 (Task HorizontalBlank)
634 * 0xd0 (Task EvenField HorizontalBlank)
635 */
636 data[5] = 0x307090d0;
637 } else {
638 /*
639 * End codes for active video, we want data in the hblank region
640 * 0xb0 (Task 0 VerticalBlank HorizontalBlank)
641 * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
642 *
643 * Since the V bit is only allowed to toggle in the EAV RP code,
644 * just before the first active region line, these two
645 * are problematic:
646 * 0x90 (Task HorizontalBlank)
647 * 0xd0 (Task EvenField HorizontalBlank)
648 *
649 * We have set the digitzer such that we don't have to worry
650 * about these problem codes.
651 */
652 data[4] = 0xB0F0B0F0;
653 /*
654 * Start codes for beginning of active line in vertical blank
655 * 0xa0 (Task VerticalBlank )
656 * 0xe0 (Task EvenField VerticalBlank )
657 */
658 data[5] = 0xA0E0A0E0;
659 }
660
661 CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
662 data[0], data[1], data[2], data[3], data[4], data[5]);
663
664 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
665}
666
667void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
668{
669 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
670 struct cx18_mdl *mdl;
671
672 if (!cx18_stream_enabled(s))
673 return;
674
675 /* Return if the firmware is not running low on MDLs */
676 if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
677 CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
678 return;
679
680 /* Return if there are no MDLs to rotate back to the firmware */
681 if (atomic_read(&s->q_full.depth) < 2)
682 return;
683
684 /*
685 * Take the oldest IDX MDL still holding data, and discard its index
686 * entries by scheduling the MDL to go back to the firmware
687 */
688 mdl = cx18_dequeue(s, &s->q_full);
689 if (mdl != NULL)
690 cx18_enqueue(s, mdl, &s->q_free);
691}
692
693static
694struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
695 struct cx18_mdl *mdl)
696{
697 struct cx18 *cx = s->cx;
698 struct cx18_queue *q;
699
700 /* Don't give it to the firmware, if we're not running a capture */
701 if (s->handle == CX18_INVALID_TASK_HANDLE ||
702 test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
703 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
704 return cx18_enqueue(s, mdl, &s->q_free);
705
706 q = cx18_enqueue(s, mdl, &s->q_busy);
707 if (q != &s->q_busy)
708 return q; /* The firmware has the max MDLs it can handle */
709
710 cx18_mdl_sync_for_device(s, mdl);
711 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
712 (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
713 s->bufs_per_mdl, mdl->id, s->mdl_size);
714 return q;
715}
716
717static
718void _cx18_stream_load_fw_queue(struct cx18_stream *s)
719{
720 struct cx18_queue *q;
721 struct cx18_mdl *mdl;
722
723 if (atomic_read(&s->q_free.depth) == 0 ||
724 atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
725 return;
726
727 /* Move from q_free to q_busy notifying the firmware, until the limit */
728 do {
729 mdl = cx18_dequeue(s, &s->q_free);
730 if (mdl == NULL)
731 break;
732 q = _cx18_stream_put_mdl_fw(s, mdl);
733 } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
734 && q == &s->q_busy);
735}
736
737void cx18_out_work_handler(struct work_struct *work)
738{
739 struct cx18_stream *s =
740 container_of(work, struct cx18_stream, out_work_order);
741
742 _cx18_stream_load_fw_queue(s);
743}
744
745static void cx18_stream_configure_mdls(struct cx18_stream *s)
746{
747 cx18_unload_queues(s);
748
749 switch (s->type) {
750 case CX18_ENC_STREAM_TYPE_YUV:
751 /*
752 * Height should be a multiple of 32 lines.
753 * Set the MDL size to the exact size needed for one frame.
754 * Use enough buffers per MDL to cover the MDL size
755 */
756 if (s->pixelformat == V4L2_PIX_FMT_HM12)
757 s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
758 else
759 s->mdl_size = 720 * s->cx->cxhdl.height * 2;
760 s->bufs_per_mdl = s->mdl_size / s->buf_size;
761 if (s->mdl_size % s->buf_size)
762 s->bufs_per_mdl++;
763 break;
764 case CX18_ENC_STREAM_TYPE_VBI:
765 s->bufs_per_mdl = 1;
766 if (cx18_raw_vbi(s->cx)) {
767 s->mdl_size = (s->cx->is_60hz ? 12 : 18)
768 * 2 * vbi_active_samples;
769 } else {
770 /*
771 * See comment in cx18_vbi_setup() below about the
772 * extra lines we capture in sliced VBI mode due to
773 * the lines on which EAV RP codes toggle.
774 */
775 s->mdl_size = s->cx->is_60hz
776 ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz
777 : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz;
778 }
779 break;
780 default:
781 s->bufs_per_mdl = 1;
782 s->mdl_size = s->buf_size * s->bufs_per_mdl;
783 break;
784 }
785
786 cx18_load_queues(s);
787}
788
789int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
790{
791 u32 data[MAX_MB_ARGUMENTS];
792 struct cx18 *cx = s->cx;
793 int captype = 0;
794 struct cx18_stream *s_idx;
795
796 if (!cx18_stream_enabled(s))
797 return -EINVAL;
798
799 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
800
801 switch (s->type) {
802 case CX18_ENC_STREAM_TYPE_MPG:
803 captype = CAPTURE_CHANNEL_TYPE_MPEG;
804 cx->mpg_data_received = cx->vbi_data_inserted = 0;
805 cx->dualwatch_jiffies = jiffies;
806 cx->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
807 cx->search_pack_header = 0;
808 break;
809
810 case CX18_ENC_STREAM_TYPE_IDX:
811 captype = CAPTURE_CHANNEL_TYPE_INDEX;
812 break;
813 case CX18_ENC_STREAM_TYPE_TS:
814 captype = CAPTURE_CHANNEL_TYPE_TS;
815 break;
816 case CX18_ENC_STREAM_TYPE_YUV:
817 captype = CAPTURE_CHANNEL_TYPE_YUV;
818 break;
819 case CX18_ENC_STREAM_TYPE_PCM:
820 captype = CAPTURE_CHANNEL_TYPE_PCM;
821 break;
822 case CX18_ENC_STREAM_TYPE_VBI:
823#ifdef CX18_ENCODER_PARSES_SLICED
824 captype = cx18_raw_vbi(cx) ?
825 CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
826#else
827 /*
828 * Currently we set things up so that Sliced VBI from the
829 * digitizer is handled as Raw VBI by the encoder
830 */
831 captype = CAPTURE_CHANNEL_TYPE_VBI;
832#endif
833 cx->vbi.frame = 0;
834 cx->vbi.inserted_frame = 0;
835 memset(cx->vbi.sliced_mpeg_size,
836 0, sizeof(cx->vbi.sliced_mpeg_size));
837 break;
838 default:
839 return -EINVAL;
840 }
841
842 /* Clear Streamoff flags in case left from last capture */
843 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
844
845 cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE);
846 s->handle = data[0];
847 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
848
849 /*
850 * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
851 * set up all the parameters, as it is not obvious which parameters the
852 * firmware shares across capture channel types and which it does not.
853 *
854 * Some of the cx18_vapi() calls below apply to only certain capture
855 * channel types. We're hoping there's no harm in calling most of them
856 * anyway, as long as the values are all consistent. Setting some
857 * shared parameters will have no effect once an analog capture channel
858 * has started streaming.
859 */
860 if (captype != CAPTURE_CHANNEL_TYPE_TS) {
861 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
862 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
863 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
864 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
865
866 /*
867 * Audio related reset according to
868 * Documentation/video4linux/cx2341x/fw-encoder-api.txt
869 */
870 if (atomic_read(&cx->ana_capturing) == 0)
871 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
872 s->handle, 12);
873
874 /*
875 * Number of lines for Field 1 & Field 2 according to
876 * Documentation/video4linux/cx2341x/fw-encoder-api.txt
877 * Field 1 is 312 for 625 line systems in BT.656
878 * Field 2 is 313 for 625 line systems in BT.656
879 */
880 cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
881 s->handle, 312, 313);
882
883 if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
884 cx18_vbi_setup(s);
885
886 /*
887 * Select to receive I, P, and B frame index entries, if the
888 * index stream is enabled. Otherwise disable index entry
889 * generation.
890 */
891 s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
892 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2,
893 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
894
895 /* Call out to the common CX2341x API setup for user controls */
896 cx->cxhdl.priv = s;
897 cx2341x_handler_setup(&cx->cxhdl);
898
899 /*
900 * When starting a capture and we're set for radio,
901 * ensure the video is muted, despite the user control.
902 */
903 if (!cx->cxhdl.video_mute &&
904 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
905 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
906 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
907
908 /* Enable the Video Format Converter for UYVY 4:2:2 support,
909 * rather than the default HM12 Macroblovk 4:2:0 support.
910 */
911 if (captype == CAPTURE_CHANNEL_TYPE_YUV) {
912 if (s->pixelformat == V4L2_PIX_FMT_UYVY)
913 cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
914 s->handle, 1);
915 else
916 /* If in doubt, default to HM12 */
917 cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
918 s->handle, 0);
919 }
920 }
921
922 if (atomic_read(&cx->tot_capturing) == 0) {
923 cx2341x_handler_set_busy(&cx->cxhdl, 1);
924 clear_bit(CX18_F_I_EOS, &cx->i_flags);
925 cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
926 }
927
928 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
929 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
930 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
931
932 /* Init all the cpu_mdls for this stream */
933 cx18_stream_configure_mdls(s);
934 _cx18_stream_load_fw_queue(s);
935
936 /* begin_capture */
937 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
938 CX18_DEBUG_WARN("Error starting capture!\n");
939 /* Ensure we're really not capturing before releasing MDLs */
940 set_bit(CX18_F_S_STOPPING, &s->s_flags);
941 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
942 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
943 else
944 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
945 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
946 /* FIXME - CX18_F_S_STREAMOFF as well? */
947 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
948 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
949 s->handle = CX18_INVALID_TASK_HANDLE;
950 clear_bit(CX18_F_S_STOPPING, &s->s_flags);
951 if (atomic_read(&cx->tot_capturing) == 0) {
952 set_bit(CX18_F_I_EOS, &cx->i_flags);
953 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
954 }
955 return -EINVAL;
956 }
957
958 /* you're live! sit back and await interrupts :) */
959 if (captype != CAPTURE_CHANNEL_TYPE_TS)
960 atomic_inc(&cx->ana_capturing);
961 atomic_inc(&cx->tot_capturing);
962 return 0;
963}
964EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);
965
966void cx18_stop_all_captures(struct cx18 *cx)
967{
968 int i;
969
970 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
971 struct cx18_stream *s = &cx->streams[i];
972
973 if (!cx18_stream_enabled(s))
974 continue;
975 if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
976 cx18_stop_v4l2_encode_stream(s, 0);
977 }
978}
979
980int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
981{
982 struct cx18 *cx = s->cx;
983
984 if (!cx18_stream_enabled(s))
985 return -EINVAL;
986
987 /* This function assumes that you are allowed to stop the capture
988 and that we are actually capturing */
989
990 CX18_DEBUG_INFO("Stop Capture\n");
991
992 if (atomic_read(&cx->tot_capturing) == 0)
993 return 0;
994
995 set_bit(CX18_F_S_STOPPING, &s->s_flags);
996 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
997 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
998 else
999 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
1000
1001 if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
1002 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
1003 }
1004
1005 if (s->type != CX18_ENC_STREAM_TYPE_TS)
1006 atomic_dec(&cx->ana_capturing);
1007 atomic_dec(&cx->tot_capturing);
1008
1009 /* Clear capture and no-read bits */
1010 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
1011
1012 /* Tell the CX23418 it can't use our buffers anymore */
1013 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
1014
1015 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
1016 s->handle = CX18_INVALID_TASK_HANDLE;
1017 clear_bit(CX18_F_S_STOPPING, &s->s_flags);
1018
1019 if (atomic_read(&cx->tot_capturing) > 0)
1020 return 0;
1021
1022 cx2341x_handler_set_busy(&cx->cxhdl, 0);
1023 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
1024 wake_up(&s->waitq);
1025
1026 return 0;
1027}
1028EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);
1029
1030u32 cx18_find_handle(struct cx18 *cx)
1031{
1032 int i;
1033
1034 /* find first available handle to be used for global settings */
1035 for (i = 0; i < CX18_MAX_STREAMS; i++) {
1036 struct cx18_stream *s = &cx->streams[i];
1037
1038 if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
1039 return s->handle;
1040 }
1041 return CX18_INVALID_TASK_HANDLE;
1042}
1043
1044struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
1045{
1046 int i;
1047 struct cx18_stream *s;
1048
1049 if (handle == CX18_INVALID_TASK_HANDLE)
1050 return NULL;
1051
1052 for (i = 0; i < CX18_MAX_STREAMS; i++) {
1053 s = &cx->streams[i];
1054 if (s->handle != handle)
1055 continue;
1056 if (cx18_stream_enabled(s))
1057 return s;
1058 }
1059 return NULL;
1060}
diff --git a/drivers/media/pci/cx18/cx18-streams.h b/drivers/media/pci/cx18/cx18-streams.h
new file mode 100644
index 000000000000..713b0e61536d
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-vbi.c b/drivers/media/pci/cx18/cx18-vbi.c
new file mode 100644
index 000000000000..6d3121ff45a2
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-vbi.h b/drivers/media/pci/cx18/cx18-vbi.h
new file mode 100644
index 000000000000..b365cf4b4668
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-version.h b/drivers/media/pci/cx18/cx18-version.h
new file mode 100644
index 000000000000..fed48b6bb67b
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-video.c b/drivers/media/pci/cx18/cx18-video.c
new file mode 100644
index 000000000000..6dc84aac8f44
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx18-video.h b/drivers/media/pci/cx18/cx18-video.h
new file mode 100644
index 000000000000..529006a06e5c
--- /dev/null
+++ b/drivers/media/pci/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/pci/cx18/cx23418.h b/drivers/media/pci/cx18/cx23418.h
new file mode 100644
index 000000000000..767a8d23e3f2
--- /dev/null
+++ b/drivers/media/pci/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 */