Skip to contentSkip to conversation

x86: i8042: Correctly initialize the controller

PATCH New Bin Meng 2 participants 10 messages Aug 17, 2015 – Aug 18, 2015 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Bin Meng

author
#1 lore raw

PATCH 2/5 x86: i8042: Correctly initialize the controller

The existing i8042 keyboard controller driver has some issues. First of all, it does not issue a self-test command (0xaa) to the controller at the very beginning. Without this, the controller does not respond any command at all. Secondly, it initializes the configuration byte reigster to turn on keyboard's interrupt, which is not allowed as U-Boot we don't normally enable interrupt. Finally, at the end of the initialization routine, it wrongly sets the controller to disable all interfaces including both keyboard and mouse.

---

 drivers/input/i8042.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)
drivers/input/i8042.c +13 -9
index 1769c5e..3799580 100644
@@ -664,6 +664,18 @@ static int wait_until_kbd_output_full(void)
 
 static int kbd_reset(void)
 {
+	/* controller self test */
+	if (kbd_input_empty() == 0)
+		return -1;
+
+	out8(I8042_COMMAND_REG, 0xaa);
+
+	if (wait_until_kbd_output_full() == 0)
+		return -1;
+
+	if (in8(I8042_DATA_REG) != 0x55) /* success */
+		return -1;
+
 	/* KB Reset */
 	if (kbd_input_empty() == 0)
 		return -1;
@@ -691,7 +703,7 @@ static int kbd_reset(void)
 	if (kbd_input_empty() == 0)
 		return -1;
 
-	out8(I8042_DATA_REG, 0x45);
+	out8(I8042_DATA_REG, 0x44);
 
 	if (kbd_input_empty() == 0)
 		return -1;
@@ -701,13 +713,5 @@ static int kbd_reset(void)
 	if (kbd_input_empty() == 0)
 		return -1;
 
-	out8(I8042_COMMAND_REG, 0x60);
-	if (kbd_input_empty() == 0)
-		return -1;
-
-	out8(I8042_DATA_REG, 0xf4);
-	if (kbd_input_empty() == 0)
-		return -1;
-
 	return 0;
 }
Signature · 1 line
1.8.2.1
#2 lore raw

PATCH 2/5 x86: i8042: Correctly initialize the controller

Quoted 10 lines · Bin Meng

The existing i8042 keyboard controller driver has some issues. First of all, it does not issue a self-test command (0xaa) to the controller at the very beginning. Without this, the controller does not respond any command at all. Secondly, it initializes the configuration byte reigster to turn on keyboard's interrupt, which is not allowed as U-Boot we don't normally enable interrupt. Finally, at the end of the initialization routine, it wrongly sets the controller to disable all interfaces including both keyboard and mouse.

Quoted 5 lines

---

 drivers/input/i8042.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)
author
#3 lore raw

PATCH 3/5 x86: i8042: Clean up the driver

In reply to a message not in the archive

This commit cleans up the existing i8042 driver by:
- Reorder those static function so that their declarations can be removed
- Remove unused routines i8042_flush() and i8042_disable()
- Remove unused CONFIG_USE_CPCIDVI wrapped codes
- Remove __weak board_i8042_skip()
- Rename CamelCase variables to conform U-Boot coding convention
- Rename wait_until_kbd_output_full() to kbd_output_full()
- Change to use macros for i8042 command and control register bits

---

 drivers/input/i8042.c | 633 +++++++++++++++++++++-----------------------------
 include/i8042.h       | 112 +++++----
 2 files changed, 317 insertions(+), 428 deletions(-)
drivers/input/i8042.c +262 -371
index 3799580..3812733 100644
@@ -10,49 +10,30 @@
 /* includes */
 
 #include <common.h>
-#include <linux/compiler.h>
-
-#ifdef CONFIG_USE_CPCIDVI
-extern u8 gt_cpcidvi_in8(u32 offset);
-extern void gt_cpcidvi_out8(u32 offset, u8 data);
-
-#define in8(a)	   gt_cpcidvi_in8(a)
-#define out8(a, b) gt_cpcidvi_out8(a, b)
-#endif
-
+#include <asm/io.h>
 #include <i8042.h>
 
 /* defines */
+#define in8(p)		inb(p)
+#define out8(p, v)	outb(v, p)
 
 #ifdef CONFIG_CONSOLE_CURSOR
 extern void console_cursor(int state);
-static int blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
+static int blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
 static int cursor_state;
 #endif
 
 /* locals */
 
