/*
 *  linux/sound/oss/dmasound/dmasound_awacs.c
 *
 *  PowerMac `AWACS' and `Burgundy' DMA Sound Driver
 *  with some limited support for DACA & Tumbler
 *
 *  See linux/sound/oss/dmasound/dmasound_core.c for copyright and
 *  history prior to 2001/01/26.
 *
 *	26/01/2001 ed 0.1 Iain Sandoe
 *		- added version info.
 *		- moved dbdma command buffer allocation to PMacXXXSqSetup()
 *		- fixed up beep dbdma cmd buffers
 *
 *	08/02/2001 [0.2]
 *		- make SNDCTL_DSP_GETFMTS return the correct info for the h/w
 *		- move soft format translations to a separate file
 *		- [0.3] make SNDCTL_DSP_GETCAPS return correct info.
 *		- [0.4] more informative machine name strings.
 *		- [0.5]
 *		- record changes.
 *		- made the default_hard/soft entries.
 *	04/04/2001 [0.6]
 *		- minor correction to bit assignments in awacs_defs.h
 *		- incorporate mixer changes from 2.2.x back-port.
 *		- take out passthru as a rec input (it isn't).
 *              - make Input Gain slider work the 'right way up'.
 *              - try to make the mixer sliders more logical - so now the
 *                input selectors are just two-state (>50% == ON) and the
 *                Input Gain slider handles the rest of the gain issues.
 *              - try to pick slider representations that most closely match
 *                the actual use - e.g. IGain for input gain... 
 *              - first stab at over/under-run detection.
 *		- minor cosmetic changes to IRQ identification.
 *		- fix bug where rates > max would be reported as supported.
 *              - first stab at over/under-run detection.
 *              - make use of i2c for mixer settings conditional on perch
 *                rather than cuda (some machines without perch have cuda).
 *              - fix bug where TX stops when dbdma status comes up "DEAD"
 *		  so far only reported on PowerComputing clones ... but.
 *		- put in AWACS/Screamer register write timeouts.
 *		- part way to partitioning the init() stuff
 *		- first pass at 'tumbler' stuff (not support - just an attempt
 *		  to allow the driver to load on new G4s).
 *      01/02/2002 [0.7] - BenH
 *	        - all sort of minor bits went in since the latest update, I
 *	          bumped the version number for that reason
 *
 *      07/26/2002 [0.8] - BenH
 *	        - More minor bits since last changelog (I should be more careful
 *	          with those)
 *	        - Support for snapper & better tumbler integration by Toby Sargeant
 *	        - Headphone detect for scremer by Julien Blache
 *	        - More tumbler fixed by Andreas Schwab
 *	11/29/2003 [0.8.1] - Renzo Davoli (King Enzo)
 *		- Support for Snapper line in
 *		- snapper input resampling (for rates < 44100)
 *		- software line gain control
 */

/* GENERAL FIXME/TODO: check that the assumptions about what is written to
   mac-io is valid for DACA & Tumbler.

   This driver is in bad need of a rewrite. The dbdma code has to be split,
   some proper device-tree parsing code has to be written, etc...
*/

#include <linux/types.h>
#include <linux/module.h>
#include <linux/config.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/soundcard.h>
#include <linux/adb.h>
#include <linux/nvram.h>
#include <linux/tty.h>
#include <linux/vt_kern.h>
#include <linux/spinlock.h>
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <asm/semaphore.h>
#ifdef CONFIG_ADB_CUDA
#include <linux/cuda.h>
#endif
#ifdef CONFIG_ADB_PMU
#include <linux/pmu.h>
#endif

#include <linux/i2c-dev.h>

#include <asm/uaccess.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/dbdma.h>
#include <asm/pmac_feature.h>
#include <asm/irq.h>
#include <asm/nvram.h>

#include "awacs_defs.h"
#include "dmasound.h"
#include "tas3001c.h"
#include "tas3004.h"
#include "tas_common.h"

#define DMASOUND_AWACS_REVISION	0
#define DMASOUND_AWACS_EDITION	7

#define AWACS_SNAPPER   110	/* fake revision # for snapper */
#define AWACS_BURGUNDY	100	/* fake revision # for burgundy */
#define AWACS_TUMBLER    90	/* fake revision # for tumbler */
#define AWACS_DACA	 80	/* fake revision # for daca (ibook) */
#define AWACS_AWACS       2     /* holding revision for AWACS */
#define AWACS_SCREAMER    3     /* holding revision for Screamer */
/*
 * Interrupt numbers and addresses, & info obtained from the device tree.
 */
static int awacs_irq, awacs_tx_irq, awacs_rx_irq;
static volatile struct awacs_regs __iomem *awacs;
static volatile u32 __iomem *i2s;
static volatile struct dbdma_regs __iomem *awacs_txdma, *awacs_rxdma;
static int awacs_rate_index;
static int awacs_subframe;
static struct device_node* awacs_node;
static struct device_node* i2s_node;

static char awacs_name[64];
static int awacs_revision;
static int awacs_sleeping;
static DECLARE_MUTEX(dmasound_sem);

static int sound_device_id;		/* exists after iMac revA */
static int hw_can_byteswap = 1 ;	/* most pmac sound h/w can */

/* model info */
/* To be replaced with better interaction with pmac_feature.c */
static int is_pbook_3X00;
static int is_pbook_g3;

/* expansion info */
static int has_perch;
static int has_ziva;

/* for earlier powerbooks which need fiddling with mac-io to enable
 * cd etc.
*/
static unsigned char __iomem *latch_base;
static unsigned char __iomem *macio_base;

/*
 * Space for the DBDMA command blocks.
 */
static void *awacs_tx_cmd_space;
static volatile struct dbdma_cmd *awacs_tx_cmds;
static int number_of_tx_cmd_buffers;

static void *awacs_rx_cmd_space;
static volatile struct dbdma_cmd *awacs_rx_cmds;
static int number_of_rx_cmd_buffers;

/*
 * Cached values of AWACS registers (we can't read them).
 * Except on the burgundy (and screamer). XXX
 */

int awacs_reg[8];
int awacs_reg1_save;

/* tracking values for the mixer contents
*/

static int spk_vol;
static int line_vol;
static int passthru_vol;

static int ip_gain;           /* mic preamp settings */
static int rec_lev = 0x4545 ; /* default CD gain 69 % */
static int mic_lev;
static int cd_lev = 0x6363 ; /* 99 % */
static int line_lev;

static int hdp_connected;

/*
 * Stuff for outputting a beep.  The values range from -327 to +327
 * so we can multiply by an amplitude in the range 0..100 to get a
 * signed short value to put in the output buffer.
 */
static short beep_wform[256] = {
	0,	40,	79,	117,	153,	187,	218,	245,
	269,	288,	304,	316,	323,	327,	327,	324,
	318,	310,	299,	288,	275,	262,	249,	236,
	224,	213,	204,	196,	190,	186,	183,	182,
	182,	183,	186,	189,	192,	196,	200,	203,
	206,	208,	209,	209,	209,	207,	204,	201,
	197,	193,	188,	183,	179,	174,	170,	166,
	163,	161,	160,	159,	159,	160,	161,	162,
	164,	166,	168,	169,	171,	171,	171,	170,
	169,	167,	163,	159,	155,	150,	144,	139,
	133,	128,	122,	117,	113,	110,	107,	105,
	103,	103,	103,	103,	104,	104,	105,	105,
	105,	103,	101,	97,	92,	86,	78,	68,
	58,	45,	32,	18,	3,	-11,	-26,	-41,
	-55,	-68,	-79,	-88,	-95,	-100,	-102,	-102,
	-99,	-93,	-85,	-75,	-62,	-48,	-33,	-16,
	0,	16,	33,	48,	62,	75,	85,	93,
	99,	102,	102,	100,	95,	88,	79,	68,
	55,	41,	26,	11,	-3,	-18,	-32,	-45,
	-58,	-68,	-78,	-86,	-92,	-97,	-101,	-103,
	-105,	-105,	-105,	-104,	-104,	-103,	-103,	-103,
	-103,	-105,	-107,	-110,	-113,	-117,	-122,	-128,
	-133,	-139,	-144,	-150,	-155,	-159,	-163,	-167,
	-169,	-170,	-171,	-171,	-171,	-169,	-168,	-166,
	-164,	-162,	-161,	-160,	-159,	-159,	-160,	-161,
	-163,	-166,	-170,	-174,	-179,	-183,	-188,	-193,
	-197,	-201,	-204,	-207,	-209,	-209,	-209,	-208,
	-206,	-203,	-200,	-196,	-192,	-189,	-186,	-183,
	-182,	-182,	-183,	-186,	-190,	-196,	-204,	-213,
	-224,	-236,	-249,	-262,	-275,	-288,	-299,	-310,
	-318,	-324,	-327,	-327,	-323,	-316,	-304,	-288,
	-269,	-245,	-218,	-187,	-153,	-117,	-79,	-40,
};

/* beep support */
#define BEEP_SRATE	22050	/* 22050 Hz sample rate */
#define BEEP_BUFLEN	512
#define BEEP_VOLUME	15	/* 0 - 100 */

static int beep_vol = BEEP_VOLUME;
static int beep_playing;
static int awacs_beep_state;
static short *beep_buf;
static void *beep_dbdma_cmd_space;
static volatile struct dbdma_cmd *beep_dbdma_cmd;

/* Burgundy functions */
static void awacs_burgundy_wcw(unsigned addr,unsigned newval);
static unsigned awacs_burgundy_rcw(unsigned addr);
static void awacs_burgundy_write_volume(unsigned address, int volume);
static int awacs_burgundy_read_volume(unsigned address);
static void awacs_burgundy_write_mvolume(unsigned address, int volume);
static int awacs_burgundy_read_mvolume(unsigned address);

/* we will allocate a single 'emergency' dbdma cmd block to use if the
   tx status comes up "DEAD".  This happens on some PowerComputing Pmac
   clones, either owing to a bug in dbdma or some interaction between
   IDE and sound.  However, this measure would deal with DEAD status if
   if appeared elsewhere.

   for the sake of memory efficiency we'll allocate this cmd as part of
   the beep cmd stuff.
*/

static volatile struct dbdma_cmd *emergency_dbdma_cmd;

#ifdef CONFIG_PMAC_PBOOK
/*
 * Stuff for restoring after a sleep.
 */
static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when);
struct pmu_sleep_notifier awacs_sleep_notifier = {
	awacs_sleep_notify, SLEEP_LEVEL_SOUND,
};
#endif /* CONFIG_PMAC_PBOOK */

/* for (soft) sample rate translations */
int expand_bal;		/* Balance factor for expanding (not volume!) */
int expand_read_bal;	/* Balance factor for expanding reads (not volume!) */

/*** Low level stuff *********************************************************/

static void *PMacAlloc(unsigned int size, int flags);
static void PMacFree(void *ptr, unsigned int size);
static int PMacIrqInit(void);
#ifdef MODULE
static void PMacIrqCleanup(void);
#endif
static void PMacSilence(void);
static void PMacInit(void);
static int PMacSetFormat(int format);
static int PMacSetVolume(int volume);
static void PMacPlay(void);
static void PMacRecord(void);
static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs);
static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs);
static irqreturn_t pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs);
static void awacs_write(int val);
static int awacs_get_volume(int reg, int lshift);
static int awacs_volume_setter(int volume, int n, int mute, int lshift);


/*** Mid level stuff **********************************************************/

static int PMacMixerIoctl(u_int cmd, u_long arg);
static int PMacWriteSqSetup(void);
static int PMacReadSqSetup(void);
static void PMacAbortRead(void);

extern TRANS transAwacsNormal ;
extern TRANS transAwacsExpand ;
extern TRANS transAwacsNormalRead ;
extern TRANS transAwacsExpandRead ;

extern int daca_init(void);
extern void daca_cleanup(void);
extern int daca_set_volume(uint left_vol, uint right_vol);
extern void daca_get_volume(uint * left_vol, uint  *right_vol);
extern int daca_enter_sleep(void);
extern int daca_leave_sleep(void);

#define TRY_LOCK()	\
	if ((rc = down_interruptible(&dmasound_sem)) != 0)	\
		return rc;
#define LOCK()		down(&dmasound_sem);

#define UNLOCK()	up(&dmasound_sem);

/* We use different versions that the ones provided in dmasound.h
 * 
 * FIXME: Use different names ;)
 */
