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