Skip to content

Commit

Permalink
auxdisplay: Move hwidth and bwidth to struct hd44780_common
Browse files Browse the repository at this point in the history
hwidth is for the hardware buffer size and bwidth is for the buffer
width of one single line. This is specific to the hd44780 displays and
so it is moved out from charlcd to struct 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>
  • Loading branch information
poeschel authored and ojeda committed Nov 4, 2020
1 parent 718e05e commit 2545c1c
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 55 deletions.
40 changes: 20 additions & 20 deletions drivers/auxdisplay/charlcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
#include <generated/utsrelease.h>

#include "charlcd.h"

#define DEFAULT_LCD_BWIDTH 40
#define DEFAULT_LCD_HWIDTH 64
#include "hd44780_common.h"

/* Keep the backlight on this many seconds for each flash */
#define LCD_BL_TEMPO_PERIOD 4
Expand Down Expand Up @@ -151,18 +149,19 @@ EXPORT_SYMBOL_GPL(charlcd_poke);
static void charlcd_gotoxy(struct charlcd *lcd)
{
struct charlcd_priv *priv = charlcd_to_priv(lcd);
struct hd44780_common *hdc = lcd->drvdata;
unsigned int addr;

/*
* we force the cursor to stay at the end of the
* line if it wants to go farther
*/
addr = priv->addr.x < lcd->bwidth ? priv->addr.x & (lcd->hwidth - 1)
: lcd->bwidth - 1;
addr = priv->addr.x < hdc->bwidth ? priv->addr.x & (hdc->hwidth - 1)
: hdc->bwidth - 1;
if (priv->addr.y & 1)
addr += lcd->hwidth;
addr += hdc->hwidth;
if (priv->addr.y & 2)
addr += lcd->bwidth;
addr += hdc->bwidth;
lcd->ops->write_cmd(lcd, LCD_CMD_SET_DDRAM_ADDR | addr);
}

