auxdisplay: Introduce hd44780_common.[ch]
There is some hd44780 specific code in charlcd and this code is used by multiple drivers. To make charlcd independent from this device specific code this has to be moved to a place where the multiple drivers can share their common code. This common place is now introduced as hd44780_common. Reviewed-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Lars Poeschel <poeschel@lemonage.de> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
Родитель
66ce7d5c1e
Коммит
718e05ed92
|
@ -16,10 +16,29 @@ menuconfig AUXDISPLAY
|
|||
|
||||
if AUXDISPLAY
|
||||
|
||||
config CHARLCD
|
||||
tristate "Character LCD core support" if COMPILE_TEST
|
||||
help
|
||||
This is the base system for character-based LCD displays.
|
||||
It makes no sense to have this alone, you select your display driver
|
||||
and if it needs the charlcd core, it will select it automatically.
|
||||
This is some character LCD core interface that multiple drivers can
|
||||
use.
|
||||
|
||||
config HD44780_COMMON
|
||||
tristate "Common functions for HD44780 (and compatibles) LCD displays" if COMPILE_TEST
|
||||
help
|
||||
This is a module with the common symbols for HD44780 (and compatibles)
|
||||
displays. This is the code that multiple other modules use. It is not
|
||||
useful alone. If you have some sort of HD44780 compatible display,
|
||||
you very likely use this. It is selected automatically by selecting
|
||||
your concrete display.
|
||||
|
||||
config HD44780
|
||||
tristate "HD44780 Character LCD support"
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
select CHARLCD
|
||||
select HD44780_COMMON
|
||||
help
|
||||
Enable support for Character LCDs using a HD44780 controller.
|
||||
The LCD is accessible through the /dev/lcd char device (10, 156).
|
||||
|
@ -168,6 +187,7 @@ menuconfig PARPORT_PANEL
|
|||
tristate "Parallel port LCD/Keypad Panel support"
|
||||
depends on PARPORT
|
||||
select CHARLCD
|
||||
select HD44780_COMMON
|
||||
help
|
||||
Say Y here if you have an HD44780 or KS-0074 LCD connected to your
|
||||
parallel port. This driver also features 4 and 6-key keypads. The LCD
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#
|
||||
|
||||
obj-$(CONFIG_CHARLCD) += charlcd.o
|
||||
obj-$(CONFIG_HD44780_COMMON) += hd44780_common.o
|
||||
obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
|
||||
obj-$(CONFIG_KS0108) += ks0108.o
|
||||
obj-$(CONFIG_CFAG12864B) += cfag12864b.o cfag12864bfb.o
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/slab.h>
|
||||
|
||||
#include "charlcd.h"
|
||||
#include "hd44780_common.h"
|
||||
|
||||
enum hd44780_pin {
|
||||
/* Order does matter due to writing to GPIO array subsets! */
|
||||
|
@ -179,8 +180,9 @@ static int hd44780_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
unsigned int i, base;
|
||||
struct charlcd *lcd;
|
||||
struct hd44780_common *hdc;
|
||||
struct hd44780 *hd;
|
||||
int ifwidth, ret;
|
||||
int ifwidth, ret = -ENOMEM;
|
||||
|
||||
/* Required pins */
|
||||
ifwidth = gpiod_count(dev, "data");
|
||||
|
@ -198,31 +200,39 @@ static int hd44780_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
lcd = charlcd_alloc(sizeof(struct hd44780));
|
||||
if (!lcd)
|
||||
hdc = hd44780_common_alloc();
|
||||
if (!hdc)
|
||||
return -ENOMEM;
|
||||
|
||||
hd = lcd->drvdata;
|
||||
lcd = charlcd_alloc(sizeof(struct hd44780));
|
||||
if (!lcd)
|
||||
goto fail1;
|
||||
|
||||
hd = kzalloc(sizeof(struct hd44780), GFP_KERNEL);
|
||||
if (!hd)
|
||||
goto fail2;
|
||||
|
||||
hdc->hd44780 = hd;
|
||||
lcd->drvdata = hdc;
|
||||
for (i = 0; i < ifwidth; i++) {
|
||||
hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i,
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(hd->pins[base + i])) {
|
||||
ret = PTR_ERR(hd->pins[base + i]);
|
||||
goto fail;
|
||||
goto fail3;
|
||||
}
|
||||
}
|
||||
|
||||
hd->pins[PIN_CTRL_E] = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(hd->pins[PIN_CTRL_E])) {
|
||||
ret = PTR_ERR(hd->pins[PIN_CTRL_E]);
|
||||
goto fail;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
hd->pins[PIN_CTRL_RS] = devm_gpiod_get(dev, "rs", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(hd->pins[PIN_CTRL_RS])) {
|
||||
ret = PTR_ERR(hd->pins[PIN_CTRL_RS]);
|
||||
goto fail;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
/* Optional pins */
|
||||
|
@ -230,24 +240,24 @@ static int hd44780_probe(struct platform_device *pdev)
|
|||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(hd->pins[PIN_CTRL_RW])) {
|
||||
ret = PTR_ERR(hd->pins[PIN_CTRL_RW]);
|
||||
goto fail;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
hd->pins[PIN_CTRL_BL] = devm_gpiod_get_optional(dev, "backlight",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(hd->pins[PIN_CTRL_BL])) {
|
||||
ret = PTR_ERR(hd->pins[PIN_CTRL_BL]);
|
||||
goto fail;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
/* Required properties */
|
||||
ret = device_property_read_u32(dev, "display-height-chars",
|
||||
&lcd->height);
|
||||
if (ret)
|
||||
goto fail;
|
||||
goto fail3;
|
||||
ret = device_property_read_u32(dev, "display-width-chars", &lcd->width);
|
||||
if (ret)
|
||||
goto fail;
|
||||
goto fail3;
|
||||
|
||||
/*
|
||||
* On displays with more than two rows, the internal buffer width is
|
||||
|
@ -264,13 +274,17 @@ static int hd44780_probe(struct platform_device *pdev)
|
|||
|
||||
ret = charlcd_register(lcd);
|
||||
if (ret)
|
||||
goto fail;
|
||||
goto fail3;
|
||||
|
||||
platform_set_drvdata(pdev, lcd);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
charlcd_free(lcd);
|
||||
fail3:
|
||||
kfree(hd);
|
||||
fail2:
|
||||
kfree(lcd);
|
||||
fail1:
|
||||
kfree(hdc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -278,9 +292,10 @@ static int hd44780_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct charlcd *lcd = platform_get_drvdata(pdev);
|
||||
|
||||
kfree(lcd->drvdata);
|
||||
charlcd_unregister(lcd);
|
||||
|
||||
charlcd_free(lcd);
|
||||
kfree(lcd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "hd44780_common.h"
|
||||
|
||||
struct hd44780_common *hd44780_common_alloc(void)
|
||||
{
|
||||
struct hd44780_common *hd;
|
||||
|
||||
hd = kzalloc(sizeof(*hd), GFP_KERNEL);
|
||||
if (!hd)
|
||||
return NULL;
|
||||
|
||||
return hd;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hd44780_common_alloc);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
struct hd44780_common {
|
||||
void *hd44780;
|
||||
};
|
||||
|
||||
struct hd44780_common *hd44780_common_alloc(void);
|
|
@ -56,6 +56,7 @@
|
|||
#include <linux/uaccess.h>
|
||||
|
||||
#include "charlcd.h"
|
||||
#include "hd44780_common.h"
|
||||
|
||||
#define LCD_MAXBYTES 256 /* max burst write */
|
||||
|
||||
|
@ -895,10 +896,20 @@ static const struct charlcd_ops charlcd_tilcd_ops = {
|
|||
static void lcd_init(void)
|
||||
{
|
||||
struct charlcd *charlcd;
|
||||
struct hd44780_common *hdc;
|
||||
|
||||
hdc = hd44780_common_alloc();
|
||||
if (!hdc)
|
||||
return;
|
||||
|
||||
charlcd = charlcd_alloc(0);
|
||||
if (!charlcd)
|
||||
if (!charlcd) {
|
||||
kfree(hdc);
|
||||
return;
|
||||
}
|
||||
|
||||
hdc->hd44780 = &lcd;
|
||||
charlcd->drvdata = hdc;
|
||||
|
||||
/*
|
||||
* Init lcd struct with load-time values to preserve exact
|
||||
|
@ -1620,7 +1631,7 @@ err_lcd_unreg:
|
|||
if (lcd.enabled)
|
||||
charlcd_unregister(lcd.charlcd);
|
||||
err_unreg_device:
|
||||
charlcd_free(lcd.charlcd);
|
||||
kfree(lcd.charlcd);
|
||||
lcd.charlcd = NULL;
|
||||
parport_unregister_device(pprt);
|
||||
pprt = NULL;
|
||||
|
@ -1647,7 +1658,8 @@ static void panel_detach(struct parport *port)
|
|||
if (lcd.enabled) {
|
||||
charlcd_unregister(lcd.charlcd);
|
||||
lcd.initialized = false;
|
||||
charlcd_free(lcd.charlcd);
|
||||
kfree(lcd.charlcd->drvdata);
|
||||
kfree(lcd.charlcd);
|
||||
lcd.charlcd = NULL;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче