• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Driver for Intel I82092AA PCI-PCMCIA bridge.
4  *
5  * (C) 2001 Red Hat, Inc.
6  *
7  * Author: Arjan Van De Ven <arjanv@redhat.com>
8  * Loosly based on i82365.c from the pcmcia-cs package
9  */
10 
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>
18 
19 #include <pcmcia/ss.h>
20 
21 #include <linux/io.h>
22 
23 #include "i82092aa.h"
24 #include "i82365.h"
25 
26 MODULE_LICENSE("GPL");
27 
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 	{ }
32 };
33 MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
34 
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,
40 };
41 
42 
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,
50 };
51 
52 /* The card can do up to 4 sockets, allocate a structure for each of them */
53 
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
61 		 */
62 	unsigned int io_base;	/* base io address of the socket */
63 
64 	struct pcmcia_socket socket;
65 	struct pci_dev *dev;	/* The PCI device for the socket */
66 };
67 
68 #define MAX_SOCKETS 4
69 static struct socket_info sockets[MAX_SOCKETS];
70 static int socket_count;	/* shortcut */
71 
72 
i82092aa_pci_probe(struct pci_dev * dev,const struct pci_device_id * id)73 static int i82092aa_pci_probe(struct pci_dev *dev,
74 			      const struct pci_device_id *id)
75 {
76 	unsigned char configbyte;
77 	int i, ret;
78 
79 	ret = pci_enable_device(dev);
80 	if (ret)
81 		return ret;
82 
83 	/* PCI Configuration Control */
84 	pci_read_config_byte(dev, 0x40, &configbyte);
85 
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;
97 
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;
103 	}
104 	dev_info(&dev->dev, "configured as a %d socket device.\n",
105 		 socket_count);
106 
107 	if (!request_region(pci_resource_start(dev, 0), 2, "i82092aa")) {
108 		ret = -EBUSY;
109 		goto err_out_disable;
110 	}
111 
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].dev = dev;
116 		sockets[i].socket.features |= SS_CAP_PCCARD;
117 		sockets[i].socket.map_size = 0x1000;
118 		sockets[i].socket.irq_mask = 0;
119 		sockets[i].socket.pci_irq  = dev->irq;
120 		sockets[i].socket.cb_dev  = dev;
121 		sockets[i].socket.owner = THIS_MODULE;
122 
123 		sockets[i].number = i;
124 
125 		if (card_present(i)) {
126 			sockets[i].card_state = 3;
127 			dev_dbg(&dev->dev, "slot %i is occupied\n", i);
128 		} else {
129 			dev_dbg(&dev->dev, "slot %i is vacant\n", i);
130 		}
131 	}
132 
133 	/* Now, specifiy that all interrupts are to be done as PCI interrupts
134 	 * bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt
135 	 */
136 	configbyte = 0xFF;
137 
138 	/* PCI Interrupt Routing Register */
139 	pci_write_config_byte(dev, 0x50, configbyte);
140 
141 	/* Register the interrupt handler */
142 	dev_dbg(&dev->dev, "Requesting interrupt %i\n", dev->irq);
143 	ret = request_irq(dev->irq, i82092aa_interrupt, IRQF_SHARED,
144 			  "i82092aa", i82092aa_interrupt);
145 	if (ret) {
146 		dev_err(&dev->dev, "Failed to register IRQ %d, aborting\n",
147 			dev->irq);
148 		goto err_out_free_res;
149 	}
150 
151 	for (i = 0; i < socket_count; i++) {
152 		sockets[i].socket.dev.parent = &dev->dev;
153 		sockets[i].socket.ops = &i82092aa_operations;
154 		sockets[i].socket.resource_ops = &pccard_nonstatic_ops;
155 		ret = pcmcia_register_socket(&sockets[i].socket);
156 		if (ret)
157 			goto err_out_free_sockets;
158 	}
159 
160 	return 0;
161 
162 err_out_free_sockets:
163 	if (i) {
164 		for (i--; i >= 0; i--)
165 			pcmcia_unregister_socket(&sockets[i].socket);
166 	}
167 	free_irq(dev->irq, i82092aa_interrupt);
168 err_out_free_res:
169 	release_region(pci_resource_start(dev, 0), 2);
170 err_out_disable:
171 	pci_disable_device(dev);
172 	return ret;
173 }
174 
i82092aa_pci_remove(struct pci_dev * dev)175 static void i82092aa_pci_remove(struct pci_dev *dev)
176 {
177 	int i;
178 
179 	free_irq(dev->irq, i82092aa_interrupt);
180 
181 	for (i = 0; i < socket_count; i++)
182 		pcmcia_unregister_socket(&sockets[i].socket);
183 }
184 
185 static DEFINE_SPINLOCK(port_lock);
186 
187 /* basic value read/write functions */
188 
indirect_read(int socket,unsigned short reg)189 static unsigned char indirect_read(int socket, unsigned short reg)
190 {
191 	unsigned short int port;
192 	unsigned char val;
193 	unsigned long flags;
194 
195 	spin_lock_irqsave(&port_lock, flags);
196 	reg += socket * 0x40;
197 	port = sockets[socket].io_base;
198 	outb(reg, port);
199 	val = inb(port+1);
200 	spin_unlock_irqrestore(&port_lock, flags);
201 	return val;
202 }
203 
indirect_write(int socket,unsigned short reg,unsigned char value)204 static void indirect_write(int socket, unsigned short reg, unsigned char value)
205 {
206 	unsigned short int port;
207 	unsigned long flags;
208 
209 	spin_lock_irqsave(&port_lock, flags);
210 	reg = reg + socket * 0x40;
211 	port = sockets[socket].io_base;
212 	outb(reg, port);
213 	outb(value, port+1);
214 	spin_unlock_irqrestore(&port_lock, flags);
215 }
216 
indirect_setbit(int socket,unsigned short reg,unsigned char mask)217 static void indirect_setbit(int socket, unsigned short reg, unsigned char mask)
218 {
219 	unsigned short int port;
220 	unsigned char val;
221 	unsigned long flags;
222 
223 	spin_lock_irqsave(&port_lock, flags);
224 	reg = reg + socket * 0x40;
225 	port = sockets[socket].io_base;
226 	outb(reg, port);
227 	val = inb(port+1);
228 	val |= mask;
229 	outb(reg, port);
230 	outb(val, port+1);
231 	spin_unlock_irqrestore(&port_lock, flags);
232 }
233 
234 
indirect_resetbit(int socket,unsigned short reg,unsigned char mask)235 static void indirect_resetbit(int socket,
236 			      unsigned short reg, unsigned char mask)
237 {
238 	unsigned short int port;
239 	unsigned char val;
240 	unsigned long flags;
241 
242 	spin_lock_irqsave(&port_lock, flags);
243 	reg = reg + socket * 0x40;
244 	port = sockets[socket].io_base;
245 	outb(reg, port);
246 	val = inb(port+1);
247 	val &= ~mask;
248 	outb(reg, port);
249 	outb(val, port+1);
250 	spin_unlock_irqrestore(&port_lock, flags);
251 }
252 
indirect_write16(int socket,unsigned short reg,unsigned short value)253 static void indirect_write16(int socket,
254 			     unsigned short reg, unsigned short value)
255 {
256 	unsigned short int port;
257 	unsigned char val;
258 	unsigned long flags;
259 
260 	spin_lock_irqsave(&port_lock, flags);
261 	reg = reg + socket * 0x40;
262 	port = sockets[socket].io_base;
263 
264 	outb(reg, port);
265 	val = value & 255;
266 	outb(val, port+1);
267 
268 	reg++;
269 
270 	outb(reg, port);
271 	val = value>>8;
272 	outb(val, port+1);
273 	spin_unlock_irqrestore(&port_lock, flags);
274 }
275 
276 /* simple helper functions */
277 /* External clock time, in nanoseconds.  120 ns = 8.33 MHz */
278 static int cycle_time = 120;
279 
to_cycles(int ns)280 static int to_cycles(int ns)
281 {
282 	if (cycle_time != 0)
283 		return ns/cycle_time;
284 	else
285 		return 0;
286 }
287 
288 
289 /* Interrupt handler functionality */
290 
i82092aa_interrupt(int irq,void * dev)291 static irqreturn_t i82092aa_interrupt(int irq, void *dev)
292 {
293 	int i;
294 	int loopcount = 0;
295 	int handled = 0;
296 
297 	unsigned int events, active = 0;
298 
299 	while (1) {
300 		loopcount++;
301 		if (loopcount > 20) {
302 			pr_err("i82092aa: infinite eventloop in interrupt\n");
303 			break;
304 		}
305 
306 		active = 0;
307 
308 		for (i = 0; i < socket_count; i++) {
309 			int csc;
310 
311 			/* Inactive socket, should not happen */
312 			if (sockets[i].card_state == 0)
313 				continue;
314 
315 			/* card status change register */
316 			csc = indirect_read(i, I365_CSC);
317 
318 			if (csc == 0)  /* no events on this socket */
319 				continue;
320 			handled = 1;
321 			events = 0;
322 
323 			if (csc & I365_CSC_DETECT) {
324 				events |= SS_DETECT;
325 				dev_info(&sockets[i].dev->dev,
326 					 "Card detected in socket %i!\n", i);
327 			}
328 
329 			if (indirect_read(i, I365_INTCTL) & I365_PC_IOCARD) {
330 				/* For IO/CARDS, bit 0 means "read the card" */
331 				if (csc & I365_CSC_STSCHG)
332 					events |= SS_STSCHG;
333 			} else {
334 				/* Check for battery/ready events */
335 				if (csc & I365_CSC_BVD1)
336 					events |= SS_BATDEAD;
337 				if (csc & I365_CSC_BVD2)
338 					events |= SS_BATWARN;
339 				if (csc & I365_CSC_READY)
340 					events |= SS_READY;
341 			}
342 
343 			if (events)
344 				pcmcia_parse_events(&sockets[i].socket, events);
345 			active |= events;
346 		}
347 
348 		if (active == 0) /* no more events to handle */
349 			break;
350 	}
351 	return IRQ_RETVAL(handled);
352 }
353 
354 
355 
356 /* socket functions */
357 
card_present(int socketno)358 static int card_present(int socketno)
359 {
360 	unsigned int val;
361 
362 	if ((socketno < 0) || (socketno >= MAX_SOCKETS))
363 		return 0;
364 	if (sockets[socketno].io_base == 0)
365 		return 0;
366 
367 
368 	val = indirect_read(socketno, 1); /* Interface status register */
369 	if ((val&12) == 12)
370 		return 1;
371 
372 	return 0;
373 }
374 
set_bridge_state(int sock)375 static void set_bridge_state(int sock)
376 {
377 	indirect_write(sock, I365_GBLCTL, 0x00);
378 	indirect_write(sock, I365_GENCTL, 0x00);
379 
380 	indirect_setbit(sock, I365_INTCTL, 0x08);
381 }
382 
383 
i82092aa_init(struct pcmcia_socket * sock)384 static int i82092aa_init(struct pcmcia_socket *sock)
385 {
386 	int i;
387 	struct resource res = { .start = 0, .end = 0x0fff };
388 	pccard_io_map io = { 0, 0, 0, 0, 1 };
389 	pccard_mem_map mem = { .res = &res, };
390 
391 	for (i = 0; i < 2; i++) {
392 		io.map = i;
393 		i82092aa_set_io_map(sock, &io);
394 	}
395 	for (i = 0; i < 5; i++) {
396 		mem.map = i;
397 		i82092aa_set_mem_map(sock, &mem);
398 	}
399 
400 	return 0;
401 }
402 
i82092aa_get_status(struct pcmcia_socket * socket,u_int * value)403 static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
404 {
405 	unsigned int sock = container_of(socket,
406 				struct socket_info, socket)->number;
407 	unsigned int status;
408 
409 	/* Interface Status Register */
410 	status = indirect_read(sock, I365_STATUS);
411 
412 	*value = 0;
413 
414 	if ((status & I365_CS_DETECT) == I365_CS_DETECT)
415 		*value |= SS_DETECT;
416 
417 	/* IO cards have a different meaning of bits 0,1 */
418 	/* Also notice the inverse-logic on the bits */
419 	if (indirect_read(sock, I365_INTCTL) & I365_PC_IOCARD) {
420 		/* IO card */
421 		if (!(status & I365_CS_STSCHG))
422 			*value |= SS_STSCHG;
423 	} else { /* non I/O card */
424 		if (!(status & I365_CS_BVD1))
425 			*value |= SS_BATDEAD;
426 		if (!(status & I365_CS_BVD2))
427 			*value |= SS_BATWARN;
428 	}
429 
430 	if (status & I365_CS_WRPROT)
431 		(*value) |= SS_WRPROT;	/* card is write protected */
432 
433 	if (status & I365_CS_READY)
434 		(*value) |= SS_READY;    /* card is not busy */
435 
436 	if (status & I365_CS_POWERON)
437 		(*value) |= SS_POWERON;  /* power is applied to the card */
438 
439 	return 0;
440 }
441 
442 
i82092aa_set_socket(struct pcmcia_socket * socket,socket_state_t * state)443 static int i82092aa_set_socket(struct pcmcia_socket *socket,
444 			       socket_state_t *state)
445 {
446 	struct socket_info *sock_info = container_of(socket, struct socket_info,
447 						     socket);
448 	unsigned int sock = sock_info->number;
449 	unsigned char reg;
450 
451 	/* First, set the global controller options */
452 
453 	set_bridge_state(sock);
454 
455 	/* Values for the IGENC register */
456 
457 	reg = 0;
458 
459 	/* The reset bit has "inverse" logic */
460 	if (!(state->flags & SS_RESET))
461 		reg = reg | I365_PC_RESET;
462 	if (state->flags & SS_IOCARD)
463 		reg = reg | I365_PC_IOCARD;
464 
465 	/* IGENC, Interrupt and General Control Register */
466 	indirect_write(sock, I365_INTCTL, reg);
467 
468 	/* Power registers */
469 
470 	reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
471 
472 	if (state->flags & SS_PWR_AUTO) {
473 		dev_info(&sock_info->dev->dev, "Auto power\n");
474 		reg |= I365_PWR_AUTO;	/* automatic power mngmnt */
475 	}
476 	if (state->flags & SS_OUTPUT_ENA) {
477 		dev_info(&sock_info->dev->dev, "Power Enabled\n");
478 		reg |= I365_PWR_OUT;	/* enable power */
479 	}
480 
481 	switch (state->Vcc) {
482 	case 0:
483 		break;
484 	case 50:
485 		dev_info(&sock_info->dev->dev,
486 			 "setting voltage to Vcc to 5V on socket %i\n",
487 			 sock);
488 		reg |= I365_VCC_5V;
489 		break;
490 	default:
491 		dev_err(&sock_info->dev->dev,
492 			"%s called with invalid VCC power value: %i",
493 			__func__, state->Vcc);
494 		return -EINVAL;
495 	}
496 
497 	switch (state->Vpp) {
498 	case 0:
499 		dev_info(&sock_info->dev->dev,
500 			 "not setting Vpp on socket %i\n", sock);
501 		break;
502 	case 50:
503 		dev_info(&sock_info->dev->dev,
504 			 "setting Vpp to 5.0 for socket %i\n", sock);
505 		reg |= I365_VPP1_5V | I365_VPP2_5V;
506 		break;
507 	case 120:
508 		dev_info(&sock_info->dev->dev, "setting Vpp to 12.0\n");
509 		reg |= I365_VPP1_12V | I365_VPP2_12V;
510 		break;
511 	default:
512 		dev_err(&sock_info->dev->dev,
513 			"%s called with invalid VPP power value: %i",
514 			__func__, state->Vcc);
515 		return -EINVAL;
516 	}
517 
518 	if (reg != indirect_read(sock, I365_POWER)) /* only write if changed */
519 		indirect_write(sock, I365_POWER, reg);
520 
521 	/* Enable specific interrupt events */
522 
523 	reg = 0x00;
524 	if (state->csc_mask & SS_DETECT)
525 		reg |= I365_CSC_DETECT;
526 	if (state->flags & SS_IOCARD) {
527 		if (state->csc_mask & SS_STSCHG)
528 			reg |= I365_CSC_STSCHG;
529 	} else {
530 		if (state->csc_mask & SS_BATDEAD)
531 			reg |= I365_CSC_BVD1;
532 		if (state->csc_mask & SS_BATWARN)
533 			reg |= I365_CSC_BVD2;
534 		if (state->csc_mask & SS_READY)
535 			reg |= I365_CSC_READY;
536 
537 	}
538 
539 	/* now write the value and clear the (probably bogus) pending stuff
540 	 * by doing a dummy read
541 	 */
542 
543 	indirect_write(sock, I365_CSCINT, reg);
544 	(void)indirect_read(sock, I365_CSC);
545 
546 	return 0;
547 }
548 
i82092aa_set_io_map(struct pcmcia_socket * socket,struct pccard_io_map * io)549 static int i82092aa_set_io_map(struct pcmcia_socket *socket,
550 			       struct pccard_io_map *io)
551 {
552 	struct socket_info *sock_info = container_of(socket, struct socket_info,
553 						     socket);
554 	unsigned int sock = sock_info->number;
555 	unsigned char map, ioctl;
556 
557 	map = io->map;
558 
559 	/* Check error conditions */
560 	if (map > 1)
561 		return -EINVAL;
562 
563 	if ((io->start > 0xffff) || (io->stop > 0xffff)
564 				 || (io->stop < io->start))
565 		return -EINVAL;
566 
567 	/* Turn off the window before changing anything */
568 	if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_IO(map))
569 		indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_IO(map));
570 
571 	/* write the new values */
572 	indirect_write16(sock, I365_IO(map)+I365_W_START, io->start);
573 	indirect_write16(sock, I365_IO(map)+I365_W_STOP, io->stop);
574 
575 	ioctl = indirect_read(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
576 
577 	if (io->flags & (MAP_16BIT|MAP_AUTOSZ))
578 		ioctl |= I365_IOCTL_16BIT(map);
579 
580 	indirect_write(sock, I365_IOCTL, ioctl);
581 
582 	/* Turn the window back on if needed */
583 	if (io->flags & MAP_ACTIVE)
584 		indirect_setbit(sock, I365_ADDRWIN, I365_ENA_IO(map));
585 
586 	return 0;
587 }
588 
i82092aa_set_mem_map(struct pcmcia_socket * socket,struct pccard_mem_map * mem)589 static int i82092aa_set_mem_map(struct pcmcia_socket *socket,
590 				struct pccard_mem_map *mem)
591 {
592 	struct socket_info *sock_info = container_of(socket, struct socket_info,
593 						     socket);
594 	unsigned int sock = sock_info->number;
595 	struct pci_bus_region region;
596 	unsigned short base, i;
597 	unsigned char map;
598 
599 	pcibios_resource_to_bus(sock_info->dev->bus, &region, mem->res);
600 
601 	map = mem->map;
602 	if (map > 4)
603 		return -EINVAL;
604 
605 	if ((mem->card_start > 0x3ffffff) || (region.start > region.end) ||
606 	     (mem->speed > 1000)) {
607 		dev_err(&sock_info->dev->dev,
608 			"invalid mem map for socket %i: %llx to %llx with a start of %x\n",
609 			sock,
610 			(unsigned long long)region.start,
611 			(unsigned long long)region.end,
612 			mem->card_start);
613 		return -EINVAL;
614 	}
615 
616 	/* Turn off the window before changing anything */
617 	if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
618 		indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
619 
620 	/* write the start address */
621 	base = I365_MEM(map);
622 	i = (region.start >> 12) & 0x0fff;
623 	if (mem->flags & MAP_16BIT)
624 		i |= I365_MEM_16BIT;
625 	if (mem->flags & MAP_0WS)
626 		i |= I365_MEM_0WS;
627 	indirect_write16(sock, base+I365_W_START, i);
628 
629 	/* write the stop address */
630 
631 	i = (region.end >> 12) & 0x0fff;
632 	switch (to_cycles(mem->speed)) {
633 	case 0:
634 		break;
635 	case 1:
636 		i |= I365_MEM_WS0;
637 		break;
638 	case 2:
639 		i |= I365_MEM_WS1;
640 		break;
641 	default:
642 		i |= I365_MEM_WS1 | I365_MEM_WS0;
643 		break;
644 	}
645 
646 	indirect_write16(sock, base+I365_W_STOP, i);
647 
648 	/* card start */
649 
650 	i = ((mem->card_start - region.start) >> 12) & 0x3fff;
651 	if (mem->flags & MAP_WRPROT)
652 		i |= I365_MEM_WRPROT;
653 	if (mem->flags & MAP_ATTRIB)
654 		i |= I365_MEM_REG;
655 	indirect_write16(sock, base+I365_W_OFF, i);
656 
657 	/* Enable the window if necessary */
658 	if (mem->flags & MAP_ACTIVE)
659 		indirect_setbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
660 
661 	return 0;
662 }
663 
i82092aa_module_init(void)664 static int i82092aa_module_init(void)
665 {
666 	return pci_register_driver(&i82092aa_pci_driver);
667 }
668 
i82092aa_module_exit(void)669 static void i82092aa_module_exit(void)
670 {
671 	pci_unregister_driver(&i82092aa_pci_driver);
672 	if (sockets[0].io_base > 0)
673 		release_region(sockets[0].io_base, 2);
674 }
675 
676 module_init(i82092aa_module_init);
677 module_exit(i82092aa_module_exit);
678 
679