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