blob: 8eebfa8c3aa47ea68c0bddd95c0d1307c24ad2f8 [file] [log] [blame]
Angel Pons210a0082020-04-02 23:48:24 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -08003
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -08004#include <console/console.h>
5#include <device/device.h>
6#include <device/pnp.h>
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -08007#include <arch/io.h>
8#include <delay.h>
Edward O'Callaghane1fe6882014-04-30 20:41:41 +10009#include <pc80/keyboard.h>
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080010#include "ec.h"
11#include "chip.h"
12
13/* kbc helper functions from drivers/pc80/keyboard.c. TODO: share functions. */
14static int kbc_input_buffer_empty(void)
15{
16 u32 timeout;
Elyes HAOUAS2b010b82016-08-25 20:57:08 +020017 for (timeout = KBC_TIMEOUT_IN_MS; timeout && (inb(KBD_STATUS) & KBD_IBF);
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080018 timeout--) {
19 mdelay(1);
20 }
21
22 if (!timeout) {
23 printk(BIOS_WARNING,
24 "Unexpected Keyboard controller input buffer full\n");
25 }
26 return !!timeout;
27}
28
29
30static int kbc_output_buffer_full(void)
31{
32 u32 timeout;
Elyes HAOUAS2b010b82016-08-25 20:57:08 +020033 for (timeout = KBC_TIMEOUT_IN_MS; timeout && ((inb(KBD_STATUS)
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080034 & KBD_OBF) == 0); timeout--) {
35 mdelay(1);
36 }
37
38 if (!timeout) {
39 printk(BIOS_INFO, "Keyboard controller output buffer result timeout\n");
40 }
41 return !!timeout;
42}
43
44int kbc_cleanup_buffers(void)
45{
46 u32 timeout;
Elyes HAOUAS2b010b82016-08-25 20:57:08 +020047 for (timeout = KBC_TIMEOUT_IN_MS; timeout && (inb(KBD_STATUS)
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080048 & (KBD_OBF | KBD_IBF)); timeout--) {
49 mdelay(1);
50 inb(KBD_DATA);
51 }
52
53 if (!timeout) {
54 printk(BIOS_ERR, "Couldn't cleanup the keyboard controller buffers\n");
55 printk(BIOS_ERR, "Status (0x%x): 0x%x, Buffer (0x%x): 0x%x\n",
56 KBD_STATUS, inb(KBD_STATUS), KBD_DATA, inb(KBD_DATA));
57 }
58
59 return !!timeout;
60}
61
62
Martin Roth8940d3e2013-07-09 21:52:41 -060063/* The ENE 60/64 EC registers are the same command/status IB/OB KBC pair.
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080064 * Check status from 64 port before each command.
65 *
66 * Ex. Get panel ID command C43/D77
67 * Check IBF empty. Then Write 0x43(CMD) to 0x64 Port
68 * Check IBF empty. Then Write 0x77(DATA) to 0x60 Port
69 * Check OBF set. Then Get Data(0x03:panel ID) from 0x60
Martin Roth8940d3e2013-07-09 21:52:41 -060070 * Different commands return may or may not respond and may have multiple
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080071 * bytes. Keep it simple for nor
72 */
73
74u8 ec_kbc_read_ob(void)
75{
76 if (!kbc_output_buffer_full()) return 0;
77 return inb(KBD_DATA);
78}
79
80void ec_kbc_write_cmd(u8 cmd)
81{
82 if (!kbc_input_buffer_empty()) return;
83 outb(cmd, KBD_COMMAND);
84}
85
86void ec_kbc_write_ib(u8 data)
87{
88 if (!kbc_input_buffer_empty()) return;
89 outb(data, KBD_DATA);
90}
91
92
93/*
94 * These functions are for accessing the ENE932 device space, but are not
95 * currently used.
96 */
97/*
98static u8 ec_io_read(u16 addr)
99{
100 outb(addr >> 8, EC_IO_HIGH);
101 outb(addr & 0xff, EC_IO_LOW);
102 return inb(EC_IO_DATA);
103}
104*/
105/*static void ec_write(u16 addr, u8 data)
106{
107 outb(addr >> 8, EC_IO_HIGH);
108 outb(addr & 0xff, EC_IO_LOW;
109 outb(data, EC_IO_DATA);
110}
111*/
112
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100113static void ene932_init(struct device *dev)
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800114{
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800115 if (!dev->enabled)
116 return;
117
118 printk(BIOS_DEBUG, "Compal ENE932: Initializing keyboard.\n");
Timothy Pearson448e3862015-11-24 14:12:01 -0600119 pc_keyboard_init(NO_AUX_DEVICE);
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800120
121}
122
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800123static struct device_operations ops = {
124 .init = ene932_init,
Edward O'Callaghan5f19eb62014-11-29 00:03:03 +1100125 .read_resources = DEVICE_NOOP,
126 .enable_resources = DEVICE_NOOP,
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800127};
128
129static struct pnp_info pnp_dev_info[] = {
Felix Helddd770a82018-07-07 00:03:47 +0200130 { NULL, 0, 0, 0, }
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800131};
132
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100133static void enable_dev(struct device *dev)
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800134{
Felix Helddd770a82018-07-07 00:03:47 +0200135 pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800136}
137
138struct chip_operations ec_compal_ene932_ops = {
139 CHIP_NAME("COMPAL ENE932 EC")
140 .enable_dev = enable_dev
141};