1 // SPDX-License-Identifier: GPL-2.0 1 2 /* 3 * Mac bong noise generator. Note - we ou 4 * here 8) 5 * 6 * -------------------------------------- 7 * 16.11.98: 8 * rewrote some functions, added support 9 * after the NetBSD asc.c console bell pa 10 * Juergen Mellinger (juergen.mellinger@t 11 */ 12 13 #include <linux/sched.h> 14 #include <linux/timer.h> 15 16 #include <asm/macintosh.h> 17 #include <asm/mac_asc.h> 18 19 #include "mac.h" 20 21 static int mac_asc_inited; 22 /* 23 * dumb triangular wave table 24 */ 25 static __u8 mac_asc_wave_tab[ 0x800 ]; 26 27 /* 28 * where the ASC hides ... 29 */ 30 static volatile __u8* mac_asc_regs = ( void* ) 31 32 /* 33 * sample rate; is this a good default value? 34 */ 35 static unsigned long mac_asc_samplespersec = 1 36 static int mac_bell_duration; 37 static unsigned long mac_bell_phase; /* 0..2*P 38 static unsigned long mac_bell_phasepersample; 39 40 /* 41 * some function protos 42 */ 43 static void mac_init_asc( void ); 44 static void mac_nosound(struct timer_list *); 45 static void mac_quadra_start_bell( unsigned in 46 static void mac_quadra_ring_bell(struct timer_ 47 static void mac_av_start_bell( unsigned int, u 48 static void ( *mac_special_bell )( unsigned in 49 50 /* 51 * our timer to start/continue/stop the bell 52 */ 53 static DEFINE_TIMER(mac_sound_timer, mac_nosou 54 55 /* 56 * Sort of initialize the sound chip (called f 57 * beep). 58 */ 59 static void mac_init_asc( void ) 60 { 61 int i; 62 63 /* 64 * do some machine specific initializa 65 * BTW: 66 * the NetBSD Quadra patch identifies 67 * mac_asc_regs[ 0x800 ] & 0xF0 ! 68 * this makes no sense here, because w 69 * rate anyway if we want correct freq 70 */ 71 switch ( macintosh_config->ident ) 72 { 73 case MAC_MODEL_IIFX: 74 /* 75 * The IIfx is always 76 */ 77 mac_asc_regs = ( void* 78 break; 79 /* 80 * not sure about how 81 * machines with the E 82 */ 83 case MAC_MODEL_Q630: 84 case MAC_MODEL_P475: 85 mac_special_bell = mac 86 mac_asc_samplespersec 87 break; 88 case MAC_MODEL_C660: 89 case MAC_MODEL_Q840: 90 /* 91 * The Quadra 660AV an 92 * It appears to be si 93 * [678]100. Because 94 * interface, this wou 95 * for AWACS could be 96 * do is figure out ho 97 * figure out where th 98 * vicinity of the AWA 99 * current location of 100 * Power Mac [678]100 101 * 102 * Quoted from Apple's 103 * "Among desktop Ma 104 * Macintosh models 105 * because of the AT 106 * codec circuitry i 107 * Converter (AWAC) 108 * 16-bit I/O functi 109 * support 16-bit st 110 * 111 * Technical Informa 112 * https://support.a 113 * 114 * --David Kilzer 115 */ 116 mac_special_bell = mac 117 break; 118 case MAC_MODEL_Q650: 119 case MAC_MODEL_Q700: 120 case MAC_MODEL_Q800: 121 case MAC_MODEL_Q900: 122 case MAC_MODEL_Q950: 123 /* 124 * Currently not imple 125 */ 126 mac_special_bell = NUL 127 break; 128 default: 129 /* 130 * Every switch needs 131 */ 132 mac_special_bell = NUL 133 break; 134 } 135 136 /* 137 * init the wave table with a simple t 138 * A sine wave would sure be nicer her 139 */ 140 for ( i = 0; i < 0x400; i++ ) 141 { 142 mac_asc_wave_tab[ i ] = i / 4; 143 mac_asc_wave_tab[ i + 0x400 ] 144 } 145 mac_asc_inited = 1; 146 } 147 148 /* 149 * Called to make noise; current single entry 150 * Does the job for simple ASC, calls other ro 151 * XXX Fixme: 152 * Should be split into asc_mksound, easc_mkso 153 * function pointer set in mac_init_asc which 154 * init time. 155 * _This_ is rather ugly ... 156 */ 157 void mac_mksound( unsigned int freq, unsigned 158 { 159 __u32 cfreq = ( freq << 5 ) / 468; 160 unsigned long flags; 161 int i; 162 163 if ( mac_special_bell == NULL ) 164 { 165 /* Do nothing */ 166 return; 167 } 168 169 if ( !mac_asc_inited ) 170 mac_init_asc(); 171 172 if ( mac_special_bell ) 173 { 174 mac_special_bell( freq, length 175 return; 176 } 177 178 if ( freq < 20 || freq > 20000 || leng 179 { 180 mac_nosound( 0 ); 181 return; 182 } 183 184 local_irq_save(flags); 185 186 del_timer( &mac_sound_timer ); 187 188 for ( i = 0; i < 0x800; i++ ) 189 mac_asc_regs[ i ] = 0; 190 for ( i = 0; i < 0x800; i++ ) 191 mac_asc_regs[ i ] = mac_asc_wa 192 193 for ( i = 0; i < 8; i++ ) 194 *( __u32* )( ( __u32 )mac_asc_ 195 196 mac_asc_regs[ 0x807 ] = 0; 197 mac_asc_regs[ ASC_VOLUME ] = 128; 198 mac_asc_regs[ 0x805 ] = 0; 199 mac_asc_regs[ 0x80F ] = 0; 200 mac_asc_regs[ ASC_MODE ] = ASC_MODE_SA 201 mac_asc_regs[ ASC_ENABLE ] = ASC_ENABL 202 203 mac_sound_timer.expires = jiffies + le 204 add_timer( &mac_sound_timer ); 205 206 local_irq_restore(flags); 207 } 208 209 /* 210 * regular ASC: stop whining .. 211 */ 212 static void mac_nosound(struct timer_list *unu 213 { 214 mac_asc_regs[ ASC_ENABLE ] = 0; 215 } 216 217 /* 218 * EASC entry; init EASC, don't load wavetable 219 */ 220 static void mac_quadra_start_bell( unsigned in 221 { 222 unsigned long flags; 223 224 /* if the bell is already ringing, rin 225 if ( mac_bell_duration > 0 ) 226 { 227 mac_bell_duration += length; 228 return; 229 } 230 231 mac_bell_duration = length; 232 mac_bell_phase = 0; 233 mac_bell_phasepersample = ( freq * siz 234 /* this is reasonably big for small fr 235 236 local_irq_save(flags); 237 238 /* set the volume */ 239 mac_asc_regs[ 0x806 ] = volume; 240 241 /* set up the ASC registers */ 242 if ( mac_asc_regs[ 0x801 ] != 1 ) 243 { 244 /* select mono mode */ 245 mac_asc_regs[ 0x807 ] = 0; 246 /* select sampled sound mode * 247 mac_asc_regs[ 0x802 ] = 0; 248 /* ??? */ 249 mac_asc_regs[ 0x801 ] = 1; 250 mac_asc_regs[ 0x803 ] |= 0x80; 251 mac_asc_regs[ 0x803 ] &= 0x7F; 252 } 253 254 mac_sound_timer.function = mac_quadra_ 255 mac_sound_timer.expires = jiffies + 1; 256 add_timer( &mac_sound_timer ); 257 258 local_irq_restore(flags); 259 } 260 261 /* 262 * EASC 'start/continue whining'; I'm not sure 263 * already load the wave table, or at least ca 264 * This piece keeps reloading the wave table u 265 */ 266 static void mac_quadra_ring_bell(struct timer_ 267 { 268 int i, count = mac_asc_samplespers 269 unsigned long flags; 270 271 /* 272 * we neither want a sound buffer over 273 * the number of samples per timer int 274 * using the asc interrupt will give b 275 * ...and the possibility to use a rea 276 */ 277 278 local_irq_save(flags); 279 280 del_timer( &mac_sound_timer ); 281 282 if ( mac_bell_duration-- > 0 ) 283 { 284 for ( i = 0; i < count; i++ ) 285 { 286 mac_bell_phase += mac_ 287 mac_asc_regs[ 0 ] = ma 288 } 289 mac_sound_timer.expires = jiff 290 add_timer( &mac_sound_timer ); 291 } 292 else 293 mac_asc_regs[ 0x801 ] = 0; 294 295 local_irq_restore(flags); 296 } 297 298 /* 299 * AV code - please fill in. 300 */ 301 static void mac_av_start_bell( unsigned int fr 302 { 303 } 304
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.