zephyr/drivers/pinctrl/pinctrl_bflb_bl60x_70x.c

117 lines
2.9 KiB
C
Raw Permalink Normal View History

/*
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/drivers/pinctrl.h>
#include <bflb_soc.h>
#include <glb_reg.h>
#include <zephyr/dt-bindings/pinctrl/bflb-common-pinctrl.h>
#if defined(CONFIG_SOC_SERIES_BL60X)
#include <zephyr/dt-bindings/pinctrl/bl60x-pinctrl.h>
#elif defined(CONFIG_SOC_SERIES_BL70X)
#include <zephyr/dt-bindings/pinctrl/bl70x-pinctrl.h>
#else
#error "Unsupported Platform"
#endif
void pinctrl_bflb_configure_uart(uint8_t pin, uint8_t func)
{
/* uart func for BL602 and BL702 Only*/
uint32_t regval;
uint8_t sig;
uint8_t sig_pos;
regval = sys_read32(GLB_BASE + GLB_UART_SIG_SEL_0_OFFSET);
sig = pin % 8;
sig_pos = sig << 2;
regval &= (~(0x0f << sig_pos));
regval |= (func << sig_pos);
for (uint8_t i = 0; i < 8; i++) {
/* reset other sigs which are the same with uart_func */
sig_pos = i << 2;
if (((regval & (0x0f << sig_pos)) == (func << sig_pos)) && (i != sig) && (func !=
0x0f)) {
regval &= (~(0x0f << sig_pos));
regval |= (0x0f << sig_pos);
}
}
sys_write32(regval, GLB_BASE + GLB_UART_SIG_SEL_0_OFFSET);
}
void pinctrl_bflb_init_pin(pinctrl_soc_pin_t pin)
{
uint8_t drive;
uint8_t function;
uint16_t mode;
uint32_t regval;
uint8_t real_pin;
uint8_t is_odd = 0;
uint32_t cfg = 0;
uint32_t cfg_address;
real_pin = BFLB_PINMUX_GET_PIN(pin);
function = BFLB_PINMUX_GET_FUN(pin);
mode = BFLB_PINMUX_GET_MODE(pin);
drive = BFLB_PINMUX_GET_DRIVER_STRENGTH(pin);
/* Disable output anyway */
regval = sys_read32(GLB_BASE + GLB_GPIO_CFGCTL34_OFFSET + ((real_pin >> 5) << 2));
regval &= ~(1 << (real_pin & 0x1f));
sys_write32(regval, GLB_BASE + GLB_GPIO_CFGCTL34_OFFSET + ((real_pin >> 5) << 2));
is_odd = real_pin & 1;
cfg_address = GLB_BASE + GLB_GPIO_CFGCTL0_OFFSET + (real_pin / 2 * 4);
cfg = sys_read32(cfg_address);
cfg &= ~(0xffff << (16 * is_odd));
regval = sys_read32(GLB_BASE + GLB_GPIO_CFGCTL34_OFFSET + ((real_pin >> 5) << 2));
if (mode == BFLB_PINMUX_MODE_analog) {
regval &= ~(1 << (real_pin & 0x1f));
function = 10;
} else if (mode == BFLB_PINMUX_MODE_periph) {
cfg |= (1 << (is_odd * 16 + 0));
regval &= ~(1 << (real_pin & 0x1f));
} else {
function = 11;
if (mode == BFLB_PINMUX_MODE_input) {
cfg |= (1 << (is_odd * 16 + 0));
}
if (mode == BFLB_PINMUX_MODE_output) {
regval |= (1 << (real_pin & 0x1f));
}
}
sys_write32(regval, GLB_BASE + GLB_GPIO_CFGCTL34_OFFSET + ((real_pin >> 5) << 2));
uint8_t pull_up = BFLB_PINMUX_GET_PULL_UP(pin);
uint8_t pull_down = BFLB_PINMUX_GET_PULL_DOWN(pin);
if (pull_up) {
cfg |= (1 << (is_odd * 16 + 4));
} else if (pull_down) {
cfg |= (1 << (is_odd * 16 + 5));
} else {
}
if (BFLB_PINMUX_GET_SMT(pin)) {
cfg |= (1 << (is_odd * 16 + 1));
}
cfg |= (drive << (is_odd * 16 + 2));
cfg |= (function << (is_odd * 16 + 8));
sys_write32(cfg, cfg_address);
}