1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
8 GPIO_DIRECTION_OUT
= 1,
15 static void pos_bit_calc(gpio_t gpio
, u32
*pos
, u32
*bit
)
17 *pos
= gpio
.id
/ MAX_GPIO_REG_BITS
;
18 *bit
= gpio
.id
% MAX_GPIO_REG_BITS
;
21 static void pos_bit_calc_for_mode(gpio_t gpio
, u32
*pos
, u32
*bit
)
23 *pos
= gpio
.id
/ MAX_GPIO_MODE_PER_REG
;
24 *bit
= (gpio
.id
% MAX_GPIO_MODE_PER_REG
) * GPIO_MODE_BITS
;
27 static s32
gpio_set_dir(gpio_t gpio
, u32 dir
)
33 pos_bit_calc(gpio
, &pos
, &bit
);
35 if (dir
== GPIO_DIRECTION_IN
)
36 reg
= &mtk_gpio
->dir
[pos
].rst
;
38 reg
= &mtk_gpio
->dir
[pos
].set
;
40 write32(reg
, 1L << bit
);
45 void gpio_set_mode(gpio_t gpio
, int mode
)
49 u32 mask
= (1L << GPIO_MODE_BITS
) - 1;
51 pos_bit_calc_for_mode(gpio
, &pos
, &bit
);
53 clrsetbits32(&mtk_gpio
->mode
[pos
].val
, mask
<< bit
, mode
<< bit
);
56 int gpio_get(gpio_t gpio
)
63 pos_bit_calc(gpio
, &pos
, &bit
);
65 reg
= &mtk_gpio
->din
[pos
].val
;
68 return (data
& (1L << bit
)) ? 1 : 0;
71 void gpio_set(gpio_t gpio
, int output
)
77 pos_bit_calc(gpio
, &pos
, &bit
);
80 reg
= &mtk_gpio
->dout
[pos
].rst
;
82 reg
= &mtk_gpio
->dout
[pos
].set
;
84 write32(reg
, 1L << bit
);
87 void gpio_input_pulldown(gpio_t gpio
)
89 gpio_set_pull(gpio
, GPIO_PULL_ENABLE
, GPIO_PULL_DOWN
);
90 gpio_set_dir(gpio
, GPIO_DIRECTION_IN
);
91 gpio_set_mode(gpio
, GPIO_MODE
);
94 void gpio_input_pullup(gpio_t gpio
)
96 gpio_set_pull(gpio
, GPIO_PULL_ENABLE
, GPIO_PULL_UP
);
97 gpio_set_dir(gpio
, GPIO_DIRECTION_IN
);
98 gpio_set_mode(gpio
, GPIO_MODE
);
101 void gpio_input(gpio_t gpio
)
103 gpio_set_pull(gpio
, GPIO_PULL_DISABLE
, GPIO_PULL_DOWN
);
104 gpio_set_dir(gpio
, GPIO_DIRECTION_IN
);
105 gpio_set_mode(gpio
, GPIO_MODE
);
108 void gpio_output(gpio_t gpio
, int value
)
110 gpio_set_pull(gpio
, GPIO_PULL_DISABLE
, GPIO_PULL_DOWN
);
111 gpio_set(gpio
, value
);
112 gpio_set_dir(gpio
, GPIO_DIRECTION_OUT
);
113 gpio_set_mode(gpio
, GPIO_MODE
);
117 MAX_EINT_REG_BITS
= 32,
120 static void pos_bit_calc_for_eint(gpio_t gpio
, u32
*pos
, u32
*bit
)
122 *pos
= gpio
.id
/ MAX_EINT_REG_BITS
;
123 *bit
= gpio
.id
% MAX_EINT_REG_BITS
;
126 int gpio_eint_poll(gpio_t gpio
)
132 pos_bit_calc_for_eint(gpio
, &pos
, &bit
);
134 status
= (read32(&mtk_eint
->sta
.regs
[pos
]) >> bit
) & 0x1;
137 write32(&mtk_eint
->ack
.regs
[pos
], 1 << bit
);
142 void gpio_eint_configure(gpio_t gpio
, enum gpio_irq_type type
)
147 pos_bit_calc_for_eint(gpio
, &pos
, &bit
);
150 /* Make it an input first. */
151 gpio_input_pullup(gpio
);
153 write32(&mtk_eint
->d0en
[pos
], mask
);
156 case IRQ_TYPE_EDGE_FALLING
:
157 write32(&mtk_eint
->sens_clr
.regs
[pos
], mask
);
158 write32(&mtk_eint
->pol_clr
.regs
[pos
], mask
);
160 case IRQ_TYPE_EDGE_RISING
:
161 write32(&mtk_eint
->sens_clr
.regs
[pos
], mask
);
162 write32(&mtk_eint
->pol_set
.regs
[pos
], mask
);
164 case IRQ_TYPE_LEVEL_LOW
:
165 write32(&mtk_eint
->sens_set
.regs
[pos
], mask
);
166 write32(&mtk_eint
->pol_clr
.regs
[pos
], mask
);
168 case IRQ_TYPE_LEVEL_HIGH
:
169 write32(&mtk_eint
->sens_set
.regs
[pos
], mask
);
170 write32(&mtk_eint
->pol_set
.regs
[pos
], mask
);
174 write32(&mtk_eint
->mask_clr
.regs
[pos
], mask
);
177 static inline bool is_valid_drv(uint8_t drv
)
179 return drv
<= GPIO_DRV_16_MA
;
182 static inline bool is_valid_drv_adv(enum gpio_drv_adv drv
)
184 return drv
<= GPIO_DRV_ADV_1_MA
&& drv
>= GPIO_DRV_ADV_125_UA
;
187 int gpio_set_driving(gpio_t gpio
, uint8_t drv
)
190 const struct gpio_drv_info
*info
= get_gpio_driving_info(gpio
.id
);
191 const struct gpio_drv_info
*adv_info
= get_gpio_driving_adv_info(gpio
.id
);
192 void *reg
, *reg_adv
, *reg_addr
;
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
);
229 if (info
->width
== 0)
232 reg
= gpio_find_reg_addr(gpio
) + info
->offset
;
233 return (read32(reg
) >> info
->shift
) & (BIT(info
->width
) - 1);
236 int gpio_set_driving_adv(gpio_t gpio
, enum gpio_drv_adv drv
)
239 const struct gpio_drv_info
*adv_info
= get_gpio_driving_adv_info(gpio
.id
);
245 if (!is_valid_drv_adv(drv
))
248 if (adv_info
->width
== 0)
251 /* Not include EH bit (the lowest bit) */
252 if ((uint32_t)drv
> (BIT(adv_info
->width
- 1) - 1))
255 reg_adv
= gpio_find_reg_addr(gpio
) + adv_info
->offset
;
256 mask
= BIT(adv_info
->width
) - 1;
258 drv
= (drv
<< 1) | BIT(0);
260 clrsetbits32(reg_adv
, mask
<< adv_info
->shift
, drv
<< adv_info
->shift
);
265 int gpio_get_driving_adv(gpio_t gpio
)
267 const struct gpio_drv_info
*adv_info
= get_gpio_driving_adv_info(gpio
.id
);
274 if (adv_info
->width
== 0)
277 reg_adv
= gpio_find_reg_addr(gpio
) + adv_info
->offset
;
278 drv
= (read32(reg_adv
) >> adv_info
->shift
) & (BIT(adv_info
->width
) - 1);