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