diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c index 4262db0237f9..6030ac5b8c63 100644 --- a/drivers/misc/panel.c +++ b/drivers/misc/panel.c @@ -648,34 +648,28 @@ static const char nexcom_keypad_profile[][4][9] = { static const char (*keypad_profile)[4][9] = old_keypad_profile; -/* FIXME: this should be converted to a bit array containing signals states */ -static struct { - unsigned char e; /* parallel LCD E (data latch on falling edge) */ - unsigned char rs; /* parallel LCD RS (0 = cmd, 1 = data) */ - unsigned char rw; /* parallel LCD R/W (0 = W, 1 = R) */ - unsigned char bl; /* parallel LCD backlight (0 = off, 1 = on) */ - unsigned char cl; /* serial LCD clock (latch on rising edge) */ - unsigned char da; /* serial LCD data */ -} bits; +static DECLARE_BITMAP(bits, LCD_BITS); + +static void lcd_get_bits(unsigned int port, int *val) +{ + unsigned int bit, state; + + for (bit = 0; bit < LCD_BITS; bit++) { + state = test_bit(bit, bits) ? BIT_SET : BIT_CLR; + *val &= lcd_bits[port][bit][BIT_MSK]; + *val |= lcd_bits[port][bit][state]; + } +} static void init_scan_timer(void); /* sets data port bits according to current signals values */ static int set_data_bits(void) { - int val, bit; + int val; val = r_dtr(pprt); - for (bit = 0; bit < LCD_BITS; bit++) - val &= lcd_bits[LCD_PORT_D][bit][BIT_MSK]; - - val |= lcd_bits[LCD_PORT_D][LCD_BIT_E][bits.e] - | lcd_bits[LCD_PORT_D][LCD_BIT_RS][bits.rs] - | lcd_bits[LCD_PORT_D][LCD_BIT_RW][bits.rw] - | lcd_bits[LCD_PORT_D][LCD_BIT_BL][bits.bl] - | lcd_bits[LCD_PORT_D][LCD_BIT_CL][bits.cl] - | lcd_bits[LCD_PORT_D][LCD_BIT_DA][bits.da]; - + lcd_get_bits(LCD_PORT_D, &val); w_dtr(pprt, val); return val; } @@ -683,19 +677,10 @@ static int set_data_bits(void) /* sets ctrl port bits according to current signals values */ static int set_ctrl_bits(void) { - int val, bit; + int val; val = r_ctr(pprt); - for (bit = 0; bit < LCD_BITS; bit++) - val &= lcd_bits[LCD_PORT_C][bit][BIT_MSK]; - - val |= lcd_bits[LCD_PORT_C][LCD_BIT_E][bits.e] - | lcd_bits[LCD_PORT_C][LCD_BIT_RS][bits.rs] - | lcd_bits[LCD_PORT_C][LCD_BIT_RW][bits.rw] - | lcd_bits[LCD_PORT_C][LCD_BIT_BL][bits.bl] - | lcd_bits[LCD_PORT_C][LCD_BIT_CL][bits.cl] - | lcd_bits[LCD_PORT_C][LCD_BIT_DA][bits.da]; - + lcd_get_bits(LCD_PORT_C, &val); w_ctr(pprt, val); return val; } @@ -791,12 +776,17 @@ static void lcd_send_serial(int byte) * LCD reads D0 on STROBE's rising edge. */ for (bit = 0; bit < 8; bit++) { - bits.cl = BIT_CLR; /* CLK low */ + clear_bit(LCD_BIT_CL, bits); /* CLK low */ panel_set_bits(); - bits.da = byte & 1; + if (byte & 1) { + set_bit(LCD_BIT_DA, bits); + } else { + clear_bit(LCD_BIT_DA, bits); + } + panel_set_bits(); udelay(2); /* maintain the data during 2 us before CLK up */ - bits.cl = BIT_SET; /* CLK high */ + set_bit(LCD_BIT_CL, bits); /* CLK high */ panel_set_bits(); udelay(1); /* maintain the strobe during 1 us */ byte >>= 1; @@ -811,7 +801,10 @@ static void lcd_backlight(int on) /* The backlight is activated by setting the AUTOFEED line to +5V */ spin_lock_irq(&pprt_lock); - bits.bl = on; + if (on) + set_bit(LCD_BIT_BL, bits); + else + clear_bit(LCD_BIT_BL, bits); panel_set_bits(); spin_unlock_irq(&pprt_lock); } @@ -846,14 +839,14 @@ static void lcd_write_cmd_p8(int cmd) w_dtr(pprt, cmd); udelay(20); /* maintain the data during 20 us before the strobe */ - bits.e = BIT_SET; - bits.rs = BIT_CLR; - bits.rw = BIT_CLR; + set_bit(LCD_BIT_E, bits); + clear_bit(LCD_BIT_RS, bits); + clear_bit(LCD_BIT_RW, bits); set_ctrl_bits(); udelay(40); /* maintain the strobe during 40 us */ - bits.e = BIT_CLR; + clear_bit(LCD_BIT_E, bits); set_ctrl_bits(); udelay(120); /* the shortest command takes at least 120 us */ @@ -868,14 +861,14 @@ static void lcd_write_data_p8(int data) w_dtr(pprt, data); udelay(20); /* maintain the data during 20 us before the strobe */ - bits.e = BIT_SET; - bits.rs = BIT_SET; - bits.rw = BIT_CLR; + set_bit(LCD_BIT_E, bits); + set_bit(LCD_BIT_RS, bits); + clear_bit(LCD_BIT_RW, bits); set_ctrl_bits(); udelay(40); /* maintain the strobe during 40 us */ - bits.e = BIT_CLR; + clear_bit(LCD_BIT_E, bits); set_ctrl_bits(); udelay(45); /* the shortest data takes at least 45 us */ @@ -968,15 +961,15 @@ static void lcd_clear_fast_p8(void) /* maintain the data during 20 us before the strobe */ udelay(20); - bits.e = BIT_SET; - bits.rs = BIT_SET; - bits.rw = BIT_CLR; + 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); - bits.e = BIT_CLR; + clear_bit(LCD_BIT_E, bits); set_ctrl_bits(); /* the shortest data takes at least 45 us */