#undef IOCTL_IN
#undef IOCTL_OUT

#define IOCTL_IN(arg, ret)	\
	rc = get_user(ret, (int __user *)(arg)); \
	if (rc) break;
#define IOCTL_OUT(arg, ret)	\
	ioctl_return2((int __user *)(arg), ret)

static inline int ioctl_return2(int __user *addr, int value)
{
	return value < 0 ? value : put_user(value, addr);
}


/*** AE - TUMBLER / SNAPPER START ************************************************/


int gpio_audio_reset, gpio_audio_reset_pol;
int gpio_amp_mute, gpio_amp_mute_pol;
int gpio_headphone_mute, gpio_headphone_mute_pol;
int gpio_headphone_detect, gpio_headphone_detect_pol;
int gpio_headphone_irq;

int
setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol)
{
	struct device_node *np;
	u32* pp;
	
	np = find_devices("gpio");
	if (!np)
		return -ENODEV;

	np = np->child;
	while(np != 0) {
		if (name) {
			char *property = get_property(np,"audio-gpio",NULL);
			if (property != 0 && strcmp(property,name) == 0)
				break;
		} else if (compatible && device_is_compatible(np, compatible))
			break;
		np = np->sibling;
	}
	if (!np)
		return -ENODEV;
	pp = (u32 *)get_property(np, "AAPL,address", NULL);
	if (!pp)
		return -ENODEV;
	*gpio_addr = (*pp) & 0x0000ffff;
	pp = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
	if (pp)
		*gpio_pol = *pp;
	else
		*gpio_pol = 1;
	if (np->n_intrs > 0)
		return np->intrs[0].line;
	
	return 0;
}

static inline void
write_audio_gpio(int gpio_addr, int data)
{
	if (!gpio_addr)
		return;
	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_addr, data ? 0x05 : 0x04);
}

static inline int
read_audio_gpio(int gpio_addr)
{
	if (!gpio_addr)
		return 0;
	return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0);
}

/*
 * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
 */
static irqreturn_t
headphone_intr(int irq, void *devid, struct pt_regs *regs)
{
	unsigned long flags;

	spin_lock_irqsave(&dmasound.lock, flags);
	if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
		printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
		write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
		write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
		tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0);
	} else {
		printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n");
		write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
		write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
		tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0);
	}
	spin_unlock_irqrestore(&dmasound.lock, flags);
	return IRQ_HANDLED;
}


/* Initialize tumbler */

static int
tas_dmasound_init(void)
{
	setup_audio_gpio(
		"audio-hw-reset",
		NULL,
		&gpio_audio_reset,
		&gpio_audio_reset_pol);
	setup_audio_gpio(
		"amp-mute",
		NULL,
		&gpio_amp_mute,
		&gpio_amp_mute_pol);
	setup_audio_gpio("headphone-mute",
		NULL,
		&gpio_headphone_mute,
		&gpio_headphone_mute_pol);
	gpio_headphone_irq = setup_audio_gpio(
		"headphone-detect",
		NULL,
		&gpio_headphone_detect,
		&gpio_headphone_detect_pol);
	/* Fix some broken OF entries in desktop machines */
	if (!gpio_headphone_irq)
		gpio_headphone_irq = setup_audio_gpio(
			NULL,
			"keywest-gpio15",
			&gpio_headphone_detect,
			&gpio_headphone_detect_pol);

	write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
	msleep(100);
	write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
	msleep(100);
  	if (gpio_headphone_irq) {
		if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",NULL) < 0) {
    			printk(KERN_ERR "tumbler: Can't request headphone interrupt\n");
    			gpio_headphone_irq = 0;
    		} else {
			u8 val;
			/* Activate headphone status interrupts */
			val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0);
			pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80);
			/* Trigger it */
  			headphone_intr(0,NULL,NULL);
  		}
  	}
  	if (!gpio_headphone_irq) {
  		/* Some machine enter this case ? */
  		printk(KERN_WARNING "tumbler: Headphone detect IRQ not found, enabling all outputs !\n");
  		write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
  		write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
  	}
	return 0;
}


static int
tas_dmasound_cleanup(void)
{
	if (gpio_headphone_irq)
		free_irq(gpio_headphone_irq, NULL);
	return 0;
}

/* We don't support 48k yet */
static int tas_freqs[1] = { 44100 } ;
static int tas_freqs_ok[1] = { 1 } ;

/* don't know what to do really - just have to leave it where
 * OF left things
*/

static int
tas_set_frame_rate(void)
{
	if (i2s) {
		out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
		out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
	}
	dmasound.hard.speed = 44100 ;
	awacs_rate_index = 0 ;
	return 44100 ;
}

static int
tas_mixer_ioctl(u_int cmd, u_long arg)
{
	int __user *argp = (int __user *)arg;
	int data;
	int rc;

        rc=tas_device_ioctl(cmd, arg);
        if (rc != -EINVAL) {
        	return rc;
        }

        if ((cmd & ~0xff) == MIXER_WRITE(0) &&
            tas_supported_mixers() & (1<<(cmd & 0xff))) {
		rc = get_user(data, argp);
                if (rc<0) return rc;
		tas_set_mixer_level(cmd & 0xff, data);
		tas_get_mixer_level(cmd & 0xff, &data);
		return ioctl_return2(argp, data);
        }
        if ((cmd & ~0xff) == MIXER_READ(0) &&
            tas_supported_mixers() & (1<<(cmd & 0xff))) {
		tas_get_mixer_level(cmd & 0xff, &data);
		return ioctl_return2(argp, data);
        }

	switch(cmd) {
	case SOUND_MIXER_READ_DEVMASK:
		data = tas_supported_mixers() | SOUND_MASK_SPEAKER;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_STEREODEVS:
		data = tas_stereo_mixers();
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_CAPS:
		rc = IOCTL_OUT(arg, 0);
		break;
	case SOUND_MIXER_READ_RECMASK:
		// XXX FIXME: find a way to check what is really available */
		data = SOUND_MASK_LINE | SOUND_MASK_MIC;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_RECSRC:
		if (awacs_reg[0] & MASK_MUX_AUDIN)
			data |= SOUND_MASK_LINE;
		if (awacs_reg[0] & MASK_MUX_MIC)
			data |= SOUND_MASK_MIC;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_WRITE_RECSRC:
 		IOCTL_IN(arg, data);
		data =0;
 		rc = IOCTL_OUT(arg, data);
 		break;
	case SOUND_MIXER_WRITE_SPEAKER:	/* really bell volume */
 		IOCTL_IN(arg, data);
 		beep_vol = data & 0xff;
 		/* fall through */
	case SOUND_MIXER_READ_SPEAKER:
		rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol);
 		break;
	case SOUND_MIXER_OUTMASK:
	case SOUND_MIXER_OUTSRC:
	default:
		rc = -EINVAL;
	}

	return rc;
}

static void __init
tas_init_frame_rates(unsigned int *prop, unsigned int l)
{
	int i ;
	if (prop) {
		for (i=0; i<1; i++)
			tas_freqs_ok[i] = 0;
		for (l /= sizeof(int); l > 0; --l) {
			unsigned int r = *prop++;
			/* Apple 'Fixed' format */
			if (r >= 0x10000)
				r >>= 16;
			for (i = 0; i < 1; ++i) {
				if (r == tas_freqs[i]) {
					tas_freqs_ok[i] = 1;
					break;
				}
			}
		}
	}
	/* else we assume that all the rates are available */
}


/*** AE - TUMBLER / SNAPPER END ************************************************/



/*** Low level stuff *********************************************************/

/*
 * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA.
 */
static void *PMacAlloc(unsigned int size, int flags)
{
	return kmalloc(size, flags);
}

static void PMacFree(void *ptr, unsigned int size)
{
	kfree(ptr);
}

static int __init PMacIrqInit(void)
{
	if (awacs)
		if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", NULL))
			return 0;
	if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", NULL)
	    || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", NULL))
		return 0;
	return 1;
}

#ifdef MODULE
static void PMacIrqCleanup(void)
{
	/* turn off input & output dma */
	DBDMA_DO_STOP(awacs_txdma);
	DBDMA_DO_STOP(awacs_rxdma);

	if (awacs)
		/* disable interrupts from awacs interface */
		out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
	
	/* Switch off the sound clock */
	pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
	/* Make sure proper bits are set on pismo & tipb */
	if ((machine_is_compatible("PowerBook3,1") ||
	    machine_is_compatible("PowerBook3,2")) && awacs) {
		awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
		awacs_write(MASK_ADDR1 | awacs_reg[1]);
		msleep(200);
	}
	if (awacs)
		free_irq(awacs_irq, NULL);
	free_irq(awacs_tx_irq, NULL);
	free_irq(awacs_rx_irq, NULL);
	
	if (awacs)
		iounmap(awacs);
	if (i2s)
		iounmap(i2s);
	iounmap(awacs_txdma);
	iounmap(awacs_rxdma);

	release_OF_resource(awacs_node, 0);
	release_OF_resource(awacs_node, 1);
	release_OF_resource(awacs_node, 2);

	if (awacs_tx_cmd_space)
		kfree(awacs_tx_cmd_space);
	if (awacs_rx_cmd_space)
		kfree(awacs_rx_cmd_space);
	if (beep_dbdma_cmd_space)
		kfree(beep_dbdma_cmd_space);
	if (beep_buf)
		kfree(beep_buf);
#ifdef CONFIG_PMAC_PBOOK
	pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
#endif
}
#endif /* MODULE */

static void PMacSilence(void)
{
	/* turn off output dma */
	DBDMA_DO_STOP(awacs_txdma);
}

/* don't know what to do really - just have to leave it where
 * OF left things
*/

static int daca_set_frame_rate(void)
{
	if (i2s) {
		out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
		out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
	}
	dmasound.hard.speed = 44100 ;
	awacs_rate_index = 0 ;
	return 44100 ;
}

static int awacs_freqs[8] = {
	44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
};
static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };

static int
awacs_set_frame_rate(int desired, int catch_r)
{
	int tolerance, i = 8 ;
	/*
	 * If we have a sample rate which is within catchRadius percent
	 * of the requested value, we don't have to expand the samples.
	 * Otherwise choose the next higher rate.
	 * N.B.: burgundy awacs only works at 44100 Hz.
	 */
	do {
		tolerance = catch_r * awacs_freqs[--i] / 100;
		if (awacs_freqs_ok[i]
		    && dmasound.soft.speed <= awacs_freqs[i] + tolerance)
			break;
	} while (i > 0);
	dmasound.hard.speed = awacs_freqs[i];
	awacs_rate_index = i;

	out_le32(&awacs->control, MASK_IEPC | (i << 8) | 0x11 );
	awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) | (i << 3);
	awacs_write(awacs_reg[1] | MASK_ADDR1);
	return dmasound.hard.speed;
}

static int
burgundy_set_frame_rate(void)
{
	awacs_rate_index = 0 ;
	awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ;
	/* XXX disable error interrupt on burgundy for now */
	out_le32(&awacs->control, MASK_IEPC | 0 | 0x11 | MASK_IEE);
	return 44100 ;
}

static int
set_frame_rate(int desired, int catch_r)
{
	switch (awacs_revision) {
		case AWACS_BURGUNDY:
			dmasound.hard.speed = burgundy_set_frame_rate();
			break ;
		case AWACS_TUMBLER:
		case AWACS_SNAPPER:
			dmasound.hard.speed = tas_set_frame_rate();
			break ;
		case AWACS_DACA:
			dmasound.hard.speed =
			  daca_set_frame_rate();
			break ;
		default:
			dmasound.hard.speed = awacs_set_frame_rate(desired,
						catch_r);
			break ;
	}
	return dmasound.hard.speed ;
}

static void
awacs_recalibrate(void)
{
	/* Sorry for the horrible delays... I hope to get that improved
	 * by making the whole PM process asynchronous in a future version
	 */
	msleep(750);
	awacs_reg[1] |= MASK_CMUTE | MASK_AMUTE;
	awacs_write(awacs_reg[1] | MASK_RECALIBRATE | MASK_ADDR1);
	msleep(1000);
	awacs_write(awacs_reg[1] | MASK_ADDR1);
}

