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