blob: f74c7372b3d14d3ba553cc8b904dd75585b28bd3 [file] [log] [blame]
Eliot Blennerhassett719f82d2010-04-21 18:17:39 +02001/*
2 * Asihpi soundcard
3 * Copyright (c) by AudioScience Inc <alsa@audioscience.com>
4 *
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;
8 *
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.
13 *
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
17 *
18 *
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.
23 */
24/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */
25#define REALLY_VERBOSE_LOGGING 0
26
27#if REALLY_VERBOSE_LOGGING
28#define VPRINTK1 snd_printd
29#else
30#define VPRINTK1(...)
31#endif
32
33#if REALLY_VERBOSE_LOGGING > 1
34#define VPRINTK2 snd_printd
35#else
36#define VPRINTK2(...)
37#endif
38
39#ifndef ASI_STYLE_NAMES
40/* not sure how ALSA style name should look */
41#define ASI_STYLE_NAMES 1
42#endif
43
44#include "hpi_internal.h"
45#include "hpimsginit.h"
46#include "hpioctl.h"
47
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>
62
63
64MODULE_LICENSE("GPL");
65MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
66MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
67
68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
69static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
70static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
71static int enable_hpi_hwdep = 1;
72
73module_param_array(index, int, NULL, S_IRUGO);
74MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
75
76module_param_array(id, charp, NULL, S_IRUGO);
77MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
78
79module_param_array(enable, bool, NULL, S_IRUGO);
80MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
81
82module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
83MODULE_PARM_DESC(enable_hpi_hwdep,
84 "ALSA enable HPI hwdep for AudioScience soundcard ");
85
86/* identify driver */
87#ifdef KERNEL_ALSA_BUILD
88static char *build_info = "built using headers from kernel source";
89module_param(build_info, charp, S_IRUGO);
90MODULE_PARM_DESC(build_info, "built using headers from kernel source");
91#else
92static char *build_info = "built within ALSA source";
93module_param(build_info, charp, S_IRUGO);
94MODULE_PARM_DESC(build_info, "built within ALSA source");
95#endif
96
97/* set to 1 to dump every control from adapter to log */
98static const int mixer_dump;
99
100#define DEFAULT_SAMPLERATE 44100
101static int adapter_fs = DEFAULT_SAMPLERATE;
102
103static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */
104
105/* defaults */
106#define PERIODS_MIN 2
107#define PERIOD_BYTES_MIN 2304
108#define BUFFER_BYTES_MAX (512 * 1024)
109
110/*#define TIMER_MILLISECONDS 20
111#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
112*/
113
114#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
115
116struct clk_source {
117 int source;
118 int index;
119 char *name;
120};
121
122struct clk_cache {
123 int count;
124 int has_local;
125 struct clk_source s[MAX_CLOCKSOURCES];
126};
127
128/* Per card data */
129struct 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;
138
139 u32 h_mixer;
140 struct clk_cache cc;
141
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;
148};
149
150/* Per stream data */
151struct 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;
163};
164
165/* universal stream verbs work with out or in stream handles */
166
167/* Functions to allow driver to give a buffer to HPI for busmastering */
168
169static 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
174)
175{
176 struct hpi_message hm;
177 struct hpi_response hr;
178 unsigned int obj = hpi_handle_object(h_stream);
179
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);
186
187 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
188 &hm.obj_index);
189
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;
195}
196
197static u16 hpi_stream_host_buffer_detach(
198 struct hpi_hsubsys *hS,
199 u32 h_stream
200)
201{
202 struct hpi_message hm;
203 struct hpi_response hr;
204 unsigned int obj = hpi_handle_object(h_stream);
205
206 if (!h_stream)
207 return HPI_ERROR_INVALID_OBJ;
208
209 hpi_init_message_response(&hm, &hr, obj,
210 obj == HPI_OBJ_OSTREAM ?
211 HPI_OSTREAM_HOSTBUFFER_FREE :
212 HPI_ISTREAM_HOSTBUFFER_FREE);
213
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;
219}
220
221static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream)
222{
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);
227}
228
229static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream)
230{
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);
235}
236
237static 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
245)
246{
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);
255}
256
257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS,
258 u32 h_master,
259 u32 h_stream)
260{
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);
265}
266
267static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS,
268 u32 h_stream)
269{
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);
274}
275
276static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS,
277 u32 h_stream, u32 *mo, u32 *mi)
278{
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);
283}
284
285static u16 handle_error(u16 err, int line, char *filename)
286{
287 if (err)
288 printk(KERN_WARNING
289 "in file %s, line %d: HPI error %d\n",
290 filename, line, err);
291 return err;
292}
293
294#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
295
296/***************************** GENERAL PCM ****************/
297#if REALLY_VERBOSE_LOGGING
298static void print_hwparams(struct snd_pcm_hw_params *p)
299{
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));
311}
312#else
313#define print_hwparams(x)
314#endif
315
316static 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
335 */
336 -1
337#else
338 /* SNDRV_PCM_FORMAT_S24_3LE */ /* { HPI_FORMAT_PCM24_SIGNED 15 */
339#endif
340};
341
342
343static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
344 u16 *hpi_format)
345{
346 u16 format;
347
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;
353 }
354 }
355
356 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
357 alsa_format);
358 *hpi_format = 0;
359 return -EINVAL;
360}
361
362static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
363 struct snd_pcm_hardware *pcmhw)
364{
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;
372
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);
387 }
388
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");
395
396 break;
397 }
398
399 rate_min = min(rate_min, sample_rate);
400 rate_max = max(rate_max, sample_rate);
401
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;
444 }
445 }
446 }
447
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;
453}
454
455static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
456 struct snd_pcm_hw_params *params)
457{
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 unsigned int bytes_per_sec;
464
465 print_hwparams(params);
466 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
467 if (err < 0)
468 return err;
469 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
470 if (err)
471 return err;
472
473 VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n",
474 format, params_channels(params),
475 params_rate(params));
476
477 hpi_handle_error(hpi_format_create(&dpcm->format,
478 params_channels(params),
479 format, params_rate(params), 0, 0));
480
481 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
482 if (hpi_instream_reset(ss, dpcm->h_stream) != 0)
483 return -EINVAL;
484
485 if (hpi_instream_set_format(ss,
486 dpcm->h_stream, &dpcm->format) != 0)
487 return -EINVAL;
488 }
489
490 dpcm->hpi_buffer_attached = 0;
491 if (card->support_mmap) {
492
493 err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream,
494 params_buffer_bytes(params), runtime->dma_addr);
495 if (err == 0) {
496 snd_printd(KERN_INFO
497 "stream_host_buffer_attach succeeded %u %lu\n",
498 params_buffer_bytes(params),
499 (unsigned long)runtime->dma_addr);
500 } else {
501 snd_printd(KERN_INFO
502 "stream_host_buffer_attach error %d\n",
503 err);
504 return -ENOMEM;
505 }
506
507 err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL,
508 &dpcm->hpi_buffer_attached,
509 NULL, NULL, NULL);
510
511 snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n",
512 dpcm->hpi_buffer_attached);
513 }
514 bytes_per_sec = params_rate(params) * params_channels(params);
515 bytes_per_sec *= snd_pcm_format_width(params_format(params));
516 bytes_per_sec /= 8;
517 if (bytes_per_sec <= 0)
518 return -EINVAL;
519
520 dpcm->bytes_per_sec = bytes_per_sec;
521 dpcm->pcm_size = params_buffer_bytes(params);
522 dpcm->pcm_count = params_period_bytes(params);
523 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n",
524 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec);
525
526 dpcm->pcm_irq_pos = 0;
527 dpcm->pcm_buf_pos = 0;
528 return 0;
529}
530
531static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
532 substream)
533{
534 struct snd_pcm_runtime *runtime = substream->runtime;
535 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
536 int expiry;
537
538 expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec);
539 /* wait longer the first time, for samples to propagate */
540 expiry = max(expiry, 20);
541 dpcm->timer.expires = jiffies + expiry;
542 dpcm->respawn_timer = 1;
543 add_timer(&dpcm->timer);
544}
545
546static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
547{
548 struct snd_pcm_runtime *runtime = substream->runtime;
549 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
550
551 dpcm->respawn_timer = 0;
552 del_timer(&dpcm->timer);
553}
554
555static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
556 int cmd)
557{
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
563 snd_printd("trigger %dstream %d\n",
564 substream->stream, substream->number);
565 switch (cmd) {
566 case SNDRV_PCM_TRIGGER_START:
567 snd_pcm_group_for_each_entry(s, substream) {
568 struct snd_card_asihpi_pcm *ds;
569 ds = s->runtime->private_data;
570
571 if (snd_pcm_substream_chip(s) != card)
572 continue;
573
574 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
575 (card->support_mmap)) {
576 /* How do I know how much valid data is present
577 * in buffer? Just guessing 2 periods, but if
578 * buffer is bigger it may contain even more
579 * data??
580 */
581 unsigned int preload = ds->pcm_count * 2;
582 VPRINTK2("preload %d\n", preload);
583 hpi_handle_error(hpi_outstream_write_buf(
584 ss, ds->h_stream,
585 &s->runtime->dma_area[0],
586 preload,
587 &ds->format));
588 }
589
590 if (card->support_grouping) {
591 VPRINTK1("\t_group %dstream %d\n", s->stream,
592 s->number);
593 e = hpi_stream_group_add(ss,
594 dpcm->h_stream,
595 ds->h_stream);
596 if (!e) {
597 snd_pcm_trigger_done(s, substream);
598 } else {
599 hpi_handle_error(e);
600 break;
601 }
602 } else
603 break;
604 }
605 snd_printd("start\n");
606 /* start the master stream */
607 snd_card_asihpi_pcm_timer_start(substream);
608 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
609 break;
610
611 case SNDRV_PCM_TRIGGER_STOP:
612 snd_card_asihpi_pcm_timer_stop(substream);
613 snd_pcm_group_for_each_entry(s, substream) {
614 if (snd_pcm_substream_chip(s) != card)
615 continue;
616
617 /*? workaround linked streams don't
618 transition to SETUP 20070706*/
619 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
620
621 if (card->support_grouping) {
622 VPRINTK1("\t_group %dstream %d\n", s->stream,
623 s->number);
624 snd_pcm_trigger_done(s, substream);
625 } else
626 break;
627 }
628 snd_printd("stop\n");
629
630 /* _prepare and _hwparams reset the stream */
631 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
632 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
633 hpi_handle_error(
634 hpi_outstream_reset(ss, dpcm->h_stream));
635
636 if (card->support_grouping)
637 hpi_handle_error(hpi_stream_group_reset(ss,
638 dpcm->h_stream));
639 break;
640
641 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
642 snd_printd("pause release\n");
643 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
644 snd_card_asihpi_pcm_timer_start(substream);
645 break;
646 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
647 snd_printd("pause\n");
648 snd_card_asihpi_pcm_timer_stop(substream);
649 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
650 break;
651 default:
652 snd_printd("\tINVALID\n");
653 return -EINVAL;
654 }
655
656 return 0;
657}
658
659static int
660snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
661{
662 struct snd_pcm_runtime *runtime = substream->runtime;
663 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
664 if (dpcm->hpi_buffer_attached)
665 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
666
667 snd_pcm_lib_free_pages(substream);
668 return 0;
669}
670
671static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
672{
673 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
674 kfree(dpcm);
675}
676
677/*algorithm outline
678 Without linking degenerates to getting single stream pos etc
679 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
680*/
681/*
682buf_pos=get_buf_pos(s);
683for_each_linked_stream(s) {
684 buf_pos=get_buf_pos(s);
685 min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size)
686 new_data = min(new_data, calc_new_data(buf_pos,irq_pos)
687}
688timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
689for_each_linked_stream(s) {
690 s->buf_pos = min_buf_pos;
691 if (new_data > pcm_count) {
692 if (mmap) {
693 irq_pos = (irq_pos + pcm_count) % pcm_size;
694 if (playback) {
695 write(pcm_count);
696 } else {
697 read(pcm_count);
698 }
699 }
700 snd_pcm_period_elapsed(s);
701 }
702}
703*/
704
705/** Minimum of 2 modulo values. Works correctly when the difference between
706* the values is less than half the modulus
707*/
708static inline unsigned int modulo_min(unsigned int a, unsigned int b,
709 unsigned long int modulus)
710{
711 unsigned int result;
712 if (((a-b) % modulus) < (modulus/2))
713 result = b;
714 else
715 result = a;
716
717 return result;
718}
719
720/** Timer function, equivalent to interrupt service routine for cards
721*/
722static void snd_card_asihpi_timer_function(unsigned long data)
723{
724 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
725 struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream);
726 struct snd_pcm_runtime *runtime;
727 struct snd_pcm_substream *s;
728 unsigned int newdata = 0;
729 unsigned int buf_pos, min_buf_pos = 0;
730 unsigned int remdata, xfercount, next_jiffies;
731 int first = 1;
732 u16 state;
733 u32 buffer_size, data_avail, samples_played, aux;
734
735 /* find minimum newdata and buffer pos in group */
736 snd_pcm_group_for_each_entry(s, dpcm->substream) {
737 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
738 runtime = s->runtime;
739
740 if (snd_pcm_substream_chip(s) != card)
741 continue;
742
743 hpi_handle_error(hpi_stream_get_info_ex(ss,
744 ds->h_stream, &state,
745 &buffer_size, &data_avail,
746 &samples_played, &aux));
747
748 /* number of bytes in on-card buffer */
749 runtime->delay = aux;
750
751 if (state == HPI_STATE_DRAINED) {
752 snd_printd(KERN_WARNING "outstream %d drained\n",
753 s->number);
754 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
755 return;
756 }
757
758 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
759 buf_pos = frames_to_bytes(runtime, samples_played);
760 } else {
761 buf_pos = data_avail + ds->pcm_irq_pos;
762 }
763
764 if (first) {
765 /* can't statically init min when wrap is involved */
766 min_buf_pos = buf_pos;
767 newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size;
768 first = 0;
769 } else {
770 min_buf_pos =
771 modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L);
772 newdata = min(
773 (buf_pos - ds->pcm_irq_pos) % ds->pcm_size,
774 newdata);
775 }
776
777 VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n",
778 (unsigned long)frames_to_bytes(runtime,
779 runtime->status->hw_ptr),
780 (unsigned long)frames_to_bytes(runtime,
781 runtime->control->appl_ptr));
782 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X,"
783 " aux=x%04X space=x%04X\n", s->number,
784 state, ds->pcm_irq_pos, buf_pos, (int)data_avail,
785 (int)aux, buffer_size-data_avail);
786 }
787
788 remdata = newdata % dpcm->pcm_count;
789 xfercount = newdata - remdata; /* a multiple of pcm_count */
790 next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1;
791 next_jiffies = max(next_jiffies, 2U * HZ / 1000U);
792 dpcm->timer.expires = jiffies + next_jiffies;
793 VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n",
794 next_jiffies, min_buf_pos, newdata, xfercount);
795
796 snd_pcm_group_for_each_entry(s, dpcm->substream) {
797 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
798 ds->pcm_buf_pos = min_buf_pos;
799
800 if (xfercount) {
801 if (card->support_mmap) {
802 ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount;
803 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
804 VPRINTK2("write OS%d x%04x\n",
805 s->number,
806 ds->pcm_count);
807 hpi_handle_error(
808 hpi_outstream_write_buf(
809 ss, ds->h_stream,
810 &s->runtime->
811 dma_area[0],
812 xfercount,
813 &ds->format));
814 } else {
815 VPRINTK2("read IS%d x%04x\n",
816 s->number,
817 dpcm->pcm_count);
818 hpi_handle_error(
819 hpi_instream_read_buf(
820 ss, ds->h_stream,
821 NULL, xfercount));
822 }
823 } /* else R/W will be handled by read/write callbacks */
824 snd_pcm_period_elapsed(s);
825 }
826 }
827
828 if (dpcm->respawn_timer)
829 add_timer(&dpcm->timer);
830}
831
832/***************************** PLAYBACK OPS ****************/
833static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
834 unsigned int cmd, void *arg)
835{
836 /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */
837 return snd_pcm_lib_ioctl(substream, cmd, arg);
838}
839
840static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
841 substream)
842{
843 struct snd_pcm_runtime *runtime = substream->runtime;
844 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
845
846 snd_printd(KERN_INFO "playback prepare %d\n", substream->number);
847
848 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
849 dpcm->pcm_irq_pos = 0;
850 dpcm->pcm_buf_pos = 0;
851
852 return 0;
853}
854
855static snd_pcm_uframes_t
856snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
857{
858 struct snd_pcm_runtime *runtime = substream->runtime;
859 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
860 snd_pcm_uframes_t ptr;
861
862 u32 samples_played;
863 u16 err;
864
865 if (!snd_pcm_stream_linked(substream)) {
866 /* NOTE, can use samples played for playback position here and
867 * in timer fn because it LAGS the actual read pointer, and is a
868 * better representation of actual playout position
869 */
870 err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
871 NULL, NULL,
872 &samples_played, NULL);
873 hpi_handle_error(err);
874
875 dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
876 }
877 /* else must return most conservative value found in timer func
878 * by looping over all streams
879 */
880
881 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
882 VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
883 return ptr;
884}
885
886static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
887 u32 h_stream,
888 struct snd_pcm_hardware *pcmhw)
889{
890 struct hpi_format hpi_format;
891 u16 format;
892 u16 err;
893 u32 h_control;
894 u32 sample_rate = 48000;
895
896 /* on cards without SRC, must query at valid rate,
897 * maybe set by external sync
898 */
899 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
900 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
901 HPI_CONTROL_SAMPLECLOCK, &h_control);
902
903 if (!err)
904 err = hpi_sample_clock_get_sample_rate(ss, h_control,
905 &sample_rate);
906
907 for (format = HPI_FORMAT_PCM8_UNSIGNED;
908 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
909 err = hpi_format_create(&hpi_format,
910 2, format, sample_rate, 128000, 0);
911 if (!err)
912 err = hpi_outstream_query_format(ss, h_stream,
913 &hpi_format);
914 if (!err && (hpi_to_alsa_formats[format] != -1))
915 pcmhw->formats |=
916 (1ULL << hpi_to_alsa_formats[format]);
917 }
918}
919
920static struct snd_pcm_hardware snd_card_asihpi_playback = {
921 .channels_min = 1,
922 .channels_max = 2,
923 .buffer_bytes_max = BUFFER_BYTES_MAX,
924 .period_bytes_min = PERIOD_BYTES_MIN,
925 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
926 .periods_min = PERIODS_MIN,
927 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
928 .fifo_size = 0,
929};
930
931static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
932{
933 struct snd_pcm_runtime *runtime = substream->runtime;
934 struct snd_card_asihpi_pcm *dpcm;
935 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
936 int err;
937
938 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
939 if (dpcm == NULL)
940 return -ENOMEM;
941
942 err =
943 hpi_outstream_open(ss, card->adapter_index,
944 substream->number, &dpcm->h_stream);
945 hpi_handle_error(err);
946 if (err)
947 kfree(dpcm);
948 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
949 return -EBUSY;
950 if (err)
951 return -EIO;
952
953 /*? also check ASI5000 samplerate source
954 If external, only support external rate.
955 If internal and other stream playing, cant switch
956 */
957
958 init_timer(&dpcm->timer);
959 dpcm->timer.data = (unsigned long) dpcm;
960 dpcm->timer.function = snd_card_asihpi_timer_function;
961 dpcm->substream = substream;
962 runtime->private_data = dpcm;
963 runtime->private_free = snd_card_asihpi_runtime_free;
964
965 snd_card_asihpi_playback.channels_max = card->out_max_chans;
966 /*?snd_card_asihpi_playback.period_bytes_min =
967 card->out_max_chans * 4096; */
968
969 snd_card_asihpi_playback_format(card, dpcm->h_stream,
970 &snd_card_asihpi_playback);
971
972 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
973
974 snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
975 SNDRV_PCM_INFO_DOUBLE |
976 SNDRV_PCM_INFO_BATCH |
977 SNDRV_PCM_INFO_BLOCK_TRANSFER |
978 SNDRV_PCM_INFO_PAUSE;
979
980 if (card->support_mmap)
981 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
982 SNDRV_PCM_INFO_MMAP_VALID;
983
984 if (card->support_grouping)
985 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
986
987 /* struct is copied, so can create initializer dynamically */
988 runtime->hw = snd_card_asihpi_playback;
989
990 if (card->support_mmap)
991 err = snd_pcm_hw_constraint_pow2(runtime, 0,
992 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
993 if (err < 0)
994 return err;
995
996 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
997 card->update_interval_frames);
998 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
999 card->update_interval_frames * 4, UINT_MAX);
1000
1001 snd_pcm_set_sync(substream);
1002
1003 snd_printd(KERN_INFO "playback open\n");
1004
1005 return 0;
1006}
1007
1008static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1009{
1010 struct snd_pcm_runtime *runtime = substream->runtime;
1011 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1012
1013 hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream));
1014 snd_printd(KERN_INFO "playback close\n");
1015
1016 return 0;
1017}
1018
1019static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1020 int channel,
1021 snd_pcm_uframes_t pos,
1022 void __user *src,
1023 snd_pcm_uframes_t count)
1024{
1025 struct snd_pcm_runtime *runtime = substream->runtime;
1026 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1027 unsigned int len;
1028
1029 len = frames_to_bytes(runtime, count);
1030
1031 if (copy_from_user(runtime->dma_area, src, len))
1032 return -EFAULT;
1033
1034 VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n",
1035 substream->number, len);
1036
1037 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1038 runtime->dma_area, len, &dpcm->format));
1039
1040 return 0;
1041}
1042
1043static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1044 substream, int channel,
1045 snd_pcm_uframes_t pos,
1046 snd_pcm_uframes_t count)
1047{
1048 unsigned int len;
1049 struct snd_pcm_runtime *runtime = substream->runtime;
1050 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1051
1052 len = frames_to_bytes(runtime, count);
1053 snd_printd(KERN_INFO "playback silence %u bytes\n", len);
1054
1055 memset(runtime->dma_area, 0, len);
1056 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1057 runtime->dma_area, len, &dpcm->format));
1058 return 0;
1059}
1060
1061static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1062 .open = snd_card_asihpi_playback_open,
1063 .close = snd_card_asihpi_playback_close,
1064 .ioctl = snd_card_asihpi_playback_ioctl,
1065 .hw_params = snd_card_asihpi_pcm_hw_params,
1066 .hw_free = snd_card_asihpi_hw_free,
1067 .prepare = snd_card_asihpi_playback_prepare,
1068 .trigger = snd_card_asihpi_trigger,
1069 .pointer = snd_card_asihpi_playback_pointer,
1070 .copy = snd_card_asihpi_playback_copy,
1071 .silence = snd_card_asihpi_playback_silence,
1072};
1073
1074static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1075 .open = snd_card_asihpi_playback_open,
1076 .close = snd_card_asihpi_playback_close,
1077 .ioctl = snd_card_asihpi_playback_ioctl,
1078 .hw_params = snd_card_asihpi_pcm_hw_params,
1079 .hw_free = snd_card_asihpi_hw_free,
1080 .prepare = snd_card_asihpi_playback_prepare,
1081 .trigger = snd_card_asihpi_trigger,
1082 .pointer = snd_card_asihpi_playback_pointer,
1083};
1084
1085/***************************** CAPTURE OPS ****************/
1086static snd_pcm_uframes_t
1087snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1088{
1089 struct snd_pcm_runtime *runtime = substream->runtime;
1090 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1091
1092 VPRINTK2("capture pointer %d=%d\n",
1093 substream->number, dpcm->pcm_buf_pos);
1094 /* NOTE Unlike playback can't use actual dwSamplesPlayed
1095 for the capture position, because those samples aren't yet in
1096 the local buffer available for reading.
1097 */
1098 return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
1099}
1100
1101static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1102 unsigned int cmd, void *arg)
1103{
1104 return snd_pcm_lib_ioctl(substream, cmd, arg);
1105}
1106
1107static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1108{
1109 struct snd_pcm_runtime *runtime = substream->runtime;
1110 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1111
1112 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream));
1113 dpcm->pcm_irq_pos = 0;
1114 dpcm->pcm_buf_pos = 0;
1115
1116 snd_printd("capture prepare %d\n", substream->number);
1117 return 0;
1118}
1119
1120
1121
1122static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1123 u32 h_stream,
1124 struct snd_pcm_hardware *pcmhw)
1125{
1126 struct hpi_format hpi_format;
1127 u16 format;
1128 u16 err;
1129 u32 h_control;
1130 u32 sample_rate = 48000;
1131
1132 /* on cards without SRC, must query at valid rate,
1133 maybe set by external sync */
1134 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
1135 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1136 HPI_CONTROL_SAMPLECLOCK, &h_control);
1137
1138 if (!err)
1139 err = hpi_sample_clock_get_sample_rate(ss, h_control,
1140 &sample_rate);
1141
1142 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1143 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1144
1145 err = hpi_format_create(&hpi_format, 2, format,
1146 sample_rate, 128000, 0);
1147 if (!err)
1148 err = hpi_instream_query_format(ss, h_stream,
1149 &hpi_format);
1150 if (!err)
1151 pcmhw->formats |=
1152 (1ULL << hpi_to_alsa_formats[format]);
1153 }
1154}
1155
1156
1157static struct snd_pcm_hardware snd_card_asihpi_capture = {
1158 .channels_min = 1,
1159 .channels_max = 2,
1160 .buffer_bytes_max = BUFFER_BYTES_MAX,
1161 .period_bytes_min = PERIOD_BYTES_MIN,
1162 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1163 .periods_min = PERIODS_MIN,
1164 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1165 .fifo_size = 0,
1166};
1167
1168static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1169{
1170 struct snd_pcm_runtime *runtime = substream->runtime;
1171 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1172 struct snd_card_asihpi_pcm *dpcm;
1173 int err;
1174
1175 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1176 if (dpcm == NULL)
1177 return -ENOMEM;
1178
1179 snd_printd("hpi_instream_open adapter %d stream %d\n",
1180 card->adapter_index, substream->number);
1181
1182 err = hpi_handle_error(
1183 hpi_instream_open(ss, card->adapter_index,
1184 substream->number, &dpcm->h_stream));
1185 if (err)
1186 kfree(dpcm);
1187 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1188 return -EBUSY;
1189 if (err)
1190 return -EIO;
1191
1192
1193 init_timer(&dpcm->timer);
1194 dpcm->timer.data = (unsigned long) dpcm;
1195 dpcm->timer.function = snd_card_asihpi_timer_function;
1196 dpcm->substream = substream;
1197 runtime->private_data = dpcm;
1198 runtime->private_free = snd_card_asihpi_runtime_free;
1199
1200 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1201 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1202 &snd_card_asihpi_capture);
1203 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1204 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED;
1205
1206 if (card->support_mmap)
1207 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1208 SNDRV_PCM_INFO_MMAP_VALID;
1209
1210 runtime->hw = snd_card_asihpi_capture;
1211
1212 if (card->support_mmap)
1213 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1214 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1215 if (err < 0)
1216 return err;
1217
1218 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1219 card->update_interval_frames);
1220 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1221 card->update_interval_frames * 2, UINT_MAX);
1222
1223 snd_pcm_set_sync(substream);
1224
1225 return 0;
1226}
1227
1228static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1229{
1230 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1231
1232 hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream));
1233 return 0;
1234}
1235
1236static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1237 int channel, snd_pcm_uframes_t pos,
1238 void __user *dst, snd_pcm_uframes_t count)
1239{
1240 struct snd_pcm_runtime *runtime = substream->runtime;
1241 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1242 u32 data_size;
1243
1244 data_size = frames_to_bytes(runtime, count);
1245
1246 VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size);
1247 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream,
1248 runtime->dma_area, data_size));
1249
1250 /* Used by capture_pointer */
1251 dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1252
1253 if (copy_to_user(dst, runtime->dma_area, data_size))
1254 return -EFAULT;
1255
1256 return 0;
1257}
1258
1259static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1260 .open = snd_card_asihpi_capture_open,
1261 .close = snd_card_asihpi_capture_close,
1262 .ioctl = snd_card_asihpi_capture_ioctl,
1263 .hw_params = snd_card_asihpi_pcm_hw_params,
1264 .hw_free = snd_card_asihpi_hw_free,
1265 .prepare = snd_card_asihpi_capture_prepare,
1266 .trigger = snd_card_asihpi_trigger,
1267 .pointer = snd_card_asihpi_capture_pointer,
1268};
1269
1270static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1271 .open = snd_card_asihpi_capture_open,
1272 .close = snd_card_asihpi_capture_close,
1273 .ioctl = snd_card_asihpi_capture_ioctl,
1274 .hw_params = snd_card_asihpi_pcm_hw_params,
1275 .hw_free = snd_card_asihpi_hw_free,
1276 .prepare = snd_card_asihpi_capture_prepare,
1277 .trigger = snd_card_asihpi_trigger,
1278 .pointer = snd_card_asihpi_capture_pointer,
1279 .copy = snd_card_asihpi_capture_copy
1280};
1281
1282static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1283 int device, int substreams)
1284{
1285 struct snd_pcm *pcm;
1286 int err;
1287
1288 err = snd_pcm_new(asihpi->card, "asihpi PCM", device,
1289 asihpi->num_outstreams, asihpi->num_instreams,
1290 &pcm);
1291 if (err < 0)
1292 return err;
1293 /* pointer to ops struct is stored, dont change ops afterwards! */
1294 if (asihpi->support_mmap) {
1295 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1296 &snd_card_asihpi_playback_mmap_ops);
1297 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1298 &snd_card_asihpi_capture_mmap_ops);
1299 } else {
1300 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1301 &snd_card_asihpi_playback_ops);
1302 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1303 &snd_card_asihpi_capture_ops);
1304 }
1305
1306 pcm->private_data = asihpi;
1307 pcm->info_flags = 0;
1308 strcpy(pcm->name, "asihpi PCM");
1309
1310 /*? do we want to emulate MMAP for non-BBM cards?
1311 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
1312 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1313 snd_dma_pci_data(asihpi->pci),
1314 64*1024, BUFFER_BYTES_MAX);
1315
1316 return 0;
1317}
1318
1319/***************************** MIXER CONTROLS ****************/
1320struct hpi_control {
1321 u32 h_control;
1322 u16 control_type;
1323 u16 src_node_type;
1324 u16 src_node_index;
1325 u16 dst_node_type;
1326 u16 dst_node_index;
1327 u16 band;
1328 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1329};
1330
1331static char *asihpi_tuner_band_names[] =
1332{
1333 "invalid",
1334 "AM",
1335 "FM mono",
1336 "TV NTSC-M",
1337 "FM stereo",
1338 "AUX",
1339 "TV PAL BG",
1340 "TV PAL I",
1341 "TV PAL DK",
1342 "TV SECAM",
1343};
1344
1345compile_time_assert(
1346 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1347 (HPI_TUNER_BAND_LAST+1)),
1348 assert_tuner_band_names_size);
1349
1350#if ASI_STYLE_NAMES
1351static char *asihpi_src_names[] =
1352{
1353 "no source",
1354 "outstream",
1355 "line_in",
1356 "aes_in",
1357 "tuner",
1358 "RF",
1359 "clock",
1360 "bitstr",
1361 "mic",
1362 "cobranet",
1363 "analog_in",
1364 "adapter",
1365};
1366#else
1367static char *asihpi_src_names[] =
1368{
1369 "no source",
1370 "PCM playback",
1371 "line in",
1372 "digital in",
1373 "tuner",
1374 "RF",
1375 "clock",
1376 "bitstream",
1377 "mic",
1378 "cobranet in",
1379 "analog in",
1380 "adapter",
1381};
1382#endif
1383
1384compile_time_assert(
1385 (ARRAY_SIZE(asihpi_src_names) ==
1386 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_BASE+1)),
1387 assert_src_names_size);
1388
1389#if ASI_STYLE_NAMES
1390static char *asihpi_dst_names[] =
1391{
1392 "no destination",
1393 "instream",
1394 "line_out",
1395 "aes_out",
1396 "RF",
1397 "speaker" ,
1398 "cobranet",
1399 "analog_out",
1400};
1401#else
1402static char *asihpi_dst_names[] =
1403{
1404 "no destination",
1405 "PCM capture",
1406 "line out",
1407 "digital out",
1408 "RF",
1409 "speaker",
1410 "cobranet out",
1411 "analog out"
1412};
1413#endif
1414
1415compile_time_assert(
1416 (ARRAY_SIZE(asihpi_dst_names) ==
1417 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_BASE+1)),
1418 assert_dst_names_size);
1419
1420static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1421 struct snd_card_asihpi *asihpi)
1422{
1423 int err;
1424
1425 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1426 if (err < 0)
1427 return err;
1428 else if (mixer_dump)
1429 snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1430
1431 return 0;
1432}
1433
1434/* Convert HPI control name and location into ALSA control name */
1435static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1436 struct hpi_control *hpi_ctl,
1437 char *name)
1438{
1439 memset(snd_control, 0, sizeof(*snd_control));
1440 snd_control->name = hpi_ctl->name;
1441 snd_control->private_value = hpi_ctl->h_control;
1442 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1443 snd_control->index = 0;
1444
1445 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1446 sprintf(hpi_ctl->name, "%s%d to %s%d %s",
1447 asihpi_src_names[hpi_ctl->src_node_type],
1448 hpi_ctl->src_node_index,
1449 asihpi_dst_names[hpi_ctl->dst_node_type],
1450 hpi_ctl->dst_node_index,
1451 name);
1452 else if (hpi_ctl->dst_node_type) {
1453 sprintf(hpi_ctl->name, "%s%d %s",
1454 asihpi_dst_names[hpi_ctl->dst_node_type],
1455 hpi_ctl->dst_node_index,
1456 name);
1457 } else {
1458 sprintf(hpi_ctl->name, "%s%d %s",
1459 asihpi_src_names[hpi_ctl->src_node_type],
1460 hpi_ctl->src_node_index,
1461 name);
1462 }
1463}
1464
1465/*------------------------------------------------------------
1466 Volume controls
1467 ------------------------------------------------------------*/
1468#define VOL_STEP_mB 1
1469static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1470 struct snd_ctl_elem_info *uinfo)
1471{
1472 u32 h_control = kcontrol->private_value;
1473 u16 err;
1474 /* native gains are in millibels */
1475 short min_gain_mB;
1476 short max_gain_mB;
1477 short step_gain_mB;
1478
1479 err = hpi_volume_query_range(ss, h_control,
1480 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1481 if (err) {
1482 max_gain_mB = 0;
1483 min_gain_mB = -10000;
1484 step_gain_mB = VOL_STEP_mB;
1485 }
1486
1487 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1488 uinfo->count = 2;
1489 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1490 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1491 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1492 return 0;
1493}
1494
1495static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1496 struct snd_ctl_elem_value *ucontrol)
1497{
1498 u32 h_control = kcontrol->private_value;
1499 short an_gain_mB[HPI_MAX_CHANNELS];
1500
1501 hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB));
1502 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1503 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1504
1505 return 0;
1506}
1507
1508static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1509 struct snd_ctl_elem_value *ucontrol)
1510{
1511 int change;
1512 u32 h_control = kcontrol->private_value;
1513 short an_gain_mB[HPI_MAX_CHANNELS];
1514
1515 an_gain_mB[0] =
1516 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1517 an_gain_mB[1] =
1518 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1519 /* change = asihpi->mixer_volume[addr][0] != left ||
1520 asihpi->mixer_volume[addr][1] != right;
1521 */
1522 change = 1;
1523 hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB));
1524 return change;
1525}
1526
1527static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1528
1529static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1530 struct hpi_control *hpi_ctl)
1531{
1532 struct snd_card *card = asihpi->card;
1533 struct snd_kcontrol_new snd_control;
1534
1535 asihpi_ctl_init(&snd_control, hpi_ctl, "volume");
1536 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1537 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1538 snd_control.info = snd_asihpi_volume_info;
1539 snd_control.get = snd_asihpi_volume_get;
1540 snd_control.put = snd_asihpi_volume_put;
1541 snd_control.tlv.p = db_scale_100;
1542
1543 return ctl_add(card, &snd_control, asihpi);
1544}
1545
1546/*------------------------------------------------------------
1547 Level controls
1548 ------------------------------------------------------------*/
1549static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1550 struct snd_ctl_elem_info *uinfo)
1551{
1552 u32 h_control = kcontrol->private_value;
1553 u16 err;
1554 short min_gain_mB;
1555 short max_gain_mB;
1556 short step_gain_mB;
1557
1558 err =
1559 hpi_level_query_range(ss, h_control, &min_gain_mB,
1560 &max_gain_mB, &step_gain_mB);
1561 if (err) {
1562 max_gain_mB = 2400;
1563 min_gain_mB = -1000;
1564 step_gain_mB = 100;
1565 }
1566
1567 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1568 uinfo->count = 2;
1569 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1570 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1571 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1572 return 0;
1573}
1574
1575static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1576 struct snd_ctl_elem_value *ucontrol)
1577{
1578 u32 h_control = kcontrol->private_value;
1579 short an_gain_mB[HPI_MAX_CHANNELS];
1580
1581 hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB));
1582 ucontrol->value.integer.value[0] =
1583 an_gain_mB[0] / HPI_UNITS_PER_dB;
1584 ucontrol->value.integer.value[1] =
1585 an_gain_mB[1] / HPI_UNITS_PER_dB;
1586
1587 return 0;
1588}
1589
1590static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1591 struct snd_ctl_elem_value *ucontrol)
1592{
1593 int change;
1594 u32 h_control = kcontrol->private_value;
1595 short an_gain_mB[HPI_MAX_CHANNELS];
1596
1597 an_gain_mB[0] =
1598 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1599 an_gain_mB[1] =
1600 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1601 /* change = asihpi->mixer_level[addr][0] != left ||
1602 asihpi->mixer_level[addr][1] != right;
1603 */
1604 change = 1;
1605 hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB));
1606 return change;
1607}
1608
1609static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1610
1611static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1612 struct hpi_control *hpi_ctl)
1613{
1614 struct snd_card *card = asihpi->card;
1615 struct snd_kcontrol_new snd_control;
1616
1617 /* can't use 'volume' cos some nodes have volume as well */
1618 asihpi_ctl_init(&snd_control, hpi_ctl, "level");
1619 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1620 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1621 snd_control.info = snd_asihpi_level_info;
1622 snd_control.get = snd_asihpi_level_get;
1623 snd_control.put = snd_asihpi_level_put;
1624 snd_control.tlv.p = db_scale_level;
1625
1626 return ctl_add(card, &snd_control, asihpi);
1627}
1628
1629/*------------------------------------------------------------
1630 AESEBU controls
1631 ------------------------------------------------------------*/
1632
1633/* AESEBU format */
1634static char *asihpi_aesebu_format_names[] =
1635{
1636 "N/A",
1637 "S/PDIF",
1638 "AES/EBU",
1639};
1640
1641static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_info *uinfo)
1643{
1644 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1645 uinfo->count = 1;
1646 uinfo->value.enumerated.items = 3;
1647
1648 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1649 uinfo->value.enumerated.item =
1650 uinfo->value.enumerated.items - 1;
1651
1652 strcpy(uinfo->value.enumerated.name,
1653 asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1654
1655 return 0;
1656}
1657
1658static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol,
1660 u16 (*func)(const struct hpi_hsubsys *, u32, u16 *))
1661{
1662 u32 h_control = kcontrol->private_value;
1663 u16 source, err;
1664
1665 err = func(ss, h_control, &source);
1666
1667 /* default to N/A */
1668 ucontrol->value.enumerated.item[0] = 0;
1669 /* return success but set the control to N/A */
1670 if (err)
1671 return 0;
1672 if (source == HPI_AESEBU_FORMAT_SPDIF)
1673 ucontrol->value.enumerated.item[0] = 1;
1674 if (source == HPI_AESEBU_FORMAT_AESEBU)
1675 ucontrol->value.enumerated.item[0] = 2;
1676
1677 return 0;
1678}
1679
1680static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1681 struct snd_ctl_elem_value *ucontrol,
1682 u16 (*func)(const struct hpi_hsubsys *, u32, u16))
1683{
1684 u32 h_control = kcontrol->private_value;
1685
1686 /* default to S/PDIF */
1687 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1688
1689 if (ucontrol->value.enumerated.item[0] == 1)
1690 source = HPI_AESEBU_FORMAT_SPDIF;
1691 if (ucontrol->value.enumerated.item[0] == 2)
1692 source = HPI_AESEBU_FORMAT_AESEBU;
1693
1694 if (func(ss, h_control, source) != 0)
1695 return -EINVAL;
1696
1697 return 1;
1698}
1699
1700static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1701 struct snd_ctl_elem_value *ucontrol) {
1702 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1703 HPI_AESEBU__receiver_get_format);
1704}
1705
1706static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1707 struct snd_ctl_elem_value *ucontrol) {
1708 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1709 HPI_AESEBU__receiver_set_format);
1710}
1711
1712static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1713 struct snd_ctl_elem_info *uinfo)
1714{
1715 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1716 uinfo->count = 1;
1717
1718 uinfo->value.integer.min = 0;
1719 uinfo->value.integer.max = 0X1F;
1720 uinfo->value.integer.step = 1;
1721
1722 return 0;
1723}
1724
1725static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1726 struct snd_ctl_elem_value *ucontrol) {
1727
1728 u32 h_control = kcontrol->private_value;
1729 u16 status;
1730
1731 hpi_handle_error(HPI_AESEBU__receiver_get_error_status(
1732 ss, h_control, &status));
1733 ucontrol->value.integer.value[0] = status;
1734 return 0;
1735}
1736
1737static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1738 struct hpi_control *hpi_ctl)
1739{
1740 struct snd_card *card = asihpi->card;
1741 struct snd_kcontrol_new snd_control;
1742
1743 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1744 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1745 snd_control.info = snd_asihpi_aesebu_format_info;
1746 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1747 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1748
1749
1750 if (ctl_add(card, &snd_control, asihpi) < 0)
1751 return -EINVAL;
1752
1753 asihpi_ctl_init(&snd_control, hpi_ctl, "status");
1754 snd_control.access =
1755 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1756 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1757 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1758
1759 return ctl_add(card, &snd_control, asihpi);
1760}
1761
1762static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1763 struct snd_ctl_elem_value *ucontrol) {
1764 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1765 HPI_AESEBU__transmitter_get_format);
1766}
1767
1768static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1769 struct snd_ctl_elem_value *ucontrol) {
1770 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1771 HPI_AESEBU__transmitter_set_format);
1772}
1773
1774
1775static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1776 struct hpi_control *hpi_ctl)
1777{
1778 struct snd_card *card = asihpi->card;
1779 struct snd_kcontrol_new snd_control;
1780
1781 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1782 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1783 snd_control.info = snd_asihpi_aesebu_format_info;
1784 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1785 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1786
1787 return ctl_add(card, &snd_control, asihpi);
1788}
1789
1790/*------------------------------------------------------------
1791 Tuner controls
1792 ------------------------------------------------------------*/
1793
1794/* Gain */
1795
1796static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1797 struct snd_ctl_elem_info *uinfo)
1798{
1799 u32 h_control = kcontrol->private_value;
1800 u16 err;
1801 short idx;
1802 u16 gain_range[3];
1803
1804 for (idx = 0; idx < 3; idx++) {
1805 err = hpi_tuner_query_gain(ss, h_control,
1806 idx, &gain_range[idx]);
1807 if (err != 0)
1808 return err;
1809 }
1810
1811 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1812 uinfo->count = 1;
1813 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1814 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1815 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1816 return 0;
1817}
1818
1819static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1820 struct snd_ctl_elem_value *ucontrol)
1821{
1822 /*
1823 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1824 */
1825 u32 h_control = kcontrol->private_value;
1826 short gain;
1827
1828 hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain));
1829 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1830
1831 return 0;
1832}
1833
1834static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1835 struct snd_ctl_elem_value *ucontrol)
1836{
1837 /*
1838 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1839 */
1840 u32 h_control = kcontrol->private_value;
1841 short gain;
1842
1843 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1844 hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain));
1845
1846 return 1;
1847}
1848
1849/* Band */
1850
1851static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1852 u16 *band_list, u32 len) {
1853 u32 h_control = kcontrol->private_value;
1854 u16 err = 0;
1855 u32 i;
1856
1857 for (i = 0; i < len; i++) {
1858 err = hpi_tuner_query_band(ss,
1859 h_control, i, &band_list[i]);
1860 if (err != 0)
1861 break;
1862 }
1863
1864 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1865 return -EIO;
1866
1867 return i;
1868}
1869
1870static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1871 struct snd_ctl_elem_info *uinfo)
1872{
1873 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1874 int num_bands = 0;
1875
1876 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1877 HPI_TUNER_BAND_LAST);
1878
1879 if (num_bands < 0)
1880 return num_bands;
1881
1882 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1883 uinfo->count = 1;
1884 uinfo->value.enumerated.items = num_bands;
1885
1886 if (num_bands > 0) {
1887 if (uinfo->value.enumerated.item >=
1888 uinfo->value.enumerated.items)
1889 uinfo->value.enumerated.item =
1890 uinfo->value.enumerated.items - 1;
1891
1892 strcpy(uinfo->value.enumerated.name,
1893 asihpi_tuner_band_names[
1894 tuner_bands[uinfo->value.enumerated.item]]);
1895
1896 }
1897 return 0;
1898}
1899
1900static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1901 struct snd_ctl_elem_value *ucontrol)
1902{
1903 u32 h_control = kcontrol->private_value;
1904 /*
1905 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1906 */
1907 u16 band, idx;
1908 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1909 u32 num_bands = 0;
1910
1911 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1912 HPI_TUNER_BAND_LAST);
1913
1914 hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band));
1915
1916 ucontrol->value.enumerated.item[0] = -1;
1917 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1918 if (tuner_bands[idx] == band) {
1919 ucontrol->value.enumerated.item[0] = idx;
1920 break;
1921 }
1922
1923 return 0;
1924}
1925
1926static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol)
1928{
1929 /*
1930 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1931 */
1932 u32 h_control = kcontrol->private_value;
1933 u16 band;
1934 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1935 u32 num_bands = 0;
1936
1937 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1938 HPI_TUNER_BAND_LAST);
1939
1940 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1941 hpi_handle_error(hpi_tuner_set_band(ss, h_control, band));
1942
1943 return 1;
1944}
1945
1946/* Freq */
1947
1948static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1949 struct snd_ctl_elem_info *uinfo)
1950{
1951 u32 h_control = kcontrol->private_value;
1952 u16 err;
1953 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1954 u16 num_bands = 0, band_iter, idx;
1955 u32 freq_range[3], temp_freq_range[3];
1956
1957 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1958 HPI_TUNER_BAND_LAST);
1959
1960 freq_range[0] = INT_MAX;
1961 freq_range[1] = 0;
1962 freq_range[2] = INT_MAX;
1963
1964 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1965 for (idx = 0; idx < 3; idx++) {
1966 err = hpi_tuner_query_frequency(ss, h_control,
1967 idx, tuner_bands[band_iter],
1968 &temp_freq_range[idx]);
1969 if (err != 0)
1970 return err;
1971 }
1972
1973 /* skip band with bogus stepping */
1974 if (temp_freq_range[2] <= 0)
1975 continue;
1976
1977 if (temp_freq_range[0] < freq_range[0])
1978 freq_range[0] = temp_freq_range[0];
1979 if (temp_freq_range[1] > freq_range[1])
1980 freq_range[1] = temp_freq_range[1];
1981 if (temp_freq_range[2] < freq_range[2])
1982 freq_range[2] = temp_freq_range[2];
1983 }
1984
1985 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1986 uinfo->count = 1;
1987 uinfo->value.integer.min = ((int)freq_range[0]);
1988 uinfo->value.integer.max = ((int)freq_range[1]);
1989 uinfo->value.integer.step = ((int)freq_range[2]);
1990 return 0;
1991}
1992
1993static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1994 struct snd_ctl_elem_value *ucontrol)
1995{
1996 u32 h_control = kcontrol->private_value;
1997 u32 freq;
1998
1999 hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq));
2000 ucontrol->value.integer.value[0] = freq;
2001
2002 return 0;
2003}
2004
2005static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2006 struct snd_ctl_elem_value *ucontrol)
2007{
2008 u32 h_control = kcontrol->private_value;
2009 u32 freq;
2010
2011 freq = ucontrol->value.integer.value[0];
2012 hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq));
2013
2014 return 1;
2015}
2016
2017/* Tuner control group initializer */
2018static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2019 struct hpi_control *hpi_ctl)
2020{
2021 struct snd_card *card = asihpi->card;
2022 struct snd_kcontrol_new snd_control;
2023
2024 snd_control.private_value = hpi_ctl->h_control;
2025 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2026
2027 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) {
2028 asihpi_ctl_init(&snd_control, hpi_ctl, "gain");
2029 snd_control.info = snd_asihpi_tuner_gain_info;
2030 snd_control.get = snd_asihpi_tuner_gain_get;
2031 snd_control.put = snd_asihpi_tuner_gain_put;
2032
2033 if (ctl_add(card, &snd_control, asihpi) < 0)
2034 return -EINVAL;
2035 }
2036
2037 asihpi_ctl_init(&snd_control, hpi_ctl, "band");
2038 snd_control.info = snd_asihpi_tuner_band_info;
2039 snd_control.get = snd_asihpi_tuner_band_get;
2040 snd_control.put = snd_asihpi_tuner_band_put;
2041
2042 if (ctl_add(card, &snd_control, asihpi) < 0)
2043 return -EINVAL;
2044
2045 asihpi_ctl_init(&snd_control, hpi_ctl, "freq");
2046 snd_control.info = snd_asihpi_tuner_freq_info;
2047 snd_control.get = snd_asihpi_tuner_freq_get;
2048 snd_control.put = snd_asihpi_tuner_freq_put;
2049
2050 return ctl_add(card, &snd_control, asihpi);
2051}
2052
2053/*------------------------------------------------------------
2054 Meter controls
2055 ------------------------------------------------------------*/
2056static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2057 struct snd_ctl_elem_info *uinfo)
2058{
2059 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2060 uinfo->count = HPI_MAX_CHANNELS;
2061 uinfo->value.integer.min = 0;
2062 uinfo->value.integer.max = 0x7FFFFFFF;
2063 return 0;
2064}
2065
2066/* linear values for 10dB steps */
2067static int log2lin[] = {
2068 0x7FFFFFFF, /* 0dB */
2069 679093956,
2070 214748365,
2071 67909396,
2072 21474837,
2073 6790940,
2074 2147484, /* -60dB */
2075 679094,
2076 214748, /* -80 */
2077 67909,
2078 21475, /* -100 */
2079 6791,
2080 2147,
2081 679,
2082 214,
2083 68,
2084 21,
2085 7,
2086 2
2087};
2088
2089static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2090 struct snd_ctl_elem_value *ucontrol)
2091{
2092 u32 h_control = kcontrol->private_value;
2093 short an_gain_mB[HPI_MAX_CHANNELS], i;
2094 u16 err;
2095
2096 err = hpi_meter_get_peak(ss, h_control, an_gain_mB);
2097
2098 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2099 if (err) {
2100 ucontrol->value.integer.value[i] = 0;
2101 } else if (an_gain_mB[i] >= 0) {
2102 ucontrol->value.integer.value[i] =
2103 an_gain_mB[i] << 16;
2104 } else {
2105 /* -ve is log value in millibels < -60dB,
2106 * convert to (roughly!) linear,
2107 */
2108 ucontrol->value.integer.value[i] =
2109 log2lin[an_gain_mB[i] / -1000];
2110 }
2111 }
2112 return 0;
2113}
2114
2115static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2116 struct hpi_control *hpi_ctl, int subidx)
2117{
2118 struct snd_card *card = asihpi->card;
2119 struct snd_kcontrol_new snd_control;
2120
2121 asihpi_ctl_init(&snd_control, hpi_ctl, "meter");
2122 snd_control.access =
2123 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2124 snd_control.info = snd_asihpi_meter_info;
2125 snd_control.get = snd_asihpi_meter_get;
2126
2127 snd_control.index = subidx;
2128
2129 return ctl_add(card, &snd_control, asihpi);
2130}
2131
2132/*------------------------------------------------------------
2133 Multiplexer controls
2134 ------------------------------------------------------------*/
2135static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2136{
2137 u32 h_control = snd_control->private_value;
2138 struct hpi_control hpi_ctl;
2139 int s, err;
2140 for (s = 0; s < 32; s++) {
2141 err = hpi_multiplexer_query_source(ss, h_control, s,
2142 &hpi_ctl.
2143 src_node_type,
2144 &hpi_ctl.
2145 src_node_index);
2146 if (err)
2147 break;
2148 }
2149 return s;
2150}
2151
2152static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2153 struct snd_ctl_elem_info *uinfo)
2154{
2155 int err;
2156 u16 src_node_type, src_node_index;
2157 u32 h_control = kcontrol->private_value;
2158
2159 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2160 uinfo->count = 1;
2161 uinfo->value.enumerated.items =
2162 snd_card_asihpi_mux_count_sources(kcontrol);
2163
2164 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2165 uinfo->value.enumerated.item =
2166 uinfo->value.enumerated.items - 1;
2167
2168 err =
2169 hpi_multiplexer_query_source(ss, h_control,
2170 uinfo->value.enumerated.item,
2171 &src_node_type, &src_node_index);
2172
2173 sprintf(uinfo->value.enumerated.name, "%s %d",
2174 asihpi_src_names[src_node_type - HPI_SOURCENODE_BASE],
2175 src_node_index);
2176 return 0;
2177}
2178
2179static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2180 struct snd_ctl_elem_value *ucontrol)
2181{
2182 u32 h_control = kcontrol->private_value;
2183 u16 source_type, source_index;
2184 u16 src_node_type, src_node_index;
2185 int s;
2186
2187 hpi_handle_error(hpi_multiplexer_get_source(ss, h_control,
2188 &source_type, &source_index));
2189 /* Should cache this search result! */
2190 for (s = 0; s < 256; s++) {
2191 if (hpi_multiplexer_query_source(ss, h_control, s,
2192 &src_node_type, &src_node_index))
2193 break;
2194
2195 if ((source_type == src_node_type)
2196 && (source_index == src_node_index)) {
2197 ucontrol->value.enumerated.item[0] = s;
2198 return 0;
2199 }
2200 }
2201 snd_printd(KERN_WARNING
2202 "control %x failed to match mux source %hu %hu\n",
2203 h_control, source_type, source_index);
2204 ucontrol->value.enumerated.item[0] = 0;
2205 return 0;
2206}
2207
2208static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2209 struct snd_ctl_elem_value *ucontrol)
2210{
2211 int change;
2212 u32 h_control = kcontrol->private_value;
2213 u16 source_type, source_index;
2214 u16 e;
2215
2216 change = 1;
2217
2218 e = hpi_multiplexer_query_source(ss, h_control,
2219 ucontrol->value.enumerated.item[0],
2220 &source_type, &source_index);
2221 if (!e)
2222 hpi_handle_error(
2223 hpi_multiplexer_set_source(ss, h_control,
2224 source_type, source_index));
2225 return change;
2226}
2227
2228
2229static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2230 struct hpi_control *hpi_ctl)
2231{
2232 struct snd_card *card = asihpi->card;
2233 struct snd_kcontrol_new snd_control;
2234
2235#if ASI_STYLE_NAMES
2236 asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2237#else
2238 asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2239#endif
2240 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2241 snd_control.info = snd_asihpi_mux_info;
2242 snd_control.get = snd_asihpi_mux_get;
2243 snd_control.put = snd_asihpi_mux_put;
2244
2245 return ctl_add(card, &snd_control, asihpi);
2246
2247}
2248
2249/*------------------------------------------------------------
2250 Channel mode controls
2251 ------------------------------------------------------------*/
2252static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2253 struct snd_ctl_elem_info *uinfo)
2254{
2255 static char *mode_names[HPI_CHANNEL_MODE_LAST] = {
2256 "normal", "swap",
2257 "from_left", "from_right",
2258 "to_left", "to_right"
2259 };
2260
2261 u32 h_control = kcontrol->private_value;
2262 u16 mode;
2263 int i;
2264
2265 /* HPI channel mode values can be from 1 to 6
2266 Some adapters only support a contiguous subset
2267 */
2268 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2269 if (hpi_channel_mode_query_mode(
2270 ss, h_control, i, &mode))
2271 break;
2272
2273 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2274 uinfo->count = 1;
2275 uinfo->value.enumerated.items = i;
2276
2277 if (uinfo->value.enumerated.item >= i)
2278 uinfo->value.enumerated.item = i - 1;
2279
2280 strcpy(uinfo->value.enumerated.name,
2281 mode_names[uinfo->value.enumerated.item]);
2282
2283 return 0;
2284}
2285
2286static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2287 struct snd_ctl_elem_value *ucontrol)
2288{
2289 u32 h_control = kcontrol->private_value;
2290 u16 mode;
2291
2292 if (hpi_channel_mode_get(ss, h_control, &mode))
2293 mode = 1;
2294
2295 ucontrol->value.enumerated.item[0] = mode - 1;
2296
2297 return 0;
2298}
2299
2300static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2301 struct snd_ctl_elem_value *ucontrol)
2302{
2303 int change;
2304 u32 h_control = kcontrol->private_value;
2305
2306 change = 1;
2307
2308 hpi_handle_error(hpi_channel_mode_set(ss, h_control,
2309 ucontrol->value.enumerated.item[0] + 1));
2310 return change;
2311}
2312
2313
2314static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2315 struct hpi_control *hpi_ctl)
2316{
2317 struct snd_card *card = asihpi->card;
2318 struct snd_kcontrol_new snd_control;
2319
2320 asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode");
2321 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2322 snd_control.info = snd_asihpi_cmode_info;
2323 snd_control.get = snd_asihpi_cmode_get;
2324 snd_control.put = snd_asihpi_cmode_put;
2325
2326 return ctl_add(card, &snd_control, asihpi);
2327}
2328
2329/*------------------------------------------------------------
2330 Sampleclock source controls
2331 ------------------------------------------------------------*/
2332
2333static char *sampleclock_sources[MAX_CLOCKSOURCES] =
2334 { "N/A", "local PLL", "AES/EBU sync", "word external", "word header",
2335 "SMPTE", "AES/EBU in1", "auto", "network", "invalid",
2336 "prev module",
2337 "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5",
2338 "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"};
2339
2340
2341
2342static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2343 struct snd_ctl_elem_info *uinfo)
2344{
2345 struct snd_card_asihpi *asihpi =
2346 (struct snd_card_asihpi *)(kcontrol->private_data);
2347 struct clk_cache *clkcache = &asihpi->cc;
2348 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2349 uinfo->count = 1;
2350 uinfo->value.enumerated.items = clkcache->count;
2351
2352 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2353 uinfo->value.enumerated.item =
2354 uinfo->value.enumerated.items - 1;
2355
2356 strcpy(uinfo->value.enumerated.name,
2357 clkcache->s[uinfo->value.enumerated.item].name);
2358 return 0;
2359}
2360
2361static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2362 struct snd_ctl_elem_value *ucontrol)
2363{
2364 struct snd_card_asihpi *asihpi =
2365 (struct snd_card_asihpi *)(kcontrol->private_data);
2366 struct clk_cache *clkcache = &asihpi->cc;
2367 u32 h_control = kcontrol->private_value;
2368 u16 source, srcindex = 0;
2369 int i;
2370
2371 ucontrol->value.enumerated.item[0] = 0;
2372 if (hpi_sample_clock_get_source(ss, h_control, &source))
2373 source = 0;
2374
2375 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2376 if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex))
2377 srcindex = 0;
2378
2379 for (i = 0; i < clkcache->count; i++)
2380 if ((clkcache->s[i].source == source) &&
2381 (clkcache->s[i].index == srcindex))
2382 break;
2383
2384 ucontrol->value.enumerated.item[0] = i;
2385
2386 return 0;
2387}
2388
2389static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2390 struct snd_ctl_elem_value *ucontrol)
2391{
2392 struct snd_card_asihpi *asihpi =
2393 (struct snd_card_asihpi *)(kcontrol->private_data);
2394 struct clk_cache *clkcache = &asihpi->cc;
2395 int change, item;
2396 u32 h_control = kcontrol->private_value;
2397
2398 change = 1;
2399 item = ucontrol->value.enumerated.item[0];
2400 if (item >= clkcache->count)
2401 item = clkcache->count-1;
2402
2403 hpi_handle_error(hpi_sample_clock_set_source(ss,
2404 h_control, clkcache->s[item].source));
2405
2406 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2407 hpi_handle_error(hpi_sample_clock_set_source_index(ss,
2408 h_control, clkcache->s[item].index));
2409 return change;
2410}
2411
2412/*------------------------------------------------------------
2413 Clkrate controls
2414 ------------------------------------------------------------*/
2415/* Need to change this to enumerated control with list of rates */
2416static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2417 struct snd_ctl_elem_info *uinfo)
2418{
2419 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2420 uinfo->count = 1;
2421 uinfo->value.integer.min = 8000;
2422 uinfo->value.integer.max = 192000;
2423 uinfo->value.integer.step = 100;
2424
2425 return 0;
2426}
2427
2428static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2429 struct snd_ctl_elem_value *ucontrol)
2430{
2431 u32 h_control = kcontrol->private_value;
2432 u32 rate;
2433 u16 e;
2434
2435 e = hpi_sample_clock_get_local_rate(ss, h_control, &rate);
2436 if (!e)
2437 ucontrol->value.integer.value[0] = rate;
2438 else
2439 ucontrol->value.integer.value[0] = 0;
2440 return 0;
2441}
2442
2443static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2444 struct snd_ctl_elem_value *ucontrol)
2445{
2446 int change;
2447 u32 h_control = kcontrol->private_value;
2448
2449 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2450 asihpi->mixer_clkrate[addr][1] != right;
2451 */
2452 change = 1;
2453 hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control,
2454 ucontrol->value.integer.value[0]));
2455 return change;
2456}
2457
2458static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2459 struct snd_ctl_elem_info *uinfo)
2460{
2461 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2462 uinfo->count = 1;
2463 uinfo->value.integer.min = 8000;
2464 uinfo->value.integer.max = 192000;
2465 uinfo->value.integer.step = 100;
2466
2467 return 0;
2468}
2469
2470static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2471 struct snd_ctl_elem_value *ucontrol)
2472{
2473 u32 h_control = kcontrol->private_value;
2474 u32 rate;
2475 u16 e;
2476
2477 e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate);
2478 if (!e)
2479 ucontrol->value.integer.value[0] = rate;
2480 else
2481 ucontrol->value.integer.value[0] = 0;
2482 return 0;
2483}
2484
2485static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2486 struct hpi_control *hpi_ctl)
2487{
2488 struct snd_card *card = asihpi->card;
2489 struct snd_kcontrol_new snd_control;
2490
2491 struct clk_cache *clkcache = &asihpi->cc;
2492 u32 hSC = hpi_ctl->h_control;
2493 int has_aes_in = 0;
2494 int i, j;
2495 u16 source;
2496
2497 snd_control.private_value = hpi_ctl->h_control;
2498
2499 clkcache->has_local = 0;
2500
2501 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2502 if (hpi_sample_clock_query_source(ss, hSC,
2503 i, &source))
2504 break;
2505 clkcache->s[i].source = source;
2506 clkcache->s[i].index = 0;
2507 clkcache->s[i].name = sampleclock_sources[source];
2508 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2509 has_aes_in = 1;
2510 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2511 clkcache->has_local = 1;
2512 }
2513 if (has_aes_in)
2514 /* already will have picked up index 0 above */
2515 for (j = 1; j < 8; j++) {
2516 if (hpi_sample_clock_query_source_index(ss, hSC,
2517 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2518 &source))
2519 break;
2520 clkcache->s[i].source =
2521 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2522 clkcache->s[i].index = j;
2523 clkcache->s[i].name = sampleclock_sources[
2524 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2525 i++;
2526 }
2527 clkcache->count = i;
2528
2529 asihpi_ctl_init(&snd_control, hpi_ctl, "source");
2530 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2531 snd_control.info = snd_asihpi_clksrc_info;
2532 snd_control.get = snd_asihpi_clksrc_get;
2533 snd_control.put = snd_asihpi_clksrc_put;
2534 if (ctl_add(card, &snd_control, asihpi) < 0)
2535 return -EINVAL;
2536
2537
2538 if (clkcache->has_local) {
2539 asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate");
2540 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2541 snd_control.info = snd_asihpi_clklocal_info;
2542 snd_control.get = snd_asihpi_clklocal_get;
2543 snd_control.put = snd_asihpi_clklocal_put;
2544
2545
2546 if (ctl_add(card, &snd_control, asihpi) < 0)
2547 return -EINVAL;
2548 }
2549
2550 asihpi_ctl_init(&snd_control, hpi_ctl, "rate");
2551 snd_control.access =
2552 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2553 snd_control.info = snd_asihpi_clkrate_info;
2554 snd_control.get = snd_asihpi_clkrate_get;
2555
2556 return ctl_add(card, &snd_control, asihpi);
2557}
2558/*------------------------------------------------------------
2559 Mixer
2560 ------------------------------------------------------------*/
2561
2562static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2563{
2564 struct snd_card *card = asihpi->card;
2565 unsigned int idx = 0;
2566 unsigned int subindex = 0;
2567 int err;
2568 struct hpi_control hpi_ctl, prev_ctl;
2569
2570 if (snd_BUG_ON(!asihpi))
2571 return -EINVAL;
2572 strcpy(card->mixername, "asihpi mixer");
2573
2574 err =
2575 hpi_mixer_open(ss, asihpi->adapter_index,
2576 &asihpi->h_mixer);
2577 hpi_handle_error(err);
2578 if (err)
2579 return -err;
2580
2581 for (idx = 0; idx < 2000; idx++) {
2582 err = hpi_mixer_get_control_by_index(
2583 ss, asihpi->h_mixer,
2584 idx,
2585 &hpi_ctl.src_node_type,
2586 &hpi_ctl.src_node_index,
2587 &hpi_ctl.dst_node_type,
2588 &hpi_ctl.dst_node_index,
2589 &hpi_ctl.control_type,
2590 &hpi_ctl.h_control);
2591 if (err) {
2592 if (err == HPI_ERROR_CONTROL_DISABLED) {
2593 if (mixer_dump)
2594 snd_printk(KERN_INFO
2595 "disabled HPI control(%d)\n",
2596 idx);
2597 continue;
2598 } else
2599 break;
2600
2601 }
2602
2603 hpi_ctl.src_node_type -= HPI_SOURCENODE_BASE;
2604 hpi_ctl.dst_node_type -= HPI_DESTNODE_BASE;
2605
2606 /* ASI50xx in SSX mode has multiple meters on the same node.
2607 Use subindex to create distinct ALSA controls
2608 for any duplicated controls.
2609 */
2610 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2611 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2612 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2613 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2614 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2615 subindex++;
2616 else
2617 subindex = 0;
2618
2619 prev_ctl = hpi_ctl;
2620
2621 switch (hpi_ctl.control_type) {
2622 case HPI_CONTROL_VOLUME:
2623 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2624 break;
2625 case HPI_CONTROL_LEVEL:
2626 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2627 break;
2628 case HPI_CONTROL_MULTIPLEXER:
2629 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2630 break;
2631 case HPI_CONTROL_CHANNEL_MODE:
2632 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2633 break;
2634 case HPI_CONTROL_METER:
2635 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2636 break;
2637 case HPI_CONTROL_SAMPLECLOCK:
2638 err = snd_asihpi_sampleclock_add(
2639 asihpi, &hpi_ctl);
2640 break;
2641 case HPI_CONTROL_CONNECTION: /* ignore these */
2642 continue;
2643 case HPI_CONTROL_TUNER:
2644 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2645 break;
2646 case HPI_CONTROL_AESEBU_TRANSMITTER:
2647 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2648 break;
2649 case HPI_CONTROL_AESEBU_RECEIVER:
2650 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2651 break;
2652 case HPI_CONTROL_VOX:
2653 case HPI_CONTROL_BITSTREAM:
2654 case HPI_CONTROL_MICROPHONE:
2655 case HPI_CONTROL_PARAMETRIC_EQ:
2656 case HPI_CONTROL_COMPANDER:
2657 default:
2658 if (mixer_dump)
2659 snd_printk(KERN_INFO
2660 "untranslated HPI control"
2661 "(%d) %d %d %d %d %d\n",
2662 idx,
2663 hpi_ctl.control_type,
2664 hpi_ctl.src_node_type,
2665 hpi_ctl.src_node_index,
2666 hpi_ctl.dst_node_type,
2667 hpi_ctl.dst_node_index);
2668 continue;
2669 };
2670 if (err < 0)
2671 return err;
2672 }
2673 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2674 hpi_handle_error(err);
2675
2676 snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2677
2678 return 0;
2679}
2680
2681/*------------------------------------------------------------
2682 /proc interface
2683 ------------------------------------------------------------*/
2684
2685static void
2686snd_asihpi_proc_read(struct snd_info_entry *entry,
2687 struct snd_info_buffer *buffer)
2688{
2689 struct snd_card_asihpi *asihpi = entry->private_data;
2690 u16 version;
2691 u32 h_control;
2692 u32 rate = 0;
2693 u16 source = 0;
2694 int err;
2695
2696 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2697 snd_iprintf(buffer,
2698 "adapter ID=%4X\n_index=%d\n"
2699 "num_outstreams=%d\n_num_instreams=%d\n",
2700 asihpi->type, asihpi->adapter_index,
2701 asihpi->num_outstreams, asihpi->num_instreams);
2702
2703 version = asihpi->version;
2704 snd_iprintf(buffer,
2705 "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
2706 asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
2707 version & 0x7,
2708 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2709
2710 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2711 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2712 HPI_CONTROL_SAMPLECLOCK, &h_control);
2713
2714 if (!err) {
2715 err = hpi_sample_clock_get_sample_rate(ss,
2716 h_control, &rate);
2717 err += hpi_sample_clock_get_source(ss, h_control, &source);
2718
2719 if (!err)
2720 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
2721 rate, sampleclock_sources[source]);
2722 }
2723
2724}
2725
2726
2727static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2728{
2729 struct snd_info_entry *entry;
2730
2731 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2732 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2733}
2734
2735/*------------------------------------------------------------
2736 HWDEP
2737 ------------------------------------------------------------*/
2738
2739static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2740{
2741 if (enable_hpi_hwdep)
2742 return 0;
2743 else
2744 return -ENODEV;
2745
2746}
2747
2748static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2749{
2750 if (enable_hpi_hwdep)
2751 return asihpi_hpi_release(file);
2752 else
2753 return -ENODEV;
2754}
2755
2756static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2757 unsigned int cmd, unsigned long arg)
2758{
2759 if (enable_hpi_hwdep)
2760 return asihpi_hpi_ioctl(file, cmd, arg);
2761 else
2762 return -ENODEV;
2763}
2764
2765
2766/* results in /dev/snd/hwC#D0 file for each card with index #
2767 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2768*/
2769static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2770 int device, struct snd_hwdep **rhwdep)
2771{
2772 struct snd_hwdep *hw;
2773 int err;
2774
2775 if (rhwdep)
2776 *rhwdep = NULL;
2777 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2778 if (err < 0)
2779 return err;
2780 strcpy(hw->name, "asihpi (HPI)");
2781 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2782 hw->ops.open = snd_asihpi_hpi_open;
2783 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2784 hw->ops.release = snd_asihpi_hpi_release;
2785 hw->private_data = asihpi;
2786 if (rhwdep)
2787 *rhwdep = hw;
2788 return 0;
2789}
2790
2791/*------------------------------------------------------------
2792 CARD
2793 ------------------------------------------------------------*/
2794static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2795 const struct pci_device_id *pci_id)
2796{
2797 int err;
2798
2799 u16 version;
2800 int pcm_substreams;
2801
2802 struct hpi_adapter *hpi_card;
2803 struct snd_card *card;
2804 struct snd_card_asihpi *asihpi;
2805
2806 u32 h_control;
2807 u32 h_stream;
2808
2809 static int dev;
2810 if (dev >= SNDRV_CARDS)
2811 return -ENODEV;
2812
2813 /* Should this be enable[hpi_card->index] ? */
2814 if (!enable[dev]) {
2815 dev++;
2816 return -ENOENT;
2817 }
2818
2819 err = asihpi_adapter_probe(pci_dev, pci_id);
2820 if (err < 0)
2821 return err;
2822
2823 hpi_card = pci_get_drvdata(pci_dev);
2824 /* first try to give the card the same index as its hardware index */
2825 err = snd_card_create(hpi_card->index,
2826 id[hpi_card->index], THIS_MODULE,
2827 sizeof(struct snd_card_asihpi),
2828 &card);
2829 if (err < 0) {
2830 /* if that fails, try the default index==next available */
2831 err =
2832 snd_card_create(index[dev], id[dev],
2833 THIS_MODULE,
2834 sizeof(struct snd_card_asihpi),
2835 &card);
2836 if (err < 0)
2837 return err;
2838 snd_printk(KERN_WARNING
2839 "**** WARNING **** adapter index %d->ALSA index %d\n",
2840 hpi_card->index, card->number);
2841 }
2842
2843 asihpi = (struct snd_card_asihpi *) card->private_data;
2844 asihpi->card = card;
2845 asihpi->pci = hpi_card->pci;
2846 asihpi->adapter_index = hpi_card->index;
2847 hpi_handle_error(hpi_adapter_get_info(ss,
2848 asihpi->adapter_index,
2849 &asihpi->num_outstreams,
2850 &asihpi->num_instreams,
2851 &asihpi->version,
2852 &asihpi->serial_number, &asihpi->type));
2853
2854 version = asihpi->version;
2855 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2856 "num_instreams=%d S/N=%d\n"
2857 "hw version %c%d DSP code version %03d\n",
2858 asihpi->type, asihpi->adapter_index,
2859 asihpi->num_outstreams,
2860 asihpi->num_instreams, asihpi->serial_number,
2861 ((version >> 3) & 0xf) + 'A',
2862 version & 0x7,
2863 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2864
2865 pcm_substreams = asihpi->num_outstreams;
2866 if (pcm_substreams < asihpi->num_instreams)
2867 pcm_substreams = asihpi->num_instreams;
2868
2869 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2870 HPI_ADAPTER_PROPERTY_CAPS1,
2871 NULL, &asihpi->support_grouping);
2872 if (err)
2873 asihpi->support_grouping = 0;
2874
2875 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2876 HPI_ADAPTER_PROPERTY_CAPS2,
2877 &asihpi->support_mrx, NULL);
2878 if (err)
2879 asihpi->support_mrx = 0;
2880
2881 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2882 HPI_ADAPTER_PROPERTY_INTERVAL,
2883 NULL, &asihpi->update_interval_frames);
2884 if (err)
2885 asihpi->update_interval_frames = 512;
2886
2887 hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index,
2888 0, &h_stream));
2889
2890 err = hpi_instream_host_buffer_free(ss, h_stream);
2891 asihpi->support_mmap = (!err);
2892
2893 hpi_handle_error(hpi_instream_close(ss, h_stream));
2894
2895 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2896 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2897 &asihpi->in_max_chans, &asihpi->out_max_chans);
2898 if (err) {
2899 asihpi->in_max_chans = 2;
2900 asihpi->out_max_chans = 2;
2901 }
2902
2903 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n",
2904 asihpi->support_mmap,
2905 asihpi->support_grouping,
2906 asihpi->support_mrx
2907 );
2908
2909
2910 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2911 if (err < 0) {
2912 snd_printk(KERN_ERR "pcm_new failed\n");
2913 goto __nodev;
2914 }
2915 err = snd_card_asihpi_mixer_new(asihpi);
2916 if (err < 0) {
2917 snd_printk(KERN_ERR "mixer_new failed\n");
2918 goto __nodev;
2919 }
2920
2921 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2922 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2923 HPI_CONTROL_SAMPLECLOCK, &h_control);
2924
2925 if (!err)
2926 err = hpi_sample_clock_set_local_rate(
2927 ss, h_control, adapter_fs);
2928
2929 snd_asihpi_proc_init(asihpi);
2930
2931 /* always create, can be enabled or disabled dynamically
2932 by enable_hwdep module param*/
2933 snd_asihpi_hpi_new(asihpi, 0, NULL);
2934
2935 if (asihpi->support_mmap)
2936 strcpy(card->driver, "ASIHPI-MMAP");
2937 else
2938 strcpy(card->driver, "ASIHPI");
2939
2940 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2941 sprintf(card->longname, "%s %i",
2942 card->shortname, asihpi->adapter_index);
2943 err = snd_card_register(card);
2944 if (!err) {
2945 hpi_card->snd_card_asihpi = card;
2946 dev++;
2947 return 0;
2948 }
2949__nodev:
2950 snd_card_free(card);
2951 snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2952 return err;
2953
2954}
2955
2956static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2957{
2958 struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
2959
2960 snd_card_free(hpi_card->snd_card_asihpi);
2961 hpi_card->snd_card_asihpi = NULL;
2962 asihpi_adapter_remove(pci_dev);
2963}
2964
2965static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2966 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2967 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2968 (kernel_ulong_t)HPI_6205},
2969 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2970 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2971 (kernel_ulong_t)HPI_6000},
2972 {0,}
2973};
2974MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2975
2976static struct pci_driver driver = {
2977 .name = "asihpi",
2978 .id_table = asihpi_pci_tbl,
2979 .probe = snd_asihpi_probe,
2980 .remove = __devexit_p(snd_asihpi_remove),
2981#ifdef CONFIG_PM
2982/* .suspend = snd_asihpi_suspend,
2983 .resume = snd_asihpi_resume, */
2984#endif
2985};
2986
2987static int __init snd_asihpi_init(void)
2988{
2989 asihpi_init();
2990 return pci_register_driver(&driver);
2991}
2992
2993static void __exit snd_asihpi_exit(void)
2994{
2995
2996 pci_unregister_driver(&driver);
2997 asihpi_exit();
2998}
2999
3000module_init(snd_asihpi_init)
3001module_exit(snd_asihpi_exit)
3002