static void PMacInit(void)
{
	int tolerance;

	switch (dmasound.soft.format) {
	    case AFMT_S16_LE:
	    case AFMT_U16_LE:
		if (hw_can_byteswap)
			dmasound.hard.format = AFMT_S16_LE;
		else
			dmasound.hard.format = AFMT_S16_BE;
		break;
	default:
		dmasound.hard.format = AFMT_S16_BE;
		break;
	}
	dmasound.hard.stereo = 1;
	dmasound.hard.size = 16;

	/* set dmasound.hard.speed - on the basis of what we want (soft)
	 * and the tolerance we'll allow.
	*/
	set_frame_rate(dmasound.soft.speed, catchRadius) ;

	tolerance = (catchRadius * dmasound.hard.speed) / 100;
	if (dmasound.soft.speed >= dmasound.hard.speed - tolerance) {
		dmasound.trans_write = &transAwacsNormal;
		dmasound.trans_read = &transAwacsNormalRead;
	} else {
		dmasound.trans_write = &transAwacsExpand;
		dmasound.trans_read = &transAwacsExpandRead;
	}

	if (awacs) {
		if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
			out_le32(&awacs->byteswap, BS_VAL);
		else
			out_le32(&awacs->byteswap, 0);
	}
	
	expand_bal = -dmasound.soft.speed;
	expand_read_bal = -dmasound.soft.speed;
}

static int PMacSetFormat(int format)
{
	int size;
	int req_format = format;
		
	switch (format) {
	case AFMT_QUERY:
		return dmasound.soft.format;
	case AFMT_MU_LAW:
	case AFMT_A_LAW:
	case AFMT_U8:
	case AFMT_S8:
		size = 8;
		break;
	case AFMT_S16_LE:
		if(!hw_can_byteswap)
			format = AFMT_S16_BE;
	case AFMT_S16_BE:
		size = 16;
		break;
	case AFMT_U16_LE:
		if(!hw_can_byteswap)
			format = AFMT_U16_BE;
	case AFMT_U16_BE:
		size = 16;
		break;
	default: /* :-) */
		printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n",
		       format);
		size = 8;
		format = AFMT_U8;
	}
	
	if (req_format == format) {
		dmasound.soft.format = format;
		dmasound.soft.size = size;
		if (dmasound.minDev == SND_DEV_DSP) {
			dmasound.dsp.format = format;
			dmasound.dsp.size = size;
		}
	}

	return format;
}

#define AWACS_VOLUME_TO_MASK(x)	(15 - ((((x) - 1) * 15) / 99))
#define AWACS_MASK_TO_VOLUME(y)	(100 - ((y) * 99 / 15))

static int awacs_get_volume(int reg, int lshift)
{
	int volume;

	volume = AWACS_MASK_TO_VOLUME((reg >> lshift) & 0xf);
	volume |= AWACS_MASK_TO_VOLUME(reg & 0xf) << 8;
	return volume;
}

static int awacs_volume_setter(int volume, int n, int mute, int lshift)
{
	int r1, rn;

	if (mute && volume == 0) {
		r1 = awacs_reg[1] | mute;
	} else {
		r1 = awacs_reg[1] & ~mute;
		rn = awacs_reg[n] & ~(0xf | (0xf << lshift));
		rn |= ((AWACS_VOLUME_TO_MASK(volume & 0xff) & 0xf) << lshift);
		rn |= AWACS_VOLUME_TO_MASK((volume >> 8) & 0xff) & 0xf;
		awacs_reg[n] = rn;
		awacs_write((n << 12) | rn);
		volume = awacs_get_volume(rn, lshift);
	}
	if (r1 != awacs_reg[1]) {
		awacs_reg[1] = r1;
		awacs_write(r1 | MASK_ADDR1);
	}
	return volume;
}

static int PMacSetVolume(int volume)
{
	printk(KERN_WARNING "Bogus call to PMacSetVolume !\n");
	return 0;
}

static void awacs_setup_for_beep(int speed)
{
	out_le32(&awacs->control,
		 (in_le32(&awacs->control) & ~0x1f00)
		 | ((speed > 0 ? speed : awacs_rate_index) << 8));

	if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1)
		out_le32(&awacs->byteswap, BS_VAL);
	else
		out_le32(&awacs->byteswap, 0);
}

/* CHECK: how much of this *really* needs IRQs masked? */
static void __PMacPlay(void)
{
	volatile struct dbdma_cmd *cp;
	int next_frg, count;

	count = 300 ; /* > two cycles at the lowest sample rate */

	/* what we want to send next */
	next_frg = (write_sq.front + write_sq.active) % write_sq.max_count;

	if (awacs_beep_state) {
		/* sound takes precedence over beeps */
		/* stop the dma channel */
		out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
		while ( (in_le32(&awacs_txdma->status) & RUN) && count--)
			udelay(1);
		if (awacs)
			awacs_setup_for_beep(-1);
		out_le32(&awacs_txdma->cmdptr,
			 virt_to_bus(&(awacs_tx_cmds[next_frg])));

		beep_playing = 0;
		awacs_beep_state = 0;
	}
	/* this won't allow more than two frags to be in the output queue at
	   once. (or one, if the max frags is 2 - because count can't exceed
	   2 in that case)
	*/
	while (write_sq.active < 2 && write_sq.active < write_sq.count) {
		count = (write_sq.count == write_sq.active + 1) ?
				write_sq.rear_size:write_sq.block_size ;
		if (count < write_sq.block_size) {
			if (!write_sq.syncing) /* last block not yet filled,*/
				break; 	/* and we're not syncing or POST-ed */
			else {
				/* pretend the block is full to force a new
				   block to be started on the next write */
				write_sq.rear_size = write_sq.block_size ;
				write_sq.syncing &= ~2 ; /* clear POST */
			}
		}
		cp = &awacs_tx_cmds[next_frg];
		st_le16(&cp->req_count, count);
		st_le16(&cp->xfer_status, 0);
		st_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS);
		/* put a STOP at the end of the queue - but only if we have
		   space for it.  This means that, if we under-run and we only
		   have two fragments, we might re-play sound from an existing
		   queued frag.  I guess the solution to that is not to set two
		   frags if you are likely to under-run...
		*/
		if (write_sq.count < write_sq.max_count) {
			if (++next_frg >= write_sq.max_count)
				next_frg = 0 ; /* wrap */
			/* if we get here then we've underrun so we will stop*/
			st_le16(&awacs_tx_cmds[next_frg].command, DBDMA_STOP);
		}
		/* set the dbdma controller going, if it is not already */
		if (write_sq.active == 0)
			out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
		(void)in_le32(&awacs_txdma->status);
		out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
		++write_sq.active;
	}
}

static void PMacPlay(void)
{
	LOCK();
	if (!awacs_sleeping) {
		unsigned long flags;

		spin_lock_irqsave(&dmasound.lock, flags);
		__PMacPlay();
		spin_unlock_irqrestore(&dmasound.lock, flags);
	}
	UNLOCK();
}

static void PMacRecord(void)
{
	unsigned long flags;

	if (read_sq.active)
		return;

	spin_lock_irqsave(&dmasound.lock, flags);

	/* This is all we have to do......Just start it up.
	*/
	out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
	read_sq.active = 1;

	spin_unlock_irqrestore(&dmasound.lock, flags);
}

/* if the TX status comes up "DEAD" - reported on some Power Computing machines
   we need to re-start the dbdma - but from a different physical start address
   and with a different transfer length.  It would get very messy to do this
   with the normal dbdma_cmd blocks - we would have to re-write the buffer start
   addresses each time.  So, we will keep a single dbdma_cmd block which can be
   fiddled with.
   When DEAD status is first reported the content of the faulted dbdma block is
   copied into the emergency buffer and we note that the buffer is in use.
   we then bump the start physical address by the amount that was successfully
   output before it died.
   On any subsequent DEAD result we just do the bump-ups (we know that we are
   already using the emergency dbdma_cmd).
   CHECK: this just tries to "do it".  It is possible that we should abandon
   xfers when the number of residual bytes gets below a certain value - I can
   see that this might cause a loop-forever if too small a transfer causes
   DEAD status.  However this is a TODO for now - we'll see what gets reported.
   When we get a successful transfer result with the emergency buffer we just
   pretend that it completed using the original dmdma_cmd and carry on.  The
   'next_cmd' field will already point back to the original loop of blocks.
*/

static irqreturn_t
pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs)
{
	int i = write_sq.front;
	int stat;
	int i_nowrap = write_sq.front;
	volatile struct dbdma_cmd *cp;
	/* != 0 when we are dealing with a DEAD xfer */
	static int emergency_in_use;

	spin_lock(&dmasound.lock);
	while (write_sq.active > 0) { /* we expect to have done something*/
		if (emergency_in_use) /* we are dealing with DEAD xfer */
			cp = emergency_dbdma_cmd ;
		else
			cp = &awacs_tx_cmds[i];
		stat = ld_le16(&cp->xfer_status);
		if (stat & DEAD) {
			unsigned short req, res ;
			unsigned int phy ;
#ifdef DEBUG_DMASOUND
printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ;
#endif
			/* to clear DEAD status we must first clear RUN
			   set it to quiescent to be on the safe side */
			(void)in_le32(&awacs_txdma->status);
			out_le32(&awacs_txdma->control,
				(RUN|PAUSE|FLUSH|WAKE) << 16);
			write_sq.died++ ;
			if (!emergency_in_use) { /* new problem */
				memcpy((void *)emergency_dbdma_cmd, (void *)cp,
					sizeof(struct dbdma_cmd));
				emergency_in_use = 1;
				cp = emergency_dbdma_cmd;
			}
			/* now bump the values to reflect the amount
			   we haven't yet shifted */
			req = ld_le16(&cp->req_count);
			res = ld_le16(&cp->res_count);
			phy = ld_le32(&cp->phy_addr);
			phy += (req - res);
			st_le16(&cp->req_count, res);
			st_le16(&cp->res_count, 0);
			st_le16(&cp->xfer_status, 0);
			st_le32(&cp->phy_addr, phy);
			st_le32(&cp->cmd_dep, virt_to_bus(&awacs_tx_cmds[(i+1)%write_sq.max_count]));
			st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS);
			
			/* point at our patched up command block */
			out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
			/* we must re-start the controller */
			(void)in_le32(&awacs_txdma->status);
			/* should complete clearing the DEAD status */
			out_le32(&awacs_txdma->control,
				((RUN|WAKE) << 16) + (RUN|WAKE));
			break; /* this block is still going */
		}
		if ((stat & ACTIVE) == 0)
			break;	/* this frame is still going */
		if (emergency_in_use)
			emergency_in_use = 0 ; /* done that */
		--write_sq.count;
		--write_sq.active;
		i_nowrap++;
		if (++i >= write_sq.max_count)
			i = 0;
	}

	/* if we stopped and we were not sync-ing - then we under-ran */
	if( write_sq.syncing == 0 ){
		stat = in_le32(&awacs_txdma->status) ;
		/* we hit the dbdma_stop */
		if( (stat & ACTIVE) == 0 ) write_sq.xruns++ ;
	}

	/* if we used some data up then wake the writer to supply some more*/
	if (i_nowrap != write_sq.front)
		WAKE_UP(write_sq.action_queue);
	write_sq.front = i;

	/* but make sure we funnel what we've already got */\
	 if (!awacs_sleeping)
		__PMacPlay();

	/* make the wake-on-empty conditional on syncing */
	if (!write_sq.active && (write_sq.syncing & 1))
		WAKE_UP(write_sq.sync_queue); /* any time we're empty */
	spin_unlock(&dmasound.lock);
	return IRQ_HANDLED;
}


