Home | History | Annotate | Line # | Download | only in obio
asc.c revision 1.16
      1  1.14    briggs /*	$NetBSD: asc.c,v 1.16 1997/02/03 17:36:00 scottr Exp $	*/
      2   1.6       cgd 
      3   1.1    briggs /*-
      4   1.1    briggs  * Copyright (C) 1993	Allen K. Briggs, Chris P. Caputo,
      5   1.1    briggs  *			Michael L. Finch, Bradley A. Grantham, and
      6   1.1    briggs  *			Lawrence A. Kesteloot
      7   1.1    briggs  * All rights reserved.
      8   1.1    briggs  *
      9   1.1    briggs  * Redistribution and use in source and binary forms, with or without
     10   1.1    briggs  * modification, are permitted provided that the following conditions
     11   1.1    briggs  * are met:
     12   1.1    briggs  * 1. Redistributions of source code must retain the above copyright
     13   1.1    briggs  *    notice, this list of conditions and the following disclaimer.
     14   1.1    briggs  * 2. Redistributions in binary form must reproduce the above copyright
     15   1.1    briggs  *    notice, this list of conditions and the following disclaimer in the
     16   1.1    briggs  *    documentation and/or other materials provided with the distribution.
     17   1.1    briggs  * 3. All advertising materials mentioning features or use of this software
     18   1.1    briggs  *    must display the following acknowledgement:
     19   1.1    briggs  *	This product includes software developed by the Alice Group.
     20   1.1    briggs  * 4. The names of the Alice Group or any of its members may not be used
     21   1.1    briggs  *    to endorse or promote products derived from this software without
     22   1.1    briggs  *    specific prior written permission.
     23   1.1    briggs  *
     24   1.1    briggs  * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
     25   1.1    briggs  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     26   1.1    briggs  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     27   1.1    briggs  * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
     28   1.1    briggs  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     29   1.1    briggs  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     30   1.1    briggs  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     31   1.1    briggs  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     32   1.1    briggs  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     33   1.1    briggs  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34   1.1    briggs  */
     35   1.1    briggs 
     36   1.1    briggs /*
     37   1.1    briggs  * ASC driver code and asc_ringbell() support
     38   1.1    briggs  */
     39   1.1    briggs 
     40   1.1    briggs #include <sys/types.h>
     41   1.8    briggs #include <sys/cdefs.h>
     42   1.1    briggs #include <sys/errno.h>
     43   1.3    briggs #include <sys/time.h>
     44   1.1    briggs #include <sys/systm.h>
     45   1.1    briggs #include <sys/param.h>
     46   1.5    briggs #include <sys/device.h>
     47  1.14    briggs 
     48  1.14    briggs #include <machine/autoconf.h>
     49   1.5    briggs #include <machine/cpu.h>
     50  1.16    scottr #include <machine/bus.h>
     51   1.1    briggs 
     52  1.11    briggs #include "ascvar.h"
     53  1.16    scottr #include "obiovar.h"
     54   1.1    briggs 
     55  1.16    scottr #define	MAC68K_ASC_BASE	((caddr_t) 0x50f14000)
     56  1.16    scottr #define	MAC68K_ASC_LEN	0x01000
     57   1.1    briggs 
     58  1.16    scottr /* bell support data */
     59  1.16    scottr static int		asc_configured = 0;
     60  1.16    scottr static bus_space_tag_t	asc_tag = MAC68K_BUS_SPACE_MEM;
     61  1.16    scottr static bus_space_handle_t asc_handle;
     62   1.1    briggs 
     63   1.1    briggs static int bell_freq = 1880;
     64   1.1    briggs static int bell_length = 10;
     65   1.1    briggs static int bell_volume = 100;
     66   1.1    briggs static int bell_ringing = 0;
     67   1.1    briggs 
     68  1.15    scottr static int  ascmatch __P((struct device *, struct cfdata *, void *));
     69   1.8    briggs static void ascattach __P((struct device *, struct device *, void *));
     70   1.5    briggs 
     71  1.10   thorpej struct cfattach asc_ca = {
     72  1.11    briggs 	sizeof(struct device), ascmatch, ascattach
     73  1.10   thorpej };
     74  1.10   thorpej 
     75  1.10   thorpej struct cfdriver asc_cd = {
     76  1.10   thorpej 	NULL, "asc", DV_DULL, NULL, 0
     77  1.10   thorpej };
     78   1.5    briggs 
     79   1.5    briggs static int
     80  1.15    scottr ascmatch(parent, cf, aux)
     81  1.15    scottr 	struct device *parent;
     82  1.15    scottr 	struct cfdata *cf;
     83  1.15    scottr 	void *aux;
     84   1.5    briggs {
     85  1.16    scottr 	static int asc_matched = 0;
     86  1.16    scottr 	struct obio_attach_args *oa = aux;
     87  1.16    scottr 	bus_space_tag_t bst = MAC68K_BUS_SPACE_MEM;
     88  1.16    scottr 	bus_space_handle_t bsh;
     89  1.16    scottr 	bus_addr_t addr;
     90  1.16    scottr 	int rval = 0;
     91  1.16    scottr 
     92  1.16    scottr 	/* Allow only one instance. */
     93  1.16    scottr 	if (asc_matched)
     94  1.16    scottr 		return (0);
     95  1.16    scottr 	asc_matched = 1;
     96  1.16    scottr 
     97  1.16    scottr 	addr = (bus_addr_t) (oa->oa_addr ? oa->oa_addr : MAC68K_ASC_BASE);
     98  1.16    scottr 
     99  1.16    scottr 	if (bus_space_map(bst, addr, MAC68K_ASC_LEN, 0, &bsh))
    100  1.16    scottr 		return (0);
    101  1.16    scottr 
    102  1.16    scottr 	if (bus_probe(bst, bsh, 0, 1))
    103  1.16    scottr 		rval = 1;
    104  1.16    scottr 	else
    105  1.16    scottr 		rval = 0;
    106  1.16    scottr 
    107  1.16    scottr 	bus_space_unmap(bst, bsh, MAC68K_ASC_LEN);
    108  1.16    scottr 
    109  1.16    scottr 	return rval;
    110   1.5    briggs }
    111   1.1    briggs 
    112   1.5    briggs static void
    113  1.16    scottr ascattach(parent, self, aux)
    114  1.16    scottr 	struct device *parent, *self;
    115  1.16    scottr 	void *aux;
    116   1.1    briggs {
    117  1.16    scottr 	struct obio_attach_args *oa = aux;
    118  1.16    scottr 	bus_addr_t addr;
    119  1.16    scottr 
    120  1.16    scottr 	addr = (bus_addr_t) (oa->oa_addr ? oa->oa_addr : MAC68K_ASC_BASE);
    121  1.16    scottr 	if (bus_space_map(asc_tag, addr, MAC68K_ASC_LEN, 0,
    122  1.16    scottr 	    &asc_handle)) {
    123  1.16    scottr 		printf("%s: can't map memory space\n", self->dv_xname);
    124  1.16    scottr 		return;
    125  1.16    scottr 	}
    126  1.16    scottr 
    127  1.16    scottr 	printf(" Apple sound chip\n");
    128  1.14    briggs 	asc_configured = 1;
    129   1.1    briggs }
    130   1.1    briggs 
    131   1.7    briggs int
    132  1.11    briggs asc_setbellparams(freq, length, volume)
    133  1.16    scottr 	int freq;
    134  1.16    scottr 	int length;
    135  1.16    scottr 	int volume;
    136  1.16    scottr {
    137  1.16    scottr 	if (!asc_configured)
    138  1.16    scottr 		return (ENODEV);
    139  1.16    scottr 
    140  1.16    scottr 	/*
    141  1.16    scottr 	 * I only perform these checks for sanity.  I suppose
    142  1.16    scottr 	 * someone might want a bell that rings all day, but then
    143  1.16    scottr 	 * they can make kernel mods themselves.
    144  1.16    scottr 	 */
    145   1.1    briggs 
    146   1.7    briggs 	if (freq < 10 || freq > 40000)
    147   1.7    briggs 		return (EINVAL);
    148   1.7    briggs 	if (length < 0 || length > 3600)
    149   1.7    briggs 		return (EINVAL);
    150   1.7    briggs 	if (volume < 0 || volume > 100)
    151   1.7    briggs 		return (EINVAL);
    152   1.1    briggs 
    153   1.1    briggs 	bell_freq = freq;
    154   1.1    briggs 	bell_length = length;
    155   1.1    briggs 	bell_volume = volume;
    156   1.1    briggs 
    157   1.7    briggs 	return (0);
    158   1.1    briggs }
    159   1.1    briggs 
    160   1.1    briggs 
    161   1.7    briggs int
    162  1.11    briggs asc_getbellparams(freq, length, volume)
    163  1.11    briggs     int *freq;
    164  1.11    briggs     int *length;
    165  1.11    briggs     int *volume;
    166   1.1    briggs {
    167  1.16    scottr 	if (!asc_configured)
    168  1.16    scottr 		return (ENODEV);
    169  1.14    briggs 
    170   1.1    briggs 	*freq = bell_freq;
    171   1.1    briggs 	*length = bell_length;
    172   1.1    briggs 	*volume = bell_volume;
    173   1.1    briggs 
    174   1.7    briggs 	return (0);
    175   1.1    briggs }
    176   1.1    briggs 
    177   1.1    briggs 
    178   1.7    briggs void
    179  1.11    briggs asc_bellstop(param)
    180  1.11    briggs     int param;
    181   1.1    briggs {
    182  1.16    scottr 	if (!asc_configured)
    183  1.16    scottr 		return;
    184  1.14    briggs 
    185   1.7    briggs 	if (bell_ringing > 1000 || bell_ringing < 0)
    186  1.16    scottr 		panic("bell got out of sync?");
    187  1.16    scottr 
    188  1.16    scottr 	if (--bell_ringing == 0)	/* disable ASC */
    189  1.16    scottr 		bus_space_write_1(asc_tag, asc_handle, 0x801, 0);
    190   1.1    briggs }
    191   1.1    briggs 
    192   1.1    briggs 
    193   1.7    briggs int
    194   1.7    briggs asc_ringbell()
    195   1.1    briggs {
    196   1.7    briggs 	int     i;
    197   1.1    briggs 	unsigned long freq;
    198  1.14    briggs 
    199  1.16    scottr 	if (!asc_configured)
    200  1.16    scottr 		return (ENODEV);
    201   1.1    briggs 
    202   1.7    briggs 	if (bell_ringing == 0) {
    203  1.16    scottr 
    204   1.7    briggs 		for (i = 0; i < 0x800; i++)
    205  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i, 0);
    206   1.7    briggs 
    207   1.7    briggs 		for (i = 0; i < 256; i++) {
    208  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i, i / 4);
    209  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i + 512, i / 4);
    210  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i + 1024, i / 4);
    211  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i + 1536, i / 4);
    212   1.7    briggs 		}		/* up part of wave, four voices ? */
    213   1.7    briggs 		for (i = 0; i < 256; i++) {
    214  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i + 256,
    215  1.16    scottr 			    0x3f - (i / 4));
    216  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i + 768,
    217  1.16    scottr 			    0x3f - (i / 4));
    218  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i + 1280,
    219  1.16    scottr 			    0x3f - (i / 4));
    220  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, i + 1792,
    221  1.16    scottr 			    0x3f - (i / 4));
    222   1.7    briggs 		}		/* down part of wave, four voices ? */
    223   1.1    briggs 
    224   1.7    briggs 		/* Fix this.  Need to find exact ASC sampling freq */
    225   1.1    briggs 		freq = 65536 * bell_freq / 466;
    226   1.1    briggs 
    227  1.13  christos 		/* printf("beep: from %d, %02x %02x %02x %02x\n",
    228   1.7    briggs 		 * cur_beep.freq, (freq >> 24) & 0xff, (freq >> 16) & 0xff,
    229   1.7    briggs 		 * (freq >> 8) & 0xff, (freq) & 0xff); */
    230   1.7    briggs 		for (i = 0; i < 8; i++) {
    231  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, 0x814 + 8 * i,
    232  1.16    scottr 			    (freq >> 24) & 0xff);
    233  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, 0x815 + 8 * i,
    234  1.16    scottr 			    (freq >> 16) & 0xff);
    235  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, 0x816 + 8 * i,
    236  1.16    scottr 			    (freq >> 8) & 0xff);
    237  1.16    scottr 			bus_space_write_1(asc_tag, asc_handle, 0x817 + 8 * i,
    238  1.16    scottr 			    (freq) & 0xff);
    239   1.7    briggs 		}		/* frequency; should put cur_beep.freq in here
    240   1.7    briggs 				 * somewhere. */
    241   1.7    briggs 
    242  1.16    scottr 		bus_space_write_1(asc_tag, asc_handle, 0x807, 3); /* 44 ? */
    243  1.16    scottr 		bus_space_write_1(asc_tag, asc_handle, 0x806,
    244  1.16    scottr 		    255 * bell_volume / 100);
    245  1.16    scottr 		bus_space_write_1(asc_tag, asc_handle, 0x805, 0);
    246  1.16    scottr 		bus_space_write_1(asc_tag, asc_handle, 0x80f, 0);
    247  1.16    scottr 		bus_space_write_1(asc_tag, asc_handle, 0x802, 2); /* sampled */
    248  1.16    scottr 		bus_space_write_1(asc_tag, asc_handle, 0x801, 2); /* enable sampled */
    249   1.1    briggs 	}
    250   1.1    briggs 	bell_ringing++;
    251   1.3    briggs 	timeout((void *) asc_bellstop, 0, bell_length);
    252  1.11    briggs 
    253  1.16    scottr 	return (0);
    254   1.1    briggs }
    255