Files
luban-lite-t3e-pro/bsp/artinchip/include/hal/hal_i2c.h

447 lines
13 KiB
C
Raw Normal View History

2023-08-30 16:21:18 +08:00
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _AIC_HAL_I2C_
#define _AIC_HAL_I2C_
#include <stdint.h>
#include <stdbool.h>
#include "aic_errno.h"
#include "aic_common.h"
#include "aic_hal_clk.h"
#include "aic_log.h"
#include "aic_io.h"
#ifdef __cplusplus
extern "C" {
#endif
2023-11-09 20:19:51 +08:00
struct aic_i2c_msg
{
uint16_t addr;
uint16_t flags;
uint16_t len;
uint8_t *buf;
};
2024-06-04 19:00:30 +08:00
enum aic_msg_status {
MSG_IDLE = 0,
MSG_IN_PROCESS = 1,
};
struct slave_param
{
uint32_t cmd;
uint8_t *arg;
};
typedef int (*i2c_slave_cb_t) (void *callback_param);
struct aic_i2c_slave_info
{
void *callback_param;
i2c_slave_cb_t slave_cb;
};
typedef struct aic_i2c_ctrl aic_i2c_ctrl;
struct aic_i2c_ctrl
{
int32_t index;
char *device_name;
unsigned long reg_base;
uint32_t addr_bit;
uint32_t speed_mode;
uint32_t bus_mode;
struct aic_i2c_msg *msg;
struct aic_i2c_slave_info slave;
enum aic_msg_status msg_status;
uint32_t slave_addr;
uint32_t abort_source;
uint32_t msg_err;
uint32_t buf_write_idx;
uint32_t buf_read_idx;
bool is_first_message;
bool is_last_message;
};
2023-08-30 16:21:18 +08:00
typedef enum {
I2C_OK = 0,
I2C_ERR = -1,
I2C_BUSY = -2,
I2C_TIMEOUT = -3,
I2C_UNSPUPPORTED = -4,
} i2c_error_t;
2024-06-04 19:00:30 +08:00
enum i2c_slave_event {
I2C_SLAVE_READ_REQUESTED,
I2C_SLAVE_WRITE_REQUESTED,
I2C_SLAVE_READ_PROCESSED,
I2C_SLAVE_WRITE_RECEIVED,
I2C_SLAVE_STOP,
};
2023-08-30 16:21:18 +08:00
#define I2C_DEFALT_CLOCK 24000000
#define I2C_CTL 0x00
#define I2C_TAR 0x04
#define I2C_SAR 0x08
#define I2C_ACK_GEN_CALL 0x0C
#define I2C_DATA_CMD 0x10
#define I2C_SS_SCL_HCNT 0x20
#define I2C_SS_SCL_LCNT 0x24
#define I2C_FS_SCL_HCNT 0x28
#define I2C_FS_SCL_LCNT 0x2C
#define I2C_SDA_HOLD 0x30
#define I2C_SDA_SETUP 0x34
#define I2C_INTR_MASK 0x38
#define I2C_INTR_CLR 0x3C
#define I2C_INTR_RAW_STAT 0x40
#define I2C_ENABLE 0x48
#define I2C_ENABLE_STATUS 0x4C
#define I2C_STATUS 0x50
#define I2C_TX_ABRT_SOURCE 0x54
#define I2C_RX_TL 0x90
#define I2C_TX_TL 0x94
#define I2C_TXFLR 0x98
#define I2C_RXFLR 0x9C
#define I2C_SCL_STUCK_TIMEOUT 0xA0
#define I2C_SDA_STUCK_TIMEOUT 0xA4
#define I2C_FS_SPIKELEN 0xB0
#define I2C_VERSION 0xFC
#define I2C_CTL_MASTER_SLAVE_SELECT_MASK (3)
#define I2C_CTL_10BIT_SELECT_MASTER (1 << 2)
#define I2C_CTL_10BIT_SELECT_SLAVE (1 << 3)
#define I2C_CTL_SPEED_MODE_SELECT_MASK (3 << 4)
#define I2C_CTL_SPEED_MODE_SS (0x1 << 4)
#define I2C_CTL_SPEED_MODE_FS (0x2 << 4)
#define I2C_CTL_RESTART_ENABLE (1 << 6)
#define I2C_CTL_STOP_DET_IFADDR (1 << 7)
#define I2C_CTL_TX_EMPTY_CTL (1 << 8)
#define I2C_CTL_RX_FIFO_FULL_HLD (1 << 9)
#define I2C_CTL_BUS_CLEAR_FEATURE (1 << 10)
#define I2C_TAR_ADDR_MASK (0x3FF)
#define I2C_TAR_START_BYTE (1 << 10)
#define I2C_TAR_GEN_CALL_CTL (1 << 11)
#define I2C_DATA_CMD_DAT_MASK (0xFF)
#define I2C_DATA_CMD_READ (1 << 8)
#define I2C_DATA_CMD_STOP (1 << 9)
#define I2C_DATA_CMD_RESTART (1 << 10)
#define I2C_SDA_TX_HOLD_MASK (0xFFFF)
#define I2C_SDA_RX_HOLD_MASK (0xFF << 16)
#define I2C_INTR_RX_UNDER (1 << 0)
#define I2C_INTR_RX_FULL (1 << 2)
#define I2C_INTR_TX_EMPTY (1 << 4)
#define I2C_INTR_RD_REQ (1 << 5)
#define I2C_INTR_TX_ABRT (1 << 6)
#define I2C_INTR_RX_DONE (1 << 7)
#define I2C_INTR_ACTIVITY (1 << 8)
#define I2C_INTR_STOP_DET (1 << 9)
#define I2C_INTR_START_DET (1 << 10)
#define I2C_INTR_GEN_CALL (1 << 11)
#define I2C_INTR_MASTER_ON_HOLD (1 << 13)
#define I2C_INTR_SCL_STUCK_AT_LOW (1 << 14)
#define I2C_ENABLE_BIT (1 << 0)
#define I2C_ENABLE_ABORT (1 << 1)
#define I2C_TX_CMD_BLOCK (1 << 2)
#define I2C_SDA_STUCK_RECOVERY_ENABLE (1 << 3)
#define I2C_STATUS_ACTIVITY (1 << 0)
#define ABRT_7BIT_ADDR_NOACK 0
#define ABRT_10BIT_ADDR1_NOACK 1
#define ABRT_10BIT_ADDR2_NOACK 2
#define ABRT_TXDATA_NOACK 3
#define ABRT_GCALL_NOACK 4
#define ABRT_GCALL_READ 5
#define ABRT_SBYTE_ACKDET 7
#define ABRT_SBYTE_NORSTRT 9
#define ABRT_10BIT_RD_NORSTRT 10
#define ABRT_MASTER_DIS 11
#define ABRT_LOST 12
#define ABRT_SLVFLUSH_TXFIFO 13
#define ABRT_SLV_ARBLOST 14
#define ABRT_SLVRD_INTX 15
#define ABRT_USER_ABRT 16
#define ABRT_SDA_STUCK_AT_LOW 17
#define I2C_ABRT_7BIT_ADDR_NOACK (1 << 0)
#define I2C_ABRT_10BIT_ADDR1_NOACK (1 << 1)
#define I2C_ABRT_10BIT_ADDR2_NOACK (1 << 2)
#define I2C_ABRT_TXDATA_NOACK (1 << 3)
#define I2C_ABRT_GCALL_NOACK (1 << 4)
#define I2C_ABRT_GCALL_READ (1 << 5)
#define I2C_ABRT_SBYTE_ACKDET (1 << 7)
#define I2C_ABRT_SBYTE_NORSTRT (1 << 9)
#define I2C_ABRT_10BIT_RD_NORSTRT (1 << 10)
#define I2C_ABRT_MASTER_DIS (1 << 11)
#define I2C_ABRT_LOST (1 << 12)
#define I2C_ABRT_SLVFLUSH_TXFIFO (1 << 13)
#define I2C_ABRT_SLV_ARBLOST (1 << 14)
#define I2C_ABRT_SLVRD_INTX (1 << 15)
#define I2C_ABRT_USER_ABRT (1 << 16)
#define I2C_ABRT_SDA_STUCK_AT_LOW (1 << 17)
#define I2C_ENABLE_MASTER_DISABLE_SLAVE (0x3)
2024-06-04 19:00:30 +08:00
#define I2C_FIFO_DEPTH 8
#define I2C_TXFIFO_THRESHOLD (I2C_FIFO_DEPTH / 2 - 1)
#define I2C_RXFIFO_THRESHOLD 0
#define FS_MIN_SCL_HIGH 600
#define FS_MIN_SCL_LOW 1300
#define SS_MIN_SCL_HIGH 4200
#define SS_MIN_SCL_LOW 5210
#define I2C_TIMEOUT_DEF_VAL 1000
#define I2C_INTR_ERROR_RX 0x0001
#define I2C_INTR_ERROR_ABRT 0x0002
#define I2C_MASTER_MODE 0
#define I2C_SLAVE_MODE 1
#define I2C_400K_SPEED 0
#define I2C_100K_SPEED 1
#define I2C_7BIT_ADDR 0
#define I2C_10BIT_ADDR 1
#define I2C_INTR_MASTER_MASK (I2C_INTR_RX_UNDER |\
I2C_INTR_RX_FULL |\
I2C_INTR_TX_EMPTY |\
I2C_INTR_TX_ABRT |\
I2C_INTR_STOP_DET)
#define I2C_INTR_SLAVE_MASK (I2C_INTR_RX_UNDER |\
I2C_INTR_RX_FULL |\
I2C_INTR_RD_REQ |\
I2C_INTR_TX_ABRT |\
I2C_INTR_RX_DONE |\
I2C_INTR_START_DET)
static inline void hal_i2c_module_enable(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
uint32_t reg_val;
2024-06-04 19:00:30 +08:00
reg_val = readl(i2c_dev->reg_base + I2C_ENABLE);
2023-08-30 16:21:18 +08:00
reg_val |= I2C_ENABLE_BIT;
2024-06-04 19:00:30 +08:00
writel(reg_val, i2c_dev->reg_base + I2C_ENABLE);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_module_disable(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
uint32_t reg_val;
2024-06-04 19:00:30 +08:00
writel(0x100, i2c_dev->reg_base + I2C_INTR_CLR);
reg_val = readl(i2c_dev->reg_base + I2C_ENABLE);
2023-08-30 16:21:18 +08:00
reg_val &= ~I2C_ENABLE_BIT;
2024-06-04 19:00:30 +08:00
writel(reg_val, i2c_dev->reg_base + I2C_ENABLE);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline unsigned long hal_i2c_module_status(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
return readl(i2c_dev->reg_base + I2C_ENABLE_STATUS) & 1;
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_transmit_data(aic_i2c_ctrl *i2c_dev, uint8_t data)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(data, i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_transmit_data_with_cmd(aic_i2c_ctrl *i2c_dev,
2023-08-30 16:21:18 +08:00
unsigned long data)
{
2024-06-04 19:00:30 +08:00
writel(data, i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_transmit_data_with_stop_bit(aic_i2c_ctrl *i2c_dev,
2023-08-30 16:21:18 +08:00
uint8_t data)
{
uint32_t reg_val;
reg_val = I2C_DATA_CMD_STOP | data;
2024-06-04 19:00:30 +08:00
writel(reg_val, i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
static inline unsigned long
2024-06-04 19:00:30 +08:00
hal_i2c_get_transmit_fifo_num(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
return readl(i2c_dev->reg_base + I2C_TXFLR);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_transfer_stop_bit(aic_i2c_ctrl *i2c_dev)
2024-01-27 08:47:24 +08:00
{
2024-06-04 19:00:30 +08:00
writel(I2C_DATA_CMD_STOP, i2c_dev->reg_base + I2C_DATA_CMD);
2024-01-27 08:47:24 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_read_data_cmd(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(I2C_DATA_CMD_READ, i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_read_data_cmd_with_stop_bit(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(I2C_DATA_CMD_READ | I2C_DATA_CMD_STOP, i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline unsigned long hal_i2c_get_receive_fifo_num(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
return readl(i2c_dev->reg_base + I2C_RXFLR);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline uint8_t hal_i2c_get_receive_data(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
return readb(i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
static inline void
2024-06-04 19:00:30 +08:00
hal_i2c_read_data_cmd_with_restart_stop_bit(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
writel(I2C_DATA_CMD_READ | I2C_DATA_CMD_STOP | I2C_DATA_CMD_RESTART,
2024-06-04 19:00:30 +08:00
i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
static inline void
2024-06-04 19:00:30 +08:00
hal_i2c_read_data_cmd_with_restart_bit(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-04-03 16:40:57 +08:00
uint32_t reg_val;
2024-06-04 19:00:30 +08:00
reg_val = readl(i2c_dev->reg_base + I2C_CTL);
2024-04-03 16:40:57 +08:00
reg_val |= I2C_CTL_RESTART_ENABLE;
2024-06-04 19:00:30 +08:00
writel(reg_val, i2c_dev->reg_base + I2C_CTL);
writel(I2C_DATA_CMD_READ | I2C_DATA_CMD_RESTART, i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline unsigned long hal_i2c_set_read_cmd(unsigned long reg_val)
2023-08-30 16:21:18 +08:00
{
return (reg_val | I2C_DATA_CMD_READ);
}
2024-06-04 19:00:30 +08:00
static inline unsigned long hal_i2c_set_stop_bit(unsigned long reg_val)
2023-08-30 16:21:18 +08:00
{
return (reg_val | I2C_DATA_CMD_STOP);
}
2024-06-04 19:00:30 +08:00
static inline unsigned long hal_i2c_set_restart_bit(unsigned long reg_val)
2023-08-30 16:21:18 +08:00
{
return (reg_val | I2C_DATA_CMD_RESTART);
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_set_restart_bit_with_data(aic_i2c_ctrl *i2c_dev,
2023-08-30 16:21:18 +08:00
uint8_t data)
{
2024-04-03 16:40:57 +08:00
uint32_t reg_val;
2024-06-04 19:00:30 +08:00
reg_val = readl(i2c_dev->reg_base + I2C_CTL);
2024-04-03 16:40:57 +08:00
reg_val |= I2C_CTL_RESTART_ENABLE;
2024-06-04 19:00:30 +08:00
writel(reg_val, i2c_dev->reg_base + I2C_CTL);
writel(data | I2C_DATA_CMD_RESTART, i2c_dev->reg_base + I2C_DATA_CMD);
2023-08-30 16:21:18 +08:00
}
static inline unsigned long
2024-06-04 19:00:30 +08:00
hal_i2c_get_raw_interrupt_state(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
return readl(i2c_dev->reg_base + I2C_INTR_RAW_STAT);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline unsigned long hal_i2c_get_interrupt_state(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
return readl(i2c_dev->reg_base + I2C_INTR_CLR);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_disable_all_irq(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(0, i2c_dev->reg_base + I2C_INTR_MASK);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_clear_irq_flags(aic_i2c_ctrl *i2c_dev,
2023-08-30 16:21:18 +08:00
unsigned long flags)
{
2024-06-04 19:00:30 +08:00
writel(flags, i2c_dev->reg_base + I2C_INTR_CLR);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_clear_all_irq_flags(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(0xffff, i2c_dev->reg_base + I2C_INTR_CLR);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_clear_rx_full_flag(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(I2C_INTR_RX_FULL, i2c_dev->reg_base + I2C_INTR_CLR);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_clear_tx_empty_flag(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(I2C_INTR_TX_EMPTY, i2c_dev->reg_base + I2C_INTR_CLR);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_master_enable_irq(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(I2C_INTR_MASTER_MASK, i2c_dev->reg_base + I2C_INTR_MASK);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_slave_enable_irq(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(I2C_INTR_SLAVE_MASK, i2c_dev->reg_base + I2C_INTR_MASK);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_set_transmit_fifo_threshold(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(I2C_TXFIFO_THRESHOLD, i2c_dev->reg_base + I2C_TX_TL);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_set_receive_fifo_threshold(aic_i2c_ctrl *i2c_dev,
uint8_t level)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(level - 1, i2c_dev->reg_base + I2C_RX_TL);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline void hal_i2c_config_fifo_slave(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
writel(0, i2c_dev->reg_base + I2C_TX_TL);
writel(0, i2c_dev->reg_base + I2C_RX_TL);
2023-08-30 16:21:18 +08:00
}
2024-06-04 19:00:30 +08:00
static inline int hal_i2c_bus_status(aic_i2c_ctrl *i2c_dev)
2023-08-30 16:21:18 +08:00
{
2024-06-04 19:00:30 +08:00
uint32_t status;
status = (readl(i2c_dev->reg_base + I2C_STATUS) & I2C_STATUS_ACTIVITY);
return status;
}
static inline void hal_i2c_flags_mask(aic_i2c_ctrl *i2c_dev, unsigned long flags)
{
writel(flags, i2c_dev->reg_base + I2C_INTR_MASK);
}
int hal_i2c_init(aic_i2c_ctrl *i2c_dev);
int hal_i2c_clk_init(aic_i2c_ctrl *i2c_dev);
int hal_i2c_set_master_slave_mode(aic_i2c_ctrl *i2c_dev);
int hal_i2c_master_10bit_addr(aic_i2c_ctrl *i2c_dev);
int hal_i2c_slave_10bit_addr(aic_i2c_ctrl *i2c_dev);
int hal_i2c_slave_own_addr(aic_i2c_ctrl *i2c_dev, uint32_t addr);
void hal_i2c_target_addr(aic_i2c_ctrl *i2c_dev, uint32_t addr);
void hal_i2c_set_hold(aic_i2c_ctrl *i2c_dev, u32 val);
int hal_i2c_speed_mode_select(aic_i2c_ctrl *i2c_dev,
uint32_t clk_freq, uint8_t mode);
int32_t hal_i2c_wait_bus_free(aic_i2c_ctrl *i2c_dev, uint32_t timeout);
int32_t hal_i2c_master_send_msg(aic_i2c_ctrl *i2c_dev,
struct aic_i2c_msg *msg, uint8_t is_last_message);
int32_t hal_i2c_master_receive_msg(aic_i2c_ctrl *i2c_dev,
2024-04-03 16:40:57 +08:00
struct aic_i2c_msg *msg, uint8_t is_last_message);
2023-08-30 16:21:18 +08:00
#ifdef __cplusplus
}
#endif
#endif /* _AIC_HAL_I2C_ */