/* 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_ */