Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/pinctrl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

zephyr_library()
zephyr_library_sources(common.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_BFLB pinctrl_bflb.c)
2 changes: 2 additions & 0 deletions drivers/pinctrl/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ config PINCTRL_DYNAMIC
runtime. This can be useful, for example, to change the pins assigned to a
peripheral at early boot stages depending on a certain input.

source "drivers/pinctrl/Kconfig.bflb"

endif # PINCTRL
9 changes: 9 additions & 0 deletions drivers/pinctrl/Kconfig.bflb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2021 Gerson Fernando Budke <[email protected]>
# SPDX-License-Identifier: Apache-2.0

config PINCTRL_BFLB
bool "Bouffalo Lab pin control driver"
depends on SOC_FAMILY_BFLB
default y
help
Bouffalo Lab pin control driver
39 changes: 39 additions & 0 deletions drivers/pinctrl/pinctrl_bflb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 Gerson Fernando Budke <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#include <drivers/pinctrl.h>
#include <dt-bindings/pinctrl/bflb-pinctrl.h>
#include <bflb_glb.h>
#include <bflb_gpio.h>

int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
uintptr_t reg)
{
GLB_GPIO_Cfg_Type pincfg;
uint8_t i;

ARG_UNUSED(reg);

for (i = 0U; i < pin_cnt; i++) {
pincfg.gpioFun = BFLB_FUN_2_FUNC(pins[i].fun);
pincfg.gpioMode = BFLB_FUN_2_MODE(pins[i].fun);
pincfg.gpioPin = pins[i].pin;
pincfg.pullType = BFLB_CFG_2_GPIO_MODE(pins[i].cfg);
pincfg.smtCtrl = BFLB_CFG_2_GPIO_INP_SMT(pins[i].cfg);
pincfg.drive = BFLB_CFG_2_GPIO_DRV_STR(pins[i].cfg);

if (pincfg.gpioFun == GPIO_FUN_UART) {
GLB_UART_Fun_Sel(pincfg.gpioPin % 8,
(BFLB_FUN_2_INST(pins[i].fun))
* BFLB_SIG_UART_LEN
+ (pins[i].flags & BFLB_SIG_UART_MASK)
);
}

GLB_GPIO_Init(&pincfg);
}

return 0;
}
40 changes: 40 additions & 0 deletions dts/bindings/gpio/bflb,bl-gpio.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright (c) 2021, Gerson Fernando Budke <[email protected]>
# SPDX-License-Identifier: Apache-2.0

description: Bouffalo Lab GPIO node

compatible: "bflb,bl-gpio"

include: [gpio-controller.yaml, base.yaml]

properties:
reg:
required: true

interrupts:
required: false

label:
required: true

"#gpio-cells":
const: 0
Comment on lines +20 to +21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? How can you implement the GPIO API without pin and flags cells here?

Please add some more detailed comments explaining this, at least to the commit log, when taking this out of draft.


"#bflb,pin-cells":
type: int
required: true
const: 2
description: Number of items to expect in a bflb,pins specifier

"#bflb,signal-cells":
type: int
required: false
const: 1
description: Number of items to expect in a bflb,signals specifier

bflb,pin-cells:
- fun
- pin

bflb,signal-cells:
- flags
90 changes: 90 additions & 0 deletions dts/bindings/pinctrl/bflb,bl-pinctrl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Copyright (c) 2021, Gerson Fernando Budke <[email protected]>
# SPDX-License-Identifier: Apache-2.0

description: Bouffalo Lab Pinctrl node

compatible: "bflb,bl-pinctrl"

include:
- name: base.yaml
- name: pincfg-node-group.yaml
child-binding:
child-binding:
property-allowlist:
- bias-high-impedance
- bias-pull-down
- bias-pull-up
- input-enable
- input-schmitt-enable
- output-enable

properties:
"#address-cells":
required: true
const: 1
"#size-cells":
required: true
const: 1

child-binding:
description: |
Bouffalo Lab pin controller pin configuration nodes. Each node is composed
by one or more groups, each defining the configuration for a set of pins.

child-binding:
description: |
Bouffalo Lab pin controller pin configuration group. Each group contains
a list of pins sharing the same set of properties. Example:
uart0_default: uart0_default {
/* group 1 (name is arbitrary) */
pins1 {
/* configure to uart0 function plus modem interrupt, pin 7 as UART_RX
pin 16 as UART_TX and finally pin 18 as gpio */
bflb,pins = <BFLB_PIN(uart0, 7)>,
<BFLB_PIN(uart0, 16)>,
<BFLB_PIN(gpio, 18)>;
bflb,signals = <BFLB_SIG_UART_RXD>,
<BFLB_SIG_UART_TXD>;
bias-pull-up;
input-schmitt-enable;
};
};
The list of supported standard properties:
- bias-high-impedance: Disable pull-up/down (default behavior, not
required).
- bias-pull-up: Enable pull-up resistor.
- bias-pull-down: Enable pull-down resistor.
- input-enable: Enable GPIO as input (default behavior, not required).
- input-schmitt-enable: Enable Schimitt Trigger when GPIO is Input.
- output-enable: Enable GPIO as output.

