Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pdaudiocf_pcm.c
Go to the documentation of this file.
1 /*
2  * Driver for Sound Core PDAudioCF soundcards
3  *
4  * PCM part
5  *
6  * Copyright (c) 2003 by Jaroslav Kysela <[email protected]>
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 #include <linux/delay.h>
24 #include <sound/core.h>
25 #include <sound/asoundef.h>
26 #include "pdaudiocf.h"
27 
28 
29 /*
30  * clear the SRAM contents
31  */
32 static int pdacf_pcm_clear_sram(struct snd_pdacf *chip)
33 {
34  int max_loop = 64 * 1024;
35 
36  while (inw(chip->port + PDAUDIOCF_REG_RDP) != inw(chip->port + PDAUDIOCF_REG_WDP)) {
37  if (max_loop-- < 0)
38  return -EIO;
39  inw(chip->port + PDAUDIOCF_REG_MD);
40  }
41  return 0;
42 }
43 
44 /*
45  * pdacf_pcm_trigger - trigger callback for capture
46  */
47 static int pdacf_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
48 {
49  struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
50  struct snd_pcm_runtime *runtime = subs->runtime;
51  int inc, ret = 0, rate;
52  unsigned short mask, val, tmp;
53 
55  return -EBUSY;
56 
57  switch (cmd) {
59  chip->pcm_hwptr = 0;
60  chip->pcm_tdone = 0;
61  /* fall thru */
64  mask = 0;
65  val = PDAUDIOCF_RECORD;
66  inc = 1;
68  break;
72  mask = PDAUDIOCF_RECORD;
73  val = 0;
74  inc = -1;
75  rate = 0;
76  break;
77  default:
78  return -EINVAL;
79  }
80  spin_lock(&chip->reg_lock);
81  chip->pcm_running += inc;
82  tmp = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
83  if (chip->pcm_running) {
84  if ((chip->ak4117->rcs0 & AK4117_UNLCK) || runtime->rate != rate) {
85  chip->pcm_running -= inc;
86  ret = -EIO;
87  goto __end;
88  }
89  }
90  tmp &= ~mask;
91  tmp |= val;
92  pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, tmp);
93  __end:
94  spin_unlock(&chip->reg_lock);
96  return ret;
97 }
98 
99 /*
100  * pdacf_pcm_hw_params - hw_params callback for playback and capture
101  */
102 static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs,
103  struct snd_pcm_hw_params *hw_params)
104 {
106  (subs, params_buffer_bytes(hw_params));
107 }
108 
109 /*
110  * pdacf_pcm_hw_free - hw_free callback for playback and capture
111  */
112 static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs)
113 {
114  return snd_pcm_lib_free_vmalloc_buffer(subs);
115 }
116 
117 /*
118  * pdacf_pcm_prepare - prepare callback for playback and capture
119  */
120 static int pdacf_pcm_prepare(struct snd_pcm_substream *subs)
121 {
122  struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
123  struct snd_pcm_runtime *runtime = subs->runtime;
124  u16 val, nval, aval;
125 
127  return -EBUSY;
128 
129  chip->pcm_channels = runtime->channels;
130 
131  chip->pcm_little = snd_pcm_format_little_endian(runtime->format) > 0;
132 #ifdef SNDRV_LITTLE_ENDIAN
133  chip->pcm_swab = snd_pcm_format_big_endian(runtime->format) > 0;
134 #else
135  chip->pcm_swab = chip->pcm_little;
136 #endif
137 
138  if (snd_pcm_format_unsigned(runtime->format))
139  chip->pcm_xor = 0x80008000;
140 
141  if (pdacf_pcm_clear_sram(chip) < 0)
142  return -EIO;
143 
144  val = nval = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
146  switch (runtime->format) {
149  break;
150  default: /* 24-bit */
152  break;
153  }
154  aval = 0;
155  chip->pcm_sample = 4;
156  switch (runtime->format) {
159  aval = AK4117_DIF_16R;
160  chip->pcm_frame = 2;
161  chip->pcm_sample = 2;
162  break;
165  chip->pcm_sample = 3;
166  /* fall through */
167  default: /* 24-bit */
168  aval = AK4117_DIF_24R;
169  chip->pcm_frame = 3;
170  chip->pcm_xor &= 0xffff0000;
171  break;
172  }
173 
174  if (val != nval) {
176  pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, nval);
177  }
178 
179  val = pdacf_reg_read(chip, PDAUDIOCF_REG_IER);
180  val &= ~(PDAUDIOCF_IRQLVLEN1);
181  val |= PDAUDIOCF_IRQLVLEN0;
182  pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val);
183 
184  chip->pcm_size = runtime->buffer_size;
185  chip->pcm_period = runtime->period_size;
186  chip->pcm_area = runtime->dma_area;
187 
188  return 0;
189 }
190 
191 
192 /*
193  * capture hw information
194  */
195 
196 static struct snd_pcm_hardware pdacf_pcm_capture_hw = {
211  .rate_min = 32000,
212  .rate_max = 192000,
213  .channels_min = 1,
214  .channels_max = 2,
215  .buffer_bytes_max = (512*1024),
216  .period_bytes_min = 8*1024,
217  .period_bytes_max = (64*1024),
218  .periods_min = 2,
219  .periods_max = 128,
220  .fifo_size = 0,
221 };
222 
223 
224 /*
225  * pdacf_pcm_capture_open - open callback for capture
226  */
227 static int pdacf_pcm_capture_open(struct snd_pcm_substream *subs)
228 {
229  struct snd_pcm_runtime *runtime = subs->runtime;
230  struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
231 
233  return -EBUSY;
234 
235  runtime->hw = pdacf_pcm_capture_hw;
236  runtime->private_data = chip;
237  chip->pcm_substream = subs;
238 
239  return 0;
240 }
241 
242 /*
243  * pdacf_pcm_capture_close - close callback for capture
244  */
245 static int pdacf_pcm_capture_close(struct snd_pcm_substream *subs)
246 {
247  struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
248 
249  if (!chip)
250  return -EINVAL;
251  pdacf_reinit(chip, 0);
252  chip->pcm_substream = NULL;
253  return 0;
254 }
255 
256 
257 /*
258  * pdacf_pcm_capture_pointer - pointer callback for capture
259  */
260 static snd_pcm_uframes_t pdacf_pcm_capture_pointer(struct snd_pcm_substream *subs)
261 {
262  struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
263  return chip->pcm_hwptr;
264 }
265 
266 /*
267  * operators for PCM capture
268  */
269 static struct snd_pcm_ops pdacf_pcm_capture_ops = {
270  .open = pdacf_pcm_capture_open,
271  .close = pdacf_pcm_capture_close,
272  .ioctl = snd_pcm_lib_ioctl,
273  .hw_params = pdacf_pcm_hw_params,
274  .hw_free = pdacf_pcm_hw_free,
275  .prepare = pdacf_pcm_prepare,
276  .trigger = pdacf_pcm_trigger,
277  .pointer = pdacf_pcm_capture_pointer,
279  .mmap = snd_pcm_lib_mmap_vmalloc,
280 };
281 
282 
283 /*
284  * snd_pdacf_pcm_new - create and initialize a pcm
285  */
286 int snd_pdacf_pcm_new(struct snd_pdacf *chip)
287 {
288  struct snd_pcm *pcm;
289  int err;
290 
291  err = snd_pcm_new(chip->card, "PDAudioCF", 0, 0, 1, &pcm);
292  if (err < 0)
293  return err;
294 
295  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pdacf_pcm_capture_ops);
296 
297  pcm->private_data = chip;
298  pcm->info_flags = 0;
299  strcpy(pcm->name, chip->card->shortname);
300  chip->pcm = pcm;
301 
302  err = snd_ak4117_build(chip->ak4117, pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
303  if (err < 0)
304  return err;
305 
306  return 0;
307 }