aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/lx6464es/lx6464es.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/lx6464es/lx6464es.c')
-rw-r--r--sound/pci/lx6464es/lx6464es.c1152
1 files changed, 1152 insertions, 0 deletions
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
new file mode 100644
index 000000000000..870bfc58c697
--- /dev/null
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -0,0 +1,1152 @@
1/* -*- linux-c -*- *
2 *
3 * ALSA driver for the digigram lx6464es interface
4 *
5 * Copyright (c) 2008, 2009 Tim Blechmann <tim@klingt.org>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 *
23 */
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/pci.h>
28#include <linux/delay.h>
29
30#include <sound/initval.h>
31#include <sound/control.h>
32#include <sound/info.h>
33
34#include "lx6464es.h"
35
36MODULE_AUTHOR("Tim Blechmann");
37MODULE_LICENSE("GPL");
38MODULE_DESCRIPTION("digigram lx6464es");
39MODULE_SUPPORTED_DEVICE("{digigram lx6464es{}}");
40
41
42static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
43static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
44static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
45
46static const char card_name[] = "LX6464ES";
47
48
49#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056
50
51static struct pci_device_id snd_lx6464es_ids[] = {
52 { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
53 .subvendor = PCI_VENDOR_ID_DIGIGRAM,
54 .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM
55 }, /* LX6464ES */
56 { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
57 .subvendor = PCI_VENDOR_ID_DIGIGRAM,
58 .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM
59 }, /* LX6464ES-CAE */
60 { 0, },
61};
62
63MODULE_DEVICE_TABLE(pci, snd_lx6464es_ids);
64
65
66
67/* PGO pour USERo dans le registre pci_0x06/loc_0xEC */
68#define CHIPSC_RESET_XILINX (1L<<16)
69
70
71/* alsa callbacks */
72static struct snd_pcm_hardware lx_caps = {
73 .info = (SNDRV_PCM_INFO_MMAP |
74 SNDRV_PCM_INFO_INTERLEAVED |
75 SNDRV_PCM_INFO_MMAP_VALID |
76 SNDRV_PCM_INFO_SYNC_START),
77 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
78 SNDRV_PCM_FMTBIT_S16_BE |
79 SNDRV_PCM_FMTBIT_S24_3LE |
80 SNDRV_PCM_FMTBIT_S24_3BE),
81 .rates = (SNDRV_PCM_RATE_CONTINUOUS |
82 SNDRV_PCM_RATE_8000_192000),
83 .rate_min = 8000,
84 .rate_max = 192000,
85 .channels_min = 2,
86 .channels_max = 64,
87 .buffer_bytes_max = 64*2*3*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER,
88 .period_bytes_min = (2*2*MICROBLAZE_IBL_MIN*2),
89 .period_bytes_max = (4*64*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER),
90 .periods_min = 2,
91 .periods_max = MAX_STREAM_BUFFER,
92};
93
94static int lx_set_granularity(struct lx6464es *chip, u32 gran);
95
96
97static int lx_hardware_open(struct lx6464es *chip,
98 struct snd_pcm_substream *substream)
99{
100 int err = 0;
101 struct snd_pcm_runtime *runtime = substream->runtime;
102 int channels = runtime->channels;
103 int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
104
105 snd_pcm_uframes_t period_size = runtime->period_size;
106
107 snd_printd(LXP "allocating pipe for %d channels\n", channels);
108 err = lx_pipe_allocate(chip, 0, is_capture, channels);
109 if (err < 0) {
110 snd_printk(KERN_ERR LXP "allocating pipe failed\n");
111 return err;
112 }
113
114 err = lx_set_granularity(chip, period_size);
115 if (err < 0) {
116 snd_printk(KERN_ERR LXP "setting granularity to %ld failed\n",
117 period_size);
118 return err;
119 }
120
121 return 0;
122}
123
124static int lx_hardware_start(struct lx6464es *chip,
125 struct snd_pcm_substream *substream)
126{
127 int err = 0;
128 struct snd_pcm_runtime *runtime = substream->runtime;
129 int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
130
131 snd_printd(LXP "setting stream format\n");
132 err = lx_stream_set_format(chip, runtime, 0, is_capture);
133 if (err < 0) {
134 snd_printk(KERN_ERR LXP "setting stream format failed\n");
135 return err;
136 }
137
138 snd_printd(LXP "starting pipe\n");
139 err = lx_pipe_start(chip, 0, is_capture);
140 if (err < 0) {
141 snd_printk(KERN_ERR LXP "starting pipe failed\n");
142 return err;
143 }
144
145 snd_printd(LXP "waiting for pipe to start\n");
146 err = lx_pipe_wait_for_start(chip, 0, is_capture);
147 if (err < 0) {
148 snd_printk(KERN_ERR LXP "waiting for pipe failed\n");
149 return err;
150 }
151
152 return err;
153}
154
155
156static int lx_hardware_stop(struct lx6464es *chip,
157 struct snd_pcm_substream *substream)
158{
159 int err = 0;
160 int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
161
162 snd_printd(LXP "pausing pipe\n");
163 err = lx_pipe_pause(chip, 0, is_capture);
164 if (err < 0) {
165 snd_printk(KERN_ERR LXP "pausing pipe failed\n");
166 return err;
167 }
168
169 snd_printd(LXP "waiting for pipe to become idle\n");
170 err = lx_pipe_wait_for_idle(chip, 0, is_capture);
171 if (err < 0) {
172 snd_printk(KERN_ERR LXP "waiting for pipe failed\n");
173 return err;
174 }
175
176 snd_printd(LXP "stopping pipe\n");
177 err = lx_pipe_stop(chip, 0, is_capture);
178 if (err < 0) {
179 snd_printk(LXP "stopping pipe failed\n");
180 return err;
181 }
182
183 return err;
184}
185
186
187static int lx_hardware_close(struct lx6464es *chip,
188 struct snd_pcm_substream *substream)
189{
190 int err = 0;
191 int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
192
193 snd_printd(LXP "releasing pipe\n");
194 err = lx_pipe_release(chip, 0, is_capture);
195 if (err < 0) {
196 snd_printk(LXP "releasing pipe failed\n");
197 return err;
198 }
199
200 return err;
201}
202
203
204static int lx_pcm_open(struct snd_pcm_substream *substream)
205{
206 struct lx6464es *chip = snd_pcm_substream_chip(substream);
207 struct snd_pcm_runtime *runtime = substream->runtime;
208 int err = 0;
209 int board_rate;
210
211 snd_printdd("->lx_pcm_open\n");
212 mutex_lock(&chip->setup_mutex);
213
214 /* copy the struct snd_pcm_hardware struct */
215 runtime->hw = lx_caps;
216
217#if 0
218 /* buffer-size should better be multiple of period-size */
219 err = snd_pcm_hw_constraint_integer(runtime,
220 SNDRV_PCM_HW_PARAM_PERIODS);
221 if (err < 0) {
222 snd_printk(KERN_WARNING LXP "could not constrain periods\n");
223 goto exit;
224 }
225#endif
226
227 /* the clock rate cannot be changed */
228 board_rate = chip->board_sample_rate;
229 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
230 board_rate, board_rate);
231
232 if (err < 0) {
233 snd_printk(KERN_WARNING LXP "could not constrain periods\n");
234 goto exit;
235 }
236
237 /* constrain period size */
238 err = snd_pcm_hw_constraint_minmax(runtime,
239 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
240 MICROBLAZE_IBL_MIN,
241 MICROBLAZE_IBL_MAX);
242 if (err < 0) {
243 snd_printk(KERN_WARNING LXP
244 "could not constrain period size\n");
245 goto exit;
246 }
247
248 snd_pcm_hw_constraint_step(runtime, 0,
249 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
250
251 snd_pcm_set_sync(substream);
252 err = 0;
253
254exit:
255 runtime->private_data = chip;
256
257 mutex_unlock(&chip->setup_mutex);
258 snd_printdd("<-lx_pcm_open, %d\n", err);
259 return err;
260}
261
262static int lx_pcm_close(struct snd_pcm_substream *substream)
263{
264 int err = 0;
265 snd_printdd("->lx_pcm_close\n");
266 return err;
267}
268
269static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream
270 *substream)
271{
272 struct lx6464es *chip = snd_pcm_substream_chip(substream);
273 snd_pcm_uframes_t pos;
274 unsigned long flags;
275 int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
276
277 struct lx_stream *lx_stream = is_capture ? &chip->capture_stream :
278 &chip->playback_stream;
279
280 snd_printdd("->lx_pcm_stream_pointer\n");
281
282 spin_lock_irqsave(&chip->lock, flags);
283 pos = lx_stream->frame_pos * substream->runtime->period_size;
284 spin_unlock_irqrestore(&chip->lock, flags);
285
286 snd_printdd(LXP "stream_pointer at %ld\n", pos);
287 return pos;
288}
289
290static int lx_pcm_prepare(struct snd_pcm_substream *substream)
291{
292 struct lx6464es *chip = snd_pcm_substream_chip(substream);
293 int err = 0;
294 const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
295
296 snd_printdd("->lx_pcm_prepare\n");
297
298 mutex_lock(&chip->setup_mutex);
299
300 if (chip->hardware_running[is_capture]) {
301 err = lx_hardware_stop(chip, substream);
302 if (err < 0) {
303 snd_printk(KERN_ERR LXP "failed to stop hardware. "
304 "Error code %d\n", err);
305 goto exit;
306 }
307
308 err = lx_hardware_close(chip, substream);
309 if (err < 0) {
310 snd_printk(KERN_ERR LXP "failed to close hardware. "
311 "Error code %d\n", err);
312 goto exit;
313 }
314 }
315
316 snd_printd(LXP "opening hardware\n");
317 err = lx_hardware_open(chip, substream);
318 if (err < 0) {
319 snd_printk(KERN_ERR LXP "failed to open hardware. "
320 "Error code %d\n", err);
321 goto exit;
322 }
323
324 err = lx_hardware_start(chip, substream);
325 if (err < 0) {
326 snd_printk(KERN_ERR LXP "failed to start hardware. "
327 "Error code %d\n", err);
328 goto exit;
329 }
330
331 chip->hardware_running[is_capture] = 1;
332
333 if (chip->board_sample_rate != substream->runtime->rate) {
334 if (!err)
335 chip->board_sample_rate = substream->runtime->rate;
336 }
337
338exit:
339 mutex_unlock(&chip->setup_mutex);
340 return err;
341}
342
343static int lx_pcm_hw_params(struct snd_pcm_substream *substream,
344 struct snd_pcm_hw_params *hw_params, int is_capture)
345{
346 struct lx6464es *chip = snd_pcm_substream_chip(substream);
347 int err = 0;
348
349 snd_printdd("->lx_pcm_hw_params\n");
350
351 mutex_lock(&chip->setup_mutex);
352
353 /* set dma buffer */
354 err = snd_pcm_lib_malloc_pages(substream,
355 params_buffer_bytes(hw_params));
356
357 if (is_capture)
358 chip->capture_stream.stream = substream;
359 else
360 chip->playback_stream.stream = substream;
361
362 mutex_unlock(&chip->setup_mutex);
363 return err;
364}
365
366static int lx_pcm_hw_params_playback(struct snd_pcm_substream *substream,
367 struct snd_pcm_hw_params *hw_params)
368{
369 return lx_pcm_hw_params(substream, hw_params, 0);
370}
371
372static int lx_pcm_hw_params_capture(struct snd_pcm_substream *substream,
373 struct snd_pcm_hw_params *hw_params)
374{
375 return lx_pcm_hw_params(substream, hw_params, 1);
376}
377
378static int lx_pcm_hw_free(struct snd_pcm_substream *substream)
379{
380 struct lx6464es *chip = snd_pcm_substream_chip(substream);
381 int err = 0;
382 int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
383
384 snd_printdd("->lx_pcm_hw_free\n");
385 mutex_lock(&chip->setup_mutex);
386
387 if (chip->hardware_running[is_capture]) {
388 err = lx_hardware_stop(chip, substream);
389 if (err < 0) {
390 snd_printk(KERN_ERR LXP "failed to stop hardware. "
391 "Error code %d\n", err);
392 goto exit;
393 }
394
395 err = lx_hardware_close(chip, substream);
396 if (err < 0) {
397 snd_printk(KERN_ERR LXP "failed to close hardware. "
398 "Error code %d\n", err);
399 goto exit;
400 }
401
402 chip->hardware_running[is_capture] = 0;
403 }
404
405 err = snd_pcm_lib_free_pages(substream);
406
407 if (is_capture)
408 chip->capture_stream.stream = 0;
409 else
410 chip->playback_stream.stream = 0;
411
412exit:
413 mutex_unlock(&chip->setup_mutex);
414 return err;
415}
416
417static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
418{
419 struct snd_pcm_substream *substream = lx_stream->stream;
420 const int is_capture = lx_stream->is_capture;
421
422 int err;
423
424 const u32 channels = substream->runtime->channels;
425 const u32 bytes_per_frame = channels * 3;
426 const u32 period_size = substream->runtime->period_size;
427 const u32 periods = substream->runtime->periods;
428 const u32 period_bytes = period_size * bytes_per_frame;
429
430 dma_addr_t buf = substream->dma_buffer.addr;
431 int i;
432
433 u32 needed, freed;
434 u32 size_array[5];
435
436 for (i = 0; i != periods; ++i) {
437 u32 buffer_index = 0;
438
439 err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed,
440 size_array);
441 snd_printdd(LXP "starting: needed %d, freed %d\n",
442 needed, freed);
443
444 err = lx_buffer_give(chip, 0, is_capture, period_bytes,
445 lower_32_bits(buf), upper_32_bits(buf),
446 &buffer_index);
447
448 snd_printdd(LXP "starting: buffer index %x on %p (%d bytes)\n",
449 buffer_index, (void *)buf, period_bytes);
450 buf += period_bytes;
451 }
452
453 err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
454 snd_printdd(LXP "starting: needed %d, freed %d\n", needed, freed);
455
456 snd_printd(LXP "starting: starting stream\n");
457 err = lx_stream_start(chip, 0, is_capture);
458 if (err < 0)
459 snd_printk(KERN_ERR LXP "couldn't start stream\n");
460 else
461 lx_stream->status = LX_STREAM_STATUS_RUNNING;
462
463 lx_stream->frame_pos = 0;
464}
465
466static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream)
467{
468 const int is_capture = lx_stream->is_capture;
469 int err;
470
471 snd_printd(LXP "stopping: stopping stream\n");
472 err = lx_stream_stop(chip, 0, is_capture);
473 if (err < 0)
474 snd_printk(KERN_ERR LXP "couldn't stop stream\n");
475 else
476 lx_stream->status = LX_STREAM_STATUS_FREE;
477
478}
479
480static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip,
481 struct lx_stream *lx_stream)
482{
483 switch (lx_stream->status) {
484 case LX_STREAM_STATUS_SCHEDULE_RUN:
485 lx_trigger_start(chip, lx_stream);
486 break;
487
488 case LX_STREAM_STATUS_SCHEDULE_STOP:
489 lx_trigger_stop(chip, lx_stream);
490 break;
491
492 default:
493 break;
494 }
495}
496
497static void lx_trigger_tasklet(unsigned long data)
498{
499 struct lx6464es *chip = (struct lx6464es *)data;
500 unsigned long flags;
501
502 snd_printdd("->lx_trigger_tasklet\n");
503
504 spin_lock_irqsave(&chip->lock, flags);
505 lx_trigger_tasklet_dispatch_stream(chip, &chip->capture_stream);
506 lx_trigger_tasklet_dispatch_stream(chip, &chip->playback_stream);
507 spin_unlock_irqrestore(&chip->lock, flags);
508}
509
510static int lx_pcm_trigger_dispatch(struct lx6464es *chip,
511 struct lx_stream *lx_stream, int cmd)
512{
513 int err = 0;
514
515 switch (cmd) {
516 case SNDRV_PCM_TRIGGER_START:
517 lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN;
518 break;
519
520 case SNDRV_PCM_TRIGGER_STOP:
521 lx_stream->status = LX_STREAM_STATUS_SCHEDULE_STOP;
522 break;
523
524 default:
525 err = -EINVAL;
526 goto exit;
527 }
528 tasklet_schedule(&chip->trigger_tasklet);
529
530exit:
531 return err;
532}
533
534
535static int lx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
536{
537 struct lx6464es *chip = snd_pcm_substream_chip(substream);
538 const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
539 struct lx_stream *stream = is_capture ? &chip->capture_stream :
540 &chip->playback_stream;
541
542 snd_printdd("->lx_pcm_trigger\n");
543
544 return lx_pcm_trigger_dispatch(chip, stream, cmd);
545}
546
547static int snd_lx6464es_free(struct lx6464es *chip)
548{
549 snd_printdd("->snd_lx6464es_free\n");
550
551 lx_irq_disable(chip);
552
553 if (chip->irq >= 0)
554 free_irq(chip->irq, chip);
555
556 iounmap(chip->port_dsp_bar);
557 ioport_unmap(chip->port_plx_remapped);
558
559 pci_release_regions(chip->pci);
560 pci_disable_device(chip->pci);
561
562 kfree(chip);
563
564 return 0;
565}
566
567static int snd_lx6464es_dev_free(struct snd_device *device)
568{
569 return snd_lx6464es_free(device->device_data);
570}
571
572/* reset the dsp during initialization */
573static int __devinit lx_init_xilinx_reset(struct lx6464es *chip)
574{
575 int i;
576 u32 plx_reg = lx_plx_reg_read(chip, ePLX_CHIPSC);
577
578 snd_printdd("->lx_init_xilinx_reset\n");
579
580 /* activate reset of xilinx */
581 plx_reg &= ~CHIPSC_RESET_XILINX;
582
583 lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg);
584 msleep(1);
585
586 lx_plx_reg_write(chip, ePLX_MBOX3, 0);
587 msleep(1);
588
589 plx_reg |= CHIPSC_RESET_XILINX;
590 lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg);
591
592 /* deactivate reset of xilinx */
593 for (i = 0; i != 100; ++i) {
594 u32 reg_mbox3;
595 msleep(10);
596 reg_mbox3 = lx_plx_reg_read(chip, ePLX_MBOX3);
597 if (reg_mbox3) {
598 snd_printd(LXP "xilinx reset done\n");
599 snd_printdd(LXP "xilinx took %d loops\n", i);
600 break;
601 }
602 }
603
604 /* todo: add some error handling? */
605
606 /* clear mr */
607 lx_dsp_reg_write(chip, eReg_CSM, 0);
608
609 /* le xilinx ES peut ne pas etre encore pret, on attend. */
610 msleep(600);
611
612 return 0;
613}
614
615static int __devinit lx_init_xilinx_test(struct lx6464es *chip)
616{
617 u32 reg;
618
619 snd_printdd("->lx_init_xilinx_test\n");
620
621 /* TEST if we have access to Xilinx/MicroBlaze */
622 lx_dsp_reg_write(chip, eReg_CSM, 0);
623
624 reg = lx_dsp_reg_read(chip, eReg_CSM);
625
626 if (reg) {
627 snd_printk(KERN_ERR LXP "Problem: Reg_CSM %x.\n", reg);
628
629 /* PCI9056_SPACE0_REMAP */
630 lx_plx_reg_write(chip, ePLX_PCICR, 1);
631
632 reg = lx_dsp_reg_read(chip, eReg_CSM);
633 if (reg) {
634 snd_printk(KERN_ERR LXP "Error: Reg_CSM %x.\n", reg);
635 return -EAGAIN; /* seems to be appropriate */
636 }
637 }
638
639 snd_printd(LXP "Xilinx/MicroBlaze access test successful\n");
640
641 return 0;
642}
643
644/* initialize ethersound */
645static int __devinit lx_init_ethersound_config(struct lx6464es *chip)
646{
647 int i;
648 u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES);
649
650 u32 default_conf_es = (64 << IOCR_OUTPUTS_OFFSET) |
651 (64 << IOCR_INPUTS_OFFSET) |
652 (FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET);
653
654 u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK)
655 | (default_conf_es & CONFES_WRITE_PART_MASK);
656
657 snd_printdd("->lx_init_ethersound\n");
658
659 chip->freq_ratio = FREQ_RATIO_SINGLE_MODE;
660
661 /*
662 * write it to the card !
663 * this actually kicks the ES xilinx, the first time since poweron.
664 * the MAC address in the Reg_ADMACESMSB Reg_ADMACESLSB registers
665 * is not ready before this is done, and the bit 2 in Reg_CSES is set.
666 * */
667 lx_dsp_reg_write(chip, eReg_CONFES, conf_es);
668
669 for (i = 0; i != 1000; ++i) {
670 if (lx_dsp_reg_read(chip, eReg_CSES) & 4) {
671 snd_printd(LXP "ethersound initialized after %dms\n",
672 i);
673 goto ethersound_initialized;
674 }
675 msleep(1);
676 }
677 snd_printk(KERN_WARNING LXP
678 "ethersound could not be initialized after %dms\n", i);
679 return -ETIMEDOUT;
680
681 ethersound_initialized:
682 snd_printd(LXP "ethersound initialized\n");
683 return 0;
684}
685
686static int __devinit lx_init_get_version_features(struct lx6464es *chip)
687{
688 u32 dsp_version;
689
690 int err;
691
692 snd_printdd("->lx_init_get_version_features\n");
693
694 err = lx_dsp_get_version(chip, &dsp_version);
695
696 if (err == 0) {
697 u32 freq;
698
699 snd_printk(LXP "DSP version: V%02d.%02d #%d\n",
700 (dsp_version>>16) & 0xff, (dsp_version>>8) & 0xff,
701 dsp_version & 0xff);
702
703 /* later: what firmware version do we expect? */
704
705 /* retrieve Play/Rec features */
706 /* done here because we may have to handle alternate
707 * DSP files. */
708 /* later */
709
710 /* init the EtherSound sample rate */
711 err = lx_dsp_get_clock_frequency(chip, &freq);
712 if (err == 0)
713 chip->board_sample_rate = freq;
714 snd_printd(LXP "actual clock frequency %d\n", freq);
715 } else {
716 snd_printk(KERN_ERR LXP "DSP corrupted \n");
717 err = -EAGAIN;
718 }
719
720 return err;
721}
722
723static int lx_set_granularity(struct lx6464es *chip, u32 gran)
724{
725 int err = 0;
726 u32 snapped_gran = MICROBLAZE_IBL_MIN;
727
728 snd_printdd("->lx_set_granularity\n");
729
730 /* blocksize is a power of 2 */
731 while ((snapped_gran < gran) &&
732 (snapped_gran < MICROBLAZE_IBL_MAX)) {
733 snapped_gran *= 2;
734 }
735
736 if (snapped_gran == chip->pcm_granularity)
737 return 0;
738
739 err = lx_dsp_set_granularity(chip, snapped_gran);
740 if (err < 0) {
741 snd_printk(KERN_WARNING LXP "could not set granularity\n");
742 err = -EAGAIN;
743 }
744
745 if (snapped_gran != gran)
746 snd_printk(LXP "snapped blocksize to %d\n", snapped_gran);
747
748 snd_printd(LXP "set blocksize on board %d\n", snapped_gran);
749 chip->pcm_granularity = snapped_gran;
750
751 return err;
752}
753
754/* initialize and test the xilinx dsp chip */
755static int __devinit lx_init_dsp(struct lx6464es *chip)
756{
757 int err;
758 u8 mac_address[6];
759 int i;
760
761 snd_printdd("->lx_init_dsp\n");
762
763 snd_printd(LXP "initialize board\n");
764 err = lx_init_xilinx_reset(chip);
765 if (err)
766 return err;
767
768 snd_printd(LXP "testing board\n");
769 err = lx_init_xilinx_test(chip);
770 if (err)
771 return err;
772
773 snd_printd(LXP "initialize ethersound configuration\n");
774 err = lx_init_ethersound_config(chip);
775 if (err)
776 return err;
777
778 lx_irq_enable(chip);
779
780 /** \todo the mac address should be ready by not, but it isn't,
781 * so we wait for it */
782 for (i = 0; i != 1000; ++i) {
783 err = lx_dsp_get_mac(chip, mac_address);
784 if (err)
785 return err;
786 if (mac_address[0] || mac_address[1] || mac_address[2] ||
787 mac_address[3] || mac_address[4] || mac_address[5])
788 goto mac_ready;
789 msleep(1);
790 }
791 return -ETIMEDOUT;
792
793mac_ready:
794 snd_printd(LXP "mac address ready read after: %dms\n", i);
795 snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
796 mac_address[0], mac_address[1], mac_address[2],
797 mac_address[3], mac_address[4], mac_address[5]);
798
799 err = lx_init_get_version_features(chip);
800 if (err)
801 return err;
802
803 lx_set_granularity(chip, MICROBLAZE_IBL_DEFAULT);
804
805 chip->playback_mute = 0;
806
807 return err;
808}
809
810static struct snd_pcm_ops lx_ops_playback = {
811 .open = lx_pcm_open,
812 .close = lx_pcm_close,
813 .ioctl = snd_pcm_lib_ioctl,
814 .prepare = lx_pcm_prepare,
815 .hw_params = lx_pcm_hw_params_playback,
816 .hw_free = lx_pcm_hw_free,
817 .trigger = lx_pcm_trigger,
818 .pointer = lx_pcm_stream_pointer,
819};
820
821static struct snd_pcm_ops lx_ops_capture = {
822 .open = lx_pcm_open,
823 .close = lx_pcm_close,
824 .ioctl = snd_pcm_lib_ioctl,
825 .prepare = lx_pcm_prepare,
826 .hw_params = lx_pcm_hw_params_capture,
827 .hw_free = lx_pcm_hw_free,
828 .trigger = lx_pcm_trigger,
829 .pointer = lx_pcm_stream_pointer,
830};
831
832static int __devinit lx_pcm_create(struct lx6464es *chip)
833{
834 int err;
835 struct snd_pcm *pcm;
836
837 u32 size = 64 * /* channels */
838 3 * /* 24 bit samples */
839 MAX_STREAM_BUFFER * /* periods */
840 MICROBLAZE_IBL_MAX * /* frames per period */
841 2; /* duplex */
842
843 size = PAGE_ALIGN(size);
844
845 /* hardcoded device name & channel count */
846 err = snd_pcm_new(chip->card, (char *)card_name, 0,
847 1, 1, &pcm);
848
849 pcm->private_data = chip;
850
851 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &lx_ops_playback);
852 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture);
853
854 pcm->info_flags = 0;
855 strcpy(pcm->name, card_name);
856
857 err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
858 snd_dma_pci_data(chip->pci),
859 size, size);
860 if (err < 0)
861 return err;
862
863 chip->pcm = pcm;
864 chip->capture_stream.is_capture = 1;
865
866 return 0;
867}
868
869static int lx_control_playback_info(struct snd_kcontrol *kcontrol,
870 struct snd_ctl_elem_info *uinfo)
871{
872 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
873 uinfo->count = 1;
874 uinfo->value.integer.min = 0;
875 uinfo->value.integer.max = 1;
876 return 0;
877}
878
879static int lx_control_playback_get(struct snd_kcontrol *kcontrol,
880 struct snd_ctl_elem_value *ucontrol)
881{
882 struct lx6464es *chip = snd_kcontrol_chip(kcontrol);
883 ucontrol->value.integer.value[0] = chip->playback_mute;
884 return 0;
885}
886
887static int lx_control_playback_put(struct snd_kcontrol *kcontrol,
888 struct snd_ctl_elem_value *ucontrol)
889{
890 struct lx6464es *chip = snd_kcontrol_chip(kcontrol);
891 int changed = 0;
892 int current_value = chip->playback_mute;
893
894 if (current_value != ucontrol->value.integer.value[0]) {
895 lx_level_unmute(chip, 0, !current_value);
896 chip->playback_mute = !current_value;
897 changed = 1;
898 }
899 return changed;
900}
901
902static struct snd_kcontrol_new lx_control_playback_switch __devinitdata = {
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = "PCM Playback Switch",
905 .index = 0,
906 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
907 .private_value = 0,
908 .info = lx_control_playback_info,
909 .get = lx_control_playback_get,
910 .put = lx_control_playback_put
911};
912
913
914
915static void lx_proc_levels_read(struct snd_info_entry *entry,
916 struct snd_info_buffer *buffer)
917{
918 u32 levels[64];
919 int err;
920 int i, j;
921 struct lx6464es *chip = entry->private_data;
922
923 snd_iprintf(buffer, "capture levels:\n");
924 err = lx_level_peaks(chip, 1, 64, levels);
925 if (err < 0)
926 return;
927
928 for (i = 0; i != 8; ++i) {
929 for (j = 0; j != 8; ++j)
930 snd_iprintf(buffer, "%08x ", levels[i*8+j]);
931 snd_iprintf(buffer, "\n");
932 }
933
934 snd_iprintf(buffer, "\nplayback levels:\n");
935
936 err = lx_level_peaks(chip, 0, 64, levels);
937 if (err < 0)
938 return;
939
940 for (i = 0; i != 8; ++i) {
941 for (j = 0; j != 8; ++j)
942 snd_iprintf(buffer, "%08x ", levels[i*8+j]);
943 snd_iprintf(buffer, "\n");
944 }
945
946 snd_iprintf(buffer, "\n");
947}
948
949static int __devinit lx_proc_create(struct snd_card *card, struct lx6464es *chip)
950{
951 struct snd_info_entry *entry;
952 int err = snd_card_proc_new(card, "levels", &entry);
953 if (err < 0)
954 return err;
955
956 snd_info_set_text_ops(entry, chip, lx_proc_levels_read);
957 return 0;
958}
959
960
961static int __devinit snd_lx6464es_create(struct snd_card *card,
962 struct pci_dev *pci,
963 struct lx6464es **rchip)
964{
965 struct lx6464es *chip;
966 int err;
967
968 static struct snd_device_ops ops = {
969 .dev_free = snd_lx6464es_dev_free,
970 };
971
972 snd_printdd("->snd_lx6464es_create\n");
973
974 *rchip = NULL;
975
976 /* enable PCI device */
977 err = pci_enable_device(pci);
978 if (err < 0)
979 return err;
980
981 pci_set_master(pci);
982
983 /* check if we can restrict PCI DMA transfers to 32 bits */
984 err = pci_set_dma_mask(pci, DMA_32BIT_MASK);
985 if (err < 0) {
986 snd_printk(KERN_ERR "architecture does not support "
987 "32bit PCI busmaster DMA\n");
988 pci_disable_device(pci);
989 return -ENXIO;
990 }
991
992 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
993 if (chip == NULL) {
994 err = -ENOMEM;
995 goto alloc_failed;
996 }
997
998 chip->card = card;
999 chip->pci = pci;
1000 chip->irq = -1;
1001
1002 /* initialize synchronization structs */
1003 spin_lock_init(&chip->lock);
1004 spin_lock_init(&chip->msg_lock);
1005 mutex_init(&chip->setup_mutex);
1006 tasklet_init(&chip->trigger_tasklet, lx_trigger_tasklet,
1007 (unsigned long)chip);
1008 tasklet_init(&chip->tasklet_capture, lx_tasklet_capture,
1009 (unsigned long)chip);
1010 tasklet_init(&chip->tasklet_playback, lx_tasklet_playback,
1011 (unsigned long)chip);
1012
1013 /* request resources */
1014 err = pci_request_regions(pci, card_name);
1015 if (err < 0)
1016 goto request_regions_failed;
1017
1018 /* plx port */
1019 chip->port_plx = pci_resource_start(pci, 1);
1020 chip->port_plx_remapped = ioport_map(chip->port_plx,
1021 pci_resource_len(pci, 1));
1022
1023 /* dsp port */
1024 chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
1025
1026 err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
1027 card_name, chip);
1028 if (err) {
1029 snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq);
1030 goto request_irq_failed;
1031 }
1032 chip->irq = pci->irq;
1033
1034 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1035 if (err < 0)
1036 goto device_new_failed;
1037
1038 err = lx_init_dsp(chip);
1039 if (err < 0) {
1040 snd_printk(KERN_ERR LXP "error during DSP initialization\n");
1041 return err;
1042 }
1043
1044 err = lx_pcm_create(chip);
1045 if (err < 0)
1046 return err;
1047
1048 err = lx_proc_create(card, chip);
1049 if (err < 0)
1050 return err;
1051
1052 err = snd_ctl_add(card, snd_ctl_new1(&lx_control_playback_switch,
1053 chip));
1054 if (err < 0)
1055 return err;
1056
1057 snd_card_set_dev(card, &pci->dev);
1058
1059 *rchip = chip;
1060 return 0;
1061
1062device_new_failed:
1063 free_irq(pci->irq, chip);
1064
1065request_irq_failed:
1066 pci_release_regions(pci);
1067
1068request_regions_failed:
1069 kfree(chip);
1070
1071alloc_failed:
1072 pci_disable_device(pci);
1073
1074 return err;
1075}
1076
1077static int __devinit snd_lx6464es_probe(struct pci_dev *pci,
1078 const struct pci_device_id *pci_id)
1079{
1080 static int dev;
1081 struct snd_card *card;
1082 struct lx6464es *chip;
1083 int err;
1084
1085 snd_printdd("->snd_lx6464es_probe\n");
1086
1087 if (dev >= SNDRV_CARDS)
1088 return -ENODEV;
1089 if (!enable[dev]) {
1090 dev++;
1091 return -ENOENT;
1092 }
1093
1094 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
1095 if (err < 0)
1096 return err;
1097
1098 err = snd_lx6464es_create(card, pci, &chip);
1099 if (err < 0) {
1100 snd_printk(KERN_ERR LXP "error during snd_lx6464es_create\n");
1101 goto out_free;
1102 }
1103
1104 strcpy(card->driver, "lx6464es");
1105 strcpy(card->shortname, "Digigram LX6464ES");
1106 sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
1107 card->shortname, chip->port_plx,
1108 chip->port_dsp_bar, chip->irq);
1109
1110 err = snd_card_register(card);
1111 if (err < 0)
1112 goto out_free;
1113
1114 snd_printdd(LXP "initialization successful\n");
1115 pci_set_drvdata(pci, card);
1116 dev++;
1117 return 0;
1118
1119out_free:
1120 snd_card_free(card);
1121 return err;
1122
1123}
1124
1125static void __devexit snd_lx6464es_remove(struct pci_dev *pci)
1126{
1127 snd_card_free(pci_get_drvdata(pci));
1128 pci_set_drvdata(pci, NULL);
1129}
1130
1131
1132static struct pci_driver driver = {
1133 .name = "Digigram LX6464ES",
1134 .id_table = snd_lx6464es_ids,
1135 .probe = snd_lx6464es_probe,
1136 .remove = __devexit_p(snd_lx6464es_remove),
1137};
1138
1139
1140/* module initialization */
1141static int __init mod_init(void)
1142{
1143 return pci_register_driver(&driver);
1144}
1145
1146static void __exit mod_exit(void)
1147{
1148 pci_unregister_driver(&driver);
1149}
1150
1151module_init(mod_init);
1152module_exit(mod_exit);