root/arch/m68k/amiga/amisound.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. init_sound
  2. amiga_mksound
  3. nosound

   1 /*
   2  * linux/amiga/amisound.c
   3  *
   4  * amiga sound driver for 680x0 Linux
   5  *
   6  * This file is subject to the terms and conditions of the GNU General Public
   7  * License.  See the file README.legal in the main directory of this archive
   8  * for more details.
   9  */
  10 
  11 #include <linux/sched.h>
  12 #include <linux/timer.h>
  13 
  14 #include <asm/system.h>
  15 #include <asm/amigahw.h>
  16 #include <asm/bootinfo.h>
  17 
  18 static u_short *snd_data = NULL;
  19 static const signed char sine_data[] = {
  20         0,  39,  75,  103,  121,  127,  121,  103,  75,  39,
  21         0, -39, -75, -103, -121, -127, -121, -103, -75, -39
  22 };
  23 #define DATA_SIZE       (sizeof(sine_data)/sizeof(sine_data[0]))
  24 
  25 /* Imported from arch/m68k/amiga/amifb.c */
  26 extern volatile u_short amiga_audio_min_period;
  27 
  28 #define MAX_PERIOD      (65535)
  29 
  30 
  31     /*
  32      *  Current period (set by dmasound.c)
  33      */
  34 
  35 u_short amiga_audio_period = MAX_PERIOD;
  36 
  37 static u_long clock_constant;
  38 
  39 static void init_sound(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         snd_data = amiga_chip_alloc(sizeof(sine_data));
  42         if (!snd_data) {
  43                 printk (KERN_CRIT "amiga init_sound: failed to allocate chipmem\n");
  44                 return;
  45         }
  46         memcpy (snd_data, sine_data, sizeof(sine_data));
  47 
  48         /* setup divisor */
  49         clock_constant = (amiga_colorclock+DATA_SIZE/2)/DATA_SIZE;
  50 }
  51 
  52 static void nosound( unsigned long ignored );
  53 static struct timer_list sound_timer = { NULL, NULL, 0, 0, nosound };
  54 
  55 void amiga_mksound( unsigned int hz, unsigned int ticks )
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57         static int inited = 0;
  58         unsigned long flags;
  59 
  60         if (!inited) {
  61                 init_sound();
  62                 inited = 1;
  63         }
  64 
  65         if (!snd_data)
  66                 return;
  67 
  68         save_flags(flags);
  69         cli();
  70         del_timer( &sound_timer );
  71 
  72         if (hz > 20 && hz < 32767) {
  73                 u_long period = (clock_constant / hz);
  74 
  75                 if (period < amiga_audio_min_period)
  76                         period = amiga_audio_min_period;
  77                 if (period > MAX_PERIOD)
  78                         period = MAX_PERIOD;
  79 
  80                 /* setup pointer to data, period, length and volume */
  81                 custom.aud[0].audlc = snd_data;
  82                 custom.aud[0].audlen = sizeof(sine_data)/2;
  83                 custom.aud[0].audper = (u_short)period;
  84                 custom.aud[0].audvol = 64; /* maxvol */
  85         
  86                 if (ticks) {
  87                         sound_timer.expires = jiffies + ticks;
  88                         add_timer( &sound_timer );
  89                 }
  90 
  91                 /* turn on DMA for audio channel 0 */
  92                 custom.dmacon = DMAF_SETCLR | DMAF_AUD0;
  93 
  94                 restore_flags(flags);
  95                 return;
  96         } else {
  97                 nosound( 0 );
  98                 restore_flags(flags);
  99                 return;
 100         }
 101 }
 102 
 103 
 104 static void nosound( unsigned long ignored )
     /* [previous][next][first][last][top][bottom][index][help] */
 105 {
 106         /* turn off DMA for audio channel 0 */
 107         custom.dmacon = DMAF_AUD0;
 108         /* restore period to previous value after beeping */
 109         custom.aud[0].audper = amiga_audio_period;
 110 }       

/* [previous][next][first][last][top][bottom][index][help] */