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