Staging: rtl8192e: Remove dead code from rtl8192_tx
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / asihpi / asihpi.c
blobc80b0b863c5493dfa54561b201a5259a660fd2ee
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.
24 /* >0: print Hw params, timer vars. >1: print stream write/copy sizes */
25 #define REALLY_VERBOSE_LOGGING 0
27 #if REALLY_VERBOSE_LOGGING
28 #define VPRINTK1 snd_printd
29 #else
30 #define VPRINTK1(...)
31 #endif
33 #if REALLY_VERBOSE_LOGGING > 1
34 #define VPRINTK2 snd_printd
35 #else
36 #define VPRINTK2(...)
37 #endif
39 #ifndef ASI_STYLE_NAMES
40 /* not sure how ALSA style name should look */
41 #define ASI_STYLE_NAMES 1
42 #endif
44 #include "hpi_internal.h"
45 #include "hpimsginit.h"
46 #include "hpioctl.h"
48 #include <linux/pci.h>
49 #include <linux/init.h>
50 #include <linux/jiffies.h>
51 #include <linux/slab.h>
52 #include <linux/time.h>
53 #include <linux/wait.h>
54 #include <sound/core.h>
55 #include <sound/control.h>
56 #include <sound/pcm.h>
57 #include <sound/pcm_params.h>
58 #include <sound/info.h>
59 #include <sound/initval.h>
60 #include <sound/tlv.h>
61 #include <sound/hwdep.h>
64 MODULE_LICENSE("GPL");
65 MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
66 MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
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 int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
71 static int 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 static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */
105 /* defaults */
106 #define PERIODS_MIN 2
107 #define PERIOD_BYTES_MIN 2304
108 #define BUFFER_BYTES_MAX (512 * 1024)
110 /*#define TIMER_MILLISECONDS 20
111 #define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
114 #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
116 struct clk_source {
117 int source;
118 int index;
119 char *name;
122 struct clk_cache {
123 int count;
124 int has_local;
125 struct clk_source s[MAX_CLOCKSOURCES];
128 /* Per card data */
129 struct snd_card_asihpi {
130 struct snd_card *card;
131 struct pci_dev *pci;
132 u16 adapter_index;
133 u32 serial_number;
134 u16 type;
135 u16 version;
136 u16 num_outstreams;
137 u16 num_instreams;
139 u32 h_mixer;
140 struct clk_cache cc;
142 u16 support_mmap;
143 u16 support_grouping;
144 u16 support_mrx;
145 u16 update_interval_frames;
146 u16 in_max_chans;
147 u16 out_max_chans;
150 /* Per stream data */
151 struct snd_card_asihpi_pcm {
152 struct timer_list timer;
153 unsigned int respawn_timer;
154 unsigned int hpi_buffer_attached;
155 unsigned int pcm_size;
156 unsigned int pcm_count;
157 unsigned int bytes_per_sec;
158 unsigned int pcm_irq_pos; /* IRQ position */
159 unsigned int pcm_buf_pos; /* position in buffer */
160 struct snd_pcm_substream *substream;
161 u32 h_stream;
162 struct hpi_format format;
165 /* universal stream verbs work with out or in stream handles */
167 /* Functions to allow driver to give a buffer to HPI for busmastering */
169 static u16 hpi_stream_host_buffer_attach(
170 struct hpi_hsubsys *hS,
171 u32 h_stream, /* handle to outstream. */
172 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
173 u32 pci_address
176 struct hpi_message hm;
177 struct hpi_response hr;
178 unsigned int obj = hpi_handle_object(h_stream);
180 if (!h_stream)
181 return HPI_ERROR_INVALID_OBJ;
182 hpi_init_message_response(&hm, &hr, obj,
183 obj == HPI_OBJ_OSTREAM ?
184 HPI_OSTREAM_HOSTBUFFER_ALLOC :
185 HPI_ISTREAM_HOSTBUFFER_ALLOC);
187 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
188 &hm.obj_index);
190 hm.u.d.u.buffer.buffer_size = size_in_bytes;
191 hm.u.d.u.buffer.pci_address = pci_address;
192 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
193 hpi_send_recv(&hm, &hr);
194 return hr.error;
197 static u16 hpi_stream_host_buffer_detach(
198 struct hpi_hsubsys *hS,
199 u32 h_stream
202 struct hpi_message hm;
203 struct hpi_response hr;
204 unsigned int obj = hpi_handle_object(h_stream);
206 if (!h_stream)
207 return HPI_ERROR_INVALID_OBJ;
209 hpi_init_message_response(&hm, &hr, obj,
210 obj == HPI_OBJ_OSTREAM ?
211 HPI_OSTREAM_HOSTBUFFER_FREE :
212 HPI_ISTREAM_HOSTBUFFER_FREE);
214 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
215 &hm.obj_index);
216 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
217 hpi_send_recv(&hm, &hr);
218 return hr.error;
221 static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream)
223 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
224 return hpi_outstream_start(hS, h_stream);
225 else
226 return hpi_instream_start(hS, h_stream);
229 static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream)
231 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
232 return hpi_outstream_stop(hS, h_stream);
233 else
234 return hpi_instream_stop(hS, h_stream);
237 static inline u16 hpi_stream_get_info_ex(
238 struct hpi_hsubsys *hS,
239 u32 h_stream,
240 u16 *pw_state,
241 u32 *pbuffer_size,
242 u32 *pdata_in_buffer,
243 u32 *psample_count,
244 u32 *pauxiliary_data
247 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
248 return hpi_outstream_get_info_ex(hS, h_stream, pw_state,
249 pbuffer_size, pdata_in_buffer,
250 psample_count, pauxiliary_data);
251 else
252 return hpi_instream_get_info_ex(hS, h_stream, pw_state,
253 pbuffer_size, pdata_in_buffer,
254 psample_count, pauxiliary_data);
257 static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS,
258 u32 h_master,
259 u32 h_stream)
261 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
262 return hpi_outstream_group_add(hS, h_master, h_stream);
263 else
264 return hpi_instream_group_add(hS, h_master, h_stream);
267 static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS,
268 u32 h_stream)
270 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
271 return hpi_outstream_group_reset(hS, h_stream);
272 else
273 return hpi_instream_group_reset(hS, h_stream);
276 static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS,
277 u32 h_stream, u32 *mo, u32 *mi)
279 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
280 return hpi_outstream_group_get_map(hS, h_stream, mo, mi);
281 else
282 return hpi_instream_group_get_map(hS, h_stream, mo, mi);
285 static u16 handle_error(u16 err, int line, char *filename)
287 if (err)
288 printk(KERN_WARNING
289 "in file %s, line %d: HPI error %d\n",
290 filename, line, err);
291 return err;
294 #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
296 /***************************** GENERAL PCM ****************/
297 #if REALLY_VERBOSE_LOGGING
298 static void print_hwparams(struct snd_pcm_hw_params *p)
300 snd_printd("HWPARAMS \n");
301 snd_printd("samplerate %d \n", params_rate(p));
302 snd_printd("channels %d \n", params_channels(p));
303 snd_printd("format %d \n", params_format(p));
304 snd_printd("subformat %d \n", params_subformat(p));
305 snd_printd("buffer bytes %d \n", params_buffer_bytes(p));
306 snd_printd("period bytes %d \n", params_period_bytes(p));
307 snd_printd("access %d \n", params_access(p));
308 snd_printd("period_size %d \n", params_period_size(p));
309 snd_printd("periods %d \n", params_periods(p));
310 snd_printd("buffer_size %d \n", params_buffer_size(p));
312 #else
313 #define print_hwparams(x)
314 #endif
316 static snd_pcm_format_t hpi_to_alsa_formats[] = {
317 -1, /* INVALID */
318 SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
319 SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
320 -1, /* HPI_FORMAT_MPEG_L1 3 */
321 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
322 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
323 -1, /* HPI_FORMAT_DOLBY_AC2 6 */
324 -1, /* HPI_FORMAT_DOLBY_AC3 7 */
325 SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
326 -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
327 -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
328 SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
329 -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
330 -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
331 SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
332 #if 1
333 /* ALSA can't handle 3 byte sample size together with power-of-2
334 * constraint on buffer_bytes, so disable this format
337 #else
338 /* SNDRV_PCM_FORMAT_S24_3LE */ /* { HPI_FORMAT_PCM24_SIGNED 15 */
339 #endif
343 static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
344 u16 *hpi_format)
346 u16 format;
348 for (format = HPI_FORMAT_PCM8_UNSIGNED;
349 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
350 if (hpi_to_alsa_formats[format] == alsa_format) {
351 *hpi_format = format;
352 return 0;
356 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
357 alsa_format);
358 *hpi_format = 0;
359 return -EINVAL;
362 static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
363 struct snd_pcm_hardware *pcmhw)
365 u16 err;
366 u32 h_control;
367 u32 sample_rate;
368 int idx;
369 unsigned int rate_min = 200000;
370 unsigned int rate_max = 0;
371 unsigned int rates = 0;
373 if (asihpi->support_mrx) {
374 rates |= SNDRV_PCM_RATE_CONTINUOUS;
375 rates |= SNDRV_PCM_RATE_8000_96000;
376 rate_min = 8000;
377 rate_max = 100000;
378 } else {
379 /* on cards without SRC,
380 valid rates are determined by sampleclock */
381 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
382 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
383 HPI_CONTROL_SAMPLECLOCK, &h_control);
384 if (err) {
385 snd_printk(KERN_ERR
386 "no local sampleclock, err %d\n", err);
389 for (idx = 0; idx < 100; idx++) {
390 if (hpi_sample_clock_query_local_rate(ss,
391 h_control, idx, &sample_rate)) {
392 if (!idx)
393 snd_printk(KERN_ERR
394 "local rate query failed\n");
396 break;
399 rate_min = min(rate_min, sample_rate);
400 rate_max = max(rate_max, sample_rate);
402 switch (sample_rate) {
403 case 5512:
404 rates |= SNDRV_PCM_RATE_5512;
405 break;
406 case 8000:
407 rates |= SNDRV_PCM_RATE_8000;
408 break;
409 case 11025:
410 rates |= SNDRV_PCM_RATE_11025;
411 break;
412 case 16000:
413 rates |= SNDRV_PCM_RATE_16000;
414 break;
415 case 22050:
416 rates |= SNDRV_PCM_RATE_22050;
417 break;
418 case 32000:
419 rates |= SNDRV_PCM_RATE_32000;
420 break;
421 case 44100:
422 rates |= SNDRV_PCM_RATE_44100;
423 break;
424 case 48000:
425 rates |= SNDRV_PCM_RATE_48000;
426 break;
427 case 64000:
428 rates |= SNDRV_PCM_RATE_64000;
429 break;
430 case 88200:
431 rates |= SNDRV_PCM_RATE_88200;
432 break;
433 case 96000:
434 rates |= SNDRV_PCM_RATE_96000;
435 break;
436 case 176400:
437 rates |= SNDRV_PCM_RATE_176400;
438 break;
439 case 192000:
440 rates |= SNDRV_PCM_RATE_192000;
441 break;
442 default: /* some other rate */
443 rates |= SNDRV_PCM_RATE_KNOT;
448 /* printk(KERN_INFO "Supported rates %X %d %d\n",
449 rates, rate_min, rate_max); */
450 pcmhw->rates = rates;
451 pcmhw->rate_min = rate_min;
452 pcmhw->rate_max = rate_max;
455 static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
456 struct snd_pcm_hw_params *params)
458 struct snd_pcm_runtime *runtime = substream->runtime;
459 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
460 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
461 int err;
462 u16 format;
463 int width;
464 unsigned int bytes_per_sec;
466 print_hwparams(params);
467 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
468 if (err < 0)
469 return err;
470 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
471 if (err)
472 return err;
474 VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n",
475 format, params_channels(params),
476 params_rate(params));
478 hpi_handle_error(hpi_format_create(&dpcm->format,
479 params_channels(params),
480 format, params_rate(params), 0, 0));
482 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
483 if (hpi_instream_reset(ss, dpcm->h_stream) != 0)
484 return -EINVAL;
486 if (hpi_instream_set_format(ss,
487 dpcm->h_stream, &dpcm->format) != 0)
488 return -EINVAL;
491 dpcm->hpi_buffer_attached = 0;
492 if (card->support_mmap) {
494 err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream,
495 params_buffer_bytes(params), runtime->dma_addr);
496 if (err == 0) {
497 snd_printd(KERN_INFO
498 "stream_host_buffer_attach succeeded %u %lu\n",
499 params_buffer_bytes(params),
500 (unsigned long)runtime->dma_addr);
501 } else {
502 snd_printd(KERN_INFO
503 "stream_host_buffer_attach error %d\n",
504 err);
505 return -ENOMEM;
508 err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL,
509 &dpcm->hpi_buffer_attached,
510 NULL, NULL, NULL);
512 snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n",
513 dpcm->hpi_buffer_attached);
515 bytes_per_sec = params_rate(params) * params_channels(params);
516 width = snd_pcm_format_width(params_format(params));
517 bytes_per_sec *= width;
518 bytes_per_sec /= 8;
519 if (width < 0 || bytes_per_sec == 0)
520 return -EINVAL;
522 dpcm->bytes_per_sec = bytes_per_sec;
523 dpcm->pcm_size = params_buffer_bytes(params);
524 dpcm->pcm_count = params_period_bytes(params);
525 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n",
526 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec);
528 dpcm->pcm_irq_pos = 0;
529 dpcm->pcm_buf_pos = 0;
530 return 0;
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 = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec);
541 /* wait longer the first time, for samples to propagate */
542 expiry = max(expiry, 20);
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;
565 snd_printd("trigger %dstream %d\n",
566 substream->stream, substream->number);
567 switch (cmd) {
568 case SNDRV_PCM_TRIGGER_START:
569 snd_pcm_group_for_each_entry(s, substream) {
570 struct snd_card_asihpi_pcm *ds;
571 ds = s->runtime->private_data;
573 if (snd_pcm_substream_chip(s) != card)
574 continue;
576 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
577 (card->support_mmap)) {
578 /* How do I know how much valid data is present
579 * in buffer? Just guessing 2 periods, but if
580 * buffer is bigger it may contain even more
581 * data??
583 unsigned int preload = ds->pcm_count * 2;
584 VPRINTK2("preload %d\n", preload);
585 hpi_handle_error(hpi_outstream_write_buf(
586 ss, ds->h_stream,
587 &s->runtime->dma_area[0],
588 preload,
589 &ds->format));
592 if (card->support_grouping) {
593 VPRINTK1("\t_group %dstream %d\n", s->stream,
594 s->number);
595 e = hpi_stream_group_add(ss,
596 dpcm->h_stream,
597 ds->h_stream);
598 if (!e) {
599 snd_pcm_trigger_done(s, substream);
600 } else {
601 hpi_handle_error(e);
602 break;
604 } else
605 break;
607 snd_printd("start\n");
608 /* start the master stream */
609 snd_card_asihpi_pcm_timer_start(substream);
610 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
611 break;
613 case SNDRV_PCM_TRIGGER_STOP:
614 snd_card_asihpi_pcm_timer_stop(substream);
615 snd_pcm_group_for_each_entry(s, substream) {
616 if (snd_pcm_substream_chip(s) != card)
617 continue;
619 /*? workaround linked streams don't
620 transition to SETUP 20070706*/
621 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
623 if (card->support_grouping) {
624 VPRINTK1("\t_group %dstream %d\n", s->stream,
625 s->number);
626 snd_pcm_trigger_done(s, substream);
627 } else
628 break;
630 snd_printd("stop\n");
632 /* _prepare and _hwparams reset the stream */
633 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
634 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
635 hpi_handle_error(
636 hpi_outstream_reset(ss, dpcm->h_stream));
638 if (card->support_grouping)
639 hpi_handle_error(hpi_stream_group_reset(ss,
640 dpcm->h_stream));
641 break;
643 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
644 snd_printd("pause release\n");
645 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
646 snd_card_asihpi_pcm_timer_start(substream);
647 break;
648 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
649 snd_printd("pause\n");
650 snd_card_asihpi_pcm_timer_stop(substream);
651 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
652 break;
653 default:
654 snd_printd("\tINVALID\n");
655 return -EINVAL;
658 return 0;
661 static int
662 snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
664 struct snd_pcm_runtime *runtime = substream->runtime;
665 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
666 if (dpcm->hpi_buffer_attached)
667 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
669 snd_pcm_lib_free_pages(substream);
670 return 0;
673 static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
675 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
676 kfree(dpcm);
679 /*algorithm outline
680 Without linking degenerates to getting single stream pos etc
681 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
684 buf_pos=get_buf_pos(s);
685 for_each_linked_stream(s) {
686 buf_pos=get_buf_pos(s);
687 min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size)
688 new_data = min(new_data, calc_new_data(buf_pos,irq_pos)
690 timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
691 for_each_linked_stream(s) {
692 s->buf_pos = min_buf_pos;
693 if (new_data > pcm_count) {
694 if (mmap) {
695 irq_pos = (irq_pos + pcm_count) % pcm_size;
696 if (playback) {
697 write(pcm_count);
698 } else {
699 read(pcm_count);
702 snd_pcm_period_elapsed(s);
707 /** Minimum of 2 modulo values. Works correctly when the difference between
708 * the values is less than half the modulus
710 static inline unsigned int modulo_min(unsigned int a, unsigned int b,
711 unsigned long int modulus)
713 unsigned int result;
714 if (((a-b) % modulus) < (modulus/2))
715 result = b;
716 else
717 result = a;
719 return result;
722 /** Timer function, equivalent to interrupt service routine for cards
724 static void snd_card_asihpi_timer_function(unsigned long data)
726 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
727 struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream);
728 struct snd_pcm_runtime *runtime;
729 struct snd_pcm_substream *s;
730 unsigned int newdata = 0;
731 unsigned int buf_pos, min_buf_pos = 0;
732 unsigned int remdata, xfercount, next_jiffies;
733 int first = 1;
734 u16 state;
735 u32 buffer_size, data_avail, samples_played, aux;
737 /* find minimum newdata and buffer pos in group */
738 snd_pcm_group_for_each_entry(s, dpcm->substream) {
739 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
740 runtime = s->runtime;
742 if (snd_pcm_substream_chip(s) != card)
743 continue;
745 hpi_handle_error(hpi_stream_get_info_ex(ss,
746 ds->h_stream, &state,
747 &buffer_size, &data_avail,
748 &samples_played, &aux));
750 /* number of bytes in on-card buffer */
751 runtime->delay = aux;
753 if (state == HPI_STATE_DRAINED) {
754 snd_printd(KERN_WARNING "outstream %d drained\n",
755 s->number);
756 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
757 return;
760 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
761 buf_pos = frames_to_bytes(runtime, samples_played);
762 } else {
763 buf_pos = data_avail + ds->pcm_irq_pos;
766 if (first) {
767 /* can't statically init min when wrap is involved */
768 min_buf_pos = buf_pos;
769 newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size;
770 first = 0;
771 } else {
772 min_buf_pos =
773 modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L);
774 newdata = min(
775 (buf_pos - ds->pcm_irq_pos) % ds->pcm_size,
776 newdata);
779 VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n",
780 (unsigned long)frames_to_bytes(runtime,
781 runtime->status->hw_ptr),
782 (unsigned long)frames_to_bytes(runtime,
783 runtime->control->appl_ptr));
784 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X,"
785 " aux=x%04X space=x%04X\n", s->number,
786 state, ds->pcm_irq_pos, buf_pos, (int)data_avail,
787 (int)aux, buffer_size-data_avail);
790 remdata = newdata % dpcm->pcm_count;
791 xfercount = newdata - remdata; /* a multiple of pcm_count */
792 next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1;
793 next_jiffies = max(next_jiffies, 2U * HZ / 1000U);
794 dpcm->timer.expires = jiffies + next_jiffies;
795 VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n",
796 next_jiffies, min_buf_pos, newdata, xfercount);
798 snd_pcm_group_for_each_entry(s, dpcm->substream) {
799 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
800 ds->pcm_buf_pos = min_buf_pos;
802 if (xfercount) {
803 if (card->support_mmap) {
804 ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount;
805 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
806 VPRINTK2("write OS%d x%04x\n",
807 s->number,
808 ds->pcm_count);
809 hpi_handle_error(
810 hpi_outstream_write_buf(
811 ss, ds->h_stream,
812 &s->runtime->
813 dma_area[0],
814 xfercount,
815 &ds->format));
816 } else {
817 VPRINTK2("read IS%d x%04x\n",
818 s->number,
819 dpcm->pcm_count);
820 hpi_handle_error(
821 hpi_instream_read_buf(
822 ss, ds->h_stream,
823 NULL, xfercount));
825 } /* else R/W will be handled by read/write callbacks */
826 snd_pcm_period_elapsed(s);
830 if (dpcm->respawn_timer)
831 add_timer(&dpcm->timer);
834 /***************************** PLAYBACK OPS ****************/
835 static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
836 unsigned int cmd, void *arg)
838 /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */
839 return snd_pcm_lib_ioctl(substream, cmd, arg);
842 static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
843 substream)
845 struct snd_pcm_runtime *runtime = substream->runtime;
846 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
848 snd_printd(KERN_INFO "playback prepare %d\n", substream->number);
850 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
851 dpcm->pcm_irq_pos = 0;
852 dpcm->pcm_buf_pos = 0;
854 return 0;
857 static snd_pcm_uframes_t
858 snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
860 struct snd_pcm_runtime *runtime = substream->runtime;
861 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
862 snd_pcm_uframes_t ptr;
864 u32 samples_played;
865 u16 err;
867 if (!snd_pcm_stream_linked(substream)) {
868 /* NOTE, can use samples played for playback position here and
869 * in timer fn because it LAGS the actual read pointer, and is a
870 * better representation of actual playout position
872 err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
873 NULL, NULL,
874 &samples_played, NULL);
875 hpi_handle_error(err);
877 dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
879 /* else must return most conservative value found in timer func
880 * by looping over all streams
883 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
884 VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
885 return ptr;
888 static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
889 u32 h_stream,
890 struct snd_pcm_hardware *pcmhw)
892 struct hpi_format hpi_format;
893 u16 format;
894 u16 err;
895 u32 h_control;
896 u32 sample_rate = 48000;
898 /* on cards without SRC, must query at valid rate,
899 * maybe set by external sync
901 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
902 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
903 HPI_CONTROL_SAMPLECLOCK, &h_control);
905 if (!err)
906 err = hpi_sample_clock_get_sample_rate(ss, h_control,
907 &sample_rate);
909 for (format = HPI_FORMAT_PCM8_UNSIGNED;
910 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
911 err = hpi_format_create(&hpi_format,
912 2, format, sample_rate, 128000, 0);
913 if (!err)
914 err = hpi_outstream_query_format(ss, h_stream,
915 &hpi_format);
916 if (!err && (hpi_to_alsa_formats[format] != -1))
917 pcmhw->formats |=
918 (1ULL << hpi_to_alsa_formats[format]);
922 static struct snd_pcm_hardware snd_card_asihpi_playback = {
923 .channels_min = 1,
924 .channels_max = 2,
925 .buffer_bytes_max = BUFFER_BYTES_MAX,
926 .period_bytes_min = PERIOD_BYTES_MIN,
927 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
928 .periods_min = PERIODS_MIN,
929 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
930 .fifo_size = 0,
933 static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
935 struct snd_pcm_runtime *runtime = substream->runtime;
936 struct snd_card_asihpi_pcm *dpcm;
937 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
938 int err;
940 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
941 if (dpcm == NULL)
942 return -ENOMEM;
944 err =
945 hpi_outstream_open(ss, card->adapter_index,
946 substream->number, &dpcm->h_stream);
947 hpi_handle_error(err);
948 if (err)
949 kfree(dpcm);
950 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
951 return -EBUSY;
952 if (err)
953 return -EIO;
955 /*? also check ASI5000 samplerate source
956 If external, only support external rate.
957 If internal and other stream playing, cant switch
960 init_timer(&dpcm->timer);
961 dpcm->timer.data = (unsigned long) dpcm;
962 dpcm->timer.function = snd_card_asihpi_timer_function;
963 dpcm->substream = substream;
964 runtime->private_data = dpcm;
965 runtime->private_free = snd_card_asihpi_runtime_free;
967 snd_card_asihpi_playback.channels_max = card->out_max_chans;
968 /*?snd_card_asihpi_playback.period_bytes_min =
969 card->out_max_chans * 4096; */
971 snd_card_asihpi_playback_format(card, dpcm->h_stream,
972 &snd_card_asihpi_playback);
974 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
976 snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
977 SNDRV_PCM_INFO_DOUBLE |
978 SNDRV_PCM_INFO_BATCH |
979 SNDRV_PCM_INFO_BLOCK_TRANSFER |
980 SNDRV_PCM_INFO_PAUSE;
982 if (card->support_mmap)
983 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
984 SNDRV_PCM_INFO_MMAP_VALID;
986 if (card->support_grouping)
987 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
989 /* struct is copied, so can create initializer dynamically */
990 runtime->hw = snd_card_asihpi_playback;
992 if (card->support_mmap)
993 err = snd_pcm_hw_constraint_pow2(runtime, 0,
994 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
995 if (err < 0)
996 return err;
998 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
999 card->update_interval_frames);
1000 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1001 card->update_interval_frames * 4, UINT_MAX);
1003 snd_pcm_set_sync(substream);
1005 snd_printd(KERN_INFO "playback open\n");
1007 return 0;
1010 static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1012 struct snd_pcm_runtime *runtime = substream->runtime;
1013 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1015 hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream));
1016 snd_printd(KERN_INFO "playback close\n");
1018 return 0;
1021 static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1022 int channel,
1023 snd_pcm_uframes_t pos,
1024 void __user *src,
1025 snd_pcm_uframes_t count)
1027 struct snd_pcm_runtime *runtime = substream->runtime;
1028 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1029 unsigned int len;
1031 len = frames_to_bytes(runtime, count);
1033 if (copy_from_user(runtime->dma_area, src, len))
1034 return -EFAULT;
1036 VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n",
1037 substream->number, len);
1039 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1040 runtime->dma_area, len, &dpcm->format));
1042 return 0;
1045 static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1046 substream, int channel,
1047 snd_pcm_uframes_t pos,
1048 snd_pcm_uframes_t count)
1050 unsigned int len;
1051 struct snd_pcm_runtime *runtime = substream->runtime;
1052 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1054 len = frames_to_bytes(runtime, count);
1055 snd_printd(KERN_INFO "playback silence %u bytes\n", len);
1057 memset(runtime->dma_area, 0, len);
1058 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1059 runtime->dma_area, len, &dpcm->format));
1060 return 0;
1063 static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1064 .open = snd_card_asihpi_playback_open,
1065 .close = snd_card_asihpi_playback_close,
1066 .ioctl = snd_card_asihpi_playback_ioctl,
1067 .hw_params = snd_card_asihpi_pcm_hw_params,
1068 .hw_free = snd_card_asihpi_hw_free,
1069 .prepare = snd_card_asihpi_playback_prepare,
1070 .trigger = snd_card_asihpi_trigger,
1071 .pointer = snd_card_asihpi_playback_pointer,
1072 .copy = snd_card_asihpi_playback_copy,
1073 .silence = snd_card_asihpi_playback_silence,
1076 static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1077 .open = snd_card_asihpi_playback_open,
1078 .close = snd_card_asihpi_playback_close,
1079 .ioctl = snd_card_asihpi_playback_ioctl,
1080 .hw_params = snd_card_asihpi_pcm_hw_params,
1081 .hw_free = snd_card_asihpi_hw_free,
1082 .prepare = snd_card_asihpi_playback_prepare,
1083 .trigger = snd_card_asihpi_trigger,
1084 .pointer = snd_card_asihpi_playback_pointer,
1087 /***************************** CAPTURE OPS ****************/
1088 static snd_pcm_uframes_t
1089 snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1091 struct snd_pcm_runtime *runtime = substream->runtime;
1092 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1094 VPRINTK2("capture pointer %d=%d\n",
1095 substream->number, dpcm->pcm_buf_pos);
1096 /* NOTE Unlike playback can't use actual dwSamplesPlayed
1097 for the capture position, because those samples aren't yet in
1098 the local buffer available for reading.
1100 return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
1103 static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1104 unsigned int cmd, void *arg)
1106 return snd_pcm_lib_ioctl(substream, cmd, arg);
1109 static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1111 struct snd_pcm_runtime *runtime = substream->runtime;
1112 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1114 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream));
1115 dpcm->pcm_irq_pos = 0;
1116 dpcm->pcm_buf_pos = 0;
1118 snd_printd("capture prepare %d\n", substream->number);
1119 return 0;
1124 static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1125 u32 h_stream,
1126 struct snd_pcm_hardware *pcmhw)
1128 struct hpi_format hpi_format;
1129 u16 format;
1130 u16 err;
1131 u32 h_control;
1132 u32 sample_rate = 48000;
1134 /* on cards without SRC, must query at valid rate,
1135 maybe set by external sync */
1136 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
1137 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1138 HPI_CONTROL_SAMPLECLOCK, &h_control);
1140 if (!err)
1141 err = hpi_sample_clock_get_sample_rate(ss, h_control,
1142 &sample_rate);
1144 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1145 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1147 err = hpi_format_create(&hpi_format, 2, format,
1148 sample_rate, 128000, 0);
1149 if (!err)
1150 err = hpi_instream_query_format(ss, h_stream,
1151 &hpi_format);
1152 if (!err)
1153 pcmhw->formats |=
1154 (1ULL << hpi_to_alsa_formats[format]);
1159 static struct snd_pcm_hardware snd_card_asihpi_capture = {
1160 .channels_min = 1,
1161 .channels_max = 2,
1162 .buffer_bytes_max = BUFFER_BYTES_MAX,
1163 .period_bytes_min = PERIOD_BYTES_MIN,
1164 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1165 .periods_min = PERIODS_MIN,
1166 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1167 .fifo_size = 0,
1170 static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1172 struct snd_pcm_runtime *runtime = substream->runtime;
1173 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1174 struct snd_card_asihpi_pcm *dpcm;
1175 int err;
1177 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1178 if (dpcm == NULL)
1179 return -ENOMEM;
1181 snd_printd("hpi_instream_open adapter %d stream %d\n",
1182 card->adapter_index, substream->number);
1184 err = hpi_handle_error(
1185 hpi_instream_open(ss, card->adapter_index,
1186 substream->number, &dpcm->h_stream));
1187 if (err)
1188 kfree(dpcm);
1189 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1190 return -EBUSY;
1191 if (err)
1192 return -EIO;
1195 init_timer(&dpcm->timer);
1196 dpcm->timer.data = (unsigned long) dpcm;
1197 dpcm->timer.function = snd_card_asihpi_timer_function;
1198 dpcm->substream = substream;
1199 runtime->private_data = dpcm;
1200 runtime->private_free = snd_card_asihpi_runtime_free;
1202 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1203 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1204 &snd_card_asihpi_capture);
1205 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1206 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED;
1208 if (card->support_mmap)
1209 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1210 SNDRV_PCM_INFO_MMAP_VALID;
1212 runtime->hw = snd_card_asihpi_capture;
1214 if (card->support_mmap)
1215 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1216 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1217 if (err < 0)
1218 return err;
1220 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1221 card->update_interval_frames);
1222 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1223 card->update_interval_frames * 2, UINT_MAX);
1225 snd_pcm_set_sync(substream);
1227 return 0;
1230 static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1232 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1234 hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream));
1235 return 0;
1238 static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1239 int channel, snd_pcm_uframes_t pos,
1240 void __user *dst, snd_pcm_uframes_t count)
1242 struct snd_pcm_runtime *runtime = substream->runtime;
1243 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1244 u32 data_size;
1246 data_size = frames_to_bytes(runtime, count);
1248 VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size);
1249 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream,
1250 runtime->dma_area, data_size));
1252 /* Used by capture_pointer */
1253 dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1255 if (copy_to_user(dst, runtime->dma_area, data_size))
1256 return -EFAULT;
1258 return 0;
1261 static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1262 .open = snd_card_asihpi_capture_open,
1263 .close = snd_card_asihpi_capture_close,
1264 .ioctl = snd_card_asihpi_capture_ioctl,
1265 .hw_params = snd_card_asihpi_pcm_hw_params,
1266 .hw_free = snd_card_asihpi_hw_free,
1267 .prepare = snd_card_asihpi_capture_prepare,
1268 .trigger = snd_card_asihpi_trigger,
1269 .pointer = snd_card_asihpi_capture_pointer,
1272 static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1273 .open = snd_card_asihpi_capture_open,
1274 .close = snd_card_asihpi_capture_close,
1275 .ioctl = snd_card_asihpi_capture_ioctl,
1276 .hw_params = snd_card_asihpi_pcm_hw_params,
1277 .hw_free = snd_card_asihpi_hw_free,
1278 .prepare = snd_card_asihpi_capture_prepare,
1279 .trigger = snd_card_asihpi_trigger,
1280 .pointer = snd_card_asihpi_capture_pointer,
1281 .copy = snd_card_asihpi_capture_copy
1284 static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1285 int device, int substreams)
1287 struct snd_pcm *pcm;
1288 int err;
1290 err = snd_pcm_new(asihpi->card, "asihpi PCM", device,
1291 asihpi->num_outstreams, asihpi->num_instreams,
1292 &pcm);
1293 if (err < 0)
1294 return err;
1295 /* pointer to ops struct is stored, dont change ops afterwards! */
1296 if (asihpi->support_mmap) {
1297 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1298 &snd_card_asihpi_playback_mmap_ops);
1299 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1300 &snd_card_asihpi_capture_mmap_ops);
1301 } else {
1302 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1303 &snd_card_asihpi_playback_ops);
1304 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1305 &snd_card_asihpi_capture_ops);
1308 pcm->private_data = asihpi;
1309 pcm->info_flags = 0;
1310 strcpy(pcm->name, "asihpi PCM");
1312 /*? do we want to emulate MMAP for non-BBM cards?
1313 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
1314 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1315 snd_dma_pci_data(asihpi->pci),
1316 64*1024, BUFFER_BYTES_MAX);
1318 return 0;
1321 /***************************** MIXER CONTROLS ****************/
1322 struct hpi_control {
1323 u32 h_control;
1324 u16 control_type;
1325 u16 src_node_type;
1326 u16 src_node_index;
1327 u16 dst_node_type;
1328 u16 dst_node_index;
1329 u16 band;
1330 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1333 static char *asihpi_tuner_band_names[] =
1335 "invalid",
1336 "AM",
1337 "FM mono",
1338 "TV NTSC-M",
1339 "FM stereo",
1340 "AUX",
1341 "TV PAL BG",
1342 "TV PAL I",
1343 "TV PAL DK",
1344 "TV SECAM",
1347 compile_time_assert(
1348 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1349 (HPI_TUNER_BAND_LAST+1)),
1350 assert_tuner_band_names_size);
1352 #if ASI_STYLE_NAMES
1353 static char *asihpi_src_names[] =
1355 "no source",
1356 "outstream",
1357 "line_in",
1358 "aes_in",
1359 "tuner",
1360 "RF",
1361 "clock",
1362 "bitstr",
1363 "mic",
1364 "cobranet",
1365 "analog_in",
1366 "adapter",
1368 #else
1369 static char *asihpi_src_names[] =
1371 "no source",
1372 "PCM playback",
1373 "line in",
1374 "digital in",
1375 "tuner",
1376 "RF",
1377 "clock",
1378 "bitstream",
1379 "mic",
1380 "cobranet in",
1381 "analog in",
1382 "adapter",
1384 #endif
1386 compile_time_assert(
1387 (ARRAY_SIZE(asihpi_src_names) ==
1388 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1389 assert_src_names_size);
1391 #if ASI_STYLE_NAMES
1392 static char *asihpi_dst_names[] =
1394 "no destination",
1395 "instream",
1396 "line_out",
1397 "aes_out",
1398 "RF",
1399 "speaker" ,
1400 "cobranet",
1401 "analog_out",
1403 #else
1404 static char *asihpi_dst_names[] =
1406 "no destination",
1407 "PCM capture",
1408 "line out",
1409 "digital out",
1410 "RF",
1411 "speaker",
1412 "cobranet out",
1413 "analog out"
1415 #endif
1417 compile_time_assert(
1418 (ARRAY_SIZE(asihpi_dst_names) ==
1419 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1420 assert_dst_names_size);
1422 static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1423 struct snd_card_asihpi *asihpi)
1425 int err;
1427 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1428 if (err < 0)
1429 return err;
1430 else if (mixer_dump)
1431 snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1433 return 0;
1436 /* Convert HPI control name and location into ALSA control name */
1437 static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1438 struct hpi_control *hpi_ctl,
1439 char *name)
1441 memset(snd_control, 0, sizeof(*snd_control));
1442 snd_control->name = hpi_ctl->name;
1443 snd_control->private_value = hpi_ctl->h_control;
1444 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1445 snd_control->index = 0;
1447 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1448 sprintf(hpi_ctl->name, "%s%d to %s%d %s",
1449 asihpi_src_names[hpi_ctl->src_node_type],
1450 hpi_ctl->src_node_index,
1451 asihpi_dst_names[hpi_ctl->dst_node_type],
1452 hpi_ctl->dst_node_index,
1453 name);
1454 else if (hpi_ctl->dst_node_type) {
1455 sprintf(hpi_ctl->name, "%s%d %s",
1456 asihpi_dst_names[hpi_ctl->dst_node_type],
1457 hpi_ctl->dst_node_index,
1458 name);
1459 } else {
1460 sprintf(hpi_ctl->name, "%s%d %s",
1461 asihpi_src_names[hpi_ctl->src_node_type],
1462 hpi_ctl->src_node_index,
1463 name);
1467 /*------------------------------------------------------------
1468 Volume controls
1469 ------------------------------------------------------------*/
1470 #define VOL_STEP_mB 1
1471 static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1472 struct snd_ctl_elem_info *uinfo)
1474 u32 h_control = kcontrol->private_value;
1475 u16 err;
1476 /* native gains are in millibels */
1477 short min_gain_mB;
1478 short max_gain_mB;
1479 short step_gain_mB;
1481 err = hpi_volume_query_range(ss, h_control,
1482 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1483 if (err) {
1484 max_gain_mB = 0;
1485 min_gain_mB = -10000;
1486 step_gain_mB = VOL_STEP_mB;
1489 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1490 uinfo->count = 2;
1491 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1492 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1493 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1494 return 0;
1497 static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1498 struct snd_ctl_elem_value *ucontrol)
1500 u32 h_control = kcontrol->private_value;
1501 short an_gain_mB[HPI_MAX_CHANNELS];
1503 hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB));
1504 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1505 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1507 return 0;
1510 static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1511 struct snd_ctl_elem_value *ucontrol)
1513 int change;
1514 u32 h_control = kcontrol->private_value;
1515 short an_gain_mB[HPI_MAX_CHANNELS];
1517 an_gain_mB[0] =
1518 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1519 an_gain_mB[1] =
1520 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1521 /* change = asihpi->mixer_volume[addr][0] != left ||
1522 asihpi->mixer_volume[addr][1] != right;
1524 change = 1;
1525 hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB));
1526 return change;
1529 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1531 static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1532 struct hpi_control *hpi_ctl)
1534 struct snd_card *card = asihpi->card;
1535 struct snd_kcontrol_new snd_control;
1537 asihpi_ctl_init(&snd_control, hpi_ctl, "volume");
1538 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1539 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1540 snd_control.info = snd_asihpi_volume_info;
1541 snd_control.get = snd_asihpi_volume_get;
1542 snd_control.put = snd_asihpi_volume_put;
1543 snd_control.tlv.p = db_scale_100;
1545 return ctl_add(card, &snd_control, asihpi);
1548 /*------------------------------------------------------------
1549 Level controls
1550 ------------------------------------------------------------*/
1551 static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1552 struct snd_ctl_elem_info *uinfo)
1554 u32 h_control = kcontrol->private_value;
1555 u16 err;
1556 short min_gain_mB;
1557 short max_gain_mB;
1558 short step_gain_mB;
1560 err =
1561 hpi_level_query_range(ss, h_control, &min_gain_mB,
1562 &max_gain_mB, &step_gain_mB);
1563 if (err) {
1564 max_gain_mB = 2400;
1565 min_gain_mB = -1000;
1566 step_gain_mB = 100;
1569 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1570 uinfo->count = 2;
1571 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1572 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1573 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1574 return 0;
1577 static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1578 struct snd_ctl_elem_value *ucontrol)
1580 u32 h_control = kcontrol->private_value;
1581 short an_gain_mB[HPI_MAX_CHANNELS];
1583 hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB));
1584 ucontrol->value.integer.value[0] =
1585 an_gain_mB[0] / HPI_UNITS_PER_dB;
1586 ucontrol->value.integer.value[1] =
1587 an_gain_mB[1] / HPI_UNITS_PER_dB;
1589 return 0;
1592 static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1593 struct snd_ctl_elem_value *ucontrol)
1595 int change;
1596 u32 h_control = kcontrol->private_value;
1597 short an_gain_mB[HPI_MAX_CHANNELS];
1599 an_gain_mB[0] =
1600 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1601 an_gain_mB[1] =
1602 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1603 /* change = asihpi->mixer_level[addr][0] != left ||
1604 asihpi->mixer_level[addr][1] != right;
1606 change = 1;
1607 hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB));
1608 return change;
1611 static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1613 static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1614 struct hpi_control *hpi_ctl)
1616 struct snd_card *card = asihpi->card;
1617 struct snd_kcontrol_new snd_control;
1619 /* can't use 'volume' cos some nodes have volume as well */
1620 asihpi_ctl_init(&snd_control, hpi_ctl, "level");
1621 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1622 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1623 snd_control.info = snd_asihpi_level_info;
1624 snd_control.get = snd_asihpi_level_get;
1625 snd_control.put = snd_asihpi_level_put;
1626 snd_control.tlv.p = db_scale_level;
1628 return ctl_add(card, &snd_control, asihpi);
1631 /*------------------------------------------------------------
1632 AESEBU controls
1633 ------------------------------------------------------------*/
1635 /* AESEBU format */
1636 static char *asihpi_aesebu_format_names[] =
1638 "N/A",
1639 "S/PDIF",
1640 "AES/EBU",
1643 static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1644 struct snd_ctl_elem_info *uinfo)
1646 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1647 uinfo->count = 1;
1648 uinfo->value.enumerated.items = 3;
1650 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1651 uinfo->value.enumerated.item =
1652 uinfo->value.enumerated.items - 1;
1654 strcpy(uinfo->value.enumerated.name,
1655 asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1657 return 0;
1660 static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1661 struct snd_ctl_elem_value *ucontrol,
1662 u16 (*func)(const struct hpi_hsubsys *, u32, u16 *))
1664 u32 h_control = kcontrol->private_value;
1665 u16 source, err;
1667 err = func(ss, h_control, &source);
1669 /* default to N/A */
1670 ucontrol->value.enumerated.item[0] = 0;
1671 /* return success but set the control to N/A */
1672 if (err)
1673 return 0;
1674 if (source == HPI_AESEBU_FORMAT_SPDIF)
1675 ucontrol->value.enumerated.item[0] = 1;
1676 if (source == HPI_AESEBU_FORMAT_AESEBU)
1677 ucontrol->value.enumerated.item[0] = 2;
1679 return 0;
1682 static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1683 struct snd_ctl_elem_value *ucontrol,
1684 u16 (*func)(const struct hpi_hsubsys *, u32, u16))
1686 u32 h_control = kcontrol->private_value;
1688 /* default to S/PDIF */
1689 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1691 if (ucontrol->value.enumerated.item[0] == 1)
1692 source = HPI_AESEBU_FORMAT_SPDIF;
1693 if (ucontrol->value.enumerated.item[0] == 2)
1694 source = HPI_AESEBU_FORMAT_AESEBU;
1696 if (func(ss, h_control, source) != 0)
1697 return -EINVAL;
1699 return 1;
1702 static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1703 struct snd_ctl_elem_value *ucontrol) {
1704 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1705 HPI_AESEBU__receiver_get_format);
1708 static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1709 struct snd_ctl_elem_value *ucontrol) {
1710 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1711 HPI_AESEBU__receiver_set_format);
1714 static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1715 struct snd_ctl_elem_info *uinfo)
1717 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1718 uinfo->count = 1;
1720 uinfo->value.integer.min = 0;
1721 uinfo->value.integer.max = 0X1F;
1722 uinfo->value.integer.step = 1;
1724 return 0;
1727 static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1728 struct snd_ctl_elem_value *ucontrol) {
1730 u32 h_control = kcontrol->private_value;
1731 u16 status;
1733 hpi_handle_error(HPI_AESEBU__receiver_get_error_status(
1734 ss, h_control, &status));
1735 ucontrol->value.integer.value[0] = status;
1736 return 0;
1739 static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1740 struct hpi_control *hpi_ctl)
1742 struct snd_card *card = asihpi->card;
1743 struct snd_kcontrol_new snd_control;
1745 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1746 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1747 snd_control.info = snd_asihpi_aesebu_format_info;
1748 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1749 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1752 if (ctl_add(card, &snd_control, asihpi) < 0)
1753 return -EINVAL;
1755 asihpi_ctl_init(&snd_control, hpi_ctl, "status");
1756 snd_control.access =
1757 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1758 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1759 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1761 return ctl_add(card, &snd_control, asihpi);
1764 static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1765 struct snd_ctl_elem_value *ucontrol) {
1766 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1767 HPI_AESEBU__transmitter_get_format);
1770 static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1771 struct snd_ctl_elem_value *ucontrol) {
1772 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1773 HPI_AESEBU__transmitter_set_format);
1777 static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1778 struct hpi_control *hpi_ctl)
1780 struct snd_card *card = asihpi->card;
1781 struct snd_kcontrol_new snd_control;
1783 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1784 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1785 snd_control.info = snd_asihpi_aesebu_format_info;
1786 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1787 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1789 return ctl_add(card, &snd_control, asihpi);
1792 /*------------------------------------------------------------
1793 Tuner controls
1794 ------------------------------------------------------------*/
1796 /* Gain */
1798 static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1799 struct snd_ctl_elem_info *uinfo)
1801 u32 h_control = kcontrol->private_value;
1802 u16 err;
1803 short idx;
1804 u16 gain_range[3];
1806 for (idx = 0; idx < 3; idx++) {
1807 err = hpi_tuner_query_gain(ss, h_control,
1808 idx, &gain_range[idx]);
1809 if (err != 0)
1810 return err;
1813 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1814 uinfo->count = 1;
1815 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1816 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1817 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1818 return 0;
1821 static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1822 struct snd_ctl_elem_value *ucontrol)
1825 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1827 u32 h_control = kcontrol->private_value;
1828 short gain;
1830 hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain));
1831 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1833 return 0;
1836 static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1837 struct snd_ctl_elem_value *ucontrol)
1840 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1842 u32 h_control = kcontrol->private_value;
1843 short gain;
1845 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1846 hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain));
1848 return 1;
1851 /* Band */
1853 static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1854 u16 *band_list, u32 len) {
1855 u32 h_control = kcontrol->private_value;
1856 u16 err = 0;
1857 u32 i;
1859 for (i = 0; i < len; i++) {
1860 err = hpi_tuner_query_band(ss,
1861 h_control, i, &band_list[i]);
1862 if (err != 0)
1863 break;
1866 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1867 return -EIO;
1869 return i;
1872 static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1873 struct snd_ctl_elem_info *uinfo)
1875 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1876 int num_bands = 0;
1878 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1879 HPI_TUNER_BAND_LAST);
1881 if (num_bands < 0)
1882 return num_bands;
1884 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1885 uinfo->count = 1;
1886 uinfo->value.enumerated.items = num_bands;
1888 if (num_bands > 0) {
1889 if (uinfo->value.enumerated.item >=
1890 uinfo->value.enumerated.items)
1891 uinfo->value.enumerated.item =
1892 uinfo->value.enumerated.items - 1;
1894 strcpy(uinfo->value.enumerated.name,
1895 asihpi_tuner_band_names[
1896 tuner_bands[uinfo->value.enumerated.item]]);
1899 return 0;
1902 static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1903 struct snd_ctl_elem_value *ucontrol)
1905 u32 h_control = kcontrol->private_value;
1907 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1909 u16 band, idx;
1910 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1911 u32 num_bands = 0;
1913 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1914 HPI_TUNER_BAND_LAST);
1916 hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band));
1918 ucontrol->value.enumerated.item[0] = -1;
1919 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1920 if (tuner_bands[idx] == band) {
1921 ucontrol->value.enumerated.item[0] = idx;
1922 break;
1925 return 0;
1928 static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1929 struct snd_ctl_elem_value *ucontrol)
1932 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1934 u32 h_control = kcontrol->private_value;
1935 u16 band;
1936 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1937 u32 num_bands = 0;
1939 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1940 HPI_TUNER_BAND_LAST);
1942 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1943 hpi_handle_error(hpi_tuner_set_band(ss, h_control, band));
1945 return 1;
1948 /* Freq */
1950 static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1951 struct snd_ctl_elem_info *uinfo)
1953 u32 h_control = kcontrol->private_value;
1954 u16 err;
1955 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1956 u16 num_bands = 0, band_iter, idx;
1957 u32 freq_range[3], temp_freq_range[3];
1959 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1960 HPI_TUNER_BAND_LAST);
1962 freq_range[0] = INT_MAX;
1963 freq_range[1] = 0;
1964 freq_range[2] = INT_MAX;
1966 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1967 for (idx = 0; idx < 3; idx++) {
1968 err = hpi_tuner_query_frequency(ss, h_control,
1969 idx, tuner_bands[band_iter],
1970 &temp_freq_range[idx]);
1971 if (err != 0)
1972 return err;
1975 /* skip band with bogus stepping */
1976 if (temp_freq_range[2] <= 0)
1977 continue;
1979 if (temp_freq_range[0] < freq_range[0])
1980 freq_range[0] = temp_freq_range[0];
1981 if (temp_freq_range[1] > freq_range[1])
1982 freq_range[1] = temp_freq_range[1];
1983 if (temp_freq_range[2] < freq_range[2])
1984 freq_range[2] = temp_freq_range[2];
1987 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1988 uinfo->count = 1;
1989 uinfo->value.integer.min = ((int)freq_range[0]);
1990 uinfo->value.integer.max = ((int)freq_range[1]);
1991 uinfo->value.integer.step = ((int)freq_range[2]);
1992 return 0;
1995 static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1996 struct snd_ctl_elem_value *ucontrol)
1998 u32 h_control = kcontrol->private_value;
1999 u32 freq;
2001 hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq));
2002 ucontrol->value.integer.value[0] = freq;
2004 return 0;
2007 static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2008 struct snd_ctl_elem_value *ucontrol)
2010 u32 h_control = kcontrol->private_value;
2011 u32 freq;
2013 freq = ucontrol->value.integer.value[0];
2014 hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq));
2016 return 1;
2019 /* Tuner control group initializer */
2020 static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2021 struct hpi_control *hpi_ctl)
2023 struct snd_card *card = asihpi->card;
2024 struct snd_kcontrol_new snd_control;
2026 snd_control.private_value = hpi_ctl->h_control;
2027 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2029 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) {
2030 asihpi_ctl_init(&snd_control, hpi_ctl, "gain");
2031 snd_control.info = snd_asihpi_tuner_gain_info;
2032 snd_control.get = snd_asihpi_tuner_gain_get;
2033 snd_control.put = snd_asihpi_tuner_gain_put;
2035 if (ctl_add(card, &snd_control, asihpi) < 0)
2036 return -EINVAL;
2039 asihpi_ctl_init(&snd_control, hpi_ctl, "band");
2040 snd_control.info = snd_asihpi_tuner_band_info;
2041 snd_control.get = snd_asihpi_tuner_band_get;
2042 snd_control.put = snd_asihpi_tuner_band_put;
2044 if (ctl_add(card, &snd_control, asihpi) < 0)
2045 return -EINVAL;
2047 asihpi_ctl_init(&snd_control, hpi_ctl, "freq");
2048 snd_control.info = snd_asihpi_tuner_freq_info;
2049 snd_control.get = snd_asihpi_tuner_freq_get;
2050 snd_control.put = snd_asihpi_tuner_freq_put;
2052 return ctl_add(card, &snd_control, asihpi);
2055 /*------------------------------------------------------------
2056 Meter controls
2057 ------------------------------------------------------------*/
2058 static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2059 struct snd_ctl_elem_info *uinfo)
2061 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2062 uinfo->count = HPI_MAX_CHANNELS;
2063 uinfo->value.integer.min = 0;
2064 uinfo->value.integer.max = 0x7FFFFFFF;
2065 return 0;
2068 /* linear values for 10dB steps */
2069 static int log2lin[] = {
2070 0x7FFFFFFF, /* 0dB */
2071 679093956,
2072 214748365,
2073 67909396,
2074 21474837,
2075 6790940,
2076 2147484, /* -60dB */
2077 679094,
2078 214748, /* -80 */
2079 67909,
2080 21475, /* -100 */
2081 6791,
2082 2147,
2083 679,
2084 214,
2091 static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2092 struct snd_ctl_elem_value *ucontrol)
2094 u32 h_control = kcontrol->private_value;
2095 short an_gain_mB[HPI_MAX_CHANNELS], i;
2096 u16 err;
2098 err = hpi_meter_get_peak(ss, h_control, an_gain_mB);
2100 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2101 if (err) {
2102 ucontrol->value.integer.value[i] = 0;
2103 } else if (an_gain_mB[i] >= 0) {
2104 ucontrol->value.integer.value[i] =
2105 an_gain_mB[i] << 16;
2106 } else {
2107 /* -ve is log value in millibels < -60dB,
2108 * convert to (roughly!) linear,
2110 ucontrol->value.integer.value[i] =
2111 log2lin[an_gain_mB[i] / -1000];
2114 return 0;
2117 static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2118 struct hpi_control *hpi_ctl, int subidx)
2120 struct snd_card *card = asihpi->card;
2121 struct snd_kcontrol_new snd_control;
2123 asihpi_ctl_init(&snd_control, hpi_ctl, "meter");
2124 snd_control.access =
2125 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2126 snd_control.info = snd_asihpi_meter_info;
2127 snd_control.get = snd_asihpi_meter_get;
2129 snd_control.index = subidx;
2131 return ctl_add(card, &snd_control, asihpi);
2134 /*------------------------------------------------------------
2135 Multiplexer controls
2136 ------------------------------------------------------------*/
2137 static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2139 u32 h_control = snd_control->private_value;
2140 struct hpi_control hpi_ctl;
2141 int s, err;
2142 for (s = 0; s < 32; s++) {
2143 err = hpi_multiplexer_query_source(ss, h_control, s,
2144 &hpi_ctl.
2145 src_node_type,
2146 &hpi_ctl.
2147 src_node_index);
2148 if (err)
2149 break;
2151 return s;
2154 static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2155 struct snd_ctl_elem_info *uinfo)
2157 int err;
2158 u16 src_node_type, src_node_index;
2159 u32 h_control = kcontrol->private_value;
2161 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2162 uinfo->count = 1;
2163 uinfo->value.enumerated.items =
2164 snd_card_asihpi_mux_count_sources(kcontrol);
2166 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2167 uinfo->value.enumerated.item =
2168 uinfo->value.enumerated.items - 1;
2170 err =
2171 hpi_multiplexer_query_source(ss, h_control,
2172 uinfo->value.enumerated.item,
2173 &src_node_type, &src_node_index);
2175 sprintf(uinfo->value.enumerated.name, "%s %d",
2176 asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
2177 src_node_index);
2178 return 0;
2181 static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2182 struct snd_ctl_elem_value *ucontrol)
2184 u32 h_control = kcontrol->private_value;
2185 u16 source_type, source_index;
2186 u16 src_node_type, src_node_index;
2187 int s;
2189 hpi_handle_error(hpi_multiplexer_get_source(ss, h_control,
2190 &source_type, &source_index));
2191 /* Should cache this search result! */
2192 for (s = 0; s < 256; s++) {
2193 if (hpi_multiplexer_query_source(ss, h_control, s,
2194 &src_node_type, &src_node_index))
2195 break;
2197 if ((source_type == src_node_type)
2198 && (source_index == src_node_index)) {
2199 ucontrol->value.enumerated.item[0] = s;
2200 return 0;
2203 snd_printd(KERN_WARNING
2204 "control %x failed to match mux source %hu %hu\n",
2205 h_control, source_type, source_index);
2206 ucontrol->value.enumerated.item[0] = 0;
2207 return 0;
2210 static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2211 struct snd_ctl_elem_value *ucontrol)
2213 int change;
2214 u32 h_control = kcontrol->private_value;
2215 u16 source_type, source_index;
2216 u16 e;
2218 change = 1;
2220 e = hpi_multiplexer_query_source(ss, h_control,
2221 ucontrol->value.enumerated.item[0],
2222 &source_type, &source_index);
2223 if (!e)
2224 hpi_handle_error(
2225 hpi_multiplexer_set_source(ss, h_control,
2226 source_type, source_index));
2227 return change;
2231 static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2232 struct hpi_control *hpi_ctl)
2234 struct snd_card *card = asihpi->card;
2235 struct snd_kcontrol_new snd_control;
2237 #if ASI_STYLE_NAMES
2238 asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2239 #else
2240 asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2241 #endif
2242 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2243 snd_control.info = snd_asihpi_mux_info;
2244 snd_control.get = snd_asihpi_mux_get;
2245 snd_control.put = snd_asihpi_mux_put;
2247 return ctl_add(card, &snd_control, asihpi);
2251 /*------------------------------------------------------------
2252 Channel mode controls
2253 ------------------------------------------------------------*/
2254 static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2255 struct snd_ctl_elem_info *uinfo)
2257 static char *mode_names[HPI_CHANNEL_MODE_LAST] = {
2258 "normal", "swap",
2259 "from_left", "from_right",
2260 "to_left", "to_right"
2263 u32 h_control = kcontrol->private_value;
2264 u16 mode;
2265 int i;
2267 /* HPI channel mode values can be from 1 to 6
2268 Some adapters only support a contiguous subset
2270 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2271 if (hpi_channel_mode_query_mode(
2272 ss, h_control, i, &mode))
2273 break;
2275 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2276 uinfo->count = 1;
2277 uinfo->value.enumerated.items = i;
2279 if (uinfo->value.enumerated.item >= i)
2280 uinfo->value.enumerated.item = i - 1;
2282 strcpy(uinfo->value.enumerated.name,
2283 mode_names[uinfo->value.enumerated.item]);
2285 return 0;
2288 static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2289 struct snd_ctl_elem_value *ucontrol)
2291 u32 h_control = kcontrol->private_value;
2292 u16 mode;
2294 if (hpi_channel_mode_get(ss, h_control, &mode))
2295 mode = 1;
2297 ucontrol->value.enumerated.item[0] = mode - 1;
2299 return 0;
2302 static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2303 struct snd_ctl_elem_value *ucontrol)
2305 int change;
2306 u32 h_control = kcontrol->private_value;
2308 change = 1;
2310 hpi_handle_error(hpi_channel_mode_set(ss, h_control,
2311 ucontrol->value.enumerated.item[0] + 1));
2312 return change;
2316 static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2317 struct hpi_control *hpi_ctl)
2319 struct snd_card *card = asihpi->card;
2320 struct snd_kcontrol_new snd_control;
2322 asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode");
2323 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2324 snd_control.info = snd_asihpi_cmode_info;
2325 snd_control.get = snd_asihpi_cmode_get;
2326 snd_control.put = snd_asihpi_cmode_put;
2328 return ctl_add(card, &snd_control, asihpi);
2331 /*------------------------------------------------------------
2332 Sampleclock source controls
2333 ------------------------------------------------------------*/
2335 static char *sampleclock_sources[MAX_CLOCKSOURCES] =
2336 { "N/A", "local PLL", "AES/EBU sync", "word external", "word header",
2337 "SMPTE", "AES/EBU in1", "auto", "network", "invalid",
2338 "prev module",
2339 "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5",
2340 "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"};
2344 static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2345 struct snd_ctl_elem_info *uinfo)
2347 struct snd_card_asihpi *asihpi =
2348 (struct snd_card_asihpi *)(kcontrol->private_data);
2349 struct clk_cache *clkcache = &asihpi->cc;
2350 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2351 uinfo->count = 1;
2352 uinfo->value.enumerated.items = clkcache->count;
2354 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2355 uinfo->value.enumerated.item =
2356 uinfo->value.enumerated.items - 1;
2358 strcpy(uinfo->value.enumerated.name,
2359 clkcache->s[uinfo->value.enumerated.item].name);
2360 return 0;
2363 static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2364 struct snd_ctl_elem_value *ucontrol)
2366 struct snd_card_asihpi *asihpi =
2367 (struct snd_card_asihpi *)(kcontrol->private_data);
2368 struct clk_cache *clkcache = &asihpi->cc;
2369 u32 h_control = kcontrol->private_value;
2370 u16 source, srcindex = 0;
2371 int i;
2373 ucontrol->value.enumerated.item[0] = 0;
2374 if (hpi_sample_clock_get_source(ss, h_control, &source))
2375 source = 0;
2377 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2378 if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex))
2379 srcindex = 0;
2381 for (i = 0; i < clkcache->count; i++)
2382 if ((clkcache->s[i].source == source) &&
2383 (clkcache->s[i].index == srcindex))
2384 break;
2386 ucontrol->value.enumerated.item[0] = i;
2388 return 0;
2391 static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2392 struct snd_ctl_elem_value *ucontrol)
2394 struct snd_card_asihpi *asihpi =
2395 (struct snd_card_asihpi *)(kcontrol->private_data);
2396 struct clk_cache *clkcache = &asihpi->cc;
2397 int change, item;
2398 u32 h_control = kcontrol->private_value;
2400 change = 1;
2401 item = ucontrol->value.enumerated.item[0];
2402 if (item >= clkcache->count)
2403 item = clkcache->count-1;
2405 hpi_handle_error(hpi_sample_clock_set_source(ss,
2406 h_control, clkcache->s[item].source));
2408 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2409 hpi_handle_error(hpi_sample_clock_set_source_index(ss,
2410 h_control, clkcache->s[item].index));
2411 return change;
2414 /*------------------------------------------------------------
2415 Clkrate controls
2416 ------------------------------------------------------------*/
2417 /* Need to change this to enumerated control with list of rates */
2418 static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2419 struct snd_ctl_elem_info *uinfo)
2421 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2422 uinfo->count = 1;
2423 uinfo->value.integer.min = 8000;
2424 uinfo->value.integer.max = 192000;
2425 uinfo->value.integer.step = 100;
2427 return 0;
2430 static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2431 struct snd_ctl_elem_value *ucontrol)
2433 u32 h_control = kcontrol->private_value;
2434 u32 rate;
2435 u16 e;
2437 e = hpi_sample_clock_get_local_rate(ss, h_control, &rate);
2438 if (!e)
2439 ucontrol->value.integer.value[0] = rate;
2440 else
2441 ucontrol->value.integer.value[0] = 0;
2442 return 0;
2445 static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2446 struct snd_ctl_elem_value *ucontrol)
2448 int change;
2449 u32 h_control = kcontrol->private_value;
2451 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2452 asihpi->mixer_clkrate[addr][1] != right;
2454 change = 1;
2455 hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control,
2456 ucontrol->value.integer.value[0]));
2457 return change;
2460 static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2461 struct snd_ctl_elem_info *uinfo)
2463 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2464 uinfo->count = 1;
2465 uinfo->value.integer.min = 8000;
2466 uinfo->value.integer.max = 192000;
2467 uinfo->value.integer.step = 100;
2469 return 0;
2472 static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2473 struct snd_ctl_elem_value *ucontrol)
2475 u32 h_control = kcontrol->private_value;
2476 u32 rate;
2477 u16 e;
2479 e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate);
2480 if (!e)
2481 ucontrol->value.integer.value[0] = rate;
2482 else
2483 ucontrol->value.integer.value[0] = 0;
2484 return 0;
2487 static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2488 struct hpi_control *hpi_ctl)
2490 struct snd_card *card = asihpi->card;
2491 struct snd_kcontrol_new snd_control;
2493 struct clk_cache *clkcache = &asihpi->cc;
2494 u32 hSC = hpi_ctl->h_control;
2495 int has_aes_in = 0;
2496 int i, j;
2497 u16 source;
2499 snd_control.private_value = hpi_ctl->h_control;
2501 clkcache->has_local = 0;
2503 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2504 if (hpi_sample_clock_query_source(ss, hSC,
2505 i, &source))
2506 break;
2507 clkcache->s[i].source = source;
2508 clkcache->s[i].index = 0;
2509 clkcache->s[i].name = sampleclock_sources[source];
2510 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2511 has_aes_in = 1;
2512 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2513 clkcache->has_local = 1;
2515 if (has_aes_in)
2516 /* already will have picked up index 0 above */
2517 for (j = 1; j < 8; j++) {
2518 if (hpi_sample_clock_query_source_index(ss, hSC,
2519 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2520 &source))
2521 break;
2522 clkcache->s[i].source =
2523 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2524 clkcache->s[i].index = j;
2525 clkcache->s[i].name = sampleclock_sources[
2526 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2527 i++;
2529 clkcache->count = i;
2531 asihpi_ctl_init(&snd_control, hpi_ctl, "source");
2532 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2533 snd_control.info = snd_asihpi_clksrc_info;
2534 snd_control.get = snd_asihpi_clksrc_get;
2535 snd_control.put = snd_asihpi_clksrc_put;
2536 if (ctl_add(card, &snd_control, asihpi) < 0)
2537 return -EINVAL;
2540 if (clkcache->has_local) {
2541 asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate");
2542 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2543 snd_control.info = snd_asihpi_clklocal_info;
2544 snd_control.get = snd_asihpi_clklocal_get;
2545 snd_control.put = snd_asihpi_clklocal_put;
2548 if (ctl_add(card, &snd_control, asihpi) < 0)
2549 return -EINVAL;
2552 asihpi_ctl_init(&snd_control, hpi_ctl, "rate");
2553 snd_control.access =
2554 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2555 snd_control.info = snd_asihpi_clkrate_info;
2556 snd_control.get = snd_asihpi_clkrate_get;
2558 return ctl_add(card, &snd_control, asihpi);
2560 /*------------------------------------------------------------
2561 Mixer
2562 ------------------------------------------------------------*/
2564 static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2566 struct snd_card *card = asihpi->card;
2567 unsigned int idx = 0;
2568 unsigned int subindex = 0;
2569 int err;
2570 struct hpi_control hpi_ctl, prev_ctl;
2572 if (snd_BUG_ON(!asihpi))
2573 return -EINVAL;
2574 strcpy(card->mixername, "asihpi mixer");
2576 err =
2577 hpi_mixer_open(ss, asihpi->adapter_index,
2578 &asihpi->h_mixer);
2579 hpi_handle_error(err);
2580 if (err)
2581 return -err;
2583 memset(&prev_ctl, 0, sizeof(prev_ctl));
2584 prev_ctl.control_type = -1;
2586 for (idx = 0; idx < 2000; idx++) {
2587 err = hpi_mixer_get_control_by_index(
2588 ss, asihpi->h_mixer,
2589 idx,
2590 &hpi_ctl.src_node_type,
2591 &hpi_ctl.src_node_index,
2592 &hpi_ctl.dst_node_type,
2593 &hpi_ctl.dst_node_index,
2594 &hpi_ctl.control_type,
2595 &hpi_ctl.h_control);
2596 if (err) {
2597 if (err == HPI_ERROR_CONTROL_DISABLED) {
2598 if (mixer_dump)
2599 snd_printk(KERN_INFO
2600 "disabled HPI control(%d)\n",
2601 idx);
2602 continue;
2603 } else
2604 break;
2608 hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2609 hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
2611 /* ASI50xx in SSX mode has multiple meters on the same node.
2612 Use subindex to create distinct ALSA controls
2613 for any duplicated controls.
2615 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2616 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2617 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2618 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2619 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2620 subindex++;
2621 else
2622 subindex = 0;
2624 prev_ctl = hpi_ctl;
2626 switch (hpi_ctl.control_type) {
2627 case HPI_CONTROL_VOLUME:
2628 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2629 break;
2630 case HPI_CONTROL_LEVEL:
2631 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2632 break;
2633 case HPI_CONTROL_MULTIPLEXER:
2634 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2635 break;
2636 case HPI_CONTROL_CHANNEL_MODE:
2637 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2638 break;
2639 case HPI_CONTROL_METER:
2640 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2641 break;
2642 case HPI_CONTROL_SAMPLECLOCK:
2643 err = snd_asihpi_sampleclock_add(
2644 asihpi, &hpi_ctl);
2645 break;
2646 case HPI_CONTROL_CONNECTION: /* ignore these */
2647 continue;
2648 case HPI_CONTROL_TUNER:
2649 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2650 break;
2651 case HPI_CONTROL_AESEBU_TRANSMITTER:
2652 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2653 break;
2654 case HPI_CONTROL_AESEBU_RECEIVER:
2655 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2656 break;
2657 case HPI_CONTROL_VOX:
2658 case HPI_CONTROL_BITSTREAM:
2659 case HPI_CONTROL_MICROPHONE:
2660 case HPI_CONTROL_PARAMETRIC_EQ:
2661 case HPI_CONTROL_COMPANDER:
2662 default:
2663 if (mixer_dump)
2664 snd_printk(KERN_INFO
2665 "untranslated HPI control"
2666 "(%d) %d %d %d %d %d\n",
2667 idx,
2668 hpi_ctl.control_type,
2669 hpi_ctl.src_node_type,
2670 hpi_ctl.src_node_index,
2671 hpi_ctl.dst_node_type,
2672 hpi_ctl.dst_node_index);
2673 continue;
2675 if (err < 0)
2676 return err;
2678 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2679 hpi_handle_error(err);
2681 snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2683 return 0;
2686 /*------------------------------------------------------------
2687 /proc interface
2688 ------------------------------------------------------------*/
2690 static void
2691 snd_asihpi_proc_read(struct snd_info_entry *entry,
2692 struct snd_info_buffer *buffer)
2694 struct snd_card_asihpi *asihpi = entry->private_data;
2695 u16 version;
2696 u32 h_control;
2697 u32 rate = 0;
2698 u16 source = 0;
2699 int err;
2701 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2702 snd_iprintf(buffer,
2703 "adapter ID=%4X\n_index=%d\n"
2704 "num_outstreams=%d\n_num_instreams=%d\n",
2705 asihpi->type, asihpi->adapter_index,
2706 asihpi->num_outstreams, asihpi->num_instreams);
2708 version = asihpi->version;
2709 snd_iprintf(buffer,
2710 "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
2711 asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
2712 version & 0x7,
2713 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2715 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2716 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2717 HPI_CONTROL_SAMPLECLOCK, &h_control);
2719 if (!err) {
2720 err = hpi_sample_clock_get_sample_rate(ss,
2721 h_control, &rate);
2722 err += hpi_sample_clock_get_source(ss, h_control, &source);
2724 if (!err)
2725 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
2726 rate, sampleclock_sources[source]);
2732 static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2734 struct snd_info_entry *entry;
2736 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2737 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2740 /*------------------------------------------------------------
2741 HWDEP
2742 ------------------------------------------------------------*/
2744 static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2746 if (enable_hpi_hwdep)
2747 return 0;
2748 else
2749 return -ENODEV;
2753 static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2755 if (enable_hpi_hwdep)
2756 return asihpi_hpi_release(file);
2757 else
2758 return -ENODEV;
2761 static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2762 unsigned int cmd, unsigned long arg)
2764 if (enable_hpi_hwdep)
2765 return asihpi_hpi_ioctl(file, cmd, arg);
2766 else
2767 return -ENODEV;
2771 /* results in /dev/snd/hwC#D0 file for each card with index #
2772 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2774 static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2775 int device, struct snd_hwdep **rhwdep)
2777 struct snd_hwdep *hw;
2778 int err;
2780 if (rhwdep)
2781 *rhwdep = NULL;
2782 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2783 if (err < 0)
2784 return err;
2785 strcpy(hw->name, "asihpi (HPI)");
2786 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2787 hw->ops.open = snd_asihpi_hpi_open;
2788 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2789 hw->ops.release = snd_asihpi_hpi_release;
2790 hw->private_data = asihpi;
2791 if (rhwdep)
2792 *rhwdep = hw;
2793 return 0;
2796 /*------------------------------------------------------------
2797 CARD
2798 ------------------------------------------------------------*/
2799 static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2800 const struct pci_device_id *pci_id)
2802 int err;
2804 u16 version;
2805 int pcm_substreams;
2807 struct hpi_adapter *hpi_card;
2808 struct snd_card *card;
2809 struct snd_card_asihpi *asihpi;
2811 u32 h_control;
2812 u32 h_stream;
2814 static int dev;
2815 if (dev >= SNDRV_CARDS)
2816 return -ENODEV;
2818 /* Should this be enable[hpi_card->index] ? */
2819 if (!enable[dev]) {
2820 dev++;
2821 return -ENOENT;
2824 err = asihpi_adapter_probe(pci_dev, pci_id);
2825 if (err < 0)
2826 return err;
2828 hpi_card = pci_get_drvdata(pci_dev);
2829 /* first try to give the card the same index as its hardware index */
2830 err = snd_card_create(hpi_card->index,
2831 id[hpi_card->index], THIS_MODULE,
2832 sizeof(struct snd_card_asihpi),
2833 &card);
2834 if (err < 0) {
2835 /* if that fails, try the default index==next available */
2836 err =
2837 snd_card_create(index[dev], id[dev],
2838 THIS_MODULE,
2839 sizeof(struct snd_card_asihpi),
2840 &card);
2841 if (err < 0)
2842 return err;
2843 snd_printk(KERN_WARNING
2844 "**** WARNING **** adapter index %d->ALSA index %d\n",
2845 hpi_card->index, card->number);
2848 asihpi = (struct snd_card_asihpi *) card->private_data;
2849 asihpi->card = card;
2850 asihpi->pci = hpi_card->pci;
2851 asihpi->adapter_index = hpi_card->index;
2852 hpi_handle_error(hpi_adapter_get_info(ss,
2853 asihpi->adapter_index,
2854 &asihpi->num_outstreams,
2855 &asihpi->num_instreams,
2856 &asihpi->version,
2857 &asihpi->serial_number, &asihpi->type));
2859 version = asihpi->version;
2860 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2861 "num_instreams=%d S/N=%d\n"
2862 "hw version %c%d DSP code version %03d\n",
2863 asihpi->type, asihpi->adapter_index,
2864 asihpi->num_outstreams,
2865 asihpi->num_instreams, asihpi->serial_number,
2866 ((version >> 3) & 0xf) + 'A',
2867 version & 0x7,
2868 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2870 pcm_substreams = asihpi->num_outstreams;
2871 if (pcm_substreams < asihpi->num_instreams)
2872 pcm_substreams = asihpi->num_instreams;
2874 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2875 HPI_ADAPTER_PROPERTY_CAPS1,
2876 NULL, &asihpi->support_grouping);
2877 if (err)
2878 asihpi->support_grouping = 0;
2880 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2881 HPI_ADAPTER_PROPERTY_CAPS2,
2882 &asihpi->support_mrx, NULL);
2883 if (err)
2884 asihpi->support_mrx = 0;
2886 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2887 HPI_ADAPTER_PROPERTY_INTERVAL,
2888 NULL, &asihpi->update_interval_frames);
2889 if (err)
2890 asihpi->update_interval_frames = 512;
2892 hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index,
2893 0, &h_stream));
2895 err = hpi_instream_host_buffer_free(ss, h_stream);
2896 asihpi->support_mmap = (!err);
2898 hpi_handle_error(hpi_instream_close(ss, h_stream));
2900 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2901 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2902 &asihpi->in_max_chans, &asihpi->out_max_chans);
2903 if (err) {
2904 asihpi->in_max_chans = 2;
2905 asihpi->out_max_chans = 2;
2908 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n",
2909 asihpi->support_mmap,
2910 asihpi->support_grouping,
2911 asihpi->support_mrx
2915 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2916 if (err < 0) {
2917 snd_printk(KERN_ERR "pcm_new failed\n");
2918 goto __nodev;
2920 err = snd_card_asihpi_mixer_new(asihpi);
2921 if (err < 0) {
2922 snd_printk(KERN_ERR "mixer_new failed\n");
2923 goto __nodev;
2926 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2927 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2928 HPI_CONTROL_SAMPLECLOCK, &h_control);
2930 if (!err)
2931 err = hpi_sample_clock_set_local_rate(
2932 ss, h_control, adapter_fs);
2934 snd_asihpi_proc_init(asihpi);
2936 /* always create, can be enabled or disabled dynamically
2937 by enable_hwdep module param*/
2938 snd_asihpi_hpi_new(asihpi, 0, NULL);
2940 if (asihpi->support_mmap)
2941 strcpy(card->driver, "ASIHPI-MMAP");
2942 else
2943 strcpy(card->driver, "ASIHPI");
2945 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2946 sprintf(card->longname, "%s %i",
2947 card->shortname, asihpi->adapter_index);
2948 err = snd_card_register(card);
2949 if (!err) {
2950 hpi_card->snd_card_asihpi = card;
2951 dev++;
2952 return 0;
2954 __nodev:
2955 snd_card_free(card);
2956 snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2957 return err;
2961 static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2963 struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
2965 snd_card_free(hpi_card->snd_card_asihpi);
2966 hpi_card->snd_card_asihpi = NULL;
2967 asihpi_adapter_remove(pci_dev);
2970 static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2971 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2972 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2973 (kernel_ulong_t)HPI_6205},
2974 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2975 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2976 (kernel_ulong_t)HPI_6000},
2977 {0,}
2979 MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2981 static struct pci_driver driver = {
2982 .name = "asihpi",
2983 .id_table = asihpi_pci_tbl,
2984 .probe = snd_asihpi_probe,
2985 .remove = __devexit_p(snd_asihpi_remove),
2986 #ifdef CONFIG_PM
2987 /* .suspend = snd_asihpi_suspend,
2988 .resume = snd_asihpi_resume, */
2989 #endif
2992 static int __init snd_asihpi_init(void)
2994 asihpi_init();
2995 return pci_register_driver(&driver);
2998 static void __exit snd_asihpi_exit(void)
3001 pci_unregister_driver(&driver);
3002 asihpi_exit();
3005 module_init(snd_asihpi_init)
3006 module_exit(snd_asihpi_exit)