hd44780.c 8.4 KB

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