drivers: pinctrl: sf32lb: Preserve the SR/IS definition for each register

Only modify the definitions that need to be changed in the pinmux register;
SR/IS will retain their default values after reset.

Signed-off-by: Haoran Jiang <halfsweet@halfsweet.cn>
This commit is contained in:
Haoran Jiang
2025-12-01 16:21:55 +08:00
committed by Benjamin Cabé
parent 7ebf5091c2
commit 6d4900d0b9

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2025 Core Devices LLC
* Copyright (c) 2025 SiFli Technologies(Nanjing) Co., Ltd
* SPDX-License-Identifier: Apache-2.0
*/
@@ -19,22 +20,48 @@ struct sf32lb52x_pinctrl_config {
struct sf32lb_clock_dt_spec clock;
};
#define SF32LB_PINMUX_MSK \
SF32LB_FSEL_MSK | SF32LB_PE_MSK | SF32LB_PS_MSK | SF32LB_IE_MSK | SF32LB_IS_MSK | \
SF32LB_SR_MSK | SF32LB_DS0_MSK
static int pinctrl_configure_pin(pinctrl_soc_pin_t pin)
{
const struct device *dev = DEVICE_DT_INST_GET(0);
const struct sf32lb52x_pinctrl_config *config = dev->config;
uintptr_t pad;
uint8_t pinr_offset;
uint32_t val;
uint8_t port = FIELD_GET(SF32LB_PORT_MSK, pin);
uint8_t pad_num = FIELD_GET(SF32LB_PAD_MSK, pin);
uint8_t ds_idx = FIELD_GET(SF32LB_DS_IDX_MSK, pin);
uint8_t ds_reg;
/*
* PA39-PA42 only have DS1 bit (no DS0), supports only 4mA (DS1=0) or 20mA (DS1=1).
* - For 2mA/4mA (idx 0,2): use 4mA (DS1=0, reg=0)
* - For 8mA/12mA (idx 1,3): invalid, return error
* - For 20mA (idx 4): use 20mA (DS1=1, reg=1)
* Other pins: 20mA (idx 4) is invalid, ds_idx maps directly to register value.
*/
if ((port == SF32LB_PORT_PA) && (pad_num >= 39U) && (pad_num <= 42U)) {
if (ds_idx == 4U) {
/* 20mA is valid for PA39-42 */
ds_reg = 1U;
} else if ((ds_idx == 0U) || (ds_idx == 2U)) {
/* 2mA/4mA -> 4mA (DS1=0) */
ds_reg = 0U;
} else {
/* 8mA/12mA not supported on PA39-42 */
return -EINVAL;
}
} else {
/* Normal pins: 20mA is not valid, ds_idx is the register value */
if (ds_idx == 4U) {
return -EINVAL;
}
ds_reg = ds_idx;
}
/* configure HPSYS_CFG *_PINR if applicable */
pinr_offset = FIELD_GET(SF32LB_PINR_OFFSET_MSK, pin);
if (pinr_offset != 0U) {
uint32_t pinr_msk;
uint32_t val;
pinr_msk = 0xFFU << (8U * FIELD_GET(SF32LB_PINR_FIELD_MSK, pin));
val = sys_read32(config->cfg + pinr_offset);
@@ -57,7 +84,12 @@ static int pinctrl_configure_pin(pinctrl_soc_pin_t pin)
pad += FIELD_GET(SF32LB_PAD_MSK, pin) * 4U;
sys_write32(FIELD_GET(SF32LB_PINMUX_MSK, pin), pad);
val = sys_read32(pad);
val &= ~SF32LB_PINMUX_CFG_MSK;
val |= (pin & (SF32LB_PINMUX_CFG_MSK & ~SF32LB_DS_MSK));
val |= FIELD_PREP(SF32LB_DS_MSK, ds_reg);
sys_write32(val, pad);
return 0;
}