10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/pci.h>
16 #include <linux/device.h>
34 static struct pci_driver i82092aa_pci_driver = {
36 .id_table = i82092aa_pci_ids,
37 .probe = i82092aa_pci_probe,
44 .init = i82092aa_init,
45 .get_status = i82092aa_get_status,
46 .set_socket = i82092aa_set_socket,
47 .set_io_map = i82092aa_set_io_map,
48 .set_mem_map = i82092aa_set_mem_map,
67 static int socket_count;
72 unsigned char configbyte;
75 enter(
"i82092aa_pci_probe");
80 pci_read_config_byte(dev, 0x40, &configbyte);
81 switch(configbyte&6) {
94 printk(
KERN_ERR "i82092aa: Oops, you did something we didn't think of.\n");
98 printk(
KERN_INFO "i82092aa: configured as a %d socket device.\n", socket_count);
102 goto err_out_disable;
105 for (i = 0;i<socket_count;i++) {
106 sockets[
i].card_state = 1;
109 sockets[
i].socket.map_size = 0x1000;
110 sockets[
i].socket.irq_mask = 0;
111 sockets[
i].socket.pci_irq = dev->
irq;
112 sockets[
i].socket.cb_dev =
dev;
115 sockets[
i].number =
i;
117 if (card_present(i)) {
118 sockets[
i].card_state = 3;
127 pci_write_config_byte(dev, 0x50, configbyte);
133 goto err_out_free_res;
136 pci_set_drvdata(dev, &sockets[i].
socket);
138 for (i = 0; i<socket_count; i++) {
139 sockets[
i].socket.dev.parent = &dev->
dev;
140 sockets[
i].socket.ops = &i82092aa_operations;
144 goto err_out_free_sockets;
148 leave(
"i82092aa_pci_probe");
151 err_out_free_sockets:
169 enter(
"i82092aa_pci_remove");
176 leave(
"i82092aa_pci_remove");
183 static unsigned char indirect_read(
int socket,
unsigned short reg)
185 unsigned short int port;
189 reg += socket * 0x40;
190 port = sockets[
socket].io_base;
193 spin_unlock_irqrestore(&port_lock,flags);
198 static unsigned short indirect_read16(
int socket,
unsigned short reg)
200 unsigned short int port;
204 reg = reg + socket * 0x40;
205 port = sockets[
socket].io_base;
210 tmp = tmp | (
inb(port+1)<<8);
211 spin_unlock_irqrestore(&port_lock,flags);
216 static void indirect_write(
int socket,
unsigned short reg,
unsigned char value)
218 unsigned short int port;
221 reg = reg + socket * 0x40;
222 port = sockets[
socket].io_base;
225 spin_unlock_irqrestore(&port_lock,flags);
228 static void indirect_setbit(
int socket,
unsigned short reg,
unsigned char mask)
230 unsigned short int port;
234 reg = reg + socket * 0x40;
235 port = sockets[
socket].io_base;
241 spin_unlock_irqrestore(&port_lock,flags);
245 static void indirect_resetbit(
int socket,
unsigned short reg,
unsigned char mask)
247 unsigned short int port;
251 reg = reg + socket * 0x40;
252 port = sockets[
socket].io_base;
258 spin_unlock_irqrestore(&port_lock,flags);
261 static void indirect_write16(
int socket,
unsigned short reg,
unsigned short value)
263 unsigned short int port;
267 reg = reg + socket * 0x40;
268 port = sockets[
socket].io_base;
279 spin_unlock_irqrestore(&port_lock,flags);
284 static int cycle_time = 120;
289 return ns/cycle_time;
297 static irqreturn_t i82092aa_interrupt(
int irq,
void *dev)
316 for (i=0;i<socket_count;i++) {
330 printk(
"Card detected in socket %i!\n",i);
361 static int card_present(
int socketno)
364 enter(
"card_present");
368 if (sockets[socketno].
io_base == 0)
372 val = indirect_read(socketno, 1);
374 leave(
"card_present 1");
378 leave(
"card_present 0");
382 static void set_bridge_state(
int sock)
384 enter(
"set_bridge_state");
389 leave(
"set_bridge_state");
400 struct resource res = { .start = 0, .end = 0x0fff };
404 enter(
"i82092aa_init");
406 for (i = 0; i < 2; i++) {
408 i82092aa_set_io_map(sock, &io);
410 for (i = 0; i < 5; i++) {
412 i82092aa_set_mem_map(sock, &mem);
415 leave(
"i82092aa_init");
424 enter(
"i82092aa_get_status");
457 leave(
"i82092aa_get_status");
467 enter(
"i82092aa_set_socket");
471 set_bridge_state(sock);
492 printk(
"Power Enabled \n");
496 switch (state->
Vcc) {
500 printk(
"setting voltage to Vcc to 5V on socket %i\n",sock);
504 printk(
"i82092aa: i82092aa_set_socket called with invalid VCC power value: %i ", state->
Vcc);
505 leave(
"i82092aa_set_socket");
510 switch (state->
Vpp) {
512 printk(
"not setting Vpp on socket %i\n",sock);
515 printk(
"setting Vpp to 5.0 for socket %i\n",sock);
519 printk(
"setting Vpp to 12.0\n");
523 printk(
"i82092aa: i82092aa_set_socket called with invalid VPP power value: %i ", state->
Vcc);
524 leave(
"i82092aa_set_socket");
555 leave(
"i82092aa_set_socket");
562 unsigned char map, ioctl;
564 enter(
"i82092aa_set_io_map");
570 leave(
"i82092aa_set_io_map with invalid map");
574 leave(
"i82092aa_set_io_map with invalid io");
599 leave(
"i82092aa_set_io_map");
606 unsigned int sock = sock_info->
number;
608 unsigned short base,
i;
611 enter(
"i82092aa_set_mem_map");
617 leave(
"i82092aa_set_mem_map: invalid map");
623 (mem->
speed > 1000) ) {
624 leave(
"i82092aa_set_mem_map: invalid address / speed");
625 printk(
"invalid mem map for socket %i: %llx to %llx with a "
628 (
unsigned long long)
region.start,
629 (
unsigned long long)
region.end,
643 i = (
region.start >> 12) & 0x0fff;
652 i= (
region.end >> 12) & 0x0fff;
686 leave(
"i82092aa_set_mem_map");
690 static int i82092aa_module_init(
void)
692 return pci_register_driver(&i82092aa_pci_driver);
695 static void i82092aa_module_exit(
void)
697 enter(
"i82092aa_module_exit");
701 leave(
"i82092aa_module_exit");