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