hd44780.c (66ce7d5c1e124b497f45aead50df1dc3c2873382) hd44780.c (718e05ed92ecac0d9d3954bcc8064527c3ce7565)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * HD44780 Character LCD driver for Linux
4 *
5 * Copyright (C) 2000-2008, Willy Tarreau <w@1wt.eu>
6 * Copyright (C) 2016-2017 Glider bvba
7 */
8
9#include <linux/delay.h>
10#include <linux/gpio/consumer.h>
11#include <linux/module.h>
12#include <linux/mod_devicetable.h>
13#include <linux/platform_device.h>
14#include <linux/property.h>
15#include <linux/slab.h>
16
17#include "charlcd.h"
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * HD44780 Character LCD driver for Linux
4 *
5 * Copyright (C) 2000-2008, Willy Tarreau <w@1wt.eu>
6 * Copyright (C) 2016-2017 Glider bvba
7 */
8
9#include <linux/delay.h>
10#include <linux/gpio/consumer.h>
11#include <linux/module.h>
12#include <linux/mod_devicetable.h>
13#include <linux/platform_device.h>
14#include <linux/property.h>
15#include <linux/slab.h>
16
17#include "charlcd.h"
18#include "hd44780_common.h"
18
19enum 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,

--- 148 unchanged lines hidden (view full) ---

