Lines Matching +full:transmit +full:- +full:retries
5 * SPDX-License-Identifier: Apache-2.0
25 #include "i2c-priv.h"
43 /* I2C recover SCL low retries */
45 /* I2C recover SDA low retries */
112 * i2c_baud_clk_period/bus_clk_period - 2 = (low_period + hi_period)
113 * bus_clk_reg (16MHz/100KHz -2) = 0x4F + 0x4F
114 * (16MHz/400KHz -2) = 0x0F + 0x17
115 * (16MHz/1MHz -2) = 0x05 + 0x09
144 (const struct i2c_xec_config *const) (dev->config); in i2c_ctl_wr()
146 (struct i2c_xec_data *const) (dev->data); in i2c_ctl_wr()
147 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in i2c_ctl_wr()
149 data->i2c_ctrl = ctrl; in i2c_ctl_wr()
150 regs->CTRLSTS = ctrl; in i2c_ctl_wr()
152 regs->BLKID = ctrl; in i2c_ctl_wr()
161 (const struct i2c_xec_config *const) (dev->config); in wait_bus_free()
163 (struct i2c_xec_data *const) (dev->data); in wait_bus_free()
164 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in wait_bus_free()
168 while (count--) { in wait_bus_free()
169 sts = regs->CTRLSTS; in wait_bus_free()
170 data->i2c_status = sts; in wait_bus_free()
177 /* NBB -> 1 not busy can occur for STOP, BER, or LAB */ in wait_bus_free()
206 (const struct i2c_xec_config *const) (dev->config); in get_lines()
207 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in get_lines()
208 uint8_t port = regs->CFG & MCHP_I2C_SMB_CFG_PORT_SEL_MASK; in get_lines()
219 (const struct i2c_xec_config *const) (dev->config); in i2c_xec_reset_config()
221 (struct i2c_xec_data *const) (dev->data); in i2c_xec_reset_config()
222 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in i2c_xec_reset_config()
224 data->state = I2C_XEC_STATE_STOPPED; in i2c_xec_reset_config()
225 data->read_discard = 0; in i2c_xec_reset_config()
228 z_mchp_xec_pcr_periph_reset(cfg->pcr_idx, cfg->pcr_bitpos); in i2c_xec_reset_config()
230 regs->CFG = MCHP_I2C_SMB_CFG_FLUSH_SXBUF_WO | in i2c_xec_reset_config()
235 mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos); in i2c_xec_reset_config()
249 regs->OWN_ADDR = EC_OWN_I2C_ADDR | (EC_OWN_I2C_ADDR << 8); in i2c_xec_reset_config()
251 if (data->target_cfg) { in i2c_xec_reset_config()
252 regs->OWN_ADDR = data->target_cfg->address; in i2c_xec_reset_config()
256 regs->CFG |= BIT(14); /* disable general call */ in i2c_xec_reset_config()
257 regs->CFG |= MCHP_I2C_SMB_CFG_FEN; in i2c_xec_reset_config()
258 regs->CFG |= (cfg->port_sel & MCHP_I2C_SMB_CFG_PORT_SEL_MASK); in i2c_xec_reset_config()
265 regs->BUSCLK = xec_cfg_params[data->speed_id].bus_clk; in i2c_xec_reset_config()
266 regs->RSHTM = xec_cfg_params[data->speed_id].start_hold_time; in i2c_xec_reset_config()
267 regs->DATATM = xec_cfg_params[data->speed_id].data_timing; in i2c_xec_reset_config()
268 regs->TMOUTSC = xec_cfg_params[data->speed_id].timeout_scale; in i2c_xec_reset_config()
269 regs->IDLSC = xec_cfg_params[data->speed_id].idle_scale; in i2c_xec_reset_config()
281 regs->CFG |= MCHP_I2C_SMB_CFG_ENAB; in i2c_xec_reset_config()
292 * between samples. If SCL remains low then return -EBUSY
303 * NOTE 1: Bit-bang mode uses a HW MUX to switch the lines away from the I2C
305 * NOTE 2: Bit-bang mode requires HW timeouts to be disabled.
306 * NOTE 3: Bit-bang mode requires the controller's configuration enable bit
308 * NOTE 4: The controller must be reset after using bit-bang mode.
313 (const struct i2c_xec_config *const) (dev->config); in i2c_xec_recover_bus()
314 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in i2c_xec_recover_bus()
320 z_mchp_xec_pcr_periph_reset(cfg->pcr_idx, cfg->pcr_bitpos); in i2c_xec_recover_bus()
322 regs->CFG = BIT(14) | MCHP_I2C_SMB_CFG_FEN | in i2c_xec_recover_bus()
323 (cfg->port_sel & MCHP_I2C_SMB_CFG_PORT_SEL_MASK); in i2c_xec_recover_bus()
324 regs->CFG |= MCHP_I2C_SMB_CFG_FLUSH_SXBUF_WO | in i2c_xec_recover_bus()
328 regs->CTRLSTS = MCHP_I2C_SMB_CTRL_PIN; in i2c_xec_recover_bus()
329 regs->BBCTRL = MCHP_I2C_SMB_BB_EN | MCHP_I2C_SMB_BB_CL | in i2c_xec_recover_bus()
331 regs->CFG |= MCHP_I2C_SMB_CFG_ENAB; in i2c_xec_recover_bus()
333 if (!(regs->BBCTRL & MCHP_I2C_SMB_BB_CLKI_RO)) { in i2c_xec_recover_bus()
336 ret = -EBUSY; in i2c_xec_recover_bus()
340 if (regs->BBCTRL & MCHP_I2C_SMB_BB_CLKI_RO) { in i2c_xec_recover_bus()
346 if (regs->BBCTRL & MCHP_I2C_SMB_BB_DATI_RO) { in i2c_xec_recover_bus()
351 ret = -EBUSY; in i2c_xec_recover_bus()
354 /* SCL output mode and tri-stated */ in i2c_xec_recover_bus()
355 regs->BBCTRL = MCHP_I2C_SMB_BB_EN | in i2c_xec_recover_bus()
362 if (regs->BBCTRL & MCHP_I2C_SMB_BB_DATI_RO) { in i2c_xec_recover_bus()
366 regs->BBCTRL = MCHP_I2C_SMB_BB_EN | in i2c_xec_recover_bus()
370 /* release SCL: pulled high by external pull-up */ in i2c_xec_recover_bus()
371 regs->BBCTRL = MCHP_I2C_SMB_BB_EN | in i2c_xec_recover_bus()
379 regs->BBCTRL = MCHP_I2C_SMB_BB_EN | MCHP_I2C_SMB_BB_CL | in i2c_xec_recover_bus()
382 regs->BBCTRL = MCHP_I2C_SMB_BB_EN | MCHP_I2C_SMB_BB_CL | in i2c_xec_recover_bus()
387 uint8_t bb = regs->BBCTRL & in i2c_xec_recover_bus()
398 regs->BBCTRL = 0; in i2c_xec_recover_bus()
399 regs->CTRLSTS = MCHP_I2C_SMB_CTRL_PIN; /* clear status */ in i2c_xec_recover_bus()
418 * NOTE: Firmware must re-enable ACK generation before the start of the next
431 (const struct i2c_xec_config *const) (dev->config); in wait_pin()
433 (struct i2c_xec_data *const) (dev->data); in wait_pin()
434 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in wait_pin()
439 data->i2c_compl = regs->COMPL; in wait_pin()
440 data->i2c_status = regs->CTRLSTS; in wait_pin()
442 if (data->i2c_status & MCHP_I2C_SMB_STS_BER) { in wait_pin()
446 if (data->i2c_status & MCHP_I2C_SMB_STS_LAB) { in wait_pin()
450 if (!(data->i2c_status & MCHP_I2C_SMB_STS_PIN)) { in wait_pin()
459 --nwait; in wait_pin()
472 (const struct i2c_xec_config *const) (dev->config); in gen_start()
474 (struct i2c_xec_data *const) (dev->data); in gen_start()
475 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in gen_start()
479 data->i2c_addr = addr8; in gen_start()
483 regs->I2CDATA = addr8; in gen_start()
486 regs->I2CDATA = addr8; in gen_start()
496 (const struct i2c_xec_config *const) (dev->config); in gen_stop()
498 (struct i2c_xec_data *const) (dev->data); in gen_stop()
499 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in gen_stop()
503 data->i2c_ctrl = ctrl; in gen_stop()
504 regs->CTRLSTS = ctrl; in gen_stop()
512 (const struct i2c_xec_config *const) (dev->config); in do_stop()
514 (struct i2c_xec_data *const) (dev->data); in do_stop()
515 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in do_stop()
518 data->state = I2C_XEC_STATE_STOPPED; in do_stop()
519 data->read_discard = 0; in do_stop()
535 regs->CTRLSTS = MCHP_I2C_SMB_CTRL_PIN | MCHP_I2C_SMB_CTRL_ESO | in do_stop()
545 (struct i2c_xec_data *const) (dev->data); in do_start()
555 /* PIN 1->0: check for NACK */ in do_start()
556 if (data->i2c_status & MCHP_I2C_SMB_STS_LRB_AD0) { in do_start()
562 return -EIO; in do_start()
572 (struct i2c_xec_data *const) (dev->data); in i2c_xec_configure()
575 return -ENOTSUP; in i2c_xec_configure()
579 return -ENOTSUP; in i2c_xec_configure()
584 data->speed_id = SPEED_100KHZ_BUS; in i2c_xec_configure()
587 data->speed_id = SPEED_400KHZ_BUS; in i2c_xec_configure()
590 data->speed_id = SPEED_1MHZ_BUS; in i2c_xec_configure()
593 return -EINVAL; in i2c_xec_configure()
601 /* I2C Controller transmit: polling implementation */
605 (const struct i2c_xec_config *const) (dev->config); in ctrl_tx()
607 (struct i2c_xec_data *const) (dev->data); in ctrl_tx()
608 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in ctrl_tx()
610 uint8_t mflags = msg->flags; in ctrl_tx()
613 if (data->state == I2C_XEC_STATE_STOPPED) { in ctrl_tx()
614 data->i2c_addr = addr8; in ctrl_tx()
629 data->state = I2C_XEC_STATE_OPEN; in ctrl_tx()
632 data->i2c_addr = addr8; in ctrl_tx()
639 for (size_t n = 0; n < msg->len; n++) { in ctrl_tx()
640 regs->I2CDATA = msg->buf[n]; in ctrl_tx()
646 if (data->i2c_status & MCHP_I2C_SMB_STS_LRB_AD0) { /* NACK? */ in ctrl_tx()
648 return -EIO; in ctrl_tx()
662 * to enter controller-read mode where every read of I2CDATA generates
663 * clocks for the next byte. When we generate START or Repeated-START
664 * and transmit an address the address is also clocked in during
683 (const struct i2c_xec_config *const) (dev->config); in ctrl_rx()
685 (struct i2c_xec_data *const) (dev->data); in ctrl_rx()
686 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in ctrl_rx()
688 size_t data_len = msg->len; in ctrl_rx()
689 uint8_t mflags = msg->flags; in ctrl_rx()
693 if (data->state == I2C_XEC_STATE_STOPPED) { in ctrl_rx()
694 data->i2c_addr = addr8; in ctrl_rx()
707 data->state = I2C_XEC_STATE_OPEN; in ctrl_rx()
710 data->read_discard = 1U; in ctrl_rx()
713 data->i2c_addr = addr8; in ctrl_rx()
720 data->read_discard = 1U; in ctrl_rx()
726 data->state = I2C_XEC_STATE_STOPPED; in ctrl_rx()
727 data->read_discard = 0; in ctrl_rx()
733 if (data->read_discard) { in ctrl_rx()
737 uint8_t *p8 = &msg->buf[0]; in ctrl_rx()
747 temp = regs->I2CDATA; /* generates clocks */ in ctrl_rx()
748 if (data->read_discard) { in ctrl_rx()
749 data->read_discard = 0; in ctrl_rx()
758 data_len--; in ctrl_rx()
762 data->state = I2C_XEC_STATE_STOPPED; in ctrl_rx()
763 data->read_discard = 0; in ctrl_rx()
766 *p8 = regs->I2CDATA; in ctrl_rx()
776 struct i2c_xec_data *data = dev->data; in i2c_xec_transfer()
780 if (data->target_attached) { in i2c_xec_transfer()
782 return -EBUSY; in i2c_xec_transfer()
789 if ((m->flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) { in i2c_xec_transfer()
795 data->state = I2C_XEC_STATE_STOPPED; in i2c_xec_transfer()
796 data->read_discard = 0; in i2c_xec_transfer()
797 LOG_ERR("i2x_xfr: flags: %x error: %d", m->flags, ret); in i2c_xec_transfer()
809 (const struct i2c_xec_config *const) (dev->config); in i2c_xec_bus_isr()
810 struct i2c_xec_data *data = dev->data; in i2c_xec_bus_isr()
812 data->target_cfg->callbacks; in i2c_xec_bus_isr()
813 struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr; in i2c_xec_bus_isr()
821 status = regs->CTRLSTS; in i2c_xec_bus_isr()
822 compl_status = regs->COMPL & MCHP_I2C_SMB_CMPL_RW1C_MASK; in i2c_xec_bus_isr()
825 if ((regs->CFG & MCHP_I2C_SMB_CFG_ENIDI) && in i2c_xec_bus_isr()
827 regs->CFG &= ~MCHP_I2C_SMB_CFG_ENIDI; in i2c_xec_bus_isr()
834 if (!data->target_attached) { in i2c_xec_bus_isr()
840 if (target_cb->stop) { in i2c_xec_bus_isr()
841 target_cb->stop(data->target_cfg); in i2c_xec_bus_isr()
849 if (target_cb->stop) { in i2c_xec_bus_isr()
850 target_cb->stop(data->target_cfg); in i2c_xec_bus_isr()
862 uint8_t rx_data = regs->I2CDATA; in i2c_xec_bus_isr()
866 data->target_read = true; in i2c_xec_bus_isr()
868 if (target_cb->read_requested) { in i2c_xec_bus_isr()
869 target_cb->read_requested( in i2c_xec_bus_isr()
870 data->target_cfg, &val); in i2c_xec_bus_isr()
872 /* Application target transmit handler in i2c_xec_bus_isr()
874 * target transmit mode the external in i2c_xec_bus_isr()
890 regs->I2CDATA = val; in i2c_xec_bus_isr()
894 data->target_read = false; in i2c_xec_bus_isr()
895 if (target_cb->write_requested) { in i2c_xec_bus_isr()
896 ret = target_cb->write_requested( in i2c_xec_bus_isr()
897 data->target_cfg); in i2c_xec_bus_isr()
904 * !!! TODO We must re-program our HW in i2c_xec_bus_isr()
915 if (data->target_read) { /* Target transmitter mode */ in i2c_xec_bus_isr()
918 status = regs->CTRLSTS; in i2c_xec_bus_isr()
923 * target transmit mode. Enable IDLE interrupt in i2c_xec_bus_isr()
924 * to catch PIN 0 -> 1 and NBB 0 -> 1. in i2c_xec_bus_isr()
926 regs->CFG |= MCHP_I2C_SMB_CFG_ENIDI; in i2c_xec_bus_isr()
930 * to de-assert 0 -> 1. Data is not transmitted. in i2c_xec_bus_isr()
933 regs->I2CDATA = dummy; in i2c_xec_bus_isr()
935 status = regs->CTRLSTS; in i2c_xec_bus_isr()
939 if (target_cb->read_processed) { in i2c_xec_bus_isr()
940 target_cb->read_processed( in i2c_xec_bus_isr()
941 data->target_cfg, &val); in i2c_xec_bus_isr()
943 regs->I2CDATA = val; in i2c_xec_bus_isr()
950 * Reading I2C Data register causes PIN status 0 -> 1. in i2c_xec_bus_isr()
952 val = regs->I2CDATA; in i2c_xec_bus_isr()
953 if (target_cb->write_received) { in i2c_xec_bus_isr()
958 ret = target_cb->write_received(data->target_cfg, val); in i2c_xec_bus_isr()
970 regs->COMPL = compl_status; in i2c_xec_bus_isr()
971 mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos); in i2c_xec_bus_isr()
979 const struct i2c_xec_config *cfg = dev->config; in i2c_xec_target_register()
980 struct i2c_xec_data *data = dev->data; in i2c_xec_target_register()
984 return -EINVAL; in i2c_xec_target_register()
987 if (data->target_attached) { in i2c_xec_target_register()
988 return -EBUSY; in i2c_xec_target_register()
999 data->target_cfg = config; in i2c_xec_target_register()
1008 data->target_attached = true; in i2c_xec_target_register()
1011 mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos); in i2c_xec_target_register()
1012 mchp_xec_ecia_girq_src_en(cfg->girq, cfg->girq_pos); in i2c_xec_target_register()
1020 const struct i2c_xec_config *cfg = dev->config; in i2c_xec_target_unregister()
1021 struct i2c_xec_data *data = dev->data; in i2c_xec_target_unregister()
1023 if (!data->target_attached) { in i2c_xec_target_unregister()
1024 return -EINVAL; in i2c_xec_target_unregister()
1027 data->target_cfg = NULL; in i2c_xec_target_unregister()
1028 data->target_attached = false; in i2c_xec_target_unregister()
1030 mchp_xec_ecia_girq_src_dis(cfg->girq, cfg->girq_pos); in i2c_xec_target_unregister()
1050 const struct i2c_xec_config *cfg = dev->config; in i2c_xec_init()
1052 (struct i2c_xec_data *const) (dev->data); in i2c_xec_init()
1056 data->state = I2C_XEC_STATE_STOPPED; in i2c_xec_init()
1057 data->target_cfg = NULL; in i2c_xec_init()
1058 data->target_attached = false; in i2c_xec_init()
1060 ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); in i2c_xec_init()
1066 bitrate_cfg = i2c_map_dt_bitrate(cfg->clock_freq); in i2c_xec_init()
1068 return -EINVAL; in i2c_xec_init()
1079 (const struct i2c_xec_config *const) (dev->config); in i2c_xec_init()
1081 config->irq_config_func(); in i2c_xec_init()