treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / pcmcia / i82092.c
blob85887d885b5f39054ba1459c903a84e21b79735c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Driver for Intel I82092AA PCI-PCMCIA bridge.
5 * (C) 2001 Red Hat, Inc.
7 * Author: Arjan Van De Ven <arjanv@redhat.com>
8 * Loosly based on i82365.c from the pcmcia-cs package
9 */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/pci.h>
14 #include <linux/init.h>
15 #include <linux/workqueue.h>
16 #include <linux/interrupt.h>
17 #include <linux/device.h>
19 #include <pcmcia/ss.h>
21 #include <linux/io.h>
23 #include "i82092aa.h"
24 #include "i82365.h"
26 MODULE_LICENSE("GPL");
28 /* PCI core routines */
29 static const struct pci_device_id i82092aa_pci_ids[] = {
30 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82092AA_0) },
31 { }
33 MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
35 static struct pci_driver i82092aa_pci_driver = {
36 .name = "i82092aa",
37 .id_table = i82092aa_pci_ids,
38 .probe = i82092aa_pci_probe,
39 .remove = i82092aa_pci_remove,
43 /* the pccard structure and its functions */
44 static struct pccard_operations i82092aa_operations = {
45 .init = i82092aa_init,
46 .get_status = i82092aa_get_status,
47 .set_socket = i82092aa_set_socket,
48 .set_io_map = i82092aa_set_io_map,
49 .set_mem_map = i82092aa_set_mem_map,
52 /* The card can do up to 4 sockets, allocate a structure for each of them */
54 struct socket_info {
55 int number;
56 int card_state;
57 /* 0 = no socket,
58 * 1 = empty socket,
59 * 2 = card but not initialized,
60 * 3 = operational card
62 unsigned int io_base; /* base io address of the socket */
64 struct pcmcia_socket socket;
65 struct pci_dev *dev; /* The PCI device for the socket */
68 #define MAX_SOCKETS 4
69 static struct socket_info sockets[MAX_SOCKETS];
70 static int socket_count; /* shortcut */
73 static int i82092aa_pci_probe(struct pci_dev *dev,
74 const struct pci_device_id *id)
76 unsigned char configbyte;
77 int i, ret;
79 ret = pci_enable_device(dev);
80 if (ret)
81 return ret;
83 /* PCI Configuration Control */
84 pci_read_config_byte(dev, 0x40, &configbyte);
86 switch (configbyte&6) {
87 case 0:
88 socket_count = 2;
89 break;
90 case 2:
91 socket_count = 1;
92 break;
93 case 4:
94 case 6:
95 socket_count = 4;
96 break;
98 default:
99 dev_err(&dev->dev,
100 "Oops, you did something we didn't think of.\n");
101 ret = -EIO;
102 goto err_out_disable;
104 dev_info(&dev->dev, "configured as a %d socket device.\n",
105 socket_count);
107 if (!request_region(pci_resource_start(dev, 0), 2, "i82092aa")) {
108 ret = -EBUSY;
109 goto err_out_disable;
112 for (i = 0; i < socket_count; i++) {
113 sockets[i].card_state = 1; /* 1 = present but empty */
114 sockets[i].io_base = pci_resource_start(dev, 0);
115 sockets[i].socket.features |= SS_CAP_PCCARD;
116 sockets[i].socket.map_size = 0x1000;
117 sockets[i].socket.irq_mask = 0;
118 sockets[i].socket.pci_irq = dev->irq;
119 sockets[i].socket.cb_dev = dev;
120 sockets[i].socket.owner = THIS_MODULE;
122 sockets[i].number = i;
124 if (card_present(i)) {
125 sockets[i].card_state = 3;
126 dev_dbg(&dev->dev, "slot %i is occupied\n", i);
127 } else {
128 dev_dbg(&dev->dev, "slot %i is vacant\n", i);
132 /* Now, specifiy that all interrupts are to be done as PCI interrupts
133 * bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt
135 configbyte = 0xFF;
137 /* PCI Interrupt Routing Register */
138 pci_write_config_byte(dev, 0x50, configbyte);
140 /* Register the interrupt handler */
141 dev_dbg(&dev->dev, "Requesting interrupt %i\n", dev->irq);
142 ret = request_irq(dev->irq, i82092aa_interrupt, IRQF_SHARED,
143 "i82092aa", i82092aa_interrupt);
144 if (ret) {
145 dev_err(&dev->dev, "Failed to register IRQ %d, aborting\n",
146 dev->irq);
147 goto err_out_free_res;
150 for (i = 0; i < socket_count; i++) {
151 sockets[i].socket.dev.parent = &dev->dev;
152 sockets[i].socket.ops = &i82092aa_operations;
153 sockets[i].socket.resource_ops = &pccard_nonstatic_ops;
154 ret = pcmcia_register_socket(&sockets[i].socket);
155 if (ret)
156 goto err_out_free_sockets;
159 return 0;
161 err_out_free_sockets:
162 if (i) {
163 for (i--; i >= 0; i--)
164 pcmcia_unregister_socket(&sockets[i].socket);
166 free_irq(dev->irq, i82092aa_interrupt);
167 err_out_free_res:
168 release_region(pci_resource_start(dev, 0), 2);
169 err_out_disable:
170 pci_disable_device(dev);
171 return ret;
174 static void i82092aa_pci_remove(struct pci_dev *dev)
176 int i;
178 free_irq(dev->irq, i82092aa_interrupt);
180 for (i = 0; i < socket_count; i++)
181 pcmcia_unregister_socket(&sockets[i].socket);
184 static DEFINE_SPINLOCK(port_lock);
186 /* basic value read/write functions */
188 static unsigned char indirect_read(int socket, unsigned short reg)
190 unsigned short int port;
191 unsigned char val;
192 unsigned long flags;
194 spin_lock_irqsave(&port_lock, flags);
195 reg += socket * 0x40;
196 port = sockets[socket].io_base;
197 outb(reg, port);
198 val = inb(port+1);
199 spin_unlock_irqrestore(&port_lock, flags);
200 return val;
203 static void indirect_write(int socket, unsigned short reg, unsigned char value)
205 unsigned short int port;
206 unsigned long flags;
208 spin_lock_irqsave(&port_lock, flags);
209 reg = reg + socket * 0x40;
210 port = sockets[socket].io_base;
211 outb(reg, port);
212 outb(value, port+1);
213 spin_unlock_irqrestore(&port_lock, flags);
216 static void indirect_setbit(int socket, unsigned short reg, unsigned char mask)
218 unsigned short int port;
219 unsigned char val;
220 unsigned long flags;
222 spin_lock_irqsave(&port_lock, flags);
223 reg = reg + socket * 0x40;
224 port = sockets[socket].io_base;
225 outb(reg, port);
226 val = inb(port+1);
227 val |= mask;
228 outb(reg, port);
229 outb(val, port+1);
230 spin_unlock_irqrestore(&port_lock, flags);
234 static void indirect_resetbit(int socket,
235 unsigned short reg, unsigned char mask)
237 unsigned short int port;
238 unsigned char val;
239 unsigned long flags;
241 spin_lock_irqsave(&port_lock, flags);
242 reg = reg + socket * 0x40;
243 port = sockets[socket].io_base;
244 outb(reg, port);
245 val = inb(port+1);
246 val &= ~mask;
247 outb(reg, port);
248 outb(val, port+1);
249 spin_unlock_irqrestore(&port_lock, flags);
252 static void indirect_write16(int socket,
253 unsigned short reg, unsigned short value)
255 unsigned short int port;
256 unsigned char val;
257 unsigned long flags;
259 spin_lock_irqsave(&port_lock, flags);
260 reg = reg + socket * 0x40;
261 port = sockets[socket].io_base;
263 outb(reg, port);
264 val = value & 255;
265 outb(val, port+1);
267 reg++;
269 outb(reg, port);
270 val = value>>8;
271 outb(val, port+1);
272 spin_unlock_irqrestore(&port_lock, flags);
275 /* simple helper functions */
276 /* External clock time, in nanoseconds. 120 ns = 8.33 MHz */
277 static int cycle_time = 120;
279 static int to_cycles(int ns)
281 if (cycle_time != 0)
282 return ns/cycle_time;
283 else
284 return 0;
288 /* Interrupt handler functionality */
290 static irqreturn_t i82092aa_interrupt(int irq, void *dev)
292 int i;
293 int loopcount = 0;
294 int handled = 0;
296 unsigned int events, active = 0;
298 while (1) {
299 loopcount++;
300 if (loopcount > 20) {
301 pr_err("i82092aa: infinite eventloop in interrupt\n");
302 break;
305 active = 0;
307 for (i = 0; i < socket_count; i++) {
308 int csc;
310 /* Inactive socket, should not happen */
311 if (sockets[i].card_state == 0)
312 continue;
314 /* card status change register */
315 csc = indirect_read(i, I365_CSC);
317 if (csc == 0) /* no events on this socket */
318 continue;
319 handled = 1;
320 events = 0;
322 if (csc & I365_CSC_DETECT) {
323 events |= SS_DETECT;
324 dev_info(&sockets[i].dev->dev,
325 "Card detected in socket %i!\n", i);
328 if (indirect_read(i, I365_INTCTL) & I365_PC_IOCARD) {
329 /* For IO/CARDS, bit 0 means "read the card" */
330 if (csc & I365_CSC_STSCHG)
331 events |= SS_STSCHG;
332 } else {
333 /* Check for battery/ready events */
334 if (csc & I365_CSC_BVD1)
335 events |= SS_BATDEAD;
336 if (csc & I365_CSC_BVD2)
337 events |= SS_BATWARN;
338 if (csc & I365_CSC_READY)
339 events |= SS_READY;
342 if (events)
343 pcmcia_parse_events(&sockets[i].socket, events);
344 active |= events;
347 if (active == 0) /* no more events to handle */
348 break;
350 return IRQ_RETVAL(handled);
355 /* socket functions */
357 static int card_present(int socketno)
359 unsigned int val;
361 if ((socketno < 0) || (socketno >= MAX_SOCKETS))
362 return 0;
363 if (sockets[socketno].io_base == 0)
364 return 0;
367 val = indirect_read(socketno, 1); /* Interface status register */
368 if ((val&12) == 12)
369 return 1;
371 return 0;
374 static void set_bridge_state(int sock)
376 indirect_write(sock, I365_GBLCTL, 0x00);
377 indirect_write(sock, I365_GENCTL, 0x00);
379 indirect_setbit(sock, I365_INTCTL, 0x08);
383 static int i82092aa_init(struct pcmcia_socket *sock)
385 int i;
386 struct resource res = { .start = 0, .end = 0x0fff };
387 pccard_io_map io = { 0, 0, 0, 0, 1 };
388 pccard_mem_map mem = { .res = &res, };
390 for (i = 0; i < 2; i++) {
391 io.map = i;
392 i82092aa_set_io_map(sock, &io);
394 for (i = 0; i < 5; i++) {
395 mem.map = i;
396 i82092aa_set_mem_map(sock, &mem);
399 return 0;
402 static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
404 unsigned int sock = container_of(socket,
405 struct socket_info, socket)->number;
406 unsigned int status;
408 /* Interface Status Register */
409 status = indirect_read(sock, I365_STATUS);
411 *value = 0;
413 if ((status & I365_CS_DETECT) == I365_CS_DETECT)
414 *value |= SS_DETECT;
416 /* IO cards have a different meaning of bits 0,1 */
417 /* Also notice the inverse-logic on the bits */
418 if (indirect_read(sock, I365_INTCTL) & I365_PC_IOCARD) {
419 /* IO card */
420 if (!(status & I365_CS_STSCHG))
421 *value |= SS_STSCHG;
422 } else { /* non I/O card */
423 if (!(status & I365_CS_BVD1))
424 *value |= SS_BATDEAD;
425 if (!(status & I365_CS_BVD2))
426 *value |= SS_BATWARN;
429 if (status & I365_CS_WRPROT)
430 (*value) |= SS_WRPROT; /* card is write protected */
432 if (status & I365_CS_READY)
433 (*value) |= SS_READY; /* card is not busy */
435 if (status & I365_CS_POWERON)
436 (*value) |= SS_POWERON; /* power is applied to the card */
438 return 0;
442 static int i82092aa_set_socket(struct pcmcia_socket *socket,
443 socket_state_t *state)
445 struct socket_info *sock_info = container_of(socket, struct socket_info,
446 socket);
447 unsigned int sock = sock_info->number;
448 unsigned char reg;
450 /* First, set the global controller options */
452 set_bridge_state(sock);
454 /* Values for the IGENC register */
456 reg = 0;
458 /* The reset bit has "inverse" logic */
459 if (!(state->flags & SS_RESET))
460 reg = reg | I365_PC_RESET;
461 if (state->flags & SS_IOCARD)
462 reg = reg | I365_PC_IOCARD;
464 /* IGENC, Interrupt and General Control Register */
465 indirect_write(sock, I365_INTCTL, reg);
467 /* Power registers */
469 reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
471 if (state->flags & SS_PWR_AUTO) {
472 dev_info(&sock_info->dev->dev, "Auto power\n");
473 reg |= I365_PWR_AUTO; /* automatic power mngmnt */
475 if (state->flags & SS_OUTPUT_ENA) {
476 dev_info(&sock_info->dev->dev, "Power Enabled\n");
477 reg |= I365_PWR_OUT; /* enable power */
480 switch (state->Vcc) {
481 case 0:
482 break;
483 case 50:
484 dev_info(&sock_info->dev->dev,
485 "setting voltage to Vcc to 5V on socket %i\n",
486 sock);
487 reg |= I365_VCC_5V;
488 break;
489 default:
490 dev_err(&sock_info->dev->dev,
491 "%s called with invalid VCC power value: %i",
492 __func__, state->Vcc);
493 return -EINVAL;
496 switch (state->Vpp) {
497 case 0:
498 dev_info(&sock_info->dev->dev,
499 "not setting Vpp on socket %i\n", sock);
500 break;
501 case 50:
502 dev_info(&sock_info->dev->dev,
503 "setting Vpp to 5.0 for socket %i\n", sock);
504 reg |= I365_VPP1_5V | I365_VPP2_5V;
505 break;
506 case 120:
507 dev_info(&sock_info->dev->dev, "setting Vpp to 12.0\n");
508 reg |= I365_VPP1_12V | I365_VPP2_12V;
509 break;
510 default:
511 dev_err(&sock_info->dev->dev,
512 "%s called with invalid VPP power value: %i",
513 __func__, state->Vcc);
514 return -EINVAL;
517 if (reg != indirect_read(sock, I365_POWER)) /* only write if changed */
518 indirect_write(sock, I365_POWER, reg);
520 /* Enable specific interrupt events */
522 reg = 0x00;
523 if (state->csc_mask & SS_DETECT)
524 reg |= I365_CSC_DETECT;
525 if (state->flags & SS_IOCARD) {
526 if (state->csc_mask & SS_STSCHG)
527 reg |= I365_CSC_STSCHG;
528 } else {
529 if (state->csc_mask & SS_BATDEAD)
530 reg |= I365_CSC_BVD1;
531 if (state->csc_mask & SS_BATWARN)
532 reg |= I365_CSC_BVD2;
533 if (state->csc_mask & SS_READY)
534 reg |= I365_CSC_READY;
538 /* now write the value and clear the (probably bogus) pending stuff
539 * by doing a dummy read
542 indirect_write(sock, I365_CSCINT, reg);
543 (void)indirect_read(sock, I365_CSC);
545 return 0;
548 static int i82092aa_set_io_map(struct pcmcia_socket *socket,
549 struct pccard_io_map *io)
551 struct socket_info *sock_info = container_of(socket, struct socket_info,
552 socket);
553 unsigned int sock = sock_info->number;
554 unsigned char map, ioctl;
556 map = io->map;
558 /* Check error conditions */
559 if (map > 1)
560 return -EINVAL;
562 if ((io->start > 0xffff) || (io->stop > 0xffff)
563 || (io->stop < io->start))
564 return -EINVAL;
566 /* Turn off the window before changing anything */
567 if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_IO(map))
568 indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_IO(map));
570 /* write the new values */
571 indirect_write16(sock, I365_IO(map)+I365_W_START, io->start);
572 indirect_write16(sock, I365_IO(map)+I365_W_STOP, io->stop);
574 ioctl = indirect_read(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
576 if (io->flags & (MAP_16BIT|MAP_AUTOSZ))
577 ioctl |= I365_IOCTL_16BIT(map);
579 indirect_write(sock, I365_IOCTL, ioctl);
581 /* Turn the window back on if needed */
582 if (io->flags & MAP_ACTIVE)
583 indirect_setbit(sock, I365_ADDRWIN, I365_ENA_IO(map));
585 return 0;
588 static int i82092aa_set_mem_map(struct pcmcia_socket *socket,
589 struct pccard_mem_map *mem)
591 struct socket_info *sock_info = container_of(socket, struct socket_info,
592 socket);
593 unsigned int sock = sock_info->number;
594 struct pci_bus_region region;
595 unsigned short base, i;
596 unsigned char map;
598 pcibios_resource_to_bus(sock_info->dev->bus, &region, mem->res);
600 map = mem->map;
601 if (map > 4)
602 return -EINVAL;
604 if ((mem->card_start > 0x3ffffff) || (region.start > region.end) ||
605 (mem->speed > 1000)) {
606 dev_err(&sock_info->dev->dev,
607 "invalid mem map for socket %i: %llx to %llx with a start of %x\n",
608 sock,
609 (unsigned long long)region.start,
610 (unsigned long long)region.end,
611 mem->card_start);
612 return -EINVAL;
615 /* Turn off the window before changing anything */
616 if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
617 indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
619 /* write the start address */
620 base = I365_MEM(map);
621 i = (region.start >> 12) & 0x0fff;
622 if (mem->flags & MAP_16BIT)
623 i |= I365_MEM_16BIT;
624 if (mem->flags & MAP_0WS)
625 i |= I365_MEM_0WS;
626 indirect_write16(sock, base+I365_W_START, i);
628 /* write the stop address */
630 i = (region.end >> 12) & 0x0fff;
631 switch (to_cycles(mem->speed)) {
632 case 0:
633 break;
634 case 1:
635 i |= I365_MEM_WS0;
636 break;
637 case 2:
638 i |= I365_MEM_WS1;
639 break;
640 default:
641 i |= I365_MEM_WS1 | I365_MEM_WS0;
642 break;
645 indirect_write16(sock, base+I365_W_STOP, i);
647 /* card start */
649 i = ((mem->card_start - region.start) >> 12) & 0x3fff;
650 if (mem->flags & MAP_WRPROT)
651 i |= I365_MEM_WRPROT;
652 if (mem->flags & MAP_ATTRIB)
653 i |= I365_MEM_REG;
654 indirect_write16(sock, base+I365_W_OFF, i);
656 /* Enable the window if necessary */
657 if (mem->flags & MAP_ACTIVE)
658 indirect_setbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
660 return 0;
663 static int i82092aa_module_init(void)
665 return pci_register_driver(&i82092aa_pci_driver);
668 static void i82092aa_module_exit(void)
670 pci_unregister_driver(&i82092aa_pci_driver);
671 if (sockets[0].io_base > 0)
672 release_region(sockets[0].io_base, 2);
675 module_init(i82092aa_module_init);
676 module_exit(i82092aa_module_exit);