174 .backlight = hd44780_backlight,
175};
176
177static int hd44780_probe(struct platform_device *pdev)
178{
179 struct device *dev = &pdev->dev;
180 unsigned int i, base;
181 struct charlcd *lcd;
19
20enum hd44780_pin {
21 /* Order does matter due to writing to GPIO array subsets! */
22 PIN_DATA0, /* Optional */
23 PIN_DATA1, /* Optional */
24 PIN_DATA2, /* Optional */
25 PIN_DATA3, /* Optional */
26 PIN_DATA4,

--- 148 unchanged lines hidden (view full) ---

175 .backlight = hd44780_backlight,
176};
177
178static int hd44780_probe(struct platform_device *pdev)
179{
180 struct device *dev = &pdev->dev;
181 unsigned int i, base;
182 struct charlcd *lcd;
183 struct hd44780_common *hdc;
182 struct hd44780 *hd;
184 struct hd44780 *hd;
183 int ifwidth, ret;
185 int ifwidth, ret = -ENOMEM;
184
185 /* Required pins */
186 ifwidth = gpiod_count(dev, "data");
187 if (ifwidth < 0)
188 return ifwidth;
189
190 switch (ifwidth) {
191 case 4:
192 base = PIN_DATA4;
193 break;
194 case 8:
195 base = PIN_DATA0;
196 break;
197 default:
198 return -EINVAL;
199 }
200
186
187 /* Required pins */
188 ifwidth = gpiod_count(dev, "data");
189 if (ifwidth < 0)
190 return ifwidth;
191
192 switch (ifwidth) {
193 case 4:
194 base = PIN_DATA4;
195 break;
196 case 8:
197 base = PIN_DATA0;
198 break;
199 default:
200 return -EINVAL;
201 }
202
203 hdc = hd44780_common_alloc();
204 if (!hdc)
205 return -ENOMEM;
206
201 lcd = charlcd_alloc(sizeof(struct hd44780));
202 if (!lcd)
207 lcd = charlcd_alloc(sizeof(struct hd44780));
208 if (!lcd)
203 return -ENOMEM;
209 goto fail1;
204
210
205 hd = lcd->drvdata;
211 hd = kzalloc(sizeof(struct hd44780), GFP_KERNEL);
212 if (!hd)
213 goto fail2;
206
214
215 hdc->hd44780 = hd;
216 lcd->drvdata = hdc;
207 for (i = 0; i < ifwidth; i++) {
208 hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i,
209 GPIOD_OUT_LOW);
210 if (IS_ERR(hd->pins[base + i])) {
211 ret = PTR_ERR(hd->pins[base + i]);
217 for (i = 0; i < ifwidth; i++) {
218 hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i,
219 GPIOD_OUT_LOW);
220 if (IS_ERR(hd->pins[base + i])) {
221 ret = PTR_ERR(hd->pins[base + i]);
212 goto fail;
222 goto fail3;
213 }
214 }
215
216 hd->pins[PIN_CTRL_E] = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
217 if (IS_ERR(hd->pins[PIN_CTRL_E])) {
218 ret = PTR_ERR(hd->pins[PIN_CTRL_E]);
223 }
224 }
225
226 hd->pins[PIN_CTRL_E] = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
227 if (IS_ERR(hd->pins[PIN_CTRL_E])) {
228 ret = PTR_ERR(hd->pins[PIN_CTRL_E]);
219 goto fail;
229 goto fail3;
220 }
221
222 hd->pins[PIN_CTRL_RS] = devm_gpiod_get(dev, "rs", GPIOD_OUT_HIGH);
223 if (IS_ERR(hd->pins[PIN_CTRL_RS])) {
224 ret = PTR_ERR(hd->pins[PIN_CTRL_RS]);
230 }
231
232 hd->pins[PIN_CTRL_RS] = devm_gpiod_get(dev, "rs", GPIOD_OUT_HIGH);
233 if (IS_ERR(hd->pins[PIN_CTRL_RS])) {
234 ret = PTR_ERR(hd->pins[PIN_CTRL_RS]);
225 goto fail;
235 goto fail3;
226 }
227
228 /* Optional pins */
229 hd->pins[PIN_CTRL_RW] = devm_gpiod_get_optional(dev, "rw",
230 GPIOD_OUT_LOW);
231 if (IS_ERR(hd->pins[PIN_CTRL_RW])) {
232 ret = PTR_ERR(hd->pins[PIN_CTRL_RW]);
236 }
237
238 /* Optional pins */
239 hd->pins[PIN_CTRL_RW] = devm_gpiod_get_optional(dev, "rw",
240 GPIOD_OUT_LOW);
241 if (IS_ERR(hd->pins[PIN_CTRL_RW])) {
242 ret = PTR_ERR(hd->pins[PIN_CTRL_RW]);
233 goto fail;
243 goto fail3;
234 }
235
236 hd->pins[PIN_CTRL_BL] = devm_gpiod_get_optional(dev, "backlight",
237 GPIOD_OUT_LOW);
238 if (IS_ERR(hd->pins[PIN_CTRL_BL])) {
239 ret = PTR_ERR(hd->pins[PIN_CTRL_BL]);
244 }
245
246 hd->pins[PIN_CTRL_BL] = devm_gpiod_get_optional(dev, "backlight",
247 GPIOD_OUT_LOW);
248 if (IS_ERR(hd->pins[PIN_CTRL_BL])) {
249 ret = PTR_ERR(hd->pins[PIN_CTRL_BL]);
240 goto fail;
250 goto fail3;
241 }
242
243 /* Required properties */
244 ret = device_property_read_u32(dev, "display-height-chars",
245 &lcd->height);
246 if (ret)
251 }
252
253 /* Required properties */
254 ret = device_property_read_u32(dev, "display-height-chars",
255 &lcd->height);
256 if (ret)
247 goto fail;
257 goto fail3;
248 ret = device_property_read_u32(dev, "display-width-chars", &lcd->width);
249 if (ret)
258 ret = device_property_read_u32(dev, "display-width-chars", &lcd->width);
259 if (ret)
250 goto fail;
260 goto fail3;
251
252 /*
253 * On displays with more than two rows, the internal buffer width is
254 * usually equal to the display width
255 */
256 if (lcd->height > 2)
257 lcd->bwidth = lcd->width;
258
259 /* Optional properties */
260 device_property_read_u32(dev, "internal-buffer-width", &lcd->bwidth);
261
262 lcd->ifwidth = ifwidth;
263 lcd->ops = ifwidth == 8 ? &hd44780_ops_gpio8 : &hd44780_ops_gpio4;
264
265 ret = charlcd_register(lcd);
266 if (ret)
261
262 /*
263 * On displays with more than two rows, the internal buffer width is
264 * usually equal to the display width
265 */
266 if (lcd->height > 2)
267 lcd->bwidth = lcd->width;
268
269 /* Optional properties */
270 device_property_read_u32(dev, "internal-buffer-width", &lcd->bwidth);
271
272 lcd->ifwidth = ifwidth;
273 lcd->ops = ifwidth == 8 ? &hd44780_ops_gpio8 : &hd44780_ops_gpio4;
274
275 ret = charlcd_register(lcd);
276 if (ret)
267 goto fail;
277 goto fail3;
268
269 platform_set_drvdata(pdev, lcd);
270 return 0;
271
278
279 platform_set_drvdata(pdev, lcd);
280 return 0;
281
272fail:
273 charlcd_free(lcd);
282fail3:
283 kfree(hd);
284fail2:
285 kfree(lcd);
286fail1:
287 kfree(hdc);
274 return ret;
275}
276
277static int hd44780_remove(struct platform_device *pdev)
278{
279 struct charlcd *lcd = platform_get_drvdata(pdev);
280
288 return ret;
289}
290
291static int hd44780_remove(struct platform_device *pdev)
292{
293 struct charlcd *lcd = platform_get_drvdata(pdev);
294
295 kfree(lcd->drvdata);
281 charlcd_unregister(lcd);
282
296 charlcd_unregister(lcd);
297
283 charlcd_free(lcd);
298 kfree(lcd);
284 return 0;
285}
286
287static const struct of_device_id hd44780_of_match[] = {
288 { .compatible = "hit,hd44780" },
289 { /* sentinel */ }
290};
291MODULE_DEVICE_TABLE(of, hd44780_of_match);

--- 14 unchanged lines hidden ---
299 return 0;
300}
301
302static const struct of_device_id hd44780_of_match[] = {
303 { .compatible = "hit,hd44780" },
304 { /* sentinel */ }
305};
306MODULE_DEVICE_TABLE(of, hd44780_of_match);

--- 14 unchanged lines hidden ---