blob: ef738e6c991912aa5b322f5a0768b3d36e5754a8 [file] [log] [blame]
Takashi Iwaid43f30102011-05-03 16:14:46 +02001/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/dma-mapping.h>
24#include <linux/pci.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include "lola.h"
28
Takashi Iwai333ff392011-05-03 16:41:02 +020029/* #define USE_SG_BUFFER */
30
31#define LOLA_MAX_BDL_ENTRIES 8
Takashi Iwaid43f30102011-05-03 16:14:46 +020032#define LOLA_MAX_BUF_SIZE (1024*1024*1024)
Takashi Iwai333ff392011-05-03 16:41:02 +020033#define LOLA_BDL_ENTRY_SIZE (16 * 16)
34
35#ifdef USE_SG_BUFFER
36#define get_addr(substream, ofs) \
37 snd_pcm_sgbuf_get_addr(substream, ofs)
38#define get_size(substream, ofs, size) \
39 snd_pcm_sgbuf_get_chunk_size(substream, ofs, size)
40#define ops_page snd_pcm_sgbuf_ops_page
41#define PREALLOC_TYPE SNDRV_DMA_TYPE_DEV_SG
42#else
43#define get_addr(substream, ofs) \
44 ((substream)->runtime->dma_addr + ofs)
45#define get_size(substream, ofs, size) \
46 (size)
47#define ops_page NULL
48#define PREALLOC_TYPE SNDRV_DMA_TYPE_DEV
49#endif
Takashi Iwaid43f30102011-05-03 16:14:46 +020050
51static struct lola_pcm *lola_get_pcm(struct snd_pcm_substream *substream)
52{
53 struct lola *chip = snd_pcm_substream_chip(substream);
54 return &chip->pcm[substream->stream];
55}
56
57static struct lola_stream *lola_get_stream(struct snd_pcm_substream *substream)
58{
59 struct lola_pcm *pcm = lola_get_pcm(substream);
60 unsigned int idx = substream->number;
61 return &pcm->streams[idx];
62}
63
64static unsigned int lola_get_lrc(struct lola *chip)
65{
66 return lola_readl(chip, BAR1, LRC);
67}
68
69static unsigned int lola_get_tstamp(struct lola *chip, bool quick_no_sync)
70{
71 unsigned int tstamp = lola_get_lrc(chip) >> 8;
72 if (chip->granularity) {
73 unsigned int wait_banks = quick_no_sync ? 0 : 8;
74 tstamp += (wait_banks + 1) * chip->granularity - 1;
75 tstamp -= tstamp % chip->granularity;
76 }
77 return tstamp << 8;
78}
79
80/* clear any pending interrupt status */
81static void lola_stream_clear_pending_irq(struct lola *chip,
82 struct lola_stream *str)
83{
84 unsigned int val = lola_dsd_read(chip, str->dsd, STS);
85 val &= LOLA_DSD_STS_DESE | LOLA_DSD_STS_BCIS;
86 if (val)
87 lola_dsd_write(chip, str->dsd, STS, val);
88}
89
90static void lola_stream_start(struct lola *chip, struct lola_stream *str,
91 unsigned int tstamp)
92{
93 lola_stream_clear_pending_irq(chip, str);
94 lola_dsd_write(chip, str->dsd, CTL,
95 LOLA_DSD_CTL_SRUN |
96 LOLA_DSD_CTL_IOCE |
97 LOLA_DSD_CTL_DEIE |
98 LOLA_DSD_CTL_VLRCV |
99 tstamp);
100}
101
102static void lola_stream_stop(struct lola *chip, struct lola_stream *str,
103 unsigned int tstamp)
104{
105 lola_dsd_write(chip, str->dsd, CTL,
106 LOLA_DSD_CTL_IOCE |
107 LOLA_DSD_CTL_DEIE |
108 LOLA_DSD_CTL_VLRCV |
109 tstamp);
110 lola_stream_clear_pending_irq(chip, str);
111}
112
Takashi Iwaid43f30102011-05-03 16:14:46 +0200113static void wait_for_srst_clear(struct lola *chip, struct lola_stream *str)
114{
Takashi Iwai333ff392011-05-03 16:41:02 +0200115 unsigned long end_time = jiffies + msecs_to_jiffies(200);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200116 while (time_before(jiffies, end_time)) {
117 unsigned int val;
118 val = lola_dsd_read(chip, str->dsd, CTL);
119 if (!(val & LOLA_DSD_CTL_SRST))
120 return;
121 msleep(1);
122 }
123 printk(KERN_WARNING SFX "SRST not clear (stream %d)\n", str->dsd);
124}
125
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200126static int lola_stream_wait_for_fifo(struct lola *chip,
127 struct lola_stream *str,
128 bool ready)
Takashi Iwaid43f30102011-05-03 16:14:46 +0200129{
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200130 unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
131 unsigned long end_time = jiffies + msecs_to_jiffies(200);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200132 while (time_before(jiffies, end_time)) {
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200133 unsigned int reg = lola_dsd_read(chip, str->dsd, STS);
134 if ((reg & LOLA_DSD_STS_FIFORDY) == val)
Takashi Iwaid43f30102011-05-03 16:14:46 +0200135 return 0;
136 msleep(1);
137 }
138 printk(KERN_WARNING SFX "FIFO not ready (stream %d)\n", str->dsd);
139 return -EIO;
140}
141
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200142static void lola_stream_reset(struct lola *chip, struct lola_stream *str)
143{
144 if (str->prepared) {
145 str->prepared = 0;
146
147 lola_dsd_write(chip, str->dsd, CTL,
148 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
149 lola_stream_wait_for_fifo(chip, str, false);
150 lola_stream_clear_pending_irq(chip, str);
151 lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRST);
152 lola_dsd_write(chip, str->dsd, LVI, 0);
153 lola_dsd_write(chip, str->dsd, BDPU, 0);
154 lola_dsd_write(chip, str->dsd, BDPL, 0);
155 wait_for_srst_clear(chip, str);
156 }
157}
158
Takashi Iwaid43f30102011-05-03 16:14:46 +0200159static struct snd_pcm_hardware lola_pcm_hw = {
160 .info = (SNDRV_PCM_INFO_MMAP |
161 SNDRV_PCM_INFO_INTERLEAVED |
162 SNDRV_PCM_INFO_BLOCK_TRANSFER |
163 SNDRV_PCM_INFO_MMAP_VALID |
164 SNDRV_PCM_INFO_PAUSE),
165 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
166 SNDRV_PCM_FMTBIT_S24_LE |
167 SNDRV_PCM_FMTBIT_S32_LE |
168 SNDRV_PCM_FMTBIT_FLOAT_LE),
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200169 .rates = SNDRV_PCM_RATE_8000_192000,
170 .rate_min = 8000,
171 .rate_max = 192000,
Takashi Iwaid43f30102011-05-03 16:14:46 +0200172 .channels_min = 1,
173 .channels_max = 2,
174 .buffer_bytes_max = LOLA_MAX_BUF_SIZE,
175 .period_bytes_min = 128,
176 .period_bytes_max = LOLA_MAX_BUF_SIZE / 2,
177 .periods_min = 2,
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200178 .periods_max = LOLA_MAX_BDL_ENTRIES,
Takashi Iwaid43f30102011-05-03 16:14:46 +0200179 .fifo_size = 0,
180};
181
182static int lola_pcm_open(struct snd_pcm_substream *substream)
183{
184 struct lola *chip = snd_pcm_substream_chip(substream);
185 struct lola_pcm *pcm = lola_get_pcm(substream);
186 struct lola_stream *str = lola_get_stream(substream);
187 struct snd_pcm_runtime *runtime = substream->runtime;
Takashi Iwaid43f30102011-05-03 16:14:46 +0200188
189 mutex_lock(&chip->open_mutex);
190 if (str->opened) {
191 mutex_unlock(&chip->open_mutex);
192 return -EBUSY;
193 }
Takashi Iwaid43f30102011-05-03 16:14:46 +0200194 str->substream = substream;
195 str->master = NULL;
196 str->opened = 1;
197 runtime->hw = lola_pcm_hw;
198 runtime->hw.channels_max = pcm->num_streams - str->index;
199 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200200 /* period size = multiple of chip->granularity (8, 16 or 32 frames)
201 * use LOLA_GRANULARITY_MAX = 32 for instance
202 */
203 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
204 LOLA_GRANULARITY_MAX);
205 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
206 LOLA_GRANULARITY_MAX);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200207 mutex_unlock(&chip->open_mutex);
208 return 0;
209}
210
211static void lola_cleanup_slave_streams(struct lola_pcm *pcm,
212 struct lola_stream *str)
213{
214 int i;
215 for (i = str->index + 1; i < pcm->num_streams; i++) {
216 struct lola_stream *s = &pcm->streams[i];
217 if (s->master != str)
218 break;
219 s->master = NULL;
220 s->opened = 0;
221 }
222}
223
224static int lola_pcm_close(struct snd_pcm_substream *substream)
225{
226 struct lola *chip = snd_pcm_substream_chip(substream);
227 struct lola_stream *str = lola_get_stream(substream);
228
229 mutex_lock(&chip->open_mutex);
230 if (str->substream == substream) {
231 str->substream = NULL;
232 str->opened = 0;
233 }
Takashi Iwaid43f30102011-05-03 16:14:46 +0200234 mutex_unlock(&chip->open_mutex);
235 return 0;
236}
237
238static int lola_pcm_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *hw_params)
240{
241 struct lola_stream *str = lola_get_stream(substream);
242
243 str->bufsize = 0;
244 str->period_bytes = 0;
245 str->format_verb = 0;
246 return snd_pcm_lib_malloc_pages(substream,
247 params_buffer_bytes(hw_params));
248}
249
250static int lola_pcm_hw_free(struct snd_pcm_substream *substream)
251{
252 struct lola *chip = snd_pcm_substream_chip(substream);
253 struct lola_pcm *pcm = lola_get_pcm(substream);
254 struct lola_stream *str = lola_get_stream(substream);
255
256 mutex_lock(&chip->open_mutex);
257 lola_stream_reset(chip, str);
258 lola_cleanup_slave_streams(pcm, str);
259 mutex_unlock(&chip->open_mutex);
260 return snd_pcm_lib_free_pages(substream);
261}
262
263/*
264 * set up a BDL entry
265 */
266static int setup_bdle(struct snd_pcm_substream *substream,
267 struct lola_stream *str, u32 **bdlp,
268 int ofs, int size)
269{
270 u32 *bdl = *bdlp;
271
272 while (size > 0) {
273 dma_addr_t addr;
274 int chunk;
275
276 if (str->frags >= LOLA_MAX_BDL_ENTRIES)
277 return -EINVAL;
278
Takashi Iwai333ff392011-05-03 16:41:02 +0200279 addr = get_addr(substream, ofs);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200280 /* program the address field of the BDL entry */
281 bdl[0] = cpu_to_le32((u32)addr);
282 bdl[1] = cpu_to_le32(upper_32_bits(addr));
283 /* program the size field of the BDL entry */
Takashi Iwai333ff392011-05-03 16:41:02 +0200284 chunk = get_size(substream, ofs, size);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200285 bdl[2] = cpu_to_le32(chunk);
286 /* program the IOC to enable interrupt
287 * only when the whole fragment is processed
288 */
289 size -= chunk;
290 bdl[3] = size ? 0 : cpu_to_le32(0x01);
291 bdl += 4;
292 str->frags++;
293 ofs += chunk;
294 }
295 *bdlp = bdl;
296 return ofs;
297}
298
299/*
300 * set up BDL entries
301 */
Takashi Iwai333ff392011-05-03 16:41:02 +0200302static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm,
Takashi Iwaid43f30102011-05-03 16:14:46 +0200303 struct snd_pcm_substream *substream,
304 struct lola_stream *str)
305{
306 u32 *bdl;
307 int i, ofs, periods, period_bytes;
308
309 period_bytes = str->period_bytes;
310 periods = str->bufsize / period_bytes;
311
312 /* program the initial BDL entries */
Takashi Iwai333ff392011-05-03 16:41:02 +0200313 bdl = (u32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200314 ofs = 0;
315 str->frags = 0;
316 for (i = 0; i < periods; i++) {
317 ofs = setup_bdle(substream, str, &bdl, ofs, period_bytes);
318 if (ofs < 0)
319 goto error;
320 }
321 return 0;
322
323 error:
324 snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
325 str->bufsize, period_bytes);
326 return -EINVAL;
327}
328
329static unsigned int lola_get_format_verb(struct snd_pcm_substream *substream)
330{
331 unsigned int verb;
332
333 switch (substream->runtime->format) {
334 case SNDRV_PCM_FORMAT_S16_LE:
335 verb = 0x00000000;
336 break;
337 case SNDRV_PCM_FORMAT_S24_LE:
338 verb = 0x00000200;
339 break;
340 case SNDRV_PCM_FORMAT_S32_LE:
341 verb = 0x00000300;
342 break;
343 case SNDRV_PCM_FORMAT_FLOAT_LE:
344 verb = 0x00001300;
345 break;
346 default:
347 return 0;
348 }
349 verb |= substream->runtime->channels;
350 return verb;
351}
352
353static int lola_set_stream_config(struct lola *chip,
354 struct lola_stream *str,
355 int channels)
356{
357 int i, err;
358 unsigned int verb, val;
359
360 /* set format info for all channels
361 * (with only one command for the first channel)
362 */
363 err = lola_codec_read(chip, str->nid, LOLA_VERB_SET_STREAM_FORMAT,
364 str->format_verb, 0, &val, NULL);
365 if (err < 0) {
366 printk(KERN_ERR SFX "Cannot set stream format 0x%x\n",
367 str->format_verb);
368 return err;
369 }
370
371 /* update stream - channel config */
372 for (i = 0; i < channels; i++) {
373 verb = (str->index << 6) | i;
374 err = lola_codec_read(chip, str[i].nid,
375 LOLA_VERB_SET_CHANNEL_STREAMID, 0, verb,
376 &val, NULL);
377 if (err < 0) {
378 printk(KERN_ERR SFX "Cannot set stream channel %d\n", i);
379 return err;
380 }
381 }
382 return 0;
383}
384
385/*
386 * set up the SD for streaming
387 */
Takashi Iwai333ff392011-05-03 16:41:02 +0200388static int lola_setup_controller(struct lola *chip, struct lola_pcm *pcm,
389 struct lola_stream *str)
Takashi Iwaid43f30102011-05-03 16:14:46 +0200390{
Takashi Iwai333ff392011-05-03 16:41:02 +0200391 dma_addr_t bdl;
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200392
393 if (str->prepared)
394 return -EINVAL;
395
Takashi Iwaid43f30102011-05-03 16:14:46 +0200396 /* set up BDL */
Takashi Iwai333ff392011-05-03 16:41:02 +0200397 bdl = pcm->bdl.addr + LOLA_BDL_ENTRY_SIZE * str->index;
398 lola_dsd_write(chip, str->dsd, BDPL, (u32)bdl);
399 lola_dsd_write(chip, str->dsd, BDPU, upper_32_bits(bdl));
Takashi Iwaid43f30102011-05-03 16:14:46 +0200400 /* program the stream LVI (last valid index) of the BDL */
401 lola_dsd_write(chip, str->dsd, LVI, str->frags - 1);
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200402 lola_stream_clear_pending_irq(chip, str);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200403
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200404 lola_dsd_write(chip, str->dsd, CTL,
405 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE | LOLA_DSD_CTL_SRUN);
406
407 str->prepared = 1;
408
409 return lola_stream_wait_for_fifo(chip, str, true);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200410}
411
412static int lola_pcm_prepare(struct snd_pcm_substream *substream)
413{
414 struct lola *chip = snd_pcm_substream_chip(substream);
415 struct lola_pcm *pcm = lola_get_pcm(substream);
416 struct lola_stream *str = lola_get_stream(substream);
417 struct snd_pcm_runtime *runtime = substream->runtime;
418 unsigned int bufsize, period_bytes, format_verb;
419 int i, err;
420
421 mutex_lock(&chip->open_mutex);
422 lola_stream_reset(chip, str);
423 lola_cleanup_slave_streams(pcm, str);
424 if (str->index + runtime->channels >= pcm->num_streams) {
425 mutex_unlock(&chip->open_mutex);
426 return -EINVAL;
427 }
428 for (i = 1; i < runtime->channels; i++) {
429 str[i].master = str;
430 str[i].opened = 1;
431 }
432 mutex_unlock(&chip->open_mutex);
433
434 bufsize = snd_pcm_lib_buffer_bytes(substream);
435 period_bytes = snd_pcm_lib_period_bytes(substream);
436 format_verb = lola_get_format_verb(substream);
437
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200438 str->bufsize = bufsize;
439 str->period_bytes = period_bytes;
440 str->format_verb = format_verb;
441
442 err = lola_setup_periods(chip, pcm, substream, str);
443 if (err < 0)
444 return err;
Takashi Iwaid43f30102011-05-03 16:14:46 +0200445
446 err = lola_set_stream_config(chip, str, runtime->channels);
447 if (err < 0)
448 return err;
449
Takashi Iwai0f8f56c2011-05-03 16:47:03 +0200450 err = lola_setup_controller(chip, pcm, str);
451 if (err < 0) {
452 lola_stream_reset(chip, str);
453 return err;
454 }
455
456 return 0;
Takashi Iwaid43f30102011-05-03 16:14:46 +0200457}
458
459static int lola_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
460{
461 struct lola *chip = snd_pcm_substream_chip(substream);
462 struct lola_stream *str;
463 struct snd_pcm_substream *s;
464 unsigned int start;
465 unsigned int tstamp;
466
467 switch (cmd) {
468 case SNDRV_PCM_TRIGGER_START:
469 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
470 case SNDRV_PCM_TRIGGER_RESUME:
471 start = 1;
472 break;
473 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
474 case SNDRV_PCM_TRIGGER_SUSPEND:
475 case SNDRV_PCM_TRIGGER_STOP:
476 start = 0;
477 break;
478 default:
479 return -EINVAL;
480 }
481
482 tstamp = lola_get_tstamp(chip, false);
483 spin_lock(&chip->reg_lock);
484 snd_pcm_group_for_each_entry(s, substream) {
485 if (s->pcm->card != substream->pcm->card)
486 continue;
487 str = lola_get_stream(s);
488 if (start)
489 lola_stream_start(chip, str, tstamp);
490 else
491 lola_stream_stop(chip, str, tstamp);
492 str->running = start;
493 snd_pcm_trigger_done(s, substream);
494 }
495 spin_unlock(&chip->reg_lock);
496 return 0;
497}
498
499static snd_pcm_uframes_t lola_pcm_pointer(struct snd_pcm_substream *substream)
500{
501 struct lola *chip = snd_pcm_substream_chip(substream);
502 struct lola_stream *str = lola_get_stream(substream);
503 unsigned int pos = lola_dsd_read(chip, str->dsd, LPIB);
504
505 if (pos >= str->bufsize)
506 pos = 0;
507 return bytes_to_frames(substream->runtime, pos);
508}
509
510void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits)
511{
512 int i;
513
514 for (i = 0; bits && i < pcm->num_streams; i++) {
515 if (bits & (1 << i)) {
516 struct lola_stream *str = &pcm->streams[i];
517 if (str->substream && str->running)
518 snd_pcm_period_elapsed(str->substream);
519 bits &= ~(1 << i);
520 }
521 }
522}
523
524static struct snd_pcm_ops lola_pcm_ops = {
525 .open = lola_pcm_open,
526 .close = lola_pcm_close,
527 .ioctl = snd_pcm_lib_ioctl,
528 .hw_params = lola_pcm_hw_params,
529 .hw_free = lola_pcm_hw_free,
530 .prepare = lola_pcm_prepare,
531 .trigger = lola_pcm_trigger,
532 .pointer = lola_pcm_pointer,
Takashi Iwai333ff392011-05-03 16:41:02 +0200533 .page = ops_page,
Takashi Iwaid43f30102011-05-03 16:14:46 +0200534};
535
536int __devinit lola_create_pcm(struct lola *chip)
537{
538 struct snd_pcm *pcm;
539 int i, err;
540
Takashi Iwai333ff392011-05-03 16:41:02 +0200541 for (i = 0; i < 2; i++) {
542 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
543 snd_dma_pci_data(chip->pci),
544 PAGE_SIZE, &chip->pcm[i].bdl);
545 if (err < 0)
546 return err;
547 }
548
Takashi Iwaid43f30102011-05-03 16:14:46 +0200549 err = snd_pcm_new(chip->card, "Digigram Lola", 0,
550 chip->pcm[SNDRV_PCM_STREAM_PLAYBACK].num_streams,
551 chip->pcm[SNDRV_PCM_STREAM_CAPTURE].num_streams,
552 &pcm);
553 if (err < 0)
554 return err;
555 strlcpy(pcm->name, "Digigram Lola", sizeof(pcm->name));
556 pcm->private_data = chip;
557 for (i = 0; i < 2; i++) {
558 if (chip->pcm[i].num_streams)
559 snd_pcm_set_ops(pcm, i, &lola_pcm_ops);
560 }
561 /* buffer pre-allocation */
Takashi Iwai333ff392011-05-03 16:41:02 +0200562 snd_pcm_lib_preallocate_pages_for_all(pcm, PREALLOC_TYPE,
Takashi Iwaid43f30102011-05-03 16:14:46 +0200563 snd_dma_pci_data(chip->pci),
564 1024 * 64, 32 * 1024 * 1024);
565 return 0;
566}
567
568void lola_free_pcm(struct lola *chip)
569{
Takashi Iwai333ff392011-05-03 16:41:02 +0200570 snd_dma_free_pages(&chip->pcm[0].bdl);
571 snd_dma_free_pages(&chip->pcm[1].bdl);
Takashi Iwaid43f30102011-05-03 16:14:46 +0200572}
573
574/*
575 */
576
577static int lola_init_stream(struct lola *chip, struct lola_stream *str,
578 int idx, int nid, int dir)
579{
580 unsigned int val;
581 int err;
582
583 str->nid = nid;
584 str->index = idx;
585 str->dsd = idx;
586 if (dir == PLAY)
587 str->dsd += MAX_STREAM_IN_COUNT;
588 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
589 if (err < 0) {
590 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
591 return err;
592 }
593 if (dir == PLAY) {
594 /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) */
595 if ((val & 0x00f00dff) != 0x00000010) {
596 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
597 val, nid);
598 return -EINVAL;
599 }
600 } else {
601 /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1)
602 * (bug : ignore bit8: Conn list = 0/1)
603 */
604 if ((val & 0x00f00cff) != 0x00100010) {
605 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
606 val, nid);
607 return -EINVAL;
608 }
609 /* test bit9:DIGITAL and bit12:SRC_PRESENT*/
610 if ((val & 0x00001200) == 0x00001200)
611 chip->input_src_caps_mask |= (1 << idx);
612 }
613
614 err = lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
615 if (err < 0) {
616 printk(KERN_ERR SFX "Can't read FORMATS 0x%x\n", nid);
617 return err;
618 }
619 val &= 3;
620 if (val == 3)
621 str->can_float = true;
622 if (!(val & 1)) {
623 printk(KERN_ERR SFX "Invalid formats 0x%x for 0x%x", val, nid);
624 return -EINVAL;
625 }
626 return 0;
627}
628
629int __devinit lola_init_pcm(struct lola *chip, int dir, int *nidp)
630{
631 struct lola_pcm *pcm = &chip->pcm[dir];
632 int i, nid, err;
633
634 nid = *nidp;
635 for (i = 0; i < pcm->num_streams; i++, nid++) {
636 err = lola_init_stream(chip, &pcm->streams[i], i, nid, dir);
637 if (err < 0)
638 return err;
639 }
640 *nidp = nid;
641 return 0;
642}