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