gpio-beeper.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Generic GPIO beeper driver
  3. *
  4. * Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. */
  11. #include <linux/input.h>
  12. #include <linux/module.h>
  13. #include <linux/of_gpio.h>
  14. #include <linux/workqueue.h>
  15. #include <linux/platform_device.h>
  16. #define BEEPER_MODNAME "gpio-beeper"
  17. struct gpio_beeper {
  18. struct work_struct work;
  19. int gpio;
  20. bool active_low;
  21. bool beeping;
  22. };
  23. static void gpio_beeper_toggle(struct gpio_beeper *beep, bool on)
  24. {
  25. gpio_set_value_cansleep(beep->gpio, on ^ beep->active_low);
  26. }
  27. static void gpio_beeper_work(struct work_struct *work)
  28. {
  29. struct gpio_beeper *beep = container_of(work, struct gpio_beeper, work);
  30. gpio_beeper_toggle(beep, beep->beeping);
  31. }
  32. static int gpio_beeper_event(struct input_dev *dev, unsigned int type,
  33. unsigned int code, int value)
  34. {
  35. struct gpio_beeper *beep = input_get_drvdata(dev);
  36. if (type != EV_SND || code != SND_BELL)
  37. return -ENOTSUPP;
  38. if (value < 0)
  39. return -EINVAL;
  40. beep->beeping = value;
  41. /* Schedule work to actually turn the beeper on or off */
  42. schedule_work(&beep->work);
  43. return 0;
  44. }
  45. static void gpio_beeper_close(struct input_dev *input)
  46. {
  47. struct gpio_beeper *beep = input_get_drvdata(input);
  48. cancel_work_sync(&beep->work);
  49. gpio_beeper_toggle(beep, false);
  50. }
  51. static int gpio_beeper_probe(struct platform_device *pdev)
  52. {
  53. struct gpio_beeper *beep;
  54. enum of_gpio_flags flags;
  55. struct input_dev *input;
  56. unsigned long gflags;
  57. int err;
  58. beep = devm_kzalloc(&pdev->dev, sizeof(*beep), GFP_KERNEL);
  59. if (!beep)
  60. return -ENOMEM;
  61. beep->gpio = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
  62. if (!gpio_is_valid(beep->gpio))
  63. return beep->gpio;
  64. input = devm_input_allocate_device(&pdev->dev);
  65. if (!input)
  66. return -ENOMEM;
  67. INIT_WORK(&beep->work, gpio_beeper_work);
  68. input->name = pdev->name;
  69. input->id.bustype = BUS_HOST;
  70. input->id.vendor = 0x0001;
  71. input->id.product = 0x0001;
  72. input->id.version = 0x0100;
  73. input->close = gpio_beeper_close;
  74. input->event = gpio_beeper_event;
  75. input_set_capability(input, EV_SND, SND_BELL);
  76. beep->active_low = flags & OF_GPIO_ACTIVE_LOW;
  77. gflags = beep->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
  78. err = devm_gpio_request_one(&pdev->dev, beep->gpio, gflags, pdev->name);
  79. if (err)
  80. return err;
  81. input_set_drvdata(input, beep);
  82. return input_register_device(input);
  83. }
  84. static struct of_device_id gpio_beeper_of_match[] = {
  85. { .compatible = BEEPER_MODNAME, },
  86. { }
  87. };
  88. MODULE_DEVICE_TABLE(of, gpio_beeper_of_match);
  89. static struct platform_driver gpio_beeper_platform_driver = {
  90. .driver = {
  91. .name = BEEPER_MODNAME,
  92. .owner = THIS_MODULE,
  93. .of_match_table = gpio_beeper_of_match,
  94. },
  95. .probe = gpio_beeper_probe,
  96. };
  97. module_platform_driver(gpio_beeper_platform_driver);
  98. MODULE_LICENSE("GPL");
  99. MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
  100. MODULE_DESCRIPTION("Generic GPIO beeper driver");