Skip to content

Commit 120691a

Browse files
asmellbykartben
authored andcommitted
drivers: pinctrl: silabs: Add support for analog bus allocation
The GPIO peripheral on Silabs Series 2 devices is responsible for allocating analog buses to analog peripherals. Enable support for this in the pinctrl driver. Since these bus allocations are not digital pins, introduce a new property silabs,analog-bus for this purpose. Signed-off-by: Aksel Skauge Mellbye <[email protected]>
1 parent 4195130 commit 120691a

File tree

9 files changed

+91
-13
lines changed

9 files changed

+91
-13
lines changed

drivers/pinctrl/pinctrl_silabs_dbus.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#define DT_DRV_COMPAT silabs_dbus_pinctrl
1313
#define PIN_MASK 0xF0000UL
14+
#define ABUS_MASK(i) GENMASK(((i) * 8) + 3, (i) * 8)
1415

1516
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
1617
{
@@ -19,16 +20,26 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp
1920
for (uint8_t i = 0U; i < pin_cnt; i++) {
2021
mem_addr_t enable_reg, route_reg;
2122

23+
/* Configure ABUS */
24+
if (pins[i].en_bit == SILABS_PINCTRL_ANALOG) {
25+
enable_reg = DT_INST_REG_ADDR_BY_NAME(0, abus) +
26+
(pins[i].base_offset * sizeof(mem_addr_t));
27+
sys_write32(FIELD_PREP(ABUS_MASK(pins[i].mode), pins[i].route_offset),
28+
enable_reg);
29+
continue;
30+
}
31+
2232
/* Configure GPIO */
2333
GPIO_PinModeSet(pins[i].port, pins[i].pin, pins[i].mode, pins[i].dout);
2434

2535
/* Configure DBUS */
26-
enable_reg = DT_INST_REG_ADDR(0) + (pins[i].base_offset * sizeof(mem_addr_t));
36+
enable_reg = DT_INST_REG_ADDR_BY_NAME(0, dbus) +
37+
(pins[i].base_offset * sizeof(mem_addr_t));
2738
route_reg = enable_reg + (pins[i].route_offset * sizeof(mem_addr_t));
2839

2940
sys_write32(pins[i].port | FIELD_PREP(PIN_MASK, pins[i].pin), route_reg);
3041

31-
if (pins[i].en_bit != 0xFFU) {
42+
if (pins[i].en_bit != SILABS_PINCTRL_UNUSED) {
3243
sys_set_bit(enable_reg, pins[i].en_bit);
3344
}
3445
}

dts/arm/silabs/efr32bg2x.dtsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@
337337

338338
pinctrl: pin-controller@5003c440 {
339339
compatible = "silabs,dbus-pinctrl";
340-
reg = <0x5003c440 0xbc0>;
340+
reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>;
341+
reg-names = "dbus", "abus";
341342
};
342343

343344
dma0: dma@40040000{

dts/arm/silabs/efr32mg21.dtsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@
315315

316316
pinctrl: pin-controller@5003c440 {
317317
compatible = "silabs,dbus-pinctrl";
318-
reg = <0x5003c440 0xbc0>;
318+
reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>;
319+
reg-names = "dbus", "abus";
319320
};
320321

321322
se: semailbox@5c000000 {

dts/arm/silabs/efr32mg24.dtsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@
388388

389389
pinctrl: pin-controller@5003c440 {
390390
compatible = "silabs,dbus-pinctrl";
391-
reg = <0x5003c440 0xbc0>;
391+
reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>;
392+
reg-names = "dbus", "abus";
392393
};
393394

394395
dma0: dma@40040000 {

dts/arm/silabs/efr32xg23.dtsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,8 @@
418418

419419
pinctrl: pin-controller@5003c440 {
420420
compatible = "silabs,dbus-pinctrl";
421-
reg = <0x5003c440 0xbc0>;
421+
reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>;
422+
reg-names = "dbus", "abus";
422423
};
423424

424425
dma0: dma@50040000{

dts/arm/silabs/xg29/xg29.dtsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@
315315

316316
pinctrl: pin-controller@5003c440 {
317317
compatible = "silabs,dbus-pinctrl";
318-
reg = <0x5003c440 0xbc0>;
318+
reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>;
319+
reg-names = "dbus", "abus";
319320
};
320321

321322
dma0: dma@40040000{

dts/bindings/pinctrl/silabs,dbus-pinctrl.yaml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ description: |
66
pin function selection and pin properties. For example, you can use this
77
node to route USART0 RX to pin PA1 and enable the pull-up resistor on the
88
pin. This pin controller is used for devices that use DBUS (Digital Bus)
9-
for alternate function configuration, including Series 2 devices.
9+
for alternate function configuration, including Series 2 devices. It is
10+
also capable of ABUS (Analog Bus) allocation.
1011
1112
The pinctrl settings are referenced in a device tree peripheral node. For
1213
example when configuring a USART:
@@ -81,6 +82,24 @@ description: |
8182
Allowed in drive-push-pull and
8283
drive-open-drain modes.
8384
85+
ABUS allocation is performed using the 'silabs,analog-bus' property. This
86+
property takes an array of buses to allocate. Example:
87+
88+
&pinctrl {
89+
iadc0_default: iadc0_default {
90+
group0 {
91+
/* Allocate even bus 0 and odd bus 1 from GPIO port A for ADC use */
92+
silabs,analog-bus = <ABUS_AEVEN0_IADC0>, <ABUS_AODD1_IADC0>;
93+
}
94+
};
95+
};
96+
97+
A given group may contain a mix of analog bus allocations and digital pin
98+
selections. Digital pin properties only apply to digital pins. Analog input
99+
selection is not done through the pin controller, this is done in the devicetree
100+
node for the respective peripheral using properties such as 'zephyr,input-positive'
101+
for ADC.
102+
84103
compatible: "silabs,dbus-pinctrl"
85104

86105
include: base.yaml
@@ -107,7 +126,6 @@ child-binding:
107126

108127
properties:
109128
pins:
110-
required: true
111129
type: array
112130
description: |
113131
An array of pins sharing the same group properties. The pins should be
@@ -126,3 +144,10 @@ child-binding:
126144
for this pin. May be used in drive-push-pull and drive-open-drain
127145
modes.
128146
type: boolean
147+
148+
silabs,analog-bus:
149+
type: array
150+
description: |
151+
Assign one or more analog buses to the given GPIO port. The bus should
152+
be defined using the ABUS_<bus>_<peripheral> macros available from the
153+
SoC DeviceTree files.

include/zephyr/dt-bindings/pinctrl/silabs-pinctrl-dbus.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
/*
1212
* Silabs Series 2 DBUS configuration is encoded in a 32-bit bitfield organized as follows:
1313
*
14-
* 31..29: Reserved
14+
* 31 : Whether the configuration represents an analog pin
15+
* If digital (bit 31 == 0):
16+
* 30..29: Reserved
1517
* 28..24: Route register offset in words from peripheral config (offset of <fun>ROUTE
1618
* register in GPIO_<periph>ROUTE_TypeDef)
1719
* 23..19: Enable bit (offset into ROUTEEN register for given function)
@@ -20,6 +22,11 @@
2022
* register in GPIO_TypeDef minus offset of first route register [DBGROUTEPEN, 0x440])
2123
* 7..4 : GPIO pin
2224
* 3..0 : GPIO port
25+
* If analog (bit 31 == 1):
26+
* 15..14: Bus selection (A, B, CD)
27+
* 13..12: Bus selection (EVEN0, EVEN1, ODD0, ODD1)
28+
* 11..8 : Peripheral selection (bit in GPIO_nBUSALLOC bitfield)
29+
* 7 ..0 : Reserved
2330
*/
2431

2532
#define SILABS_PINCTRL_GPIO_PORT_MASK 0x0000000FUL
@@ -29,6 +36,14 @@
2936
#define SILABS_PINCTRL_EN_BIT_MASK 0x00F80000UL
3037
#define SILABS_PINCTRL_ROUTE_MASK 0x1F000000UL
3138

39+
#define SILABS_PINCTRL_ANALOG_MASK 0x80000000UL
40+
#define SILABS_PINCTRL_ABUS_BUS_MASK 0x0000C000UL
41+
#define SILABS_PINCTRL_ABUS_PARITY_MASK 0x00003000UL
42+
#define SILABS_PINCTRL_ABUS_PERIPH_MASK 0x00000F00UL
43+
44+
#define SILABS_PINCTRL_UNUSED 0xFF
45+
#define SILABS_PINCTRL_ANALOG 0xAA
46+
3247
#define SILABS_DBUS(port, pin, periph_base, en_present, en_bit, route) \
3348
(FIELD_PREP(SILABS_PINCTRL_GPIO_PORT_MASK, port) | \
3449
FIELD_PREP(SILABS_PINCTRL_GPIO_PIN_MASK, pin) | \
@@ -37,4 +52,10 @@
3752
FIELD_PREP(SILABS_PINCTRL_EN_BIT_MASK, en_bit) | \
3853
FIELD_PREP(SILABS_PINCTRL_ROUTE_MASK, route))
3954

55+
#define SILABS_ABUS(bus, parity, peripheral) \
56+
(FIELD_PREP(SILABS_PINCTRL_ANALOG_MASK, 1) | \
57+
FIELD_PREP(SILABS_PINCTRL_ABUS_BUS_MASK, bus) | \
58+
FIELD_PREP(SILABS_PINCTRL_ABUS_PARITY_MASK, parity) | \
59+
FIELD_PREP(SILABS_PINCTRL_ABUS_PERIPH_MASK, peripheral))
60+
4061
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_SILABS_PINCTRL_DBUS_H_ */

soc/silabs/common/pinctrl_soc.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,30 @@ typedef struct pinctrl_soc_pin {
7373
.en_bit = \
7474
(FIELD_GET(SILABS_PINCTRL_HAVE_EN_MASK, DT_PROP_BY_IDX(node, prop, idx)) \
7575
? FIELD_GET(SILABS_PINCTRL_EN_BIT_MASK, DT_PROP_BY_IDX(node, prop, idx)) \
76-
: 0xFF), \
76+
: SILABS_PINCTRL_UNUSED), \
7777
.route_offset = FIELD_GET(SILABS_PINCTRL_ROUTE_MASK, DT_PROP_BY_IDX(node, prop, idx)), \
7878
.mode = Z_PINCTRL_SILABS_MODE_INIT(node), \
7979
.dout = Z_PINCTRL_SILABS_DOUT_INIT(node)},
8080

81+
#define Z_PINCTRL_STATE_ABUS_INIT(node, prop, idx) \
82+
{ \
83+
.base_offset = \
84+
FIELD_GET(SILABS_PINCTRL_ABUS_BUS_MASK, DT_PROP_BY_IDX(node, prop, idx)), \
85+
.route_offset = FIELD_GET(SILABS_PINCTRL_ABUS_PERIPH_MASK, \
86+
DT_PROP_BY_IDX(node, prop, idx)), \
87+
.en_bit = SILABS_PINCTRL_ANALOG, \
88+
.mode = FIELD_GET(SILABS_PINCTRL_ABUS_PARITY_MASK, \
89+
DT_PROP_BY_IDX(node, prop, idx)), \
90+
},
91+
92+
#define Z_PINCTRL_SILABS_DISPATCH(group) \
93+
IF_ENABLED(DT_NODE_HAS_PROP(group, pins), \
94+
(DT_FOREACH_PROP_ELEM(group, pins, Z_PINCTRL_STATE_PIN_INIT))) \
95+
IF_ENABLED(DT_NODE_HAS_PROP(group, silabs_analog_bus), \
96+
(DT_FOREACH_PROP_ELEM(group, silabs_analog_bus, Z_PINCTRL_STATE_ABUS_INIT)))
97+
8198
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
82-
{DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pins, \
83-
Z_PINCTRL_STATE_PIN_INIT)}
99+
{DT_FOREACH_CHILD(DT_PHANDLE(node_id, prop), Z_PINCTRL_SILABS_DISPATCH)}
84100

85101
#else
86102

0 commit comments

Comments
 (0)