Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vidc.c
Go to the documentation of this file.
1 /*
2  * linux/drivers/sound/vidc.c
3  *
4  * Copyright (C) 1997-2000 by Russell King <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * VIDC20 audio driver.
11  *
12  * The VIDC20 sound hardware consists of the VIDC20 itself, a DAC and a DMA
13  * engine. The DMA transfers fixed-format (16-bit little-endian linear)
14  * samples to the VIDC20, which then transfers this data serially to the
15  * DACs. The samplerate is controlled by the VIDC.
16  *
17  * We currently support a mixer device, but it is currently non-functional.
18  */
19 
20 #include <linux/gfp.h>
21 #include <linux/init.h>
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/interrupt.h>
25 
26 #include <mach/hardware.h>
27 #include <asm/dma.h>
28 #include <asm/io.h>
29 #include <asm/hardware/iomd.h>
30 #include <asm/irq.h>
31 
32 #include "sound_config.h"
33 #include "vidc.h"
34 
35 #ifndef _SIOC_TYPE
36 #define _SIOC_TYPE(x) _IOC_TYPE(x)
37 #endif
38 #ifndef _SIOC_NR
39 #define _SIOC_NR(x) _IOC_NR(x)
40 #endif
41 
42 #define VIDC_SOUND_CLOCK (250000)
43 #define VIDC_SOUND_CLOCK_EXT (176400)
44 
45 /*
46  * When using SERIAL SOUND mode (external DAC), the number of physical
47  * channels is fixed at 2.
48  */
49 static int vidc_busy;
50 static int vidc_adev;
51 static int vidc_audio_rate;
52 static char vidc_audio_format;
53 static char vidc_audio_channels;
54 
55 static unsigned char vidc_level_l[SOUND_MIXER_NRDEVICES] = {
56  85, /* master */
57  50, /* bass */
58  50, /* treble */
59  0, /* synth */
60  75, /* pcm */
61  0, /* speaker */
62  100, /* ext line */
63  0, /* mic */
64  100, /* CD */
65  0,
66 };
67 
68 static unsigned char vidc_level_r[SOUND_MIXER_NRDEVICES] = {
69  85, /* master */
70  50, /* bass */
71  50, /* treble */
72  0, /* synth */
73  75, /* pcm */
74  0, /* speaker */
75  100, /* ext line */
76  0, /* mic */
77  100, /* CD */
78  0,
79 };
80 
81 static unsigned int vidc_audio_volume_l; /* left PCM vol, 0 - 65536 */
82 static unsigned int vidc_audio_volume_r; /* right PCM vol, 0 - 65536 */
83 
84 extern void vidc_update_filler(int bits, int channels);
85 extern int softoss_dev;
86 
87 static void
88 vidc_mixer_set(int mdev, unsigned int level)
89 {
90  unsigned int lev_l = level & 0x007f;
91  unsigned int lev_r = (level & 0x7f00) >> 8;
92  unsigned int mlev_l, mlev_r;
93 
94  if (lev_l > 100)
95  lev_l = 100;
96  if (lev_r > 100)
97  lev_r = 100;
98 
99 #define SCALE(lev,master) ((lev) * (master) * 65536 / 10000)
100 
101  mlev_l = vidc_level_l[SOUND_MIXER_VOLUME];
102  mlev_r = vidc_level_r[SOUND_MIXER_VOLUME];
103 
104  switch (mdev) {
105  case SOUND_MIXER_VOLUME:
106  case SOUND_MIXER_PCM:
107  vidc_level_l[mdev] = lev_l;
108  vidc_level_r[mdev] = lev_r;
109 
110  vidc_audio_volume_l = SCALE(lev_l, mlev_l);
111  vidc_audio_volume_r = SCALE(lev_r, mlev_r);
112 /*printk("VIDC: PCM vol %05X %05X\n", vidc_audio_volume_l, vidc_audio_volume_r);*/
113  break;
114  }
115 #undef SCALE
116 }
117 
118 static int vidc_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
119 {
120  unsigned int val;
121  unsigned int mdev;
122 
123  if (_SIOC_TYPE(cmd) != 'M')
124  return -EINVAL;
125 
126  mdev = _SIOC_NR(cmd);
127 
128  if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
129  if (get_user(val, (unsigned int __user *)arg))
130  return -EFAULT;
131 
132  if (mdev < SOUND_MIXER_NRDEVICES)
133  vidc_mixer_set(mdev, val);
134  else
135  return -EINVAL;
136  }
137 
138  /*
139  * Return parameters
140  */
141  switch (mdev) {
142  case SOUND_MIXER_RECSRC:
143  val = 0;
144  break;
145 
146  case SOUND_MIXER_DEVMASK:
148  break;
149 
152  break;
153 
154  case SOUND_MIXER_RECMASK:
155  val = 0;
156  break;
157 
158  case SOUND_MIXER_CAPS:
159  val = 0;
160  break;
161 
162  default:
163  if (mdev < SOUND_MIXER_NRDEVICES)
164  val = vidc_level_l[mdev] | vidc_level_r[mdev] << 8;
165  else
166  return -EINVAL;
167  }
168 
169  return put_user(val, (unsigned int __user *)arg) ? -EFAULT : 0;
170 }
171 
172 static unsigned int vidc_audio_set_format(int dev, unsigned int fmt)
173 {
174  switch (fmt) {
175  default:
176  fmt = AFMT_S16_LE;
177  case AFMT_U8:
178  case AFMT_S8:
179  case AFMT_S16_LE:
180  vidc_audio_format = fmt;
181  vidc_update_filler(vidc_audio_format, vidc_audio_channels);
182  case AFMT_QUERY:
183  break;
184  }
185  return vidc_audio_format;
186 }
187 
188 #define my_abs(i) ((i)<0 ? -(i) : (i))
189 
190 static int vidc_audio_set_speed(int dev, int rate)
191 {
192  if (rate) {
193  unsigned int hwctrl, hwrate, hwrate_ext, rate_int, rate_ext;
194  unsigned int diff_int, diff_ext;
195  unsigned int newsize, new2size;
196 
197  hwctrl = 0x00000003;
198 
199  /* Using internal clock */
200  hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1;
201  if (hwrate < 3)
202  hwrate = 3;
203  if (hwrate > 255)
204  hwrate = 255;
205 
206  /* Using exernal clock */
207  hwrate_ext = (((VIDC_SOUND_CLOCK_EXT * 2) / rate) + 1) >> 1;
208  if (hwrate_ext < 3)
209  hwrate_ext = 3;
210  if (hwrate_ext > 255)
211  hwrate_ext = 255;
212 
213  rate_int = VIDC_SOUND_CLOCK / hwrate;
214  rate_ext = VIDC_SOUND_CLOCK_EXT / hwrate_ext;
215 
216  /* Chose between external and internal clock */
217  diff_int = my_abs(rate_ext-rate);
218  diff_ext = my_abs(rate_int-rate);
219  if (diff_ext < diff_int) {
220  /*printk("VIDC: external %d %d %d\n", rate, rate_ext, hwrate_ext);*/
221  hwrate=hwrate_ext;
222  hwctrl=0x00000002;
223  /* Allow roughly 0.4% tolerance */
224  if (diff_ext > (rate/256))
225  rate=rate_ext;
226  } else {
227  /*printk("VIDC: internal %d %d %d\n", rate, rate_int, hwrate);*/
228  hwctrl=0x00000003;
229  /* Allow roughly 0.4% tolerance */
230  if (diff_int > (rate/256))
231  rate=rate_int;
232  }
233 
234  vidc_writel(0xb0000000 | (hwrate - 2));
235  vidc_writel(0xb1000000 | hwctrl);
236 
237  newsize = (10000 / hwrate) & ~3;
238  if (newsize < 208)
239  newsize = 208;
240  if (newsize > 4096)
241  newsize = 4096;
242  for (new2size = 128; new2size < newsize; new2size <<= 1);
243  if (new2size - newsize > newsize - (new2size >> 1))
244  new2size >>= 1;
245  if (new2size > 4096) {
246  printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n",
247  newsize, new2size);
248  new2size = 4096;
249  }
250  /*printk("VIDC: dma size %d\n", new2size);*/
251  dma_bufsize = new2size;
252  vidc_audio_rate = rate;
253  }
254  return vidc_audio_rate;
255 }
256 
257 static short vidc_audio_set_channels(int dev, short channels)
258 {
259  switch (channels) {
260  default:
261  channels = 2;
262  case 1:
263  case 2:
264  vidc_audio_channels = channels;
265  vidc_update_filler(vidc_audio_format, vidc_audio_channels);
266  case 0:
267  break;
268  }
269  return vidc_audio_channels;
270 }
271 
272 /*
273  * Open the device
274  */
275 static int vidc_audio_open(int dev, int mode)
276 {
277  /* This audio device does not have recording capability */
278  if (mode == OPEN_READ)
279  return -EPERM;
280 
281  if (vidc_busy)
282  return -EBUSY;
283 
284  vidc_busy = 1;
285  return 0;
286 }
287 
288 /*
289  * Close the device
290  */
291 static void vidc_audio_close(int dev)
292 {
293  vidc_busy = 0;
294 }
295 
296 /*
297  * Output a block via DMA to sound device.
298  *
299  * We just set the DMA start and count; the DMA interrupt routine
300  * will take care of formatting the samples (via the appropriate
301  * vidc_filler routine), and flag via vidc_audio_dma_interrupt when
302  * more data is required.
303  */
304 static void
305 vidc_audio_output_block(int dev, unsigned long buf, int total_count, int one)
306 {
307  struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
308  unsigned long flags;
309 
310  local_irq_save(flags);
311  dma_start = buf - (unsigned long)dmap->raw_buf_phys + (unsigned long)dmap->raw_buf;
312  dma_count = total_count;
313  local_irq_restore(flags);
314 }
315 
316 static void
317 vidc_audio_start_input(int dev, unsigned long buf, int count, int intrflag)
318 {
319 }
320 
321 static int vidc_audio_prepare_for_input(int dev, int bsize, int bcount)
322 {
323  return -EINVAL;
324 }
325 
326 static irqreturn_t vidc_audio_dma_interrupt(void)
327 {
328  DMAbuf_outputintr(vidc_adev, 1);
329  return IRQ_HANDLED;
330 }
331 
332 /*
333  * Prepare for outputting samples.
334  *
335  * Each buffer that will be passed will be `bsize' bytes long,
336  * with a total of `bcount' buffers.
337  */
338 static int vidc_audio_prepare_for_output(int dev, int bsize, int bcount)
339 {
340  struct audio_operations *adev = audio_devs[dev];
341 
343  adev->dmap_out->flags |= DMA_NODMA;
344 
345  return 0;
346 }
347 
348 /*
349  * Stop our current operation.
350  */
351 static void vidc_audio_reset(int dev)
352 {
354 }
355 
356 static int vidc_audio_local_qlen(int dev)
357 {
358  return /*dma_count !=*/ 0;
359 }
360 
361 static void vidc_audio_trigger(int dev, int enable_bits)
362 {
363  struct audio_operations *adev = audio_devs[dev];
364 
365  if (enable_bits & PCM_ENABLE_OUTPUT) {
366  if (!(adev->dmap_out->flags & DMA_ACTIVE)) {
367  unsigned long flags;
368 
369  local_irq_save(flags);
370 
371  /* prevent recusion */
372  adev->dmap_out->flags |= DMA_ACTIVE;
373 
374  dma_interrupt = vidc_audio_dma_interrupt;
377 
378  local_irq_restore(flags);
379  }
380  }
381 }
382 
383 static struct audio_driver vidc_audio_driver =
384 {
385  .owner = THIS_MODULE,
386  .open = vidc_audio_open,
387  .close = vidc_audio_close,
388  .output_block = vidc_audio_output_block,
389  .start_input = vidc_audio_start_input,
390  .prepare_for_input = vidc_audio_prepare_for_input,
391  .prepare_for_output = vidc_audio_prepare_for_output,
392  .halt_io = vidc_audio_reset,
393  .local_qlen = vidc_audio_local_qlen,
394  .trigger = vidc_audio_trigger,
395  .set_speed = vidc_audio_set_speed,
396  .set_bits = vidc_audio_set_format,
397  .set_channels = vidc_audio_set_channels
398 };
399 
400 static struct mixer_operations vidc_mixer_operations = {
401  .owner = THIS_MODULE,
402  .id = "VIDC",
403  .name = "VIDCsound",
404  .ioctl = vidc_mixer_ioctl
405 };
406 
407 void vidc_update_filler(int format, int channels)
408 {
409 #define TYPE(fmt,ch) (((fmt)<<2) | ((ch)&3))
410 
411  switch (TYPE(format, channels)) {
412  default:
413  case TYPE(AFMT_U8, 1):
415  break;
416 
417  case TYPE(AFMT_U8, 2):
419  break;
420 
421  case TYPE(AFMT_S8, 1):
423  break;
424 
425  case TYPE(AFMT_S8, 2):
427  break;
428 
429  case TYPE(AFMT_S16_LE, 1):
431  break;
432 
433  case TYPE(AFMT_S16_LE, 2):
435  break;
436  }
437 }
438 
439 static void __init attach_vidc(struct address_info *hw_config)
440 {
441  char name[32];
442  int i, adev;
443 
444  sprintf(name, "VIDC %d-bit sound", hw_config->card_subtype);
445  conf_printf(name, hw_config);
446  memset(dma_buf, 0, sizeof(dma_buf));
447 
449  &vidc_audio_driver, sizeof(vidc_audio_driver),
451  NULL, hw_config->dma, hw_config->dma2);
452 
453  if (adev < 0)
454  goto audio_failed;
455 
456  /*
457  * 1024 bytes => 64 buffers
458  */
459  audio_devs[adev]->min_fragment = 10;
460  audio_devs[adev]->mixer_dev = num_mixers;
461 
462  audio_devs[adev]->mixer_dev =
464  name, &vidc_mixer_operations,
465  sizeof(vidc_mixer_operations), NULL);
466 
467  if (audio_devs[adev]->mixer_dev < 0)
468  goto mixer_failed;
469 
470  for (i = 0; i < 2; i++) {
472  if (!dma_buf[i]) {
473  printk(KERN_ERR "%s: can't allocate required buffers\n",
474  name);
475  goto mem_failed;
476  }
477  dma_pbuf[i] = virt_to_phys((void *)dma_buf[i]);
478  }
479 
480  if (sound_alloc_dma(hw_config->dma, hw_config->name)) {
481  printk(KERN_ERR "%s: DMA %d is in use\n", name, hw_config->dma);
482  goto dma_failed;
483  }
484 
485  if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0,
486  hw_config->name, &dma_start)) {
487  printk(KERN_ERR "%s: IRQ %d is in use\n", name, hw_config->irq);
488  goto irq_failed;
489  }
490  vidc_adev = adev;
491  vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8));
492 
493  return;
494 
495 irq_failed:
496  sound_free_dma(hw_config->dma);
497 dma_failed:
498 mem_failed:
499  for (i = 0; i < 2; i++)
500  free_page(dma_buf[i]);
501  sound_unload_mixerdev(audio_devs[adev]->mixer_dev);
502 mixer_failed:
503  sound_unload_audiodev(adev);
504 audio_failed:
505  return;
506 }
507 
508 static int __init probe_vidc(struct address_info *hw_config)
509 {
510  hw_config->irq = IRQ_DMAS0;
511  hw_config->dma = DMA_VIRTUAL_SOUND;
512  hw_config->dma2 = -1;
513  hw_config->card_subtype = 16;
514  hw_config->name = "VIDC20";
515  return 1;
516 }
517 
518 static void __exit unload_vidc(struct address_info *hw_config)
519 {
520  int i, adev = vidc_adev;
521 
522  vidc_adev = -1;
523 
524  free_irq(hw_config->irq, &dma_start);
525  sound_free_dma(hw_config->dma);
526 
527  if (adev >= 0) {
528  sound_unload_mixerdev(audio_devs[adev]->mixer_dev);
529  sound_unload_audiodev(adev);
530  for (i = 0; i < 2; i++)
531  free_page(dma_buf[i]);
532  }
533 }
534 
535 static struct address_info cfg;
536 
537 static int __init init_vidc(void)
538 {
539  if (probe_vidc(&cfg) == 0)
540  return -ENODEV;
541 
542  attach_vidc(&cfg);
543 
544  return 0;
545 }
546 
547 static void __exit cleanup_vidc(void)
548 {
549  unload_vidc(&cfg);
550 }
551 
552 module_init(init_vidc);
553 module_exit(cleanup_vidc);
554 
555 MODULE_AUTHOR("Russell King");
556 MODULE_DESCRIPTION("VIDC20 audio driver");
557 MODULE_LICENSE("GPL");