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