-static int  kbd_input	 = -1;		/* no input yet */
-static int  kbd_mapping	 = KBD_US;	/* default US keyboard */
-static int  kbd_flags	 = NORMAL;	/* after reset */
-static int  kbd_state;			/* unshift code */
-
-static void kbd_conv_char(unsigned char scan_code);
-static void kbd_led_set(void);
-static void kbd_normal(unsigned char scan_code);
-static void kbd_shift(unsigned char scan_code);
-static void kbd_ctrl(unsigned char scan_code);
-static void kbd_num(unsigned char scan_code);
-static void kbd_caps(unsigned char scan_code);
-static void kbd_scroll(unsigned char scan_code);
-static void kbd_alt(unsigned char scan_code);
-static int  kbd_input_empty(void);
-static int  kbd_reset(void);
+static int kbd_input = -1;		/* no input yet */
+static int kbd_mapping = KBD_US;	/* default US keyboard */
+static int kbd_flags = NORMAL;		/* after reset */
+static int kbd_state;			/* unshift code */
 
 static unsigned char kbd_fct_map[144] = {
 	/* kbd_fct_map table for scan code */
-	 0,  AS,  AS,  AS,  AS,  AS,  AS,  AS, /* scan  0- 7 */
-	AS,  AS,  AS,  AS,  AS,  AS,  AS,  AS, /* scan  8- F */
+	 0,  AS,  AS,  AS,  AS,  AS,  AS,  AS, /* scan 00-07 */
+	AS,  AS,  AS,  AS,  AS,  AS,  AS,  AS, /* scan 08-0F */
 	AS,  AS,  AS,  AS,  AS,  AS,  AS,  AS, /* scan 10-17 */
 	AS,  AS,  AS,  AS,  AS,  CN,  AS,  AS, /* scan 18-1F */
 	AS,  AS,  AS,  AS,  AS,  AS,  AS,  AS, /* scan 20-27 */
@@ -74,8 +55,8 @@ static unsigned char kbd_fct_map[144] = {
 static unsigned char kbd_key_map[2][5][144] = {
 	{ /* US keyboard */
 	{ /* unshift code */
-	   0, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan  0- 7 */
-	 '7',  '8',  '9',  '0',  '-',  '=', 0x08, '\t', /* scan  8- F */
+	   0, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan 00-07 */
+	 '7',  '8',  '9',  '0',  '-',  '=', 0x08, '\t', /* scan 08-0F */
 	 'q',  'w',  'e',  'r',  't',  'y',  'u',  'i', /* scan 10-17 */
 	 'o',  'p',  '[',  ']', '\r',   CN,  'a',  's', /* scan 18-1F */
 	 'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';', /* scan 20-27 */
@@ -94,8 +75,8 @@ static unsigned char kbd_key_map[2][5][144] = {
 	   0,  'D',  'C',    0,  'B',    0,  '@',  'P'  /* extended */
 	},
 	{ /* shift code */
-	   0, 0x1b,  '!',  '@',  '#',  '$',  '%',  '^', /* scan  0- 7 */
-	 '&',  '*',  '(',  ')',  '_',  '+', 0x08, '\t', /* scan  8- F */
+	   0, 0x1b,  '!',  '@',  '#',  '$',  '%',  '^', /* scan 00-07 */
+	 '&',  '*',  '(',  ')',  '_',  '+', 0x08, '\t', /* scan 08-0F */
 	 'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I', /* scan 10-17 */
 	 'O',  'P',  '{',  '}', '\r',   CN,  'A',  'S', /* scan 18-1F */
 	 'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':', /* scan 20-27 */
@@ -114,8 +95,8 @@ static unsigned char kbd_key_map[2][5][144] = {
 	   0,  'D',  'C',    0,  'B',    0,  '@',  'P'  /* extended */
 	},
 	{ /* control code */
-	0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan  0- 7 */
-	0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan  8- F */
+	0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
+	0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 08-0F */
 	0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */
 	0x0f, 0x10, 0x1b, 0x1d, '\r',   CN, 0x01, 0x13, /* scan 18-1F */
 	0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */
@@ -134,8 +115,8 @@ static unsigned char kbd_key_map[2][5][144] = {
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff  /* extended */
 	},
 	{ /* non numeric code */
-	   0, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan  0- 7 */
-	 '7',  '8',  '9',  '0',  '-',  '=', 0x08, '\t', /* scan  8- F */
+	   0, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan 00-07 */
+	 '7',  '8',  '9',  '0',  '-',  '=', 0x08, '\t', /* scan 08-0F */
 	 'q',  'w',  'e',  'r',  't',  'y',  'u',  'i', /* scan 10-17 */
 	 'o',  'p',  '[',  ']', '\r',   CN,  'a',  's', /* scan 18-1F */
 	 'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';', /* scan 20-27 */
@@ -154,30 +135,30 @@ static unsigned char kbd_key_map[2][5][144] = {
 	   0,  'D',  'C',    0,  'B',    0,  '@',  'P'  /* extended */
 	},
 	{ /* right alt mode - not used in US keyboard */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan  0 - 7 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 8 - F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50 -57 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 08-0F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10-17 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18-1F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20-27 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28-2F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30-37 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40-47 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff  /* extended */
 	}
 	},
-	{ /* german keyboard */
+	{ /* German keyboard */
 	{ /* unshift code */
-	   0, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan  0- 7 */
-	 '7',  '8',  '9',  '0', 0xe1, '\'', 0x08, '\t', /* scan  8- F */
+	   0, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan 00-07 */
+	 '7',  '8',  '9',  '0', 0xe1, '\'', 0x08, '\t', /* scan 08-0F */
 	 'q',  'w',  'e',  'r',  't',  'z',  'u',  'i', /* scan 10-17 */
 	 'o',  'p', 0x81,  '+', '\r',   CN,  'a',  's', /* scan 18-1F */
 	 'd',  'f',  'g',  'h',  'j',  'k',  'l', 0x94, /* scan 20-27 */
@@ -196,8 +177,8 @@ static unsigned char kbd_key_map[2][5][144] = {
 	   0,  'D',  'C',    0,  'B',    0,  '@',  'P'  /* extended */
 	},
 	{ /* shift code */
-	   0, 0x1b,  '!',  '"', 0x15,  '$',  '%',  '&', /* scan  0- 7 */
-	 '/',  '(',  ')',  '=',  '?',  '`', 0x08, '\t', /* scan  8- F */
+	   0, 0x1b,  '!',  '"', 0x15,  '$',  '%',  '&', /* scan 00-07 */
+	 '/',  '(',  ')',  '=',  '?',  '`', 0x08, '\t', /* scan 08-0F */
 	 'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I', /* scan 10-17 */
 	 'O',  'P', 0x9a,  '*', '\r',   CN,  'A',  'S', /* scan 18-1F */
 	 'D',  'F',  'G',  'H',  'J',  'K',  'L', 0x99, /* scan 20-27 */
@@ -216,8 +197,8 @@ static unsigned char kbd_key_map[2][5][144] = {
 	   0,  'D',  'C',    0,  'B',    0,  '@',  'P'  /* extended */
 	},
 	{ /* control code */
-	0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan  0- 7 */
-	0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan  8- F */
+	0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
+	0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 08-0F */
 	0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */
 	0x0f, 0x10, 0x1b, 0x1d, '\r',   CN, 0x01, 0x13, /* scan 18-1F */
 	0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */
@@ -236,8 +217,8 @@ static unsigned char kbd_key_map[2][5][144] = {
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff  /* extended */
 	},
 	{ /* non numeric code */
-	   0, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan  0- 7 */
-	 '7',  '8',  '9',  '0', 0xe1, '\'', 0x08, '\t', /* scan  8- F */
+	   0, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan 00-07 */
+	 '7',  '8',  '9',  '0', 0xe1, '\'', 0x08, '\t', /* scan 08-0F */
 	 'q',  'w',  'e',  'r',  't',  'z',  'u',  'i', /* scan 10-17 */
 	 'o',  'p', 0x81,  '+', '\r',   CN,  'a',  's', /* scan 18-1F */
 	 'd',  'f',  'g',  'h',  'j',  'k',  'l', 0x94, /* scan 20-27 */
@@ -255,23 +236,23 @@ static unsigned char kbd_key_map[2][5][144] = {
 	'\r',   CN,  '/',  '*',  ' ',   ST,  'F',  'A', /* extended */
 	   0,  'D',  'C',    0,  'B',    0,  '@',  'P'  /* extended */
 	},
-	{ /* Right alt mode - is used in German keyboard */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan  0 - 7 */
-	 '{',  '[',  ']',  '}', '\\', 0xff, 0xff, 0xff, /* scan  8 - F */
-	 '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */
-	0xff, 0xff, 0xff,  '~', 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */
-	0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  '|', 0xff, /* scan 50 -57 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */
+	{ /* right alt mode - is used in German keyboard */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
+	 '{',  '[',  ']',  '}', '\\', 0xff, 0xff, 0xff, /* scan 08-0F */
+	 '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10-17 */
+	0xff, 0xff, 0xff,  '~', 0xff, 0xff, 0xff, 0xff, /* scan 18-1F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20-27 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28-2F */
+	0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30-37 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40-47 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  '|', 0xff, /* scan 50-57 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff  /* extended */
 	}
@@ -298,167 +279,113 @@ static unsigned char ext_key_map[] = {
 	0x00  /* map end */
 	};
 
-/******************************************************************************/
-
-static int kbd_controller_present(void)
-{
-	return in8(I8042_STATUS_REG) != 0xff;
-}
-
-/*
- * Implement a weak default function for boards that optionally
- * need to skip the i8042 initialization.
- */
-int __weak board_i8042_skip(void)
+static int kbd_input_empty(void)
 {
-	/* As default, don't skip */
-	return 0;
-}
+	int kbd_timeout = KBD_TIMEOUT * 1000;
 
-void i8042_flush(void)
-{
-	int timeout;
-
-	/*
-	 * The delay is to give the keyboard controller some time to fill the
-	 * next byte.
-	 */
-	while (1) {
-		timeout = 100;  /* wait for no longer than 100us */
-		while (timeout > 0 && !(in8(I8042_STATUS_REG) & 0x01)) {
-			udelay(1);
-			timeout--;
-		}
+	while ((in8(I8042_STS_REG) & STATUS_IBF) && kbd_timeout--)
+		udelay(1);
 
-		/* Try to pull next byte if not timeout. */
-		if (in8(I8042_STATUS_REG) & 0x01)
-			in8(I8042_DATA_REG);
-		else
-			break;
-	}
+	return kbd_timeout != -1;
 }
 
-int i8042_disable(void)
+static int kbd_output_full(void)
 {
-	if (kbd_input_empty() == 0)
-		return -1;
-
-	/* Disable keyboard */
-	out8(I8042_COMMAND_REG, 0xad);
+	int kbd_timeout = KBD_TIMEOUT * 1000;
 
-	if (kbd_input_empty() == 0)
-		return -1;
+	while (((in8(I8042_STS_REG) & STATUS_OBF) == 0) && kbd_timeout--)
+		udelay(1);
 
-	return 0;
+	return kbd_timeout != -1;
 }
 
-
-/*******************************************************************************
- *
- * i8042_kbd_init - reset keyboard and init state flags
- */
-int i8042_kbd_init(void)
+static void kbd_led_set(void)
 {
-	int keymap, try;
-	char *penv;
+	kbd_input_empty();
+	out8(I8042_DATA_REG, CMD_SET_KBD_LED);
+	kbd_input_empty();
+	out8(I8042_DATA_REG, (kbd_flags & 0x7));
+}
 
-	if (!kbd_controller_present() || board_i8042_skip())
-		return -1;
+static void kbd_normal(unsigned char scan_code)
+{
+	unsigned char chr;
 
-#ifdef CONFIG_USE_CPCIDVI
-	penv = getenv("console");
-	if (penv != NULL) {
-		if (strncmp(penv, "serial", 7) == 0)
-			return -1;
-	}
-#endif
-	/* Init keyboard device (default US layout) */
-	keymap = KBD_US;
-	penv = getenv("keymap");
-	if (penv != NULL) {
-		if (strncmp(penv, "de", 3) == 0)
-			keymap = KBD_GER;
-	}
+	if ((kbd_flags & BRK) == NORMAL) {
+		chr = kbd_key_map[kbd_mapping][kbd_state][scan_code];
+		if ((chr == 0xff) || (chr == 0x00))
+			return;
 
-	for (try = 0; try < KBD_RESET_TRIES; try++) {
-		if (kbd_reset() == 0) {
-			kbd_mapping = keymap;
-			kbd_flags   = NORMAL;
-			kbd_state   = 0;
-			kbd_led_set();
-			return 0;
+		/* if caps lock convert upper to lower */
+		if (((kbd_flags & CAPS) == CAPS) &&
+		    (chr >= 'a' && chr <= 'z')) {
+			chr -= 'a' - 'A';
 		}
+		kbd_input = chr;
 	}
-	return -1;
 }
 
-
-/*******************************************************************************
- *
- * i8042_tstc - test if keyboard input is available
- *		option: cursor blinking if called in a loop
- */
-int i8042_tstc(struct stdio_dev *dev)
+static void kbd_shift(unsigned char scan_code)
 {
-	unsigned char scan_code = 0;
-
-#ifdef CONFIG_CONSOLE_CURSOR
-	if (--blinkCount == 0) {
-		cursor_state ^= 1;
-		console_cursor(cursor_state);
-		blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
-		udelay(10);
+	if ((kbd_flags & BRK) == BRK) {
+		kbd_state = AS;
+		kbd_flags &= (~SHIFT);
+	} else {
+		kbd_state = SH;
+		kbd_flags |= SHIFT;
 	}
-#endif
+}
 
-	if ((in8(I8042_STATUS_REG) & 0x01) == 0) {
-		return 0;
+static void kbd_ctrl(unsigned char scan_code)
+{
+	if ((kbd_flags & BRK) == BRK) {
+		kbd_state = AS;
+		kbd_flags &= (~CTRL);
 	} else {
-		scan_code = in8(I8042_DATA_REG);
-		if (scan_code == 0xfa)
-			return 0;
-
-		kbd_conv_char(scan_code);
-
-		if (kbd_input != -1)
-			return 1;
+		kbd_state = CN;
+		kbd_flags |= CTRL;
 	}
-	return 0;
 }
 
-
-/*******************************************************************************
- *
- * i8042_getc - wait till keyboard input is available
- *		option: turn on/off cursor while waiting
- */
-int i8042_getc(struct stdio_dev *dev)
+static void kbd_num(unsigned char scan_code)
 {
-	int ret_chr;
-	unsigned char scan_code;
+	if ((kbd_flags & BRK) == NORMAL) {
+		kbd_flags ^= NUM;
+		kbd_state = (kbd_flags & NUM) ? AS : NM;
+		kbd_led_set();
+	}
+}
 
-	while (kbd_input == -1) {
-		while ((in8(I8042_STATUS_REG) & 0x01) == 0) {
-#ifdef CONFIG_CONSOLE_CURSOR
-			if (--blinkCount == 0) {
-				cursor_state ^= 1;
-				console_cursor(cursor_state);
-				blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
-			}
-			udelay(10);
-#endif
-		}
-		scan_code = in8(I8042_DATA_REG);
-		if (scan_code != 0xfa)
-			kbd_conv_char (scan_code);
+static void kbd_alt(unsigned char scan_code)
+{
+	if ((kbd_flags & BRK) == BRK) {
+		kbd_state = AS;
+		kbd_flags &= (~ALT);
+	} else {
+		kbd_state = AK;
+		kbd_flags &= ALT;
 	}
-	ret_chr = kbd_input;
-	kbd_input = -1;
-	return ret_chr;
 }
 
+static void kbd_caps(unsigned char scan_code)
+{
+	if ((kbd_flags & BRK) == NORMAL) {
+		kbd_flags ^= CAPS;
+		kbd_led_set();
+	}
+}
 
-/******************************************************************************/
+static void kbd_scroll(unsigned char scan_code)
+{
+	if ((kbd_flags & BRK) == NORMAL) {
+		kbd_flags ^= STP;
+		kbd_led_set();
+		if (kbd_flags & STP)
+			kbd_input = 0x13;
+		else
+			kbd_input = 0x11;
+	}
+}
 
 static void kbd_conv_char(unsigned char scan_code)
 {
@@ -475,8 +402,8 @@ static void kbd_conv_char(unsigned char scan_code)
 
 	if ((scan_code == 0xe1) || (kbd_flags & E1)) {
 		if (scan_code == 0xe1) {
-			kbd_flags ^= BRK;    /* reset the break flag */
-			kbd_flags ^= E1;     /* bitwise EXOR with E1 flag */
+			kbd_flags ^= BRK;	/* reset the break flag */
+			kbd_flags ^= E1;	/* bitwise EXOR with E1 flag */
 		}
 		return;
 	}
@@ -511,207 +438,171 @@ static void kbd_conv_char(unsigned char scan_code)
 	case NM:
 		kbd_num(scan_code);
 		break;
+	case AK:
+		kbd_alt(scan_code);
+		break;
 	case CP:
 		kbd_caps(scan_code);
 		break;
 	case ST:
 		kbd_scroll(scan_code);
 		break;
-	case AK:
-		kbd_alt(scan_code);
-		break;
 	}
+
 	return;
 }
 
-
-/******************************************************************************/
-
-static void kbd_normal(unsigned char scan_code)
+static int kbd_reset(void)
 {
-	unsigned char chr;
+	u8 config;
 
-	if ((kbd_flags & BRK) == NORMAL) {
-		chr = kbd_key_map[kbd_mapping][kbd_state][scan_code];
-		if ((chr == 0xff) || (chr == 0x00))
-			return;
+	/* controller self test */
+	if (kbd_input_empty() == 0)
+		return -1;
+	out8(I8042_CMD_REG, CMD_SELF_TEST);
+	if (kbd_output_full() == 0)
+		return -1;
+	if (in8(I8042_DATA_REG) != KBC_TEST_OK)
+		return -1;
 
-		/* if caps lock convert upper to lower */
-		if (((kbd_flags & CAPS) == CAPS) &&
-				(chr >= 'a' && chr <= 'z')) {
-			chr -= 'a' - 'A';
-		}
-		kbd_input = chr;
-	}
-}
+	/* keyboard reset */
+	if (kbd_input_empty() == 0)
+		return -1;
+	out8(I8042_DATA_REG, CMD_RESET_KBD);
+	if (kbd_output_full() == 0)
+		return -1;
+	if (in8(I8042_DATA_REG) != KBD_ACK)
+		return -1;
+	if (kbd_output_full() == 0)
+		return -1;
+	if (in8(I8042_DATA_REG) != KBD_POR)
+		return -1;
 
+	/* set AT translation and disable irq */
+	if (kbd_input_empty() == 0)
+		return -1;
+	out8(I8042_CMD_REG, CMD_RD_CONFIG);
+	if (kbd_output_full() == 0)
+		return -1;
+	config = in8(I8042_DATA_REG);
+	config |= CONFIG_AT_TRANS;
+	config &= ~(CONFIG_KIRQ_EN | CONFIG_MIRQ_EN);
+	if (kbd_input_empty() == 0)
+		return -1;
+	out8(I8042_CMD_REG, CMD_WR_CONFIG);
+	if (kbd_input_empty() == 0)
+		return -1;
+	out8(I8042_DATA_REG, config);
 
-/******************************************************************************/
+	/* enable keyboard */
+	if (kbd_input_empty() == 0)
+		return -1;
+	out8(I8042_CMD_REG, CMD_KBD_EN);
+	if (kbd_input_empty() == 0)
+		return -1;
 
-static void kbd_shift(unsigned char scan_code)
-{
-	if ((kbd_flags & BRK) == BRK) {
-		kbd_state = AS;
-		kbd_flags &= (~SHIFT);
-	} else {
-		kbd_state = SH;
-		kbd_flags |= SHIFT;
-	}
+	return 0;
 }
 
-
-/******************************************************************************/
-
-static void kbd_ctrl(unsigned char scan_code)
+static int kbd_controller_present(void)
 {
-	if ((kbd_flags & BRK) == BRK) {
-		kbd_state = AS;
-		kbd_flags &= (~CTRL);
-	} else {
-		kbd_state = CN;
-		kbd_flags |= CTRL;
-	}
+	return in8(I8042_STS_REG) != 0xff;
 }
 
-
-/******************************************************************************/
-
-static void kbd_caps(unsigned char scan_code)
+/* i8042_kbd_init - reset keyboard and init state flags */
+int i8042_kbd_init(void)
 {
-	if ((kbd_flags & BRK) == NORMAL) {
-		kbd_flags ^= CAPS;
-		kbd_led_set();    /* update keyboard LED */
-	}
-}
-
-
-/******************************************************************************/
+	int keymap, try;
+	char *penv;
 
-static void kbd_num(unsigned char scan_code)
-{
-	if ((kbd_flags & BRK) == NORMAL) {
-		kbd_flags ^= NUM;
-		kbd_state = (kbd_flags & NUM) ? AS : NM;
-		kbd_led_set();    /* update keyboard LED */
+	if (!kbd_controller_present()) {
+		debug("i8042 keyboard controller is not present\n");
+		return -1;
 	}
-}
-
-
-/******************************************************************************/
 
-static void kbd_scroll(unsigned char scan_code)
-{
-	if ((kbd_flags & BRK) == NORMAL) {
-		kbd_flags ^= STP;
-		kbd_led_set();    /* update keyboard LED */
-		if (kbd_flags & STP)
-			kbd_input = 0x13;
-		else
-			kbd_input = 0x11;
+	/* Init keyboard device (default US layout) */
+	keymap = KBD_US;
+	penv = getenv("keymap");
+	if (penv != NULL) {
+		if (strncmp(penv, "de", 3) == 0)
+			keymap = KBD_GER;
 	}
-}
 
-/******************************************************************************/
+	for (try = 0; try < KBD_RESET_TRIES; try++) {
+		if (kbd_reset() == 0) {
+			kbd_mapping = keymap;
+			kbd_flags   = NORMAL;
+			kbd_state   = 0;
+			kbd_led_set();
 
-static void kbd_alt(unsigned char scan_code)
-{
-	if ((kbd_flags & BRK) == BRK) {
-		kbd_state = AS;
-		kbd_flags &= (~ALT);
-	} else {
-		kbd_state = AK;
-		kbd_flags &= ALT;
+			return 0;
+		}
 	}
-}
 
-
-/******************************************************************************/
-
-static void kbd_led_set(void)
-{
-	kbd_input_empty();
-	out8(I8042_DATA_REG, 0xed);    /* SET LED command */
-	kbd_input_empty();
-	out8(I8042_DATA_REG, (kbd_flags & 0x7));    /* LED bits only */
+	return -1;
 }
 
-
-/******************************************************************************/
-
-static int kbd_input_empty(void)
+/*
+ * i8042_tstc - test if keyboard input is available
+ *
+ * option: cursor blinking if called in a loop
+ */
+int i8042_tstc(struct stdio_dev *dev)
 {
-	int kbdTimeout = KBD_TIMEOUT * 1000;
-
-	while ((in8(I8042_STATUS_REG) & I8042_STATUS_IN_DATA) && kbdTimeout--)
-		udelay(1);
+	unsigned char scan_code = 0;
 
-	return kbdTimeout != -1;
-}
+#ifdef CONFIG_CONSOLE_CURSOR
+	if (--blink_count == 0) {
+		cursor_state ^= 1;
+		console_cursor(cursor_state);
+		blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
+		udelay(10);
+	}
+#endif
 
-/******************************************************************************/
+	if ((in8(I8042_STS_REG) & STATUS_OBF) == 0) {
+		return 0;
+	} else {
+		scan_code = in8(I8042_DATA_REG);
+		if (scan_code == 0xfa)
+			return 0;
 
-static int wait_until_kbd_output_full(void)
-{
-	int kbdTimeout = KBD_TIMEOUT * 1000;
+		kbd_conv_char(scan_code);
 
-	while (((in8(I8042_STATUS_REG) & 0x01) == 0) && kbdTimeout--)
-		udelay(1);
+		if (kbd_input != -1)
+			return 1;
+	}
 
-	return kbdTimeout != -1;
+	return 0;
 }
 
-/******************************************************************************/
-
-static int kbd_reset(void)
+/*
+ * i8042_getc - wait till keyboard input is available
+ *
+ * option: turn on/off cursor while waiting
+ */
+int i8042_getc(struct stdio_dev *dev)
 {
-	/* controller self test */
-	if (kbd_input_empty() == 0)
-		return -1;
-
-	out8(I8042_COMMAND_REG, 0xaa);
-
-	if (wait_until_kbd_output_full() == 0)
-		return -1;
-
-	if (in8(I8042_DATA_REG) != 0x55) /* success */
-		return -1;
-
-	/* KB Reset */
-	if (kbd_input_empty() == 0)
-		return -1;
-
-	out8(I8042_DATA_REG, 0xff);
-
-	if (wait_until_kbd_output_full() == 0)
-		return -1;
-
-	if (in8(I8042_DATA_REG) != 0xfa) /* ACK */
-		return -1;
-
-	if (wait_until_kbd_output_full() == 0)
-		return -1;
-
-	if (in8(I8042_DATA_REG) != 0xaa) /* Test Pass*/
-		return -1;
-
-	if (kbd_input_empty() == 0)
-		return -1;
-
-	/* Set KBC mode */
-	out8(I8042_COMMAND_REG, 0x60);
-
-	if (kbd_input_empty() == 0)
-		return -1;
-
-	out8(I8042_DATA_REG, 0x44);
-
-	if (kbd_input_empty() == 0)
-		return -1;
+	int ret_chr;
+	unsigned char scan_code;
 
-	/* Enable Keyboard */
-	out8(I8042_COMMAND_REG, 0xae);
-	if (kbd_input_empty() == 0)
-		return -1;
+	while (kbd_input == -1) {
+		while ((in8(I8042_STS_REG) & STATUS_OBF) == 0) {
+#ifdef CONFIG_CONSOLE_CURSOR
+			if (--blink_count == 0) {
+				cursor_state ^= 1;
+				console_cursor(cursor_state);
+				blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
+			}
+			udelay(10);
+#endif
+		}
+		scan_code = in8(I8042_DATA_REG);
+		if (scan_code != 0xfa)
+			kbd_conv_char(scan_code);
+	}
+	ret_chr = kbd_input;
+	kbd_input = -1;
 
-	return 0;
+	return ret_chr;
 }
include/i8042.h +55 -57

123 lines not on this page · raw message

Signature · 1 line
1.8.2.1
#4 lore raw

PATCH 3/5 x86: i8042: Clean up the driver

Quoted 9 lines · Bin Meng

This commit cleans up the existing i8042 driver by:
- Reorder those static function so that their declarations can be removed
- Remove unused routines i8042_flush() and i8042_disable()
- Remove unused CONFIG_USE_CPCIDVI wrapped codes
- Remove __weak board_i8042_skip()
- Rename CamelCase variables to conform U-Boot coding convention
- Rename wait_until_kbd_output_full() to kbd_output_full()
- Change to use macros for i8042 command and control register bits

Quoted 6 lines

---

 drivers/input/i8042.c | 633 +++++++++++++++++++++-----------------------------
 include/i8042.h       | 112 +++++----
 2 files changed, 317 insertions(+), 428 deletions(-)

It would be better to split this into a few patches (e.g. one to remove stuff, one to reorder, one for everything else) but this is a big improvement.

author
#5 lore raw

PATCH 3/5 x86: i8042: Clean up the driver

Hi Simon,

Quoted 13 lines · Simon Glass
Quoted 12 lines · Bin Meng

This commit cleans up the existing i8042 driver by:
- Reorder those static function so that their declarations can be removed
- Remove unused routines i8042_flush() and i8042_disable()
- Remove unused CONFIG_USE_CPCIDVI wrapped codes
- Remove __weak board_i8042_skip()
- Rename CamelCase variables to conform U-Boot coding convention
- Rename wait_until_kbd_output_full() to kbd_output_full()
- Change to use macros for i8042 command and control register bits

---

Quoted 7 lines
Quoted 3 lines
 drivers/input/i8042.c | 633 +++++++++++++++++++++-----------------------------
 include/i8042.h       | 112 +++++----
 2 files changed, 317 insertions(+), 428 deletions(-)

It would be better to split this into a few patches (e.g. one to remove stuff, one to reorder, one for everything else) but this is a big improvement.

Ah, I see. This single patch is hard to review as it is totally different from the original. I will see if I can do a v2 to split this.

Quoted 2 lines

Regards,
Bin

author
#6 lore raw

PATCH 4/5 video: cfb_console: Allow VGA device to work without i8042 keyboard

In reply to a message not in the archive

So far if CONFIG_VGA_AS_SINGLE_DEVICE is not defined, the VGA device will try to initialize a keyboard device (for x86, it is i8042). But if i8042 controller initialization fails (eg: there is no keyboard connected to the PS/2 port), drv_video_init() just simply returns. This kills the opportunity of using a usb keyboard later with the vga concole, as the vga initialization part is actually ok, only keyboard part fails. Change the code logic to allow this.

---
In the long term, we should remove CONFIG_VGA_AS_SINGLE_DEVICE and treat the cfb_concole an output device only. The keyboard part should be moved out of cfb_console driver and be as a input device driver separately.

 drivers/video/cfb_console.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/video/cfb_console.c +5 -6
index 30e0317..aa7ca86 100644
@@ -2247,16 +2247,17 @@ __weak int board_video_skip(void)
 
 int drv_video_init(void)
 {
-	int skip_dev_init;
 	struct stdio_dev console_dev;
 	bool have_keyboard;
+	bool __maybe_unused keyboard_ok = false;
 
 	/* Check if video initialization should be skipped */
 	if (board_video_skip())
 		return 0;
 
 	/* Init video chip - returns with framebuffer cleared */
-	skip_dev_init = (video_init() == -1);
+	if (video_init() == -1)
+		return 0;
 
 	if (board_cfb_skip())
 		return 0;
@@ -2272,11 +2273,9 @@ int drv_video_init(void)
 	if (have_keyboard) {
 		debug("KBD: Keyboard init ...\n");
 #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
-		skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
+		keyboard_ok = !(VIDEO_KBD_INIT_FCT == -1);
 #endif
 	}
-	if (skip_dev_init)
-		return 0;
 
 	/* Init vga device */
 	memset(&console_dev, 0, sizeof(console_dev));
@@ -2287,7 +2286,7 @@ int drv_video_init(void)
 	console_dev.puts = video_puts;	/* 'puts' function */
 
 #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
-	if (have_keyboard) {
+	if (have_keyboard && keyboard_ok) {
 		/* Also init console device */
 		console_dev.flags |= DEV_FLAGS_INPUT;
 		console_dev.tstc = VIDEO_TSTC_FCT;	/* 'tstc' function */
Signature · 1 line
1.8.2.1
#7 lore raw

PATCH 4/5 video: cfb_console: Allow VGA device to work without i8042 keyboard

+Anatolij

Hi Bin,

Quoted 6 lines · Bin Meng

So far if CONFIG_VGA_AS_SINGLE_DEVICE is not defined, the VGA device will try to initialize a keyboard device (for x86, it is i8042). But if i8042 controller initialization fails (eg: there is no keyboard connected to the PS/2 port), drv_video_init() just simply returns. This kills the opportunity of using a usb keyboard later with the vga concole, as the vga initialization part is actually ok, only keyboard

console

Quoted 1 line

part fails. Change the code logic to allow this.

This is a change in behaviour. It seems OK to me though. In fact this problem annoyed me quite recently.

Quoted 8 lines

---
In the long term, we should remove CONFIG_VGA_AS_SINGLE_DEVICE and treat the cfb_concole an output device only. The keyboard part should be moved out of cfb_console driver and be as a input device driver separately.

Agreed. Actually we should implement driver model for vga/lcd and input.

Quoted 3 lines
 drivers/video/cfb_console.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
Quoted 48 lines
drivers/video/cfb_console.c +5 -7
index 30e0317..aa7ca86 100644
@@ -2247,16 +2247,17 @@ __weak int board_video_skip(void)
 
 int drv_video_init(void)
 {
-       int skip_dev_init;
        struct stdio_dev console_dev;
        bool have_keyboard;
+       bool __maybe_unused keyboard_ok = false;
 
        /* Check if video initialization should be skipped */
        if (board_video_skip())
                return 0;
 
        /* Init video chip - returns with framebuffer cleared */
-       skip_dev_init = (video_init() == -1);
+       if (video_init() == -1)
+               return 0;
 
        if (board_cfb_skip())
                return 0;
@@ -2272,11 +2273,9 @@ int drv_video_init(void)
        if (have_keyboard) {
                debug("KBD: Keyboard init ...\n");
 #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
-               skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
+               keyboard_ok = !(VIDEO_KBD_INIT_FCT == -1);
 #endif
        }
-       if (skip_dev_init)
-               return 0;
 
        /* Init vga device */
        memset(&console_dev, 0, sizeof(console_dev));
@@ -2287,7 +2286,7 @@ int drv_video_init(void)
        console_dev.puts = video_puts;  /* 'puts' function */
 
 #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
-       if (have_keyboard) {
+       if (have_keyboard && keyboard_ok) {
                /* Also init console device */
                console_dev.flags |= DEV_FLAGS_INPUT;
                console_dev.tstc = VIDEO_TSTC_FCT;      /* 'tstc' function */
--
Quoted 2 lines

1.8.2.1

Regards,
Simon

author
#8 lore raw

PATCH 4/5 video: cfb_console: Allow VGA device to work without i8042 keyboard

Quoted 5 lines · Simon Glass

+Anatolij

Hi Bin,

On 17 August 2015 at 04:45, Bin Meng <[email protected]> wrote:

Quoted 8 lines
Quoted 6 lines

So far if CONFIG_VGA_AS_SINGLE_DEVICE is not defined, the VGA device will try to initialize a keyboard device (for x86, it is i8042). But if i8042 controller initialization fails (eg: there is no keyboard connected to the PS/2 port), drv_video_init() just simply returns. This kills the opportunity of using a usb keyboard later with the vga concole, as the vga initialization part is actually ok, only keyboard

console

Will fix in v2.

Quoted 9 lines
Quoted 2 lines

part fails. Change the code logic to allow this.

This is a change in behaviour. It seems OK to me though. In fact this problem annoyed me quite recently.

Quoted 3 lines
Quoted 7 lines
Quoted 5 lines

---
In the long term, we should remove CONFIG_VGA_AS_SINGLE_DEVICE and treat the cfb_concole an output device only. The keyboard part should be moved out of cfb_console driver and be as a input device driver separately.

Agreed. Actually we should implement driver model for vga/lcd and input.

Yes, I was planning to do. But that's a lot work so I decided not to change it in this series.

Quoted 48 lines
Quoted 4 lines

 drivers/video/cfb_console.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
Quoted 41 lines
drivers/video/cfb_console.c +4 -5
index 30e0317..aa7ca86 100644
@@ -2247,16 +2247,17 @@ __weak int board_video_skip(void)
 
 int drv_video_init(void)
 {
-       int skip_dev_init;
        struct stdio_dev console_dev;
        bool have_keyboard;
+       bool __maybe_unused keyboard_ok = false;
 
        /* Check if video initialization should be skipped */
        if (board_video_skip())
                return 0;
 
        /* Init video chip - returns with framebuffer cleared */
-       skip_dev_init = (video_init() == -1);
+       if (video_init() == -1)
+               return 0;
 
        if (board_cfb_skip())
                return 0;
@@ -2272,11 +2273,9 @@ int drv_video_init(void)
        if (have_keyboard) {
                debug("KBD: Keyboard init ...\n");
 #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
-               skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
+               keyboard_ok = !(VIDEO_KBD_INIT_FCT == -1);
 #endif
        }
-       if (skip_dev_init)
-               return 0;
 
        /* Init vga device */
        memset(&console_dev, 0, sizeof(console_dev));
@@ -2287,7 +2286,7 @@ int drv_video_init(void)
        console_dev.puts = video_puts;  /* 'puts' function */
 
Quoted 7 lines

drivers/video/cfb_console.c int drv_video_init(void)

Quoted 7 lines
drivers/video/cfb_console.c +1 -2
 #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
-       if (have_keyboard) {
+       if (have_keyboard && keyboard_ok) {
                /* Also init console device */
                console_dev.flags |= DEV_FLAGS_INPUT;
                console_dev.tstc = VIDEO_TSTC_FCT;      /* 'tstc' function */
--

Regards,
Bin

author
#9 lore raw

PATCH 5/5 x86: crownbay: Enable on-board SMSC superio keyboard controller

In reply to a message not in the archive

So far we only enabled one legacy serial port on the SMSC LPC47m superio chipset on Intel Crown Bay board. As the board also has dual PS/2 ports routed out, enable the keyboard controller which is i8042 compatible so that we can use PS/2 keyboard and mouse.

In order to make PS/2 keyboard work with the VGA console, remove CONFIG_VGA_AS_SINGLE_DEVICE. To boot Linux kernel with PIC mode using PIRQ routing table, adjust the mask in the device tree to reserve irq12 which is used by PS/2 mouse.

---

 arch/x86/dts/crownbay.dts       | 2 +-
 board/intel/crownbay/crownbay.c | 7 ++++---
 include/configs/crownbay.h      | 3 ---
 3 files changed, 5 insertions(+), 7 deletions(-)
arch/x86/dts/crownbay.dts +1 -1
index 841f47e..6eb55d9 100644
@@ -168,7 +168,7 @@
 			compatible = "intel,irq-router";
 			intel,pirq-config = "pci";
 			intel,pirq-link = <0x60 8>;
-			intel,pirq-mask = <0xdee0>;
+			intel,pirq-mask = <0xcee0>;
 			intel,pirq-routing = <
 				/* TunnelCreek PCI devices */
 				PCI_BDF(0, 2, 0) INTA PIRQE
board/intel/crownbay/crownbay.c +4 -3
index ad2d5b6..d6de9fa 100644
@@ -10,11 +10,12 @@
 #include <netdev.h>
 #include <smsc_lpc47m.h>
 
-#define SERIAL_DEV PNP_DEV(0x2e, 4)
-
 int board_early_init_f(void)
 {
-	lpc47m_enable_serial(SERIAL_DEV, UART0_BASE, UART0_IRQ);
+	lpc47m_enable_serial(PNP_DEV(LPC47M_IO_PORT, LPC47M_SP1),
+			     UART0_BASE, UART0_IRQ);
+	lpc47m_enable_kbc(PNP_DEV(LPC47M_IO_PORT, LPC47M_KBC),
+			  KBD_IRQ, MSE_IRQ);
 
 	return 0;
 }
include/configs/crownbay.h +0 -3
index e87bd54..32b6006 100644
@@ -54,9 +54,6 @@
 #define CONFIG_PCH_GBE
 #define CONFIG_PHYLIB
 
-/* TunnelCreek IGD support */
-#define CONFIG_VGA_AS_SINGLE_DEVICE
-
 /* Environment configuration */
 #define CONFIG_ENV_SECT_SIZE		0x1000
 #define CONFIG_ENV_OFFSET		0
Signature · 1 line
1.8.2.1
#10 lore raw

PATCH 5/5 x86: crownbay: Enable on-board SMSC superio keyboard controller

Quoted 10 lines · Bin Meng

So far we only enabled one legacy serial port on the SMSC LPC47m superio chipset on Intel Crown Bay board. As the board also has dual PS/2 ports routed out, enable the keyboard controller which is i8042 compatible so that we can use PS/2 keyboard and mouse.

In order to make PS/2 keyboard work with the VGA console, remove CONFIG_VGA_AS_SINGLE_DEVICE. To boot Linux kernel with PIC mode using PIRQ routing table, adjust the mask in the device tree to reserve irq12 which is used by PS/2 mouse.

Quoted 8 lines

---

 arch/x86/dts/crownbay.dts       | 2 +-
 board/intel/crownbay/crownbay.c | 7 ++++---
 include/configs/crownbay.h      | 3 ---
 3 files changed, 5 insertions(+), 7 deletions(-)