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