1351f683bSMiguel Ojeda // SPDX-License-Identifier: GPL-2.0+ 2d47d8836SGeert Uytterhoeven /* 3d47d8836SGeert Uytterhoeven * HD44780 Character LCD driver for Linux 4d47d8836SGeert Uytterhoeven * 5d47d8836SGeert Uytterhoeven * Copyright (C) 2000-2008, Willy Tarreau <w@1wt.eu> 6d47d8836SGeert Uytterhoeven * Copyright (C) 2016-2017 Glider bvba 7d47d8836SGeert Uytterhoeven */ 8d47d8836SGeert Uytterhoeven 9d47d8836SGeert Uytterhoeven #include <linux/delay.h> 10d47d8836SGeert Uytterhoeven #include <linux/gpio/consumer.h> 11d47d8836SGeert Uytterhoeven #include <linux/module.h> 12ac316725SRandy Dunlap #include <linux/mod_devicetable.h> 13d47d8836SGeert Uytterhoeven #include <linux/platform_device.h> 14d47d8836SGeert Uytterhoeven #include <linux/property.h> 15d47d8836SGeert Uytterhoeven #include <linux/slab.h> 16d47d8836SGeert Uytterhoeven 1775354284SMasahiro Yamada #include "charlcd.h" 18718e05edSLars Poeschel #include "hd44780_common.h" 19d47d8836SGeert Uytterhoeven 20d47d8836SGeert Uytterhoeven enum hd44780_pin { 21d47d8836SGeert Uytterhoeven /* Order does matter due to writing to GPIO array subsets! */ 22d47d8836SGeert Uytterhoeven PIN_DATA0, /* Optional */ 23d47d8836SGeert Uytterhoeven PIN_DATA1, /* Optional */ 24d47d8836SGeert Uytterhoeven PIN_DATA2, /* Optional */ 25d47d8836SGeert Uytterhoeven PIN_DATA3, /* Optional */ 26d47d8836SGeert Uytterhoeven PIN_DATA4, 27d47d8836SGeert Uytterhoeven PIN_DATA5, 28d47d8836SGeert Uytterhoeven PIN_DATA6, 29d47d8836SGeert Uytterhoeven PIN_DATA7, 30d47d8836SGeert Uytterhoeven PIN_CTRL_RS, 31d47d8836SGeert Uytterhoeven PIN_CTRL_RW, /* Optional */ 32d47d8836SGeert Uytterhoeven PIN_CTRL_E, 33d47d8836SGeert Uytterhoeven PIN_CTRL_BL, /* Optional */ 34d47d8836SGeert Uytterhoeven PIN_NUM 35d47d8836SGeert Uytterhoeven }; 36d47d8836SGeert Uytterhoeven 37d47d8836SGeert Uytterhoeven struct hd44780 { 38d47d8836SGeert Uytterhoeven struct gpio_desc *pins[PIN_NUM]; 39d47d8836SGeert Uytterhoeven }; 40d47d8836SGeert Uytterhoeven 4166ce7d5cSLars Poeschel static void hd44780_backlight(struct charlcd *lcd, enum charlcd_onoff on) 42d47d8836SGeert Uytterhoeven { 432545c1c9SLars Poeschel struct hd44780_common *hdc = lcd->drvdata; 442545c1c9SLars Poeschel struct hd44780 *hd = hdc->hd44780; 45d47d8836SGeert Uytterhoeven 46d47d8836SGeert Uytterhoeven if (hd->pins[PIN_CTRL_BL]) 47d47d8836SGeert Uytterhoeven gpiod_set_value_cansleep(hd->pins[PIN_CTRL_BL], on); 48d47d8836SGeert Uytterhoeven } 49d47d8836SGeert Uytterhoeven 50d47d8836SGeert Uytterhoeven static void hd44780_strobe_gpio(struct hd44780 *hd) 51d47d8836SGeert Uytterhoeven { 52d47d8836SGeert Uytterhoeven /* Maintain the data during 20 us before the strobe */ 53d47d8836SGeert Uytterhoeven udelay(20); 54d47d8836SGeert Uytterhoeven 55d47d8836SGeert Uytterhoeven gpiod_set_value_cansleep(hd->pins[PIN_CTRL_E], 1); 56d47d8836SGeert Uytterhoeven 57d47d8836SGeert Uytterhoeven /* Maintain the strobe during 40 us */ 58d47d8836SGeert Uytterhoeven udelay(40); 59d47d8836SGeert Uytterhoeven 60d47d8836SGeert Uytterhoeven gpiod_set_value_cansleep(hd->pins[PIN_CTRL_E], 0); 61d47d8836SGeert Uytterhoeven } 62d47d8836SGeert Uytterhoeven 63d47d8836SGeert Uytterhoeven /* write to an LCD panel register in 8 bit GPIO mode */ 64d47d8836SGeert Uytterhoeven static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs) 65d47d8836SGeert Uytterhoeven { 66b9762bebSJanusz Krzysztofik DECLARE_BITMAP(values, 10); /* for DATA[0-7], RS, RW */ 67b9762bebSJanusz Krzysztofik unsigned int n; 68d47d8836SGeert Uytterhoeven 69b9762bebSJanusz Krzysztofik values[0] = val; 70b9762bebSJanusz Krzysztofik __assign_bit(8, values, rs); 71b9762bebSJanusz Krzysztofik n = hd->pins[PIN_CTRL_RW] ? 10 : 9; 72d47d8836SGeert Uytterhoeven 73d47d8836SGeert Uytterhoeven /* Present the data to the port */ 7477588c14SJanusz Krzysztofik gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA0], NULL, values); 75d47d8836SGeert Uytterhoeven 76d47d8836SGeert Uytterhoeven hd44780_strobe_gpio(hd); 77d47d8836SGeert Uytterhoeven } 78d47d8836SGeert Uytterhoeven 79d47d8836SGeert Uytterhoeven /* write to an LCD panel register in 4 bit GPIO mode */ 80d47d8836SGeert Uytterhoeven static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs) 81d47d8836SGeert Uytterhoeven { 82b9762bebSJanusz Krzysztofik DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */ 83b9762bebSJanusz Krzysztofik unsigned int n; 84d47d8836SGeert Uytterhoeven 85d47d8836SGeert Uytterhoeven /* High nibble + RS, RW */ 86b9762bebSJanusz Krzysztofik values[0] = val >> 4; 87b9762bebSJanusz Krzysztofik __assign_bit(4, values, rs); 88b9762bebSJanusz Krzysztofik n = hd->pins[PIN_CTRL_RW] ? 6 : 5; 89d47d8836SGeert Uytterhoeven 90d47d8836SGeert Uytterhoeven /* Present the data to the port */ 9177588c14SJanusz Krzysztofik gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL, values); 92d47d8836SGeert Uytterhoeven 93d47d8836SGeert Uytterhoeven hd44780_strobe_gpio(hd); 94d47d8836SGeert Uytterhoeven 95d47d8836SGeert Uytterhoeven /* Low nibble */ 96b9762bebSJanusz Krzysztofik values[0] &= ~0x0fUL; 97b9762bebSJanusz Krzysztofik values[0] |= val & 0x0f; 98d47d8836SGeert Uytterhoeven 99d47d8836SGeert Uytterhoeven /* Present the data to the port */ 10077588c14SJanusz Krzysztofik gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL, values); 101d47d8836SGeert Uytterhoeven 102d47d8836SGeert Uytterhoeven hd44780_strobe_gpio(hd); 103d47d8836SGeert Uytterhoeven } 104d47d8836SGeert Uytterhoeven 105d47d8836SGeert Uytterhoeven /* Send a command to the LCD panel in 8 bit GPIO mode */ 1062c6a82f2SLars Poeschel static void hd44780_write_cmd_gpio8(struct hd44780_common *hdc, int cmd) 107d47d8836SGeert Uytterhoeven { 1082545c1c9SLars Poeschel struct hd44780 *hd = hdc->hd44780; 109d47d8836SGeert Uytterhoeven 110d47d8836SGeert Uytterhoeven hd44780_write_gpio8(hd, cmd, 0); 111d47d8836SGeert Uytterhoeven 112d47d8836SGeert Uytterhoeven /* The shortest command takes at least 120 us */ 113d47d8836SGeert Uytterhoeven udelay(120); 114d47d8836SGeert Uytterhoeven } 115d47d8836SGeert Uytterhoeven 116d47d8836SGeert Uytterhoeven /* Send data to the LCD panel in 8 bit GPIO mode */ 11771ff701bSLars Poeschel static void hd44780_write_data_gpio8(struct hd44780_common *hdc, int data) 118d47d8836SGeert Uytterhoeven { 1192545c1c9SLars Poeschel struct hd44780 *hd = hdc->hd44780; 120d47d8836SGeert Uytterhoeven 121d47d8836SGeert Uytterhoeven hd44780_write_gpio8(hd, data, 1); 122d47d8836SGeert Uytterhoeven 123d47d8836SGeert Uytterhoeven /* The shortest data takes at least 45 us */ 124d47d8836SGeert Uytterhoeven udelay(45); 125d47d8836SGeert Uytterhoeven } 126d47d8836SGeert Uytterhoeven 127d47d8836SGeert Uytterhoeven static const struct charlcd_ops hd44780_ops_gpio8 = { 128d47d8836SGeert Uytterhoeven .backlight = hd44780_backlight, 129b26deabbSLars Poeschel .print = hd44780_common_print, 130d3a2fb81SLars Poeschel .gotoxy = hd44780_common_gotoxy, 13188645a86SLars Poeschel .home = hd44780_common_home, 13245421ffeSLars Poeschel .clear_display = hd44780_common_clear_display, 13301ec46dfSLars Poeschel .init_display = hd44780_common_init_display, 134d2f2187eSLars Poeschel .shift_cursor = hd44780_common_shift_cursor, 135d2f2187eSLars Poeschel .shift_display = hd44780_common_shift_display, 136d2f2187eSLars Poeschel .display = hd44780_common_display, 137d2f2187eSLars Poeschel .cursor = hd44780_common_cursor, 138d2f2187eSLars Poeschel .blink = hd44780_common_blink, 139d2f2187eSLars Poeschel .fontsize = hd44780_common_fontsize, 140d2f2187eSLars Poeschel .lines = hd44780_common_lines, 141339acb08SLars Poeschel .redefine_char = hd44780_common_redefine_char, 142d47d8836SGeert Uytterhoeven }; 143d47d8836SGeert Uytterhoeven 144d47d8836SGeert Uytterhoeven /* Send a command to the LCD panel in 4 bit GPIO mode */ 1452c6a82f2SLars Poeschel static void hd44780_write_cmd_gpio4(struct hd44780_common *hdc, int cmd) 146d47d8836SGeert Uytterhoeven { 1472545c1c9SLars Poeschel struct hd44780 *hd = hdc->hd44780; 148d47d8836SGeert Uytterhoeven 149d47d8836SGeert Uytterhoeven hd44780_write_gpio4(hd, cmd, 0); 150d47d8836SGeert Uytterhoeven 151d47d8836SGeert Uytterhoeven /* The shortest command takes at least 120 us */ 152d47d8836SGeert Uytterhoeven udelay(120); 153d47d8836SGeert Uytterhoeven } 154d47d8836SGeert Uytterhoeven 155d47d8836SGeert Uytterhoeven /* Send 4-bits of a command to the LCD panel in raw 4 bit GPIO mode */ 1562c6a82f2SLars Poeschel static void hd44780_write_cmd_raw_gpio4(struct hd44780_common *hdc, int cmd) 157d47d8836SGeert Uytterhoeven { 158b9762bebSJanusz Krzysztofik DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */ 1592545c1c9SLars Poeschel struct hd44780 *hd = hdc->hd44780; 160b9762bebSJanusz Krzysztofik unsigned int n; 161d47d8836SGeert Uytterhoeven 162d47d8836SGeert Uytterhoeven /* Command nibble + RS, RW */ 163b9762bebSJanusz Krzysztofik values[0] = cmd & 0x0f; 164b9762bebSJanusz Krzysztofik n = hd->pins[PIN_CTRL_RW] ? 6 : 5; 165d47d8836SGeert Uytterhoeven 166d47d8836SGeert Uytterhoeven /* Present the data to the port */ 16777588c14SJanusz Krzysztofik gpiod_set_array_value_cansleep(n, &hd->pins[PIN_DATA4], NULL, values); 168d47d8836SGeert Uytterhoeven 169d47d8836SGeert Uytterhoeven hd44780_strobe_gpio(hd); 170d47d8836SGeert Uytterhoeven } 171d47d8836SGeert Uytterhoeven 172d47d8836SGeert Uytterhoeven /* Send data to the LCD panel in 4 bit GPIO mode */ 17371ff701bSLars Poeschel static void hd44780_write_data_gpio4(struct hd44780_common *hdc, int data) 174d47d8836SGeert Uytterhoeven { 1752545c1c9SLars Poeschel struct hd44780 *hd = hdc->hd44780; 176d47d8836SGeert Uytterhoeven 177d47d8836SGeert Uytterhoeven hd44780_write_gpio4(hd, data, 1); 178d47d8836SGeert Uytterhoeven 179d47d8836SGeert Uytterhoeven /* The shortest data takes at least 45 us */ 180d47d8836SGeert Uytterhoeven udelay(45); 181d47d8836SGeert Uytterhoeven } 182d47d8836SGeert Uytterhoeven 183d47d8836SGeert Uytterhoeven static const struct charlcd_ops hd44780_ops_gpio4 = { 184d47d8836SGeert Uytterhoeven .backlight = hd44780_backlight, 185b26deabbSLars Poeschel .print = hd44780_common_print, 186d3a2fb81SLars Poeschel .gotoxy = hd44780_common_gotoxy, 18788645a86SLars Poeschel .home = hd44780_common_home, 18845421ffeSLars Poeschel .clear_display = hd44780_common_clear_display, 18901ec46dfSLars Poeschel .init_display = hd44780_common_init_display, 190d2f2187eSLars Poeschel .shift_cursor = hd44780_common_shift_cursor, 191d2f2187eSLars Poeschel .shift_display = hd44780_common_shift_display, 192d2f2187eSLars Poeschel .display = hd44780_common_display, 193d2f2187eSLars Poeschel .cursor = hd44780_common_cursor, 194d2f2187eSLars Poeschel .blink = hd44780_common_blink, 195d2f2187eSLars Poeschel .fontsize = hd44780_common_fontsize, 196d2f2187eSLars Poeschel .lines = hd44780_common_lines, 197339acb08SLars Poeschel .redefine_char = hd44780_common_redefine_char, 198d47d8836SGeert Uytterhoeven }; 199d47d8836SGeert Uytterhoeven 200d47d8836SGeert Uytterhoeven static int hd44780_probe(struct platform_device *pdev) 201d47d8836SGeert Uytterhoeven { 202d47d8836SGeert Uytterhoeven struct device *dev = &pdev->dev; 203d47d8836SGeert Uytterhoeven unsigned int i, base; 204d47d8836SGeert Uytterhoeven struct charlcd *lcd; 205718e05edSLars Poeschel struct hd44780_common *hdc; 206d47d8836SGeert Uytterhoeven struct hd44780 *hd; 207718e05edSLars Poeschel int ifwidth, ret = -ENOMEM; 208d47d8836SGeert Uytterhoeven 209d47d8836SGeert Uytterhoeven /* Required pins */ 210d47d8836SGeert Uytterhoeven ifwidth = gpiod_count(dev, "data"); 211d47d8836SGeert Uytterhoeven if (ifwidth < 0) 212d47d8836SGeert Uytterhoeven return ifwidth; 213d47d8836SGeert Uytterhoeven 214d47d8836SGeert Uytterhoeven switch (ifwidth) { 215d47d8836SGeert Uytterhoeven case 4: 216d47d8836SGeert Uytterhoeven base = PIN_DATA4; 217d47d8836SGeert Uytterhoeven break; 218d47d8836SGeert Uytterhoeven case 8: 219d47d8836SGeert Uytterhoeven base = PIN_DATA0; 220d47d8836SGeert Uytterhoeven break; 221d47d8836SGeert Uytterhoeven default: 222d47d8836SGeert Uytterhoeven return -EINVAL; 223d47d8836SGeert Uytterhoeven } 224d47d8836SGeert Uytterhoeven 225718e05edSLars Poeschel hdc = hd44780_common_alloc(); 226718e05edSLars Poeschel if (!hdc) 227d47d8836SGeert Uytterhoeven return -ENOMEM; 228d47d8836SGeert Uytterhoeven 2292545c1c9SLars Poeschel lcd = charlcd_alloc(); 230718e05edSLars Poeschel if (!lcd) 231718e05edSLars Poeschel goto fail1; 232d47d8836SGeert Uytterhoeven 233718e05edSLars Poeschel hd = kzalloc(sizeof(struct hd44780), GFP_KERNEL); 234718e05edSLars Poeschel if (!hd) 235718e05edSLars Poeschel goto fail2; 236718e05edSLars Poeschel 237718e05edSLars Poeschel hdc->hd44780 = hd; 238718e05edSLars Poeschel lcd->drvdata = hdc; 239d47d8836SGeert Uytterhoeven for (i = 0; i < ifwidth; i++) { 240d47d8836SGeert Uytterhoeven hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i, 241d47d8836SGeert Uytterhoeven GPIOD_OUT_LOW); 242d47d8836SGeert Uytterhoeven if (IS_ERR(hd->pins[base + i])) { 243d47d8836SGeert Uytterhoeven ret = PTR_ERR(hd->pins[base + i]); 244718e05edSLars Poeschel goto fail3; 245d47d8836SGeert Uytterhoeven } 246d47d8836SGeert Uytterhoeven } 247d47d8836SGeert Uytterhoeven 248d47d8836SGeert Uytterhoeven hd->pins[PIN_CTRL_E] = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); 249d47d8836SGeert Uytterhoeven if (IS_ERR(hd->pins[PIN_CTRL_E])) { 250d47d8836SGeert Uytterhoeven ret = PTR_ERR(hd->pins[PIN_CTRL_E]); 251718e05edSLars Poeschel goto fail3; 252d47d8836SGeert Uytterhoeven } 253d47d8836SGeert Uytterhoeven 254d47d8836SGeert Uytterhoeven hd->pins[PIN_CTRL_RS] = devm_gpiod_get(dev, "rs", GPIOD_OUT_HIGH); 255d47d8836SGeert Uytterhoeven if (IS_ERR(hd->pins[PIN_CTRL_RS])) { 256d47d8836SGeert Uytterhoeven ret = PTR_ERR(hd->pins[PIN_CTRL_RS]); 257718e05edSLars Poeschel goto fail3; 258d47d8836SGeert Uytterhoeven } 259d47d8836SGeert Uytterhoeven 260d47d8836SGeert Uytterhoeven /* Optional pins */ 261d47d8836SGeert Uytterhoeven hd->pins[PIN_CTRL_RW] = devm_gpiod_get_optional(dev, "rw", 262d47d8836SGeert Uytterhoeven GPIOD_OUT_LOW); 263d47d8836SGeert Uytterhoeven if (IS_ERR(hd->pins[PIN_CTRL_RW])) { 264d47d8836SGeert Uytterhoeven ret = PTR_ERR(hd->pins[PIN_CTRL_RW]); 265718e05edSLars Poeschel goto fail3; 266d47d8836SGeert Uytterhoeven } 267d47d8836SGeert Uytterhoeven 268d47d8836SGeert Uytterhoeven hd->pins[PIN_CTRL_BL] = devm_gpiod_get_optional(dev, "backlight", 269d47d8836SGeert Uytterhoeven GPIOD_OUT_LOW); 270d47d8836SGeert Uytterhoeven if (IS_ERR(hd->pins[PIN_CTRL_BL])) { 271d47d8836SGeert Uytterhoeven ret = PTR_ERR(hd->pins[PIN_CTRL_BL]); 272718e05edSLars Poeschel goto fail3; 273d47d8836SGeert Uytterhoeven } 274d47d8836SGeert Uytterhoeven 275d47d8836SGeert Uytterhoeven /* Required properties */ 276c7c3f096SGeert Uytterhoeven ret = device_property_read_u32(dev, "display-height-chars", 277c7c3f096SGeert Uytterhoeven &lcd->height); 278d47d8836SGeert Uytterhoeven if (ret) 279718e05edSLars Poeschel goto fail3; 280c7c3f096SGeert Uytterhoeven ret = device_property_read_u32(dev, "display-width-chars", &lcd->width); 281d47d8836SGeert Uytterhoeven if (ret) 282718e05edSLars Poeschel goto fail3; 283d47d8836SGeert Uytterhoeven 284d47d8836SGeert Uytterhoeven /* 285d47d8836SGeert Uytterhoeven * On displays with more than two rows, the internal buffer width is 286d47d8836SGeert Uytterhoeven * usually equal to the display width 287d47d8836SGeert Uytterhoeven */ 288d47d8836SGeert Uytterhoeven if (lcd->height > 2) 2892545c1c9SLars Poeschel hdc->bwidth = lcd->width; 290d47d8836SGeert Uytterhoeven 291d47d8836SGeert Uytterhoeven /* Optional properties */ 2922545c1c9SLars Poeschel device_property_read_u32(dev, "internal-buffer-width", &hdc->bwidth); 293d47d8836SGeert Uytterhoeven 2943fc04dd7SLars Poeschel hdc->ifwidth = ifwidth; 29571ff701bSLars Poeschel if (ifwidth == 8) { 29671ff701bSLars Poeschel lcd->ops = &hd44780_ops_gpio8; 29771ff701bSLars Poeschel hdc->write_data = hd44780_write_data_gpio8; 2982c6a82f2SLars Poeschel hdc->write_cmd = hd44780_write_cmd_gpio8; 29971ff701bSLars Poeschel } else { 30071ff701bSLars Poeschel lcd->ops = &hd44780_ops_gpio4; 30171ff701bSLars Poeschel hdc->write_data = hd44780_write_data_gpio4; 3022c6a82f2SLars Poeschel hdc->write_cmd = hd44780_write_cmd_gpio4; 3032c6a82f2SLars Poeschel hdc->write_cmd_raw4 = hd44780_write_cmd_raw_gpio4; 30471ff701bSLars Poeschel } 305d47d8836SGeert Uytterhoeven 306d47d8836SGeert Uytterhoeven ret = charlcd_register(lcd); 307d47d8836SGeert Uytterhoeven if (ret) 308718e05edSLars Poeschel goto fail3; 309d47d8836SGeert Uytterhoeven 310d47d8836SGeert Uytterhoeven platform_set_drvdata(pdev, lcd); 311d47d8836SGeert Uytterhoeven return 0; 312d47d8836SGeert Uytterhoeven 313718e05edSLars Poeschel fail3: 314718e05edSLars Poeschel kfree(hd); 315718e05edSLars Poeschel fail2: 316718e05edSLars Poeschel kfree(lcd); 317718e05edSLars Poeschel fail1: 318718e05edSLars Poeschel kfree(hdc); 319d47d8836SGeert Uytterhoeven return ret; 320d47d8836SGeert Uytterhoeven } 321d47d8836SGeert Uytterhoeven 322*9ea02f7cSUwe Kleine-König static void hd44780_remove(struct platform_device *pdev) 323d47d8836SGeert Uytterhoeven { 324d47d8836SGeert Uytterhoeven struct charlcd *lcd = platform_get_drvdata(pdev); 325ddf75a86SJianglei Nie struct hd44780_common *hdc = lcd->drvdata; 326d47d8836SGeert Uytterhoeven 327d47d8836SGeert Uytterhoeven charlcd_unregister(lcd); 328ddf75a86SJianglei Nie kfree(hdc->hd44780); 329333ff32dSLars Poeschel kfree(lcd->drvdata); 33041c8d0adSAndy Shevchenko 331718e05edSLars Poeschel kfree(lcd); 332d47d8836SGeert Uytterhoeven } 333d47d8836SGeert Uytterhoeven 334d47d8836SGeert Uytterhoeven static const struct of_device_id hd44780_of_match[] = { 335d47d8836SGeert Uytterhoeven { .compatible = "hit,hd44780" }, 336d47d8836SGeert Uytterhoeven { /* sentinel */ } 337d47d8836SGeert Uytterhoeven }; 338d47d8836SGeert Uytterhoeven MODULE_DEVICE_TABLE(of, hd44780_of_match); 339d47d8836SGeert Uytterhoeven 340d47d8836SGeert Uytterhoeven static struct platform_driver hd44780_driver = { 341d47d8836SGeert Uytterhoeven .probe = hd44780_probe, 342*9ea02f7cSUwe Kleine-König .remove_new = hd44780_remove, 343d47d8836SGeert Uytterhoeven .driver = { 344d47d8836SGeert Uytterhoeven .name = "hd44780", 345d47d8836SGeert Uytterhoeven .of_match_table = hd44780_of_match, 346d47d8836SGeert Uytterhoeven }, 347d47d8836SGeert Uytterhoeven }; 348d47d8836SGeert Uytterhoeven 349d47d8836SGeert Uytterhoeven module_platform_driver(hd44780_driver); 350d47d8836SGeert Uytterhoeven MODULE_DESCRIPTION("HD44780 Character LCD driver"); 351d47d8836SGeert Uytterhoeven MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>"); 352d47d8836SGeert Uytterhoeven MODULE_LICENSE("GPL"); 353