static irqreturn_t
pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs)
{
	int stat ;
	/* For some reason on my PowerBook G3, I get one interrupt
	 * when the interrupt vector is installed (like something is
	 * pending).  This happens before the dbdma is initialized by
	 * us, so I just check the command pointer and if it is zero,
	 * just blow it off.
	 */
	if (in_le32(&awacs_rxdma->cmdptr) == 0)
		return IRQ_HANDLED;

	/* We also want to blow 'em off when shutting down.
	*/
	if (read_sq.active == 0)
		return IRQ_HANDLED;

	spin_lock(&dmasound.lock);
	/* Check multiple buffers in case we were held off from
	 * interrupt processing for a long time.  Geeze, I really hope
	 * this doesn't happen.
	 */
	while ((stat=awacs_rx_cmds[read_sq.rear].xfer_status)) {

		/* if we got a "DEAD" status then just log it for now.
		   and try to restart dma.
		   TODO: figure out how best to fix it up
		*/
		if (stat & DEAD){
#ifdef DEBUG_DMASOUND
printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n");
#endif
			/* to clear DEAD status we must first clear RUN
			   set it to quiescent to be on the safe side */
			(void)in_le32(&awacs_txdma->status);
			out_le32(&awacs_txdma->control,
				(RUN|PAUSE|FLUSH|WAKE) << 16);
			awacs_rx_cmds[read_sq.rear].xfer_status = 0;
			awacs_rx_cmds[read_sq.rear].res_count = 0;
			read_sq.died++ ;
			(void)in_le32(&awacs_txdma->status);
			/* re-start the same block */
			out_le32(&awacs_rxdma->cmdptr,
				virt_to_bus(&awacs_rx_cmds[read_sq.rear]));
			/* we must re-start the controller */
			(void)in_le32(&awacs_rxdma->status);
			/* should complete clearing the DEAD status */
			out_le32(&awacs_rxdma->control,
				((RUN|WAKE) << 16) + (RUN|WAKE));
			spin_unlock(&dmasound.lock);
			return IRQ_HANDLED; /* try this block again */
		}
		/* Clear status and move on to next buffer.
		*/
		awacs_rx_cmds[read_sq.rear].xfer_status = 0;
		read_sq.rear++;

		/* Wrap the buffer ring.
		*/
		if (read_sq.rear >= read_sq.max_active)
			read_sq.rear = 0;

		/* If we have caught up to the front buffer, bump it.
		 * This will cause weird (but not fatal) results if the
		 * read loop is currently using this buffer.  The user is
		 * behind in this case anyway, so weird things are going
		 * to happen.
		 */
		if (read_sq.rear == read_sq.front) {
			read_sq.front++;
			read_sq.xruns++ ; /* we overan */
			if (read_sq.front >= read_sq.max_active)
				read_sq.front = 0;
		}
	}

	WAKE_UP(read_sq.action_queue);
	spin_unlock(&dmasound.lock);
	return IRQ_HANDLED;
}


static irqreturn_t
pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs)
{
	int ctrl;
	int status;
	int r1;

	spin_lock(&dmasound.lock);
	ctrl = in_le32(&awacs->control);
	status = in_le32(&awacs->codec_stat);

	if (ctrl & MASK_PORTCHG) {
		/* tested on Screamer, should work on others too */
		if (awacs_revision == AWACS_SCREAMER) {
			if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) {
				hdp_connected = 1;
				
				r1 = awacs_reg[1] | MASK_SPKMUTE;
				awacs_reg[1] = r1;
				awacs_write(r1 | MASK_ADDR_MUTE);
			} else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) {
				hdp_connected = 0;
				
				r1 = awacs_reg[1] & ~MASK_SPKMUTE;
				awacs_reg[1] = r1;
				awacs_write(r1 | MASK_ADDR_MUTE);
			}
		}
	}
	if (ctrl & MASK_CNTLERR) {
		int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16;
		/* CHECK: we just swallow burgundy errors at the moment..*/
		if (err != 0 && awacs_revision != AWACS_BURGUNDY)
			printk(KERN_ERR "dmasound_pmac: error %x\n", err);
	}
	/* Writing 1s to the CNTLERR and PORTCHG bits clears them... */
	out_le32(&awacs->control, ctrl);
	spin_unlock(&dmasound.lock);
	return IRQ_HANDLED;
}

static void
awacs_write(int val)
{
	int count = 300 ;
	if (awacs_revision >= AWACS_DACA || !awacs)
		return ;

	while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
		udelay(1) ;	/* timeout is > 2 samples at lowest rate */
	out_le32(&awacs->codec_ctrl, val | (awacs_subframe << 22));
	(void)in_le32(&awacs->byteswap);
}

/* this is called when the beep timer expires... it will be called even
   if the beep has been overidden by other sound output.
*/
static void awacs_nosound(unsigned long xx)
{
	unsigned long flags;
	int count = 600 ; /* > four samples at lowest rate */

	spin_lock_irqsave(&dmasound.lock, flags);
	if (beep_playing) {
		st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
		out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
		while ((in_le32(&awacs_txdma->status) & RUN) && count--)
			udelay(1);
		if (awacs)
			awacs_setup_for_beep(-1);
		beep_playing = 0;
	}
	spin_unlock_irqrestore(&dmasound.lock, flags);
}

/*
 * We generate the beep with a single dbdma command that loops a buffer
 * forever - without generating interrupts.
 *
 * So, to stop it you have to stop dma output as per awacs_nosound.
 */
static int awacs_beep_event(struct input_dev *dev, unsigned int type,
		unsigned int code, int hz)
{
	unsigned long flags;
	int beep_speed = 0;
	int srate;
	int period, ncycles, nsamples;
	int i, j, f;
	short *p;
	static int beep_hz_cache;
	static int beep_nsamples_cache;
	static int beep_volume_cache;

	if (type != EV_SND)
		return -1;
	switch (code) {
	case SND_BELL:
		if (hz)
			hz = 1000;
		break;
	case SND_TONE:
		break;
	default:
		return -1;
	}

	if (beep_buf == NULL)
		return -1;

	/* quick-hack fix for DACA, Burgundy & Tumbler */

	if (awacs_revision >= AWACS_DACA){
		srate = 44100 ;
	} else {
		for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i)
			if (awacs_freqs_ok[i])
				beep_speed = i;
		srate = awacs_freqs[beep_speed];
	}

	if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
		/* cancel beep currently playing */
		awacs_nosound(0);
		return 0;
	}

	spin_lock_irqsave(&dmasound.lock, flags);
	if (beep_playing || write_sq.active || beep_buf == NULL) {
		spin_unlock_irqrestore(&dmasound.lock, flags);
		return -1;		/* too hard, sorry :-( */
	}
	beep_playing = 1;
	st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
	spin_unlock_irqrestore(&dmasound.lock, flags);

	if (hz == beep_hz_cache && beep_vol == beep_volume_cache) {
		nsamples = beep_nsamples_cache;
	} else {
		period = srate * 256 / hz;	/* fixed point */
		ncycles = BEEP_BUFLEN * 256 / period;
		nsamples = (period * ncycles) >> 8;
		f = ncycles * 65536 / nsamples;
		j = 0;
		p = beep_buf;
		for (i = 0; i < nsamples; ++i, p += 2) {
			p[0] = p[1] = beep_wform[j >> 8] * beep_vol;
			j = (j + f) & 0xffff;
		}
		beep_hz_cache = hz;
		beep_volume_cache = beep_vol;
		beep_nsamples_cache = nsamples;
	}

	st_le16(&beep_dbdma_cmd->req_count, nsamples*4);
	st_le16(&beep_dbdma_cmd->xfer_status, 0);
	st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd));
	st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
	awacs_beep_state = 1;

	spin_lock_irqsave(&dmasound.lock, flags);
	if (beep_playing) {	/* i.e. haven't been terminated already */
		int count = 300 ;
		out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
		while ((in_le32(&awacs_txdma->status) & RUN) && count--)
			udelay(1); /* timeout > 2 samples at lowest rate*/
		if (awacs)
			awacs_setup_for_beep(beep_speed);
		out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
		(void)in_le32(&awacs_txdma->status);
		out_le32(&awacs_txdma->control, RUN | (RUN << 16));
	}
	spin_unlock_irqrestore(&dmasound.lock, flags);

	return 0;
}

/* used in init and for wake-up */

static void
load_awacs(void)
{
	awacs_write(awacs_reg[0] + MASK_ADDR0);
	awacs_write(awacs_reg[1] + MASK_ADDR1);
	awacs_write(awacs_reg[2] + MASK_ADDR2);
	awacs_write(awacs_reg[4] + MASK_ADDR4);

	if (awacs_revision == AWACS_SCREAMER) {
		awacs_write(awacs_reg[5] + MASK_ADDR5);
		msleep(100);
		awacs_write(awacs_reg[6] + MASK_ADDR6);
		msleep(2);
		awacs_write(awacs_reg[1] + MASK_ADDR1);
		awacs_write(awacs_reg[7] + MASK_ADDR7);
	}
	if (awacs) {
		if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
			out_le32(&awacs->byteswap, BS_VAL);
		else
			out_le32(&awacs->byteswap, 0);
	}
}

#ifdef CONFIG_PMAC_PBOOK
/*
 * Save state when going to sleep, restore it afterwards.
 */
/* FIXME: sort out disabling/re-enabling of read stuff as well */
static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
	unsigned long flags;

	switch (when) {
	case PBOOK_SLEEP_NOW:		
		LOCK();
		awacs_sleeping = 1;
		/* Tell the rest of the driver we are now going to sleep */
		mb();
		if (awacs_revision == AWACS_SCREAMER ||
		    awacs_revision == AWACS_AWACS) {
			awacs_reg1_save = awacs_reg[1];
			awacs_reg[1] |= MASK_AMUTE | MASK_CMUTE;
			awacs_write(MASK_ADDR1 | awacs_reg[1]);
		}

		PMacSilence();
		/* stop rx - if going - a bit of a daft user... but */
		out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16));
		/* deny interrupts */
		if (awacs)
			disable_irq(awacs_irq);
		disable_irq(awacs_tx_irq);
		disable_irq(awacs_rx_irq);
		/* Chip specific sleep code */
		switch (awacs_revision) {
			case AWACS_TUMBLER:
			case AWACS_SNAPPER:
				write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
				write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
				tas_enter_sleep();
				write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
				break ;
			case AWACS_DACA:
				daca_enter_sleep();
				break ;
			case AWACS_BURGUNDY:
				break ;
			case AWACS_SCREAMER:
			case AWACS_AWACS:
			default:
				out_le32(&awacs->control, 0x11) ;
				break ;
		}
		/* Disable sound clock */
		pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
		/* According to Darwin, we do that after turning off the sound
		 * chip clock. All this will have to be cleaned up once we properly
		 * parse the OF sound-objects
		 */
		if ((machine_is_compatible("PowerBook3,1") ||
		    machine_is_compatible("PowerBook3,2")) && awacs) {
			awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
			awacs_write(MASK_ADDR1 | awacs_reg[1]);
			msleep(200);
		}
		break;
	case PBOOK_WAKE:
		/* Enable sound clock */
		pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1);
		if ((machine_is_compatible("PowerBook3,1") ||
		    machine_is_compatible("PowerBook3,2")) && awacs) {
			msleep(100);
			awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1);
			awacs_write(MASK_ADDR1 | awacs_reg[1]);
			msleep(300);
		} else
			msleep(1000);
 		/* restore settings */
		switch (awacs_revision) {
			case AWACS_TUMBLER:
			case AWACS_SNAPPER:
				write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
				write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
				write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
				msleep(100);
				write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
				msleep(150);
				tas_leave_sleep(); /* Stub for now */
				headphone_intr(0,NULL,NULL);
				break;
			case AWACS_DACA:
				msleep(10); /* Check this !!! */
				daca_leave_sleep();
				break ;		/* dont know how yet */
			case AWACS_BURGUNDY:
				break ;
			case AWACS_SCREAMER:
			case AWACS_AWACS:
			default:
		 		load_awacs() ;
				break ;
		}
		/* Recalibrate chip */
		if (awacs_revision == AWACS_SCREAMER && awacs)
			awacs_recalibrate();
		/* Make sure dma is stopped */
		PMacSilence();
		if (awacs)
			enable_irq(awacs_irq);
		enable_irq(awacs_tx_irq);
 		enable_irq(awacs_rx_irq);
 		if (awacs) {
 			/* OK, allow ints back again */
	 		out_le32(&awacs->control, MASK_IEPC
 			 	| (awacs_rate_index << 8) | 0x11
 				 | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
 		}
 		if (macio_base && is_pbook_g3) {
			/* FIXME: should restore the setup we had...*/
			out_8(macio_base + 0x37, 3);
 		} else if (is_pbook_3X00) {
			in_8(latch_base + 0x190);
		}
		/* Remove mute */
		if (awacs_revision == AWACS_SCREAMER ||
		    awacs_revision == AWACS_AWACS) {
			awacs_reg[1] = awacs_reg1_save;
			awacs_write(MASK_ADDR1 | awacs_reg[1]);
		}
 		awacs_sleeping = 0;
		/* Resume pending sounds. */
		/* we don't try to restart input... */
		spin_lock_irqsave(&dmasound.lock, flags);
		__PMacPlay();
		spin_unlock_irqrestore(&dmasound.lock, flags);
		UNLOCK();
	}
	return PBOOK_SLEEP_OK;
}
#endif /* CONFIG_PMAC_PBOOK */


