gpio-ingenic.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. * Ingenic JZ47xx GPIO driver
  3. *
  4. * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
  5. *
  6. * License terms: GNU General Public License (GPL) version 2
  7. */
  8. #include <linux/gpio/driver.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/io.h>
  11. #include <linux/module.h>
  12. #include <linux/of_address.h>
  13. #include <linux/of_device.h>
  14. #include <linux/of_irq.h>
  15. #include <linux/pinctrl/consumer.h>
  16. #include <linux/regmap.h>
  17. #define GPIO_PIN 0x00
  18. #define GPIO_MSK 0x20
  19. #define JZ4740_GPIO_DATA 0x10
  20. #define JZ4740_GPIO_SELECT 0x50
  21. #define JZ4740_GPIO_DIR 0x60
  22. #define JZ4740_GPIO_TRIG 0x70
  23. #define JZ4740_GPIO_FLAG 0x80
  24. #define JZ4770_GPIO_INT 0x10
  25. #define JZ4770_GPIO_PAT1 0x30
  26. #define JZ4770_GPIO_PAT0 0x40
  27. #define JZ4770_GPIO_FLAG 0x50
  28. #define REG_SET(x) ((x) + 0x4)
  29. #define REG_CLEAR(x) ((x) + 0x8)
  30. enum jz_version {
  31. ID_JZ4740,
  32. ID_JZ4770,
  33. ID_JZ4780,
  34. };
  35. struct ingenic_gpio_chip {
  36. struct regmap *map;
  37. struct gpio_chip gc;
  38. struct irq_chip irq_chip;
  39. unsigned int irq, reg_base;
  40. enum jz_version version;
  41. };
  42. static u32 gpio_ingenic_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg)
  43. {
  44. unsigned int val;
  45. regmap_read(jzgc->map, jzgc->reg_base + reg, &val);
  46. return (u32) val;
  47. }
  48. static void gpio_ingenic_set_bit(struct ingenic_gpio_chip *jzgc,
  49. u8 reg, u8 offset, bool set)
  50. {
  51. if (set)
  52. reg = REG_SET(reg);
  53. else
  54. reg = REG_CLEAR(reg);
  55. regmap_write(jzgc->map, jzgc->reg_base + reg, BIT(offset));
  56. }
  57. static inline bool gpio_get_value(struct ingenic_gpio_chip *jzgc, u8 offset)
  58. {
  59. unsigned int val = gpio_ingenic_read_reg(jzgc, GPIO_PIN);
  60. return !!(val & BIT(offset));
  61. }
  62. static void gpio_set_value(struct ingenic_gpio_chip *jzgc, u8 offset, int value)
  63. {
  64. if (jzgc->version >= ID_JZ4770)
  65. gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
  66. else
  67. gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
  68. }
  69. static void irq_set_type(struct ingenic_gpio_chip *jzgc,
  70. u8 offset, unsigned int type)
  71. {
  72. u8 reg1, reg2;
  73. if (jzgc->version >= ID_JZ4770) {
  74. reg1 = JZ4770_GPIO_PAT1;
  75. reg2 = JZ4770_GPIO_PAT0;
  76. } else {
  77. reg1 = JZ4740_GPIO_TRIG;
  78. reg2 = JZ4740_GPIO_DIR;
  79. }
  80. switch (type) {
  81. case IRQ_TYPE_EDGE_RISING:
  82. gpio_ingenic_set_bit(jzgc, reg2, offset, true);
  83. gpio_ingenic_set_bit(jzgc, reg1, offset, true);
  84. break;
  85. case IRQ_TYPE_EDGE_FALLING:
  86. gpio_ingenic_set_bit(jzgc, reg2, offset, false);
  87. gpio_ingenic_set_bit(jzgc, reg1, offset, true);
  88. break;
  89. case IRQ_TYPE_LEVEL_HIGH:
  90. gpio_ingenic_set_bit(jzgc, reg2, offset, true);
  91. gpio_ingenic_set_bit(jzgc, reg1, offset, false);
  92. break;
  93. case IRQ_TYPE_LEVEL_LOW:
  94. default:
  95. gpio_ingenic_set_bit(jzgc, reg2, offset, false);
  96. gpio_ingenic_set_bit(jzgc, reg1, offset, false);
  97. break;
  98. }
  99. }
  100. static void ingenic_gpio_irq_mask(struct irq_data *irqd)
  101. {
  102. struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
  103. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  104. gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
  105. }
  106. static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
  107. {
  108. struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
  109. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  110. gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
  111. }
  112. static void ingenic_gpio_irq_enable(struct irq_data *irqd)
  113. {
  114. struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
  115. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  116. int irq = irqd->hwirq;
  117. if (jzgc->version >= ID_JZ4770)
  118. gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
  119. else
  120. gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
  121. ingenic_gpio_irq_unmask(irqd);
  122. }
  123. static void ingenic_gpio_irq_disable(struct irq_data *irqd)
  124. {
  125. struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
  126. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  127. int irq = irqd->hwirq;
  128. ingenic_gpio_irq_mask(irqd);
  129. if (jzgc->version >= ID_JZ4770)
  130. gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
  131. else
  132. gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
  133. }
  134. static void ingenic_gpio_irq_ack(struct irq_data *irqd)
  135. {
  136. struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
  137. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  138. int irq = irqd->hwirq;
  139. bool high;
  140. if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) {
  141. /*
  142. * Switch to an interrupt for the opposite edge to the one that
  143. * triggered the interrupt being ACKed.
  144. */
  145. high = gpio_get_value(jzgc, irq);
  146. if (high)
  147. irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
  148. else
  149. irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
  150. }
  151. if (jzgc->version >= ID_JZ4770)
  152. gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
  153. else
  154. gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
  155. }
  156. static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
  157. {
  158. struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
  159. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  160. switch (type) {
  161. case IRQ_TYPE_EDGE_BOTH:
  162. case IRQ_TYPE_EDGE_RISING:
  163. case IRQ_TYPE_EDGE_FALLING:
  164. irq_set_handler_locked(irqd, handle_edge_irq);
  165. break;
  166. case IRQ_TYPE_LEVEL_HIGH:
  167. case IRQ_TYPE_LEVEL_LOW:
  168. irq_set_handler_locked(irqd, handle_level_irq);
  169. break;
  170. default:
  171. irq_set_handler_locked(irqd, handle_bad_irq);
  172. }
  173. if (type == IRQ_TYPE_EDGE_BOTH) {
  174. /*
  175. * The hardware does not support interrupts on both edges. The
  176. * best we can do is to set up a single-edge interrupt and then
  177. * switch to the opposing edge when ACKing the interrupt.
  178. */
  179. bool high = gpio_get_value(jzgc, irqd->hwirq);
  180. type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
  181. }
  182. irq_set_type(jzgc, irqd->hwirq, type);
  183. return 0;
  184. }
  185. static int ingenic_gpio_irq_set_wake(struct irq_data *irqd, unsigned int on)
  186. {
  187. struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
  188. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  189. return irq_set_irq_wake(jzgc->irq, on);
  190. }
  191. static void ingenic_gpio_irq_handler(struct irq_desc *desc)
  192. {
  193. struct gpio_chip *gc = irq_desc_get_handler_data(desc);
  194. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  195. struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data);
  196. unsigned long flag, i;
  197. chained_irq_enter(irq_chip, desc);
  198. if (jzgc->version >= ID_JZ4770)
  199. flag = gpio_ingenic_read_reg(jzgc, JZ4770_GPIO_FLAG);
  200. else
  201. flag = gpio_ingenic_read_reg(jzgc, JZ4740_GPIO_FLAG);
  202. for_each_set_bit(i, &flag, 32)
  203. generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
  204. chained_irq_exit(irq_chip, desc);
  205. }
  206. static void ingenic_gpio_set(struct gpio_chip *gc,
  207. unsigned int offset, int value)
  208. {
  209. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  210. gpio_set_value(jzgc, offset, value);
  211. }
  212. static int ingenic_gpio_get(struct gpio_chip *gc, unsigned int offset)
  213. {
  214. struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
  215. return (int) gpio_get_value(jzgc, offset);
  216. }
  217. static int ingenic_gpio_direction_input(struct gpio_chip *gc,
  218. unsigned int offset)
  219. {
  220. return pinctrl_gpio_direction_input(gc->base + offset);
  221. }
  222. static int ingenic_gpio_direction_output(struct gpio_chip *gc,
  223. unsigned int offset, int value)
  224. {
  225. ingenic_gpio_set(gc, offset, value);
  226. return pinctrl_gpio_direction_output(gc->base + offset);
  227. }
  228. static const struct of_device_id ingenic_gpio_of_match[] = {
  229. { .compatible = "ingenic,jz4740-gpio", .data = (void *)ID_JZ4740 },
  230. { .compatible = "ingenic,jz4770-gpio", .data = (void *)ID_JZ4770 },
  231. { .compatible = "ingenic,jz4780-gpio", .data = (void *)ID_JZ4780 },
  232. {},
  233. };
  234. MODULE_DEVICE_TABLE(of, ingenic_gpio_of_match);
  235. static int ingenic_gpio_probe(struct platform_device *pdev)
  236. {
  237. struct device *dev = &pdev->dev;
  238. const struct of_device_id *of_id = of_match_device(
  239. ingenic_gpio_of_match, dev);
  240. struct ingenic_gpio_chip *jzgc;
  241. u32 bank;
  242. int err;
  243. jzgc = devm_kzalloc(dev, sizeof(*jzgc), GFP_KERNEL);
  244. if (!jzgc)
  245. return -ENOMEM;
  246. jzgc->map = dev_get_drvdata(dev->parent);
  247. if (!jzgc->map) {
  248. dev_err(dev, "Cannot get parent regmap\n");
  249. return -ENXIO;
  250. }
  251. err = of_property_read_u32(dev->of_node, "reg", &bank);
  252. if (err) {
  253. dev_err(dev, "Cannot read \"reg\" property: %i\n", err);
  254. return err;
  255. }
  256. jzgc->reg_base = bank * 0x100;
  257. jzgc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "GPIO%c", 'A' + bank);
  258. if (!jzgc->gc.label)
  259. return -ENOMEM;
  260. /* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
  261. * ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
  262. * <linux/gpio/consumer.h> INSTEAD.
  263. */
  264. jzgc->gc.base = bank * 32;
  265. jzgc->gc.ngpio = 32;
  266. jzgc->gc.parent = dev;
  267. jzgc->gc.of_node = dev->of_node;
  268. jzgc->gc.owner = THIS_MODULE;
  269. jzgc->version = (enum jz_version)of_id->data;
  270. jzgc->gc.set = ingenic_gpio_set;
  271. jzgc->gc.get = ingenic_gpio_get;
  272. jzgc->gc.direction_input = ingenic_gpio_direction_input;
  273. jzgc->gc.direction_output = ingenic_gpio_direction_output;
  274. if (of_property_read_bool(dev->of_node, "gpio-ranges")) {
  275. jzgc->gc.request = gpiochip_generic_request;
  276. jzgc->gc.free = gpiochip_generic_free;
  277. }
  278. err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
  279. if (err)
  280. return err;
  281. jzgc->irq = irq_of_parse_and_map(dev->of_node, 0);
  282. if (!jzgc->irq)
  283. return -EINVAL;
  284. jzgc->irq_chip.name = jzgc->gc.label;
  285. jzgc->irq_chip.irq_enable = ingenic_gpio_irq_enable;
  286. jzgc->irq_chip.irq_disable = ingenic_gpio_irq_disable;
  287. jzgc->irq_chip.irq_unmask = ingenic_gpio_irq_unmask;
  288. jzgc->irq_chip.irq_mask = ingenic_gpio_irq_mask;
  289. jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
  290. jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
  291. jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
  292. jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
  293. err = gpiochip_irqchip_add(&jzgc->gc, &jzgc->irq_chip, 0,
  294. handle_level_irq, IRQ_TYPE_NONE);
  295. if (err)
  296. return err;
  297. gpiochip_set_chained_irqchip(&jzgc->gc, &jzgc->irq_chip,
  298. jzgc->irq, ingenic_gpio_irq_handler);
  299. return 0;
  300. }
  301. static int ingenic_gpio_remove(struct platform_device *pdev)
  302. {
  303. return 0;
  304. }
  305. static struct platform_driver ingenic_gpio_driver = {
  306. .driver = {
  307. .name = "gpio-ingenic",
  308. .of_match_table = of_match_ptr(ingenic_gpio_of_match),
  309. },
  310. .probe = ingenic_gpio_probe,
  311. .remove = ingenic_gpio_remove,
  312. };
  313. static int __init ingenic_gpio_drv_register(void)
  314. {
  315. return platform_driver_register(&ingenic_gpio_driver);
  316. }
  317. subsys_initcall(ingenic_gpio_drv_register);
  318. static void __exit ingenic_gpio_drv_unregister(void)
  319. {
  320. platform_driver_unregister(&ingenic_gpio_driver);
  321. }
  322. module_exit(ingenic_gpio_drv_unregister);
  323. MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
  324. MODULE_DESCRIPTION("Ingenic JZ47xx GPIO driver");
  325. MODULE_LICENSE("GPL");