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