]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - sound/pci/asihpi/asihpi.c
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-jammy-kernel.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,
1328 snd_dma_pci_data(asihpi->pci),
1329 64*1024, BUFFER_BYTES_MAX);
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{
1522 int change;
1523 u32 h_control = kcontrol->private_value;
1524 short an_gain_mB[HPI_MAX_CHANNELS];
1525
1526 an_gain_mB[0] =
1527 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1528 an_gain_mB[1] =
1529 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1530 /* change = asihpi->mixer_volume[addr][0] != left ||
1531 asihpi->mixer_volume[addr][1] != right;
1532 */
1533 change = 1;
ba94455c 1534 hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
719f82d3
EB
1535 return change;
1536}
1537
1538static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1539
000477a0 1540#define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
fe0aa88e
EB
1541
1542static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
1543 struct snd_ctl_elem_value *ucontrol)
1544{
1545 u32 h_control = kcontrol->private_value;
1546 u32 mute;
1547
1548 hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
1549 ucontrol->value.integer.value[0] = mute ? 0 : 1;
1550
1551 return 0;
1552}
1553
1554static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
1555 struct snd_ctl_elem_value *ucontrol)
1556{
1557 u32 h_control = kcontrol->private_value;
1558 int change = 1;
1559 /* HPI currently only supports all or none muting of multichannel volume
1560 ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
1561 */
1562 int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
1563 hpi_handle_error(hpi_volume_set_mute(h_control, mute));
1564 return change;
1565}
1566
e23e7a14
BP
1567static int snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1568 struct hpi_control *hpi_ctl)
719f82d3
EB
1569{
1570 struct snd_card *card = asihpi->card;
1571 struct snd_kcontrol_new snd_control;
fe0aa88e
EB
1572 int err;
1573 u32 mute;
719f82d3 1574
e64b1a28 1575 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
719f82d3
EB
1576 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1577 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1578 snd_control.info = snd_asihpi_volume_info;
1579 snd_control.get = snd_asihpi_volume_get;
1580 snd_control.put = snd_asihpi_volume_put;
1581 snd_control.tlv.p = db_scale_100;
1582
fe0aa88e
EB
1583 err = ctl_add(card, &snd_control, asihpi);
1584 if (err)
1585 return err;
1586
1587 if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
1588 asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
1589 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1590 snd_control.info = snd_asihpi_volume_mute_info;
1591 snd_control.get = snd_asihpi_volume_mute_get;
1592 snd_control.put = snd_asihpi_volume_mute_put;
1593 err = ctl_add(card, &snd_control, asihpi);
1594 }
1595 return err;
719f82d3
EB
1596}
1597
1598/*------------------------------------------------------------
1599 Level controls
1600 ------------------------------------------------------------*/
1601static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1602 struct snd_ctl_elem_info *uinfo)
1603{
1604 u32 h_control = kcontrol->private_value;
1605 u16 err;
1606 short min_gain_mB;
1607 short max_gain_mB;
1608 short step_gain_mB;
1609
1610 err =
ba94455c 1611 hpi_level_query_range(h_control, &min_gain_mB,
719f82d3
EB
1612 &max_gain_mB, &step_gain_mB);
1613 if (err) {
1614 max_gain_mB = 2400;
1615 min_gain_mB = -1000;
1616 step_gain_mB = 100;
1617 }
1618
1619 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1620 uinfo->count = 2;
1621 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1622 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1623 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1624 return 0;
1625}
1626
1627static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1628 struct snd_ctl_elem_value *ucontrol)
1629{
1630 u32 h_control = kcontrol->private_value;
1631 short an_gain_mB[HPI_MAX_CHANNELS];
1632
ba94455c 1633 hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
719f82d3
EB
1634 ucontrol->value.integer.value[0] =
1635 an_gain_mB[0] / HPI_UNITS_PER_dB;
1636 ucontrol->value.integer.value[1] =
1637 an_gain_mB[1] / HPI_UNITS_PER_dB;
1638
1639 return 0;
1640}
1641
1642static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1643 struct snd_ctl_elem_value *ucontrol)
1644{
1645 int change;
1646 u32 h_control = kcontrol->private_value;
1647 short an_gain_mB[HPI_MAX_CHANNELS];
1648
1649 an_gain_mB[0] =
1650 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1651 an_gain_mB[1] =
1652 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1653 /* change = asihpi->mixer_level[addr][0] != left ||
1654 asihpi->mixer_level[addr][1] != right;
1655 */
1656 change = 1;
ba94455c 1657 hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
719f82d3
EB
1658 return change;
1659}
1660
1661static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1662
e23e7a14
BP
1663static int snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1664 struct hpi_control *hpi_ctl)
719f82d3
EB
1665{
1666 struct snd_card *card = asihpi->card;
1667 struct snd_kcontrol_new snd_control;
1668
1669 /* can't use 'volume' cos some nodes have volume as well */
e64b1a28 1670 asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
719f82d3
EB
1671 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1672 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1673 snd_control.info = snd_asihpi_level_info;
1674 snd_control.get = snd_asihpi_level_get;
1675 snd_control.put = snd_asihpi_level_put;
1676 snd_control.tlv.p = db_scale_level;
1677
1678 return ctl_add(card, &snd_control, asihpi);
1679}
1680
1681/*------------------------------------------------------------
1682 AESEBU controls
1683 ------------------------------------------------------------*/
1684
1685/* AESEBU format */
ba94455c
EB
1686static const char * const asihpi_aesebu_format_names[] = {
1687 "N/A", "S/PDIF", "AES/EBU" };
719f82d3
EB
1688
1689static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1690 struct snd_ctl_elem_info *uinfo)
1691{
30d0ae42 1692 return snd_ctl_enum_info(uinfo, 1, 3, asihpi_aesebu_format_names);
719f82d3
EB
1693}
1694
1695static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1696 struct snd_ctl_elem_value *ucontrol,
ba94455c 1697 u16 (*func)(u32, u16 *))
719f82d3
EB
1698{
1699 u32 h_control = kcontrol->private_value;
1700 u16 source, err;
1701
ba94455c 1702 err = func(h_control, &source);
719f82d3
EB
1703
1704 /* default to N/A */
1705 ucontrol->value.enumerated.item[0] = 0;
1706 /* return success but set the control to N/A */
1707 if (err)
1708 return 0;
1709 if (source == HPI_AESEBU_FORMAT_SPDIF)
1710 ucontrol->value.enumerated.item[0] = 1;
1711 if (source == HPI_AESEBU_FORMAT_AESEBU)
1712 ucontrol->value.enumerated.item[0] = 2;
1713
1714 return 0;
1715}
1716
1717static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1718 struct snd_ctl_elem_value *ucontrol,
ba94455c 1719 u16 (*func)(u32, u16))
719f82d3
EB
1720{
1721 u32 h_control = kcontrol->private_value;
1722
1723 /* default to S/PDIF */
1724 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1725
1726 if (ucontrol->value.enumerated.item[0] == 1)
1727 source = HPI_AESEBU_FORMAT_SPDIF;
1728 if (ucontrol->value.enumerated.item[0] == 2)
1729 source = HPI_AESEBU_FORMAT_AESEBU;
1730
ba94455c 1731 if (func(h_control, source) != 0)
719f82d3
EB
1732 return -EINVAL;
1733
1734 return 1;
1735}
1736
1737static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1738 struct snd_ctl_elem_value *ucontrol) {
1739 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
ba94455c 1740 hpi_aesebu_receiver_get_format);
719f82d3
EB
1741}
1742
1743static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1744 struct snd_ctl_elem_value *ucontrol) {
1745 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
ba94455c 1746 hpi_aesebu_receiver_set_format);
719f82d3
EB
1747}
1748
1749static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1750 struct snd_ctl_elem_info *uinfo)
1751{
1752 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1753 uinfo->count = 1;
1754
1755 uinfo->value.integer.min = 0;
1756 uinfo->value.integer.max = 0X1F;
1757 uinfo->value.integer.step = 1;
1758
1759 return 0;
1760}
1761
1762static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1763 struct snd_ctl_elem_value *ucontrol) {
1764
1765 u32 h_control = kcontrol->private_value;
1766 u16 status;
1767
ba94455c
EB
1768 hpi_handle_error(hpi_aesebu_receiver_get_error_status(
1769 h_control, &status));
719f82d3
EB
1770 ucontrol->value.integer.value[0] = status;
1771 return 0;
1772}
1773
e23e7a14
BP
1774static int snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1775 struct hpi_control *hpi_ctl)
719f82d3
EB
1776{
1777 struct snd_card *card = asihpi->card;
1778 struct snd_kcontrol_new snd_control;
1779
e64b1a28 1780 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
719f82d3
EB
1781 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1782 snd_control.info = snd_asihpi_aesebu_format_info;
1783 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1784 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1785
1786
1787 if (ctl_add(card, &snd_control, asihpi) < 0)
1788 return -EINVAL;
1789
e64b1a28 1790 asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
719f82d3
EB
1791 snd_control.access =
1792 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1793 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1794 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1795
1796 return ctl_add(card, &snd_control, asihpi);
1797}
1798
1799static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1800 struct snd_ctl_elem_value *ucontrol) {
1801 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
ba94455c 1802 hpi_aesebu_transmitter_get_format);
719f82d3
EB
1803}
1804
1805static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1806 struct snd_ctl_elem_value *ucontrol) {
1807 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
ba94455c 1808 hpi_aesebu_transmitter_set_format);
719f82d3
EB
1809}
1810
1811
e23e7a14
BP
1812static int snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1813 struct hpi_control *hpi_ctl)
719f82d3
EB
1814{
1815 struct snd_card *card = asihpi->card;
1816 struct snd_kcontrol_new snd_control;
1817
e64b1a28 1818 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
719f82d3
EB
1819 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1820 snd_control.info = snd_asihpi_aesebu_format_info;
1821 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1822 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1823
1824 return ctl_add(card, &snd_control, asihpi);
1825}
1826
1827/*------------------------------------------------------------
1828 Tuner controls
1829 ------------------------------------------------------------*/
1830
1831/* Gain */
1832
1833static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1834 struct snd_ctl_elem_info *uinfo)
1835{
1836 u32 h_control = kcontrol->private_value;
1837 u16 err;
1838 short idx;
1839 u16 gain_range[3];
1840
1841 for (idx = 0; idx < 3; idx++) {
ba94455c 1842 err = hpi_tuner_query_gain(h_control,
719f82d3
EB
1843 idx, &gain_range[idx]);
1844 if (err != 0)
1845 return err;
1846 }
1847
1848 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1849 uinfo->count = 1;
1850 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1851 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1852 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1853 return 0;
1854}
1855
1856static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1857 struct snd_ctl_elem_value *ucontrol)
1858{
1859 /*
1860 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1861 */
1862 u32 h_control = kcontrol->private_value;
1863 short gain;
1864
ba94455c 1865 hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
719f82d3
EB
1866 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1867
1868 return 0;
1869}
1870
1871static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1872 struct snd_ctl_elem_value *ucontrol)
1873{
1874 /*
1875 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1876 */
1877 u32 h_control = kcontrol->private_value;
1878 short gain;
1879
1880 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
ba94455c 1881 hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
719f82d3
EB
1882
1883 return 1;
1884}
1885
1886/* Band */
1887
1888static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1889 u16 *band_list, u32 len) {
1890 u32 h_control = kcontrol->private_value;
1891 u16 err = 0;
1892 u32 i;
1893
1894 for (i = 0; i < len; i++) {
ba94455c 1895 err = hpi_tuner_query_band(
719f82d3
EB
1896 h_control, i, &band_list[i]);
1897 if (err != 0)
1898 break;
1899 }
1900
1901 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1902 return -EIO;
1903
1904 return i;
1905}
1906
1907static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1908 struct snd_ctl_elem_info *uinfo)
1909{
1910 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1911 int num_bands = 0;
1912
1913 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1914 HPI_TUNER_BAND_LAST);
1915
1916 if (num_bands < 0)
1917 return num_bands;
1918
30d0ae42 1919 return snd_ctl_enum_info(uinfo, 1, num_bands, asihpi_tuner_band_names);
719f82d3
EB
1920}
1921
1922static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1923 struct snd_ctl_elem_value *ucontrol)
1924{
1925 u32 h_control = kcontrol->private_value;
1926 /*
1927 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1928 */
1929 u16 band, idx;
1930 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1931 u32 num_bands = 0;
1932
1933 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1934 HPI_TUNER_BAND_LAST);
1935
ba94455c 1936 hpi_handle_error(hpi_tuner_get_band(h_control, &band));
719f82d3
EB
1937
1938 ucontrol->value.enumerated.item[0] = -1;
1939 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1940 if (tuner_bands[idx] == band) {
1941 ucontrol->value.enumerated.item[0] = idx;
1942 break;
1943 }
1944
1945 return 0;
1946}
1947
1948static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1949 struct snd_ctl_elem_value *ucontrol)
1950{
1951 /*
1952 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1953 */
1954 u32 h_control = kcontrol->private_value;
0c21fccd 1955 unsigned int idx;
719f82d3
EB
1956 u16 band;
1957 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1958 u32 num_bands = 0;
1959
1960 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1961 HPI_TUNER_BAND_LAST);
1962
0c21fccd
DC
1963 idx = ucontrol->value.enumerated.item[0];
1964 if (idx >= ARRAY_SIZE(tuner_bands))
1965 idx = ARRAY_SIZE(tuner_bands) - 1;
1966 band = tuner_bands[idx];
ba94455c 1967 hpi_handle_error(hpi_tuner_set_band(h_control, band));
719f82d3
EB
1968
1969 return 1;
1970}
1971
1972/* Freq */
1973
1974static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1975 struct snd_ctl_elem_info *uinfo)
1976{
1977 u32 h_control = kcontrol->private_value;
1978 u16 err;
1979 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1980 u16 num_bands = 0, band_iter, idx;
1981 u32 freq_range[3], temp_freq_range[3];
1982
1983 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1984 HPI_TUNER_BAND_LAST);
1985
1986 freq_range[0] = INT_MAX;
1987 freq_range[1] = 0;
1988 freq_range[2] = INT_MAX;
1989
1990 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1991 for (idx = 0; idx < 3; idx++) {
ba94455c 1992 err = hpi_tuner_query_frequency(h_control,
719f82d3
EB
1993 idx, tuner_bands[band_iter],
1994 &temp_freq_range[idx]);
1995 if (err != 0)
1996 return err;
1997 }
1998
1999 /* skip band with bogus stepping */
2000 if (temp_freq_range[2] <= 0)
2001 continue;
2002
2003 if (temp_freq_range[0] < freq_range[0])
2004 freq_range[0] = temp_freq_range[0];
2005 if (temp_freq_range[1] > freq_range[1])
2006 freq_range[1] = temp_freq_range[1];
2007 if (temp_freq_range[2] < freq_range[2])
2008 freq_range[2] = temp_freq_range[2];
2009 }
2010
2011 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2012 uinfo->count = 1;
2013 uinfo->value.integer.min = ((int)freq_range[0]);
2014 uinfo->value.integer.max = ((int)freq_range[1]);
2015 uinfo->value.integer.step = ((int)freq_range[2]);
2016 return 0;
2017}
2018
2019static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
2020 struct snd_ctl_elem_value *ucontrol)
2021{
2022 u32 h_control = kcontrol->private_value;
2023 u32 freq;
2024
ba94455c 2025 hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
719f82d3
EB
2026 ucontrol->value.integer.value[0] = freq;
2027
2028 return 0;
2029}
2030
2031static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2032 struct snd_ctl_elem_value *ucontrol)
2033{
2034 u32 h_control = kcontrol->private_value;
2035 u32 freq;
2036
2037 freq = ucontrol->value.integer.value[0];
ba94455c 2038 hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
719f82d3
EB
2039
2040 return 1;
2041}
2042
2043/* Tuner control group initializer */
e23e7a14
BP
2044static int snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2045 struct hpi_control *hpi_ctl)
719f82d3
EB
2046{
2047 struct snd_card *card = asihpi->card;
2048 struct snd_kcontrol_new snd_control;
2049
2050 snd_control.private_value = hpi_ctl->h_control;
2051 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2052
ba94455c 2053 if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
e64b1a28 2054 asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
719f82d3
EB
2055 snd_control.info = snd_asihpi_tuner_gain_info;
2056 snd_control.get = snd_asihpi_tuner_gain_get;
2057 snd_control.put = snd_asihpi_tuner_gain_put;
2058
2059 if (ctl_add(card, &snd_control, asihpi) < 0)
2060 return -EINVAL;
2061 }
2062
e64b1a28 2063 asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
719f82d3
EB
2064 snd_control.info = snd_asihpi_tuner_band_info;
2065 snd_control.get = snd_asihpi_tuner_band_get;
2066 snd_control.put = snd_asihpi_tuner_band_put;
2067
2068 if (ctl_add(card, &snd_control, asihpi) < 0)
2069 return -EINVAL;
2070
e64b1a28 2071 asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
719f82d3
EB
2072 snd_control.info = snd_asihpi_tuner_freq_info;
2073 snd_control.get = snd_asihpi_tuner_freq_get;
2074 snd_control.put = snd_asihpi_tuner_freq_put;
2075
2076 return ctl_add(card, &snd_control, asihpi);
2077}
2078
2079/*------------------------------------------------------------
2080 Meter controls
2081 ------------------------------------------------------------*/
2082static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2083 struct snd_ctl_elem_info *uinfo)
2084{
d4b06d23
EB
2085 u32 h_control = kcontrol->private_value;
2086 u32 count;
2087 u16 err;
2088 err = hpi_meter_query_channels(h_control, &count);
2089 if (err)
2090 count = HPI_MAX_CHANNELS;
2091
719f82d3 2092 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
d4b06d23 2093 uinfo->count = count;
719f82d3
EB
2094 uinfo->value.integer.min = 0;
2095 uinfo->value.integer.max = 0x7FFFFFFF;
2096 return 0;
2097}
2098
2099/* linear values for 10dB steps */
2100static int log2lin[] = {
2101 0x7FFFFFFF, /* 0dB */
2102 679093956,
2103 214748365,
2104 67909396,
2105 21474837,
2106 6790940,
2107 2147484, /* -60dB */
2108 679094,
2109 214748, /* -80 */
2110 67909,
2111 21475, /* -100 */
2112 6791,
2113 2147,
2114 679,
2115 214,
2116 68,
2117 21,
2118 7,
2119 2
2120};
2121
2122static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2123 struct snd_ctl_elem_value *ucontrol)
2124{
2125 u32 h_control = kcontrol->private_value;
2126 short an_gain_mB[HPI_MAX_CHANNELS], i;
2127 u16 err;
2128
ba94455c 2129 err = hpi_meter_get_peak(h_control, an_gain_mB);
719f82d3
EB
2130
2131 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2132 if (err) {
2133 ucontrol->value.integer.value[i] = 0;
2134 } else if (an_gain_mB[i] >= 0) {
2135 ucontrol->value.integer.value[i] =
2136 an_gain_mB[i] << 16;
2137 } else {
2138 /* -ve is log value in millibels < -60dB,
2139 * convert to (roughly!) linear,
2140 */
2141 ucontrol->value.integer.value[i] =
2142 log2lin[an_gain_mB[i] / -1000];
2143 }
2144 }
2145 return 0;
2146}
2147
e23e7a14
BP
2148static int snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2149 struct hpi_control *hpi_ctl, int subidx)
719f82d3
EB
2150{
2151 struct snd_card *card = asihpi->card;
2152 struct snd_kcontrol_new snd_control;
2153
e64b1a28 2154 asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
719f82d3
EB
2155 snd_control.access =
2156 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2157 snd_control.info = snd_asihpi_meter_info;
2158 snd_control.get = snd_asihpi_meter_get;
2159
2160 snd_control.index = subidx;
2161
2162 return ctl_add(card, &snd_control, asihpi);
2163}
2164
2165/*------------------------------------------------------------
2166 Multiplexer controls
2167 ------------------------------------------------------------*/
2168static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2169{
2170 u32 h_control = snd_control->private_value;
2171 struct hpi_control hpi_ctl;
2172 int s, err;
2173 for (s = 0; s < 32; s++) {
ba94455c 2174 err = hpi_multiplexer_query_source(h_control, s,
719f82d3
EB
2175 &hpi_ctl.
2176 src_node_type,
2177 &hpi_ctl.
2178 src_node_index);
2179 if (err)
2180 break;
2181 }
2182 return s;
2183}
2184
2185static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2186 struct snd_ctl_elem_info *uinfo)
2187{
2188 int err;
2189 u16 src_node_type, src_node_index;
2190 u32 h_control = kcontrol->private_value;
2191
2192 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2193 uinfo->count = 1;
2194 uinfo->value.enumerated.items =
2195 snd_card_asihpi_mux_count_sources(kcontrol);
2196
2197 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2198 uinfo->value.enumerated.item =
2199 uinfo->value.enumerated.items - 1;
2200
2201 err =
ba94455c 2202 hpi_multiplexer_query_source(h_control,
719f82d3
EB
2203 uinfo->value.enumerated.item,
2204 &src_node_type, &src_node_index);
2205
2206 sprintf(uinfo->value.enumerated.name, "%s %d",
168f1b07 2207 asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
719f82d3
EB
2208 src_node_index);
2209 return 0;
2210}
2211
2212static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2213 struct snd_ctl_elem_value *ucontrol)
2214{
2215 u32 h_control = kcontrol->private_value;
2216 u16 source_type, source_index;
2217 u16 src_node_type, src_node_index;
2218 int s;
2219
ba94455c 2220 hpi_handle_error(hpi_multiplexer_get_source(h_control,
719f82d3
EB
2221 &source_type, &source_index));
2222 /* Should cache this search result! */
2223 for (s = 0; s < 256; s++) {
ba94455c 2224 if (hpi_multiplexer_query_source(h_control, s,
719f82d3
EB
2225 &src_node_type, &src_node_index))
2226 break;
2227
2228 if ((source_type == src_node_type)
2229 && (source_index == src_node_index)) {
2230 ucontrol->value.enumerated.item[0] = s;
2231 return 0;
2232 }
2233 }
2234 snd_printd(KERN_WARNING
e64b1a28 2235 "Control %x failed to match mux source %hu %hu\n",
719f82d3
EB
2236 h_control, source_type, source_index);
2237 ucontrol->value.enumerated.item[0] = 0;
2238 return 0;
2239}
2240
2241static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2242 struct snd_ctl_elem_value *ucontrol)
2243{
2244 int change;
2245 u32 h_control = kcontrol->private_value;
2246 u16 source_type, source_index;
2247 u16 e;
2248
2249 change = 1;
2250
ba94455c 2251 e = hpi_multiplexer_query_source(h_control,
719f82d3
EB
2252 ucontrol->value.enumerated.item[0],
2253 &source_type, &source_index);
2254 if (!e)
2255 hpi_handle_error(
ba94455c 2256 hpi_multiplexer_set_source(h_control,
719f82d3
EB
2257 source_type, source_index));
2258 return change;
2259}
2260
2261
e23e7a14
BP
2262static int snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2263 struct hpi_control *hpi_ctl)
719f82d3
EB
2264{
2265 struct snd_card *card = asihpi->card;
2266 struct snd_kcontrol_new snd_control;
2267
e64b1a28 2268 asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
719f82d3
EB
2269 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2270 snd_control.info = snd_asihpi_mux_info;
2271 snd_control.get = snd_asihpi_mux_get;
2272 snd_control.put = snd_asihpi_mux_put;
2273
2274 return ctl_add(card, &snd_control, asihpi);
2275
2276}
2277
2278/*------------------------------------------------------------
2279 Channel mode controls
2280 ------------------------------------------------------------*/
2281static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2282 struct snd_ctl_elem_info *uinfo)
2283{
e64b1a28
EB
2284 static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
2285 "invalid",
2286 "Normal", "Swap",
2287 "From Left", "From Right",
2288 "To Left", "To Right"
719f82d3
EB
2289 };
2290
2291 u32 h_control = kcontrol->private_value;
2292 u16 mode;
2293 int i;
30d0ae42 2294 const char *mapped_names[6];
e64b1a28 2295 int valid_modes = 0;
719f82d3
EB
2296
2297 /* HPI channel mode values can be from 1 to 6
2298 Some adapters only support a contiguous subset
2299 */
2300 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
e64b1a28 2301 if (!hpi_channel_mode_query_mode(
ba94455c 2302 h_control, i, &mode)) {
30d0ae42 2303 mapped_names[valid_modes] = mode_names[mode];
e64b1a28
EB
2304 valid_modes++;
2305 }
719f82d3 2306
74eeb141
TI
2307 if (!valid_modes)
2308 return -EINVAL;
2309
30d0ae42 2310 return snd_ctl_enum_info(uinfo, 1, valid_modes, mapped_names);
719f82d3
EB
2311}
2312
2313static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2314 struct snd_ctl_elem_value *ucontrol)
2315{
2316 u32 h_control = kcontrol->private_value;
2317 u16 mode;
2318
ba94455c 2319 if (hpi_channel_mode_get(h_control, &mode))
719f82d3
EB
2320 mode = 1;
2321
2322 ucontrol->value.enumerated.item[0] = mode - 1;
2323
2324 return 0;
2325}
2326
2327static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2328 struct snd_ctl_elem_value *ucontrol)
2329{
2330 int change;
2331 u32 h_control = kcontrol->private_value;
2332
2333 change = 1;
2334
ba94455c 2335 hpi_handle_error(hpi_channel_mode_set(h_control,
719f82d3
EB
2336 ucontrol->value.enumerated.item[0] + 1));
2337 return change;
2338}
2339
2340
e23e7a14
BP
2341static int snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2342 struct hpi_control *hpi_ctl)
719f82d3
EB
2343{
2344 struct snd_card *card = asihpi->card;
2345 struct snd_kcontrol_new snd_control;
2346
e64b1a28 2347 asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
719f82d3
EB
2348 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2349 snd_control.info = snd_asihpi_cmode_info;
2350 snd_control.get = snd_asihpi_cmode_get;
2351 snd_control.put = snd_asihpi_cmode_put;
2352
2353 return ctl_add(card, &snd_control, asihpi);
2354}
2355
2356/*------------------------------------------------------------
2357 Sampleclock source controls
2358 ------------------------------------------------------------*/
46d212cb 2359static const char * const sampleclock_sources[] = {
ba94455c
EB
2360 "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
2361 "SMPTE", "Digital1", "Auto", "Network", "Invalid",
3872f19d 2362 "Prev Module", "BLU-Link",
ba94455c
EB
2363 "Digital2", "Digital3", "Digital4", "Digital5",
2364 "Digital6", "Digital7", "Digital8"};
719f82d3 2365
3872f19d
EB
2366 /* Number of strings must match expected enumerated values */
2367 compile_time_assert(
2368 (ARRAY_SIZE(sampleclock_sources) == MAX_CLOCKSOURCES),
2369 assert_sampleclock_sources_size);
2370
719f82d3
EB
2371static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2372 struct snd_ctl_elem_info *uinfo)
2373{
2374 struct snd_card_asihpi *asihpi =
2375 (struct snd_card_asihpi *)(kcontrol->private_data);
2376 struct clk_cache *clkcache = &asihpi->cc;
2377 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2378 uinfo->count = 1;
2379 uinfo->value.enumerated.items = clkcache->count;
2380
2381 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2382 uinfo->value.enumerated.item =
2383 uinfo->value.enumerated.items - 1;
2384
2385 strcpy(uinfo->value.enumerated.name,
2386 clkcache->s[uinfo->value.enumerated.item].name);
2387 return 0;
2388}
2389
2390static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2391 struct snd_ctl_elem_value *ucontrol)
2392{
2393 struct snd_card_asihpi *asihpi =
2394 (struct snd_card_asihpi *)(kcontrol->private_data);
2395 struct clk_cache *clkcache = &asihpi->cc;
2396 u32 h_control = kcontrol->private_value;
2397 u16 source, srcindex = 0;
2398 int i;
2399
2400 ucontrol->value.enumerated.item[0] = 0;
ba94455c 2401 if (hpi_sample_clock_get_source(h_control, &source))
719f82d3
EB
2402 source = 0;
2403
2404 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
ba94455c 2405 if (hpi_sample_clock_get_source_index(h_control, &srcindex))
719f82d3
EB
2406 srcindex = 0;
2407
2408 for (i = 0; i < clkcache->count; i++)
2409 if ((clkcache->s[i].source == source) &&
2410 (clkcache->s[i].index == srcindex))
2411 break;
2412
2413 ucontrol->value.enumerated.item[0] = i;
2414
2415 return 0;
2416}
2417
2418static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2419 struct snd_ctl_elem_value *ucontrol)
2420{
2421 struct snd_card_asihpi *asihpi =
2422 (struct snd_card_asihpi *)(kcontrol->private_data);
2423 struct clk_cache *clkcache = &asihpi->cc;
0c21fccd
DC
2424 unsigned int item;
2425 int change;
719f82d3
EB
2426 u32 h_control = kcontrol->private_value;
2427
2428 change = 1;
2429 item = ucontrol->value.enumerated.item[0];
2430 if (item >= clkcache->count)
2431 item = clkcache->count-1;
2432
ba94455c 2433 hpi_handle_error(hpi_sample_clock_set_source(
719f82d3
EB
2434 h_control, clkcache->s[item].source));
2435
2436 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
ba94455c 2437 hpi_handle_error(hpi_sample_clock_set_source_index(
719f82d3
EB
2438 h_control, clkcache->s[item].index));
2439 return change;
2440}
2441
2442/*------------------------------------------------------------
2443 Clkrate controls
2444 ------------------------------------------------------------*/
2445/* Need to change this to enumerated control with list of rates */
2446static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2447 struct snd_ctl_elem_info *uinfo)
2448{
2449 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2450 uinfo->count = 1;
2451 uinfo->value.integer.min = 8000;
2452 uinfo->value.integer.max = 192000;
2453 uinfo->value.integer.step = 100;
2454
2455 return 0;
2456}
2457
2458static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2459 struct snd_ctl_elem_value *ucontrol)
2460{
2461 u32 h_control = kcontrol->private_value;
2462 u32 rate;
2463 u16 e;
2464
ba94455c 2465 e = hpi_sample_clock_get_local_rate(h_control, &rate);
719f82d3
EB
2466 if (!e)
2467 ucontrol->value.integer.value[0] = rate;
2468 else
2469 ucontrol->value.integer.value[0] = 0;
2470 return 0;
2471}
2472
2473static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2474 struct snd_ctl_elem_value *ucontrol)
2475{
2476 int change;
2477 u32 h_control = kcontrol->private_value;
2478
2479 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2480 asihpi->mixer_clkrate[addr][1] != right;
2481 */
2482 change = 1;
ba94455c 2483 hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
719f82d3
EB
2484 ucontrol->value.integer.value[0]));
2485 return change;
2486}
2487
2488static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2489 struct snd_ctl_elem_info *uinfo)
2490{
2491 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2492 uinfo->count = 1;
2493 uinfo->value.integer.min = 8000;
2494 uinfo->value.integer.max = 192000;
2495 uinfo->value.integer.step = 100;
2496
2497 return 0;
2498}
2499
2500static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2501 struct snd_ctl_elem_value *ucontrol)
2502{
2503 u32 h_control = kcontrol->private_value;
2504 u32 rate;
2505 u16 e;
2506
ba94455c 2507 e = hpi_sample_clock_get_sample_rate(h_control, &rate);
719f82d3
EB
2508 if (!e)
2509 ucontrol->value.integer.value[0] = rate;
2510 else
2511 ucontrol->value.integer.value[0] = 0;
2512 return 0;
2513}
2514
e23e7a14
BP
2515static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2516 struct hpi_control *hpi_ctl)
719f82d3 2517{
f9a376c3 2518 struct snd_card *card;
719f82d3
EB
2519 struct snd_kcontrol_new snd_control;
2520
f9a376c3 2521 struct clk_cache *clkcache;
719f82d3
EB
2522 u32 hSC = hpi_ctl->h_control;
2523 int has_aes_in = 0;
2524 int i, j;
2525 u16 source;
2526
f9a376c3
EB
2527 if (snd_BUG_ON(!asihpi))
2528 return -EINVAL;
2529 card = asihpi->card;
2530 clkcache = &asihpi->cc;
719f82d3
EB
2531 snd_control.private_value = hpi_ctl->h_control;
2532
2533 clkcache->has_local = 0;
2534
2535 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
ba94455c 2536 if (hpi_sample_clock_query_source(hSC,
719f82d3
EB
2537 i, &source))
2538 break;
2539 clkcache->s[i].source = source;
2540 clkcache->s[i].index = 0;
2541 clkcache->s[i].name = sampleclock_sources[source];
2542 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2543 has_aes_in = 1;
2544 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2545 clkcache->has_local = 1;
2546 }
2547 if (has_aes_in)
2548 /* already will have picked up index 0 above */
2549 for (j = 1; j < 8; j++) {
ba94455c 2550 if (hpi_sample_clock_query_source_index(hSC,
719f82d3
EB
2551 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2552 &source))
2553 break;
2554 clkcache->s[i].source =
2555 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2556 clkcache->s[i].index = j;
2557 clkcache->s[i].name = sampleclock_sources[
2558 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2559 i++;
2560 }
2561 clkcache->count = i;
2562
e64b1a28 2563 asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
719f82d3
EB
2564 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2565 snd_control.info = snd_asihpi_clksrc_info;
2566 snd_control.get = snd_asihpi_clksrc_get;
2567 snd_control.put = snd_asihpi_clksrc_put;
2568 if (ctl_add(card, &snd_control, asihpi) < 0)
2569 return -EINVAL;
2570
2571
2572 if (clkcache->has_local) {
e64b1a28 2573 asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
719f82d3
EB
2574 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2575 snd_control.info = snd_asihpi_clklocal_info;
2576 snd_control.get = snd_asihpi_clklocal_get;
2577 snd_control.put = snd_asihpi_clklocal_put;
2578
2579
2580 if (ctl_add(card, &snd_control, asihpi) < 0)
2581 return -EINVAL;
2582 }
2583
e64b1a28 2584 asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
719f82d3
EB
2585 snd_control.access =
2586 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2587 snd_control.info = snd_asihpi_clkrate_info;
2588 snd_control.get = snd_asihpi_clkrate_get;
2589
2590 return ctl_add(card, &snd_control, asihpi);
2591}
2592/*------------------------------------------------------------
2593 Mixer
2594 ------------------------------------------------------------*/
2595
e23e7a14 2596static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
719f82d3 2597{
2e9b9a3c 2598 struct snd_card *card;
719f82d3
EB
2599 unsigned int idx = 0;
2600 unsigned int subindex = 0;
2601 int err;
2602 struct hpi_control hpi_ctl, prev_ctl;
2603
2604 if (snd_BUG_ON(!asihpi))
2605 return -EINVAL;
2e9b9a3c 2606 card = asihpi->card;
e64b1a28 2607 strcpy(card->mixername, "Asihpi Mixer");
719f82d3
EB
2608
2609 err =
7036b92d 2610 hpi_mixer_open(asihpi->hpi->adapter->index,
719f82d3
EB
2611 &asihpi->h_mixer);
2612 hpi_handle_error(err);
2613 if (err)
2614 return -err;
2615
21896bc0
TI
2616 memset(&prev_ctl, 0, sizeof(prev_ctl));
2617 prev_ctl.control_type = -1;
2618
719f82d3
EB
2619 for (idx = 0; idx < 2000; idx++) {
2620 err = hpi_mixer_get_control_by_index(
ba94455c 2621 asihpi->h_mixer,
719f82d3
EB
2622 idx,
2623 &hpi_ctl.src_node_type,
2624 &hpi_ctl.src_node_index,
2625 &hpi_ctl.dst_node_type,
2626 &hpi_ctl.dst_node_index,
2627 &hpi_ctl.control_type,
2628 &hpi_ctl.h_control);
2629 if (err) {
2630 if (err == HPI_ERROR_CONTROL_DISABLED) {
2631 if (mixer_dump)
12eb0898 2632 dev_info(&asihpi->pci->dev,
e64b1a28 2633 "Disabled HPI Control(%d)\n",
719f82d3
EB
2634 idx);
2635 continue;
2636 } else
2637 break;
2638
2639 }
2640
168f1b07
EB
2641 hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2642 hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
719f82d3
EB
2643
2644 /* ASI50xx in SSX mode has multiple meters on the same node.
2645 Use subindex to create distinct ALSA controls
2646 for any duplicated controls.
2647 */
2648 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2649 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2650 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2651 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2652 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2653 subindex++;
2654 else
2655 subindex = 0;
2656
2657 prev_ctl = hpi_ctl;
2658
2659 switch (hpi_ctl.control_type) {
2660 case HPI_CONTROL_VOLUME:
2661 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2662 break;
2663 case HPI_CONTROL_LEVEL:
2664 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2665 break;
2666 case HPI_CONTROL_MULTIPLEXER:
2667 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2668 break;
2669 case HPI_CONTROL_CHANNEL_MODE:
2670 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2671 break;
2672 case HPI_CONTROL_METER:
2673 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2674 break;
2675 case HPI_CONTROL_SAMPLECLOCK:
2676 err = snd_asihpi_sampleclock_add(
2677 asihpi, &hpi_ctl);
2678 break;
2679 case HPI_CONTROL_CONNECTION: /* ignore these */
2680 continue;
2681 case HPI_CONTROL_TUNER:
2682 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2683 break;
2684 case HPI_CONTROL_AESEBU_TRANSMITTER:
2685 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2686 break;
2687 case HPI_CONTROL_AESEBU_RECEIVER:
2688 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2689 break;
2690 case HPI_CONTROL_VOX:
2691 case HPI_CONTROL_BITSTREAM:
2692 case HPI_CONTROL_MICROPHONE:
2693 case HPI_CONTROL_PARAMETRIC_EQ:
2694 case HPI_CONTROL_COMPANDER:
2695 default:
2696 if (mixer_dump)
12eb0898
EB
2697 dev_info(&asihpi->pci->dev,
2698 "Untranslated HPI Control (%d) %d %d %d %d %d\n",
719f82d3
EB
2699 idx,
2700 hpi_ctl.control_type,
2701 hpi_ctl.src_node_type,
2702 hpi_ctl.src_node_index,
2703 hpi_ctl.dst_node_type,
2704 hpi_ctl.dst_node_index);
2705 continue;
395d9dd5 2706 }
719f82d3
EB
2707 if (err < 0)
2708 return err;
2709 }
2710 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2711 hpi_handle_error(err);
2712
12eb0898 2713 dev_info(&asihpi->pci->dev, "%d mixer controls found\n", idx);
719f82d3
EB
2714
2715 return 0;
2716}
2717
2718/*------------------------------------------------------------
2719 /proc interface
2720 ------------------------------------------------------------*/
2721
2722static void
2723snd_asihpi_proc_read(struct snd_info_entry *entry,
2724 struct snd_info_buffer *buffer)
2725{
2726 struct snd_card_asihpi *asihpi = entry->private_data;
719f82d3
EB
2727 u32 h_control;
2728 u32 rate = 0;
2729 u16 source = 0;
7036b92d
EB
2730
2731 u16 num_outstreams;
2732 u16 num_instreams;
2733 u16 version;
2734 u32 serial_number;
2735 u16 type;
2736
719f82d3
EB
2737 int err;
2738
2739 snd_iprintf(buffer, "ASIHPI driver proc file\n");
7036b92d
EB
2740
2741 hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
2742 &num_outstreams, &num_instreams,
2743 &version, &serial_number, &type));
2744
719f82d3 2745 snd_iprintf(buffer,
7036b92d
EB
2746 "Adapter type ASI%4X\nHardware Index %d\n"
2747 "%d outstreams\n%d instreams\n",
2748 type, asihpi->hpi->adapter->index,
2749 num_outstreams, num_instreams);
719f82d3 2750
719f82d3 2751 snd_iprintf(buffer,
7036b92d
EB
2752 "Serial#%d\nHardware version %c%d\nDSP code version %03d\n",
2753 serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7,
719f82d3
EB
2754 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2755
ba94455c 2756 err = hpi_mixer_get_control(asihpi->h_mixer,
719f82d3
EB
2757 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2758 HPI_CONTROL_SAMPLECLOCK, &h_control);
2759
2760 if (!err) {
7036b92d 2761 err = hpi_sample_clock_get_sample_rate(h_control, &rate);
ba94455c 2762 err += hpi_sample_clock_get_source(h_control, &source);
719f82d3
EB
2763
2764 if (!err)
7036b92d 2765 snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
719f82d3
EB
2766 rate, sampleclock_sources[source]);
2767 }
719f82d3
EB
2768}
2769
e23e7a14 2770static void snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
719f82d3 2771{
47f2769b
TI
2772 snd_card_ro_proc_new(asihpi->card, "info", asihpi,
2773 snd_asihpi_proc_read);
719f82d3
EB
2774}
2775
2776/*------------------------------------------------------------
2777 HWDEP
2778 ------------------------------------------------------------*/
2779
2780static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2781{
2782 if (enable_hpi_hwdep)
2783 return 0;
2784 else
2785 return -ENODEV;
2786
2787}
2788
2789static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2790{
2791 if (enable_hpi_hwdep)
2792 return asihpi_hpi_release(file);
2793 else
2794 return -ENODEV;
2795}
2796
2797static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2798 unsigned int cmd, unsigned long arg)
2799{
2800 if (enable_hpi_hwdep)
2801 return asihpi_hpi_ioctl(file, cmd, arg);
2802 else
2803 return -ENODEV;
2804}
2805
2806
2807/* results in /dev/snd/hwC#D0 file for each card with index #
2808 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2809*/
d18132aa 2810static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, int device)
719f82d3
EB
2811{
2812 struct snd_hwdep *hw;
2813 int err;
2814
719f82d3
EB
2815 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2816 if (err < 0)
2817 return err;
2818 strcpy(hw->name, "asihpi (HPI)");
2819 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2820 hw->ops.open = snd_asihpi_hpi_open;
2821 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2822 hw->ops.release = snd_asihpi_hpi_release;
2823 hw->private_data = asihpi;
719f82d3
EB
2824 return 0;
2825}
2826
2827/*------------------------------------------------------------
2828 CARD
2829 ------------------------------------------------------------*/
e23e7a14
BP
2830static int snd_asihpi_probe(struct pci_dev *pci_dev,
2831 const struct pci_device_id *pci_id)
719f82d3
EB
2832{
2833 int err;
7036b92d 2834 struct hpi_adapter *hpi;
719f82d3
EB
2835 struct snd_card *card;
2836 struct snd_card_asihpi *asihpi;
2837
2838 u32 h_control;
2839 u32 h_stream;
7036b92d 2840 u32 adapter_index;
719f82d3
EB
2841
2842 static int dev;
2843 if (dev >= SNDRV_CARDS)
2844 return -ENODEV;
2845
7036b92d 2846 /* Should this be enable[hpi->index] ? */
719f82d3
EB
2847 if (!enable[dev]) {
2848 dev++;
2849 return -ENOENT;
2850 }
2851
7036b92d 2852 /* Initialise low-level HPI driver */
719f82d3
EB
2853 err = asihpi_adapter_probe(pci_dev, pci_id);
2854 if (err < 0)
2855 return err;
2856
7036b92d
EB
2857 hpi = pci_get_drvdata(pci_dev);
2858 adapter_index = hpi->adapter->index;
719f82d3 2859 /* first try to give the card the same index as its hardware index */
60c5772b
TI
2860 err = snd_card_new(&pci_dev->dev, adapter_index, id[adapter_index],
2861 THIS_MODULE, sizeof(struct snd_card_asihpi), &card);
719f82d3
EB
2862 if (err < 0) {
2863 /* if that fails, try the default index==next available */
60c5772b
TI
2864 err = snd_card_new(&pci_dev->dev, index[dev], id[dev],
2865 THIS_MODULE, sizeof(struct snd_card_asihpi),
2866 &card);
719f82d3
EB
2867 if (err < 0)
2868 return err;
12eb0898 2869 dev_warn(&pci_dev->dev, "Adapter index %d->ALSA index %d\n",
7036b92d 2870 adapter_index, card->number);
719f82d3
EB
2871 }
2872
7036b92d 2873 asihpi = card->private_data;
719f82d3 2874 asihpi->card = card;
1225367a 2875 asihpi->pci = pci_dev;
7036b92d 2876 asihpi->hpi = hpi;
f9a376c3 2877 hpi->snd_card = card;
7036b92d 2878
7036b92d 2879 err = hpi_adapter_get_property(adapter_index,
719f82d3
EB
2880 HPI_ADAPTER_PROPERTY_CAPS1,
2881 NULL, &asihpi->support_grouping);
2882 if (err)
2883 asihpi->support_grouping = 0;
2884
7036b92d 2885 err = hpi_adapter_get_property(adapter_index,
719f82d3
EB
2886 HPI_ADAPTER_PROPERTY_CAPS2,
2887 &asihpi->support_mrx, NULL);
2888 if (err)
2889 asihpi->support_mrx = 0;
2890
7036b92d 2891 err = hpi_adapter_get_property(adapter_index,
719f82d3
EB
2892 HPI_ADAPTER_PROPERTY_INTERVAL,
2893 NULL, &asihpi->update_interval_frames);
2894 if (err)
2895 asihpi->update_interval_frames = 512;
2896
f9a376c3
EB
2897 if (hpi->interrupt_mode) {
2898 asihpi->pcm_start = snd_card_asihpi_pcm_int_start;
2899 asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop;
2900 tasklet_init(&asihpi->t, snd_card_asihpi_int_task,
2901 (unsigned long)hpi);
2902 hpi->interrupt_callback = snd_card_asihpi_isr;
2903 } else {
2904 asihpi->pcm_start = snd_card_asihpi_pcm_timer_start;
2905 asihpi->pcm_stop = snd_card_asihpi_pcm_timer_stop;
2906 }
26aebef4 2907
7036b92d 2908 hpi_handle_error(hpi_instream_open(adapter_index,
719f82d3
EB
2909 0, &h_stream));
2910
ba94455c 2911 err = hpi_instream_host_buffer_free(h_stream);
f3d145aa 2912 asihpi->can_dma = (!err);
719f82d3 2913
ba94455c 2914 hpi_handle_error(hpi_instream_close(h_stream));
719f82d3 2915
f9a376c3
EB
2916 if (!asihpi->can_dma)
2917 asihpi->update_interval_frames *= 2;
2918
7036b92d 2919 err = hpi_adapter_get_property(adapter_index,
719f82d3
EB
2920 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2921 &asihpi->in_max_chans, &asihpi->out_max_chans);
2922 if (err) {
2923 asihpi->in_max_chans = 2;
2924 asihpi->out_max_chans = 2;
2925 }
2926
c382a5da
EB
2927 if (asihpi->out_max_chans > 2) { /* assume LL mode */
2928 asihpi->out_min_chans = asihpi->out_max_chans;
2929 asihpi->in_min_chans = asihpi->in_max_chans;
2930 asihpi->support_grouping = 0;
2931 } else {
2932 asihpi->out_min_chans = 1;
2933 asihpi->in_min_chans = 1;
2934 }
2935
12eb0898 2936 dev_info(&pci_dev->dev, "Has dma:%d, grouping:%d, mrx:%d, uif:%d\n",
f3d145aa 2937 asihpi->can_dma,
719f82d3 2938 asihpi->support_grouping,
12eb0898
EB
2939 asihpi->support_mrx,
2940 asihpi->update_interval_frames
719f82d3
EB
2941 );
2942
7036b92d 2943 err = snd_card_asihpi_pcm_new(asihpi, 0);
719f82d3 2944 if (err < 0) {
12eb0898 2945 dev_err(&pci_dev->dev, "pcm_new failed\n");
719f82d3
EB
2946 goto __nodev;
2947 }
2948 err = snd_card_asihpi_mixer_new(asihpi);
2949 if (err < 0) {
12eb0898 2950 dev_err(&pci_dev->dev, "mixer_new failed\n");
719f82d3
EB
2951 goto __nodev;
2952 }
2953
ba94455c 2954 err = hpi_mixer_get_control(asihpi->h_mixer,
719f82d3
EB
2955 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2956 HPI_CONTROL_SAMPLECLOCK, &h_control);
2957
2958 if (!err)
2959 err = hpi_sample_clock_set_local_rate(
ba94455c 2960 h_control, adapter_fs);
719f82d3
EB
2961
2962 snd_asihpi_proc_init(asihpi);
2963
2964 /* always create, can be enabled or disabled dynamically
2965 by enable_hwdep module param*/
d18132aa 2966 snd_asihpi_hpi_new(asihpi, 0);
719f82d3 2967
f3d145aa 2968 strcpy(card->driver, "ASIHPI");
719f82d3 2969
7036b92d
EB
2970 sprintf(card->shortname, "AudioScience ASI%4X",
2971 asihpi->hpi->adapter->type);
719f82d3 2972 sprintf(card->longname, "%s %i",
7036b92d 2973 card->shortname, adapter_index);
719f82d3 2974 err = snd_card_register(card);
b2e65c8e 2975
719f82d3 2976 if (!err) {
719f82d3
EB
2977 dev++;
2978 return 0;
2979 }
2980__nodev:
2981 snd_card_free(card);
12eb0898 2982 dev_err(&pci_dev->dev, "snd_asihpi_probe error %d\n", err);
719f82d3
EB
2983 return err;
2984
2985}
2986
e23e7a14 2987static void snd_asihpi_remove(struct pci_dev *pci_dev)
719f82d3 2988{
7036b92d 2989 struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
f9a376c3
EB
2990 struct snd_card_asihpi *asihpi = hpi->snd_card->private_data;
2991
2992 /* Stop interrupts */
2993 if (hpi->interrupt_mode) {
2994 hpi->interrupt_callback = NULL;
2995 hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index,
2996 HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
2997 tasklet_kill(&asihpi->t);
2998 }
2999
7036b92d
EB
3000 snd_card_free(hpi->snd_card);
3001 hpi->snd_card = NULL;
719f82d3
EB
3002 asihpi_adapter_remove(pci_dev);
3003}
3004
9baa3c34 3005static const struct pci_device_id asihpi_pci_tbl[] = {
719f82d3
EB
3006 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
3007 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
3008 (kernel_ulong_t)HPI_6205},
3009 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
3010 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
3011 (kernel_ulong_t)HPI_6000},
3012 {0,}
3013};
3014MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
3015
3016static struct pci_driver driver = {
3733e424 3017 .name = KBUILD_MODNAME,
719f82d3
EB
3018 .id_table = asihpi_pci_tbl,
3019 .probe = snd_asihpi_probe,
e23e7a14 3020 .remove = snd_asihpi_remove,
719f82d3
EB
3021};
3022
3023static int __init snd_asihpi_init(void)
3024{
3025 asihpi_init();
3026 return pci_register_driver(&driver);
3027}
3028
3029static void __exit snd_asihpi_exit(void)
3030{
3031
3032 pci_unregister_driver(&driver);
3033 asihpi_exit();
3034}
3035
3036module_init(snd_asihpi_init)
3037module_exit(snd_asihpi_exit)
3038