Merge tag 'v3.3.7' into 3.3/master
[zen-stable.git] / sound / pci / asihpi / asihpi.c
blobe8de831f98bc510c6cde42159bce817dad45408b
1 /*
2 * Asihpi soundcard
3 * Copyright (c) by AudioScience Inc <alsa@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"
32 #include <linux/pci.h>
33 #include <linux/init.h>
34 #include <linux/jiffies.h>
35 #include <linux/slab.h>
36 #include <linux/time.h>
37 #include <linux/wait.h>
38 #include <linux/module.h>
39 #include <sound/core.h>
40 #include <sound/control.h>
41 #include <sound/pcm.h>
42 #include <sound/pcm_params.h>
43 #include <sound/info.h>
44 #include <sound/initval.h>
45 #include <sound/tlv.h>
46 #include <sound/hwdep.h>
48 MODULE_LICENSE("GPL");
49 MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
50 MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx "
51 HPI_VER_STRING);
53 #if defined CONFIG_SND_DEBUG_VERBOSE
54 /**
55 * snd_printddd - very verbose debug printk
56 * @format: format string
58 * Works like snd_printk() for debugging purposes.
59 * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
60 * Must set snd module debug parameter to 3 to enable at runtime.
62 #define snd_printddd(format, args...) \
63 __snd_printk(3, __FILE__, __LINE__, format, ##args)
64 #else
65 #define snd_printddd(format, args...) do { } while (0)
66 #endif
68 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
69 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
70 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
71 static bool enable_hpi_hwdep = 1;
73 module_param_array(index, int, NULL, S_IRUGO);
74 MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
76 module_param_array(id, charp, NULL, S_IRUGO);
77 MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
79 module_param_array(enable, bool, NULL, S_IRUGO);
80 MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
82 module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
83 MODULE_PARM_DESC(enable_hpi_hwdep,
84 "ALSA enable HPI hwdep for AudioScience soundcard ");
86 /* identify driver */
87 #ifdef KERNEL_ALSA_BUILD
88 static char *build_info = "Built using headers from kernel source";
89 module_param(build_info, charp, S_IRUGO);
90 MODULE_PARM_DESC(build_info, "built using headers from kernel source");
91 #else
92 static char *build_info = "Built within ALSA source";
93 module_param(build_info, charp, S_IRUGO);
94 MODULE_PARM_DESC(build_info, "built within ALSA source");
95 #endif
97 /* set to 1 to dump every control from adapter to log */
98 static const int mixer_dump;
100 #define DEFAULT_SAMPLERATE 44100
101 static int adapter_fs = DEFAULT_SAMPLERATE;
103 /* defaults */
104 #define PERIODS_MIN 2
105 #define PERIOD_BYTES_MIN 2048
106 #define BUFFER_BYTES_MAX (512 * 1024)
108 #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
110 struct clk_source {
111 int source;
112 int index;
113 char *name;
116 struct clk_cache {
117 int count;
118 int has_local;
119 struct clk_source s[MAX_CLOCKSOURCES];
122 /* Per card data */
123 struct snd_card_asihpi {
124 struct snd_card *card;
125 struct pci_dev *pci;
126 struct hpi_adapter *hpi;
128 u32 h_mixer;
129 struct clk_cache cc;
131 u16 can_dma;
132 u16 support_grouping;
133 u16 support_mrx;
134 u16 update_interval_frames;
135 u16 in_max_chans;
136 u16 out_max_chans;
137 u16 in_min_chans;
138 u16 out_min_chans;
141 /* Per stream data */
142 struct snd_card_asihpi_pcm {
143 struct timer_list timer;
144 unsigned int respawn_timer;
145 unsigned int hpi_buffer_attached;
146 unsigned int buffer_bytes;
147 unsigned int period_bytes;
148 unsigned int bytes_per_sec;
149 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
150 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
151 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
152 unsigned int drained_count;
153 struct snd_pcm_substream *substream;
154 u32 h_stream;
155 struct hpi_format format;
158 /* universal stream verbs work with out or in stream handles */
160 /* Functions to allow driver to give a buffer to HPI for busmastering */
162 static u16 hpi_stream_host_buffer_attach(
163 u32 h_stream, /* handle to outstream. */
164 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
165 u32 pci_address
168 struct hpi_message hm;
169 struct hpi_response hr;
170 unsigned int obj = hpi_handle_object(h_stream);
172 if (!h_stream)
173 return HPI_ERROR_INVALID_OBJ;
174 hpi_init_message_response(&hm, &hr, obj,
175 obj == HPI_OBJ_OSTREAM ?
176 HPI_OSTREAM_HOSTBUFFER_ALLOC :
177 HPI_ISTREAM_HOSTBUFFER_ALLOC);
179 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
180 &hm.obj_index);
182 hm.u.d.u.buffer.buffer_size = size_in_bytes;
183 hm.u.d.u.buffer.pci_address = pci_address;
184 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
185 hpi_send_recv(&hm, &hr);
186 return hr.error;
189 static u16 hpi_stream_host_buffer_detach(u32 h_stream)
191 struct hpi_message hm;
192 struct hpi_response hr;
193 unsigned int obj = hpi_handle_object(h_stream);
195 if (!h_stream)
196 return HPI_ERROR_INVALID_OBJ;
198 hpi_init_message_response(&hm, &hr, obj,
199 obj == HPI_OBJ_OSTREAM ?
200 HPI_OSTREAM_HOSTBUFFER_FREE :
201 HPI_ISTREAM_HOSTBUFFER_FREE);
203 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
204 &hm.obj_index);
205 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
206 hpi_send_recv(&hm, &hr);
207 return hr.error;
210 static inline u16 hpi_stream_start(u32 h_stream)
212 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
213 return hpi_outstream_start(h_stream);
214 else
215 return hpi_instream_start(h_stream);
218 static inline u16 hpi_stream_stop(u32 h_stream)
220 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
221 return hpi_outstream_stop(h_stream);
222 else
223 return hpi_instream_stop(h_stream);
226 static inline u16 hpi_stream_get_info_ex(
227 u32 h_stream,
228 u16 *pw_state,
229 u32 *pbuffer_size,
230 u32 *pdata_in_buffer,
231 u32 *psample_count,
232 u32 *pauxiliary_data
235 u16 e;
236 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
237 e = hpi_outstream_get_info_ex(h_stream, pw_state,
238 pbuffer_size, pdata_in_buffer,
239 psample_count, pauxiliary_data);
240 else
241 e = hpi_instream_get_info_ex(h_stream, pw_state,
242 pbuffer_size, pdata_in_buffer,
243 psample_count, pauxiliary_data);
244 return e;
247 static inline u16 hpi_stream_group_add(
248 u32 h_master,
249 u32 h_stream)
251 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
252 return hpi_outstream_group_add(h_master, h_stream);
253 else
254 return hpi_instream_group_add(h_master, h_stream);
257 static inline u16 hpi_stream_group_reset(u32 h_stream)
259 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
260 return hpi_outstream_group_reset(h_stream);
261 else
262 return hpi_instream_group_reset(h_stream);
265 static inline u16 hpi_stream_group_get_map(
266 u32 h_stream, u32 *mo, u32 *mi)
268 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
269 return hpi_outstream_group_get_map(h_stream, mo, mi);
270 else
271 return hpi_instream_group_get_map(h_stream, mo, mi);
274 static u16 handle_error(u16 err, int line, char *filename)
276 if (err)
277 printk(KERN_WARNING
278 "in file %s, line %d: HPI error %d\n",
279 filename, line, err);
280 return err;
283 #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
285 /***************************** GENERAL PCM ****************/
287 static void print_hwparams(struct snd_pcm_substream *substream,
288 struct snd_pcm_hw_params *p)
290 char name[16];
291 snd_pcm_debug_name(substream, name, sizeof(name));
292 snd_printd("%s HWPARAMS\n", name);
293 snd_printd(" samplerate %d Hz\n", params_rate(p));
294 snd_printd(" channels %d\n", params_channels(p));
295 snd_printd(" format %d\n", params_format(p));
296 snd_printd(" subformat %d\n", params_subformat(p));
297 snd_printd(" buffer %d B\n", params_buffer_bytes(p));
298 snd_printd(" period %d B\n", params_period_bytes(p));
299 snd_printd(" access %d\n", params_access(p));
300 snd_printd(" period_size %d\n", params_period_size(p));
301 snd_printd(" periods %d\n", params_periods(p));
302 snd_printd(" buffer_size %d\n", params_buffer_size(p));
303 snd_printd(" %d B/s\n", params_rate(p) *
304 params_channels(p) *
305 snd_pcm_format_width(params_format(p)) / 8);
309 static snd_pcm_format_t hpi_to_alsa_formats[] = {
310 -1, /* INVALID */
311 SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
312 SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
313 -1, /* HPI_FORMAT_MPEG_L1 3 */
314 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
315 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
316 -1, /* HPI_FORMAT_DOLBY_AC2 6 */
317 -1, /* HPI_FORMAT_DOLBY_AC3 7 */
318 SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
319 -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
320 -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
321 SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
322 -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
323 -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
324 SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
325 #if 1
326 /* ALSA can't handle 3 byte sample size together with power-of-2
327 * constraint on buffer_bytes, so disable this format
330 #else
331 /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
332 #endif
336 static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
337 u16 *hpi_format)
339 u16 format;
341 for (format = HPI_FORMAT_PCM8_UNSIGNED;
342 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
343 if (hpi_to_alsa_formats[format] == alsa_format) {
344 *hpi_format = format;
345 return 0;
349 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
350 alsa_format);
351 *hpi_format = 0;
352 return -EINVAL;
355 static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
356 struct snd_pcm_hardware *pcmhw)
358 u16 err;
359 u32 h_control;
360 u32 sample_rate;
361 int idx;
362 unsigned int rate_min = 200000;
363 unsigned int rate_max = 0;
364 unsigned int rates = 0;
366 if (asihpi->support_mrx) {
367 rates |= SNDRV_PCM_RATE_CONTINUOUS;
368 rates |= SNDRV_PCM_RATE_8000_96000;
369 rate_min = 8000;
370 rate_max = 100000;
371 } else {
372 /* on cards without SRC,
373 valid rates are determined by sampleclock */
374 err = hpi_mixer_get_control(asihpi->h_mixer,
375 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
376 HPI_CONTROL_SAMPLECLOCK, &h_control);
377 if (err) {
378 snd_printk(KERN_ERR
379 "No local sampleclock, err %d\n", err);
382 for (idx = -1; idx < 100; idx++) {
383 if (idx == -1) {
384 if (hpi_sample_clock_get_sample_rate(h_control,
385 &sample_rate))
386 continue;
387 } else if (hpi_sample_clock_query_local_rate(h_control,
388 idx, &sample_rate)) {
389 break;
392 rate_min = min(rate_min, sample_rate);
393 rate_max = max(rate_max, sample_rate);
395 switch (sample_rate) {
396 case 5512:
397 rates |= SNDRV_PCM_RATE_5512;
398 break;
399 case 8000:
400 rates |= SNDRV_PCM_RATE_8000;
401 break;
402 case 11025:
403 rates |= SNDRV_PCM_RATE_11025;
404 break;
405 case 16000:
406 rates |= SNDRV_PCM_RATE_16000;
407 break;
408 case 22050:
409 rates |= SNDRV_PCM_RATE_22050;
410 break;
411 case 32000:
412 rates |= SNDRV_PCM_RATE_32000;
413 break;
414 case 44100:
415 rates |= SNDRV_PCM_RATE_44100;
416 break;
417 case 48000:
418 rates |= SNDRV_PCM_RATE_48000;
419 break;
420 case 64000:
421 rates |= SNDRV_PCM_RATE_64000;
422 break;
423 case 88200:
424 rates |= SNDRV_PCM_RATE_88200;
425 break;
426 case 96000:
427 rates |= SNDRV_PCM_RATE_96000;
428 break;
429 case 176400:
430 rates |= SNDRV_PCM_RATE_176400;
431 break;
432 case 192000:
433 rates |= SNDRV_PCM_RATE_192000;
434 break;
435 default: /* some other rate */
436 rates |= SNDRV_PCM_RATE_KNOT;
441 pcmhw->rates = rates;
442 pcmhw->rate_min = rate_min;
443 pcmhw->rate_max = rate_max;
446 static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
447 struct snd_pcm_hw_params *params)
449 struct snd_pcm_runtime *runtime = substream->runtime;
450 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
451 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
452 int err;
453 u16 format;
454 int width;
455 unsigned int bytes_per_sec;
457 print_hwparams(substream, params);
458 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
459 if (err < 0)
460 return err;
461 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
462 if (err)
463 return err;
465 hpi_handle_error(hpi_format_create(&dpcm->format,
466 params_channels(params),
467 format, params_rate(params), 0, 0));
469 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
470 if (hpi_instream_reset(dpcm->h_stream) != 0)
471 return -EINVAL;
473 if (hpi_instream_set_format(
474 dpcm->h_stream, &dpcm->format) != 0)
475 return -EINVAL;
478 dpcm->hpi_buffer_attached = 0;
479 if (card->can_dma) {
480 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
481 params_buffer_bytes(params), runtime->dma_addr);
482 if (err == 0) {
483 snd_printdd(
484 "stream_host_buffer_attach succeeded %u %lu\n",
485 params_buffer_bytes(params),
486 (unsigned long)runtime->dma_addr);
487 } else {
488 snd_printd("stream_host_buffer_attach error %d\n",
489 err);
490 return -ENOMEM;
493 err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
494 &dpcm->hpi_buffer_attached,
495 NULL, NULL, NULL);
497 snd_printdd("stream_host_buffer_attach status 0x%x\n",
498 dpcm->hpi_buffer_attached);
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;
541 /*? (dpcm->period_bytes * HZ / dpcm->bytes_per_sec); */
542 expiry = max(expiry, 1); /* don't let it be zero! */
543 dpcm->timer.expires = jiffies + expiry;
544 dpcm->respawn_timer = 1;
545 add_timer(&dpcm->timer);
548 static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
550 struct snd_pcm_runtime *runtime = substream->runtime;
551 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
553 dpcm->respawn_timer = 0;
554 del_timer(&dpcm->timer);
557 static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
558 int cmd)
560 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
561 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
562 struct snd_pcm_substream *s;
563 u16 e;
564 char name[16];
566 snd_pcm_debug_name(substream, name, sizeof(name));
567 snd_printdd("%s trigger\n", name);
569 switch (cmd) {
570 case SNDRV_PCM_TRIGGER_START:
571 snd_pcm_group_for_each_entry(s, substream) {
572 struct snd_pcm_runtime *runtime = s->runtime;
573 struct snd_card_asihpi_pcm *ds = runtime->private_data;
575 if (snd_pcm_substream_chip(s) != card)
576 continue;
578 /* don't link Cap and Play */
579 if (substream->stream != s->stream)
580 continue;
582 ds->drained_count = 0;
583 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
584 /* How do I know how much valid data is present
585 * in buffer? Must be at least one period!
586 * Guessing 2 periods, but if
587 * buffer is bigger it may contain even more
588 * data??
590 unsigned int preload = ds->period_bytes * 1;
591 snd_printddd("%d preload x%x\n", s->number, preload);
592 hpi_handle_error(hpi_outstream_write_buf(
593 ds->h_stream,
594 &runtime->dma_area[0],
595 preload,
596 &ds->format));
597 ds->pcm_buf_host_rw_ofs = preload;
600 if (card->support_grouping) {
601 snd_printdd("%d group\n", s->number);
602 e = hpi_stream_group_add(
603 dpcm->h_stream,
604 ds->h_stream);
605 if (!e) {
606 snd_pcm_trigger_done(s, substream);
607 } else {
608 hpi_handle_error(e);
609 break;
611 } else
612 break;
614 snd_printdd("start\n");
615 /* start the master stream */
616 snd_card_asihpi_pcm_timer_start(substream);
617 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
618 !card->can_dma)
619 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
620 break;
622 case SNDRV_PCM_TRIGGER_STOP:
623 snd_card_asihpi_pcm_timer_stop(substream);
624 snd_pcm_group_for_each_entry(s, substream) {
625 if (snd_pcm_substream_chip(s) != card)
626 continue;
627 /* don't link Cap and Play */
628 if (substream->stream != s->stream)
629 continue;
631 /*? workaround linked streams don't
632 transition to SETUP 20070706*/
633 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
635 if (card->support_grouping) {
636 snd_printdd("%d group\n", s->number);
637 snd_pcm_trigger_done(s, substream);
638 } else
639 break;
641 snd_printdd("stop\n");
643 /* _prepare and _hwparams reset the stream */
644 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
645 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
646 hpi_handle_error(
647 hpi_outstream_reset(dpcm->h_stream));
649 if (card->support_grouping)
650 hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
651 break;
653 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
654 snd_printdd("pause release\n");
655 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
656 snd_card_asihpi_pcm_timer_start(substream);
657 break;
658 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
659 snd_printdd("pause\n");
660 snd_card_asihpi_pcm_timer_stop(substream);
661 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
662 break;
663 default:
664 snd_printd(KERN_ERR "\tINVALID\n");
665 return -EINVAL;
668 return 0;
671 /*algorithm outline
672 Without linking degenerates to getting single stream pos etc
673 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
676 pcm_buf_dma_ofs=get_buf_pos(s);
677 for_each_linked_stream(s) {
678 pcm_buf_dma_ofs=get_buf_pos(s);
679 min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes)
680 new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
682 timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
683 for_each_linked_stream(s) {
684 s->pcm_buf_dma_ofs = min_buf_pos;
685 if (new_data > period_bytes) {
686 if (mmap) {
687 irq_pos = (irq_pos + period_bytes) % buffer_bytes;
688 if (playback) {
689 write(period_bytes);
690 } else {
691 read(period_bytes);
694 snd_pcm_period_elapsed(s);
699 /** Minimum of 2 modulo values. Works correctly when the difference between
700 * the values is less than half the modulus
702 static inline unsigned int modulo_min(unsigned int a, unsigned int b,
703 unsigned long int modulus)
705 unsigned int result;
706 if (((a-b) % modulus) < (modulus/2))
707 result = b;
708 else
709 result = a;
711 return result;
714 /** Timer function, equivalent to interrupt service routine for cards
716 static void snd_card_asihpi_timer_function(unsigned long data)
718 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
719 struct snd_pcm_substream *substream = dpcm->substream;
720 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
721 struct snd_pcm_runtime *runtime;
722 struct snd_pcm_substream *s;
723 unsigned int newdata = 0;
724 unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
725 unsigned int remdata, xfercount, next_jiffies;
726 int first = 1;
727 int loops = 0;
728 u16 state;
729 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
730 char name[16];
732 snd_pcm_debug_name(substream, name, sizeof(name));
734 snd_printdd("%s snd_card_asihpi_timer_function\n", name);
736 /* find minimum newdata and buffer pos in group */
737 snd_pcm_group_for_each_entry(s, substream) {
738 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
739 runtime = s->runtime;
741 if (snd_pcm_substream_chip(s) != card)
742 continue;
744 /* don't link Cap and Play */
745 if (substream->stream != s->stream)
746 continue;
748 hpi_handle_error(hpi_stream_get_info_ex(
749 ds->h_stream, &state,
750 &buffer_size, &bytes_avail,
751 &samples_played, &on_card_bytes));
753 /* number of bytes in on-card buffer */
754 runtime->delay = on_card_bytes;
756 if (!card->can_dma)
757 on_card_bytes = bytes_avail;
759 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
760 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
761 if (state == HPI_STATE_STOPPED) {
762 if (bytes_avail == 0) {
763 hpi_handle_error(hpi_stream_start(ds->h_stream));
764 snd_printdd("P%d start\n", s->number);
765 ds->drained_count = 0;
767 } else if (state == HPI_STATE_DRAINED) {
768 snd_printd(KERN_WARNING "P%d drained\n",
769 s->number);
770 ds->drained_count++;
771 if (ds->drained_count > 20) {
772 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
773 continue;
775 } else {
776 ds->drained_count = 0;
778 } else
779 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
781 if (first) {
782 /* can't statically init min when wrap is involved */
783 min_buf_pos = pcm_buf_dma_ofs;
784 newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
785 first = 0;
786 } else {
787 min_buf_pos =
788 modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
789 newdata = min(
790 (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
791 newdata);
794 snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n",
795 (unsigned long)frames_to_bytes(runtime,
796 runtime->status->hw_ptr),
797 (unsigned long)frames_to_bytes(runtime,
798 runtime->control->appl_ptr));
800 snd_printdd("%d S=%d, "
801 "rw=0x%04X, dma=0x%04X, left=0x%04X, "
802 "aux=0x%04X space=0x%04X\n",
803 s->number, state,
804 ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs,
805 (int)bytes_avail,
806 (int)on_card_bytes, buffer_size-bytes_avail);
807 loops++;
809 pcm_buf_dma_ofs = min_buf_pos;
811 remdata = newdata % dpcm->period_bytes;
812 xfercount = newdata - remdata; /* a multiple of period_bytes */
813 /* come back when on_card_bytes has decreased enough to allow
814 write to happen, or when data has been consumed to make another
815 period
817 if (xfercount && (on_card_bytes > dpcm->period_bytes))
818 next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
819 else
820 next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
822 next_jiffies = max(next_jiffies, 1U);
823 dpcm->timer.expires = jiffies + next_jiffies;
824 snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n",
825 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
827 snd_pcm_group_for_each_entry(s, substream) {
828 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
830 /* don't link Cap and Play */
831 if (substream->stream != s->stream)
832 continue;
834 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
836 if (xfercount &&
837 /* Limit use of on card fifo for playback */
838 ((on_card_bytes <= ds->period_bytes) ||
839 (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
843 unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
844 unsigned int xfer1, xfer2;
845 char *pd = &s->runtime->dma_area[buf_ofs];
847 if (card->can_dma) { /* buffer wrap is handled at lower level */
848 xfer1 = xfercount;
849 xfer2 = 0;
850 } else {
851 xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
852 xfer2 = xfercount - xfer1;
855 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
856 snd_printddd("P%d write1 0x%04X 0x%04X\n",
857 s->number, xfer1, buf_ofs);
858 hpi_handle_error(
859 hpi_outstream_write_buf(
860 ds->h_stream, pd, xfer1,
861 &ds->format));
863 if (xfer2) {
864 pd = s->runtime->dma_area;
866 snd_printddd("P%d write2 0x%04X 0x%04X\n",
867 s->number,
868 xfercount - xfer1, buf_ofs);
869 hpi_handle_error(
870 hpi_outstream_write_buf(
871 ds->h_stream, pd,
872 xfercount - xfer1,
873 &ds->format));
875 } else {
876 snd_printddd("C%d read1 0x%04x\n",
877 s->number, xfer1);
878 hpi_handle_error(
879 hpi_instream_read_buf(
880 ds->h_stream,
881 pd, xfer1));
882 if (xfer2) {
883 pd = s->runtime->dma_area;
884 snd_printddd("C%d read2 0x%04x\n",
885 s->number, xfer2);
886 hpi_handle_error(
887 hpi_instream_read_buf(
888 ds->h_stream,
889 pd, xfer2));
892 ds->pcm_buf_host_rw_ofs += xfercount;
893 ds->pcm_buf_elapsed_dma_ofs += xfercount;
894 snd_pcm_period_elapsed(s);
898 if (dpcm->respawn_timer)
899 add_timer(&dpcm->timer);
902 /***************************** PLAYBACK OPS ****************/
903 static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
904 unsigned int cmd, void *arg)
906 char name[16];
907 snd_pcm_debug_name(substream, name, sizeof(name));
908 snd_printddd(KERN_INFO "%s ioctl %d\n", name, cmd);
909 return snd_pcm_lib_ioctl(substream, cmd, arg);
912 static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
913 substream)
915 struct snd_pcm_runtime *runtime = substream->runtime;
916 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
918 snd_printdd("P%d prepare\n", substream->number);
920 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
921 dpcm->pcm_buf_host_rw_ofs = 0;
922 dpcm->pcm_buf_dma_ofs = 0;
923 dpcm->pcm_buf_elapsed_dma_ofs = 0;
924 return 0;
927 static snd_pcm_uframes_t
928 snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
930 struct snd_pcm_runtime *runtime = substream->runtime;
931 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
932 snd_pcm_uframes_t ptr;
933 char name[16];
934 snd_pcm_debug_name(substream, name, sizeof(name));
936 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
937 snd_printddd("%s pointer = 0x%04lx\n", name, (unsigned long)ptr);
938 return ptr;
941 static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
942 u32 h_stream)
944 struct hpi_format hpi_format;
945 u16 format;
946 u16 err;
947 u32 h_control;
948 u32 sample_rate = 48000;
949 u64 formats = 0;
951 /* on cards without SRC, must query at valid rate,
952 * maybe set by external sync
954 err = hpi_mixer_get_control(asihpi->h_mixer,
955 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
956 HPI_CONTROL_SAMPLECLOCK, &h_control);
958 if (!err)
959 err = hpi_sample_clock_get_sample_rate(h_control,
960 &sample_rate);
962 for (format = HPI_FORMAT_PCM8_UNSIGNED;
963 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
964 err = hpi_format_create(&hpi_format, asihpi->out_max_chans,
965 format, sample_rate, 128000, 0);
966 if (!err)
967 err = hpi_outstream_query_format(h_stream, &hpi_format);
968 if (!err && (hpi_to_alsa_formats[format] != -1))
969 formats |= (1ULL << hpi_to_alsa_formats[format]);
971 return formats;
974 static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
976 struct snd_pcm_runtime *runtime = substream->runtime;
977 struct snd_card_asihpi_pcm *dpcm;
978 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
979 struct snd_pcm_hardware snd_card_asihpi_playback;
980 int err;
982 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
983 if (dpcm == NULL)
984 return -ENOMEM;
986 err = hpi_outstream_open(card->hpi->adapter->index,
987 substream->number, &dpcm->h_stream);
988 hpi_handle_error(err);
989 if (err)
990 kfree(dpcm);
991 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
992 return -EBUSY;
993 if (err)
994 return -EIO;
996 /*? also check ASI5000 samplerate source
997 If external, only support external rate.
998 If internal and other stream playing, can't switch
1001 init_timer(&dpcm->timer);
1002 dpcm->timer.data = (unsigned long) dpcm;
1003 dpcm->timer.function = snd_card_asihpi_timer_function;
1004 dpcm->substream = substream;
1005 runtime->private_data = dpcm;
1006 runtime->private_free = snd_card_asihpi_runtime_free;
1008 memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback));
1009 snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
1010 snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN;
1011 /*?snd_card_asihpi_playback.period_bytes_min =
1012 card->out_max_chans * 4096; */
1013 snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
1014 snd_card_asihpi_playback.periods_min = PERIODS_MIN;
1015 snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
1016 /* snd_card_asihpi_playback.fifo_size = 0; */
1017 snd_card_asihpi_playback.channels_max = card->out_max_chans;
1018 snd_card_asihpi_playback.channels_min = card->out_min_chans;
1019 snd_card_asihpi_playback.formats =
1020 snd_card_asihpi_playback_formats(card, dpcm->h_stream);
1022 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
1024 snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
1025 SNDRV_PCM_INFO_DOUBLE |
1026 SNDRV_PCM_INFO_BATCH |
1027 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1028 SNDRV_PCM_INFO_PAUSE |
1029 SNDRV_PCM_INFO_MMAP |
1030 SNDRV_PCM_INFO_MMAP_VALID;
1032 if (card->support_grouping) {
1033 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
1034 snd_pcm_set_sync(substream);
1037 /* struct is copied, so can create initializer dynamically */
1038 runtime->hw = snd_card_asihpi_playback;
1040 if (card->can_dma)
1041 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1042 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1043 if (err < 0)
1044 return err;
1046 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1047 card->update_interval_frames);
1049 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1050 card->update_interval_frames * 2, UINT_MAX);
1052 snd_printdd("playback open\n");
1054 return 0;
1057 static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1059 struct snd_pcm_runtime *runtime = substream->runtime;
1060 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1062 hpi_handle_error(hpi_outstream_close(dpcm->h_stream));
1063 snd_printdd("playback close\n");
1065 return 0;
1068 static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1069 .open = snd_card_asihpi_playback_open,
1070 .close = snd_card_asihpi_playback_close,
1071 .ioctl = snd_card_asihpi_playback_ioctl,
1072 .hw_params = snd_card_asihpi_pcm_hw_params,
1073 .hw_free = snd_card_asihpi_hw_free,
1074 .prepare = snd_card_asihpi_playback_prepare,
1075 .trigger = snd_card_asihpi_trigger,
1076 .pointer = snd_card_asihpi_playback_pointer,
1079 /***************************** CAPTURE OPS ****************/
1080 static snd_pcm_uframes_t
1081 snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1083 struct snd_pcm_runtime *runtime = substream->runtime;
1084 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1086 snd_printddd("capture pointer %d=%d\n",
1087 substream->number, dpcm->pcm_buf_dma_ofs);
1088 /* NOTE Unlike playback can't use actual samples_played
1089 for the capture position, because those samples aren't yet in
1090 the local buffer available for reading.
1092 return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
1095 static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1096 unsigned int cmd, void *arg)
1098 return snd_pcm_lib_ioctl(substream, cmd, arg);
1101 static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1103 struct snd_pcm_runtime *runtime = substream->runtime;
1104 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1106 hpi_handle_error(hpi_instream_reset(dpcm->h_stream));
1107 dpcm->pcm_buf_host_rw_ofs = 0;
1108 dpcm->pcm_buf_dma_ofs = 0;
1109 dpcm->pcm_buf_elapsed_dma_ofs = 0;
1111 snd_printdd("Capture Prepare %d\n", substream->number);
1112 return 0;
1117 static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
1118 u32 h_stream)
1120 struct hpi_format hpi_format;
1121 u16 format;
1122 u16 err;
1123 u32 h_control;
1124 u32 sample_rate = 48000;
1125 u64 formats = 0;
1127 /* on cards without SRC, must query at valid rate,
1128 maybe set by external sync */
1129 err = hpi_mixer_get_control(asihpi->h_mixer,
1130 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1131 HPI_CONTROL_SAMPLECLOCK, &h_control);
1133 if (!err)
1134 err = hpi_sample_clock_get_sample_rate(h_control,
1135 &sample_rate);
1137 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1138 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1140 err = hpi_format_create(&hpi_format, asihpi->in_max_chans,
1141 format, sample_rate, 128000, 0);
1142 if (!err)
1143 err = hpi_instream_query_format(h_stream, &hpi_format);
1144 if (!err)
1145 formats |= (1ULL << hpi_to_alsa_formats[format]);
1147 return formats;
1150 static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1152 struct snd_pcm_runtime *runtime = substream->runtime;
1153 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1154 struct snd_card_asihpi_pcm *dpcm;
1155 struct snd_pcm_hardware snd_card_asihpi_capture;
1156 int err;
1158 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1159 if (dpcm == NULL)
1160 return -ENOMEM;
1162 snd_printdd("capture open adapter %d stream %d\n",
1163 card->hpi->adapter->index, substream->number);
1165 err = hpi_handle_error(
1166 hpi_instream_open(card->hpi->adapter->index,
1167 substream->number, &dpcm->h_stream));
1168 if (err)
1169 kfree(dpcm);
1170 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1171 return -EBUSY;
1172 if (err)
1173 return -EIO;
1175 init_timer(&dpcm->timer);
1176 dpcm->timer.data = (unsigned long) dpcm;
1177 dpcm->timer.function = snd_card_asihpi_timer_function;
1178 dpcm->substream = substream;
1179 runtime->private_data = dpcm;
1180 runtime->private_free = snd_card_asihpi_runtime_free;
1182 memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture));
1183 snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
1184 snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN;
1185 snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
1186 snd_card_asihpi_capture.periods_min = PERIODS_MIN;
1187 snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
1188 /* snd_card_asihpi_capture.fifo_size = 0; */
1189 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1190 snd_card_asihpi_capture.channels_min = card->in_min_chans;
1191 snd_card_asihpi_capture.formats =
1192 snd_card_asihpi_capture_formats(card, dpcm->h_stream);
1193 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1194 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
1195 SNDRV_PCM_INFO_MMAP |
1196 SNDRV_PCM_INFO_MMAP_VALID;
1198 if (card->support_grouping)
1199 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1201 runtime->hw = snd_card_asihpi_capture;
1203 if (card->can_dma)
1204 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1205 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1206 if (err < 0)
1207 return err;
1209 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1210 card->update_interval_frames);
1211 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1212 card->update_interval_frames * 2, UINT_MAX);
1214 snd_pcm_set_sync(substream);
1216 return 0;
1219 static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1221 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1223 hpi_handle_error(hpi_instream_close(dpcm->h_stream));
1224 return 0;
1227 static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1228 .open = snd_card_asihpi_capture_open,
1229 .close = snd_card_asihpi_capture_close,
1230 .ioctl = snd_card_asihpi_capture_ioctl,
1231 .hw_params = snd_card_asihpi_pcm_hw_params,
1232 .hw_free = snd_card_asihpi_hw_free,
1233 .prepare = snd_card_asihpi_capture_prepare,
1234 .trigger = snd_card_asihpi_trigger,
1235 .pointer = snd_card_asihpi_capture_pointer,
1238 static int __devinit snd_card_asihpi_pcm_new(
1239 struct snd_card_asihpi *asihpi, int device)
1241 struct snd_pcm *pcm;
1242 int err;
1243 u16 num_instreams, num_outstreams, x16;
1244 u32 x32;
1246 err = hpi_adapter_get_info(asihpi->hpi->adapter->index,
1247 &num_outstreams, &num_instreams,
1248 &x16, &x32, &x16);
1250 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1251 num_outstreams, num_instreams, &pcm);
1252 if (err < 0)
1253 return err;
1254 /* pointer to ops struct is stored, dont change ops afterwards! */
1255 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1256 &snd_card_asihpi_playback_mmap_ops);
1257 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1258 &snd_card_asihpi_capture_mmap_ops);
1260 pcm->private_data = asihpi;
1261 pcm->info_flags = 0;
1262 strcpy(pcm->name, "Asihpi PCM");
1264 /*? do we want to emulate MMAP for non-BBM cards?
1265 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
1266 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1267 snd_dma_pci_data(asihpi->pci),
1268 64*1024, BUFFER_BYTES_MAX);
1270 return 0;
1273 /***************************** MIXER CONTROLS ****************/
1274 struct hpi_control {
1275 u32 h_control;
1276 u16 control_type;
1277 u16 src_node_type;
1278 u16 src_node_index;
1279 u16 dst_node_type;
1280 u16 dst_node_index;
1281 u16 band;
1282 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1285 static const char * const asihpi_tuner_band_names[] = {
1286 "invalid",
1287 "AM",
1288 "FM mono",
1289 "TV NTSC-M",
1290 "FM stereo",
1291 "AUX",
1292 "TV PAL BG",
1293 "TV PAL I",
1294 "TV PAL DK",
1295 "TV SECAM",
1298 compile_time_assert(
1299 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1300 (HPI_TUNER_BAND_LAST+1)),
1301 assert_tuner_band_names_size);
1303 static const char * const asihpi_src_names[] = {
1304 "no source",
1305 "PCM",
1306 "Line",
1307 "Digital",
1308 "Tuner",
1309 "RF",
1310 "Clock",
1311 "Bitstream",
1312 "Mic",
1313 "Net",
1314 "Analog",
1315 "Adapter",
1316 "RTP",
1317 "Internal"
1320 compile_time_assert(
1321 (ARRAY_SIZE(asihpi_src_names) ==
1322 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1323 assert_src_names_size);
1325 static const char * const asihpi_dst_names[] = {
1326 "no destination",
1327 "PCM",
1328 "Line",
1329 "Digital",
1330 "RF",
1331 "Speaker",
1332 "Net",
1333 "Analog",
1334 "RTP",
1337 compile_time_assert(
1338 (ARRAY_SIZE(asihpi_dst_names) ==
1339 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1340 assert_dst_names_size);
1342 static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1343 struct snd_card_asihpi *asihpi)
1345 int err;
1347 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1348 if (err < 0)
1349 return err;
1350 else if (mixer_dump)
1351 snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1353 return 0;
1356 /* Convert HPI control name and location into ALSA control name */
1357 static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1358 struct hpi_control *hpi_ctl,
1359 char *name)
1361 char *dir;
1362 memset(snd_control, 0, sizeof(*snd_control));
1363 snd_control->name = hpi_ctl->name;
1364 snd_control->private_value = hpi_ctl->h_control;
1365 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1366 snd_control->index = 0;
1368 if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
1369 dir = ""; /* clock is neither capture nor playback */
1370 else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1371 dir = "Capture "; /* On or towards a PCM capture destination*/
1372 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1373 (!hpi_ctl->dst_node_type))
1374 dir = "Capture "; /* On a source node that is not PCM playback */
1375 else if (hpi_ctl->src_node_type &&
1376 (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1377 (hpi_ctl->dst_node_type))
1378 dir = "Monitor Playback "; /* Between an input and an output */
1379 else
1380 dir = "Playback "; /* PCM Playback source, or output node */
1382 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1383 sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
1384 asihpi_src_names[hpi_ctl->src_node_type],
1385 hpi_ctl->src_node_index,
1386 asihpi_dst_names[hpi_ctl->dst_node_type],
1387 hpi_ctl->dst_node_index,
1388 dir, name);
1389 else if (hpi_ctl->dst_node_type) {
1390 sprintf(hpi_ctl->name, "%s %d %s%s",
1391 asihpi_dst_names[hpi_ctl->dst_node_type],
1392 hpi_ctl->dst_node_index,
1393 dir, name);
1394 } else {
1395 sprintf(hpi_ctl->name, "%s %d %s%s",
1396 asihpi_src_names[hpi_ctl->src_node_type],
1397 hpi_ctl->src_node_index,
1398 dir, name);
1400 /* printk(KERN_INFO "Adding %s %d to %d ", hpi_ctl->name,
1401 hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */
1404 /*------------------------------------------------------------
1405 Volume controls
1406 ------------------------------------------------------------*/
1407 #define VOL_STEP_mB 1
1408 static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1409 struct snd_ctl_elem_info *uinfo)
1411 u32 h_control = kcontrol->private_value;
1412 u32 count;
1413 u16 err;
1414 /* native gains are in millibels */
1415 short min_gain_mB;
1416 short max_gain_mB;
1417 short step_gain_mB;
1419 err = hpi_volume_query_range(h_control,
1420 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1421 if (err) {
1422 max_gain_mB = 0;
1423 min_gain_mB = -10000;
1424 step_gain_mB = VOL_STEP_mB;
1427 err = hpi_meter_query_channels(h_control, &count);
1428 if (err)
1429 count = HPI_MAX_CHANNELS;
1431 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1432 uinfo->count = count;
1433 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1434 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1435 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1436 return 0;
1439 static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1440 struct snd_ctl_elem_value *ucontrol)
1442 u32 h_control = kcontrol->private_value;
1443 short an_gain_mB[HPI_MAX_CHANNELS];
1445 hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB));
1446 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1447 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1449 return 0;
1452 static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1453 struct snd_ctl_elem_value *ucontrol)
1455 int change;
1456 u32 h_control = kcontrol->private_value;
1457 short an_gain_mB[HPI_MAX_CHANNELS];
1459 an_gain_mB[0] =
1460 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1461 an_gain_mB[1] =
1462 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1463 /* change = asihpi->mixer_volume[addr][0] != left ||
1464 asihpi->mixer_volume[addr][1] != right;
1466 change = 1;
1467 hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
1468 return change;
1471 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1473 #define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
1475 static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
1476 struct snd_ctl_elem_value *ucontrol)
1478 u32 h_control = kcontrol->private_value;
1479 u32 mute;
1481 hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
1482 ucontrol->value.integer.value[0] = mute ? 0 : 1;
1484 return 0;
1487 static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
1488 struct snd_ctl_elem_value *ucontrol)
1490 u32 h_control = kcontrol->private_value;
1491 int change = 1;
1492 /* HPI currently only supports all or none muting of multichannel volume
1493 ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
1495 int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
1496 hpi_handle_error(hpi_volume_set_mute(h_control, mute));
1497 return change;
1500 static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1501 struct hpi_control *hpi_ctl)
1503 struct snd_card *card = asihpi->card;
1504 struct snd_kcontrol_new snd_control;
1505 int err;
1506 u32 mute;
1508 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
1509 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1510 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1511 snd_control.info = snd_asihpi_volume_info;
1512 snd_control.get = snd_asihpi_volume_get;
1513 snd_control.put = snd_asihpi_volume_put;
1514 snd_control.tlv.p = db_scale_100;
1516 err = ctl_add(card, &snd_control, asihpi);
1517 if (err)
1518 return err;
1520 if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
1521 asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
1522 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1523 snd_control.info = snd_asihpi_volume_mute_info;
1524 snd_control.get = snd_asihpi_volume_mute_get;
1525 snd_control.put = snd_asihpi_volume_mute_put;
1526 err = ctl_add(card, &snd_control, asihpi);
1528 return err;
1531 /*------------------------------------------------------------
1532 Level controls
1533 ------------------------------------------------------------*/
1534 static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1535 struct snd_ctl_elem_info *uinfo)
1537 u32 h_control = kcontrol->private_value;
1538 u16 err;
1539 short min_gain_mB;
1540 short max_gain_mB;
1541 short step_gain_mB;
1543 err =
1544 hpi_level_query_range(h_control, &min_gain_mB,
1545 &max_gain_mB, &step_gain_mB);
1546 if (err) {
1547 max_gain_mB = 2400;
1548 min_gain_mB = -1000;
1549 step_gain_mB = 100;
1552 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1553 uinfo->count = 2;
1554 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1555 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1556 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1557 return 0;
1560 static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1561 struct snd_ctl_elem_value *ucontrol)
1563 u32 h_control = kcontrol->private_value;
1564 short an_gain_mB[HPI_MAX_CHANNELS];
1566 hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
1567 ucontrol->value.integer.value[0] =
1568 an_gain_mB[0] / HPI_UNITS_PER_dB;
1569 ucontrol->value.integer.value[1] =
1570 an_gain_mB[1] / HPI_UNITS_PER_dB;
1572 return 0;
1575 static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1576 struct snd_ctl_elem_value *ucontrol)
1578 int change;
1579 u32 h_control = kcontrol->private_value;
1580 short an_gain_mB[HPI_MAX_CHANNELS];
1582 an_gain_mB[0] =
1583 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1584 an_gain_mB[1] =
1585 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1586 /* change = asihpi->mixer_level[addr][0] != left ||
1587 asihpi->mixer_level[addr][1] != right;
1589 change = 1;
1590 hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
1591 return change;
1594 static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1596 static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1597 struct hpi_control *hpi_ctl)
1599 struct snd_card *card = asihpi->card;
1600 struct snd_kcontrol_new snd_control;
1602 /* can't use 'volume' cos some nodes have volume as well */
1603 asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
1604 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1605 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1606 snd_control.info = snd_asihpi_level_info;
1607 snd_control.get = snd_asihpi_level_get;
1608 snd_control.put = snd_asihpi_level_put;
1609 snd_control.tlv.p = db_scale_level;
1611 return ctl_add(card, &snd_control, asihpi);
1614 /*------------------------------------------------------------
1615 AESEBU controls
1616 ------------------------------------------------------------*/
1618 /* AESEBU format */
1619 static const char * const asihpi_aesebu_format_names[] = {
1620 "N/A", "S/PDIF", "AES/EBU" };
1622 static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1623 struct snd_ctl_elem_info *uinfo)
1625 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1626 uinfo->count = 1;
1627 uinfo->value.enumerated.items = 3;
1629 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1630 uinfo->value.enumerated.item =
1631 uinfo->value.enumerated.items - 1;
1633 strcpy(uinfo->value.enumerated.name,
1634 asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1636 return 0;
1639 static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1640 struct snd_ctl_elem_value *ucontrol,
1641 u16 (*func)(u32, u16 *))
1643 u32 h_control = kcontrol->private_value;
1644 u16 source, err;
1646 err = func(h_control, &source);
1648 /* default to N/A */
1649 ucontrol->value.enumerated.item[0] = 0;
1650 /* return success but set the control to N/A */
1651 if (err)
1652 return 0;
1653 if (source == HPI_AESEBU_FORMAT_SPDIF)
1654 ucontrol->value.enumerated.item[0] = 1;
1655 if (source == HPI_AESEBU_FORMAT_AESEBU)
1656 ucontrol->value.enumerated.item[0] = 2;
1658 return 0;
1661 static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1662 struct snd_ctl_elem_value *ucontrol,
1663 u16 (*func)(u32, u16))
1665 u32 h_control = kcontrol->private_value;
1667 /* default to S/PDIF */
1668 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1670 if (ucontrol->value.enumerated.item[0] == 1)
1671 source = HPI_AESEBU_FORMAT_SPDIF;
1672 if (ucontrol->value.enumerated.item[0] == 2)
1673 source = HPI_AESEBU_FORMAT_AESEBU;
1675 if (func(h_control, source) != 0)
1676 return -EINVAL;
1678 return 1;
1681 static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1682 struct snd_ctl_elem_value *ucontrol) {
1683 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1684 hpi_aesebu_receiver_get_format);
1687 static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1688 struct snd_ctl_elem_value *ucontrol) {
1689 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1690 hpi_aesebu_receiver_set_format);
1693 static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1694 struct snd_ctl_elem_info *uinfo)
1696 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1697 uinfo->count = 1;
1699 uinfo->value.integer.min = 0;
1700 uinfo->value.integer.max = 0X1F;
1701 uinfo->value.integer.step = 1;
1703 return 0;
1706 static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1707 struct snd_ctl_elem_value *ucontrol) {
1709 u32 h_control = kcontrol->private_value;
1710 u16 status;
1712 hpi_handle_error(hpi_aesebu_receiver_get_error_status(
1713 h_control, &status));
1714 ucontrol->value.integer.value[0] = status;
1715 return 0;
1718 static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1719 struct hpi_control *hpi_ctl)
1721 struct snd_card *card = asihpi->card;
1722 struct snd_kcontrol_new snd_control;
1724 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1725 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1726 snd_control.info = snd_asihpi_aesebu_format_info;
1727 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1728 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1731 if (ctl_add(card, &snd_control, asihpi) < 0)
1732 return -EINVAL;
1734 asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
1735 snd_control.access =
1736 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1737 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1738 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1740 return ctl_add(card, &snd_control, asihpi);
1743 static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1744 struct snd_ctl_elem_value *ucontrol) {
1745 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1746 hpi_aesebu_transmitter_get_format);
1749 static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1750 struct snd_ctl_elem_value *ucontrol) {
1751 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1752 hpi_aesebu_transmitter_set_format);
1756 static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1757 struct hpi_control *hpi_ctl)
1759 struct snd_card *card = asihpi->card;
1760 struct snd_kcontrol_new snd_control;
1762 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1763 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1764 snd_control.info = snd_asihpi_aesebu_format_info;
1765 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1766 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1768 return ctl_add(card, &snd_control, asihpi);
1771 /*------------------------------------------------------------
1772 Tuner controls
1773 ------------------------------------------------------------*/
1775 /* Gain */
1777 static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1778 struct snd_ctl_elem_info *uinfo)
1780 u32 h_control = kcontrol->private_value;
1781 u16 err;
1782 short idx;
1783 u16 gain_range[3];
1785 for (idx = 0; idx < 3; idx++) {
1786 err = hpi_tuner_query_gain(h_control,
1787 idx, &gain_range[idx]);
1788 if (err != 0)
1789 return err;
1792 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1793 uinfo->count = 1;
1794 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1795 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1796 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1797 return 0;
1800 static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1801 struct snd_ctl_elem_value *ucontrol)
1804 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1806 u32 h_control = kcontrol->private_value;
1807 short gain;
1809 hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
1810 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1812 return 0;
1815 static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1816 struct snd_ctl_elem_value *ucontrol)
1819 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1821 u32 h_control = kcontrol->private_value;
1822 short gain;
1824 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1825 hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
1827 return 1;
1830 /* Band */
1832 static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1833 u16 *band_list, u32 len) {
1834 u32 h_control = kcontrol->private_value;
1835 u16 err = 0;
1836 u32 i;
1838 for (i = 0; i < len; i++) {
1839 err = hpi_tuner_query_band(
1840 h_control, i, &band_list[i]);
1841 if (err != 0)
1842 break;
1845 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1846 return -EIO;
1848 return i;
1851 static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1852 struct snd_ctl_elem_info *uinfo)
1854 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1855 int num_bands = 0;
1857 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1858 HPI_TUNER_BAND_LAST);
1860 if (num_bands < 0)
1861 return num_bands;
1863 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1864 uinfo->count = 1;
1865 uinfo->value.enumerated.items = num_bands;
1867 if (num_bands > 0) {
1868 if (uinfo->value.enumerated.item >=
1869 uinfo->value.enumerated.items)
1870 uinfo->value.enumerated.item =
1871 uinfo->value.enumerated.items - 1;
1873 strcpy(uinfo->value.enumerated.name,
1874 asihpi_tuner_band_names[
1875 tuner_bands[uinfo->value.enumerated.item]]);
1878 return 0;
1881 static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1882 struct snd_ctl_elem_value *ucontrol)
1884 u32 h_control = kcontrol->private_value;
1886 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1888 u16 band, idx;
1889 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1890 u32 num_bands = 0;
1892 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1893 HPI_TUNER_BAND_LAST);
1895 hpi_handle_error(hpi_tuner_get_band(h_control, &band));
1897 ucontrol->value.enumerated.item[0] = -1;
1898 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1899 if (tuner_bands[idx] == band) {
1900 ucontrol->value.enumerated.item[0] = idx;
1901 break;
1904 return 0;
1907 static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1908 struct snd_ctl_elem_value *ucontrol)
1911 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1913 u32 h_control = kcontrol->private_value;
1914 u16 band;
1915 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1916 u32 num_bands = 0;
1918 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1919 HPI_TUNER_BAND_LAST);
1921 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1922 hpi_handle_error(hpi_tuner_set_band(h_control, band));
1924 return 1;
1927 /* Freq */
1929 static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1930 struct snd_ctl_elem_info *uinfo)
1932 u32 h_control = kcontrol->private_value;
1933 u16 err;
1934 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1935 u16 num_bands = 0, band_iter, idx;
1936 u32 freq_range[3], temp_freq_range[3];
1938 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1939 HPI_TUNER_BAND_LAST);
1941 freq_range[0] = INT_MAX;
1942 freq_range[1] = 0;
1943 freq_range[2] = INT_MAX;
1945 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1946 for (idx = 0; idx < 3; idx++) {
1947 err = hpi_tuner_query_frequency(h_control,
1948 idx, tuner_bands[band_iter],
1949 &temp_freq_range[idx]);
1950 if (err != 0)
1951 return err;
1954 /* skip band with bogus stepping */
1955 if (temp_freq_range[2] <= 0)
1956 continue;
1958 if (temp_freq_range[0] < freq_range[0])
1959 freq_range[0] = temp_freq_range[0];
1960 if (temp_freq_range[1] > freq_range[1])
1961 freq_range[1] = temp_freq_range[1];
1962 if (temp_freq_range[2] < freq_range[2])
1963 freq_range[2] = temp_freq_range[2];
1966 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1967 uinfo->count = 1;
1968 uinfo->value.integer.min = ((int)freq_range[0]);
1969 uinfo->value.integer.max = ((int)freq_range[1]);
1970 uinfo->value.integer.step = ((int)freq_range[2]);
1971 return 0;
1974 static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1975 struct snd_ctl_elem_value *ucontrol)
1977 u32 h_control = kcontrol->private_value;
1978 u32 freq;
1980 hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
1981 ucontrol->value.integer.value[0] = freq;
1983 return 0;
1986 static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
1987 struct snd_ctl_elem_value *ucontrol)
1989 u32 h_control = kcontrol->private_value;
1990 u32 freq;
1992 freq = ucontrol->value.integer.value[0];
1993 hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
1995 return 1;
1998 /* Tuner control group initializer */
1999 static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2000 struct hpi_control *hpi_ctl)
2002 struct snd_card *card = asihpi->card;
2003 struct snd_kcontrol_new snd_control;
2005 snd_control.private_value = hpi_ctl->h_control;
2006 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2008 if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
2009 asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
2010 snd_control.info = snd_asihpi_tuner_gain_info;
2011 snd_control.get = snd_asihpi_tuner_gain_get;
2012 snd_control.put = snd_asihpi_tuner_gain_put;
2014 if (ctl_add(card, &snd_control, asihpi) < 0)
2015 return -EINVAL;
2018 asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
2019 snd_control.info = snd_asihpi_tuner_band_info;
2020 snd_control.get = snd_asihpi_tuner_band_get;
2021 snd_control.put = snd_asihpi_tuner_band_put;
2023 if (ctl_add(card, &snd_control, asihpi) < 0)
2024 return -EINVAL;
2026 asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
2027 snd_control.info = snd_asihpi_tuner_freq_info;
2028 snd_control.get = snd_asihpi_tuner_freq_get;
2029 snd_control.put = snd_asihpi_tuner_freq_put;
2031 return ctl_add(card, &snd_control, asihpi);
2034 /*------------------------------------------------------------
2035 Meter controls
2036 ------------------------------------------------------------*/
2037 static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2038 struct snd_ctl_elem_info *uinfo)
2040 u32 h_control = kcontrol->private_value;
2041 u32 count;
2042 u16 err;
2043 err = hpi_meter_query_channels(h_control, &count);
2044 if (err)
2045 count = HPI_MAX_CHANNELS;
2047 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2048 uinfo->count = count;
2049 uinfo->value.integer.min = 0;
2050 uinfo->value.integer.max = 0x7FFFFFFF;
2051 return 0;
2054 /* linear values for 10dB steps */
2055 static int log2lin[] = {
2056 0x7FFFFFFF, /* 0dB */
2057 679093956,
2058 214748365,
2059 67909396,
2060 21474837,
2061 6790940,
2062 2147484, /* -60dB */
2063 679094,
2064 214748, /* -80 */
2065 67909,
2066 21475, /* -100 */
2067 6791,
2068 2147,
2069 679,
2070 214,
2077 static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2078 struct snd_ctl_elem_value *ucontrol)
2080 u32 h_control = kcontrol->private_value;
2081 short an_gain_mB[HPI_MAX_CHANNELS], i;
2082 u16 err;
2084 err = hpi_meter_get_peak(h_control, an_gain_mB);
2086 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2087 if (err) {
2088 ucontrol->value.integer.value[i] = 0;
2089 } else if (an_gain_mB[i] >= 0) {
2090 ucontrol->value.integer.value[i] =
2091 an_gain_mB[i] << 16;
2092 } else {
2093 /* -ve is log value in millibels < -60dB,
2094 * convert to (roughly!) linear,
2096 ucontrol->value.integer.value[i] =
2097 log2lin[an_gain_mB[i] / -1000];
2100 return 0;
2103 static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2104 struct hpi_control *hpi_ctl, int subidx)
2106 struct snd_card *card = asihpi->card;
2107 struct snd_kcontrol_new snd_control;
2109 asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
2110 snd_control.access =
2111 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2112 snd_control.info = snd_asihpi_meter_info;
2113 snd_control.get = snd_asihpi_meter_get;
2115 snd_control.index = subidx;
2117 return ctl_add(card, &snd_control, asihpi);
2120 /*------------------------------------------------------------
2121 Multiplexer controls
2122 ------------------------------------------------------------*/
2123 static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2125 u32 h_control = snd_control->private_value;
2126 struct hpi_control hpi_ctl;
2127 int s, err;
2128 for (s = 0; s < 32; s++) {
2129 err = hpi_multiplexer_query_source(h_control, s,
2130 &hpi_ctl.
2131 src_node_type,
2132 &hpi_ctl.
2133 src_node_index);
2134 if (err)
2135 break;
2137 return s;
2140 static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2141 struct snd_ctl_elem_info *uinfo)
2143 int err;
2144 u16 src_node_type, src_node_index;
2145 u32 h_control = kcontrol->private_value;
2147 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2148 uinfo->count = 1;
2149 uinfo->value.enumerated.items =
2150 snd_card_asihpi_mux_count_sources(kcontrol);
2152 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2153 uinfo->value.enumerated.item =
2154 uinfo->value.enumerated.items - 1;
2156 err =
2157 hpi_multiplexer_query_source(h_control,
2158 uinfo->value.enumerated.item,
2159 &src_node_type, &src_node_index);
2161 sprintf(uinfo->value.enumerated.name, "%s %d",
2162 asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
2163 src_node_index);
2164 return 0;
2167 static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2168 struct snd_ctl_elem_value *ucontrol)
2170 u32 h_control = kcontrol->private_value;
2171 u16 source_type, source_index;
2172 u16 src_node_type, src_node_index;
2173 int s;
2175 hpi_handle_error(hpi_multiplexer_get_source(h_control,
2176 &source_type, &source_index));
2177 /* Should cache this search result! */
2178 for (s = 0; s < 256; s++) {
2179 if (hpi_multiplexer_query_source(h_control, s,
2180 &src_node_type, &src_node_index))
2181 break;
2183 if ((source_type == src_node_type)
2184 && (source_index == src_node_index)) {
2185 ucontrol->value.enumerated.item[0] = s;
2186 return 0;
2189 snd_printd(KERN_WARNING
2190 "Control %x failed to match mux source %hu %hu\n",
2191 h_control, source_type, source_index);
2192 ucontrol->value.enumerated.item[0] = 0;
2193 return 0;
2196 static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2197 struct snd_ctl_elem_value *ucontrol)
2199 int change;
2200 u32 h_control = kcontrol->private_value;
2201 u16 source_type, source_index;
2202 u16 e;
2204 change = 1;
2206 e = hpi_multiplexer_query_source(h_control,
2207 ucontrol->value.enumerated.item[0],
2208 &source_type, &source_index);
2209 if (!e)
2210 hpi_handle_error(
2211 hpi_multiplexer_set_source(h_control,
2212 source_type, source_index));
2213 return change;
2217 static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2218 struct hpi_control *hpi_ctl)
2220 struct snd_card *card = asihpi->card;
2221 struct snd_kcontrol_new snd_control;
2223 asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
2224 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2225 snd_control.info = snd_asihpi_mux_info;
2226 snd_control.get = snd_asihpi_mux_get;
2227 snd_control.put = snd_asihpi_mux_put;
2229 return ctl_add(card, &snd_control, asihpi);
2233 /*------------------------------------------------------------
2234 Channel mode controls
2235 ------------------------------------------------------------*/
2236 static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2237 struct snd_ctl_elem_info *uinfo)
2239 static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
2240 "invalid",
2241 "Normal", "Swap",
2242 "From Left", "From Right",
2243 "To Left", "To Right"
2246 u32 h_control = kcontrol->private_value;
2247 u16 mode;
2248 int i;
2249 u16 mode_map[6];
2250 int valid_modes = 0;
2252 /* HPI channel mode values can be from 1 to 6
2253 Some adapters only support a contiguous subset
2255 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2256 if (!hpi_channel_mode_query_mode(
2257 h_control, i, &mode)) {
2258 mode_map[valid_modes] = mode;
2259 valid_modes++;
2262 if (!valid_modes)
2263 return -EINVAL;
2265 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2266 uinfo->count = 1;
2267 uinfo->value.enumerated.items = valid_modes;
2269 if (uinfo->value.enumerated.item >= valid_modes)
2270 uinfo->value.enumerated.item = valid_modes - 1;
2272 strcpy(uinfo->value.enumerated.name,
2273 mode_names[mode_map[uinfo->value.enumerated.item]]);
2275 return 0;
2278 static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2279 struct snd_ctl_elem_value *ucontrol)
2281 u32 h_control = kcontrol->private_value;
2282 u16 mode;
2284 if (hpi_channel_mode_get(h_control, &mode))
2285 mode = 1;
2287 ucontrol->value.enumerated.item[0] = mode - 1;
2289 return 0;
2292 static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2293 struct snd_ctl_elem_value *ucontrol)
2295 int change;
2296 u32 h_control = kcontrol->private_value;
2298 change = 1;
2300 hpi_handle_error(hpi_channel_mode_set(h_control,
2301 ucontrol->value.enumerated.item[0] + 1));
2302 return change;
2306 static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2307 struct hpi_control *hpi_ctl)
2309 struct snd_card *card = asihpi->card;
2310 struct snd_kcontrol_new snd_control;
2312 asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
2313 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2314 snd_control.info = snd_asihpi_cmode_info;
2315 snd_control.get = snd_asihpi_cmode_get;
2316 snd_control.put = snd_asihpi_cmode_put;
2318 return ctl_add(card, &snd_control, asihpi);
2321 /*------------------------------------------------------------
2322 Sampleclock source controls
2323 ------------------------------------------------------------*/
2324 static char *sampleclock_sources[MAX_CLOCKSOURCES] = {
2325 "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
2326 "SMPTE", "Digital1", "Auto", "Network", "Invalid",
2327 "Prev Module",
2328 "Digital2", "Digital3", "Digital4", "Digital5",
2329 "Digital6", "Digital7", "Digital8"};
2331 static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2332 struct snd_ctl_elem_info *uinfo)
2334 struct snd_card_asihpi *asihpi =
2335 (struct snd_card_asihpi *)(kcontrol->private_data);
2336 struct clk_cache *clkcache = &asihpi->cc;
2337 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2338 uinfo->count = 1;
2339 uinfo->value.enumerated.items = clkcache->count;
2341 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2342 uinfo->value.enumerated.item =
2343 uinfo->value.enumerated.items - 1;
2345 strcpy(uinfo->value.enumerated.name,
2346 clkcache->s[uinfo->value.enumerated.item].name);
2347 return 0;
2350 static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2351 struct snd_ctl_elem_value *ucontrol)
2353 struct snd_card_asihpi *asihpi =
2354 (struct snd_card_asihpi *)(kcontrol->private_data);
2355 struct clk_cache *clkcache = &asihpi->cc;
2356 u32 h_control = kcontrol->private_value;
2357 u16 source, srcindex = 0;
2358 int i;
2360 ucontrol->value.enumerated.item[0] = 0;
2361 if (hpi_sample_clock_get_source(h_control, &source))
2362 source = 0;
2364 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2365 if (hpi_sample_clock_get_source_index(h_control, &srcindex))
2366 srcindex = 0;
2368 for (i = 0; i < clkcache->count; i++)
2369 if ((clkcache->s[i].source == source) &&
2370 (clkcache->s[i].index == srcindex))
2371 break;
2373 ucontrol->value.enumerated.item[0] = i;
2375 return 0;
2378 static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2379 struct snd_ctl_elem_value *ucontrol)
2381 struct snd_card_asihpi *asihpi =
2382 (struct snd_card_asihpi *)(kcontrol->private_data);
2383 struct clk_cache *clkcache = &asihpi->cc;
2384 int change, item;
2385 u32 h_control = kcontrol->private_value;
2387 change = 1;
2388 item = ucontrol->value.enumerated.item[0];
2389 if (item >= clkcache->count)
2390 item = clkcache->count-1;
2392 hpi_handle_error(hpi_sample_clock_set_source(
2393 h_control, clkcache->s[item].source));
2395 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2396 hpi_handle_error(hpi_sample_clock_set_source_index(
2397 h_control, clkcache->s[item].index));
2398 return change;
2401 /*------------------------------------------------------------
2402 Clkrate controls
2403 ------------------------------------------------------------*/
2404 /* Need to change this to enumerated control with list of rates */
2405 static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2406 struct snd_ctl_elem_info *uinfo)
2408 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2409 uinfo->count = 1;
2410 uinfo->value.integer.min = 8000;
2411 uinfo->value.integer.max = 192000;
2412 uinfo->value.integer.step = 100;
2414 return 0;
2417 static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2418 struct snd_ctl_elem_value *ucontrol)
2420 u32 h_control = kcontrol->private_value;
2421 u32 rate;
2422 u16 e;
2424 e = hpi_sample_clock_get_local_rate(h_control, &rate);
2425 if (!e)
2426 ucontrol->value.integer.value[0] = rate;
2427 else
2428 ucontrol->value.integer.value[0] = 0;
2429 return 0;
2432 static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2433 struct snd_ctl_elem_value *ucontrol)
2435 int change;
2436 u32 h_control = kcontrol->private_value;
2438 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2439 asihpi->mixer_clkrate[addr][1] != right;
2441 change = 1;
2442 hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
2443 ucontrol->value.integer.value[0]));
2444 return change;
2447 static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2448 struct snd_ctl_elem_info *uinfo)
2450 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2451 uinfo->count = 1;
2452 uinfo->value.integer.min = 8000;
2453 uinfo->value.integer.max = 192000;
2454 uinfo->value.integer.step = 100;
2456 return 0;
2459 static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2460 struct snd_ctl_elem_value *ucontrol)
2462 u32 h_control = kcontrol->private_value;
2463 u32 rate;
2464 u16 e;
2466 e = hpi_sample_clock_get_sample_rate(h_control, &rate);
2467 if (!e)
2468 ucontrol->value.integer.value[0] = rate;
2469 else
2470 ucontrol->value.integer.value[0] = 0;
2471 return 0;
2474 static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2475 struct hpi_control *hpi_ctl)
2477 struct snd_card *card = asihpi->card;
2478 struct snd_kcontrol_new snd_control;
2480 struct clk_cache *clkcache = &asihpi->cc;
2481 u32 hSC = hpi_ctl->h_control;
2482 int has_aes_in = 0;
2483 int i, j;
2484 u16 source;
2486 snd_control.private_value = hpi_ctl->h_control;
2488 clkcache->has_local = 0;
2490 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2491 if (hpi_sample_clock_query_source(hSC,
2492 i, &source))
2493 break;
2494 clkcache->s[i].source = source;
2495 clkcache->s[i].index = 0;
2496 clkcache->s[i].name = sampleclock_sources[source];
2497 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2498 has_aes_in = 1;
2499 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2500 clkcache->has_local = 1;
2502 if (has_aes_in)
2503 /* already will have picked up index 0 above */
2504 for (j = 1; j < 8; j++) {
2505 if (hpi_sample_clock_query_source_index(hSC,
2506 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2507 &source))
2508 break;
2509 clkcache->s[i].source =
2510 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2511 clkcache->s[i].index = j;
2512 clkcache->s[i].name = sampleclock_sources[
2513 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2514 i++;
2516 clkcache->count = i;
2518 asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
2519 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2520 snd_control.info = snd_asihpi_clksrc_info;
2521 snd_control.get = snd_asihpi_clksrc_get;
2522 snd_control.put = snd_asihpi_clksrc_put;
2523 if (ctl_add(card, &snd_control, asihpi) < 0)
2524 return -EINVAL;
2527 if (clkcache->has_local) {
2528 asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
2529 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2530 snd_control.info = snd_asihpi_clklocal_info;
2531 snd_control.get = snd_asihpi_clklocal_get;
2532 snd_control.put = snd_asihpi_clklocal_put;
2535 if (ctl_add(card, &snd_control, asihpi) < 0)
2536 return -EINVAL;
2539 asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
2540 snd_control.access =
2541 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2542 snd_control.info = snd_asihpi_clkrate_info;
2543 snd_control.get = snd_asihpi_clkrate_get;
2545 return ctl_add(card, &snd_control, asihpi);
2547 /*------------------------------------------------------------
2548 Mixer
2549 ------------------------------------------------------------*/
2551 static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2553 struct snd_card *card = asihpi->card;
2554 unsigned int idx = 0;
2555 unsigned int subindex = 0;
2556 int err;
2557 struct hpi_control hpi_ctl, prev_ctl;
2559 if (snd_BUG_ON(!asihpi))
2560 return -EINVAL;
2561 strcpy(card->mixername, "Asihpi Mixer");
2563 err =
2564 hpi_mixer_open(asihpi->hpi->adapter->index,
2565 &asihpi->h_mixer);
2566 hpi_handle_error(err);
2567 if (err)
2568 return -err;
2570 memset(&prev_ctl, 0, sizeof(prev_ctl));
2571 prev_ctl.control_type = -1;
2573 for (idx = 0; idx < 2000; idx++) {
2574 err = hpi_mixer_get_control_by_index(
2575 asihpi->h_mixer,
2576 idx,
2577 &hpi_ctl.src_node_type,
2578 &hpi_ctl.src_node_index,
2579 &hpi_ctl.dst_node_type,
2580 &hpi_ctl.dst_node_index,
2581 &hpi_ctl.control_type,
2582 &hpi_ctl.h_control);
2583 if (err) {
2584 if (err == HPI_ERROR_CONTROL_DISABLED) {
2585 if (mixer_dump)
2586 snd_printk(KERN_INFO
2587 "Disabled HPI Control(%d)\n",
2588 idx);
2589 continue;
2590 } else
2591 break;
2595 hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2596 hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
2598 /* ASI50xx in SSX mode has multiple meters on the same node.
2599 Use subindex to create distinct ALSA controls
2600 for any duplicated controls.
2602 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2603 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2604 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2605 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2606 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2607 subindex++;
2608 else
2609 subindex = 0;
2611 prev_ctl = hpi_ctl;
2613 switch (hpi_ctl.control_type) {
2614 case HPI_CONTROL_VOLUME:
2615 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2616 break;
2617 case HPI_CONTROL_LEVEL:
2618 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2619 break;
2620 case HPI_CONTROL_MULTIPLEXER:
2621 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2622 break;
2623 case HPI_CONTROL_CHANNEL_MODE:
2624 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2625 break;
2626 case HPI_CONTROL_METER:
2627 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2628 break;
2629 case HPI_CONTROL_SAMPLECLOCK:
2630 err = snd_asihpi_sampleclock_add(
2631 asihpi, &hpi_ctl);
2632 break;
2633 case HPI_CONTROL_CONNECTION: /* ignore these */
2634 continue;
2635 case HPI_CONTROL_TUNER:
2636 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2637 break;
2638 case HPI_CONTROL_AESEBU_TRANSMITTER:
2639 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2640 break;
2641 case HPI_CONTROL_AESEBU_RECEIVER:
2642 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2643 break;
2644 case HPI_CONTROL_VOX:
2645 case HPI_CONTROL_BITSTREAM:
2646 case HPI_CONTROL_MICROPHONE:
2647 case HPI_CONTROL_PARAMETRIC_EQ:
2648 case HPI_CONTROL_COMPANDER:
2649 default:
2650 if (mixer_dump)
2651 snd_printk(KERN_INFO
2652 "Untranslated HPI Control"
2653 "(%d) %d %d %d %d %d\n",
2654 idx,
2655 hpi_ctl.control_type,
2656 hpi_ctl.src_node_type,
2657 hpi_ctl.src_node_index,
2658 hpi_ctl.dst_node_type,
2659 hpi_ctl.dst_node_index);
2660 continue;
2662 if (err < 0)
2663 return err;
2665 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2666 hpi_handle_error(err);
2668 snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2670 return 0;
2673 /*------------------------------------------------------------
2674 /proc interface
2675 ------------------------------------------------------------*/
2677 static void
2678 snd_asihpi_proc_read(struct snd_info_entry *entry,
2679 struct snd_info_buffer *buffer)
2681 struct snd_card_asihpi *asihpi = entry->private_data;
2682 u32 h_control;
2683 u32 rate = 0;
2684 u16 source = 0;
2686 u16 num_outstreams;
2687 u16 num_instreams;
2688 u16 version;
2689 u32 serial_number;
2690 u16 type;
2692 int err;
2694 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2696 hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
2697 &num_outstreams, &num_instreams,
2698 &version, &serial_number, &type));
2700 snd_iprintf(buffer,
2701 "Adapter type ASI%4X\nHardware Index %d\n"
2702 "%d outstreams\n%d instreams\n",
2703 type, asihpi->hpi->adapter->index,
2704 num_outstreams, num_instreams);
2706 snd_iprintf(buffer,
2707 "Serial#%d\nHardware version %c%d\nDSP code version %03d\n",
2708 serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7,
2709 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2711 err = hpi_mixer_get_control(asihpi->h_mixer,
2712 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2713 HPI_CONTROL_SAMPLECLOCK, &h_control);
2715 if (!err) {
2716 err = hpi_sample_clock_get_sample_rate(h_control, &rate);
2717 err += hpi_sample_clock_get_source(h_control, &source);
2719 if (!err)
2720 snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
2721 rate, sampleclock_sources[source]);
2725 static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2727 struct snd_info_entry *entry;
2729 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2730 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2733 /*------------------------------------------------------------
2734 HWDEP
2735 ------------------------------------------------------------*/
2737 static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2739 if (enable_hpi_hwdep)
2740 return 0;
2741 else
2742 return -ENODEV;
2746 static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2748 if (enable_hpi_hwdep)
2749 return asihpi_hpi_release(file);
2750 else
2751 return -ENODEV;
2754 static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2755 unsigned int cmd, unsigned long arg)
2757 if (enable_hpi_hwdep)
2758 return asihpi_hpi_ioctl(file, cmd, arg);
2759 else
2760 return -ENODEV;
2764 /* results in /dev/snd/hwC#D0 file for each card with index #
2765 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2767 static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2768 int device, struct snd_hwdep **rhwdep)
2770 struct snd_hwdep *hw;
2771 int err;
2773 if (rhwdep)
2774 *rhwdep = NULL;
2775 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2776 if (err < 0)
2777 return err;
2778 strcpy(hw->name, "asihpi (HPI)");
2779 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2780 hw->ops.open = snd_asihpi_hpi_open;
2781 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2782 hw->ops.release = snd_asihpi_hpi_release;
2783 hw->private_data = asihpi;
2784 if (rhwdep)
2785 *rhwdep = hw;
2786 return 0;
2789 /*------------------------------------------------------------
2790 CARD
2791 ------------------------------------------------------------*/
2792 static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2793 const struct pci_device_id *pci_id)
2795 int err;
2796 struct hpi_adapter *hpi;
2797 struct snd_card *card;
2798 struct snd_card_asihpi *asihpi;
2800 u32 h_control;
2801 u32 h_stream;
2802 u32 adapter_index;
2804 static int dev;
2805 if (dev >= SNDRV_CARDS)
2806 return -ENODEV;
2808 /* Should this be enable[hpi->index] ? */
2809 if (!enable[dev]) {
2810 dev++;
2811 return -ENOENT;
2814 /* Initialise low-level HPI driver */
2815 err = asihpi_adapter_probe(pci_dev, pci_id);
2816 if (err < 0)
2817 return err;
2819 hpi = pci_get_drvdata(pci_dev);
2820 adapter_index = hpi->adapter->index;
2821 /* first try to give the card the same index as its hardware index */
2822 err = snd_card_create(adapter_index,
2823 id[adapter_index], THIS_MODULE,
2824 sizeof(struct snd_card_asihpi),
2825 &card);
2826 if (err < 0) {
2827 /* if that fails, try the default index==next available */
2828 err =
2829 snd_card_create(index[dev], id[dev],
2830 THIS_MODULE,
2831 sizeof(struct snd_card_asihpi),
2832 &card);
2833 if (err < 0)
2834 return err;
2835 snd_printk(KERN_WARNING
2836 "**** WARNING **** Adapter index %d->ALSA index %d\n",
2837 adapter_index, card->number);
2840 snd_card_set_dev(card, &pci_dev->dev);
2842 asihpi = card->private_data;
2843 asihpi->card = card;
2844 asihpi->pci = pci_dev;
2845 asihpi->hpi = hpi;
2847 snd_printk(KERN_INFO "adapter ID=%4X index=%d\n",
2848 asihpi->hpi->adapter->type, adapter_index);
2850 err = hpi_adapter_get_property(adapter_index,
2851 HPI_ADAPTER_PROPERTY_CAPS1,
2852 NULL, &asihpi->support_grouping);
2853 if (err)
2854 asihpi->support_grouping = 0;
2856 err = hpi_adapter_get_property(adapter_index,
2857 HPI_ADAPTER_PROPERTY_CAPS2,
2858 &asihpi->support_mrx, NULL);
2859 if (err)
2860 asihpi->support_mrx = 0;
2862 err = hpi_adapter_get_property(adapter_index,
2863 HPI_ADAPTER_PROPERTY_INTERVAL,
2864 NULL, &asihpi->update_interval_frames);
2865 if (err)
2866 asihpi->update_interval_frames = 512;
2868 if (!asihpi->can_dma)
2869 asihpi->update_interval_frames *= 2;
2871 hpi_handle_error(hpi_instream_open(adapter_index,
2872 0, &h_stream));
2874 err = hpi_instream_host_buffer_free(h_stream);
2875 asihpi->can_dma = (!err);
2877 hpi_handle_error(hpi_instream_close(h_stream));
2879 err = hpi_adapter_get_property(adapter_index,
2880 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2881 &asihpi->in_max_chans, &asihpi->out_max_chans);
2882 if (err) {
2883 asihpi->in_max_chans = 2;
2884 asihpi->out_max_chans = 2;
2887 if (asihpi->out_max_chans > 2) { /* assume LL mode */
2888 asihpi->out_min_chans = asihpi->out_max_chans;
2889 asihpi->in_min_chans = asihpi->in_max_chans;
2890 asihpi->support_grouping = 0;
2891 } else {
2892 asihpi->out_min_chans = 1;
2893 asihpi->in_min_chans = 1;
2896 snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n",
2897 asihpi->can_dma,
2898 asihpi->support_grouping,
2899 asihpi->support_mrx
2902 err = snd_card_asihpi_pcm_new(asihpi, 0);
2903 if (err < 0) {
2904 snd_printk(KERN_ERR "pcm_new failed\n");
2905 goto __nodev;
2907 err = snd_card_asihpi_mixer_new(asihpi);
2908 if (err < 0) {
2909 snd_printk(KERN_ERR "mixer_new failed\n");
2910 goto __nodev;
2913 err = hpi_mixer_get_control(asihpi->h_mixer,
2914 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2915 HPI_CONTROL_SAMPLECLOCK, &h_control);
2917 if (!err)
2918 err = hpi_sample_clock_set_local_rate(
2919 h_control, adapter_fs);
2921 snd_asihpi_proc_init(asihpi);
2923 /* always create, can be enabled or disabled dynamically
2924 by enable_hwdep module param*/
2925 snd_asihpi_hpi_new(asihpi, 0, NULL);
2927 strcpy(card->driver, "ASIHPI");
2929 sprintf(card->shortname, "AudioScience ASI%4X",
2930 asihpi->hpi->adapter->type);
2931 sprintf(card->longname, "%s %i",
2932 card->shortname, adapter_index);
2933 err = snd_card_register(card);
2935 if (!err) {
2936 hpi->snd_card = card;
2937 dev++;
2938 return 0;
2940 __nodev:
2941 snd_card_free(card);
2942 snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2943 return err;
2947 static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2949 struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
2950 snd_card_free(hpi->snd_card);
2951 hpi->snd_card = NULL;
2952 asihpi_adapter_remove(pci_dev);
2955 static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2956 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2957 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2958 (kernel_ulong_t)HPI_6205},
2959 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2960 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2961 (kernel_ulong_t)HPI_6000},
2962 {0,}
2964 MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2966 static struct pci_driver driver = {
2967 .name = KBUILD_MODNAME,
2968 .id_table = asihpi_pci_tbl,
2969 .probe = snd_asihpi_probe,
2970 .remove = __devexit_p(snd_asihpi_remove),
2971 #ifdef CONFIG_PM
2972 /* .suspend = snd_asihpi_suspend,
2973 .resume = snd_asihpi_resume, */
2974 #endif
2977 static int __init snd_asihpi_init(void)
2979 asihpi_init();
2980 return pci_register_driver(&driver);
2983 static void __exit snd_asihpi_exit(void)
2986 pci_unregister_driver(&driver);
2987 asihpi_exit();
2990 module_init(snd_asihpi_init)
2991 module_exit(snd_asihpi_exit)