/*
 *  linux/drivers/ide/legacy/macide.c -- Macintosh IDE Driver
 *
 *     Copyright (C) 1998 by Michael Schmitz
 *
 *  This driver was written based on information obtained from the MacOS IDE
 *  driver binary by Mikael Forselius
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License.  See the file COPYING in the main directory of this archive for
 *  more details.
 */

#include <linux/types.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/delay.h>
#include <linux/ide.h>

#include <asm/machw.h>
#include <asm/macintosh.h>
#include <asm/macints.h>
#include <asm/mac_baboon.h>

#define IDE_BASE 0x50F1A000	/* Base address of IDE controller */

/*
 * Generic IDE registers as offsets from the base
 * These match MkLinux so they should be correct.
 */

#define IDE_DATA	0x00
#define IDE_ERROR	0x04	/* see err-bits */
#define IDE_NSECTOR	0x08	/* nr of sectors to read/write */
#define IDE_SECTOR	0x0c	/* starting sector */
#define IDE_LCYL	0x10	/* starting cylinder */
#define IDE_HCYL	0x14	/* high byte of starting cyl */
#define IDE_SELECT	0x18	/* 101dhhhh , d=drive, hhhh=head */
#define IDE_STATUS	0x1c	/* see status-bits */
#define IDE_CONTROL	0x38	/* control/altstatus */

/*
 * Mac-specific registers
 */

/*
 * this register is odd; it doesn't seem to do much and it's
 * not word-aligned like virtually every other hardware register
 * on the Mac...
 */

#define IDE_IFR		0x101	/* (0x101) IDE interrupt flags on Quadra:
				 *
				 * Bit 0+1: some interrupt flags
				 * Bit 2+3: some interrupt enable
				 * Bit 4:   ??
				 * Bit 5:   IDE interrupt flag (any hwif)
				 * Bit 6:   maybe IDE interrupt enable (any hwif) ??
				 * Bit 7:   Any interrupt condition
				 */

volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR);

static int macide_offsets[IDE_NR_PORTS] = {
    IDE_DATA, IDE_ERROR,  IDE_NSECTOR, IDE_SECTOR, IDE_LCYL,
    IDE_HCYL, IDE_SELECT, IDE_STATUS,  IDE_CONTROL
};

int macide_ack_intr(ide_hwif_t* hwif)
{
	if (*ide_ifr & 0x20) {
		*ide_ifr &= ~0x20;
		return 1;
	}
	return 0;
}

#ifdef CONFIG_BLK_DEV_MAC_MEDIABAY
static void macide_mediabay_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	int state = baboon->mb_status & 0x04;

	printk(KERN_INFO "macide: media bay %s detected\n", state? "removal":"insertion");
}
#endif

/*
 * Probe for a Macintosh IDE interface
 */

void macide_init(void)
{
	hw_regs_t hw;
	ide_hwif_t *hwif;
	int index = -1;

	switch (macintosh_config->ide_type) {
	case MAC_IDE_QUADRA:
		ide_setup_ports(&hw, IDE_BASE, macide_offsets,
				0, 0, macide_ack_intr,
//				quadra_ide_iops,
				IRQ_NUBUS_F);
		index = ide_register_hw(&hw, &hwif);
		break;
	case MAC_IDE_PB:
		ide_setup_ports(&hw, IDE_BASE, macide_offsets,
				0, 0, macide_ack_intr,
//				macide_pb_iops,
				IRQ_NUBUS_C);
		index = ide_register_hw(&hw, &hwif);
		break;
	case MAC_IDE_BABOON:
		ide_setup_ports(&hw, BABOON_BASE, macide_offsets,
				0, 0, NULL,
//				macide_baboon_iops,
				IRQ_BABOON_1);
		index = ide_register_hw(&hw, &hwif);
		if (index == -1) break;
		if (macintosh_config->ident == MAC_MODEL_PB190) {

			/* Fix breakage in ide-disk.c: drive capacity	*/
			/* is not initialized for drives without a 	*/
			/* hardware ID, and we can't get that without	*/
			/* probing the drive which freezes a 190.	*/

			ide_drive_t *drive = &ide_hwifs[index].drives[0];
			drive->capacity64 = drive->cyl*drive->head*drive->sect;

#ifdef CONFIG_BLK_DEV_MAC_MEDIABAY
			request_irq(IRQ_BABOON_2, macide_mediabay_interrupt,
					IRQ_FLG_FAST, "mediabay",
					macide_mediabay_interrupt);
#endif
		}
		break;

	default:
	    return;
	}

        if (index != -1) {
		hwif->mmio = 2;
		if (macintosh_config->ide_type == MAC_IDE_QUADRA)
			printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index);
		else if (macintosh_config->ide_type == MAC_IDE_PB)
			printk(KERN_INFO "ide%d: Macintosh Powerbook IDE interface\n", index);
		else if (macintosh_config->ide_type == MAC_IDE_BABOON)
			printk(KERN_INFO "ide%d: Macintosh Powerbook Baboon IDE interface\n", index);
		else
			printk(KERN_INFO "ide%d: Unknown Macintosh IDE interface\n", index);
	}
}
