/[openvortex]/alsa/pci/au88x0/au88x0_pcm.c
ViewVC logotype

Diff of /alsa/pci/au88x0/au88x0_pcm.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by vizard, Sun Aug 10 20:00:34 2003 UTC revision 1.9 by vizard, Sun Aug 10 20:12:04 2003 UTC
# Line 27  static snd_pcm_hardware_t snd_vortex_pla Line 27  static snd_pcm_hardware_t snd_vortex_pla
27      .rate_min = 5000,      .rate_min = 5000,
28      .rate_max = 48000,      .rate_max = 48000,
29      .channels_min = 1,      .channels_min = 1,
30      .channels_max = 2,  #ifdef CHIP_AU8830
31        .channels_max = 4,
32    #else
33            .channels_max = 2,
34    #endif
35      .buffer_bytes_max = 0x10000,      .buffer_bytes_max = 0x10000,
36      .period_bytes_min = 0x0100,      .period_bytes_min = 0x100,
37      .period_bytes_max = 0x1000,      .period_bytes_max = 0x1000,
38      .periods_min = 1,      .periods_min = 1,
39      .periods_max = 64,      .periods_max = 64,
40  };  };
41    
42    #ifndef CHIP_AU8810
43  static snd_pcm_hardware_t snd_vortex_playback_hw_wt = {  static snd_pcm_hardware_t snd_vortex_playback_hw_wt = {
44      .info = (SNDRV_PCM_INFO_MMAP |      .info = (SNDRV_PCM_INFO_MMAP |
45               SNDRV_PCM_INFO_INTERLEAVED |               SNDRV_PCM_INFO_INTERLEAVED |
# Line 51  static snd_pcm_hardware_t snd_vortex_pla Line 56  static snd_pcm_hardware_t snd_vortex_pla
56      .periods_min = 1,      .periods_min = 1,
57      .periods_max = 64,      .periods_max = 64,
58  };  };
59    #endif
60  /* open callback */  /* open callback */
61  static int snd_vortex_pcm_open(snd_pcm_substream_t *substream) {  static int snd_vortex_pcm_open(snd_pcm_substream_t *substream) {
62      chip_t *chip = snd_pcm_substream_chip(substream);      chip_t *chip = snd_pcm_substream_chip(substream);
63      snd_pcm_runtime_t *runtime = substream->runtime;      snd_pcm_runtime_t *runtime = substream->runtime;
64          int dma, err;          int err;
65                    
66          /* Force equal size periods */          /* Force equal size periods */
67          if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)          if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
68          return err;          return err;
69          /* Force DMA 32 bit alignment */          /* Force DMA 32 bit alignment */
70          if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4)) < 0)          if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 4)) < 0)
71          return err;          return err;
72                    
73      if (substream->pcm == chip->pcm_adb) {      if (substream->pcm == chip->pcm_adb) {
74                  runtime->hw = snd_vortex_playback_hw_adb;                  runtime->hw = snd_vortex_playback_hw_adb;
75                  dma = vortex_getadb(chip);                  substream->runtime->private_data = NULL;
76                  if (dma < 0)      }
77                          return -EBUSY;  #ifndef CHIP_AU8810
78                  substream->runtime->private_data = &chip->dma_adb[dma];          else {
         chip->dma_adb[dma].substream = substream;  
     } else {  
79                  runtime->hw = snd_vortex_playback_hw_wt;                  runtime->hw = snd_vortex_playback_hw_wt;
80                  dma = vortex_getwt(chip);                  substream->runtime->private_data = NULL;
                 if (dma < 0)  
                         return -EBUSY;  
                 substream->runtime->private_data = &chip->dma_wt[dma];  
         chip->dma_wt[dma].substream = substream;  
81      }      }
82    #endif
83      return 0;      return 0;
84  }  }
85    
86  /* close callback */  /* close callback */
87  static int snd_vortex_pcm_close(snd_pcm_substream_t *substream) {  static int snd_vortex_pcm_close(snd_pcm_substream_t *substream) {
88      //vortex_t *chip = snd_pcm_substream_chip(substream);      //vortex_t *chip = snd_pcm_substream_chip(substream);
89          dma_t *dma = (dma_t*)substream->runtime->private_data;          stream_t *stream = (stream_t*)substream->runtime->private_data;
90            
91      // the hardware-specific codes will be here      // the hardware-specific codes will be here
92      // Dealloc DMA and remove audio route.          if (stream != NULL) {
93      dma->substream = NULL;          stream->substream = NULL;
94          dma->nr_ch = 0;                  stream->nr_ch = 0;
95            }
96      substream->runtime->private_data = NULL;      substream->runtime->private_data = NULL;
97      return 0;      return 0;
98  }  }
# Line 100  static int snd_vortex_pcm_close(snd_pcm_ Line 101  static int snd_vortex_pcm_close(snd_pcm_
101  static int snd_vortex_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *hw_params) {  static int snd_vortex_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *hw_params) {
102          chip_t *chip = snd_pcm_substream_chip(substream);          chip_t *chip = snd_pcm_substream_chip(substream);
103          snd_pcm_runtime_t *runtime = substream->runtime;          snd_pcm_runtime_t *runtime = substream->runtime;
104          dma_t *dma = (dma_t*)substream->runtime->private_data;          stream_t *stream = (stream_t*)(substream->runtime->private_data);
   
105          int err;          int err;
106    
107          // Alloc buffer memory.          // Alloc buffer memory.
# Line 113  static int snd_vortex_pcm_hw_params(snd_ Line 113  static int snd_vortex_pcm_hw_params(snd_
113    
114          printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),          printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
115                  params_period_bytes(hw_params), params_channels(hw_params));                  params_period_bytes(hw_params), params_channels(hw_params));
   
         if (params_buffer_bytes(hw_params) != (params_periods(hw_params)*params_period_bytes(hw_params)))  
                 printk(KERN_INFO "vortex: Warning: Click condition (non integer period count).\n");  
