aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-05-25 20:40:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:10:42 -0500
commit9722c8f95a5bd51a3d392cb2f125c8240b745c48 (patch)
treeb7346813bbfccb672be30a6025d558318c6fd472 /drivers/media/video/cx18
parent5eb3291fe84b30a8e2fda31fd5fa44c40575f283 (diff)
V4L/DVB: cx18-alsa: Initial non-working cx18-alsa files
Initial cx18-alsa module files check-in to avoid losing work. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.c191
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.h23
-rw-r--r--drivers/media/video/cx18/cx18-alsa.c303
-rw-r--r--drivers/media/video/cx18/cx18-alsa.h55
-rw-r--r--drivers/media/video/cx18/cx18-driver.h1
5 files changed, 573 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/video/cx18/cx18-alsa-mixer.c
new file mode 100644
index 000000000000..b80391a8a9fc
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.c
@@ -0,0 +1,191 @@
1/*
2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.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 * Mixer manipulations are like v4l2 ioctl() calls to manipulate controls,
40 * just use the same lock we use for ioctl()s for now
41 */
42static inline void snd_cx18_mixer_lock(struct snd_cx18_card *cxsc)
43{
44 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
45 mutex_lock(&cx->serialize_lock);
46}
47
48static inline void snd_cx18_mixer_unlock(struct snd_cx18_card *cxsc)
49{
50 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
51 mutex_unlock(&cx->serialize_lock);
52}
53
54/*
55 * Note the cx18-av-core volume scale is funny, due to the alignment of the
56 * scale with another chip's range:
57 *
58 * v4l2_control value /512 indicated dB actual dB reg 0x8d4
59 * 0x0000 - 0x01ff 0 -119 -96 228
60 * 0x0200 - 0x02ff 1 -118 -96 228
61 * ...
62 * 0x2c00 - 0x2dff 22 -97 -96 228
63 * 0x2e00 - 0x2fff 23 -96 -96 228
64 * 0x3000 - 0x31ff 24 -95 -95 226
65 * ...
66 * 0xee00 - 0xefff 119 0 0 36
67 * ...
68 * 0xfe00 - 0xffff 127 +8 +8 20
69 */
70static inline int dB_to_cx18_av_vol(int dB)
71{
72 if (dB < -96)
73 dB = -96;
74 else if (dB > 8)
75 dB = 8;
76 return (dB + 119) << 9;
77}
78
79static inline int cx18_av_vol_to_dB(int v)
80{
81 if (v < (23 << 9))
82 v = (23 << 9);
83 else if (v > (127 << 9))
84 v = (127 << 9);
85 return (v >> 9) - 119;
86}
87
88static int snd_cx18_mixer_tv_vol_info(struct snd_kcontrol *kcontrol,
89 struct snd_ctl_elem_info *uinfo)
90{
91 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
92 uinfo->count = 1;
93 /* We're already translating values, just keep this control in dB */
94 uinfo->value.integer.min = -96;
95 uinfo->value.integer.max = +8;
96 uinfo->value.integer.step = 1;
97 return 0;
98}
99
100static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl,
101 struct snd_ctl_elem_value *uctl)
102{
103 struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
104 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
105 struct v4l2_control vctrl;
106 int ret;
107
108 vctrl.id = V4L2_CID_AUDIO_VOLUME;
109 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
110
111 snd_cx18_mixer_lock(cxsc);
112 ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
113 snd_cx18_mixer_unlock(cxsc);
114
115 if (!ret)
116 uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value);
117 return ret;
118}
119
120static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl,
121 struct snd_ctl_elem_value *uctl)
122{
123 struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
124 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
125 struct v4l2_control vctrl;
126 int ret;
127
128 vctrl.id = V4L2_CID_AUDIO_VOLUME;
129 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
130
131 snd_cx18_mixer_lock(cxsc);
132
133 /* Fetch current state */
134 ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
135
136 if (ret ||
137 (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) {
138
139 /* Set, if needed */
140 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
141 ret = v4l2_subdev_call(cx->sd_av, core, s_ctrl, &vctrl);
142 if (!ret)
143 ret = 1; /* Indicate control was changed w/o error */
144 }
145 snd_cx18_mixer_unlock(cxsc);
146
147 return ret;
148}
149
150
151/* This is a bit of overkill, the slider is already in dB internally */
152static DECLARE_TLV_DB_SCALE(snd_cx18_mixer_tv_vol_db_scale, -9600, 100, 0);
153
154static struct snd_kcontrol_new snd_cx18_mixer_tv_vol __initdata = {
155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
156 .name = "Analog TV Capture Volume",
157 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
158 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
159 .info = snd_cx18_mixer_tv_volume_info,
160 .get = snd_cx18_mixer_tv_volume_get,
161 .put = snd_cx18_mixer_tv_volume_put,
162 .tlv.p = snd_cx18_mixer_tv_vol_db_scale
163};
164
165/* FIXME - add mute switch and balance, bass, treble sliders:
166 V4L2_CID_AUDIO_MUTE
167
168 V4L2_CID_AUDIO_BALANCE
169
170 V4L2_CID_AUDIO_BASS
171 V4L2_CID_AUDIO_TREBLE
172*/
173
174/* FIXME - add stereo, lang1, lang2, mono menu */
175/* FIXME - add CS5345 I2S volume for HVR-1600 */
176
177int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc)
178{
179 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
180 struct snd_card *sc = cxsc->sc;
181 int ret;
182
183 strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername));
184
185 ret = snd_ctl_add(sc, snd_ctl_new1(snd_cx18_mixer_tv_vol, cxsc));
186 if (ret) {
187 CX18_ALSA_WARN("%s: failed to add %s control, err %d\n",
188 __func__, snd_cx18_mixer_tv_vol.name, ret);
189 }
190 return ret;
191}
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/video/cx18/cx18-alsa-mixer.h
new file mode 100644
index 000000000000..2d418db000fe
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.h
@@ -0,0 +1,23 @@
1/*
2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc);
diff --git a/drivers/media/video/cx18/cx18-alsa.c b/drivers/media/video/cx18/cx18-alsa.c
new file mode 100644
index 000000000000..dde2b0482f34
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa.c
@@ -0,0 +1,303 @@
1/*
2 * ALSA interface to cx18 PCM capture streams
3 *
4 * Copyright (C) 2009 Andy Walls <awalls@radix.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
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/device.h>
26#include <linux/spinlock.h>
27
28#include <media/v4l2-device.h>
29
30#include <sound/core.h>
31#include <sound/initval.h>
32
33#include "cx18-driver.h"
34#include "cx18-alsa-mixer.h"
35#include "cx18-alsa-pcm.h"
36
37int cx18_alsa_debug;
38
39module_param_named(debug, cx18_alsa_debug, int, 0644);
40MODULE_PARM_DESC(debug,
41 "Debug level (bitmask). Default: 0\n"
42 "\t\t\t 1/0x0001: warning\n"
43 "\t\t\t 2/0x0002: info\n");
44
45MODULE_AUTHOR("Andy Walls");
46MODULE_DESCRIPTION("CX23418 ALSA Interface");
47MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
48MODULE_LICENSE("GPL");
49
50MODULE_VERSION(CX18_VERSION);
51
52static inline
53struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
54{
55 return to_cx18(v4l2_dev)->alsa;
56}
57
58static inline
59struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
60{
61 return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
62}
63
64static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
65{
66 if (cxsc == NULL)
67 return;
68
69 if (cxsc->v4l2_dev != NULL)
70 to_cx18(cxsc->v4l2_dev)->alsa = NULL;
71
72 /* FIXME - take any other stopping actions needed */
73
74 kfree(cxsc);
75}
76
77static void snd_cx18_card_private_free(struct snd_card *sc)
78{
79 if (sc == NULL)
80 return;
81 snd_cx18_card_free(sc->private_data);
82 sc->private_data = NULL;
83 sc->private_free = NULL;
84}
85
86static int __init snd_cx18_card_create(struct v4l2_device *v4l2_dev,
87 struct snd_card *sc,
88 struct snd_cx18_card **cxsc)
89{
90 *cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL);
91 if (*cxsc == NULL)
92 return -ENOMEM;
93
94 (*cxsc)->v4l2_dev = v4l2_dev;
95 (*cxsc)->sc = sc;
96
97 sc->private_data = *cxsc;
98 sc->private_free = snd_cx18_card_private_free;
99
100 return 0;
101}
102
103static int __init snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
104{
105 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
106 struct snd_card *sc = cxsc->sc;
107
108 /* sc->driver is used by alsa-lib's configurator: simple, unique */
109 strlcpy(sc->driver, "CX23418", sizeof(sc->driver));
110
111 /* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
112 snprintf(sc->shortname, sizeof(sc->shortname), "CX18-%d",
113 cx->instance);
114
115 /* sc->longname is read from /proc/asound/cards */
116 snprintf(sc->longname, sizeof(sc->longname),
117 "CX23418 #%d %s TV/FM Radio/Line-In Capture",
118 cx->instance, cx->card_name);
119}
120
121static int __init snd_cx18_init(struct v4l2_device *v4l2_dev)
122{
123 struct cx18 *cx = to_cx18(v4l2_dev);
124 struct snd_card *sc;
125 struct snd_cx18_card *cxsc;
126 int ret;
127
128 /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
129
130 /* (1) Check and increment the device index */
131 /* This is a no-op for us. We'll use the cx->instance */
132
133 /* (2) Create a card instance */
134 ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
135 SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
136 THIS_MODULE, 0, &sc);
137 if (ret) {
138 CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
139 __func__, ret);
140 goto err_exit;
141 }
142
143 /* (3) Create a main component */
144 ret = snd_cx18_card_create(v4l2_dev, sc, &cxsc);
145 if (ret) {
146 CX18_ALSA_ERR("%s: snd_cx18_card_create() failed with err %d\n",
147 __func__, ret);
148 goto err_exit_free;
149 }
150
151 /* (4) Set the driver ID and name strings */
152 snd_cx18_card_set_names(cxsc);
153
154 /* (5) Create other components: mixer, PCM, & proc files */
155 ret = snd_cx18_mixer_create(cxsc);
156 if (ret) {
157 CX18_ALSA_WARN("%s: snd_cx18_mixer_create() failed with err %d:"
158 "proceeding anyway\n", __func__, ret);
159 }
160
161 ret = snd_cx18_pcm_create(cxsc);
162 if (ret) {
163 CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
164 __func__, ret);
165 goto err_exit_free;
166 }
167 /* FIXME - proc files */
168
169 /* (7) Set the driver data and return 0 */
170 /* We do this out of normal order for PCI drivers to avoid races */
171 cx->alsa = cxsc;
172
173 /* (6) Register the card instance */
174 ret = snd_card_register(sc);
175 if (ret) {
176 cx->alsa = NULL;
177 CX18_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
178 __func__, ret);
179 goto err_exit_free;
180 }
181
182 return 0;
183
184err_exit_free:
185 snd_card_free(sc);
186err_exit:
187 return ret;
188}
189
190static int __init cx18_alsa_init_callback(struct device *dev, void *data)
191{
192 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
193 int *count = data;
194 struct cx18 *cx;
195 struct cx18_stream *s;
196
197 if (v4l2_dev == NULL) {
198 printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
199 __func__);
200 return 0;
201 }
202
203 cx = to_cx18(v4l2_dev);
204 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
205 if (s->video_dev == NULL) {
206 CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
207 "skipping\n", __func__);
208 return 0;
209 }
210
211 if (cx->alsa != NULL) {
212 CX18_ALSA_ERR("%s: struct snd_cx18_card * already exists\n",
213 __func__);
214 return 0;
215 }
216
217 if (snd_cx18_init(v4l2_dev)) {
218 CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n",
219 __func__);
220 } else {
221 CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance "
222 "%d\n", __func__, *count);
223 (*count)++;
224 }
225 return 0;
226}
227
228static int __init cx18_alsa_init(void)
229{
230 struct device_driver *drv;
231 int count = 0;
232 int ret;
233
234 printk(KERN_INFO "cx18-alsa: module loading...\n");
235
236 drv = driver_find("cx18", &pci_bus_type);
237 ret = driver_for_each_device(drv, NULL, &count,
238 cx18_alsa_init_callback);
239 put_driver(drv);
240
241 if (count == 0) {
242 printk(KERN_ERR "cx18-alsa: no cx18 cards found with a PCM "
243 "capture stream allocated\n");
244 ret = -ENODEV;
245 } else {
246 printk(KERN_INFO "cx18-alsa: ALSA interface(s) created for %d "
247 "cx18 card(s)\n", count);
248 ret = 0;
249 }
250
251 printk(KERN_INFO "cx18-alsa: module load complete\n");
252 return ret;
253}
254
255static void snd_cx18_exit(struct snd_cx18_card *cxsc)
256{
257 struct cx18 *cx = to_cx18(cxsc->4l2_dev);
258
259 /* FIXME - pointer checks & shutdown cxsc */
260
261 snd_card_free(cxsc->sc);
262 cx->alsa = NULL;
263}
264
265static int cx18_alsa_exit_callback(struct device *dev, void *data)
266{
267 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
268 struct snd_cx18_card *cxsc;
269 struct cx18 *cx;
270
271 if (v4l2_dev == NULL) {
272 printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
273 __func__);
274 return 0;
275 }
276
277 cxsc = to_snd_cx18_card(v4l2_dev);
278 if (cxsc == NULL) {
279 CX18_ALSA_WARN("%s: struct snd_cx18_card * is NULL\n",
280 __func__);
281 return 0;
282 }
283
284 snd_cx18_exit(cxsc);
285 return 0;
286}
287
288static void cx18_alsa_exit(void)
289{
290 struct device_driver *drv;
291 int ret;
292
293 printk(KERN_INFO "cx18-alsa: module unloading...\n");
294
295 drv = driver_find("cx18", &pci_bus_type);
296 ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
297 put_driver(drv);
298
299 printk(KERN_INFO "cx18-alsa: module unload complete\n");
300}
301
302module_init(cx18_alsa_init);
303module_exit(cx18_alsa_exit);
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h
new file mode 100644
index 000000000000..ea8576fd5786
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa.h
@@ -0,0 +1,55 @@
1/*
2 * ALSA interface to cx18 PCM capture streams
3 *
4 * Copyright (C) 2009 Andy Walls <awalls@radix.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};
28
29extern int cx18_alsa_debug;
30
31#define CX18_ALSA_DBGFLG_WARN (1 << 0)
32#define CX18_ALSA_DBGFLG_WARN (1 << 0)
33#define CX18_ALSA_DBGFLG_INFO (1 << 1)
34
35#define CX18_ALSA_DEBUG(x, type, fmt, args...) \
36 do { \
37 if ((x) & cx18_alsa_debug) \
38 printk(KERN_INFO "%s-alsa: " type ": " fmt, \
39 v4l2_dev->name , ## args); \
40 } while (0)
41
42#define CX18_ALSA_DEBUG_WARN(fmt, args...) \
43 CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_WARN, "warning", fmt , ## args)
44
45#define CX18_ALSA_DEBUG_INFO(fmt, args...) \
46 CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_INFO, "info", fmt , ## args)
47
48#define CX18_ALSA_ERR(fmt, args...) \
49 printk(KERN_ERR "%s-alsa: " fmt, v4l2_dev->name , ## args)
50
51#define CX18_ALSA_WARN(fmt, args...) \
52 printk(KERN_WARNING "%s-alsa: " fmt, v4l2_dev->name , ## args)
53
54#define CX18_ALSA_INFO(fmt, args...) \
55 printk(KERN_INFO "%s-alsa: " fmt, v4l2_dev->name , ## args)
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index fecebf3fb556..fcb99531dab3 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -574,6 +574,7 @@ struct cx18 {
574 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */ 574 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
575 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ 575 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
576 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ 576 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
577 struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
577 unsigned long i_flags; /* global cx18 flags */ 578 unsigned long i_flags; /* global cx18 flags */
578 atomic_t ana_capturing; /* count number of active analog capture streams */ 579 atomic_t ana_capturing; /* count number of active analog capture streams */
579 atomic_t tot_capturing; /* total count number of active capture streams */ 580 atomic_t tot_capturing; /* total count number of active capture streams */