1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "hpi_internal.h"
26#include "hpimsginit.h"
27#include "hpioctl.h"
28
29#include <linux/pci.h>
30#include <linux/version.h>
31#include <linux/init.h>
32#include <linux/jiffies.h>
33#include <linux/slab.h>
34#include <linux/time.h>
35#include <linux/wait.h>
36#include <sound/core.h>
37#include <sound/control.h>
38#include <sound/pcm.h>
39#include <sound/pcm_params.h>
40#include <sound/info.h>
41#include <sound/initval.h>
42#include <sound/tlv.h>
43#include <sound/hwdep.h>
44
45MODULE_LICENSE("GPL");
46MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
47MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
48
49#if defined CONFIG_SND_DEBUG_VERBOSE
50
51
52
53
54
55
56
57
58#define snd_printddd(format, args...) \
59 __snd_printk(3, __FILE__, __LINE__, format, ##args)
60#else
61#define snd_printddd(format, args...) do { } while (0)
62#endif
63
64static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
65static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
66static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
67static int enable_hpi_hwdep = 1;
68
69module_param_array(index, int, NULL, S_IRUGO);
70MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
71
72module_param_array(id, charp, NULL, S_IRUGO);
73MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
74
75module_param_array(enable, bool, NULL, S_IRUGO);
76MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
77
78module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
79MODULE_PARM_DESC(enable_hpi_hwdep,
80 "ALSA enable HPI hwdep for AudioScience soundcard ");
81
82
83#ifdef KERNEL_ALSA_BUILD
84static char *build_info = "Built using headers from kernel source";
85module_param(build_info, charp, S_IRUGO);
86MODULE_PARM_DESC(build_info, "built using headers from kernel source");
87#else
88static char *build_info = "Built within ALSA source";
89module_param(build_info, charp, S_IRUGO);
90MODULE_PARM_DESC(build_info, "built within ALSA source");
91#endif
92
93
94static const int mixer_dump;
95
96#define DEFAULT_SAMPLERATE 44100
97static int adapter_fs = DEFAULT_SAMPLERATE;
98
99
100#define PERIODS_MIN 2
101#define PERIOD_BYTES_MIN 2048
102#define BUFFER_BYTES_MAX (512 * 1024)
103
104
105#define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C')
106
107
108
109
110
111#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
112
113struct clk_source {
114 int source;
115 int index;
116 char *name;
117};
118
119struct clk_cache {
120 int count;
121 int has_local;
122 struct clk_source s[MAX_CLOCKSOURCES];
123};
124
125
126struct snd_card_asihpi {
127 struct snd_card *card;
128 struct pci_dev *pci;
129 u16 adapter_index;
130 u32 serial_number;
131 u16 type;
132 u16 version;
133 u16 num_outstreams;
134 u16 num_instreams;
135
136 u32 h_mixer;
137 struct clk_cache cc;
138
139 u16 support_mmap;
140 u16 support_grouping;
141 u16 support_mrx;
142 u16 update_interval_frames;
143 u16 in_max_chans;
144 u16 out_max_chans;
145};
146
147
148struct snd_card_asihpi_pcm {
149 struct timer_list timer;
150 unsigned int respawn_timer;
151 unsigned int hpi_buffer_attached;
152 unsigned int buffer_bytes;
153 unsigned int period_bytes;
154 unsigned int bytes_per_sec;
155 unsigned int pcm_buf_host_rw_ofs;
156 unsigned int pcm_buf_dma_ofs;
157 unsigned int pcm_buf_elapsed_dma_ofs;
158 struct snd_pcm_substream *substream;
159 u32 h_stream;
160 struct hpi_format format;
161};
162
163
164
165
166
167static u16 hpi_stream_host_buffer_attach(
168 u32 h_stream,
169 u32 size_in_bytes,
170 u32 pci_address
171)
172{
173 struct hpi_message hm;
174 struct hpi_response hr;
175 unsigned int obj = hpi_handle_object(h_stream);
176
177 if (!h_stream)
178 return HPI_ERROR_INVALID_OBJ;
179 hpi_init_message_response(&hm, &hr, obj,
180 obj == HPI_OBJ_OSTREAM ?
181 HPI_OSTREAM_HOSTBUFFER_ALLOC :
182 HPI_ISTREAM_HOSTBUFFER_ALLOC);
183
184 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
185 &hm.obj_index);
186
187 hm.u.d.u.buffer.buffer_size = size_in_bytes;
188 hm.u.d.u.buffer.pci_address = pci_address;
189 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
190 hpi_send_recv(&hm, &hr);
191 return hr.error;
192}
193
194static u16 hpi_stream_host_buffer_detach(u32 h_stream)
195{
196 struct hpi_message hm;
197 struct hpi_response hr;
198 unsigned int obj = hpi_handle_object(h_stream);
199
200 if (!h_stream)
201 return HPI_ERROR_INVALID_OBJ;
202
203 hpi_init_message_response(&hm, &hr, obj,
204 obj == HPI_OBJ_OSTREAM ?
205 HPI_OSTREAM_HOSTBUFFER_FREE :
206 HPI_ISTREAM_HOSTBUFFER_FREE);
207
208 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
209 &hm.obj_index);
210 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
211 hpi_send_recv(&hm, &hr);
212 return hr.error;
213}
214
215static inline u16 hpi_stream_start(u32 h_stream)
216{
217 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
218 return hpi_outstream_start(h_stream);
219 else
220 return hpi_instream_start(h_stream);
221}
222
223static inline u16 hpi_stream_stop(u32 h_stream)
224{
225 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
226 return hpi_outstream_stop(h_stream);
227 else
228 return hpi_instream_stop(h_stream);
229}
230
231static inline u16 hpi_stream_get_info_ex(
232 u32 h_stream,
233 u16 *pw_state,
234 u32 *pbuffer_size,
235 u32 *pdata_in_buffer,
236 u32 *psample_count,
237 u32 *pauxiliary_data
238)
239{
240 u16 e;
241 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
242 e = hpi_outstream_get_info_ex(h_stream, pw_state,
243 pbuffer_size, pdata_in_buffer,
244 psample_count, pauxiliary_data);
245 else
246 e = hpi_instream_get_info_ex(h_stream, pw_state,
247 pbuffer_size, pdata_in_buffer,
248 psample_count, pauxiliary_data);
249 return e;
250}
251
252static inline u16 hpi_stream_group_add(
253 u32 h_master,
254 u32 h_stream)
255{
256 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
257 return hpi_outstream_group_add(h_master, h_stream);
258 else
259 return hpi_instream_group_add(h_master, h_stream);
260}
261
262static inline u16 hpi_stream_group_reset(u32 h_stream)
263{
264 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
265 return hpi_outstream_group_reset(h_stream);
266 else
267 return hpi_instream_group_reset(h_stream);
268}
269
270static inline u16 hpi_stream_group_get_map(
271 u32 h_stream, u32 *mo, u32 *mi)
272{
273 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
274 return hpi_outstream_group_get_map(h_stream, mo, mi);
275 else
276 return hpi_instream_group_get_map(h_stream, mo, mi);
277}
278
279static u16 handle_error(u16 err, int line, char *filename)
280{
281 if (err)
282 printk(KERN_WARNING
283 "in file %s, line %d: HPI error %d\n",
284 filename, line, err);
285 return err;
286}
287
288#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
289
290
291static void print_hwparams(struct snd_pcm_hw_params *p)
292{
293 snd_printd("HWPARAMS \n");
294 snd_printd("samplerate %d \n", params_rate(p));
295 snd_printd("Channels %d \n", params_channels(p));
296 snd_printd("Format %d \n", params_format(p));
297 snd_printd("subformat %d \n", params_subformat(p));
298 snd_printd("Buffer bytes %d \n", params_buffer_bytes(p));
299 snd_printd("Period bytes %d \n", params_period_bytes(p));
300 snd_printd("access %d \n", params_access(p));
301 snd_printd("period_size %d \n", params_period_size(p));
302 snd_printd("periods %d \n", params_periods(p));
303 snd_printd("buffer_size %d \n", params_buffer_size(p));
304}
305
306static snd_pcm_format_t hpi_to_alsa_formats[] = {
307 -1,
308 SNDRV_PCM_FORMAT_U8,
309 SNDRV_PCM_FORMAT_S16,
310 -1,
311 SNDRV_PCM_FORMAT_MPEG,
312 SNDRV_PCM_FORMAT_MPEG,
313 -1,
314 -1,
315 SNDRV_PCM_FORMAT_S16_BE,
316 -1,
317 -1,
318 SNDRV_PCM_FORMAT_S32,
319 -1,
320 -1,
321 SNDRV_PCM_FORMAT_FLOAT,
322#if 1
323
324
325
326 -1
327#else
328
329#endif
330};
331
332
333static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
334 u16 *hpi_format)
335{
336 u16 format;
337
338 for (format = HPI_FORMAT_PCM8_UNSIGNED;
339 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
340 if (hpi_to_alsa_formats[format] == alsa_format) {
341 *hpi_format = format;
342 return 0;
343 }
344 }
345
346 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
347 alsa_format);
348 *hpi_format = 0;
349 return -EINVAL;
350}
351
352static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
353 struct snd_pcm_hardware *pcmhw)
354{
355 u16 err;
356 u32 h_control;
357 u32 sample_rate;
358 int idx;
359 unsigned int rate_min = 200000;
360 unsigned int rate_max = 0;
361 unsigned int rates = 0;
362
363 if (asihpi->support_mrx) {
364 rates |= SNDRV_PCM_RATE_CONTINUOUS;
365 rates |= SNDRV_PCM_RATE_8000_96000;
366 rate_min = 8000;
367 rate_max = 100000;
368 } else {
369
370
371 err = hpi_mixer_get_control(asihpi->h_mixer,
372 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
373 HPI_CONTROL_SAMPLECLOCK, &h_control);
374 if (err) {
375 snd_printk(KERN_ERR
376 "No local sampleclock, err %d\n", err);
377 }
378
379 for (idx = -1; idx < 100; idx++) {
380 if (idx == -1) {
381 if (hpi_sample_clock_get_sample_rate(h_control,
382 &sample_rate))
383 continue;
384 } else if (hpi_sample_clock_query_local_rate(h_control,
385 idx, &sample_rate)) {
386 break;
387 }
388
389 rate_min = min(rate_min, sample_rate);
390 rate_max = max(rate_max, sample_rate);
391
392 switch (sample_rate) {
393 case 5512:
394 rates |= SNDRV_PCM_RATE_5512;
395 break;
396 case 8000:
397 rates |= SNDRV_PCM_RATE_8000;
398 break;
399 case 11025:
400 rates |= SNDRV_PCM_RATE_11025;
401 break;
402 case 16000:
403 rates |= SNDRV_PCM_RATE_16000;
404 break;
405 case 22050:
406 rates |= SNDRV_PCM_RATE_22050;
407 break;
408 case 32000:
409 rates |= SNDRV_PCM_RATE_32000;
410 break;
411 case 44100:
412 rates |= SNDRV_PCM_RATE_44100;
413 break;
414 case 48000:
415 rates |= SNDRV_PCM_RATE_48000;
416 break;
417 case 64000:
418 rates |= SNDRV_PCM_RATE_64000;
419 break;
420 case 88200:
421 rates |= SNDRV_PCM_RATE_88200;
422 break;
423 case 96000:
424 rates |= SNDRV_PCM_RATE_96000;
425 break;
426 case 176400:
427 rates |= SNDRV_PCM_RATE_176400;
428 break;
429 case 192000:
430 rates |= SNDRV_PCM_RATE_192000;
431 break;
432 default:
433 rates |= SNDRV_PCM_RATE_KNOT;
434 }
435 }
436 }
437
438 pcmhw->rates = rates;
439 pcmhw->rate_min = rate_min;
440 pcmhw->rate_max = rate_max;
441}
442
443static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
444 struct snd_pcm_hw_params *params)
445{
446 struct snd_pcm_runtime *runtime = substream->runtime;
447 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
448 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
449 int err;
450 u16 format;
451 int width;
452 unsigned int bytes_per_sec;
453
454 print_hwparams(params);
455 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
456 if (err < 0)
457 return err;
458 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
459 if (err)
460 return err;
461
462 snd_printdd("format %d, %d chans, %d_hz\n",
463 format, params_channels(params),
464 params_rate(params));
465
466 hpi_handle_error(hpi_format_create(&dpcm->format,
467 params_channels(params),
468 format, params_rate(params), 0, 0));
469
470 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
471 if (hpi_instream_reset(dpcm->h_stream) != 0)
472 return -EINVAL;
473
474 if (hpi_instream_set_format(
475 dpcm->h_stream, &dpcm->format) != 0)
476 return -EINVAL;
477 }
478
479 dpcm->hpi_buffer_attached = 0;
480 if (card->support_mmap) {
481
482 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
483 params_buffer_bytes(params), runtime->dma_addr);
484 if (err == 0) {
485 snd_printdd(
486 "stream_host_buffer_attach succeeded %u %lu\n",
487 params_buffer_bytes(params),
488 (unsigned long)runtime->dma_addr);
489 } else {
490 snd_printd("stream_host_buffer_attach error %d\n",
491 err);
492 return -ENOMEM;
493 }
494
495 err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
496 &dpcm->hpi_buffer_attached,
497 NULL, NULL, NULL);
498
499 snd_printdd("stream_host_buffer_attach status 0x%x\n",
500 dpcm->hpi_buffer_attached);
501 }
502 bytes_per_sec = params_rate(params) * params_channels(params);
503 width = snd_pcm_format_width(params_format(params));
504 bytes_per_sec *= width;
505 bytes_per_sec /= 8;
506 if (width < 0 || bytes_per_sec == 0)
507 return -EINVAL;
508
509 dpcm->bytes_per_sec = bytes_per_sec;
510 dpcm->buffer_bytes = params_buffer_bytes(params);
511 dpcm->period_bytes = params_period_bytes(params);
512 snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n",
513 dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec);
514
515 return 0;
516}
517
518static int
519snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
520{
521 struct snd_pcm_runtime *runtime = substream->runtime;
522 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
523 if (dpcm->hpi_buffer_attached)
524 hpi_stream_host_buffer_detach(dpcm->h_stream);
525
526 snd_pcm_lib_free_pages(substream);
527 return 0;
528}
529
530static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
531{
532 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
533 kfree(dpcm);
534}
535
536static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
537 substream)
538{
539 struct snd_pcm_runtime *runtime = substream->runtime;
540 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
541 int expiry;
542
543 expiry = HZ / 200;
544
545 expiry = max(expiry, 1);
546 dpcm->timer.expires = jiffies + expiry;
547 dpcm->respawn_timer = 1;
548 add_timer(&dpcm->timer);
549}
550
551static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
552{
553 struct snd_pcm_runtime *runtime = substream->runtime;
554 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
555
556 dpcm->respawn_timer = 0;
557 del_timer(&dpcm->timer);
558}
559
560static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
561 int cmd)
562{
563 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
564 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
565 struct snd_pcm_substream *s;
566 u16 e;
567
568 snd_printdd("%c%d trigger\n",
569 SCHR(substream->stream), substream->number);
570 switch (cmd) {
571 case SNDRV_PCM_TRIGGER_START:
572 snd_pcm_group_for_each_entry(s, substream) {
573 struct snd_pcm_runtime *runtime = s->runtime;
574 struct snd_card_asihpi_pcm *ds = runtime->private_data;
575
576 if (snd_pcm_substream_chip(s) != card)
577 continue;
578
579
580 if (substream->stream != s->stream)
581 continue;
582
583 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
584 (card->support_mmap)) {
585
586
587
588
589
590
591 unsigned int preload = ds->period_bytes * 1;
592 snd_printddd("%d preload x%x\n", s->number, preload);
593 hpi_handle_error(hpi_outstream_write_buf(
594 ds->h_stream,
595 &runtime->dma_area[0],
596 preload,
597 &ds->format));
598 ds->pcm_buf_host_rw_ofs = preload;
599 }
600
601 if (card->support_grouping) {
602 snd_printdd("\t%c%d group\n",
603 SCHR(s->stream),
604 s->number);
605 e = hpi_stream_group_add(
606 dpcm->h_stream,
607 ds->h_stream);
608 if (!e) {
609 snd_pcm_trigger_done(s, substream);
610 } else {
611 hpi_handle_error(e);
612 break;
613 }
614 } else
615 break;
616 }
617 snd_printdd("start\n");
618
619 snd_card_asihpi_pcm_timer_start(substream);
620 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
621 !card->support_mmap)
622 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
623 break;
624
625 case SNDRV_PCM_TRIGGER_STOP:
626 snd_card_asihpi_pcm_timer_stop(substream);
627 snd_pcm_group_for_each_entry(s, substream) {
628 if (snd_pcm_substream_chip(s) != card)
629 continue;
630
631 if (substream->stream != s->stream)
632 continue;
633
634
635
636 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
637
638 if (card->support_grouping) {
639 snd_printdd("\t%c%d group\n",
640 SCHR(s->stream),
641 s->number);
642 snd_pcm_trigger_done(s, substream);
643 } else
644 break;
645 }
646 snd_printdd("stop\n");
647
648
649 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
650 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
651 hpi_handle_error(
652 hpi_outstream_reset(dpcm->h_stream));
653
654 if (card->support_grouping)
655 hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
656 break;
657
658 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
659 snd_printdd("pause release\n");
660 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
661 snd_card_asihpi_pcm_timer_start(substream);
662 break;
663 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
664 snd_printdd("pause\n");
665 snd_card_asihpi_pcm_timer_stop(substream);
666 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
667 break;
668 default:
669 snd_printd(KERN_ERR "\tINVALID\n");
670 return -EINVAL;
671 }
672
673 return 0;
674}
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707static inline unsigned int modulo_min(unsigned int a, unsigned int b,
708 unsigned long int modulus)
709{
710 unsigned int result;
711 if (((a-b) % modulus) < (modulus/2))
712 result = b;
713 else
714 result = a;
715
716 return result;
717}
718
719
720
721static void snd_card_asihpi_timer_function(unsigned long data)
722{
723 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
724 struct snd_pcm_substream *substream = dpcm->substream;
725 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
726 struct snd_pcm_runtime *runtime;
727 struct snd_pcm_substream *s;
728 unsigned int newdata = 0;
729 unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
730 unsigned int remdata, xfercount, next_jiffies;
731 int first = 1;
732 int loops = 0;
733 u16 state;
734 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
735
736 snd_printdd("%c%d snd_card_asihpi_timer_function\n",
737 SCHR(substream->stream), substream->number);
738
739
740 snd_pcm_group_for_each_entry(s, substream) {
741 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
742 runtime = s->runtime;
743
744 if (snd_pcm_substream_chip(s) != card)
745 continue;
746
747
748 if (substream->stream != s->stream)
749 continue;
750
751 hpi_handle_error(hpi_stream_get_info_ex(
752 ds->h_stream, &state,
753 &buffer_size, &bytes_avail,
754 &samples_played, &on_card_bytes));
755
756
757 runtime->delay = on_card_bytes;
758
759 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
760 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
761 if (state == HPI_STATE_STOPPED) {
762 if ((bytes_avail == 0) &&
763 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
764 hpi_handle_error(hpi_stream_start(ds->h_stream));
765 snd_printdd("P%d start\n", s->number);
766 }
767 } else if (state == HPI_STATE_DRAINED) {
768 snd_printd(KERN_WARNING "P%d drained\n",
769 s->number);
770
771
772 }
773 } else
774 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
775
776 if (first) {
777
778 min_buf_pos = pcm_buf_dma_ofs;
779 newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
780 first = 0;
781 } else {
782 min_buf_pos =
783 modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
784 newdata = min(
785 (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
786 newdata);
787 }
788
789 snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n",
790 (unsigned long)frames_to_bytes(runtime,
791 runtime->status->hw_ptr),
792 (unsigned long)frames_to_bytes(runtime,
793 runtime->control->appl_ptr));
794
795 snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X,"
796 " aux=x%04X space=x%04X\n",
797 loops, SCHR(s->stream), s->number,
798 state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail,
799 (int)on_card_bytes, buffer_size-bytes_avail);
800 loops++;
801 }
802 pcm_buf_dma_ofs = min_buf_pos;
803
804 remdata = newdata % dpcm->period_bytes;
805 xfercount = newdata - remdata;
806
807
808
809
810 if (xfercount && (on_card_bytes > dpcm->period_bytes))
811 next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
812 else
813 next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
814
815 next_jiffies = max(next_jiffies, 1U);
816 dpcm->timer.expires = jiffies + next_jiffies;
817 snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n",
818 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
819
820 snd_pcm_group_for_each_entry(s, substream) {
821 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
822
823
824 if (substream->stream != s->stream)
825 continue;
826
827 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
828
829 if (xfercount && (on_card_bytes <= ds->period_bytes)) {
830 if (card->support_mmap) {
831 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
832 snd_printddd("P%d write x%04x\n",
833 s->number,
834 ds->period_bytes);
835 hpi_handle_error(
836 hpi_outstream_write_buf(
837 ds->h_stream,
838 &s->runtime->
839 dma_area[0],
840 xfercount,
841 &ds->format));
842 } else {
843 snd_printddd("C%d read x%04x\n",
844 s->number,
845 xfercount);
846 hpi_handle_error(
847 hpi_instream_read_buf(
848 ds->h_stream,
849 NULL, xfercount));
850 }
851 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
852 }
853 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
854 snd_pcm_period_elapsed(s);
855 }
856 }
857
858 if (dpcm->respawn_timer)
859 add_timer(&dpcm->timer);
860}
861
862
863static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
864 unsigned int cmd, void *arg)
865{
866 snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd);
867 return snd_pcm_lib_ioctl(substream, cmd, arg);
868}
869
870static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
871 substream)
872{
873 struct snd_pcm_runtime *runtime = substream->runtime;
874 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
875
876 snd_printdd("playback prepare %d\n", substream->number);
877
878 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
879 dpcm->pcm_buf_host_rw_ofs = 0;
880 dpcm->pcm_buf_dma_ofs = 0;
881 dpcm->pcm_buf_elapsed_dma_ofs = 0;
882 return 0;
883}
884
885static snd_pcm_uframes_t
886snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
887{
888 struct snd_pcm_runtime *runtime = substream->runtime;
889 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
890 snd_pcm_uframes_t ptr;
891
892 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
893 snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr);
894 return ptr;
895}
896
897static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
898 u32 h_stream,
899 struct snd_pcm_hardware *pcmhw)
900{
901 struct hpi_format hpi_format;
902 u16 format;
903 u16 err;
904 u32 h_control;
905 u32 sample_rate = 48000;
906
907
908
909
910 err = hpi_mixer_get_control(asihpi->h_mixer,
911 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
912 HPI_CONTROL_SAMPLECLOCK, &h_control);
913
914 if (!err)
915 err = hpi_sample_clock_get_sample_rate(h_control,
916 &sample_rate);
917
918 for (format = HPI_FORMAT_PCM8_UNSIGNED;
919 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
920 err = hpi_format_create(&hpi_format,
921 2, format, sample_rate, 128000, 0);
922 if (!err)
923 err = hpi_outstream_query_format(h_stream,
924 &hpi_format);
925 if (!err && (hpi_to_alsa_formats[format] != -1))
926 pcmhw->formats |=
927 (1ULL << hpi_to_alsa_formats[format]);
928 }
929}
930
931static struct snd_pcm_hardware snd_card_asihpi_playback = {
932 .channels_min = 1,
933 .channels_max = 2,
934 .buffer_bytes_max = BUFFER_BYTES_MAX,
935 .period_bytes_min = PERIOD_BYTES_MIN,
936 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
937 .periods_min = PERIODS_MIN,
938 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
939 .fifo_size = 0,
940};
941
942static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
943{
944 struct snd_pcm_runtime *runtime = substream->runtime;
945 struct snd_card_asihpi_pcm *dpcm;
946 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
947 int err;
948
949 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
950 if (dpcm == NULL)
951 return -ENOMEM;
952
953 err =
954 hpi_outstream_open(card->adapter_index,
955 substream->number, &dpcm->h_stream);
956 hpi_handle_error(err);
957 if (err)
958 kfree(dpcm);
959 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
960 return -EBUSY;
961 if (err)
962 return -EIO;
963
964
965
966
967
968
969 init_timer(&dpcm->timer);
970 dpcm->timer.data = (unsigned long) dpcm;
971 dpcm->timer.function = snd_card_asihpi_timer_function;
972 dpcm->substream = substream;
973 runtime->private_data = dpcm;
974 runtime->private_free = snd_card_asihpi_runtime_free;
975
976 snd_card_asihpi_playback.channels_max = card->out_max_chans;
977
978
979
980 snd_card_asihpi_playback_format(card, dpcm->h_stream,
981 &snd_card_asihpi_playback);
982
983 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
984
985 snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
986 SNDRV_PCM_INFO_DOUBLE |
987 SNDRV_PCM_INFO_BATCH |
988 SNDRV_PCM_INFO_BLOCK_TRANSFER |
989 SNDRV_PCM_INFO_PAUSE;
990
991 if (card->support_mmap)
992 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
993 SNDRV_PCM_INFO_MMAP_VALID;
994
995 if (card->support_grouping)
996 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
997
998
999 runtime->hw = snd_card_asihpi_playback;
1000
1001 if (card->support_mmap)
1002 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1003 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1004 if (err < 0)
1005 return err;
1006
1007 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1008 card->update_interval_frames);
1009
1010 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1011 card->update_interval_frames * 2, UINT_MAX);
1012
1013 snd_pcm_set_sync(substream);
1014
1015 snd_printdd("playback open\n");
1016
1017 return 0;
1018}
1019
1020static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1021{
1022 struct snd_pcm_runtime *runtime = substream->runtime;
1023 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1024
1025 hpi_handle_error(hpi_outstream_close(dpcm->h_stream));
1026 snd_printdd("playback close\n");
1027
1028 return 0;
1029}
1030
1031static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1032 int channel,
1033 snd_pcm_uframes_t pos,
1034 void __user *src,
1035 snd_pcm_uframes_t count)
1036{
1037 struct snd_pcm_runtime *runtime = substream->runtime;
1038 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1039 unsigned int len;
1040
1041 len = frames_to_bytes(runtime, count);
1042
1043 if (copy_from_user(runtime->dma_area, src, len))
1044 return -EFAULT;
1045
1046 snd_printddd("playback copy%d %u bytes\n",
1047 substream->number, len);
1048
1049 hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream,
1050 runtime->dma_area, len, &dpcm->format));
1051
1052 dpcm->pcm_buf_host_rw_ofs += len;
1053
1054 return 0;
1055}
1056
1057static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1058 substream, int channel,
1059 snd_pcm_uframes_t pos,
1060 snd_pcm_uframes_t count)
1061{
1062
1063
1064
1065
1066
1067 return 0;
1068}
1069
1070static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1071 .open = snd_card_asihpi_playback_open,
1072 .close = snd_card_asihpi_playback_close,
1073 .ioctl = snd_card_asihpi_playback_ioctl,
1074 .hw_params = snd_card_asihpi_pcm_hw_params,
1075 .hw_free = snd_card_asihpi_hw_free,
1076 .prepare = snd_card_asihpi_playback_prepare,
1077 .trigger = snd_card_asihpi_trigger,
1078 .pointer = snd_card_asihpi_playback_pointer,
1079 .copy = snd_card_asihpi_playback_copy,
1080 .silence = snd_card_asihpi_playback_silence,
1081};
1082
1083static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1084 .open = snd_card_asihpi_playback_open,
1085 .close = snd_card_asihpi_playback_close,
1086 .ioctl = snd_card_asihpi_playback_ioctl,
1087 .hw_params = snd_card_asihpi_pcm_hw_params,
1088 .hw_free = snd_card_asihpi_hw_free,
1089 .prepare = snd_card_asihpi_playback_prepare,
1090 .trigger = snd_card_asihpi_trigger,
1091 .pointer = snd_card_asihpi_playback_pointer,
1092};
1093
1094
1095static snd_pcm_uframes_t
1096snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1097{
1098 struct snd_pcm_runtime *runtime = substream->runtime;
1099 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1100
1101 snd_printddd("capture pointer %d=%d\n",
1102 substream->number, dpcm->pcm_buf_dma_ofs);
1103
1104
1105
1106
1107 return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
1108}
1109
1110static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1111 unsigned int cmd, void *arg)
1112{
1113 return snd_pcm_lib_ioctl(substream, cmd, arg);
1114}
1115
1116static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1117{
1118 struct snd_pcm_runtime *runtime = substream->runtime;
1119 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1120
1121 hpi_handle_error(hpi_instream_reset(dpcm->h_stream));
1122 dpcm->pcm_buf_host_rw_ofs = 0;
1123 dpcm->pcm_buf_dma_ofs = 0;
1124 dpcm->pcm_buf_elapsed_dma_ofs = 0;
1125
1126 snd_printdd("Capture Prepare %d\n", substream->number);
1127 return 0;
1128}
1129
1130
1131
1132static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1133 u32 h_stream,
1134 struct snd_pcm_hardware *pcmhw)
1135{
1136 struct hpi_format hpi_format;
1137 u16 format;
1138 u16 err;
1139 u32 h_control;
1140 u32 sample_rate = 48000;
1141
1142
1143
1144 err = hpi_mixer_get_control(asihpi->h_mixer,
1145 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1146 HPI_CONTROL_SAMPLECLOCK, &h_control);
1147
1148 if (!err)
1149 err = hpi_sample_clock_get_sample_rate(h_control,
1150 &sample_rate);
1151
1152 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1153 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1154
1155 err = hpi_format_create(&hpi_format, 2, format,
1156 sample_rate, 128000, 0);
1157 if (!err)
1158 err = hpi_instream_query_format(h_stream,
1159 &hpi_format);
1160 if (!err)
1161 pcmhw->formats |=
1162 (1ULL << hpi_to_alsa_formats[format]);
1163 }
1164}
1165
1166
1167static struct snd_pcm_hardware snd_card_asihpi_capture = {
1168 .channels_min = 1,
1169 .channels_max = 2,
1170 .buffer_bytes_max = BUFFER_BYTES_MAX,
1171 .period_bytes_min = PERIOD_BYTES_MIN,
1172 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1173 .periods_min = PERIODS_MIN,
1174 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1175 .fifo_size = 0,
1176};
1177
1178static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1179{
1180 struct snd_pcm_runtime *runtime = substream->runtime;
1181 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1182 struct snd_card_asihpi_pcm *dpcm;
1183 int err;
1184
1185 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1186 if (dpcm == NULL)
1187 return -ENOMEM;
1188
1189 snd_printdd("capture open adapter %d stream %d\n",
1190 card->adapter_index, substream->number);
1191
1192 err = hpi_handle_error(
1193 hpi_instream_open(card->adapter_index,
1194 substream->number, &dpcm->h_stream));
1195 if (err)
1196 kfree(dpcm);
1197 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1198 return -EBUSY;
1199 if (err)
1200 return -EIO;
1201
1202
1203 init_timer(&dpcm->timer);
1204 dpcm->timer.data = (unsigned long) dpcm;
1205 dpcm->timer.function = snd_card_asihpi_timer_function;
1206 dpcm->substream = substream;
1207 runtime->private_data = dpcm;
1208 runtime->private_free = snd_card_asihpi_runtime_free;
1209
1210 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1211 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1212 &snd_card_asihpi_capture);
1213 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1214 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED;
1215
1216 if (card->support_mmap)
1217 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1218 SNDRV_PCM_INFO_MMAP_VALID;
1219
1220 if (card->support_grouping)
1221 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1222
1223 runtime->hw = snd_card_asihpi_capture;
1224
1225 if (card->support_mmap)
1226 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1227 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1228 if (err < 0)
1229 return err;
1230
1231 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1232 card->update_interval_frames);
1233 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1234 card->update_interval_frames * 2, UINT_MAX);
1235
1236 snd_pcm_set_sync(substream);
1237
1238 return 0;
1239}
1240
1241static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1242{
1243 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1244
1245 hpi_handle_error(hpi_instream_close(dpcm->h_stream));
1246 return 0;
1247}
1248
1249static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1250 int channel, snd_pcm_uframes_t pos,
1251 void __user *dst, snd_pcm_uframes_t count)
1252{
1253 struct snd_pcm_runtime *runtime = substream->runtime;
1254 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1255 u32 len;
1256
1257 len = frames_to_bytes(runtime, count);
1258
1259 snd_printddd("capture copy%d %d bytes\n", substream->number, len);
1260 hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream,
1261 runtime->dma_area, len));
1262
1263 dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
1264
1265 if (copy_to_user(dst, runtime->dma_area, len))
1266 return -EFAULT;
1267
1268 return 0;
1269}
1270
1271static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1272 .open = snd_card_asihpi_capture_open,
1273 .close = snd_card_asihpi_capture_close,
1274 .ioctl = snd_card_asihpi_capture_ioctl,
1275 .hw_params = snd_card_asihpi_pcm_hw_params,
1276 .hw_free = snd_card_asihpi_hw_free,
1277 .prepare = snd_card_asihpi_capture_prepare,
1278 .trigger = snd_card_asihpi_trigger,
1279 .pointer = snd_card_asihpi_capture_pointer,
1280};
1281
1282static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1283 .open = snd_card_asihpi_capture_open,
1284 .close = snd_card_asihpi_capture_close,
1285 .ioctl = snd_card_asihpi_capture_ioctl,
1286 .hw_params = snd_card_asihpi_pcm_hw_params,
1287 .hw_free = snd_card_asihpi_hw_free,
1288 .prepare = snd_card_asihpi_capture_prepare,
1289 .trigger = snd_card_asihpi_trigger,
1290 .pointer = snd_card_asihpi_capture_pointer,
1291 .copy = snd_card_asihpi_capture_copy
1292};
1293
1294static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1295 int device, int substreams)
1296{
1297 struct snd_pcm *pcm;
1298 int err;
1299
1300 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1301 asihpi->num_outstreams, asihpi->num_instreams,
1302 &pcm);
1303 if (err < 0)
1304 return err;
1305
1306 if (asihpi->support_mmap) {
1307 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1308 &snd_card_asihpi_playback_mmap_ops);
1309 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1310 &snd_card_asihpi_capture_mmap_ops);
1311 } else {
1312 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1313 &snd_card_asihpi_playback_ops);
1314 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1315 &snd_card_asihpi_capture_ops);
1316 }
1317
1318 pcm->private_data = asihpi;
1319 pcm->info_flags = 0;
1320 strcpy(pcm->name, "Asihpi PCM");
1321
1322
1323
1324 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1325 snd_dma_pci_data(asihpi->pci),
1326 64*1024, BUFFER_BYTES_MAX);
1327
1328 return 0;
1329}
1330
1331
1332struct hpi_control {
1333 u32 h_control;
1334 u16 control_type;
1335 u16 src_node_type;
1336 u16 src_node_index;
1337 u16 dst_node_type;
1338 u16 dst_node_index;
1339 u16 band;
1340 char name[44];
1341};
1342
1343static const char * const asihpi_tuner_band_names[] = {
1344 "invalid",
1345 "AM",
1346 "FM mono",
1347 "TV NTSC-M",
1348 "FM stereo",
1349 "AUX",
1350 "TV PAL BG",
1351 "TV PAL I",
1352 "TV PAL DK",
1353 "TV SECAM",
1354};
1355
1356compile_time_assert(
1357 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1358 (HPI_TUNER_BAND_LAST+1)),
1359 assert_tuner_band_names_size);
1360
1361static const char * const asihpi_src_names[] = {
1362 "no source",
1363 "PCM",
1364 "Line",
1365 "Digital",
1366 "Tuner",
1367 "RF",
1368 "Clock",
1369 "Bitstream",
1370 "Microphone",
1371 "Cobranet",
1372 "Analog",
1373 "Adapter",
1374};
1375
1376compile_time_assert(
1377 (ARRAY_SIZE(asihpi_src_names) ==
1378 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1379 assert_src_names_size);
1380
1381static const char * const asihpi_dst_names[] = {
1382 "no destination",
1383 "PCM",
1384 "Line",
1385 "Digital",
1386 "RF",
1387 "Speaker",
1388 "Cobranet Out",
1389 "Analog"
1390};
1391
1392compile_time_assert(
1393 (ARRAY_SIZE(asihpi_dst_names) ==
1394 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1395 assert_dst_names_size);
1396
1397static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1398 struct snd_card_asihpi *asihpi)
1399{
1400 int err;
1401
1402 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1403 if (err < 0)
1404 return err;
1405 else if (mixer_dump)
1406 snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1407
1408 return 0;
1409}
1410
1411
1412static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1413 struct hpi_control *hpi_ctl,
1414 char *name)
1415{
1416 char *dir = "";
1417 memset(snd_control, 0, sizeof(*snd_control));
1418 snd_control->name = hpi_ctl->name;
1419 snd_control->private_value = hpi_ctl->h_control;
1420 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1421 snd_control->index = 0;
1422
1423 if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1424 dir = "Capture ";
1425 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1426 (!hpi_ctl->dst_node_type))
1427 dir = "Capture ";
1428 else if (hpi_ctl->src_node_type &&
1429 (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1430 (hpi_ctl->dst_node_type))
1431 dir = "Monitor Playback ";
1432 else
1433 dir = "Playback ";
1434
1435 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1436 sprintf(hpi_ctl->name, "%s%d %s%d %s%s",
1437 asihpi_src_names[hpi_ctl->src_node_type],
1438 hpi_ctl->src_node_index,
1439 asihpi_dst_names[hpi_ctl->dst_node_type],
1440 hpi_ctl->dst_node_index,
1441 dir, name);
1442 else if (hpi_ctl->dst_node_type) {
1443 sprintf(hpi_ctl->name, "%s %d %s%s",
1444 asihpi_dst_names[hpi_ctl->dst_node_type],
1445 hpi_ctl->dst_node_index,
1446 dir, name);
1447 } else {
1448 sprintf(hpi_ctl->name, "%s %d %s%s",
1449 asihpi_src_names[hpi_ctl->src_node_type],
1450 hpi_ctl->src_node_index,
1451 dir, name);
1452 }
1453
1454
1455}
1456
1457
1458
1459
1460#define VOL_STEP_mB 1
1461static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1462 struct snd_ctl_elem_info *uinfo)
1463{
1464 u32 h_control = kcontrol->private_value;
1465 u16 err;
1466
1467 short min_gain_mB;
1468 short max_gain_mB;
1469 short step_gain_mB;
1470
1471 err = hpi_volume_query_range(h_control,
1472 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1473 if (err) {
1474 max_gain_mB = 0;
1475 min_gain_mB = -10000;
1476 step_gain_mB = VOL_STEP_mB;
1477 }
1478
1479 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1480 uinfo->count = 2;
1481 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1482 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1483 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1484 return 0;
1485}
1486
1487static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1488 struct snd_ctl_elem_value *ucontrol)
1489{
1490 u32 h_control = kcontrol->private_value;
1491 short an_gain_mB[HPI_MAX_CHANNELS];
1492
1493 hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB));
1494 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1495 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1496
1497 return 0;
1498}
1499
1500static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1501 struct snd_ctl_elem_value *ucontrol)
1502{
1503 int change;
1504 u32 h_control = kcontrol->private_value;
1505 short an_gain_mB[HPI_MAX_CHANNELS];
1506
1507 an_gain_mB[0] =
1508 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1509 an_gain_mB[1] =
1510 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1511
1512
1513
1514 change = 1;
1515 hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
1516 return change;
1517}
1518
1519static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1520
1521static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1522 struct hpi_control *hpi_ctl)
1523{
1524 struct snd_card *card = asihpi->card;
1525 struct snd_kcontrol_new snd_control;
1526
1527 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
1528 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1529 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1530 snd_control.info = snd_asihpi_volume_info;
1531 snd_control.get = snd_asihpi_volume_get;
1532 snd_control.put = snd_asihpi_volume_put;
1533 snd_control.tlv.p = db_scale_100;
1534
1535 return ctl_add(card, &snd_control, asihpi);
1536}
1537
1538
1539
1540
1541static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1542 struct snd_ctl_elem_info *uinfo)
1543{
1544 u32 h_control = kcontrol->private_value;
1545 u16 err;
1546 short min_gain_mB;
1547 short max_gain_mB;
1548 short step_gain_mB;
1549
1550 err =
1551 hpi_level_query_range(h_control, &min_gain_mB,
1552 &max_gain_mB, &step_gain_mB);
1553 if (err) {
1554 max_gain_mB = 2400;
1555 min_gain_mB = -1000;
1556 step_gain_mB = 100;
1557 }
1558
1559 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1560 uinfo->count = 2;
1561 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1562 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1563 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1564 return 0;
1565}
1566
1567static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1568 struct snd_ctl_elem_value *ucontrol)
1569{
1570 u32 h_control = kcontrol->private_value;
1571 short an_gain_mB[HPI_MAX_CHANNELS];
1572
1573 hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
1574 ucontrol->value.integer.value[0] =
1575 an_gain_mB[0] / HPI_UNITS_PER_dB;
1576 ucontrol->value.integer.value[1] =
1577 an_gain_mB[1] / HPI_UNITS_PER_dB;
1578
1579 return 0;
1580}
1581
1582static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1583 struct snd_ctl_elem_value *ucontrol)
1584{
1585 int change;
1586 u32 h_control = kcontrol->private_value;
1587 short an_gain_mB[HPI_MAX_CHANNELS];
1588
1589 an_gain_mB[0] =
1590 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1591 an_gain_mB[1] =
1592 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1593
1594
1595
1596 change = 1;
1597 hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
1598 return change;
1599}
1600
1601static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1602
1603static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1604 struct hpi_control *hpi_ctl)
1605{
1606 struct snd_card *card = asihpi->card;
1607 struct snd_kcontrol_new snd_control;
1608
1609
1610 asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
1611 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1612 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1613 snd_control.info = snd_asihpi_level_info;
1614 snd_control.get = snd_asihpi_level_get;
1615 snd_control.put = snd_asihpi_level_put;
1616 snd_control.tlv.p = db_scale_level;
1617
1618 return ctl_add(card, &snd_control, asihpi);
1619}
1620
1621
1622
1623
1624
1625
1626static const char * const asihpi_aesebu_format_names[] = {
1627 "N/A", "S/PDIF", "AES/EBU" };
1628
1629static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1630 struct snd_ctl_elem_info *uinfo)
1631{
1632 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1633 uinfo->count = 1;
1634 uinfo->value.enumerated.items = 3;
1635
1636 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1637 uinfo->value.enumerated.item =
1638 uinfo->value.enumerated.items - 1;
1639
1640 strcpy(uinfo->value.enumerated.name,
1641 asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1642
1643 return 0;
1644}
1645
1646static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1647 struct snd_ctl_elem_value *ucontrol,
1648 u16 (*func)(u32, u16 *))
1649{
1650 u32 h_control = kcontrol->private_value;
1651 u16 source, err;
1652
1653 err = func(h_control, &source);
1654
1655
1656 ucontrol->value.enumerated.item[0] = 0;
1657
1658 if (err)
1659 return 0;
1660 if (source == HPI_AESEBU_FORMAT_SPDIF)
1661 ucontrol->value.enumerated.item[0] = 1;
1662 if (source == HPI_AESEBU_FORMAT_AESEBU)
1663 ucontrol->value.enumerated.item[0] = 2;
1664
1665 return 0;
1666}
1667
1668static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1669 struct snd_ctl_elem_value *ucontrol,
1670 u16 (*func)(u32, u16))
1671{
1672 u32 h_control = kcontrol->private_value;
1673
1674
1675 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1676
1677 if (ucontrol->value.enumerated.item[0] == 1)
1678 source = HPI_AESEBU_FORMAT_SPDIF;
1679 if (ucontrol->value.enumerated.item[0] == 2)
1680 source = HPI_AESEBU_FORMAT_AESEBU;
1681
1682 if (func(h_control, source) != 0)
1683 return -EINVAL;
1684
1685 return 1;
1686}
1687
1688static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1689 struct snd_ctl_elem_value *ucontrol) {
1690 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1691 hpi_aesebu_receiver_get_format);
1692}
1693
1694static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1695 struct snd_ctl_elem_value *ucontrol) {
1696 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1697 hpi_aesebu_receiver_set_format);
1698}
1699
1700static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1701 struct snd_ctl_elem_info *uinfo)
1702{
1703 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1704 uinfo->count = 1;
1705
1706 uinfo->value.integer.min = 0;
1707 uinfo->value.integer.max = 0X1F;
1708 uinfo->value.integer.step = 1;
1709
1710 return 0;
1711}
1712
1713static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1714 struct snd_ctl_elem_value *ucontrol) {
1715
1716 u32 h_control = kcontrol->private_value;
1717 u16 status;
1718
1719 hpi_handle_error(hpi_aesebu_receiver_get_error_status(
1720 h_control, &status));
1721 ucontrol->value.integer.value[0] = status;
1722 return 0;
1723}
1724
1725static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1726 struct hpi_control *hpi_ctl)
1727{
1728 struct snd_card *card = asihpi->card;
1729 struct snd_kcontrol_new snd_control;
1730
1731 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1732 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1733 snd_control.info = snd_asihpi_aesebu_format_info;
1734 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1735 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1736
1737
1738 if (ctl_add(card, &snd_control, asihpi) < 0)
1739 return -EINVAL;
1740
1741 asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
1742 snd_control.access =
1743 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1744 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1745 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1746
1747 return ctl_add(card, &snd_control, asihpi);
1748}
1749
1750static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1751 struct snd_ctl_elem_value *ucontrol) {
1752 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1753 hpi_aesebu_transmitter_get_format);
1754}
1755
1756static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1757 struct snd_ctl_elem_value *ucontrol) {
1758 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1759 hpi_aesebu_transmitter_set_format);
1760}
1761
1762
1763static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1764 struct hpi_control *hpi_ctl)
1765{
1766 struct snd_card *card = asihpi->card;
1767 struct snd_kcontrol_new snd_control;
1768
1769 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1770 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1771 snd_control.info = snd_asihpi_aesebu_format_info;
1772 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1773 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1774
1775 return ctl_add(card, &snd_control, asihpi);
1776}
1777
1778
1779
1780
1781
1782
1783
1784static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1785 struct snd_ctl_elem_info *uinfo)
1786{
1787 u32 h_control = kcontrol->private_value;
1788 u16 err;
1789 short idx;
1790 u16 gain_range[3];
1791
1792 for (idx = 0; idx < 3; idx++) {
1793 err = hpi_tuner_query_gain(h_control,
1794 idx, &gain_range[idx]);
1795 if (err != 0)
1796 return err;
1797 }
1798
1799 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1800 uinfo->count = 1;
1801 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1802 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1803 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1804 return 0;
1805}
1806
1807static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1808 struct snd_ctl_elem_value *ucontrol)
1809{
1810
1811
1812
1813 u32 h_control = kcontrol->private_value;
1814 short gain;
1815
1816 hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
1817 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1818
1819 return 0;
1820}
1821
1822static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1823 struct snd_ctl_elem_value *ucontrol)
1824{
1825
1826
1827
1828 u32 h_control = kcontrol->private_value;
1829 short gain;
1830
1831 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1832 hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
1833
1834 return 1;
1835}
1836
1837
1838
1839static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1840 u16 *band_list, u32 len) {
1841 u32 h_control = kcontrol->private_value;
1842 u16 err = 0;
1843 u32 i;
1844
1845 for (i = 0; i < len; i++) {
1846 err = hpi_tuner_query_band(
1847 h_control, i, &band_list[i]);
1848 if (err != 0)
1849 break;
1850 }
1851
1852 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1853 return -EIO;
1854
1855 return i;
1856}
1857
1858static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1859 struct snd_ctl_elem_info *uinfo)
1860{
1861 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1862 int num_bands = 0;
1863
1864 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1865 HPI_TUNER_BAND_LAST);
1866
1867 if (num_bands < 0)
1868 return num_bands;
1869
1870 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1871 uinfo->count = 1;
1872 uinfo->value.enumerated.items = num_bands;
1873
1874 if (num_bands > 0) {
1875 if (uinfo->value.enumerated.item >=
1876 uinfo->value.enumerated.items)
1877 uinfo->value.enumerated.item =
1878 uinfo->value.enumerated.items - 1;
1879
1880 strcpy(uinfo->value.enumerated.name,
1881 asihpi_tuner_band_names[
1882 tuner_bands[uinfo->value.enumerated.item]]);
1883
1884 }
1885 return 0;
1886}
1887
1888static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1889 struct snd_ctl_elem_value *ucontrol)
1890{
1891 u32 h_control = kcontrol->private_value;
1892
1893
1894
1895 u16 band, idx;
1896 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1897 u32 num_bands = 0;
1898
1899 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1900 HPI_TUNER_BAND_LAST);
1901
1902 hpi_handle_error(hpi_tuner_get_band(h_control, &band));
1903
1904 ucontrol->value.enumerated.item[0] = -1;
1905 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1906 if (tuner_bands[idx] == band) {
1907 ucontrol->value.enumerated.item[0] = idx;
1908 break;
1909 }
1910
1911 return 0;
1912}
1913
1914static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1915 struct snd_ctl_elem_value *ucontrol)
1916{
1917
1918
1919
1920 u32 h_control = kcontrol->private_value;
1921 u16 band;
1922 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1923 u32 num_bands = 0;
1924
1925 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1926 HPI_TUNER_BAND_LAST);
1927
1928 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1929 hpi_handle_error(hpi_tuner_set_band(h_control, band));
1930
1931 return 1;
1932}
1933
1934
1935
1936static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1937 struct snd_ctl_elem_info *uinfo)
1938{
1939 u32 h_control = kcontrol->private_value;
1940 u16 err;
1941 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1942 u16 num_bands = 0, band_iter, idx;
1943 u32 freq_range[3], temp_freq_range[3];
1944
1945 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1946 HPI_TUNER_BAND_LAST);
1947
1948 freq_range[0] = INT_MAX;
1949 freq_range[1] = 0;
1950 freq_range[2] = INT_MAX;
1951
1952 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1953 for (idx = 0; idx < 3; idx++) {
1954 err = hpi_tuner_query_frequency(h_control,
1955 idx, tuner_bands[band_iter],
1956 &temp_freq_range[idx]);
1957 if (err != 0)
1958 return err;
1959 }
1960
1961
1962 if (temp_freq_range[2] <= 0)
1963 continue;
1964
1965 if (temp_freq_range[0] < freq_range[0])
1966 freq_range[0] = temp_freq_range[0];
1967 if (temp_freq_range[1] > freq_range[1])
1968 freq_range[1] = temp_freq_range[1];
1969 if (temp_freq_range[2] < freq_range[2])
1970 freq_range[2] = temp_freq_range[2];
1971 }
1972
1973 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1974 uinfo->count = 1;
1975 uinfo->value.integer.min = ((int)freq_range[0]);
1976 uinfo->value.integer.max = ((int)freq_range[1]);
1977 uinfo->value.integer.step = ((int)freq_range[2]);
1978 return 0;
1979}
1980
1981static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1982 struct snd_ctl_elem_value *ucontrol)
1983{
1984 u32 h_control = kcontrol->private_value;
1985 u32 freq;
1986
1987 hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
1988 ucontrol->value.integer.value[0] = freq;
1989
1990 return 0;
1991}
1992
1993static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
1994 struct snd_ctl_elem_value *ucontrol)
1995{
1996 u32 h_control = kcontrol->private_value;
1997 u32 freq;
1998
1999 freq = ucontrol->value.integer.value[0];
2000 hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
2001
2002 return 1;
2003}
2004
2005
2006static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2007 struct hpi_control *hpi_ctl)
2008{
2009 struct snd_card *card = asihpi->card;
2010 struct snd_kcontrol_new snd_control;
2011
2012 snd_control.private_value = hpi_ctl->h_control;
2013 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2014
2015 if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
2016 asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
2017 snd_control.info = snd_asihpi_tuner_gain_info;
2018 snd_control.get = snd_asihpi_tuner_gain_get;
2019 snd_control.put = snd_asihpi_tuner_gain_put;
2020
2021 if (ctl_add(card, &snd_control, asihpi) < 0)
2022 return -EINVAL;
2023 }
2024
2025 asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
2026 snd_control.info = snd_asihpi_tuner_band_info;
2027 snd_control.get = snd_asihpi_tuner_band_get;
2028 snd_control.put = snd_asihpi_tuner_band_put;
2029
2030 if (ctl_add(card, &snd_control, asihpi) < 0)
2031 return -EINVAL;
2032
2033 asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
2034 snd_control.info = snd_asihpi_tuner_freq_info;
2035 snd_control.get = snd_asihpi_tuner_freq_get;
2036 snd_control.put = snd_asihpi_tuner_freq_put;
2037
2038 return ctl_add(card, &snd_control, asihpi);
2039}
2040
2041
2042
2043
2044static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2045 struct snd_ctl_elem_info *uinfo)
2046{
2047 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2048 uinfo->count = HPI_MAX_CHANNELS;
2049 uinfo->value.integer.min = 0;
2050 uinfo->value.integer.max = 0x7FFFFFFF;
2051 return 0;
2052}
2053
2054
2055static int log2lin[] = {
2056 0x7FFFFFFF,
2057 679093956,
2058 214748365,
2059 67909396,
2060 21474837,
2061 6790940,
2062 2147484,
2063 679094,
2064 214748,
2065 67909,
2066 21475,
2067 6791,
2068 2147,
2069 679,
2070 214,
2071 68,
2072 21,
2073 7,
2074 2
2075};
2076
2077static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2078 struct snd_ctl_elem_value *ucontrol)
2079{
2080 u32 h_control = kcontrol->private_value;
2081 short an_gain_mB[HPI_MAX_CHANNELS], i;
2082 u16 err;
2083
2084 err = hpi_meter_get_peak(h_control, an_gain_mB);
2085
2086 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2087 if (err) {
2088 ucontrol->value.integer.value[i] = 0;
2089 } else if (an_gain_mB[i] >= 0) {
2090 ucontrol->value.integer.value[i] =
2091 an_gain_mB[i] << 16;
2092 } else {
2093
2094
2095
2096 ucontrol->value.integer.value[i] =
2097 log2lin[an_gain_mB[i] / -1000];
2098 }
2099 }
2100 return 0;
2101}
2102
2103static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2104 struct hpi_control *hpi_ctl, int subidx)
2105{
2106 struct snd_card *card = asihpi->card;
2107 struct snd_kcontrol_new snd_control;
2108
2109 asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
2110 snd_control.access =
2111 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2112 snd_control.info = snd_asihpi_meter_info;
2113 snd_control.get = snd_asihpi_meter_get;
2114
2115 snd_control.index = subidx;
2116
2117 return ctl_add(card, &snd_control, asihpi);
2118}
2119
2120
2121
2122
2123static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2124{
2125 u32 h_control = snd_control->private_value;
2126 struct hpi_control hpi_ctl;
2127 int s, err;
2128 for (s = 0; s < 32; s++) {
2129 err = hpi_multiplexer_query_source(h_control, s,
2130 &hpi_ctl.
2131 src_node_type,
2132 &hpi_ctl.
2133 src_node_index);
2134 if (err)
2135 break;
2136 }
2137 return s;
2138}
2139
2140static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2141 struct snd_ctl_elem_info *uinfo)
2142{
2143 int err;
2144 u16 src_node_type, src_node_index;
2145 u32 h_control = kcontrol->private_value;
2146
2147 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2148 uinfo->count = 1;
2149 uinfo->value.enumerated.items =
2150 snd_card_asihpi_mux_count_sources(kcontrol);
2151
2152 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2153 uinfo->value.enumerated.item =
2154 uinfo->value.enumerated.items - 1;
2155
2156 err =
2157 hpi_multiplexer_query_source(h_control,
2158 uinfo->value.enumerated.item,
2159 &src_node_type, &src_node_index);
2160
2161 sprintf(uinfo->value.enumerated.name, "%s %d",
2162 asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
2163 src_node_index);
2164 return 0;
2165}
2166
2167static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2168 struct snd_ctl_elem_value *ucontrol)
2169{
2170 u32 h_control = kcontrol->private_value;
2171 u16 source_type, source_index;
2172 u16 src_node_type, src_node_index;
2173 int s;
2174
2175 hpi_handle_error(hpi_multiplexer_get_source(h_control,
2176 &source_type, &source_index));
2177
2178 for (s = 0; s < 256; s++) {
2179 if (hpi_multiplexer_query_source(h_control, s,
2180 &src_node_type, &src_node_index))
2181 break;
2182
2183 if ((source_type == src_node_type)
2184 && (source_index == src_node_index)) {
2185 ucontrol->value.enumerated.item[0] = s;
2186 return 0;
2187 }
2188 }
2189 snd_printd(KERN_WARNING
2190 "Control %x failed to match mux source %hu %hu\n",
2191 h_control, source_type, source_index);
2192 ucontrol->value.enumerated.item[0] = 0;
2193 return 0;
2194}
2195
2196static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2197 struct snd_ctl_elem_value *ucontrol)
2198{
2199 int change;
2200 u32 h_control = kcontrol->private_value;
2201 u16 source_type, source_index;
2202 u16 e;
2203
2204 change = 1;
2205
2206 e = hpi_multiplexer_query_source(h_control,
2207 ucontrol->value.enumerated.item[0],
2208 &source_type, &source_index);
2209 if (!e)
2210 hpi_handle_error(
2211 hpi_multiplexer_set_source(h_control,
2212 source_type, source_index));
2213 return change;
2214}
2215
2216
2217static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2218 struct hpi_control *hpi_ctl)
2219{
2220 struct snd_card *card = asihpi->card;
2221 struct snd_kcontrol_new snd_control;
2222
2223 asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
2224 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2225 snd_control.info = snd_asihpi_mux_info;
2226 snd_control.get = snd_asihpi_mux_get;
2227 snd_control.put = snd_asihpi_mux_put;
2228
2229 return ctl_add(card, &snd_control, asihpi);
2230
2231}
2232
2233
2234
2235
2236static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2237 struct snd_ctl_elem_info *uinfo)
2238{
2239 static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
2240 "invalid",
2241 "Normal", "Swap",
2242 "From Left", "From Right",
2243 "To Left", "To Right"
2244 };
2245
2246 u32 h_control = kcontrol->private_value;
2247 u16 mode;
2248 int i;
2249 u16 mode_map[6];
2250 int valid_modes = 0;
2251
2252
2253
2254
2255 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2256 if (!hpi_channel_mode_query_mode(
2257 h_control, i, &mode)) {
2258 mode_map[valid_modes] = mode;
2259 valid_modes++;
2260 }
2261
2262 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2263 uinfo->count = 1;
2264 uinfo->value.enumerated.items = valid_modes;
2265
2266 if (uinfo->value.enumerated.item >= valid_modes)
2267 uinfo->value.enumerated.item = valid_modes - 1;
2268
2269 strcpy(uinfo->value.enumerated.name,
2270 mode_names[mode_map[uinfo->value.enumerated.item]]);
2271
2272 return 0;
2273}
2274
2275static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2276 struct snd_ctl_elem_value *ucontrol)
2277{
2278 u32 h_control = kcontrol->private_value;
2279 u16 mode;
2280
2281 if (hpi_channel_mode_get(h_control, &mode))
2282 mode = 1;
2283
2284 ucontrol->value.enumerated.item[0] = mode - 1;
2285
2286 return 0;
2287}
2288
2289static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2290 struct snd_ctl_elem_value *ucontrol)
2291{
2292 int change;
2293 u32 h_control = kcontrol->private_value;
2294
2295 change = 1;
2296
2297 hpi_handle_error(hpi_channel_mode_set(h_control,
2298 ucontrol->value.enumerated.item[0] + 1));
2299 return change;
2300}
2301
2302
2303static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2304 struct hpi_control *hpi_ctl)
2305{
2306 struct snd_card *card = asihpi->card;
2307 struct snd_kcontrol_new snd_control;
2308
2309 asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
2310 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2311 snd_control.info = snd_asihpi_cmode_info;
2312 snd_control.get = snd_asihpi_cmode_get;
2313 snd_control.put = snd_asihpi_cmode_put;
2314
2315 return ctl_add(card, &snd_control, asihpi);
2316}
2317
2318
2319
2320
2321static char *sampleclock_sources[MAX_CLOCKSOURCES] = {
2322 "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
2323 "SMPTE", "Digital1", "Auto", "Network", "Invalid",
2324 "Prev Module",
2325 "Digital2", "Digital3", "Digital4", "Digital5",
2326 "Digital6", "Digital7", "Digital8"};
2327
2328static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2329 struct snd_ctl_elem_info *uinfo)
2330{
2331 struct snd_card_asihpi *asihpi =
2332 (struct snd_card_asihpi *)(kcontrol->private_data);
2333 struct clk_cache *clkcache = &asihpi->cc;
2334 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2335 uinfo->count = 1;
2336 uinfo->value.enumerated.items = clkcache->count;
2337
2338 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2339 uinfo->value.enumerated.item =
2340 uinfo->value.enumerated.items - 1;
2341
2342 strcpy(uinfo->value.enumerated.name,
2343 clkcache->s[uinfo->value.enumerated.item].name);
2344 return 0;
2345}
2346
2347static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2348 struct snd_ctl_elem_value *ucontrol)
2349{
2350 struct snd_card_asihpi *asihpi =
2351 (struct snd_card_asihpi *)(kcontrol->private_data);
2352 struct clk_cache *clkcache = &asihpi->cc;
2353 u32 h_control = kcontrol->private_value;
2354 u16 source, srcindex = 0;
2355 int i;
2356
2357 ucontrol->value.enumerated.item[0] = 0;
2358 if (hpi_sample_clock_get_source(h_control, &source))
2359 source = 0;
2360
2361 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2362 if (hpi_sample_clock_get_source_index(h_control, &srcindex))
2363 srcindex = 0;
2364
2365 for (i = 0; i < clkcache->count; i++)
2366 if ((clkcache->s[i].source == source) &&
2367 (clkcache->s[i].index == srcindex))
2368 break;
2369
2370 ucontrol->value.enumerated.item[0] = i;
2371
2372 return 0;
2373}
2374
2375static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2376 struct snd_ctl_elem_value *ucontrol)
2377{
2378 struct snd_card_asihpi *asihpi =
2379 (struct snd_card_asihpi *)(kcontrol->private_data);
2380 struct clk_cache *clkcache = &asihpi->cc;
2381 int change, item;
2382 u32 h_control = kcontrol->private_value;
2383
2384 change = 1;
2385 item = ucontrol->value.enumerated.item[0];
2386 if (item >= clkcache->count)
2387 item = clkcache->count-1;
2388
2389 hpi_handle_error(hpi_sample_clock_set_source(
2390 h_control, clkcache->s[item].source));
2391
2392 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2393 hpi_handle_error(hpi_sample_clock_set_source_index(
2394 h_control, clkcache->s[item].index));
2395 return change;
2396}
2397
2398
2399
2400
2401
2402static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2403 struct snd_ctl_elem_info *uinfo)
2404{
2405 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2406 uinfo->count = 1;
2407 uinfo->value.integer.min = 8000;
2408 uinfo->value.integer.max = 192000;
2409 uinfo->value.integer.step = 100;
2410
2411 return 0;
2412}
2413
2414static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2415 struct snd_ctl_elem_value *ucontrol)
2416{
2417 u32 h_control = kcontrol->private_value;
2418 u32 rate;
2419 u16 e;
2420
2421 e = hpi_sample_clock_get_local_rate(h_control, &rate);
2422 if (!e)
2423 ucontrol->value.integer.value[0] = rate;
2424 else
2425 ucontrol->value.integer.value[0] = 0;
2426 return 0;
2427}
2428
2429static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2430 struct snd_ctl_elem_value *ucontrol)
2431{
2432 int change;
2433 u32 h_control = kcontrol->private_value;
2434
2435
2436
2437
2438 change = 1;
2439 hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
2440 ucontrol->value.integer.value[0]));
2441 return change;
2442}
2443
2444static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2445 struct snd_ctl_elem_info *uinfo)
2446{
2447 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2448 uinfo->count = 1;
2449 uinfo->value.integer.min = 8000;
2450 uinfo->value.integer.max = 192000;
2451 uinfo->value.integer.step = 100;
2452
2453 return 0;
2454}
2455
2456static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2457 struct snd_ctl_elem_value *ucontrol)
2458{
2459 u32 h_control = kcontrol->private_value;
2460 u32 rate;
2461 u16 e;
2462
2463 e = hpi_sample_clock_get_sample_rate(h_control, &rate);
2464 if (!e)
2465 ucontrol->value.integer.value[0] = rate;
2466 else
2467 ucontrol->value.integer.value[0] = 0;
2468 return 0;
2469}
2470
2471static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2472 struct hpi_control *hpi_ctl)
2473{
2474 struct snd_card *card = asihpi->card;
2475 struct snd_kcontrol_new snd_control;
2476
2477 struct clk_cache *clkcache = &asihpi->cc;
2478 u32 hSC = hpi_ctl->h_control;
2479 int has_aes_in = 0;
2480 int i, j;
2481 u16 source;
2482
2483 snd_control.private_value = hpi_ctl->h_control;
2484
2485 clkcache->has_local = 0;
2486
2487 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2488 if (hpi_sample_clock_query_source(hSC,
2489 i, &source))
2490 break;
2491 clkcache->s[i].source = source;
2492 clkcache->s[i].index = 0;
2493 clkcache->s[i].name = sampleclock_sources[source];
2494 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2495 has_aes_in = 1;
2496 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2497 clkcache->has_local = 1;
2498 }
2499 if (has_aes_in)
2500
2501 for (j = 1; j < 8; j++) {
2502 if (hpi_sample_clock_query_source_index(hSC,
2503 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2504 &source))
2505 break;
2506 clkcache->s[i].source =
2507 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2508 clkcache->s[i].index = j;
2509 clkcache->s[i].name = sampleclock_sources[
2510 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2511 i++;
2512 }
2513 clkcache->count = i;
2514
2515 asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
2516 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2517 snd_control.info = snd_asihpi_clksrc_info;
2518 snd_control.get = snd_asihpi_clksrc_get;
2519 snd_control.put = snd_asihpi_clksrc_put;
2520 if (ctl_add(card, &snd_control, asihpi) < 0)
2521 return -EINVAL;
2522
2523
2524 if (clkcache->has_local) {
2525 asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
2526 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2527 snd_control.info = snd_asihpi_clklocal_info;
2528 snd_control.get = snd_asihpi_clklocal_get;
2529 snd_control.put = snd_asihpi_clklocal_put;
2530
2531
2532 if (ctl_add(card, &snd_control, asihpi) < 0)
2533 return -EINVAL;
2534 }
2535
2536 asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
2537 snd_control.access =
2538 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2539 snd_control.info = snd_asihpi_clkrate_info;
2540 snd_control.get = snd_asihpi_clkrate_get;
2541
2542 return ctl_add(card, &snd_control, asihpi);
2543}
2544
2545
2546
2547
2548static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2549{
2550 struct snd_card *card = asihpi->card;
2551 unsigned int idx = 0;
2552 unsigned int subindex = 0;
2553 int err;
2554 struct hpi_control hpi_ctl, prev_ctl;
2555
2556 if (snd_BUG_ON(!asihpi))
2557 return -EINVAL;
2558 strcpy(card->mixername, "Asihpi Mixer");
2559
2560 err =
2561 hpi_mixer_open(asihpi->adapter_index,
2562 &asihpi->h_mixer);
2563 hpi_handle_error(err);
2564 if (err)
2565 return -err;
2566
2567 memset(&prev_ctl, 0, sizeof(prev_ctl));
2568 prev_ctl.control_type = -1;
2569
2570 for (idx = 0; idx < 2000; idx++) {
2571 err = hpi_mixer_get_control_by_index(
2572 asihpi->h_mixer,
2573 idx,
2574 &hpi_ctl.src_node_type,
2575 &hpi_ctl.src_node_index,
2576 &hpi_ctl.dst_node_type,
2577 &hpi_ctl.dst_node_index,
2578 &hpi_ctl.control_type,
2579 &hpi_ctl.h_control);
2580 if (err) {
2581 if (err == HPI_ERROR_CONTROL_DISABLED) {
2582 if (mixer_dump)
2583 snd_printk(KERN_INFO
2584 "Disabled HPI Control(%d)\n",
2585 idx);
2586 continue;
2587 } else
2588 break;
2589
2590 }
2591
2592 hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2593 hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
2594
2595
2596
2597
2598
2599 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2600 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2601 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2602 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2603 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2604 subindex++;
2605 else
2606 subindex = 0;
2607
2608 prev_ctl = hpi_ctl;
2609
2610 switch (hpi_ctl.control_type) {
2611 case HPI_CONTROL_VOLUME:
2612 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2613 break;
2614 case HPI_CONTROL_LEVEL:
2615 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2616 break;
2617 case HPI_CONTROL_MULTIPLEXER:
2618 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2619 break;
2620 case HPI_CONTROL_CHANNEL_MODE:
2621 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2622 break;
2623 case HPI_CONTROL_METER:
2624 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2625 break;
2626 case HPI_CONTROL_SAMPLECLOCK:
2627 err = snd_asihpi_sampleclock_add(
2628 asihpi, &hpi_ctl);
2629 break;
2630 case HPI_CONTROL_CONNECTION:
2631 continue;
2632 case HPI_CONTROL_TUNER:
2633 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2634 break;
2635 case HPI_CONTROL_AESEBU_TRANSMITTER:
2636 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2637 break;
2638 case HPI_CONTROL_AESEBU_RECEIVER:
2639 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2640 break;
2641 case HPI_CONTROL_VOX:
2642 case HPI_CONTROL_BITSTREAM:
2643 case HPI_CONTROL_MICROPHONE:
2644 case HPI_CONTROL_PARAMETRIC_EQ:
2645 case HPI_CONTROL_COMPANDER:
2646 default:
2647 if (mixer_dump)
2648 snd_printk(KERN_INFO
2649 "Untranslated HPI Control"
2650 "(%d) %d %d %d %d %d\n",
2651 idx,
2652 hpi_ctl.control_type,
2653 hpi_ctl.src_node_type,
2654 hpi_ctl.src_node_index,
2655 hpi_ctl.dst_node_type,
2656 hpi_ctl.dst_node_index);
2657 continue;
2658 };
2659 if (err < 0)
2660 return err;
2661 }
2662 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2663 hpi_handle_error(err);
2664
2665 snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2666
2667 return 0;
2668}
2669
2670
2671
2672
2673
2674static void
2675snd_asihpi_proc_read(struct snd_info_entry *entry,
2676 struct snd_info_buffer *buffer)
2677{
2678 struct snd_card_asihpi *asihpi = entry->private_data;
2679 u16 version;
2680 u32 h_control;
2681 u32 rate = 0;
2682 u16 source = 0;
2683 int err;
2684
2685 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2686 snd_iprintf(buffer,
2687 "adapter ID=%4X\n_index=%d\n"
2688 "num_outstreams=%d\n_num_instreams=%d\n",
2689 asihpi->type, asihpi->adapter_index,
2690 asihpi->num_outstreams, asihpi->num_instreams);
2691
2692 version = asihpi->version;
2693 snd_iprintf(buffer,
2694 "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
2695 asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
2696 version & 0x7,
2697 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2698
2699 err = hpi_mixer_get_control(asihpi->h_mixer,
2700 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2701 HPI_CONTROL_SAMPLECLOCK, &h_control);
2702
2703 if (!err) {
2704 err = hpi_sample_clock_get_sample_rate(
2705 h_control, &rate);
2706 err += hpi_sample_clock_get_source(h_control, &source);
2707
2708 if (!err)
2709 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
2710 rate, sampleclock_sources[source]);
2711 }
2712
2713}
2714
2715
2716static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2717{
2718 struct snd_info_entry *entry;
2719
2720 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2721 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2722}
2723
2724
2725
2726
2727
2728static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2729{
2730 if (enable_hpi_hwdep)
2731 return 0;
2732 else
2733 return -ENODEV;
2734
2735}
2736
2737static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2738{
2739 if (enable_hpi_hwdep)
2740 return asihpi_hpi_release(file);
2741 else
2742 return -ENODEV;
2743}
2744
2745static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2746 unsigned int cmd, unsigned long arg)
2747{
2748 if (enable_hpi_hwdep)
2749 return asihpi_hpi_ioctl(file, cmd, arg);
2750 else
2751 return -ENODEV;
2752}
2753
2754
2755
2756
2757
2758static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2759 int device, struct snd_hwdep **rhwdep)
2760{
2761 struct snd_hwdep *hw;
2762 int err;
2763
2764 if (rhwdep)
2765 *rhwdep = NULL;
2766 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2767 if (err < 0)
2768 return err;
2769 strcpy(hw->name, "asihpi (HPI)");
2770 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2771 hw->ops.open = snd_asihpi_hpi_open;
2772 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2773 hw->ops.release = snd_asihpi_hpi_release;
2774 hw->private_data = asihpi;
2775 if (rhwdep)
2776 *rhwdep = hw;
2777 return 0;
2778}
2779
2780
2781
2782
2783static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2784 const struct pci_device_id *pci_id)
2785{
2786 int err;
2787
2788 u16 version;
2789 int pcm_substreams;
2790
2791 struct hpi_adapter *hpi_card;
2792 struct snd_card *card;
2793 struct snd_card_asihpi *asihpi;
2794
2795 u32 h_control;
2796 u32 h_stream;
2797
2798 static int dev;
2799 if (dev >= SNDRV_CARDS)
2800 return -ENODEV;
2801
2802
2803 if (!enable[dev]) {
2804 dev++;
2805 return -ENOENT;
2806 }
2807
2808 err = asihpi_adapter_probe(pci_dev, pci_id);
2809 if (err < 0)
2810 return err;
2811
2812 hpi_card = pci_get_drvdata(pci_dev);
2813
2814 err = snd_card_create(hpi_card->index,
2815 id[hpi_card->index], THIS_MODULE,
2816 sizeof(struct snd_card_asihpi),
2817 &card);
2818 if (err < 0) {
2819
2820 err =
2821 snd_card_create(index[dev], id[dev],
2822 THIS_MODULE,
2823 sizeof(struct snd_card_asihpi),
2824 &card);
2825 if (err < 0)
2826 return err;
2827 snd_printk(KERN_WARNING
2828 "**** WARNING **** Adapter index %d->ALSA index %d\n",
2829 hpi_card->index, card->number);
2830 }
2831
2832 snd_card_set_dev(card, &pci_dev->dev);
2833
2834 asihpi = (struct snd_card_asihpi *) card->private_data;
2835 asihpi->card = card;
2836 asihpi->pci = pci_dev;
2837 asihpi->adapter_index = hpi_card->index;
2838 hpi_handle_error(hpi_adapter_get_info(
2839 asihpi->adapter_index,
2840 &asihpi->num_outstreams,
2841 &asihpi->num_instreams,
2842 &asihpi->version,
2843 &asihpi->serial_number, &asihpi->type));
2844
2845 version = asihpi->version;
2846 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2847 "num_instreams=%d S/N=%d\n"
2848 "Hw Version %c%d DSP code version %03d\n",
2849 asihpi->type, asihpi->adapter_index,
2850 asihpi->num_outstreams,
2851 asihpi->num_instreams, asihpi->serial_number,
2852 ((version >> 3) & 0xf) + 'A',
2853 version & 0x7,
2854 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2855
2856 pcm_substreams = asihpi->num_outstreams;
2857 if (pcm_substreams < asihpi->num_instreams)
2858 pcm_substreams = asihpi->num_instreams;
2859
2860 err = hpi_adapter_get_property(asihpi->adapter_index,
2861 HPI_ADAPTER_PROPERTY_CAPS1,
2862 NULL, &asihpi->support_grouping);
2863 if (err)
2864 asihpi->support_grouping = 0;
2865
2866 err = hpi_adapter_get_property(asihpi->adapter_index,
2867 HPI_ADAPTER_PROPERTY_CAPS2,
2868 &asihpi->support_mrx, NULL);
2869 if (err)
2870 asihpi->support_mrx = 0;
2871
2872 err = hpi_adapter_get_property(asihpi->adapter_index,
2873 HPI_ADAPTER_PROPERTY_INTERVAL,
2874 NULL, &asihpi->update_interval_frames);
2875 if (err)
2876 asihpi->update_interval_frames = 512;
2877
2878 if (!asihpi->support_mmap)
2879 asihpi->update_interval_frames *= 2;
2880
2881 hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
2882 0, &h_stream));
2883
2884 err = hpi_instream_host_buffer_free(h_stream);
2885 asihpi->support_mmap = (!err);
2886
2887 hpi_handle_error(hpi_instream_close(h_stream));
2888
2889 err = hpi_adapter_get_property(asihpi->adapter_index,
2890 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2891 &asihpi->in_max_chans, &asihpi->out_max_chans);
2892 if (err) {
2893 asihpi->in_max_chans = 2;
2894 asihpi->out_max_chans = 2;
2895 }
2896
2897 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n",
2898 asihpi->support_mmap,
2899 asihpi->support_grouping,
2900 asihpi->support_mrx
2901 );
2902
2903 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2904 if (err < 0) {
2905 snd_printk(KERN_ERR "pcm_new failed\n");
2906 goto __nodev;
2907 }
2908 err = snd_card_asihpi_mixer_new(asihpi);
2909 if (err < 0) {
2910 snd_printk(KERN_ERR "mixer_new failed\n");
2911 goto __nodev;
2912 }
2913
2914 err = hpi_mixer_get_control(asihpi->h_mixer,
2915 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2916 HPI_CONTROL_SAMPLECLOCK, &h_control);
2917
2918 if (!err)
2919 err = hpi_sample_clock_set_local_rate(
2920 h_control, adapter_fs);
2921
2922 snd_asihpi_proc_init(asihpi);
2923
2924
2925
2926 snd_asihpi_hpi_new(asihpi, 0, NULL);
2927
2928 if (asihpi->support_mmap)
2929 strcpy(card->driver, "ASIHPI-MMAP");
2930 else
2931 strcpy(card->driver, "ASIHPI");
2932
2933 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2934 sprintf(card->longname, "%s %i",
2935 card->shortname, asihpi->adapter_index);
2936 err = snd_card_register(card);
2937
2938 if (!err) {
2939 hpi_card->snd_card_asihpi = card;
2940 dev++;
2941 return 0;
2942 }
2943__nodev:
2944 snd_card_free(card);
2945 snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2946 return err;
2947
2948}
2949
2950static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2951{
2952 struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
2953
2954 snd_card_free(hpi_card->snd_card_asihpi);
2955 hpi_card->snd_card_asihpi = NULL;
2956 asihpi_adapter_remove(pci_dev);
2957}
2958
2959static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2960 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2961 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2962 (kernel_ulong_t)HPI_6205},
2963 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2964 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2965 (kernel_ulong_t)HPI_6000},
2966 {0,}
2967};
2968MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2969
2970static struct pci_driver driver = {
2971 .name = "asihpi",
2972 .id_table = asihpi_pci_tbl,
2973 .probe = snd_asihpi_probe,
2974 .remove = __devexit_p(snd_asihpi_remove),
2975#ifdef CONFIG_PM
2976
2977
2978#endif
2979};
2980
2981static int __init snd_asihpi_init(void)
2982{
2983 asihpi_init();
2984 return pci_register_driver(&driver);
2985}
2986
2987static void __exit snd_asihpi_exit(void)
2988{
2989
2990 pci_unregister_driver(&driver);
2991 asihpi_exit();
2992}
2993
2994module_init(snd_asihpi_init)
2995module_exit(snd_asihpi_exit)
2996
2997