116                    
117          // Make audio routes and config buffer DMA.          // Make audio routes and config buffer DMA.
118          if (substream->pcm == chip->pcm_adb) {          if (substream->pcm == chip->pcm_adb) {
119                  vortex_adbdma_setbuffers(chip, dma->dma, (u32)(runtime->dma_addr), params_period_bytes(hw_params), params_periods(hw_params));                  int dma;
120                  //if (dma->nr_ch != 0)                  /* Dealloc any routes. */
121                          vortex_adb_waveroute(chip, dma->dma, 0);                  if (stream != NULL)
122                  //if (params_channels(hw_params) != 0)                          vortex_adb_allocroute(chip, stream->dma, stream->nr_ch, stream->dir);
123                          vortex_adb_waveroute(chip, dma->dma, params_channels(hw_params));                  /* Alloc routes. */
124          } else {                  dma = vortex_adb_allocroute(chip, -1, params_channels(hw_params), substream->stream);
125                  vortex_wtdma_setbuffers(chip, dma->dma, (u32)(runtime->dma_addr), params_period_bytes(hw_params), params_periods(hw_params));                  if (dma < 0)
126                  if (dma->nr_ch)                          return dma;
127                          vortex_wt_waveroute(chip, dma->dma, 0);                  stream = substream->runtime->private_data = &chip->dma_adb[dma];
128                  if (params_channels(hw_params))                  stream->substream = substream;
129                          vortex_wt_waveroute(chip, dma->dma, params_channels(hw_params));                  /* Setup Buffers. */
130                    vortex_adbdma_setbuffers(chip, dma, (u32)(runtime->dma_addr), params_period_bytes(hw_params), params_periods(hw_params));
131            }
132    #ifndef CHIP_AU8810
133            else {
134                    if (stream != NULL)
135                            vortex_wt_allocroute(chip, substream->number, 0);
136                    vortex_wt_allocroute(chip, substream->number, params_channels(hw_params));
137                    stream = substream->runtime->private_data = &chip->dma_wt[substream->number];
138                    stream->substream = substream;
139                    vortex_wtdma_setbuffers(chip, substream->number, (u32)(runtime->dma_addr), params_period_bytes(hw_params), params_periods(hw_params));
140          }          }
141    #endif
142          return 0;          return 0;
143  }  }
144    
145  /* hw_free callback */  /* hw_free callback */
146  static int snd_vortex_pcm_hw_free(snd_pcm_substream_t *substream) {  static int snd_vortex_pcm_hw_free(snd_pcm_substream_t *substream) {
147      chip_t *chip = snd_pcm_substream_chip(substream);      chip_t *chip = snd_pcm_substream_chip(substream);
148      dma_t *dma = (dma_t*)substream->runtime->private_data;          stream_t *stream = (stream_t*)(substream->runtime->private_data);
149            
150      // Delete audio routes.      // Delete audio routes.
151      if (substream->pcm == chip->pcm_adb)      if (substream->pcm == chip->pcm_adb) {
152          vortex_adb_waveroute(chip, dma->dma, 0);                  if (stream != NULL)
153      else                  vortex_adb_allocroute(chip, stream->dma, stream->nr_ch, stream->dir);
154          vortex_wt_waveroute(chip, dma->dma, 0);          }
155    #ifndef CHIP_AU8810
156            else {
157                    if (stream != NULL)
158                    vortex_wt_allocroute(chip, stream->dma, 0);    
159            }
160    #endif
161            substream->runtime->private_data = NULL;
162    
163      return snd_pcm_lib_free_pages(substream);      return snd_pcm_lib_free_pages(substream);
164  }  }
# Line 152  static int snd_vortex_pcm_hw_free(snd_pc Line 167  static int snd_vortex_pcm_hw_free(snd_pc
167  static int snd_vortex_pcm_prepare(snd_pcm_substream_t *substream) {  static int snd_vortex_pcm_prepare(snd_pcm_substream_t *substream) {
168      vortex_t *chip = snd_pcm_substream_chip(substream);      vortex_t *chip = snd_pcm_substream_chip(substream);
169      snd_pcm_runtime_t *runtime = substream->runtime;      snd_pcm_runtime_t *runtime = substream->runtime;
170          dma_t *dma = (dma_t*)substream->runtime->private_data;      stream_t *stream = (stream_t*)substream->runtime->private_data;
171      int fmt, dir;          int dma = stream->dma, fmt, dir;
172    
173      // set up the hardware with the current configuration.      // set up the hardware with the current configuration.
174          if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)          if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
# Line 162  static int snd_vortex_pcm_prepare(snd_pc Line 177  static int snd_vortex_pcm_prepare(snd_pc
177                  dir = 0;                  dir = 0;
178      fmt = vortex_alsafmt_aspfmt(runtime->format);      fmt = vortex_alsafmt_aspfmt(runtime->format);
179      if (substream->pcm == chip->pcm_adb) {      if (substream->pcm == chip->pcm_adb) {
180          vortex_adbdma_setmode(chip, dma->dma, 1, dir, fmt, 0/*?*/, 0);          vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0/*?*/, 0);
181          vortex_adbdma_setstartbuffer(chip, dma->dma, 0);          vortex_adbdma_setstartbuffer(chip, dma, 0);
182          vortex_adb_setsrc(chip, dma->dma, runtime->rate, dir);          vortex_adb_setsrc(chip, dma, runtime->rate, dir);
183      } else {          }
184          vortex_wtdma_setmode(chip, dma->dma, 1, dir, fmt, 0, 0);  #ifndef CHIP_AU8810
185            else {
186            vortex_wtdma_setmode(chip, dma, 1, dir, fmt, 0, 0);
187          // FIXME: Set rate (i guess using vortex_wt_writereg() somehow).          // FIXME: Set rate (i guess using vortex_wt_writereg() somehow).
188          vortex_wtdma_setstartbuffer(chip, dma->dma, 0);          vortex_wtdma_setstartbuffer(chip, dma, 0);
189      }      }
190    #endif
191      return 0;      return 0;
192  }  }
193    
194  /* trigger callback */  /* trigger callback */
195  static int snd_vortex_pcm_trigger(snd_pcm_substream_t *substream, int cmd) {  static int snd_vortex_pcm_trigger(snd_pcm_substream_t *substream, int cmd) {
196      chip_t *chip = snd_pcm_substream_chip(substream);      chip_t *chip = snd_pcm_substream_chip(substream);
197      dma_t *dma = (dma_t*)substream->runtime->private_data;      stream_t *stream = (stream_t*)substream->runtime->private_data;
198            int dma = stream->dma;
199            
200      switch (cmd) {      switch (cmd) {
201      case SNDRV_PCM_TRIGGER_START:      case SNDRV_PCM_TRIGGER_START:
202          // do something to start the PCM engine          // do something to start the PCM engine
203          printk(KERN_INFO "vortex: start %d\n", dma->dma);          printk(KERN_INFO "vortex: start %d\n", dma);
204          if (substream->pcm == chip->pcm_adb) {          if (substream->pcm == chip->pcm_adb) {
205              dma->fifo_enabled = 1;              stream->fifo_enabled = 1;
206              vortex_adbdma_startfifo(chip, dma->dma);              vortex_adbdma_startfifo(chip, dma);
207          } else {          }
208              dma->fifo_enabled = 1;  #ifndef CHIP_AU8810            
209              vortex_wtdma_startfifo(chip, dma->dma);                  else {
210                stream->fifo_enabled = 1;
211                vortex_wtdma_startfifo(chip, dma);
212          }          }
213    #endif
214          break;          break;
215      case SNDRV_PCM_TRIGGER_STOP:      case SNDRV_PCM_TRIGGER_STOP:
216          // do something to stop the PCM engine          // do something to stop the PCM engine
217          printk(KERN_INFO "vortex: stop %d\n", dma->dma);          printk(KERN_INFO "vortex: stop %d\n", dma);
218          if (substream->pcm == chip->pcm_adb) {          if (substream->pcm == chip->pcm_adb) {
219              dma->fifo_enabled = 0;              stream->fifo_enabled = 0;
220              vortex_adbdma_stopfifo(chip, dma->dma);              vortex_adbdma_stopfifo(chip, dma);
221          }          }
222    #ifndef CHIP_AU8810
223          else {          else {
224              dma->fifo_enabled = 0;              stream->fifo_enabled = 0;
225              vortex_wtdma_stopfifo(chip, dma->dma);              vortex_wtdma_stopfifo(chip, dma);
226          }          }
227    #endif
228          break;          break;
229      case SNDRV_PCM_TRIGGER_PAUSE_PUSH:      case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
230          printk(KERN_INFO "vortex: pause %d\n", dma->dma);          printk(KERN_INFO "vortex: pause %d\n", dma);
231          if (substream->pcm == chip->pcm_adb)          if (substream->pcm == chip->pcm_adb)
232              vortex_adbdma_pausefifo(chip, dma->dma);              vortex_adbdma_pausefifo(chip, dma);
233    #ifndef CHIP_AU8810
234          else          else
235              vortex_wtdma_pausefifo(chip, dma->dma);              vortex_wtdma_pausefifo(chip, dma);
236    #endif
237          break;          break;
238      case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:      case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
239          printk(KERN_INFO "vortex: resume %d\n", dma->dma);          printk(KERN_INFO "vortex: resume %d\n", dma);
240          if (substream->pcm == chip->pcm_adb)          if (substream->pcm == chip->pcm_adb)
241              vortex_adbdma_resumefifo(chip, dma->dma);              vortex_adbdma_resumefifo(chip, dma);
242    #ifndef CHIP_AU8810
243          else          else
244              vortex_wtdma_resumefifo(chip, dma->dma);              vortex_wtdma_resumefifo(chip, dma);
245    #endif
246          break;          break;
247      default:      default:
248          return -EINVAL;          return -EINVAL;
# Line 225  static int snd_vortex_pcm_trigger(snd_pc Line 253  static int snd_vortex_pcm_trigger(snd_pc
253  /* pointer callback */  /* pointer callback */
254  static snd_pcm_uframes_t snd_vortex_pcm_pointer(snd_pcm_substream_t *substream) {  static snd_pcm_uframes_t snd_vortex_pcm_pointer(snd_pcm_substream_t *substream) {
255      vortex_t *chip = snd_pcm_substream_chip(substream);      vortex_t *chip = snd_pcm_substream_chip(substream);
256        stream_t *stream = (stream_t*)substream->runtime->private_data;
257            int dma = stream->dma;
258      snd_pcm_uframes_t current_ptr = 0;      snd_pcm_uframes_t current_ptr = 0;
         dma_t *dma = (dma_t*)substream->runtime->private_data;  
259    
260          spin_lock(&chip->lock);          spin_lock(&chip->lock);
261      if (substream->pcm == chip->pcm_adb)      if (substream->pcm == chip->pcm_adb)
262          current_ptr = vortex_adbdma_getlinearpos(chip, dma->dma);          current_ptr = vortex_adbdma_getlinearpos(chip, dma);
263    #ifndef CHIP_AU8810
264      else      else
265          current_ptr = vortex_wtdma_getlinearpos(chip, dma->dma);          current_ptr = vortex_wtdma_getlinearpos(chip, dma);
266    #endif
267      //printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);      //printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
268          spin_unlock(&chip->lock);          spin_unlock(&chip->lock);
269      return (bytes_to_frames(substream->runtime, current_ptr));      return (bytes_to_frames(substream->runtime, current_ptr));
# Line 268  int __devinit snd_vortex_new_pcm(vortex_ Line 299  int __devinit snd_vortex_new_pcm(vortex_
299              return err;              return err;
300          strcpy(pcm->name, "adb");          strcpy(pcm->name, "adb");
301          chip->pcm_adb = pcm;          chip->pcm_adb = pcm;
302      } else {          }
303    #ifndef CHIP_AU8810
304        else {
305          if ((err = snd_pcm_new(chip->card, "Aureal Vortex WT", idx, nr, 0, &pcm)) < 0)          if ((err = snd_pcm_new(chip->card, "Aureal Vortex WT", idx, nr, 0, &pcm)) < 0)
306              return err;              return err;
307          strcpy(pcm->name, "wt");          strcpy(pcm->name, "wt");
308                  chip->pcm_wt = pcm;                  chip->pcm_wt = pcm;
309      }      }
310    #endif
311      pcm->private_data = chip;      pcm->private_data = chip;
312      /* set operators */      /* set operators */
313      snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vortex_playback_ops);      snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vortex_playback_ops);

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26