gpio-mockup.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /*
  2. * GPIO Testing Device Driver
  3. *
  4. * Copyright (C) 2014 Kamlakant Patel <kamlakant.patel@broadcom.com>
  5. * Copyright (C) 2015-2016 Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
  6. * Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. *
  13. */
  14. #include <linux/init.h>
  15. #include <linux/module.h>
  16. #include <linux/gpio/driver.h>
  17. #include <linux/gpio/consumer.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/slab.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/irq.h>
  22. #include <linux/irq_sim.h>
  23. #include <linux/debugfs.h>
  24. #include <linux/uaccess.h>
  25. #include "gpiolib.h"
  26. #define GPIO_MOCKUP_NAME "gpio-mockup"
  27. #define GPIO_MOCKUP_MAX_GC 10
  28. /*
  29. * We're storing two values per chip: the GPIO base and the number
  30. * of GPIO lines.
  31. */
  32. #define GPIO_MOCKUP_MAX_RANGES (GPIO_MOCKUP_MAX_GC * 2)
  33. enum {
  34. GPIO_MOCKUP_DIR_OUT = 0,
  35. GPIO_MOCKUP_DIR_IN = 1,
  36. };
  37. /*
  38. * struct gpio_pin_status - structure describing a GPIO status
  39. * @dir: Configures direction of gpio as "in" or "out", 0=in, 1=out
  40. * @value: Configures status of the gpio as 0(low) or 1(high)
  41. */
  42. struct gpio_mockup_line_status {
  43. int dir;
  44. bool value;
  45. };
  46. struct gpio_mockup_chip {
  47. struct gpio_chip gc;
  48. struct gpio_mockup_line_status *lines;
  49. struct irq_sim irqsim;
  50. struct dentry *dbg_dir;
  51. };
  52. struct gpio_mockup_dbgfs_private {
  53. struct gpio_mockup_chip *chip;
  54. struct gpio_desc *desc;
  55. int offset;
  56. };
  57. static int gpio_mockup_ranges[GPIO_MOCKUP_MAX_RANGES];
  58. static int gpio_mockup_params_nr;
  59. module_param_array(gpio_mockup_ranges, int, &gpio_mockup_params_nr, 0400);
  60. static bool gpio_mockup_named_lines;
  61. module_param_named(gpio_mockup_named_lines,
  62. gpio_mockup_named_lines, bool, 0400);
  63. static const char gpio_mockup_name_start = 'A';
  64. static struct dentry *gpio_mockup_dbg_dir;
  65. static int gpio_mockup_get(struct gpio_chip *gc, unsigned int offset)
  66. {
  67. struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
  68. return chip->lines[offset].value;
  69. }
  70. static void gpio_mockup_set(struct gpio_chip *gc, unsigned int offset,
  71. int value)
  72. {
  73. struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
  74. chip->lines[offset].value = !!value;
  75. }
  76. static int gpio_mockup_dirout(struct gpio_chip *gc, unsigned int offset,
  77. int value)
  78. {
  79. struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
  80. gpio_mockup_set(gc, offset, value);
  81. chip->lines[offset].dir = GPIO_MOCKUP_DIR_OUT;
  82. return 0;
  83. }
  84. static int gpio_mockup_dirin(struct gpio_chip *gc, unsigned int offset)
  85. {
  86. struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
  87. chip->lines[offset].dir = GPIO_MOCKUP_DIR_IN;
  88. return 0;
  89. }
  90. static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset)
  91. {
  92. struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
  93. return chip->lines[offset].dir;
  94. }
  95. static int gpio_mockup_name_lines(struct device *dev,
  96. struct gpio_mockup_chip *chip)
  97. {
  98. struct gpio_chip *gc = &chip->gc;
  99. char **names;
  100. int i;
  101. names = devm_kcalloc(dev, gc->ngpio, sizeof(char *), GFP_KERNEL);
  102. if (!names)
  103. return -ENOMEM;
  104. for (i = 0; i < gc->ngpio; i++) {
  105. names[i] = devm_kasprintf(dev, GFP_KERNEL,
  106. "%s-%d", gc->label, i);
  107. if (!names[i])
  108. return -ENOMEM;
  109. }
  110. gc->names = (const char *const *)names;
  111. return 0;
  112. }
  113. static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
  114. {
  115. struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
  116. return irq_sim_irqnum(&chip->irqsim, offset);
  117. }
  118. static ssize_t gpio_mockup_event_write(struct file *file,
  119. const char __user *usr_buf,
  120. size_t size, loff_t *ppos)
  121. {
  122. struct gpio_mockup_dbgfs_private *priv;
  123. struct gpio_mockup_chip *chip;
  124. struct seq_file *sfile;
  125. struct gpio_desc *desc;
  126. int rv, val;
  127. rv = kstrtoint_from_user(usr_buf, size, 0, &val);
  128. if (rv)
  129. return rv;
  130. if (val != 0 && val != 1)
  131. return -EINVAL;
  132. sfile = file->private_data;
  133. priv = sfile->private;
  134. desc = priv->desc;
  135. chip = priv->chip;
  136. gpiod_set_value_cansleep(desc, val);
  137. irq_sim_fire(&chip->irqsim, priv->offset);
  138. return size;
  139. }
  140. static int gpio_mockup_event_open(struct inode *inode, struct file *file)
  141. {
  142. return single_open(file, NULL, inode->i_private);
  143. }
  144. static const struct file_operations gpio_mockup_event_ops = {
  145. .owner = THIS_MODULE,
  146. .open = gpio_mockup_event_open,
  147. .write = gpio_mockup_event_write,
  148. .llseek = no_llseek,
  149. };
  150. static void gpio_mockup_debugfs_setup(struct device *dev,
  151. struct gpio_mockup_chip *chip)
  152. {
  153. struct gpio_mockup_dbgfs_private *priv;
  154. struct dentry *evfile;
  155. struct gpio_chip *gc;
  156. char *name;
  157. int i;
  158. gc = &chip->gc;
  159. chip->dbg_dir = debugfs_create_dir(gc->label, gpio_mockup_dbg_dir);
  160. if (!chip->dbg_dir)
  161. goto err;
  162. for (i = 0; i < gc->ngpio; i++) {
  163. name = devm_kasprintf(dev, GFP_KERNEL, "%d", i);
  164. if (!name)
  165. goto err;
  166. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  167. if (!priv)
  168. goto err;
  169. priv->chip = chip;
  170. priv->offset = i;
  171. priv->desc = &gc->gpiodev->descs[i];
  172. evfile = debugfs_create_file(name, 0200, chip->dbg_dir, priv,
  173. &gpio_mockup_event_ops);
  174. if (!evfile)
  175. goto err;
  176. }
  177. return;
  178. err:
  179. dev_err(dev, "error creating debugfs directory\n");
  180. }
  181. static int gpio_mockup_add(struct device *dev,
  182. struct gpio_mockup_chip *chip,
  183. const char *name, int base, int ngpio)
  184. {
  185. struct gpio_chip *gc = &chip->gc;
  186. int ret;
  187. gc->base = base;
  188. gc->ngpio = ngpio;
  189. gc->label = name;
  190. gc->owner = THIS_MODULE;
  191. gc->parent = dev;
  192. gc->get = gpio_mockup_get;
  193. gc->set = gpio_mockup_set;
  194. gc->direction_output = gpio_mockup_dirout;
  195. gc->direction_input = gpio_mockup_dirin;
  196. gc->get_direction = gpio_mockup_get_direction;
  197. gc->to_irq = gpio_mockup_to_irq;
  198. chip->lines = devm_kcalloc(dev, gc->ngpio,
  199. sizeof(*chip->lines), GFP_KERNEL);
  200. if (!chip->lines)
  201. return -ENOMEM;
  202. if (gpio_mockup_named_lines) {
  203. ret = gpio_mockup_name_lines(dev, chip);
  204. if (ret)
  205. return ret;
  206. }
  207. ret = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio);
  208. if (ret)
  209. return ret;
  210. ret = devm_gpiochip_add_data(dev, &chip->gc, chip);
  211. if (ret)
  212. return ret;
  213. if (gpio_mockup_dbg_dir)
  214. gpio_mockup_debugfs_setup(dev, chip);
  215. return 0;
  216. }
  217. static int gpio_mockup_probe(struct platform_device *pdev)
  218. {
  219. int ret, i, base, ngpio, num_chips;
  220. struct device *dev = &pdev->dev;
  221. struct gpio_mockup_chip *chips;
  222. char *chip_name;
  223. if (gpio_mockup_params_nr < 2 || (gpio_mockup_params_nr % 2))
  224. return -EINVAL;
  225. /* Each chip is described by two values. */
  226. num_chips = gpio_mockup_params_nr / 2;
  227. chips = devm_kcalloc(dev, num_chips, sizeof(*chips), GFP_KERNEL);
  228. if (!chips)
  229. return -ENOMEM;
  230. platform_set_drvdata(pdev, chips);
  231. for (i = 0; i < num_chips; i++) {
  232. base = gpio_mockup_ranges[i * 2];
  233. if (base == -1)
  234. ngpio = gpio_mockup_ranges[i * 2 + 1];
  235. else
  236. ngpio = gpio_mockup_ranges[i * 2 + 1] - base;
  237. if (ngpio >= 0) {
  238. chip_name = devm_kasprintf(dev, GFP_KERNEL,
  239. "%s-%c", GPIO_MOCKUP_NAME,
  240. gpio_mockup_name_start + i);
  241. if (!chip_name)
  242. return -ENOMEM;
  243. ret = gpio_mockup_add(dev, &chips[i],
  244. chip_name, base, ngpio);
  245. } else {
  246. ret = -EINVAL;
  247. }
  248. if (ret) {
  249. dev_err(dev,
  250. "adding gpiochip failed: %d (base: %d, ngpio: %d)\n",
  251. ret, base, base < 0 ? ngpio : base + ngpio);
  252. return ret;
  253. }
  254. }
  255. return 0;
  256. }
  257. static struct platform_driver gpio_mockup_driver = {
  258. .driver = {
  259. .name = GPIO_MOCKUP_NAME,
  260. },
  261. .probe = gpio_mockup_probe,
  262. };
  263. static struct platform_device *pdev;
  264. static int __init mock_device_init(void)
  265. {
  266. int err;
  267. gpio_mockup_dbg_dir = debugfs_create_dir("gpio-mockup-event", NULL);
  268. if (!gpio_mockup_dbg_dir)
  269. pr_err("%s: error creating debugfs directory\n",
  270. GPIO_MOCKUP_NAME);
  271. pdev = platform_device_alloc(GPIO_MOCKUP_NAME, -1);
  272. if (!pdev)
  273. return -ENOMEM;
  274. err = platform_device_add(pdev);
  275. if (err) {
  276. platform_device_put(pdev);
  277. return err;
  278. }
  279. err = platform_driver_register(&gpio_mockup_driver);
  280. if (err) {
  281. platform_device_unregister(pdev);
  282. return err;
  283. }
  284. return 0;
  285. }
  286. static void __exit mock_device_exit(void)
  287. {
  288. debugfs_remove_recursive(gpio_mockup_dbg_dir);
  289. platform_driver_unregister(&gpio_mockup_driver);
  290. platform_device_unregister(pdev);
  291. }
  292. module_init(mock_device_init);
  293. module_exit(mock_device_exit);
  294. MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>");
  295. MODULE_AUTHOR("Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>");
  296. MODULE_AUTHOR("Bartosz Golaszewski <brgl@bgdev.pl>");
  297. MODULE_DESCRIPTION("GPIO Testing driver");
  298. MODULE_LICENSE("GPL v2");