// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2009 ST-Ericsson SA
* Copyright (C) 2009 STMicroelectronics
*
* I2C master mode controller driver, used in Nomadik 8815
* and Ux500 platforms.
*
* Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
* Author: Sachin Verma <sachin.verma@st.com>
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/amba/bus.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#define DRIVER_NAME "nmk-i2c"
/* I2C Controller register offsets */
#define I2C_CR (0x000)
#define I2C_SCR (0x004)
#define I2C_HSMCR (0x008)
#define I2C_MCR (0x00C)
#define I2C_TFR (0x010)
#define I2C_SR (0x014)
#define I2C_RFR (0x018)
#define I2C_TFTR (0x01C)
#define I2C_RFTR (0x020)
#define I2C_DMAR (0x024)
#define I2C_BRCR (0x028)
#define I2C_IMSCR (0x02C)
#define I2C_RISR (0x030)
#define I2C_MISR (0x034)
#define I2C_ICR (0x038)
/* Control registers */
#define I2C_CR_PE (0x1 << 0) /* Peripheral Enable */
#define I2C_CR_OM (0x3 << 1) /* Operating mode */
#define I2C_CR_SAM (0x1 << 3) /* Slave addressing mode */
#define I2C_CR_SM (0x3 << 4) /* Speed mode */
#define I2C_CR_SGCM (0x1 << 6) /* Slave general call mode */
#define I2C_CR_FTX (0x1 << 7) /* Flush Transmit */
#define I2C_CR_FRX (0x1 << 8) /* Flush Receive */
#define I2C_CR_DMA_TX_EN (0x1 << 9) /* DMA Tx enable */
#define I2C_CR_DMA_RX_EN (0x1 << 10) /* DMA Rx Enable */
#define I2C_CR_DMA_SLE (0x1 << 11) /* DMA sync. logic enable */
#define I2C_CR_LM (0x1 << 12) /* Loopback mode */
#define I2C_CR_FON (0x3 << 13) /* Filtering on */
#define I2C_CR_FS (0x3 << 15) /* Force stop enable */
/* Master controller (MCR) register */
#define I2C_MCR_OP (0x1 << 0) /* Operation */
#define I2C_MCR_A7 (0x7f << 1) /* 7-bit address */
#define I2C_MCR_EA10 (0x7 << 8) /* 10-bit Extended address */
#define I2C_MCR_SB (0x1 << 11) /* Extended address */
#define I2C_MCR_AM (0x3 << 12) /* Address type */
#define I2C_MCR_STOP (0x1 << 14) /* Stop condition */
#define I2C_MCR_LENGTH (0x7ff << 15) /* Transaction length */
/* Status register (SR) */
#define I2C_SR_OP (0x3 << 0) /* Operation */
#define I2C_SR_STATUS (0x3 << 2) /* controller status */
#define I2C_SR_CAUSE (0x7 << 4) /* Abort cause */
#define I2C_SR_TYPE (0x3 << 7) /* Receive type */
#define I2C_SR_LENGTH (0x7ff << 9) /* Transfer length */
/* Interrupt mask set/clear (IMSCR) bits */
#define I2C_IT_TXFE (0x1 << 0)
#define I2C_IT_TXFNE (0x1 << 1)
#define I2C_IT_TXFF (0x1 << 2)
#define I2C_IT_TXFOVR (0x1 << 3)
#define I2C_IT_RXFE (0x1 << 4)
#define I2C_IT_RXFNF (0x1 << 5)
#define I2C_IT_RXFF (0x1 << 6)
#define I2C_IT_RFSR (0x1 << 16)
#define I2C_IT_RFSE (0x1 << 17)
#define I2C_IT_WTSR (0x1 << 18)
#define I2C_IT_MTD (0x1 << 19)
#define I2C_IT_STD (0x1 << 20)
#define I2C_IT_MAL (0x1 << 24)
#define I2C_IT_BERR (0x1 << 25)
#define I2C_IT_MTDWS (0x1 << 28)
#define GEN_MASK(val, mask, sb) (((val) << (sb)) & (mask))
/* some bits in ICR are reserved */
#define I2C_CLEAR_ALL_INTS 0x131f007f
/* first three msb bits are reserved */
#define IRQ_MASK(mask) (mask & 0x1fffffff)
/* maximum threshold value */
#define MAX_I2C_FIFO_THRESHOLD 15
enum i2c_freq_mode {
I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */
I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */
};
/**
* struct i2c_vendor_data - per-vendor variations
* @has_mtdws: variant has the MTDWS bit
* @fifodepth: variant FIFO depth
*/
struct i2c_vendor_data {
bool has_mtdws;
u32 fifodepth;
};
enum i2c_status {
I2C_NOP,
I2C_ON_GOING,
I2C_OK,
I2C_ABORT
};
/* operation */
enum i2c_operation {
I2C_NO_OPERATION = 0xff,
I2C_WRITE = 0x00,
I2C_READ = 0x01
};
/**
* struct i2c_nmk_client - client specific data
* @slave_adr: 7-bit slave address
* @count: no. bytes to be transferred
* @buffer: client data buffer
* @xfer_bytes: bytes transferred till now
* @operation: current I2C operation
*/
struct i2c_nmk_client {
unsigned short slave_adr;
unsigned long count;
unsigned char *buffer;
unsigned long xfer_bytes;
enum i2c_operation operation;
};
/**
* struct nmk_i2c_dev - private data structure of the controller.
* @vendor: vendor data for this variant.
* @adev: parent amba device.
* @adap: corresponding I2C adapter.
* @irq: interrupt line for the controller.
* @virtbase: virtual io memory area.
* @clk: hardware i2c block clock.
* @cli: holder of client specific data.
* @clk_freq: clock frequency for the operation mode
* @tft: Tx FIFO Threshold in bytes
* @rft: Rx FIFO Threshold in bytes
* @timeout Slave response timeout (ms)
* @sm: speed mode
* @stop: stop condition.
* @xfer_complete: acknowledge completion for a I2C message.
* @result: controller propogated result.
*/
struct nmk_i2c_dev {
struct i2c_vendor_data *vendor;
struct amba_device *adev;
struct i2c_adapter adap;
int irq;
void __iomem *virtbase;
struct clk *clk;
struct i2c_nmk_client cli;
u32 clk_freq;
unsigned char tft;
unsigned char rft;
int timeout;
enum i2c_freq_mode sm;
int stop;
struct completion xfer_complete;
int result;
};
/* controller's abort causes */
static const char *abort_causes[] = {
"no ack received after address transmission",
"no ack received during data phase",
"ack received after xmission of master code",
"master lost arbitration",
"slave restarts",
"slave reset",
"overflow, maxsize is 2047 bytes",
};
static inline void i2c_set_bit(void __iomem *reg, u32 mask)
{
writel(readl(reg) | mask, reg);
}
static inline void i2c_clr_bit(void __iomem *reg, u32 mask)
{
writel(readl(reg) &