aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRicardo Cerqueira <v4l@cerqueira.org>2005-11-09 00:37:11 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:15 -0500
commitbd15eba3a0f2b175bd80c21d5fc86c02ed4c56f6 (patch)
tree62890926bf734408e1e4e34f8a1a273974fb984e /drivers
parent2f8d4f5139fe7817f43202d8ee2f4b68ac53e58f (diff)
[PATCH] v4l: 720: alsa support for saa7134 that should work wonderful
- Alsa support for saa7134 that should work. Signed-off-by: Ricardo Cerqueira <v4l@cerqueira.org> Signed-off-by: Nickolay V. Shmyrev <nshmyrev@yandex.ru> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c1076
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c23
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c5
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h8
-rw-r--r--drivers/media/video/saa7134/saa7134.h10
5 files changed, 718 insertions, 404 deletions
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index d09e01f7fc3b..84eeeba21d74 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -1,543 +1,821 @@
1/* 1/*
2 * SAA713x ALSA support for V4L
3 * Ricardo Cerqueira <v4l@cerqueira.org>
2 * 4 *
3 * Support for audio capture
4 * PCI function #1 of the saa7134
5 * 5 *
6 * (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br> 6 * Caveats:
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> 7 * I still haven't got the mixer settings right.
8 * (c) 2003 Clemens Ladisch <clemens@ladisch.de>
9 * 8 *
10 * This program is free software; you can redistribute it and/or modify 9 * - Volume doesn't work (it's always at max)
11 * it under the terms of the GNU General Public License as published by 10 * - There's no "memory" of the capture channel. It can be changed,
12 * the Free Software Foundation; either version 2 of the License, or 11 * but alsamixer doesn't show it after a module restart (rmmod/insmod)
13 * (at your option) any later version.
14 * 12 *
15 * This program is distributed in the hope that it will be useful, 13 * Hotswapping DOES NOT work yet! Please remove the module before
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * inserting cardbus cards. pcmcia-cs or pccardd should load it
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * properly after insertion, and things will work
18 * GNU General Public License for more details. 16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, version 2
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * 29 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */ 30 */
24 31
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/device.h>
28#include <linux/interrupt.h>
29#include <asm/delay.h>
30#include <sound/driver.h> 32#include <sound/driver.h>
33#include <linux/init.h>
34#include <linux/slab.h>
35#include <linux/time.h>
36#include <linux/wait.h>
37#include <linux/moduleparam.h>
38#include <linux/module.h>
31#include <sound/core.h> 39#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/control.h> 40#include <sound/control.h>
41#include <sound/pcm.h>
42#include <sound/rawmidi.h>
35#include <sound/initval.h> 43#include <sound/initval.h>
36 44
37#include "saa7134.h" 45#include "saa7134.h"
38#include "saa7134-reg.h" 46#include "saa7134-reg.h"
39 47
40#define dprintk(level,fmt, arg...) if (debug >= level) \ 48static unsigned int alsa_debug = 0;
41 printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg) 49module_param(alsa_debug, int, 0644);
42 50MODULE_PARM_DESC(alsa_debug,"enable debug messages [alsa]");
43 51
44/**************************************************************************** 52#define MAX_PCM_DEVICES 1
45 Data type declarations - Can be moded to a header file later 53#define MAX_PCM_SUBSTREAMS 1
46 ****************************************************************************/ 54
47 55/* defaults */
48#define ANALOG_CLOCK 1792000 56#define MAX_BUFFER_SIZE (256*1024)
49#define CLOCK_DIV_MIN 4 57#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE
50#define CLOCK_DIV_MAX 15 58#define USE_RATE SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000
51#define MAX_PCM_DEVICES 4 59#define USE_RATE_MIN 32000
52#define MAX_PCM_SUBSTREAMS 16 60#define USE_RATE_MAX 48000
61#define USE_CHANNELS_MIN 1
62#define USE_CHANNELS_MAX 2
63#ifndef USE_PERIODS_MIN
64#define USE_PERIODS_MIN 2
65#endif
66#ifndef USE_PERIODS_MAX
67#define USE_PERIODS_MAX 1024
68#endif
53 69
54enum { DEVICE_DIGITAL, DEVICE_ANALOG };
55 70
56/* These can be replaced after done */ 71#define dprintk(fmt, arg...) if (alsa_debug) \
57#define MIXER_ADDR_LAST MAX_saa7134_INPUT 72 printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
58 73
59struct saa7134_audio_dev {
60 struct saa7134_core *core;
61 struct saa7134_buffer *buf;
62 struct saa7134_dmaqueue q;
63 74
64 /* pci i/o */ 75static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
65 struct pci_dev *pci; 76static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
66 unsigned char pci_rev,pci_lat; 77static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
78
79#define MIXER_ADDR_TVTUNER 0
80#define MIXER_ADDR_LINE1 1
81#define MIXER_ADDR_LINE2 2
82#define MIXER_ADDR_LAST 2
83
84typedef struct snd_card_saa7134 {
85 snd_card_t *card;
86 spinlock_t mixer_lock;
87 int mixer_volume[MIXER_ADDR_LAST+1][2];
88 int capture_source[MIXER_ADDR_LAST+1][2];
89 struct pci_dev *pci;
90 struct saa7134_dev *saadev;
91
92 unsigned long iobase;
93 int irq;
94
95 spinlock_t lock;
96} snd_card_saa7134_t;
97
98typedef struct snd_card_saa7134_pcm {
99 struct saa7134_dev *saadev;
100
101 spinlock_t lock;
102 unsigned int pcm_size; /* buffer size */
103 unsigned int pcm_count; /* bytes per period */
104 unsigned int pcm_bps; /* bytes per second */
105 snd_pcm_substream_t *substream;
106} snd_card_saa7134_pcm_t;
67 107
68 /* audio controls */ 108static snd_card_t *snd_saa7134_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
69 int irq;
70 int dig_rate; /* Digital sampling rate */
71 109
72 snd_card_t *card; 110static void saa7134_dma_stop(struct saa7134_dev *dev)
111{
112 dev->oss.dma_blk = -1;
113 dev->oss.dma_running = 0;
114 saa7134_set_dmabits(dev);
115}
73 116
74 spinlock_t reg_lock; 117static void saa7134_dma_start(struct saa7134_dev *dev)
118{
119 dev->oss.dma_blk = 0;
120 dev->oss.dma_running = 1;
121 saa7134_set_dmabits(dev);
122}
75 123
76 unsigned int dma_size; 124void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
77 unsigned int period_size; 125{
126 int next_blk, reg = 0;
78 127
79 int mixer_volume[MIXER_ADDR_LAST+1][2]; 128 spin_lock(&dev->slock);
80 int capture_source[MIXER_ADDR_LAST+1][2]; 129 if (UNSET == dev->oss.dma_blk) {
130 dprintk("irq: recording stopped\n");
131 goto done;
132 }
133 if (0 != (status & 0x0f000000))
134 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
135 if (0 == (status & 0x10000000)) {
136 /* odd */
137 if (0 == (dev->oss.dma_blk & 0x01))
138 reg = SAA7134_RS_BA1(6);
139 } else {
140 /* even */
141 if (1 == (dev->oss.dma_blk & 0x01))
142 reg = SAA7134_RS_BA2(6);
143 }
144 if (0 == reg) {
145 dprintk("irq: field oops [%s]\n",
146 (status & 0x10000000) ? "even" : "odd");
147 goto done;
148 }
81 149
82 long opened; 150 if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) {
83 snd_pcm_substream_t *substream; 151 dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->oss.read_count,
84}; 152 dev->oss.bufsize, dev->oss.blocks);
85typedef struct saa7134_audio_dev snd_saa7134_card_t; 153 saa7134_dma_stop(dev);
154 goto done;
155 }
86 156
87/**************************************************************************** 157 /* next block addr */
88 Module global static vars 158 next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks;
89 ****************************************************************************/ 159 saa_writel(reg,next_blk * dev->oss.blksize);
160 if (alsa_debug > 2)
161 dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
162 (status & 0x10000000) ? "even" : "odd ", next_blk,
163 next_blk * dev->oss.blksize, dev->oss.blocks, dev->oss.blksize, dev->oss.read_count);
90 164
91static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
92static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
93static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
94 165
95module_param_array(enable, bool, NULL, 0444); 166 /* update status & wake waiting readers */
96MODULE_PARM_DESC(enable, "Enable saa7134x soundcard. default enabled."); 167 dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks;
168 dev->oss.read_count += dev->oss.blksize;
97 169
98/**************************************************************************** 170 dev->oss.recording_on = reg;
99 Module macros
100 ****************************************************************************/
101 171
102MODULE_DESCRIPTION("ALSA driver module for saa7134 based TV cards"); 172 if (dev->oss.read_count >= snd_pcm_lib_period_bytes(dev->oss.substream)) {
103MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>"); 173 spin_unlock(&dev->slock);
104MODULE_LICENSE("GPL"); 174 snd_pcm_period_elapsed(dev->oss.substream);
105MODULE_SUPPORTED_DEVICE("{{Philips, saa7131E}," 175 spin_lock(&dev->slock);
106 "{{Philips, saa7134}," 176 }
107 "{{Philips, saa7133}"); 177 done:
108static unsigned int debug = 0; 178 spin_unlock(&dev->slock);
109module_param(debug,int,0644);
110MODULE_PARM_DESC(debug,"enable debug messages");
111 179
112/**************************************************************************** 180}
113 Module specific funtions
114 ****************************************************************************/
115 181
116/*
117 * BOARD Specific: Sets audio DMA
118 */
119 182
120int saa7134_start_audio_dma(snd_saa7134_card_t *chip) 183static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
184 int cmd)
121{ 185{
122 struct saa7134_core *core = chip->core;
123
124 return 0; 186 return 0;
125} 187}
126 188
127/* 189static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
128 * BOARD Specific: Resets audio DMA
129 */
130int saa7134_stop_audio_dma(snd_saa7134_card_t *chip)
131{ 190{
132 struct saa7134_core *core=chip->core; 191 if (blksize < 0x100)
133 return 0; 192 blksize = 0x100;
193 if (blksize > 0x10000)
194 blksize = 0x10000;
195
196 if (blocks < 2)
197 blocks = 2;
198 if ((blksize * blocks) > 1024*1024)
199 blocks = 1024*1024 / blksize;
200
201 dev->oss.blocks = blocks;
202 dev->oss.blksize = blksize;
203 dev->oss.bufsize = blksize * blocks;
204
205 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
206 blocks,blksize,blksize * blocks / 1024);
207 return 0;
134} 208}
135 209
136#define MAX_IRQ_LOOP 10 210static int dsp_buffer_init(struct saa7134_dev *dev)
137
138static void saa713401_timeout(unsigned long data)
139{ 211{
140 snd_saa7134_card_t *chip = (snd_saa7134_card_t *)data; 212 int err;
213
214 if (!dev->oss.bufsize)
215 BUG();
216 videobuf_dma_init(&dev->oss.dma);
217 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
218 (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
219 if (0 != err)
220 return err;
221 return 0;
141} 222}
142 223
143/* FIXME: Wrong values*/
144static char *saa7134_aud_irqs[32] = {
145 "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
146 "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
147 "y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
148 "y_sync", "u_sync", "v_sync", "vbi_sync",
149 "opc_err", "par_err", "rip_err", "pci_abort",
150};
151
152 224
153static void saa713401_aud_irq(snd_saa7134_card_t *chip) 225static int snd_card_saa7134_pcm_prepare(snd_pcm_substream_t * substream)
154{ 226{
155 struct saa7134_core *core = chip->core; 227 snd_pcm_runtime_t *runtime = substream->runtime;
156} 228 int err, bswap, sign;
229 u32 fmt, control;
230 unsigned long flags;
231 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
232 struct saa7134_dev *dev;
233 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
234 unsigned int bps;
235 unsigned long size;
236 unsigned count;
237
238 size = snd_pcm_lib_buffer_bytes(substream);
239 count = snd_pcm_lib_period_bytes(substream);
240
241 saapcm->saadev->oss.substream = substream;
242 bps = runtime->rate * runtime->channels;
243 bps *= snd_pcm_format_width(runtime->format);
244 bps /= 8;
245 if (bps <= 0)
246 return -EINVAL;
247 saapcm->pcm_bps = bps;
248 saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
249 saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
250
251
252 dev=saa7134->saadev;
253
254 dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
255
256 err = dsp_buffer_init(dev);
257 if (0 != err)
258 goto fail2;
259
260 /* prepare buffer */
261 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma)))
262 return err;
263 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt)))
264 goto fail1;
265 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt,
266 dev->oss.dma.sglist,
267 dev->oss.dma.sglen,
268 0)))
269 goto fail2;
270
271
272
273 switch (runtime->format) {
274 case SNDRV_PCM_FORMAT_U8:
275 case SNDRV_PCM_FORMAT_S8:
276 fmt = 0x00;
277 break;
278 case SNDRV_PCM_FORMAT_U16_LE:
279 case SNDRV_PCM_FORMAT_U16_BE:
280 case SNDRV_PCM_FORMAT_S16_LE:
281 case SNDRV_PCM_FORMAT_S16_BE:
282 fmt = 0x01;
283 break;
284 default:
285 err = -EINVAL;
286 return 1;
287 }
288
289 switch (runtime->format) {
290 case SNDRV_PCM_FORMAT_S8:
291 case SNDRV_PCM_FORMAT_S16_LE:
292 case SNDRV_PCM_FORMAT_S16_BE:
293 sign = 1;
294 break;
295 default:
296 sign = 0;
297 break;
298 }
299
300 switch (runtime->format) {
301 case SNDRV_PCM_FORMAT_U16_BE:
302 case SNDRV_PCM_FORMAT_S16_BE:
303 bswap = 1; break;
304 default:
305 bswap = 0; break;
306 }
307
308 switch (dev->pci->device) {
309 case PCI_DEVICE_ID_PHILIPS_SAA7134:
310 if (1 == runtime->channels)
311 fmt |= (1 << 3);
312 if (2 == runtime->channels)
313 fmt |= (3 << 3);
314 if (sign)
315 fmt |= 0x04;
316
317 fmt |= (MIXER_ADDR_TVTUNER == dev->oss.input) ? 0xc0 : 0x80;
318 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff));
319 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8);
320 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16);
321 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
322
323 break;
324 case PCI_DEVICE_ID_PHILIPS_SAA7133:
325 case PCI_DEVICE_ID_PHILIPS_SAA7135:
326 if (1 == runtime->channels)
327 fmt |= (1 << 4);
328 if (2 == runtime->channels)
329 fmt |= (2 << 4);
330 if (!sign)
331 fmt |= 0x04;
332 //saa_writel(SAA7133_NUM_SAMPLES, dev->oss.blksize -1);
333 saa_writel(SAA7133_NUM_SAMPLES, dev->oss.blksize -1);
334 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
335 //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
336 break;
337 }
338
339 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
340 runtime->format, runtime->channels, fmt,
341 bswap ? 'b' : '-');
342 /* dma: setup channel 6 (= AUDIO) */
343 control = SAA7134_RS_CONTROL_BURST_16 |
344 SAA7134_RS_CONTROL_ME |
345 (dev->oss.pt.dma >> 12);
346 if (bswap)
347 control |= SAA7134_RS_CONTROL_BSWAP;
348
349 runtime->dma_area = dev->oss.dma.vmalloc;
350 saa_writel(SAA7134_RS_BA1(6),0);
351 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
352 saa_writel(SAA7134_RS_PITCH(6),0);
353 saa_writel(SAA7134_RS_CONTROL(6),control);
354
355 dev->oss.rate = runtime->rate;
356 /* start dma */
357 spin_lock_irqsave(&dev->slock,flags);
358 saa7134_dma_start(dev);
359 spin_unlock_irqrestore(&dev->slock,flags);
157 360
158static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) 361 return 0;
159{ 362 fail2:
160 snd_saa7134_card_t *chip = dev_id; 363 saa7134_pgtable_free(dev->pci,&dev->oss.pt);
161 struct saa7134_core *core = chip->core; 364 fail1:
162} 365 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
366 return err;
163 367
164/****************************************************************************
165 ALSA PCM Interface
166 ****************************************************************************/
167 368
168/* 369}
169 * Digital hardware definition
170 */
171static snd_pcm_hardware_t snd_saa7134_digital_hw = {
172 .info = SNDRV_PCM_INFO_MMAP |
173 SNDRV_PCM_INFO_INTERLEAVED |
174 SNDRV_PCM_INFO_BLOCK_TRANSFER |
175 SNDRV_PCM_INFO_MMAP_VALID,
176 .formats = SNDRV_PCM_FMTBIT_S16_LE,
177 .rates = 0, /* set at runtime */
178 .channels_min = 2,
179 .channels_max = 2,
180 .buffer_bytes_max = 255 * 4092,
181 .period_bytes_min = 32,
182 .period_bytes_max = 4092,
183 .periods_min = 2,
184 .periods_max = 255,
185};
186 370
187/* 371static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
188 * Sets board to provide digital audio
189 */
190static int snd_saa7134_set_digital_hw(snd_saa7134_card_t *chip, snd_pcm_runtime_t *runtime)
191{ 372{
192 return 0; 373 return snd_card_saa7134_pcm_prepare(substream);
193} 374}
194 375
195/* 376static snd_pcm_uframes_t snd_card_saa7134_pointer(snd_pcm_substream_t * substream)
196 * audio open callback
197 */
198static int snd_saa7134_pcm_open(snd_pcm_substream_t *substream)
199{ 377{
200 snd_saa7134_card_t *chip = snd_pcm_substream_chip(substream);
201 snd_pcm_runtime_t *runtime = substream->runtime; 378 snd_pcm_runtime_t *runtime = substream->runtime;
202 int err; 379 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
380 struct saa7134_dev *dev=saapcm->saadev;
203 381
204 if (test_and_set_bit(0, &chip->opened))
205 return -EBUSY;
206 382
207 err = snd_saa7134_set_digital_hw(chip, runtime);
208 383
209 if (err < 0) 384 if (dev->oss.read_count) {
210 goto _error; 385 dev->oss.read_count -= snd_pcm_lib_period_bytes(substream);
386 dev->oss.read_offset += snd_pcm_lib_period_bytes(substream);
387 if (dev->oss.read_offset == dev->oss.bufsize)
388 dev->oss.read_offset = 0;
389 }
211 390
212 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 391 //return bytes_to_frames(runtime, saa_readl(dev->oss.recording_on));
213 if (err < 0) 392 return bytes_to_frames(runtime, dev->oss.read_offset);
214 goto _error; 393}
215 394
216 chip->substream = substream;
217 return 0;
218 395
219_error: 396static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
220 clear_bit(0, &chip->opened); 397{
221 smp_mb__after_clear_bit(); 398 return snd_card_saa7134_pointer(substream);
222 return err;
223} 399}
224 400
225/* 401static snd_pcm_hardware_t snd_card_saa7134_capture =
226 * audio close callback
227 */
228static int snd_saa7134_close(snd_pcm_substream_t *substream)
229{ 402{
230 snd_saa7134_card_t *chip = snd_pcm_substream_chip(substream); 403 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
404 SNDRV_PCM_INFO_BLOCK_TRANSFER |
405 SNDRV_PCM_INFO_MMAP_VALID),
406 .formats = USE_FORMATS,
407 .rates = USE_RATE,
408 .rate_min = USE_RATE_MIN,
409 .rate_max = USE_RATE_MAX,
410 .channels_min = USE_CHANNELS_MIN,
411 .channels_max = USE_CHANNELS_MAX,
412 .buffer_bytes_max = MAX_BUFFER_SIZE,
413 .period_bytes_min = 64,
414 .period_bytes_max = MAX_BUFFER_SIZE,
415 .periods_min = USE_PERIODS_MIN,
416 .periods_max = USE_PERIODS_MAX,
417 .fifo_size = 0x08070503,
418};
231 419
232 chip->substream = NULL; 420static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
233 clear_bit(0, &chip->opened); 421{
234 smp_mb__after_clear_bit(); 422 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
235 return 0; 423
424 kfree(saapcm);
236} 425}
237 426
238/* 427
239 * hw_params callback 428static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
240 */ 429 snd_pcm_hw_params_t * hw_params)
241static int snd_saa7134_hw_params(snd_pcm_substream_t * substream,
242 snd_pcm_hw_params_t * hw_params)
243{ 430{
431
244 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 432 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
433
434
245} 435}
246 436
247/* 437static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
248 * hw free callback
249 */
250static int snd_saa7134_hw_free(snd_pcm_substream_t * substream)
251{ 438{
252 return snd_pcm_lib_free_pages(substream); 439 return snd_pcm_lib_free_pages(substream);
253} 440}
254 441
255/* 442static int dsp_buffer_free(struct saa7134_dev *dev)
256 * prepare callback
257 */
258static int snd_saa7134_prepare(snd_pcm_substream_t *substream)
259{ 443{
260 snd_saa7134_card_t *chip = snd_pcm_substream_chip(substream); 444 if (!dev->oss.blksize)
261 return 0; 445 BUG();
262}
263 446
447 videobuf_dma_free(&dev->oss.dma);
264 448
265/* 449 dev->oss.blocks = 0;
266 * trigger callback 450 dev->oss.blksize = 0;
267 */ 451 dev->oss.bufsize = 0;
268static int snd_saa7134_card_trigger(snd_pcm_substream_t *substream, int cmd) 452
269{ 453 return 0;
270 snd_saa7134_card_t *chip = snd_pcm_substream_chip(substream);
271
272 switch (cmd) {
273 case SNDRV_PCM_TRIGGER_START:
274 return snd_saa7134_start(chip);
275 case SNDRV_PCM_TRIGGER_STOP:
276 return snd_saa7134_stop(chip);
277 default:
278 return -EINVAL;
279 }
280} 454}
281 455
282/* 456
283 * pointer callback 457static int saa7134_cap_close(struct saa7134_dev *dev)
284 */
285static snd_pcm_uframes_t snd_saa7134_pointer(snd_pcm_substream_t *substream)
286{ 458{
287// snd_saa7134_card_t *chip = snd_pcm_substream_chip(substream); 459 unsigned long flags;
288// snd_pcm_runtime_t *runtime = substream->runtime; 460
461 /* stop dma */
462 spin_lock_irqsave(&dev->slock,flags);
463 saa7134_dma_stop(dev);
464 spin_unlock_irqrestore(&dev->slock,flags);
465
466 /* unlock buffer */
467 saa7134_pgtable_free(dev->pci,&dev->oss.pt);
468 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
289 469
290// return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes); 470 dsp_buffer_free(dev);
471 return 0;
291} 472}
292 473
293/*
294 * operators
295 */
296static snd_pcm_ops_t snd_saa7134_pcm_ops = {
297 .open = snd_saa7134_pcm_open,
298 .close = snd_saa7134_close,
299 .ioctl = snd_pcm_lib_ioctl,
300 .hw_params = snd_saa7134_hw_params,
301 .hw_free = snd_saa7134_hw_free,
302 .prepare = snd_saa7134_prepare,
303 .trigger = snd_saa7134_card_trigger,
304 .pointer = snd_saa7134_pointer,
305 .page = snd_pcm_sgbuf_ops_page,
306};
307 474
308/* 475static int saa7134_cap_open(struct saa7134_dev *dev) {
309 * create a PCM device
310 */
311static int __devinit snd_saa7134_pcm(snd_saa7134_card_t *chip, int device, char *name)
312{
313 int err;
314 snd_pcm_t *pcm;
315 476
316 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); 477 down(&dev->oss.lock);
317 if (err < 0)
318 return err;
319 pcm->private_data = chip;
320 strcpy(pcm->name, name);
321 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_saa7134_pcm_ops);
322 return snd_pcm_lib_preallocate_pages_for_all(pcm,
323 SNDRV_DMA_TYPE_DEV_SG,
324 snd_dma_pci_data(chip->pci),
325 128 * 1024,
326 (255 * 4092 + 1023) & ~1023);
327}
328 478
329/**************************************************************************** 479 dev->oss.afmt = SNDRV_PCM_FORMAT_U8;
330 CONTROL INTERFACE 480 dev->oss.channels = 2;
331 ****************************************************************************/ 481 dev->oss.read_count = 0;
332static int snd_saa7134_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info) 482 dev->oss.read_offset = 0;
333{ 483
334 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 484 up(&dev->oss.lock);
335 info->count = 1;
336 info->value.integer.min = 0;
337 info->value.integer.max = 0x3f;
338 485
339 return 0; 486 return 0;
340} 487}
341 488
342/* OK - TODO: test it */ 489static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
343static int snd_saa7134_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
344{ 490{
345 snd_saa7134_card_t *chip = snd_kcontrol_chip(kcontrol); 491 snd_pcm_runtime_t *runtime = substream->runtime;
346 struct saa7134_core *core=chip->core; 492 snd_card_saa7134_pcm_t *saapcm;
493 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
494 int err;
495
496 saa7134_cap_open(saa7134->saadev);
497
498 saapcm = kcalloc(1, sizeof(*saapcm), GFP_KERNEL);
499 if (saapcm == NULL)
500 return -ENOMEM;
501 saapcm->saadev=saa7134->saadev;
502
503 spin_lock_init(&saapcm->lock);
504
505 saapcm->substream = substream;
506 runtime->private_data = saapcm;
507 runtime->private_free = snd_card_saa7134_runtime_free;
508 runtime->hw = snd_card_saa7134_capture;
509
510 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
511 return err;
347 512
348 return 0; 513 return 0;
349} 514}
350 515
351/* OK - TODO: test it */ 516static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
352static int snd_saa7134_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
353{ 517{
354 snd_saa7134_card_t *chip = snd_kcontrol_chip(kcontrol); 518 snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
355 struct saa7134_core *core=chip->core;
356 519
520 saa7134_cap_close(chip->saadev);
357 return 0; 521 return 0;
358} 522}
359 523
360static snd_kcontrol_new_t snd_saa7134_capture_volume = { 524static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 525 .open = snd_card_saa7134_capture_open,
362 .name = "Capture Volume", 526 .close = snd_card_saa7134_capture_close,
363 .info = snd_saa7134_capture_volume_info, 527 .ioctl = snd_pcm_lib_ioctl,
364 .get = snd_saa7134_capture_volume_get, 528 .hw_params = snd_card_saa7134_hw_params,
365 .put = snd_saa7134_capture_volume_put, 529 .hw_free = snd_card_saa7134_hw_free,
530 .prepare = snd_card_saa7134_capture_prepare,
531 .trigger = snd_card_saa7134_capture_trigger,
532 .pointer = snd_card_saa7134_capture_pointer,
366}; 533};
367 534
368/* 535static int __init snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
369 *************************************** 536{
370 */ 537 snd_pcm_t *pcm;
538 int err;
371 539
372/**************************************************************************** 540 if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
373 Basic Flow for Sound Devices 541 return err;
374 ****************************************************************************/ 542 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
543 pcm->private_data = saa7134;
544 pcm->info_flags = 0;
545 strcpy(pcm->name, "SAA7134 PCM");
546 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
547 snd_dma_pci_data(saa7134->pci),
548 128*1024, 256*1024);
549 return 0;
550}
375 551
376/* 552#define SAA713x_VOLUME(xname, xindex, addr) \
377 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio 553{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
378 * Only boards with eeprom and byte 1 at eeprom=1 have it 554 .info = snd_saa7134_volume_info, \
379 */ 555 .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
556 .private_value = addr }
380 557
381struct pci_device_id saa7134_audio_pci_tbl[] = { 558static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
382 {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 559{
383 {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 560 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
384 {0, } 561 uinfo->count = 2;
385}; 562 uinfo->value.integer.min = 0;
386MODULE_DEVICE_TABLE(pci, saa7134_audio_pci_tbl); 563 uinfo->value.integer.max = 20;
564 return 0;
565}
387 566
388/* 567static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
389 * Chip-specific destructor 568{
390 */ 569 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
570 unsigned long flags;
571 int addr = kcontrol->private_value;
572
573 spin_lock_irqsave(&chip->mixer_lock, flags);
574 ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
575 ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
576 spin_unlock_irqrestore(&chip->mixer_lock, flags);
577 return 0;
578}
391 579
392static int snd_saa7134_free(snd_saa7134_card_t *chip) 580static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
393{ 581{
394 if (chip->irq >= 0) 582 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
395 free_irq(chip->irq, chip); 583 unsigned long flags;
584 int change, addr = kcontrol->private_value;
585 int left, right;
586
587 left = ucontrol->value.integer.value[0];
588 if (left < 0)
589 left = 0;
590 if (left > 20)
591 left = 20;
592 right = ucontrol->value.integer.value[1];
593 if (right < 0)
594 right = 0;
595 if (right > 20)
596 right = 20;
597 spin_lock_irqsave(&chip->mixer_lock, flags);
598 change = chip->mixer_volume[addr][0] != left ||
599 chip->mixer_volume[addr][1] != right;
600 chip->mixer_volume[addr][0] = left;
601 chip->mixer_volume[addr][1] = right;
602 spin_unlock_irqrestore(&chip->mixer_lock, flags);
603 return change;
604}
396 605
397 /* free memory */ 606#define SAA713x_CAPSRC(xname, xindex, addr) \
398 saa7134_core_put(chip->core,chip->pci); 607{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
608 .info = snd_saa7134_capsrc_info, \
609 .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
610 .private_value = addr }
399 611
400 pci_release_regions(chip->pci); 612static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
401 pci_disable_device(chip->pci); 613{
614 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
615 uinfo->count = 1;
616 uinfo->value.integer.min = 0;
617 uinfo->value.integer.max = 1;
618 return 0;
619}
402 620
403 kfree(chip); 621static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
622{
623 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
624 unsigned long flags;
625 int addr = kcontrol->private_value;
626
627 spin_lock_irqsave(&chip->mixer_lock, flags);
628 ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
629 ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
630 spin_unlock_irqrestore(&chip->mixer_lock, flags);
404 return 0; 631 return 0;
405} 632}
406 633
407/* 634static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
408 * Component Destructor
409 */
410static int snd_saa7134_dev_free(snd_device_t *device)
411{ 635{
412 snd_saa7134_card_t *chip = device->device_data; 636 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
413 return snd_saa7134_free(chip); 637 unsigned long flags;
638 int change, addr = kcontrol->private_value;
639 int left, right;
640 u32 anabar, xbarin;
641 int analog_io, rate;
642 struct saa7134_dev *dev;
643
644 dev = chip->saadev;
645
646 left = ucontrol->value.integer.value[0] & 1;
647 right = ucontrol->value.integer.value[1] & 1;
648 spin_lock_irqsave(&chip->mixer_lock, flags);
649
650 change = chip->capture_source[addr][0] != left &&
651 chip->capture_source[addr][1] != right;
652 chip->capture_source[addr][0] = left;
653 chip->capture_source[addr][1] = right;
654 dev->oss.input=addr;
655 spin_unlock_irqrestore(&chip->mixer_lock, flags);
656
657
658 switch (dev->pci->device) {
659
660 case PCI_DEVICE_ID_PHILIPS_SAA7134:
661 switch (addr) {
662 case MIXER_ADDR_TVTUNER:
663 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
664 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
665 break;
666 case MIXER_ADDR_LINE1:
667 case MIXER_ADDR_LINE2:
668 analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
669 rate = (32000 == dev->oss.rate) ? 0x01 : 0x03;
670 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
671 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
672 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
673 break;
674 }
675
676 case PCI_DEVICE_ID_PHILIPS_SAA7133:
677 case PCI_DEVICE_ID_PHILIPS_SAA7135:
678 xbarin = 0x03; // adc
679 anabar = 0;
680 switch (addr) {
681 case MIXER_ADDR_TVTUNER:
682 xbarin = 0; // Demodulator
683 anabar = 2; // DACs
684 break;
685 case MIXER_ADDR_LINE1:
686 anabar = 0; // aux1, aux1
687 break;
688 case MIXER_ADDR_LINE2:
689 anabar = 9; // aux2, aux2
690 break;
691 }
692
693 /* output xbar always main channel */
694 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
695
696 if (left || right) { // We've got data, turn the input on
697 //saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL2, 0x101010);
698 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
699 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
700 } else {
701 //saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL2, 0x101010);
702 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
703 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
704 }
705 }
706
707 return change;
414} 708}
415 709
710static snd_kcontrol_new_t snd_saa7134_controls[] = {
711SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
712SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
713SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
714SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
715SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
716SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
717};
416 718
417/* 719static int __init snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
418 * Alsa Constructor - Component probe 720{
419 */ 721 snd_card_t *card = chip->card;
722 unsigned int idx;
723 int err;
724
725 snd_assert(chip != NULL, return -EINVAL);
726 strcpy(card->mixername, "SAA7134 Mixer");
420 727
421static int devno=0; 728 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
422static int __devinit snd_saa7134_create(snd_card_t *card, struct pci_dev *pci, 729 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
423 snd_saa7134_card_t **rchip) 730 return err;
731 }
732 return 0;
733}
734
735static int snd_saa7134_free(snd_card_saa7134_t *chip)
424{ 736{
425 snd_saa7134_card_t *chip;
426 struct saa7134_core *core;
427 return 0; 737 return 0;
428} 738}
429 739
430static int __devinit saa7134_audio_initdev(struct pci_dev *pci, 740static int snd_saa7134_dev_free(snd_device_t *device)
431 const struct pci_device_id *pci_id)
432{ 741{
433 snd_card_t *card; 742 snd_card_saa7134_t *chip = device->device_data;
434 snd_saa7134_card_t *chip; 743 return snd_saa7134_free(chip);
435 int err; 744}
436 745
437 if (devno >= SNDRV_CARDS) 746int alsa_card_saa7134_create(struct saa7134_dev *saadev)
438 return (-ENODEV); 747{
748 static int dev;
749 snd_card_t *card;
750 struct snd_card_saa7134 *chip;
751 int err;
752 static snd_device_ops_t ops = {
753 .dev_free = snd_saa7134_dev_free,
754 };
439 755
440 if (!enable[devno]) { 756 if (dev >= SNDRV_CARDS)
441 ++devno; 757 return -ENODEV;
442 return (-ENOENT); 758 if (!enable[dev])
443 } 759 return -ENODEV;
760 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
761 sizeof(struct snd_card_saa7134));
762 if (card == NULL)
763 return -ENOMEM;
444 764
445 card = snd_card_new(index[devno], id[devno], THIS_MODULE, 0); 765 strcpy(card->driver, "SAA7134");
446 if (!card)
447 return (-ENOMEM);
448 766
449 err = snd_saa7134_create(card, pci, &chip); 767 /* Card "creation" */
450 if (err < 0) 768 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
451 return (err); 769 if (chip == NULL) {
770 return -ENOMEM;
771 }
452 772
453/* 773 spin_lock_init(&chip->lock);
454 err = snd_saa7134_pcm(chip, DEVICE_DIGITAL, "saa7134 Digital");
455 if (err < 0)
456 goto fail_free;
457*/
458 err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_capture_volume, chip));
459 if (err < 0) {
460 snd_card_free(card);
461 return (err);
462 }
463 774
464 strcpy (card->driver, "saa7134_ALSA"); 775 chip->saadev = saadev;
465 sprintf(card->shortname, "Saa7134 %x", pci->device);
466 sprintf(card->longname, "%s at %#lx",
467 card->shortname, pci_resource_start(pci, 0));
468 strcpy (card->mixername, "saa7134");
469 776
470 dprintk (0, "%s/%i: Alsa support for saa7134x boards\n", 777 chip->card = card;
471 card->driver,devno); 778 chip->pci = saadev->pci;
779 chip->irq = saadev->pci->irq;
780 chip->iobase = pci_resource_start(saadev->pci, 0);
472 781
473 err = snd_card_register(card); 782 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
474 if (err < 0) { 783 snd_saa7134_free(chip);
475 snd_card_free(card); 784 return err;
476 return (err); 785 }
477 }
478 786
479 pci_set_drvdata(pci,card);
480 787
481 devno++; 788 if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
482 return 0; 789 goto __nodev;
483}
484/*
485 * ALSA destructor
486 */
487static void __devexit saa7134_audio_finidev(struct pci_dev *pci)
488{
489 snd_card_free(pci_get_drvdata(pci));
490 pci_set_drvdata(pci, NULL);
491 790
492 devno--; 791 if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
493} 792 goto __nodev;
793 spin_lock_init(&chip->mixer_lock);
494 794
495/* 795 snd_card_set_dev(card, &chip->pci->dev);
496 * PCI driver definition
497 */
498 796
499static struct pci_driver saa7134_audio_pci_driver = { 797 /* End of "creation" */
500 .name = "saa7134_audio",
501 .id_table = saa7134_audio_pci_tbl,
502 .probe = saa7134_audio_initdev,
503 .remove = saa7134_audio_finidev,
504 SND_PCI_PM_CALLBACKS
505};
506 798
507/**************************************************************************** 799 strcpy(card->shortname, "SAA7134");
508 LINUX MODULE INIT 800 sprintf(card->longname, "%s at 0x%lx irq %d",
509 ****************************************************************************/ 801 card->shortname, chip->iobase, chip->irq);
510 802
511/* 803
512 * module init 804 if ((err = snd_card_register(card)) == 0) {
513 */ 805 snd_saa7134_cards[dev] = card;
514static int saa7134_audio_init(void) 806 return 0;
515{ 807 }
516 printk(KERN_INFO "saa7134x alsa driver version %d.%d.%d loaded\n", 808
517 (saa7134_VERSION_CODE >> 16) & 0xff, 809__nodev:
518 (saa7134_VERSION_CODE >> 8) & 0xff, 810 snd_card_free(card);
519 saa7134_VERSION_CODE & 0xff); 811 kfree(card);
520#ifdef SNAPSHOT 812 return err;
521 printk(KERN_INFO "saa7134x: snapshot date %04d-%02d-%02d\n",
522 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
523#endif
524 return pci_module_init(&saa7134_audio_pci_driver);
525} 813}
526 814
527/* 815void alsa_card_saa7134_exit(void)
528 * module remove
529 */
530static void saa7134_audio_fini(void)
531{ 816{
532 pci_unregister_driver(&saa7134_audio_pci_driver); 817 int idx;
818 for (idx = 0; idx < SNDRV_CARDS; idx++) {
819 snd_card_free(snd_saa7134_cards[idx]);
820 }
533} 821}
534
535module_init(saa7134_audio_init);
536module_exit(saa7134_audio_fini);
537
538/* ----------------------------------------------------------- */
539/*
540 * Local variables:
541 * c-basic-offset: 8
542 * End:
543 */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 109c815c5e6c..538c9ce2f2bb 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -57,6 +57,10 @@ static unsigned int oss = 0;
57module_param(oss, int, 0444); 57module_param(oss, int, 0444);
58MODULE_PARM_DESC(oss,"register oss devices (default: no)"); 58MODULE_PARM_DESC(oss,"register oss devices (default: no)");
59 59
60static unsigned int alsa = 0;
61module_param(alsa, int, 0444);
62MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
63
60static unsigned int latency = UNSET; 64static unsigned int latency = UNSET;
61module_param(latency, int, 0444); 65module_param(latency, int, 0444);
62MODULE_PARM_DESC(latency,"pci latency timer"); 66MODULE_PARM_DESC(latency,"pci latency timer");
@@ -591,13 +595,19 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
591 card_has_mpeg(dev)) 595 card_has_mpeg(dev))
592 saa7134_irq_ts_done(dev,status); 596 saa7134_irq_ts_done(dev,status);
593 597
594 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) 598 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
595 saa7134_irq_oss_done(dev,status); 599 if (oss) {
600 saa7134_irq_oss_done(dev,status);
601 } else if (alsa) {
602 saa7134_irq_alsa_done(dev,status);
603 }
604 }
596 605
597 if ((report & (SAA7134_IRQ_REPORT_GPIO16 | 606 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
598 SAA7134_IRQ_REPORT_GPIO18)) && 607 SAA7134_IRQ_REPORT_GPIO18)) &&
599 dev->remote) 608 dev->remote)
600 saa7134_input_irq(dev); 609 saa7134_input_irq(dev);
610
601 } 611 }
602 612
603 if (10 == loop) { 613 if (10 == loop) {
@@ -1016,6 +1026,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1016 goto fail5; 1026 goto fail5;
1017 printk(KERN_INFO "%s: registered device mixer%d\n", 1027 printk(KERN_INFO "%s: registered device mixer%d\n",
1018 dev->name,dev->oss.minor_mixer >> 4); 1028 dev->name,dev->oss.minor_mixer >> 4);
1029 } else if (alsa) {
1030 alsa_card_saa7134_create(dev);
1031 printk(KERN_INFO "%s: registered ALSA devices\n",
1032 dev->name);
1019 } 1033 }
1020 break; 1034 break;
1021 } 1035 }
@@ -1043,6 +1057,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1043 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1057 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1044 if (oss) 1058 if (oss)
1045 unregister_sound_dsp(dev->oss.minor_dsp); 1059 unregister_sound_dsp(dev->oss.minor_dsp);
1060 else if (alsa)
1061 alsa_card_saa7134_exit();
1046 break; 1062 break;
1047 } 1063 }
1048 fail4: 1064 fail4:
@@ -1102,7 +1118,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1102 if (oss) { 1118 if (oss) {
1103 unregister_sound_mixer(dev->oss.minor_mixer); 1119 unregister_sound_mixer(dev->oss.minor_mixer);
1104 unregister_sound_dsp(dev->oss.minor_dsp); 1120 unregister_sound_dsp(dev->oss.minor_dsp);
1105 } 1121 } else if (alsa)
1122 alsa_card_saa7134_exit();
1106 break; 1123 break;
1107 } 1124 }
1108 saa7134_unregister_video(dev); 1125 saa7134_unregister_video(dev);
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index c20630c82f1c..b1dcb4d10788 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -44,6 +44,7 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
44#define dprintk(fmt, arg...) if (oss_debug) \ 44#define dprintk(fmt, arg...) if (oss_debug) \
45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) 45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
46 46
47
47/* ------------------------------------------------------------------ */ 48/* ------------------------------------------------------------------ */
48 49
49static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) 50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
@@ -173,8 +174,8 @@ static int dsp_rec_start(struct saa7134_dev *dev)
173 fmt |= (2 << 4); 174 fmt |= (2 << 4);
174 if (!sign) 175 if (!sign)
175 fmt |= 0x04; 176 fmt |= 0x04;
176 saa_writel(0x588 >> 2, dev->oss.blksize -4); 177 saa_writel(SAA7133_NUM_SAMPLES, dev->oss.blksize -4);
177 saa_writel(0x58c >> 2, 0x543210 | (fmt << 24)); 178 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
178 break; 179 break;
179 } 180 }
180 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", 181 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index fce4f185ef92..58c521fade85 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -43,6 +43,14 @@
43#define SAA7134_FIFO_SIZE (0x2a0 >> 2) 43#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
44#define SAA7134_THRESHOULD (0x2a4 >> 2) 44#define SAA7134_THRESHOULD (0x2a4 >> 2)
45 45
46#define SAA7133_NUM_SAMPLES (0x588 >> 2)
47#define SAA7133_AUDIO_CHANNEL (0x58c >> 2)
48#define SAA7133_AUDIO_FORMAT (0x58f >> 2)
49#define SAA7133_DIGITAL_OUTPUT_SEL1 (0x46c >> 2)
50#define SAA7133_DIGITAL_OUTPUT_SEL2 (0x470 >> 2)
51#define SAA7133_DIGITAL_INPUT_XBAR1 (0x464 >> 2)
52#define SAA7133_ANALOG_IO_SELECT (0x594 >> 2)
53
46/* main control */ 54/* main control */
47#define SAA7134_MAIN_CTRL (0x2a8 >> 2) 55#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
48#define SAA7134_MAIN_CTRL_VPLLE (1 << 15) 56#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 9dfd45bed92b..7a35ef8fecb7 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -45,6 +45,10 @@
45#endif 45#endif
46#define UNSET (-1U) 46#define UNSET (-1U)
47 47
48#include <sound/driver.h>
49#include <sound/core.h>
50#include <sound/pcm.h>
51
48/* ----------------------------------------------------------- */ 52/* ----------------------------------------------------------- */
49/* enums */ 53/* enums */
50 54
@@ -364,6 +368,7 @@ struct saa7134_oss {
364 unsigned int dma_blk; 368 unsigned int dma_blk;
365 unsigned int read_offset; 369 unsigned int read_offset;
366 unsigned int read_count; 370 unsigned int read_count;
371 snd_pcm_substream_t *substream;
367}; 372};
368 373
369/* IR input */ 374/* IR input */
@@ -644,6 +649,11 @@ int saa7134_input_init1(struct saa7134_dev *dev);
644void saa7134_input_fini(struct saa7134_dev *dev); 649void saa7134_input_fini(struct saa7134_dev *dev);
645void saa7134_input_irq(struct saa7134_dev *dev); 650void saa7134_input_irq(struct saa7134_dev *dev);
646 651
652int alsa_card_saa7134_create(struct saa7134_dev *saadev);
653void alsa_card_saa7134_exit(void);
654void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status);
655
656
647/* 657/*
648 * Local variables: 658 * Local variables:
649 * c-basic-offset: 8 659 * c-basic-offset: 8