28 /* from sb/intel/lynxpoint/lp_gpio.c */
29 func lp_gpio_to_pirq(gpioNum
uint16) int {
30 var pirqmap
= map[uint16] int {
48 pirq
, valid
:= pirqmap
[gpioNum
]
56 func conf0str(conf0
uint32) string {
58 return "GPIO_MODE_NATIVE"
60 s
:= []string{"GPIO_MODE_GPIO"}
62 if ((conf0
>> 2) & 1) == 1 {
63 s
= append(s
, "GPIO_DIR_INPUT")
66 s
= append(s
, "GPIO_DIR_OUTPUT")
69 if ((conf0
>> 3) & 1) == 1 {
70 s
= append(s
, "GPIO_INVERT")
72 if ((conf0
>> 4) & 1) == 1 {
73 s
= append(s
, "GPIO_IRQ_LEVEL")
76 if ((conf0
>> 31) & 1) == 1 {
77 s
= append(s
, "GPO_LEVEL_HIGH")
79 s
= append(s
, "GPO_LEVEL_LOW")
82 return strings
.Join(s
, " | ")
86 func lpgpio_preset(conf0
uint32, owner
uint32, route
uint32, irqen
uint32, pirq
uint32) string {
87 if conf0
== 0xd { /* 0b1101: MODE_GPIO | INPUT | INVERT */
88 if owner
== 0 { /* OWNER_ACPI */
89 if irqen
== 0 && pirq
== 0 {
90 if route
== 0 { /* SCI */
91 return "GPIO_ACPI_SCI"
93 return "GPIO_ACPI_SMI"
97 } else { /* OWNER_GPIO */
98 if route
== 0 && irqen
== 0 && pirq
!= 0 {
99 return "GPIO_INPUT_INVERT"
105 if conf0
== 0x5 && owner
== 1 { /* 0b101: MODE_GPIO | INPUT, OWNER_GPIO */
106 if route
== 0 && irqen
== 0 {
116 if owner
== 1 && irqen
== 1 {
117 if route
== 0 && pirq
== 0 {
118 if conf0
== 0x5 { /* 0b00101 */
119 return "GPIO_IRQ_EDGE"
121 if conf0
== 0x15 { /* 0b10101 */
122 return "GPIO_IRQ_LEVEL"
130 func gpio_str(conf0
uint32, conf1
uint32, owner
uint32, route
uint32, irqen
uint32, reset
uint32, blink
uint32, pirq
uint32) string {
132 s
= append(s
, fmt
.Sprintf(".conf0 = %s", conf0str(conf0
)))
134 s
= append(s
, fmt
.Sprintf(".conf1 = 0x%x", conf1
))
137 s
= append(s
, ".owner = GPIO_OWNER_GPIO")
140 s
= append(s
, ".route = GPIO_ROUTE_SMI")
143 s
= append(s
, ".irqen = GPIO_IRQ_ENABLE")
146 s
= append(s
, ".reset = GPIO_RESET_RSMRST")
149 s
= append(s
, ".blink = GPO_BLINK")
152 s
= append(s
, ".pirq = GPIO_PIRQ_APIC_ROUTE")
154 return strings
.Join(s
, ", ")
157 /* start addresses of GPIO registers */
160 GPIPIRQ2IOXAPIC
= 0x10
169 func PrintLPGPIO(gpio
*os
.File
, inteltool InteltoolData
) {
170 for gpioNum
:= uint16(0); gpioNum
<= 94; gpioNum
++ {
172 fmt
.Fprintf(gpio
, "\t[%d] = ", gpioNum
)
174 fmt
.Fprintf(gpio
, "\t[%d] = ", gpioNum
)
176 conf0
:= inteltool
.GPIO
[GPnCONFIGA
+gpioNum
*8]
177 conf1
:= inteltool
.GPIO
[GPnCONFIGB
+gpioNum
*8]
180 /* owner only effective in GPIO mode */
181 owner
:= (inteltool
.GPIO
[GPIO_OWN
+set
*4] >> bit
) & 1
182 route
:= (inteltool
.GPIO
[GPI_ROUT
+set
*4] >> bit
) & 1
183 irqen
:= (inteltool
.GPIO
[GPI_IE
+set
*4] >> bit
) & 1
184 reset
:= (inteltool
.GPIO
[GP_RST_SEL
+set
*4] >> bit
) & 1
185 var blink
, pirq
uint32
186 /* blink only effective in GPIO output mode */
188 blink
= (inteltool
.GPIO
[GPO_BLINK
] >> bit
) & 1
192 irqset
:= lp_gpio_to_pirq(gpioNum
)
194 pirq
= (inteltool
.GPIO
[GPIPIRQ2IOXAPIC
] >> uint(irqset
)) & 1
199 if (conf0
& 1) == 0 {
200 fmt
.Fprintf(gpio
, "LP_GPIO_NATIVE,\n")
201 } else if (conf0
& 4) == 0 {
202 /* configured as output */
203 if ((conf0
>> 31) & 1) == 0 {
204 fmt
.Fprintf(gpio
, "LP_GPIO_OUT_LOW,\n")
206 fmt
.Fprintf(gpio
, "LP_GPIO_OUT_HIGH,\n")
208 } else if (conf1
& 4) != 0 {
209 /* configured as input and sensing disabled */
210 fmt
.Fprintf(gpio
, "LP_GPIO_UNUSED,\n")
213 if conf1
== 0 && reset
== 0 && blink
== 0 {
214 preset
:= lpgpio_preset(conf0
, owner
, route
, irqen
, pirq
)
216 fmt
.Fprintf(gpio
, "LP_%s,\n", preset
)
221 fmt
.Fprintf(gpio
, "{ %s },\n", gpio_str(conf0
, conf1
, owner
, route
, irqen
, reset
, blink
, pirq
))
227 func Lynxpoint_LP_GPIO(ctx Context
, inteltool InteltoolData
) {
228 gpio
:= Create(ctx
, "gpio.c")
231 AddROMStageFile("gpio.c", "")
234 gpio
.WriteString(`#include <southbridge/intel/lynxpoint/lp_gpio.h>
236 const struct pch_lp_gpio_map mainboard_lp_gpio_map[] = {
238 PrintLPGPIO(gpio
, inteltool
)
239 gpio
.WriteString("\tLP_GPIO_END\n};\n")