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