155 lines
4 KiB
C
155 lines
4 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only
|
|
*
|
|
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _I2C_SLAVE_H_
|
|
#define _I2C_SLAVE_H_
|
|
|
|
#define I2C_S_DEVICE_ADDR 0x00
|
|
#define I2C_S_IRQ_STATUS 0x08
|
|
#define I2C_S_IRQ_CLR 0x0C
|
|
#define I2C_S_IRQ_EN 0x10
|
|
#define I2C_S_IRQ_FORCE 0x14
|
|
#define I2C_S_CONFIG 0x18
|
|
#define I2C_S_CONTROL 0x1C
|
|
#define I2C_S_FIFOS_STATUS 0x20
|
|
#define I2C_S_TX_FIFO 0x24
|
|
#define I2C_S_RX_FIFO 0x28
|
|
#define I2C_S_CORE_VERSION 0x2C
|
|
#define I2C_S_CHAR_DATA0 0x30
|
|
#define I2C_S_CHAR_DATA1 0x34
|
|
#define I2C_S_CHAR_CFG 0x38
|
|
#define I2C_S_DEBUG_REG1 0x3C
|
|
#define I2C_S_DEBUG_REG2 0x40
|
|
#define I2C_S_SW_RESET_REG 0x4C
|
|
#define I2C_S_CLK_LOW_TIMEOUT 0x50
|
|
#define I2C_S_CLK_RELEASE_DELAY_CNT_VAL 0x54
|
|
#define I2C_S_SDA_HOLD_CNT_VAL 0x58
|
|
#define SMBALERT_REG 0x5C
|
|
#define SMBALERT_STATUS_REG 0x60
|
|
#define SMBALERT_PEC_REG 0x64
|
|
|
|
/* I2C Slave CONFIG reg fields */
|
|
#define CORE_EN (BIT(0))
|
|
#define GCA_SUPPORTED (BIT(3))
|
|
|
|
/* I2C Slave CONTROL reg fields */
|
|
#define CLEAR_RX_FIFO (BIT(0))
|
|
#define CLEAR_TX_FIFO (BIT(1))
|
|
#define NACK (BIT(2))
|
|
#define ACK_RESUME (BIT(3))
|
|
|
|
/* I2C Slave SW RESET reg fields */
|
|
#define SW_RESET (BIT(0))
|
|
|
|
/* I2C Slave CLK_LOW_TIMEOUT reg fields */
|
|
#define TIMER_MODE (BIT(30))
|
|
|
|
#define SLAVE_ADDR 0x30
|
|
#define I2C_SLAVE_MAX_MSG_SIZE 32
|
|
#define I2C_SLAVE_BYTE_DATA 1
|
|
#define I2C_SLAVE_WORD_DATA 2
|
|
#define APPS_PROC_TO_I2C_SLAVE_VOTE 1190000
|
|
|
|
/* Dev node for poll function */
|
|
#define I2C_SLAVE_DEV "i2c-poll"
|
|
|
|
#define I2C_SLAVE_ERR(log_ctx, print, dev, x...) \
|
|
do { \
|
|
ipc_log_string(log_ctx, x); \
|
|
if (print) { \
|
|
if (dev) \
|
|
dev_err((dev), x); \
|
|
else \
|
|
pr_err(x); \
|
|
if (dev) \
|
|
i2c_slave_trace_log(dev, x); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define I2C_SLAVE_DBG(log_ctx, print, dev, x...) \
|
|
do { \
|
|
ipc_log_string(log_ctx, x); \
|
|
if (print) { \
|
|
if (dev) \
|
|
dev_info((dev), x); \
|
|
else \
|
|
pr_debug(x); \
|
|
if (dev) \
|
|
i2c_slave_trace_log(dev, x); \
|
|
} \
|
|
} while (0)
|
|
|
|
/* I2C_S_IRQ_STATUS fields */
|
|
enum i2c_slave_irq_status {
|
|
STOP_DETECTED = 0,
|
|
RX_FIFO_FULL,
|
|
TX_FIFO_EMPTY,
|
|
RX_DATA_AVAIL,
|
|
CLOCK_LOW_TIMEOUT,
|
|
STRCH_WR,
|
|
STRCH_RD,
|
|
GCA_DETECTED,
|
|
ERR_CONDITION,
|
|
RESTART_DETECTED,
|
|
SMBALERT_ARA_DONE,
|
|
SMBALERT_LOST_ARB,
|
|
ALL_IRQ = 0xFFF
|
|
};
|
|
|
|
static const char * const irq_log[] = {
|
|
[STOP_DETECTED] = "Stop bit detected ",
|
|
[RX_FIFO_FULL] = "Rx FIFO Full",
|
|
[TX_FIFO_EMPTY] = "Tx FIFO empty",
|
|
[RX_DATA_AVAIL] = "Rx data available",
|
|
[CLOCK_LOW_TIMEOUT] = "Timeout happended",
|
|
[STRCH_WR] = "clock stretching during WR (Rx) phase",
|
|
[STRCH_RD] = "clock stretch during RD (Tx) phase.",
|
|
[GCA_DETECTED] = "General Call address detcted",
|
|
[ERR_CONDITION] = "Error condition: unexpected Start / Stop bits",
|
|
[RESTART_DETECTED] = "Repeated start bit detected",
|
|
[SMBALERT_ARA_DONE] = "ARA/SMBAlert done",
|
|
[SMBALERT_LOST_ARB] = "SLAVE arbitration lost",
|
|
};
|
|
|
|
/**
|
|
* i2c_slave: Represent an I2C slave device
|
|
* @client: Handle to slave device
|
|
* @dev: Driver model device node for the slave.
|
|
* @cdev: cdev struct to dev node
|
|
* @base: pointer to HW register base address
|
|
* @adapter: manages the bus segment hosting this I2C device
|
|
* @ipcl: pointer to IPC log
|
|
* @ahb_clk: Pointer to AHB Clock structure
|
|
* @xo_clk: Pointer to XO Clock structure
|
|
* @slave_addr: I2C slave address
|
|
* @rx_count: RX data count
|
|
* @rx_msg_buf: RX Data buffer
|
|
* @tx_count: TX data count
|
|
* @tx_msg_buf: TX Data buffer
|
|
* @irq: IRQ generated by i2c slave
|
|
* @icc_path: ICC path structure.
|
|
* @bw: ICB bandwidth.
|
|
* @readq: waitqueue for rx data.
|
|
*/
|
|
struct i2c_slave {
|
|
struct i2c_client *client;
|
|
struct device *dev;
|
|
struct cdev cdev;
|
|
void __iomem *base;
|
|
struct i2c_adapter adap;
|
|
void *ipcl;
|
|
struct clk *ahb_clk;
|
|
struct clk *xo_clk;
|
|
int slave_addr;
|
|
u8 rx_count;
|
|
u8 rx_msg_buf[I2C_SLAVE_MAX_MSG_SIZE];
|
|
u8 tx_count;
|
|
u8 *tx_msg_buf;
|
|
int irq;
|
|
struct icc_path *icc_path;
|
|
unsigned int bw;
|
|
wait_queue_head_t readq;
|
|
};
|
|
#endif /* _I2C_SLAVE_H_ */
|