diff --git a/boards/arm/efm32pg_stk3402a/Kconfig.defconfig b/boards/arm/efm32pg_stk3402a/Kconfig.defconfig index c673513723e..1a8bd748961 100644 --- a/boards/arm/efm32pg_stk3402a/Kconfig.defconfig +++ b/boards/arm/efm32pg_stk3402a/Kconfig.defconfig @@ -38,13 +38,6 @@ config GPIO_GECKO_PORTF endif # GPIO_GECKO -if LEUART_GECKO - -config LEUART_GECKO_0 - default y - -endif # LEUART_GECKO - if I2C_GECKO config I2C_0 diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.dts b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.dts index ce84043078a..dd6d6fdde7e 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.dts +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.dts @@ -62,7 +62,8 @@ &leuart0 { current-speed = <9600>; - location = <18>; + location-rx = ; + location-tx = ; status = "ok"; }; diff --git a/boards/arm/efr32mg_sltb004a/Kconfig.defconfig b/boards/arm/efr32mg_sltb004a/Kconfig.defconfig index 89f5a6b02a3..611acca4a00 100644 --- a/boards/arm/efr32mg_sltb004a/Kconfig.defconfig +++ b/boards/arm/efr32mg_sltb004a/Kconfig.defconfig @@ -29,13 +29,6 @@ config GPIO_GECKO_PORTF endif # GPIO_GECKO -if LEUART_GECKO - -config LEUART_GECKO_0 - default y - -endif # LEUART_GECKO - if I2C_GECKO config I2C_0 diff --git a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts index 5c8f24c9b95..054a2b6f2e6 100644 --- a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts +++ b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts @@ -61,7 +61,8 @@ &leuart0 { current-speed = <9600>; - location = <27>; + location-rx = ; + location-tx = ; status = "ok"; }; diff --git a/drivers/serial/Kconfig.leuart_gecko b/drivers/serial/Kconfig.leuart_gecko index e7ccbf74546..39aa5da1a4b 100644 --- a/drivers/serial/Kconfig.leuart_gecko +++ b/drivers/serial/Kconfig.leuart_gecko @@ -5,7 +5,7 @@ # SPDX-License-Identifier: Apache-2.0 # -menuconfig LEUART_GECKO +config LEUART_GECKO bool "Gecko leuart driver" depends on HAS_SILABS_GECKO depends on GPIO_GECKO @@ -14,19 +14,3 @@ menuconfig LEUART_GECKO select SOC_GECKO_LEUART help Enable the Gecko leuart driver. - -if LEUART_GECKO - -config LEUART_GECKO_0 - bool "Enable Gecko Low Energy UART 0" - help - Enable support for Gecko LEUART0 port in the driver. Say y here if you - want to use LEUART0 device. - -config LEUART_GECKO_1 - bool "Enable Gecko Low Energy UART 1" - help - Enable support for Gecko LEUART1 port in the driver. Say y here if you - want to use LEUART1 device. - -endif # LEUART_GECKO diff --git a/drivers/serial/leuart_gecko.c b/drivers/serial/leuart_gecko.c index 819d20a88f1..855aab69c3b 100644 --- a/drivers/serial/leuart_gecko.c +++ b/drivers/serial/leuart_gecko.c @@ -22,11 +22,16 @@ struct leuart_gecko_config { LEUART_TypeDef *base; CMU_Clock_TypeDef clock; u32_t baud_rate; - struct soc_gpio_pin pin_rx; - struct soc_gpio_pin pin_tx; - unsigned int loc; #ifdef CONFIG_UART_INTERRUPT_DRIVEN void (*irq_config_func)(struct device *dev); +#endif + struct soc_gpio_pin pin_rx; + struct soc_gpio_pin pin_tx; +#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION + u8_t loc_rx; + u8_t loc_tx; +#else + u8_t loc; #endif }; @@ -238,18 +243,14 @@ static void leuart_gecko_init_pins(struct device *dev) soc_gpio_configure(&config->pin_rx); soc_gpio_configure(&config->pin_tx); -#ifdef _LEUART_ROUTEPEN_MASK +#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION base->ROUTEPEN = LEUART_ROUTEPEN_RXPEN | LEUART_ROUTEPEN_TXPEN; - base->ROUTELOC0 = (base->ROUTELOC0 - & ~(_LEUART_ROUTELOC0_TXLOC_MASK - | _LEUART_ROUTELOC0_RXLOC_MASK)) - | (config->loc << - _LEUART_ROUTELOC0_TXLOC_SHIFT) - | (config->loc << - _LEUART_ROUTELOC0_RXLOC_SHIFT); + base->ROUTELOC0 = + (config->loc_tx << _LEUART_ROUTELOC0_TXLOC_SHIFT) | + (config->loc_rx << _LEUART_ROUTELOC0_RXLOC_SHIFT); #else base->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN - | (config->loc << 8); + | (config->loc << 8); #endif } @@ -265,15 +266,15 @@ static int leuart_gecko_init(struct device *dev) leuartInit.baudrate = config->baud_rate; - /* Enable LEUART clock */ - CMU_ClockEnable(config->clock, true); - /* Enable CORE LE clock in order to access LE modules */ CMU_ClockEnable(cmuClock_CORELE, true); /* Select LFXO for LEUARTs (and wait for it to stabilize) */ CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO); + /* Enable LEUART clock */ + CMU_ClockEnable(config->clock, true); + /* Init LEUART */ LEUART_Init(base, &leuartInit); @@ -309,19 +310,33 @@ static const struct uart_driver_api leuart_gecko_driver_api = { #endif }; -#ifdef CONFIG_LEUART_GECKO_0 +#ifdef DT_SILABS_GECKO_LEUART_0 + +#define PIN_LEUART_0_RXD {DT_SILABS_GECKO_LEUART_0_LOCATION_RX_1, \ + DT_SILABS_GECKO_LEUART_0_LOCATION_RX_2, gpioModeInput, 1} +#define PIN_LEUART_0_TXD {DT_SILABS_GECKO_LEUART_0_LOCATION_TX_1, \ + DT_SILABS_GECKO_LEUART_0_LOCATION_TX_2, gpioModePushPull, 1} #ifdef CONFIG_UART_INTERRUPT_DRIVEN static void leuart_gecko_config_func_0(struct device *dev); #endif static const struct leuart_gecko_config leuart_gecko_0_config = { - .base = (LEUART_TypeDef *)DT_SILABS_GECKO_LEUART_LEUART_0_BASE_ADDRESS, + .base = (LEUART_TypeDef *)DT_SILABS_GECKO_LEUART_0_BASE_ADDRESS, .clock = cmuClock_LEUART0, - .baud_rate = DT_SILABS_GECKO_LEUART_LEUART_0_CURRENT_SPEED, - .pin_rx = PIN_LEUART0_RXD, - .pin_tx = PIN_LEUART0_TXD, - .loc = DT_SILABS_GECKO_LEUART_LEUART_0_LOCATION, + .baud_rate = DT_SILABS_GECKO_LEUART_0_CURRENT_SPEED, + .pin_rx = PIN_LEUART_0_RXD, + .pin_tx = PIN_LEUART_0_TXD, +#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION + .loc_rx = DT_SILABS_GECKO_LEUART_0_LOCATION_RX_0, + .loc_tx = DT_SILABS_GECKO_LEUART_0_LOCATION_TX_0, +#else +#if DT_SILABS_GECKO_LEUART_0_LOCATION_RX_0 \ + != DT_SILABS_GECKO_LEUART_0_LOCATION_TX_0 +#error LEUART_0 DTS location-* properties must have identical value +#endif + .loc = DT_SILABS_GECKO_LEUART_0_LOCATION_RX_0, +#endif #ifdef CONFIG_UART_INTERRUPT_DRIVEN .irq_config_func = leuart_gecko_config_func_0, #endif @@ -329,7 +344,7 @@ static const struct leuart_gecko_config leuart_gecko_0_config = { static struct leuart_gecko_data leuart_gecko_0_data; -DEVICE_AND_API_INIT(leuart_0, DT_SILABS_GECKO_LEUART_LEUART_0_LABEL, +DEVICE_AND_API_INIT(leuart_0, DT_SILABS_GECKO_LEUART_0_LABEL, &leuart_gecko_init, &leuart_gecko_0_data, &leuart_gecko_0_config, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, @@ -338,29 +353,43 @@ DEVICE_AND_API_INIT(leuart_0, DT_SILABS_GECKO_LEUART_LEUART_0_LABEL, #ifdef CONFIG_UART_INTERRUPT_DRIVEN static void leuart_gecko_config_func_0(struct device *dev) { - IRQ_CONNECT(DT_SILABS_GECKO_LEUART_LEUART_0_IRQ, - DT_SILABS_GECKO_LEUART_LEUART_0_IRQ_PRIORITY, + IRQ_CONNECT(DT_SILABS_GECKO_LEUART_0_IRQ_0, + DT_SILABS_GECKO_LEUART_0_IRQ_0_PRIORITY, leuart_gecko_isr, DEVICE_GET(leuart_0), 0); - irq_enable(DT_SILABS_GECKO_LEUART_LEUART_0_IRQ); + irq_enable(DT_SILABS_GECKO_LEUART_0_IRQ_0); } #endif -#endif /* CONFIG_LEUART_GECKO_0 */ +#endif /* DT_SILABS_GECKO_LEUART_0 */ -#ifdef CONFIG_LEUART_GECKO_1 +#ifdef DT_SILABS_GECKO_LEUART_1 + +#define PIN_LEUART_1_RXD {DT_SILABS_GECKO_LEUART_1_LOCATION_RX_1, \ + DT_SILABS_GECKO_LEUART_1_LOCATION_RX_2, gpioModeInput, 1} +#define PIN_LEUART_1_TXD {DT_SILABS_GECKO_LEUART_1_LOCATION_TX_1, \ + DT_SILABS_GECKO_LEUART_1_LOCATION_TX_2, gpioModePushPull, 1} #ifdef CONFIG_UART_INTERRUPT_DRIVEN static void leuart_gecko_config_func_1(struct device *dev); #endif static const struct leuart_gecko_config leuart_gecko_1_config = { - .base = (LEUART_TypeDef *)DT_SILABS_GECKO_LEUART_LEUART_1_BASE_ADDRESS, + .base = (LEUART_TypeDef *)DT_SILABS_GECKO_LEUART_1_BASE_ADDRESS, .clock = cmuClock_LEUART0, - .baud_rate = DT_SILABS_GECKO_LEUART_LEUART_1_CURRENT_SPEED, - .pin_rx = PIN_LEUART1_RXD, - .pin_tx = PIN_LEUART1_TXD, - .loc = DT_SILABS_GECKO_LEUART_LEUART_1_LOCATION, + .baud_rate = DT_SILABS_GECKO_LEUART_1_CURRENT_SPEED, + .pin_rx = PIN_LEUART_1_RXD, + .pin_tx = PIN_LEUART_1_TXD, +#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION + .loc_rx = DT_SILABS_GECKO_LEUART_1_LOCATION_RX_0, + .loc_tx = DT_SILABS_GECKO_LEUART_1_LOCATION_TX_0, +#else +#if DT_SILABS_GECKO_LEUART_1_LOCATION_RX_0 \ + != DT_SILABS_GECKO_LEUART_1_LOCATION_TX_0 +#error LEUART_1 DTS location-* properties must have identical value +#endif + .loc = DT_SILABS_GECKO_LEUART_1_LOCATION_RX_0, +#endif #ifdef CONFIG_UART_INTERRUPT_DRIVEN .irq_config_func = leuart_gecko_config_func_1, #endif @@ -368,7 +397,7 @@ static const struct leuart_gecko_config leuart_gecko_1_config = { static struct leuart_gecko_data leuart_gecko_1_data; -DEVICE_AND_API_INIT(leuart_1, DT_SILABS_GECKO_LEUART_LEUART_1_LABEL, +DEVICE_AND_API_INIT(leuart_1, DT_SILABS_GECKO_LEUART_1_LABEL, &leuart_gecko_init, &leuart_gecko_1_data, &leuart_gecko_1_config, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, @@ -377,12 +406,12 @@ DEVICE_AND_API_INIT(leuart_1, DT_SILABS_GECKO_LEUART_LEUART_1_LABEL, #ifdef CONFIG_UART_INTERRUPT_DRIVEN static void leuart_gecko_config_func_1(struct device *dev) { - IRQ_CONNECT(DT_SILABS_GECKO_LEUART_LEUART_1_IRQ, - DT_SILABS_GECKO_LEUART_LEUART_1_IRQ_PRIORITY, + IRQ_CONNECT(DT_SILABS_GECKO_LEUART_1_IRQ_0, + DT_SILABS_GECKO_LEUART_1_IRQ_0_PRIORITY, leuart_gecko_isr, DEVICE_GET(leuart_1), 0); - irq_enable(DT_SILABS_GECKO_LEUART_LEUART_1_IRQ); + irq_enable(DT_SILABS_GECKO_LEUART_1_IRQ_0); } #endif -#endif /* CONFIG_LEUART_GECKO_1 */ +#endif /* DT_SILABS_GECKO_LEUART_1 */ diff --git a/dts/arm/silabs/efm32hg.dtsi b/dts/arm/silabs/efm32hg.dtsi index dc4c094d292..0c556301ab5 100644 --- a/dts/arm/silabs/efm32hg.dtsi +++ b/dts/arm/silabs/efm32hg.dtsi @@ -53,6 +53,14 @@ label = "UART_1"; }; + leuart0: leuart@40084000 { /* LEUART0 */ + compatible = "silabs,gecko-leuart"; + reg = <0x40084000 0x400>; + interrupts = <10 0>; + status = "disabled"; + label = "LEUART_0"; + }; + gpio@40006100 { compatible = "silabs,efm32-gpio"; reg = <0x40006100 0xf00>; diff --git a/dts/arm/silabs/efm32pg12b.dtsi b/dts/arm/silabs/efm32pg12b.dtsi index 6ac51f23fc8..fa99a813744 100644 --- a/dts/arm/silabs/efm32pg12b.dtsi +++ b/dts/arm/silabs/efm32pg12b.dtsi @@ -26,7 +26,6 @@ }; aliases { - leuart-0 = &leuart0; i2c-0 = &i2c0; i2c-1 = &i2c1; }; diff --git a/dts/arm/silabs/efm32wg.dtsi b/dts/arm/silabs/efm32wg.dtsi index d7743499ac2..6cf43eee37e 100644 --- a/dts/arm/silabs/efm32wg.dtsi +++ b/dts/arm/silabs/efm32wg.dtsi @@ -80,6 +80,22 @@ label = "UART_4"; }; + leuart0: leuart@40084000 { /* LEUART0 */ + compatible = "silabs,gecko-leuart"; + reg = <0x40084000 0x400>; + interrupts = <24 0>; + status = "disabled"; + label = "LEUART_0"; + }; + + leuart1: leuart@40084400 { /* LEUART1 */ + compatible = "silabs,gecko-leuart"; + reg = <0x40084400 0x400>; + interrupts = <25 0>; + status = "disabled"; + label = "LEUART_1"; + }; + gpio@40006100 { compatible = "silabs,efm32-gpio"; reg = <0x40006100 0xf00>; diff --git a/dts/arm/silabs/efr32fg1p.dtsi b/dts/arm/silabs/efr32fg1p.dtsi index facff1f6ea8..e6e3c63ccc4 100644 --- a/dts/arm/silabs/efr32fg1p.dtsi +++ b/dts/arm/silabs/efr32fg1p.dtsi @@ -53,6 +53,14 @@ label = "USART_1"; }; + leuart0: leuart@4004a000 { /* LEUART0 */ + compatible = "silabs,gecko-leuart"; + reg = <0x4004a000 0x400>; + interrupts = <21 0>; + status = "disabled"; + label = "LEUART_0"; + }; + gpio: gpio@4000a400 { compatible = "silabs,efr32xg1-gpio"; reg = <0x4000a400 0xc00>; diff --git a/dts/arm/silabs/efr32mg.dtsi b/dts/arm/silabs/efr32mg.dtsi index 19c66893247..34465267358 100644 --- a/dts/arm/silabs/efr32mg.dtsi +++ b/dts/arm/silabs/efr32mg.dtsi @@ -20,7 +20,6 @@ }; aliases { - leuart-0 = &leuart0; i2c-0 = &i2c0; i2c-1 = &i2c1; }; diff --git a/dts/bindings/serial/silabs,gecko-leuart.yaml b/dts/bindings/serial/silabs,gecko-leuart.yaml index 953bbb9a669..fb5f31d00f1 100644 --- a/dts/bindings/serial/silabs,gecko-leuart.yaml +++ b/dts/bindings/serial/silabs,gecko-leuart.yaml @@ -27,9 +27,18 @@ properties: description: required interrupts generation: define - location: - type: int + # Note: Not all SoC series support setting individual pin location. If this + # is a case all location-* properties need to have identical value. + + location-rx: + type: array category: required - description: PIN location + description: RX pin configuration defined as + generation: define + + location-tx: + type: array + category: required + description: TX pin configuration defined as generation: define ... diff --git a/soc/arm/silabs_exx32/efm32pg12b/soc_pinmap.h b/soc/arm/silabs_exx32/efm32pg12b/soc_pinmap.h index 9f6e35d0795..448d4a63841 100644 --- a/soc/arm/silabs_exx32/efm32pg12b/soc_pinmap.h +++ b/soc/arm/silabs_exx32/efm32pg12b/soc_pinmap.h @@ -31,17 +31,6 @@ #endif #endif /* CONFIG_GPIO_GECKO */ -#ifdef CONFIG_LEUART_GECKO -#ifdef CONFIG_LEUART_GECKO_0 -#if (DT_SILABS_GECKO_LEUART_LEUART_0_LOCATION == 18) -#define PIN_LEUART0_TXD {gpioPortD, 10, gpioModePushPull, 1} -#define PIN_LEUART0_RXD {gpioPortD, 11, gpioModeInput, 1} -#else -#error ("Serial Driver for Gecko MCUs not implemented for this location index") -#endif -#endif /* CONFIG_LEUART_GECKO_0 */ -#endif /* CONFIG_LEUART_GECKO */ - #ifdef CONFIG_I2C_GECKO #ifdef CONFIG_I2C_0 #if (DT_SILABS_GECKO_I2C_I2C_0_LOCATION == 15) diff --git a/soc/arm/silabs_exx32/efr32mg12p/soc_pinmap.h b/soc/arm/silabs_exx32/efr32mg12p/soc_pinmap.h index 81a21a35420..148b6235e76 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/soc_pinmap.h +++ b/soc/arm/silabs_exx32/efr32mg12p/soc_pinmap.h @@ -30,17 +30,6 @@ #endif #endif /* CONFIG_GPIO_GECKO */ -#ifdef CONFIG_LEUART_GECKO -#ifdef CONFIG_LEUART_GECKO_0 -#if (DT_SILABS_GECKO_LEUART_LEUART_0_LOCATION == 27) -#define PIN_LEUART0_TXD {gpioPortF, 3, gpioModePushPull, 1} -#define PIN_LEUART0_RXD {gpioPortF, 4, gpioModeInput, 1} -#else -#error ("Serial Driver for Gecko MCUs not implemented for this location index") -#endif -#endif /* CONFIG_LEUART_GECKO_0 */ -#endif /* CONFIG_LEUART_GECKO */ - #ifdef CONFIG_I2C_GECKO #ifdef CONFIG_I2C_0 #if (DT_SILABS_GECKO_I2C_I2C_0_LOCATION == 15)