linux/drivers/input/serio/apbps2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 2013 Aeroflex Gaisler
   4 *
   5 * This driver supports the APBPS2 PS/2 core available in the GRLIB
   6 * VHDL IP core library.
   7 *
   8 * Full documentation of the APBPS2 core can be found here:
   9 * http://www.gaisler.com/products/grlib/grip.pdf
  10 *
  11 * See "Documentation/devicetree/bindings/input/ps2keyb-mouse-apbps2.txt" for
  12 * information on open firmware properties.
  13 *
  14 * Contributors: Daniel Hellstrom <daniel@gaisler.com>
  15 */
  16#include <linux/platform_device.h>
  17#include <linux/of_device.h>
  18#include <linux/module.h>
  19#include <linux/serio.h>
  20#include <linux/errno.h>
  21#include <linux/interrupt.h>
  22#include <linux/of_irq.h>
  23#include <linux/device.h>
  24#include <linux/delay.h>
  25#include <linux/err.h>
  26#include <linux/slab.h>
  27#include <linux/string.h>
  28#include <linux/kernel.h>
  29#include <linux/io.h>
  30
  31struct apbps2_regs {
  32        u32 __iomem data;       /* 0x00 */
  33        u32 __iomem status;     /* 0x04 */
  34        u32 __iomem ctrl;       /* 0x08 */
  35        u32 __iomem reload;     /* 0x0c */
  36};
  37
  38#define APBPS2_STATUS_DR        (1<<0)
  39#define APBPS2_STATUS_PE        (1<<1)
  40#define APBPS2_STATUS_FE        (1<<2)
  41#define APBPS2_STATUS_KI        (1<<3)
  42#define APBPS2_STATUS_RF        (1<<4)
  43#define APBPS2_STATUS_TF        (1<<5)
  44#define APBPS2_STATUS_TCNT      (0x1f<<22)
  45#define APBPS2_STATUS_RCNT      (0x1f<<27)
  46
  47#define APBPS2_CTRL_RE          (1<<0)
  48#define APBPS2_CTRL_TE          (1<<1)
  49#define APBPS2_CTRL_RI          (1<<2)
  50#define APBPS2_CTRL_TI          (1<<3)
  51
  52struct apbps2_priv {
  53        struct serio            *io;
  54        struct apbps2_regs      *regs;
  55};
  56
  57static int apbps2_idx;
  58
  59static irqreturn_t apbps2_isr(int irq, void *dev_id)
  60{
  61        struct apbps2_priv *priv = dev_id;
  62        unsigned long status, data, rxflags;
  63        irqreturn_t ret = IRQ_NONE;
  64
  65        while ((status = ioread32be(&priv->regs->status)) & APBPS2_STATUS_DR) {
  66                data = ioread32be(&priv->regs->data);
  67                rxflags = (status & APBPS2_STATUS_PE) ? SERIO_PARITY : 0;
  68                rxflags |= (status & APBPS2_STATUS_FE) ? SERIO_FRAME : 0;
  69
  70                /* clear error bits? */
  71                if (rxflags)
  72                        iowrite32be(0, &priv->regs->status);
  73
  74                serio_interrupt(priv->io, data, rxflags);
  75
  76                ret = IRQ_HANDLED;
  77        }
  78
  79        return ret;
  80}
  81
  82static int apbps2_write(struct serio *io, unsigned char val)
  83{
  84        struct apbps2_priv *priv = io->port_data;
  85        unsigned int tleft = 10000; /* timeout in 100ms */
  86
  87        /* delay until PS/2 controller has room for more chars */
  88        while ((ioread32be(&priv->regs->status) & APBPS2_STATUS_TF) && tleft--)
  89                udelay(10);
  90
  91        if ((ioread32be(&priv->regs->status) & APBPS2_STATUS_TF) == 0) {
  92                iowrite32be(val, &priv->regs->data);
  93
  94                iowrite32be(APBPS2_CTRL_RE | APBPS2_CTRL_RI | APBPS2_CTRL_TE,
  95                                &priv->regs->ctrl);
  96                return 0;
  97        }
  98
  99        return -ETIMEDOUT;
 100}
 101
 102static int apbps2_open(struct serio *io)
 103{
 104        struct apbps2_priv *priv = io->port_data;
 105        int limit;
 106        unsigned long tmp;
 107
 108        /* clear error flags */
 109        iowrite32be(0, &priv->regs->status);
 110
 111        /* Clear old data if available (unlikely) */
 112        limit = 1024;
 113        while ((ioread32be(&priv->regs->status) & APBPS2_STATUS_DR) && --limit)
 114                tmp = ioread32be(&priv->regs->data);
 115
 116        /* Enable reciever and it's interrupt */
 117        iowrite32be(APBPS2_CTRL_RE | APBPS2_CTRL_RI, &priv->regs->ctrl);
 118
 119        return 0;
 120}
 121
 122static void apbps2_close(struct serio *io)
 123{
 124        struct apbps2_priv *priv = io->port_data;
 125
 126        /* stop interrupts at PS/2 HW level */
 127        iowrite32be(0, &priv->regs->ctrl);
 128}
 129
 130/* Initialize one APBPS2 PS/2 core */
 131static int apbps2_of_probe(struct platform_device *ofdev)
 132{
 133        struct apbps2_priv *priv;
 134        int irq, err;
 135        u32 freq_hz;
 136        struct resource *res;
 137
 138        priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL);
 139        if (!priv) {
 140                dev_err(&ofdev->dev, "memory allocation failed\n");
 141                return -ENOMEM;
 142        }
 143
 144        /* Find Device Address */
 145        res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
 146        priv->regs = devm_ioremap_resource(&ofdev->dev, res);
 147        if (IS_ERR(priv->regs))
 148                return PTR_ERR(priv->regs);
 149
 150        /* Reset hardware, disable interrupt */
 151        iowrite32be(0, &priv->regs->ctrl);
 152
 153        /* IRQ */
 154        irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
 155        err = devm_request_irq(&ofdev->dev, irq, apbps2_isr,
 156                                IRQF_SHARED, "apbps2", priv);
 157        if (err) {
 158                dev_err(&ofdev->dev, "request IRQ%d failed\n", irq);
 159                return err;
 160        }
 161
 162        /* Get core frequency */
 163        if (of_property_read_u32(ofdev->dev.of_node, "freq", &freq_hz)) {
 164                dev_err(&ofdev->dev, "unable to get core frequency\n");
 165                return -EINVAL;
 166        }
 167
 168        /* Set reload register to core freq in kHz/10 */
 169        iowrite32be(freq_hz / 10000, &priv->regs->reload);
 170
 171        priv->io = kzalloc(sizeof(struct serio), GFP_KERNEL);
 172        if (!priv->io)
 173                return -ENOMEM;
 174
 175        priv->io->id.type = SERIO_8042;
 176        priv->io->open = apbps2_open;
 177        priv->io->close = apbps2_close;
 178        priv->io->write = apbps2_write;
 179        priv->io->port_data = priv;
 180        strlcpy(priv->io->name, "APBPS2 PS/2", sizeof(priv->io->name));
 181        snprintf(priv->io->phys, sizeof(priv->io->phys),
 182                 "apbps2_%d", apbps2_idx++);
 183
 184        dev_info(&ofdev->dev, "irq = %d, base = 0x%p\n", irq, priv->regs);
 185
 186        serio_register_port(priv->io);
 187
 188        platform_set_drvdata(ofdev, priv);
 189
 190        return 0;
 191}
 192
 193static int apbps2_of_remove(struct platform_device *of_dev)
 194{
 195        struct apbps2_priv *priv = platform_get_drvdata(of_dev);
 196
 197        serio_unregister_port(priv->io);
 198
 199        return 0;
 200}
 201
 202static const struct of_device_id apbps2_of_match[] = {
 203        { .name = "GAISLER_APBPS2", },
 204        { .name = "01_060", },
 205        {}
 206};
 207
 208MODULE_DEVICE_TABLE(of, apbps2_of_match);
 209
 210static struct platform_driver apbps2_of_driver = {
 211        .driver = {
 212                .name = "grlib-apbps2",
 213                .of_match_table = apbps2_of_match,
 214        },
 215        .probe = apbps2_of_probe,
 216        .remove = apbps2_of_remove,
 217};
 218
 219module_platform_driver(apbps2_of_driver);
 220
 221MODULE_AUTHOR("Aeroflex Gaisler AB.");
 222MODULE_DESCRIPTION("GRLIB APBPS2 PS/2 serial I/O");
 223MODULE_LICENSE("GPL");
 224