0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008 #include <linux/init.h>
0009 #include <linux/serio.h>
0010 #include <linux/errno.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/ioport.h>
0013 #include <linux/delay.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/slab.h>
0016 #include <linux/spinlock.h>
0017 #include <linux/err.h>
0018
0019 #include <asm/io.h>
0020 #include <asm/irq.h>
0021 #include <asm/ip32/mace.h>
0022 #include <asm/ip32/ip32_ints.h>
0023
0024 MODULE_AUTHOR("Vivien Chappelier <vivien.chappelier@linux-mips.org");
0025 MODULE_DESCRIPTION("SGI O2 MACE PS2 controller driver");
0026 MODULE_LICENSE("GPL");
0027
0028 #define MACE_PS2_TIMEOUT 10000
0029
0030 #define PS2_STATUS_CLOCK_SIGNAL BIT(0)
0031 #define PS2_STATUS_CLOCK_INHIBIT BIT(1)
0032 #define PS2_STATUS_TX_INPROGRESS BIT(2)
0033 #define PS2_STATUS_TX_EMPTY BIT(3)
0034 #define PS2_STATUS_RX_FULL BIT(4)
0035 #define PS2_STATUS_RX_INPROGRESS BIT(5)
0036 #define PS2_STATUS_ERROR_PARITY BIT(6)
0037 #define PS2_STATUS_ERROR_FRAMING BIT(7)
0038
0039 #define PS2_CONTROL_TX_CLOCK_DISABLE BIT(0)
0040 #define PS2_CONTROL_TX_ENABLE BIT(1)
0041 #define PS2_CONTROL_TX_INT_ENABLE BIT(2)
0042 #define PS2_CONTROL_RX_INT_ENABLE BIT(3)
0043 #define PS2_CONTROL_RX_CLOCK_ENABLE BIT(4)
0044 #define PS2_CONTROL_RESET BIT(5)
0045
0046 struct maceps2_data {
0047 struct mace_ps2port *port;
0048 int irq;
0049 };
0050
0051 static struct maceps2_data port_data[2];
0052 static struct serio *maceps2_port[2];
0053 static struct platform_device *maceps2_device;
0054
0055 static int maceps2_write(struct serio *dev, unsigned char val)
0056 {
0057 struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
0058 unsigned int timeout = MACE_PS2_TIMEOUT;
0059
0060 do {
0061 if (port->status & PS2_STATUS_TX_EMPTY) {
0062 port->tx = val;
0063 return 0;
0064 }
0065 udelay(50);
0066 } while (timeout--);
0067
0068 return -1;
0069 }
0070
0071 static irqreturn_t maceps2_interrupt(int irq, void *dev_id)
0072 {
0073 struct serio *dev = dev_id;
0074 struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
0075 unsigned long byte;
0076
0077 if (port->status & PS2_STATUS_RX_FULL) {
0078 byte = port->rx;
0079 serio_interrupt(dev, byte & 0xff, 0);
0080 }
0081
0082 return IRQ_HANDLED;
0083 }
0084
0085 static int maceps2_open(struct serio *dev)
0086 {
0087 struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
0088
0089 if (request_irq(data->irq, maceps2_interrupt, 0, "PS2 port", dev)) {
0090 printk(KERN_ERR "Could not allocate PS/2 IRQ\n");
0091 return -EBUSY;
0092 }
0093
0094
0095 data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
0096 udelay(100);
0097
0098
0099 data->port->control = PS2_CONTROL_RX_CLOCK_ENABLE |
0100 PS2_CONTROL_TX_ENABLE |
0101 PS2_CONTROL_RX_INT_ENABLE;
0102
0103 return 0;
0104 }
0105
0106 static void maceps2_close(struct serio *dev)
0107 {
0108 struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
0109
0110 data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
0111 udelay(100);
0112 free_irq(data->irq, dev);
0113 }
0114
0115
0116 static struct serio *maceps2_allocate_port(int idx)
0117 {
0118 struct serio *serio;
0119
0120 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
0121 if (serio) {
0122 serio->id.type = SERIO_8042;
0123 serio->write = maceps2_write;
0124 serio->open = maceps2_open;
0125 serio->close = maceps2_close;
0126 snprintf(serio->name, sizeof(serio->name), "MACE PS/2 port%d", idx);
0127 snprintf(serio->phys, sizeof(serio->phys), "mace/serio%d", idx);
0128 serio->port_data = &port_data[idx];
0129 serio->dev.parent = &maceps2_device->dev;
0130 }
0131
0132 return serio;
0133 }
0134
0135 static int maceps2_probe(struct platform_device *dev)
0136 {
0137 maceps2_port[0] = maceps2_allocate_port(0);
0138 maceps2_port[1] = maceps2_allocate_port(1);
0139 if (!maceps2_port[0] || !maceps2_port[1]) {
0140 kfree(maceps2_port[0]);
0141 kfree(maceps2_port[1]);
0142 return -ENOMEM;
0143 }
0144
0145 serio_register_port(maceps2_port[0]);
0146 serio_register_port(maceps2_port[1]);
0147
0148 return 0;
0149 }
0150
0151 static int maceps2_remove(struct platform_device *dev)
0152 {
0153 serio_unregister_port(maceps2_port[0]);
0154 serio_unregister_port(maceps2_port[1]);
0155
0156 return 0;
0157 }
0158
0159 static struct platform_driver maceps2_driver = {
0160 .driver = {
0161 .name = "maceps2",
0162 },
0163 .probe = maceps2_probe,
0164 .remove = maceps2_remove,
0165 };
0166
0167 static int __init maceps2_init(void)
0168 {
0169 int error;
0170
0171 error = platform_driver_register(&maceps2_driver);
0172 if (error)
0173 return error;
0174
0175 maceps2_device = platform_device_alloc("maceps2", -1);
0176 if (!maceps2_device) {
0177 error = -ENOMEM;
0178 goto err_unregister_driver;
0179 }
0180
0181 port_data[0].port = &mace->perif.ps2.keyb;
0182 port_data[0].irq = MACEISA_KEYB_IRQ;
0183 port_data[1].port = &mace->perif.ps2.mouse;
0184 port_data[1].irq = MACEISA_MOUSE_IRQ;
0185
0186 error = platform_device_add(maceps2_device);
0187 if (error)
0188 goto err_free_device;
0189
0190 return 0;
0191
0192 err_free_device:
0193 platform_device_put(maceps2_device);
0194 err_unregister_driver:
0195 platform_driver_unregister(&maceps2_driver);
0196 return error;
0197 }
0198
0199 static void __exit maceps2_exit(void)
0200 {
0201 platform_device_unregister(maceps2_device);
0202 platform_driver_unregister(&maceps2_driver);
0203 }
0204
0205 module_init(maceps2_init);
0206 module_exit(maceps2_exit);