cbfs: Remove remnants of ext-win-*
[coreboot2.git] / src / superio / smsc / lpc47n227 / early_serial.c
blob21a54c889d05d38ee06728684388a97f6c6e281d
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /* Pre-RAM driver for SMSC LPC47N227 Super I/O chip. */
5 #include <arch/io.h>
6 #include <assert.h>
7 #include <device/pnp_ops.h>
9 #include "lpc47n227.h"
11 void pnp_enter_conf_state(pnp_devfn_t dev)
13 u16 port = dev >> 8;
14 outb(0x55, port);
17 void pnp_exit_conf_state(pnp_devfn_t dev)
19 u16 port = dev >> 8;
20 outb(0xaa, port);
23 /**
24 * Program the base I/O port for the specified logical device.
26 * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
27 * @param iobase Base I/O port for the logical device.
29 static void lpc47n227_pnp_set_iobase(pnp_devfn_t dev, u16 iobase)
31 /* LPC47N227 requires base ports to be a multiple of 4. */
32 /* it's not very useful to do an ASSERT here: if it trips,
33 * there's no console to report it.
34 ASSERT(!(iobase & 0x3));
37 switch (dev & 0xFF) {
38 case LPC47N227_PP:
39 pnp_write_config(dev, 0x23, (iobase >> 2) & 0xff);
40 break;
41 case LPC47N227_SP1:
42 pnp_write_config(dev, 0x24, (iobase >> 2) & 0xff);
43 break;
44 case LPC47N227_SP2:
45 pnp_write_config(dev, 0x25, (iobase >> 2) & 0xff);
46 break;
47 default:
48 break;
52 /**
53 * Enable or disable the specified logical device.
55 * Technically, a full disable requires setting the device's base I/O port
56 * below 0x100. We don't do that here, because we don't have access to a data
57 * structure that specifies what the 'real' base port is (when asked to enable
58 * the device). Also the function is used only to disable the device while its
59 * true base port is programmed (see lpc47n227_enable_serial() below).
61 * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
62 * @param enable 0 to disable, anything else to enable.
64 static void lpc47n227_pnp_set_enable(pnp_devfn_t dev, int enable)
66 u8 power_register = 0, power_mask = 0, current_power, new_power;
68 switch (dev & 0xFF) {
69 case LPC47N227_PP:
70 power_register = 0x01;
71 power_mask = 0x04;
72 break;
73 case LPC47N227_SP1:
74 power_register = 0x02;
75 power_mask = 0x08;
76 break;
77 case LPC47N227_SP2:
78 power_register = 0x02;
79 power_mask = 0x80;
80 break;
81 default:
82 return;
85 current_power = pnp_read_config(dev, power_register);
86 new_power = current_power & ~power_mask; /* Disable by default. */
87 if (enable)
88 new_power |= power_mask; /* Enable. */
89 pnp_write_config(dev, power_register, new_power);
92 /**
93 * Configure the base I/O port of the specified serial device and enable the
94 * serial device.
96 * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
97 * @param iobase Processor I/O port address to assign to this serial device.
99 void lpc47n227_enable_serial(pnp_devfn_t dev, u16 iobase)
102 * NOTE: Cannot use pnp_set_XXX() here because they assume chip
103 * support for logical devices, which the LPC47N227 doesn't have.
105 pnp_enter_conf_state(dev);
106 lpc47n227_pnp_set_enable(dev, 0);
107 lpc47n227_pnp_set_iobase(dev, iobase);
108 lpc47n227_pnp_set_enable(dev, 1);
109 pnp_exit_conf_state(dev);