vmalloc: fix __GFP_HIGHMEM usage for vmalloc_32 on 32b systems
[linux/fpc-iii.git] / sound / pci / asihpi / asihpi.c
blob720361455c60166061aa7e1921d0de147d1c42ce
1 /*
2 * Asihpi soundcard
3 * Copyright (c) by AudioScience Inc <support@audioscience.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation;
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * The following is not a condition of use, merely a request:
20 * If you modify this program, particularly if you fix errors, AudioScience Inc
21 * would appreciate it if you grant us the right to use those modifications
22 * for any purpose including commercial applications.
25 #include "hpi_internal.h"
26 #include "hpi_version.h"
27 #include "hpimsginit.h"
28 #include "hpioctl.h"
29 #include "hpicmn.h"
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>
47 MODULE_LICENSE("GPL");
48 MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
49 MODULE_DESCRIPTION("AudioScience ALSA ASI5xxx ASI6xxx ASI87xx ASI89xx "
50 HPI_VER_STRING);
52 #if defined CONFIG_SND_DEBUG_VERBOSE
53 /**
54 * snd_printddd - very verbose debug printk
55 * @format: format string
57 * Works like snd_printk() for debugging purposes.
58 * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
59 * Must set snd module debug parameter to 3 to enable at runtime.
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
67 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
68 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
69 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
70 static bool enable_hpi_hwdep = 1;
72 module_param_array(index, int, NULL, S_IRUGO);
73 MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
75 module_param_array(id, charp, NULL, S_IRUGO);
76 MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
78 module_param_array(enable, bool, NULL, S_IRUGO);
79 MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
81 module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
82 MODULE_PARM_DESC(enable_hpi_hwdep,
83 "ALSA enable HPI hwdep for AudioScience soundcard ");
85 /* identify driver */
86 #ifdef KERNEL_ALSA_BUILD
87 static char *build_info = "Built using headers from kernel source";
88 module_param(build_info, charp, S_IRUGO);
89 MODULE_PARM_DESC(build_info, "Built using headers from kernel source");
90 #else
91 static char *build_info = "Built within ALSA source";
92 module_param(build_info, charp, S_IRUGO);
93 MODULE_PARM_DESC(build_info, "Built within ALSA source");
94 #endif
96 /* set to 1 to dump every control from adapter to log */
97 static const int mixer_dump;
99 #define DEFAULT_SAMPLERATE 44100
100 static int adapter_fs = DEFAULT_SAMPLERATE;
102 /* defaults */
103 #define PERIODS_MIN 2
104 #define PERIOD_BYTES_MIN 2048
105 #define BUFFER_BYTES_MAX (512 * 1024)
107 #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
109 struct clk_source {
110 int source;
111 int index;
112 const char *name;
115 struct clk_cache {
116 int count;
117 int has_local;
118 struct clk_source s[MAX_CLOCKSOURCES];
121 /* Per card data */
122 struct snd_card_asihpi {
123 struct snd_card *card;
124 struct pci_dev *pci;
125 struct hpi_adapter *hpi;
127 /* In low latency mode there is only one stream, a pointer to its
128 * private data is stored here on trigger and cleared on stop.
129 * The interrupt handler uses it as a parameter when calling
130 * snd_card_asihpi_timer_function().
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);
137 u32 h_mixer;
138 struct clk_cache cc;
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;
150 /* Per stream data */
151 struct 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; /* Host R/W pos */
159 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
160 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
161 unsigned int drained_count;
162 struct snd_pcm_substream *substream;
163 u32 h_stream;
164 struct hpi_format format;
167 /* universal stream verbs work with out or in stream handles */
169 /* Functions to allow driver to give a buffer to HPI for busmastering */
171 static u16 hpi_stream_host_buffer_attach(
172 u32 h_stream, /* handle to outstream. */
173 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
174 u32 pci_address
177 struct hpi_message hm;
178 struct hpi_response hr;
179 unsigned int obj = hpi_handle_object(h_stream);
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);
188 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
189 &hm.obj_index);
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;
198 static u16 hpi_stream_host_buffer_detach(u32 h_stream)
200 struct hpi_message hm;
201 struct hpi_response hr;
202 unsigned int obj = hpi_handle_object(h_stream);
204 if (!h_stream)
205 return HPI_ERROR_INVALID_OBJ;
207 hpi_init_message_response(&hm, &hr, obj,
208 obj == HPI_OBJ_OSTREAM ?
209 HPI_OSTREAM_HOSTBUFFER_FREE :
210 HPI_ISTREAM_HOSTBUFFER_FREE);
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;
219 static inline u16 hpi_stream_start(u32 h_stream)
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);
227 static inline u16 hpi_stream_stop(u32 h_stream)
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);
235 static 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
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;
256 static inline u16 hpi_stream_group_add(
257 u32 h_master,
258 u32 h_stream)
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);
266 static inline u16 hpi_stream_group_reset(u32 h_stream)
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);
274 static inline u16 hpi_stream_group_get_map(
275 u32 h_stream, u32 *mo, u32 *mi)
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);
283 static u16 handle_error(u16 err, int line, char *filename)
285 if (err)
286 printk(KERN_WARNING
287 "in file %s, line %d: HPI error %d\n",
288 filename, line, err);
289 return err;
292 #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
294 /***************************** GENERAL PCM ****************/
296 static void print_hwparams(struct snd_pcm_substream *substream,
297 struct snd_pcm_hw_params *p)
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);
314 static snd_pcm_format_t hpi_to_alsa_formats[] = {
315 -1, /* INVALID */
316 SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
317 SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
318 -1, /* HPI_FORMAT_MPEG_L1 3 */
319 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
320 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
321 -1, /* HPI_FORMAT_DOLBY_AC2 6 */
322 -1, /* HPI_FORMAT_DOLBY_AC3 7 */
323 SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
324 -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
325 -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
326 SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
327 -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
328 -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
329 SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
330 #if 1
331 /* ALSA can't handle 3 byte sample size together with power-of-2
332 * constraint on buffer_bytes, so disable this format
335 #else
336 /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
337 #endif
341 static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
342 u16 *hpi_format)
344 u16 format;
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;
354 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
355 alsa_format);
356 *hpi_format = 0;
357 return -EINVAL;
360 static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
361 struct snd_pcm_hardware *pcmhw)
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;
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 /* on cards without SRC,
378 valid rates are determined by sampleclock */
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);
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;
397 rate_min = min(rate_min, sample_rate);
398 rate_max = max(rate_max, sample_rate);
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: /* some other rate */
441 rates |= SNDRV_PCM_RATE_KNOT;
446 pcmhw->rates = rates;
447 pcmhw->rate_min = rate_min;
448 pcmhw->rate_max = rate_max;
451 static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
452 struct snd_pcm_hw_params *params)
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;
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;
470 hpi_handle_error(hpi_format_create(&dpcm->format,
471 params_channels(params),
472 format, params_rate(params), 0, 0));
474 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
475 if (hpi_instream_reset(dpcm->h_stream) != 0)
476 return -EINVAL;
478 if (hpi_instream_set_format(
479 dpcm->h_stream, &dpcm->format) != 0)
480 return -EINVAL;
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;
498 err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
499 &dpcm->hpi_buffer_attached, NULL, NULL, NULL);
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;
508 dpcm->bytes_per_sec = bytes_per_sec;
509 dpcm->buffer_bytes = params_buffer_bytes(params);
510 dpcm->period_bytes = params_period_bytes(params);
512 return 0;
515 static int
516 snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
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);
523 snd_pcm_lib_free_pages(substream);
524 return 0;
527 static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
529 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
530 kfree(dpcm);
533 static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
534 substream)
536 struct snd_pcm_runtime *runtime = substream->runtime;
537 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
538 int expiry;
540 expiry = HZ / 200;
542 expiry = max(expiry, 1); /* don't let it be zero! */
543 mod_timer(&dpcm->timer, jiffies + expiry);
544 dpcm->respawn_timer = 1;
547 static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
549 struct snd_pcm_runtime *runtime = substream->runtime;
550 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
552 dpcm->respawn_timer = 0;
553 del_timer(&dpcm->timer);
556 static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream)
558 struct snd_card_asihpi_pcm *dpcm;
559 struct snd_card_asihpi *card;
561 dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data;
562 card = snd_pcm_substream_chip(substream);
564 WARN_ON(in_interrupt());
565 tasklet_disable(&card->t);
566 card->llmode_streampriv = dpcm;
567 tasklet_enable(&card->t);
569 hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
570 HPI_ADAPTER_PROPERTY_IRQ_RATE,
571 card->update_interval_frames, 0));
574 static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream)
576 struct snd_card_asihpi *card;
578 card = snd_pcm_substream_chip(substream);
580 hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
581 HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
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);
592 static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
593 int cmd)
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];
601 snd_pcm_debug_name(substream, name, sizeof(name));
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;
610 if (snd_pcm_substream_chip(s) != card)
611 continue;
613 /* don't link Cap and Play */
614 if (substream->stream != s->stream)
615 continue;
617 ds->drained_count = 0;
618 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
619 /* How do I know how much valid data is present
620 * in buffer? Must be at least one period!
621 * Guessing 2 periods, but if
622 * buffer is bigger it may contain even more
623 * data??
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;
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;
646 } else
647 break;
649 /* start the master stream */
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;
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 /* don't link Cap and Play */
663 if (substream->stream != s->stream)
664 continue;
666 /*? workaround linked streams don't
667 transition to SETUP 20070706*/
668 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
670 if (card->support_grouping) {
671 snd_printdd("%d group\n", s->number);
672 snd_pcm_trigger_done(s, substream);
673 } else
674 break;
677 /* _prepare and _hwparams reset the stream */
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));
683 if (card->support_grouping)
684 hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
685 break;
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;
702 return 0;
705 /*algorithm outline
706 Without linking degenerates to getting single stream pos etc
707 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
710 pcm_buf_dma_ofs=get_buf_pos(s);
711 for_each_linked_stream(s) {
712 pcm_buf_dma_ofs=get_buf_pos(s);
713 min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes)
714 new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
716 timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
717 for_each_linked_stream(s) {
718 s->pcm_buf_dma_ofs = min_buf_pos;
719 if (new_data > period_bytes) {
720 if (mmap) {
721 irq_pos = (irq_pos + period_bytes) % buffer_bytes;
722 if (playback) {
723 write(period_bytes);
724 } else {
725 read(period_bytes);
728 snd_pcm_period_elapsed(s);
733 /** Minimum of 2 modulo values. Works correctly when the difference between
734 * the values is less than half the modulus
736 static inline unsigned int modulo_min(unsigned int a, unsigned int b,
737 unsigned long int modulus)
739 unsigned int result;
740 if (((a-b) % modulus) < (modulus/2))
741 result = b;
742 else
743 result = a;
745 return result;
748 /** Timer function, equivalent to interrupt service routine for cards
750 static void snd_card_asihpi_timer_function(struct timer_list *t)
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];
767 snd_pcm_debug_name(substream, name, sizeof(name));
769 /* find minimum newdata and buffer pos in group */
770 snd_pcm_group_for_each_entry(s, substream) {
771 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
772 runtime = s->runtime;
774 if (snd_pcm_substream_chip(s) != card)
775 continue;
777 /* don't link Cap and Play */
778 if (substream->stream != s->stream)
779 continue;
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));
786 /* number of bytes in on-card buffer */
787 runtime->delay = on_card_bytes;
789 if (!card->can_dma)
790 on_card_bytes = bytes_avail;
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;
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;
808 } else {
809 ds->drained_count = 0;
811 } else
812 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
814 if (first) {
815 /* can't statically init min when wrap is involved */
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);
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,
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)
842 loops++;
844 pcm_buf_dma_ofs = min_buf_pos;
846 remdata = newdata % dpcm->period_bytes;
847 xfercount = newdata - remdata; /* a multiple of period_bytes */
848 /* come back when on_card_bytes has decreased enough to allow
849 write to happen, or when data has been consumed to make another
850 period
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);
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);
862 snd_pcm_group_for_each_entry(s, substream) {
863 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
865 /* don't link Cap and Play */
866 if (substream->stream != s->stream)
867 continue;
869 /* Store dma offset for use by pointer callback */
870 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
872 if (xfercount &&
873 /* Limit use of on card fifo for playback */
874 ((on_card_bytes <= ds->period_bytes) ||
875 (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
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];
883 if (card->can_dma) { /* buffer wrap is handled at lower level */
884 xfer1 = xfercount;
885 xfer2 = 0;
886 } else {
887 xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
888 xfer2 = xfercount - xfer1;
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));
899 if (xfer2) {
900 pd = s->runtime->dma_area;
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));
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));
928 /* ? host_rw_ofs always ahead of elapsed_dma_ofs by preload size? */
929 ds->pcm_buf_host_rw_ofs += xfercount;
930 ds->pcm_buf_elapsed_dma_ofs += xfercount;
931 snd_pcm_period_elapsed(s);
935 if (!card->hpi->interrupt_mode && dpcm->respawn_timer)
936 add_timer(&dpcm->timer);
939 static void snd_card_asihpi_int_task(unsigned long data)
941 struct hpi_adapter *a = (struct hpi_adapter *)data;
942 struct snd_card_asihpi *asihpi;
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);
951 static void snd_card_asihpi_isr(struct hpi_adapter *a)
953 struct snd_card_asihpi *asihpi;
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);
960 /***************************** PLAYBACK OPS ****************/
961 static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
962 unsigned int cmd, void *arg)
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);
970 static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
971 substream)
973 struct snd_pcm_runtime *runtime = substream->runtime;
974 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
976 snd_printdd("P%d prepare\n", substream->number);
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;
985 static snd_pcm_uframes_t
986 snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
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));
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;
999 static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
1000 u32 h_stream)
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;
1009 /* on cards without SRC, must query at valid rate,
1010 * maybe set by external sync
1012 err = hpi_mixer_get_control(asihpi->h_mixer,
1013 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1014 HPI_CONTROL_SAMPLECLOCK, &h_control);
1016 if (!err)
1017 err = hpi_sample_clock_get_sample_rate(h_control,
1018 &sample_rate);
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]);
1029 return formats;
1032 static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
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;
1040 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1041 if (dpcm == NULL)
1042 return -ENOMEM;
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;
1054 /*? also check ASI5000 samplerate source
1055 If external, only support external rate.
1056 If internal and other stream playing, can't switch
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;
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;
1081 /* snd_card_asihpi_playback.fifo_size = 0; */
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);
1087 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
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;
1097 if (card->support_grouping) {
1098 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
1099 snd_pcm_set_sync(substream);
1102 /* struct is copied, so can create initializer dynamically */
1103 runtime->hw = snd_card_asihpi_playback;
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;
1111 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1112 card->update_interval_frames);
1114 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1115 card->update_interval_frames, UINT_MAX);
1117 snd_printdd("playback open\n");
1119 return 0;
1122 static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1124 struct snd_pcm_runtime *runtime = substream->runtime;
1125 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1127 hpi_handle_error(hpi_outstream_close(dpcm->h_stream));
1128 snd_printdd("playback close\n");
1130 return 0;
1133 static 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,
1144 /***************************** CAPTURE OPS ****************/
1145 static snd_pcm_uframes_t
1146 snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
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));
1153 snd_printddd("%s, pointer=%d\n", name, dpcm->pcm_buf_dma_ofs);
1154 /* NOTE Unlike playback can't use actual samples_played
1155 for the capture position, because those samples aren't yet in
1156 the local buffer available for reading.
1158 return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
1161 static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1162 unsigned int cmd, void *arg)
1164 return snd_pcm_lib_ioctl(substream, cmd, arg);
1167 static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1169 struct snd_pcm_runtime *runtime = substream->runtime;
1170 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
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;
1177 snd_printdd("Capture Prepare %d\n", substream->number);
1178 return 0;
1181 static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
1182 u32 h_stream)
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;
1191 /* on cards without SRC, must query at valid rate,
1192 maybe set by external sync */
1193 err = hpi_mixer_get_control(asihpi->h_mixer,
1194 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1195 HPI_CONTROL_SAMPLECLOCK, &h_control);
1197 if (!err)
1198 err = hpi_sample_clock_get_sample_rate(h_control,
1199 &sample_rate);
1201 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1202 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
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]);
1211 return formats;
1214 static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
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;
1222 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1223 if (dpcm == NULL)
1224 return -ENOMEM;
1226 snd_printdd("capture open adapter %d stream %d\n",
1227 card->hpi->adapter->index, substream->number);
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;
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;
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;
1260 /* snd_card_asihpi_capture.fifo_size = 0; */
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;
1270 if (card->support_grouping)
1271 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1273 runtime->hw = snd_card_asihpi_capture;
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;
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);
1286 snd_pcm_set_sync(substream);
1288 return 0;
1291 static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1293 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1295 hpi_handle_error(hpi_instream_close(dpcm->h_stream));
1296 return 0;
1299 static 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,
1310 static int snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, int device)
1312 struct snd_pcm *pcm;
1313 int err;
1314 u16 num_instreams, num_outstreams, x16;
1315 u32 x32;
1317 err = hpi_adapter_get_info(asihpi->hpi->adapter->index,
1318 &num_outstreams, &num_instreams,
1319 &x16, &x32, &x16);
1321 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1322 num_outstreams, num_instreams, &pcm);
1323 if (err < 0)
1324 return err;
1326 /* pointer to ops struct is stored, dont change ops afterwards! */
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);
1332 pcm->private_data = asihpi;
1333 pcm->info_flags = 0;
1334 strcpy(pcm->name, "Asihpi PCM");
1336 /*? do we want to emulate MMAP for non-BBM cards?
1337 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
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);
1342 return 0;
1345 /***************************** MIXER CONTROLS ****************/
1346 struct 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]; /* copied to snd_ctl_elem_id.name[44]; */
1357 static 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",
1370 /* Number of strings must match the enumerations for HPI_TUNER_BAND in hpi.h */
1371 compile_time_assert(
1372 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1373 (HPI_TUNER_BAND_LAST+1)),
1374 assert_tuner_band_names_size);
1376 static 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"
1394 /* Number of strings must match the enumerations for HPI_SOURCENODES in hpi.h */
1395 compile_time_assert(
1396 (ARRAY_SIZE(asihpi_src_names) ==
1397 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1398 assert_src_names_size);
1400 static 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"
1414 /* Number of strings must match the enumerations for HPI_DESTNODES in hpi.h */
1415 compile_time_assert(
1416 (ARRAY_SIZE(asihpi_dst_names) ==
1417 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1418 assert_dst_names_size);
1420 static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1421 struct snd_card_asihpi *asihpi)
1423 int err;
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);
1431 return 0;
1434 /* Convert HPI control name and location into ALSA control name */
1435 static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1436 struct hpi_control *hpi_ctl,
1437 char *name)
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;
1446 if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
1447 dir = ""; /* clock is neither capture nor playback */
1448 else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1449 dir = "Capture "; /* On or towards a PCM capture destination*/
1450 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1451 (!hpi_ctl->dst_node_type))
1452 dir = "Capture "; /* On a source node that is not PCM playback */
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 "; /* Between an input and an output */
1457 else
1458 dir = "Playback "; /* PCM Playback source, or output node */
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);
1478 /* printk(KERN_INFO "Adding %s %d to %d ", hpi_ctl->name,
1479 hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */
1482 /*------------------------------------------------------------
1483 Volume controls
1484 ------------------------------------------------------------*/
1485 #define VOL_STEP_mB 1
1486 static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1487 struct snd_ctl_elem_info *uinfo)
1489 u32 h_control = kcontrol->private_value;
1490 u32 count;
1491 u16 err;
1492 /* native gains are in millibels */
1493 short min_gain_mB;
1494 short max_gain_mB;
1495 short step_gain_mB;
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;
1505 err = hpi_meter_query_channels(h_control, &count);
1506 if (err)
1507 count = HPI_MAX_CHANNELS;
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;
1517 static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1518 struct snd_ctl_elem_value *ucontrol)
1520 u32 h_control = kcontrol->private_value;
1521 short an_gain_mB[HPI_MAX_CHANNELS];
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;
1527 return 0;
1530 static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1531 struct snd_ctl_elem_value *ucontrol)
1533 int change;
1534 u32 h_control = kcontrol->private_value;
1535 short an_gain_mB[HPI_MAX_CHANNELS];
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 /* change = asihpi->mixer_volume[addr][0] != left ||
1542 asihpi->mixer_volume[addr][1] != right;
1544 change = 1;
1545 hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
1546 return change;
1549 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1551 #define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
1553 static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
1554 struct snd_ctl_elem_value *ucontrol)
1556 u32 h_control = kcontrol->private_value;
1557 u32 mute;
1559 hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
1560 ucontrol->value.integer.value[0] = mute ? 0 : 1;
1562 return 0;
1565 static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
1566 struct snd_ctl_elem_value *ucontrol)
1568 u32 h_control = kcontrol->private_value;
1569 int change = 1;
1570 /* HPI currently only supports all or none muting of multichannel volume
1571 ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
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;
1578 static int snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1579 struct hpi_control *hpi_ctl)
1581 struct snd_card *card = asihpi->card;
1582 struct snd_kcontrol_new snd_control;
1583 int err;
1584 u32 mute;
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;
1594 err = ctl_add(card, &snd_control, asihpi);
1595 if (err)
1596 return err;
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);
1606 return err;
1609 /*------------------------------------------------------------
1610 Level controls
1611 ------------------------------------------------------------*/
1612 static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1613 struct snd_ctl_elem_info *uinfo)
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;
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;
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;
1638 static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1639 struct snd_ctl_elem_value *ucontrol)
1641 u32 h_control = kcontrol->private_value;
1642 short an_gain_mB[HPI_MAX_CHANNELS];
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;
1650 return 0;
1653 static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1654 struct snd_ctl_elem_value *ucontrol)
1656 int change;
1657 u32 h_control = kcontrol->private_value;
1658 short an_gain_mB[HPI_MAX_CHANNELS];
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 /* change = asihpi->mixer_level[addr][0] != left ||
1665 asihpi->mixer_level[addr][1] != right;
1667 change = 1;
1668 hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
1669 return change;
1672 static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1674 static int snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1675 struct hpi_control *hpi_ctl)
1677 struct snd_card *card = asihpi->card;
1678 struct snd_kcontrol_new snd_control;
1680 /* can't use 'volume' cos some nodes have volume as well */
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;
1689 return ctl_add(card, &snd_control, asihpi);
1692 /*------------------------------------------------------------
1693 AESEBU controls
1694 ------------------------------------------------------------*/
1696 /* AESEBU format */
1697 static const char * const asihpi_aesebu_format_names[] = {
1698 "N/A", "S/PDIF", "AES/EBU" };
1700 static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1701 struct snd_ctl_elem_info *uinfo)
1703 return snd_ctl_enum_info(uinfo, 1, 3, asihpi_aesebu_format_names);
1706 static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1707 struct snd_ctl_elem_value *ucontrol,
1708 u16 (*func)(u32, u16 *))
1710 u32 h_control = kcontrol->private_value;
1711 u16 source, err;
1713 err = func(h_control, &source);
1715 /* default to N/A */
1716 ucontrol->value.enumerated.item[0] = 0;
1717 /* return success but set the control to N/A */
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;
1725 return 0;
1728 static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1729 struct snd_ctl_elem_value *ucontrol,
1730 u16 (*func)(u32, u16))
1732 u32 h_control = kcontrol->private_value;
1734 /* default to S/PDIF */
1735 u16 source = HPI_AESEBU_FORMAT_SPDIF;
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;
1742 if (func(h_control, source) != 0)
1743 return -EINVAL;
1745 return 1;
1748 static 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);
1754 static 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);
1760 static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1761 struct snd_ctl_elem_info *uinfo)
1763 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1764 uinfo->count = 1;
1766 uinfo->value.integer.min = 0;
1767 uinfo->value.integer.max = 0X1F;
1768 uinfo->value.integer.step = 1;
1770 return 0;
1773 static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1774 struct snd_ctl_elem_value *ucontrol) {
1776 u32 h_control = kcontrol->private_value;
1777 u16 status;
1779 hpi_handle_error(hpi_aesebu_receiver_get_error_status(
1780 h_control, &status));
1781 ucontrol->value.integer.value[0] = status;
1782 return 0;
1785 static int snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1786 struct hpi_control *hpi_ctl)
1788 struct snd_card *card = asihpi->card;
1789 struct snd_kcontrol_new snd_control;
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;
1798 if (ctl_add(card, &snd_control, asihpi) < 0)
1799 return -EINVAL;
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;
1807 return ctl_add(card, &snd_control, asihpi);
1810 static 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);
1816 static 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);
1823 static int snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1824 struct hpi_control *hpi_ctl)
1826 struct snd_card *card = asihpi->card;
1827 struct snd_kcontrol_new snd_control;
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;
1835 return ctl_add(card, &snd_control, asihpi);
1838 /*------------------------------------------------------------
1839 Tuner controls
1840 ------------------------------------------------------------*/
1842 /* Gain */
1844 static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1845 struct snd_ctl_elem_info *uinfo)
1847 u32 h_control = kcontrol->private_value;
1848 u16 err;
1849 short idx;
1850 u16 gain_range[3];
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;
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;
1867 static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1868 struct snd_ctl_elem_value *ucontrol)
1871 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1873 u32 h_control = kcontrol->private_value;
1874 short gain;
1876 hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
1877 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1879 return 0;
1882 static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1883 struct snd_ctl_elem_value *ucontrol)
1886 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1888 u32 h_control = kcontrol->private_value;
1889 short gain;
1891 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1892 hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
1894 return 1;
1897 /* Band */
1899 static 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;
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;
1912 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1913 return -EIO;
1915 return i;
1918 static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1919 struct snd_ctl_elem_info *uinfo)
1921 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1922 int num_bands = 0;
1924 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1925 HPI_TUNER_BAND_LAST);
1927 if (num_bands < 0)
1928 return num_bands;
1930 return snd_ctl_enum_info(uinfo, 1, num_bands, asihpi_tuner_band_names);
1933 static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1934 struct snd_ctl_elem_value *ucontrol)
1936 u32 h_control = kcontrol->private_value;
1938 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1940 u16 band, idx;
1941 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1942 u32 num_bands = 0;
1944 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1945 HPI_TUNER_BAND_LAST);
1947 hpi_handle_error(hpi_tuner_get_band(h_control, &band));
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;
1956 return 0;
1959 static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1960 struct snd_ctl_elem_value *ucontrol)
1963 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
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;
1971 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1972 HPI_TUNER_BAND_LAST);
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));
1980 return 1;
1983 /* Freq */
1985 static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1986 struct snd_ctl_elem_info *uinfo)
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];
1994 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1995 HPI_TUNER_BAND_LAST);
1997 freq_range[0] = INT_MAX;
1998 freq_range[1] = 0;
1999 freq_range[2] = INT_MAX;
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;
2010 /* skip band with bogus stepping */
2011 if (temp_freq_range[2] <= 0)
2012 continue;
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];
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;
2030 static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_value *ucontrol)
2033 u32 h_control = kcontrol->private_value;
2034 u32 freq;
2036 hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
2037 ucontrol->value.integer.value[0] = freq;
2039 return 0;
2042 static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2043 struct snd_ctl_elem_value *ucontrol)
2045 u32 h_control = kcontrol->private_value;
2046 u32 freq;
2048 freq = ucontrol->value.integer.value[0];
2049 hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
2051 return 1;
2054 /* Tuner control group initializer */
2055 static int snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2056 struct hpi_control *hpi_ctl)
2058 struct snd_card *card = asihpi->card;
2059 struct snd_kcontrol_new snd_control;
2061 snd_control.private_value = hpi_ctl->h_control;
2062 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
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;
2070 if (ctl_add(card, &snd_control, asihpi) < 0)
2071 return -EINVAL;
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;
2079 if (ctl_add(card, &snd_control, asihpi) < 0)
2080 return -EINVAL;
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;
2087 return ctl_add(card, &snd_control, asihpi);
2090 /*------------------------------------------------------------
2091 Meter controls
2092 ------------------------------------------------------------*/
2093 static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2094 struct snd_ctl_elem_info *uinfo)
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;
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;
2110 /* linear values for 10dB steps */
2111 static int log2lin[] = {
2112 0x7FFFFFFF, /* 0dB */
2113 679093956,
2114 214748365,
2115 67909396,
2116 21474837,
2117 6790940,
2118 2147484, /* -60dB */
2119 679094,
2120 214748, /* -80 */
2121 67909,
2122 21475, /* -100 */
2123 6791,
2124 2147,
2125 679,
2126 214,
2133 static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2134 struct snd_ctl_elem_value *ucontrol)
2136 u32 h_control = kcontrol->private_value;
2137 short an_gain_mB[HPI_MAX_CHANNELS], i;
2138 u16 err;
2140 err = hpi_meter_get_peak(h_control, an_gain_mB);
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 /* -ve is log value in millibels < -60dB,
2150 * convert to (roughly!) linear,
2152 ucontrol->value.integer.value[i] =
2153 log2lin[an_gain_mB[i] / -1000];
2156 return 0;
2159 static int snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2160 struct hpi_control *hpi_ctl, int subidx)
2162 struct snd_card *card = asihpi->card;
2163 struct snd_kcontrol_new snd_control;
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;
2171 snd_control.index = subidx;
2173 return ctl_add(card, &snd_control, asihpi);
2176 /*------------------------------------------------------------
2177 Multiplexer controls
2178 ------------------------------------------------------------*/
2179 static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
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;
2193 return s;
2196 static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2197 struct snd_ctl_elem_info *uinfo)
2199 int err;
2200 u16 src_node_type, src_node_index;
2201 u32 h_control = kcontrol->private_value;
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);
2208 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2209 uinfo->value.enumerated.item =
2210 uinfo->value.enumerated.items - 1;
2212 err =
2213 hpi_multiplexer_query_source(h_control,
2214 uinfo->value.enumerated.item,
2215 &src_node_type, &src_node_index);
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;
2223 static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2224 struct snd_ctl_elem_value *ucontrol)
2226 u32 h_control = kcontrol->private_value;
2227 u16 source_type, source_index;
2228 u16 src_node_type, src_node_index;
2229 int s;
2231 hpi_handle_error(hpi_multiplexer_get_source(h_control,
2232 &source_type, &source_index));
2233 /* Should cache this search result! */
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;
2239 if ((source_type == src_node_type)
2240 && (source_index == src_node_index)) {
2241 ucontrol->value.enumerated.item[0] = s;
2242 return 0;
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;
2252 static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2253 struct snd_ctl_elem_value *ucontrol)
2255 int change;
2256 u32 h_control = kcontrol->private_value;
2257 u16 source_type, source_index;
2258 u16 e;
2260 change = 1;
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;
2273 static int snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2274 struct hpi_control *hpi_ctl)
2276 struct snd_card *card = asihpi->card;
2277 struct snd_kcontrol_new snd_control;
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;
2285 return ctl_add(card, &snd_control, asihpi);
2289 /*------------------------------------------------------------
2290 Channel mode controls
2291 ------------------------------------------------------------*/
2292 static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2293 struct snd_ctl_elem_info *uinfo)
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"
2302 u32 h_control = kcontrol->private_value;
2303 u16 mode;
2304 int i;
2305 const char *mapped_names[6];
2306 int valid_modes = 0;
2308 /* HPI channel mode values can be from 1 to 6
2309 Some adapters only support a contiguous subset
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++;
2318 if (!valid_modes)
2319 return -EINVAL;
2321 return snd_ctl_enum_info(uinfo, 1, valid_modes, mapped_names);
2324 static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2325 struct snd_ctl_elem_value *ucontrol)
2327 u32 h_control = kcontrol->private_value;
2328 u16 mode;
2330 if (hpi_channel_mode_get(h_control, &mode))
2331 mode = 1;
2333 ucontrol->value.enumerated.item[0] = mode - 1;
2335 return 0;
2338 static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2339 struct snd_ctl_elem_value *ucontrol)
2341 int change;
2342 u32 h_control = kcontrol->private_value;
2344 change = 1;
2346 hpi_handle_error(hpi_channel_mode_set(h_control,
2347 ucontrol->value.enumerated.item[0] + 1));
2348 return change;
2352 static int snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2353 struct hpi_control *hpi_ctl)
2355 struct snd_card *card = asihpi->card;
2356 struct snd_kcontrol_new snd_control;
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;
2364 return ctl_add(card, &snd_control, asihpi);
2367 /*------------------------------------------------------------
2368 Sampleclock source controls
2369 ------------------------------------------------------------*/
2370 static 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"};
2377 /* Number of strings must match expected enumerated values */
2378 compile_time_assert(
2379 (ARRAY_SIZE(sampleclock_sources) == MAX_CLOCKSOURCES),
2380 assert_sampleclock_sources_size);
2382 static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2383 struct snd_ctl_elem_info *uinfo)
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;
2392 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2393 uinfo->value.enumerated.item =
2394 uinfo->value.enumerated.items - 1;
2396 strcpy(uinfo->value.enumerated.name,
2397 clkcache->s[uinfo->value.enumerated.item].name);
2398 return 0;
2401 static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2402 struct snd_ctl_elem_value *ucontrol)
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;
2411 ucontrol->value.enumerated.item[0] = 0;
2412 if (hpi_sample_clock_get_source(h_control, &source))
2413 source = 0;
2415 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2416 if (hpi_sample_clock_get_source_index(h_control, &srcindex))
2417 srcindex = 0;
2419 for (i = 0; i < clkcache->count; i++)
2420 if ((clkcache->s[i].source == source) &&
2421 (clkcache->s[i].index == srcindex))
2422 break;
2424 ucontrol->value.enumerated.item[0] = i;
2426 return 0;
2429 static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2430 struct snd_ctl_elem_value *ucontrol)
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;
2439 change = 1;
2440 item = ucontrol->value.enumerated.item[0];
2441 if (item >= clkcache->count)
2442 item = clkcache->count-1;
2444 hpi_handle_error(hpi_sample_clock_set_source(
2445 h_control, clkcache->s[item].source));
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;
2453 /*------------------------------------------------------------
2454 Clkrate controls
2455 ------------------------------------------------------------*/
2456 /* Need to change this to enumerated control with list of rates */
2457 static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2458 struct snd_ctl_elem_info *uinfo)
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;
2466 return 0;
2469 static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2470 struct snd_ctl_elem_value *ucontrol)
2472 u32 h_control = kcontrol->private_value;
2473 u32 rate;
2474 u16 e;
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;
2484 static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2485 struct snd_ctl_elem_value *ucontrol)
2487 int change;
2488 u32 h_control = kcontrol->private_value;
2490 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2491 asihpi->mixer_clkrate[addr][1] != right;
2493 change = 1;
2494 hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
2495 ucontrol->value.integer.value[0]));
2496 return change;
2499 static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2500 struct snd_ctl_elem_info *uinfo)
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;
2508 return 0;
2511 static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2512 struct snd_ctl_elem_value *ucontrol)
2514 u32 h_control = kcontrol->private_value;
2515 u32 rate;
2516 u16 e;
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;
2526 static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2527 struct hpi_control *hpi_ctl)
2529 struct snd_card *card;
2530 struct snd_kcontrol_new snd_control;
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;
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;
2544 clkcache->has_local = 0;
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;
2558 if (has_aes_in)
2559 /* already will have picked up index 0 above */
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++;
2572 clkcache->count = i;
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;
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;
2591 if (ctl_add(card, &snd_control, asihpi) < 0)
2592 return -EINVAL;
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;
2601 return ctl_add(card, &snd_control, asihpi);
2603 /*------------------------------------------------------------
2604 Mixer
2605 ------------------------------------------------------------*/
2607 static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
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;
2615 if (snd_BUG_ON(!asihpi))
2616 return -EINVAL;
2617 card = asihpi->card;
2618 strcpy(card->mixername, "Asihpi Mixer");
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;
2627 memset(&prev_ctl, 0, sizeof(prev_ctl));
2628 prev_ctl.control_type = -1;
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;
2652 hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2653 hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
2655 /* ASI50xx in SSX mode has multiple meters on the same node.
2656 Use subindex to create distinct ALSA controls
2657 for any duplicated controls.
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;
2668 prev_ctl = hpi_ctl;
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: /* ignore these */
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;
2718 if (err < 0)
2719 return err;
2721 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2722 hpi_handle_error(err);
2724 dev_info(&asihpi->pci->dev, "%d mixer controls found\n", idx);
2726 return 0;
2729 /*------------------------------------------------------------
2730 /proc interface
2731 ------------------------------------------------------------*/
2733 static void
2734 snd_asihpi_proc_read(struct snd_info_entry *entry,
2735 struct snd_info_buffer *buffer)
2737 struct snd_card_asihpi *asihpi = entry->private_data;
2738 u32 h_control;
2739 u32 rate = 0;
2740 u16 source = 0;
2742 u16 num_outstreams;
2743 u16 num_instreams;
2744 u16 version;
2745 u32 serial_number;
2746 u16 type;
2748 int err;
2750 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2752 hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
2753 &num_outstreams, &num_instreams,
2754 &version, &serial_number, &type));
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);
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));
2767 err = hpi_mixer_get_control(asihpi->h_mixer,
2768 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2769 HPI_CONTROL_SAMPLECLOCK, &h_control);
2771 if (!err) {
2772 err = hpi_sample_clock_get_sample_rate(h_control, &rate);
2773 err += hpi_sample_clock_get_source(h_control, &source);
2775 if (!err)
2776 snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
2777 rate, sampleclock_sources[source]);
2781 static void snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2783 struct snd_info_entry *entry;
2785 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2786 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2789 /*------------------------------------------------------------
2790 HWDEP
2791 ------------------------------------------------------------*/
2793 static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2795 if (enable_hpi_hwdep)
2796 return 0;
2797 else
2798 return -ENODEV;
2802 static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2804 if (enable_hpi_hwdep)
2805 return asihpi_hpi_release(file);
2806 else
2807 return -ENODEV;
2810 static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2811 unsigned int cmd, unsigned long arg)
2813 if (enable_hpi_hwdep)
2814 return asihpi_hpi_ioctl(file, cmd, arg);
2815 else
2816 return -ENODEV;
2820 /* results in /dev/snd/hwC#D0 file for each card with index #
2821 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2823 static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, int device)
2825 struct snd_hwdep *hw;
2826 int err;
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;
2840 /*------------------------------------------------------------
2841 CARD
2842 ------------------------------------------------------------*/
2843 static int snd_asihpi_probe(struct pci_dev *pci_dev,
2844 const struct pci_device_id *pci_id)
2846 int err;
2847 struct hpi_adapter *hpi;
2848 struct snd_card *card;
2849 struct snd_card_asihpi *asihpi;
2851 u32 h_control;
2852 u32 h_stream;
2853 u32 adapter_index;
2855 static int dev;
2856 if (dev >= SNDRV_CARDS)
2857 return -ENODEV;
2859 /* Should this be enable[hpi->index] ? */
2860 if (!enable[dev]) {
2861 dev++;
2862 return -ENOENT;
2865 /* Initialise low-level HPI driver */
2866 err = asihpi_adapter_probe(pci_dev, pci_id);
2867 if (err < 0)
2868 return err;
2870 hpi = pci_get_drvdata(pci_dev);
2871 adapter_index = hpi->adapter->index;
2872 /* first try to give the card the same index as its hardware index */
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 /* if that fails, try the default index==next available */
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);
2886 asihpi = card->private_data;
2887 asihpi->card = card;
2888 asihpi->pci = pci_dev;
2889 asihpi->hpi = hpi;
2890 hpi->snd_card = card;
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;
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;
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;
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;
2921 hpi_handle_error(hpi_instream_open(adapter_index,
2922 0, &h_stream));
2924 err = hpi_instream_host_buffer_free(h_stream);
2925 asihpi->can_dma = (!err);
2927 hpi_handle_error(hpi_instream_close(h_stream));
2929 if (!asihpi->can_dma)
2930 asihpi->update_interval_frames *= 2;
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;
2940 if (asihpi->out_max_chans > 2) { /* assume LL mode */
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;
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
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;
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;
2967 err = hpi_mixer_get_control(asihpi->h_mixer,
2968 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2969 HPI_CONTROL_SAMPLECLOCK, &h_control);
2971 if (!err)
2972 err = hpi_sample_clock_set_local_rate(
2973 h_control, adapter_fs);
2975 snd_asihpi_proc_init(asihpi);
2977 /* always create, can be enabled or disabled dynamically
2978 by enable_hwdep module param*/
2979 snd_asihpi_hpi_new(asihpi, 0);
2981 strcpy(card->driver, "ASIHPI");
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);
2989 if (!err) {
2990 dev++;
2991 return 0;
2993 __nodev:
2994 snd_card_free(card);
2995 dev_err(&pci_dev->dev, "snd_asihpi_probe error %d\n", err);
2996 return err;
3000 static void snd_asihpi_remove(struct pci_dev *pci_dev)
3002 struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
3003 struct snd_card_asihpi *asihpi = hpi->snd_card->private_data;
3005 /* Stop interrupts */
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);
3013 snd_card_free(hpi->snd_card);
3014 hpi->snd_card = NULL;
3015 asihpi_adapter_remove(pci_dev);
3018 static 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,}
3027 MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
3029 static struct pci_driver driver = {
3030 .name = KBUILD_MODNAME,
3031 .id_table = asihpi_pci_tbl,
3032 .probe = snd_asihpi_probe,
3033 .remove = snd_asihpi_remove,
3036 static int __init snd_asihpi_init(void)
3038 asihpi_init();
3039 return pci_register_driver(&driver);
3042 static void __exit snd_asihpi_exit(void)
3045 pci_unregister_driver(&driver);
3046 asihpi_exit();
3049 module_init(snd_asihpi_init)
3050 module_exit(snd_asihpi_exit)