/* All the burgundy functions: */

/* Waits for busy flag to clear */
inline static void
awacs_burgundy_busy_wait(void)
{
	int count = 50; /* > 2 samples at 44k1 */
	while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
		udelay(1) ;
}

inline static void
awacs_burgundy_extend_wait(void)
{
	int count = 50 ; /* > 2 samples at 44k1 */
	while ((!(in_le32(&awacs->codec_stat) & MASK_EXTEND)) && count--)
		udelay(1) ;
	count = 50;
	while ((in_le32(&awacs->codec_stat) & MASK_EXTEND) && count--)
		udelay(1);
}

static void
awacs_burgundy_wcw(unsigned addr, unsigned val)
{
	out_le32(&awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff));
	awacs_burgundy_busy_wait();
	out_le32(&awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff));
	awacs_burgundy_busy_wait();
	out_le32(&awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff));
	awacs_burgundy_busy_wait();
	out_le32(&awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff));
	awacs_burgundy_busy_wait();
}

static unsigned
awacs_burgundy_rcw(unsigned addr)
{
	unsigned val = 0;
	unsigned long flags;

	/* should have timeouts here */
	spin_lock_irqsave(&dmasound.lock, flags);

	out_le32(&awacs->codec_ctrl, addr + 0x100000);
	awacs_burgundy_busy_wait();
	awacs_burgundy_extend_wait();
	val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;

	out_le32(&awacs->codec_ctrl, addr + 0x100100);
	awacs_burgundy_busy_wait();
	awacs_burgundy_extend_wait();
	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<8;

	out_le32(&awacs->codec_ctrl, addr + 0x100200);
	awacs_burgundy_busy_wait();
	awacs_burgundy_extend_wait();
	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<16;

	out_le32(&awacs->codec_ctrl, addr + 0x100300);
	awacs_burgundy_busy_wait();
	awacs_burgundy_extend_wait();
	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24;

	spin_unlock_irqrestore(&dmasound.lock, flags);

	return val;
}


static void
awacs_burgundy_wcb(unsigned addr, unsigned val)
{
	out_le32(&awacs->codec_ctrl, addr + 0x300000 + (val & 0xff));
	awacs_burgundy_busy_wait();
}

static unsigned
awacs_burgundy_rcb(unsigned addr)
{
	unsigned val = 0;
	unsigned long flags;

	/* should have timeouts here */
	spin_lock_irqsave(&dmasound.lock, flags);

	out_le32(&awacs->codec_ctrl, addr + 0x100000);
	awacs_burgundy_busy_wait();
	awacs_burgundy_extend_wait();
	val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;

	spin_unlock_irqrestore(&dmasound.lock, flags);

	return val;
}

static int
awacs_burgundy_check(void)
{
	/* Checks to see the chip is alive and kicking */
	int error = in_le32(&awacs->codec_ctrl) & MASK_ERRCODE;

	return error == 0xf0000;
}

static int
awacs_burgundy_init(void)
{
	if (awacs_burgundy_check()) {
		printk(KERN_WARNING "dmasound_pmac: burgundy not working :-(\n");
		return 1;
	}

	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_OUTPUTENABLES,
			   DEF_BURGUNDY_OUTPUTENABLES);
	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
			   DEF_BURGUNDY_MORE_OUTPUTENABLES);
	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_OUTPUTSELECTS,
			   DEF_BURGUNDY_OUTPUTSELECTS);

	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL21,
			   DEF_BURGUNDY_INPSEL21);
	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL3,
			   DEF_BURGUNDY_INPSEL3);
	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINCD,
			   DEF_BURGUNDY_GAINCD);
	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINLINE,
			   DEF_BURGUNDY_GAINLINE);
	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMIC,
			   DEF_BURGUNDY_GAINMIC);
	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMODEM,
			   DEF_BURGUNDY_GAINMODEM);

	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER,
			   DEF_BURGUNDY_ATTENSPEAKER);
	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENLINEOUT,
			   DEF_BURGUNDY_ATTENLINEOUT);
	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENHP,
			   DEF_BURGUNDY_ATTENHP);

	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_MASTER_VOLUME,
			   DEF_BURGUNDY_MASTER_VOLUME);
	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLCD,
			   DEF_BURGUNDY_VOLCD);
	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLLINE,
			   DEF_BURGUNDY_VOLLINE);
	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLMIC,
			   DEF_BURGUNDY_VOLMIC);
	return 0;
}

static void
awacs_burgundy_write_volume(unsigned address, int volume)
{
	int hardvolume,lvolume,rvolume;

	lvolume = (volume & 0xff) ? (volume & 0xff) + 155 : 0;
	rvolume = ((volume >>8)&0xff) ? ((volume >> 8)&0xff ) + 155 : 0;

	hardvolume = lvolume + (rvolume << 16);

	awacs_burgundy_wcw(address, hardvolume);
}

static int
awacs_burgundy_read_volume(unsigned address)
{
	int softvolume,wvolume;

	wvolume = awacs_burgundy_rcw(address);

	softvolume = (wvolume & 0xff) - 155;
	softvolume += (((wvolume >> 16) & 0xff) - 155)<<8;

	return softvolume > 0 ? softvolume : 0;
}

static int
awacs_burgundy_read_mvolume(unsigned address)
{
	int lvolume,rvolume,wvolume;

	wvolume = awacs_burgundy_rcw(address);

	wvolume &= 0xffff;

	rvolume = (wvolume & 0xff) - 155;
	lvolume = ((wvolume & 0xff00)>>8) - 155;

	return lvolume + (rvolume << 8);
}

static void
awacs_burgundy_write_mvolume(unsigned address, int volume)
{
	int lvolume,rvolume,hardvolume;

	lvolume = (volume &0xff) ? (volume & 0xff) + 155 :0;
	rvolume = ((volume >>8) & 0xff) ? (volume >> 8) + 155 :0;

	hardvolume = lvolume + (rvolume << 8);
	hardvolume += (hardvolume << 16);

	awacs_burgundy_wcw(address, hardvolume);
}

/* End burgundy functions */

/* Set up output volumes on machines with the 'perch/whisper' extension card.
 * this has an SGS i2c chip (7433) which is accessed using the cuda.
 *
 * TODO: split this out and make use of the other parts of the SGS chip to
 * do Bass, Treble etc.
 */

static void
awacs_enable_amp(int spkr_vol)
{
#ifdef CONFIG_ADB_CUDA
	struct adb_request req;

	if (sys_ctrler != SYS_CTRLER_CUDA)
		return;

	/* turn on headphones */
	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
		     0x8a, 4, 0);
	while (!req.complete) cuda_poll();
	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
		     0x8a, 6, 0);
	while (!req.complete) cuda_poll();

	/* turn on speaker */
	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
		     0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100);
	while (!req.complete) cuda_poll();
	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
		     0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100);
	while (!req.complete) cuda_poll();

	cuda_request(&req, NULL, 5, CUDA_PACKET,
		     CUDA_GET_SET_IIC, 0x8a, 1, 0x29);
	while (!req.complete) cuda_poll();
#endif /* CONFIG_ADB_CUDA */
}


/*** Mid level stuff *********************************************************/


/*
 * /dev/mixer abstraction
 */

static void do_line_lev(int data)
{
		line_lev = data ;
		awacs_reg[0] &= ~MASK_MUX_AUDIN;
		if ((data & 0xff) >= 50)
			awacs_reg[0] |= MASK_MUX_AUDIN;
		awacs_write(MASK_ADDR0 | awacs_reg[0]);
}

static void do_ip_gain(int data)
{
	ip_gain = data ;
	data &= 0xff;
	awacs_reg[0] &= ~MASK_GAINLINE;
	if (awacs_revision == AWACS_SCREAMER) {
		awacs_reg[6] &= ~MASK_MIC_BOOST ;
		if (data >= 33) {
			awacs_reg[0] |= MASK_GAINLINE;
			if( data >= 66)
				awacs_reg[6] |= MASK_MIC_BOOST ;
		}
		awacs_write(MASK_ADDR6 | awacs_reg[6]) ;
	} else {
		if (data >= 50)
			awacs_reg[0] |= MASK_GAINLINE;
	}
	awacs_write(MASK_ADDR0 | awacs_reg[0]);
}

static void do_mic_lev(int data)
{
	mic_lev = data ;
	data &= 0xff;
	awacs_reg[0] &= ~MASK_MUX_MIC;
	if (data >= 50)
		awacs_reg[0] |= MASK_MUX_MIC;
	awacs_write(MASK_ADDR0 | awacs_reg[0]);
}

static void do_cd_lev(int data)
{
	cd_lev = data ;
	awacs_reg[0] &= ~MASK_MUX_CD;
	if ((data & 0xff) >= 50)
		awacs_reg[0] |= MASK_MUX_CD;
	awacs_write(MASK_ADDR0 | awacs_reg[0]);
}

static void do_rec_lev(int data)
{
	int left, right ;
	rec_lev = data ;
	/* need to fudge this to use the volume setter routine */
	left = 100 - (data & 0xff) ; if( left < 0 ) left = 0 ;
	right = 100 - ((data >> 8) & 0xff) ; if( right < 0 ) right = 0 ;
	left |= (right << 8 );
	left = awacs_volume_setter(left, 0, 0, 4);
}

static void do_passthru_vol(int data)
{
	passthru_vol = data ;
	awacs_reg[1] &= ~MASK_LOOPTHRU;
	if (awacs_revision == AWACS_SCREAMER) {
		if( data ) { /* switch it on for non-zero */
			awacs_reg[1] |= MASK_LOOPTHRU;
			awacs_write(MASK_ADDR1 | awacs_reg[1]);
		}
		data = awacs_volume_setter(data, 5, 0, 6) ;
	} else {
		if ((data & 0xff) >= 50)
			awacs_reg[1] |= MASK_LOOPTHRU;
		awacs_write(MASK_ADDR1 | awacs_reg[1]);
		data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0;
	}
}

static int awacs_mixer_ioctl(u_int cmd, u_long arg)
{
	int data;
	int rc;

	switch (cmd) {
	case SOUND_MIXER_READ_CAPS:
		/* say we will allow multiple inputs?  prob. wrong
			so I'm switching it to single */
		return IOCTL_OUT(arg, 1);
	case SOUND_MIXER_READ_DEVMASK:
		data  = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
			| SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD
			| SOUND_MASK_IGAIN | SOUND_MASK_RECLEV
			| SOUND_MASK_ALTPCM
			| SOUND_MASK_MONITOR;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_RECMASK:
		data = SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_RECSRC:
		data = 0;
		if (awacs_reg[0] & MASK_MUX_AUDIN)
			data |= SOUND_MASK_LINE;
		if (awacs_reg[0] & MASK_MUX_MIC)
			data |= SOUND_MASK_MIC;
		if (awacs_reg[0] & MASK_MUX_CD)
			data |= SOUND_MASK_CD;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_WRITE_RECSRC:
		IOCTL_IN(arg, data);
		data &= (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD);
		awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
				  | MASK_MUX_AUDIN);
		if (data & SOUND_MASK_LINE)
			awacs_reg[0] |= MASK_MUX_AUDIN;
		if (data & SOUND_MASK_MIC)
			awacs_reg[0] |= MASK_MUX_MIC;
		if (data & SOUND_MASK_CD)
			awacs_reg[0] |= MASK_MUX_CD;
		awacs_write(awacs_reg[0] | MASK_ADDR0);
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_STEREODEVS:
		data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER| SOUND_MASK_RECLEV  ;
		if (awacs_revision == AWACS_SCREAMER)
			data |= SOUND_MASK_MONITOR ;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_WRITE_VOLUME:
		IOCTL_IN(arg, data);
		line_vol = data ;
		awacs_volume_setter(data, 2, 0, 6);
		/* fall through */
	case SOUND_MIXER_READ_VOLUME:
		rc = IOCTL_OUT(arg, line_vol);
		break;
	case SOUND_MIXER_WRITE_SPEAKER:
		IOCTL_IN(arg, data);
		spk_vol = data ;
		if (has_perch)
			awacs_enable_amp(data);
		else
			(void)awacs_volume_setter(data, 4, MASK_CMUTE, 6);
		/* fall though */
	case SOUND_MIXER_READ_SPEAKER:
		rc = IOCTL_OUT(arg, spk_vol);
		break;
	case SOUND_MIXER_WRITE_ALTPCM:	/* really bell volume */
		IOCTL_IN(arg, data);
		beep_vol = data & 0xff;
		/* fall through */
	case SOUND_MIXER_READ_ALTPCM:
		rc = IOCTL_OUT(arg, beep_vol);
		break;
	case SOUND_MIXER_WRITE_LINE:
		IOCTL_IN(arg, data);
		do_line_lev(data) ;
		/* fall through */
	case SOUND_MIXER_READ_LINE:
		rc = IOCTL_OUT(arg, line_lev);
		break;
	case SOUND_MIXER_WRITE_IGAIN:
		IOCTL_IN(arg, data);
		do_ip_gain(data) ;
		/* fall through */
	case SOUND_MIXER_READ_IGAIN:
		rc = IOCTL_OUT(arg, ip_gain);
		break;
	case SOUND_MIXER_WRITE_MIC:
		IOCTL_IN(arg, data);
		do_mic_lev(data);
		/* fall through */
	case SOUND_MIXER_READ_MIC:
		rc = IOCTL_OUT(arg, mic_lev);
		break;
	case SOUND_MIXER_WRITE_CD:
		IOCTL_IN(arg, data);
		do_cd_lev(data);
		/* fall through */
	case SOUND_MIXER_READ_CD:
		rc = IOCTL_OUT(arg, cd_lev);
		break;
	case SOUND_MIXER_WRITE_RECLEV:
		IOCTL_IN(arg, data);
		do_rec_lev(data) ;
		/* fall through */
	case SOUND_MIXER_READ_RECLEV:
		rc = IOCTL_OUT(arg, rec_lev);
		break;
	case MIXER_WRITE(SOUND_MIXER_MONITOR):
		IOCTL_IN(arg, data);
		do_passthru_vol(data) ;
		/* fall through */
	case MIXER_READ(SOUND_MIXER_MONITOR):
		rc = IOCTL_OUT(arg, passthru_vol);
		break;
	default:
		rc = -EINVAL;
	}
	
	return rc;
}

