drivers: pinctrl: add driver for EOS S3
This adds a new pinctrl driver for Quicklogic EOS S3 SoC Signed-off-by: Wojciech Sipak <wsipak@antmicro.com>
This commit is contained in:
parent
b51dd4ade0
commit
bff69f5384
|
@ -33,3 +33,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_K3 pinctrl_ti_k3.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c)
|
||||
|
|
|
@ -62,5 +62,6 @@ source "drivers/pinctrl/Kconfig.ti_k3"
|
|||
source "drivers/pinctrl/Kconfig.emsdp"
|
||||
source "drivers/pinctrl/Kconfig.ti_cc32xx"
|
||||
source "drivers/pinctrl/Kconfig.numaker"
|
||||
source "drivers/pinctrl/Kconfig.eos_s3"
|
||||
|
||||
endif # PINCTRL
|
||||
|
|
9
drivers/pinctrl/Kconfig.eos_s3
Normal file
9
drivers/pinctrl/Kconfig.eos_s3
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config PINCTRL_QUICKLOGIC_EOS_S3
|
||||
bool "QuickLogic EOS S3 SoC pinctrl driver"
|
||||
default y
|
||||
depends on DT_HAS_QUICKLOGIC_EOS_S3_PINCTRL_ENABLED
|
||||
help
|
||||
Enable driver for the QuickLogic EOS S3 SoC pinctrl driver
|
128
drivers/pinctrl/pinctrl_eos_s3.c
Normal file
128
drivers/pinctrl/pinctrl_eos_s3.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT quicklogic_eos_s3_pinctrl
|
||||
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h>
|
||||
#include <soc.h>
|
||||
|
||||
LOG_MODULE_REGISTER(pinctrl_eos_s3, CONFIG_PINCTRL_LOG_LEVEL);
|
||||
|
||||
#define FUNCTION_REGISTER(func) (func >> 13)
|
||||
#define PAD_FUNC_SEL_MASK GENMASK(2, 0)
|
||||
#define PAD_CTRL_SEL_BIT0 3
|
||||
#define PAD_CTRL_SEL_BIT1 4
|
||||
#define PAD_OUTPUT_EN_BIT 5
|
||||
#define PAD_PULL_UP_BIT 6
|
||||
#define PAD_PULL_DOWN_BIT 7
|
||||
#define PAD_DRIVE_STRENGTH_BIT0 8
|
||||
#define PAD_DRIVE_STRENGTH_BIT1 9
|
||||
#define PAD_SLEW_RATE_BIT 10
|
||||
#define PAD_INPUT_EN_BIT 11
|
||||
#define PAD_SCHMITT_EN_BIT 12
|
||||
|
||||
/*
|
||||
* Program IOMUX_func_SEL register.
|
||||
*/
|
||||
static int pinctrl_eos_s3_input_selection(uint32_t pin, uint32_t sel_reg)
|
||||
{
|
||||
volatile uint32_t *reg = (uint32_t *)IO_MUX_BASE;
|
||||
|
||||
if (sel_reg <= IO_MUX_MAX_PAD_NR || sel_reg > IO_MUX_REG_MAX_OFFSET) {
|
||||
return -EINVAL;
|
||||
}
|
||||
reg += sel_reg;
|
||||
*reg = pin;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Program IOMUX_PAD_x_CTRL register.
|
||||
*/
|
||||
static int pinctrl_eos_s3_set(uint32_t pin, uint32_t func)
|
||||
{
|
||||
volatile uint32_t *reg = (uint32_t *)IO_MUX_BASE;
|
||||
|
||||
if (pin > IO_MUX_REG_MAX_OFFSET) {
|
||||
return -EINVAL;
|
||||
}
|
||||
reg += pin;
|
||||
*reg = func;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pinctrl_eos_s3_configure_pin(const pinctrl_soc_pin_t *pin)
|
||||
{
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
/* Set function. */
|
||||
reg_value |= (pin->iof & PAD_FUNC_SEL_MASK);
|
||||
|
||||
/* Output enable is active low. */
|
||||
WRITE_BIT(reg_value, PAD_OUTPUT_EN_BIT, pin->output_enable ? 0 : 1);
|
||||
|
||||
/* These are active high. */
|
||||
WRITE_BIT(reg_value, PAD_INPUT_EN_BIT, pin->input_enable);
|
||||
WRITE_BIT(reg_value, PAD_SLEW_RATE_BIT, pin->slew_rate);
|
||||
WRITE_BIT(reg_value, PAD_SCHMITT_EN_BIT, pin->schmitt_enable);
|
||||
WRITE_BIT(reg_value, PAD_CTRL_SEL_BIT0, pin->control_selection & BIT(0));
|
||||
WRITE_BIT(reg_value, PAD_CTRL_SEL_BIT1, pin->control_selection & BIT(1));
|
||||
|
||||
switch (pin->drive_strength) {
|
||||
case 2:
|
||||
WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 0);
|
||||
WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 0);
|
||||
break;
|
||||
case 4:
|
||||
WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 1);
|
||||
WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 0);
|
||||
break;
|
||||
case 8:
|
||||
WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 0);
|
||||
WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 1);
|
||||
break;
|
||||
case 12:
|
||||
WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 1);
|
||||
WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 1);
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Selected drive-strength is not supported: %d\n", pin->drive_strength);
|
||||
}
|
||||
|
||||
/* Enable pull-up by default; overwrite if any setting was chosen. */
|
||||
WRITE_BIT(reg_value, PAD_PULL_UP_BIT, 1);
|
||||
WRITE_BIT(reg_value, PAD_PULL_DOWN_BIT, 0);
|
||||
if (pin->high_impedance) {
|
||||
WRITE_BIT(reg_value, PAD_PULL_UP_BIT, 0);
|
||||
} else if (pin->pull_up | pin->pull_down) {
|
||||
WRITE_BIT(reg_value, PAD_PULL_UP_BIT, pin->pull_up);
|
||||
WRITE_BIT(reg_value, PAD_PULL_DOWN_BIT, pin->pull_down);
|
||||
}
|
||||
|
||||
/* Program registers. */
|
||||
pinctrl_eos_s3_set(pin->pin, reg_value);
|
||||
if (pin->input_enable && FUNCTION_REGISTER(pin->iof)) {
|
||||
pinctrl_eos_s3_input_selection(pin->pin, FUNCTION_REGISTER(pin->iof));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
|
||||
{
|
||||
ARG_UNUSED(reg);
|
||||
|
||||
for (int i = 0; i < pin_cnt; i++) {
|
||||
pinctrl_eos_s3_configure_pin(&pins[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -7,6 +7,7 @@ menuconfig UART_PL011
|
|||
depends on DT_HAS_ARM_PL011_ENABLED || DT_HAS_ARM_SBSA_UART_ENABLED
|
||||
select SERIAL_HAS_DRIVER
|
||||
select SERIAL_SUPPORT_INTERRUPT
|
||||
select PINCTRL if SOC_EOS_S3
|
||||
help
|
||||
This option enables the UART driver for the PL011
|
||||
|
||||
|
|
|
@ -8,5 +8,6 @@ config UART_QUICKLOGIC_USBSERIALPORT_S3B
|
|||
default y
|
||||
depends on DT_HAS_QUICKLOGIC_USBSERIALPORT_S3B_ENABLED
|
||||
select SERIAL_HAS_DRIVER
|
||||
select PINCTRL
|
||||
help
|
||||
This option enables the QuickLogic USBserialport_S3B serial driver.
|
||||
|
|
|
@ -64,6 +64,11 @@
|
|||
pin-secondary-config = <0x00>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@40004c00 {
|
||||
compatible = "quicklogic,eos-s3-pinctrl";
|
||||
reg = <0x40004c00 0x1b0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
75
dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml
Normal file
75
dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
Quicklogic EOS S3 IO MUX binding covers the 46 IOMUX_PAD_x_CTRL registers
|
||||
that can be used to set the direction and the function of a pad.
|
||||
|
||||
Device pin configuration should be placed in the child nodes of this node.
|
||||
Populate the 'pinmux' field with IO function and pin number.
|
||||
|
||||
For example, setting pins 44 and 45 for use as UART would look like this:
|
||||
|
||||
#include <dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h>
|
||||
|
||||
&pinctrl {
|
||||
uart0_rx_default: uart0_rx_default {
|
||||
pinmux = <UART_RX_PAD45>;
|
||||
input-enable;
|
||||
};
|
||||
uart0_tx_default: uart0_tx_default {
|
||||
pinmux = <UART_TX_PAD44>;
|
||||
output-enable;
|
||||
};
|
||||
};
|
||||
|
||||
compatible: "quicklogic,eos-s3-pinctrl"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
child-binding:
|
||||
description: |
|
||||
This binding gives a base representation of the SiFive FE310 pins
|
||||
configuration.
|
||||
|
||||
include:
|
||||
- name: pincfg-node.yaml
|
||||
property-allowlist:
|
||||
- input-enable
|
||||
- output-enable
|
||||
- bias-pull-up
|
||||
- bias-pull-down
|
||||
- bias-high-impedance
|
||||
- input-schmitt-enable
|
||||
- drive-strength
|
||||
properties:
|
||||
pinmux:
|
||||
required: true
|
||||
type: array
|
||||
description: |
|
||||
Quicklogic EOS S3 pin's configuration (pin, IO function).
|
||||
slew-rate:
|
||||
description: |
|
||||
The default value "slow" matches the power-on reset value.
|
||||
default: "slow"
|
||||
type: string
|
||||
enum:
|
||||
- "slow"
|
||||
- "fast"
|
||||
quicklogic,control-selection:
|
||||
description: |
|
||||
Control selection for IO output.
|
||||
It's either controlled from registers of the A0 always-on domain,
|
||||
fabric-controlled for signaling with FPGA,
|
||||
or other-controller for bidirectional signals.
|
||||
The default value "a0registers" matches the power-on reset value.
|
||||
default: "a0registers"
|
||||
type: string
|
||||
enum:
|
||||
- "a0registers"
|
||||
- "others"
|
||||
- "fabric"
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_
|
||||
#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_
|
||||
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
|
||||
#define IO_MUX_REG_MAX_OFFSET 107
|
||||
#define IO_MUX_MAX_PAD_NR 45
|
||||
|
||||
#define FUNC_SEL_UART_RX (77 << 13)
|
||||
|
||||
#define QUICKLOGIC_EOS_S3_PINMUX(pin, fun) (pin) (fun)
|
||||
|
||||
#define UART_TX_PAD44 QUICKLOGIC_EOS_S3_PINMUX(44, 0x3)
|
||||
#define UART_RX_PAD45 QUICKLOGIC_EOS_S3_PINMUX(45, FUNC_SEL_UART_RX | BIT(2))
|
||||
#define USB_PU_CTRL_PAD23 QUICKLOGIC_EOS_S3_PINMUX(23, 0x0)
|
||||
#define USB_DN_PAD28 QUICKLOGIC_EOS_S3_PINMUX(28, 0x0)
|
||||
#define USB_DP_PAD31 QUICKLOGIC_EOS_S3_PINMUX(31, 0x0)
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_ */
|
55
soc/arm/quicklogic_eos_s3/pinctrl_soc.h
Normal file
55
soc/arm/quicklogic_eos_s3/pinctrl_soc.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_
|
||||
#define ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_
|
||||
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct pinctrl_soc_pin_t {
|
||||
uint32_t pin;
|
||||
uint32_t iof;
|
||||
uint32_t input_enable: 1;
|
||||
uint32_t output_enable: 1;
|
||||
uint32_t pull_up: 1;
|
||||
uint32_t pull_down: 1;
|
||||
uint32_t high_impedance: 1;
|
||||
uint32_t slew_rate: 2;
|
||||
uint8_t drive_strength;
|
||||
uint32_t schmitt_enable: 1;
|
||||
uint32_t control_selection: 2;
|
||||
} pinctrl_soc_pin_t;
|
||||
|
||||
#define QUICKLOGIC_EOS_S3_DT_PIN(node_id) \
|
||||
{ \
|
||||
.pin = DT_PROP_BY_IDX(node_id, pinmux, 0), \
|
||||
.iof = DT_PROP_BY_IDX(node_id, pinmux, 1), \
|
||||
.input_enable = DT_PROP(node_id, input_enable), \
|
||||
.output_enable = DT_PROP(node_id, output_enable), \
|
||||
.pull_up = DT_PROP(node_id, bias_pull_up), \
|
||||
.pull_down = DT_PROP(node_id, bias_pull_down), \
|
||||
.high_impedance = DT_PROP(node_id, bias_high_impedance), \
|
||||
.slew_rate = DT_ENUM_IDX(node_id, slew_rate), \
|
||||
.drive_strength = DT_PROP_OR(node_id, drive_strength, 4), \
|
||||
.schmitt_enable = DT_PROP(node_id, input_schmitt_enable), \
|
||||
.control_selection = DT_ENUM_IDX(node_id, quicklogic_control_selection), \
|
||||
},
|
||||
|
||||
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \
|
||||
QUICKLOGIC_EOS_S3_DT_PIN(DT_PROP_BY_IDX(node_id, prop, idx))
|
||||
|
||||
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
|
||||
{ DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_ */
|
Loading…
Reference in a new issue