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