Expand All @@ -178,29 +177,31 @@ static void charlcd_home(struct charlcd *lcd)
static void charlcd_print(struct charlcd *lcd, char c)
{
struct charlcd_priv *priv = charlcd_to_priv(lcd);
struct hd44780_common *hdc = lcd->drvdata;

if (priv->addr.x < lcd->bwidth) {
if (priv->addr.x < hdc->bwidth) {
if (lcd->char_conv)
c = lcd->char_conv[(unsigned char)c];
lcd->ops->write_data(lcd, c);
priv->addr.x++;

/* prevents the cursor from wrapping onto the next line */
if (priv->addr.x == lcd->bwidth)
if (priv->addr.x == hdc->bwidth)
charlcd_gotoxy(lcd);
}
}

static void charlcd_clear_fast(struct charlcd *lcd)
{
struct hd44780_common *hdc = lcd->drvdata;
int pos;

charlcd_home(lcd);

if (lcd->ops->clear_fast)
lcd->ops->clear_fast(lcd);
else
for (pos = 0; pos < min(2, lcd->height) * lcd->hwidth; pos++)
for (pos = 0; pos < min(2, lcd->height) * hdc->hwidth; pos++)
lcd->ops->write_data(lcd, ' ');

charlcd_home(lcd);
Expand Down Expand Up @@ -348,6 +349,7 @@ static bool parse_xy(const char *s, unsigned long *x, unsigned long *y)
static inline int handle_lcd_special_code(struct charlcd *lcd)
{
struct charlcd_priv *priv = charlcd_to_priv(lcd);
struct hd44780_common *hdc = lcd->drvdata;

/* LCD special codes */

Expand Down Expand Up @@ -413,7 +415,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
case 'l': /* Shift Cursor Left */
if (priv->addr.x > 0) {
/* back one char if not at end of line */
if (priv->addr.x < lcd->bwidth)
if (priv->addr.x < hdc->bwidth)
lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT);
priv->addr.x--;
}
Expand All @@ -422,7 +424,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
case 'r': /* shift cursor right */
if (priv->addr.x < lcd->width) {
/* allow the cursor to pass the end of the line */
if (priv->addr.x < (lcd->bwidth - 1))
if (priv->addr.x < (hdc->bwidth - 1))
lcd->ops->write_cmd(lcd,
LCD_CMD_SHIFT | LCD_CMD_SHIFT_RIGHT);
priv->addr.x++;
Expand All @@ -442,7 +444,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
case 'k': { /* kill end of line */
int x;

for (x = priv->addr.x; x < lcd->bwidth; x++)
for (x = priv->addr.x; x < hdc->bwidth; x++)
lcd->ops->write_data(lcd, ' ');

/* restore cursor position */
Expand Down Expand Up @@ -554,6 +556,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
static void charlcd_write_char(struct charlcd *lcd, char c)
{
struct charlcd_priv *priv = charlcd_to_priv(lcd);
struct hd44780_common *hdc = lcd->drvdata;

/* first, we'll test if we're in escape mode */
if ((c != '\n') && priv->esc_seq.len >= 0) {
Expand All @@ -577,7 +580,7 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
* check if we're not at the
* end of the line
*/
if (priv->addr.x < lcd->bwidth)
if (priv->addr.x < hdc->bwidth)
/* back one char */
lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT);
priv->addr.x--;
Expand All @@ -596,7 +599,7 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
* flush the remainder of the current line and
* go to the beginning of the next line
*/
for (; priv->addr.x < lcd->bwidth; priv->addr.x++)
for (; priv->addr.x < hdc->bwidth; priv->addr.x++)
lcd->ops->write_data(lcd, ' ');
priv->addr.x = 0;
priv->addr.y = (priv->addr.y + 1) % lcd->height;
Expand Down Expand Up @@ -779,22 +782,19 @@ static int charlcd_init(struct charlcd *lcd)
return 0;
}

struct charlcd *charlcd_alloc(unsigned int drvdata_size)
struct charlcd *charlcd_alloc(void)
{
struct charlcd_priv *priv;
struct charlcd *lcd;

priv = kzalloc(sizeof(*priv) + drvdata_size, GFP_KERNEL);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return NULL;

priv->esc_seq.len = -1;

lcd = &priv->lcd;
lcd->ifwidth = 8;
lcd->bwidth = DEFAULT_LCD_BWIDTH;
lcd->hwidth = DEFAULT_LCD_HWIDTH;
lcd->drvdata = priv->drvdata;

return lcd;
}
Expand Down
6 changes: 2 additions & 4 deletions drivers/auxdisplay/charlcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ struct charlcd {
int ifwidth; /* 4-bit or 8-bit (default) */
int height;
int width;
int bwidth; /* Default set by charlcd_alloc() */
int hwidth; /* Default set by charlcd_alloc() */

void *drvdata; /* Set by charlcd_alloc() */
void *drvdata;
};

struct charlcd_ops {
Expand All @@ -38,7 +36,7 @@ struct charlcd_ops {
void (*backlight)(struct charlcd *lcd, enum charlcd_onoff on);
};

struct charlcd *charlcd_alloc(unsigned int drvdata_size);
struct charlcd *charlcd_alloc(void);
void charlcd_free(struct charlcd *lcd);

int charlcd_register(struct charlcd *lcd);
Expand Down
24 changes: 15 additions & 9 deletions drivers/auxdisplay/hd44780.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ struct hd44780 {

static void hd44780_backlight(struct charlcd *lcd, enum charlcd_onoff on)
{
struct hd44780 *hd = lcd->drvdata;
struct hd44780_common *hdc = lcd->drvdata;
struct hd44780 *hd = hdc->hd44780;

if (hd->pins[PIN_CTRL_BL])
gpiod_set_value_cansleep(hd->pins[PIN_CTRL_BL], on);
Expand Down Expand Up @@ -104,7 +105,8 @@ static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs)
/* Send a command to the LCD panel in 8 bit GPIO mode */
static void hd44780_write_cmd_gpio8(struct charlcd *lcd, int cmd)
{
struct hd44780 *hd = lcd->drvdata;
struct hd44780_common *hdc = lcd->drvdata;
struct hd44780 *hd = hdc->hd44780;

hd44780_write_gpio8(hd, cmd, 0);

Expand All @@ -115,7 +117,8 @@ static void hd44780_write_cmd_gpio8(struct charlcd *lcd, int cmd)
/* Send data to the LCD panel in 8 bit GPIO mode */
static void hd44780_write_data_gpio8(struct charlcd *lcd, int data)
{
struct hd44780 *hd = lcd->drvdata;
struct hd44780_common *hdc = lcd->drvdata;
struct hd44780 *hd = hdc->hd44780;

hd44780_write_gpio8(hd, data, 1);

Expand All @@ -132,7 +135,8 @@ static const struct charlcd_ops hd44780_ops_gpio8 = {
/* Send a command to the LCD panel in 4 bit GPIO mode */
static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
{
struct hd44780 *hd = lcd->drvdata;
struct hd44780_common *hdc = lcd->drvdata;
struct hd44780 *hd = hdc->hd44780;

hd44780_write_gpio4(hd, cmd, 0);

Expand All @@ -144,7 +148,8 @@ static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
{
DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */
struct hd44780 *hd = lcd->drvdata;
struct hd44780_common *hdc = lcd->drvdata;
struct hd44780 *hd = hdc->hd44780;
unsigned int n;

/* Command nibble + RS, RW */
Expand All @@ -160,7 +165,8 @@ static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
/* Send data to the LCD panel in 4 bit GPIO mode */
static void hd44780_write_data_gpio4(struct charlcd *lcd, int data)
{
struct hd44780 *hd = lcd->drvdata;
struct hd44780_common *hdc = lcd->drvdata;
struct hd44780 *hd = hdc->hd44780;

hd44780_write_gpio4(hd, data, 1);

Expand Down Expand Up @@ -204,7 +210,7 @@ static int hd44780_probe(struct platform_device *pdev)
if (!hdc)
return -ENOMEM;

lcd = charlcd_alloc(sizeof(struct hd44780));
lcd = charlcd_alloc();
if (!lcd)
goto fail1;

Expand Down Expand Up @@ -264,10 +270,10 @@ static int hd44780_probe(struct platform_device *pdev)
* usually equal to the display width
*/
if (lcd->height > 2)
lcd->bwidth = lcd->width;
hdc->bwidth = lcd->width;

/* Optional properties */
device_property_read_u32(dev, "internal-buffer-width", &lcd->bwidth);
device_property_read_u32(dev, "internal-buffer-width", &hdc->bwidth);

lcd->ifwidth = ifwidth;
lcd->ops = ifwidth == 8 ? &hd44780_ops_gpio8 : &hd44780_ops_gpio4;
Expand Down
2 changes: 2 additions & 0 deletions drivers/auxdisplay/hd44780_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ struct hd44780_common *hd44780_common_alloc(void)
if (!hd)
return NULL;

hd->bwidth = DEFAULT_LCD_BWIDTH;
hd->hwidth = DEFAULT_LCD_HWIDTH;
return hd;
}
EXPORT_SYMBOL_GPL(hd44780_common_alloc);
Expand Down
5 changes: 5 additions & 0 deletions drivers/auxdisplay/hd44780_common.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#define DEFAULT_LCD_BWIDTH 40
#define DEFAULT_LCD_HWIDTH 64

struct hd44780_common {
int bwidth; /* Default set by hd44780_alloc() */
int hwidth; /* Default set by hd44780_alloc() */
void *hd44780;
};

Expand Down
Loading

0 comments on commit 2545c1c

Please sign in to comment.