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