1 /* 2 * linux/arch/m68k/atari/atasound.c 3 * 4 * ++Geert: Moved almost all stuff to linux/drivers/sound/ 5 * 6 * The author of atari_nosound, atari_mksound and atari_microwire_cmd is 7 * unknown. (++roman: That's me... :-) 8 * 9 * This file is subject to the terms and conditions of the GNU General Public 10 * License. See the file COPYING in the main directory of this archive 11 * for more details. 12 * 13 * 1998-05-31 ++andreas: atari_mksound rewritten to always use the envelope, 14 * no timer, atari_nosound removed. 15 * 16 */ 17 18 19 #include <linux/sched.h> 20 #include <linux/timer.h> 21 #include <linux/major.h> 22 #include <linux/fcntl.h> 23 #include <linux/errno.h> 24 #include <linux/mm.h> 25 #include <linux/module.h> 26 27 #include <asm/atarihw.h> 28 #include <asm/irq.h> 29 #include <asm/atariints.h> 30 31 #include "atari.h" 32 33 /* 34 * stuff from the old atasound.c 35 */ 36 37 void atari_microwire_cmd (int cmd) 38 { 39 tt_microwire.mask = 0x7ff; 40 tt_microwire.data = MW_LM1992_ADDR | cmd; 41 42 /* Busy wait for data being completely sent :-( */ 43 while( tt_microwire.mask != 0x7ff) 44 ; 45 } 46 EXPORT_SYMBOL(atari_microwire_cmd); 47 48 49 /* PSG base frequency */ 50 #define PSG_FREQ 125000 51 /* PSG envelope base frequency times 10 */ 52 #define PSG_ENV_FREQ_10 78125 53 54 void atari_mksound (unsigned int hz, unsigned int ticks) 55 { 56 /* Generates sound of some frequency for some number of clock 57 ticks. */ 58 unsigned long flags; 59 unsigned char tmp; 60 int period; 61 62 local_irq_save(flags); 63 64 65 /* Disable generator A in mixer control. */ 66 sound_ym.rd_data_reg_sel = 7; 67 tmp = sound_ym.rd_data_reg_sel; 68 tmp |= 011; 69 sound_ym.wd_data = tmp; 70 71 if (hz) { 72 /* Convert from frequency value to PSG period value (base 73 frequency 125 kHz). */ 74 75 period = PSG_FREQ / hz; 76 77 if (period > 0xfff) period = 0xfff; 78 79 /* Set generator A frequency to hz. */ 80 sound_ym.rd_data_reg_sel = 0; 81 sound_ym.wd_data = period & 0xff; 82 sound_ym.rd_data_reg_sel = 1; 83 sound_ym.wd_data = (period >> 8) & 0xf; 84 if (ticks) { 85 /* Set length of envelope (max 8 sec). */ 86 int length = (ticks * PSG_ENV_FREQ_10) / HZ / 10; 87 88 if (length > 0xffff) length = 0xffff; 89 sound_ym.rd_data_reg_sel = 11; 90 sound_ym.wd_data = length & 0xff; 91 sound_ym.rd_data_reg_sel = 12; 92 sound_ym.wd_data = length >> 8; 93 /* Envelope form: max -> min single. */ 94 sound_ym.rd_data_reg_sel = 13; 95 sound_ym.wd_data = 0; 96 /* Use envelope for generator A. */ 97 sound_ym.rd_data_reg_sel = 8; 98 sound_ym.wd_data = 0x10; 99 } else { 100 /* Set generator A level to maximum, no envelope. */ 101 sound_ym.rd_data_reg_sel = 8; 102 sound_ym.wd_data = 15; 103 } 104 /* Turn on generator A in mixer control. */ 105 sound_ym.rd_data_reg_sel = 7; 106 tmp &= ~1; 107 sound_ym.wd_data = tmp; 108 } 109 local_irq_restore(flags); 110 } 111