diff --git a/boards/arm/mec1501modular_assy6885/Kconfig.defconfig b/boards/arm/mec1501modular_assy6885/Kconfig.defconfig index 55197a750d5..0bf8ab2a98c 100644 --- a/boards/arm/mec1501modular_assy6885/Kconfig.defconfig +++ b/boards/arm/mec1501modular_assy6885/Kconfig.defconfig @@ -39,16 +39,6 @@ config SYS_CLOCK_TICKS_PER_SEC endif # RTOS_TIMER -if PS2 - -config PS2_XEC_0 - default y - -config PS2_XEC_1 - default y - -endif # PS2 - config TACH_XEC default y depends on SENSOR diff --git a/boards/arm/mec1501modular_assy6885/pinmux.c b/boards/arm/mec1501modular_assy6885/pinmux.c index 6812a05a4e0..a082adfc30d 100644 --- a/boards/arm/mec1501modular_assy6885/pinmux.c +++ b/boards/arm/mec1501modular_assy6885/pinmux.c @@ -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); #endif -#ifdef CONFIG_PS2_XEC_0 +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ps2_0), okay) /* Set muxing for PS20B*/ mchp_pcr_periph_slp_ctrl(PCR_PS2_0, MCHP_PCR_SLEEP_DIS); 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); #endif -#ifdef CONFIG_PS2_XEC_1 +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ps2_1), okay) /* Set muxing for PS21B*/ mchp_pcr_periph_slp_ctrl(PCR_PS2_1, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(portd, MCHP_GPIO_154, MCHP_GPIO_CTRL_MUX_F2 | diff --git a/boards/arm/mec15xxevb_assy6853/Kconfig.defconfig b/boards/arm/mec15xxevb_assy6853/Kconfig.defconfig index b977d306451..f62160c8790 100644 --- a/boards/arm/mec15xxevb_assy6853/Kconfig.defconfig +++ b/boards/arm/mec15xxevb_assy6853/Kconfig.defconfig @@ -39,16 +39,6 @@ config SYS_CLOCK_TICKS_PER_SEC endif # RTOS_TIMER -if PS2 - -config PS2_XEC_0 - default y - -config PS2_XEC_1 - default y - -endif # PS2 - if SPI config SPI_XEC_QMSPI diff --git a/boards/arm/mec15xxevb_assy6853/pinmux.c b/boards/arm/mec15xxevb_assy6853/pinmux.c index 93e7cdc2bfa..29bc8825567 100644 --- a/boards/arm/mec15xxevb_assy6853/pinmux.c +++ b/boards/arm/mec15xxevb_assy6853/pinmux.c @@ -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); #endif -#ifdef CONFIG_PS2_XEC_0 +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ps2_0), okay) /* Set muxing for PS20B*/ mchp_pcr_periph_slp_ctrl(PCR_PS2_0, MCHP_PCR_SLEEP_DIS); 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); #endif -#ifdef CONFIG_PS2_XEC_1 +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ps2_1), okay) /* Set muxing for PS21B*/ mchp_pcr_periph_slp_ctrl(PCR_PS2_1, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(portd, MCHP_GPIO_154, MCHP_GPIO_CTRL_MUX_F2 | diff --git a/drivers/ps2/Kconfig.xec b/drivers/ps2/Kconfig.xec index cc297a7fcbc..0ace21a7467 100644 --- a/drivers/ps2/Kconfig.xec +++ b/drivers/ps2/Kconfig.xec @@ -3,23 +3,9 @@ # Copyright (c) 2019 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -menuconfig PS2_XEC +config PS2_XEC bool "XEC Microchip PS2 driver" depends on SOC_FAMILY_MEC && ESPI_PERIPHERAL_8042_KBC help Enable the Microchip XEC PS2 IO driver. The driver also 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 diff --git a/drivers/ps2/ps2_mchp_xec.c b/drivers/ps2/ps2_mchp_xec.c index 9618ff7ca47..659c981b01d 100644 --- a/drivers/ps2/ps2_mchp_xec.c +++ b/drivers/ps2/ps2_mchp_xec.c @@ -1,11 +1,13 @@ /* * Copyright (c) 2019 Intel Corporation + * Copyright (c) 2022 Microchip Technology Inc. * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT microchip_xec_ps2 +#include #include #include #include @@ -19,10 +21,13 @@ LOG_MODULE_REGISTER(ps2_mchp_xec); #define PS2_TIMEOUT 10000 struct ps2_xec_config { - PS2_Type *base; + struct ps2_regs * const regs; + int isr_nvic; uint8_t girq_id; 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 { @@ -30,14 +35,39 @@ struct ps2_xec_data { 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, ps2_callback_t callback_isr) { - const struct ps2_xec_config *config = dev->config; - struct ps2_xec_data *data = dev->data; - PS2_Type *base = config->base; + const struct ps2_xec_config * const config = dev->config; + struct ps2_xec_data * const data = dev->data; + struct ps2_regs * const regs = config->regs; - uint8_t __attribute__((unused)) dummy; + uint8_t __attribute__((unused)) temp; if (!callback_isr) { return -EINVAL; @@ -50,17 +80,18 @@ static int ps2_xec_configure(const struct device *dev, * interrupts. Instances must be allocated before the BAT or * the host may time out. */ - MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit); - dummy = base->TRX_BUFF; - base->STATUS = MCHP_PS2_STATUS_RW1C_MASK; + temp = regs->TRX_BUFF; + regs->STATUS = MCHP_PS2_STATUS_RW1C_MASK; + /* clear next higher level */ + ps2_xec_girq_clr(dev); /* 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 * 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); @@ -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) { - const struct ps2_xec_config *config = dev->config; - struct ps2_xec_data *data = dev->data; - PS2_Type *base = config->base; + const struct ps2_xec_config * const config = dev->config; + struct ps2_xec_data * const data = dev->data; + struct ps2_regs * const regs = config->regs; int i = 0; - uint8_t __attribute__((unused)) dummy; + uint8_t __attribute__((unused)) temp; if (k_sem_take(&data->tx_lock, K_NO_WAIT)) { 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 * FSM. */ - while (((base->STATUS & + while (((regs->STATUS & (MCHP_PS2_STATUS_RX_BUSY | MCHP_PS2_STATUS_TX_IDLE)) != MCHP_PS2_STATUS_TX_IDLE) && (i < PS2_TIMEOUT)) { 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 */ - base->CTRL = 0x00; + regs->CTRL = 0x00; /* Read to clear data ready bit in the status register*/ - dummy = base->TRX_BUFF; + temp = regs->TRX_BUFF; 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 */ - 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 */ - base->TRX_BUFF = value; + regs->TRX_BUFF = value; 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) { - const struct ps2_xec_config *config = dev->config; - struct ps2_xec_data *data = dev->data; - PS2_Type *base = config->base; + const struct ps2_xec_config * const config = dev->config; + struct ps2_xec_data * const data = dev->data; + struct ps2_regs * const regs = config->regs; if (k_sem_take(&data->tx_lock, K_MSEC(10)) != 0) { return -EACCES; } - base->CTRL = 0x00; - MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit); + regs->CTRL = 0x00; + regs->STATUS = MCHP_PS2_STATUS_RW1C_MASK; + ps2_xec_girq_clr(dev); NVIC_ClearPendingIRQ(config->isr_nvic); 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) { - const struct ps2_xec_config *config = dev->config; - struct ps2_xec_data *data = dev->data; - PS2_Type *base = config->base; + const struct ps2_xec_config * const config = dev->config; + struct ps2_xec_data * const data = dev->data; + struct ps2_regs * const regs = config->regs; - MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit); - base->CTRL = MCHP_PS2_CTRL_EN; + ps2_xec_girq_clr(dev); + regs->CTRL = MCHP_PS2_CTRL_EN; k_sem_give(&data->tx_lock); return 0; } + static void ps2_xec_isr(const struct device *dev) { - const struct ps2_xec_config *config = dev->config; - struct ps2_xec_data *data = dev->data; - PS2_Type *base = config->base; + const struct ps2_xec_config * const config = dev->config; + struct ps2_xec_data * const data = dev->data; + struct ps2_regs * const regs = config->regs; uint32_t status; - MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit); - /* 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) { - base->CTRL = 0x00; + regs->CTRL = 0x00; if (data->callback_isr) { - data->callback_isr(dev, base->TRX_BUFF); + data->callback_isr(dev, regs->TRX_BUFF); } } else if (status & (MCHP_PS2_STATUS_TX_TMOUT | MCHP_PS2_STATUS_TX_ST_TMOUT)) { /* 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); } /* The control register reverts to RX automatically after * 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 = { @@ -187,78 +221,50 @@ static const struct ps2_driver_api ps2_xec_driver_api = { .enable_callback = ps2_xec_enable_interface, }; -#ifdef CONFIG_PS2_XEC_0 -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) +static int ps2_xec_init(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); - IRQ_CONNECT(DT_INST_IRQN(0), - DT_INST_IRQ(0, priority), - ps2_xec_isr, DEVICE_DT_INST_GET(0), 0); - - irq_enable(DT_INST_IRQN(0)); + cfg->irq_config_func(); return 0; } -#endif /* CONFIG_PS2_XEC_0 */ -#ifdef CONFIG_PS2_XEC_1 -static int ps2_xec_init_1(const struct device *dev); +#define XEC_PS2_CONFIG(inst) \ + 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 = { - .base = (PS2_Type *) DT_INST_REG_ADDR(1), - .girq_id = DT_INST_PROP(1, girq), - .girq_bit = DT_INST_PROP(1, girq_bit), - .isr_nvic = DT_INST_IRQN(1), +#define PS2_XEC_DEVICE(i) \ + \ + static void ps2_xec_irq_config_func_##i(void) \ + { \ + 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); -}; - -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 */ +DT_INST_FOREACH_STATUS_OKAY(PS2_XEC_DEVICE) diff --git a/dts/arm/microchip/mec1501hsz.dtsi b/dts/arm/microchip/mec1501hsz.dtsi index 3f539a843cc..bf70931633e 100644 --- a/dts/arm/microchip/mec1501hsz.dtsi +++ b/dts/arm/microchip/mec1501hsz.dtsi @@ -320,23 +320,23 @@ compatible = "microchip,xec-ps2"; reg = <0x40009000 0x40>; interrupts = <100 1>; + girqs = <18 10>; + pcrs = <3 5>; label = "PS2_0"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; - girq = <18>; - girq-bit = <10>; }; ps2_1: ps2@40009040 { compatible = "microchip,xec-ps2"; reg = <0x40009040 0x40>; interrupts = <101 1>; + girqs = <18 11>; + pcrs = <3 6>; label = "PS2_1"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; - girq = <18>; - girq-bit = <11>; }; pwm0: pwm@40005800 { compatible = "microchip,xec-pwm"; diff --git a/dts/bindings/ps2/microchip,xec-ps2.yaml b/dts/bindings/ps2/microchip,xec-ps2.yaml index ec1c50613c5..940343655f6 100644 --- a/dts/bindings/ps2/microchip,xec-ps2.yaml +++ b/dts/bindings/ps2/microchip,xec-ps2.yaml @@ -14,12 +14,22 @@ properties: interrupts: required: true - girq: - type: int + girqs: + type: array required: true - description: GIRQ for this device + description: | + Array of GIRQ and bit position pairs for each interrupt + signal the block generates. - girq-bit: - type: int + pcrs: + type: array 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