Note that bias options are mutually exclusive. It is the same with GPIO
input/output enable options.
properties:
"bflb,pins":
required: true
type: phandle-array
description: |
An phandle-array of pins sharing the same group properties. The pins
should be defined using the BFLB_PIN utility macro that encode
function and pin. Some special functions require a signal to complete
route matrix.
"bflb,signals":
required: false
type: array
description: |
An optional array that add flags to a pin. The signal flag is defined
at bflb-pinctrl.h and have BFLB_SIG_ as prefix. It don't require same
len that bflb,pins property.
drive-strength:
required: false
type: int
default: 0
enum:
- 0 # Default value, lower strength, 8mA
- 1 # 9.6mA
- 2 # 11.2mA
- 3 # highest strength, 12.8mA
description: |
Pin drive strength. It tunes pin max current where 0 means lower
value, which is the default, and 3 represents max drive strength.
20 changes: 20 additions & 0 deletions dts/riscv/bouffalolab/bl6.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

#include <mem.h>
#include <dt-bindings/pinctrl/bflb-pinctrl.h>

/ {
#address-cells = <1>;
Expand Down Expand Up @@ -76,6 +77,25 @@
sifive,numlevels = <16>;
};

pinctrl: pinctrl@40000000 {
compatible = "bflb,bl-pinctrl";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x40000000 0x40000000 0x1000>;

glb: gpio@40000000 {
compatible = "bflb,bl-gpio";
reg = <0x40000000 0x1000>;
label = "GLB";
interrupts = <1 0>;
interrupt-parent = <&ictrl>;
gpio-controller;
#gpio-cells = <0>;
#bflb,pin-cells = <2>;
#bflb,signal-cells = <1>;
};
};