static void awacs_mixer_init(void)
{
	awacs_volume_setter(line_vol, 2, 0, 6);
	if (has_perch)
		awacs_enable_amp(spk_vol);
	else
		(void)awacs_volume_setter(spk_vol, 4, MASK_CMUTE, 6);
	do_line_lev(line_lev) ;
	do_ip_gain(ip_gain) ;
	do_mic_lev(mic_lev) ;
	do_cd_lev(cd_lev) ;
	do_rec_lev(rec_lev) ;
	do_passthru_vol(passthru_vol) ;
}

static int burgundy_mixer_ioctl(u_int cmd, u_long arg)
{
	int data;
	int rc;

	/* We are, we are, we are... Burgundy or better */
	switch(cmd) {
	case SOUND_MIXER_READ_DEVMASK:
		data = SOUND_MASK_VOLUME | SOUND_MASK_CD |
			SOUND_MASK_LINE | SOUND_MASK_MIC |
			SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_RECMASK:
		data = SOUND_MASK_LINE | SOUND_MASK_MIC
			| SOUND_MASK_CD;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_RECSRC:
		data = 0;
		if (awacs_reg[0] & MASK_MUX_AUDIN)
			data |= SOUND_MASK_LINE;
		if (awacs_reg[0] & MASK_MUX_MIC)
			data |= SOUND_MASK_MIC;
		if (awacs_reg[0] & MASK_MUX_CD)
			data |= SOUND_MASK_CD;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_WRITE_RECSRC:
		IOCTL_IN(arg, data);
		data &= (SOUND_MASK_LINE
			 | SOUND_MASK_MIC | SOUND_MASK_CD);
		awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
				  | MASK_MUX_AUDIN);
		if (data & SOUND_MASK_LINE)
			awacs_reg[0] |= MASK_MUX_AUDIN;
		if (data & SOUND_MASK_MIC)
			awacs_reg[0] |= MASK_MUX_MIC;
		if (data & SOUND_MASK_CD)
			awacs_reg[0] |= MASK_MUX_CD;
		awacs_write(awacs_reg[0] | MASK_ADDR0);
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_STEREODEVS:
		data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
			| SOUND_MASK_RECLEV | SOUND_MASK_CD
			| SOUND_MASK_LINE;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_CAPS:
		rc = IOCTL_OUT(arg, 0);
		break;
	case SOUND_MIXER_WRITE_VOLUME:
		IOCTL_IN(arg, data);
		awacs_burgundy_write_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME, data);
				/* Fall through */
	case SOUND_MIXER_READ_VOLUME:
		rc = IOCTL_OUT(arg, awacs_burgundy_read_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME));
		break;
	case SOUND_MIXER_WRITE_SPEAKER:
		IOCTL_IN(arg, data);
		if (!(data & 0xff)) {
			/* Mute the left speaker */
			awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
					   awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x2);
		} else {
			/* Unmute the left speaker */
			awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
					   awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x2);
		}
		if (!(data & 0xff00)) {
			/* Mute the right speaker */
			awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
					   awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x4);
		} else {
			/* Unmute the right speaker */
			awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
					   awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x4);
		}

		data = (((data&0xff)*16)/100 > 0xf ? 0xf :
			(((data&0xff)*16)/100)) +
			((((data>>8)*16)/100 > 0xf ? 0xf :
			  ((((data>>8)*16)/100)))<<4);

		awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, ~data);
				/* Fall through */
	case SOUND_MIXER_READ_SPEAKER:
		data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
		data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
		rc = IOCTL_OUT(arg, (~data) & 0x0000ffff);
		break;
	case SOUND_MIXER_WRITE_ALTPCM:	/* really bell volume */
		IOCTL_IN(arg, data);
		beep_vol = data & 0xff;
				/* fall through */
	case SOUND_MIXER_READ_ALTPCM:
		rc = IOCTL_OUT(arg, beep_vol);
		break;
	case SOUND_MIXER_WRITE_LINE:
		IOCTL_IN(arg, data);
		awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLLINE, data);

				/* fall through */
	case SOUND_MIXER_READ_LINE:
		data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLLINE);
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_WRITE_MIC:
		IOCTL_IN(arg, data);
				/* Mic is mono device */
		data = (data << 8) + (data << 24);
		awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLMIC, data);
				/* fall through */
	case SOUND_MIXER_READ_MIC:
		data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLMIC);
		data <<= 24;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_WRITE_CD:
		IOCTL_IN(arg, data);
		awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLCD, data);
				/* fall through */
	case SOUND_MIXER_READ_CD:
		data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLCD);
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_WRITE_RECLEV:
		IOCTL_IN(arg, data);
		data = awacs_volume_setter(data, 0, 0, 4);
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_RECLEV:
		data = awacs_get_volume(awacs_reg[0], 4);
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_OUTMASK:
	case SOUND_MIXER_OUTSRC:
	default:
		rc = -EINVAL;
	}
	
	return rc;
}

static int daca_mixer_ioctl(u_int cmd, u_long arg)
{
	int data;
	int rc;

	/* And the DACA's no genius either! */

	switch(cmd) {
	case SOUND_MIXER_READ_DEVMASK:
		data = SOUND_MASK_VOLUME;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_RECMASK:
		data = 0;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_RECSRC:
		data = 0;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_WRITE_RECSRC:
		IOCTL_IN(arg, data);
		data =0;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_STEREODEVS:
		data = SOUND_MASK_VOLUME;
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_READ_CAPS:
		rc = IOCTL_OUT(arg, 0);
		break;
	case SOUND_MIXER_WRITE_VOLUME:
		IOCTL_IN(arg, data);
		daca_set_volume(data, data);
		/* Fall through */
	case SOUND_MIXER_READ_VOLUME:
		daca_get_volume(& data, &data);
		rc = IOCTL_OUT(arg, data);
		break;
	case SOUND_MIXER_OUTMASK:
	case SOUND_MIXER_OUTSRC:
	default:
		rc = -EINVAL;
	}
	return rc;
}

static int PMacMixerIoctl(u_int cmd, u_long arg)
{
	int rc;
	
	/* Different IOCTLS for burgundy and, eventually, DACA & Tumbler */

	TRY_LOCK();
	
	switch (awacs_revision){
		case AWACS_BURGUNDY:
			rc = burgundy_mixer_ioctl(cmd, arg);
			break ;
		case AWACS_DACA:
			rc = daca_mixer_ioctl(cmd, arg);
			break;
		case AWACS_TUMBLER:
		case AWACS_SNAPPER:
			rc = tas_mixer_ioctl(cmd, arg);
			break ;
		default: /* ;-)) */
			rc = awacs_mixer_ioctl(cmd, arg);
	}

	UNLOCK();
	
	return rc;
}

static void PMacMixerInit(void)
{
	switch (awacs_revision) {
		case AWACS_TUMBLER:
		  printk("AE-Init tumbler mixer\n");
		  break ;
		case AWACS_SNAPPER:
		  printk("AE-Init snapper mixer\n");
		  break ;
		case AWACS_DACA:
		case AWACS_BURGUNDY:
			break ;	/* don't know yet */
		case AWACS_AWACS:
		case AWACS_SCREAMER:
		default:
			awacs_mixer_init() ;
			break ;
	}
}

/* Write/Read sq setup functions:
   Check to see if we have enough (or any) dbdma cmd buffers for the
   user's fragment settings.  If not, allocate some. If this fails we will
   point at the beep buffer - as an emergency provision - to stop dma tromping
   on some random bit of memory (if someone lets it go anyway).
   The command buffers are then set up to point to the fragment buffers
   (allocated elsewhere).  We need n+1 commands the last of which holds
   a NOP + loop to start.
*/

static int PMacWriteSqSetup(void)
{
	int i, count = 600 ;
	volatile struct dbdma_cmd *cp;

	LOCK();
	
	/* stop the controller from doing any output - if it isn't already.
	   it _should_ be before this is called anyway */

	out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
	while ((in_le32(&awacs_txdma->status) & RUN) && count--)
		udelay(1);
#ifdef DEBUG_DMASOUND
if (count <= 0)
	printk("dmasound_pmac: write sq setup: timeout waiting for dma to stop\n");
#endif

	if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) {
		if (awacs_tx_cmd_space)
			kfree(awacs_tx_cmd_space);
		number_of_tx_cmd_buffers = 0;

		/* we need nbufs + 1 (for the loop) and we should request + 1
		   again because the DBDMA_ALIGN might pull the start up by up
		   to sizeof(struct dbdma_cmd) - 4.
		*/

		awacs_tx_cmd_space = kmalloc
			((write_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
			 GFP_KERNEL);
		if (awacs_tx_cmd_space == NULL) {
			/* don't leave it dangling - nasty but better than a
			   random address */
			out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
			printk(KERN_ERR
			   "dmasound_pmac: can't allocate dbdma cmd buffers"
			   ", driver disabled\n");
			UNLOCK();
			return -ENOMEM;
		}
		awacs_tx_cmds = (volatile struct dbdma_cmd *)
			DBDMA_ALIGN(awacs_tx_cmd_space);
		number_of_tx_cmd_buffers = write_sq.max_count + 1;
	}

	cp = awacs_tx_cmds;
	memset((void *)cp, 0, (write_sq.max_count+1) * sizeof(struct dbdma_cmd));
	for (i = 0; i < write_sq.max_count; ++i, ++cp) {
		st_le32(&cp->phy_addr, virt_to_bus(write_sq.buffers[i]));
	}
	st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
	st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds));
	/* point the controller at the command stack - ready to go */
	out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds));
	UNLOCK();
	return 0;
}

