root/drivers/input/serio/arc_ps2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arc_ps2_check_rx
  2. arc_ps2_interrupt
  3. arc_ps2_write
  4. arc_ps2_open
  5. arc_ps2_close
  6. arc_ps2_calc_addr
  7. arc_ps2_inhibit_ports
  8. arc_ps2_create_port
  9. arc_ps2_probe
  10. arc_ps2_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
   4  *
   5  * Driver is originally developed by Pavel Sokolov <psokolov@synopsys.com>
   6  */
   7 
   8 #include <linux/err.h>
   9 #include <linux/module.h>
  10 #include <linux/interrupt.h>
  11 #include <linux/input.h>
  12 #include <linux/serio.h>
  13 #include <linux/platform_device.h>
  14 #include <linux/of.h>
  15 #include <linux/io.h>
  16 #include <linux/kernel.h>
  17 #include <linux/slab.h>
  18 
  19 #define ARC_PS2_PORTS                   2
  20 
  21 #define ARC_ARC_PS2_ID                  0x0001f609
  22 
  23 #define STAT_TIMEOUT                    128
  24 
  25 #define PS2_STAT_RX_FRM_ERR             (1)
  26 #define PS2_STAT_RX_BUF_OVER            (1 << 1)
  27 #define PS2_STAT_RX_INT_EN              (1 << 2)
  28 #define PS2_STAT_RX_VAL                 (1 << 3)
  29 #define PS2_STAT_TX_ISNOT_FUL           (1 << 4)
  30 #define PS2_STAT_TX_INT_EN              (1 << 5)
  31 
  32 struct arc_ps2_port {
  33         void __iomem *data_addr;
  34         void __iomem *status_addr;
  35         struct serio *io;
  36 };
  37 
  38 struct arc_ps2_data {
  39         struct arc_ps2_port port[ARC_PS2_PORTS];
  40         void __iomem *addr;
  41         unsigned int frame_error;
  42         unsigned int buf_overflow;
  43         unsigned int total_int;
  44 };
  45 
  46 static void arc_ps2_check_rx(struct arc_ps2_data *arc_ps2,
  47                              struct arc_ps2_port *port)
  48 {
  49         unsigned int timeout = 1000;
  50         unsigned int flag, status;
  51         unsigned char data;
  52 
  53         do {
  54                 status = ioread32(port->status_addr);
  55                 if (!(status & PS2_STAT_RX_VAL))
  56                         return;
  57 
  58                 data = ioread32(port->data_addr) & 0xff;
  59 
  60                 flag = 0;
  61                 arc_ps2->total_int++;
  62                 if (status & PS2_STAT_RX_FRM_ERR) {
  63                         arc_ps2->frame_error++;
  64                         flag |= SERIO_PARITY;
  65                 } else if (status & PS2_STAT_RX_BUF_OVER) {
  66                         arc_ps2->buf_overflow++;
  67                         flag |= SERIO_FRAME;
  68                 }
  69 
  70                 serio_interrupt(port->io, data, flag);
  71         } while (--timeout);
  72 
  73         dev_err(&port->io->dev, "PS/2 hardware stuck\n");
  74 }
  75 
  76 static irqreturn_t arc_ps2_interrupt(int irq, void *dev)
  77 {
  78         struct arc_ps2_data *arc_ps2 = dev;
  79         int i;
  80 
  81         for (i = 0; i < ARC_PS2_PORTS; i++)
  82                 arc_ps2_check_rx(arc_ps2, &arc_ps2->port[i]);
  83 
  84         return IRQ_HANDLED;
  85 }
  86 
  87 static int arc_ps2_write(struct serio *io, unsigned char val)
  88 {
  89         unsigned status;
  90         struct arc_ps2_port *port = io->port_data;
  91         int timeout = STAT_TIMEOUT;
  92 
  93         do {
  94                 status = ioread32(port->status_addr);
  95                 cpu_relax();
  96 
  97                 if (status & PS2_STAT_TX_ISNOT_FUL) {
  98                         iowrite32(val & 0xff, port->data_addr);
  99                         return 0;
 100                 }
 101 
 102         } while (--timeout);
 103 
 104         dev_err(&io->dev, "write timeout\n");
 105         return -ETIMEDOUT;
 106 }
 107 
 108 static int arc_ps2_open(struct serio *io)
 109 {
 110         struct arc_ps2_port *port = io->port_data;
 111 
 112         iowrite32(PS2_STAT_RX_INT_EN, port->status_addr);
 113 
 114         return 0;
 115 }
 116 
 117 static void arc_ps2_close(struct serio *io)
 118 {
 119         struct arc_ps2_port *port = io->port_data;
 120 
 121         iowrite32(ioread32(port->status_addr) & ~PS2_STAT_RX_INT_EN,
 122                   port->status_addr);
 123 }
 124 
 125 static void __iomem *arc_ps2_calc_addr(struct arc_ps2_data *arc_ps2,
 126                                                   int index, bool status)
 127 {
 128         void __iomem *addr;
 129 
 130         addr = arc_ps2->addr + 4 + 4 * index;
 131         if (status)
 132                 addr += ARC_PS2_PORTS * 4;
 133 
 134         return addr;
 135 }
 136 
 137 static void arc_ps2_inhibit_ports(struct arc_ps2_data *arc_ps2)
 138 {
 139         void __iomem *addr;
 140         u32 val;
 141         int i;
 142 
 143         for (i = 0; i < ARC_PS2_PORTS; i++) {
 144                 addr = arc_ps2_calc_addr(arc_ps2, i, true);
 145                 val = ioread32(addr);
 146                 val &= ~(PS2_STAT_RX_INT_EN | PS2_STAT_TX_INT_EN);
 147                 iowrite32(val, addr);
 148         }
 149 }
 150 
 151 static int arc_ps2_create_port(struct platform_device *pdev,
 152                                          struct arc_ps2_data *arc_ps2,
 153                                          int index)
 154 {
 155         struct arc_ps2_port *port = &arc_ps2->port[index];
 156         struct serio *io;
 157 
 158         io = kzalloc(sizeof(struct serio), GFP_KERNEL);
 159         if (!io)
 160                 return -ENOMEM;
 161 
 162         io->id.type = SERIO_8042;
 163         io->write = arc_ps2_write;
 164         io->open = arc_ps2_open;
 165         io->close = arc_ps2_close;
 166         snprintf(io->name, sizeof(io->name), "ARC PS/2 port%d", index);
 167         snprintf(io->phys, sizeof(io->phys), "arc/serio%d", index);
 168         io->port_data = port;
 169 
 170         port->io = io;
 171 
 172         port->data_addr = arc_ps2_calc_addr(arc_ps2, index, false);
 173         port->status_addr = arc_ps2_calc_addr(arc_ps2, index, true);
 174 
 175         dev_dbg(&pdev->dev, "port%d is allocated (data = 0x%p, status = 0x%p)\n",
 176                 index, port->data_addr, port->status_addr);
 177 
 178         serio_register_port(port->io);
 179         return 0;
 180 }
 181 
 182 static int arc_ps2_probe(struct platform_device *pdev)
 183 {
 184         struct arc_ps2_data *arc_ps2;
 185         struct resource *res;
 186         int irq;
 187         int error, id, i;
 188 
 189         irq = platform_get_irq_byname(pdev, "arc_ps2_irq");
 190         if (irq < 0)
 191                 return -EINVAL;
 192 
 193         arc_ps2 = devm_kzalloc(&pdev->dev, sizeof(struct arc_ps2_data),
 194                                 GFP_KERNEL);
 195         if (!arc_ps2) {
 196                 dev_err(&pdev->dev, "out of memory\n");
 197                 return -ENOMEM;
 198         }
 199 
 200         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 201         arc_ps2->addr = devm_ioremap_resource(&pdev->dev, res);
 202         if (IS_ERR(arc_ps2->addr))
 203                 return PTR_ERR(arc_ps2->addr);
 204 
 205         dev_info(&pdev->dev, "irq = %d, address = 0x%p, ports = %i\n",
 206                  irq, arc_ps2->addr, ARC_PS2_PORTS);
 207 
 208         id = ioread32(arc_ps2->addr);
 209         if (id != ARC_ARC_PS2_ID) {
 210                 dev_err(&pdev->dev, "device id does not match\n");
 211                 return -ENXIO;
 212         }
 213 
 214         arc_ps2_inhibit_ports(arc_ps2);
 215 
 216         error = devm_request_irq(&pdev->dev, irq, arc_ps2_interrupt,
 217                                  0, "arc_ps2", arc_ps2);
 218         if (error) {
 219                 dev_err(&pdev->dev, "Could not allocate IRQ\n");
 220                 return error;
 221         }
 222 
 223         for (i = 0; i < ARC_PS2_PORTS; i++) {
 224                 error = arc_ps2_create_port(pdev, arc_ps2, i);
 225                 if (error) {
 226                         while (--i >= 0)
 227                                 serio_unregister_port(arc_ps2->port[i].io);
 228                         return error;
 229                 }
 230         }
 231 
 232         platform_set_drvdata(pdev, arc_ps2);
 233 
 234         return 0;
 235 }
 236 
 237 static int arc_ps2_remove(struct platform_device *pdev)
 238 {
 239         struct arc_ps2_data *arc_ps2 = platform_get_drvdata(pdev);
 240         int i;
 241 
 242         for (i = 0; i < ARC_PS2_PORTS; i++)
 243                 serio_unregister_port(arc_ps2->port[i].io);
 244 
 245         dev_dbg(&pdev->dev, "interrupt count = %i\n", arc_ps2->total_int);
 246         dev_dbg(&pdev->dev, "frame error count = %i\n", arc_ps2->frame_error);
 247         dev_dbg(&pdev->dev, "buffer overflow count = %i\n",
 248                 arc_ps2->buf_overflow);
 249 
 250         return 0;
 251 }
 252 
 253 #ifdef CONFIG_OF
 254 static const struct of_device_id arc_ps2_match[] = {
 255         { .compatible = "snps,arc_ps2" },
 256         { },
 257 };
 258 MODULE_DEVICE_TABLE(of, arc_ps2_match);
 259 #endif
 260 
 261 static struct platform_driver arc_ps2_driver = {
 262         .driver = {
 263                 .name           = "arc_ps2",
 264                 .of_match_table = of_match_ptr(arc_ps2_match),
 265         },
 266         .probe  = arc_ps2_probe,
 267         .remove = arc_ps2_remove,
 268 };
 269 
 270 module_platform_driver(arc_ps2_driver);
 271 
 272 MODULE_LICENSE("GPL");
 273 MODULE_AUTHOR("Pavel Sokolov <psokolov@synopsys.com>");
 274 MODULE_DESCRIPTION("ARC PS/2 Driver");

/* [<][>][^][v][top][bottom][index][help] */