1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <device/pci_ops.h>
6 #include <device/device.h>
7 #include <device/pci.h>
12 static u16
get_gpio_base(void)
14 #ifdef __SIMPLE_DEVICE__
15 return pci_read_config16(PCH_LPC_DEV
, GPIO_BASE
) & 0xfffc;
17 return pci_read_config16(pcidev_on_root(0x1f, 0),
23 * This function will return a number that indicates which PIRQ
24 * this GPIO maps to. If this is not a PIRQ capable GPIO then
25 * it will return -1. The GPIO to PIRQ mapping is not linear.
27 static int lp_gpio_to_pirq(int gpio
)
30 case 8: return 0; /* PIRQI */
31 case 9: return 1; /* PIRQJ */
32 case 10: return 2; /* PIRQK */
33 case 13: return 3; /* PIRQL */
34 case 14: return 4; /* PIRQM */
35 case 45: return 5; /* PIRQN */
36 case 46: return 6; /* PIRQO */
37 case 47: return 7; /* PIRQP */
38 case 48: return 8; /* PIRQQ */
39 case 49: return 9; /* PIRQR */
40 case 50: return 10; /* PIRQS */
41 case 51: return 11; /* PIRQT */
42 case 52: return 12; /* PIRQU */
43 case 53: return 13; /* PIRQV */
44 case 54: return 14; /* PIRQW */
45 case 55: return 15; /* PIRQX */
50 void setup_pch_lp_gpios(const struct pch_lp_gpio_map map
[])
52 u16 gpio_base
= get_gpio_base();
53 const struct pch_lp_gpio_map
*config
;
60 int set
, bit
, gpio
= 0;
62 for (config
= map
; config
->conf0
!= GPIO_LIST_END
; config
++, gpio
++) {
63 if (gpio
> MAX_GPIO_NUMBER
)
66 /* Setup Configuration registers 1 and 2 */
67 outl(config
->conf0
, gpio_base
+ GPIO_CONFIG0(gpio
));
68 outl(config
->conf1
, gpio_base
+ GPIO_CONFIG1(gpio
));
70 /* Determine set and bit based on GPIO number */
74 /* Apply settings to set specific bits */
75 owner
[set
] |= config
->owner
<< bit
;
76 route
[set
] |= config
->route
<< bit
;
77 irqen
[set
] |= config
->irqen
<< bit
;
78 reset
[set
] |= config
->reset
<< bit
;
81 blink
|= config
->blink
<< bit
;
83 /* PIRQ to IO-APIC map */
84 if (config
->pirq
== GPIO_PIRQ_APIC_ROUTE
) {
85 set
= lp_gpio_to_pirq(gpio
);
87 pirq2apic
|= 1 << set
;
91 for (set
= 0; set
<= 2; set
++) {
92 outl(owner
[set
], gpio_base
+ GPIO_OWNER(set
));
93 outl(route
[set
], gpio_base
+ GPIO_ROUTE(set
));
94 outl(irqen
[set
], gpio_base
+ GPIO_IRQ_IE(set
));
95 outl(reset
[set
], gpio_base
+ GPIO_RESET(set
));
98 outl(blink
, gpio_base
+ GPIO_BLINK
);
99 outl(pirq2apic
, gpio_base
+ GPIO_PIRQ_APIC_EN
);
102 int get_gpio(int gpio_num
)
104 u16 gpio_base
= get_gpio_base();
106 if (gpio_num
> MAX_GPIO_NUMBER
)
109 return !!(inl(gpio_base
+ GPIO_CONFIG0(gpio_num
)) & GPI_LEVEL
);
113 * get a number comprised of multiple GPIO values. gpio_num_array points to
114 * the array of gpio pin numbers to scan, terminated by -1.
116 unsigned int get_gpios(const int *gpio_num_array
)
119 unsigned int bitmask
= 1;
120 unsigned int vector
= 0;
123 ((gpio
= *gpio_num_array
++) != -1)) {
131 void set_gpio(int gpio_num
, int value
)
133 u16 gpio_base
= get_gpio_base();
136 if (gpio_num
> MAX_GPIO_NUMBER
)
139 conf0
= inl(gpio_base
+ GPIO_CONFIG0(gpio_num
));
140 conf0
&= ~GPO_LEVEL_MASK
;
141 conf0
|= value
<< GPO_LEVEL_SHIFT
;
142 outl(conf0
, gpio_base
+ GPIO_CONFIG0(gpio_num
));
145 int gpio_is_native(int gpio_num
)
147 u16 gpio_base
= get_gpio_base();
149 return !(inl(gpio_base
+ GPIO_CONFIG0(gpio_num
)) & 1);