From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Glass Date: Wed, 11 Nov 2015 10:05:46 -0700 Subject: [U-Boot] [PATCH v3 10/12] i8042: Handle a duplicate power-on-reset response In-Reply-To: <1447261548-14304-1-git-send-email-sjg@chromium.org> References: <1447261548-14304-1-git-send-email-sjg@chromium.org> Message-ID: <1447261548-14304-11-git-send-email-sjg@chromium.org> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Sometimes we seem to get 0xaa twice which causes the config read to fail. This causes chromebook_link to fail to set up the keyboard. Add a check for this and read the config again when detected. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v3: - Fix 'QUICK' typo Changes in v2: - Use device tree to handle this quirk drivers/input/i8042.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c index e5e2926..661d7fd 100644 --- a/drivers/input/i8042.c +++ b/drivers/input/i8042.c @@ -15,13 +15,20 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + /* defines */ #define in8(p) inb(p) #define out8(p, v) outb(v, p) +enum { + QUIRK_DUP_POR = 1 << 0, +}; + /* locals */ struct i8042_kbd_priv { bool extended; /* true if an extended keycode is expected next */ + int quirks; /* quirks that we support */ }; static unsigned char ext_key_map[] = { @@ -113,7 +120,7 @@ static int kbd_cmd_write(int cmd, int data) return kbd_write(I8042_DATA_REG, data); } -static int kbd_reset(void) +static int kbd_reset(int quirk) { int config; @@ -132,6 +139,10 @@ static int kbd_reset(void) if (config == -1) goto err; + /* Sometimes get a second byte */ + else if ((quirk & QUIRK_DUP_POR) && config == KBD_POR) + config = kbd_cmd_read(CMD_RD_CONFIG); + config |= CONFIG_AT_TRANS; config &= ~(CONFIG_KIRQ_EN | CONFIG_MIRQ_EN); if (kbd_cmd_write(CMD_WR_CONFIG, config)) @@ -246,6 +257,7 @@ static int i8042_kbd_check(struct input_config *input) static int i8042_start(struct udevice *dev) { struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); + struct i8042_kbd_priv *priv = dev_get_priv(dev); struct input_config *input = &uc_priv->input; int keymap, try; char *penv; @@ -264,7 +276,7 @@ static int i8042_start(struct udevice *dev) keymap = KBD_GER; } - for (try = 0; kbd_reset() != 0; try++) { + for (try = 0; kbd_reset(priv->quirks) != 0; try++) { if (try >= KBD_RESET_TRIES) return -1; } @@ -294,10 +306,15 @@ static int i8042_start(struct udevice *dev) static int i8042_kbd_probe(struct udevice *dev) { struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); + struct i8042_kbd_priv *priv = dev_get_priv(dev); struct stdio_dev *sdev = &uc_priv->sdev; struct input_config *input = &uc_priv->input; int ret; + if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, + "intel,duplicate-por")) + priv->quirks |= QUIRK_DUP_POR; + /* Register the device. i8042_start() will be called soon */ input->dev = dev; input->read_keys = i8042_kbd_check; -- 2.6.0.rc2.230.g3dd15c0