Blame view
drivers/ide/cy82c693.c
6.29 KB
09c434b8a treewide: Add SPD... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
1da177e4c Linux-2.6.12-rc2 |
2 |
/* |
1da177e4c Linux-2.6.12-rc2 |
3 4 |
* Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator |
0ab3d8b32 cy82c693: fix PCI... |
5 |
* Copyright (C) 2007-2011 Bartlomiej Zolnierkiewicz |
1da177e4c Linux-2.6.12-rc2 |
6 7 8 9 |
* * CYPRESS CY82C693 chipset IDE controller * * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards. |
1da177e4c Linux-2.6.12-rc2 |
10 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 |
#include <linux/module.h> #include <linux/types.h> #include <linux/pci.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 17 |
#include <linux/ide.h> #include <linux/init.h> #include <asm/io.h> |
ced3ec8aa ide: prefix messa... |
18 |
#define DRV_NAME "cy82c693" |
1da177e4c Linux-2.6.12-rc2 |
19 |
/* |
1da177e4c Linux-2.6.12-rc2 |
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
* NOTE: the value for busmaster timeout is tricky and I got it by * trial and error! By using a to low value will cause DMA timeouts * and drop IDE performance, and by using a to high value will cause * audio playback to scatter. * If you know a better value or how to calc it, please let me know. */ /* twice the value written in cy82c693ub datasheet */ #define BUSMASTER_TIMEOUT 0x50 /* * the value above was tested on my machine and it seems to work okay */ /* here are the offset definitions for the registers */ #define CY82_IDE_CMDREG 0x04 #define CY82_IDE_ADDRSETUP 0x48 #define CY82_IDE_MASTER_IOR 0x4C #define CY82_IDE_MASTER_IOW 0x4D #define CY82_IDE_SLAVE_IOR 0x4E #define CY82_IDE_SLAVE_IOW 0x4F #define CY82_IDE_MASTER_8BIT 0x50 #define CY82_IDE_SLAVE_8BIT 0x51 #define CY82_INDEX_PORT 0x22 #define CY82_DATA_PORT 0x23 |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 |
#define CY82_INDEX_CHANNEL0 0x30 #define CY82_INDEX_CHANNEL1 0x31 #define CY82_INDEX_TIMEOUT 0x32 |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 |
/* * set DMA mode a specific channel for CY82C693 */ |
8776168ca ide: change ->set... |
51 |
static void cy82c693_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
52 |
{ |
8776168ca ide: change ->set... |
53 |
const u8 mode = drive->dma_mode; |
8704de8f2 cy82c693: add ->s... |
54 |
u8 single = (mode & 0x10) >> 4, index = 0, data = 0; |
1da177e4c Linux-2.6.12-rc2 |
55 |
|
8704de8f2 cy82c693: add ->s... |
56 |
index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0; |
1da177e4c Linux-2.6.12-rc2 |
57 |
|
8704de8f2 cy82c693: add ->s... |
58 |
data = (mode & 3) | (single << 2); |
1da177e4c Linux-2.6.12-rc2 |
59 |
|
0ecdca26e ide: use PIO/MMIO... |
60 61 |
outb(index, CY82_INDEX_PORT); outb(data, CY82_DATA_PORT); |
1da177e4c Linux-2.6.12-rc2 |
62 |
|
175f354b7 IDE: Coding Style... |
63 |
/* |
1da177e4c Linux-2.6.12-rc2 |
64 |
* note: below we set the value for Bus Master IDE TimeOut Register |
25985edce Fix common misspe... |
65 |
* I'm not absolutely sure what this does, but it solved my problem |
1da177e4c Linux-2.6.12-rc2 |
66 67 68 69 70 71 72 73 |
* with IDE DMA and sound, so I now can play sound and work with * my IDE driver at the same time :-) * * If you know the correct (best) value for this register please * let me know - ASK */ data = BUSMASTER_TIMEOUT; |
0ecdca26e ide: use PIO/MMIO... |
74 75 |
outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT); outb(data, CY82_DATA_PORT); |
1da177e4c Linux-2.6.12-rc2 |
76 |
} |
e085b3cae ide: change ->set... |
77 |
static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
78 |
{ |
36501650e ide: keep pointer... |
79 |
struct pci_dev *dev = to_pci_dev(hwif->dev); |
4d6b32894 cy82c693: fix PIO... |
80 81 |
int bus_speed = ide_pci_clk ? ide_pci_clk : 33; const unsigned long T = 1000000 / bus_speed; |
1da177e4c Linux-2.6.12-rc2 |
82 |
unsigned int addrCtrl; |
4d6b32894 cy82c693: fix PIO... |
83 84 |
struct ide_timing t; u8 time_16, time_8; |
1da177e4c Linux-2.6.12-rc2 |
85 86 |
/* select primary or secondary channel */ |
0ab3d8b32 cy82c693: fix PCI... |
87 |
if (drive->dn > 1) { /* drive is on the secondary channel */ |
652aa1629 [PATCH] IDE: more... |
88 |
dev = pci_get_slot(dev->bus, dev->devfn+1); |
1da177e4c Linux-2.6.12-rc2 |
89 90 91 92 93 94 95 96 |
if (!dev) { printk(KERN_ERR "%s: tune_drive: " "Cannot find secondary interface! ", drive->name); return; } } |
e085b3cae ide: change ->set... |
97 |
ide_timing_compute(drive, drive->pio_mode, &t, T, 1); |
4d6b32894 cy82c693: fix PIO... |
98 99 100 101 102 |
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); |
1da177e4c Linux-2.6.12-rc2 |
103 104 |
/* now let's write the clocks registers */ |
123995b97 ide: use 'drive->... |
105 |
if ((drive->dn & 1) == 0) { |
1da177e4c Linux-2.6.12-rc2 |
106 107 108 109 |
/* * set master drive * address setup control register * is 32 bit !!! |
175f354b7 IDE: Coding Style... |
110 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
111 |
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); |
175f354b7 IDE: Coding Style... |
112 |
|
1da177e4c Linux-2.6.12-rc2 |
113 |
addrCtrl &= (~0xF); |
4d6b32894 cy82c693: fix PIO... |
114 |
addrCtrl |= clamp_val(t.setup - 1, 0, 15); |
1da177e4c Linux-2.6.12-rc2 |
115 116 117 |
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); /* now let's set the remaining registers */ |
4d6b32894 cy82c693: fix PIO... |
118 119 120 |
pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, time_16); pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, time_16); pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, time_8); |
1da177e4c Linux-2.6.12-rc2 |
121 122 123 124 125 |
} else { /* * set slave drive * address setup control register * is 32 bit !!! |
175f354b7 IDE: Coding Style... |
126 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
127 128 129 |
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); addrCtrl &= (~0xF0); |
4d6b32894 cy82c693: fix PIO... |
130 |
addrCtrl |= (clamp_val(t.setup - 1, 0, 15) << 4); |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 |
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); /* now let's set the remaining registers */ |
4d6b32894 cy82c693: fix PIO... |
134 135 136 |
pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, time_16); pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16); pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8); |
175f354b7 IDE: Coding Style... |
137 |
} |
0ab3d8b32 cy82c693: fix PCI... |
138 |
if (drive->dn > 1) |
0302899e1 drivers/ide/cy82c... |
139 |
pci_dev_put(dev); |
1da177e4c Linux-2.6.12-rc2 |
140 |
} |
fe31edc8a Drivers: ide: rem... |
141 |
static void init_iops_cy82c693(ide_hwif_t *hwif) |
1da177e4c Linux-2.6.12-rc2 |
142 |
{ |
f32d26ae2 cy82c693: fix bui... |
143 |
static ide_hwif_t *primary; |
36501650e ide: keep pointer... |
144 |
struct pci_dev *dev = to_pci_dev(hwif->dev); |
f32d26ae2 cy82c693: fix bui... |
145 |
|
36501650e ide: keep pointer... |
146 |
if (PCI_FUNC(dev->devfn) == 1) |
1da177e4c Linux-2.6.12-rc2 |
147 148 149 150 151 152 |
primary = hwif; else { hwif->mate = primary; hwif->channel = 1; } } |
ac95beedf ide: add struct i... |
153 154 155 156 |
static const struct ide_port_ops cy82c693_port_ops = { .set_pio_mode = cy82c693_set_pio_mode, .set_dma_mode = cy82c693_set_dma_mode, }; |
fe31edc8a Drivers: ide: rem... |
157 |
static const struct ide_port_info cy82c693_chipset = { |
ced3ec8aa ide: prefix messa... |
158 |
.name = DRV_NAME, |
7b77d864a ide: remove ide_p... |
159 |
.init_iops = init_iops_cy82c693, |
ac95beedf ide: add struct i... |
160 |
.port_ops = &cy82c693_port_ops, |
951784b66 ide: remove IDE_H... |
161 |
.host_flags = IDE_HFLAG_SINGLE, |
4099d1432 ide: add PIO masks |
162 |
.pio_mask = ATA_PIO4, |
8704de8f2 cy82c693: add ->s... |
163 164 |
.swdma_mask = ATA_SWDMA2, .mwdma_mask = ATA_MWDMA2, |
1da177e4c Linux-2.6.12-rc2 |
165 |
}; |
fe31edc8a Drivers: ide: rem... |
166 167 |
static int cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
1da177e4c Linux-2.6.12-rc2 |
168 |
{ |
1da177e4c Linux-2.6.12-rc2 |
169 170 171 172 173 |
struct pci_dev *dev2; int ret = -ENODEV; /* CY82C693 is more than only a IDE controller. Function 1 is primary IDE channel, function 2 - secondary. */ |
175f354b7 IDE: Coding Style... |
174 |
if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && |
1da177e4c Linux-2.6.12-rc2 |
175 |
PCI_FUNC(dev->devfn) == 1) { |
652aa1629 [PATCH] IDE: more... |
176 |
dev2 = pci_get_slot(dev->bus, dev->devfn + 1); |
6cdf6eb35 ide: add ->dev an... |
177 |
ret = ide_pci_init_two(dev, dev2, &cy82c693_chipset, NULL); |
cd68841b8 cy82c693: add ->r... |
178 179 |
if (ret) pci_dev_put(dev2); |
1da177e4c Linux-2.6.12-rc2 |
180 181 182 |
} return ret; } |
fe31edc8a Drivers: ide: rem... |
183 |
static void cy82c693_remove(struct pci_dev *dev) |
cd68841b8 cy82c693: add ->r... |
184 185 186 187 188 189 190 |
{ struct ide_host *host = pci_get_drvdata(dev); struct pci_dev *dev2 = host->dev[1] ? to_pci_dev(host->dev[1]) : NULL; ide_pci_remove(dev); pci_dev_put(dev2); } |
9cbcc5e3c ide: use PCI_VDEV... |
191 192 |
static const struct pci_device_id cy82c693_pci_tbl[] = { { PCI_VDEVICE(CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693), 0 }, |
1da177e4c Linux-2.6.12-rc2 |
193 194 195 |
{ 0, }, }; MODULE_DEVICE_TABLE(pci, cy82c693_pci_tbl); |
a9ab09e26 ide: use unique n... |
196 |
static struct pci_driver cy82c693_pci_driver = { |
1da177e4c Linux-2.6.12-rc2 |
197 198 199 |
.name = "Cypress_IDE", .id_table = cy82c693_pci_tbl, .probe = cy82c693_init_one, |
fe31edc8a Drivers: ide: rem... |
200 |
.remove = cy82c693_remove, |
feb22b7f8 ide: add proper P... |
201 202 |
.suspend = ide_pci_suspend, .resume = ide_pci_resume, |
1da177e4c Linux-2.6.12-rc2 |
203 |
}; |
82ab1eece ide: add missing ... |
204 |
static int __init cy82c693_ide_init(void) |
1da177e4c Linux-2.6.12-rc2 |
205 |
{ |
a9ab09e26 ide: use unique n... |
206 |
return ide_pci_register_driver(&cy82c693_pci_driver); |
1da177e4c Linux-2.6.12-rc2 |
207 |
} |
cd68841b8 cy82c693: add ->r... |
208 209 |
static void __exit cy82c693_ide_exit(void) { |
a9ab09e26 ide: use unique n... |
210 |
pci_unregister_driver(&cy82c693_pci_driver); |
cd68841b8 cy82c693: add ->r... |
211 |
} |
1da177e4c Linux-2.6.12-rc2 |
212 |
module_init(cy82c693_ide_init); |
cd68841b8 cy82c693: add ->r... |
213 |
module_exit(cy82c693_ide_exit); |
1da177e4c Linux-2.6.12-rc2 |
214 |
|
4d6b32894 cy82c693: fix PIO... |
215 |
MODULE_AUTHOR("Andreas Krebs, Andre Hedrick, Bartlomiej Zolnierkiewicz"); |
1da177e4c Linux-2.6.12-rc2 |
216 217 |
MODULE_DESCRIPTION("PCI driver module for the Cypress CY82C693 IDE"); MODULE_LICENSE("GPL"); |