hd44780.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*
  2. * HD44780 Character LCD driver for Linux
  3. *
  4. * Copyright (C) 2000-2008, Willy Tarreau <w@1wt.eu>
  5. * Copyright (C) 2016-2017 Glider bvba
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version
  10. * 2 of the License, or (at your option) any later version.
  11. */
  12. #include <linux/delay.h>
  13. #include <linux/gpio/consumer.h>
  14. #include <linux/module.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/property.h>
  17. #include <linux/slab.h>
  18. #include <misc/charlcd.h>
  19. enum hd44780_pin {
  20. /* Order does matter due to writing to GPIO array subsets! */
  21. PIN_DATA0, /* Optional */
  22. PIN_DATA1, /* Optional */
  23. PIN_DATA2, /* Optional */
  24. PIN_DATA3, /* Optional */
  25. PIN_DATA4,
  26. PIN_DATA5,
  27. PIN_DATA6,
  28. PIN_DATA7,
  29. PIN_CTRL_RS,
  30. PIN_CTRL_RW, /* Optional */
  31. PIN_CTRL_E,
  32. PIN_CTRL_BL, /* Optional */
  33. PIN_NUM
  34. };
  35. struct hd44780 {
  36. struct gpio_desc *pins[PIN_NUM];
  37. };
  38. static void hd44780_backlight(struct charlcd *lcd, int on)
  39. {
  40. struct hd44780 *hd = lcd->drvdata;
  41. if (hd->pins[PIN_CTRL_BL])
  42. gpiod_set_value_cansleep(hd->pins[PIN_CTRL_BL], on);
  43. }
  44. static void hd44780_strobe_gpio(struct hd44780 *hd)
  45. {
  46. /* Maintain the data during 20 us before the strobe */
  47. udelay(20);
  48. gpiod_set_value_cansleep(hd->pins[PIN_CTRL_E], 1);
  49. /* Maintain the strobe during 40 us */
  50. udelay(40);
  51. gpiod_set_value_cansleep(hd->pins[PIN_CTRL_E], 0);
  52. }
  53. /* write to an LCD panel register in 8 bit GPIO mode */
  54. static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
  55. {
  56. int values[10]; /* for DATA[0-7], RS, RW */
  57. unsigned int i, n;
  58. for (i = 0; i < 8; i++)
  59. values[PIN_DATA0 + i] = !!(val & BIT(i));
  60. values[PIN_CTRL_RS] = rs;
  61. n = 9;
  62. if (hd->pins[PIN_CTRL_RW]) {
  63. values[PIN_CTRL_RW] = 0;
  64. n++;
  65. }
  66. /* Present the data to the port */
  67. gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], values);
  68. hd44780_strobe_gpio(hd);
  69. }
  70. /* write to an LCD panel register in 4 bit GPIO mode */
  71. static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs)
  72. {
  73. int values[10]; /* for DATA[0-7], RS, RW, but DATA[0-3] is unused */
  74. unsigned int i, n;
  75. /* High nibble + RS, RW */
  76. for (i = 4; i < 8; i++)
  77. values[PIN_DATA0 + i] = !!(val & BIT(i));
  78. values[PIN_CTRL_RS] = rs;
  79. n = 5;
  80. if (hd->pins[PIN_CTRL_RW]) {
  81. values[PIN_CTRL_RW] = 0;
  82. n++;
  83. }
  84. /* Present the data to the port */
  85. gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
  86. &values[PIN_DATA4]);
  87. hd44780_strobe_gpio(hd);
  88. /* Low nibble */
  89. for (i = 0; i < 4; i++)
  90. values[PIN_DATA4 + i] = !!(val & BIT(i));
  91. /* Present the data to the port */
  92. gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
  93. &values[PIN_DATA4]);
  94. hd44780_strobe_gpio(hd);
  95. }
  96. /* Send a command to the LCD panel in 8 bit GPIO mode */
  97. static void hd44780_write_cmd_gpio8(struct charlcd *lcd, int cmd)
  98. {
  99. struct hd44780 *hd = lcd->drvdata;
  100. hd44780_write_gpio8(hd, cmd, 0);
  101. /* The shortest command takes at least 120 us */
  102. udelay(120);
  103. }
  104. /* Send data to the LCD panel in 8 bit GPIO mode */
  105. static void hd44780_write_data_gpio8(struct charlcd *lcd, int data)
  106. {
  107. struct hd44780 *hd = lcd->drvdata;
  108. hd44780_write_gpio8(hd, data, 1);
  109. /* The shortest data takes at least 45 us */
  110. udelay(45);
  111. }
  112. static const struct charlcd_ops hd44780_ops_gpio8 = {
  113. .write_cmd = hd44780_write_cmd_gpio8,
  114. .write_data = hd44780_write_data_gpio8,
  115. .backlight = hd44780_backlight,
  116. };
  117. /* Send a command to the LCD panel in 4 bit GPIO mode */
  118. static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
  119. {
  120. struct hd44780 *hd = lcd->drvdata;
  121. hd44780_write_gpio4(hd, cmd, 0);
  122. /* The shortest command takes at least 120 us */
  123. udelay(120);
  124. }
  125. /* Send 4-bits of a command to the LCD panel in raw 4 bit GPIO mode */
  126. static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
  127. {
  128. int values[10]; /* for DATA[0-7], RS, RW, but DATA[0-3] is unused */
  129. struct hd44780 *hd = lcd->drvdata;
  130. unsigned int i, n;
  131. /* Command nibble + RS, RW */
  132. for (i = 0; i < 4; i++)
  133. values[PIN_DATA4 + i] = !!(cmd & BIT(i));
  134. values[PIN_CTRL_RS] = 0;
  135. n = 5;
  136. if (hd->pins[PIN_CTRL_RW]) {
  137. values[PIN_CTRL_RW] = 0;
  138. n++;
  139. }
  140. /* Present the data to the port */
  141. gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4],
  142. &values[PIN_DATA4]);
  143. hd44780_strobe_gpio(hd);
  144. }
  145. /* Send data to the LCD panel in 4 bit GPIO mode */
  146. static void hd44780_write_data_gpio4(struct charlcd *lcd, int data)
  147. {
  148. struct hd44780 *hd = lcd->drvdata;
  149. hd44780_write_gpio4(hd, data, 1);
  150. /* The shortest data takes at least 45 us */
  151. udelay(45);
  152. }
  153. static const struct charlcd_ops hd44780_ops_gpio4 = {
  154. .write_cmd = hd44780_write_cmd_gpio4,
  155. .write_cmd_raw4 = hd44780_write_cmd_raw_gpio4,
  156. .write_data = hd44780_write_data_gpio4,
  157. .backlight = hd44780_backlight,
  158. };
  159. static int hd44780_probe(struct platform_device *pdev)
  160. {
  161. struct device *dev = &pdev->dev;
  162. unsigned int i, base;
  163. struct charlcd *lcd;
  164. struct hd44780 *hd;
  165. int ifwidth, ret;
  166. /* Required pins */
  167. ifwidth = gpiod_count(dev, "data");
  168. if (ifwidth < 0)
  169. return ifwidth;
  170. switch (ifwidth) {
  171. case 4:
  172. base = PIN_DATA4;
  173. break;
  174. case 8:
  175. base = PIN_DATA0;
  176. break;
  177. default:
  178. return -EINVAL;
  179. }
  180. lcd = charlcd_alloc(sizeof(struct hd44780));
  181. if (!lcd)
  182. return -ENOMEM;
  183. hd = lcd->drvdata;
  184. for (i = 0; i < ifwidth; i++) {
  185. hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i,
  186. GPIOD_OUT_LOW);
  187. if (IS_ERR(hd->pins[base + i])) {
  188. ret = PTR_ERR(hd->pins[base + i]);
  189. goto fail;
  190. }
  191. }
  192. hd->pins[PIN_CTRL_E] = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
  193. if (IS_ERR(hd->pins[PIN_CTRL_E])) {
  194. ret = PTR_ERR(hd->pins[PIN_CTRL_E]);
  195. goto fail;
  196. }
  197. hd->pins[PIN_CTRL_RS] = devm_gpiod_get(dev, "rs", GPIOD_OUT_HIGH);
  198. if (IS_ERR(hd->pins[PIN_CTRL_RS])) {
  199. ret = PTR_ERR(hd->pins[PIN_CTRL_RS]);
  200. goto fail;
  201. }
  202. /* Optional pins */
  203. hd->pins[PIN_CTRL_RW] = devm_gpiod_get_optional(dev, "rw",
  204. GPIOD_OUT_LOW);
  205. if (IS_ERR(hd->pins[PIN_CTRL_RW])) {
  206. ret = PTR_ERR(hd->pins[PIN_CTRL_RW]);
  207. goto fail;
  208. }
  209. hd->pins[PIN_CTRL_BL] = devm_gpiod_get_optional(dev, "backlight",
  210. GPIOD_OUT_LOW);
  211. if (IS_ERR(hd->pins[PIN_CTRL_BL])) {
  212. ret = PTR_ERR(hd->pins[PIN_CTRL_BL]);
  213. goto fail;
  214. }
  215. /* Required properties */
  216. ret = device_property_read_u32(dev, "display-height-chars",
  217. &lcd->height);
  218. if (ret)
  219. goto fail;
  220. ret = device_property_read_u32(dev, "display-width-chars", &lcd->width);
  221. if (ret)
  222. goto fail;
  223. /*
  224. * On displays with more than two rows, the internal buffer width is
  225. * usually equal to the display width
  226. */
  227. if (lcd->height > 2)
  228. lcd->bwidth = lcd->width;
  229. /* Optional properties */
  230. device_property_read_u32(dev, "internal-buffer-width", &lcd->bwidth);
  231. lcd->ifwidth = ifwidth;
  232. lcd->ops = ifwidth == 8 ? &hd44780_ops_gpio8 : &hd44780_ops_gpio4;
  233. ret = charlcd_register(lcd);
  234. if (ret)
  235. goto fail;
  236. platform_set_drvdata(pdev, lcd);
  237. return 0;
  238. fail:
  239. kfree(lcd);
  240. return ret;
  241. }
  242. static int hd44780_remove(struct platform_device *pdev)
  243. {
  244. struct charlcd *lcd = platform_get_drvdata(pdev);
  245. charlcd_unregister(lcd);
  246. return 0;
  247. }
  248. static const struct of_device_id hd44780_of_match[] = {
  249. { .compatible = "hit,hd44780" },
  250. { /* sentinel */ }
  251. };
  252. MODULE_DEVICE_TABLE(of, hd44780_of_match);
  253. static struct platform_driver hd44780_driver = {
  254. .probe = hd44780_probe,
  255. .remove = hd44780_remove,
  256. .driver = {
  257. .name = "hd44780",
  258. .of_match_table = hd44780_of_match,
  259. },
  260. };
  261. module_platform_driver(hd44780_driver);
  262. MODULE_DESCRIPTION("HD44780 Character LCD driver");
  263. MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
  264. MODULE_LICENSE("GPL");