123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- * Copyright (C) 2017-2020 Alibaba Group Holding Limited
- */
- #include <common.h>
- #include <asm/io.h>
- #include <asm/types.h>
- #include <linux/bitops.h>
- #include "dw_iic_ll.h"
- #include <linux/delay.h>
- int dw_iic_wait_bus_idle(dw_iic_regs_t *iic_base, uint32_t timeout)
- {
- /*wait prev iic op is completed*/
- int ret = -3;
- uint32_t time_out = 0;
- while(time_out < timeout) {
- if (!(DW_IIC_STATUS_ACTIVITY_STATE & dw_iic_get_iic_state(iic_base))) {
- ret = 0;
- break;
- }
- mdelay(1);
- time_out++;
- }
- return ret;
- }
- void dw_iic_set_target_address(dw_iic_regs_t *iic_base, uint32_t address)
- {
- uint32_t iic_status;
- iic_status = dw_iic_get_iic_status(iic_base);
- dw_iic_disable(iic_base);
- uint32_t target_address = iic_base->IC_TAR;
- target_address &= (DW_IIC_TAR_MASTER_ADDR_MODE | DW_IIC_TAR_SPECIAL | DW_IIC_TAR_GC_OR_START);
- target_address |= address;
- iic_base->IC_TAR = target_address; /* this register can be written only when the I2C is disabled*/
- if (iic_status == DW_IIC_EN) {
- dw_iic_enable(iic_base);
- }
- }
- void dw_iic_set_transfer_speed_high(dw_iic_regs_t *iic_base)
- {
- uint32_t speed_config = iic_base->IC_CON;
- speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN);
- speed_config |= DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN;
- iic_base->IC_CON = speed_config;
- }
- void dw_iic_set_transfer_speed_fast(dw_iic_regs_t *iic_base)
- {
- uint32_t speed_config = iic_base->IC_CON;
- speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN);
- speed_config |= DW_IIC_CON_SPEEDH_EN;
- iic_base->IC_CON = speed_config;
- }
- void dw_iic_set_transfer_speed_standard(dw_iic_regs_t *iic_base)
- {
- uint32_t speed_config = iic_base->IC_CON;
- speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN);
- speed_config |= DW_IIC_CON_SPEEDL_EN;
- iic_base->IC_CON = speed_config;
- }
- void dw_iic_set_slave_mode(dw_iic_regs_t *iic_base)
- {
- uint32_t iic_status;
- iic_status = dw_iic_get_iic_status(iic_base);
- dw_iic_disable(iic_base);
- uint32_t val = DW_IIC_CON_MASTER_EN | DW_IIC_CON_SLAVE_EN;
- iic_base->IC_CON &= ~val; ///< set 0 to disabled master mode; set 0 to enabled slave mode
- if (iic_status == DW_IIC_EN) {
- dw_iic_enable(iic_base);
- }
- }
- void dw_iic_set_master_mode(dw_iic_regs_t *iic_base)
- {
- uint32_t iic_status;
- iic_status = dw_iic_get_iic_status(iic_base);
- dw_iic_disable(iic_base);
- uint32_t val = DW_IIC_CON_MASTER_EN | DW_IIC_CON_SLAVE_EN; ///< set 1 to enabled master mode; set 1 to disabled slave mode
- iic_base->IC_CON |= val;
- if (iic_status == DW_IIC_EN) {
- dw_iic_enable(iic_base);
- }
- }
- uint32_t dw_iic_find_max_prime_num(uint32_t num)
- {
- uint32_t i = 0U;
- for (i = 8U; i > 0U; i --) {
- if (!num) {
- i = 1U;
- break;
- }
- if (!(num % i)) {
- break;
- }
- }
- return i;
- }
|