1 #include <linux/module.h>
3 #include <linux/uio_driver.h>
5 #define PCI_VENDOR_ID_HUMUSOFT 0x186c
6 #define PCI_DEVICE_ID_MF614 0x0614
7 #define PCI_SUBVENDOR_ID_HUMUSOFT 0x186c
8 #define PCI_SUBDEVICE_DEVICE 0x0000
10 #define STATUS_OFFSET 0x10
11 #define STATUS_T5INTE (u32) (1 << 19)
12 #define STATUS_T5 (u32) (1 << 18)
13 #define STATUS_CCINTE (u32) (1 << 3)
14 #define STATUS_CC (u32) (1 << 2)
17 static irqreturn_t mf614_irq_handler(int irq, struct uio_info *dev_info)
19 void __iomem *status_reg = dev_info->priv + STATUS_OFFSET;
21 if ((ioread16(status_reg) & STATUS_T5INTE)
22 && (ioread16(status_reg) & STATUS_T5))
24 iowrite16(ioread16(status_reg) & ~STATUS_T5, status_reg);
28 if ((ioread16(status_reg) & STATUS_CCINTE)
29 && (ioread16(status_reg) & STATUS_CC))
31 iowrite16(ioread16(status_reg) & ~STATUS_CC, status_reg);
38 static int __devinit mf614_pci_probe(struct pci_dev *dev,
39 const struct pci_device_id *id)
41 struct uio_info *info;
43 info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
47 if (pci_enable_device(dev)) //FIXME what is return value??
50 if (pci_request_regions(dev, "mf614"))
54 info->version = "0.0.1";
56 info->port[0].porttype = UIO_PORT_X86;
57 info->port[0].start = pci_resource_start(dev, 0);
58 if (!info->port[0].start)
60 info->port[0].size = pci_resource_len(dev, 0);
62 info->port[1].porttype = UIO_PORT_X86;
63 info->port[1].start = pci_resource_start(dev, 2);
64 if (!info->port[1].start)
66 info->port[1].size = pci_resource_len(dev, 2);
68 info->priv = pci_iomap(dev, 2, 0);
72 info->mem[0].addr = pci_resource_start(dev, 4);
73 if (!info->mem[0].addr)
75 info->mem[0].size = pci_resource_len(dev, 4);
76 info->mem[0].memtype = UIO_MEM_PHYS;
77 info->mem[0].internal_addr = pci_ioremap_bar(dev, 4);
78 if (!info->mem[0].internal_addr)
82 info->irq_flags = IRQF_SHARED;
83 info->handler = mf614_irq_handler;
85 if(uio_register_device(&dev->dev, info))
88 pci_set_drvdata(dev, info);
93 iounmap(info->mem[0].internal_addr);
95 pci_release_regions(dev);
97 pci_disable_device(dev);
103 static void mf614_pci_remove(struct pci_dev *dev)
108 static struct pci_device_id mf614_pci_id[] __devinitdata = {
110 .vendor = PCI_VENDOR_ID_HUMUSOFT,
111 .device = PCI_DEVICE_ID_MF614,
112 .subvendor = PCI_SUBVENDOR_ID_HUMUSOFT,
113 .subdevice = PCI_SUBDEVICE_DEVICE,
118 static struct pci_driver mf614_pci_driver = {
120 .id_table = mf614_pci_id,
121 .probe = mf614_pci_probe,
122 .remove = mf614_pci_remove,
125 static int __init mf614_init_module(void)
127 return pci_register_driver(&mf614_pci_driver);
130 static void __exit mf614_exit_module(void)
132 pci_unregister_driver(&mf614_pci_driver);
135 module_init(mf614_init_module);
136 module_exit(mf614_exit_module);
138 MODULE_LICENSE("GPL v2");
139 MODULE_AUTHOR("Rostislav Lisovy <lisovy@gmail.com>");