coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
superio.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <console/console.h>
4 #include <device/pnp.h>
5 #include <device/device.h>
6 #include <superio/conf_mode.h>
7 
8 #include "nct5104d.h"
9 #include "chip.h"
10 
11 static void set_irq_trigger_type(struct device *dev, bool trig_level)
12 {
13  u8 reg10, reg11, reg26;
14 
15  //Before accessing CR10 OR CR11 Bit 4 in CR26 must be set to 1
16  reg26 = pnp_read_config(dev, GLOBAL_OPTION_CR26);
17  reg26 |= CR26_LOCK_REG;
19 
20  switch (dev->path.pnp.device) {
21  //SP1 (UARTA) IRQ type selection (1:level,0:edge) is controlled by CR 10, bit 5
22  case NCT5104D_SP1:
23  reg10 = pnp_read_config(dev, IRQ_TYPE_SEL_CR10);
24  if (trig_level)
25  reg10 |= (1 << 5);
26  else
27  reg10 &= ~(1 << 5);
29  break;
30  //SP2 (UARTB) IRQ type selection (1:level,0:edge) is controlled by CR 10, bit 4
31  case NCT5104D_SP2:
32  reg10 = pnp_read_config(dev, IRQ_TYPE_SEL_CR10);
33  if (trig_level)
34  reg10 |= (1 << 4);
35  else
36  reg10 &= ~(1 << 4);
38  break;
39  //SP3 (UARTC) IRQ type selection (1:level,0:edge) is controlled by CR 11, bit 5
40  case NCT5104D_SP3:
42  if (trig_level)
43  reg11 |= (1 << 5);
44  else
45  reg11 &= ~(1 << 5);
47  break;
48  //SP4 (UARTD) IRQ type selection (1:level,0:edge) is controlled by CR 11, bit 4
49  case NCT5104D_SP4:
51  if (trig_level)
52  reg11 |= (1 << 4);
53  else
54  reg11 &= ~(1 << 4);
56  break;
57  default:
58  break;
59  }
60 
61  //Clear access control register
62  reg26 = pnp_read_config(dev, GLOBAL_OPTION_CR26);
63  reg26 &= ~CR26_LOCK_REG;
65 }
66 
67 static void route_pins_to_uart(struct device *dev, bool to_uart)
68 {
69  u8 reg;
70 
71  reg = pnp_read_config(dev, 0x1c);
72 
73  switch (dev->path.pnp.device) {
74  case NCT5104D_SP3:
75  case NCT5104D_GPIO0:
76  /* Route pins 33 - 40. */
77  if (to_uart)
78  reg |= (1 << 3);
79  else
80  reg &= ~(1 << 3);
81  break;
82  case NCT5104D_SP4:
83  case NCT5104D_GPIO1:
84  /* Route pins 41 - 48. */
85  if (to_uart)
86  reg |= (1 << 2);
87  else
88  reg &= ~(1 << 2);
89  break;
90  default:
91  break;
92  }
93 
94  pnp_write_config(dev, 0x1c, reg);
95 }
96 
97 static void reset_gpio_default_in(struct device *dev)
98 {
100  /*
101  * Soft reset GPIOs to default state: IN.
102  * The main GPIO LDN holds registers that configure the pins as output
103  * or input. These registers are located at offset 0xE0 plus the GPIO
104  * bank number multiplied by 4: 0xE0 for GPIO0, 0xE4 for GPIO1 and
105  * 0xF8 for GPIO6.
106  */
107  pnp_write_config(dev, NCT5104D_GPIO0_IO + (dev->path.pnp.device >> 8) * 4, 0xFF);
108 }
109 
110 static void reset_gpio_default_od(struct device *dev)
111 {
112  struct device *gpio0, *gpio1, *gpio6;
113 
115 
119 
120  /*
121  * Soft reset GPIOs to default state: Open-drain.
122  * The NCT5104D_GPIO_PP_OD LDN holds registers (1 for each GPIO bank)
123  * that configure each GPIO pin to be open dain or push pull. System
124  * reset is known to not reset the values in this register. The
125  * registers are located at offsets begginign from 0xE0 plus GPIO bank
126  * number, i.e. 0xE0 for GPIO0, 0xE1 for GPIO1 and 0xE6 for GPIO6.
127  */
128  if (gpio0 && gpio0->enabled)
129  pnp_write_config(dev,
130  (gpio0->path.pnp.device >> 8) + NCT5104D_GPIO0_PP_OD, 0xFF);
131 
132  if (gpio1 && gpio1->enabled)
133  pnp_write_config(dev,
134  (gpio1->path.pnp.device >> 8) + NCT5104D_GPIO0_PP_OD, 0xFF);
135 
136  if (gpio6 && gpio6->enabled)
137  pnp_write_config(dev,
138  (gpio6->path.pnp.device >> 8) + NCT5104D_GPIO0_PP_OD, 0xFF);
139 }
140 
141 static void disable_gpio_io_port(struct device *dev)
142 {
143  struct device *gpio0, *gpio1, *gpio6;
144 
145  /*
146  * Since UARTC and UARTD share pins with GPIO0 and GPIO1 and the
147  * GPIO/UART can be selected via Kconfig, check whether at least one of
148  * GPIOs is enabled and if yes keep the GPIO IO VLDN enabled. If no
149  * GPIOs are enabled, disable the VLDN in order to protect from invalid
150  * devicetree + Kconfig settings.
151  */
155 
156  if (!((gpio0 && gpio0->enabled) || (gpio1 && gpio1->enabled) ||
157  (gpio6 && gpio6->enabled))) {
158  dev->enabled = 0;
159  printk(BIOS_WARNING, "GPIO IO port configured,"
160  " but no GPIO enabled. Disabling...");
161  }
162 }
163 
164 static void nct5104d_init(struct device *dev)
165 {
166  struct superio_nuvoton_nct5104d_config *conf = dev->chip_info;
167 
168  if (!dev->enabled)
169  return;
170 
171  pnp_enter_conf_mode(dev);
172 
173  switch (dev->path.pnp.device) {
174  case NCT5104D_SP1:
175  case NCT5104D_SP2:
176  set_irq_trigger_type(dev, conf->irq_trigger_type != 0);
177  break;
178  case NCT5104D_SP3:
179  case NCT5104D_SP4:
180  route_pins_to_uart(dev, true);
181  set_irq_trigger_type(dev, conf->irq_trigger_type != 0);
182  break;
183  case NCT5104D_GPIO0:
184  case NCT5104D_GPIO1:
185  route_pins_to_uart(dev, false);
187  case NCT5104D_GPIO6:
188  if (conf->reset_gpios)
190  break;
191  case NCT5104D_GPIO_PP_OD:
192  if (conf->reset_gpios)
194  break;
195  case NCT5104D_GPIO_IO:
197  break;
198  default:
199  break;
200  }
201 
202  pnp_exit_conf_mode(dev);
203 }
204 
205 static struct device_operations ops = {
207  .set_resources = pnp_set_resources,
208  .enable_resources = pnp_enable_resources,
209  .enable = pnp_alt_enable,
210  .init = nct5104d_init,
211  .ops_pnp_mode = &pnp_conf_mode_8787_aa,
212 };
213 
214 static struct pnp_info pnp_dev_info[] = {
215  { NULL, NCT5104D_FDC, PNP_IO0 | PNP_IRQ0, 0x07f8, },
216  { NULL, NCT5104D_SP1, PNP_IO0 | PNP_IRQ0, 0x07f8, },
217  { NULL, NCT5104D_SP2, PNP_IO0 | PNP_IRQ0, 0x07f8, },
218  { NULL, NCT5104D_SP3, PNP_IO0 | PNP_IRQ0, 0x07f8, },
219  { NULL, NCT5104D_SP4, PNP_IO0 | PNP_IRQ0, 0x07f8, },
221  { NULL, NCT5104D_GPIO0},
222  { NULL, NCT5104D_GPIO1},
223  { NULL, NCT5104D_GPIO6},
225  { NULL, NCT5104D_GPIO_IO, PNP_IO0, 0x07f8, },
226  { NULL, NCT5104D_PORT80},
227 };
228 
229 static void enable_dev(struct device *dev)
230 {
232 }
233 
235  CHIP_NAME("Nuvoton NCT5104D Super I/O")
236  .enable_dev = enable_dev,
237 };
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define printk(level,...)
Definition: stdlib.h:16
#define __fallthrough
Definition: compiler.h:39
const struct pnp_mode_ops pnp_conf_mode_8787_aa
Definition: conf_mode.c:202
DEVTREE_CONST struct device * dev_find_slot_pnp(u16 port, u16 device)
Given a PnP port and a device number, find the device structure.
Definition: device_const.c:331
#define CHIP_NAME(X)
Definition: device.h:32
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
#define NCT5104D_GPIO0_PP_OD
Definition: nct5104d.h:20
#define NCT5104D_GPIO_WDT
Definition: nct5104d.h:44
#define NCT5104D_FDC
Definition: nct5104d.h:25
#define NCT5104D_SP1
Definition: nct5104d.h:26
#define NCT5104D_PORT80
Definition: nct5104d.h:31
#define CR26_LOCK_REG
Definition: nct5104d.h:12
#define NCT5104D_SP3
Definition: nct5104d.h:29
#define NCT5104D_GPIO_PP_OD
Definition: nct5104d.h:28
#define NCT5104D_GPIO0_IO
Definition: nct5104d.h:15
#define NCT5104D_GPIO0
Definition: nct5104d.h:40
#define NCT5104D_SP4
Definition: nct5104d.h:30
#define NCT5104D_GPIO_IO
Definition: nct5104d.h:45
#define GLOBAL_OPTION_CR26
Definition: nct5104d.h:11
#define NCT5104D_GPIO1
Definition: nct5104d.h:41
#define IRQ_TYPE_SEL_CR10
Definition: nct5104d.h:9
#define NCT5104D_SP2
Definition: nct5104d.h:27
#define IRQ_TYPE_SEL_CR11
Definition: nct5104d.h:10
#define NCT5104D_GPIO6
Definition: nct5104d.h:42
static void reset_gpio_default_in(struct device *dev)
Definition: superio.c:97
static void enable_dev(struct device *dev)
Definition: superio.c:229
static void disable_gpio_io_port(struct device *dev)
Definition: superio.c:141
static struct device_operations ops
Definition: superio.c:205
static struct pnp_info pnp_dev_info[]
Definition: superio.c:214
static void set_irq_trigger_type(struct device *dev, bool trig_level)
Definition: superio.c:11
static void route_pins_to_uart(struct device *dev, bool to_uart)
Definition: superio.c:67
static void nct5104d_init(struct device *dev)
Definition: superio.c:164
static void reset_gpio_default_od(struct device *dev)
Definition: superio.c:110
struct chip_operations superio_nuvoton_nct5104d_ops
Definition: superio.c:234
#define PNP_IO0
Definition: pnp.h:42
#define PNP_IRQ0
Definition: pnp.h:47
void pnp_exit_conf_mode(struct device *dev)
Definition: pnp_device.c:17
void pnp_read_resources(struct device *dev)
Definition: pnp_device.c:114
void pnp_enable_devices(struct device *base_dev, struct device_operations *ops, unsigned int functions, struct pnp_info *info)
Definition: pnp_device.c:371
void pnp_set_logical_device(struct device *dev)
Definition: pnp_device.c:59
void pnp_set_resources(struct device *dev)
Definition: pnp_device.c:157
void pnp_alt_enable(struct device *dev)
Definition: pnp_device.c:191
u8 pnp_read_config(struct device *dev, u8 reg)
Definition: pnp_device.c:44
void pnp_enter_conf_mode(struct device *dev)
Definition: pnp_device.c:11
void pnp_write_config(struct device *dev, u8 reg, u8 value)
Definition: pnp_device.c:38
void pnp_enable_resources(struct device *dev)
Definition: pnp_device.c:173
#define NULL
Definition: stddef.h:19
uint8_t u8
Definition: stdint.h:45
void(* read_resources)(struct device *dev)
Definition: device.h:39
struct pnp_path pnp
Definition: path.h:117
Definition: device.h:107
struct device_path path
Definition: device.h:115
DEVTREE_CONST void * chip_info
Definition: device.h:164
unsigned int enabled
Definition: device.h:122
Definition: pnp.h:37
unsigned int port
Definition: path.h:58
unsigned int device
Definition: path.h:59