VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / sound / drivers / vx / vx_pcm.c
1 /*
2  * Driver for Digigram VX soundcards
3  *
4  * PCM part
5  *
6  * Copyright (c) 2002,2003 by Takashi Iwai <tiwai@suse.de>
7  *
8  *   This program is free software; you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  *
22  *
23  * STRATEGY
24  *  for playback, we send series of "chunks", which size is equal with the
25  *  IBL size, typically 126 samples.  at each end of chunk, the end-of-buffer
26  *  interrupt is notified, and the interrupt handler will feed the next chunk.
27  *
28  *  the current position is calculated from the sample count RMH.
29  *  pipe->transferred is the counter of data which has been already transferred.
30  *  if this counter reaches to the period size, snd_pcm_period_elapsed() will
31  *  be issued.
32  *
33  *  for capture, the situation is much easier.
34  *  to get a low latency response, we'll check the capture streams at each
35  *  interrupt (capture stream has no EOB notification).  if the pending
36  *  data is accumulated to the period size, snd_pcm_period_elapsed() is
37  *  called and the pointer is updated.
38  *
39  *  the current point of read buffer is kept in pipe->hw_ptr.  note that
40  *  this is in bytes.
41  *
42  *
43  * TODO
44  *  - linked trigger for full-duplex mode.
45  *  - scheduled action on the stream.
46  */
47
48 #include <sound/driver.h>
49 #include <linux/slab.h>
50 #include <linux/vmalloc.h>
51 #include <sound/core.h>
52 #include <sound/asoundef.h>
53 #include <sound/pcm.h>
54 #include <sound/vx_core.h>
55 #include "vx_cmd.h"
56
57 #define chip_t  vx_core_t
58
59
60 /*
61  * we use a vmalloc'ed (sg-)buffer
62  */
63
64 /* get the physical page pointer on the given offset */
65 static struct page *snd_pcm_get_vmalloc_page(snd_pcm_substream_t *subs, unsigned long offset)
66 {
67         void *pageptr = subs->runtime->dma_area + offset;
68         return vmalloc_to_page(pageptr);
69 }
70
71 /*
72  * allocate a buffer via vmalloc_32().
73  * called from hw_params
74  * NOTE: this may be called not only once per pcm open!
75  */
76 static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
77 {
78         snd_pcm_runtime_t *runtime = subs->runtime;
79         if (runtime->dma_area) {
80                 /* already allocated */
81                 if (runtime->dma_bytes >= size)
82                         return 0; /* already enough large */
83                 vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */
84         }
85         runtime->dma_area = vmalloc_32(size);
86         if (! runtime->dma_area)
87                 return -ENOMEM;
88         memset(runtime->dma_area, 0, size);
89         runtime->dma_bytes = size;
90         return 1; /* changed */
91 }
92
93 /*
94  * free the buffer.
95  * called from hw_free callback
96  * NOTE: this may be called not only once per pcm open!
97  */
98 static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
99 {
100         snd_pcm_runtime_t *runtime = subs->runtime;
101         if (runtime->dma_area) {
102                 vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */
103                 runtime->dma_area = NULL;
104         }
105         return 0;
106 }
107
108
109 /*
110  * read three pending pcm bytes via inb()
111  */
112 static void vx_pcm_read_per_bytes(vx_core_t *chip, snd_pcm_runtime_t *runtime, vx_pipe_t *pipe)
113 {
114         int offset = pipe->hw_ptr;
115         unsigned char *buf = (unsigned char *)(runtime->dma_area + offset);
116         *buf++ = vx_inb(chip, RXH);
117         if (++offset >= pipe->buffer_bytes) {
118                 offset = 0;
119                 buf = (unsigned char *)runtime->dma_area;
120         }
121         *buf++ = vx_inb(chip, RXM);
122         if (++offset >= pipe->buffer_bytes) {
123                 offset = 0;
124                 buf = (unsigned char *)runtime->dma_area;
125         }
126         *buf++ = vx_inb(chip, RXL);
127         if (++offset >= pipe->buffer_bytes) {
128                 offset = 0;
129                 buf = (unsigned char *)runtime->dma_area;
130         }
131         pipe->hw_ptr = offset;
132 }
133
134 /*
135  * vx_set_pcx_time - convert from the PC time to the RMH status time.
136  * @pc_time: the pointer for the PC-time to set
137  * @dsp_time: the pointer for RMH status time array
138  */
139 static void vx_set_pcx_time(vx_core_t *chip, pcx_time_t *pc_time, unsigned int *dsp_time)
140 {
141         dsp_time[0] = (unsigned int)((*pc_time) >> 24) & PCX_TIME_HI_MASK;
142         dsp_time[1] = (unsigned int)(*pc_time) &  MASK_DSP_WORD;
143 }
144
145 /*
146  * vx_set_differed_time - set the differed time if specified
147  * @rmh: the rmh record to modify
148  * @pipe: the pipe to be checked
149  *
150  * if the pipe is programmed with the differed time, set the DSP time
151  * on the rmh and changes its command length.
152  *
153  * returns the increase of the command length.
154  */
155 static int vx_set_differed_time(vx_core_t *chip, struct vx_rmh *rmh, vx_pipe_t *pipe)
156 {
157         /* Update The length added to the RMH command by the timestamp */
158         if (! (pipe->differed_type & DC_DIFFERED_DELAY))
159                 return 0;
160                 
161         /* Set the T bit */
162         rmh->Cmd[0] |= DSP_DIFFERED_COMMAND_MASK;
163
164         /* Time stamp is the 1st following parameter */
165         vx_set_pcx_time(chip, &pipe->pcx_time, &rmh->Cmd[1]);
166
167         /* Add the flags to a notified differed command */
168         if (pipe->differed_type & DC_NOTIFY_DELAY)
169                 rmh->Cmd[1] |= NOTIFY_MASK_TIME_HIGH ;
170
171         /* Add the flags to a multiple differed command */
172         if (pipe->differed_type & DC_MULTIPLE_DELAY)
173                 rmh->Cmd[1] |= MULTIPLE_MASK_TIME_HIGH;
174
175         /* Add the flags to a stream-time differed command */
176         if (pipe->differed_type & DC_STREAM_TIME_DELAY)
177                 rmh->Cmd[1] |= STREAM_MASK_TIME_HIGH;
178                 
179         rmh->LgCmd += 2;
180         return 2;
181 }
182
183 /*
184  * vx_set_stream_format - send the stream format command
185  * @pipe: the affected pipe
186  * @data: format bitmask
187  */
188 static int vx_set_stream_format(vx_core_t *chip, vx_pipe_t *pipe, unsigned int data)
189 {
190         struct vx_rmh rmh;
191
192         vx_init_rmh(&rmh, pipe->is_capture ?
193                     CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
194         rmh.Cmd[0] |= pipe->number << FIELD_SIZE;
195
196         /* Command might be longer since we may have to add a timestamp */
197         vx_set_differed_time(chip, &rmh, pipe);
198
199         rmh.Cmd[rmh.LgCmd] = (data & 0xFFFFFF00) >> 8;
200         rmh.Cmd[rmh.LgCmd + 1] = (data & 0xFF) << 16 /*| (datal & 0xFFFF00) >> 8*/;
201         rmh.LgCmd += 2;
202     
203         return vx_send_msg(chip, &rmh);
204 }
205
206
207 /*
208  * vx_set_format - set the format of a pipe
209  * @pipe: the affected pipe
210  * @runtime: pcm runtime instance to be referred
211  *
212  * returns 0 if successful, or a negative error code.
213  */
214 static int vx_set_format(vx_core_t *chip, vx_pipe_t *pipe,
215                          snd_pcm_runtime_t *runtime)
216 {
217         unsigned int header = HEADER_FMT_BASE;
218
219         if (runtime->channels == 1)
220                 header |= HEADER_FMT_MONO;
221         if (snd_pcm_format_little_endian(runtime->format))
222                 header |= HEADER_FMT_INTEL;
223         if (runtime->rate < 32000 && runtime->rate > 11025)
224                 header |= HEADER_FMT_UPTO32;
225         else if (runtime->rate <= 11025)
226                 header |= HEADER_FMT_UPTO11;
227
228         switch (snd_pcm_format_physical_width(runtime->format)) {
229         // case 8: break;
230         case 16: header |= HEADER_FMT_16BITS; break;
231         case 24: header |= HEADER_FMT_24BITS; break;
232         default : 
233                 snd_BUG();
234                 return -EINVAL;
235         };
236
237         return vx_set_stream_format(chip, pipe, header);
238 }
239
240 /*
241  * set / query the IBL size
242  */
243 static int vx_set_ibl(vx_core_t *chip, struct vx_ibl_info *info)
244 {
245         int err;
246         struct vx_rmh rmh;
247
248         vx_init_rmh(&rmh, CMD_IBL);
249         rmh.Cmd[0] |= info->size & 0x03ffff;
250         err = vx_send_msg(chip, &rmh);
251         if (err < 0)
252                 return err;
253         info->size = rmh.Stat[0];
254         info->max_size = rmh.Stat[1];
255         info->min_size = rmh.Stat[2];
256         info->granularity = rmh.Stat[3];
257         snd_printdd(KERN_DEBUG "vx_set_ibl: size = %d, max = %d, min = %d, gran = %d\n",
258                    info->size, info->max_size, info->min_size, info->granularity);
259         return 0;
260 }
261
262
263 /*
264  * vx_get_pipe_state - get the state of a pipe
265  * @pipe: the pipe to be checked
266  * @state: the pointer for the returned state
267  *
268  * checks the state of a given pipe, and stores the state (1 = running,
269  * 0 = paused) on the given pointer.
270  *
271  * called from trigger callback only
272  */
273 static int vx_get_pipe_state(vx_core_t *chip, vx_pipe_t *pipe, int *state)
274 {
275         int err;
276         struct vx_rmh rmh;
277
278         vx_init_rmh(&rmh, CMD_PIPE_STATE);
279         vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
280         err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
281         if (! err)
282                 *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
283         return err;
284 }
285
286
287 /*
288  * vx_query_hbuffer_size - query available h-buffer size in bytes
289  * @pipe: the pipe to be checked
290  *
291  * return the available size on h-buffer in bytes,
292  * or a negative error code.
293  *
294  * NOTE: calling this function always switches to the stream mode.
295  *       you'll need to disconnect the host to get back to the
296  *       normal mode.
297  */
298 static int vx_query_hbuffer_size(vx_core_t *chip, vx_pipe_t *pipe)
299 {
300         int result;
301         struct vx_rmh rmh;
302
303         vx_init_rmh(&rmh, CMD_SIZE_HBUFFER);
304         vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
305         if (pipe->is_capture)
306                 rmh.Cmd[0] |= 0x00000001;
307         result = vx_send_msg(chip, &rmh);
308         if (! result)
309                 result = rmh.Stat[0] & 0xffff;
310         return result;
311 }
312
313
314 /*
315  * vx_pipe_can_start - query whether a pipe is ready for start
316  * @pipe: the pipe to be checked
317  *
318  * return 1 if ready, 0 if not ready, and negative value on error.
319  *
320  * called from trigger callback only
321  */
322 static int vx_pipe_can_start(vx_core_t *chip, vx_pipe_t *pipe)
323 {
324         int err;
325         struct vx_rmh rmh;
326         
327         vx_init_rmh(&rmh, CMD_CAN_START_PIPE);
328         vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
329         rmh.Cmd[0] |= 1;
330
331         err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
332         if (! err) {
333                 if (rmh.Stat[0])
334                         err = 1;
335         }
336         return err;
337 }
338
339 /*
340  * vx_conf_pipe - tell the pipe to stand by and wait for IRQA.
341  * @pipe: the pipe to be configured
342  */
343 static int vx_conf_pipe(vx_core_t *chip, vx_pipe_t *pipe)
344 {
345         struct vx_rmh rmh;
346
347         vx_init_rmh(&rmh, CMD_CONF_PIPE);
348         if (pipe->is_capture)
349                 rmh.Cmd[0] |= COMMAND_RECORD_MASK;
350         rmh.Cmd[1] = 1 << pipe->number;
351         return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
352 }
353
354 /*
355  * vx_send_irqa - trigger IRQA
356  */
357 static int vx_send_irqa(vx_core_t *chip)
358 {
359         struct vx_rmh rmh;
360
361         vx_init_rmh(&rmh, CMD_SEND_IRQA);
362         return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
363 }
364
365
366 #define MAX_WAIT_FOR_DSP        250
367 /*
368  * vx boards do not support inter-card sync, besides
369  * only 126 samples require to be prepared before a pipe can start
370  */
371 #define CAN_START_DELAY         2       /* wait 2ms only before asking if the pipe is ready*/
372 #define WAIT_STATE_DELAY        2       /* wait 2ms after irqA was requested and check if the pipe state toggled*/
373
374 /*
375  * vx_toggle_pipe - start / pause a pipe
376  * @pipe: the pipe to be triggered
377  * @state: start = 1, pause = 0
378  *
379  * called from trigger callback only
380  *
381  */
382 static int vx_toggle_pipe(vx_core_t *chip, vx_pipe_t *pipe, int state)
383 {
384         int err, i, cur_state, delay;
385
386         /* Check the pipe is not already in the requested state */
387         if (vx_get_pipe_state(chip, pipe, &cur_state) < 0)
388                 return -EBADFD;
389         if (state == cur_state)
390                 return 0;
391
392         /* If a start is requested, ask the DSP to get prepared
393          * and wait for a positive acknowledge (when there are
394          * enough sound buffer for this pipe)
395          */
396         if (state) {
397                 int delay = CAN_START_DELAY;
398                 for (i = 0 ; i < MAX_WAIT_FOR_DSP; i++) {
399                         snd_vx_delay(chip, delay);
400                         err = vx_pipe_can_start(chip, pipe);
401                         if (err > 0)
402                                 break;
403                         /* Wait for a few, before asking again
404                          * to avoid flooding the DSP with our requests
405                          */
406                         if ((i % 4 ) == 0)
407                                 delay <<= 1;
408                 }
409         }
410     
411         if ((err = vx_conf_pipe(chip, pipe)) < 0)
412                 return err;
413
414         if ((err = vx_send_irqa(chip)) < 0)
415                 return err;
416     
417         /* If it completes successfully, wait for the pipes
418          * reaching the expected state before returning
419          * Check one pipe only (since they are synchronous)
420          */
421         delay = WAIT_STATE_DELAY;
422         for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
423                 snd_vx_delay(chip, delay);
424                 err = vx_get_pipe_state(chip, pipe, &cur_state);
425                 if (err < 0 || cur_state == state)
426                         break;
427                 err = -EIO;
428                 if ((i % 4 ) == 0)
429                         delay <<= 1;
430         }
431         return err < 0 ? -EIO : 0;
432 }
433
434     
435 /*
436  * vx_stop_pipe - stop a pipe
437  * @pipe: the pipe to be stopped
438  *
439  * called from trigger callback only
440  */
441 static int vx_stop_pipe(vx_core_t *chip, vx_pipe_t *pipe)
442 {
443         struct vx_rmh rmh;
444         vx_init_rmh(&rmh, CMD_STOP_PIPE);
445         vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
446         return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
447 }
448
449
450 /*
451  * vx_alloc_pipe - allocate a pipe and initialize the pipe instance
452  * @capture: 0 = playback, 1 = capture operation
453  * @audioid: the audio id to be assigned
454  * @num_audio: number of audio channels
455  * @pipep: the returned pipe instance
456  *
457  * return 0 on success, or a negative error code.
458  */
459 static int vx_alloc_pipe(vx_core_t *chip, int capture,
460                          int audioid, int num_audio,
461                          vx_pipe_t **pipep)
462 {
463         int err;
464         vx_pipe_t *pipe;
465         struct vx_rmh rmh;
466         int data_mode;
467
468         *pipep = NULL;
469         vx_init_rmh(&rmh, CMD_RES_PIPE);
470         vx_set_pipe_cmd_params(&rmh, capture, audioid, num_audio);
471 #if 0   // NYI
472         if (underrun_skip_sound)
473                 rmh.Cmd[0] |= BIT_SKIP_SOUND;
474 #endif  // NYI
475         data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
476         if (! capture && data_mode)
477                 rmh.Cmd[0] |= BIT_DATA_MODE;
478         err = vx_send_msg(chip, &rmh);
479         if (err < 0)
480                 return err;
481
482         /* initialize the pipe record */
483         pipe = snd_magic_kcalloc(vx_pipe_t, 0, GFP_KERNEL);
484         if (! pipe) {
485                 /* release the pipe */
486                 vx_init_rmh(&rmh, CMD_FREE_PIPE);
487                 vx_set_pipe_cmd_params(&rmh, capture, audioid, 0);
488                 vx_send_msg(chip, &rmh);
489                 return -ENOMEM;
490         }
491
492         /* the pipe index should be identical with the audio index */
493         pipe->number = audioid;
494         pipe->is_capture = capture;
495         pipe->channels = num_audio;
496         pipe->differed_type = 0;
497         pipe->pcx_time = 0;
498         pipe->data_mode = data_mode;
499         *pipep = pipe;
500
501         return 0;
502 }
503
504
505 /*
506  * vx_free_pipe - release a pipe
507  * @pipe: pipe to be released
508  */
509 static int vx_free_pipe(vx_core_t *chip, vx_pipe_t *pipe)
510 {
511         struct vx_rmh rmh;
512
513         vx_init_rmh(&rmh, CMD_FREE_PIPE);
514         vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
515         vx_send_msg(chip, &rmh);
516
517         snd_magic_kfree(pipe);
518         return 0;
519 }
520
521
522 /*
523  * vx_start_stream - start the stream
524  *
525  * called from trigger callback only
526  */
527 static int vx_start_stream(vx_core_t *chip, vx_pipe_t *pipe)
528 {
529         struct vx_rmh rmh;
530
531         vx_init_rmh(&rmh, CMD_START_ONE_STREAM);
532         vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
533         vx_set_differed_time(chip, &rmh, pipe);
534         return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
535 }
536
537
538 /*
539  * vx_stop_stream - stop the stream
540  *
541  * called from trigger callback only
542  */
543 static int vx_stop_stream(vx_core_t *chip, vx_pipe_t *pipe)
544 {
545         struct vx_rmh rmh;
546
547         vx_init_rmh(&rmh, CMD_STOP_STREAM);
548         vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
549         return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
550 }
551
552
553 /*
554  * playback hw information
555  */
556
557 static snd_pcm_hardware_t vx_pcm_playback_hw = {
558         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
559                                  SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
560         .formats =              /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
561         .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
562         .rate_min =             5000,
563         .rate_max =             48000,
564         .channels_min =         1,
565         .channels_max =         2,
566         .buffer_bytes_max =     (128*1024),
567         .period_bytes_min =     126,
568         .period_bytes_max =     (128*1024),
569         .periods_min =          2,
570         .periods_max =          VX_MAX_PERIODS,
571         .fifo_size =            126,
572 };
573
574
575 static void vx_pcm_delayed_start(unsigned long arg);
576
577 /*
578  * vx_pcm_playback_open - open callback for playback
579  */
580 static int vx_pcm_playback_open(snd_pcm_substream_t *subs)
581 {
582         snd_pcm_runtime_t *runtime = subs->runtime;
583         vx_core_t *chip = snd_pcm_substream_chip(subs);
584         vx_pipe_t *pipe = NULL;
585         unsigned int audio;
586         int err;
587
588         if (chip->chip_status & VX_STAT_IS_STALE)
589                 return -EBUSY;
590
591         audio = subs->pcm->device * 2;
592         snd_assert(audio < chip->audio_outs, return -EINVAL);
593         
594         /* playback pipe may have been already allocated for monitoring */
595         pipe = chip->playback_pipes[audio];
596         if (! pipe) {
597                 /* not allocated yet */
598                 err = vx_alloc_pipe(chip, 0, audio, 2, &pipe); /* stereo playback */
599                 if (err < 0)
600                         return err;
601                 chip->playback_pipes[audio] = pipe;
602         }
603         /* open for playback */
604         pipe->references++;
605
606         pipe->substream = subs;
607         tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
608         chip->playback_pipes[audio] = pipe;
609
610         runtime->hw = vx_pcm_playback_hw;
611         runtime->hw.period_bytes_min = chip->ibl.size;
612         runtime->private_data = pipe;
613
614         /* align to 4 bytes (otherwise will be problematic when 24bit is used) */ 
615         snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
616         snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
617
618         return 0;
619 }
620
621 /*
622  * vx_pcm_playback_close - close callback for playback
623  */
624 static int vx_pcm_playback_close(snd_pcm_substream_t *subs)
625 {
626         vx_core_t *chip = snd_pcm_substream_chip(subs);
627         vx_pipe_t *pipe;
628
629         if (! subs->runtime->private_data)
630                 return -EINVAL;
631
632         pipe = snd_magic_cast(vx_pipe_t, subs->runtime->private_data, return -EINVAL);
633
634         if (--pipe->references == 0) {
635                 chip->playback_pipes[pipe->number] = NULL;
636                 vx_free_pipe(chip, pipe);
637         }
638
639         return 0;
640
641 }
642
643
644 /*
645  * vx_notify_end_of_buffer - send "end-of-buffer" notifier at the given pipe
646  * @pipe: the pipe to notify
647  *
648  * NB: call with a certain lock.
649  */
650 static int vx_notify_end_of_buffer(vx_core_t *chip, vx_pipe_t *pipe)
651 {
652         int err;
653         struct vx_rmh rmh;  /* use a temporary rmh here */
654
655         /* Toggle Dsp Host Interface into Message mode */
656         vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
657         vx_init_rmh(&rmh, CMD_NOTIFY_END_OF_BUFFER);
658         vx_set_stream_cmd_params(&rmh, 0, pipe->number);
659         err = vx_send_msg_nolock(chip, &rmh);
660         if (err < 0)
661                 return err;
662         /* Toggle Dsp Host Interface back to sound transfer mode */
663         vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
664         return 0;
665 }
666
667 /*
668  * vx_pcm_playback_transfer_chunk - transfer a single chunk
669  * @subs: substream
670  * @pipe: the pipe to transfer
671  * @size: chunk size in bytes
672  *
673  * transfer a single buffer chunk.  EOB notificaton is added after that.
674  * called from the interrupt handler, too.
675  *
676  * return 0 if ok.
677  */
678 static int vx_pcm_playback_transfer_chunk(vx_core_t *chip, snd_pcm_runtime_t *runtime, vx_pipe_t *pipe, int size)
679 {
680         int space, err = 0;
681
682         space = vx_query_hbuffer_size(chip, pipe);
683         if (space < 0) {
684                 /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
685                 vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
686                 snd_printd("error hbuffer\n");
687                 return space;
688         }
689         if (space < size) {
690                 vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
691                 snd_printd("no enough hbuffer space %d\n", space);
692                 return -EIO; /* XRUN */
693         }
694                 
695         /* we don't need irqsave here, because this function
696          * is called from either trigger callback or irq handler
697          */
698         spin_lock(&chip->lock); 
699         vx_pseudo_dma_write(chip, runtime, pipe, size);
700         err = vx_notify_end_of_buffer(chip, pipe);
701         /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
702         vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
703         spin_unlock(&chip->lock);
704         return err;
705 }
706
707 /*
708  * update the position of the given pipe.
709  * pipe->position is updated and wrapped within the buffer size.
710  * pipe->transferred is updated, too, but the size is not wrapped,
711  * so that the caller can check the total transferred size later
712  * (to call snd_pcm_period_elapsed).
713  */
714 static int vx_update_pipe_position(vx_core_t *chip, snd_pcm_runtime_t *runtime, vx_pipe_t *pipe)
715 {
716         struct vx_rmh rmh;
717         int err, update;
718         u64 count;
719
720         vx_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
721         vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
722         err = vx_send_msg(chip, &rmh);
723         if (err < 0)
724                 return err;
725
726         count = ((u64)(rmh.Stat[0] & 0xfffff) << 24) | (u64)rmh.Stat[1];
727         update = (int)(count - pipe->cur_count);
728         pipe->cur_count = count;
729         pipe->position += update;
730         if (pipe->position >= (int)runtime->buffer_size)
731                 pipe->position %= runtime->buffer_size;
732         pipe->transferred += update;
733         return 0;
734 }
735
736 /*
737  * transfer the pending playback buffer data to DSP
738  * called from interrupt handler
739  */
740 static void vx_pcm_playback_transfer(vx_core_t *chip, snd_pcm_substream_t *subs, vx_pipe_t *pipe, int nchunks)
741 {
742         int i, err;
743         snd_pcm_runtime_t *runtime = subs->runtime;
744
745         if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
746                 return;
747         for (i = 0; i < nchunks; i++) {
748                 if ((err = vx_pcm_playback_transfer_chunk(chip, runtime, pipe,
749                                                           chip->ibl.size)) < 0)
750                         return;
751         }
752 }
753
754 /*
755  * update the playback position and call snd_pcm_period_elapsed() if necessary
756  * called from interrupt handler
757  */
758 static void vx_pcm_playback_update(vx_core_t *chip, snd_pcm_substream_t *subs, vx_pipe_t *pipe)
759 {
760         int err;
761         snd_pcm_runtime_t *runtime = subs->runtime;
762
763         if (pipe->running && ! (chip->chip_status & VX_STAT_IS_STALE)) {
764                 if ((err = vx_update_pipe_position(chip, runtime, pipe)) < 0)
765                         return;
766                 if (pipe->transferred >= (int)runtime->period_size) {
767                         pipe->transferred %= runtime->period_size;
768                         snd_pcm_period_elapsed(subs);
769                 }
770         }
771 }
772
773 /*
774  * start the stream and pipe.
775  * this function is called from tasklet, which is invoked by the trigger
776  * START callback.
777  */
778 static void vx_pcm_delayed_start(unsigned long arg)
779 {
780         snd_pcm_substream_t *subs = (snd_pcm_substream_t *)arg;
781         vx_core_t *chip = snd_magic_cast(vx_core_t, subs->pcm->private_data, return);
782         vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, subs->runtime->private_data, return);
783         int err;
784
785         /*  printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/
786
787         if ((err = vx_start_stream(chip, pipe)) < 0) {
788                 snd_printk(KERN_ERR "vx: cannot start stream\n");
789                 return;
790         }
791         if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) {
792                 snd_printk(KERN_ERR "vx: cannot start pipe\n");
793                 return;
794         }
795         /*   printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/
796 }
797
798 /*
799  * vx_pcm_playback_trigger - trigger callback for playback
800  */
801 static int vx_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
802 {
803         vx_core_t *chip = snd_pcm_substream_chip(subs);
804         vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, subs->runtime->private_data, return -EINVAL);
805         int err;
806
807         if (chip->chip_status & VX_STAT_IS_STALE)
808                 return -EBUSY;
809                 
810         switch (cmd) {
811         case SNDRV_PCM_TRIGGER_START:
812                 if (! pipe->is_capture)
813                         vx_pcm_playback_transfer(chip, subs, pipe, 2);
814                 /* FIXME:
815                  * we trigger the pipe using tasklet, so that the interrupts are
816                  * issued surely after the trigger is completed.
817                  */ 
818                 tasklet_hi_schedule(&pipe->start_tq);
819                 chip->pcm_running++;
820                 pipe->running = 1;
821                 break;
822         case SNDRV_PCM_TRIGGER_STOP:
823                 vx_toggle_pipe(chip, pipe, 0);
824                 vx_stop_pipe(chip, pipe);
825                 vx_stop_stream(chip, pipe);
826                 chip->pcm_running--;
827                 pipe->running = 0;
828                 break;
829         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
830                 if ((err = vx_toggle_pipe(chip, pipe, 0)) < 0)
831                         return err;
832                 break;
833         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
834                 if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0)
835                         return err;
836                 break;
837         default:
838                 return -EINVAL;
839         }
840         return 0;
841 }
842
843 /*
844  * vx_pcm_playback_pointer - pointer callback for playback
845  */
846 static snd_pcm_uframes_t vx_pcm_playback_pointer(snd_pcm_substream_t *subs)
847 {
848         snd_pcm_runtime_t *runtime = subs->runtime;
849         vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, runtime->private_data, return -EINVAL);
850         return pipe->position;
851 }
852
853 /*
854  * vx_pcm_hw_params - hw_params callback for playback and capture
855  */
856 static int vx_pcm_hw_params(snd_pcm_substream_t *subs,
857                                      snd_pcm_hw_params_t *hw_params)
858 {
859         return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params));
860 }
861
862 /*
863  * vx_pcm_hw_free - hw_free callback for playback and capture
864  */
865 static int vx_pcm_hw_free(snd_pcm_substream_t *subs)
866 {
867         return snd_pcm_free_vmalloc_buffer(subs);
868 }
869
870 /*
871  * vx_pcm_prepare - prepare callback for playback and capture
872  */
873 static int vx_pcm_prepare(snd_pcm_substream_t *subs)
874 {
875         vx_core_t *chip = snd_pcm_substream_chip(subs);
876         snd_pcm_runtime_t *runtime = subs->runtime;
877         vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, runtime->private_data, return -EINVAL);
878         int err, data_mode;
879         // int max_size, nchunks;
880
881         if (chip->chip_status & VX_STAT_IS_STALE)
882                 return -EBUSY;
883
884         data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
885         if (data_mode != pipe->data_mode && ! pipe->is_capture) {
886                 /* IEC958 status (raw-mode) was changed */
887                 /* we reopen the pipe */
888                 struct vx_rmh rmh;
889                 snd_printdd(KERN_DEBUG "reopen the pipe with data_mode = %d\n", data_mode);
890                 vx_init_rmh(&rmh, CMD_FREE_PIPE);
891                 vx_set_pipe_cmd_params(&rmh, 0, pipe->number, 0);
892                 if ((err = vx_send_msg(chip, &rmh)) < 0)
893                         return err;
894                 vx_init_rmh(&rmh, CMD_RES_PIPE);
895                 vx_set_pipe_cmd_params(&rmh, 0, pipe->number, pipe->channels);
896                 if (data_mode)
897                         rmh.Cmd[0] |= BIT_DATA_MODE;
898                 if ((err = vx_send_msg(chip, &rmh)) < 0)
899                         return err;
900                 pipe->data_mode = data_mode;
901         }
902
903         if (chip->pcm_running && chip->freq != runtime->rate) {
904                 snd_printk(KERN_ERR "vx: cannot set different clock %d from the current %d\n", runtime->rate, chip->freq);
905                 return -EINVAL;
906         }
907         vx_set_clock(chip, runtime->rate);
908
909         if ((err = vx_set_format(chip, pipe, runtime)) < 0)
910                 return err;
911
912         if (vx_is_pcmcia(chip)) {
913                 pipe->align = 2; /* 16bit word */
914         } else {
915                 pipe->align = 4; /* 32bit word */
916         }
917
918         pipe->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
919         pipe->period_bytes = frames_to_bytes(runtime, runtime->period_size);
920         pipe->hw_ptr = 0;
921
922         /* set the timestamp */
923         vx_update_pipe_position(chip, runtime, pipe);
924         /* clear again */
925         pipe->transferred = 0;
926         pipe->position = 0;
927
928         pipe->prepared = 1;
929
930         return 0;
931 }
932
933
934 /*
935  * operators for PCM playback
936  */
937 static snd_pcm_ops_t vx_pcm_playback_ops = {
938         .open =         vx_pcm_playback_open,
939         .close =        vx_pcm_playback_close,
940         .ioctl =        snd_pcm_lib_ioctl,
941         .hw_params =    vx_pcm_hw_params,
942         .hw_free =      vx_pcm_hw_free,
943         .prepare =      vx_pcm_prepare,
944         .trigger =      vx_pcm_trigger,
945         .pointer =      vx_pcm_playback_pointer,
946         .page =         snd_pcm_get_vmalloc_page,
947 };
948
949
950 /*
951  * playback hw information
952  */
953
954 static snd_pcm_hardware_t vx_pcm_capture_hw = {
955         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
956                                  SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
957         .formats =              /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
958         .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
959         .rate_min =             5000,
960         .rate_max =             48000,
961         .channels_min =         1,
962         .channels_max =         2,
963         .buffer_bytes_max =     (128*1024),
964         .period_bytes_min =     126,
965         .period_bytes_max =     (128*1024),
966         .periods_min =          2,
967         .periods_max =          VX_MAX_PERIODS,
968         .fifo_size =            126,
969 };
970
971
972 /*
973  * vx_pcm_capture_open - open callback for capture
974  */
975 static int vx_pcm_capture_open(snd_pcm_substream_t *subs)
976 {
977         snd_pcm_runtime_t *runtime = subs->runtime;
978         vx_core_t *chip = snd_pcm_substream_chip(subs);
979         vx_pipe_t *pipe;
980         vx_pipe_t *pipe_out_monitoring = NULL;
981         unsigned int audio;
982         int err;
983
984         if (chip->chip_status & VX_STAT_IS_STALE)
985                 return -EBUSY;
986
987         audio = subs->pcm->device * 2;
988         snd_assert(audio < chip->audio_ins, return -EINVAL);
989         err = vx_alloc_pipe(chip, 1, audio, 2, &pipe);
990         if (err < 0)
991                 return err;
992         pipe->substream = subs;
993         tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
994         chip->capture_pipes[audio] = pipe;
995
996         /* check if monitoring is needed */
997         if (chip->audio_monitor_active[audio]) {
998                 pipe_out_monitoring = chip->playback_pipes[audio];
999                 if (! pipe_out_monitoring) {
1000                         /* allocate a pipe */
1001                         err = vx_alloc_pipe(chip, 0, audio, 2, &pipe_out_monitoring);
1002                         if (err < 0)
1003                                 return err;
1004                         chip->playback_pipes[audio] = pipe_out_monitoring;
1005                 }
1006                 pipe_out_monitoring->references++;
1007                 /* 
1008                    if an output pipe is available, it's audios still may need to be 
1009                    unmuted. hence we'll have to call a mixer entry point.
1010                 */
1011                 vx_set_monitor_level(chip, audio, chip->audio_monitor[audio], chip->audio_monitor_active[audio]);
1012                 /* assuming stereo */
1013                 vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1], chip->audio_monitor_active[audio+1]); 
1014         }
1015
1016         pipe->monitoring_pipe = pipe_out_monitoring; /* default value NULL */
1017
1018         runtime->hw = vx_pcm_capture_hw;
1019         runtime->hw.period_bytes_min = chip->ibl.size;
1020         runtime->private_data = pipe;
1021
1022         /* align to 4 bytes (otherwise will be problematic when 24bit is used) */ 
1023         snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
1024         snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
1025
1026         return 0;
1027 }
1028
1029 /*
1030  * vx_pcm_capture_close - close callback for capture
1031  */
1032 static int vx_pcm_capture_close(snd_pcm_substream_t *subs)
1033 {
1034         vx_core_t *chip = snd_pcm_substream_chip(subs);
1035         vx_pipe_t *pipe;
1036         vx_pipe_t *pipe_out_monitoring;
1037         
1038         if (! subs->runtime->private_data)
1039                 return -EINVAL;
1040         pipe = snd_magic_cast(vx_pipe_t, subs->runtime->private_data, return -EINVAL);
1041         chip->capture_pipes[pipe->number] = NULL;
1042
1043         pipe_out_monitoring = pipe->monitoring_pipe;
1044
1045         /*
1046           if an output pipe is attached to this input, 
1047           check if it needs to be released.
1048         */
1049         if (pipe_out_monitoring) {
1050                 if (--pipe_out_monitoring->references == 0) {
1051                         vx_free_pipe(chip, pipe_out_monitoring);
1052                         chip->playback_pipes[pipe->number] = NULL;
1053                         pipe->monitoring_pipe = NULL;
1054                 }
1055         }
1056         
1057         vx_free_pipe(chip, pipe);
1058         return 0;
1059 }
1060
1061
1062
1063 #define DMA_READ_ALIGN  6       /* hardware alignment for read */
1064
1065 /*
1066  * vx_pcm_capture_update - update the capture buffer
1067  */
1068 static void vx_pcm_capture_update(vx_core_t *chip, snd_pcm_substream_t *subs, vx_pipe_t *pipe)
1069 {
1070         int size, space, count;
1071         snd_pcm_runtime_t *runtime = subs->runtime;
1072
1073         if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
1074                 return;
1075
1076         size = runtime->buffer_size - snd_pcm_capture_avail(runtime);
1077         if (! size)
1078                 return;
1079         size = frames_to_bytes(runtime, size);
1080         space = vx_query_hbuffer_size(chip, pipe);
1081         if (space < 0)
1082                 goto _error;
1083         if (size > space)
1084                 size = space;
1085         size = (size / 3) * 3; /* align to 3 bytes */
1086         if (size < DMA_READ_ALIGN)
1087                 goto _error;
1088
1089         /* keep the last 6 bytes, they will be read after disconnection */
1090         count = size - DMA_READ_ALIGN;
1091         /* read bytes until the current pointer reaches to the aligned position
1092          * for word-transfer
1093          */
1094         while (count > 0) {
1095                 if ((pipe->hw_ptr % pipe->align) == 0)
1096                         break;
1097                 if (vx_wait_for_rx_full(chip) < 0)
1098                         goto _error;
1099                 vx_pcm_read_per_bytes(chip, runtime, pipe);
1100                 count -= 3;
1101         }
1102         if (count > 0) {
1103                 /* ok, let's accelerate! */
1104                 int align = pipe->align * 3;
1105                 space = (count / align) * align;
1106                 vx_pseudo_dma_read(chip, runtime, pipe, space);
1107                 count -= space;
1108         }
1109         /* read the rest of bytes */
1110         while (count > 0) {
1111                 if (vx_wait_for_rx_full(chip) < 0)
1112                         goto _error;
1113                 vx_pcm_read_per_bytes(chip, runtime, pipe);
1114                 count -= 3;
1115         }
1116         /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
1117         vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
1118         /* read the last pending 6 bytes */
1119         count = DMA_READ_ALIGN;
1120         while (count > 0) {
1121                 vx_pcm_read_per_bytes(chip, runtime, pipe);
1122                 count -= 3;
1123         }
1124         /* update the position */
1125         pipe->transferred += size;
1126         if (pipe->transferred >= pipe->period_bytes) {
1127                 pipe->transferred %= pipe->period_bytes;
1128                 snd_pcm_period_elapsed(subs);
1129         }
1130         return;
1131
1132  _error:
1133         /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
1134         vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
1135         return;
1136 }
1137
1138 /*
1139  * vx_pcm_capture_pointer - pointer callback for capture
1140  */
1141 static snd_pcm_uframes_t vx_pcm_capture_pointer(snd_pcm_substream_t *subs)
1142 {
1143         snd_pcm_runtime_t *runtime = subs->runtime;
1144         vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, runtime->private_data, return -EINVAL);
1145         return bytes_to_frames(runtime, pipe->hw_ptr);
1146 }
1147
1148 /*
1149  * operators for PCM capture
1150  */
1151 static snd_pcm_ops_t vx_pcm_capture_ops = {
1152         .open =         vx_pcm_capture_open,
1153         .close =        vx_pcm_capture_close,
1154         .ioctl =        snd_pcm_lib_ioctl,
1155         .hw_params =    vx_pcm_hw_params,
1156         .hw_free =      vx_pcm_hw_free,
1157         .prepare =      vx_pcm_prepare,
1158         .trigger =      vx_pcm_trigger,
1159         .pointer =      vx_pcm_capture_pointer,
1160         .page =         snd_pcm_get_vmalloc_page,
1161 };
1162
1163
1164 /*
1165  * interrupt handler for pcm streams
1166  */
1167 void vx_pcm_update_intr(vx_core_t *chip, unsigned int events)
1168 {
1169         unsigned int i;
1170         vx_pipe_t *pipe;
1171
1172 #define EVENT_MASK      (END_OF_BUFFER_EVENTS_PENDING|ASYNC_EVENTS_PENDING)
1173
1174         if (events & EVENT_MASK) {
1175                 vx_init_rmh(&chip->irq_rmh, CMD_ASYNC);
1176                 if (events & ASYNC_EVENTS_PENDING)
1177                         chip->irq_rmh.Cmd[0] |= 0x00000001;     /* SEL_ASYNC_EVENTS */
1178                 if (events & END_OF_BUFFER_EVENTS_PENDING)
1179                         chip->irq_rmh.Cmd[0] |= 0x00000002;     /* SEL_END_OF_BUF_EVENTS */
1180
1181                 if (vx_send_msg(chip, &chip->irq_rmh) < 0) {
1182                         snd_printdd(KERN_ERR "msg send error!!\n");
1183                         return;
1184                 }
1185
1186                 i = 1;
1187                 while (i < chip->irq_rmh.LgStat) {
1188                         int p, buf, capture, eob;
1189                         p = chip->irq_rmh.Stat[i] & MASK_FIRST_FIELD;
1190                         capture = (chip->irq_rmh.Stat[i] & 0x400000) ? 1 : 0;
1191                         eob = (chip->irq_rmh.Stat[i] & 0x800000) ? 1 : 0;
1192                         i++;
1193                         if (events & ASYNC_EVENTS_PENDING)
1194                                 i++;
1195                         buf = 1; /* force to transfer */
1196                         if (events & END_OF_BUFFER_EVENTS_PENDING) {
1197                                 if (eob)
1198                                         buf = chip->irq_rmh.Stat[i];
1199                                 i++;
1200                         }
1201                         if (capture)
1202                                 continue;
1203                         snd_assert(p >= 0 && (unsigned int)p < chip->audio_outs,);
1204                         pipe = chip->playback_pipes[p];
1205                         if (pipe && pipe->substream) {
1206                                 vx_pcm_playback_update(chip, pipe->substream, pipe);
1207                                 vx_pcm_playback_transfer(chip, pipe->substream, pipe, buf);
1208                         }
1209                 }
1210         }
1211
1212         /* update the capture pcm pointers as frequently as possible */
1213         for (i = 0; i < chip->audio_ins; i++) {
1214                 pipe = chip->capture_pipes[i];
1215                 if (pipe && pipe->substream)
1216                         vx_pcm_capture_update(chip, pipe->substream, pipe);
1217         }
1218 }
1219
1220
1221 /*
1222  * vx_init_audio_io - check the availabe audio i/o and allocate pipe arrays
1223  */
1224 static int vx_init_audio_io(vx_core_t *chip)
1225 {
1226         struct vx_rmh rmh;
1227         int preferred;
1228
1229         vx_init_rmh(&rmh, CMD_SUPPORTED);
1230         if (vx_send_msg(chip, &rmh) < 0) {
1231                 snd_printk(KERN_ERR "vx: cannot get the supported audio data\n");
1232                 return -ENXIO;
1233         }
1234
1235         chip->audio_outs = rmh.Stat[0] & MASK_FIRST_FIELD;
1236         chip->audio_ins = (rmh.Stat[0] >> (FIELD_SIZE*2)) & MASK_FIRST_FIELD;
1237         chip->audio_info = rmh.Stat[1];
1238
1239         /* allocate pipes */
1240         chip->playback_pipes = kmalloc(sizeof(vx_pipe_t *) * chip->audio_outs, GFP_KERNEL);
1241         chip->capture_pipes = kmalloc(sizeof(vx_pipe_t *) * chip->audio_ins, GFP_KERNEL);
1242         if (! chip->playback_pipes || ! chip->capture_pipes)
1243                 return -ENOMEM;
1244
1245         memset(chip->playback_pipes, 0, sizeof(vx_pipe_t *) * chip->audio_outs);
1246         memset(chip->capture_pipes, 0, sizeof(vx_pipe_t *) * chip->audio_ins);
1247
1248         preferred = chip->ibl.size;
1249         chip->ibl.size = 0;
1250         vx_set_ibl(chip, &chip->ibl); /* query the info */
1251         if (preferred > 0) {
1252                 chip->ibl.size = ((preferred + chip->ibl.granularity - 1) / chip->ibl.granularity) * chip->ibl.granularity;
1253                 if (chip->ibl.size > chip->ibl.max_size)
1254                         chip->ibl.size = chip->ibl.max_size;
1255         } else
1256                 chip->ibl.size = chip->ibl.min_size; /* set to the minimum */
1257         vx_set_ibl(chip, &chip->ibl);
1258
1259         return 0;
1260 }
1261
1262
1263 /*
1264  * free callback for pcm
1265  */
1266 static void snd_vx_pcm_free(snd_pcm_t *pcm)
1267 {
1268         vx_core_t *chip = snd_magic_cast(vx_core_t, pcm->private_data, return);
1269         chip->pcm[pcm->device] = NULL;
1270         if (chip->playback_pipes) {
1271                 kfree(chip->playback_pipes);
1272                 chip->playback_pipes = NULL;
1273         }
1274         if (chip->capture_pipes) {
1275                 kfree(chip->capture_pipes);
1276                 chip->capture_pipes = NULL;
1277         }
1278 }
1279
1280 /*
1281  * snd_vx_pcm_new - create and initialize a pcm
1282  */
1283 int snd_vx_pcm_new(vx_core_t *chip)
1284 {
1285         snd_pcm_t *pcm;
1286         unsigned int i;
1287         int err;
1288
1289         if ((err = vx_init_audio_io(chip)) < 0)
1290                 return err;
1291
1292         for (i = 0; i < chip->hw->num_codecs; i++) {
1293                 unsigned int outs, ins;
1294                 outs = chip->audio_outs > i * 2 ? 1 : 0;
1295                 ins = chip->audio_ins > i * 2 ? 1 : 0;
1296                 if (! outs && ! ins)
1297                         break;
1298                 err = snd_pcm_new(chip->card, "VX PCM", i,
1299                                   outs, ins, &pcm);
1300                 if (err < 0)
1301                         return err;
1302                 if (outs)
1303                         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &vx_pcm_playback_ops);
1304                 if (ins)
1305                         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &vx_pcm_capture_ops);
1306
1307                 pcm->private_data = chip;
1308                 pcm->private_free = snd_vx_pcm_free;
1309                 pcm->info_flags = 0;
1310                 strcpy(pcm->name, chip->card->shortname);
1311                 chip->pcm[i] = pcm;
1312         }
1313
1314         return 0;
1315 }