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