]> err.no Git - linux-2.6/blob - sound/pci/oxygen/oxygen_pcm.c
[ALSA] oxygen: fix SPDIF input rates
[linux-2.6] / sound / pci / oxygen / oxygen_pcm.c
1 /*
2  * C-Media CMI8788 driver - PCM code
3  *
4  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5  *
6  *
7  *  This driver is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License, version 2.
9  *
10  *  This driver is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this driver; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18  */
19
20 #include <linux/pci.h>
21 #include <sound/control.h>
22 #include <sound/core.h>
23 #include <sound/pcm.h>
24 #include <sound/pcm_params.h>
25 #include "oxygen.h"
26
27 static const struct snd_pcm_hardware oxygen_stereo_hardware = {
28         .info = SNDRV_PCM_INFO_MMAP |
29                 SNDRV_PCM_INFO_MMAP_VALID |
30                 SNDRV_PCM_INFO_INTERLEAVED |
31                 SNDRV_PCM_INFO_PAUSE |
32                 SNDRV_PCM_INFO_SYNC_START,
33         .formats = SNDRV_PCM_FMTBIT_S16_LE |
34                    SNDRV_PCM_FMTBIT_S32_LE,
35         .rates = SNDRV_PCM_RATE_32000 |
36                  SNDRV_PCM_RATE_44100 |
37                  SNDRV_PCM_RATE_48000 |
38                  SNDRV_PCM_RATE_64000 |
39                  SNDRV_PCM_RATE_88200 |
40                  SNDRV_PCM_RATE_96000 |
41                  SNDRV_PCM_RATE_176400 |
42                  SNDRV_PCM_RATE_192000,
43         .rate_min = 32000,
44         .rate_max = 192000,
45         .channels_min = 2,
46         .channels_max = 2,
47         .buffer_bytes_max = 256 * 1024,
48         .period_bytes_min = 128,
49         .period_bytes_max = 128 * 1024,
50         .periods_min = 2,
51         .periods_max = 2048,
52 };
53 static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
54         .info = SNDRV_PCM_INFO_MMAP |
55                 SNDRV_PCM_INFO_MMAP_VALID |
56                 SNDRV_PCM_INFO_INTERLEAVED |
57                 SNDRV_PCM_INFO_PAUSE |
58                 SNDRV_PCM_INFO_SYNC_START,
59         .formats = SNDRV_PCM_FMTBIT_S16_LE |
60                    SNDRV_PCM_FMTBIT_S32_LE,
61         .rates = SNDRV_PCM_RATE_32000 |
62                  SNDRV_PCM_RATE_44100 |
63                  SNDRV_PCM_RATE_48000 |
64                  SNDRV_PCM_RATE_64000 |
65                  SNDRV_PCM_RATE_88200 |
66                  SNDRV_PCM_RATE_96000 |
67                  SNDRV_PCM_RATE_176400 |
68                  SNDRV_PCM_RATE_192000,
69         .rate_min = 32000,
70         .rate_max = 192000,
71         .channels_min = 2,
72         .channels_max = 8,
73         .buffer_bytes_max = 2048 * 1024,
74         .period_bytes_min = 128,
75         .period_bytes_max = 256 * 1024,
76         .periods_min = 2,
77         .periods_max = 16384,
78 };
79 static const struct snd_pcm_hardware oxygen_ac97_hardware = {
80         .info = SNDRV_PCM_INFO_MMAP |
81                 SNDRV_PCM_INFO_MMAP_VALID |
82                 SNDRV_PCM_INFO_INTERLEAVED |
83                 SNDRV_PCM_INFO_PAUSE |
84                 SNDRV_PCM_INFO_SYNC_START,
85         .formats = SNDRV_PCM_FMTBIT_S16_LE,
86         .rates = SNDRV_PCM_RATE_48000,
87         .rate_min = 48000,
88         .rate_max = 48000,
89         .channels_min = 2,
90         .channels_max = 2,
91         .buffer_bytes_max = 256 * 1024,
92         .period_bytes_min = 128,
93         .period_bytes_max = 128 * 1024,
94         .periods_min = 2,
95         .periods_max = 2048,
96 };
97
98 static const struct snd_pcm_hardware *const oxygen_hardware[PCM_COUNT] = {
99         [PCM_A] = &oxygen_stereo_hardware,
100         [PCM_B] = &oxygen_stereo_hardware,
101         [PCM_C] = &oxygen_stereo_hardware,
102         [PCM_SPDIF] = &oxygen_stereo_hardware,
103         [PCM_MULTICH] = &oxygen_multichannel_hardware,
104         [PCM_AC97] = &oxygen_ac97_hardware,
105 };
106
107 static inline unsigned int
108 oxygen_substream_channel(struct snd_pcm_substream *substream)
109 {
110         return (unsigned int)(uintptr_t)substream->runtime->private_data;
111 }
112
113 static int oxygen_open(struct snd_pcm_substream *substream,
114                        unsigned int channel)
115 {
116         struct oxygen *chip = snd_pcm_substream_chip(substream);
117         struct snd_pcm_runtime *runtime = substream->runtime;
118         int err;
119
120         runtime->private_data = (void *)(uintptr_t)channel;
121         runtime->hw = *oxygen_hardware[channel];
122         if (channel == PCM_C) {
123                 runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 |
124                                        SNDRV_PCM_RATE_64000);
125                 runtime->hw.rate_min = 44100;
126         }
127         if (chip->model->pcm_hardware_filter)
128                 chip->model->pcm_hardware_filter(channel, &runtime->hw);
129         err = snd_pcm_hw_constraint_step(runtime, 0,
130                                          SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
131         if (err < 0)
132                 return err;
133         err = snd_pcm_hw_constraint_step(runtime, 0,
134                                          SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
135         if (err < 0)
136                 return err;
137         if (runtime->hw.formats & SNDRV_PCM_FMTBIT_S32_LE) {
138                 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
139                 if (err < 0)
140                         return err;
141         }
142         if (runtime->hw.channels_max > 2) {
143                 err = snd_pcm_hw_constraint_step(runtime, 0,
144                                                  SNDRV_PCM_HW_PARAM_CHANNELS,
145                                                  2);
146                 if (err < 0)
147                         return err;
148         }
149         snd_pcm_set_sync(substream);
150         chip->streams[channel] = substream;
151
152         mutex_lock(&chip->mutex);
153         chip->pcm_active |= 1 << channel;
154         if (channel == PCM_SPDIF) {
155                 chip->spdif_pcm_bits = chip->spdif_bits;
156                 chip->controls[CONTROL_SPDIF_PCM]->vd[0].access &=
157                         ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
158                 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
159                                SNDRV_CTL_EVENT_MASK_INFO,
160                                &chip->controls[CONTROL_SPDIF_PCM]->id);
161         }
162         mutex_unlock(&chip->mutex);
163
164         return 0;
165 }
166
167 static int oxygen_rec_a_open(struct snd_pcm_substream *substream)
168 {
169         return oxygen_open(substream, PCM_A);
170 }
171
172 static int oxygen_rec_b_open(struct snd_pcm_substream *substream)
173 {
174         return oxygen_open(substream, PCM_B);
175 }
176
177 static int oxygen_rec_c_open(struct snd_pcm_substream *substream)
178 {
179         return oxygen_open(substream, PCM_C);
180 }
181
182 static int oxygen_spdif_open(struct snd_pcm_substream *substream)
183 {
184         return oxygen_open(substream, PCM_SPDIF);
185 }
186
187 static int oxygen_multich_open(struct snd_pcm_substream *substream)
188 {
189         return oxygen_open(substream, PCM_MULTICH);
190 }
191
192 static int oxygen_ac97_open(struct snd_pcm_substream *substream)
193 {
194         return oxygen_open(substream, PCM_AC97);
195 }
196
197 static int oxygen_close(struct snd_pcm_substream *substream)
198 {
199         struct oxygen *chip = snd_pcm_substream_chip(substream);
200         unsigned int channel = oxygen_substream_channel(substream);
201
202         mutex_lock(&chip->mutex);
203         chip->pcm_active &= ~(1 << channel);
204         if (channel == PCM_SPDIF) {
205                 chip->controls[CONTROL_SPDIF_PCM]->vd[0].access |=
206                         SNDRV_CTL_ELEM_ACCESS_INACTIVE;
207                 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
208                                SNDRV_CTL_EVENT_MASK_INFO,
209                                &chip->controls[CONTROL_SPDIF_PCM]->id);
210         }
211         if (channel == PCM_SPDIF || channel == PCM_MULTICH)
212                 oxygen_update_spdif_source(chip);
213         mutex_unlock(&chip->mutex);
214
215         chip->streams[channel] = NULL;
216         return 0;
217 }
218
219 static unsigned int oxygen_format(struct snd_pcm_hw_params *hw_params)
220 {
221         if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
222                 return OXYGEN_FORMAT_24;
223         else
224                 return OXYGEN_FORMAT_16;
225 }
226
227 static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
228 {
229         switch (params_rate(hw_params)) {
230         case 32000:
231                 return OXYGEN_RATE_32000;
232         case 44100:
233                 return OXYGEN_RATE_44100;
234         default: /* 48000 */
235                 return OXYGEN_RATE_48000;
236         case 64000:
237                 return OXYGEN_RATE_64000;
238         case 88200:
239                 return OXYGEN_RATE_88200;
240         case 96000:
241                 return OXYGEN_RATE_96000;
242         case 176400:
243                 return OXYGEN_RATE_176400;
244         case 192000:
245                 return OXYGEN_RATE_192000;
246         }
247 }
248
249 static unsigned int oxygen_i2s_mclk(struct snd_pcm_hw_params *hw_params)
250 {
251         return params_rate(hw_params) <= 96000
252                 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_128;
253 }
254
255 static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
256 {
257         if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
258                 return OXYGEN_I2S_BITS_24;
259         else
260                 return OXYGEN_I2S_BITS_16;
261 }
262
263 static unsigned int oxygen_play_channels(struct snd_pcm_hw_params *hw_params)
264 {
265         switch (params_channels(hw_params)) {
266         default: /* 2 */
267                 return OXYGEN_PLAY_CHANNELS_2;
268         case 4:
269                 return OXYGEN_PLAY_CHANNELS_4;
270         case 6:
271                 return OXYGEN_PLAY_CHANNELS_6;
272         case 8:
273                 return OXYGEN_PLAY_CHANNELS_8;
274         }
275 }
276
277 static const unsigned int channel_base_registers[PCM_COUNT] = {
278         [PCM_A] = OXYGEN_DMA_A_ADDRESS,
279         [PCM_B] = OXYGEN_DMA_B_ADDRESS,
280         [PCM_C] = OXYGEN_DMA_C_ADDRESS,
281         [PCM_SPDIF] = OXYGEN_DMA_SPDIF_ADDRESS,
282         [PCM_MULTICH] = OXYGEN_DMA_MULTICH_ADDRESS,
283         [PCM_AC97] = OXYGEN_DMA_AC97_ADDRESS,
284 };
285
286 static int oxygen_hw_params(struct snd_pcm_substream *substream,
287                             struct snd_pcm_hw_params *hw_params)
288 {
289         struct oxygen *chip = snd_pcm_substream_chip(substream);
290         unsigned int channel = oxygen_substream_channel(substream);
291         int err;
292
293         err = snd_pcm_lib_malloc_pages(substream,
294                                        params_buffer_bytes(hw_params));
295         if (err < 0)
296                 return err;
297
298         oxygen_write32(chip, channel_base_registers[channel],
299                        (u32)substream->runtime->dma_addr);
300         if (channel == PCM_MULTICH) {
301                 oxygen_write32(chip, OXYGEN_DMA_MULTICH_COUNT,
302                                params_buffer_bytes(hw_params) / 4 - 1);
303                 oxygen_write32(chip, OXYGEN_DMA_MULTICH_TCOUNT,
304                                params_period_bytes(hw_params) / 4 - 1);
305         } else {
306                 oxygen_write16(chip, channel_base_registers[channel] + 4,
307                                params_buffer_bytes(hw_params) / 4 - 1);
308                 oxygen_write16(chip, channel_base_registers[channel] + 6,
309                                params_period_bytes(hw_params) / 4 - 1);
310         }
311         return 0;
312 }
313
314 static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
315                                   struct snd_pcm_hw_params *hw_params)
316 {
317         struct oxygen *chip = snd_pcm_substream_chip(substream);
318         int err;
319
320         err = oxygen_hw_params(substream, hw_params);
321         if (err < 0)
322                 return err;
323
324         spin_lock_irq(&chip->reg_lock);
325         oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
326                              oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT,
327                              OXYGEN_REC_FORMAT_A_MASK);
328         oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
329                               oxygen_rate(hw_params) |
330                               oxygen_i2s_mclk(hw_params) |
331                               chip->model->adc_i2s_format |
332                               oxygen_i2s_bits(hw_params),
333                               OXYGEN_I2S_RATE_MASK |
334                               OXYGEN_I2S_FORMAT_MASK |
335                               OXYGEN_I2S_MCLK_MASK |
336                               OXYGEN_I2S_BITS_MASK);
337         oxygen_write8_masked(chip, OXYGEN_REC_ROUTING,
338                              OXYGEN_REC_A_ROUTE_I2S_ADC_1,
339                              OXYGEN_REC_A_ROUTE_MASK);
340         spin_unlock_irq(&chip->reg_lock);
341
342         mutex_lock(&chip->mutex);
343         chip->model->set_adc_params(chip, hw_params);
344         mutex_unlock(&chip->mutex);
345         return 0;
346 }
347
348 static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
349                                   struct snd_pcm_hw_params *hw_params)
350 {
351         struct oxygen *chip = snd_pcm_substream_chip(substream);
352         int err;
353
354         err = oxygen_hw_params(substream, hw_params);
355         if (err < 0)
356                 return err;
357
358         spin_lock_irq(&chip->reg_lock);
359         oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
360                              oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT,
361                              OXYGEN_REC_FORMAT_B_MASK);
362         oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
363                               oxygen_rate(hw_params) |
364                               oxygen_i2s_mclk(hw_params) |
365                               chip->model->adc_i2s_format |
366                               oxygen_i2s_bits(hw_params),
367                               OXYGEN_I2S_RATE_MASK |
368                               OXYGEN_I2S_FORMAT_MASK |
369                               OXYGEN_I2S_MCLK_MASK |
370                               OXYGEN_I2S_BITS_MASK);
371         oxygen_write8_masked(chip, OXYGEN_REC_ROUTING,
372                              OXYGEN_REC_B_ROUTE_I2S_ADC_2,
373                              OXYGEN_REC_B_ROUTE_MASK);
374         spin_unlock_irq(&chip->reg_lock);
375
376         mutex_lock(&chip->mutex);
377         chip->model->set_adc_params(chip, hw_params);
378         mutex_unlock(&chip->mutex);
379         return 0;
380 }
381
382 static int oxygen_rec_c_hw_params(struct snd_pcm_substream *substream,
383                                   struct snd_pcm_hw_params *hw_params)
384 {
385         struct oxygen *chip = snd_pcm_substream_chip(substream);
386         int err;
387
388         err = oxygen_hw_params(substream, hw_params);
389         if (err < 0)
390                 return err;
391
392         spin_lock_irq(&chip->reg_lock);
393         oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
394                              oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT,
395                              OXYGEN_REC_FORMAT_C_MASK);
396         oxygen_write8_masked(chip, OXYGEN_REC_ROUTING,
397                              OXYGEN_REC_C_ROUTE_SPDIF,
398                              OXYGEN_REC_C_ROUTE_MASK);
399         spin_unlock_irq(&chip->reg_lock);
400         return 0;
401 }
402
403 static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
404                                   struct snd_pcm_hw_params *hw_params)
405 {
406         struct oxygen *chip = snd_pcm_substream_chip(substream);
407         int err;
408
409         err = oxygen_hw_params(substream, hw_params);
410         if (err < 0)
411                 return err;
412
413         spin_lock_irq(&chip->reg_lock);
414         oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
415                             OXYGEN_SPDIF_OUT_ENABLE);
416         oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
417                              oxygen_format(hw_params) << OXYGEN_SPDIF_FORMAT_SHIFT,
418                              OXYGEN_SPDIF_FORMAT_MASK);
419         oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL,
420                               oxygen_rate(hw_params) << OXYGEN_SPDIF_OUT_RATE_SHIFT,
421                               OXYGEN_SPDIF_OUT_RATE_MASK);
422         oxygen_update_spdif_source(chip);
423         spin_unlock_irq(&chip->reg_lock);
424         return 0;
425 }
426
427 static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
428                                     struct snd_pcm_hw_params *hw_params)
429 {
430         struct oxygen *chip = snd_pcm_substream_chip(substream);
431         int err;
432
433         err = oxygen_hw_params(substream, hw_params);
434         if (err < 0)
435                 return err;
436
437         spin_lock_irq(&chip->reg_lock);
438         oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS,
439                              oxygen_play_channels(hw_params),
440                              OXYGEN_PLAY_CHANNELS_MASK);
441         oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
442                              oxygen_format(hw_params) << OXYGEN_MULTICH_FORMAT_SHIFT,
443                              OXYGEN_MULTICH_FORMAT_MASK);
444         oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
445                               oxygen_rate(hw_params) |
446                               chip->model->dac_i2s_format |
447                               oxygen_i2s_bits(hw_params),
448                               OXYGEN_I2S_RATE_MASK |
449                               OXYGEN_I2S_FORMAT_MASK |
450                               OXYGEN_I2S_BITS_MASK);
451         oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING,
452                               OXYGEN_PLAY_MULTICH_I2S_DAC,
453                               OXYGEN_PLAY_MUTE01 | OXYGEN_PLAY_MUTE23 |
454                               OXYGEN_PLAY_MUTE45 | OXYGEN_PLAY_MUTE67 |
455                               OXYGEN_PLAY_MULTICH_MASK);
456         oxygen_update_dac_routing(chip);
457         oxygen_update_spdif_source(chip);
458         spin_unlock_irq(&chip->reg_lock);
459
460         mutex_lock(&chip->mutex);
461         chip->model->set_dac_params(chip, hw_params);
462         mutex_unlock(&chip->mutex);
463         return 0;
464 }
465
466 static int oxygen_hw_free(struct snd_pcm_substream *substream)
467 {
468         struct oxygen *chip = snd_pcm_substream_chip(substream);
469         unsigned int channel = oxygen_substream_channel(substream);
470
471         spin_lock_irq(&chip->reg_lock);
472         chip->interrupt_mask &= ~(1 << channel);
473         oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
474         spin_unlock_irq(&chip->reg_lock);
475
476         return snd_pcm_lib_free_pages(substream);
477 }
478
479 static int oxygen_spdif_hw_free(struct snd_pcm_substream *substream)
480 {
481         struct oxygen *chip = snd_pcm_substream_chip(substream);
482
483         spin_lock_irq(&chip->reg_lock);
484         oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
485                             OXYGEN_SPDIF_OUT_ENABLE);
486         spin_unlock_irq(&chip->reg_lock);
487         return oxygen_hw_free(substream);
488 }
489
490 static int oxygen_prepare(struct snd_pcm_substream *substream)
491 {
492         struct oxygen *chip = snd_pcm_substream_chip(substream);
493         unsigned int channel = oxygen_substream_channel(substream);
494         unsigned int channel_mask = 1 << channel;
495
496         spin_lock_irq(&chip->reg_lock);
497         oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
498         oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
499
500         chip->interrupt_mask |= channel_mask;
501         oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
502         spin_unlock_irq(&chip->reg_lock);
503         return 0;
504 }
505
506 static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd)
507 {
508         struct oxygen *chip = snd_pcm_substream_chip(substream);
509         struct snd_pcm_substream *s;
510         unsigned int mask = 0;
511         int pausing;
512
513         switch (cmd) {
514         case SNDRV_PCM_TRIGGER_STOP:
515         case SNDRV_PCM_TRIGGER_START:
516                 pausing = 0;
517                 break;
518         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
519         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
520                 pausing = 1;
521                 break;
522         default:
523                 return -EINVAL;
524         }
525
526         snd_pcm_group_for_each_entry(s, substream) {
527                 if (snd_pcm_substream_chip(s) == chip) {
528                         mask |= 1 << oxygen_substream_channel(s);
529                         snd_pcm_trigger_done(s, substream);
530                 }
531         }
532
533         spin_lock(&chip->reg_lock);
534         if (!pausing) {
535                 if (cmd == SNDRV_PCM_TRIGGER_START)
536                         chip->pcm_running |= mask;
537                 else
538                         chip->pcm_running &= ~mask;
539                 oxygen_write8(chip, OXYGEN_DMA_STATUS, chip->pcm_running);
540         } else {
541                 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
542                         oxygen_set_bits8(chip, OXYGEN_DMA_PAUSE, mask);
543                 else
544                         oxygen_clear_bits8(chip, OXYGEN_DMA_PAUSE, mask);
545         }
546         spin_unlock(&chip->reg_lock);
547         return 0;
548 }
549
550 static snd_pcm_uframes_t oxygen_pointer(struct snd_pcm_substream *substream)
551 {
552         struct oxygen *chip = snd_pcm_substream_chip(substream);
553         struct snd_pcm_runtime *runtime = substream->runtime;
554         unsigned int channel = oxygen_substream_channel(substream);
555         u32 curr_addr;
556
557         /* no spinlock, this read should be atomic */
558         curr_addr = oxygen_read32(chip, channel_base_registers[channel]);
559         return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr);
560 }
561
562 static struct snd_pcm_ops oxygen_rec_a_ops = {
563         .open      = oxygen_rec_a_open,
564         .close     = oxygen_close,
565         .ioctl     = snd_pcm_lib_ioctl,
566         .hw_params = oxygen_rec_a_hw_params,
567         .hw_free   = oxygen_hw_free,
568         .prepare   = oxygen_prepare,
569         .trigger   = oxygen_trigger,
570         .pointer   = oxygen_pointer,
571 };
572
573 static struct snd_pcm_ops oxygen_rec_b_ops = {
574         .open      = oxygen_rec_b_open,
575         .close     = oxygen_close,
576         .ioctl     = snd_pcm_lib_ioctl,
577         .hw_params = oxygen_rec_b_hw_params,
578         .hw_free   = oxygen_hw_free,
579         .prepare   = oxygen_prepare,
580         .trigger   = oxygen_trigger,
581         .pointer   = oxygen_pointer,
582 };
583
584 static struct snd_pcm_ops oxygen_rec_c_ops = {
585         .open      = oxygen_rec_c_open,
586         .close     = oxygen_close,
587         .ioctl     = snd_pcm_lib_ioctl,
588         .hw_params = oxygen_rec_c_hw_params,
589         .hw_free   = oxygen_hw_free,
590         .prepare   = oxygen_prepare,
591         .trigger   = oxygen_trigger,
592         .pointer   = oxygen_pointer,
593 };
594
595 static struct snd_pcm_ops oxygen_spdif_ops = {
596         .open      = oxygen_spdif_open,
597         .close     = oxygen_close,
598         .ioctl     = snd_pcm_lib_ioctl,
599         .hw_params = oxygen_spdif_hw_params,
600         .hw_free   = oxygen_spdif_hw_free,
601         .prepare   = oxygen_prepare,
602         .trigger   = oxygen_trigger,
603         .pointer   = oxygen_pointer,
604 };
605
606 static struct snd_pcm_ops oxygen_multich_ops = {
607         .open      = oxygen_multich_open,
608         .close     = oxygen_close,
609         .ioctl     = snd_pcm_lib_ioctl,
610         .hw_params = oxygen_multich_hw_params,
611         .hw_free   = oxygen_hw_free,
612         .prepare   = oxygen_prepare,
613         .trigger   = oxygen_trigger,
614         .pointer   = oxygen_pointer,
615 };
616
617 static struct snd_pcm_ops oxygen_ac97_ops = {
618         .open      = oxygen_ac97_open,
619         .close     = oxygen_close,
620         .ioctl     = snd_pcm_lib_ioctl,
621         .hw_params = oxygen_hw_params,
622         .hw_free   = oxygen_hw_free,
623         .prepare   = oxygen_prepare,
624         .trigger   = oxygen_trigger,
625         .pointer   = oxygen_pointer,
626 };
627
628 static void oxygen_pcm_free(struct snd_pcm *pcm)
629 {
630         snd_pcm_lib_preallocate_free_for_all(pcm);
631 }
632
633 int __devinit oxygen_pcm_init(struct oxygen *chip)
634 {
635         struct snd_pcm *pcm;
636         int outs, ins;
637         int err;
638
639         outs = 1; /* OXYGEN_CHANNEL_MULTICH is always used */
640         ins = !!(chip->model->used_channels & (OXYGEN_CHANNEL_A |
641                                                OXYGEN_CHANNEL_B));
642         err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm);
643         if (err < 0)
644                 return err;
645         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_multich_ops);
646         if (chip->model->used_channels & OXYGEN_CHANNEL_A)
647                 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
648                                 &oxygen_rec_a_ops);
649         else if (chip->model->used_channels & OXYGEN_CHANNEL_B)
650                 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
651                                 &oxygen_rec_b_ops);
652         pcm->private_data = chip;
653         pcm->private_free = oxygen_pcm_free;
654         strcpy(pcm->name, "Analog");
655         snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
656                                       SNDRV_DMA_TYPE_DEV,
657                                       snd_dma_pci_data(chip->pci),
658                                       512 * 1024, 2048 * 1024);
659         if (ins)
660                 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
661                                               SNDRV_DMA_TYPE_DEV,
662                                               snd_dma_pci_data(chip->pci),
663                                               128 * 1024, 256 * 1024);
664
665         outs = !!(chip->model->used_channels & OXYGEN_CHANNEL_SPDIF);
666         ins = !!(chip->model->used_channels & OXYGEN_CHANNEL_C);
667         if (outs | ins) {
668                 err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
669                 if (err < 0)
670                         return err;
671                 if (outs)
672                         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
673                                         &oxygen_spdif_ops);
674                 if (ins)
675                         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
676                                         &oxygen_rec_c_ops);
677                 pcm->private_data = chip;
678                 pcm->private_free = oxygen_pcm_free;
679                 strcpy(pcm->name, "Digital");
680                 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
681                                                       snd_dma_pci_data(chip->pci),
682                                                       128 * 1024, 256 * 1024);
683         }
684
685         outs = chip->has_ac97_1 &&
686                 (chip->model->used_channels & OXYGEN_CHANNEL_AC97);
687         ins = (chip->model->used_channels & (OXYGEN_CHANNEL_A |
688                                              OXYGEN_CHANNEL_B))
689                 == (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B);
690         if (outs | ins) {
691                 err = snd_pcm_new(chip->card, ins ? "Analog2" : "AC97",
692                                   2, outs, ins, &pcm);
693                 if (err < 0)
694                         return err;
695                 if (outs)
696                         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
697                                         &oxygen_ac97_ops);
698                 if (ins)
699                         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
700                                         &oxygen_rec_b_ops);
701                 pcm->private_data = chip;
702                 pcm->private_free = oxygen_pcm_free;
703                 strcpy(pcm->name, ins ? "Analog 2" : "Front Panel");
704                 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
705                                                       snd_dma_pci_data(chip->pci),
706                                                       128 * 1024, 256 * 1024);
707         }
708         return 0;
709 }