summaryrefslogtreecommitdiff
path: root/drivers/auxdisplay/panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/auxdisplay/panel.c')
-rw-r--r--drivers/auxdisplay/panel.c173
1 files changed, 62 insertions, 111 deletions
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index 1c82d824ae00..ff5755ee5694 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -56,6 +56,7 @@
#include <linux/uaccess.h>
#include "charlcd.h"
+#include "hd44780_common.h"
#define LCD_MAXBYTES 256 /* max burst write */
@@ -298,8 +299,6 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
#define DEFAULT_LCD_TYPE LCD_TYPE_OLD
#define DEFAULT_LCD_HEIGHT 2
#define DEFAULT_LCD_WIDTH 40
-#define DEFAULT_LCD_BWIDTH 40
-#define DEFAULT_LCD_HWIDTH 64
#define DEFAULT_LCD_CHARSET LCD_CHARSET_NORMAL
#define DEFAULT_LCD_PROTO LCD_PROTO_PARALLEL
@@ -708,7 +707,7 @@ static void lcd_send_serial(int byte)
}
/* turn the backlight on or off */
-static void lcd_backlight(struct charlcd *charlcd, int on)
+static void lcd_backlight(struct charlcd *charlcd, enum charlcd_onoff on)
{
if (lcd.pins.bl == PIN_NONE)
return;
@@ -724,7 +723,7 @@ static void lcd_backlight(struct charlcd *charlcd, int on)
}
/* send a command to the LCD panel in serial mode */
-static void lcd_write_cmd_s(struct charlcd *charlcd, int cmd)
+static void lcd_write_cmd_s(struct hd44780_common *hdc, int cmd)
{
spin_lock_irq(&pprt_lock);
lcd_send_serial(0x1F); /* R/W=W, RS=0 */
@@ -735,7 +734,7 @@ static void lcd_write_cmd_s(struct charlcd *charlcd, int cmd)
}
/* send data to the LCD panel in serial mode */
-static void lcd_write_data_s(struct charlcd *charlcd, int data)
+static void lcd_write_data_s(struct hd44780_common *hdc, int data)
{
spin_lock_irq(&pprt_lock);
lcd_send_serial(0x5F); /* R/W=W, RS=1 */
@@ -746,7 +745,7 @@ static void lcd_write_data_s(struct charlcd *charlcd, int data)
}
/* send a command to the LCD panel in 8 bits parallel mode */
-static void lcd_write_cmd_p8(struct charlcd *charlcd, int cmd)
+static void lcd_write_cmd_p8(struct hd44780_common *hdc, int cmd)
{
spin_lock_irq(&pprt_lock);
/* present the data to the data port */
@@ -768,7 +767,7 @@ static void lcd_write_cmd_p8(struct charlcd *charlcd, int cmd)
}
/* send data to the LCD panel in 8 bits parallel mode */
-static void lcd_write_data_p8(struct charlcd *charlcd, int data)
+static void lcd_write_data_p8(struct hd44780_common *hdc, int data)
{
spin_lock_irq(&pprt_lock);
/* present the data to the data port */
@@ -790,7 +789,7 @@ static void lcd_write_data_p8(struct charlcd *charlcd, int data)
}
/* send a command to the TI LCD panel */
-static void lcd_write_cmd_tilcd(struct charlcd *charlcd, int cmd)
+static void lcd_write_cmd_tilcd(struct hd44780_common *hdc, int cmd)
{
spin_lock_irq(&pprt_lock);
/* present the data to the control port */
@@ -800,7 +799,7 @@ static void lcd_write_cmd_tilcd(struct charlcd *charlcd, int cmd)
}
/* send data to the TI LCD panel */
-static void lcd_write_data_tilcd(struct charlcd *charlcd, int data)
+static void lcd_write_data_tilcd(struct hd44780_common *hdc, int data)
{
spin_lock_irq(&pprt_lock);
/* present the data to the data port */
@@ -809,105 +808,50 @@ static void lcd_write_data_tilcd(struct charlcd *charlcd, int data)
spin_unlock_irq(&pprt_lock);
}
-/* fills the display with spaces and resets X/Y */
-static void lcd_clear_fast_s(struct charlcd *charlcd)
-{
- int pos;
-
- spin_lock_irq(&pprt_lock);
- for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
- lcd_send_serial(0x5F); /* R/W=W, RS=1 */
- lcd_send_serial(' ' & 0x0F);
- lcd_send_serial((' ' >> 4) & 0x0F);
- /* the shortest data takes at least 40 us */
- udelay(40);
- }
- spin_unlock_irq(&pprt_lock);
-}
-
-/* fills the display with spaces and resets X/Y */
-static void lcd_clear_fast_p8(struct charlcd *charlcd)
-{
- int pos;
-
- spin_lock_irq(&pprt_lock);
- for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
- /* present the data to the data port */
- w_dtr(pprt, ' ');
-
- /* maintain the data during 20 us before the strobe */
- udelay(20);
-
- set_bit(LCD_BIT_E, bits);
- set_bit(LCD_BIT_RS, bits);
- clear_bit(LCD_BIT_RW, bits);
- set_ctrl_bits();
-
- /* maintain the strobe during 40 us */
- udelay(40);
-
- clear_bit(LCD_BIT_E, bits);
- set_ctrl_bits();
-
- /* the shortest data takes at least 45 us */
- udelay(45);
- }
- spin_unlock_irq(&pprt_lock);
-}
-
-/* fills the display with spaces and resets X/Y */
-static void lcd_clear_fast_tilcd(struct charlcd *charlcd)
-{
- int pos;
-
- spin_lock_irq(&pprt_lock);
- for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
- /* present the data to the data port */
- w_dtr(pprt, ' ');
- udelay(60);
- }
-
- spin_unlock_irq(&pprt_lock);
-}
-
-static const struct charlcd_ops charlcd_serial_ops = {
- .write_cmd = lcd_write_cmd_s,
- .write_data = lcd_write_data_s,
- .clear_fast = lcd_clear_fast_s,
- .backlight = lcd_backlight,
-};
-
-static const struct charlcd_ops charlcd_parallel_ops = {
- .write_cmd = lcd_write_cmd_p8,
- .write_data = lcd_write_data_p8,
- .clear_fast = lcd_clear_fast_p8,
- .backlight = lcd_backlight,
-};
-
-static const struct charlcd_ops charlcd_tilcd_ops = {
- .write_cmd = lcd_write_cmd_tilcd,
- .write_data = lcd_write_data_tilcd,
- .clear_fast = lcd_clear_fast_tilcd,
+static const struct charlcd_ops charlcd_ops = {
.backlight = lcd_backlight,
+ .print = hd44780_common_print,
+ .gotoxy = hd44780_common_gotoxy,
+ .home = hd44780_common_home,
+ .clear_display = hd44780_common_clear_display,
+ .init_display = hd44780_common_init_display,
+ .shift_cursor = hd44780_common_shift_cursor,
+ .shift_display = hd44780_common_shift_display,
+ .display = hd44780_common_display,
+ .cursor = hd44780_common_cursor,
+ .blink = hd44780_common_blink,
+ .fontsize = hd44780_common_fontsize,
+ .lines = hd44780_common_lines,
+ .redefine_char = hd44780_common_redefine_char,
};
/* initialize the LCD driver */
static void lcd_init(void)
{
struct charlcd *charlcd;
+ struct hd44780_common *hdc;
- charlcd = charlcd_alloc(0);
- if (!charlcd)
+ hdc = hd44780_common_alloc();
+ if (!hdc)
return;
+ charlcd = charlcd_alloc();
+ if (!charlcd) {
+ kfree(hdc);
+ return;
+ }
+
+ hdc->hd44780 = &lcd;
+ charlcd->drvdata = hdc;
+
/*
* Init lcd struct with load-time values to preserve exact
* current functionality (at least for now).
*/
charlcd->height = lcd_height;
charlcd->width = lcd_width;
- charlcd->bwidth = lcd_bwidth;
- charlcd->hwidth = lcd_hwidth;
+ hdc->bwidth = lcd_bwidth;
+ hdc->hwidth = lcd_hwidth;
switch (selected_lcd_type) {
case LCD_TYPE_OLD:
@@ -918,8 +862,8 @@ static void lcd_init(void)
lcd.pins.rs = PIN_AUTOLF;
charlcd->width = 40;
- charlcd->bwidth = 40;
- charlcd->hwidth = 64;
+ hdc->bwidth = 40;
+ hdc->hwidth = 64;
charlcd->height = 2;
break;
case LCD_TYPE_KS0074:
@@ -931,8 +875,8 @@ static void lcd_init(void)
lcd.pins.da = PIN_D0;
charlcd->width = 16;
- charlcd->bwidth = 40;
- charlcd->hwidth = 16;
+ hdc->bwidth = 40;
+ hdc->hwidth = 16;
charlcd->height = 2;
break;
case LCD_TYPE_NEXCOM:
@@ -944,8 +888,8 @@ static void lcd_init(void)
lcd.pins.rw = PIN_INITP;
charlcd->width = 16;
- charlcd->bwidth = 40;
- charlcd->hwidth = 64;
+ hdc->bwidth = 40;
+ hdc->hwidth = 64;
charlcd->height = 2;
break;
case LCD_TYPE_CUSTOM:
@@ -963,8 +907,8 @@ static void lcd_init(void)
lcd.pins.rs = PIN_SELECP;
charlcd->width = 16;
- charlcd->bwidth = 40;
- charlcd->hwidth = 64;
+ hdc->bwidth = 40;
+ hdc->hwidth = 64;
charlcd->height = 2;
break;
}
@@ -975,9 +919,9 @@ static void lcd_init(void)
if (lcd_width != NOT_SET)
charlcd->width = lcd_width;
if (lcd_bwidth != NOT_SET)
- charlcd->bwidth = lcd_bwidth;
+ hdc->bwidth = lcd_bwidth;
if (lcd_hwidth != NOT_SET)
- charlcd->hwidth = lcd_hwidth;
+ hdc->hwidth = lcd_hwidth;
if (lcd_charset != NOT_SET)
lcd.charset = lcd_charset;
if (lcd_proto != NOT_SET)
@@ -998,15 +942,17 @@ static void lcd_init(void)
/* this is used to catch wrong and default values */
if (charlcd->width <= 0)
charlcd->width = DEFAULT_LCD_WIDTH;
- if (charlcd->bwidth <= 0)
- charlcd->bwidth = DEFAULT_LCD_BWIDTH;
- if (charlcd->hwidth <= 0)
- charlcd->hwidth = DEFAULT_LCD_HWIDTH;
+ if (hdc->bwidth <= 0)
+ hdc->bwidth = DEFAULT_LCD_BWIDTH;
+ if (hdc->hwidth <= 0)
+ hdc->hwidth = DEFAULT_LCD_HWIDTH;
if (charlcd->height <= 0)
charlcd->height = DEFAULT_LCD_HEIGHT;
if (lcd.proto == LCD_PROTO_SERIAL) { /* SERIAL */
- charlcd->ops = &charlcd_serial_ops;
+ charlcd->ops = &charlcd_ops;
+ hdc->write_data = lcd_write_data_s;
+ hdc->write_cmd = lcd_write_cmd_s;
if (lcd.pins.cl == PIN_NOT_SET)
lcd.pins.cl = DEFAULT_LCD_PIN_SCL;
@@ -1014,7 +960,9 @@ static void lcd_init(void)
lcd.pins.da = DEFAULT_LCD_PIN_SDA;
} else if (lcd.proto == LCD_PROTO_PARALLEL) { /* PARALLEL */
- charlcd->ops = &charlcd_parallel_ops;
+ charlcd->ops = &charlcd_ops;
+ hdc->write_data = lcd_write_data_p8;
+ hdc->write_cmd = lcd_write_cmd_p8;
if (lcd.pins.e == PIN_NOT_SET)
lcd.pins.e = DEFAULT_LCD_PIN_E;
@@ -1023,7 +971,9 @@ static void lcd_init(void)
if (lcd.pins.rw == PIN_NOT_SET)
lcd.pins.rw = DEFAULT_LCD_PIN_RW;
} else {
- charlcd->ops = &charlcd_tilcd_ops;
+ charlcd->ops = &charlcd_ops;
+ hdc->write_data = lcd_write_data_tilcd;
+ hdc->write_cmd = lcd_write_cmd_tilcd;
}
if (lcd.pins.bl == PIN_NOT_SET)
@@ -1620,7 +1570,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 +1597,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;
}