1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <device/mmio.h>
9 GPIO_DIRECTION_OUT
= 1,
16 static void pos_bit_calc(gpio_t gpio
, u32
*pos
, u32
*bit
)
18 *pos
= gpio
.id
/ MAX_GPIO_REG_BITS
;
19 *bit
= gpio
.id
% MAX_GPIO_REG_BITS
;
22 static void pos_bit_calc_for_mode(gpio_t gpio
, u32
*pos
, u32
*bit
)
24 *pos
= gpio
.id
/ MAX_GPIO_MODE_PER_REG
;
25 *bit
= (gpio
.id
% MAX_GPIO_MODE_PER_REG
) * GPIO_MODE_BITS
;
28 static s32
gpio_set_dir(gpio_t gpio
, u32 dir
)
34 pos_bit_calc(gpio
, &pos
, &bit
);
36 if (dir
== GPIO_DIRECTION_IN
)
37 reg
= &mtk_gpio
->dir
[pos
].rst
;
39 reg
= &mtk_gpio
->dir
[pos
].set
;
41 write32(reg
, 1L << bit
);
46 void gpio_set_mode(gpio_t gpio
, int mode
)
50 u32 mask
= (1L << GPIO_MODE_BITS
) - 1;
52 pos_bit_calc_for_mode(gpio
, &pos
, &bit
);
54 clrsetbits32(&mtk_gpio
->mode
[pos
].val
, mask
<< bit
, mode
<< bit
);
57 int gpio_get(gpio_t gpio
)
64 pos_bit_calc(gpio
, &pos
, &bit
);
66 reg
= &mtk_gpio
->din
[pos
].val
;
69 return (data
& (1L << bit
)) ? 1 : 0;
72 void gpio_set(gpio_t gpio
, int output
)
78 pos_bit_calc(gpio
, &pos
, &bit
);
81 reg
= &mtk_gpio
->dout
[pos
].rst
;
83 reg
= &mtk_gpio
->dout
[pos
].set
;
85 write32(reg
, 1L << bit
);
88 void gpio_input_pulldown(gpio_t gpio
)
90 gpio_set_pull(gpio
, GPIO_PULL_ENABLE
, GPIO_PULL_DOWN
);
91 gpio_set_dir(gpio
, GPIO_DIRECTION_IN
);
92 gpio_set_mode(gpio
, GPIO_MODE
);
95 void gpio_input_pullup(gpio_t gpio
)
97 gpio_set_pull(gpio
, GPIO_PULL_ENABLE
, GPIO_PULL_UP
);
98 gpio_set_dir(gpio
, GPIO_DIRECTION_IN
);
99 gpio_set_mode(gpio
, GPIO_MODE
);
102 void gpio_input(gpio_t gpio
)
104 gpio_set_pull(gpio
, GPIO_PULL_DISABLE
, GPIO_PULL_DOWN
);
105 gpio_set_dir(gpio
, GPIO_DIRECTION_IN
);
106 gpio_set_mode(gpio
, GPIO_MODE
);
109 void gpio_output(gpio_t gpio
, int value
)
111 gpio_set_pull(gpio
, GPIO_PULL_DISABLE
, GPIO_PULL_DOWN
);
112 gpio_set(gpio
, value
);
113 gpio_set_dir(gpio
, GPIO_DIRECTION_OUT
);
114 gpio_set_mode(gpio
, GPIO_MODE
);
117 int gpio_eint_poll(gpio_t gpio
)
122 struct eint_regs
*mtk_eint
;
124 gpio_calc_eint_pos_bit(gpio
, &pos
, &bit
);
125 mtk_eint
= gpio_get_eint_reg(gpio
);
128 status
= (read32(&mtk_eint
->sta
.regs
[pos
]) >> bit
) & 0x1;
131 write32(&mtk_eint
->ack
.regs
[pos
], 1 << bit
);
136 void gpio_eint_configure(gpio_t gpio
, enum gpio_irq_type type
)
140 struct eint_regs
*mtk_eint
;
142 gpio_calc_eint_pos_bit(gpio
, &pos
, &bit
);
143 mtk_eint
= gpio_get_eint_reg(gpio
);
148 /* Make it an input first. */
149 gpio_input_pullup(gpio
);
151 write32(&mtk_eint
->d0en
[pos
], mask
);
154 case IRQ_TYPE_EDGE_FALLING
:
155 write32(&mtk_eint
->sens_clr
.regs
[pos
], mask
);
156 write32(&mtk_eint
->pol_clr
.regs
[pos
], mask
);
158 case IRQ_TYPE_EDGE_RISING
:
159 write32(&mtk_eint
->sens_clr
.regs
[pos
], mask
);
160 write32(&mtk_eint
->pol_set
.regs
[pos
], mask
);
162 case IRQ_TYPE_LEVEL_LOW
:
163 write32(&mtk_eint
->sens_set
.regs
[pos
], mask
);
164 write32(&mtk_eint
->pol_clr
.regs
[pos
], mask
);
166 case IRQ_TYPE_LEVEL_HIGH
:
167 write32(&mtk_eint
->sens_set
.regs
[pos
], mask
);
168 write32(&mtk_eint
->pol_set
.regs
[pos
], mask
);
172 write32(&mtk_eint
->mask_clr
.regs
[pos
], mask
);
175 static inline bool is_valid_drv(uint8_t drv
)
177 return drv
<= GPIO_DRV_16_MA
;
180 static inline bool is_valid_drv_adv(enum gpio_drv_adv drv
)
182 return drv
<= GPIO_DRV_ADV_1_MA
&& drv
>= GPIO_DRV_ADV_125_UA
;
185 int gpio_set_driving(gpio_t gpio
, uint8_t drv
)
188 const struct gpio_drv_info
*info
= get_gpio_driving_info(gpio
.id
);
189 const struct gpio_drv_info
*adv_info
= get_gpio_driving_adv_info(gpio
.id
);
190 void *reg
, *reg_adv
, *reg_addr
;
193 printk(BIOS_ERR
, "%s: raw_id %u is out of range\n", __func__
, gpio
.id
);
197 if (!is_valid_drv(drv
))
200 if (info
->width
== 0)
203 mask
= BIT(info
->width
) - 1;
204 /* Check setting value is not beyond width */
205 if ((uint32_t)drv
> mask
)
208 reg_addr
= gpio_find_reg_addr(gpio
);
209 reg
= reg_addr
+ info
->offset
;
210 clrsetbits32(reg
, mask
<< info
->shift
, drv
<< info
->shift
);
212 /* Disable EH if supported */
213 if (adv_info
&& adv_info
->width
!= 0) {
214 reg_adv
= reg_addr
+ adv_info
->offset
;
215 clrbits32(reg_adv
, BIT(adv_info
->shift
));
221 int gpio_get_driving(gpio_t gpio
)
223 const struct gpio_drv_info
*info
= get_gpio_driving_info(gpio
.id
);
227 printk(BIOS_ERR
, "%s: raw_id %u is out of range\n", __func__
, gpio
.id
);
231 if (info
->width
== 0)
234 reg
= gpio_find_reg_addr(gpio
) + info
->offset
;
235 return (read32(reg
) >> info
->shift
) & (BIT(info
->width
) - 1);
238 int gpio_set_driving_adv(gpio_t gpio
, enum gpio_drv_adv drv
)
241 const struct gpio_drv_info
*adv_info
= get_gpio_driving_adv_info(gpio
.id
);
245 printk(BIOS_ERR
, "%s: raw_id %u is out of range\n", __func__
, gpio
.id
);
249 if (!is_valid_drv_adv(drv
))
252 if (adv_info
->width
== 0)
255 /* Not include EH bit (the lowest bit) */
256 if ((uint32_t)drv
> (BIT(adv_info
->width
- 1) - 1))
259 reg_adv
= gpio_find_reg_addr(gpio
) + adv_info
->offset
;
260 mask
= BIT(adv_info
->width
) - 1;
262 drv
= (drv
<< 1) | BIT(0);
264 clrsetbits32(reg_adv
, mask
<< adv_info
->shift
, drv
<< adv_info
->shift
);
269 int gpio_get_driving_adv(gpio_t gpio
)
271 const struct gpio_drv_info
*adv_info
= get_gpio_driving_adv_info(gpio
.id
);
276 printk(BIOS_ERR
, "%s: raw_id %u is out of range\n", __func__
, gpio
.id
);
280 if (adv_info
->width
== 0)
283 reg_adv
= gpio_find_reg_addr(gpio
) + adv_info
->offset
;
284 drv
= (read32(reg_adv
) >> adv_info
->shift
) & (BIT(adv_info
->width
) - 1);