Lines Matching +full:tx +full:- +full:inst +full:- +full:mode
4 * SPDX-License-Identifier: Apache-2.0
21 #include <zephyr/dt-bindings/clock/npcx_clock.h>
30 * Set WDAT3-0 and clear CLK3-0 in the PSOSIG register to
39 * The max duration of a PS/2 clock is about 100 micro-seconds.
56 * (i.e. the bit position of CLK3-0 in the PS2_PSOSIG register)
61 /* The semaphore to synchronize the Tx transaction */
71 ((struct ps2_reg *)((const struct ps2_npcx_ctrl_config *)(dev)->config)->base)
81 struct ps2_npcx_ctrl_data *const data = dev->data; in ps2_npcx_ctrl_configure()
85 return -EINVAL; in ps2_npcx_ctrl_configure()
89 return -EINVAL; in ps2_npcx_ctrl_configure()
92 k_sem_take(&data->lock, K_FOREVER); in ps2_npcx_ctrl_configure()
93 data->callback_isr[channel_id] = callback_isr; in ps2_npcx_ctrl_configure()
94 k_sem_give(&data->lock); in ps2_npcx_ctrl_configure()
102 struct ps2_npcx_ctrl_data *const data = dev->data; in ps2_npcx_ctrl_enable_interface()
103 struct ps2_reg *const inst = HAL_PS2_INSTANCE(dev); in ps2_npcx_ctrl_enable_interface() local
106 k_sem_take(&data->lock, K_FOREVER); in ps2_npcx_ctrl_enable_interface()
116 k_sem_give(&data->lock); in ps2_npcx_ctrl_enable_interface()
117 return -EINVAL; in ps2_npcx_ctrl_enable_interface()
122 data->channel_enabled_mask |= ch_clk_mask; in ps2_npcx_ctrl_enable_interface()
124 inst->PSOSIG |= ch_clk_mask; in ps2_npcx_ctrl_enable_interface()
126 data->channel_enabled_mask &= ~ch_clk_mask; in ps2_npcx_ctrl_enable_interface()
128 inst->PSOSIG &= ~ch_clk_mask; in ps2_npcx_ctrl_enable_interface()
132 k_sem_give(&data->lock); in ps2_npcx_ctrl_enable_interface()
139 struct ps2_reg *const inst = HAL_PS2_INSTANCE(dev); in ps2_npcx_ctrl_bus_busy() local
142 * The driver pulls the CLK for non-active channels to low when Start in ps2_npcx_ctrl_bus_busy()
148 return (IS_BIT_SET(inst->PSTAT, NPCX_PSTAT_SOT) || in ps2_npcx_ctrl_bus_busy()
149 IS_BIT_SET(inst->PSTAT, NPCX_PSTAT_EOT)) ? in ps2_npcx_ctrl_bus_busy()
150 -EBUSY : in ps2_npcx_ctrl_bus_busy()
157 struct ps2_npcx_ctrl_data *const data = dev->data; in ps2_npcx_ctrl_write()
158 struct ps2_reg *const inst = HAL_PS2_INSTANCE(dev); in ps2_npcx_ctrl_write() local
163 return -EINVAL; in ps2_npcx_ctrl_write()
167 data->channel_enabled_mask)) { in ps2_npcx_ctrl_write()
169 return -EINVAL; in ps2_npcx_ctrl_write()
172 k_sem_take(&data->lock, K_FOREVER); in ps2_npcx_ctrl_write()
184 /* Set PS/2 in transmit mode */ in ps2_npcx_ctrl_write()
185 inst->PSCON |= BIT(NPCX_PSCON_XMT); in ps2_npcx_ctrl_write()
187 inst->PSIEN |= BIT(NPCX_PSIEN_SOTIE); in ps2_npcx_ctrl_write()
190 inst->PSOSIG = NPCX_PS2_SHIFT_MECH_RESET; in ps2_npcx_ctrl_write()
191 /* Inhibit communication should last at least 100 micro-seconds */ in ps2_npcx_ctrl_write()
195 inst->PSDAT = value; in ps2_npcx_ctrl_write()
196 /* Apply the Request-to-send */ in ps2_npcx_ctrl_write()
197 inst->PSOSIG &= ~BIT(NPCX_PSOSIG_WDAT(channel_id)); in ps2_npcx_ctrl_write()
198 inst->PSOSIG |= ps2_npcx_ctrl_get_ch_clk_mask(channel_id); in ps2_npcx_ctrl_write()
199 if (k_sem_take(&data->tx_sync_sem, PS2_TRANSACTION_TIMEOUT) != 0) { in ps2_npcx_ctrl_write()
201 LOG_ERR("PS/2 Tx timeout"); in ps2_npcx_ctrl_write()
203 inst->PSOSIG = NPCX_PS2_SHIFT_MECH_RESET; in ps2_npcx_ctrl_write()
204 /* Change the PS/2 module to receive mode */ in ps2_npcx_ctrl_write()
205 inst->PSCON &= ~BIT(NPCX_PSCON_XMT); in ps2_npcx_ctrl_write()
210 inst->PSOSIG |= data->channel_enabled_mask; in ps2_npcx_ctrl_write()
215 k_sem_give(&data->lock); in ps2_npcx_ctrl_write()
219 k_sem_give(&data->lock); in ps2_npcx_ctrl_write()
220 return -ETIMEDOUT; in ps2_npcx_ctrl_write()
225 struct ps2_reg *const inst = HAL_PS2_INSTANCE(dev); in ps2_npcx_ctrl_is_rx_error() local
228 status = inst->PSTAT & (BIT(NPCX_PSTAT_PERR) | BIT(NPCX_PSTAT_RFERR)); in ps2_npcx_ctrl_is_rx_error()
236 return -EIO; in ps2_npcx_ctrl_is_rx_error()
245 struct ps2_reg *const inst = HAL_PS2_INSTANCE(dev); in ps2_npcx_ctrl_isr() local
246 struct ps2_npcx_ctrl_data *const data = dev->data; in ps2_npcx_ctrl_isr()
254 active_ch = GET_FIELD(inst->PSTAT, NPCX_PSTAT_ACH); in ps2_npcx_ctrl_isr()
255 active_ch = active_ch > 2 ? (active_ch - 2) : (active_ch - 1); in ps2_npcx_ctrl_isr()
259 * Inhibit PS/2 transaction of the other non-active channels by in ps2_npcx_ctrl_isr()
263 inst->PSOSIG &= mask; in ps2_npcx_ctrl_isr()
266 if (IS_BIT_SET(inst->PSTAT, NPCX_PSTAT_SOT) && in ps2_npcx_ctrl_isr()
267 IS_BIT_SET(inst->PSIEN, NPCX_PSIEN_SOTIE)) { in ps2_npcx_ctrl_isr()
273 inst->PSIEN &= ~BIT(NPCX_PSIEN_SOTIE); in ps2_npcx_ctrl_isr()
276 } else if (IS_BIT_SET(inst->PSTAT, NPCX_PSTAT_EOT)) { in ps2_npcx_ctrl_isr()
277 inst->PSIEN &= ~BIT(NPCX_PSIEN_EOTIE); in ps2_npcx_ctrl_isr()
283 inst->PSOSIG &= ~BIT(NPCX_PSOSIG_CLK(active_ch)); in ps2_npcx_ctrl_isr()
285 /* Tx is done */ in ps2_npcx_ctrl_isr()
286 if (IS_BIT_SET(inst->PSCON, NPCX_PSCON_XMT)) { in ps2_npcx_ctrl_isr()
287 /* Change the PS/2 module to receive mode */ in ps2_npcx_ctrl_isr()
288 inst->PSCON &= ~BIT(NPCX_PSCON_XMT); in ps2_npcx_ctrl_isr()
289 k_sem_give(&data->tx_sync_sem); in ps2_npcx_ctrl_isr()
293 uint8_t data_in = inst->PSDAT; in ps2_npcx_ctrl_isr()
296 callback = data->callback_isr[active_ch]; in ps2_npcx_ctrl_isr()
304 inst->PSOSIG |= data->channel_enabled_mask; in ps2_npcx_ctrl_isr()
306 * Re-enable the Start Of Transaction interrupt when in ps2_npcx_ctrl_isr()
309 inst->PSIEN |= BIT(NPCX_PSIEN_SOTIE); in ps2_npcx_ctrl_isr()
310 inst->PSIEN |= BIT(NPCX_PSIEN_EOTIE); in ps2_npcx_ctrl_isr()
331 const struct ps2_npcx_ctrl_config *const config = dev->config; in ps2_npcx_ctrl_init()
332 struct ps2_npcx_ctrl_data *const data = dev->data; in ps2_npcx_ctrl_init()
333 struct ps2_reg *const inst = HAL_PS2_INSTANCE(dev); in ps2_npcx_ctrl_init() local
338 LOG_ERR("%s device not ready", clk_dev->name); in ps2_npcx_ctrl_init()
339 return -ENODEV; in ps2_npcx_ctrl_init()
344 (clock_control_subsys_t)&config->clk_cfg); in ps2_npcx_ctrl_init()
350 /* Disable shift mechanism and configure PS/2 to received mode. */ in ps2_npcx_ctrl_init()
351 inst->PSCON = 0x0; in ps2_npcx_ctrl_init()
352 /* Set WDAT3-0 and clear CLK3-0 before enabling shift mechanism */ in ps2_npcx_ctrl_init()
353 inst->PSOSIG = NPCX_PS2_SHIFT_MECH_RESET; in ps2_npcx_ctrl_init()
356 * [0] - : SOTIE = 1: Start Of Transaction Interrupt Enable in ps2_npcx_ctrl_init()
357 * [1] - : EOTIE = 1: End Of Transaction Interrupt Enable in ps2_npcx_ctrl_init()
358 * [4] - : WUE = 1: Wake-Up Enable in ps2_npcx_ctrl_init()
359 * [7] - : CLK_SEL = 1: Select Free-Run clock as the basic clock in ps2_npcx_ctrl_init()
362 inst->PSIEN = BIT(NPCX_PSIEN_SOTIE) | BIT(NPCX_PSIEN_EOTIE) | in ps2_npcx_ctrl_init()
364 if (config->clk_cfg.bus == NPCX_CLOCK_BUS_FREERUN) { in ps2_npcx_ctrl_init()
365 inst->PSIEN |= BIT(NPCX_PSIEN_PS2_CLK_SEL); in ps2_npcx_ctrl_init()
367 /* Enable weak internal pull-up */ in ps2_npcx_ctrl_init()
368 inst->PSCON |= BIT(NPCX_PSCON_WPUED); in ps2_npcx_ctrl_init()
370 inst->PSCON |= BIT(NPCX_PSCON_EN); in ps2_npcx_ctrl_init()
372 k_sem_init(&data->lock, 1, 1); in ps2_npcx_ctrl_init()
373 k_sem_init(&data->tx_sync_sem, 0, 1); in ps2_npcx_ctrl_init()