coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ec.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/io.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <delay.h>
7 
8 #include "ec.h"
9 #include "chip.h"
10 
13 
14 #define KBD_IBF (1 << 1) /* 1: input buffer full (data ready for ec) */
15 #define KBD_OBF (1 << 0) /* 1: output buffer full (data ready for host) */
16 
17 static void ec_setports(u16 data, u16 cmd)
18 {
19  ec_data_port = data;
20  ec_cmd_port = cmd;
21 }
22 
23 static int send_kbd_command(u8 command)
24 {
25  int timeout;
26 
27  timeout = 100000; /* 1 second */
28  while ((inb(ec_cmd_port) & KBD_IBF) && --timeout) {
29  udelay(10);
30  if ((timeout & 0xff) == 0)
31  printk(BIOS_SPEW, ".");
32  }
33  if (!timeout) {
34  printk(BIOS_DEBUG, "Timeout while sending command 0x%02x to EC!\n",
35  command);
36  return -1;
37  }
38 
39  outb(command, ec_cmd_port);
40  return 0;
41 }
42 
43 static int send_kbd_data(u8 data)
44 {
45  int timeout;
46 
47  timeout = 100000; /* 1 second */
48  while ((inb(ec_cmd_port) & KBD_IBF) && --timeout) { /* wait for IBF = 0 */
49  udelay(10);
50  if ((timeout & 0xff) == 0)
51  printk(BIOS_SPEW, ".");
52  }
53  if (!timeout) {
54  printk(BIOS_DEBUG, "Timeout while sending data 0x%02x to EC!\n",
55  data);
56  return -1;
57  }
58 
59  outb(data, ec_data_port);
60  return 0;
61 }
62 
63 /*
64  * kbc1126_thermalinit: initialize fan control
65  * The code is found in EcThermalInit of the vendor firmware.
66  */
67 static int kbc1126_thermalinit(u8 cmd, u8 value)
68 {
69  printk(BIOS_DEBUG, "KBC1126: initialize fan control.");
70 
71  if (send_kbd_command(cmd) < 0)
72  return -1;
73 
74  if (send_kbd_data(0x27) < 0)
75  return -1;
76 
77  if (send_kbd_data(0x01) < 0)
78  return -1;
79 
80  /*
81  * The following code is needed for fan control when AC is plugged in.
82  */
83 
84  if (send_kbd_command(cmd) < 0)
85  return -1;
86 
87  if (send_kbd_data(0xd5) < 0)
88  return -1;
89 
90  if (send_kbd_data(value) < 0)
91  return -1;
92 
93  printk(BIOS_DEBUG, "KBC1126: fan control initialized.\n");
94  return 0;
95 }
96 
97 /*
98  * kbc1126_kbdled: set CapsLock and NumLock LEDs
99  * This is used in MemoryErrorReport of the vendor firmware.
100  */
101 static void kbc1126_kbdled(u8 cmd, u8 val)
102 {
103  if (send_kbd_command(cmd) < 0)
104  return;
105 
106  if (send_kbd_data(0xf0) < 0)
107  return;
108 
109  if (send_kbd_data(val) < 0)
110  return;
111 }
112 
113 static void kbc1126_enable(struct device *dev)
114 {
115  struct ec_hp_kbc1126_config *conf = dev->chip_info;
116  ec_setports(conf->ec_data_port, conf->ec_cmd_port);
117  kbc1126_kbdled(conf->ec_ctrl_reg, 0);
118  if (kbc1126_thermalinit(conf->ec_ctrl_reg, conf->ec_fan_ctrl_value) < 0)
119  printk(BIOS_DEBUG, "KBC1126: error when initializing fan control.\n");
120 }
121 
123  CHIP_NAME("SMSC KBC1126 for HP laptops")
124  .enable_dev = kbc1126_enable
125 };
pte_t value
Definition: mmu.c:91
#define printk(level,...)
Definition: stdlib.h:16
u8 inb(u16 port)
void outb(u8 val, u16 port)
static int kbc1126_thermalinit(u8 cmd, u8 value)
Definition: ec.c:67
static int send_kbd_command(u8 command)
Definition: ec.c:23
static u16 ec_data_port
Definition: ec.c:11
static u16 ec_cmd_port
Definition: ec.c:12
static void kbc1126_enable(struct device *dev)
Definition: ec.c:113
#define KBD_IBF
Definition: ec.c:14
static void kbc1126_kbdled(u8 cmd, u8 val)
Definition: ec.c:101
static void ec_setports(u16 data, u16 cmd)
Definition: ec.c:17
static int send_kbd_data(u8 data)
Definition: ec.c:43
struct chip_operations ec_hp_kbc1126_ops
Definition: ec.c:122
#define CHIP_NAME(X)
Definition: device.h:32
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
Definition: device.h:107
DEVTREE_CONST void * chip_info
Definition: device.h:164
u16 ec_data_port
Definition: chip.h:8
u8 ec_fan_ctrl_value
Definition: chip.h:11
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15