| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * AD7879/AD7889 based touchscreen and GPIO driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the GPL-2 or later. |
|---|
| 7 | 6 | * |
|---|
| 8 | 7 | * History: |
|---|
| 9 | 8 | * Copyright (c) 2005 David Brownell |
|---|
| .. | .. |
|---|
| 29 | 28 | #include <linux/property.h> |
|---|
| 30 | 29 | #include <linux/regmap.h> |
|---|
| 31 | 30 | #include <linux/slab.h> |
|---|
| 32 | | -#include <linux/gpio.h> |
|---|
| 31 | +#include <linux/gpio/driver.h> |
|---|
| 33 | 32 | |
|---|
| 34 | 33 | #include <linux/input/touchscreen.h> |
|---|
| 35 | | -#include <linux/platform_data/ad7879.h> |
|---|
| 36 | 34 | #include <linux/module.h> |
|---|
| 37 | 35 | #include "ad7879.h" |
|---|
| 38 | 36 | |
|---|
| .. | .. |
|---|
| 247 | 245 | static irqreturn_t ad7879_irq(int irq, void *handle) |
|---|
| 248 | 246 | { |
|---|
| 249 | 247 | struct ad7879 *ts = handle; |
|---|
| 248 | + int error; |
|---|
| 250 | 249 | |
|---|
| 251 | | - regmap_bulk_read(ts->regmap, AD7879_REG_XPLUS, |
|---|
| 252 | | - ts->conversion_data, AD7879_NR_SENSE); |
|---|
| 253 | | - |
|---|
| 254 | | - if (!ad7879_report(ts)) |
|---|
| 250 | + error = regmap_bulk_read(ts->regmap, AD7879_REG_XPLUS, |
|---|
| 251 | + ts->conversion_data, AD7879_NR_SENSE); |
|---|
| 252 | + if (error) |
|---|
| 253 | + dev_err_ratelimited(ts->dev, "failed to read %#02x: %d\n", |
|---|
| 254 | + AD7879_REG_XPLUS, error); |
|---|
| 255 | + else if (!ad7879_report(ts)) |
|---|
| 255 | 256 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); |
|---|
| 256 | 257 | |
|---|
| 257 | 258 | return IRQ_HANDLED; |
|---|
| .. | .. |
|---|
| 290 | 291 | return 0; |
|---|
| 291 | 292 | } |
|---|
| 292 | 293 | |
|---|
| 293 | | -static void ad7879_close(struct input_dev* input) |
|---|
| 294 | +static void ad7879_close(struct input_dev *input) |
|---|
| 294 | 295 | { |
|---|
| 295 | 296 | struct ad7879 *ts = input_get_drvdata(input); |
|---|
| 296 | 297 | |
|---|
| .. | .. |
|---|
| 452 | 453 | mutex_unlock(&ts->mutex); |
|---|
| 453 | 454 | } |
|---|
| 454 | 455 | |
|---|
| 455 | | -static int ad7879_gpio_add(struct ad7879 *ts, |
|---|
| 456 | | - const struct ad7879_platform_data *pdata) |
|---|
| 456 | +static int ad7879_gpio_add(struct ad7879 *ts) |
|---|
| 457 | 457 | { |
|---|
| 458 | | - bool gpio_export; |
|---|
| 459 | | - int gpio_base; |
|---|
| 460 | 458 | int ret = 0; |
|---|
| 461 | | - |
|---|
| 462 | | - if (pdata) { |
|---|
| 463 | | - gpio_export = pdata->gpio_export; |
|---|
| 464 | | - gpio_base = pdata->gpio_base; |
|---|
| 465 | | - } else { |
|---|
| 466 | | - gpio_export = device_property_read_bool(ts->dev, |
|---|
| 467 | | - "gpio-controller"); |
|---|
| 468 | | - gpio_base = -1; |
|---|
| 469 | | - } |
|---|
| 470 | 459 | |
|---|
| 471 | 460 | mutex_init(&ts->mutex); |
|---|
| 472 | 461 | |
|---|
| 473 | | - if (gpio_export) { |
|---|
| 474 | | - ts->gc.direction_input = ad7879_gpio_direction_input; |
|---|
| 475 | | - ts->gc.direction_output = ad7879_gpio_direction_output; |
|---|
| 476 | | - ts->gc.get = ad7879_gpio_get_value; |
|---|
| 477 | | - ts->gc.set = ad7879_gpio_set_value; |
|---|
| 478 | | - ts->gc.can_sleep = 1; |
|---|
| 479 | | - ts->gc.base = gpio_base; |
|---|
| 480 | | - ts->gc.ngpio = 1; |
|---|
| 481 | | - ts->gc.label = "AD7879-GPIO"; |
|---|
| 482 | | - ts->gc.owner = THIS_MODULE; |
|---|
| 483 | | - ts->gc.parent = ts->dev; |
|---|
| 462 | + /* Do not create a chip unless flagged for it */ |
|---|
| 463 | + if (!device_property_read_bool(ts->dev, "gpio-controller")) |
|---|
| 464 | + return 0; |
|---|
| 484 | 465 | |
|---|
| 485 | | - ret = devm_gpiochip_add_data(ts->dev, &ts->gc, ts); |
|---|
| 486 | | - if (ret) |
|---|
| 487 | | - dev_err(ts->dev, "failed to register gpio %d\n", |
|---|
| 488 | | - ts->gc.base); |
|---|
| 489 | | - } |
|---|
| 466 | + ts->gc.direction_input = ad7879_gpio_direction_input; |
|---|
| 467 | + ts->gc.direction_output = ad7879_gpio_direction_output; |
|---|
| 468 | + ts->gc.get = ad7879_gpio_get_value; |
|---|
| 469 | + ts->gc.set = ad7879_gpio_set_value; |
|---|
| 470 | + ts->gc.can_sleep = 1; |
|---|
| 471 | + ts->gc.base = -1; |
|---|
| 472 | + ts->gc.ngpio = 1; |
|---|
| 473 | + ts->gc.label = "AD7879-GPIO"; |
|---|
| 474 | + ts->gc.owner = THIS_MODULE; |
|---|
| 475 | + ts->gc.parent = ts->dev; |
|---|
| 476 | + |
|---|
| 477 | + ret = devm_gpiochip_add_data(ts->dev, &ts->gc, ts); |
|---|
| 478 | + if (ret) |
|---|
| 479 | + dev_err(ts->dev, "failed to register gpio %d\n", |
|---|
| 480 | + ts->gc.base); |
|---|
| 490 | 481 | |
|---|
| 491 | 482 | return ret; |
|---|
| 492 | 483 | } |
|---|
| 493 | 484 | #else |
|---|
| 494 | | -static int ad7879_gpio_add(struct ad7879 *ts, |
|---|
| 495 | | - const struct ad7879_platform_data *pdata) |
|---|
| 485 | +static int ad7879_gpio_add(struct ad7879 *ts) |
|---|
| 496 | 486 | { |
|---|
| 497 | 487 | return 0; |
|---|
| 498 | 488 | } |
|---|
| .. | .. |
|---|
| 527 | 517 | int ad7879_probe(struct device *dev, struct regmap *regmap, |
|---|
| 528 | 518 | int irq, u16 bustype, u8 devid) |
|---|
| 529 | 519 | { |
|---|
| 530 | | - struct ad7879_platform_data *pdata = dev_get_platdata(dev); |
|---|
| 531 | 520 | struct ad7879 *ts; |
|---|
| 532 | 521 | struct input_dev *input_dev; |
|---|
| 533 | 522 | int err; |
|---|
| .. | .. |
|---|
| 542 | 531 | if (!ts) |
|---|
| 543 | 532 | return -ENOMEM; |
|---|
| 544 | 533 | |
|---|
| 545 | | - if (pdata) { |
|---|
| 546 | | - /* Platform data use swapped axis (backward compatibility) */ |
|---|
| 547 | | - ts->swap_xy = !pdata->swap_xy; |
|---|
| 548 | | - |
|---|
| 549 | | - ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; |
|---|
| 550 | | - |
|---|
| 551 | | - ts->first_conversion_delay = pdata->first_conversion_delay; |
|---|
| 552 | | - ts->acquisition_time = pdata->acquisition_time; |
|---|
| 553 | | - ts->averaging = pdata->averaging; |
|---|
| 554 | | - ts->pen_down_acc_interval = pdata->pen_down_acc_interval; |
|---|
| 555 | | - ts->median = pdata->median; |
|---|
| 556 | | - } else { |
|---|
| 557 | | - err = ad7879_parse_dt(dev, ts); |
|---|
| 558 | | - if (err) |
|---|
| 559 | | - return err; |
|---|
| 560 | | - } |
|---|
| 534 | + err = ad7879_parse_dt(dev, ts); |
|---|
| 535 | + if (err) |
|---|
| 536 | + return err; |
|---|
| 561 | 537 | |
|---|
| 562 | 538 | input_dev = devm_input_allocate_device(dev); |
|---|
| 563 | 539 | if (!input_dev) { |
|---|
| .. | .. |
|---|
| 585 | 561 | |
|---|
| 586 | 562 | input_set_capability(input_dev, EV_KEY, BTN_TOUCH); |
|---|
| 587 | 563 | |
|---|
| 588 | | - if (pdata) { |
|---|
| 589 | | - input_set_abs_params(input_dev, ABS_X, |
|---|
| 590 | | - pdata->x_min ? : 0, |
|---|
| 591 | | - pdata->x_max ? : MAX_12BIT, |
|---|
| 592 | | - 0, 0); |
|---|
| 593 | | - input_set_abs_params(input_dev, ABS_Y, |
|---|
| 594 | | - pdata->y_min ? : 0, |
|---|
| 595 | | - pdata->y_max ? : MAX_12BIT, |
|---|
| 596 | | - 0, 0); |
|---|
| 597 | | - input_set_abs_params(input_dev, ABS_PRESSURE, |
|---|
| 598 | | - pdata->pressure_min, |
|---|
| 599 | | - pdata->pressure_max ? : ~0, |
|---|
| 600 | | - 0, 0); |
|---|
| 601 | | - } else { |
|---|
| 602 | | - input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); |
|---|
| 603 | | - input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); |
|---|
| 604 | | - input_set_capability(input_dev, EV_ABS, ABS_PRESSURE); |
|---|
| 605 | | - touchscreen_parse_properties(input_dev, false, NULL); |
|---|
| 606 | | - if (!input_abs_get_max(input_dev, ABS_PRESSURE)) { |
|---|
| 607 | | - dev_err(dev, "Touchscreen pressure is not specified\n"); |
|---|
| 608 | | - return -EINVAL; |
|---|
| 609 | | - } |
|---|
| 564 | + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); |
|---|
| 565 | + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); |
|---|
| 566 | + input_set_capability(input_dev, EV_ABS, ABS_PRESSURE); |
|---|
| 567 | + touchscreen_parse_properties(input_dev, false, NULL); |
|---|
| 568 | + if (!input_abs_get_max(input_dev, ABS_PRESSURE)) { |
|---|
| 569 | + dev_err(dev, "Touchscreen pressure is not specified\n"); |
|---|
| 570 | + return -EINVAL; |
|---|
| 610 | 571 | } |
|---|
| 611 | 572 | |
|---|
| 612 | 573 | err = ad7879_write(ts, AD7879_REG_CTRL2, AD7879_RESET); |
|---|
| .. | .. |
|---|
| 655 | 616 | if (err) |
|---|
| 656 | 617 | return err; |
|---|
| 657 | 618 | |
|---|
| 658 | | - err = ad7879_gpio_add(ts, pdata); |
|---|
| 619 | + err = ad7879_gpio_add(ts); |
|---|
| 659 | 620 | if (err) |
|---|
| 660 | 621 | return err; |
|---|
| 661 | 622 | |
|---|