pata_cypress.c 4.26 KB
Newer Older
1 2 3
/*
 * pata_cypress.c 	- Cypress PATA for new ATA layer
 *			  (C) 2006 Red Hat Inc
4
 *			  Alan Cox
5 6 7 8 9
 *
 * Based heavily on
 * linux/drivers/ide/pci/cy82c693.c		Version 0.40	Sep. 10, 2002
 *
 */
10

11 12 13 14 15 16 17 18 19
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>

#define DRV_NAME "pata_cypress"
Jeff Garzik's avatar
Jeff Garzik committed
20
#define DRV_VERSION "0.1.5"
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

/* here are the offset definitions for the registers */

enum {
	CY82_IDE_CMDREG		= 0x04,
	CY82_IDE_ADDRSETUP	= 0x48,
	CY82_IDE_MASTER_IOR	= 0x4C,
	CY82_IDE_MASTER_IOW	= 0x4D,
	CY82_IDE_SLAVE_IOR	= 0x4E,
	CY82_IDE_SLAVE_IOW	= 0x4F,
	CY82_IDE_MASTER_8BIT	= 0x50,
	CY82_IDE_SLAVE_8BIT	= 0x51,

	CY82_INDEX_PORT		= 0x22,
	CY82_DATA_PORT		= 0x23,

	CY82_INDEX_CTRLREG1	= 0x01,
	CY82_INDEX_CHANNEL0	= 0x30,
	CY82_INDEX_CHANNEL1	= 0x31,
	CY82_INDEX_TIMEOUT	= 0x32
};

/**
 *	cy82c693_set_piomode	-	set initial PIO mode data
 *	@ap: ATA interface
 *	@adev: ATA device
 *
 *	Called to do the PIO mode setup.
 */
50

51 52 53 54 55 56 57
static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	struct ata_timing t;
	const unsigned long T = 1000000 / 33;
	short time_16, time_8;
	u32 addr;
58

59 60 61 62 63
	if (ata_timing_compute(adev, adev->pio_mode, &t, T, 1) < 0) {
		printk(KERN_ERR DRV_NAME ": mome computation failed.\n");
		return;
	}

64 65 66 67
	time_16 = clamp_val(t.recover - 1, 0, 15) |
		  (clamp_val(t.active - 1, 0, 15) << 4);
	time_8 = clamp_val(t.act8b - 1, 0, 15) |
		 (clamp_val(t.rec8b - 1, 0, 15) << 4);
68

69 70
	if (adev->devno == 0) {
		pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr);
71

72
		addr &= ~0x0F;	/* Mask bits */
73
		addr |= clamp_val(t.setup - 1, 0, 15);
74

75 76 77 78 79 80
		pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr);
		pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16);
		pci_write_config_byte(pdev, CY82_IDE_MASTER_IOW, time_16);
		pci_write_config_byte(pdev, CY82_IDE_MASTER_8BIT, time_8);
	} else {
		pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr);
81

82
		addr &= ~0xF0;	/* Mask bits */
83
		addr |= (clamp_val(t.setup - 1, 0, 15) << 4);
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

		pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr);
		pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16);
		pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOW, time_16);
		pci_write_config_byte(pdev, CY82_IDE_SLAVE_8BIT, time_8);
	}
}

/**
 *	cy82c693_set_dmamode	-	set initial DMA mode data
 *	@ap: ATA interface
 *	@adev: ATA device
 *
 *	Called to do the DMA mode setup.
 */
99

100 101 102
static void cy82c693_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
	int reg = CY82_INDEX_CHANNEL0 + ap->port_no;
103

104 105 106
	/* Be afraid, be very afraid. Magic registers  in low I/O space */
	outb(reg, 0x22);
	outb(adev->dma_mode - XFER_MW_DMA_0, 0x23);
107

108 109 110 111 112 113
	/* 0x50 gives the best behaviour on the Alpha's using this chip */
	outb(CY82_INDEX_TIMEOUT, 0x22);
	outb(0x50, 0x23);
}

static struct scsi_host_template cy82c693_sht = {
114
	ATA_BMDMA_SHT(DRV_NAME),
115 116 117
};

static struct ata_port_operations cy82c693_port_ops = {
118 119
	.inherits	= &ata_bmdma_port_ops,
	.cable_detect	= ata_cable_40wire,
120 121
	.set_piomode	= cy82c693_set_piomode,
	.set_dmamode	= cy82c693_set_dmamode,
122
};
123 124 125

static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
Tejun Heo's avatar
Tejun Heo committed
126
	static const struct ata_port_info info = {
127
		.flags = ATA_FLAG_SLAVE_POSS,
128 129
		.pio_mask = ATA_PIO4,
		.mwdma_mask = ATA_MWDMA2,
130 131
		.port_ops = &cy82c693_port_ops
	};
Tejun Heo's avatar
Tejun Heo committed
132
	const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
133

134 135
	/* Devfn 1 is the ATA primary. The secondary is magic and on devfn2.
	   For the moment we don't handle the secondary. FIXME */
136

137 138
	if (PCI_FUNC(pdev->devfn) != 1)
		return -ENODEV;
139

140
	return ata_pci_bmdma_init_one(pdev, ppi, &cy82c693_sht, NULL, 0);
141 142
}

143 144 145 146
static const struct pci_device_id cy82c693[] = {
	{ PCI_VDEVICE(CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693), },

	{ },
147 148 149
};

static struct pci_driver cy82c693_pci_driver = {
150
	.name 		= DRV_NAME,
151 152
	.id_table	= cy82c693,
	.probe 		= cy82c693_init_one,
153
	.remove		= ata_pci_remove_one,
154
#ifdef CONFIG_PM_SLEEP
155 156
	.suspend	= ata_pci_device_suspend,
	.resume		= ata_pci_device_resume,
157
#endif
158 159
};

Axel Lin's avatar
Axel Lin committed
160
module_pci_driver(cy82c693_pci_driver);
161 162 163 164 165 166

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for the CY82C693 PATA controller");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, cy82c693);
MODULE_VERSION(DRV_VERSION);