1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/device.h>
5 #include <linux/slab.h>
7 #include <linux/kernel.h>
8 #include <linux/uio_driver.h>
10 #define PCI_VENDOR_ID_HUMUSOFT 0x186c
11 #define PCI_DEVICE_ID_MF614 0x0614
12 #define PCI_SUBVENDOR_ID_HUMUSOFT 0x186c
13 #define PCI_SUBDEVICE_DEVICE 0x0000
15 #define STATUS_REG 0x10
16 #define STATUS_T5INTE (u32) (1 << 19)
17 #define STATUS_T5 (u32) (1 << 3)
18 #define STATUS_CCINTE (u32) (1 << 18)
19 #define STATUS_CC (u32) (1 << 2)
22 static irqreturn_t mf614_irq_handler(int irq, struct uio_info *info)
24 void __iomem *status_reg = info->priv;
25 status_reg = ((u8*) status_reg) + STATUS_REG;
28 if ((ioread32(status_reg) & STATUS_T5INTE)
29 && (ioread32(status_reg) & STATUS_T5))
32 iowrite32(ioread32(status_reg) & ~STATUS_T5INTE, status_reg);
36 if ((ioread32(status_reg) & STATUS_CCINTE)
37 && (ioread32(status_reg) & STATUS_CC))
40 iowrite32(ioread32(status_reg) & ~STATUS_CCINTE, status_reg);
47 static int mf614_irqcontrol(struct uio_info *info, s32 irq_on)
49 void __iomem *status_reg = info->priv;
50 status_reg = ((u8*) status_reg) + STATUS_REG;
53 if (irq_on == 0) { /* Disable interrupts */
54 iowrite32(ioread32(status_reg) & ~STATUS_T5INTE, status_reg);
55 iowrite32(ioread32(status_reg) & ~STATUS_CCINTE, status_reg);
57 else if (irq_on == 1) {
58 iowrite32(ioread32(status_reg) | STATUS_T5INTE, status_reg);
59 iowrite32(ioread32(status_reg) | STATUS_CCINTE, status_reg);
65 static int __devinit mf614_pci_probe(struct pci_dev *dev,
66 const struct pci_device_id *id)
68 struct uio_info *info;
70 info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
74 if (pci_enable_device(dev))
77 if (pci_request_regions(dev, "mf614"))
81 info->version = "0.0.1";
83 info->port[0].name = "Board programming registers";
84 info->port[0].porttype = UIO_PORT_X86;
85 info->port[0].start = pci_resource_start(dev, 0);
86 if (!info->port[0].start)
88 info->port[0].size = pci_resource_len(dev, 0);
91 info->port[1].name = "OX9162 local configuration registers";
92 info->port[1].porttype = UIO_PORT_X86;
93 info->port[1].start = pci_resource_start(dev, 2);
94 if (!info->port[1].start)
96 info->port[1].size = pci_resource_len(dev, 2);
98 info->priv = pci_iomap(dev, 2, 0);
103 info->mem[0].name = "Board programming registers";
104 info->mem[0].addr = pci_resource_start(dev, 4);
105 if (!info->mem[0].addr)
107 info->mem[0].size = pci_resource_len(dev, 4);
108 info->mem[0].memtype = UIO_MEM_PHYS;
109 info->mem[0].internal_addr = pci_ioremap_bar(dev, 4);
110 if (!info->mem[0].internal_addr)
114 info->mem[1].name = "OX9162 local configuration registers";
115 info->mem[1].addr = pci_resource_start(dev, 3);
116 if (!info->mem[1].addr)
118 info->mem[1].size = pci_resource_len(dev, 3);
119 info->mem[1].memtype = UIO_MEM_PHYS;
120 info->mem[1].internal_addr = pci_ioremap_bar(dev, 3);
121 if (!info->mem[1].internal_addr)
125 info->irq = dev->irq;
126 info->irq_flags = IRQF_SHARED;
127 info->handler = mf614_irq_handler;
129 info->irqcontrol = mf614_irqcontrol;
131 if(uio_register_device(&dev->dev, info))
134 pci_set_drvdata(dev, info);
139 iounmap(info->mem[0].internal_addr);
140 iounmap(info->mem[1].internal_addr);
141 pci_iounmap(dev, info->priv);
143 pci_release_regions(dev);
145 pci_disable_device(dev);
151 static void mf614_pci_remove(struct pci_dev *dev)
153 struct uio_info *info = pci_get_drvdata(dev);
154 void __iomem *status_reg = info->priv;
155 status_reg = ((u8*) status_reg) + STATUS_REG;
157 /* Disable interrupts */
158 iowrite32(ioread32(status_reg) & ~STATUS_T5INTE, status_reg);
159 iowrite32(ioread32(status_reg) & ~STATUS_CCINTE, status_reg);
161 uio_unregister_device(info);
162 pci_release_regions(dev);
163 pci_disable_device(dev);
164 pci_set_drvdata(dev, NULL);
165 pci_iounmap(dev, info->priv);
166 iounmap(info->mem[0].internal_addr);
167 iounmap(info->mem[1].internal_addr);
172 static struct pci_device_id mf614_pci_id[] __devinitdata = {
174 .vendor = PCI_VENDOR_ID_HUMUSOFT,
175 .device = PCI_DEVICE_ID_MF614,
176 .subvendor = PCI_SUBVENDOR_ID_HUMUSOFT,
177 .subdevice = PCI_SUBDEVICE_DEVICE,
182 static struct pci_driver mf614_pci_driver = {
184 .id_table = mf614_pci_id,
185 .probe = mf614_pci_probe,
186 .remove = mf614_pci_remove,
189 static int __init mf614_init_module(void)
191 return pci_register_driver(&mf614_pci_driver);
194 static void __exit mf614_exit_module(void)
196 pci_unregister_driver(&mf614_pci_driver);
199 module_init(mf614_init_module);
200 module_exit(mf614_exit_module);
202 MODULE_LICENSE("GPL v2");
203 MODULE_AUTHOR("Rostislav Lisovy <lisovy@gmail.com>");