spi0: spi@4000a200 {
compatible = "bflb,bl-spi";
reg = <0x4000a200 0x100>;
Expand Down
131 changes: 131 additions & 0 deletions include/dt-bindings/pinctrl/bflb-pinctrl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2021 Gerson Fernando Budke <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_BFLB_PINCTRL_H_
#define ZEPHYR_BFLB_PINCTRL_H_

/**
* @brief FUN configuration bitfield
*
* The Zephyr version of Bouffalo Lab function field encode 3 information:
* - The pin function itself
* - The peripheral instance (ex. uart0, uart1, etc)
* - The pin mode
*
* Because GPIO is a subset of functions, it is necessary define all modes
* when a pin is configured. To keep it simple, mode is already defined for all
* alternate functions and analog. In the case of GPIO, the pincfg-node should
* be used to configure GPIO function.
*
* Pin function configuration is coded using 2 bytes with the following fields
* Byte 0 - Function
* Byte 1 - Pin Mode [ 0 : 1 ]
* - Peripheral Instance [ 4 : 5 ]
*
* ex.:
* uart1 - 0x1207
* 1 2 07
* Instance Alternate Mode Function UART
*
* gpio - 0x010b
* 0 2 0b
* Instance Output Function GPIO
*/

#define BFLB_FUN_clk_out 0x0200
#define BFLB_FUN_bt_coexist 0x0201
#define BFLB_FUN_flash_psram 0x0202
#define BFLB_FUN_qspi 0x0202
#define BFLB_FUN_i2s 0x0203
#define BFLB_FUN_spi 0x0204
#define BFLB_FUN_i2c 0x0206
#define BFLB_FUN_uart0 0x0207
#define BFLB_FUN_uart1 0x1207
#define BFLB_FUN_pwm 0x0208
#define BFLB_FUN_cam 0x0209
#define BFLB_FUN_analog 0x030a
#define BFLB_FUN_gpio 0x000b
#define BFLB_FUN_rf_test 0x020c
#define BFLB_FUN_scan 0x020d
#define BFLB_FUN_jtag 0x020e
#define BFLB_FUN_debug 0x020f
#define BFLB_FUN_external_pa 0x0210
#define BFLB_FUN_usb_transceiver 0x0211
#define BFLB_FUN_usb_controller 0x0212
#define BFLB_FUN_ether_mac 0x0213
#define BFLB_FUN_emca 0x0213
#define BFLB_FUN_qdec 0x0014
#define BFLB_FUN_key_scan_in 0x0215
#define BFLB_FUN_key_scan_row 0x0215
#define BFLB_FUN_key_scan_drive 0x0216
#define BFLB_FUN_key_scan_col 0x0216
#define BFLB_FUN_cam_misc 0x0217
#define BFLB_FUN_FUNC_POS 0U
#define BFLB_FUN_FUNC_MASK 0x1F

#define BFLB_FUN_MODE_POS 8U
#define BFLB_FUN_MODE_MASK 0x03
#define BFLB_FUN_MODE_INPUT (0x0 << BFLB_FUN_MODE_POS)
#define BFLB_FUN_MODE_OUTPUT (0x1 << BFLB_FUN_MODE_POS)
#define BFLB_FUN_MODE_AF (0x2 << BFLB_FUN_MODE_POS)
#define BFLB_FUN_MODE_ANALOG (0x3 << BFLB_FUN_MODE_POS)

#define BFLB_FUN_INST_POS 12U
#define BFLB_FUN_INST_MASK 0x03
#define BFLB_FUN_INST_0 (0x0 << BFLB_FUN_INST_POS)
#define BFLB_FUN_INST_1 (0x1 << BFLB_FUN_INST_POS)

#define BFLB_SIG_UART_RTS 0x0
#define BFLB_SIG_UART_CTS 0x1
#define BFLB_SIG_UART_TXD 0x2
#define BFLB_SIG_UART_RXD 0x3
#define BFLB_SIG_UART_LEN 0x4
#define BFLB_SIG_UART_MASK 0x3

/**
* @brief helper macro to encode an IO port pin in a numerical format
*
* - fun Function value. It should be lower case value defined by a
* BFLB_FUN_function.
* - pin Pin number.
*
* ex.: How to define uart0 rx/tx pins, which is define as BFLB_FUN_uart0
*
* bflb,pins = <BFLB_PIN(uart0, 7)>,
* <BFLB_PIN(uart0, 16)>;
*/
#define BFLB_PIN(fun, pin) &glb BFLB_FUN_##fun pin

#define BFLB_FUN_2_FUNC(fun) (((fun) >> BFLB_FUN_FUNC_POS) & BFLB_FUN_FUNC_MASK)
#define BFLB_FUN_2_MODE(fun) (((fun) >> BFLB_FUN_MODE_POS) & BFLB_FUN_MODE_MASK)
#define BFLB_FUN_2_INST(fun) (((fun) >> BFLB_FUN_INST_POS) & BFLB_FUN_INST_MASK)

/*
* Pin configuration is coded following below bit fields:
* - GPIO Mode [ 0 : 1 ]
* - GPIO Schmitt Trigger [ 2 ]
* - GPIO Drive Strength [ 3 : 4 ]
*/

/* GPIO Pull-up/pull-down/High impedance */
#define BFLB_GPIO_MODE_POS 0U
#define BFLB_GPIO_MODE_MASK 0x3
#define BFLB_GPIO_MODE_HIGH_IMPEDANCE (0x0 << BFLB_GPIO_MODE_POS)
#define BFLB_GPIO_MODE_PULL_UP (0x1 << BFLB_GPIO_MODE_POS)
#define BFLB_GPIO_MODE_PULL_DOWN (0x2 << BFLB_GPIO_MODE_POS)
#define BFLB_CFG_2_GPIO_MODE(cfg) (((cfg) >> BFLB_GPIO_MODE_POS) & BFLB_GPIO_MODE_MASK)

/* GPIO Input Schmitt trigger */
#define BFLB_GPIO_INP_SMT_POS 2U
#define BFLB_GPIO_INP_SMT_MASK 0x1
#define BFLB_GPIO_INP_SMT_EN (0x1 << BFLB_GPIO_INP_SMT_POS)
#define BFLB_CFG_2_GPIO_INP_SMT(cfg) (((cfg) >> BFLB_GPIO_INP_SMT_POS) & BFLB_GPIO_INP_SMT_MASK)

/* GPIO Output Drive Strength */
#define BFLB_GPIO_DRV_STR_POS 3U
#define BFLB_GPIO_DRV_STR_MASK 0x3
#define BFLB_CFG_2_GPIO_DRV_STR(cfg) (((cfg) >> BFLB_GPIO_DRV_STR_POS) & BFLB_GPIO_DRV_STR_MASK)

#endif /* ZEPHYR_BFLB_PINCTRL_H_ */
13 changes: 13 additions & 0 deletions modules/hal_bouffalolab/include/bflb_gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2021 Gerson Fernando Budke <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_HAL_BFLB_GPIO_H_
#define ZEPHYR_HAL_BFLB_GPIO_H_

#ifdef CONFIG_SOC_SERIES_BL6
#include <bl602_gpio.h>
#endif

#endif /* ZEPHYR_HAL_BFLB_GPIO_H_ */
Loading