drivers: power: report battery voltage in AOSP compatible format
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / ide / ide-cs.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 A driver for PCMCIA IDE/ATA disk cards
4
1da177e4
LT
5 The contents of this file are subject to the Mozilla Public
6 License Version 1.1 (the "License"); you may not use this file
7 except in compliance with the License. You may obtain a copy of
8 the License at http://www.mozilla.org/MPL/
9
10 Software distributed under the License is distributed on an "AS
11 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
12 implied. See the License for the specific language governing
13 rights and limitations under the License.
14
15 The initial developer of the original code is David A. Hinds
16 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
17 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
18
19 Alternatively, the contents of this file may be used under the
20 terms of the GNU General Public License version 2 (the "GPL"), in
21 which case the provisions of the GPL are applicable instead of the
22 above. If you wish to allow the use of your version of this file
23 only under the terms of the GPL and not to allow others to use
24 your version of this file under the MPL, indicate your decision
25 by deleting the provisions above and replace them with the notice
26 and other provisions required by the GPL. If you do not delete
27 the provisions above, a recipient may use your version of this
28 file under either the MPL or the GPL.
7b1dec59 29
1da177e4
LT
30======================================================================*/
31
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/init.h>
1da177e4
LT
35#include <linux/ptrace.h>
36#include <linux/slab.h>
37#include <linux/string.h>
38#include <linux/timer.h>
39#include <linux/ioport.h>
40#include <linux/ide.h>
1da177e4 41#include <linux/major.h>
2aad5f03 42#include <linux/delay.h>
1da177e4 43#include <asm/io.h>
1da177e4 44
1da177e4
LT
45#include <pcmcia/cistpl.h>
46#include <pcmcia/ds.h>
47#include <pcmcia/cisreg.h>
48#include <pcmcia/ciscode.h>
49
d703b79e
BZ
50#define DRV_NAME "ide-cs"
51
1da177e4
LT
52/*====================================================================*/
53
54/* Module parameters */
55
56MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
57MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
58MODULE_LICENSE("Dual MPL/GPL");
59
1da177e4
LT
60/*====================================================================*/
61
1da177e4 62typedef struct ide_info_t {
fd238232 63 struct pcmcia_device *p_dev;
48c3c107 64 struct ide_host *host;
ded6a1a3 65 int ndev;
1da177e4
LT
66} ide_info_t;
67
fba395ee 68static void ide_release(struct pcmcia_device *);
15b99ac1 69static int ide_config(struct pcmcia_device *);
1da177e4 70
cc3b4866 71static void ide_detach(struct pcmcia_device *p_dev);
1da177e4 72
15b99ac1 73static int ide_probe(struct pcmcia_device *link)
1da177e4
LT
74{
75 ide_info_t *info;
f8cfa618 76
444486a5 77 dev_dbg(&link->dev, "ide_attach()\n");
1da177e4
LT
78
79 /* Create new ide device */
f5e3c2fa 80 info = kzalloc(sizeof(*info), GFP_KERNEL);
f8cfa618
DB
81 if (!info)
82 return -ENOMEM;
fd238232 83
fba395ee 84 info->p_dev = link;
fd238232 85 link->priv = info;
1da177e4 86
00990e7c
DB
87 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
88 CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
f8cfa618 89
15b99ac1 90 return ide_config(link);
1da177e4
LT
91} /* ide_attach */
92
fba395ee 93static void ide_detach(struct pcmcia_device *link)
1da177e4 94{
d703b79e 95 ide_info_t *info = link->priv;
d703b79e 96
444486a5 97 dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
1da177e4 98
e2d40963 99 ide_release(link);
b4635811 100
d703b79e 101 kfree(info);
1da177e4
LT
102} /* ide_detach */
103
ac95beed
BZ
104static const struct ide_port_ops idecs_port_ops = {
105 .quirkproc = ide_undecoded_slave,
106};
107
dccdf527
BZ
108static const struct ide_port_info idecs_port_info = {
109 .port_ops = &idecs_port_ops,
110 .host_flags = IDE_HFLAG_NO_DMA,
255115fb 111 .irq_flags = IRQF_SHARED,
29e52cf7 112 .chipset = ide_pci,
dccdf527
BZ
113};
114
48c3c107 115static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
d703b79e 116 unsigned long irq, struct pcmcia_device *handle)
1da177e4 117{
48c3c107 118 struct ide_host *host;
9e016a71 119 ide_hwif_t *hwif;
6f904d01 120 int i, rc;
9f36d314 121 struct ide_hw hw, *hws[] = { &hw };
9e016a71 122
d703b79e
BZ
123 if (!request_region(io, 8, DRV_NAME)) {
124 printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
125 DRV_NAME, io, io + 7);
126 return NULL;
127 }
128
129 if (!request_region(ctl, 1, DRV_NAME)) {
130 printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
131 DRV_NAME, ctl);
132 release_region(io, 8);
133 return NULL;
134 }
135
1da177e4 136 memset(&hw, 0, sizeof(hw));
dcb425f5 137 ide_std_init_ports(&hw, io, ctl);
1da177e4 138 hw.irq = irq;
4349d5cd 139 hw.dev = &handle->dev;
9e016a71 140
dca39830 141 rc = ide_host_add(&idecs_port_info, hws, 1, &host);
6f904d01 142 if (rc)
d703b79e 143 goto out_release;
9e016a71 144
48c3c107 145 hwif = host->ports[0];
9e016a71 146
d703b79e 147 if (hwif->present)
48c3c107 148 return host;
d703b79e 149
792a1a98
BZ
150 /* retry registration in case device is still spinning up */
151 for (i = 0; i < 10; i++) {
152 msleep(100);
153 ide_port_scan(hwif);
154 if (hwif->present)
48c3c107 155 return host;
792a1a98
BZ
156 }
157
48c3c107 158 return host;
792a1a98 159
d703b79e
BZ
160out_release:
161 release_region(ctl, 1);
162 release_region(io, 8);
163 return NULL;
1da177e4
LT
164}
165
00990e7c 166static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
0bac660a 167{
00990e7c
DB
168 int *is_kme = priv_data;
169
e58c5de8
JL
170 if ((pdev->resource[0]->flags & IO_DATA_PATH_WIDTH)
171 != IO_DATA_PATH_WIDTH_8) {
00990e7c
DB
172 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
173 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
174 }
175 pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
176 pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
177
178 if (pdev->resource[1]->end) {
179 pdev->resource[0]->end = 8;
180 pdev->resource[1]->end = (*is_kme) ? 2 : 1;
181 } else {
182 if (pdev->resource[0]->end < 16)
8e2fc39d 183 return -ENODEV;
0bac660a 184 }
00990e7c
DB
185
186 return pcmcia_request_io(pdev);
0bac660a
DB
187}
188
15b99ac1 189static int ide_config(struct pcmcia_device *link)
1da177e4 190{
1da177e4 191 ide_info_t *info = link->priv;
444486a5 192 int ret = 0, is_kme = 0;
2f1b9250 193 unsigned long io_base, ctl_base;
48c3c107 194 struct ide_host *host;
1da177e4 195
444486a5 196 dev_dbg(&link->dev, "ide_config(0x%p)\n", link);
1da177e4 197
efd50585
DB
198 is_kme = ((link->manf_id == MANFID_KME) &&
199 ((link->card_id == PRODID_KME_KXLC005_A) ||
200 (link->card_id == PRODID_KME_KXLC005_B)));
1da177e4 201
00990e7c 202 if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) {
440eed43 203 link->config_flags &= ~CONF_AUTO_CHECK_VCC;
00990e7c 204 if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme))
0bac660a 205 goto failed; /* No suitable config found */
1da177e4 206 }
9a017a91 207 io_base = link->resource[0]->start;
00990e7c
DB
208 if (link->resource[1]->end)
209 ctl_base = link->resource[1]->start;
210 else
211 ctl_base = link->resource[0]->start + 0x0e;
1da177e4 212
eb14120f 213 if (!link->irq)
444486a5 214 goto failed;
1ac71e5a
DB
215
216 ret = pcmcia_enable_device(link);
444486a5
DB
217 if (ret)
218 goto failed;
1da177e4
LT
219
220 /* disable drive interrupts during IDE probe */
2f1b9250 221 outb(0x02, ctl_base);
1da177e4
LT
222
223 /* special setup for KXLC005 card */
224 if (is_kme)
2f1b9250 225 outb(0x81, ctl_base+1);
1da177e4 226
eb14120f 227 host = idecs_register(io_base, ctl_base, link->irq, link);
9a017a91 228 if (host == NULL && resource_size(link->resource[0]) == 0x20) {
2f1b9250 229 outb(0x02, ctl_base + 0x10);
48c3c107 230 host = idecs_register(io_base + 0x10, ctl_base + 0x10,
eb14120f 231 link->irq, link);
1da177e4
LT
232 }
233
48c3c107 234 if (host == NULL)
1da177e4 235 goto failed;
1da177e4
LT
236
237 info->ndev = 1;
48c3c107 238 info->host = host;
ded6a1a3
DB
239 dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n",
240 'a' + host->ports[0]->index * 2,
e8405f0f 241 link->vpp / 10, link->vpp % 10);
1da177e4 242
15b99ac1 243 return 0;
1da177e4 244
1da177e4 245failed:
1da177e4 246 ide_release(link);
15b99ac1 247 return -ENODEV;
1da177e4
LT
248} /* ide_config */
249
727c6742 250static void ide_release(struct pcmcia_device *link)
1da177e4
LT
251{
252 ide_info_t *info = link->priv;
48c3c107 253 struct ide_host *host = info->host;
7b1dec59 254
444486a5 255 dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
1da177e4 256
d4ae5415
WS
257 if (info->ndev) {
258 ide_hwif_t *hwif = host->ports[0];
259 unsigned long data_addr, ctl_addr;
260
261 data_addr = hwif->io_ports.data_addr;
262 ctl_addr = hwif->io_ports.ctl_addr;
263
48c3c107 264 ide_host_remove(host);
d4ae5415 265 info->ndev = 0;
48c3c107 266
d4ae5415
WS
267 release_region(ctl_addr, 1);
268 release_region(data_addr, 8);
269 }
1da177e4 270
fba395ee 271 pcmcia_disable_device(link);
1da177e4
LT
272} /* ide_release */
273
98e4c28b 274
25f8f54f 275static const struct pcmcia_device_id ide_ids[] = {
f70b7d40 276 PCMCIA_DEVICE_FUNC_ID(4),
7b1dec59 277 PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */
725a6abf 278 PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
ed896167
MD
279 PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */
280 PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */
f70b7d40 281 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
795659ef 282 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
ed896167 283 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
a49c06bf 284 PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */
795659ef 285 PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */
d3feb184 286 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
f70b7d40 287 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
d3feb184 288 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
7b1dec59 289 PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
f70b7d40 290 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
ed896167
MD
291 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100), /* Viking CFA */
292 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar, Viking CFA */
f70b7d40
DB
293 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
294 PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
295 PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
296 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
297 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
c9a2bfd1 298 PCMCIA_DEVICE_PROD_ID12("CNF ", "CD-ROM", 0x46d7db81, 0x66536591),
f70b7d40
DB
299 PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
300 PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
301 PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
d277ad0e 302 PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
f70b7d40
DB
303 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
304 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
305 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
725a6abf
RP
306 PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
307 PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
7b1dec59 308 PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
264a3412 309 PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
f70b7d40 310 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
85ea2d3f 311 PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
f25798ed 312 PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
363f7e42 313 PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
f70b7d40
DB
314 PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
315 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
316 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
317 PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b),
74e23386 318 PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee),
4fa902a9 319 PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
2570b746 320 PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
f70b7d40
DB
321 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
322 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
323 PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
4fa902a9
MJ
324 PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883),
325 PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
326 PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
f70b7d40 327 PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
42935656 328 PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
a17bf220 329 PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32),
bf4e1829 330 PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
aa12b284 331 PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
4fa902a9 332 PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
85ea2d3f 333 PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
f25798ed 334 PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
f70b7d40 335 PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
0517793f 336 PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
f70b7d40 337 PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
d3feb184 338 PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
698e22c4 339 PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
980fc29f 340 PCMCIA_DEVICE_PROD_ID2("Flash Card", 0x5a362506),
f70b7d40
DB
341 PCMCIA_DEVICE_NULL,
342};
343MODULE_DEVICE_TABLE(pcmcia, ide_ids);
344
1da177e4
LT
345static struct pcmcia_driver ide_cs_driver = {
346 .owner = THIS_MODULE,
2e9b981a 347 .name = "ide-cs",
15b99ac1 348 .probe = ide_probe,
cc3b4866 349 .remove = ide_detach,
f70b7d40 350 .id_table = ide_ids,
1da177e4
LT
351};
352
353static int __init init_ide_cs(void)
354{
355 return pcmcia_register_driver(&ide_cs_driver);
356}
357
358static void __exit exit_ide_cs(void)
359{
360 pcmcia_unregister_driver(&ide_cs_driver);
1da177e4
LT
361}
362
2b8d4669 363late_initcall(init_ide_cs);
1da177e4 364module_exit(exit_ide_cs);