Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: ad7879 - support auxiliary GPIOs via gpiolib

Drop the simple fancy sysfs hooks for the aux GPIOs and expose these via
the gpiolib interface so that other drivers can use them.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by

Michael Hennerich and committed by
Dmitry Torokhov
ec51b7f5 c332e9fc

+155 -66
+147 -62
drivers/input/touchscreen/ad7879.c
··· 47 47 #include <linux/workqueue.h> 48 48 #include <linux/spi/spi.h> 49 49 #include <linux/i2c.h> 50 + #include <linux/gpio.h> 50 51 51 52 #include <linux/spi/ad7879.h> 52 53 ··· 133 132 struct input_dev *input; 134 133 struct work_struct work; 135 134 struct timer_list timer; 136 - 135 + #ifdef CONFIG_GPIOLIB 136 + struct gpio_chip gc; 137 + #endif 137 138 struct mutex mutex; 138 139 unsigned disabled:1; /* P: mutex */ 139 140 ··· 153 150 u8 median; 154 151 u16 x_plate_ohms; 155 152 u16 pressure_max; 156 - u16 gpio_init; 157 153 u16 cmd_crtl1; 158 154 u16 cmd_crtl2; 159 155 u16 cmd_crtl3; 160 - unsigned gpio:1; 161 156 }; 162 157 163 158 static int ad7879_read(bus_device *, u8); ··· 238 237 239 238 static void ad7879_setup(struct ad7879 *ts) 240 239 { 241 - ts->cmd_crtl3 = AD7879_YPLUS_BIT | 242 - AD7879_XPLUS_BIT | 243 - AD7879_Z2_BIT | 244 - AD7879_Z1_BIT | 245 - AD7879_TEMPMASK_BIT | 246 - AD7879_AUXVBATMASK_BIT | 247 - AD7879_GPIOALERTMASK_BIT; 248 - 249 - ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR | 250 - AD7879_AVG(ts->averaging) | 251 - AD7879_MFS(ts->median) | 252 - AD7879_FCD(ts->first_conversion_delay) | 253 - ts->gpio_init; 254 - 255 - ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 | 256 - AD7879_ACQ(ts->acquisition_time) | 257 - AD7879_TMR(ts->pen_down_acc_interval); 258 - 259 240 ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); 260 241 ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3); 261 242 ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1); ··· 307 324 308 325 static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store); 309 326 310 - static ssize_t ad7879_gpio_show(struct device *dev, 311 - struct device_attribute *attr, char *buf) 312 - { 313 - struct ad7879 *ts = dev_get_drvdata(dev); 314 - 315 - return sprintf(buf, "%u\n", ts->gpio); 316 - } 317 - 318 - static ssize_t ad7879_gpio_store(struct device *dev, 319 - struct device_attribute *attr, 320 - const char *buf, size_t count) 321 - { 322 - struct ad7879 *ts = dev_get_drvdata(dev); 323 - unsigned long val; 324 - int error; 325 - 326 - error = strict_strtoul(buf, 10, &val); 327 - if (error) 328 - return error; 329 - 330 - mutex_lock(&ts->mutex); 331 - ts->gpio = !!val; 332 - error = ad7879_write(ts->bus, AD7879_REG_CTRL2, 333 - ts->gpio ? 334 - ts->cmd_crtl2 & ~AD7879_GPIO_DATA : 335 - ts->cmd_crtl2 | AD7879_GPIO_DATA); 336 - mutex_unlock(&ts->mutex); 337 - 338 - return error ? : count; 339 - } 340 - 341 - static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store); 342 - 343 327 static struct attribute *ad7879_attributes[] = { 344 328 &dev_attr_disable.attr, 345 - &dev_attr_gpio.attr, 346 329 NULL 347 330 }; 348 331 349 332 static const struct attribute_group ad7879_attr_group = { 350 333 .attrs = ad7879_attributes, 351 334 }; 335 + 336 + #ifdef CONFIG_GPIOLIB 337 + static int ad7879_gpio_direction_input(struct gpio_chip *chip, 338 + unsigned gpio) 339 + { 340 + struct ad7879 *ts = container_of(chip, struct ad7879, gc); 341 + int err; 342 + 343 + mutex_lock(&ts->mutex); 344 + ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL; 345 + err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); 346 + mutex_unlock(&ts->mutex); 347 + 348 + return err; 349 + } 350 + 351 + static int ad7879_gpio_direction_output(struct gpio_chip *chip, 352 + unsigned gpio, int level) 353 + { 354 + struct ad7879 *ts = container_of(chip, struct ad7879, gc); 355 + int err; 356 + 357 + mutex_lock(&ts->mutex); 358 + ts->cmd_crtl2 &= ~AD7879_GPIODIR; 359 + ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIOPOL; 360 + if (level) 361 + ts->cmd_crtl2 |= AD7879_GPIO_DATA; 362 + else 363 + ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; 364 + 365 + err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); 366 + mutex_unlock(&ts->mutex); 367 + 368 + return err; 369 + } 370 + 371 + static int ad7879_gpio_get_value(struct gpio_chip *chip, unsigned gpio) 372 + { 373 + struct ad7879 *ts = container_of(chip, struct ad7879, gc); 374 + u16 val; 375 + 376 + mutex_lock(&ts->mutex); 377 + val = ad7879_read(ts->bus, AD7879_REG_CTRL2); 378 + mutex_unlock(&ts->mutex); 379 + 380 + return !!(val & AD7879_GPIO_DATA); 381 + } 382 + 383 + static void ad7879_gpio_set_value(struct gpio_chip *chip, 384 + unsigned gpio, int value) 385 + { 386 + struct ad7879 *ts = container_of(chip, struct ad7879, gc); 387 + 388 + mutex_lock(&ts->mutex); 389 + if (value) 390 + ts->cmd_crtl2 |= AD7879_GPIO_DATA; 391 + else 392 + ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; 393 + 394 + ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); 395 + mutex_unlock(&ts->mutex); 396 + } 397 + 398 + static int __devinit ad7879_gpio_add(struct device *dev) 399 + { 400 + struct ad7879 *ts = dev_get_drvdata(dev); 401 + struct ad7879_platform_data *pdata = dev->platform_data; 402 + int ret = 0; 403 + 404 + if (pdata->gpio_export) { 405 + ts->gc.direction_input = ad7879_gpio_direction_input; 406 + ts->gc.direction_output = ad7879_gpio_direction_output; 407 + ts->gc.get = ad7879_gpio_get_value; 408 + ts->gc.set = ad7879_gpio_set_value; 409 + ts->gc.can_sleep = 1; 410 + ts->gc.base = pdata->gpio_base; 411 + ts->gc.ngpio = 1; 412 + ts->gc.label = "AD7879-GPIO"; 413 + ts->gc.owner = THIS_MODULE; 414 + ts->gc.dev = dev; 415 + 416 + ret = gpiochip_add(&ts->gc); 417 + if (ret) 418 + dev_err(dev, "failed to register gpio %d\n", 419 + ts->gc.base); 420 + } 421 + 422 + return ret; 423 + } 424 + 425 + /* 426 + * We mark ad7879_gpio_remove inline so there is a chance the code 427 + * gets discarded when not needed. We can't do __devinit/__devexit 428 + * markup since it is used in both probe and remove methods. 429 + */ 430 + static inline void ad7879_gpio_remove(struct device *dev) 431 + { 432 + struct ad7879 *ts = dev_get_drvdata(dev); 433 + struct ad7879_platform_data *pdata = dev->platform_data; 434 + int ret; 435 + 436 + if (pdata->gpio_export) { 437 + ret = gpiochip_remove(&ts->gc); 438 + if (ret) 439 + dev_err(dev, "failed to remove gpio %d\n", 440 + ts->gc.base); 441 + } 442 + } 443 + #else 444 + static inline int ad7879_gpio_add(struct device *dev) 445 + { 446 + return 0; 447 + } 448 + 449 + static inline void ad7879_gpio_remove(struct device *dev) 450 + { 451 + } 452 + #endif 352 453 353 454 static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) 354 455 { ··· 469 402 ts->averaging = pdata->averaging; 470 403 ts->pen_down_acc_interval = pdata->pen_down_acc_interval; 471 404 ts->median = pdata->median; 472 - 473 - if (pdata->gpio_output) 474 - ts->gpio_init = AD7879_GPIO_EN | 475 - (pdata->gpio_default ? 0 : AD7879_GPIO_DATA); 476 - else 477 - ts->gpio_init = AD7879_GPIO_EN | AD7879_GPIODIR; 478 405 479 406 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev)); 480 407 ··· 507 446 goto err_free_mem; 508 447 } 509 448 449 + ts->cmd_crtl3 = AD7879_YPLUS_BIT | 450 + AD7879_XPLUS_BIT | 451 + AD7879_Z2_BIT | 452 + AD7879_Z1_BIT | 453 + AD7879_TEMPMASK_BIT | 454 + AD7879_AUXVBATMASK_BIT | 455 + AD7879_GPIOALERTMASK_BIT; 456 + 457 + ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR | 458 + AD7879_AVG(ts->averaging) | 459 + AD7879_MFS(ts->median) | 460 + AD7879_FCD(ts->first_conversion_delay); 461 + 462 + ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 | 463 + AD7879_ACQ(ts->acquisition_time) | 464 + AD7879_TMR(ts->pen_down_acc_interval); 465 + 510 466 ad7879_setup(ts); 511 467 512 468 err = request_irq(bus->irq, ad7879_irq, ··· 538 460 if (err) 539 461 goto err_free_irq; 540 462 541 - err = input_register_device(input_dev); 463 + err = ad7879_gpio_add(&bus->dev); 542 464 if (err) 543 465 goto err_remove_attr; 466 + 467 + err = input_register_device(input_dev); 468 + if (err) 469 + goto err_remove_gpio; 544 470 545 471 dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n", 546 472 revid >> 8, bus->irq); 547 473 548 474 return 0; 549 475 476 + err_remove_gpio: 477 + ad7879_gpio_remove(&bus->dev); 550 478 err_remove_attr: 551 479 sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group); 552 480 err_free_irq: ··· 565 481 566 482 static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts) 567 483 { 484 + ad7879_gpio_remove(&bus->dev); 568 485 ad7879_disable(ts); 569 486 sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group); 570 487 free_irq(ts->bus->irq, ts);
+8 -4
include/linux/spi/ad7879.h
··· 28 28 * 1 = 4, 2 = 8, 3 = 16 (median > averaging) 29 29 */ 30 30 u8 median; 31 - /* 1 = AUX/VBAT/GPIO set to GPIO Output */ 32 - u8 gpio_output; 33 - /* Initial GPIO pin state (valid if gpio_output = 1) */ 34 - u8 gpio_default; 31 + /* 1 = AUX/VBAT/GPIO export GPIO to gpiolib 32 + * requires CONFIG_GPIOLIB 33 + */ 34 + bool gpio_export; 35 + /* identifies the first GPIO number handled by this chip; 36 + * or, if negative, requests dynamic ID allocation. 37 + */ 38 + s32 gpio_base; 35 39 };