I2C: Add helper macro for i2c_driver boilerplate
[zen-stable.git] / sound / pci / asihpi / asihpi.c
blobf4b9e2b7ae87ae1df0b5dfa374c1e2528b2232b7
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 "hpimsginit.h"
27 #include "hpioctl.h"
29 #include <linux/pci.h>
30 #include <linux/init.h>
31 #include <linux/jiffies.h>
32 #include <linux/slab.h>
33 #include <linux/time.h>
34 #include <linux/wait.h>
35 #include <linux/module.h>
36 #include <sound/core.h>
37 #include <sound/control.h>
38 #include <sound/pcm.h>
39 #include <sound/pcm_params.h>
40 #include <sound/info.h>
41 #include <sound/initval.h>
42 #include <sound/tlv.h>
43 #include <sound/hwdep.h>
45 MODULE_LICENSE("GPL");
46 MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
47 MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
49 #if defined CONFIG_SND_DEBUG_VERBOSE
50 /**
51 * snd_printddd - very verbose debug printk
52 * @format: format string
54 * Works like snd_printk() for debugging purposes.
55 * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
56 * Must set snd module debug parameter to 3 to enable at runtime.
58 #define snd_printddd(format, args...) \
59 __snd_printk(3, __FILE__, __LINE__, format, ##args)
60 #else
61 #define snd_printddd(format, args...) do { } while (0)
62 #endif
64 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
65 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
66 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
67 static int enable_hpi_hwdep = 1;
69 module_param_array(index, int, NULL, S_IRUGO);
70 MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
72 module_param_array(id, charp, NULL, S_IRUGO);
73 MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
75 module_param_array(enable, bool, NULL, S_IRUGO);
76 MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
78 module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
79 MODULE_PARM_DESC(enable_hpi_hwdep,
80 "ALSA enable HPI hwdep for AudioScience soundcard ");
82 /* identify driver */
83 #ifdef KERNEL_ALSA_BUILD
84 static char *build_info = "Built using headers from kernel source";
85 module_param(build_info, charp, S_IRUGO);
86 MODULE_PARM_DESC(build_info, "built using headers from kernel source");
87 #else
88 static char *build_info = "Built within ALSA source";
89 module_param(build_info, charp, S_IRUGO);
90 MODULE_PARM_DESC(build_info, "built within ALSA source");
91 #endif
93 /* set to 1 to dump every control from adapter to log */
94 static const int mixer_dump;
96 #define DEFAULT_SAMPLERATE 44100
97 static int adapter_fs = DEFAULT_SAMPLERATE;
99 /* defaults */
100 #define PERIODS_MIN 2
101 #define PERIOD_BYTES_MIN 2048
102 #define BUFFER_BYTES_MAX (512 * 1024)
104 #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
106 struct clk_source {
107 int source;
108 int index;
109 char *name;
112 struct clk_cache {
113 int count;
114 int has_local;
115 struct clk_source s[MAX_CLOCKSOURCES];
118 /* Per card data */
119 struct snd_card_asihpi {
120 struct snd_card *card;
121 struct pci_dev *pci;
122 u16 adapter_index;
123 u32 serial_number;
124 u16 type;
125 u16 version;
126 u16 num_outstreams;
127 u16 num_instreams;
129 u32 h_mixer;
130 struct clk_cache cc;
132 u16 can_dma;
133 u16 support_grouping;
134 u16 support_mrx;
135 u16 update_interval_frames;
136 u16 in_max_chans;
137 u16 out_max_chans;
140 /* Per stream data */
141 struct snd_card_asihpi_pcm {
142 struct timer_list timer;
143 unsigned int respawn_timer;
144 unsigned int hpi_buffer_attached;
145 unsigned int buffer_bytes;
146 unsigned int period_bytes;
147 unsigned int bytes_per_sec;
148 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
149 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
150 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
151 unsigned int drained_count;
152 struct snd_pcm_substream *substream;
153 u32 h_stream;
154 struct hpi_format format;
157 /* universal stream verbs work with out or in stream handles */
159 /* Functions to allow driver to give a buffer to HPI for busmastering */
161 static u16 hpi_stream_host_buffer_attach(
162 u32 h_stream, /* handle to outstream. */
163 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
164 u32 pci_address
167 struct hpi_message hm;
168 struct hpi_response hr;
169 unsigned int obj = hpi_handle_object(h_stream);
171 if (!h_stream)
172 return HPI_ERROR_INVALID_OBJ;
173 hpi_init_message_response(&hm, &hr, obj,
174 obj == HPI_OBJ_OSTREAM ?
175 HPI_OSTREAM_HOSTBUFFER_ALLOC :
176 HPI_ISTREAM_HOSTBUFFER_ALLOC);
178 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
179 &hm.obj_index);
181 hm.u.d.u.buffer.buffer_size = size_in_bytes;
182 hm.u.d.u.buffer.pci_address = pci_address;
183 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
184 hpi_send_recv(&hm, &hr);
185 return hr.error;
188 static u16 hpi_stream_host_buffer_detach(u32 h_stream)
190 struct hpi_message hm;
191 struct hpi_response hr;
192 unsigned int obj = hpi_handle_object(h_stream);
194 if (!h_stream)
195 return HPI_ERROR_INVALID_OBJ;
197 hpi_init_message_response(&hm, &hr, obj,
198 obj == HPI_OBJ_OSTREAM ?
199 HPI_OSTREAM_HOSTBUFFER_FREE :
200 HPI_ISTREAM_HOSTBUFFER_FREE);
202 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
203 &hm.obj_index);
204 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
205 hpi_send_recv(&hm, &hr);
206 return hr.error;
209 static inline u16 hpi_stream_start(u32 h_stream)
211 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
212 return hpi_outstream_start(h_stream);
213 else
214 return hpi_instream_start(h_stream);
217 static inline u16 hpi_stream_stop(u32 h_stream)
219 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
220 return hpi_outstream_stop(h_stream);
221 else
222 return hpi_instream_stop(h_stream);
225 static inline u16 hpi_stream_get_info_ex(
226 u32 h_stream,
227 u16 *pw_state,
228 u32 *pbuffer_size,
229 u32 *pdata_in_buffer,
230 u32 *psample_count,
231 u32 *pauxiliary_data
234 u16 e;
235 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
236 e = hpi_outstream_get_info_ex(h_stream, pw_state,
237 pbuffer_size, pdata_in_buffer,
238 psample_count, pauxiliary_data);
239 else
240 e = hpi_instream_get_info_ex(h_stream, pw_state,
241 pbuffer_size, pdata_in_buffer,
242 psample_count, pauxiliary_data);
243 return e;
246 static inline u16 hpi_stream_group_add(
247 u32 h_master,
248 u32 h_stream)
250 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
251 return hpi_outstream_group_add(h_master, h_stream);
252 else
253 return hpi_instream_group_add(h_master, h_stream);
256 static inline u16 hpi_stream_group_reset(u32 h_stream)
258 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
259 return hpi_outstream_group_reset(h_stream);
260 else
261 return hpi_instream_group_reset(h_stream);
264 static inline u16 hpi_stream_group_get_map(
265 u32 h_stream, u32 *mo, u32 *mi)
267 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
268 return hpi_outstream_group_get_map(h_stream, mo, mi);
269 else
270 return hpi_instream_group_get_map(h_stream, mo, mi);
273 static u16 handle_error(u16 err, int line, char *filename)
275 if (err)
276 printk(KERN_WARNING
277 "in file %s, line %d: HPI error %d\n",
278 filename, line, err);
279 return err;
282 #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
284 /***************************** GENERAL PCM ****************/
286 static void print_hwparams(struct snd_pcm_substream *substream,
287 struct snd_pcm_hw_params *p)
289 char name[16];
290 snd_pcm_debug_name(substream, name, sizeof(name));
291 snd_printd("%s HWPARAMS\n", name);
292 snd_printd(" samplerate %d Hz\n", params_rate(p));
293 snd_printd(" channels %d\n", params_channels(p));
294 snd_printd(" format %d\n", params_format(p));
295 snd_printd(" subformat %d\n", params_subformat(p));
296 snd_printd(" buffer %d B\n", params_buffer_bytes(p));
297 snd_printd(" period %d B\n", params_period_bytes(p));
298 snd_printd(" access %d\n", params_access(p));
299 snd_printd(" period_size %d\n", params_period_size(p));
300 snd_printd(" periods %d\n", params_periods(p));
301 snd_printd(" buffer_size %d\n", params_buffer_size(p));
302 snd_printd(" %d B/s\n", params_rate(p) *
303 params_channels(p) *
304 snd_pcm_format_width(params_format(p)) / 8);
308 static snd_pcm_format_t hpi_to_alsa_formats[] = {
309 -1, /* INVALID */
310 SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
311 SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
312 -1, /* HPI_FORMAT_MPEG_L1 3 */
313 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
314 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
315 -1, /* HPI_FORMAT_DOLBY_AC2 6 */
316 -1, /* HPI_FORMAT_DOLBY_AC3 7 */
317 SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
318 -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
319 -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
320 SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
321 -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
322 -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
323 SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
324 #if 1
325 /* ALSA can't handle 3 byte sample size together with power-of-2
326 * constraint on buffer_bytes, so disable this format
329 #else
330 /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
331 #endif
335 static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
336 u16 *hpi_format)
338 u16 format;
340 for (format = HPI_FORMAT_PCM8_UNSIGNED;
341 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
342 if (hpi_to_alsa_formats[format] == alsa_format) {
343 *hpi_format = format;
344 return 0;
348 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
349 alsa_format);
350 *hpi_format = 0;
351 return -EINVAL;
354 static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
355 struct snd_pcm_hardware *pcmhw)
357 u16 err;
358 u32 h_control;
359 u32 sample_rate;
360 int idx;
361 unsigned int rate_min = 200000;
362 unsigned int rate_max = 0;
363 unsigned int rates = 0;
365 if (asihpi->support_mrx) {
366 rates |= SNDRV_PCM_RATE_CONTINUOUS;
367 rates |= SNDRV_PCM_RATE_8000_96000;
368 rate_min = 8000;
369 rate_max = 100000;
370 } else {
371 /* on cards without SRC,
372 valid rates are determined by sampleclock */
373 err = hpi_mixer_get_control(asihpi->h_mixer,
374 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
375 HPI_CONTROL_SAMPLECLOCK, &h_control);
376 if (err) {
377 snd_printk(KERN_ERR
378 "No local sampleclock, err %d\n", err);
381 for (idx = -1; idx < 100; idx++) {
382 if (idx == -1) {
383 if (hpi_sample_clock_get_sample_rate(h_control,
384 &sample_rate))
385 continue;
386 } else if (hpi_sample_clock_query_local_rate(h_control,
387 idx, &sample_rate)) {
388 break;
391 rate_min = min(rate_min, sample_rate);
392 rate_max = max(rate_max, sample_rate);
394 switch (sample_rate) {
395 case 5512:
396 rates |= SNDRV_PCM_RATE_5512;
397 break;
398 case 8000:
399 rates |= SNDRV_PCM_RATE_8000;
400 break;
401 case 11025:
402 rates |= SNDRV_PCM_RATE_11025;
403 break;
404 case 16000:
405 rates |= SNDRV_PCM_RATE_16000;
406 break;
407 case 22050:
408 rates |= SNDRV_PCM_RATE_22050;
409 break;
410 case 32000:
411 rates |= SNDRV_PCM_RATE_32000;
412 break;
413 case 44100:
414 rates |= SNDRV_PCM_RATE_44100;
415 break;
416 case 48000:
417 rates |= SNDRV_PCM_RATE_48000;
418 break;
419 case 64000:
420 rates |= SNDRV_PCM_RATE_64000;
421 break;
422 case 88200:
423 rates |= SNDRV_PCM_RATE_88200;
424 break;
425 case 96000:
426 rates |= SNDRV_PCM_RATE_96000;
427 break;
428 case 176400:
429 rates |= SNDRV_PCM_RATE_176400;
430 break;
431 case 192000:
432 rates |= SNDRV_PCM_RATE_192000;
433 break;
434 default: /* some other rate */
435 rates |= SNDRV_PCM_RATE_KNOT;
440 pcmhw->rates = rates;
441 pcmhw->rate_min = rate_min;
442 pcmhw->rate_max = rate_max;
445 static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
446 struct snd_pcm_hw_params *params)
448 struct snd_pcm_runtime *runtime = substream->runtime;
449 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
450 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
451 int err;
452 u16 format;
453 int width;
454 unsigned int bytes_per_sec;
456 print_hwparams(substream, params);
457 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
458 if (err < 0)
459 return err;
460 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
461 if (err)
462 return err;
464 hpi_handle_error(hpi_format_create(&dpcm->format,
465 params_channels(params),
466 format, params_rate(params), 0, 0));
468 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
469 if (hpi_instream_reset(dpcm->h_stream) != 0)
470 return -EINVAL;
472 if (hpi_instream_set_format(
473 dpcm->h_stream, &dpcm->format) != 0)
474 return -EINVAL;
477 dpcm->hpi_buffer_attached = 0;
478 if (card->can_dma) {
479 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
480 params_buffer_bytes(params), runtime->dma_addr);
481 if (err == 0) {
482 snd_printdd(
483 "stream_host_buffer_attach succeeded %u %lu\n",
484 params_buffer_bytes(params),
485 (unsigned long)runtime->dma_addr);
486 } else {
487 snd_printd("stream_host_buffer_attach error %d\n",
488 err);
489 return -ENOMEM;
492 err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
493 &dpcm->hpi_buffer_attached,
494 NULL, NULL, NULL);
496 snd_printdd("stream_host_buffer_attach status 0x%x\n",
497 dpcm->hpi_buffer_attached);
499 bytes_per_sec = params_rate(params) * params_channels(params);
500 width = snd_pcm_format_width(params_format(params));
501 bytes_per_sec *= width;
502 bytes_per_sec /= 8;
503 if (width < 0 || bytes_per_sec == 0)
504 return -EINVAL;
506 dpcm->bytes_per_sec = bytes_per_sec;
507 dpcm->buffer_bytes = params_buffer_bytes(params);
508 dpcm->period_bytes = params_period_bytes(params);
510 return 0;
513 static int
514 snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
516 struct snd_pcm_runtime *runtime = substream->runtime;
517 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
518 if (dpcm->hpi_buffer_attached)
519 hpi_stream_host_buffer_detach(dpcm->h_stream);
521 snd_pcm_lib_free_pages(substream);
522 return 0;
525 static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
527 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
528 kfree(dpcm);
531 static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
532 substream)
534 struct snd_pcm_runtime *runtime = substream->runtime;
535 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
536 int expiry;
538 expiry = HZ / 200;
539 /*? (dpcm->period_bytes * HZ / dpcm->bytes_per_sec); */
540 expiry = max(expiry, 1); /* don't let it be zero! */
541 dpcm->timer.expires = jiffies + expiry;
542 dpcm->respawn_timer = 1;
543 add_timer(&dpcm->timer);
546 static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
548 struct snd_pcm_runtime *runtime = substream->runtime;
549 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
551 dpcm->respawn_timer = 0;
552 del_timer(&dpcm->timer);
555 static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
556 int cmd)
558 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
559 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
560 struct snd_pcm_substream *s;
561 u16 e;
562 char name[16];
564 snd_pcm_debug_name(substream, name, sizeof(name));
565 snd_printdd("%s trigger\n", name);
567 switch (cmd) {
568 case SNDRV_PCM_TRIGGER_START:
569 snd_pcm_group_for_each_entry(s, substream) {
570 struct snd_pcm_runtime *runtime = s->runtime;
571 struct snd_card_asihpi_pcm *ds = runtime->private_data;
573 if (snd_pcm_substream_chip(s) != card)
574 continue;
576 /* don't link Cap and Play */
577 if (substream->stream != s->stream)
578 continue;
580 ds->drained_count = 0;
581 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
582 /* How do I know how much valid data is present
583 * in buffer? Must be at least one period!
584 * Guessing 2 periods, but if
585 * buffer is bigger it may contain even more
586 * data??
588 unsigned int preload = ds->period_bytes * 1;
589 snd_printddd("%d preload x%x\n", s->number, preload);
590 hpi_handle_error(hpi_outstream_write_buf(
591 ds->h_stream,
592 &runtime->dma_area[0],
593 preload,
594 &ds->format));
595 ds->pcm_buf_host_rw_ofs = preload;
598 if (card->support_grouping) {
599 snd_printdd("%d group\n", s->number);
600 e = hpi_stream_group_add(
601 dpcm->h_stream,
602 ds->h_stream);
603 if (!e) {
604 snd_pcm_trigger_done(s, substream);
605 } else {
606 hpi_handle_error(e);
607 break;
609 } else
610 break;
612 snd_printdd("start\n");
613 /* start the master stream */
614 snd_card_asihpi_pcm_timer_start(substream);
615 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
616 !card->can_dma)
617 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
618 break;
620 case SNDRV_PCM_TRIGGER_STOP:
621 snd_card_asihpi_pcm_timer_stop(substream);
622 snd_pcm_group_for_each_entry(s, substream) {
623 if (snd_pcm_substream_chip(s) != card)
624 continue;
625 /* don't link Cap and Play */
626 if (substream->stream != s->stream)
627 continue;
629 /*? workaround linked streams don't
630 transition to SETUP 20070706*/
631 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
633 if (card->support_grouping) {
634 snd_printdd("%d group\n", s->number);
635 snd_pcm_trigger_done(s, substream);
636 } else
637 break;
639 snd_printdd("stop\n");
641 /* _prepare and _hwparams reset the stream */
642 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
643 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
644 hpi_handle_error(
645 hpi_outstream_reset(dpcm->h_stream));
647 if (card->support_grouping)
648 hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
649 break;
651 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
652 snd_printdd("pause release\n");
653 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
654 snd_card_asihpi_pcm_timer_start(substream);
655 break;
656 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
657 snd_printdd("pause\n");
658 snd_card_asihpi_pcm_timer_stop(substream);
659 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
660 break;
661 default:
662 snd_printd(KERN_ERR "\tINVALID\n");
663 return -EINVAL;
666 return 0;
669 /*algorithm outline
670 Without linking degenerates to getting single stream pos etc
671 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
674 pcm_buf_dma_ofs=get_buf_pos(s);
675 for_each_linked_stream(s) {
676 pcm_buf_dma_ofs=get_buf_pos(s);
677 min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes)
678 new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
680 timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
681 for_each_linked_stream(s) {
682 s->pcm_buf_dma_ofs = min_buf_pos;
683 if (new_data > period_bytes) {
684 if (mmap) {
685 irq_pos = (irq_pos + period_bytes) % buffer_bytes;
686 if (playback) {
687 write(period_bytes);
688 } else {
689 read(period_bytes);
692 snd_pcm_period_elapsed(s);
697 /** Minimum of 2 modulo values. Works correctly when the difference between
698 * the values is less than half the modulus
700 static inline unsigned int modulo_min(unsigned int a, unsigned int b,
701 unsigned long int modulus)
703 unsigned int result;
704 if (((a-b) % modulus) < (modulus/2))
705 result = b;
706 else
707 result = a;
709 return result;
712 /** Timer function, equivalent to interrupt service routine for cards
714 static void snd_card_asihpi_timer_function(unsigned long data)
716 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
717 struct snd_pcm_substream *substream = dpcm->substream;
718 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
719 struct snd_pcm_runtime *runtime;
720 struct snd_pcm_substream *s;
721 unsigned int newdata = 0;
722 unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
723 unsigned int remdata, xfercount, next_jiffies;
724 int first = 1;
725 int loops = 0;
726 u16 state;
727 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
728 char name[16];
730 snd_pcm_debug_name(substream, name, sizeof(name));
732 snd_printdd("%s snd_card_asihpi_timer_function\n", name);
734 /* find minimum newdata and buffer pos in group */
735 snd_pcm_group_for_each_entry(s, substream) {
736 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
737 runtime = s->runtime;
739 if (snd_pcm_substream_chip(s) != card)
740 continue;
742 /* don't link Cap and Play */
743 if (substream->stream != s->stream)
744 continue;
746 hpi_handle_error(hpi_stream_get_info_ex(
747 ds->h_stream, &state,
748 &buffer_size, &bytes_avail,
749 &samples_played, &on_card_bytes));
751 /* number of bytes in on-card buffer */
752 runtime->delay = on_card_bytes;
754 if (!card->can_dma)
755 on_card_bytes = bytes_avail;
757 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
758 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
759 if (state == HPI_STATE_STOPPED) {
760 if ((bytes_avail == 0) &&
761 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
762 hpi_handle_error(hpi_stream_start(ds->h_stream));
763 snd_printdd("P%d start\n", s->number);
764 ds->drained_count = 0;
766 } else if (state == HPI_STATE_DRAINED) {
767 snd_printd(KERN_WARNING "P%d drained\n",
768 s->number);
769 ds->drained_count++;
770 if (ds->drained_count > 2) {
771 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
772 continue;
774 } else {
775 ds->drained_count = 0;
777 } else
778 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
780 if (first) {
781 /* can't statically init min when wrap is involved */
782 min_buf_pos = pcm_buf_dma_ofs;
783 newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
784 first = 0;
785 } else {
786 min_buf_pos =
787 modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
788 newdata = min(
789 (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
790 newdata);
793 snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n",
794 (unsigned long)frames_to_bytes(runtime,
795 runtime->status->hw_ptr),
796 (unsigned long)frames_to_bytes(runtime,
797 runtime->control->appl_ptr));
799 snd_printdd("%d S=%d, "
800 "rw=0x%04X, dma=0x%04X, left=0x%04X, "
801 "aux=0x%04X space=0x%04X\n",
802 s->number, state,
803 ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs,
804 (int)bytes_avail,
805 (int)on_card_bytes, buffer_size-bytes_avail);
806 loops++;
808 pcm_buf_dma_ofs = min_buf_pos;
810 remdata = newdata % dpcm->period_bytes;
811 xfercount = newdata - remdata; /* a multiple of period_bytes */
812 /* come back when on_card_bytes has decreased enough to allow
813 write to happen, or when data has been consumed to make another
814 period
816 if (xfercount && (on_card_bytes > dpcm->period_bytes))
817 next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
818 else
819 next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
821 next_jiffies = max(next_jiffies, 1U);
822 dpcm->timer.expires = jiffies + next_jiffies;
823 snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n",
824 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
826 snd_pcm_group_for_each_entry(s, substream) {
827 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
829 /* don't link Cap and Play */
830 if (substream->stream != s->stream)
831 continue;
833 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
835 if (xfercount &&
836 /* Limit use of on card fifo for playback */
837 ((on_card_bytes <= ds->period_bytes) ||
838 (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
842 unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
843 unsigned int xfer1, xfer2;
844 char *pd = &s->runtime->dma_area[buf_ofs];
846 if (card->can_dma) { /* buffer wrap is handled at lower level */
847 xfer1 = xfercount;
848 xfer2 = 0;
849 } else {
850 xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
851 xfer2 = xfercount - xfer1;
854 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
855 snd_printddd("P%d write1 0x%04X 0x%04X\n",
856 s->number, xfer1, buf_ofs);
857 hpi_handle_error(
858 hpi_outstream_write_buf(
859 ds->h_stream, pd, xfer1,
860 &ds->format));
862 if (xfer2) {
863 pd = s->runtime->dma_area;
865 snd_printddd("P%d write2 0x%04X 0x%04X\n",
866 s->number,
867 xfercount - xfer1, buf_ofs);
868 hpi_handle_error(
869 hpi_outstream_write_buf(
870 ds->h_stream, pd,
871 xfercount - xfer1,
872 &ds->format));
874 } else {
875 snd_printddd("C%d read1 0x%04x\n",
876 s->number, xfer1);
877 hpi_handle_error(
878 hpi_instream_read_buf(
879 ds->h_stream,
880 pd, xfer1));
881 if (xfer2) {
882 pd = s->runtime->dma_area;
883 snd_printddd("C%d read2 0x%04x\n",
884 s->number, xfer2);
885 hpi_handle_error(
886 hpi_instream_read_buf(
887 ds->h_stream,
888 pd, xfer2));
891 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
892 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
893 snd_pcm_period_elapsed(s);
897 if (dpcm->respawn_timer)
898 add_timer(&dpcm->timer);
901 /***************************** PLAYBACK OPS ****************/
902 static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
903 unsigned int cmd, void *arg)
905 snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd);
906 return snd_pcm_lib_ioctl(substream, cmd, arg);
909 static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
910 substream)
912 struct snd_pcm_runtime *runtime = substream->runtime;
913 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
915 snd_printdd("P%d prepare\n", substream->number);
917 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
918 dpcm->pcm_buf_host_rw_ofs = 0;
919 dpcm->pcm_buf_dma_ofs = 0;
920 dpcm->pcm_buf_elapsed_dma_ofs = 0;
921 return 0;
924 static snd_pcm_uframes_t
925 snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
927 struct snd_pcm_runtime *runtime = substream->runtime;
928 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
929 snd_pcm_uframes_t ptr;
931 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
932 snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr);
933 return ptr;
936 static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
937 u32 h_stream,
938 struct snd_pcm_hardware *pcmhw)
940 struct hpi_format hpi_format;
941 u16 format;
942 u16 err;
943 u32 h_control;
944 u32 sample_rate = 48000;
946 /* on cards without SRC, must query at valid rate,
947 * maybe set by external sync
949 err = hpi_mixer_get_control(asihpi->h_mixer,
950 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
951 HPI_CONTROL_SAMPLECLOCK, &h_control);
953 if (!err)
954 err = hpi_sample_clock_get_sample_rate(h_control,
955 &sample_rate);
957 for (format = HPI_FORMAT_PCM8_UNSIGNED;
958 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
959 err = hpi_format_create(&hpi_format,
960 2, format, sample_rate, 128000, 0);
961 if (!err)
962 err = hpi_outstream_query_format(h_stream,
963 &hpi_format);
964 if (!err && (hpi_to_alsa_formats[format] != -1))
965 pcmhw->formats |=
966 (1ULL << hpi_to_alsa_formats[format]);
970 static struct snd_pcm_hardware snd_card_asihpi_playback = {
971 .channels_min = 1,
972 .channels_max = 2,
973 .buffer_bytes_max = BUFFER_BYTES_MAX,
974 .period_bytes_min = PERIOD_BYTES_MIN,
975 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
976 .periods_min = PERIODS_MIN,
977 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
978 .fifo_size = 0,
981 static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
983 struct snd_pcm_runtime *runtime = substream->runtime;
984 struct snd_card_asihpi_pcm *dpcm;
985 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
986 int err;
988 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
989 if (dpcm == NULL)
990 return -ENOMEM;
992 err =
993 hpi_outstream_open(card->adapter_index,
994 substream->number, &dpcm->h_stream);
995 hpi_handle_error(err);
996 if (err)
997 kfree(dpcm);
998 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
999 return -EBUSY;
1000 if (err)
1001 return -EIO;
1003 /*? also check ASI5000 samplerate source
1004 If external, only support external rate.
1005 If internal and other stream playing, can't switch
1008 init_timer(&dpcm->timer);
1009 dpcm->timer.data = (unsigned long) dpcm;
1010 dpcm->timer.function = snd_card_asihpi_timer_function;
1011 dpcm->substream = substream;
1012 runtime->private_data = dpcm;
1013 runtime->private_free = snd_card_asihpi_runtime_free;
1015 snd_card_asihpi_playback.channels_max = card->out_max_chans;
1016 /*?snd_card_asihpi_playback.period_bytes_min =
1017 card->out_max_chans * 4096; */
1019 snd_card_asihpi_playback_format(card, dpcm->h_stream,
1020 &snd_card_asihpi_playback);
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;
1035 /* struct is copied, so can create initializer dynamically */
1036 runtime->hw = snd_card_asihpi_playback;
1038 if (card->can_dma)
1039 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1040 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1041 if (err < 0)
1042 return err;
1044 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1045 card->update_interval_frames);
1047 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1048 card->update_interval_frames * 2, UINT_MAX);
1050 snd_pcm_set_sync(substream);
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 void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1118 u32 h_stream,
1119 struct snd_pcm_hardware *pcmhw)
1121 struct hpi_format hpi_format;
1122 u16 format;
1123 u16 err;
1124 u32 h_control;
1125 u32 sample_rate = 48000;
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, 2, format,
1141 sample_rate, 128000, 0);
1142 if (!err)
1143 err = hpi_instream_query_format(h_stream,
1144 &hpi_format);
1145 if (!err)
1146 pcmhw->formats |=
1147 (1ULL << hpi_to_alsa_formats[format]);
1152 static struct snd_pcm_hardware snd_card_asihpi_capture = {
1153 .channels_min = 1,
1154 .channels_max = 2,
1155 .buffer_bytes_max = BUFFER_BYTES_MAX,
1156 .period_bytes_min = PERIOD_BYTES_MIN,
1157 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1158 .periods_min = PERIODS_MIN,
1159 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1160 .fifo_size = 0,
1163 static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1165 struct snd_pcm_runtime *runtime = substream->runtime;
1166 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1167 struct snd_card_asihpi_pcm *dpcm;
1168 int err;
1170 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1171 if (dpcm == NULL)
1172 return -ENOMEM;
1174 snd_printdd("capture open adapter %d stream %d\n",
1175 card->adapter_index, substream->number);
1177 err = hpi_handle_error(
1178 hpi_instream_open(card->adapter_index,
1179 substream->number, &dpcm->h_stream));
1180 if (err)
1181 kfree(dpcm);
1182 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1183 return -EBUSY;
1184 if (err)
1185 return -EIO;
1188 init_timer(&dpcm->timer);
1189 dpcm->timer.data = (unsigned long) dpcm;
1190 dpcm->timer.function = snd_card_asihpi_timer_function;
1191 dpcm->substream = substream;
1192 runtime->private_data = dpcm;
1193 runtime->private_free = snd_card_asihpi_runtime_free;
1195 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1196 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1197 &snd_card_asihpi_capture);
1198 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1199 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
1200 SNDRV_PCM_INFO_MMAP |
1201 SNDRV_PCM_INFO_MMAP_VALID;
1203 if (card->support_grouping)
1204 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1206 runtime->hw = snd_card_asihpi_capture;
1208 if (card->can_dma)
1209 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1210 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1211 if (err < 0)
1212 return err;
1214 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1215 card->update_interval_frames);
1216 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1217 card->update_interval_frames * 2, UINT_MAX);
1219 snd_pcm_set_sync(substream);
1221 return 0;
1224 static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1226 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1228 hpi_handle_error(hpi_instream_close(dpcm->h_stream));
1229 return 0;
1232 static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1233 .open = snd_card_asihpi_capture_open,
1234 .close = snd_card_asihpi_capture_close,
1235 .ioctl = snd_card_asihpi_capture_ioctl,
1236 .hw_params = snd_card_asihpi_pcm_hw_params,
1237 .hw_free = snd_card_asihpi_hw_free,
1238 .prepare = snd_card_asihpi_capture_prepare,
1239 .trigger = snd_card_asihpi_trigger,
1240 .pointer = snd_card_asihpi_capture_pointer,
1243 static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1244 int device, int substreams)
1246 struct snd_pcm *pcm;
1247 int err;
1249 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1250 asihpi->num_outstreams, asihpi->num_instreams,
1251 &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 "GPI",
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",
1335 "GPO",
1338 compile_time_assert(
1339 (ARRAY_SIZE(asihpi_dst_names) ==
1340 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1341 assert_dst_names_size);
1343 static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1344 struct snd_card_asihpi *asihpi)
1346 int err;
1348 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1349 if (err < 0)
1350 return err;
1351 else if (mixer_dump)
1352 snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1354 return 0;
1357 /* Convert HPI control name and location into ALSA control name */
1358 static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1359 struct hpi_control *hpi_ctl,
1360 char *name)
1362 char *dir;
1363 memset(snd_control, 0, sizeof(*snd_control));
1364 snd_control->name = hpi_ctl->name;
1365 snd_control->private_value = hpi_ctl->h_control;
1366 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1367 snd_control->index = 0;
1369 if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
1370 dir = ""; /* clock is neither capture nor playback */
1371 else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1372 dir = "Capture "; /* On or towards a PCM capture destination*/
1373 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1374 (!hpi_ctl->dst_node_type))
1375 dir = "Capture "; /* On a source node that is not PCM playback */
1376 else if (hpi_ctl->src_node_type &&
1377 (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1378 (hpi_ctl->dst_node_type))
1379 dir = "Monitor Playback "; /* Between an input and an output */
1380 else
1381 dir = "Playback "; /* PCM Playback source, or output node */
1383 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1384 sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
1385 asihpi_src_names[hpi_ctl->src_node_type],
1386 hpi_ctl->src_node_index,
1387 asihpi_dst_names[hpi_ctl->dst_node_type],
1388 hpi_ctl->dst_node_index,
1389 dir, name);
1390 else if (hpi_ctl->dst_node_type) {
1391 sprintf(hpi_ctl->name, "%s %d %s%s",
1392 asihpi_dst_names[hpi_ctl->dst_node_type],
1393 hpi_ctl->dst_node_index,
1394 dir, name);
1395 } else {
1396 sprintf(hpi_ctl->name, "%s %d %s%s",
1397 asihpi_src_names[hpi_ctl->src_node_type],
1398 hpi_ctl->src_node_index,
1399 dir, name);
1401 /* printk(KERN_INFO "Adding %s %d to %d ", hpi_ctl->name,
1402 hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */
1405 /*------------------------------------------------------------
1406 Volume controls
1407 ------------------------------------------------------------*/
1408 #define VOL_STEP_mB 1
1409 static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1410 struct snd_ctl_elem_info *uinfo)
1412 u32 h_control = kcontrol->private_value;
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 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1428 uinfo->count = 2;
1429 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1430 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1431 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1432 return 0;
1435 static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1436 struct snd_ctl_elem_value *ucontrol)
1438 u32 h_control = kcontrol->private_value;
1439 short an_gain_mB[HPI_MAX_CHANNELS];
1441 hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB));
1442 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1443 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1445 return 0;
1448 static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1449 struct snd_ctl_elem_value *ucontrol)
1451 int change;
1452 u32 h_control = kcontrol->private_value;
1453 short an_gain_mB[HPI_MAX_CHANNELS];
1455 an_gain_mB[0] =
1456 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1457 an_gain_mB[1] =
1458 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1459 /* change = asihpi->mixer_volume[addr][0] != left ||
1460 asihpi->mixer_volume[addr][1] != right;
1462 change = 1;
1463 hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
1464 return change;
1467 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1469 #define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
1471 static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
1472 struct snd_ctl_elem_value *ucontrol)
1474 u32 h_control = kcontrol->private_value;
1475 u32 mute;
1477 hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
1478 ucontrol->value.integer.value[0] = mute ? 0 : 1;
1480 return 0;
1483 static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
1484 struct snd_ctl_elem_value *ucontrol)
1486 u32 h_control = kcontrol->private_value;
1487 int change = 1;
1488 /* HPI currently only supports all or none muting of multichannel volume
1489 ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
1491 int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
1492 hpi_handle_error(hpi_volume_set_mute(h_control, mute));
1493 return change;
1496 static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1497 struct hpi_control *hpi_ctl)
1499 struct snd_card *card = asihpi->card;
1500 struct snd_kcontrol_new snd_control;
1501 int err;
1502 u32 mute;
1504 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
1505 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1506 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1507 snd_control.info = snd_asihpi_volume_info;
1508 snd_control.get = snd_asihpi_volume_get;
1509 snd_control.put = snd_asihpi_volume_put;
1510 snd_control.tlv.p = db_scale_100;
1512 err = ctl_add(card, &snd_control, asihpi);
1513 if (err)
1514 return err;
1516 if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
1517 asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
1518 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1519 snd_control.info = snd_asihpi_volume_mute_info;
1520 snd_control.get = snd_asihpi_volume_mute_get;
1521 snd_control.put = snd_asihpi_volume_mute_put;
1522 err = ctl_add(card, &snd_control, asihpi);
1524 return err;
1527 /*------------------------------------------------------------
1528 Level controls
1529 ------------------------------------------------------------*/
1530 static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1531 struct snd_ctl_elem_info *uinfo)
1533 u32 h_control = kcontrol->private_value;
1534 u16 err;
1535 short min_gain_mB;
1536 short max_gain_mB;
1537 short step_gain_mB;
1539 err =
1540 hpi_level_query_range(h_control, &min_gain_mB,
1541 &max_gain_mB, &step_gain_mB);
1542 if (err) {
1543 max_gain_mB = 2400;
1544 min_gain_mB = -1000;
1545 step_gain_mB = 100;
1548 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1549 uinfo->count = 2;
1550 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1551 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1552 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1553 return 0;
1556 static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1557 struct snd_ctl_elem_value *ucontrol)
1559 u32 h_control = kcontrol->private_value;
1560 short an_gain_mB[HPI_MAX_CHANNELS];
1562 hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
1563 ucontrol->value.integer.value[0] =
1564 an_gain_mB[0] / HPI_UNITS_PER_dB;
1565 ucontrol->value.integer.value[1] =
1566 an_gain_mB[1] / HPI_UNITS_PER_dB;
1568 return 0;
1571 static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1572 struct snd_ctl_elem_value *ucontrol)
1574 int change;
1575 u32 h_control = kcontrol->private_value;
1576 short an_gain_mB[HPI_MAX_CHANNELS];
1578 an_gain_mB[0] =
1579 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1580 an_gain_mB[1] =
1581 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1582 /* change = asihpi->mixer_level[addr][0] != left ||
1583 asihpi->mixer_level[addr][1] != right;
1585 change = 1;
1586 hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
1587 return change;
1590 static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1592 static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1593 struct hpi_control *hpi_ctl)
1595 struct snd_card *card = asihpi->card;
1596 struct snd_kcontrol_new snd_control;
1598 /* can't use 'volume' cos some nodes have volume as well */
1599 asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
1600 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1601 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1602 snd_control.info = snd_asihpi_level_info;
1603 snd_control.get = snd_asihpi_level_get;
1604 snd_control.put = snd_asihpi_level_put;
1605 snd_control.tlv.p = db_scale_level;
1607 return ctl_add(card, &snd_control, asihpi);
1610 /*------------------------------------------------------------
1611 AESEBU controls
1612 ------------------------------------------------------------*/
1614 /* AESEBU format */
1615 static const char * const asihpi_aesebu_format_names[] = {
1616 "N/A", "S/PDIF", "AES/EBU" };
1618 static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1619 struct snd_ctl_elem_info *uinfo)
1621 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1622 uinfo->count = 1;
1623 uinfo->value.enumerated.items = 3;
1625 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1626 uinfo->value.enumerated.item =
1627 uinfo->value.enumerated.items - 1;
1629 strcpy(uinfo->value.enumerated.name,
1630 asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1632 return 0;
1635 static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1636 struct snd_ctl_elem_value *ucontrol,
1637 u16 (*func)(u32, u16 *))
1639 u32 h_control = kcontrol->private_value;
1640 u16 source, err;
1642 err = func(h_control, &source);
1644 /* default to N/A */
1645 ucontrol->value.enumerated.item[0] = 0;
1646 /* return success but set the control to N/A */
1647 if (err)
1648 return 0;
1649 if (source == HPI_AESEBU_FORMAT_SPDIF)
1650 ucontrol->value.enumerated.item[0] = 1;
1651 if (source == HPI_AESEBU_FORMAT_AESEBU)
1652 ucontrol->value.enumerated.item[0] = 2;
1654 return 0;
1657 static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1658 struct snd_ctl_elem_value *ucontrol,
1659 u16 (*func)(u32, u16))
1661 u32 h_control = kcontrol->private_value;
1663 /* default to S/PDIF */
1664 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1666 if (ucontrol->value.enumerated.item[0] == 1)
1667 source = HPI_AESEBU_FORMAT_SPDIF;
1668 if (ucontrol->value.enumerated.item[0] == 2)
1669 source = HPI_AESEBU_FORMAT_AESEBU;
1671 if (func(h_control, source) != 0)
1672 return -EINVAL;
1674 return 1;
1677 static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1678 struct snd_ctl_elem_value *ucontrol) {
1679 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1680 hpi_aesebu_receiver_get_format);
1683 static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1684 struct snd_ctl_elem_value *ucontrol) {
1685 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1686 hpi_aesebu_receiver_set_format);
1689 static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1690 struct snd_ctl_elem_info *uinfo)
1692 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1693 uinfo->count = 1;
1695 uinfo->value.integer.min = 0;
1696 uinfo->value.integer.max = 0X1F;
1697 uinfo->value.integer.step = 1;
1699 return 0;
1702 static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1703 struct snd_ctl_elem_value *ucontrol) {
1705 u32 h_control = kcontrol->private_value;
1706 u16 status;
1708 hpi_handle_error(hpi_aesebu_receiver_get_error_status(
1709 h_control, &status));
1710 ucontrol->value.integer.value[0] = status;
1711 return 0;
1714 static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1715 struct hpi_control *hpi_ctl)
1717 struct snd_card *card = asihpi->card;
1718 struct snd_kcontrol_new snd_control;
1720 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1721 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1722 snd_control.info = snd_asihpi_aesebu_format_info;
1723 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1724 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1727 if (ctl_add(card, &snd_control, asihpi) < 0)
1728 return -EINVAL;
1730 asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
1731 snd_control.access =
1732 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1733 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1734 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1736 return ctl_add(card, &snd_control, asihpi);
1739 static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1740 struct snd_ctl_elem_value *ucontrol) {
1741 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1742 hpi_aesebu_transmitter_get_format);
1745 static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1746 struct snd_ctl_elem_value *ucontrol) {
1747 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1748 hpi_aesebu_transmitter_set_format);
1752 static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1753 struct hpi_control *hpi_ctl)
1755 struct snd_card *card = asihpi->card;
1756 struct snd_kcontrol_new snd_control;
1758 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1759 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1760 snd_control.info = snd_asihpi_aesebu_format_info;
1761 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1762 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1764 return ctl_add(card, &snd_control, asihpi);
1767 /*------------------------------------------------------------
1768 Tuner controls
1769 ------------------------------------------------------------*/
1771 /* Gain */
1773 static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1774 struct snd_ctl_elem_info *uinfo)
1776 u32 h_control = kcontrol->private_value;
1777 u16 err;
1778 short idx;
1779 u16 gain_range[3];
1781 for (idx = 0; idx < 3; idx++) {
1782 err = hpi_tuner_query_gain(h_control,
1783 idx, &gain_range[idx]);
1784 if (err != 0)
1785 return err;
1788 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1789 uinfo->count = 1;
1790 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1791 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1792 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1793 return 0;
1796 static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1797 struct snd_ctl_elem_value *ucontrol)
1800 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1802 u32 h_control = kcontrol->private_value;
1803 short gain;
1805 hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
1806 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1808 return 0;
1811 static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1812 struct snd_ctl_elem_value *ucontrol)
1815 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1817 u32 h_control = kcontrol->private_value;
1818 short gain;
1820 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1821 hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
1823 return 1;
1826 /* Band */
1828 static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1829 u16 *band_list, u32 len) {
1830 u32 h_control = kcontrol->private_value;
1831 u16 err = 0;
1832 u32 i;
1834 for (i = 0; i < len; i++) {
1835 err = hpi_tuner_query_band(
1836 h_control, i, &band_list[i]);
1837 if (err != 0)
1838 break;
1841 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1842 return -EIO;
1844 return i;
1847 static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1848 struct snd_ctl_elem_info *uinfo)
1850 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1851 int num_bands = 0;
1853 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1854 HPI_TUNER_BAND_LAST);
1856 if (num_bands < 0)
1857 return num_bands;
1859 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1860 uinfo->count = 1;
1861 uinfo->value.enumerated.items = num_bands;
1863 if (num_bands > 0) {
1864 if (uinfo->value.enumerated.item >=
1865 uinfo->value.enumerated.items)
1866 uinfo->value.enumerated.item =
1867 uinfo->value.enumerated.items - 1;
1869 strcpy(uinfo->value.enumerated.name,
1870 asihpi_tuner_band_names[
1871 tuner_bands[uinfo->value.enumerated.item]]);
1874 return 0;
1877 static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1878 struct snd_ctl_elem_value *ucontrol)
1880 u32 h_control = kcontrol->private_value;
1882 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1884 u16 band, idx;
1885 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1886 u32 num_bands = 0;
1888 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1889 HPI_TUNER_BAND_LAST);
1891 hpi_handle_error(hpi_tuner_get_band(h_control, &band));
1893 ucontrol->value.enumerated.item[0] = -1;
1894 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1895 if (tuner_bands[idx] == band) {
1896 ucontrol->value.enumerated.item[0] = idx;
1897 break;
1900 return 0;
1903 static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1904 struct snd_ctl_elem_value *ucontrol)
1907 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1909 u32 h_control = kcontrol->private_value;
1910 u16 band;
1911 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1912 u32 num_bands = 0;
1914 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1915 HPI_TUNER_BAND_LAST);
1917 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1918 hpi_handle_error(hpi_tuner_set_band(h_control, band));
1920 return 1;
1923 /* Freq */
1925 static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1926 struct snd_ctl_elem_info *uinfo)
1928 u32 h_control = kcontrol->private_value;
1929 u16 err;
1930 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1931 u16 num_bands = 0, band_iter, idx;
1932 u32 freq_range[3], temp_freq_range[3];
1934 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1935 HPI_TUNER_BAND_LAST);
1937 freq_range[0] = INT_MAX;
1938 freq_range[1] = 0;
1939 freq_range[2] = INT_MAX;
1941 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1942 for (idx = 0; idx < 3; idx++) {
1943 err = hpi_tuner_query_frequency(h_control,
1944 idx, tuner_bands[band_iter],
1945 &temp_freq_range[idx]);
1946 if (err != 0)
1947 return err;
1950 /* skip band with bogus stepping */
1951 if (temp_freq_range[2] <= 0)
1952 continue;
1954 if (temp_freq_range[0] < freq_range[0])
1955 freq_range[0] = temp_freq_range[0];
1956 if (temp_freq_range[1] > freq_range[1])
1957 freq_range[1] = temp_freq_range[1];
1958 if (temp_freq_range[2] < freq_range[2])
1959 freq_range[2] = temp_freq_range[2];
1962 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1963 uinfo->count = 1;
1964 uinfo->value.integer.min = ((int)freq_range[0]);
1965 uinfo->value.integer.max = ((int)freq_range[1]);
1966 uinfo->value.integer.step = ((int)freq_range[2]);
1967 return 0;
1970 static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1971 struct snd_ctl_elem_value *ucontrol)
1973 u32 h_control = kcontrol->private_value;
1974 u32 freq;
1976 hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
1977 ucontrol->value.integer.value[0] = freq;
1979 return 0;
1982 static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
1983 struct snd_ctl_elem_value *ucontrol)
1985 u32 h_control = kcontrol->private_value;
1986 u32 freq;
1988 freq = ucontrol->value.integer.value[0];
1989 hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
1991 return 1;
1994 /* Tuner control group initializer */
1995 static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
1996 struct hpi_control *hpi_ctl)
1998 struct snd_card *card = asihpi->card;
1999 struct snd_kcontrol_new snd_control;
2001 snd_control.private_value = hpi_ctl->h_control;
2002 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2004 if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
2005 asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
2006 snd_control.info = snd_asihpi_tuner_gain_info;
2007 snd_control.get = snd_asihpi_tuner_gain_get;
2008 snd_control.put = snd_asihpi_tuner_gain_put;
2010 if (ctl_add(card, &snd_control, asihpi) < 0)
2011 return -EINVAL;
2014 asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
2015 snd_control.info = snd_asihpi_tuner_band_info;
2016 snd_control.get = snd_asihpi_tuner_band_get;
2017 snd_control.put = snd_asihpi_tuner_band_put;
2019 if (ctl_add(card, &snd_control, asihpi) < 0)
2020 return -EINVAL;
2022 asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
2023 snd_control.info = snd_asihpi_tuner_freq_info;
2024 snd_control.get = snd_asihpi_tuner_freq_get;
2025 snd_control.put = snd_asihpi_tuner_freq_put;
2027 return ctl_add(card, &snd_control, asihpi);
2030 /*------------------------------------------------------------
2031 Meter controls
2032 ------------------------------------------------------------*/
2033 static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2034 struct snd_ctl_elem_info *uinfo)
2036 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2037 uinfo->count = HPI_MAX_CHANNELS;
2038 uinfo->value.integer.min = 0;
2039 uinfo->value.integer.max = 0x7FFFFFFF;
2040 return 0;
2043 /* linear values for 10dB steps */
2044 static int log2lin[] = {
2045 0x7FFFFFFF, /* 0dB */
2046 679093956,
2047 214748365,
2048 67909396,
2049 21474837,
2050 6790940,
2051 2147484, /* -60dB */
2052 679094,
2053 214748, /* -80 */
2054 67909,
2055 21475, /* -100 */
2056 6791,
2057 2147,
2058 679,
2059 214,
2066 static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2067 struct snd_ctl_elem_value *ucontrol)
2069 u32 h_control = kcontrol->private_value;
2070 short an_gain_mB[HPI_MAX_CHANNELS], i;
2071 u16 err;
2073 err = hpi_meter_get_peak(h_control, an_gain_mB);
2075 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2076 if (err) {
2077 ucontrol->value.integer.value[i] = 0;
2078 } else if (an_gain_mB[i] >= 0) {
2079 ucontrol->value.integer.value[i] =
2080 an_gain_mB[i] << 16;
2081 } else {
2082 /* -ve is log value in millibels < -60dB,
2083 * convert to (roughly!) linear,
2085 ucontrol->value.integer.value[i] =
2086 log2lin[an_gain_mB[i] / -1000];
2089 return 0;
2092 static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2093 struct hpi_control *hpi_ctl, int subidx)
2095 struct snd_card *card = asihpi->card;
2096 struct snd_kcontrol_new snd_control;
2098 asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
2099 snd_control.access =
2100 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2101 snd_control.info = snd_asihpi_meter_info;
2102 snd_control.get = snd_asihpi_meter_get;
2104 snd_control.index = subidx;
2106 return ctl_add(card, &snd_control, asihpi);
2109 /*------------------------------------------------------------
2110 Multiplexer controls
2111 ------------------------------------------------------------*/
2112 static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2114 u32 h_control = snd_control->private_value;
2115 struct hpi_control hpi_ctl;
2116 int s, err;
2117 for (s = 0; s < 32; s++) {
2118 err = hpi_multiplexer_query_source(h_control, s,
2119 &hpi_ctl.
2120 src_node_type,
2121 &hpi_ctl.
2122 src_node_index);
2123 if (err)
2124 break;
2126 return s;
2129 static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2130 struct snd_ctl_elem_info *uinfo)
2132 int err;
2133 u16 src_node_type, src_node_index;
2134 u32 h_control = kcontrol->private_value;
2136 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2137 uinfo->count = 1;
2138 uinfo->value.enumerated.items =
2139 snd_card_asihpi_mux_count_sources(kcontrol);
2141 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2142 uinfo->value.enumerated.item =
2143 uinfo->value.enumerated.items - 1;
2145 err =
2146 hpi_multiplexer_query_source(h_control,
2147 uinfo->value.enumerated.item,
2148 &src_node_type, &src_node_index);
2150 sprintf(uinfo->value.enumerated.name, "%s %d",
2151 asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
2152 src_node_index);
2153 return 0;
2156 static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2157 struct snd_ctl_elem_value *ucontrol)
2159 u32 h_control = kcontrol->private_value;
2160 u16 source_type, source_index;
2161 u16 src_node_type, src_node_index;
2162 int s;
2164 hpi_handle_error(hpi_multiplexer_get_source(h_control,
2165 &source_type, &source_index));
2166 /* Should cache this search result! */
2167 for (s = 0; s < 256; s++) {
2168 if (hpi_multiplexer_query_source(h_control, s,
2169 &src_node_type, &src_node_index))
2170 break;
2172 if ((source_type == src_node_type)
2173 && (source_index == src_node_index)) {
2174 ucontrol->value.enumerated.item[0] = s;
2175 return 0;
2178 snd_printd(KERN_WARNING
2179 "Control %x failed to match mux source %hu %hu\n",
2180 h_control, source_type, source_index);
2181 ucontrol->value.enumerated.item[0] = 0;
2182 return 0;
2185 static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2186 struct snd_ctl_elem_value *ucontrol)
2188 int change;
2189 u32 h_control = kcontrol->private_value;
2190 u16 source_type, source_index;
2191 u16 e;
2193 change = 1;
2195 e = hpi_multiplexer_query_source(h_control,
2196 ucontrol->value.enumerated.item[0],
2197 &source_type, &source_index);
2198 if (!e)
2199 hpi_handle_error(
2200 hpi_multiplexer_set_source(h_control,
2201 source_type, source_index));
2202 return change;
2206 static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2207 struct hpi_control *hpi_ctl)
2209 struct snd_card *card = asihpi->card;
2210 struct snd_kcontrol_new snd_control;
2212 asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
2213 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2214 snd_control.info = snd_asihpi_mux_info;
2215 snd_control.get = snd_asihpi_mux_get;
2216 snd_control.put = snd_asihpi_mux_put;
2218 return ctl_add(card, &snd_control, asihpi);
2222 /*------------------------------------------------------------
2223 Channel mode controls
2224 ------------------------------------------------------------*/
2225 static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2226 struct snd_ctl_elem_info *uinfo)
2228 static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
2229 "invalid",
2230 "Normal", "Swap",
2231 "From Left", "From Right",
2232 "To Left", "To Right"
2235 u32 h_control = kcontrol->private_value;
2236 u16 mode;
2237 int i;
2238 u16 mode_map[6];
2239 int valid_modes = 0;
2241 /* HPI channel mode values can be from 1 to 6
2242 Some adapters only support a contiguous subset
2244 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2245 if (!hpi_channel_mode_query_mode(
2246 h_control, i, &mode)) {
2247 mode_map[valid_modes] = mode;
2248 valid_modes++;
2251 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2252 uinfo->count = 1;
2253 uinfo->value.enumerated.items = valid_modes;
2255 if (uinfo->value.enumerated.item >= valid_modes)
2256 uinfo->value.enumerated.item = valid_modes - 1;
2258 strcpy(uinfo->value.enumerated.name,
2259 mode_names[mode_map[uinfo->value.enumerated.item]]);
2261 return 0;
2264 static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2265 struct snd_ctl_elem_value *ucontrol)
2267 u32 h_control = kcontrol->private_value;
2268 u16 mode;
2270 if (hpi_channel_mode_get(h_control, &mode))
2271 mode = 1;
2273 ucontrol->value.enumerated.item[0] = mode - 1;
2275 return 0;
2278 static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2279 struct snd_ctl_elem_value *ucontrol)
2281 int change;
2282 u32 h_control = kcontrol->private_value;
2284 change = 1;
2286 hpi_handle_error(hpi_channel_mode_set(h_control,
2287 ucontrol->value.enumerated.item[0] + 1));
2288 return change;
2292 static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2293 struct hpi_control *hpi_ctl)
2295 struct snd_card *card = asihpi->card;
2296 struct snd_kcontrol_new snd_control;
2298 asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
2299 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2300 snd_control.info = snd_asihpi_cmode_info;
2301 snd_control.get = snd_asihpi_cmode_get;
2302 snd_control.put = snd_asihpi_cmode_put;
2304 return ctl_add(card, &snd_control, asihpi);
2307 /*------------------------------------------------------------
2308 Sampleclock source controls
2309 ------------------------------------------------------------*/
2310 static char *sampleclock_sources[MAX_CLOCKSOURCES] = {
2311 "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
2312 "SMPTE", "Digital1", "Auto", "Network", "Invalid",
2313 "Prev Module",
2314 "Digital2", "Digital3", "Digital4", "Digital5",
2315 "Digital6", "Digital7", "Digital8"};
2317 static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2318 struct snd_ctl_elem_info *uinfo)
2320 struct snd_card_asihpi *asihpi =
2321 (struct snd_card_asihpi *)(kcontrol->private_data);
2322 struct clk_cache *clkcache = &asihpi->cc;
2323 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2324 uinfo->count = 1;
2325 uinfo->value.enumerated.items = clkcache->count;
2327 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2328 uinfo->value.enumerated.item =
2329 uinfo->value.enumerated.items - 1;
2331 strcpy(uinfo->value.enumerated.name,
2332 clkcache->s[uinfo->value.enumerated.item].name);
2333 return 0;
2336 static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2337 struct snd_ctl_elem_value *ucontrol)
2339 struct snd_card_asihpi *asihpi =
2340 (struct snd_card_asihpi *)(kcontrol->private_data);
2341 struct clk_cache *clkcache = &asihpi->cc;
2342 u32 h_control = kcontrol->private_value;
2343 u16 source, srcindex = 0;
2344 int i;
2346 ucontrol->value.enumerated.item[0] = 0;
2347 if (hpi_sample_clock_get_source(h_control, &source))
2348 source = 0;
2350 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2351 if (hpi_sample_clock_get_source_index(h_control, &srcindex))
2352 srcindex = 0;
2354 for (i = 0; i < clkcache->count; i++)
2355 if ((clkcache->s[i].source == source) &&
2356 (clkcache->s[i].index == srcindex))
2357 break;
2359 ucontrol->value.enumerated.item[0] = i;
2361 return 0;
2364 static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2365 struct snd_ctl_elem_value *ucontrol)
2367 struct snd_card_asihpi *asihpi =
2368 (struct snd_card_asihpi *)(kcontrol->private_data);
2369 struct clk_cache *clkcache = &asihpi->cc;
2370 int change, item;
2371 u32 h_control = kcontrol->private_value;
2373 change = 1;
2374 item = ucontrol->value.enumerated.item[0];
2375 if (item >= clkcache->count)
2376 item = clkcache->count-1;
2378 hpi_handle_error(hpi_sample_clock_set_source(
2379 h_control, clkcache->s[item].source));
2381 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2382 hpi_handle_error(hpi_sample_clock_set_source_index(
2383 h_control, clkcache->s[item].index));
2384 return change;
2387 /*------------------------------------------------------------
2388 Clkrate controls
2389 ------------------------------------------------------------*/
2390 /* Need to change this to enumerated control with list of rates */
2391 static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2392 struct snd_ctl_elem_info *uinfo)
2394 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2395 uinfo->count = 1;
2396 uinfo->value.integer.min = 8000;
2397 uinfo->value.integer.max = 192000;
2398 uinfo->value.integer.step = 100;
2400 return 0;
2403 static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2404 struct snd_ctl_elem_value *ucontrol)
2406 u32 h_control = kcontrol->private_value;
2407 u32 rate;
2408 u16 e;
2410 e = hpi_sample_clock_get_local_rate(h_control, &rate);
2411 if (!e)
2412 ucontrol->value.integer.value[0] = rate;
2413 else
2414 ucontrol->value.integer.value[0] = 0;
2415 return 0;
2418 static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2419 struct snd_ctl_elem_value *ucontrol)
2421 int change;
2422 u32 h_control = kcontrol->private_value;
2424 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2425 asihpi->mixer_clkrate[addr][1] != right;
2427 change = 1;
2428 hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
2429 ucontrol->value.integer.value[0]));
2430 return change;
2433 static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2434 struct snd_ctl_elem_info *uinfo)
2436 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2437 uinfo->count = 1;
2438 uinfo->value.integer.min = 8000;
2439 uinfo->value.integer.max = 192000;
2440 uinfo->value.integer.step = 100;
2442 return 0;
2445 static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2446 struct snd_ctl_elem_value *ucontrol)
2448 u32 h_control = kcontrol->private_value;
2449 u32 rate;
2450 u16 e;
2452 e = hpi_sample_clock_get_sample_rate(h_control, &rate);
2453 if (!e)
2454 ucontrol->value.integer.value[0] = rate;
2455 else
2456 ucontrol->value.integer.value[0] = 0;
2457 return 0;
2460 static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2461 struct hpi_control *hpi_ctl)
2463 struct snd_card *card = asihpi->card;
2464 struct snd_kcontrol_new snd_control;
2466 struct clk_cache *clkcache = &asihpi->cc;
2467 u32 hSC = hpi_ctl->h_control;
2468 int has_aes_in = 0;
2469 int i, j;
2470 u16 source;
2472 snd_control.private_value = hpi_ctl->h_control;
2474 clkcache->has_local = 0;
2476 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2477 if (hpi_sample_clock_query_source(hSC,
2478 i, &source))
2479 break;
2480 clkcache->s[i].source = source;
2481 clkcache->s[i].index = 0;
2482 clkcache->s[i].name = sampleclock_sources[source];
2483 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2484 has_aes_in = 1;
2485 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2486 clkcache->has_local = 1;
2488 if (has_aes_in)
2489 /* already will have picked up index 0 above */
2490 for (j = 1; j < 8; j++) {
2491 if (hpi_sample_clock_query_source_index(hSC,
2492 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2493 &source))
2494 break;
2495 clkcache->s[i].source =
2496 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2497 clkcache->s[i].index = j;
2498 clkcache->s[i].name = sampleclock_sources[
2499 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2500 i++;
2502 clkcache->count = i;
2504 asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
2505 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2506 snd_control.info = snd_asihpi_clksrc_info;
2507 snd_control.get = snd_asihpi_clksrc_get;
2508 snd_control.put = snd_asihpi_clksrc_put;
2509 if (ctl_add(card, &snd_control, asihpi) < 0)
2510 return -EINVAL;
2513 if (clkcache->has_local) {
2514 asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
2515 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2516 snd_control.info = snd_asihpi_clklocal_info;
2517 snd_control.get = snd_asihpi_clklocal_get;
2518 snd_control.put = snd_asihpi_clklocal_put;
2521 if (ctl_add(card, &snd_control, asihpi) < 0)
2522 return -EINVAL;
2525 asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
2526 snd_control.access =
2527 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2528 snd_control.info = snd_asihpi_clkrate_info;
2529 snd_control.get = snd_asihpi_clkrate_get;
2531 return ctl_add(card, &snd_control, asihpi);
2533 /*------------------------------------------------------------
2534 Mixer
2535 ------------------------------------------------------------*/
2537 static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2539 struct snd_card *card = asihpi->card;
2540 unsigned int idx = 0;
2541 unsigned int subindex = 0;
2542 int err;
2543 struct hpi_control hpi_ctl, prev_ctl;
2545 if (snd_BUG_ON(!asihpi))
2546 return -EINVAL;
2547 strcpy(card->mixername, "Asihpi Mixer");
2549 err =
2550 hpi_mixer_open(asihpi->adapter_index,
2551 &asihpi->h_mixer);
2552 hpi_handle_error(err);
2553 if (err)
2554 return -err;
2556 memset(&prev_ctl, 0, sizeof(prev_ctl));
2557 prev_ctl.control_type = -1;
2559 for (idx = 0; idx < 2000; idx++) {
2560 err = hpi_mixer_get_control_by_index(
2561 asihpi->h_mixer,
2562 idx,
2563 &hpi_ctl.src_node_type,
2564 &hpi_ctl.src_node_index,
2565 &hpi_ctl.dst_node_type,
2566 &hpi_ctl.dst_node_index,
2567 &hpi_ctl.control_type,
2568 &hpi_ctl.h_control);
2569 if (err) {
2570 if (err == HPI_ERROR_CONTROL_DISABLED) {
2571 if (mixer_dump)
2572 snd_printk(KERN_INFO
2573 "Disabled HPI Control(%d)\n",
2574 idx);
2575 continue;
2576 } else
2577 break;
2581 hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2582 hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
2584 /* ASI50xx in SSX mode has multiple meters on the same node.
2585 Use subindex to create distinct ALSA controls
2586 for any duplicated controls.
2588 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2589 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2590 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2591 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2592 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2593 subindex++;
2594 else
2595 subindex = 0;
2597 prev_ctl = hpi_ctl;
2599 switch (hpi_ctl.control_type) {
2600 case HPI_CONTROL_VOLUME:
2601 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2602 break;
2603 case HPI_CONTROL_LEVEL:
2604 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2605 break;
2606 case HPI_CONTROL_MULTIPLEXER:
2607 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2608 break;
2609 case HPI_CONTROL_CHANNEL_MODE:
2610 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2611 break;
2612 case HPI_CONTROL_METER:
2613 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2614 break;
2615 case HPI_CONTROL_SAMPLECLOCK:
2616 err = snd_asihpi_sampleclock_add(
2617 asihpi, &hpi_ctl);
2618 break;
2619 case HPI_CONTROL_CONNECTION: /* ignore these */
2620 continue;
2621 case HPI_CONTROL_TUNER:
2622 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2623 break;
2624 case HPI_CONTROL_AESEBU_TRANSMITTER:
2625 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2626 break;
2627 case HPI_CONTROL_AESEBU_RECEIVER:
2628 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2629 break;
2630 case HPI_CONTROL_VOX:
2631 case HPI_CONTROL_BITSTREAM:
2632 case HPI_CONTROL_MICROPHONE:
2633 case HPI_CONTROL_PARAMETRIC_EQ:
2634 case HPI_CONTROL_COMPANDER:
2635 default:
2636 if (mixer_dump)
2637 snd_printk(KERN_INFO
2638 "Untranslated HPI Control"
2639 "(%d) %d %d %d %d %d\n",
2640 idx,
2641 hpi_ctl.control_type,
2642 hpi_ctl.src_node_type,
2643 hpi_ctl.src_node_index,
2644 hpi_ctl.dst_node_type,
2645 hpi_ctl.dst_node_index);
2646 continue;
2648 if (err < 0)
2649 return err;
2651 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2652 hpi_handle_error(err);
2654 snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2656 return 0;
2659 /*------------------------------------------------------------
2660 /proc interface
2661 ------------------------------------------------------------*/
2663 static void
2664 snd_asihpi_proc_read(struct snd_info_entry *entry,
2665 struct snd_info_buffer *buffer)
2667 struct snd_card_asihpi *asihpi = entry->private_data;
2668 u16 version;
2669 u32 h_control;
2670 u32 rate = 0;
2671 u16 source = 0;
2672 int err;
2674 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2675 snd_iprintf(buffer,
2676 "adapter ID=%4X\n_index=%d\n"
2677 "num_outstreams=%d\n_num_instreams=%d\n",
2678 asihpi->type, asihpi->adapter_index,
2679 asihpi->num_outstreams, asihpi->num_instreams);
2681 version = asihpi->version;
2682 snd_iprintf(buffer,
2683 "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
2684 asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
2685 version & 0x7,
2686 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2688 err = hpi_mixer_get_control(asihpi->h_mixer,
2689 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2690 HPI_CONTROL_SAMPLECLOCK, &h_control);
2692 if (!err) {
2693 err = hpi_sample_clock_get_sample_rate(
2694 h_control, &rate);
2695 err += hpi_sample_clock_get_source(h_control, &source);
2697 if (!err)
2698 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
2699 rate, sampleclock_sources[source]);
2705 static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2707 struct snd_info_entry *entry;
2709 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2710 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2713 /*------------------------------------------------------------
2714 HWDEP
2715 ------------------------------------------------------------*/
2717 static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2719 if (enable_hpi_hwdep)
2720 return 0;
2721 else
2722 return -ENODEV;
2726 static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2728 if (enable_hpi_hwdep)
2729 return asihpi_hpi_release(file);
2730 else
2731 return -ENODEV;
2734 static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2735 unsigned int cmd, unsigned long arg)
2737 if (enable_hpi_hwdep)
2738 return asihpi_hpi_ioctl(file, cmd, arg);
2739 else
2740 return -ENODEV;
2744 /* results in /dev/snd/hwC#D0 file for each card with index #
2745 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2747 static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2748 int device, struct snd_hwdep **rhwdep)
2750 struct snd_hwdep *hw;
2751 int err;
2753 if (rhwdep)
2754 *rhwdep = NULL;
2755 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2756 if (err < 0)
2757 return err;
2758 strcpy(hw->name, "asihpi (HPI)");
2759 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2760 hw->ops.open = snd_asihpi_hpi_open;
2761 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2762 hw->ops.release = snd_asihpi_hpi_release;
2763 hw->private_data = asihpi;
2764 if (rhwdep)
2765 *rhwdep = hw;
2766 return 0;
2769 /*------------------------------------------------------------
2770 CARD
2771 ------------------------------------------------------------*/
2772 static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2773 const struct pci_device_id *pci_id)
2775 int err;
2777 u16 version;
2778 int pcm_substreams;
2780 struct hpi_adapter *hpi_card;
2781 struct snd_card *card;
2782 struct snd_card_asihpi *asihpi;
2784 u32 h_control;
2785 u32 h_stream;
2787 static int dev;
2788 if (dev >= SNDRV_CARDS)
2789 return -ENODEV;
2791 /* Should this be enable[hpi_card->index] ? */
2792 if (!enable[dev]) {
2793 dev++;
2794 return -ENOENT;
2797 err = asihpi_adapter_probe(pci_dev, pci_id);
2798 if (err < 0)
2799 return err;
2801 hpi_card = pci_get_drvdata(pci_dev);
2802 /* first try to give the card the same index as its hardware index */
2803 err = snd_card_create(hpi_card->index,
2804 id[hpi_card->index], THIS_MODULE,
2805 sizeof(struct snd_card_asihpi),
2806 &card);
2807 if (err < 0) {
2808 /* if that fails, try the default index==next available */
2809 err =
2810 snd_card_create(index[dev], id[dev],
2811 THIS_MODULE,
2812 sizeof(struct snd_card_asihpi),
2813 &card);
2814 if (err < 0)
2815 return err;
2816 snd_printk(KERN_WARNING
2817 "**** WARNING **** Adapter index %d->ALSA index %d\n",
2818 hpi_card->index, card->number);
2821 snd_card_set_dev(card, &pci_dev->dev);
2823 asihpi = (struct snd_card_asihpi *) card->private_data;
2824 asihpi->card = card;
2825 asihpi->pci = pci_dev;
2826 asihpi->adapter_index = hpi_card->index;
2827 hpi_handle_error(hpi_adapter_get_info(
2828 asihpi->adapter_index,
2829 &asihpi->num_outstreams,
2830 &asihpi->num_instreams,
2831 &asihpi->version,
2832 &asihpi->serial_number, &asihpi->type));
2834 version = asihpi->version;
2835 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2836 "num_instreams=%d S/N=%d\n"
2837 "Hw Version %c%d DSP code version %03d\n",
2838 asihpi->type, asihpi->adapter_index,
2839 asihpi->num_outstreams,
2840 asihpi->num_instreams, asihpi->serial_number,
2841 ((version >> 3) & 0xf) + 'A',
2842 version & 0x7,
2843 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2845 pcm_substreams = asihpi->num_outstreams;
2846 if (pcm_substreams < asihpi->num_instreams)
2847 pcm_substreams = asihpi->num_instreams;
2849 err = hpi_adapter_get_property(asihpi->adapter_index,
2850 HPI_ADAPTER_PROPERTY_CAPS1,
2851 NULL, &asihpi->support_grouping);
2852 if (err)
2853 asihpi->support_grouping = 0;
2855 err = hpi_adapter_get_property(asihpi->adapter_index,
2856 HPI_ADAPTER_PROPERTY_CAPS2,
2857 &asihpi->support_mrx, NULL);
2858 if (err)
2859 asihpi->support_mrx = 0;
2861 err = hpi_adapter_get_property(asihpi->adapter_index,
2862 HPI_ADAPTER_PROPERTY_INTERVAL,
2863 NULL, &asihpi->update_interval_frames);
2864 if (err)
2865 asihpi->update_interval_frames = 512;
2867 if (!asihpi->can_dma)
2868 asihpi->update_interval_frames *= 2;
2870 hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
2871 0, &h_stream));
2873 err = hpi_instream_host_buffer_free(h_stream);
2874 asihpi->can_dma = (!err);
2876 hpi_handle_error(hpi_instream_close(h_stream));
2878 err = hpi_adapter_get_property(asihpi->adapter_index,
2879 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2880 &asihpi->in_max_chans, &asihpi->out_max_chans);
2881 if (err) {
2882 asihpi->in_max_chans = 2;
2883 asihpi->out_max_chans = 2;
2886 snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n",
2887 asihpi->can_dma,
2888 asihpi->support_grouping,
2889 asihpi->support_mrx
2892 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2893 if (err < 0) {
2894 snd_printk(KERN_ERR "pcm_new failed\n");
2895 goto __nodev;
2897 err = snd_card_asihpi_mixer_new(asihpi);
2898 if (err < 0) {
2899 snd_printk(KERN_ERR "mixer_new failed\n");
2900 goto __nodev;
2903 err = hpi_mixer_get_control(asihpi->h_mixer,
2904 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2905 HPI_CONTROL_SAMPLECLOCK, &h_control);
2907 if (!err)
2908 err = hpi_sample_clock_set_local_rate(
2909 h_control, adapter_fs);
2911 snd_asihpi_proc_init(asihpi);
2913 /* always create, can be enabled or disabled dynamically
2914 by enable_hwdep module param*/
2915 snd_asihpi_hpi_new(asihpi, 0, NULL);
2917 strcpy(card->driver, "ASIHPI");
2919 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2920 sprintf(card->longname, "%s %i",
2921 card->shortname, asihpi->adapter_index);
2922 err = snd_card_register(card);
2924 if (!err) {
2925 hpi_card->snd_card_asihpi = card;
2926 dev++;
2927 return 0;
2929 __nodev:
2930 snd_card_free(card);
2931 snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2932 return err;
2936 static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2938 struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
2940 snd_card_free(hpi_card->snd_card_asihpi);
2941 hpi_card->snd_card_asihpi = NULL;
2942 asihpi_adapter_remove(pci_dev);
2945 static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2946 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2947 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2948 (kernel_ulong_t)HPI_6205},
2949 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2950 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2951 (kernel_ulong_t)HPI_6000},
2952 {0,}
2954 MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2956 static struct pci_driver driver = {
2957 .name = KBUILD_MODNAME,
2958 .id_table = asihpi_pci_tbl,
2959 .probe = snd_asihpi_probe,
2960 .remove = __devexit_p(snd_asihpi_remove),
2961 #ifdef CONFIG_PM
2962 /* .suspend = snd_asihpi_suspend,
2963 .resume = snd_asihpi_resume, */
2964 #endif
2967 static int __init snd_asihpi_init(void)
2969 asihpi_init();
2970 return pci_register_driver(&driver);
2973 static void __exit snd_asihpi_exit(void)
2976 pci_unregister_driver(&driver);
2977 asihpi_exit();
2980 module_init(snd_asihpi_init)
2981 module_exit(snd_asihpi_exit)