diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 13:46:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 13:46:37 -0400 |
commit | d3e458d78167102cc961237cfceef6fffc80c0b3 (patch) | |
tree | e9195c1294daf053614e63ac52b0b44a28479017 /sound/pci/asihpi/asihpi.c | |
parent | f2e1fbb5f2177227f71c4fc0491e531dd7acd385 (diff) | |
parent | d351cf4603edb2a5bfa9a48d06c425511c63f2a3 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (308 commits)
ALSA: sound/pci/asihpi: check adapter index in hpi_ioctl
ALSA: aloop - Fix possible IRQ lock inversion
ALSA: sound/core: merge list_del()/list_add_tail() to list_move_tail()
ALSA: ctxfi - use list_move() instead of list_del()/list_add() combination
ALSA: firewire - msleep needs delay.h
ALSA: firewire-lib, firewire-speakers: handle packet queueing errors
ALSA: firewire-lib: allocate DMA buffer separately
ALSA: firewire-lib: use no-info SYT for packets without SYT sample
ALSA: add LaCie FireWire Speakers/Griffin FireWave Surround driver
ALSA: hda - Remove an unused variable in patch_realtek.c
ALSA: hda - pin-adc-mux-dmic auto-configuration of 92HD8X codecs
ALSA: hda - fix digital mic selection in mixer on 92HD8X codecs
ALSA: hda - Move default input-src selection to init part
ALSA: hda - Initialize special cases for input src in init phase
ALSA: ctxfi - Clear input settings before initialization
ALSA: ctxfi - Fix SPDIF status retrieval
ALSA: ctxfi - Fix incorrect SPDIF status bit mask
ALSA: ctxfi - Fix microphone boost codes/comments
ALSA: atiixp - Fix wrong time-out checks during ac-link reset
ALSA: intel8x0m: append 'm' to "r_intel8x0"
...
Diffstat (limited to 'sound/pci/asihpi/asihpi.c')
-rw-r--r-- | sound/pci/asihpi/asihpi.c | 774 |
1 files changed, 386 insertions, 388 deletions
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index c80b0b863c54..0ac1f98d91a1 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -21,6 +21,7 @@ | |||
21 | * would appreciate it if you grant us the right to use those modifications | 21 | * would appreciate it if you grant us the right to use those modifications |
22 | * for any purpose including commercial applications. | 22 | * for any purpose including commercial applications. |
23 | */ | 23 | */ |
24 | |||
24 | /* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ | 25 | /* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ |
25 | #define REALLY_VERBOSE_LOGGING 0 | 26 | #define REALLY_VERBOSE_LOGGING 0 |
26 | 27 | ||
@@ -36,16 +37,12 @@ | |||
36 | #define VPRINTK2(...) | 37 | #define VPRINTK2(...) |
37 | #endif | 38 | #endif |
38 | 39 | ||
39 | #ifndef ASI_STYLE_NAMES | ||
40 | /* not sure how ALSA style name should look */ | ||
41 | #define ASI_STYLE_NAMES 1 | ||
42 | #endif | ||
43 | |||
44 | #include "hpi_internal.h" | 40 | #include "hpi_internal.h" |
45 | #include "hpimsginit.h" | 41 | #include "hpimsginit.h" |
46 | #include "hpioctl.h" | 42 | #include "hpioctl.h" |
47 | 43 | ||
48 | #include <linux/pci.h> | 44 | #include <linux/pci.h> |
45 | #include <linux/version.h> | ||
49 | #include <linux/init.h> | 46 | #include <linux/init.h> |
50 | #include <linux/jiffies.h> | 47 | #include <linux/jiffies.h> |
51 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
@@ -85,11 +82,11 @@ MODULE_PARM_DESC(enable_hpi_hwdep, | |||
85 | 82 | ||
86 | /* identify driver */ | 83 | /* identify driver */ |
87 | #ifdef KERNEL_ALSA_BUILD | 84 | #ifdef KERNEL_ALSA_BUILD |
88 | static char *build_info = "built using headers from kernel source"; | 85 | static char *build_info = "Built using headers from kernel source"; |
89 | module_param(build_info, charp, S_IRUGO); | 86 | module_param(build_info, charp, S_IRUGO); |
90 | MODULE_PARM_DESC(build_info, "built using headers from kernel source"); | 87 | MODULE_PARM_DESC(build_info, "built using headers from kernel source"); |
91 | #else | 88 | #else |
92 | static char *build_info = "built within ALSA source"; | 89 | static char *build_info = "Built within ALSA source"; |
93 | module_param(build_info, charp, S_IRUGO); | 90 | module_param(build_info, charp, S_IRUGO); |
94 | MODULE_PARM_DESC(build_info, "built within ALSA source"); | 91 | MODULE_PARM_DESC(build_info, "built within ALSA source"); |
95 | #endif | 92 | #endif |
@@ -100,13 +97,14 @@ static const int mixer_dump; | |||
100 | #define DEFAULT_SAMPLERATE 44100 | 97 | #define DEFAULT_SAMPLERATE 44100 |
101 | static int adapter_fs = DEFAULT_SAMPLERATE; | 98 | static int adapter_fs = DEFAULT_SAMPLERATE; |
102 | 99 | ||
103 | static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */ | ||
104 | |||
105 | /* defaults */ | 100 | /* defaults */ |
106 | #define PERIODS_MIN 2 | 101 | #define PERIODS_MIN 2 |
107 | #define PERIOD_BYTES_MIN 2304 | 102 | #define PERIOD_BYTES_MIN 2048 |
108 | #define BUFFER_BYTES_MAX (512 * 1024) | 103 | #define BUFFER_BYTES_MAX (512 * 1024) |
109 | 104 | ||
105 | /* convert stream to character */ | ||
106 | #define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C') | ||
107 | |||
110 | /*#define TIMER_MILLISECONDS 20 | 108 | /*#define TIMER_MILLISECONDS 20 |
111 | #define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000) | 109 | #define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000) |
112 | */ | 110 | */ |
@@ -152,11 +150,12 @@ struct snd_card_asihpi_pcm { | |||
152 | struct timer_list timer; | 150 | struct timer_list timer; |
153 | unsigned int respawn_timer; | 151 | unsigned int respawn_timer; |
154 | unsigned int hpi_buffer_attached; | 152 | unsigned int hpi_buffer_attached; |
155 | unsigned int pcm_size; | 153 | unsigned int buffer_bytes; |
156 | unsigned int pcm_count; | 154 | unsigned int period_bytes; |
157 | unsigned int bytes_per_sec; | 155 | unsigned int bytes_per_sec; |
158 | unsigned int pcm_irq_pos; /* IRQ position */ | 156 | unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ |
159 | unsigned int pcm_buf_pos; /* position in buffer */ | 157 | unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ |
158 | unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ | ||
160 | struct snd_pcm_substream *substream; | 159 | struct snd_pcm_substream *substream; |
161 | u32 h_stream; | 160 | u32 h_stream; |
162 | struct hpi_format format; | 161 | struct hpi_format format; |
@@ -167,7 +166,6 @@ struct snd_card_asihpi_pcm { | |||
167 | /* Functions to allow driver to give a buffer to HPI for busmastering */ | 166 | /* Functions to allow driver to give a buffer to HPI for busmastering */ |
168 | 167 | ||
169 | static u16 hpi_stream_host_buffer_attach( | 168 | static u16 hpi_stream_host_buffer_attach( |
170 | struct hpi_hsubsys *hS, | ||
171 | u32 h_stream, /* handle to outstream. */ | 169 | u32 h_stream, /* handle to outstream. */ |
172 | u32 size_in_bytes, /* size in bytes of bus mastering buffer */ | 170 | u32 size_in_bytes, /* size in bytes of bus mastering buffer */ |
173 | u32 pci_address | 171 | u32 pci_address |
@@ -194,10 +192,7 @@ static u16 hpi_stream_host_buffer_attach( | |||
194 | return hr.error; | 192 | return hr.error; |
195 | } | 193 | } |
196 | 194 | ||
197 | static u16 hpi_stream_host_buffer_detach( | 195 | static u16 hpi_stream_host_buffer_detach(u32 h_stream) |
198 | struct hpi_hsubsys *hS, | ||
199 | u32 h_stream | ||
200 | ) | ||
201 | { | 196 | { |
202 | struct hpi_message hm; | 197 | struct hpi_message hm; |
203 | struct hpi_response hr; | 198 | struct hpi_response hr; |
@@ -218,24 +213,23 @@ static u16 hpi_stream_host_buffer_detach( | |||
218 | return hr.error; | 213 | return hr.error; |
219 | } | 214 | } |
220 | 215 | ||
221 | static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream) | 216 | static inline u16 hpi_stream_start(u32 h_stream) |
222 | { | 217 | { |
223 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) | 218 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) |
224 | return hpi_outstream_start(hS, h_stream); | 219 | return hpi_outstream_start(h_stream); |
225 | else | 220 | else |
226 | return hpi_instream_start(hS, h_stream); | 221 | return hpi_instream_start(h_stream); |
227 | } | 222 | } |
228 | 223 | ||
229 | static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream) | 224 | static inline u16 hpi_stream_stop(u32 h_stream) |
230 | { | 225 | { |
231 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) | 226 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) |
232 | return hpi_outstream_stop(hS, h_stream); | 227 | return hpi_outstream_stop(h_stream); |
233 | else | 228 | else |
234 | return hpi_instream_stop(hS, h_stream); | 229 | return hpi_instream_stop(h_stream); |
235 | } | 230 | } |
236 | 231 | ||
237 | static inline u16 hpi_stream_get_info_ex( | 232 | static inline u16 hpi_stream_get_info_ex( |
238 | struct hpi_hsubsys *hS, | ||
239 | u32 h_stream, | 233 | u32 h_stream, |
240 | u16 *pw_state, | 234 | u16 *pw_state, |
241 | u32 *pbuffer_size, | 235 | u32 *pbuffer_size, |
@@ -244,42 +238,43 @@ static inline u16 hpi_stream_get_info_ex( | |||
244 | u32 *pauxiliary_data | 238 | u32 *pauxiliary_data |
245 | ) | 239 | ) |
246 | { | 240 | { |
241 | u16 e; | ||
247 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) | 242 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) |
248 | return hpi_outstream_get_info_ex(hS, h_stream, pw_state, | 243 | e = hpi_outstream_get_info_ex(h_stream, pw_state, |
249 | pbuffer_size, pdata_in_buffer, | 244 | pbuffer_size, pdata_in_buffer, |
250 | psample_count, pauxiliary_data); | 245 | psample_count, pauxiliary_data); |
251 | else | 246 | else |
252 | return hpi_instream_get_info_ex(hS, h_stream, pw_state, | 247 | e = hpi_instream_get_info_ex(h_stream, pw_state, |
253 | pbuffer_size, pdata_in_buffer, | 248 | pbuffer_size, pdata_in_buffer, |
254 | psample_count, pauxiliary_data); | 249 | psample_count, pauxiliary_data); |
250 | return e; | ||
255 | } | 251 | } |
256 | 252 | ||
257 | static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS, | 253 | static inline u16 hpi_stream_group_add( |
258 | u32 h_master, | 254 | u32 h_master, |
259 | u32 h_stream) | 255 | u32 h_stream) |
260 | { | 256 | { |
261 | if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM) | 257 | if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM) |
262 | return hpi_outstream_group_add(hS, h_master, h_stream); | 258 | return hpi_outstream_group_add(h_master, h_stream); |
263 | else | 259 | else |
264 | return hpi_instream_group_add(hS, h_master, h_stream); | 260 | return hpi_instream_group_add(h_master, h_stream); |
265 | } | 261 | } |
266 | 262 | ||
267 | static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS, | 263 | static inline u16 hpi_stream_group_reset(u32 h_stream) |
268 | u32 h_stream) | ||
269 | { | 264 | { |
270 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) | 265 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) |
271 | return hpi_outstream_group_reset(hS, h_stream); | 266 | return hpi_outstream_group_reset(h_stream); |
272 | else | 267 | else |
273 | return hpi_instream_group_reset(hS, h_stream); | 268 | return hpi_instream_group_reset(h_stream); |
274 | } | 269 | } |
275 | 270 | ||
276 | static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS, | 271 | static inline u16 hpi_stream_group_get_map( |
277 | u32 h_stream, u32 *mo, u32 *mi) | 272 | u32 h_stream, u32 *mo, u32 *mi) |
278 | { | 273 | { |
279 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) | 274 | if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) |
280 | return hpi_outstream_group_get_map(hS, h_stream, mo, mi); | 275 | return hpi_outstream_group_get_map(h_stream, mo, mi); |
281 | else | 276 | else |
282 | return hpi_instream_group_get_map(hS, h_stream, mo, mi); | 277 | return hpi_instream_group_get_map(h_stream, mo, mi); |
283 | } | 278 | } |
284 | 279 | ||
285 | static u16 handle_error(u16 err, int line, char *filename) | 280 | static u16 handle_error(u16 err, int line, char *filename) |
@@ -299,11 +294,11 @@ static void print_hwparams(struct snd_pcm_hw_params *p) | |||
299 | { | 294 | { |
300 | snd_printd("HWPARAMS \n"); | 295 | snd_printd("HWPARAMS \n"); |
301 | snd_printd("samplerate %d \n", params_rate(p)); | 296 | snd_printd("samplerate %d \n", params_rate(p)); |
302 | snd_printd("channels %d \n", params_channels(p)); | 297 | snd_printd("Channels %d \n", params_channels(p)); |
303 | snd_printd("format %d \n", params_format(p)); | 298 | snd_printd("Format %d \n", params_format(p)); |
304 | snd_printd("subformat %d \n", params_subformat(p)); | 299 | snd_printd("subformat %d \n", params_subformat(p)); |
305 | snd_printd("buffer bytes %d \n", params_buffer_bytes(p)); | 300 | snd_printd("Buffer bytes %d \n", params_buffer_bytes(p)); |
306 | snd_printd("period bytes %d \n", params_period_bytes(p)); | 301 | snd_printd("Period bytes %d \n", params_period_bytes(p)); |
307 | snd_printd("access %d \n", params_access(p)); | 302 | snd_printd("access %d \n", params_access(p)); |
308 | snd_printd("period_size %d \n", params_period_size(p)); | 303 | snd_printd("period_size %d \n", params_period_size(p)); |
309 | snd_printd("periods %d \n", params_periods(p)); | 304 | snd_printd("periods %d \n", params_periods(p)); |
@@ -335,7 +330,7 @@ static snd_pcm_format_t hpi_to_alsa_formats[] = { | |||
335 | */ | 330 | */ |
336 | -1 | 331 | -1 |
337 | #else | 332 | #else |
338 | /* SNDRV_PCM_FORMAT_S24_3LE */ /* { HPI_FORMAT_PCM24_SIGNED 15 */ | 333 | /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */ |
339 | #endif | 334 | #endif |
340 | }; | 335 | }; |
341 | 336 | ||
@@ -378,20 +373,20 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, | |||
378 | } else { | 373 | } else { |
379 | /* on cards without SRC, | 374 | /* on cards without SRC, |
380 | valid rates are determined by sampleclock */ | 375 | valid rates are determined by sampleclock */ |
381 | err = hpi_mixer_get_control(ss, asihpi->h_mixer, | 376 | err = hpi_mixer_get_control(asihpi->h_mixer, |
382 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, | 377 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, |
383 | HPI_CONTROL_SAMPLECLOCK, &h_control); | 378 | HPI_CONTROL_SAMPLECLOCK, &h_control); |
384 | if (err) { | 379 | if (err) { |
385 | snd_printk(KERN_ERR | 380 | snd_printk(KERN_ERR |
386 | "no local sampleclock, err %d\n", err); | 381 | "No local sampleclock, err %d\n", err); |
387 | } | 382 | } |
388 | 383 | ||
389 | for (idx = 0; idx < 100; idx++) { | 384 | for (idx = 0; idx < 100; idx++) { |
390 | if (hpi_sample_clock_query_local_rate(ss, | 385 | if (hpi_sample_clock_query_local_rate( |
391 | h_control, idx, &sample_rate)) { | 386 | h_control, idx, &sample_rate)) { |
392 | if (!idx) | 387 | if (!idx) |
393 | snd_printk(KERN_ERR | 388 | snd_printk(KERN_ERR |
394 | "local rate query failed\n"); | 389 | "Local rate query failed\n"); |
395 | 390 | ||
396 | break; | 391 | break; |
397 | } | 392 | } |
@@ -480,10 +475,10 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
480 | format, params_rate(params), 0, 0)); | 475 | format, params_rate(params), 0, 0)); |
481 | 476 | ||
482 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 477 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
483 | if (hpi_instream_reset(ss, dpcm->h_stream) != 0) | 478 | if (hpi_instream_reset(dpcm->h_stream) != 0) |
484 | return -EINVAL; | 479 | return -EINVAL; |
485 | 480 | ||
486 | if (hpi_instream_set_format(ss, | 481 | if (hpi_instream_set_format( |
487 | dpcm->h_stream, &dpcm->format) != 0) | 482 | dpcm->h_stream, &dpcm->format) != 0) |
488 | return -EINVAL; | 483 | return -EINVAL; |
489 | } | 484 | } |
@@ -491,10 +486,10 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
491 | dpcm->hpi_buffer_attached = 0; | 486 | dpcm->hpi_buffer_attached = 0; |
492 | if (card->support_mmap) { | 487 | if (card->support_mmap) { |
493 | 488 | ||
494 | err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream, | 489 | err = hpi_stream_host_buffer_attach(dpcm->h_stream, |
495 | params_buffer_bytes(params), runtime->dma_addr); | 490 | params_buffer_bytes(params), runtime->dma_addr); |
496 | if (err == 0) { | 491 | if (err == 0) { |
497 | snd_printd(KERN_INFO | 492 | VPRINTK1(KERN_INFO |
498 | "stream_host_buffer_attach succeeded %u %lu\n", | 493 | "stream_host_buffer_attach succeeded %u %lu\n", |
499 | params_buffer_bytes(params), | 494 | params_buffer_bytes(params), |
500 | (unsigned long)runtime->dma_addr); | 495 | (unsigned long)runtime->dma_addr); |
@@ -505,11 +500,11 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
505 | return -ENOMEM; | 500 | return -ENOMEM; |
506 | } | 501 | } |
507 | 502 | ||
508 | err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL, | 503 | err = hpi_stream_get_info_ex(dpcm->h_stream, NULL, |
509 | &dpcm->hpi_buffer_attached, | 504 | &dpcm->hpi_buffer_attached, |
510 | NULL, NULL, NULL); | 505 | NULL, NULL, NULL); |
511 | 506 | ||
512 | snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n", | 507 | VPRINTK1(KERN_INFO "stream_host_buffer_attach status 0x%x\n", |
513 | dpcm->hpi_buffer_attached); | 508 | dpcm->hpi_buffer_attached); |
514 | } | 509 | } |
515 | bytes_per_sec = params_rate(params) * params_channels(params); | 510 | bytes_per_sec = params_rate(params) * params_channels(params); |
@@ -520,16 +515,32 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
520 | return -EINVAL; | 515 | return -EINVAL; |
521 | 516 | ||
522 | dpcm->bytes_per_sec = bytes_per_sec; | 517 | dpcm->bytes_per_sec = bytes_per_sec; |
523 | dpcm->pcm_size = params_buffer_bytes(params); | 518 | dpcm->buffer_bytes = params_buffer_bytes(params); |
524 | dpcm->pcm_count = params_period_bytes(params); | 519 | dpcm->period_bytes = params_period_bytes(params); |
525 | snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n", | 520 | VPRINTK1(KERN_INFO "buffer_bytes=%d, period_bytes=%d, bps=%d\n", |
526 | dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec); | 521 | dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec); |
527 | 522 | ||
528 | dpcm->pcm_irq_pos = 0; | ||
529 | dpcm->pcm_buf_pos = 0; | ||
530 | return 0; | 523 | return 0; |
531 | } | 524 | } |
532 | 525 | ||
526 | static int | ||
527 | snd_card_asihpi_hw_free(struct snd_pcm_substream *substream) | ||
528 | { | ||
529 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
530 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | ||
531 | if (dpcm->hpi_buffer_attached) | ||
532 | hpi_stream_host_buffer_detach(dpcm->h_stream); | ||
533 | |||
534 | snd_pcm_lib_free_pages(substream); | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime) | ||
539 | { | ||
540 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | ||
541 | kfree(dpcm); | ||
542 | } | ||
543 | |||
533 | static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * | 544 | static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * |
534 | substream) | 545 | substream) |
535 | { | 546 | { |
@@ -537,9 +548,9 @@ static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * | |||
537 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 548 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
538 | int expiry; | 549 | int expiry; |
539 | 550 | ||
540 | expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec); | 551 | expiry = HZ / 200; |
541 | /* wait longer the first time, for samples to propagate */ | 552 | /*? (dpcm->period_bytes * HZ / dpcm->bytes_per_sec); */ |
542 | expiry = max(expiry, 20); | 553 | expiry = max(expiry, 1); /* don't let it be zero! */ |
543 | dpcm->timer.expires = jiffies + expiry; | 554 | dpcm->timer.expires = jiffies + expiry; |
544 | dpcm->respawn_timer = 1; | 555 | dpcm->respawn_timer = 1; |
545 | add_timer(&dpcm->timer); | 556 | add_timer(&dpcm->timer); |
@@ -562,37 +573,44 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
562 | struct snd_pcm_substream *s; | 573 | struct snd_pcm_substream *s; |
563 | u16 e; | 574 | u16 e; |
564 | 575 | ||
565 | snd_printd("trigger %dstream %d\n", | 576 | VPRINTK1(KERN_INFO "%c%d trigger\n", |
566 | substream->stream, substream->number); | 577 | SCHR(substream->stream), substream->number); |
567 | switch (cmd) { | 578 | switch (cmd) { |
568 | case SNDRV_PCM_TRIGGER_START: | 579 | case SNDRV_PCM_TRIGGER_START: |
569 | snd_pcm_group_for_each_entry(s, substream) { | 580 | snd_pcm_group_for_each_entry(s, substream) { |
570 | struct snd_card_asihpi_pcm *ds; | 581 | struct snd_pcm_runtime *runtime = s->runtime; |
571 | ds = s->runtime->private_data; | 582 | struct snd_card_asihpi_pcm *ds = runtime->private_data; |
572 | 583 | ||
573 | if (snd_pcm_substream_chip(s) != card) | 584 | if (snd_pcm_substream_chip(s) != card) |
574 | continue; | 585 | continue; |
575 | 586 | ||
587 | /* don't link Cap and Play */ | ||
588 | if (substream->stream != s->stream) | ||
589 | continue; | ||
590 | |||
576 | if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && | 591 | if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && |
577 | (card->support_mmap)) { | 592 | (card->support_mmap)) { |
578 | /* How do I know how much valid data is present | 593 | /* How do I know how much valid data is present |
579 | * in buffer? Just guessing 2 periods, but if | 594 | * in buffer? Must be at least one period! |
595 | * Guessing 2 periods, but if | ||
580 | * buffer is bigger it may contain even more | 596 | * buffer is bigger it may contain even more |
581 | * data?? | 597 | * data?? |
582 | */ | 598 | */ |
583 | unsigned int preload = ds->pcm_count * 2; | 599 | unsigned int preload = ds->period_bytes * 1; |
584 | VPRINTK2("preload %d\n", preload); | 600 | VPRINTK2(KERN_INFO "%d preload x%x\n", s->number, preload); |
585 | hpi_handle_error(hpi_outstream_write_buf( | 601 | hpi_handle_error(hpi_outstream_write_buf( |
586 | ss, ds->h_stream, | 602 | ds->h_stream, |
587 | &s->runtime->dma_area[0], | 603 | &runtime->dma_area[0], |
588 | preload, | 604 | preload, |
589 | &ds->format)); | 605 | &ds->format)); |
606 | ds->pcm_buf_host_rw_ofs = preload; | ||
590 | } | 607 | } |
591 | 608 | ||
592 | if (card->support_grouping) { | 609 | if (card->support_grouping) { |
593 | VPRINTK1("\t_group %dstream %d\n", s->stream, | 610 | VPRINTK1(KERN_INFO "\t%c%d group\n", |
611 | SCHR(s->stream), | ||
594 | s->number); | 612 | s->number); |
595 | e = hpi_stream_group_add(ss, | 613 | e = hpi_stream_group_add( |
596 | dpcm->h_stream, | 614 | dpcm->h_stream, |
597 | ds->h_stream); | 615 | ds->h_stream); |
598 | if (!e) { | 616 | if (!e) { |
@@ -604,10 +622,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
604 | } else | 622 | } else |
605 | break; | 623 | break; |
606 | } | 624 | } |
607 | snd_printd("start\n"); | 625 | VPRINTK1(KERN_INFO "start\n"); |
608 | /* start the master stream */ | 626 | /* start the master stream */ |
609 | snd_card_asihpi_pcm_timer_start(substream); | 627 | snd_card_asihpi_pcm_timer_start(substream); |
610 | hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream)); | 628 | if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || |
629 | !card->support_mmap) | ||
630 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); | ||
611 | break; | 631 | break; |
612 | 632 | ||
613 | case SNDRV_PCM_TRIGGER_STOP: | 633 | case SNDRV_PCM_TRIGGER_STOP: |
@@ -615,88 +635,73 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
615 | snd_pcm_group_for_each_entry(s, substream) { | 635 | snd_pcm_group_for_each_entry(s, substream) { |
616 | if (snd_pcm_substream_chip(s) != card) | 636 | if (snd_pcm_substream_chip(s) != card) |
617 | continue; | 637 | continue; |
638 | /* don't link Cap and Play */ | ||
639 | if (substream->stream != s->stream) | ||
640 | continue; | ||
618 | 641 | ||
619 | /*? workaround linked streams don't | 642 | /*? workaround linked streams don't |
620 | transition to SETUP 20070706*/ | 643 | transition to SETUP 20070706*/ |
621 | s->runtime->status->state = SNDRV_PCM_STATE_SETUP; | 644 | s->runtime->status->state = SNDRV_PCM_STATE_SETUP; |
622 | 645 | ||
623 | if (card->support_grouping) { | 646 | if (card->support_grouping) { |
624 | VPRINTK1("\t_group %dstream %d\n", s->stream, | 647 | VPRINTK1(KERN_INFO "\t%c%d group\n", |
648 | SCHR(s->stream), | ||
625 | s->number); | 649 | s->number); |
626 | snd_pcm_trigger_done(s, substream); | 650 | snd_pcm_trigger_done(s, substream); |
627 | } else | 651 | } else |
628 | break; | 652 | break; |
629 | } | 653 | } |
630 | snd_printd("stop\n"); | 654 | VPRINTK1(KERN_INFO "stop\n"); |
631 | 655 | ||
632 | /* _prepare and _hwparams reset the stream */ | 656 | /* _prepare and _hwparams reset the stream */ |
633 | hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream)); | 657 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); |
634 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 658 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
635 | hpi_handle_error( | 659 | hpi_handle_error( |
636 | hpi_outstream_reset(ss, dpcm->h_stream)); | 660 | hpi_outstream_reset(dpcm->h_stream)); |
637 | 661 | ||
638 | if (card->support_grouping) | 662 | if (card->support_grouping) |
639 | hpi_handle_error(hpi_stream_group_reset(ss, | 663 | hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream)); |
640 | dpcm->h_stream)); | ||
641 | break; | 664 | break; |
642 | 665 | ||
643 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 666 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
644 | snd_printd("pause release\n"); | 667 | VPRINTK1(KERN_INFO "pause release\n"); |
645 | hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream)); | 668 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); |
646 | snd_card_asihpi_pcm_timer_start(substream); | 669 | snd_card_asihpi_pcm_timer_start(substream); |
647 | break; | 670 | break; |
648 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 671 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
649 | snd_printd("pause\n"); | 672 | VPRINTK1(KERN_INFO "pause\n"); |
650 | snd_card_asihpi_pcm_timer_stop(substream); | 673 | snd_card_asihpi_pcm_timer_stop(substream); |
651 | hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream)); | 674 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); |
652 | break; | 675 | break; |
653 | default: | 676 | default: |
654 | snd_printd("\tINVALID\n"); | 677 | snd_printd(KERN_ERR "\tINVALID\n"); |
655 | return -EINVAL; | 678 | return -EINVAL; |
656 | } | 679 | } |
657 | 680 | ||
658 | return 0; | 681 | return 0; |
659 | } | 682 | } |
660 | 683 | ||
661 | static int | ||
662 | snd_card_asihpi_hw_free(struct snd_pcm_substream *substream) | ||
663 | { | ||
664 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
665 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | ||
666 | if (dpcm->hpi_buffer_attached) | ||
667 | hpi_stream_host_buffer_detach(ss, dpcm->h_stream); | ||
668 | |||
669 | snd_pcm_lib_free_pages(substream); | ||
670 | return 0; | ||
671 | } | ||
672 | |||
673 | static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime) | ||
674 | { | ||
675 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | ||
676 | kfree(dpcm); | ||
677 | } | ||
678 | |||
679 | /*algorithm outline | 684 | /*algorithm outline |
680 | Without linking degenerates to getting single stream pos etc | 685 | Without linking degenerates to getting single stream pos etc |
681 | Without mmap 2nd loop degenerates to snd_pcm_period_elapsed | 686 | Without mmap 2nd loop degenerates to snd_pcm_period_elapsed |
682 | */ | 687 | */ |
683 | /* | 688 | /* |
684 | buf_pos=get_buf_pos(s); | 689 | pcm_buf_dma_ofs=get_buf_pos(s); |
685 | for_each_linked_stream(s) { | 690 | for_each_linked_stream(s) { |
686 | buf_pos=get_buf_pos(s); | 691 | pcm_buf_dma_ofs=get_buf_pos(s); |
687 | min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size) | 692 | min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes) |
688 | new_data = min(new_data, calc_new_data(buf_pos,irq_pos) | 693 | new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos) |
689 | } | 694 | } |
690 | timer.expires = jiffies + predict_next_period_ready(min_buf_pos); | 695 | timer.expires = jiffies + predict_next_period_ready(min_buf_pos); |
691 | for_each_linked_stream(s) { | 696 | for_each_linked_stream(s) { |
692 | s->buf_pos = min_buf_pos; | 697 | s->pcm_buf_dma_ofs = min_buf_pos; |
693 | if (new_data > pcm_count) { | 698 | if (new_data > period_bytes) { |
694 | if (mmap) { | 699 | if (mmap) { |
695 | irq_pos = (irq_pos + pcm_count) % pcm_size; | 700 | irq_pos = (irq_pos + period_bytes) % buffer_bytes; |
696 | if (playback) { | 701 | if (playback) { |
697 | write(pcm_count); | 702 | write(period_bytes); |
698 | } else { | 703 | } else { |
699 | read(pcm_count); | 704 | read(period_bytes); |
700 | } | 705 | } |
701 | } | 706 | } |
702 | snd_pcm_period_elapsed(s); | 707 | snd_pcm_period_elapsed(s); |
@@ -724,105 +729,136 @@ static inline unsigned int modulo_min(unsigned int a, unsigned int b, | |||
724 | static void snd_card_asihpi_timer_function(unsigned long data) | 729 | static void snd_card_asihpi_timer_function(unsigned long data) |
725 | { | 730 | { |
726 | struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data; | 731 | struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data; |
727 | struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream); | 732 | struct snd_pcm_substream *substream = dpcm->substream; |
733 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); | ||
728 | struct snd_pcm_runtime *runtime; | 734 | struct snd_pcm_runtime *runtime; |
729 | struct snd_pcm_substream *s; | 735 | struct snd_pcm_substream *s; |
730 | unsigned int newdata = 0; | 736 | unsigned int newdata = 0; |
731 | unsigned int buf_pos, min_buf_pos = 0; | 737 | unsigned int pcm_buf_dma_ofs, min_buf_pos = 0; |
732 | unsigned int remdata, xfercount, next_jiffies; | 738 | unsigned int remdata, xfercount, next_jiffies; |
733 | int first = 1; | 739 | int first = 1; |
740 | int loops = 0; | ||
734 | u16 state; | 741 | u16 state; |
735 | u32 buffer_size, data_avail, samples_played, aux; | 742 | u32 buffer_size, bytes_avail, samples_played, on_card_bytes; |
743 | |||
744 | VPRINTK1(KERN_INFO "%c%d snd_card_asihpi_timer_function\n", | ||
745 | SCHR(substream->stream), substream->number); | ||
736 | 746 | ||
737 | /* find minimum newdata and buffer pos in group */ | 747 | /* find minimum newdata and buffer pos in group */ |
738 | snd_pcm_group_for_each_entry(s, dpcm->substream) { | 748 | snd_pcm_group_for_each_entry(s, substream) { |
739 | struct snd_card_asihpi_pcm *ds = s->runtime->private_data; | 749 | struct snd_card_asihpi_pcm *ds = s->runtime->private_data; |
740 | runtime = s->runtime; | 750 | runtime = s->runtime; |
741 | 751 | ||
742 | if (snd_pcm_substream_chip(s) != card) | 752 | if (snd_pcm_substream_chip(s) != card) |
743 | continue; | 753 | continue; |
744 | 754 | ||
745 | hpi_handle_error(hpi_stream_get_info_ex(ss, | 755 | /* don't link Cap and Play */ |
756 | if (substream->stream != s->stream) | ||
757 | continue; | ||
758 | |||
759 | hpi_handle_error(hpi_stream_get_info_ex( | ||
746 | ds->h_stream, &state, | 760 | ds->h_stream, &state, |
747 | &buffer_size, &data_avail, | 761 | &buffer_size, &bytes_avail, |
748 | &samples_played, &aux)); | 762 | &samples_played, &on_card_bytes)); |
749 | 763 | ||
750 | /* number of bytes in on-card buffer */ | 764 | /* number of bytes in on-card buffer */ |
751 | runtime->delay = aux; | 765 | runtime->delay = on_card_bytes; |
752 | |||
753 | if (state == HPI_STATE_DRAINED) { | ||
754 | snd_printd(KERN_WARNING "outstream %d drained\n", | ||
755 | s->number); | ||
756 | snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); | ||
757 | return; | ||
758 | } | ||
759 | 766 | ||
760 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 767 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
761 | buf_pos = frames_to_bytes(runtime, samples_played); | 768 | pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; |
762 | } else { | 769 | if (state == HPI_STATE_STOPPED) { |
763 | buf_pos = data_avail + ds->pcm_irq_pos; | 770 | if ((bytes_avail == 0) && |
764 | } | 771 | (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { |
772 | hpi_handle_error(hpi_stream_start(ds->h_stream)); | ||
773 | VPRINTK1(KERN_INFO "P%d start\n", s->number); | ||
774 | } | ||
775 | } else if (state == HPI_STATE_DRAINED) { | ||
776 | VPRINTK1(KERN_WARNING "P%d drained\n", | ||
777 | s->number); | ||
778 | /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); | ||
779 | continue; */ | ||
780 | } | ||
781 | } else | ||
782 | pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; | ||
765 | 783 | ||
766 | if (first) { | 784 | if (first) { |
767 | /* can't statically init min when wrap is involved */ | 785 | /* can't statically init min when wrap is involved */ |
768 | min_buf_pos = buf_pos; | 786 | min_buf_pos = pcm_buf_dma_ofs; |
769 | newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size; | 787 | newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes; |
770 | first = 0; | 788 | first = 0; |
771 | } else { | 789 | } else { |
772 | min_buf_pos = | 790 | min_buf_pos = |
773 | modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L); | 791 | modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L); |
774 | newdata = min( | 792 | newdata = min( |
775 | (buf_pos - ds->pcm_irq_pos) % ds->pcm_size, | 793 | (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes, |
776 | newdata); | 794 | newdata); |
777 | } | 795 | } |
778 | 796 | ||
779 | VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n", | 797 | VPRINTK1(KERN_INFO "PB timer hw_ptr x%04lX, appl_ptr x%04lX\n", |
780 | (unsigned long)frames_to_bytes(runtime, | 798 | (unsigned long)frames_to_bytes(runtime, |
781 | runtime->status->hw_ptr), | 799 | runtime->status->hw_ptr), |
782 | (unsigned long)frames_to_bytes(runtime, | 800 | (unsigned long)frames_to_bytes(runtime, |
783 | runtime->control->appl_ptr)); | 801 | runtime->control->appl_ptr)); |
784 | VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X," | 802 | |
785 | " aux=x%04X space=x%04X\n", s->number, | 803 | VPRINTK1(KERN_INFO "%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," |
786 | state, ds->pcm_irq_pos, buf_pos, (int)data_avail, | 804 | " aux=x%04X space=x%04X\n", |
787 | (int)aux, buffer_size-data_avail); | 805 | loops, SCHR(s->stream), s->number, |
806 | state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, | ||
807 | (int)on_card_bytes, buffer_size-bytes_avail); | ||
808 | loops++; | ||
788 | } | 809 | } |
810 | pcm_buf_dma_ofs = min_buf_pos; | ||
789 | 811 | ||
790 | remdata = newdata % dpcm->pcm_count; | 812 | remdata = newdata % dpcm->period_bytes; |
791 | xfercount = newdata - remdata; /* a multiple of pcm_count */ | 813 | xfercount = newdata - remdata; /* a multiple of period_bytes */ |
792 | next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1; | 814 | /* come back when on_card_bytes has decreased enough to allow |
793 | next_jiffies = max(next_jiffies, 2U * HZ / 1000U); | 815 | write to happen, or when data has been consumed to make another |
816 | period | ||
817 | */ | ||
818 | if (xfercount && (on_card_bytes > dpcm->period_bytes)) | ||
819 | next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec); | ||
820 | else | ||
821 | next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec); | ||
822 | |||
823 | next_jiffies = max(next_jiffies, 1U); | ||
794 | dpcm->timer.expires = jiffies + next_jiffies; | 824 | dpcm->timer.expires = jiffies + next_jiffies; |
795 | VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n", | 825 | VPRINTK1(KERN_INFO "jif %d buf pos x%04X newdata x%04X xfer x%04X\n", |
796 | next_jiffies, min_buf_pos, newdata, xfercount); | 826 | next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); |
797 | 827 | ||
798 | snd_pcm_group_for_each_entry(s, dpcm->substream) { | 828 | snd_pcm_group_for_each_entry(s, substream) { |
799 | struct snd_card_asihpi_pcm *ds = s->runtime->private_data; | 829 | struct snd_card_asihpi_pcm *ds = s->runtime->private_data; |
800 | ds->pcm_buf_pos = min_buf_pos; | ||
801 | 830 | ||
802 | if (xfercount) { | 831 | /* don't link Cap and Play */ |
832 | if (substream->stream != s->stream) | ||
833 | continue; | ||
834 | |||
835 | ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; | ||
836 | |||
837 | if (xfercount && (on_card_bytes <= ds->period_bytes)) { | ||
803 | if (card->support_mmap) { | 838 | if (card->support_mmap) { |
804 | ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount; | ||
805 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 839 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
806 | VPRINTK2("write OS%d x%04x\n", | 840 | VPRINTK2(KERN_INFO "P%d write x%04x\n", |
807 | s->number, | 841 | s->number, |
808 | ds->pcm_count); | 842 | ds->period_bytes); |
809 | hpi_handle_error( | 843 | hpi_handle_error( |
810 | hpi_outstream_write_buf( | 844 | hpi_outstream_write_buf( |
811 | ss, ds->h_stream, | 845 | ds->h_stream, |
812 | &s->runtime-> | 846 | &s->runtime-> |
813 | dma_area[0], | 847 | dma_area[0], |
814 | xfercount, | 848 | xfercount, |
815 | &ds->format)); | 849 | &ds->format)); |
816 | } else { | 850 | } else { |
817 | VPRINTK2("read IS%d x%04x\n", | 851 | VPRINTK2(KERN_INFO "C%d read x%04x\n", |
818 | s->number, | 852 | s->number, |
819 | dpcm->pcm_count); | 853 | xfercount); |
820 | hpi_handle_error( | 854 | hpi_handle_error( |
821 | hpi_instream_read_buf( | 855 | hpi_instream_read_buf( |
822 | ss, ds->h_stream, | 856 | ds->h_stream, |
823 | NULL, xfercount)); | 857 | NULL, xfercount)); |
824 | } | 858 | } |
859 | ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; | ||
825 | } /* else R/W will be handled by read/write callbacks */ | 860 | } /* else R/W will be handled by read/write callbacks */ |
861 | ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; | ||
826 | snd_pcm_period_elapsed(s); | 862 | snd_pcm_period_elapsed(s); |
827 | } | 863 | } |
828 | } | 864 | } |
@@ -845,12 +881,12 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream * | |||
845 | struct snd_pcm_runtime *runtime = substream->runtime; | 881 | struct snd_pcm_runtime *runtime = substream->runtime; |
846 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 882 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
847 | 883 | ||
848 | snd_printd(KERN_INFO "playback prepare %d\n", substream->number); | 884 | VPRINTK1(KERN_INFO "playback prepare %d\n", substream->number); |
849 | |||
850 | hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream)); | ||
851 | dpcm->pcm_irq_pos = 0; | ||
852 | dpcm->pcm_buf_pos = 0; | ||
853 | 885 | ||
886 | hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); | ||
887 | dpcm->pcm_buf_host_rw_ofs = 0; | ||
888 | dpcm->pcm_buf_dma_ofs = 0; | ||
889 | dpcm->pcm_buf_elapsed_dma_ofs = 0; | ||
854 | return 0; | 890 | return 0; |
855 | } | 891 | } |
856 | 892 | ||
@@ -861,27 +897,8 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) | |||
861 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 897 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
862 | snd_pcm_uframes_t ptr; | 898 | snd_pcm_uframes_t ptr; |
863 | 899 | ||
864 | u32 samples_played; | 900 | ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); |
865 | u16 err; | 901 | /* VPRINTK2(KERN_INFO "playback_pointer=x%04lx\n", (unsigned long)ptr); */ |
866 | |||
867 | if (!snd_pcm_stream_linked(substream)) { | ||
868 | /* NOTE, can use samples played for playback position here and | ||
869 | * in timer fn because it LAGS the actual read pointer, and is a | ||
870 | * better representation of actual playout position | ||
871 | */ | ||
872 | err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL, | ||
873 | NULL, NULL, | ||
874 | &samples_played, NULL); | ||
875 | hpi_handle_error(err); | ||
876 | |||
877 | dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played); | ||
878 | } | ||
879 | /* else must return most conservative value found in timer func | ||
880 | * by looping over all streams | ||
881 | */ | ||
882 | |||
883 | ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size); | ||
884 | VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr); | ||
885 | return ptr; | 902 | return ptr; |
886 | } | 903 | } |
887 | 904 | ||
@@ -898,12 +915,12 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, | |||
898 | /* on cards without SRC, must query at valid rate, | 915 | /* on cards without SRC, must query at valid rate, |
899 | * maybe set by external sync | 916 | * maybe set by external sync |
900 | */ | 917 | */ |
901 | err = hpi_mixer_get_control(ss, asihpi->h_mixer, | 918 | err = hpi_mixer_get_control(asihpi->h_mixer, |
902 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, | 919 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, |
903 | HPI_CONTROL_SAMPLECLOCK, &h_control); | 920 | HPI_CONTROL_SAMPLECLOCK, &h_control); |
904 | 921 | ||
905 | if (!err) | 922 | if (!err) |
906 | err = hpi_sample_clock_get_sample_rate(ss, h_control, | 923 | err = hpi_sample_clock_get_sample_rate(h_control, |
907 | &sample_rate); | 924 | &sample_rate); |
908 | 925 | ||
909 | for (format = HPI_FORMAT_PCM8_UNSIGNED; | 926 | for (format = HPI_FORMAT_PCM8_UNSIGNED; |
@@ -911,7 +928,7 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, | |||
911 | err = hpi_format_create(&hpi_format, | 928 | err = hpi_format_create(&hpi_format, |
912 | 2, format, sample_rate, 128000, 0); | 929 | 2, format, sample_rate, 128000, 0); |
913 | if (!err) | 930 | if (!err) |
914 | err = hpi_outstream_query_format(ss, h_stream, | 931 | err = hpi_outstream_query_format(h_stream, |
915 | &hpi_format); | 932 | &hpi_format); |
916 | if (!err && (hpi_to_alsa_formats[format] != -1)) | 933 | if (!err && (hpi_to_alsa_formats[format] != -1)) |
917 | pcmhw->formats |= | 934 | pcmhw->formats |= |
@@ -942,7 +959,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
942 | return -ENOMEM; | 959 | return -ENOMEM; |
943 | 960 | ||
944 | err = | 961 | err = |
945 | hpi_outstream_open(ss, card->adapter_index, | 962 | hpi_outstream_open(card->adapter_index, |
946 | substream->number, &dpcm->h_stream); | 963 | substream->number, &dpcm->h_stream); |
947 | hpi_handle_error(err); | 964 | hpi_handle_error(err); |
948 | if (err) | 965 | if (err) |
@@ -998,11 +1015,11 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
998 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 1015 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
999 | card->update_interval_frames); | 1016 | card->update_interval_frames); |
1000 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 1017 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
1001 | card->update_interval_frames * 4, UINT_MAX); | 1018 | card->update_interval_frames * 2, UINT_MAX); |
1002 | 1019 | ||
1003 | snd_pcm_set_sync(substream); | 1020 | snd_pcm_set_sync(substream); |
1004 | 1021 | ||
1005 | snd_printd(KERN_INFO "playback open\n"); | 1022 | VPRINTK1(KERN_INFO "playback open\n"); |
1006 | 1023 | ||
1007 | return 0; | 1024 | return 0; |
1008 | } | 1025 | } |
@@ -1012,8 +1029,8 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream) | |||
1012 | struct snd_pcm_runtime *runtime = substream->runtime; | 1029 | struct snd_pcm_runtime *runtime = substream->runtime; |
1013 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 1030 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1014 | 1031 | ||
1015 | hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream)); | 1032 | hpi_handle_error(hpi_outstream_close(dpcm->h_stream)); |
1016 | snd_printd(KERN_INFO "playback close\n"); | 1033 | VPRINTK1(KERN_INFO "playback close\n"); |
1017 | 1034 | ||
1018 | return 0; | 1035 | return 0; |
1019 | } | 1036 | } |
@@ -1036,9 +1053,11 @@ static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream, | |||
1036 | VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n", | 1053 | VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n", |
1037 | substream->number, len); | 1054 | substream->number, len); |
1038 | 1055 | ||
1039 | hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream, | 1056 | hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, |
1040 | runtime->dma_area, len, &dpcm->format)); | 1057 | runtime->dma_area, len, &dpcm->format)); |
1041 | 1058 | ||
1059 | dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; | ||
1060 | |||
1042 | return 0; | 1061 | return 0; |
1043 | } | 1062 | } |
1044 | 1063 | ||
@@ -1052,10 +1071,10 @@ static int snd_card_asihpi_playback_silence(struct snd_pcm_substream * | |||
1052 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 1071 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1053 | 1072 | ||
1054 | len = frames_to_bytes(runtime, count); | 1073 | len = frames_to_bytes(runtime, count); |
1055 | snd_printd(KERN_INFO "playback silence %u bytes\n", len); | 1074 | VPRINTK1(KERN_INFO "playback silence %u bytes\n", len); |
1056 | 1075 | ||
1057 | memset(runtime->dma_area, 0, len); | 1076 | memset(runtime->dma_area, 0, len); |
1058 | hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream, | 1077 | hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, |
1059 | runtime->dma_area, len, &dpcm->format)); | 1078 | runtime->dma_area, len, &dpcm->format)); |
1060 | return 0; | 1079 | return 0; |
1061 | } | 1080 | } |
@@ -1091,13 +1110,13 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream) | |||
1091 | struct snd_pcm_runtime *runtime = substream->runtime; | 1110 | struct snd_pcm_runtime *runtime = substream->runtime; |
1092 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 1111 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1093 | 1112 | ||
1094 | VPRINTK2("capture pointer %d=%d\n", | 1113 | VPRINTK2(KERN_INFO "capture pointer %d=%d\n", |
1095 | substream->number, dpcm->pcm_buf_pos); | 1114 | substream->number, dpcm->pcm_buf_dma_ofs); |
1096 | /* NOTE Unlike playback can't use actual dwSamplesPlayed | 1115 | /* NOTE Unlike playback can't use actual samples_played |
1097 | for the capture position, because those samples aren't yet in | 1116 | for the capture position, because those samples aren't yet in |
1098 | the local buffer available for reading. | 1117 | the local buffer available for reading. |
1099 | */ | 1118 | */ |
1100 | return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size); | 1119 | return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); |
1101 | } | 1120 | } |
1102 | 1121 | ||
1103 | static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream, | 1122 | static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream, |
@@ -1111,11 +1130,12 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) | |||
1111 | struct snd_pcm_runtime *runtime = substream->runtime; | 1130 | struct snd_pcm_runtime *runtime = substream->runtime; |
1112 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 1131 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1113 | 1132 | ||
1114 | hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream)); | 1133 | hpi_handle_error(hpi_instream_reset(dpcm->h_stream)); |
1115 | dpcm->pcm_irq_pos = 0; | 1134 | dpcm->pcm_buf_host_rw_ofs = 0; |
1116 | dpcm->pcm_buf_pos = 0; | 1135 | dpcm->pcm_buf_dma_ofs = 0; |
1136 | dpcm->pcm_buf_elapsed_dma_ofs = 0; | ||
1117 | 1137 | ||
1118 | snd_printd("capture prepare %d\n", substream->number); | 1138 | VPRINTK1("Capture Prepare %d\n", substream->number); |
1119 | return 0; | 1139 | return 0; |
1120 | } | 1140 | } |
1121 | 1141 | ||
@@ -1133,12 +1153,12 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, | |||
1133 | 1153 | ||
1134 | /* on cards without SRC, must query at valid rate, | 1154 | /* on cards without SRC, must query at valid rate, |
1135 | maybe set by external sync */ | 1155 | maybe set by external sync */ |
1136 | err = hpi_mixer_get_control(ss, asihpi->h_mixer, | 1156 | err = hpi_mixer_get_control(asihpi->h_mixer, |
1137 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, | 1157 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, |
1138 | HPI_CONTROL_SAMPLECLOCK, &h_control); | 1158 | HPI_CONTROL_SAMPLECLOCK, &h_control); |
1139 | 1159 | ||
1140 | if (!err) | 1160 | if (!err) |
1141 | err = hpi_sample_clock_get_sample_rate(ss, h_control, | 1161 | err = hpi_sample_clock_get_sample_rate(h_control, |
1142 | &sample_rate); | 1162 | &sample_rate); |
1143 | 1163 | ||
1144 | for (format = HPI_FORMAT_PCM8_UNSIGNED; | 1164 | for (format = HPI_FORMAT_PCM8_UNSIGNED; |
@@ -1147,7 +1167,7 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, | |||
1147 | err = hpi_format_create(&hpi_format, 2, format, | 1167 | err = hpi_format_create(&hpi_format, 2, format, |
1148 | sample_rate, 128000, 0); | 1168 | sample_rate, 128000, 0); |
1149 | if (!err) | 1169 | if (!err) |
1150 | err = hpi_instream_query_format(ss, h_stream, | 1170 | err = hpi_instream_query_format(h_stream, |
1151 | &hpi_format); | 1171 | &hpi_format); |
1152 | if (!err) | 1172 | if (!err) |
1153 | pcmhw->formats |= | 1173 | pcmhw->formats |= |
@@ -1178,11 +1198,11 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | |||
1178 | if (dpcm == NULL) | 1198 | if (dpcm == NULL) |
1179 | return -ENOMEM; | 1199 | return -ENOMEM; |
1180 | 1200 | ||
1181 | snd_printd("hpi_instream_open adapter %d stream %d\n", | 1201 | VPRINTK1("hpi_instream_open adapter %d stream %d\n", |
1182 | card->adapter_index, substream->number); | 1202 | card->adapter_index, substream->number); |
1183 | 1203 | ||
1184 | err = hpi_handle_error( | 1204 | err = hpi_handle_error( |
1185 | hpi_instream_open(ss, card->adapter_index, | 1205 | hpi_instream_open(card->adapter_index, |
1186 | substream->number, &dpcm->h_stream)); | 1206 | substream->number, &dpcm->h_stream)); |
1187 | if (err) | 1207 | if (err) |
1188 | kfree(dpcm); | 1208 | kfree(dpcm); |
@@ -1209,6 +1229,9 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | |||
1209 | snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | | 1229 | snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | |
1210 | SNDRV_PCM_INFO_MMAP_VALID; | 1230 | SNDRV_PCM_INFO_MMAP_VALID; |
1211 | 1231 | ||
1232 | if (card->support_grouping) | ||
1233 | snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START; | ||
1234 | |||
1212 | runtime->hw = snd_card_asihpi_capture; | 1235 | runtime->hw = snd_card_asihpi_capture; |
1213 | 1236 | ||
1214 | if (card->support_mmap) | 1237 | if (card->support_mmap) |
@@ -1231,7 +1254,7 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream) | |||
1231 | { | 1254 | { |
1232 | struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data; | 1255 | struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data; |
1233 | 1256 | ||
1234 | hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream)); | 1257 | hpi_handle_error(hpi_instream_close(dpcm->h_stream)); |
1235 | return 0; | 1258 | return 0; |
1236 | } | 1259 | } |
1237 | 1260 | ||
@@ -1241,18 +1264,17 @@ static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream, | |||
1241 | { | 1264 | { |
1242 | struct snd_pcm_runtime *runtime = substream->runtime; | 1265 | struct snd_pcm_runtime *runtime = substream->runtime; |
1243 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 1266 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1244 | u32 data_size; | 1267 | u32 len; |
1245 | 1268 | ||
1246 | data_size = frames_to_bytes(runtime, count); | 1269 | len = frames_to_bytes(runtime, count); |
1247 | 1270 | ||
1248 | VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size); | 1271 | VPRINTK2(KERN_INFO "capture copy%d %d bytes\n", substream->number, len); |
1249 | hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream, | 1272 | hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, |
1250 | runtime->dma_area, data_size)); | 1273 | runtime->dma_area, len)); |
1251 | 1274 | ||
1252 | /* Used by capture_pointer */ | 1275 | dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; |
1253 | dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size; | ||
1254 | 1276 | ||
1255 | if (copy_to_user(dst, runtime->dma_area, data_size)) | 1277 | if (copy_to_user(dst, runtime->dma_area, len)) |
1256 | return -EFAULT; | 1278 | return -EFAULT; |
1257 | 1279 | ||
1258 | return 0; | 1280 | return 0; |
@@ -1287,7 +1309,7 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, | |||
1287 | struct snd_pcm *pcm; | 1309 | struct snd_pcm *pcm; |
1288 | int err; | 1310 | int err; |
1289 | 1311 | ||
1290 | err = snd_pcm_new(asihpi->card, "asihpi PCM", device, | 1312 | err = snd_pcm_new(asihpi->card, "Asihpi PCM", device, |
1291 | asihpi->num_outstreams, asihpi->num_instreams, | 1313 | asihpi->num_outstreams, asihpi->num_instreams, |
1292 | &pcm); | 1314 | &pcm); |
1293 | if (err < 0) | 1315 | if (err < 0) |
@@ -1307,7 +1329,7 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, | |||
1307 | 1329 | ||
1308 | pcm->private_data = asihpi; | 1330 | pcm->private_data = asihpi; |
1309 | pcm->info_flags = 0; | 1331 | pcm->info_flags = 0; |
1310 | strcpy(pcm->name, "asihpi PCM"); | 1332 | strcpy(pcm->name, "Asihpi PCM"); |
1311 | 1333 | ||
1312 | /*? do we want to emulate MMAP for non-BBM cards? | 1334 | /*? do we want to emulate MMAP for non-BBM cards? |
1313 | Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */ | 1335 | Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */ |
@@ -1330,8 +1352,7 @@ struct hpi_control { | |||
1330 | char name[44]; /* copied to snd_ctl_elem_id.name[44]; */ | 1352 | char name[44]; /* copied to snd_ctl_elem_id.name[44]; */ |
1331 | }; | 1353 | }; |
1332 | 1354 | ||
1333 | static char *asihpi_tuner_band_names[] = | 1355 | static const char * const asihpi_tuner_band_names[] = { |
1334 | { | ||
1335 | "invalid", | 1356 | "invalid", |
1336 | "AM", | 1357 | "AM", |
1337 | "FM mono", | 1358 | "FM mono", |
@@ -1349,70 +1370,36 @@ compile_time_assert( | |||
1349 | (HPI_TUNER_BAND_LAST+1)), | 1370 | (HPI_TUNER_BAND_LAST+1)), |
1350 | assert_tuner_band_names_size); | 1371 | assert_tuner_band_names_size); |
1351 | 1372 | ||
1352 | #if ASI_STYLE_NAMES | 1373 | static const char * const asihpi_src_names[] = { |
1353 | static char *asihpi_src_names[] = | ||
1354 | { | ||
1355 | "no source", | 1374 | "no source", |
1356 | "outstream", | 1375 | "PCM", |
1357 | "line_in", | 1376 | "Line", |
1358 | "aes_in", | 1377 | "Digital", |
1359 | "tuner", | 1378 | "Tuner", |
1360 | "RF", | 1379 | "RF", |
1361 | "clock", | 1380 | "Clock", |
1362 | "bitstr", | 1381 | "Bitstream", |
1363 | "mic", | 1382 | "Microphone", |
1364 | "cobranet", | 1383 | "Cobranet", |
1365 | "analog_in", | 1384 | "Analog", |
1366 | "adapter", | 1385 | "Adapter", |
1367 | }; | 1386 | }; |
1368 | #else | ||
1369 | static char *asihpi_src_names[] = | ||
1370 | { | ||
1371 | "no source", | ||
1372 | "PCM playback", | ||
1373 | "line in", | ||
1374 | "digital in", | ||
1375 | "tuner", | ||
1376 | "RF", | ||
1377 | "clock", | ||
1378 | "bitstream", | ||
1379 | "mic", | ||
1380 | "cobranet in", | ||
1381 | "analog in", | ||
1382 | "adapter", | ||
1383 | }; | ||
1384 | #endif | ||
1385 | 1387 | ||
1386 | compile_time_assert( | 1388 | compile_time_assert( |
1387 | (ARRAY_SIZE(asihpi_src_names) == | 1389 | (ARRAY_SIZE(asihpi_src_names) == |
1388 | (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), | 1390 | (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), |
1389 | assert_src_names_size); | 1391 | assert_src_names_size); |
1390 | 1392 | ||
1391 | #if ASI_STYLE_NAMES | 1393 | static const char * const asihpi_dst_names[] = { |
1392 | static char *asihpi_dst_names[] = | ||
1393 | { | ||
1394 | "no destination", | ||
1395 | "instream", | ||
1396 | "line_out", | ||
1397 | "aes_out", | ||
1398 | "RF", | ||
1399 | "speaker" , | ||
1400 | "cobranet", | ||
1401 | "analog_out", | ||
1402 | }; | ||
1403 | #else | ||
1404 | static char *asihpi_dst_names[] = | ||
1405 | { | ||
1406 | "no destination", | 1394 | "no destination", |
1407 | "PCM capture", | 1395 | "PCM", |
1408 | "line out", | 1396 | "Line", |
1409 | "digital out", | 1397 | "Digital", |
1410 | "RF", | 1398 | "RF", |
1411 | "speaker", | 1399 | "Speaker", |
1412 | "cobranet out", | 1400 | "Cobranet Out", |
1413 | "analog out" | 1401 | "Analog" |
1414 | }; | 1402 | }; |
1415 | #endif | ||
1416 | 1403 | ||
1417 | compile_time_assert( | 1404 | compile_time_assert( |
1418 | (ARRAY_SIZE(asihpi_dst_names) == | 1405 | (ARRAY_SIZE(asihpi_dst_names) == |
@@ -1438,30 +1425,45 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, | |||
1438 | struct hpi_control *hpi_ctl, | 1425 | struct hpi_control *hpi_ctl, |
1439 | char *name) | 1426 | char *name) |
1440 | { | 1427 | { |
1428 | char *dir = ""; | ||
1441 | memset(snd_control, 0, sizeof(*snd_control)); | 1429 | memset(snd_control, 0, sizeof(*snd_control)); |
1442 | snd_control->name = hpi_ctl->name; | 1430 | snd_control->name = hpi_ctl->name; |
1443 | snd_control->private_value = hpi_ctl->h_control; | 1431 | snd_control->private_value = hpi_ctl->h_control; |
1444 | snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 1432 | snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
1445 | snd_control->index = 0; | 1433 | snd_control->index = 0; |
1446 | 1434 | ||
1435 | if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) | ||
1436 | dir = "Capture "; /* On or towards a PCM capture destination*/ | ||
1437 | else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && | ||
1438 | (!hpi_ctl->dst_node_type)) | ||
1439 | dir = "Capture "; /* On a source node that is not PCM playback */ | ||
1440 | else if (hpi_ctl->src_node_type && | ||
1441 | (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && | ||
1442 | (hpi_ctl->dst_node_type)) | ||
1443 | dir = "Monitor Playback "; /* Between an input and an output */ | ||
1444 | else | ||
1445 | dir = "Playback "; /* PCM Playback source, or output node */ | ||
1446 | |||
1447 | if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) | 1447 | if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) |
1448 | sprintf(hpi_ctl->name, "%s%d to %s%d %s", | 1448 | sprintf(hpi_ctl->name, "%s%d %s%d %s%s", |
1449 | asihpi_src_names[hpi_ctl->src_node_type], | 1449 | asihpi_src_names[hpi_ctl->src_node_type], |
1450 | hpi_ctl->src_node_index, | 1450 | hpi_ctl->src_node_index, |
1451 | asihpi_dst_names[hpi_ctl->dst_node_type], | 1451 | asihpi_dst_names[hpi_ctl->dst_node_type], |
1452 | hpi_ctl->dst_node_index, | 1452 | hpi_ctl->dst_node_index, |
1453 | name); | 1453 | dir, name); |
1454 | else if (hpi_ctl->dst_node_type) { | 1454 | else if (hpi_ctl->dst_node_type) { |
1455 | sprintf(hpi_ctl->name, "%s%d %s", | 1455 | sprintf(hpi_ctl->name, "%s %d %s%s", |
1456 | asihpi_dst_names[hpi_ctl->dst_node_type], | 1456 | asihpi_dst_names[hpi_ctl->dst_node_type], |
1457 | hpi_ctl->dst_node_index, | 1457 | hpi_ctl->dst_node_index, |
1458 | name); | 1458 | dir, name); |
1459 | } else { | 1459 | } else { |
1460 | sprintf(hpi_ctl->name, "%s%d %s", | 1460 | sprintf(hpi_ctl->name, "%s %d %s%s", |
1461 | asihpi_src_names[hpi_ctl->src_node_type], | 1461 | asihpi_src_names[hpi_ctl->src_node_type], |
1462 | hpi_ctl->src_node_index, | 1462 | hpi_ctl->src_node_index, |
1463 | name); | 1463 | dir, name); |
1464 | } | 1464 | } |
1465 | /* printk(KERN_INFO "Adding %s %d to %d ", hpi_ctl->name, | ||
1466 | hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */ | ||
1465 | } | 1467 | } |
1466 | 1468 | ||
1467 | /*------------------------------------------------------------ | 1469 | /*------------------------------------------------------------ |
@@ -1478,7 +1480,7 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol, | |||
1478 | short max_gain_mB; | 1480 | short max_gain_mB; |
1479 | short step_gain_mB; | 1481 | short step_gain_mB; |
1480 | 1482 | ||
1481 | err = hpi_volume_query_range(ss, h_control, | 1483 | err = hpi_volume_query_range(h_control, |
1482 | &min_gain_mB, &max_gain_mB, &step_gain_mB); | 1484 | &min_gain_mB, &max_gain_mB, &step_gain_mB); |
1483 | if (err) { | 1485 | if (err) { |
1484 | max_gain_mB = 0; | 1486 | max_gain_mB = 0; |
@@ -1500,7 +1502,7 @@ static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol, | |||
1500 | u32 h_control = kcontrol->private_value; | 1502 | u32 h_control = kcontrol->private_value; |
1501 | short an_gain_mB[HPI_MAX_CHANNELS]; | 1503 | short an_gain_mB[HPI_MAX_CHANNELS]; |
1502 | 1504 | ||
1503 | hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB)); | 1505 | hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB)); |
1504 | ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB; | 1506 | ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB; |
1505 | ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB; | 1507 | ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB; |
1506 | 1508 | ||
@@ -1522,7 +1524,7 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol, | |||
1522 | asihpi->mixer_volume[addr][1] != right; | 1524 | asihpi->mixer_volume[addr][1] != right; |
1523 | */ | 1525 | */ |
1524 | change = 1; | 1526 | change = 1; |
1525 | hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB)); | 1527 | hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB)); |
1526 | return change; | 1528 | return change; |
1527 | } | 1529 | } |
1528 | 1530 | ||
@@ -1534,7 +1536,7 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi, | |||
1534 | struct snd_card *card = asihpi->card; | 1536 | struct snd_card *card = asihpi->card; |
1535 | struct snd_kcontrol_new snd_control; | 1537 | struct snd_kcontrol_new snd_control; |
1536 | 1538 | ||
1537 | asihpi_ctl_init(&snd_control, hpi_ctl, "volume"); | 1539 | asihpi_ctl_init(&snd_control, hpi_ctl, "Volume"); |
1538 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | 1540 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
1539 | SNDRV_CTL_ELEM_ACCESS_TLV_READ; | 1541 | SNDRV_CTL_ELEM_ACCESS_TLV_READ; |
1540 | snd_control.info = snd_asihpi_volume_info; | 1542 | snd_control.info = snd_asihpi_volume_info; |
@@ -1558,7 +1560,7 @@ static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol, | |||
1558 | short step_gain_mB; | 1560 | short step_gain_mB; |
1559 | 1561 | ||
1560 | err = | 1562 | err = |
1561 | hpi_level_query_range(ss, h_control, &min_gain_mB, | 1563 | hpi_level_query_range(h_control, &min_gain_mB, |
1562 | &max_gain_mB, &step_gain_mB); | 1564 | &max_gain_mB, &step_gain_mB); |
1563 | if (err) { | 1565 | if (err) { |
1564 | max_gain_mB = 2400; | 1566 | max_gain_mB = 2400; |
@@ -1580,7 +1582,7 @@ static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol, | |||
1580 | u32 h_control = kcontrol->private_value; | 1582 | u32 h_control = kcontrol->private_value; |
1581 | short an_gain_mB[HPI_MAX_CHANNELS]; | 1583 | short an_gain_mB[HPI_MAX_CHANNELS]; |
1582 | 1584 | ||
1583 | hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB)); | 1585 | hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB)); |
1584 | ucontrol->value.integer.value[0] = | 1586 | ucontrol->value.integer.value[0] = |
1585 | an_gain_mB[0] / HPI_UNITS_PER_dB; | 1587 | an_gain_mB[0] / HPI_UNITS_PER_dB; |
1586 | ucontrol->value.integer.value[1] = | 1588 | ucontrol->value.integer.value[1] = |
@@ -1604,7 +1606,7 @@ static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol, | |||
1604 | asihpi->mixer_level[addr][1] != right; | 1606 | asihpi->mixer_level[addr][1] != right; |
1605 | */ | 1607 | */ |
1606 | change = 1; | 1608 | change = 1; |
1607 | hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB)); | 1609 | hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB)); |
1608 | return change; | 1610 | return change; |
1609 | } | 1611 | } |
1610 | 1612 | ||
@@ -1617,7 +1619,7 @@ static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi, | |||
1617 | struct snd_kcontrol_new snd_control; | 1619 | struct snd_kcontrol_new snd_control; |
1618 | 1620 | ||
1619 | /* can't use 'volume' cos some nodes have volume as well */ | 1621 | /* can't use 'volume' cos some nodes have volume as well */ |
1620 | asihpi_ctl_init(&snd_control, hpi_ctl, "level"); | 1622 | asihpi_ctl_init(&snd_control, hpi_ctl, "Level"); |
1621 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | 1623 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
1622 | SNDRV_CTL_ELEM_ACCESS_TLV_READ; | 1624 | SNDRV_CTL_ELEM_ACCESS_TLV_READ; |
1623 | snd_control.info = snd_asihpi_level_info; | 1625 | snd_control.info = snd_asihpi_level_info; |
@@ -1633,12 +1635,8 @@ static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi, | |||
1633 | ------------------------------------------------------------*/ | 1635 | ------------------------------------------------------------*/ |
1634 | 1636 | ||
1635 | /* AESEBU format */ | 1637 | /* AESEBU format */ |
1636 | static char *asihpi_aesebu_format_names[] = | 1638 | static const char * const asihpi_aesebu_format_names[] = { |
1637 | { | 1639 | "N/A", "S/PDIF", "AES/EBU" }; |
1638 | "N/A", | ||
1639 | "S/PDIF", | ||
1640 | "AES/EBU", | ||
1641 | }; | ||
1642 | 1640 | ||
1643 | static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol, | 1641 | static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol, |
1644 | struct snd_ctl_elem_info *uinfo) | 1642 | struct snd_ctl_elem_info *uinfo) |
@@ -1659,12 +1657,12 @@ static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol, | |||
1659 | 1657 | ||
1660 | static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol, | 1658 | static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol, |
1661 | struct snd_ctl_elem_value *ucontrol, | 1659 | struct snd_ctl_elem_value *ucontrol, |
1662 | u16 (*func)(const struct hpi_hsubsys *, u32, u16 *)) | 1660 | u16 (*func)(u32, u16 *)) |
1663 | { | 1661 | { |
1664 | u32 h_control = kcontrol->private_value; | 1662 | u32 h_control = kcontrol->private_value; |
1665 | u16 source, err; | 1663 | u16 source, err; |
1666 | 1664 | ||
1667 | err = func(ss, h_control, &source); | 1665 | err = func(h_control, &source); |
1668 | 1666 | ||
1669 | /* default to N/A */ | 1667 | /* default to N/A */ |
1670 | ucontrol->value.enumerated.item[0] = 0; | 1668 | ucontrol->value.enumerated.item[0] = 0; |
@@ -1681,7 +1679,7 @@ static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol, | |||
1681 | 1679 | ||
1682 | static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol, | 1680 | static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol, |
1683 | struct snd_ctl_elem_value *ucontrol, | 1681 | struct snd_ctl_elem_value *ucontrol, |
1684 | u16 (*func)(const struct hpi_hsubsys *, u32, u16)) | 1682 | u16 (*func)(u32, u16)) |
1685 | { | 1683 | { |
1686 | u32 h_control = kcontrol->private_value; | 1684 | u32 h_control = kcontrol->private_value; |
1687 | 1685 | ||
@@ -1693,7 +1691,7 @@ static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol, | |||
1693 | if (ucontrol->value.enumerated.item[0] == 2) | 1691 | if (ucontrol->value.enumerated.item[0] == 2) |
1694 | source = HPI_AESEBU_FORMAT_AESEBU; | 1692 | source = HPI_AESEBU_FORMAT_AESEBU; |
1695 | 1693 | ||
1696 | if (func(ss, h_control, source) != 0) | 1694 | if (func(h_control, source) != 0) |
1697 | return -EINVAL; | 1695 | return -EINVAL; |
1698 | 1696 | ||
1699 | return 1; | 1697 | return 1; |
@@ -1702,13 +1700,13 @@ static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol, | |||
1702 | static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol, | 1700 | static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol, |
1703 | struct snd_ctl_elem_value *ucontrol) { | 1701 | struct snd_ctl_elem_value *ucontrol) { |
1704 | return snd_asihpi_aesebu_format_get(kcontrol, ucontrol, | 1702 | return snd_asihpi_aesebu_format_get(kcontrol, ucontrol, |
1705 | HPI_AESEBU__receiver_get_format); | 1703 | hpi_aesebu_receiver_get_format); |
1706 | } | 1704 | } |
1707 | 1705 | ||
1708 | static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol, | 1706 | static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol, |
1709 | struct snd_ctl_elem_value *ucontrol) { | 1707 | struct snd_ctl_elem_value *ucontrol) { |
1710 | return snd_asihpi_aesebu_format_put(kcontrol, ucontrol, | 1708 | return snd_asihpi_aesebu_format_put(kcontrol, ucontrol, |
1711 | HPI_AESEBU__receiver_set_format); | 1709 | hpi_aesebu_receiver_set_format); |
1712 | } | 1710 | } |
1713 | 1711 | ||
1714 | static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol, | 1712 | static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol, |
@@ -1730,8 +1728,8 @@ static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol, | |||
1730 | u32 h_control = kcontrol->private_value; | 1728 | u32 h_control = kcontrol->private_value; |
1731 | u16 status; | 1729 | u16 status; |
1732 | 1730 | ||
1733 | hpi_handle_error(HPI_AESEBU__receiver_get_error_status( | 1731 | hpi_handle_error(hpi_aesebu_receiver_get_error_status( |
1734 | ss, h_control, &status)); | 1732 | h_control, &status)); |
1735 | ucontrol->value.integer.value[0] = status; | 1733 | ucontrol->value.integer.value[0] = status; |
1736 | return 0; | 1734 | return 0; |
1737 | } | 1735 | } |
@@ -1742,7 +1740,7 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi, | |||
1742 | struct snd_card *card = asihpi->card; | 1740 | struct snd_card *card = asihpi->card; |
1743 | struct snd_kcontrol_new snd_control; | 1741 | struct snd_kcontrol_new snd_control; |
1744 | 1742 | ||
1745 | asihpi_ctl_init(&snd_control, hpi_ctl, "format"); | 1743 | asihpi_ctl_init(&snd_control, hpi_ctl, "Format"); |
1746 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | 1744 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; |
1747 | snd_control.info = snd_asihpi_aesebu_format_info; | 1745 | snd_control.info = snd_asihpi_aesebu_format_info; |
1748 | snd_control.get = snd_asihpi_aesebu_rx_format_get; | 1746 | snd_control.get = snd_asihpi_aesebu_rx_format_get; |
@@ -1752,7 +1750,7 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi, | |||
1752 | if (ctl_add(card, &snd_control, asihpi) < 0) | 1750 | if (ctl_add(card, &snd_control, asihpi) < 0) |
1753 | return -EINVAL; | 1751 | return -EINVAL; |
1754 | 1752 | ||
1755 | asihpi_ctl_init(&snd_control, hpi_ctl, "status"); | 1753 | asihpi_ctl_init(&snd_control, hpi_ctl, "Status"); |
1756 | snd_control.access = | 1754 | snd_control.access = |
1757 | SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; | 1755 | SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; |
1758 | snd_control.info = snd_asihpi_aesebu_rxstatus_info; | 1756 | snd_control.info = snd_asihpi_aesebu_rxstatus_info; |
@@ -1764,13 +1762,13 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi, | |||
1764 | static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol, | 1762 | static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol, |
1765 | struct snd_ctl_elem_value *ucontrol) { | 1763 | struct snd_ctl_elem_value *ucontrol) { |
1766 | return snd_asihpi_aesebu_format_get(kcontrol, ucontrol, | 1764 | return snd_asihpi_aesebu_format_get(kcontrol, ucontrol, |
1767 | HPI_AESEBU__transmitter_get_format); | 1765 | hpi_aesebu_transmitter_get_format); |
1768 | } | 1766 | } |
1769 | 1767 | ||
1770 | static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol, | 1768 | static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol, |
1771 | struct snd_ctl_elem_value *ucontrol) { | 1769 | struct snd_ctl_elem_value *ucontrol) { |
1772 | return snd_asihpi_aesebu_format_put(kcontrol, ucontrol, | 1770 | return snd_asihpi_aesebu_format_put(kcontrol, ucontrol, |
1773 | HPI_AESEBU__transmitter_set_format); | 1771 | hpi_aesebu_transmitter_set_format); |
1774 | } | 1772 | } |
1775 | 1773 | ||
1776 | 1774 | ||
@@ -1780,7 +1778,7 @@ static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi, | |||
1780 | struct snd_card *card = asihpi->card; | 1778 | struct snd_card *card = asihpi->card; |
1781 | struct snd_kcontrol_new snd_control; | 1779 | struct snd_kcontrol_new snd_control; |
1782 | 1780 | ||
1783 | asihpi_ctl_init(&snd_control, hpi_ctl, "format"); | 1781 | asihpi_ctl_init(&snd_control, hpi_ctl, "Format"); |
1784 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | 1782 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; |
1785 | snd_control.info = snd_asihpi_aesebu_format_info; | 1783 | snd_control.info = snd_asihpi_aesebu_format_info; |
1786 | snd_control.get = snd_asihpi_aesebu_tx_format_get; | 1784 | snd_control.get = snd_asihpi_aesebu_tx_format_get; |
@@ -1804,7 +1802,7 @@ static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol, | |||
1804 | u16 gain_range[3]; | 1802 | u16 gain_range[3]; |
1805 | 1803 | ||
1806 | for (idx = 0; idx < 3; idx++) { | 1804 | for (idx = 0; idx < 3; idx++) { |
1807 | err = hpi_tuner_query_gain(ss, h_control, | 1805 | err = hpi_tuner_query_gain(h_control, |
1808 | idx, &gain_range[idx]); | 1806 | idx, &gain_range[idx]); |
1809 | if (err != 0) | 1807 | if (err != 0) |
1810 | return err; | 1808 | return err; |
@@ -1827,7 +1825,7 @@ static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol, | |||
1827 | u32 h_control = kcontrol->private_value; | 1825 | u32 h_control = kcontrol->private_value; |
1828 | short gain; | 1826 | short gain; |
1829 | 1827 | ||
1830 | hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain)); | 1828 | hpi_handle_error(hpi_tuner_get_gain(h_control, &gain)); |
1831 | ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB; | 1829 | ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB; |
1832 | 1830 | ||
1833 | return 0; | 1831 | return 0; |
@@ -1843,7 +1841,7 @@ static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol, | |||
1843 | short gain; | 1841 | short gain; |
1844 | 1842 | ||
1845 | gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB; | 1843 | gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB; |
1846 | hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain)); | 1844 | hpi_handle_error(hpi_tuner_set_gain(h_control, gain)); |
1847 | 1845 | ||
1848 | return 1; | 1846 | return 1; |
1849 | } | 1847 | } |
@@ -1857,7 +1855,7 @@ static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol, | |||
1857 | u32 i; | 1855 | u32 i; |
1858 | 1856 | ||
1859 | for (i = 0; i < len; i++) { | 1857 | for (i = 0; i < len; i++) { |
1860 | err = hpi_tuner_query_band(ss, | 1858 | err = hpi_tuner_query_band( |
1861 | h_control, i, &band_list[i]); | 1859 | h_control, i, &band_list[i]); |
1862 | if (err != 0) | 1860 | if (err != 0) |
1863 | break; | 1861 | break; |
@@ -1913,7 +1911,7 @@ static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol, | |||
1913 | num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, | 1911 | num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, |
1914 | HPI_TUNER_BAND_LAST); | 1912 | HPI_TUNER_BAND_LAST); |
1915 | 1913 | ||
1916 | hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band)); | 1914 | hpi_handle_error(hpi_tuner_get_band(h_control, &band)); |
1917 | 1915 | ||
1918 | ucontrol->value.enumerated.item[0] = -1; | 1916 | ucontrol->value.enumerated.item[0] = -1; |
1919 | for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++) | 1917 | for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++) |
@@ -1940,7 +1938,7 @@ static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol, | |||
1940 | HPI_TUNER_BAND_LAST); | 1938 | HPI_TUNER_BAND_LAST); |
1941 | 1939 | ||
1942 | band = tuner_bands[ucontrol->value.enumerated.item[0]]; | 1940 | band = tuner_bands[ucontrol->value.enumerated.item[0]]; |
1943 | hpi_handle_error(hpi_tuner_set_band(ss, h_control, band)); | 1941 | hpi_handle_error(hpi_tuner_set_band(h_control, band)); |
1944 | 1942 | ||
1945 | return 1; | 1943 | return 1; |
1946 | } | 1944 | } |
@@ -1965,7 +1963,7 @@ static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol, | |||
1965 | 1963 | ||
1966 | for (band_iter = 0; band_iter < num_bands; band_iter++) { | 1964 | for (band_iter = 0; band_iter < num_bands; band_iter++) { |
1967 | for (idx = 0; idx < 3; idx++) { | 1965 | for (idx = 0; idx < 3; idx++) { |
1968 | err = hpi_tuner_query_frequency(ss, h_control, | 1966 | err = hpi_tuner_query_frequency(h_control, |
1969 | idx, tuner_bands[band_iter], | 1967 | idx, tuner_bands[band_iter], |
1970 | &temp_freq_range[idx]); | 1968 | &temp_freq_range[idx]); |
1971 | if (err != 0) | 1969 | if (err != 0) |
@@ -1998,7 +1996,7 @@ static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol, | |||
1998 | u32 h_control = kcontrol->private_value; | 1996 | u32 h_control = kcontrol->private_value; |
1999 | u32 freq; | 1997 | u32 freq; |
2000 | 1998 | ||
2001 | hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq)); | 1999 | hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq)); |
2002 | ucontrol->value.integer.value[0] = freq; | 2000 | ucontrol->value.integer.value[0] = freq; |
2003 | 2001 | ||
2004 | return 0; | 2002 | return 0; |
@@ -2011,7 +2009,7 @@ static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol, | |||
2011 | u32 freq; | 2009 | u32 freq; |
2012 | 2010 | ||
2013 | freq = ucontrol->value.integer.value[0]; | 2011 | freq = ucontrol->value.integer.value[0]; |
2014 | hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq)); | 2012 | hpi_handle_error(hpi_tuner_set_frequency(h_control, freq)); |
2015 | 2013 | ||
2016 | return 1; | 2014 | return 1; |
2017 | } | 2015 | } |
@@ -2026,8 +2024,8 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi, | |||
2026 | snd_control.private_value = hpi_ctl->h_control; | 2024 | snd_control.private_value = hpi_ctl->h_control; |
2027 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | 2025 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; |
2028 | 2026 | ||
2029 | if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) { | 2027 | if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) { |
2030 | asihpi_ctl_init(&snd_control, hpi_ctl, "gain"); | 2028 | asihpi_ctl_init(&snd_control, hpi_ctl, "Gain"); |
2031 | snd_control.info = snd_asihpi_tuner_gain_info; | 2029 | snd_control.info = snd_asihpi_tuner_gain_info; |
2032 | snd_control.get = snd_asihpi_tuner_gain_get; | 2030 | snd_control.get = snd_asihpi_tuner_gain_get; |
2033 | snd_control.put = snd_asihpi_tuner_gain_put; | 2031 | snd_control.put = snd_asihpi_tuner_gain_put; |
@@ -2036,7 +2034,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi, | |||
2036 | return -EINVAL; | 2034 | return -EINVAL; |
2037 | } | 2035 | } |
2038 | 2036 | ||
2039 | asihpi_ctl_init(&snd_control, hpi_ctl, "band"); | 2037 | asihpi_ctl_init(&snd_control, hpi_ctl, "Band"); |
2040 | snd_control.info = snd_asihpi_tuner_band_info; | 2038 | snd_control.info = snd_asihpi_tuner_band_info; |
2041 | snd_control.get = snd_asihpi_tuner_band_get; | 2039 | snd_control.get = snd_asihpi_tuner_band_get; |
2042 | snd_control.put = snd_asihpi_tuner_band_put; | 2040 | snd_control.put = snd_asihpi_tuner_band_put; |
@@ -2044,7 +2042,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi, | |||
2044 | if (ctl_add(card, &snd_control, asihpi) < 0) | 2042 | if (ctl_add(card, &snd_control, asihpi) < 0) |
2045 | return -EINVAL; | 2043 | return -EINVAL; |
2046 | 2044 | ||
2047 | asihpi_ctl_init(&snd_control, hpi_ctl, "freq"); | 2045 | asihpi_ctl_init(&snd_control, hpi_ctl, "Freq"); |
2048 | snd_control.info = snd_asihpi_tuner_freq_info; | 2046 | snd_control.info = snd_asihpi_tuner_freq_info; |
2049 | snd_control.get = snd_asihpi_tuner_freq_get; | 2047 | snd_control.get = snd_asihpi_tuner_freq_get; |
2050 | snd_control.put = snd_asihpi_tuner_freq_put; | 2048 | snd_control.put = snd_asihpi_tuner_freq_put; |
@@ -2095,7 +2093,7 @@ static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol, | |||
2095 | short an_gain_mB[HPI_MAX_CHANNELS], i; | 2093 | short an_gain_mB[HPI_MAX_CHANNELS], i; |
2096 | u16 err; | 2094 | u16 err; |
2097 | 2095 | ||
2098 | err = hpi_meter_get_peak(ss, h_control, an_gain_mB); | 2096 | err = hpi_meter_get_peak(h_control, an_gain_mB); |
2099 | 2097 | ||
2100 | for (i = 0; i < HPI_MAX_CHANNELS; i++) { | 2098 | for (i = 0; i < HPI_MAX_CHANNELS; i++) { |
2101 | if (err) { | 2099 | if (err) { |
@@ -2120,7 +2118,7 @@ static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi, | |||
2120 | struct snd_card *card = asihpi->card; | 2118 | struct snd_card *card = asihpi->card; |
2121 | struct snd_kcontrol_new snd_control; | 2119 | struct snd_kcontrol_new snd_control; |
2122 | 2120 | ||
2123 | asihpi_ctl_init(&snd_control, hpi_ctl, "meter"); | 2121 | asihpi_ctl_init(&snd_control, hpi_ctl, "Meter"); |
2124 | snd_control.access = | 2122 | snd_control.access = |
2125 | SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; | 2123 | SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; |
2126 | snd_control.info = snd_asihpi_meter_info; | 2124 | snd_control.info = snd_asihpi_meter_info; |
@@ -2140,7 +2138,7 @@ static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control) | |||
2140 | struct hpi_control hpi_ctl; | 2138 | struct hpi_control hpi_ctl; |
2141 | int s, err; | 2139 | int s, err; |
2142 | for (s = 0; s < 32; s++) { | 2140 | for (s = 0; s < 32; s++) { |
2143 | err = hpi_multiplexer_query_source(ss, h_control, s, | 2141 | err = hpi_multiplexer_query_source(h_control, s, |
2144 | &hpi_ctl. | 2142 | &hpi_ctl. |
2145 | src_node_type, | 2143 | src_node_type, |
2146 | &hpi_ctl. | 2144 | &hpi_ctl. |
@@ -2168,7 +2166,7 @@ static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol, | |||
2168 | uinfo->value.enumerated.items - 1; | 2166 | uinfo->value.enumerated.items - 1; |
2169 | 2167 | ||
2170 | err = | 2168 | err = |
2171 | hpi_multiplexer_query_source(ss, h_control, | 2169 | hpi_multiplexer_query_source(h_control, |
2172 | uinfo->value.enumerated.item, | 2170 | uinfo->value.enumerated.item, |
2173 | &src_node_type, &src_node_index); | 2171 | &src_node_type, &src_node_index); |
2174 | 2172 | ||
@@ -2186,11 +2184,11 @@ static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol, | |||
2186 | u16 src_node_type, src_node_index; | 2184 | u16 src_node_type, src_node_index; |
2187 | int s; | 2185 | int s; |
2188 | 2186 | ||
2189 | hpi_handle_error(hpi_multiplexer_get_source(ss, h_control, | 2187 | hpi_handle_error(hpi_multiplexer_get_source(h_control, |
2190 | &source_type, &source_index)); | 2188 | &source_type, &source_index)); |
2191 | /* Should cache this search result! */ | 2189 | /* Should cache this search result! */ |
2192 | for (s = 0; s < 256; s++) { | 2190 | for (s = 0; s < 256; s++) { |
2193 | if (hpi_multiplexer_query_source(ss, h_control, s, | 2191 | if (hpi_multiplexer_query_source(h_control, s, |
2194 | &src_node_type, &src_node_index)) | 2192 | &src_node_type, &src_node_index)) |
2195 | break; | 2193 | break; |
2196 | 2194 | ||
@@ -2201,7 +2199,7 @@ static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol, | |||
2201 | } | 2199 | } |
2202 | } | 2200 | } |
2203 | snd_printd(KERN_WARNING | 2201 | snd_printd(KERN_WARNING |
2204 | "control %x failed to match mux source %hu %hu\n", | 2202 | "Control %x failed to match mux source %hu %hu\n", |
2205 | h_control, source_type, source_index); | 2203 | h_control, source_type, source_index); |
2206 | ucontrol->value.enumerated.item[0] = 0; | 2204 | ucontrol->value.enumerated.item[0] = 0; |
2207 | return 0; | 2205 | return 0; |
@@ -2217,12 +2215,12 @@ static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol, | |||
2217 | 2215 | ||
2218 | change = 1; | 2216 | change = 1; |
2219 | 2217 | ||
2220 | e = hpi_multiplexer_query_source(ss, h_control, | 2218 | e = hpi_multiplexer_query_source(h_control, |
2221 | ucontrol->value.enumerated.item[0], | 2219 | ucontrol->value.enumerated.item[0], |
2222 | &source_type, &source_index); | 2220 | &source_type, &source_index); |
2223 | if (!e) | 2221 | if (!e) |
2224 | hpi_handle_error( | 2222 | hpi_handle_error( |
2225 | hpi_multiplexer_set_source(ss, h_control, | 2223 | hpi_multiplexer_set_source(h_control, |
2226 | source_type, source_index)); | 2224 | source_type, source_index)); |
2227 | return change; | 2225 | return change; |
2228 | } | 2226 | } |
@@ -2234,11 +2232,7 @@ static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi, | |||
2234 | struct snd_card *card = asihpi->card; | 2232 | struct snd_card *card = asihpi->card; |
2235 | struct snd_kcontrol_new snd_control; | 2233 | struct snd_kcontrol_new snd_control; |
2236 | 2234 | ||
2237 | #if ASI_STYLE_NAMES | 2235 | asihpi_ctl_init(&snd_control, hpi_ctl, "Route"); |
2238 | asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer"); | ||
2239 | #else | ||
2240 | asihpi_ctl_init(&snd_control, hpi_ctl, "route"); | ||
2241 | #endif | ||
2242 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | 2236 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; |
2243 | snd_control.info = snd_asihpi_mux_info; | 2237 | snd_control.info = snd_asihpi_mux_info; |
2244 | snd_control.get = snd_asihpi_mux_get; | 2238 | snd_control.get = snd_asihpi_mux_get; |
@@ -2254,33 +2248,38 @@ static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi, | |||
2254 | static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, | 2248 | static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, |
2255 | struct snd_ctl_elem_info *uinfo) | 2249 | struct snd_ctl_elem_info *uinfo) |
2256 | { | 2250 | { |
2257 | static char *mode_names[HPI_CHANNEL_MODE_LAST] = { | 2251 | static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = { |
2258 | "normal", "swap", | 2252 | "invalid", |
2259 | "from_left", "from_right", | 2253 | "Normal", "Swap", |
2260 | "to_left", "to_right" | 2254 | "From Left", "From Right", |
2255 | "To Left", "To Right" | ||
2261 | }; | 2256 | }; |
2262 | 2257 | ||
2263 | u32 h_control = kcontrol->private_value; | 2258 | u32 h_control = kcontrol->private_value; |
2264 | u16 mode; | 2259 | u16 mode; |
2265 | int i; | 2260 | int i; |
2261 | u16 mode_map[6]; | ||
2262 | int valid_modes = 0; | ||
2266 | 2263 | ||
2267 | /* HPI channel mode values can be from 1 to 6 | 2264 | /* HPI channel mode values can be from 1 to 6 |
2268 | Some adapters only support a contiguous subset | 2265 | Some adapters only support a contiguous subset |
2269 | */ | 2266 | */ |
2270 | for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++) | 2267 | for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++) |
2271 | if (hpi_channel_mode_query_mode( | 2268 | if (!hpi_channel_mode_query_mode( |
2272 | ss, h_control, i, &mode)) | 2269 | h_control, i, &mode)) { |
2273 | break; | 2270 | mode_map[valid_modes] = mode; |
2271 | valid_modes++; | ||
2272 | } | ||
2274 | 2273 | ||
2275 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2274 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
2276 | uinfo->count = 1; | 2275 | uinfo->count = 1; |
2277 | uinfo->value.enumerated.items = i; | 2276 | uinfo->value.enumerated.items = valid_modes; |
2278 | 2277 | ||
2279 | if (uinfo->value.enumerated.item >= i) | 2278 | if (uinfo->value.enumerated.item >= valid_modes) |
2280 | uinfo->value.enumerated.item = i - 1; | 2279 | uinfo->value.enumerated.item = valid_modes - 1; |
2281 | 2280 | ||
2282 | strcpy(uinfo->value.enumerated.name, | 2281 | strcpy(uinfo->value.enumerated.name, |
2283 | mode_names[uinfo->value.enumerated.item]); | 2282 | mode_names[mode_map[uinfo->value.enumerated.item]]); |
2284 | 2283 | ||
2285 | return 0; | 2284 | return 0; |
2286 | } | 2285 | } |
@@ -2291,7 +2290,7 @@ static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol, | |||
2291 | u32 h_control = kcontrol->private_value; | 2290 | u32 h_control = kcontrol->private_value; |
2292 | u16 mode; | 2291 | u16 mode; |
2293 | 2292 | ||
2294 | if (hpi_channel_mode_get(ss, h_control, &mode)) | 2293 | if (hpi_channel_mode_get(h_control, &mode)) |
2295 | mode = 1; | 2294 | mode = 1; |
2296 | 2295 | ||
2297 | ucontrol->value.enumerated.item[0] = mode - 1; | 2296 | ucontrol->value.enumerated.item[0] = mode - 1; |
@@ -2307,7 +2306,7 @@ static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol, | |||
2307 | 2306 | ||
2308 | change = 1; | 2307 | change = 1; |
2309 | 2308 | ||
2310 | hpi_handle_error(hpi_channel_mode_set(ss, h_control, | 2309 | hpi_handle_error(hpi_channel_mode_set(h_control, |
2311 | ucontrol->value.enumerated.item[0] + 1)); | 2310 | ucontrol->value.enumerated.item[0] + 1)); |
2312 | return change; | 2311 | return change; |
2313 | } | 2312 | } |
@@ -2319,7 +2318,7 @@ static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi, | |||
2319 | struct snd_card *card = asihpi->card; | 2318 | struct snd_card *card = asihpi->card; |
2320 | struct snd_kcontrol_new snd_control; | 2319 | struct snd_kcontrol_new snd_control; |
2321 | 2320 | ||
2322 | asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode"); | 2321 | asihpi_ctl_init(&snd_control, hpi_ctl, "Mode"); |
2323 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | 2322 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; |
2324 | snd_control.info = snd_asihpi_cmode_info; | 2323 | snd_control.info = snd_asihpi_cmode_info; |
2325 | snd_control.get = snd_asihpi_cmode_get; | 2324 | snd_control.get = snd_asihpi_cmode_get; |
@@ -2331,15 +2330,12 @@ static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi, | |||
2331 | /*------------------------------------------------------------ | 2330 | /*------------------------------------------------------------ |
2332 | Sampleclock source controls | 2331 | Sampleclock source controls |
2333 | ------------------------------------------------------------*/ | 2332 | ------------------------------------------------------------*/ |
2334 | 2333 | static char *sampleclock_sources[MAX_CLOCKSOURCES] = { | |
2335 | static char *sampleclock_sources[MAX_CLOCKSOURCES] = | 2334 | "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header", |
2336 | { "N/A", "local PLL", "AES/EBU sync", "word external", "word header", | 2335 | "SMPTE", "Digital1", "Auto", "Network", "Invalid", |
2337 | "SMPTE", "AES/EBU in1", "auto", "network", "invalid", | 2336 | "Prev Module", |
2338 | "prev module", | 2337 | "Digital2", "Digital3", "Digital4", "Digital5", |
2339 | "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5", | 2338 | "Digital6", "Digital7", "Digital8"}; |
2340 | "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"}; | ||
2341 | |||
2342 | |||
2343 | 2339 | ||
2344 | static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol, | 2340 | static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol, |
2345 | struct snd_ctl_elem_info *uinfo) | 2341 | struct snd_ctl_elem_info *uinfo) |
@@ -2371,11 +2367,11 @@ static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol, | |||
2371 | int i; | 2367 | int i; |
2372 | 2368 | ||
2373 | ucontrol->value.enumerated.item[0] = 0; | 2369 | ucontrol->value.enumerated.item[0] = 0; |
2374 | if (hpi_sample_clock_get_source(ss, h_control, &source)) | 2370 | if (hpi_sample_clock_get_source(h_control, &source)) |
2375 | source = 0; | 2371 | source = 0; |
2376 | 2372 | ||
2377 | if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) | 2373 | if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) |
2378 | if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex)) | 2374 | if (hpi_sample_clock_get_source_index(h_control, &srcindex)) |
2379 | srcindex = 0; | 2375 | srcindex = 0; |
2380 | 2376 | ||
2381 | for (i = 0; i < clkcache->count; i++) | 2377 | for (i = 0; i < clkcache->count; i++) |
@@ -2402,11 +2398,11 @@ static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol, | |||
2402 | if (item >= clkcache->count) | 2398 | if (item >= clkcache->count) |
2403 | item = clkcache->count-1; | 2399 | item = clkcache->count-1; |
2404 | 2400 | ||
2405 | hpi_handle_error(hpi_sample_clock_set_source(ss, | 2401 | hpi_handle_error(hpi_sample_clock_set_source( |
2406 | h_control, clkcache->s[item].source)); | 2402 | h_control, clkcache->s[item].source)); |
2407 | 2403 | ||
2408 | if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) | 2404 | if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) |
2409 | hpi_handle_error(hpi_sample_clock_set_source_index(ss, | 2405 | hpi_handle_error(hpi_sample_clock_set_source_index( |
2410 | h_control, clkcache->s[item].index)); | 2406 | h_control, clkcache->s[item].index)); |
2411 | return change; | 2407 | return change; |
2412 | } | 2408 | } |
@@ -2434,7 +2430,7 @@ static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol, | |||
2434 | u32 rate; | 2430 | u32 rate; |
2435 | u16 e; | 2431 | u16 e; |
2436 | 2432 | ||
2437 | e = hpi_sample_clock_get_local_rate(ss, h_control, &rate); | 2433 | e = hpi_sample_clock_get_local_rate(h_control, &rate); |
2438 | if (!e) | 2434 | if (!e) |
2439 | ucontrol->value.integer.value[0] = rate; | 2435 | ucontrol->value.integer.value[0] = rate; |
2440 | else | 2436 | else |
@@ -2452,7 +2448,7 @@ static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol, | |||
2452 | asihpi->mixer_clkrate[addr][1] != right; | 2448 | asihpi->mixer_clkrate[addr][1] != right; |
2453 | */ | 2449 | */ |
2454 | change = 1; | 2450 | change = 1; |
2455 | hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control, | 2451 | hpi_handle_error(hpi_sample_clock_set_local_rate(h_control, |
2456 | ucontrol->value.integer.value[0])); | 2452 | ucontrol->value.integer.value[0])); |
2457 | return change; | 2453 | return change; |
2458 | } | 2454 | } |
@@ -2476,7 +2472,7 @@ static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol, | |||
2476 | u32 rate; | 2472 | u32 rate; |
2477 | u16 e; | 2473 | u16 e; |
2478 | 2474 | ||
2479 | e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate); | 2475 | e = hpi_sample_clock_get_sample_rate(h_control, &rate); |
2480 | if (!e) | 2476 | if (!e) |
2481 | ucontrol->value.integer.value[0] = rate; | 2477 | ucontrol->value.integer.value[0] = rate; |
2482 | else | 2478 | else |
@@ -2501,7 +2497,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, | |||
2501 | clkcache->has_local = 0; | 2497 | clkcache->has_local = 0; |
2502 | 2498 | ||
2503 | for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) { | 2499 | for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) { |
2504 | if (hpi_sample_clock_query_source(ss, hSC, | 2500 | if (hpi_sample_clock_query_source(hSC, |
2505 | i, &source)) | 2501 | i, &source)) |
2506 | break; | 2502 | break; |
2507 | clkcache->s[i].source = source; | 2503 | clkcache->s[i].source = source; |
@@ -2515,7 +2511,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, | |||
2515 | if (has_aes_in) | 2511 | if (has_aes_in) |
2516 | /* already will have picked up index 0 above */ | 2512 | /* already will have picked up index 0 above */ |
2517 | for (j = 1; j < 8; j++) { | 2513 | for (j = 1; j < 8; j++) { |
2518 | if (hpi_sample_clock_query_source_index(ss, hSC, | 2514 | if (hpi_sample_clock_query_source_index(hSC, |
2519 | j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT, | 2515 | j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT, |
2520 | &source)) | 2516 | &source)) |
2521 | break; | 2517 | break; |
@@ -2528,7 +2524,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, | |||
2528 | } | 2524 | } |
2529 | clkcache->count = i; | 2525 | clkcache->count = i; |
2530 | 2526 | ||
2531 | asihpi_ctl_init(&snd_control, hpi_ctl, "source"); | 2527 | asihpi_ctl_init(&snd_control, hpi_ctl, "Source"); |
2532 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; | 2528 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; |
2533 | snd_control.info = snd_asihpi_clksrc_info; | 2529 | snd_control.info = snd_asihpi_clksrc_info; |
2534 | snd_control.get = snd_asihpi_clksrc_get; | 2530 | snd_control.get = snd_asihpi_clksrc_get; |
@@ -2538,7 +2534,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, | |||
2538 | 2534 | ||
2539 | 2535 | ||
2540 | if (clkcache->has_local) { | 2536 | if (clkcache->has_local) { |
2541 | asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate"); | 2537 | asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate"); |
2542 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; | 2538 | snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; |
2543 | snd_control.info = snd_asihpi_clklocal_info; | 2539 | snd_control.info = snd_asihpi_clklocal_info; |
2544 | snd_control.get = snd_asihpi_clklocal_get; | 2540 | snd_control.get = snd_asihpi_clklocal_get; |
@@ -2549,7 +2545,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, | |||
2549 | return -EINVAL; | 2545 | return -EINVAL; |
2550 | } | 2546 | } |
2551 | 2547 | ||
2552 | asihpi_ctl_init(&snd_control, hpi_ctl, "rate"); | 2548 | asihpi_ctl_init(&snd_control, hpi_ctl, "Rate"); |
2553 | snd_control.access = | 2549 | snd_control.access = |
2554 | SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; | 2550 | SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; |
2555 | snd_control.info = snd_asihpi_clkrate_info; | 2551 | snd_control.info = snd_asihpi_clkrate_info; |
@@ -2571,10 +2567,10 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2571 | 2567 | ||
2572 | if (snd_BUG_ON(!asihpi)) | 2568 | if (snd_BUG_ON(!asihpi)) |
2573 | return -EINVAL; | 2569 | return -EINVAL; |
2574 | strcpy(card->mixername, "asihpi mixer"); | 2570 | strcpy(card->mixername, "Asihpi Mixer"); |
2575 | 2571 | ||
2576 | err = | 2572 | err = |
2577 | hpi_mixer_open(ss, asihpi->adapter_index, | 2573 | hpi_mixer_open(asihpi->adapter_index, |
2578 | &asihpi->h_mixer); | 2574 | &asihpi->h_mixer); |
2579 | hpi_handle_error(err); | 2575 | hpi_handle_error(err); |
2580 | if (err) | 2576 | if (err) |
@@ -2585,7 +2581,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2585 | 2581 | ||
2586 | for (idx = 0; idx < 2000; idx++) { | 2582 | for (idx = 0; idx < 2000; idx++) { |
2587 | err = hpi_mixer_get_control_by_index( | 2583 | err = hpi_mixer_get_control_by_index( |
2588 | ss, asihpi->h_mixer, | 2584 | asihpi->h_mixer, |
2589 | idx, | 2585 | idx, |
2590 | &hpi_ctl.src_node_type, | 2586 | &hpi_ctl.src_node_type, |
2591 | &hpi_ctl.src_node_index, | 2587 | &hpi_ctl.src_node_index, |
@@ -2597,7 +2593,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2597 | if (err == HPI_ERROR_CONTROL_DISABLED) { | 2593 | if (err == HPI_ERROR_CONTROL_DISABLED) { |
2598 | if (mixer_dump) | 2594 | if (mixer_dump) |
2599 | snd_printk(KERN_INFO | 2595 | snd_printk(KERN_INFO |
2600 | "disabled HPI control(%d)\n", | 2596 | "Disabled HPI Control(%d)\n", |
2601 | idx); | 2597 | idx); |
2602 | continue; | 2598 | continue; |
2603 | } else | 2599 | } else |
@@ -2662,7 +2658,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2662 | default: | 2658 | default: |
2663 | if (mixer_dump) | 2659 | if (mixer_dump) |
2664 | snd_printk(KERN_INFO | 2660 | snd_printk(KERN_INFO |
2665 | "untranslated HPI control" | 2661 | "Untranslated HPI Control" |
2666 | "(%d) %d %d %d %d %d\n", | 2662 | "(%d) %d %d %d %d %d\n", |
2667 | idx, | 2663 | idx, |
2668 | hpi_ctl.control_type, | 2664 | hpi_ctl.control_type, |
@@ -2712,14 +2708,14 @@ snd_asihpi_proc_read(struct snd_info_entry *entry, | |||
2712 | version & 0x7, | 2708 | version & 0x7, |
2713 | ((version >> 13) * 100) + ((version >> 7) & 0x3f)); | 2709 | ((version >> 13) * 100) + ((version >> 7) & 0x3f)); |
2714 | 2710 | ||
2715 | err = hpi_mixer_get_control(ss, asihpi->h_mixer, | 2711 | err = hpi_mixer_get_control(asihpi->h_mixer, |
2716 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, | 2712 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, |
2717 | HPI_CONTROL_SAMPLECLOCK, &h_control); | 2713 | HPI_CONTROL_SAMPLECLOCK, &h_control); |
2718 | 2714 | ||
2719 | if (!err) { | 2715 | if (!err) { |
2720 | err = hpi_sample_clock_get_sample_rate(ss, | 2716 | err = hpi_sample_clock_get_sample_rate( |
2721 | h_control, &rate); | 2717 | h_control, &rate); |
2722 | err += hpi_sample_clock_get_source(ss, h_control, &source); | 2718 | err += hpi_sample_clock_get_source(h_control, &source); |
2723 | 2719 | ||
2724 | if (!err) | 2720 | if (!err) |
2725 | snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n", | 2721 | snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n", |
@@ -2841,15 +2837,17 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2841 | if (err < 0) | 2837 | if (err < 0) |
2842 | return err; | 2838 | return err; |
2843 | snd_printk(KERN_WARNING | 2839 | snd_printk(KERN_WARNING |
2844 | "**** WARNING **** adapter index %d->ALSA index %d\n", | 2840 | "**** WARNING **** Adapter index %d->ALSA index %d\n", |
2845 | hpi_card->index, card->number); | 2841 | hpi_card->index, card->number); |
2846 | } | 2842 | } |
2847 | 2843 | ||
2844 | snd_card_set_dev(card, &pci_dev->dev); | ||
2845 | |||
2848 | asihpi = (struct snd_card_asihpi *) card->private_data; | 2846 | asihpi = (struct snd_card_asihpi *) card->private_data; |
2849 | asihpi->card = card; | 2847 | asihpi->card = card; |
2850 | asihpi->pci = hpi_card->pci; | 2848 | asihpi->pci = pci_dev; |
2851 | asihpi->adapter_index = hpi_card->index; | 2849 | asihpi->adapter_index = hpi_card->index; |
2852 | hpi_handle_error(hpi_adapter_get_info(ss, | 2850 | hpi_handle_error(hpi_adapter_get_info( |
2853 | asihpi->adapter_index, | 2851 | asihpi->adapter_index, |
2854 | &asihpi->num_outstreams, | 2852 | &asihpi->num_outstreams, |
2855 | &asihpi->num_instreams, | 2853 | &asihpi->num_instreams, |
@@ -2859,7 +2857,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2859 | version = asihpi->version; | 2857 | version = asihpi->version; |
2860 | snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d " | 2858 | snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d " |
2861 | "num_instreams=%d S/N=%d\n" | 2859 | "num_instreams=%d S/N=%d\n" |
2862 | "hw version %c%d DSP code version %03d\n", | 2860 | "Hw Version %c%d DSP code version %03d\n", |
2863 | asihpi->type, asihpi->adapter_index, | 2861 | asihpi->type, asihpi->adapter_index, |
2864 | asihpi->num_outstreams, | 2862 | asihpi->num_outstreams, |
2865 | asihpi->num_instreams, asihpi->serial_number, | 2863 | asihpi->num_instreams, asihpi->serial_number, |
@@ -2871,33 +2869,33 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2871 | if (pcm_substreams < asihpi->num_instreams) | 2869 | if (pcm_substreams < asihpi->num_instreams) |
2872 | pcm_substreams = asihpi->num_instreams; | 2870 | pcm_substreams = asihpi->num_instreams; |
2873 | 2871 | ||
2874 | err = hpi_adapter_get_property(ss, asihpi->adapter_index, | 2872 | err = hpi_adapter_get_property(asihpi->adapter_index, |
2875 | HPI_ADAPTER_PROPERTY_CAPS1, | 2873 | HPI_ADAPTER_PROPERTY_CAPS1, |
2876 | NULL, &asihpi->support_grouping); | 2874 | NULL, &asihpi->support_grouping); |
2877 | if (err) | 2875 | if (err) |
2878 | asihpi->support_grouping = 0; | 2876 | asihpi->support_grouping = 0; |
2879 | 2877 | ||
2880 | err = hpi_adapter_get_property(ss, asihpi->adapter_index, | 2878 | err = hpi_adapter_get_property(asihpi->adapter_index, |
2881 | HPI_ADAPTER_PROPERTY_CAPS2, | 2879 | HPI_ADAPTER_PROPERTY_CAPS2, |
2882 | &asihpi->support_mrx, NULL); | 2880 | &asihpi->support_mrx, NULL); |
2883 | if (err) | 2881 | if (err) |
2884 | asihpi->support_mrx = 0; | 2882 | asihpi->support_mrx = 0; |
2885 | 2883 | ||
2886 | err = hpi_adapter_get_property(ss, asihpi->adapter_index, | 2884 | err = hpi_adapter_get_property(asihpi->adapter_index, |
2887 | HPI_ADAPTER_PROPERTY_INTERVAL, | 2885 | HPI_ADAPTER_PROPERTY_INTERVAL, |
2888 | NULL, &asihpi->update_interval_frames); | 2886 | NULL, &asihpi->update_interval_frames); |
2889 | if (err) | 2887 | if (err) |
2890 | asihpi->update_interval_frames = 512; | 2888 | asihpi->update_interval_frames = 512; |
2891 | 2889 | ||
2892 | hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index, | 2890 | hpi_handle_error(hpi_instream_open(asihpi->adapter_index, |
2893 | 0, &h_stream)); | 2891 | 0, &h_stream)); |
2894 | 2892 | ||
2895 | err = hpi_instream_host_buffer_free(ss, h_stream); | 2893 | err = hpi_instream_host_buffer_free(h_stream); |
2896 | asihpi->support_mmap = (!err); | 2894 | asihpi->support_mmap = (!err); |
2897 | 2895 | ||
2898 | hpi_handle_error(hpi_instream_close(ss, h_stream)); | 2896 | hpi_handle_error(hpi_instream_close(h_stream)); |
2899 | 2897 | ||
2900 | err = hpi_adapter_get_property(ss, asihpi->adapter_index, | 2898 | err = hpi_adapter_get_property(asihpi->adapter_index, |
2901 | HPI_ADAPTER_PROPERTY_CURCHANNELS, | 2899 | HPI_ADAPTER_PROPERTY_CURCHANNELS, |
2902 | &asihpi->in_max_chans, &asihpi->out_max_chans); | 2900 | &asihpi->in_max_chans, &asihpi->out_max_chans); |
2903 | if (err) { | 2901 | if (err) { |
@@ -2923,13 +2921,13 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2923 | goto __nodev; | 2921 | goto __nodev; |
2924 | } | 2922 | } |
2925 | 2923 | ||
2926 | err = hpi_mixer_get_control(ss, asihpi->h_mixer, | 2924 | err = hpi_mixer_get_control(asihpi->h_mixer, |
2927 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, | 2925 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, |
2928 | HPI_CONTROL_SAMPLECLOCK, &h_control); | 2926 | HPI_CONTROL_SAMPLECLOCK, &h_control); |
2929 | 2927 | ||
2930 | if (!err) | 2928 | if (!err) |
2931 | err = hpi_sample_clock_set_local_rate( | 2929 | err = hpi_sample_clock_set_local_rate( |
2932 | ss, h_control, adapter_fs); | 2930 | h_control, adapter_fs); |
2933 | 2931 | ||
2934 | snd_asihpi_proc_init(asihpi); | 2932 | snd_asihpi_proc_init(asihpi); |
2935 | 2933 | ||