blob: 7d8880c1856c79cd51d912338791bc0df6fa07ad [file] [log] [blame]
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080015 */
16
17#ifndef __PRE_RAM__
18
19#include <console/console.h>
20#include <device/device.h>
21#include <device/pnp.h>
22#include <stdlib.h>
23#include <arch/io.h>
24#include <delay.h>
Edward O'Callaghane1fe6882014-04-30 20:41:41 +100025#include <pc80/keyboard.h>
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080026#include "ec.h"
27#include "chip.h"
28
29/* kbc helper functions from drivers/pc80/keyboard.c. TODO: share functions. */
30static int kbc_input_buffer_empty(void)
31{
32 u32 timeout;
Elyes HAOUAS2b010b82016-08-25 20:57:08 +020033 for (timeout = KBC_TIMEOUT_IN_MS; timeout && (inb(KBD_STATUS) & KBD_IBF);
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080034 timeout--) {
35 mdelay(1);
36 }
37
38 if (!timeout) {
39 printk(BIOS_WARNING,
40 "Unexpected Keyboard controller input buffer full\n");
41 }
42 return !!timeout;
43}
44
45
46static int kbc_output_buffer_full(void)
47{
48 u32 timeout;
Elyes HAOUAS2b010b82016-08-25 20:57:08 +020049 for (timeout = KBC_TIMEOUT_IN_MS; timeout && ((inb(KBD_STATUS)
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080050 & KBD_OBF) == 0); timeout--) {
51 mdelay(1);
52 }
53
54 if (!timeout) {
55 printk(BIOS_INFO, "Keyboard controller output buffer result timeout\n");
56 }
57 return !!timeout;
58}
59
60int kbc_cleanup_buffers(void)
61{
62 u32 timeout;
Elyes HAOUAS2b010b82016-08-25 20:57:08 +020063 for (timeout = KBC_TIMEOUT_IN_MS; timeout && (inb(KBD_STATUS)
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080064 & (KBD_OBF | KBD_IBF)); timeout--) {
65 mdelay(1);
66 inb(KBD_DATA);
67 }
68
69 if (!timeout) {
70 printk(BIOS_ERR, "Couldn't cleanup the keyboard controller buffers\n");
71 printk(BIOS_ERR, "Status (0x%x): 0x%x, Buffer (0x%x): 0x%x\n",
72 KBD_STATUS, inb(KBD_STATUS), KBD_DATA, inb(KBD_DATA));
73 }
74
75 return !!timeout;
76}
77
78
Martin Roth8940d3e2013-07-09 21:52:41 -060079/* The ENE 60/64 EC registers are the same command/status IB/OB KBC pair.
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080080 * Check status from 64 port before each command.
81 *
82 * Ex. Get panel ID command C43/D77
83 * Check IBF empty. Then Write 0x43(CMD) to 0x64 Port
84 * Check IBF empty. Then Write 0x77(DATA) to 0x60 Port
85 * Check OBF set. Then Get Data(0x03:panel ID) from 0x60
Martin Roth8940d3e2013-07-09 21:52:41 -060086 * Different commands return may or may not respond and may have multiple
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -080087 * bytes. Keep it simple for nor
88 */
89
90u8 ec_kbc_read_ob(void)
91{
92 if (!kbc_output_buffer_full()) return 0;
93 return inb(KBD_DATA);
94}
95
96void ec_kbc_write_cmd(u8 cmd)
97{
98 if (!kbc_input_buffer_empty()) return;
99 outb(cmd, KBD_COMMAND);
100}
101
102void ec_kbc_write_ib(u8 data)
103{
104 if (!kbc_input_buffer_empty()) return;
105 outb(data, KBD_DATA);
106}
107
108
109/*
110 * These functions are for accessing the ENE932 device space, but are not
111 * currently used.
112 */
113/*
114static u8 ec_io_read(u16 addr)
115{
116 outb(addr >> 8, EC_IO_HIGH);
117 outb(addr & 0xff, EC_IO_LOW);
118 return inb(EC_IO_DATA);
119}
120*/
121/*static void ec_write(u16 addr, u8 data)
122{
123 outb(addr >> 8, EC_IO_HIGH);
124 outb(addr & 0xff, EC_IO_LOW;
125 outb(data, EC_IO_DATA);
126}
127*/
128
129#ifndef __SMM__
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100130static void ene932_init(struct device *dev)
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800131{
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800132 if (!dev->enabled)
133 return;
134
135 printk(BIOS_DEBUG, "Compal ENE932: Initializing keyboard.\n");
Timothy Pearson448e3862015-11-24 14:12:01 -0600136 pc_keyboard_init(NO_AUX_DEVICE);
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800137
138}
139
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800140static struct device_operations ops = {
141 .init = ene932_init,
Edward O'Callaghan5f19eb62014-11-29 00:03:03 +1100142 .read_resources = DEVICE_NOOP,
143 .enable_resources = DEVICE_NOOP,
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800144};
145
146static struct pnp_info pnp_dev_info[] = {
Felix Helddd770a82018-07-07 00:03:47 +0200147 { NULL, 0, 0, 0, }
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800148};
149
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100150static void enable_dev(struct device *dev)
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800151{
Felix Helddd770a82018-07-07 00:03:47 +0200152 pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
Stefan Reinauerd8a5fd22012-12-11 15:51:47 -0800153}
154
155struct chip_operations ec_compal_ene932_ops = {
156 CHIP_NAME("COMPAL ENE932 EC")
157 .enable_dev = enable_dev
158};
159#endif /* ! __SMM__ */
160#endif /* ! __PRE_RAM__ */