[ALSA] Implement different capture sources.
[safe/jmp/linux-2.6] / sound / pci / emu10k1 / p16v.c
1 /*
2  *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3  *  Driver p16v chips
4  *  Version: 0.22
5  *
6  *  FEATURES currently supported:
7  *    Output fixed at S32_LE, 2 channel to hw:0,0
8  *    Rates: 44.1, 48, 96, 192.
9  *
10  *  Changelog:
11  *  0.8
12  *    Use separate card based buffer for periods table.
13  *  0.9
14  *    Use 2 channel output streams instead of 8 channel.
15  *       (8 channel output streams might be good for ASIO type output)
16  *    Corrected speaker output, so Front -> Front etc.
17  *  0.10
18  *    Fixed missed interrupts.
19  *  0.11
20  *    Add Sound card model number and names.
21  *    Add Analog volume controls.
22  *  0.12
23  *    Corrected playback interrupts. Now interrupt per period, instead of half period.
24  *  0.13
25  *    Use single trigger for multichannel.
26  *  0.14
27  *    Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
28  *  0.15
29  *    Force buffer_size / period_size == INTEGER.
30  *  0.16
31  *    Update p16v.c to work with changed alsa api.
32  *  0.17
33  *    Update p16v.c to work with changed alsa api. Removed boot_devs.
34  *  0.18
35  *    Merging with snd-emu10k1 driver.
36  *  0.19
37  *    One stereo channel at 24bit now works.
38  *  0.20
39  *    Added better register defines.
40  *  0.21
41  *    Integrated with snd-emu10k1 driver.
42  *  0.22
43  *    Removed #if 0 ... #endif
44  *  0.23
45  *    Implement different capture rates.
46  *  0.24
47  *    Implement different capture source channels.
48  *    e.g. When HD Capture source is set to SPDIF,
49  *    setting HD Capture channel to 0 captures from CDROM digital input.
50  *    setting HD Capture channel to 1 captures from SPDIF in.
51  *
52  *  BUGS:
53  *    Some stability problems when unloading the snd-p16v kernel module.
54  *    --
55  *
56  *  TODO:
57  *    SPDIF out.
58  *    Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
59  *    Currently capture fixed at 48000Hz.
60  *
61  *    --
62  *  GENERAL INFO:
63  *    Model: SB0240
64  *    P16V Chip: CA0151-DBS
65  *    Audigy 2 Chip: CA0102-IAT
66  *    AC97 Codec: STAC 9721
67  *    ADC: Philips 1361T (Stereo 24bit)
68  *    DAC: CS4382-K (8-channel, 24bit, 192Khz)
69  *
70  *  This code was initally based on code from ALSA's emu10k1x.c which is:
71  *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
72  *
73  *   This program is free software; you can redistribute it and/or modify
74  *   it under the terms of the GNU General Public License as published by
75  *   the Free Software Foundation; either version 2 of the License, or
76  *   (at your option) any later version.
77  *
78  *   This program is distributed in the hope that it will be useful,
79  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
80  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
81  *   GNU General Public License for more details.
82  *
83  *   You should have received a copy of the GNU General Public License
84  *   along with this program; if not, write to the Free Software
85  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
86  *
87  */
88 #include <sound/driver.h>
89 #include <linux/delay.h>
90 #include <linux/init.h>
91 #include <linux/interrupt.h>
92 #include <linux/pci.h>
93 #include <linux/slab.h>
94 #include <linux/moduleparam.h>
95 #include <sound/core.h>
96 #include <sound/initval.h>
97 #include <sound/pcm.h>
98 #include <sound/ac97_codec.h>
99 #include <sound/info.h>
100 #include <sound/emu10k1.h>
101 #include "p16v.h"
102
103 #define SET_CHANNEL 0  /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
104 #define PCM_FRONT_CHANNEL 0
105 #define PCM_REAR_CHANNEL 1
106 #define PCM_CENTER_LFE_CHANNEL 2
107 #define PCM_UNKNOWN_CHANNEL 3
108 #define CONTROL_FRONT_CHANNEL 0
109 #define CONTROL_REAR_CHANNEL 3
110 #define CONTROL_CENTER_LFE_CHANNEL 1
111 #define CONTROL_UNKNOWN_CHANNEL 2
112
113 /* Card IDs:
114  * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
115  * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1007 -> Audigy2 6.1    Model:SB0240
116  * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1002 -> Audigy2 Platinum  Model:SB msb0240230009266
117  * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2007 -> Audigy4 Pro Model:SB0380 M1SB0380472001901E
118  *
119  */
120
121  /* hardware definition */
122 static snd_pcm_hardware_t snd_p16v_playback_hw = {
123         .info =                 (SNDRV_PCM_INFO_MMAP | 
124                                  SNDRV_PCM_INFO_INTERLEAVED |
125                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
126                                  SNDRV_PCM_INFO_MMAP_VALID),
127         .formats =              SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
128         .rates =                SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 
129         .rate_min =             44100,
130         .rate_max =             192000,
131         .channels_min =         8, 
132         .channels_max =         8,
133         .buffer_bytes_max =     ((65536 - 64) * 8),
134         .period_bytes_min =     64,
135         .period_bytes_max =     (65536 - 64),
136         .periods_min =          2,
137         .periods_max =          8,
138         .fifo_size =            0,
139 };
140
141 static snd_pcm_hardware_t snd_p16v_capture_hw = {
142         .info =                 (SNDRV_PCM_INFO_MMAP |
143                                  SNDRV_PCM_INFO_INTERLEAVED |
144                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
145                                  SNDRV_PCM_INFO_MMAP_VALID),
146         .formats =              SNDRV_PCM_FMTBIT_S32_LE,
147         .rates =                SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 
148         .rate_min =             44100,
149         .rate_max =             192000,
150         .channels_min =         2,
151         .channels_max =         2,
152         .buffer_bytes_max =     (32*1024),
153         .period_bytes_min =     64,
154         .period_bytes_max =     (16*1024),
155         .periods_min =          2,
156         .periods_max =          2,
157         .fifo_size =            0,
158 };
159
160 static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime)
161 {
162         emu10k1_pcm_t *epcm = runtime->private_data;
163   
164         if (epcm) {
165                 //snd_printk("epcm free: %p\n", epcm);
166                 kfree(epcm);
167         }
168 }
169
170 /* open_playback callback */
171 static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
172 {
173         emu10k1_t *emu = snd_pcm_substream_chip(substream);
174         emu10k1_voice_t *channel = &(emu->p16v_voices[channel_id]);
175         emu10k1_pcm_t *epcm;
176         snd_pcm_runtime_t *runtime = substream->runtime;
177         int err;
178
179         epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
180         //snd_printk("epcm kcalloc: %p\n", epcm);
181
182         if (epcm == NULL)
183                 return -ENOMEM;
184         epcm->emu = emu;
185         epcm->substream = substream;
186         //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id);
187   
188         runtime->private_data = epcm;
189         runtime->private_free = snd_p16v_pcm_free_substream;
190   
191         runtime->hw = snd_p16v_playback_hw;
192
193         channel->emu = emu;
194         channel->number = channel_id;
195
196         channel->use=1;
197         //snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use);
198         //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
199         //channel->interrupt = snd_p16v_pcm_channel_interrupt;
200         channel->epcm=epcm;
201         if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
202                 return err;
203
204         return 0;
205 }
206 /* open_capture callback */
207 static int snd_p16v_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id)
208 {
209         emu10k1_t *emu = snd_pcm_substream_chip(substream);
210         emu10k1_voice_t *channel = &(emu->p16v_capture_voice);
211         emu10k1_pcm_t *epcm;
212         snd_pcm_runtime_t *runtime = substream->runtime;
213         int err;
214
215         epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
216         //snd_printk("epcm kcalloc: %p\n", epcm);
217
218         if (epcm == NULL)
219                 return -ENOMEM;
220         epcm->emu = emu;
221         epcm->substream = substream;
222         //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id);
223
224         runtime->private_data = epcm;
225         runtime->private_free = snd_p16v_pcm_free_substream;
226   
227         runtime->hw = snd_p16v_capture_hw;
228
229         channel->emu = emu;
230         channel->number = channel_id;
231
232         channel->use=1;
233         //snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use);
234         //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
235         //channel->interrupt = snd_p16v_pcm_channel_interrupt;
236         channel->epcm=epcm;
237         if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
238                 return err;
239
240         return 0;
241 }
242
243
244 /* close callback */
245 static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream)
246 {
247         emu10k1_t *emu = snd_pcm_substream_chip(substream);
248         //snd_pcm_runtime_t *runtime = substream->runtime;
249         //emu10k1_pcm_t *epcm = runtime->private_data;
250         emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0;
251         /* FIXME: maybe zero others */
252         return 0;
253 }
254
255 /* close callback */
256 static int snd_p16v_pcm_close_capture(snd_pcm_substream_t *substream)
257 {
258         emu10k1_t *emu = snd_pcm_substream_chip(substream);
259         //snd_pcm_runtime_t *runtime = substream->runtime;
260         //emu10k1_pcm_t *epcm = runtime->private_data;
261         emu->p16v_capture_voice.use=0;
262         /* FIXME: maybe zero others */
263         return 0;
264 }
265
266 static int snd_p16v_pcm_open_playback_front(snd_pcm_substream_t *substream)
267 {
268         return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
269 }
270
271 static int snd_p16v_pcm_open_capture(snd_pcm_substream_t *substream)
272 {
273         // Only using channel 0 for now, but the card has 2 channels.
274         return snd_p16v_pcm_open_capture_channel(substream, 0);
275 }
276
277 /* hw_params callback */
278 static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream,
279                                       snd_pcm_hw_params_t * hw_params)
280 {
281         int result;
282         result = snd_pcm_lib_malloc_pages(substream,
283                                         params_buffer_bytes(hw_params));
284         return result;
285 }
286
287 /* hw_params callback */
288 static int snd_p16v_pcm_hw_params_capture(snd_pcm_substream_t *substream,
289                                       snd_pcm_hw_params_t * hw_params)
290 {
291         int result;
292         result = snd_pcm_lib_malloc_pages(substream,
293                                         params_buffer_bytes(hw_params));
294         return result;
295 }
296
297
298 /* hw_free callback */
299 static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream)
300 {
301         int result;
302         result = snd_pcm_lib_free_pages(substream);
303         return result;
304 }
305
306 /* hw_free callback */
307 static int snd_p16v_pcm_hw_free_capture(snd_pcm_substream_t *substream)
308 {
309         int result;
310         result = snd_pcm_lib_free_pages(substream);
311         return result;
312 }
313
314
315 /* prepare playback callback */
316 static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream)
317 {
318         emu10k1_t *emu = snd_pcm_substream_chip(substream);
319         snd_pcm_runtime_t *runtime = substream->runtime;
320         int channel = substream->pcm->device - emu->p16v_device_offset;
321         u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
322         u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
323         int i;
324         u32 tmp;
325         
326         //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
327         //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
328         //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->p16v_buffer.addr, emu->p16v_buffer.area, emu->p16v_buffer.bytes);
329         tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
330         switch (runtime->rate) {
331         case 44100:
332           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
333           break;
334         case 96000:
335           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
336           break;
337         case 192000:
338           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
339           break;
340         case 48000:
341         default:
342           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
343           break;
344         }
345         /* FIXME: Check emu->buffer.size before actually writing to it. */
346         for(i=0; i < runtime->periods; i++) {
347                 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
348                 table_base[(i*2)+1]=period_size_bytes<<16;
349         }
350  
351         snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer.addr+(8*16*channel));
352         snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
353         snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
354         snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
355         //snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
356         snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
357         snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
358         snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
359         snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
360
361         return 0;
362 }
363
364 /* prepare capture callback */
365 static int snd_p16v_pcm_prepare_capture(snd_pcm_substream_t *substream)
366 {
367         emu10k1_t *emu = snd_pcm_substream_chip(substream);
368         snd_pcm_runtime_t *runtime = substream->runtime;
369         int channel = substream->pcm->device - emu->p16v_device_offset;
370         u32 tmp;
371         //printk("prepare capture:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size,  frames_to_bytes(runtime, 1));
372         tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
373         switch (runtime->rate) {
374         case 44100:
375           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800);
376           break;
377         case 96000:
378           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400);
379           break;
380         case 192000:
381           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200);
382           break;
383         case 48000:
384         default:
385           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000);
386           break;
387         }
388         /* FIXME: Check emu->buffer.size before actually writing to it. */
389         snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
390         snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
391         snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
392         snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0);
393         //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */
394         //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
395
396         return 0;
397 }
398
399 static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb)
400 {
401         unsigned long flags;
402         unsigned int enable;
403
404         spin_lock_irqsave(&emu->emu_lock, flags);
405         enable = inl(emu->port + INTE2) | intrenb;
406         outl(enable, emu->port + INTE2);
407         spin_unlock_irqrestore(&emu->emu_lock, flags);
408 }
409
410 static void snd_p16v_intr_disable(emu10k1_t *emu, unsigned int intrenb)
411 {
412         unsigned long flags;
413         unsigned int disable;
414
415         spin_lock_irqsave(&emu->emu_lock, flags);
416         disable = inl(emu->port + INTE2) & (~intrenb);
417         outl(disable, emu->port + INTE2);
418         spin_unlock_irqrestore(&emu->emu_lock, flags);
419 }
420
421 /* trigger_playback callback */
422 static int snd_p16v_pcm_trigger_playback(snd_pcm_substream_t *substream,
423                                     int cmd)
424 {
425         emu10k1_t *emu = snd_pcm_substream_chip(substream);
426         snd_pcm_runtime_t *runtime;
427         emu10k1_pcm_t *epcm;
428         int channel;
429         int result = 0;
430         struct list_head *pos;
431         snd_pcm_substream_t *s;
432         u32 basic = 0;
433         u32 inte = 0;
434         int running=0;
435
436         switch (cmd) {
437         case SNDRV_PCM_TRIGGER_START:
438                 running=1;
439                 break;
440         case SNDRV_PCM_TRIGGER_STOP:
441         default:
442                 running=0;
443                 break;
444         }
445         snd_pcm_group_for_each(pos, substream) {
446                 s = snd_pcm_group_substream_entry(pos);
447                 runtime = s->runtime;
448                 epcm = runtime->private_data;
449                 channel = substream->pcm->device-emu->p16v_device_offset;
450                 //snd_printk("p16v channel=%d\n",channel);
451                 epcm->running = running;
452                 basic |= (0x1<<channel);
453                 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
454                 snd_pcm_trigger_done(s, substream);
455         }
456         //snd_printk("basic=0x%x, inte=0x%x\n",basic, inte);
457
458         switch (cmd) {
459         case SNDRV_PCM_TRIGGER_START:
460                 snd_p16v_intr_enable(emu, inte);
461                 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic));
462                 break;
463         case SNDRV_PCM_TRIGGER_STOP:
464                 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
465                 snd_p16v_intr_disable(emu, inte);
466                 break;
467         default:
468                 result = -EINVAL;
469                 break;
470         }
471         return result;
472 }
473
474 /* trigger_capture callback */
475 static int snd_p16v_pcm_trigger_capture(snd_pcm_substream_t *substream,
476                                    int cmd)
477 {
478         emu10k1_t *emu = snd_pcm_substream_chip(substream);
479         snd_pcm_runtime_t *runtime = substream->runtime;
480         emu10k1_pcm_t *epcm = runtime->private_data;
481         int channel = 0;
482         int result = 0;
483         u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;
484
485         switch (cmd) {
486         case SNDRV_PCM_TRIGGER_START:
487                 snd_p16v_intr_enable(emu, inte);
488                 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
489                 epcm->running = 1;
490                 break;
491         case SNDRV_PCM_TRIGGER_STOP:
492                 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
493                 snd_p16v_intr_disable(emu, inte);
494                 //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
495                 epcm->running = 0;
496                 break;
497         default:
498                 result = -EINVAL;
499                 break;
500         }
501         return result;
502 }
503
504 /* pointer_playback callback */
505 static snd_pcm_uframes_t
506 snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream)
507 {
508         emu10k1_t *emu = snd_pcm_substream_chip(substream);
509         snd_pcm_runtime_t *runtime = substream->runtime;
510         emu10k1_pcm_t *epcm = runtime->private_data;
511         snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
512         int channel = substream->pcm->device - emu->p16v_device_offset;
513         if (!epcm->running)
514                 return 0;
515
516         ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
517         ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
518         ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
519         if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
520         ptr2 = bytes_to_frames(runtime, ptr1);
521         ptr2+= (ptr4 >> 3) * runtime->period_size;
522         ptr=ptr2;
523         if (ptr >= runtime->buffer_size)
524                 ptr -= runtime->buffer_size;
525
526         return ptr;
527 }
528
529 /* pointer_capture callback */
530 static snd_pcm_uframes_t
531 snd_p16v_pcm_pointer_capture(snd_pcm_substream_t *substream)
532 {
533         emu10k1_t *emu = snd_pcm_substream_chip(substream);
534         snd_pcm_runtime_t *runtime = substream->runtime;
535         emu10k1_pcm_t *epcm = runtime->private_data;
536         snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
537         int channel = 0;
538
539         if (!epcm->running)
540                 return 0;
541
542         ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel);
543         ptr2 = bytes_to_frames(runtime, ptr1);
544         ptr=ptr2;
545         if (ptr >= runtime->buffer_size) {
546                 ptr -= runtime->buffer_size;
547                 printk("buffer capture limited!\n");
548         }
549         //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
550
551         return ptr;
552 }
553
554 /* operators */
555 static snd_pcm_ops_t snd_p16v_playback_front_ops = {
556         .open =        snd_p16v_pcm_open_playback_front,
557         .close =       snd_p16v_pcm_close_playback,
558         .ioctl =       snd_pcm_lib_ioctl,
559         .hw_params =   snd_p16v_pcm_hw_params_playback,
560         .hw_free =     snd_p16v_pcm_hw_free_playback,
561         .prepare =     snd_p16v_pcm_prepare_playback,
562         .trigger =     snd_p16v_pcm_trigger_playback,
563         .pointer =     snd_p16v_pcm_pointer_playback,
564 };
565
566 static snd_pcm_ops_t snd_p16v_capture_ops = {
567         .open =        snd_p16v_pcm_open_capture,
568         .close =       snd_p16v_pcm_close_capture,
569         .ioctl =       snd_pcm_lib_ioctl,
570         .hw_params =   snd_p16v_pcm_hw_params_capture,
571         .hw_free =     snd_p16v_pcm_hw_free_capture,
572         .prepare =     snd_p16v_pcm_prepare_capture,
573         .trigger =     snd_p16v_pcm_trigger_capture,
574         .pointer =     snd_p16v_pcm_pointer_capture,
575 };
576
577
578 int snd_p16v_free(emu10k1_t *chip)
579 {
580         // release the data
581         if (chip->p16v_buffer.area) {
582                 snd_dma_free_pages(&chip->p16v_buffer);
583                 //snd_printk("period lables free: %p\n", &chip->p16v_buffer);
584         }
585         return 0;
586 }
587
588 static void snd_p16v_pcm_free(snd_pcm_t *pcm)
589 {
590         emu10k1_t *emu = pcm->private_data;
591         //snd_printk("snd_p16v_pcm_free pcm: called\n");
592         snd_pcm_lib_preallocate_free_for_all(pcm);
593         emu->pcm = NULL;
594 }
595
596 int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm)
597 {
598         snd_pcm_t *pcm;
599         snd_pcm_substream_t *substream;
600         int err;
601         int capture=1;
602   
603         //snd_printk("snd_p16v_pcm called. device=%d\n", device);
604         emu->p16v_device_offset = device;
605         if (rpcm)
606                 *rpcm = NULL;
607
608         if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
609                 return err;
610   
611         pcm->private_data = emu;
612         pcm->private_free = snd_p16v_pcm_free;
613         // Single playback 8 channel device.
614         // Single capture 2 channel device.
615         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
616         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops);
617
618         pcm->info_flags = 0;
619         pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
620         strcpy(pcm->name, "p16v");
621         emu->pcm = pcm;
622
623         for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 
624             substream; 
625             substream = substream->next) {
626                 if ((err = snd_pcm_lib_preallocate_pages(substream, 
627                                                          SNDRV_DMA_TYPE_DEV, 
628                                                          snd_dma_pci_data(emu->pci), 
629                                                          ((65536 - 64) * 8), ((65536 - 64) * 8))) < 0) 
630                         return err;
631                 //snd_printk("preallocate playback substream: err=%d\n", err);
632         }
633
634         for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 
635               substream; 
636               substream = substream->next) {
637                 if ((err = snd_pcm_lib_preallocate_pages(substream, 
638                                                    SNDRV_DMA_TYPE_DEV, 
639                                                    snd_dma_pci_data(emu->pci), 
640                                                    64*1024, 64*1024)) < 0)
641                         return err;
642                 //snd_printk("preallocate capture substream: err=%d\n", err);
643         }
644   
645         if (rpcm)
646                 *rpcm = pcm;
647   
648         return 0;
649 }
650
651 static int snd_p16v_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
652 {
653         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
654         uinfo->count = 2;
655         uinfo->value.integer.min = 0;
656         uinfo->value.integer.max = 255;
657         return 0;
658 }
659
660 static int snd_p16v_volume_get(snd_kcontrol_t * kcontrol,
661                                        snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
662 {
663         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
664         u32 value;
665
666         value = snd_emu10k1_ptr20_read(emu, reg, high_low);
667         if (high_low == 1) {
668                 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
669                 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
670         } else {
671                 ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
672                 ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
673         }
674         return 0;
675 }
676
677 static int snd_p16v_volume_get_spdif_front(snd_kcontrol_t * kcontrol,
678                                        snd_ctl_elem_value_t * ucontrol)
679 {
680         int high_low = 0;
681         int reg = PLAYBACK_VOLUME_MIXER7;
682         return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
683 }
684
685 static int snd_p16v_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol,
686                                        snd_ctl_elem_value_t * ucontrol)
687 {
688         int high_low = 1;
689         int reg = PLAYBACK_VOLUME_MIXER7;
690         return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
691 }
692 static int snd_p16v_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol,
693                                        snd_ctl_elem_value_t * ucontrol)
694 {
695         int high_low = 0;
696         int reg = PLAYBACK_VOLUME_MIXER8;
697         return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
698 }
699 static int snd_p16v_volume_get_spdif_rear(snd_kcontrol_t * kcontrol,
700                                        snd_ctl_elem_value_t * ucontrol)
701 {
702         int high_low = 1;
703         int reg = PLAYBACK_VOLUME_MIXER8;
704         return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
705 }
706
707 static int snd_p16v_volume_get_analog_front(snd_kcontrol_t * kcontrol,
708                                        snd_ctl_elem_value_t * ucontrol)
709 {
710         int high_low = 0;
711         int reg = PLAYBACK_VOLUME_MIXER9;
712         return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
713 }
714
715 static int snd_p16v_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
716                                        snd_ctl_elem_value_t * ucontrol)
717 {
718         int high_low = 1;
719         int reg = PLAYBACK_VOLUME_MIXER9;
720         return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
721 }
722 static int snd_p16v_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
723                                        snd_ctl_elem_value_t * ucontrol)
724 {
725         int high_low = 1;
726         int reg = PLAYBACK_VOLUME_MIXER10;
727         return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
728 }
729
730 static int snd_p16v_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
731                                        snd_ctl_elem_value_t * ucontrol)
732 {
733         int high_low = 0;
734         int reg = PLAYBACK_VOLUME_MIXER10;
735         return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
736 }
737
738 static int snd_p16v_volume_put(snd_kcontrol_t * kcontrol,
739                                        snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
740 {
741         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
742         u32 value;
743         value = snd_emu10k1_ptr20_read(emu, reg, 0);
744         //value = value & 0xffff;
745         if (high_low == 1) {
746                 value &= 0xffff;
747                 value = value | ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
748         } else {
749                 value &= 0xffff0000;
750                 value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
751         }
752                 snd_emu10k1_ptr20_write(emu, reg, 0, value);
753         return 1;
754 }
755
756 static int snd_p16v_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
757                                        snd_ctl_elem_value_t * ucontrol)
758 {
759         int high_low = 0;
760         int reg = PLAYBACK_VOLUME_MIXER7;
761         return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
762 }
763
764 static int snd_p16v_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
765                                        snd_ctl_elem_value_t * ucontrol)
766 {
767         int high_low = 1;
768         int reg = PLAYBACK_VOLUME_MIXER7;
769         return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
770 }
771
772 static int snd_p16v_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
773                                        snd_ctl_elem_value_t * ucontrol)
774 {
775         int high_low = 0;
776         int reg = PLAYBACK_VOLUME_MIXER8;
777         return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
778 }
779
780 static int snd_p16v_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
781                                        snd_ctl_elem_value_t * ucontrol)
782 {
783         int high_low = 1;
784         int reg = PLAYBACK_VOLUME_MIXER8;
785         return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
786 }
787
788 static int snd_p16v_volume_put_analog_front(snd_kcontrol_t * kcontrol,
789                                        snd_ctl_elem_value_t * ucontrol)
790 {
791         int high_low = 0;
792         int reg = PLAYBACK_VOLUME_MIXER9;
793         return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
794 }
795
796 static int snd_p16v_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
797                                        snd_ctl_elem_value_t * ucontrol)
798 {
799         int high_low = 1;
800         int reg = PLAYBACK_VOLUME_MIXER9;
801         return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
802 }
803
804 static int snd_p16v_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
805                                        snd_ctl_elem_value_t * ucontrol)
806 {
807         int high_low = 1;
808         int reg = PLAYBACK_VOLUME_MIXER10;
809         return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
810 }
811
812 static int snd_p16v_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
813                                        snd_ctl_elem_value_t * ucontrol)
814 {
815         int high_low = 0;
816         int reg = PLAYBACK_VOLUME_MIXER10;
817         return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
818 }
819
820 static snd_kcontrol_new_t snd_p16v_volume_control_analog_front =
821 {
822         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
823         .name =         "HD Analog Front Volume",
824         .info =         snd_p16v_volume_info,
825         .get =          snd_p16v_volume_get_analog_front,
826         .put =          snd_p16v_volume_put_analog_front
827 };
828
829 static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe =
830 {
831         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
832         .name =         "HD Analog Center/LFE Volume",
833         .info =         snd_p16v_volume_info,
834         .get =          snd_p16v_volume_get_analog_center_lfe,
835         .put =          snd_p16v_volume_put_analog_center_lfe
836 };
837
838 static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown =
839 {
840         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
841         .name =         "HD Analog Unknown Volume",
842         .info =         snd_p16v_volume_info,
843         .get =          snd_p16v_volume_get_analog_unknown,
844         .put =          snd_p16v_volume_put_analog_unknown
845 };
846
847 static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear =
848 {
849         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
850         .name =         "HD Analog Rear Volume",
851         .info =         snd_p16v_volume_info,
852         .get =          snd_p16v_volume_get_analog_rear,
853         .put =          snd_p16v_volume_put_analog_rear
854 };
855
856 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front =
857 {
858         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
859         .name =         "HD SPDIF Front Volume",
860         .info =         snd_p16v_volume_info,
861         .get =          snd_p16v_volume_get_spdif_front,
862         .put =          snd_p16v_volume_put_spdif_front
863 };
864
865 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe =
866 {
867         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
868         .name =         "HD SPDIF Center/LFE Volume",
869         .info =         snd_p16v_volume_info,
870         .get =          snd_p16v_volume_get_spdif_center_lfe,
871         .put =          snd_p16v_volume_put_spdif_center_lfe
872 };
873
874 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown =
875 {
876         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
877         .name =         "HD SPDIF Unknown Volume",
878         .info =         snd_p16v_volume_info,
879         .get =          snd_p16v_volume_get_spdif_unknown,
880         .put =          snd_p16v_volume_put_spdif_unknown
881 };
882
883 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear =
884 {
885         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
886         .name =         "HD SPDIF Rear Volume",
887         .info =         snd_p16v_volume_info,
888         .get =          snd_p16v_volume_get_spdif_rear,
889         .put =          snd_p16v_volume_put_spdif_rear
890 };
891
892 static int snd_p16v_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
893 {
894         static char *texts[8] = { "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", "CDIF", "FX", "AC97" };
895
896         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
897         uinfo->count = 1;
898         uinfo->value.enumerated.items = 8;
899         if (uinfo->value.enumerated.item > 7)
900                 uinfo->value.enumerated.item = 7;
901         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
902         return 0;
903 }
904
905 static int snd_p16v_capture_source_get(snd_kcontrol_t * kcontrol,
906                                         snd_ctl_elem_value_t * ucontrol)
907 {
908         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
909
910         ucontrol->value.enumerated.item[0] = emu->p16v_capture_source;
911         return 0;
912 }
913
914 static int snd_p16v_capture_source_put(snd_kcontrol_t * kcontrol,
915                                         snd_ctl_elem_value_t * ucontrol)
916 {
917         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
918         unsigned int val;
919         int change = 0;
920         u32 mask;
921         u32 source;
922
923         val = ucontrol->value.enumerated.item[0] ;
924         change = (emu->p16v_capture_source != val);
925         if (change) {
926                 emu->p16v_capture_source = val;
927                 source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
928                 mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff;
929                 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask);
930         }
931         return change;
932 }
933
934 static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata =
935 {
936         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
937         .name =         "HD Capture source",
938         .info =         snd_p16v_capture_source_info,
939         .get =          snd_p16v_capture_source_get,
940         .put =          snd_p16v_capture_source_put
941 };
942
943 static int snd_p16v_capture_channel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
944 {
945         static char *texts[4] = { "0", "1", "2", "3",  };
946
947         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
948         uinfo->count = 1;
949         uinfo->value.enumerated.items = 4;
950         if (uinfo->value.enumerated.item > 3)
951                 uinfo->value.enumerated.item = 3;
952         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
953         return 0;
954 }
955
956 static int snd_p16v_capture_channel_get(snd_kcontrol_t * kcontrol,
957                                         snd_ctl_elem_value_t * ucontrol)
958 {
959         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
960
961         ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel;
962         return 0;
963 }
964
965 static int snd_p16v_capture_channel_put(snd_kcontrol_t * kcontrol,
966                                         snd_ctl_elem_value_t * ucontrol)
967 {
968         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
969         unsigned int val;
970         int change = 0;
971         u32 tmp;
972
973         val = ucontrol->value.enumerated.item[0] ;
974         change = (emu->p16v_capture_channel != val);
975         if (change) {
976                 emu->p16v_capture_channel = val;
977                 tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc;
978                 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val);
979         }
980         return change;
981 }
982
983 static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata =
984 {
985         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
986         .name =         "HD Capture channel",
987         .info =         snd_p16v_capture_channel_info,
988         .get =          snd_p16v_capture_channel_get,
989         .put =          snd_p16v_capture_channel_put
990 };
991
992 int snd_p16v_mixer(emu10k1_t *emu)
993 {
994         int err;
995         snd_kcontrol_t *kctl;
996         snd_card_t *card = emu->card;
997         if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_front, emu)) == NULL)
998                 return -ENOMEM;
999         if ((err = snd_ctl_add(card, kctl)))
1000                 return err;
1001         if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_rear, emu)) == NULL)
1002                 return -ENOMEM;
1003         if ((err = snd_ctl_add(card, kctl)))
1004                 return err;
1005         if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_center_lfe, emu)) == NULL)
1006                 return -ENOMEM;
1007         if ((err = snd_ctl_add(card, kctl)))
1008                 return err;
1009         if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_unknown, emu)) == NULL)
1010                 return -ENOMEM;
1011         if ((err = snd_ctl_add(card, kctl)))
1012                 return err;
1013         if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_front, emu)) == NULL)
1014                 return -ENOMEM;
1015         if ((err = snd_ctl_add(card, kctl)))
1016                 return err;
1017         if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_rear, emu)) == NULL)
1018                 return -ENOMEM;
1019         if ((err = snd_ctl_add(card, kctl)))
1020                 return err;
1021         if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_center_lfe, emu)) == NULL)
1022                 return -ENOMEM;
1023         if ((err = snd_ctl_add(card, kctl)))
1024                 return err;
1025         if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_unknown, emu)) == NULL)
1026                 return -ENOMEM;
1027         if ((err = snd_ctl_add(card, kctl)))
1028                 return err;
1029         if ((kctl = snd_ctl_new1(&snd_p16v_capture_source, emu)) == NULL)
1030                 return -ENOMEM;
1031         if ((err = snd_ctl_add(card, kctl)))
1032                 return err;
1033         if ((kctl = snd_ctl_new1(&snd_p16v_capture_channel, emu)) == NULL)
1034                 return -ENOMEM;
1035         if ((err = snd_ctl_add(card, kctl)))
1036                 return err;
1037         return 0;
1038 }
1039