drivers: ps2: Standarize device tree and structure

Standardize PS2 device tree properties. Standardize device
structure usage. Abstract GIRQ and PCR register access.

Signed-off-by: Jay Vasanth <jay.vasanth@microchip.com>
This commit is contained in:
Jay Vasanth 2022-04-14 14:54:46 -04:00 committed by Maureen Helm
commit bacf4ff730
8 changed files with 136 additions and 154 deletions

View file

@ -39,16 +39,6 @@ config SYS_CLOCK_TICKS_PER_SEC
endif # RTOS_TIMER endif # RTOS_TIMER
if PS2
config PS2_XEC_0
default y
config PS2_XEC_1
default y
endif # PS2
config TACH_XEC config TACH_XEC
default y default y
depends on SENSOR depends on SENSOR

View file

@ -280,7 +280,7 @@ static int board_pinmux_init(const struct device *dev)
pinmux_pin_set(portb, MCHP_GPIO_073, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(portb, MCHP_GPIO_073, MCHP_GPIO_CTRL_MUX_F1);
#endif #endif
#ifdef CONFIG_PS2_XEC_0 #if DT_NODE_HAS_STATUS(DT_NODELABEL(ps2_0), okay)
/* Set muxing for PS20B*/ /* Set muxing for PS20B*/
mchp_pcr_periph_slp_ctrl(PCR_PS2_0, MCHP_PCR_SLEEP_DIS); mchp_pcr_periph_slp_ctrl(PCR_PS2_0, MCHP_PCR_SLEEP_DIS);
pinmux_pin_set(porta, MCHP_GPIO_007, MCHP_GPIO_CTRL_MUX_F2 | pinmux_pin_set(porta, MCHP_GPIO_007, MCHP_GPIO_CTRL_MUX_F2 |
@ -289,7 +289,7 @@ static int board_pinmux_init(const struct device *dev)
MCHP_GPIO_CTRL_BUFT_OPENDRAIN); MCHP_GPIO_CTRL_BUFT_OPENDRAIN);
#endif #endif
#ifdef CONFIG_PS2_XEC_1 #if DT_NODE_HAS_STATUS(DT_NODELABEL(ps2_1), okay)
/* Set muxing for PS21B*/ /* Set muxing for PS21B*/
mchp_pcr_periph_slp_ctrl(PCR_PS2_1, MCHP_PCR_SLEEP_DIS); mchp_pcr_periph_slp_ctrl(PCR_PS2_1, MCHP_PCR_SLEEP_DIS);
pinmux_pin_set(portd, MCHP_GPIO_154, MCHP_GPIO_CTRL_MUX_F2 | pinmux_pin_set(portd, MCHP_GPIO_154, MCHP_GPIO_CTRL_MUX_F2 |

View file

@ -39,16 +39,6 @@ config SYS_CLOCK_TICKS_PER_SEC
endif # RTOS_TIMER endif # RTOS_TIMER
if PS2
config PS2_XEC_0
default y
config PS2_XEC_1
default y
endif # PS2
if SPI if SPI
config SPI_XEC_QMSPI config SPI_XEC_QMSPI

View file

@ -270,7 +270,7 @@ static int board_pinmux_init(const struct device *dev)
pinmux_pin_set(portb, MCHP_GPIO_073, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(portb, MCHP_GPIO_073, MCHP_GPIO_CTRL_MUX_F1);
#endif #endif
#ifdef CONFIG_PS2_XEC_0 #if DT_NODE_HAS_STATUS(DT_NODELABEL(ps2_0), okay)
/* Set muxing for PS20B*/ /* Set muxing for PS20B*/
mchp_pcr_periph_slp_ctrl(PCR_PS2_0, MCHP_PCR_SLEEP_DIS); mchp_pcr_periph_slp_ctrl(PCR_PS2_0, MCHP_PCR_SLEEP_DIS);
pinmux_pin_set(porta, MCHP_GPIO_007, MCHP_GPIO_CTRL_MUX_F2 | pinmux_pin_set(porta, MCHP_GPIO_007, MCHP_GPIO_CTRL_MUX_F2 |
@ -279,7 +279,7 @@ static int board_pinmux_init(const struct device *dev)
MCHP_GPIO_CTRL_BUFT_OPENDRAIN); MCHP_GPIO_CTRL_BUFT_OPENDRAIN);
#endif #endif
#ifdef CONFIG_PS2_XEC_1 #if DT_NODE_HAS_STATUS(DT_NODELABEL(ps2_1), okay)
/* Set muxing for PS21B*/ /* Set muxing for PS21B*/
mchp_pcr_periph_slp_ctrl(PCR_PS2_1, MCHP_PCR_SLEEP_DIS); mchp_pcr_periph_slp_ctrl(PCR_PS2_1, MCHP_PCR_SLEEP_DIS);
pinmux_pin_set(portd, MCHP_GPIO_154, MCHP_GPIO_CTRL_MUX_F2 | pinmux_pin_set(portd, MCHP_GPIO_154, MCHP_GPIO_CTRL_MUX_F2 |

View file

@ -3,23 +3,9 @@
# Copyright (c) 2019 Intel Corporation # Copyright (c) 2019 Intel Corporation
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
menuconfig PS2_XEC config PS2_XEC
bool "XEC Microchip PS2 driver" bool "XEC Microchip PS2 driver"
depends on SOC_FAMILY_MEC && ESPI_PERIPHERAL_8042_KBC depends on SOC_FAMILY_MEC && ESPI_PERIPHERAL_8042_KBC
help help
Enable the Microchip XEC PS2 IO driver. The driver also Enable the Microchip XEC PS2 IO driver. The driver also
depends on the KBC 8042 keyboard controller. depends on the KBC 8042 keyboard controller.
if PS2_XEC
config PS2_XEC_0
bool "PS2_XEC_0"
help
Enable PS2 0.
config PS2_XEC_1
bool "PS2_XEC_1"
help
Enable PS2 1.
endif # PS2_XEC

View file

@ -1,11 +1,13 @@
/* /*
* Copyright (c) 2019 Intel Corporation * Copyright (c) 2019 Intel Corporation
* Copyright (c) 2022 Microchip Technology Inc.
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#define DT_DRV_COMPAT microchip_xec_ps2 #define DT_DRV_COMPAT microchip_xec_ps2
#include <arch/arm/aarch32/cortex_m/cmsis.h>
#include <errno.h> #include <errno.h>
#include <device.h> #include <device.h>
#include <drivers/ps2.h> #include <drivers/ps2.h>
@ -19,10 +21,13 @@ LOG_MODULE_REGISTER(ps2_mchp_xec);
#define PS2_TIMEOUT 10000 #define PS2_TIMEOUT 10000
struct ps2_xec_config { struct ps2_xec_config {
PS2_Type *base; struct ps2_regs * const regs;
int isr_nvic;
uint8_t girq_id; uint8_t girq_id;
uint8_t girq_bit; uint8_t girq_bit;
uint8_t isr_nvic; uint8_t pcr_idx;
uint8_t pcr_pos;
void (*irq_config_func)(void);
}; };
struct ps2_xec_data { struct ps2_xec_data {
@ -30,14 +35,39 @@ struct ps2_xec_data {
struct k_sem tx_lock; struct k_sem tx_lock;
}; };
static inline void ps2_xec_slp_en_clr(const struct device *dev)
{
const struct ps2_xec_config * const cfg = dev->config;
if (cfg->pcr_pos == MCHP_PCR3_PS2_0_POS) {
mchp_pcr_periph_slp_ctrl(PCR_PS2_0, 0);
} else {
mchp_pcr_periph_slp_ctrl(PCR_PS2_1, 0);
}
}
static inline void ps2_xec_girq_clr(const struct device *dev)
{
const struct ps2_xec_config * const cfg = dev->config;
MCHP_GIRQ_SRC(cfg->girq_id) = BIT(cfg->girq_bit);
}
static inline void ps2_xec_girq_en(const struct device *dev)
{
const struct ps2_xec_config * const cfg = dev->config;
MCHP_GIRQ_ENSET(cfg->girq_id) = BIT(cfg->girq_bit);
}
static int ps2_xec_configure(const struct device *dev, static int ps2_xec_configure(const struct device *dev,
ps2_callback_t callback_isr) ps2_callback_t callback_isr)
{ {
const struct ps2_xec_config *config = dev->config; const struct ps2_xec_config * const config = dev->config;
struct ps2_xec_data *data = dev->data; struct ps2_xec_data * const data = dev->data;
PS2_Type *base = config->base; struct ps2_regs * const regs = config->regs;
uint8_t __attribute__((unused)) dummy; uint8_t __attribute__((unused)) temp;
if (!callback_isr) { if (!callback_isr) {
return -EINVAL; return -EINVAL;
@ -50,17 +80,18 @@ static int ps2_xec_configure(const struct device *dev,
* interrupts. Instances must be allocated before the BAT or * interrupts. Instances must be allocated before the BAT or
* the host may time out. * the host may time out.
*/ */
MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit); temp = regs->TRX_BUFF;
dummy = base->TRX_BUFF; regs->STATUS = MCHP_PS2_STATUS_RW1C_MASK;
base->STATUS = MCHP_PS2_STATUS_RW1C_MASK; /* clear next higher level */
ps2_xec_girq_clr(dev);
/* Enable FSM and init instance in rx mode*/ /* Enable FSM and init instance in rx mode*/
base->CTRL = MCHP_PS2_CTRL_EN_POS; regs->CTRL = MCHP_PS2_CTRL_EN_POS;
/* We enable the interrupts in the EC aggregator so that the /* We enable the interrupts in the EC aggregator so that the
* result can be forwarded to the ARM NVIC * result can be forwarded to the ARM NVIC
*/ */
MCHP_GIRQ_ENSET(config->girq_id) = BIT(config->girq_bit); ps2_xec_girq_en(dev);
k_sem_give(&data->tx_lock); k_sem_give(&data->tx_lock);
@ -70,12 +101,12 @@ static int ps2_xec_configure(const struct device *dev,
static int ps2_xec_write(const struct device *dev, uint8_t value) static int ps2_xec_write(const struct device *dev, uint8_t value)
{ {
const struct ps2_xec_config *config = dev->config; const struct ps2_xec_config * const config = dev->config;
struct ps2_xec_data *data = dev->data; struct ps2_xec_data * const data = dev->data;
PS2_Type *base = config->base; struct ps2_regs * const regs = config->regs;
int i = 0; int i = 0;
uint8_t __attribute__((unused)) dummy; uint8_t __attribute__((unused)) temp;
if (k_sem_take(&data->tx_lock, K_NO_WAIT)) { if (k_sem_take(&data->tx_lock, K_NO_WAIT)) {
return -EACCES; return -EACCES;
@ -86,7 +117,7 @@ static int ps2_xec_write(const struct device *dev, uint8_t value)
* transaction to complete. The PS2 block has a single * transaction to complete. The PS2 block has a single
* FSM. * FSM.
*/ */
while (((base->STATUS & while (((regs->STATUS &
(MCHP_PS2_STATUS_RX_BUSY | MCHP_PS2_STATUS_TX_IDLE)) (MCHP_PS2_STATUS_RX_BUSY | MCHP_PS2_STATUS_TX_IDLE))
!= MCHP_PS2_STATUS_TX_IDLE) && (i < PS2_TIMEOUT)) { != MCHP_PS2_STATUS_TX_IDLE) && (i < PS2_TIMEOUT)) {
k_busy_wait(50); k_busy_wait(50);
@ -99,18 +130,18 @@ static int ps2_xec_write(const struct device *dev, uint8_t value)
} }
/* Inhibit ps2 controller and clear status register */ /* Inhibit ps2 controller and clear status register */
base->CTRL = 0x00; regs->CTRL = 0x00;
/* Read to clear data ready bit in the status register*/ /* Read to clear data ready bit in the status register*/
dummy = base->TRX_BUFF; temp = regs->TRX_BUFF;
k_sleep(K_MSEC(1)); k_sleep(K_MSEC(1));
base->STATUS = MCHP_PS2_STATUS_RW1C_MASK; regs->STATUS = MCHP_PS2_STATUS_RW1C_MASK;
/* Switch the interface to TX mode and enable state machine */ /* Switch the interface to TX mode and enable state machine */
base->CTRL = MCHP_PS2_CTRL_TR_TX | MCHP_PS2_CTRL_EN; regs->CTRL = MCHP_PS2_CTRL_TR_TX | MCHP_PS2_CTRL_EN;
/* Write value to TX/RX register */ /* Write value to TX/RX register */
base->TRX_BUFF = value; regs->TRX_BUFF = value;
k_sem_give(&data->tx_lock); k_sem_give(&data->tx_lock);
@ -119,16 +150,17 @@ static int ps2_xec_write(const struct device *dev, uint8_t value)
static int ps2_xec_inhibit_interface(const struct device *dev) static int ps2_xec_inhibit_interface(const struct device *dev)
{ {
const struct ps2_xec_config *config = dev->config; const struct ps2_xec_config * const config = dev->config;
struct ps2_xec_data *data = dev->data; struct ps2_xec_data * const data = dev->data;
PS2_Type *base = config->base; struct ps2_regs * const regs = config->regs;
if (k_sem_take(&data->tx_lock, K_MSEC(10)) != 0) { if (k_sem_take(&data->tx_lock, K_MSEC(10)) != 0) {
return -EACCES; return -EACCES;
} }
base->CTRL = 0x00; regs->CTRL = 0x00;
MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit); regs->STATUS = MCHP_PS2_STATUS_RW1C_MASK;
ps2_xec_girq_clr(dev);
NVIC_ClearPendingIRQ(config->isr_nvic); NVIC_ClearPendingIRQ(config->isr_nvic);
k_sem_give(&data->tx_lock); k_sem_give(&data->tx_lock);
@ -138,45 +170,47 @@ static int ps2_xec_inhibit_interface(const struct device *dev)
static int ps2_xec_enable_interface(const struct device *dev) static int ps2_xec_enable_interface(const struct device *dev)
{ {
const struct ps2_xec_config *config = dev->config; const struct ps2_xec_config * const config = dev->config;
struct ps2_xec_data *data = dev->data; struct ps2_xec_data * const data = dev->data;
PS2_Type *base = config->base; struct ps2_regs * const regs = config->regs;
MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit); ps2_xec_girq_clr(dev);
base->CTRL = MCHP_PS2_CTRL_EN; regs->CTRL = MCHP_PS2_CTRL_EN;
k_sem_give(&data->tx_lock); k_sem_give(&data->tx_lock);
return 0; return 0;
} }
static void ps2_xec_isr(const struct device *dev) static void ps2_xec_isr(const struct device *dev)
{ {
const struct ps2_xec_config *config = dev->config; const struct ps2_xec_config * const config = dev->config;
struct ps2_xec_data *data = dev->data; struct ps2_xec_data * const data = dev->data;
PS2_Type *base = config->base; struct ps2_regs * const regs = config->regs;
uint32_t status; uint32_t status;
MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit);
/* Read and clear status */ /* Read and clear status */
status = base->STATUS; status = regs->STATUS;
/* clear next higher level the GIRQ */
ps2_xec_girq_clr(dev);
if (status & MCHP_PS2_STATUS_RXD_RDY) { if (status & MCHP_PS2_STATUS_RXD_RDY) {
base->CTRL = 0x00; regs->CTRL = 0x00;
if (data->callback_isr) { if (data->callback_isr) {
data->callback_isr(dev, base->TRX_BUFF); data->callback_isr(dev, regs->TRX_BUFF);
} }
} else if (status & } else if (status &
(MCHP_PS2_STATUS_TX_TMOUT | MCHP_PS2_STATUS_TX_ST_TMOUT)) { (MCHP_PS2_STATUS_TX_TMOUT | MCHP_PS2_STATUS_TX_ST_TMOUT)) {
/* Clear sticky bits and go to read mode */ /* Clear sticky bits and go to read mode */
base->STATUS = MCHP_PS2_STATUS_RW1C_MASK; regs->STATUS = MCHP_PS2_STATUS_RW1C_MASK;
LOG_ERR("TX time out: %0x", status); LOG_ERR("TX time out: %0x", status);
} }
/* The control register reverts to RX automatically after /* The control register reverts to RX automatically after
* transmitting the data * transmitting the data
*/ */
base->CTRL = MCHP_PS2_CTRL_EN; regs->CTRL = MCHP_PS2_CTRL_EN;
} }
static const struct ps2_driver_api ps2_xec_driver_api = { static const struct ps2_driver_api ps2_xec_driver_api = {
@ -187,78 +221,50 @@ static const struct ps2_driver_api ps2_xec_driver_api = {
.enable_callback = ps2_xec_enable_interface, .enable_callback = ps2_xec_enable_interface,
}; };
#ifdef CONFIG_PS2_XEC_0 static int ps2_xec_init(const struct device *dev)
static int ps2_xec_init_0(const struct device *dev);
static const struct ps2_xec_config ps2_xec_config_0 = {
.base = (PS2_Type *) DT_INST_REG_ADDR(0),
.girq_id = DT_INST_PROP(0, girq),
.girq_bit = DT_INST_PROP(0, girq_bit),
.isr_nvic = DT_INST_IRQN(0),
};
static struct ps2_xec_data ps2_xec_port_data_0;
DEVICE_DT_INST_DEFINE(0,
&ps2_xec_init_0,
NULL,
&ps2_xec_port_data_0, &ps2_xec_config_0,
POST_KERNEL, CONFIG_PS2_INIT_PRIORITY,
&ps2_xec_driver_api);
static int ps2_xec_init_0(const struct device *dev)
{ {
ARG_UNUSED(dev); const struct ps2_xec_config * const cfg = dev->config;
struct ps2_xec_data * const data = dev->data;
struct ps2_xec_data *data = dev->data; ps2_xec_slp_en_clr(dev);
k_sem_init(&data->tx_lock, 0, 1); k_sem_init(&data->tx_lock, 0, 1);
IRQ_CONNECT(DT_INST_IRQN(0), cfg->irq_config_func();
DT_INST_IRQ(0, priority),
ps2_xec_isr, DEVICE_DT_INST_GET(0), 0);
irq_enable(DT_INST_IRQN(0));
return 0; return 0;
} }
#endif /* CONFIG_PS2_XEC_0 */
#ifdef CONFIG_PS2_XEC_1 #define XEC_PS2_CONFIG(inst) \
static int ps2_xec_init_1(const struct device *dev); static const struct ps2_xec_config ps2_xec_config_##inst = { \
.regs = (struct ps2_regs * const)(DT_INST_REG_ADDR(inst)), \
.isr_nvic = DT_INST_IRQN(inst), \
.girq_id = (uint8_t)(DT_INST_PROP_BY_IDX(inst, girqs, 0)), \
.girq_bit = (uint8_t)(DT_INST_PROP_BY_IDX(inst, girqs, 1)), \
.pcr_idx = (uint8_t)(DT_INST_PROP_BY_IDX(inst, pcrs, 0)), \
.pcr_pos = (uint8_t)(DT_INST_PROP_BY_IDX(inst, pcrs, 1)), \
.irq_config_func = ps2_xec_irq_config_func_##inst, \
}
static const struct ps2_xec_config ps2_xec_config_1 = { #define PS2_XEC_DEVICE(i) \
.base = (PS2_Type *) DT_INST_REG_ADDR(1), \
.girq_id = DT_INST_PROP(1, girq), static void ps2_xec_irq_config_func_##i(void) \
.girq_bit = DT_INST_PROP(1, girq_bit), { \
.isr_nvic = DT_INST_IRQN(1), IRQ_CONNECT(DT_INST_IRQN(i), \
DT_INST_IRQ(i, priority), \
ps2_xec_isr, \
DEVICE_DT_INST_GET(i), 0); \
irq_enable(DT_INST_IRQN(i)); \
} \
\
static struct ps2_xec_data ps2_xec_port_data_##i; \
\
XEC_PS2_CONFIG(i); \
\
DEVICE_DT_INST_DEFINE(i, &ps2_xec_init, \
NULL, \
&ps2_xec_port_data_##i, &ps2_xec_config_##i, \
POST_KERNEL, CONFIG_PS2_INIT_PRIORITY, \
&ps2_xec_driver_api);
}; DT_INST_FOREACH_STATUS_OKAY(PS2_XEC_DEVICE)
static struct ps2_xec_data ps2_xec_port_data_1;
DEVICE_DT_INST_DEFINE(1,
&ps2_xec_init_1,
NULL,
&ps2_xec_port_data_1, &ps2_xec_config_1,
POST_KERNEL, CONFIG_PS2_INIT_PRIORITY,
&ps2_xec_driver_api);
static int ps2_xec_init_1(const struct device *dev)
{
ARG_UNUSED(dev);
struct ps2_xec_data *data = dev->data;
k_sem_init(&data->tx_lock, 0, 1);
IRQ_CONNECT(DT_INST_IRQN(1),
DT_INST_IRQ(1, priority),
ps2_xec_isr, DEVICE_DT_INST_GET(1), 0);
irq_enable(DT_INST_IRQN(1));
return 0;
}
#endif /* CONFIG_PS2_XEC_1 */

View file

@ -320,23 +320,23 @@
compatible = "microchip,xec-ps2"; compatible = "microchip,xec-ps2";
reg = <0x40009000 0x40>; reg = <0x40009000 0x40>;
interrupts = <100 1>; interrupts = <100 1>;
girqs = <18 10>;
pcrs = <3 5>;
label = "PS2_0"; label = "PS2_0";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
status = "disabled"; status = "disabled";
girq = <18>;
girq-bit = <10>;
}; };
ps2_1: ps2@40009040 { ps2_1: ps2@40009040 {
compatible = "microchip,xec-ps2"; compatible = "microchip,xec-ps2";
reg = <0x40009040 0x40>; reg = <0x40009040 0x40>;
interrupts = <101 1>; interrupts = <101 1>;
girqs = <18 11>;
pcrs = <3 6>;
label = "PS2_1"; label = "PS2_1";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
status = "disabled"; status = "disabled";
girq = <18>;
girq-bit = <11>;
}; };
pwm0: pwm@40005800 { pwm0: pwm@40005800 {
compatible = "microchip,xec-pwm"; compatible = "microchip,xec-pwm";

View file

@ -14,12 +14,22 @@ properties:
interrupts: interrupts:
required: true required: true
girq: girqs:
type: int type: array
required: true required: true
description: GIRQ for this device description: |
Array of GIRQ and bit position pairs for each interrupt
signal the block generates.
girq-bit: pcrs:
type: int type: array
required: true required: true
description: Bit position in GIRQ for this device description: PS2 PCR register index and bit position
girq-cells:
- girqnum
- bitpos
pcr-cells:
- regidx
- bitpos