| 1 | |
| 2 | |
| 3 | * GPIO based serio bus driver for bit banging the PS/2 protocol
|
| 4 | *
|
| 5 | * Author: Danilo Krummrich <[email protected]>
|
| 6 |
|
| 7 |
|
| 8 | #include <linux/gpio/consumer.h>
|
| 9 | #include <linux/interrupt.h>
|
| 10 | #include <linux/module.h>
|
| 11 | #include <linux/serio.h>
|
| 12 | #include <linux/slab.h>
|
| 13 | #include <linux/platform_device.h>
|
| 14 | #include <linux/workqueue.h>
|
| 15 | #include <linux/completion.h>
|
| 16 | #include <linux/mutex.h>
|
| 17 | #include <linux/preempt.h>
|
| 18 | #include <linux/property.h>
|
| 19 | #include <linux/of.h>
|
| 20 | #include <linux/jiffies.h>
|
| 21 | #include <linux/delay.h>
|
| 22 | #include <linux/timekeeping.h>
|
| 23 |
|
| 24 | #define DRIVER_NAME "ps2-gpio"
|
| 25 |
|
| 26 | #define PS2_MODE_RX 0
|
| 27 | #define PS2_MODE_TX 1
|
| 28 |
|
| 29 | #define PS2_START_BIT 0
|
| 30 | #define PS2_DATA_BIT0 1
|
| 31 | #define PS2_DATA_BIT1 2
|
| 32 | #define PS2_DATA_BIT2 3
|
| 33 | #define PS2_DATA_BIT3 4
|
| 34 | #define PS2_DATA_BIT4 5
|
| 35 | #define PS2_DATA_BIT5 6
|
| 36 | #define PS2_DATA_BIT6 7
|
| 37 | #define PS2_DATA_BIT7 8
|
| 38 | #define PS2_PARITY_BIT 9
|
| 39 | #define PS2_STOP_BIT 10
|
| 40 | #define PS2_ACK_BIT 11
|
| 41 |
|
| 42 | #define PS2_DEV_RET_ACK 0xfa
|
| 43 | #define PS2_DEV_RET_NACK 0xfe
|
| 44 |
|
| 45 | #define PS2_CMD_RESEND 0xfe
|
| 46 |
|
| 47 | |
| 48 | * The PS2 protocol specifies a clock frequency between 10kHz and 16.7kHz,
|
| 49 | * therefore the maximal interrupt interval should be 100us and the minimum
|
| 50 | * interrupt interval should be ~60us. Let's allow +/- 20us for frequency
|
| 51 | * deviations and interrupt latency.
|
| 52 | *
|
| 53 | * The data line must be sampled after ~30us to 50us after the falling edge,
|
| 54 | * since the device updates the data line at the rising edge.
|
| 55 | *
|
| 56 | * ___ ______ ______ ______ ___
|
| 57 | * \ / \ / \ / \ /
|
| 58 | * \ / \ / \ / \ /
|
| 59 | * \______/ \______/ \______/ \______/
|
| 60 | *
|
| 61 | * |-----------------| |--------|
|
| 62 | * 60us/100us 30us/50us
|
| 63 |
|
| 64 | #define PS2_CLK_FREQ_MIN_HZ 10000
|
| 65 | #define PS2_CLK_FREQ_MAX_HZ 16700
|
| 66 | #define PS2_CLK_MIN_INTERVAL_US ((1000 * 1000) / PS2_CLK_FREQ_MAX_HZ)
|
| 67 | #define PS2_CLK_MAX_INTERVAL_US ((1000 * 1000) / PS2_CLK_FREQ_MIN_HZ)
|
| 68 | #define PS2_IRQ_MIN_INTERVAL_US (PS2_CLK_MIN_INTERVAL_US - 20)
|
| 69 | #define PS2_IRQ_MAX_INTERVAL_US (PS2_CLK_MAX_INTERVAL_US + 20)
|
| 70 |
|
| 71 | struct ps2_gpio_data {
|
| 72 | struct device *dev;
|
| 73 | struct serio *serio;
|
| 74 | unsigned char mode;
|
| 75 | struct gpio_desc *gpio_clk;
|
| 76 | struct gpio_desc *gpio_data;
|
| 77 | bool write_enable;
|
| 78 | int irq;
|
| 79 | ktime_t t_irq_now;
|
| 80 | ktime_t t_irq_last;
|
| 81 | struct {
|
| 82 | unsigned char cnt;
|
| 83 | unsigned char byte;
|
| 84 | } rx;
|
| 85 | struct {
|
| 86 | unsigned char cnt;
|
| 87 | unsigned char byte;
|
| 88 | ktime_t t_xfer_start;
|
| 89 | ktime_t t_xfer_end;
|
| 90 | struct completion complete;
|
| 91 | struct mutex mutex;
|
| 92 | struct delayed_work work;
|
| 93 | } tx;
|
| 94 | };
|
| 95 |
|
| 96 | static int ps2_gpio_open(struct serio *serio)
|
| 97 | {
|
| 98 | struct ps2_gpio_data *drvdata = serio->port_data;
|
| 99 |
|
| 100 | drvdata->t_irq_last = 0;
|
| 101 | drvdata->tx.t_xfer_end = 0;
|
| 102 |
|
| 103 | enable_irq(drvdata->irq);
|
| 104 | return 0;
|
| 105 | }
|
| 106 |
|
| 107 | static void ps2_gpio_close(struct serio *serio)
|
| 108 | {
|
| 109 | struct ps2_gpio_data *drvdata = serio->port_data;
|
| 110 |
|
| 111 | flush_delayed_work(&drvdata->tx.work);
|
| 112 | disable_irq(drvdata->irq);
|
| 113 | }
|
| 114 |
|
| 115 | static int __ps2_gpio_write(struct serio *serio, unsigned char val)
|
| 116 | {
|
| 117 | struct ps2_gpio_data *drvdata = serio->port_data;
|
| 118 |
|
| 119 | disable_irq_nosync(drvdata->irq);
|
| 120 | gpiod_direction_output(drvdata->gpio_clk, 0);
|
| 121 |
|
| 122 | drvdata->mode = PS2_MODE_TX;
|
| 123 | drvdata->tx.byte = val;
|
| 124 |
|
| 125 | schedule_delayed_work(&drvdata->tx.work, usecs_to_jiffies(200));
|
| 126 |
|
| 127 | return 0;
|
| 128 | }
|
| 129 |
|
| 130 | static int ps2_gpio_write(struct serio *serio, unsigned char val)
|
| 131 | {
|
| 132 | struct ps2_gpio_data *drvdata = serio->port_data;
|
| 133 | int ret = 0;
|
| 134 |
|
| 135 | if (in_task()) {
|
| 136 | guard(mutex)(&drvdata->tx.mutex);
|
| 137 |
|
| 138 | __ps2_gpio_write(serio, val);
|
| 139 | if (!wait_for_completion_timeout(&drvdata->tx.complete,
|
| 140 | msecs_to_jiffies(10000)))
|
| 141 | ret = SERIO_TIMEOUT;
|
| 142 | } else {
|
| 143 | __ps2_gpio_write(serio, val);
|
| 144 | }
|
| 145 |
|
| 146 | return ret;
|
| 147 | }
|
| 148 |
|
| 149 | static void ps2_gpio_tx_work_fn(struct work_struct *work)
|
| 150 | {
|
| 151 | struct delayed_work *dwork = to_delayed_work(work);
|
| 152 | struct ps2_gpio_data *drvdata = container_of(dwork,
|
| 153 | struct ps2_gpio_data,
|
| 154 | tx.work);
|
| 155 |
|
| 156 | drvdata->tx.t_xfer_start = ktime_get();
|
| 157 | enable_irq(drvdata->irq);
|
| 158 | gpiod_direction_output(drvdata->gpio_data, 0);
|
| 159 | gpiod_direction_input(drvdata->gpio_clk);
|
| 160 | }
|
| 161 |
|
| 162 | static irqreturn_t ps2_gpio_irq_rx(struct ps2_gpio_data *drvdata)
|
| 163 | {
|
| 164 | unsigned char byte, cnt;
|
| 165 | int data;
|
| 166 | int rxflags = 0;
|
| 167 | s64 us_delta;
|
| 168 |
|
| 169 | byte = drvdata->rx.byte;
|
| 170 | cnt = drvdata->rx.cnt;
|
| 171 |
|
| 172 | drvdata->t_irq_now = ktime_get();
|
| 173 |
|
| 174 | |
| 175 | * We need to consider spurious interrupts happening right after
|
| 176 | * a TX xfer finished.
|
| 177 |
|
| 178 | us_delta = ktime_us_delta(drvdata->t_irq_now, drvdata->tx.t_xfer_end);
|
| 179 | if (unlikely(us_delta < PS2_IRQ_MIN_INTERVAL_US))
|
| 180 | goto end;
|
| 181 |
|
| 182 | us_delta = ktime_us_delta(drvdata->t_irq_now, drvdata->t_irq_last);
|
| 183 | if (us_delta > PS2_IRQ_MAX_INTERVAL_US && cnt) {
|
| 184 | dev_err(drvdata->dev,
|
| 185 | "RX: timeout, probably we missed an interrupt\n");
|
| 186 | goto err;
|
| 187 | } else if (unlikely(us_delta < PS2_IRQ_MIN_INTERVAL_US)) {
|
| 188 |
|
| 189 | goto end;
|
| 190 | }
|
| 191 | drvdata->t_irq_last = drvdata->t_irq_now;
|
| 192 |
|
| 193 | data = gpiod_get_value(drvdata->gpio_data);
|
| 194 | if (unlikely(data < 0)) {
|
| 195 | dev_err(drvdata->dev, "RX: failed to get data gpio val: %d\n",
|
| 196 | data);
|
| 197 | goto err;
|
| 198 | }
|
| 199 |
|
| 200 | switch (cnt) {
|
| 201 | case PS2_START_BIT:
|
| 202 |
|
| 203 | if (unlikely(data)) {
|
| 204 | dev_err(drvdata->dev, "RX: start bit should be low\n");
|
| 205 | goto err;
|
| 206 | }
|
| 207 | break;
|
| 208 | case PS2_DATA_BIT0:
|
| 209 | case PS2_DATA_BIT1:
|
| 210 | case PS2_DATA_BIT2:
|
| 211 | case PS2_DATA_BIT3:
|
| 212 | case PS2_DATA_BIT4:
|
| 213 | case PS2_DATA_BIT5:
|
| 214 | case PS2_DATA_BIT6:
|
| 215 | case PS2_DATA_BIT7:
|
| 216 |
|
| 217 | if (data)
|
| 218 | byte |= (data << (cnt - 1));
|
| 219 | break;
|
| 220 | case PS2_PARITY_BIT:
|
| 221 |
|
| 222 | if (!((hweight8(byte) & 1) ^ data)) {
|
| 223 | rxflags |= SERIO_PARITY;
|
| 224 | dev_warn(drvdata->dev, "RX: parity error\n");
|
| 225 | if (!drvdata->write_enable)
|
| 226 | goto err;
|
| 227 | }
|
| 228 | break;
|
| 229 | case PS2_STOP_BIT:
|
| 230 |
|
| 231 | if (unlikely(!data)) {
|
| 232 | dev_err(drvdata->dev, "RX: stop bit should be high\n");
|
| 233 | goto err;
|
| 234 | }
|
| 235 |
|
| 236 | |
| 237 | * Do not send spurious ACK's and NACK's when write fn is
|
| 238 | * not provided.
|
| 239 |
|
| 240 | if (!drvdata->write_enable) {
|
| 241 | if (byte == PS2_DEV_RET_NACK)
|
| 242 | goto err;
|
| 243 | else if (byte == PS2_DEV_RET_ACK)
|
| 244 | break;
|
| 245 | }
|
| 246 |
|
| 247 | serio_interrupt(drvdata->serio, byte, rxflags);
|
| 248 | dev_dbg(drvdata->dev, "RX: sending byte 0x%x\n", byte);
|
| 249 |
|
| 250 | cnt = byte = 0;
|
| 251 |
|
| 252 | goto end;
|
| 253 | default:
|
| 254 | dev_err(drvdata->dev, "RX: got out of sync with the device\n");
|
| 255 | goto err;
|
| 256 | }
|
| 257 |
|
| 258 | cnt++;
|
| 259 | goto end;
|
| 260 |
|
| 261 | err:
|
| 262 | cnt = byte = 0;
|
| 263 | __ps2_gpio_write(drvdata->serio, PS2_CMD_RESEND);
|
| 264 | end:
|
| 265 | drvdata->rx.cnt = cnt;
|
| 266 | drvdata->rx.byte = byte;
|
| 267 | return IRQ_HANDLED;
|
| 268 | }
|
| 269 |
|
| 270 | static irqreturn_t ps2_gpio_irq_tx(struct ps2_gpio_data *drvdata)
|
| 271 | {
|
| 272 | unsigned char byte, cnt;
|
| 273 | int data;
|
| 274 | s64 us_delta;
|
| 275 |
|
| 276 | cnt = drvdata->tx.cnt;
|
| 277 | byte = drvdata->tx.byte;
|
| 278 |
|
| 279 | drvdata->t_irq_now = ktime_get();
|
| 280 |
|
| 281 | |
| 282 | * There might be pending IRQs since we disabled IRQs in
|
| 283 | * __ps2_gpio_write(). We can expect at least one clock period until
|
| 284 | * the device generates the first falling edge after releasing the
|
| 285 | * clock line.
|
| 286 |
|
| 287 | us_delta = ktime_us_delta(drvdata->t_irq_now,
|
| 288 | drvdata->tx.t_xfer_start);
|
| 289 | if (unlikely(us_delta < PS2_CLK_MIN_INTERVAL_US))
|
| 290 | goto end;
|
| 291 |
|
| 292 | us_delta = ktime_us_delta(drvdata->t_irq_now, drvdata->t_irq_last);
|
| 293 | if (us_delta > PS2_IRQ_MAX_INTERVAL_US && cnt > 1) {
|
| 294 | dev_err(drvdata->dev,
|
| 295 | "TX: timeout, probably we missed an interrupt\n");
|
| 296 | goto err;
|
| 297 | } else if (unlikely(us_delta < PS2_IRQ_MIN_INTERVAL_US)) {
|
| 298 |
|
| 299 | goto end;
|
| 300 | }
|
| 301 | drvdata->t_irq_last = drvdata->t_irq_now;
|
| 302 |
|
| 303 | switch (cnt) {
|
| 304 | case PS2_START_BIT:
|
| 305 |
|
| 306 | dev_err(drvdata->dev,
|
| 307 | "TX: start bit should have been sent already\n");
|
| 308 | goto err;
|
| 309 | case PS2_DATA_BIT0:
|
| 310 | case PS2_DATA_BIT1:
|
| 311 | case PS2_DATA_BIT2:
|
| 312 | case PS2_DATA_BIT3:
|
| 313 | case PS2_DATA_BIT4:
|
| 314 | case PS2_DATA_BIT5:
|
| 315 | case PS2_DATA_BIT6:
|
| 316 | case PS2_DATA_BIT7:
|
| 317 | data = byte & BIT(cnt - 1);
|
| 318 | gpiod_set_value(drvdata->gpio_data, data);
|
| 319 | break;
|
| 320 | case PS2_PARITY_BIT:
|
| 321 |
|
| 322 | data = !(hweight8(byte) & 1);
|
| 323 | gpiod_set_value(drvdata->gpio_data, data);
|
| 324 | break;
|
| 325 | case PS2_STOP_BIT:
|
| 326 |
|
| 327 | gpiod_direction_input(drvdata->gpio_data);
|
| 328 | break;
|
| 329 | case PS2_ACK_BIT:
|
| 330 | data = gpiod_get_value(drvdata->gpio_data);
|
| 331 | if (data) {
|
| 332 | dev_warn(drvdata->dev, "TX: received NACK, retry\n");
|
| 333 | goto err;
|
| 334 | }
|
| 335 |
|
| 336 | drvdata->tx.t_xfer_end = ktime_get();
|
| 337 | drvdata->mode = PS2_MODE_RX;
|
| 338 | complete(&drvdata->tx.complete);
|
| 339 |
|
| 340 | cnt = 1;
|
| 341 | goto end;
|
| 342 | default:
|
| 343 | |
| 344 | * Probably we missed the stop bit. Therefore we release data
|
| 345 | * line and try again.
|
| 346 |
|
| 347 | gpiod_direction_input(drvdata->gpio_data);
|
| 348 | dev_err(drvdata->dev, "TX: got out of sync with the device\n");
|
| 349 | goto err;
|
| 350 | }
|
| 351 |
|
| 352 | cnt++;
|
| 353 | goto end;
|
| 354 |
|
| 355 | err:
|
| 356 | cnt = 1;
|
| 357 | gpiod_direction_input(drvdata->gpio_data);
|
| 358 | __ps2_gpio_write(drvdata->serio, drvdata->tx.byte);
|
| 359 | end:
|
| 360 | drvdata->tx.cnt = cnt;
|
| 361 | return IRQ_HANDLED;
|
| 362 | }
|
| 363 |
|
| 364 | static irqreturn_t ps2_gpio_irq(int irq, void *dev_id)
|
| 365 | {
|
| 366 | struct ps2_gpio_data *drvdata = dev_id;
|
| 367 |
|
| 368 | return drvdata->mode ? ps2_gpio_irq_tx(drvdata) :
|
| 369 | ps2_gpio_irq_rx(drvdata);
|
| 370 | }
|
| 371 |
|
| 372 | static int ps2_gpio_get_props(struct device *dev,
|
| 373 | struct ps2_gpio_data *drvdata)
|
| 374 | {
|
| 375 | enum gpiod_flags gflags;
|
| 376 |
|
| 377 |
|
| 378 | gflags = GPIOD_IN | GPIOD_FLAGS_BIT_OPEN_DRAIN;
|
| 379 |
|
| 380 | drvdata->gpio_data = devm_gpiod_get(dev, "data", gflags);
|
| 381 | if (IS_ERR(drvdata->gpio_data)) {
|
| 382 | dev_err(dev, "failed to request data gpio: %ld",
|
| 383 | PTR_ERR(drvdata->gpio_data));
|
| 384 | return PTR_ERR(drvdata->gpio_data);
|
| 385 | }
|
| 386 |
|
| 387 | drvdata->gpio_clk = devm_gpiod_get(dev, "clk", gflags);
|
| 388 | if (IS_ERR(drvdata->gpio_clk)) {
|
| 389 | dev_err(dev, "failed to request clock gpio: %ld",
|
| 390 | PTR_ERR(drvdata->gpio_clk));
|
| 391 | return PTR_ERR(drvdata->gpio_clk);
|
| 392 | }
|
| 393 |
|
| 394 | drvdata->write_enable = device_property_read_bool(dev,
|
| 395 | "write-enable");
|
| 396 |
|
| 397 | return 0;
|
| 398 | }
|
| 399 |
|
| 400 | static int ps2_gpio_probe(struct platform_device *pdev)
|
| 401 | {
|
| 402 | struct ps2_gpio_data *drvdata;
|
| 403 | struct serio *serio;
|
| 404 | struct device *dev = &pdev->dev;
|
| 405 | int error;
|
| 406 |
|
| 407 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
|
| 408 | serio = kzalloc_obj(*serio);
|
| 409 | if (!drvdata || !serio) {
|
| 410 | error = -ENOMEM;
|
| 411 | goto err_free_serio;
|
| 412 | }
|
| 413 |
|
| 414 | error = ps2_gpio_get_props(dev, drvdata);
|
| 415 | if (error)
|
| 416 | goto err_free_serio;
|
| 417 |
|
| 418 | if (gpiod_cansleep(drvdata->gpio_data) ||
|
| 419 | gpiod_cansleep(drvdata->gpio_clk)) {
|
| 420 | dev_err(dev, "GPIO data or clk are connected via slow bus\n");
|
| 421 | error = -EINVAL;
|
| 422 | goto err_free_serio;
|
| 423 | }
|
| 424 |
|
| 425 | drvdata->irq = platform_get_irq(pdev, 0);
|
| 426 | if (drvdata->irq < 0) {
|
| 427 | error = drvdata->irq;
|
| 428 | goto err_free_serio;
|
| 429 | }
|
| 430 |
|
| 431 | error = devm_request_irq(dev, drvdata->irq, ps2_gpio_irq,
|
| 432 | IRQF_NO_THREAD | IRQF_NO_AUTOEN, DRIVER_NAME,
|
| 433 | drvdata);
|
| 434 | if (error) {
|
| 435 | dev_err(dev, "failed to request irq %d: %d\n",
|
| 436 | drvdata->irq, error);
|
| 437 | goto err_free_serio;
|
| 438 | }
|
| 439 |
|
| 440 | serio->id.type = SERIO_8042;
|
| 441 | serio->open = ps2_gpio_open;
|
| 442 | serio->close = ps2_gpio_close;
|
| 443 | |
| 444 | * Write can be enabled in platform/dt data, but possibly it will not
|
| 445 | * work because of the tough timings.
|
| 446 |
|
| 447 | serio->write = drvdata->write_enable ? ps2_gpio_write : NULL;
|
| 448 | serio->port_data = drvdata;
|
| 449 | serio->dev.parent = dev;
|
| 450 | strscpy(serio->name, dev_name(dev), sizeof(serio->name));
|
| 451 | strscpy(serio->phys, dev_name(dev), sizeof(serio->phys));
|
| 452 |
|
| 453 | drvdata->serio = serio;
|
| 454 | drvdata->dev = dev;
|
| 455 | drvdata->mode = PS2_MODE_RX;
|
| 456 |
|
| 457 | |
| 458 | * Tx count always starts at 1, as the start bit is sent implicitly by
|
| 459 | * host-to-device communication initialization.
|
| 460 |
|
| 461 | drvdata->tx.cnt = 1;
|
| 462 |
|
| 463 | INIT_DELAYED_WORK(&drvdata->tx.work, ps2_gpio_tx_work_fn);
|
| 464 | init_completion(&drvdata->tx.complete);
|
| 465 | mutex_init(&drvdata->tx.mutex);
|
| 466 |
|
| 467 | serio_register_port(serio);
|
| 468 | platform_set_drvdata(pdev, drvdata);
|
| 469 |
|
| 470 | return 0;
|
| 471 |
|
| 472 | err_free_serio:
|
| 473 | kfree(serio);
|
| 474 | return error;
|
| 475 | }
|
| 476 |
|
| 477 | static void ps2_gpio_remove(struct platform_device *pdev)
|
| 478 | {
|
| 479 | struct ps2_gpio_data *drvdata = platform_get_drvdata(pdev);
|
| 480 |
|
| 481 | serio_unregister_port(drvdata->serio);
|
| 482 | }
|
| 483 |
|
| 484 | #if defined(CONFIG_OF)
|
| 485 | static const struct of_device_id ps2_gpio_match[] = {
|
| 486 | { .compatible = "ps2-gpio", },
|
| 487 | { },
|
| 488 | };
|
| 489 | MODULE_DEVICE_TABLE(of, ps2_gpio_match);
|
| 490 | #endif
|
| 491 |
|
| 492 | static struct platform_driver ps2_gpio_driver = {
|
| 493 | .probe = ps2_gpio_probe,
|
| 494 | .remove = ps2_gpio_remove,
|
| 495 | .driver = {
|
| 496 | .name = DRIVER_NAME,
|
| 497 | .of_match_table = of_match_ptr(ps2_gpio_match),
|
| 498 | },
|
| 499 | };
|
| 500 | module_platform_driver(ps2_gpio_driver);
|
| 501 |
|
| 502 | MODULE_AUTHOR("Danilo Krummrich <[email protected]>");
|
| 503 | MODULE_DESCRIPTION("GPIO PS2 driver");
|
| 504 | MODULE_LICENSE("GPL v2");
|