/*
 *  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_PM
/*
 * 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_PM */

/* 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);

	kfree(awacs_tx_cmd_space);
	kfree(awacs_rx_cmd_space);
	kfree(beep_dbdma_cmd_space);
	kfree(beep_buf);
#ifdef CONFIG_PM
	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_PM
/*
 * 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_PM */


/* All the burgundy functions: */

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

static inline 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) {
		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 ) {
		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");
		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_PM
	pmu_register_sleep_notifier(&awacs_sleep_notifier);
#endif /* CONFIG_PM */

	/* 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);