static int PMacReadSqSetup(void)
{
	int i, count = 600;
	volatile struct dbdma_cmd *cp;

	LOCK();
	
	/* stop the controller from doing any input - if it isn't already.
	   it _should_ be before this is called anyway */
	
	out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
	while ((in_le32(&awacs_rxdma->status) & RUN) && count--)
		udelay(1);
#ifdef DEBUG_DMASOUND
if (count <= 0)
	printk("dmasound_pmac: read sq setup: timeout waiting for dma to stop\n");
#endif

	if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) {
		if (awacs_rx_cmd_space)
			kfree(awacs_rx_cmd_space);
		number_of_rx_cmd_buffers = 0;

		/* we need nbufs + 1 (for the loop) and we should request + 1 again
		   because the DBDMA_ALIGN might pull the start up by up to
		   sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits).
		*/

		awacs_rx_cmd_space = kmalloc
			((read_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
			 GFP_KERNEL);
		if (awacs_rx_cmd_space == NULL) {
			/* don't leave it dangling - nasty but better than a
			   random address */
			out_le32(&awacs_rxdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
			printk(KERN_ERR
			   "dmasound_pmac: can't allocate dbdma cmd buffers"
			   ", driver disabled\n");
			UNLOCK();
			return -ENOMEM;
		}
		awacs_rx_cmds = (volatile struct dbdma_cmd *)
			DBDMA_ALIGN(awacs_rx_cmd_space);
		number_of_rx_cmd_buffers = read_sq.max_count + 1 ;
	}
	cp = awacs_rx_cmds;
	memset((void *)cp, 0, (read_sq.max_count+1) * sizeof(struct dbdma_cmd));

	/* Set dma buffers up in a loop */
	for (i = 0; i < read_sq.max_count; i++,cp++) {
		st_le32(&cp->phy_addr, virt_to_bus(read_sq.buffers[i]));
		st_le16(&cp->command, INPUT_MORE + INTR_ALWAYS);
		st_le16(&cp->req_count, read_sq.block_size);
		st_le16(&cp->xfer_status, 0);
	}

	/* The next two lines make the thing loop around.
	*/
	st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
	st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds));
	/* point the controller at the command stack - ready to go */
	out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds));

	UNLOCK();
	return 0;
}

/* TODO: this needs work to guarantee that when it returns DMA has stopped
   but in a more elegant way than is done here....
*/

static void PMacAbortRead(void)
{
	int i;
	volatile struct dbdma_cmd *cp;

	LOCK();
	/* give it a chance to update the output and provide the IRQ
	   that is expected.
	*/

	out_le32(&awacs_rxdma->control, ((FLUSH) << 16) + FLUSH );

	cp = awacs_rx_cmds;
	for (i = 0; i < read_sq.max_count; i++,cp++)
		st_le16(&cp->command, DBDMA_STOP);
	/*
	 * We should probably wait for the thing to stop before we
	 * release the memory.
	 */

	msleep(100) ; /* give it a (small) chance to act */

	/* apply the sledgehammer approach - just stop it now */

	out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
	UNLOCK();
}

extern char *get_afmt_string(int);
static int PMacStateInfo(char *b, size_t sp)
{
	int i, len = 0;
	len = sprintf(b,"HW rates: ");
	switch (awacs_revision){
		case AWACS_DACA:
		case AWACS_BURGUNDY:
			len += sprintf(b,"44100 ") ;
			break ;
		case AWACS_TUMBLER:
		case AWACS_SNAPPER:
			for (i=0; i<1; i++){
				if (tas_freqs_ok[i])
					len += sprintf(b+len,"%d ", tas_freqs[i]) ;
			}
			break ;
		case AWACS_AWACS:
		case AWACS_SCREAMER:
		default:
			for (i=0; i<8; i++){
				if (awacs_freqs_ok[i])
					len += sprintf(b+len,"%d ", awacs_freqs[i]) ;
			}
			break ;
	}
	len += sprintf(b+len,"s/sec\n") ;
	if (len < sp) {
		len += sprintf(b+len,"HW AFMTS: ");
		i = AFMT_U16_BE ;
		while (i) {
			if (i & dmasound.mach.hardware_afmts)
				len += sprintf(b+len,"%s ",
					get_afmt_string(i & dmasound.mach.hardware_afmts));
			i >>= 1 ;
		}
		len += sprintf(b+len,"\n") ;
	}
	return len ;
}

/*** Machine definitions *****************************************************/

static SETTINGS def_hard = {
	.format	= AFMT_S16_BE,
	.stereo	= 1,
	.size	= 16,
	.speed	= 44100
} ;

static SETTINGS def_soft = {
	.format	= AFMT_S16_BE,
	.stereo	= 1,
	.size	= 16,
	.speed	= 44100
} ;

static MACHINE machPMac = {
	.name		= awacs_name,
	.name2		= "PowerMac Built-in Sound",
	.owner		= THIS_MODULE,
	.dma_alloc	= PMacAlloc,
	.dma_free	= PMacFree,
	.irqinit	= PMacIrqInit,
#ifdef MODULE
	.irqcleanup	= PMacIrqCleanup,
#endif /* MODULE */
	.init		= PMacInit,
	.silence	= PMacSilence,
	.setFormat	= PMacSetFormat,
	.setVolume	= PMacSetVolume,
	.play		= PMacPlay,
	.record		= NULL,		/* default to no record */
	.mixer_init	= PMacMixerInit,
	.mixer_ioctl	= PMacMixerIoctl,
	.write_sq_setup	= PMacWriteSqSetup,
	.read_sq_setup	= PMacReadSqSetup,
	.state_info	= PMacStateInfo,
	.abort_read	= PMacAbortRead,
	.min_dsp_speed	= 7350,
	.max_dsp_speed	= 44100,
	.version	= ((DMASOUND_AWACS_REVISION<<8) + DMASOUND_AWACS_EDITION)
};


/*** Config & Setup **********************************************************/

/* Check for pmac models that we care about in terms of special actions.
*/

void __init
set_model(void)
{
	/* portables/lap-tops */

	if (machine_is_compatible("AAPL,3400/2400") ||
	    machine_is_compatible("AAPL,3500"))	{
		is_pbook_3X00 = 1 ;
	}
	if (machine_is_compatible("PowerBook1,1")  || /* lombard */
	    machine_is_compatible("AAPL,PowerBook1998")){ /* wallstreet */
		is_pbook_g3 = 1 ;
		return ;
	}
}

/* Get the OF node that tells us about the registers, interrupts etc. to use
   for sound IO.

   On most machines the sound IO OF node is the 'davbus' node.  On newer pmacs
   with DACA (& Tumbler) the node to use is i2s-a.  On much older machines i.e.
   before 9500 there is no davbus node and we have to use the 'awacs' property.

  In the latter case we signal this by setting the codec value - so that the
  code that looks for chip properties knows how to go about it.
*/

static struct device_node* __init
get_snd_io_node(void)
{
	struct device_node *np = NULL;

	/* set up awacs_node for early OF which doesn't have a full set of
	 * properties on davbus
	*/

	awacs_node = find_devices("awacs");
	if (awacs_node)
		awacs_revision = AWACS_AWACS;

	/* powermac models after 9500 (other than those which use DACA or
	 * Tumbler) have a node called "davbus".
	 */
	np = find_devices("davbus");
	/*
	 * if we didn't find a davbus device, try 'i2s-a' since
	 * this seems to be what iBooks (& Tumbler) have.
	 */
	if (np == NULL)
		np = i2s_node = find_devices("i2s-a");

	/* if we didn't find this - perhaps we are on an early model
	 * which _only_ has an 'awacs' node
	*/
	if (np == NULL && awacs_node)
		np = awacs_node ;

	/* if we failed all these return null - this will cause the
	 * driver to give up...
	*/
	return np ;
}

/* Get the OF node that contains the info about the sound chip, inputs s-rates
   etc.
   This node does not exist (or contains much reduced info) on earlier machines
   we have to deduce the info other ways for these.
*/

static struct device_node* __init
get_snd_info_node(struct device_node *io)
{
	struct device_node *info;

	info = find_devices("sound");
	while (info && info->parent != io)
		info = info->next;
	return info;
}

/* Find out what type of codec we have.
*/

static int __init
get_codec_type(struct device_node *info)
{
	/* already set if pre-davbus model and info will be NULL */
	int codec = awacs_revision ;

	if (info) {
		/* must do awacs first to allow screamer to overide it */
		if (device_is_compatible(info, "awacs"))
			codec = AWACS_AWACS ;
		if (device_is_compatible(info, "screamer"))
			codec = AWACS_SCREAMER;
		if (device_is_compatible(info, "burgundy"))
			codec = AWACS_BURGUNDY ;
		if (device_is_compatible(info, "daca"))
			codec = AWACS_DACA;
		if (device_is_compatible(info, "tumbler"))
			codec = AWACS_TUMBLER;
		if (device_is_compatible(info, "snapper"))
			codec = AWACS_SNAPPER;
	}
	return codec ;
}

/* find out what type, if any, of expansion card we have
*/
static void __init
get_expansion_type(void)
{
	if (find_devices("perch") != NULL)
		has_perch = 1;

	if (find_devices("pb-ziva-pc") != NULL)
		has_ziva = 1;
	/* need to work out how we deal with iMac SRS module */
}

/* set up frame rates.
 * I suspect that these routines don't quite go about it the right way:
 * - where there is more than one rate - I think that the first property
 * value is the number of rates.
 * TODO: check some more device trees and modify accordingly
 *       Set dmasound.mach.max_dsp_rate on the basis of these routines.
*/

static void __init
awacs_init_frame_rates(unsigned int *prop, unsigned int l)
{
	int i ;
	if (prop) {
		for (i=0; i<8; i++)
			awacs_freqs_ok[i] = 0 ;
		for (l /= sizeof(int); l > 0; --l) {
			unsigned int r = *prop++;
			/* Apple 'Fixed' format */
			if (r >= 0x10000)
				r >>= 16;
			for (i = 0; i < 8; ++i) {
				if (r == awacs_freqs[i]) {
					awacs_freqs_ok[i] = 1;
					break;
				}
			}
		}
	}
	/* else we assume that all the rates are available */
}

static void __init
burgundy_init_frame_rates(unsigned int *prop, unsigned int l)
{
	int temp[9] ;
	int i = 0 ;
	if (prop) {
		for (l /= sizeof(int); l > 0; --l) {
			unsigned int r = *prop++;
			/* Apple 'Fixed' format */
			if (r >= 0x10000)
				r >>= 16;
			temp[i] = r ;
			i++ ; if(i>=9) i=8;
		}
	}
#ifdef DEBUG_DMASOUND
if (i > 1){
	int j;
	printk("dmasound_pmac: burgundy with multiple frame rates\n");
	for(j=0; j<i; j++)
		printk("%d ", temp[j]) ;
	printk("\n") ;
}
#endif
}

static void __init
daca_init_frame_rates(unsigned int *prop, unsigned int l)
{
	int temp[9] ;
	int i = 0 ;
	if (prop) {
		for (l /= sizeof(int); l > 0; --l) {
			unsigned int r = *prop++;
			/* Apple 'Fixed' format */
			if (r >= 0x10000)
				r >>= 16;
			temp[i] = r ;
			i++ ; if(i>=9) i=8;

		}
	}
#ifdef DEBUG_DMASOUND
if (i > 1){
	int j;
	printk("dmasound_pmac: DACA with multiple frame rates\n");
	for(j=0; j<i; j++)
		printk("%d ", temp[j]) ;
	printk("\n") ;
}
#endif
}

static void __init
init_frame_rates(unsigned int *prop, unsigned int l)
{
	switch (awacs_revision) {
		case AWACS_TUMBLER:
		case AWACS_SNAPPER:
			tas_init_frame_rates(prop, l);
			break ;
		case AWACS_DACA:
			daca_init_frame_rates(prop, l);
			break ;
		case AWACS_BURGUNDY:
			burgundy_init_frame_rates(prop, l);
			break ;
		default:
			awacs_init_frame_rates(prop, l);
			break ;
	}
}

/* find things/machines that can't do mac-io byteswap
*/

static void __init
set_hw_byteswap(struct device_node *io)
{
	struct device_node *mio ;
	unsigned int kl = 0 ;

	/* if seems that Keylargo can't byte-swap  */

	for (mio = io->parent; mio ; mio = mio->parent) {
		if (strcmp(mio->name, "mac-io") == 0) {
			if (device_is_compatible(mio, "Keylargo"))
				kl = 1;
			break;
		}
	}
	hw_can_byteswap = !kl;
}

/* Allocate the resources necessary for beep generation.  This cannot be (quite)
   done statically (yet) because we cannot do virt_to_bus() on static vars when
   the code is loaded as a module.

   for the sake of saving the possibility that two allocations will incur the
   overhead of two pull-ups in DBDMA_ALIGN() we allocate the 'emergency' dmdma
   command here as well... even tho' it is not part of the beep process.
*/

