Lines Matching +full:min +full:- +full:bus +full:- +full:freq

4  * SPDX-License-Identifier: Apache-2.0
18 #include <zephyr/dt-bindings/i2c/it8xxx2-i2c.h>
25 #include "i2c-priv.h"
89 /* operation freq of i2c */
96 uint8_t freq; member
108 /* Bus error */
114 /* Time-out error */
134 const struct i2c_it8xxx2_config *config = dev->config; in i2c_parsing_return_value()
135 struct i2c_it8xxx2_data *data = dev->data; in i2c_parsing_return_value()
137 if (!data->err) { in i2c_parsing_return_value()
141 if (data->err == ETIMEDOUT) { in i2c_parsing_return_value()
144 config->port, data->addr_16bit); in i2c_parsing_return_value()
147 config->port, data->addr_16bit); in i2c_parsing_return_value()
149 if (data->err & HOSTA_TMOE) { in i2c_parsing_return_value()
150 LOG_ERR("Time-out error: hardware time-out error."); in i2c_parsing_return_value()
152 if (data->err & HOSTA_NACK) { in i2c_parsing_return_value()
155 if (data->err & HOSTA_FAIL) { in i2c_parsing_return_value()
158 if (data->err & HOSTA_BSER) { in i2c_parsing_return_value()
159 LOG_ERR("BUS error: SMBus has lost arbitration."); in i2c_parsing_return_value()
163 return -EIO; in i2c_parsing_return_value()
168 const struct i2c_it8xxx2_config *config = dev->config; in i2c_get_line_levels()
169 uint8_t *base = config->base; in i2c_get_line_levels()
177 const struct i2c_it8xxx2_config *config = dev->config; in i2c_is_busy()
178 uint8_t *base = config->base; in i2c_is_busy()
188 return -EIO; in i2c_bus_not_available()
196 const struct i2c_it8xxx2_config *config = dev->config; in i2c_reset()
197 uint8_t *base = config->base; in i2c_reset()
238 const struct i2c_it8xxx2_config *config = dev->config; in i2c_standard_port_set_frequency()
246 i2c_standard_port_timing_regs_400khz(config->port); in i2c_standard_port_set_frequency()
248 IT8XXX2_SMB_SCLKTS(config->port) = freq_set; in i2c_standard_port_set_frequency()
258 const struct i2c_it8xxx2_config *config = dev->config; in i2c_it8xxx2_configure()
259 struct i2c_it8xxx2_data *const data = dev->data; in i2c_it8xxx2_configure()
263 return -EINVAL; in i2c_it8xxx2_configure()
267 return -EINVAL; in i2c_it8xxx2_configure()
270 data->bus_freq = I2C_SPEED_GET(dev_config_raw); in i2c_it8xxx2_configure()
272 switch (data->bus_freq) { in i2c_it8xxx2_configure()
286 return -EINVAL; in i2c_it8xxx2_configure()
289 i2c_standard_port_set_frequency(dev, config->bitrate, freq_set); in i2c_it8xxx2_configure()
297 struct i2c_it8xxx2_data *const data = dev->data; in i2c_it8xxx2_get_config()
300 if (!data->bus_freq) { in i2c_it8xxx2_get_config()
301 LOG_ERR("The bus frequency is not initially configured."); in i2c_it8xxx2_get_config()
302 return -EIO; in i2c_it8xxx2_get_config()
305 switch (data->bus_freq) { in i2c_it8xxx2_get_config()
310 speed = I2C_SPEED_SET(data->bus_freq); in i2c_it8xxx2_get_config()
313 return -ERANGE; in i2c_it8xxx2_get_config()
323 struct i2c_it8xxx2_data *data = dev->data; in i2c_r_last_byte()
324 const struct i2c_it8xxx2_config *config = dev->config; in i2c_r_last_byte()
325 uint8_t *base = config->base; in i2c_r_last_byte()
331 if ((data->active_msg->flags & I2C_MSG_STOP) && in i2c_r_last_byte()
332 (data->ridx == data->active_msg->len - 1)) { in i2c_r_last_byte()
339 const struct i2c_it8xxx2_config *config = dev->config; in i2c_w2r_change_direction()
340 uint8_t *base = config->base; in i2c_w2r_change_direction()
362 const struct i2c_it8xxx2_config *config = dev->config; in i2c_fifo_en_w2r()
366 if (config->port == SMB_CHANNEL_A) { in i2c_fifo_en_w2r()
369 } else if (config->port == SMB_CHANNEL_B) { in i2c_fifo_en_w2r()
372 } else if (config->port == SMB_CHANNEL_C) { in i2c_fifo_en_w2r()
377 if (config->port == SMB_CHANNEL_A) { in i2c_fifo_en_w2r()
380 } else if (config->port == SMB_CHANNEL_B) { in i2c_fifo_en_w2r()
383 } else if (config->port == SMB_CHANNEL_C) { in i2c_fifo_en_w2r()
394 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_write_start()
395 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_write_start()
397 uint8_t *base = config->base; in i2c_tran_fifo_write_start()
398 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_tran_fifo_write_start()
401 data->active_msg->flags &= ~I2C_MSG_START; in i2c_tran_fifo_write_start()
409 IT8XXX2_SMB_D0REG(base) = data->active_msg->len; in i2c_tran_fifo_write_start()
414 IT8XXX2_SMB_TRASLA(base) = (uint8_t)data->addr_16bit << 1; in i2c_tran_fifo_write_start()
416 data->bytecnt = MIN(data->active_msg->len, I2C_FIFO_MODE_MAX_SIZE); in i2c_tran_fifo_write_start()
418 for (i = 0; i < data->bytecnt; i++) { in i2c_tran_fifo_write_start()
420 IT8XXX2_SMB_HOBDB(base) = *(data->active_msg->buf++); in i2c_tran_fifo_write_start()
423 data->bytecnt = data->active_msg->len - data->bytecnt; in i2c_tran_fifo_write_start()
436 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_write_next_block()
437 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_write_next_block()
439 uint8_t *base = config->base; in i2c_tran_fifo_write_next_block()
440 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_tran_fifo_write_next_block()
443 _bytecnt = MIN(data->bytecnt, I2C_FIFO_MODE_MAX_SIZE); in i2c_tran_fifo_write_next_block()
447 IT8XXX2_SMB_HOBDB(base) = *(data->active_msg->buf++); in i2c_tran_fifo_write_next_block()
452 data->bytecnt -= _bytecnt; in i2c_tran_fifo_write_next_block()
457 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_write_finish()
458 uint8_t *base = config->base; in i2c_tran_fifo_write_finish()
470 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_w2r_change_direction()
471 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_w2r_change_direction()
472 uint8_t *base = config->base; in i2c_tran_fifo_w2r_change_direction()
474 if (++data->active_msg_index >= data->num_msgs) { in i2c_tran_fifo_w2r_change_direction()
476 data->err = EINVAL; in i2c_tran_fifo_w2r_change_direction()
489 data->active_msg = &data->msgs_list[data->active_msg_index]; in i2c_tran_fifo_w2r_change_direction()
491 IT8XXX2_SMB_D0REG(base) = data->active_msg->len; in i2c_tran_fifo_w2r_change_direction()
492 data->bytecnt = data->active_msg->len; in i2c_tran_fifo_w2r_change_direction()
494 IT8XXX2_SMB_IWRFISTA = BIT(config->port); in i2c_tran_fifo_w2r_change_direction()
501 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_read_start()
502 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_read_start()
503 uint8_t *base = config->base; in i2c_tran_fifo_read_start()
504 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_tran_fifo_read_start()
507 data->active_msg->flags &= ~I2C_MSG_START; in i2c_tran_fifo_read_start()
515 IT8XXX2_SMB_D0REG(base) = data->active_msg->len; in i2c_tran_fifo_read_start()
520 IT8XXX2_SMB_TRASLA(base) = (uint8_t)(data->addr_16bit << 1) | in i2c_tran_fifo_read_start()
523 data->bytecnt = data->active_msg->len; in i2c_tran_fifo_read_start()
536 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_read_next_block()
537 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_read_next_block()
539 uint8_t *base = config->base; in i2c_tran_fifo_read_next_block()
540 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_tran_fifo_read_next_block()
544 *(data->active_msg->buf++) = IT8XXX2_SMB_HOBDB(base); in i2c_tran_fifo_read_next_block()
549 data->bytecnt -= I2C_FIFO_MODE_MAX_SIZE; in i2c_tran_fifo_read_next_block()
554 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_read_finish()
555 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_read_finish()
557 uint8_t *base = config->base; in i2c_tran_fifo_read_finish()
559 for (i = 0; i < data->bytecnt; i++) { in i2c_tran_fifo_read_finish()
561 *(data->active_msg->buf++) = IT8XXX2_SMB_HOBDB(base); in i2c_tran_fifo_read_finish()
574 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_write_to_read()
575 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_write_to_read()
576 uint8_t *base = config->base; in i2c_tran_fifo_write_to_read()
577 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_tran_fifo_write_to_read()
580 if (data->active_msg->flags & I2C_MSG_START) { in i2c_tran_fifo_write_to_read()
592 } else if (IT8XXX2_SMB_IWRFISTA & BIT(config->port)) { in i2c_tran_fifo_write_to_read()
596 * returned the data->err. in i2c_tran_fifo_write_to_read()
614 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_read()
615 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_read()
616 uint8_t *base = config->base; in i2c_tran_fifo_read()
617 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_tran_fifo_read()
619 if (data->active_msg->flags & I2C_MSG_START) { in i2c_tran_fifo_read()
640 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_fifo_write()
641 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_fifo_write()
642 uint8_t *base = config->base; in i2c_tran_fifo_write()
643 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_tran_fifo_write()
645 if (data->active_msg->flags & I2C_MSG_START) { in i2c_tran_fifo_write()
666 struct i2c_it8xxx2_data *data = dev->data; in i2c_fifo_transaction()
667 const struct i2c_it8xxx2_config *config = dev->config; in i2c_fifo_transaction()
668 uint8_t *base = config->base; in i2c_fifo_transaction()
672 data->err = (IT8XXX2_SMB_HOSTA(base) & HOSTA_ANY_ERROR); in i2c_fifo_transaction()
674 if (data->num_msgs == 2) { in i2c_fifo_transaction()
676 } else if (data->active_msg->flags & I2C_MSG_READ) { in i2c_fifo_transaction()
693 struct i2c_it8xxx2_data *data = dev->data; in fifo_mode_allowed()
694 const struct i2c_it8xxx2_config *config = dev->config; in fifo_mode_allowed()
700 if (data->i2ccs != I2C_CH_NORMAL) { in fifo_mode_allowed()
707 if (!config->fifo_enable) { in fifo_mode_allowed()
717 if (data->num_msgs == 1 && (msgs[0].flags & I2C_MSG_STOP) && in fifo_mode_allowed()
726 if (data->num_msgs == 2) { in fifo_mode_allowed()
753 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_read()
754 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_read()
755 uint8_t *base = config->base; in i2c_tran_read()
757 if (data->active_msg->flags & I2C_MSG_START) { in i2c_tran_read()
766 IT8XXX2_SMB_TRASLA(base) = (uint8_t)(data->addr_16bit << 1) | in i2c_tran_read()
769 data->active_msg->flags &= ~I2C_MSG_START; in i2c_tran_read()
777 if ((data->active_msg->len == 1) && in i2c_tran_read()
778 (data->active_msg->flags & I2C_MSG_STOP)) { in i2c_tran_read()
789 if ((data->i2ccs == I2C_CH_REPEAT_START) || in i2c_tran_read()
790 (data->i2ccs == I2C_CH_WAIT_READ)) { in i2c_tran_read()
791 if (data->i2ccs == I2C_CH_REPEAT_START) { in i2c_tran_read()
800 data->i2ccs = I2C_CH_NORMAL; in i2c_tran_read()
802 if (data->ridx < data->active_msg->len) { in i2c_tran_read()
804 *(data->active_msg->buf++) = IT8XXX2_SMB_HOBDB(base); in i2c_tran_read()
805 data->ridx++; in i2c_tran_read()
809 if (data->ridx == data->active_msg->len) { in i2c_tran_read()
810 data->active_msg->len = 0; in i2c_tran_read()
811 if (data->active_msg->flags & I2C_MSG_STOP) { in i2c_tran_read()
816 data->stop = 1; in i2c_tran_read()
818 data->i2ccs = I2C_CH_WAIT_READ; in i2c_tran_read()
835 struct i2c_it8xxx2_data *data = dev->data; in i2c_tran_write()
836 const struct i2c_it8xxx2_config *config = dev->config; in i2c_tran_write()
837 uint8_t *base = config->base; in i2c_tran_write()
839 if (data->active_msg->flags & I2C_MSG_START) { in i2c_tran_write()
848 IT8XXX2_SMB_TRASLA(base) = (uint8_t)data->addr_16bit << 1; in i2c_tran_write()
850 IT8XXX2_SMB_HOBDB(base) = *(data->active_msg->buf++); in i2c_tran_write()
852 data->widx++; in i2c_tran_write()
854 data->active_msg->flags &= ~I2C_MSG_START; in i2c_tran_write()
866 if (data->widx < data->active_msg->len) { in i2c_tran_write()
868 IT8XXX2_SMB_HOBDB(base) = *(data->active_msg->buf++); in i2c_tran_write()
870 data->widx++; in i2c_tran_write()
874 if (data->i2ccs == I2C_CH_REPEAT_START) { in i2c_tran_write()
875 data->i2ccs = I2C_CH_NORMAL; in i2c_tran_write()
879 data->active_msg->len = 0; in i2c_tran_write()
880 if (data->active_msg->flags & I2C_MSG_STOP) { in i2c_tran_write()
887 data->stop = 1; in i2c_tran_write()
889 data->i2ccs = I2C_CH_REPEAT_START; in i2c_tran_write()
901 struct i2c_it8xxx2_data *data = dev->data; in i2c_pio_transaction()
902 const struct i2c_it8xxx2_config *config = dev->config; in i2c_pio_transaction()
903 uint8_t *base = config->base; in i2c_pio_transaction()
907 data->err = (IT8XXX2_SMB_HOSTA(base) & HOSTA_ANY_ERROR); in i2c_pio_transaction()
909 if (!data->stop) { in i2c_pio_transaction()
916 if (data->active_msg->flags & I2C_MSG_READ) { in i2c_pio_transaction()
932 data->stop = 0; in i2c_pio_transaction()
940 struct i2c_it8xxx2_data *data = dev->data; in i2c_it8xxx2_transfer()
941 const struct i2c_it8xxx2_config *config = dev->config; in i2c_it8xxx2_transfer()
945 k_mutex_lock(&data->mutex, K_FOREVER); in i2c_it8xxx2_transfer()
949 * exclude checking bus busy. in i2c_it8xxx2_transfer()
951 if (data->i2ccs == I2C_CH_NORMAL) { in i2c_it8xxx2_transfer()
956 /* Recovery I2C bus */ in i2c_it8xxx2_transfer()
959 * After resetting I2C bus, if I2C bus is not available in i2c_it8xxx2_transfer()
960 * (No external pull-up), drop the transaction. in i2c_it8xxx2_transfer()
964 k_mutex_unlock(&data->mutex); in i2c_it8xxx2_transfer()
965 return -EIO; in i2c_it8xxx2_transfer()
969 start_msg->flags |= I2C_MSG_START; in i2c_it8xxx2_transfer()
973 data->num_msgs = num_msgs; in i2c_it8xxx2_transfer()
975 data->msgs_list = msgs; in i2c_it8xxx2_transfer()
985 data->widx = 0; in i2c_it8xxx2_transfer()
986 data->ridx = 0; in i2c_it8xxx2_transfer()
987 data->err = 0; in i2c_it8xxx2_transfer()
988 data->active_msg = &msgs[i]; in i2c_it8xxx2_transfer()
989 data->addr_16bit = addr; in i2c_it8xxx2_transfer()
992 data->active_msg_index = 0; in i2c_it8xxx2_transfer()
1001 irq_enable(config->i2c_irq_base); in i2c_it8xxx2_transfer()
1008 irq_enable(config->i2c_irq_base); in i2c_it8xxx2_transfer()
1012 res = k_sem_take(&data->device_sync_sem, K_MSEC(config->transfer_timeout_ms)); in i2c_it8xxx2_transfer()
1019 irq_disable(config->i2c_irq_base); in i2c_it8xxx2_transfer()
1022 * bus error, device error). in i2c_it8xxx2_transfer()
1024 if (data->err) { in i2c_it8xxx2_transfer()
1029 data->err = ETIMEDOUT; in i2c_it8xxx2_transfer()
1033 config->port, data->addr_16bit, I2C_RC_TIMEOUT); in i2c_it8xxx2_transfer()
1050 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_it8xxx2_transfer()
1055 if (data->num_msgs == 2) { in i2c_it8xxx2_transfer()
1063 if (data->err || (data->active_msg->flags & I2C_MSG_STOP)) { in i2c_it8xxx2_transfer()
1064 data->i2ccs = I2C_CH_NORMAL; in i2c_it8xxx2_transfer()
1069 k_mutex_unlock(&data->mutex); in i2c_it8xxx2_transfer()
1076 struct i2c_it8xxx2_data *data = dev->data; in i2c_it8xxx2_isr()
1077 const struct i2c_it8xxx2_config *config = dev->config; in i2c_it8xxx2_isr()
1080 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_it8xxx2_isr()
1083 if (config->fifo_enable && (*reg_mstfctrl & IT8XXX2_SMB_FFEN)) { in i2c_it8xxx2_isr()
1094 irq_disable(config->i2c_irq_base); in i2c_it8xxx2_isr()
1095 k_sem_give(&data->device_sync_sem); in i2c_it8xxx2_isr()
1100 struct i2c_it8xxx2_data *data = dev->data; in i2c_it8xxx2_init()
1101 const struct i2c_it8xxx2_config *config = dev->config; in i2c_it8xxx2_init()
1102 uint8_t *base = config->base; in i2c_it8xxx2_init()
1107 k_mutex_init(&data->mutex); in i2c_it8xxx2_init()
1108 k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT); in i2c_it8xxx2_init()
1112 (IT8XXX2_ECPM_BASE + (config->clock_gate_offset >> 8)); in i2c_it8xxx2_init()
1113 uint8_t reg_mask = config->clock_gate_offset & 0xff; in i2c_it8xxx2_init()
1120 * and support I2C-compatible cycles. in i2c_it8xxx2_init()
1138 volatile uint8_t *reg_mstfctrl = config->reg_mstfctrl; in i2c_it8xxx2_init()
1140 if (config->port == SMB_CHANNEL_B && config->fifo_enable) { in i2c_it8xxx2_init()
1143 } else if (config->port == SMB_CHANNEL_C && config->fifo_enable) { in i2c_it8xxx2_init()
1149 /* ChannelA-C switch selection of I2C pin */ in i2c_it8xxx2_init()
1150 if (config->port == SMB_CHANNEL_A) { in i2c_it8xxx2_init()
1152 config->channel_switch_sel; in i2c_it8xxx2_init()
1153 } else if (config->port == SMB_CHANNEL_B) { in i2c_it8xxx2_init()
1154 IT8XXX2_SMB_SMB01CHS = (config->channel_switch_sel << 4) | in i2c_it8xxx2_init()
1156 } else if (config->port == SMB_CHANNEL_C) { in i2c_it8xxx2_init()
1158 config->channel_switch_sel; in i2c_it8xxx2_init()
1162 if (config->bitrate == I2C_BITRATE_STANDARD || in i2c_it8xxx2_init()
1163 config->bitrate == I2C_BITRATE_FAST || in i2c_it8xxx2_init()
1164 config->bitrate == I2C_BITRATE_FAST_PLUS) { in i2c_it8xxx2_init()
1165 bitrate_cfg = i2c_map_dt_bitrate(config->bitrate); in i2c_it8xxx2_init()
1172 data->i2ccs = I2C_CH_NORMAL; in i2c_it8xxx2_init()
1180 status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); in i2c_it8xxx2_init()
1191 const struct i2c_it8xxx2_config *config = dev->config; in i2c_it8xxx2_recover_bus()
1195 gpio_flags_t flags = GPIO_OUTPUT | (config->push_pull_recovery ? 0 : GPIO_OPEN_DRAIN); in i2c_it8xxx2_recover_bus()
1197 gpio_pin_configure_dt(&config->scl_gpios, flags); in i2c_it8xxx2_recover_bus()
1199 gpio_pin_configure_dt(&config->sda_gpios, flags); in i2c_it8xxx2_recover_bus()
1202 * In I2C recovery bus, 1ms sleep interval for bitbanging i2c in i2c_it8xxx2_recover_bus()
1207 gpio_pin_set_dt(&config->scl_gpios, 1); in i2c_it8xxx2_recover_bus()
1208 gpio_pin_set_dt(&config->sda_gpios, 1); in i2c_it8xxx2_recover_bus()
1212 gpio_pin_set_dt(&config->sda_gpios, 0); in i2c_it8xxx2_recover_bus()
1214 gpio_pin_set_dt(&config->scl_gpios, 0); in i2c_it8xxx2_recover_bus()
1220 gpio_pin_set_dt(&config->sda_gpios, 1); in i2c_it8xxx2_recover_bus()
1222 gpio_pin_set_dt(&config->scl_gpios, 1); in i2c_it8xxx2_recover_bus()
1225 gpio_pin_set_dt(&config->scl_gpios, 0); in i2c_it8xxx2_recover_bus()
1229 gpio_pin_set_dt(&config->sda_gpios, 0); in i2c_it8xxx2_recover_bus()
1233 gpio_pin_set_dt(&config->scl_gpios, 1); in i2c_it8xxx2_recover_bus()
1235 gpio_pin_set_dt(&config->sda_gpios, 1); in i2c_it8xxx2_recover_bus()
1239 status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); in i2c_it8xxx2_recover_bus()
1247 LOG_ERR("I2C ch%d reset cause %d", config->port, in i2c_it8xxx2_recover_bus()