serial: stm32: Add setparity support
authorPatrick Delaunay <patrick.delaunay@st.com>
Thu, 17 May 2018 12:50:45 +0000 (14:50 +0200)
committerTom Rini <trini@konsulko.com>
Sat, 26 May 2018 22:19:18 +0000 (18:19 -0400)
Add possibility to update the serial parity used.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
drivers/serial/serial_stm32.c
drivers/serial/serial_stm32.h

index eeaa8ab050d912bc5f11d4e636b13c191bc26651..f26234549c3e18ee18b7d532ac707c379dd83067 100644 (file)
@@ -47,6 +47,45 @@ static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
        return 0;
 }
 
+static int stm32_serial_setparity(struct udevice *dev, enum serial_par parity)
+{
+       struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
+       bool stm32f4 = plat->uart_info->stm32f4;
+       u8 uart_enable_bit = plat->uart_info->uart_enable_bit;
+       u32 cr1 = plat->base + CR1_OFFSET(stm32f4);
+       u32 config = 0;
+
+       if (stm32f4)
+               return -EINVAL; /* not supported in driver*/
+
+       clrbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit));
+       /* update usart configuration (uart need to be disable)
+        * PCE: parity check control
+        * PS : '0' : Even / '1' : Odd
+        * M[1:0] = '00' : 8 Data bits
+        * M[1:0] = '01' : 9 Data bits with parity
+        */
+       switch (parity) {
+       default:
+       case SERIAL_PAR_NONE:
+               config = 0;
+               break;
+       case SERIAL_PAR_ODD:
+               config = USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0;
+               break;
+       case SERIAL_PAR_EVEN:
+               config = USART_CR1_PCE | USART_CR1_M0;
+               break;
+       }
+       clrsetbits_le32(cr1,
+                       USART_CR1_PCE | USART_CR1_PS | USART_CR1_M1 |
+                       USART_CR1_M0,
+                       config);
+       setbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit));
+
+       return 0;
+}
+
 static int stm32_serial_getc(struct udevice *dev)
 {
        struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
@@ -57,9 +96,10 @@ static int stm32_serial_getc(struct udevice *dev)
        if ((isr & USART_ISR_RXNE) == 0)
                return -EAGAIN;
 
-       if (isr & (USART_ISR_ORE)) {
+       if (isr & (USART_ISR_PE | USART_ISR_ORE)) {
                if (!stm32f4)
-                       setbits_le32(base + ICR_OFFSET, USART_ICR_ORECF);
+                       setbits_le32(base + ICR_OFFSET,
+                                    USART_ICR_PCECF | USART_ICR_ORECF);
                else
                        readl(base + RDR_OFFSET(stm32f4));
                return -EIO;
@@ -170,6 +210,7 @@ static const struct dm_serial_ops stm32_serial_ops = {
        .pending = stm32_serial_pending,
        .getc = stm32_serial_getc,
        .setbrg = stm32_serial_setbrg,
+       .setparity = stm32_serial_setparity
 };
 
 U_BOOT_DRIVER(serial_stm32) = {
index c478e3507020179f64895a8218b3c42050260e05..ccafa31219a1b765b48ba255b9be13cac5996844 100644 (file)
@@ -13,6 +13,7 @@
 #define ISR_OFFSET(x)  (x ? 0x00 : 0x1c)
 
 #define ICR_OFFSET     0x20
+
 /*
  * STM32F4 has one Data Register (DR) for received or transmitted
  * data, so map Receive Data Register (RDR) and Transmit Data
@@ -53,7 +54,11 @@ struct stm32x7_serial_platdata {
 };
 
 #define USART_CR1_FIFOEN               BIT(29)
+#define USART_CR1_M1                   BIT(28)
 #define USART_CR1_OVER8                        BIT(15)
+#define USART_CR1_M0                   BIT(12)
+#define USART_CR1_PCE                  BIT(10)
+#define USART_CR1_PS                   BIT(9)
 #define USART_CR1_TE                   BIT(3)
 #define USART_CR1_RE                   BIT(2)
 
@@ -62,10 +67,13 @@ struct stm32x7_serial_platdata {
 #define USART_ISR_TXE                  BIT(7)
 #define USART_ISR_RXNE                 BIT(5)
 #define USART_ISR_ORE                  BIT(3)
+#define USART_ISR_PE                   BIT(0)
 
 #define USART_BRR_F_MASK               GENMASK(7, 0)
 #define USART_BRR_M_SHIFT              4
 #define USART_BRR_M_MASK               GENMASK(15, 4)
 
 #define USART_ICR_ORECF                        BIT(3)
+#define USART_ICR_PCECF                        BIT(0)
+
 #endif