linux/drivers/input/rmi4/rmi_f03.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015-2016 Red Hat
   3 * Copyright (C) 2015 Lyude Paul <thatslyude@gmail.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 as published by
   7 * the Free Software Foundation.
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/slab.h>
  12#include <linux/serio.h>
  13#include <linux/notifier.h>
  14#include "rmi_driver.h"
  15
  16#define RMI_F03_RX_DATA_OFB             0x01
  17#define RMI_F03_OB_SIZE                 2
  18
  19#define RMI_F03_OB_OFFSET               2
  20#define RMI_F03_OB_DATA_OFFSET          1
  21#define RMI_F03_OB_FLAG_TIMEOUT         BIT(6)
  22#define RMI_F03_OB_FLAG_PARITY          BIT(7)
  23
  24#define RMI_F03_DEVICE_COUNT            0x07
  25#define RMI_F03_BYTES_PER_DEVICE        0x07
  26#define RMI_F03_BYTES_PER_DEVICE_SHIFT  4
  27#define RMI_F03_QUEUE_LENGTH            0x0F
  28
  29#define PSMOUSE_OOB_EXTRA_BTNS          0x01
  30
  31struct f03_data {
  32        struct rmi_function *fn;
  33
  34        struct serio *serio;
  35
  36        unsigned int overwrite_buttons;
  37
  38        u8 device_count;
  39        u8 rx_queue_length;
  40};
  41
  42int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
  43                             int value)
  44{
  45        struct f03_data *f03 = dev_get_drvdata(&fn->dev);
  46        unsigned int bit;
  47
  48        if (button < BTN_LEFT || button > BTN_MIDDLE)
  49                return -EINVAL;
  50
  51        bit = BIT(button - BTN_LEFT);
  52
  53        if (value)
  54                f03->overwrite_buttons |= bit;
  55        else
  56                f03->overwrite_buttons &= ~bit;
  57
  58        return 0;
  59}
  60
  61void rmi_f03_commit_buttons(struct rmi_function *fn)
  62{
  63        struct f03_data *f03 = dev_get_drvdata(&fn->dev);
  64        struct serio *serio = f03->serio;
  65
  66        serio_pause_rx(serio);
  67        if (serio->drv) {
  68                serio->drv->interrupt(serio, PSMOUSE_OOB_EXTRA_BTNS,
  69                                      SERIO_OOB_DATA);
  70                serio->drv->interrupt(serio, f03->overwrite_buttons,
  71                                      SERIO_OOB_DATA);
  72        }
  73        serio_continue_rx(serio);
  74}
  75
  76static int rmi_f03_pt_write(struct serio *id, unsigned char val)
  77{
  78        struct f03_data *f03 = id->port_data;
  79        int error;
  80
  81        rmi_dbg(RMI_DEBUG_FN, &f03->fn->dev,
  82                "%s: Wrote %.2hhx to PS/2 passthrough address",
  83                __func__, val);
  84
  85        error = rmi_write(f03->fn->rmi_dev, f03->fn->fd.data_base_addr, val);
  86        if (error) {
  87                dev_err(&f03->fn->dev,
  88                        "%s: Failed to write to F03 TX register (%d).\n",
  89                        __func__, error);
  90                return error;
  91        }
  92
  93        return 0;
  94}
  95
  96static int rmi_f03_initialize(struct f03_data *f03)
  97{
  98        struct rmi_function *fn = f03->fn;
  99        struct device *dev = &fn->dev;
 100        int error;
 101        u8 bytes_per_device;
 102        u8 query1;
 103        u8 query2[RMI_F03_DEVICE_COUNT * RMI_F03_BYTES_PER_DEVICE];
 104        size_t query2_len;
 105
 106        error = rmi_read(fn->rmi_dev, fn->fd.query_base_addr, &query1);
 107        if (error) {
 108                dev_err(dev, "Failed to read query register (%d).\n", error);
 109                return error;
 110        }
 111
 112        f03->device_count = query1 & RMI_F03_DEVICE_COUNT;
 113        bytes_per_device = (query1 >> RMI_F03_BYTES_PER_DEVICE_SHIFT) &
 114                                RMI_F03_BYTES_PER_DEVICE;
 115
 116        query2_len = f03->device_count * bytes_per_device;
 117
 118        /*
 119         * The first generation of image sensors don't have a second part to
 120         * their f03 query, as such we have to set some of these values manually
 121         */
 122        if (query2_len < 1) {
 123                f03->device_count = 1;
 124                f03->rx_queue_length = 7;
 125        } else {
 126                error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr + 1,
 127                                       query2, query2_len);
 128                if (error) {
 129                        dev_err(dev,
 130                                "Failed to read second set of query registers (%d).\n",
 131                                error);
 132                        return error;
 133                }
 134
 135                f03->rx_queue_length = query2[0] & RMI_F03_QUEUE_LENGTH;
 136        }
 137
 138        return 0;
 139}
 140
 141static int rmi_f03_register_pt(struct f03_data *f03)
 142{
 143        struct serio *serio;
 144
 145        serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
 146        if (!serio)
 147                return -ENOMEM;
 148
 149        serio->id.type = SERIO_8042;
 150        serio->write = rmi_f03_pt_write;
 151        serio->port_data = f03;
 152
 153        strlcpy(serio->name, "Synaptics RMI4 PS/2 pass-through",
 154                sizeof(serio->name));
 155        strlcpy(serio->phys, "synaptics-rmi4-pt/serio1",
 156                sizeof(serio->phys));
 157        serio->dev.parent = &f03->fn->dev;
 158
 159        f03->serio = serio;
 160
 161        serio_register_port(serio);
 162
 163        return 0;
 164}
 165
 166static int rmi_f03_probe(struct rmi_function *fn)
 167{
 168        struct device *dev = &fn->dev;
 169        struct f03_data *f03;
 170        int error;
 171
 172        f03 = devm_kzalloc(dev, sizeof(struct f03_data), GFP_KERNEL);
 173        if (!f03)
 174                return -ENOMEM;
 175
 176        f03->fn = fn;
 177
 178        error = rmi_f03_initialize(f03);
 179        if (error < 0)
 180                return error;
 181
 182        if (f03->device_count != 1)
 183                dev_warn(dev, "found %d devices on PS/2 passthrough",
 184                         f03->device_count);
 185
 186        dev_set_drvdata(dev, f03);
 187
 188        error = rmi_f03_register_pt(f03);
 189        if (error)
 190                return error;
 191
 192        return 0;
 193}
 194
 195static int rmi_f03_config(struct rmi_function *fn)
 196{
 197        fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn->irq_mask);
 198
 199        return 0;
 200}
 201
 202static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
 203{
 204        struct rmi_device *rmi_dev = fn->rmi_dev;
 205        struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
 206        struct f03_data *f03 = dev_get_drvdata(&fn->dev);
 207        u16 data_addr = fn->fd.data_base_addr;
 208        const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
 209        u8 obs[RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE];
 210        u8 ob_status;
 211        u8 ob_data;
 212        unsigned int serio_flags;
 213        int i;
 214        int error;
 215
 216        if (drvdata->attn_data.data) {
 217                /* First grab the data passed by the transport device */
 218                if (drvdata->attn_data.size < ob_len) {
 219                        dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
 220                        return 0;
 221                }
 222
 223                memcpy(obs, drvdata->attn_data.data, ob_len);
 224
 225                drvdata->attn_data.data += ob_len;
 226                drvdata->attn_data.size -= ob_len;
 227        } else {
 228                /* Grab all of the data registers, and check them for data */
 229                error = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET,
 230                                       &obs, ob_len);
 231                if (error) {
 232                        dev_err(&fn->dev,
 233                                "%s: Failed to read F03 output buffers: %d\n",
 234                                __func__, error);
 235                        serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
 236                        return error;
 237                }
 238        }
 239
 240        for (i = 0; i < ob_len; i += RMI_F03_OB_SIZE) {
 241                ob_status = obs[i];
 242                ob_data = obs[i + RMI_F03_OB_DATA_OFFSET];
 243                serio_flags = 0;
 244
 245                if (!(ob_status & RMI_F03_RX_DATA_OFB))
 246                        continue;
 247
 248                if (ob_status & RMI_F03_OB_FLAG_TIMEOUT)
 249                        serio_flags |= SERIO_TIMEOUT;
 250                if (ob_status & RMI_F03_OB_FLAG_PARITY)
 251                        serio_flags |= SERIO_PARITY;
 252
 253                rmi_dbg(RMI_DEBUG_FN, &fn->dev,
 254                        "%s: Received %.2hhx from PS2 guest T: %c P: %c\n",
 255                        __func__, ob_data,
 256                        serio_flags & SERIO_TIMEOUT ?  'Y' : 'N',
 257                        serio_flags & SERIO_PARITY ? 'Y' : 'N');
 258
 259                serio_interrupt(f03->serio, ob_data, serio_flags);
 260        }
 261
 262        return 0;
 263}
 264
 265static void rmi_f03_remove(struct rmi_function *fn)
 266{
 267        struct f03_data *f03 = dev_get_drvdata(&fn->dev);
 268
 269        serio_unregister_port(f03->serio);
 270}
 271
 272struct rmi_function_handler rmi_f03_handler = {
 273        .driver = {
 274                .name = "rmi4_f03",
 275        },
 276        .func = 0x03,
 277        .probe = rmi_f03_probe,
 278        .config = rmi_f03_config,
 279        .attention = rmi_f03_attention,
 280        .remove = rmi_f03_remove,
 281};
 282
 283MODULE_AUTHOR("Lyude Paul <thatslyude@gmail.com>");
 284MODULE_DESCRIPTION("RMI F03 module");
 285MODULE_LICENSE("GPL");
 286