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

static const char *mac_ide_name[] =
	{ "Quadra", "Powerbook", "Powerbook Baboon" };

/*
 * Probe for a Macintosh IDE interface
 */

static int __init macide_init(void)
{
	hw_regs_t hw;
	ide_hwif_t *hwif;

	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);
		break;
	case MAC_IDE_PB:
		ide_setup_ports(&hw, IDE_BASE, macide_offsets,
				0, 0, macide_ack_intr,
//				macide_pb_iops,
				IRQ_NUBUS_C);
		break;
	case MAC_IDE_BABOON:
		ide_setup_ports(&hw, BABOON_BASE, macide_offsets,
				0, 0, NULL,
//				macide_baboon_iops,
				IRQ_BABOON_1);
		break;
	default:
		return -ENODEV;
	}

	printk(KERN_INFO "ide: Macintosh %s IDE controller\n",
			 mac_ide_name[macintosh_config->ide_type - 1]);

	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
	if (hwif) {
		u8 index = hwif->index;
		u8 idx[4] = { index, 0xff, 0xff, 0xff };

		ide_init_port_data(hwif, index);
		ide_init_port_hw(hwif, &hw);

		if (macintosh_config->ide_type == MAC_IDE_BABOON &&
		    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 = &hwif->drives[0];
			drive->capacity64 = drive->cyl*drive->head*drive->sect;
		}

		hwif->mmio = 1;

		ide_device_add(idx);
	}

	return 0;
}

module_init(macide_init);
