1/* 2 * IDE Chipset driver for the Compaq TriFlex IDE controller. 3 * 4 * Known to work with the Compaq Workstation 5x00 series. 5 * 6 * Copyright (C) 2002 Hewlett-Packard Development Group, L.P. 7 * Author: Torben Mathiasen <torben.mathiasen@hp.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 * Loosely based on the piix & svwks drivers. 23 * 24 * Documentation: 25 * Not publicly available. 26 */ 27 28#include <linux/types.h> 29#include <linux/module.h> 30#include <linux/kernel.h> 31#include <linux/pci.h> 32#include <linux/ide.h> 33#include <linux/init.h> 34 35#define DRV_NAME "triflex" 36 37static void triflex_set_mode(ide_hwif_t *hwif, ide_drive_t *drive) 38{ 39 struct pci_dev *dev = to_pci_dev(hwif->dev); 40 u32 triflex_timings = 0; 41 u16 timing = 0; 42 u8 channel_offset = hwif->channel ? 0x74 : 0x70, unit = drive->dn & 1; 43 44 pci_read_config_dword(dev, channel_offset, &triflex_timings); 45 46 switch (drive->dma_mode) { 47 case XFER_MW_DMA_2: 48 timing = 0x0103; 49 break; 50 case XFER_MW_DMA_1: 51 timing = 0x0203; 52 break; 53 case XFER_MW_DMA_0: 54 timing = 0x0808; 55 break; 56 case XFER_SW_DMA_2: 57 case XFER_SW_DMA_1: 58 case XFER_SW_DMA_0: 59 timing = 0x0f0f; 60 break; 61 case XFER_PIO_4: 62 timing = 0x0202; 63 break; 64 case XFER_PIO_3: 65 timing = 0x0204; 66 break; 67 case XFER_PIO_2: 68 timing = 0x0404; 69 break; 70 case XFER_PIO_1: 71 timing = 0x0508; 72 break; 73 case XFER_PIO_0: 74 timing = 0x0808; 75 break; 76 } 77 78 triflex_timings &= ~(0xFFFF << (16 * unit)); 79 triflex_timings |= (timing << (16 * unit)); 80 81 pci_write_config_dword(dev, channel_offset, triflex_timings); 82} 83 84static void triflex_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) 85{ 86 drive->dma_mode = drive->pio_mode; 87 triflex_set_mode(hwif, drive); 88} 89 90static const struct ide_port_ops triflex_port_ops = { 91 .set_pio_mode = triflex_set_pio_mode, 92 .set_dma_mode = triflex_set_mode, 93}; 94 95static const struct ide_port_info triflex_device = { 96 .name = DRV_NAME, 97 .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, 98 .port_ops = &triflex_port_ops, 99 .pio_mask = ATA_PIO4, 100 .swdma_mask = ATA_SWDMA2, 101 .mwdma_mask = ATA_MWDMA2, 102}; 103 104static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) 105{ 106 return ide_pci_init_one(dev, &triflex_device, NULL); 107} 108 109static const struct pci_device_id triflex_pci_tbl[] = { 110 { PCI_VDEVICE(COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE), 0 }, 111 { 0, }, 112}; 113MODULE_DEVICE_TABLE(pci, triflex_pci_tbl); 114 115#ifdef CONFIG_PM 116static int triflex_ide_pci_suspend(struct pci_dev *dev, pm_message_t state) 117{ 118 /* 119 * We must not disable or powerdown the device. 120 * APM bios refuses to suspend if IDE is not accessible. 121 */ 122 pci_save_state(dev); 123 return 0; 124} 125#else 126#define triflex_ide_pci_suspend NULL 127#endif 128 129static struct pci_driver triflex_pci_driver = { 130 .name = "TRIFLEX_IDE", 131 .id_table = triflex_pci_tbl, 132 .probe = triflex_init_one, 133 .remove = ide_pci_remove, 134 .suspend = triflex_ide_pci_suspend, 135 .resume = ide_pci_resume, 136}; 137 138static int __init triflex_ide_init(void) 139{ 140 return ide_pci_register_driver(&triflex_pci_driver); 141} 142 143static void __exit triflex_ide_exit(void) 144{ 145 pci_unregister_driver(&triflex_pci_driver); 146} 147 148module_init(triflex_ide_init); 149module_exit(triflex_ide_exit); 150 151MODULE_AUTHOR("Torben Mathiasen"); 152MODULE_DESCRIPTION("PCI driver module for Compaq Triflex IDE"); 153MODULE_LICENSE("GPL"); 154 155 156