int32_t
__init setup_beep(void)
{
	/* Initialize beep stuff */
	/* want one cmd buffer for beeps, and a second one for emergencies
	   - i.e. dbdma error conditions.
	   ask for three to allow for pull up in DBDMA_ALIGN().
	*/
	beep_dbdma_cmd_space =
		kmalloc((2 + 1) * sizeof(struct dbdma_cmd), GFP_KERNEL);
	if(beep_dbdma_cmd_space == NULL) {
		printk(KERN_ERR "dmasound_pmac: no beep dbdma cmd space\n") ;
		return -ENOMEM ;
	}
	beep_dbdma_cmd = (volatile struct dbdma_cmd *)
			DBDMA_ALIGN(beep_dbdma_cmd_space);
	/* set up emergency dbdma cmd */
	emergency_dbdma_cmd = beep_dbdma_cmd+1 ;
	beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
	if (beep_buf == NULL) {
		printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n");
		if( beep_dbdma_cmd_space ) kfree(beep_dbdma_cmd_space) ;
		return -ENOMEM ;
	}
	return 0 ;
}

static struct input_dev awacs_beep_dev = {
	.evbit		= { BIT(EV_SND) },
	.sndbit		= { BIT(SND_BELL) | BIT(SND_TONE) },
	.event		= awacs_beep_event,
	.name		= "dmasound beeper",
	.phys		= "macio/input0", /* what the heck is this?? */
	.id		= {
		.bustype	= BUS_HOST,
	},
};

int __init dmasound_awacs_init(void)
{
	struct device_node *io = NULL, *info = NULL;
	int vol, res;

	if (_machine != _MACH_Pmac)
		return -ENODEV;

	awacs_subframe = 0;
	awacs_revision = 0;
	hw_can_byteswap = 1 ; /* most can */

	/* look for models we need to handle specially */
	set_model() ;

	/* find the OF node that tells us about the dbdma stuff
	*/
	io = get_snd_io_node();
	if (io == NULL) {
#ifdef DEBUG_DMASOUND
printk("dmasound_pmac: couldn't find sound io OF node\n");
#endif
		return -ENODEV ;
	}

	/* find the OF node that tells us about the sound sub-system
	 * this doesn't exist on pre-davbus machines (earlier than 9500)
	*/
	if (awacs_revision != AWACS_AWACS) { /* set for pre-davbus */
		info = get_snd_info_node(io) ;
		if (info == NULL){
#ifdef DEBUG_DMASOUND
printk("dmasound_pmac: couldn't find 'sound' OF node\n");
#endif
			return -ENODEV ;
		}
	}

	awacs_revision = get_codec_type(info) ;
	if (awacs_revision == 0) {
#ifdef DEBUG_DMASOUND
printk("dmasound_pmac: couldn't find a Codec we can handle\n");
#endif
		return -ENODEV ; /* we don't know this type of h/w */
	}

	/* set up perch, ziva, SRS or whatever else we have as sound
	 *  expansion.
	*/
	get_expansion_type();

	/* we've now got enough information to make up the audio topology.
	 * we will map the sound part of mac-io now so that we can probe for
	 * other info if necessary (early AWACS we want to read chip ids)
	 */

	if (io->n_addrs < 3 || io->n_intrs < 3) {
		/* OK - maybe we need to use the 'awacs' node (on earlier
		 * machines).
		*/
		if (awacs_node) {
			io = awacs_node ;
			if (io->n_addrs < 3 || io->n_intrs < 3) {
				printk("dmasound_pmac: can't use %s"
					" (%d addrs, %d intrs)\n",
		      		 io->full_name, io->n_addrs, io->n_intrs);
				return -ENODEV;
			}
		} else {
			printk("dmasound_pmac: can't use %s (%d addrs, %d intrs)\n",
		 	      io->full_name, io->n_addrs, io->n_intrs);
		}
	}

	if (!request_OF_resource(io, 0, NULL)) {
		printk(KERN_ERR "dmasound: can't request IO resource !\n");
		return -ENODEV;
	}
	if (!request_OF_resource(io, 1, " (tx dma)")) {
		release_OF_resource(io, 0);
		printk(KERN_ERR "dmasound: can't request TX DMA resource !\n");
		return -ENODEV;
	}

	if (!request_OF_resource(io, 2, " (rx dma)")) {
		release_OF_resource(io, 0);
		release_OF_resource(io, 1);
		printk(KERN_ERR "dmasound: can't request RX DMA resource !\n");
		return -ENODEV;
	}

	/* all OF versions I've seen use this value */
	if (i2s_node)
		i2s = ioremap(io->addrs[0].address, 0x1000);
	else
		awacs = ioremap(io->addrs[0].address, 0x1000);
	awacs_txdma = ioremap(io->addrs[1].address, 0x100);
	awacs_rxdma = ioremap(io->addrs[2].address, 0x100);

	/* first of all make sure that the chip is powered up....*/
	pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
	if (awacs_revision == AWACS_SCREAMER && awacs)
		awacs_recalibrate();

	awacs_irq = io->intrs[0].line;
	awacs_tx_irq = io->intrs[1].line;
	awacs_rx_irq = io->intrs[2].line;

	/* Hack for legacy crap that will be killed someday */
	awacs_node = io;

	/* if we have an awacs or screamer - probe the chip to make
	 * sure we have the right revision.
	*/

	if (awacs_revision <= AWACS_SCREAMER){
		uint32_t temp, rev, mfg ;
		/* find out the awacs revision from the chip */
		temp = in_le32(&awacs->codec_stat);
		rev = (temp >> 12) & 0xf;
		mfg = (temp >>  8) & 0xf;
#ifdef DEBUG_DMASOUND
printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
#endif
		if (rev >= AWACS_SCREAMER)
			awacs_revision = AWACS_SCREAMER ;
		else
			awacs_revision = rev ;
	}

	dmasound.mach = machPMac;

	/* find out other bits & pieces from OF, these may be present
	   only on some models ... so be careful.
	*/

	/* in the absence of a frame rates property we will use the defaults
	*/

	if (info) {
		unsigned int *prop, l;

		sound_device_id = 0;
		/* device ID appears post g3 b&w */
		prop = (unsigned int *)get_property(info, "device-id", NULL);
		if (prop != 0)
			sound_device_id = *prop;

		/* look for a property saying what sample rates
		   are available */

		prop = (unsigned int *)get_property(info, "sample-rates", &l);
		if (prop == 0)
			prop = (unsigned int *) get_property
				(info, "output-frame-rates", &l);

		/* if it's there use it to set up frame rates */
		init_frame_rates(prop, l) ;
	}

	if (awacs)
		out_le32(&awacs->control, 0x11); /* set everything quiesent */

	set_hw_byteswap(io) ; /* figure out if the h/w can do it */

#ifdef CONFIG_NVRAM
	/* get default volume from nvram */
	vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
#else
	vol = 0;
#endif

	/* set up tracking values */
	spk_vol = vol * 100 ;
	spk_vol /= 7 ; /* get set value to a percentage */
	spk_vol |= (spk_vol << 8) ; /* equal left & right */
 	line_vol = passthru_vol = spk_vol ;

	/* fill regs that are shared between AWACS & Burgundy */

	awacs_reg[2] = vol + (vol << 6);
	awacs_reg[4] = vol + (vol << 6);
	awacs_reg[5] = vol + (vol << 6); /* screamer has loopthru vol control */
	awacs_reg[6] = 0; /* maybe should be vol << 3 for PCMCIA speaker */
	awacs_reg[7] = 0;

	awacs_reg[0] = MASK_MUX_CD;
	awacs_reg[1] = MASK_LOOPTHRU;

	/* FIXME: Only machines with external SRS module need MASK_PAROUT */
	if (has_perch || sound_device_id == 0x5
	    || /*sound_device_id == 0x8 ||*/ sound_device_id == 0xb)
		awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;

	switch (awacs_revision) {
		case AWACS_TUMBLER:
                        tas_register_driver(&tas3001c_hooks);
			tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C);
			tas_dmasound_init();
			tas_post_init();
			break ;
		case AWACS_SNAPPER:
                        tas_register_driver(&tas3004_hooks);
			tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004);
			tas_dmasound_init();
			tas_post_init();
			break;
		case AWACS_DACA:
			daca_init();
			break;	
		case AWACS_BURGUNDY:
			awacs_burgundy_init();
			break ;
		case AWACS_SCREAMER:
		case AWACS_AWACS:
		default:
			load_awacs();
			break ;
	}

	/* enable/set-up external modules - when we know how */

	if (has_perch)
		awacs_enable_amp(100 * 0x101);

	/* Reset dbdma channels */
	out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
	while (in_le32(&awacs_txdma->status) & RUN)
		udelay(1);
	out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
	while (in_le32(&awacs_rxdma->status) & RUN)
		udelay(1);

	/* Initialize beep stuff */
	if ((res=setup_beep()))
		return res ;

#ifdef CONFIG_PMAC_PBOOK
	pmu_register_sleep_notifier(&awacs_sleep_notifier);
#endif /* CONFIG_PMAC_PBOOK */

	/* Powerbooks have odd ways of enabling inputs such as
	   an expansion-bay CD or sound from an internal modem
	   or a PC-card modem. */
	if (is_pbook_3X00) {
		/*
		 * Enable CD and PC-card sound inputs.
		 * This is done by reading from address
		 * f301a000, + 0x10 to enable the expansion-bay
		 * CD sound input, + 0x80 to enable the PC-card
		 * sound input.  The 0x100 enables the SCSI bus
		 * terminator power.
		 */
		latch_base = ioremap (0xf301a000, 0x1000);
		in_8(latch_base + 0x190);

	} else if (is_pbook_g3) {
		struct device_node* mio;
		macio_base = NULL;
		for (mio = io->parent; mio; mio = mio->parent) {
			if (strcmp(mio->name, "mac-io") == 0
			    && mio->n_addrs > 0) {
				macio_base = ioremap(mio->addrs[0].address, 0x40);
				break;
			}
		}
		/*
		 * Enable CD sound input.
		 * The relevant bits for writing to this byte are 0x8f.
		 * I haven't found out what the 0x80 bit does.
		 * For the 0xf bits, writing 3 or 7 enables the CD
		 * input, any other value disables it.  Values
		 * 1, 3, 5, 7 enable the microphone.  Values 0, 2,
		 * 4, 6, 8 - f enable the input from the modem.
		 *  -- paulus.
		 */
		if (macio_base)
			out_8(macio_base + 0x37, 3);
	}

	if (hw_can_byteswap)
 		dmasound.mach.hardware_afmts = (AFMT_S16_BE | AFMT_S16_LE) ;
 	else
		dmasound.mach.hardware_afmts = AFMT_S16_BE ;

	/* shut out chips that do output only.
	 * may need to extend this to machines which have no inputs - even tho'
	 * they use screamer - IIRC one of the powerbooks is like this.
	 */

	if (awacs_revision != AWACS_DACA) {
		dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
		dmasound.mach.record = PMacRecord ;
	}

	dmasound.mach.default_hard = def_hard ;
	dmasound.mach.default_soft = def_soft ;

	switch (awacs_revision) {
		case AWACS_BURGUNDY:
			sprintf(awacs_name, "PowerMac Burgundy ") ;
			break ;
		case AWACS_DACA:
			sprintf(awacs_name, "PowerMac DACA ") ;
			break ;
		case AWACS_TUMBLER:
			sprintf(awacs_name, "PowerMac Tumbler ") ;
			break ;
		case AWACS_SNAPPER:
			sprintf(awacs_name, "PowerMac Snapper ") ;
			break ;
		case AWACS_SCREAMER:
			sprintf(awacs_name, "PowerMac Screamer ") ;
			break ;
		case AWACS_AWACS:
		default:
			sprintf(awacs_name, "PowerMac AWACS rev %d ", awacs_revision) ;
			break ;
	}

	/*
	 * XXX: we should handle errors here, but that would mean
	 * rewriting the whole init code.  later..
	 */
	input_register_device(&awacs_beep_dev);

	return dmasound_init();
}

static void __exit dmasound_awacs_cleanup(void)
{
	input_unregister_device(&awacs_beep_dev);

	switch (awacs_revision) {
		case AWACS_TUMBLER:
		case AWACS_SNAPPER:
			tas_dmasound_cleanup();
			tas_cleanup();
			break ;
		case AWACS_DACA:
			daca_cleanup();
			break;
	}
	dmasound_deinit();

}

MODULE_DESCRIPTION("PowerMac built-in audio driver.");
MODULE_LICENSE("GPL");

module_init(dmasound_awacs_init);
module_exit(dmasound_awacs_cleanup);
